From bf7c0f2705c32e44d3c3b62d60453a30dbbffe3f Mon Sep 17 00:00:00 2001 From: eadler Date: Sat, 15 Jun 2013 20:29:07 +0000 Subject: Remove CVS from the base system. Discussed with: many Reviewed by: peter, zi Approved by: core --- ObsoleteFiles.inc | 27 + UPDATING | 4 + contrib/cvs/AUTHORS | 90 - contrib/cvs/BUGS | 100 - contrib/cvs/COPYING | 251 - contrib/cvs/COPYING.LIB | 484 - contrib/cvs/ChangeLog | 5271 ----- contrib/cvs/ChangeLog.zoo | 700 - contrib/cvs/DEVEL-CVS | 30 - contrib/cvs/FAQ | 8562 ------- contrib/cvs/FREEBSD-Xlist | 22 - contrib/cvs/FREEBSD-upgrade | 45 - contrib/cvs/FREEBSD-vendstock | 11 - contrib/cvs/HACKING | 256 - contrib/cvs/INSTALL | 517 - contrib/cvs/MINOR-BUGS | 61 - contrib/cvs/Makefile.am | 58 - contrib/cvs/Makefile.in | 675 - contrib/cvs/NEWS | 1905 -- contrib/cvs/PROJECTS | 53 - contrib/cvs/README | 144 - contrib/cvs/TESTS | 240 - contrib/cvs/TODO | 862 - contrib/cvs/acinclude.m4 | 361 - contrib/cvs/aclocal.m4 | 938 - contrib/cvs/compile | 142 - contrib/cvs/config.h.in | 520 - contrib/cvs/configure | 14785 ------------ contrib/cvs/configure.in | 1172 - contrib/cvs/contrib/ChangeLog | 765 - contrib/cvs/contrib/Makefile.am | 103 - contrib/cvs/contrib/Makefile.in | 497 - contrib/cvs/contrib/README | 132 - contrib/cvs/contrib/check_cvs.in | 822 - contrib/cvs/contrib/clmerge.in | 164 - contrib/cvs/contrib/cln_hist.in | 103 - contrib/cvs/contrib/commit_prep.in | 86 - contrib/cvs/contrib/cvs2vendor.sh | 159 - contrib/cvs/contrib/cvs_acls.html | 459 - contrib/cvs/contrib/cvs_acls.in | 963 - contrib/cvs/contrib/cvscheck.man | 52 - contrib/cvs/contrib/cvscheck.sh | 95 - contrib/cvs/contrib/cvshelp.man | 561 - contrib/cvs/contrib/debug_check_log.sh | 201 - contrib/cvs/contrib/descend.man | 114 - contrib/cvs/contrib/descend.sh | 127 - contrib/cvs/contrib/dirfns.shar | 481 - contrib/cvs/contrib/intro.doc | 112 - contrib/cvs/contrib/log.in | 238 - contrib/cvs/contrib/log_accum.in | 749 - contrib/cvs/contrib/mfpipe.in | 115 - contrib/cvs/contrib/pvcs2rcs.in | 1150 - contrib/cvs/contrib/rcs-to-cvs.sh | 193 - contrib/cvs/contrib/rcs2log.sh | 742 - contrib/cvs/contrib/rcs2sccs.sh | 156 - contrib/cvs/contrib/rcslock.in | 265 - contrib/cvs/contrib/sccs2rcs.in | 327 - contrib/cvs/cvs-format.el | 93 - contrib/cvs/depcomp | 584 - contrib/cvs/diff/ChangeLog | 534 - contrib/cvs/diff/Makefile.am | 25 - contrib/cvs/diff/Makefile.in | 429 - contrib/cvs/diff/analyze.c | 1082 - contrib/cvs/diff/cmpbuf.c | 38 - contrib/cvs/diff/cmpbuf.h | 18 - contrib/cvs/diff/context.c | 462 - contrib/cvs/diff/diff.c | 1266 -- contrib/cvs/diff/diff.h | 354 - contrib/cvs/diff/diff3.c | 1930 -- contrib/cvs/diff/diffrun.h | 69 - contrib/cvs/diff/dir.c | 218 - contrib/cvs/diff/ed.c | 198 - contrib/cvs/diff/ifdef.c | 436 - contrib/cvs/diff/io.c | 711 - contrib/cvs/diff/normal.c | 69 - contrib/cvs/diff/side.c | 294 - contrib/cvs/diff/system.h | 304 - contrib/cvs/diff/util.c | 849 - contrib/cvs/diff/version.c | 5 - contrib/cvs/doc/ChangeLog | 4762 ---- contrib/cvs/doc/ChangeLog.fsf | 38 - contrib/cvs/doc/HACKING.DOCS | 46 - contrib/cvs/doc/Makefile.am | 121 - contrib/cvs/doc/Makefile.in | 816 - contrib/cvs/doc/RCSFILES | 276 - contrib/cvs/doc/cvs-paper.ms | 1069 - contrib/cvs/doc/cvs.1 | 3968 ---- contrib/cvs/doc/cvs.man.footer | 58 - contrib/cvs/doc/cvs.man.header | 61 - contrib/cvs/doc/cvs.texinfo | 14892 ------------ contrib/cvs/doc/cvsclient.texi | 2080 -- contrib/cvs/doc/mdate-sh | 201 - contrib/cvs/doc/mkman.pl | 372 - contrib/cvs/doc/stamp-1 | 4 - contrib/cvs/doc/stamp-vti | 4 - contrib/cvs/doc/version-client.texi | 4 - contrib/cvs/doc/version.texi | 4 - contrib/cvs/install-sh | 507 - contrib/cvs/lib/ChangeLog | 1161 - contrib/cvs/lib/ChangeLog.fsf | 90 - contrib/cvs/lib/Makefile.am | 118 - contrib/cvs/lib/Makefile.in | 614 - contrib/cvs/lib/argmatch.c | 85 - contrib/cvs/lib/dup2.c | 40 - contrib/cvs/lib/fncase.c | 155 - contrib/cvs/lib/fnmatch.c | 181 - contrib/cvs/lib/fnmatch.h.in | 44 - contrib/cvs/lib/ftruncate.c | 76 - contrib/cvs/lib/getdate.y | 1030 - contrib/cvs/lib/gethostname.c | 45 - contrib/cvs/lib/getline.c | 174 - contrib/cvs/lib/getline.h | 23 - contrib/cvs/lib/getopt.c | 755 - contrib/cvs/lib/getopt.h | 149 - contrib/cvs/lib/getopt1.c | 183 - contrib/cvs/lib/getpagesize.h | 55 - contrib/cvs/lib/getpass.c | 111 - contrib/cvs/lib/md5.c | 332 - contrib/cvs/lib/md5.h | 41 - contrib/cvs/lib/memmove.c | 54 - contrib/cvs/lib/mkdir.c | 125 - contrib/cvs/lib/regex.c | 6375 ------ contrib/cvs/lib/regex.h | 533 - contrib/cvs/lib/rename.c | 80 - contrib/cvs/lib/savecwd.c | 142 - contrib/cvs/lib/savecwd.h | 20 - contrib/cvs/lib/sighandle.c | 418 - contrib/cvs/lib/strerror.c | 810 - contrib/cvs/lib/stripslash.c | 40 - contrib/cvs/lib/strstr.c | 40 - contrib/cvs/lib/strtoul.c | 100 - contrib/cvs/lib/system.h | 570 - contrib/cvs/lib/test-getdate.sh | 127 - contrib/cvs/lib/valloc.c | 25 - contrib/cvs/lib/wait.h | 42 - contrib/cvs/lib/waitpid.c | 80 - contrib/cvs/lib/xgetwd.c | 67 - contrib/cvs/lib/xgssapi.h | 30 - contrib/cvs/lib/xselect.h | 21 - contrib/cvs/lib/xsize.h | 110 - contrib/cvs/lib/xtime.h | 61 - contrib/cvs/lib/yesno.c | 38 - contrib/cvs/man/ChangeLog | 382 - contrib/cvs/man/Makefile.am | 26 - contrib/cvs/man/Makefile.in | 437 - contrib/cvs/man/cvs.1 | 2212 -- contrib/cvs/man/cvs.5 | 330 - contrib/cvs/man/cvsbug.8 | 244 - contrib/cvs/mdate-sh | 92 - contrib/cvs/missing | 367 - contrib/cvs/mkinstalldirs | 161 - contrib/cvs/mktemp.sh | 39 - contrib/cvs/src/ChangeLog | 9664 -------- contrib/cvs/src/ChangeLog-9194 | 524 - contrib/cvs/src/ChangeLog-9395 | 3731 --- contrib/cvs/src/ChangeLog-96 | 4434 ---- contrib/cvs/src/ChangeLog-97 | 3249 --- contrib/cvs/src/Makefile.am | 138 - contrib/cvs/src/Makefile.in | 658 - contrib/cvs/src/add.c | 951 - contrib/cvs/src/admin.c | 950 - contrib/cvs/src/annotate.c | 302 - contrib/cvs/src/buffer.c | 1980 -- contrib/cvs/src/buffer.h | 168 - contrib/cvs/src/checkin.c | 192 - contrib/cvs/src/checkout.c | 1284 -- contrib/cvs/src/classify.c | 474 - contrib/cvs/src/client.c | 5948 ----- contrib/cvs/src/client.h | 222 - contrib/cvs/src/commit.c | 2433 -- contrib/cvs/src/create_adm.c | 187 - contrib/cvs/src/cvs.h | 945 - contrib/cvs/src/cvsbug.in | 525 - contrib/cvs/src/cvsrc.c | 169 - contrib/cvs/src/diff.c | 1178 - contrib/cvs/src/edit.c | 1164 - contrib/cvs/src/edit.h | 41 - contrib/cvs/src/entries.c | 1263 -- contrib/cvs/src/error.c | 255 - contrib/cvs/src/error.h | 62 - contrib/cvs/src/expand_path.c | 318 - contrib/cvs/src/fileattr.c | 656 - contrib/cvs/src/fileattr.h | 136 - contrib/cvs/src/filesubr.c | 1100 - contrib/cvs/src/find_names.c | 427 - contrib/cvs/src/hardlink.c | 307 - contrib/cvs/src/hardlink.h | 35 - contrib/cvs/src/hash.c | 528 - contrib/cvs/src/hash.h | 64 - contrib/cvs/src/history.c | 1666 -- contrib/cvs/src/history.h | 15 - contrib/cvs/src/ignore.c | 503 - contrib/cvs/src/import.c | 1653 -- contrib/cvs/src/lock.c | 1166 - contrib/cvs/src/log.c | 1818 -- contrib/cvs/src/login.c | 686 - contrib/cvs/src/logmsg.c | 988 - contrib/cvs/src/main.c | 1240 - contrib/cvs/src/mkmodules.c | 1054 - contrib/cvs/src/modules.c | 1101 - contrib/cvs/src/myndbm.c | 331 - contrib/cvs/src/myndbm.h | 59 - contrib/cvs/src/no_diff.c | 101 - contrib/cvs/src/parseinfo.c | 511 - contrib/cvs/src/patch.c | 849 - contrib/cvs/src/rcs.c | 9074 -------- contrib/cvs/src/rcs.h | 266 - contrib/cvs/src/rcscmds.c | 628 - contrib/cvs/src/recurse.c | 1299 -- contrib/cvs/src/release.c | 334 - contrib/cvs/src/remove.c | 294 - contrib/cvs/src/repos.c | 211 - contrib/cvs/src/root.c | 864 - contrib/cvs/src/root.h | 57 - contrib/cvs/src/run.c | 578 - contrib/cvs/src/sanity.sh | 30254 ------------------------- contrib/cvs/src/scramble.c | 245 - contrib/cvs/src/server.c | 6760 ------ contrib/cvs/src/server.h | 202 - contrib/cvs/src/stack.c | 188 - contrib/cvs/src/stack.h | 17 - contrib/cvs/src/status.c | 357 - contrib/cvs/src/subr.c | 968 - contrib/cvs/src/tag.c | 1465 -- contrib/cvs/src/update.c | 3049 --- contrib/cvs/src/update.h | 23 - contrib/cvs/src/vers_ts.c | 429 - contrib/cvs/src/version.c | 86 - contrib/cvs/src/watch.c | 522 - contrib/cvs/src/watch.h | 52 - contrib/cvs/src/wrapper.c | 623 - contrib/cvs/src/zlib.c | 760 - contrib/cvs/tools/ChangeLog | 107 - contrib/cvs/tools/Makefile.am | 24 - contrib/cvs/tools/Makefile.in | 334 - contrib/cvs/tools/README | 10 - etc/inetd.conf | 4 +- etc/mtree/BSD.usr.dist | 6 - gnu/usr.bin/Makefile | 5 - gnu/usr.bin/cvs/Makefile | 5 - gnu/usr.bin/cvs/Makefile.inc | 17 - gnu/usr.bin/cvs/contrib/Makefile | 35 - gnu/usr.bin/cvs/contrib/easy-import.pl | 403 - gnu/usr.bin/cvs/cvs/Makefile | 64 - gnu/usr.bin/cvs/cvs/prepend_args.c | 86 - gnu/usr.bin/cvs/cvs/prepend_args.h | 26 - gnu/usr.bin/cvs/cvsbug/Makefile | 25 - gnu/usr.bin/cvs/doc/Makefile | 12 - gnu/usr.bin/cvs/lib/Makefile | 37 - gnu/usr.bin/cvs/lib/config.h.proto | 532 - gnu/usr.bin/cvs/libdiff/Makefile | 17 - share/doc/psd/28.cvs/Makefile | 10 - share/doc/psd/Makefile | 3 +- share/mk/bsd.own.mk | 1 - tools/build/mk/OptionalObsoleteFiles.inc | 29 - tools/build/options/WITHOUT_KERBEROS_SUPPORT | 1 - tools/tools/nanobsd/gateworks/common | 1 - 257 files changed, 34 insertions(+), 228896 deletions(-) delete mode 100644 contrib/cvs/AUTHORS delete mode 100644 contrib/cvs/BUGS delete mode 100644 contrib/cvs/COPYING delete mode 100644 contrib/cvs/COPYING.LIB delete mode 100644 contrib/cvs/ChangeLog delete mode 100644 contrib/cvs/ChangeLog.zoo delete mode 100644 contrib/cvs/DEVEL-CVS delete mode 100644 contrib/cvs/FAQ delete mode 100644 contrib/cvs/FREEBSD-Xlist delete mode 100644 contrib/cvs/FREEBSD-upgrade delete mode 100644 contrib/cvs/FREEBSD-vendstock delete mode 100644 contrib/cvs/HACKING delete mode 100644 contrib/cvs/INSTALL delete mode 100644 contrib/cvs/MINOR-BUGS delete mode 100644 contrib/cvs/Makefile.am delete mode 100644 contrib/cvs/Makefile.in delete mode 100644 contrib/cvs/NEWS delete mode 100644 contrib/cvs/PROJECTS delete mode 100644 contrib/cvs/README delete mode 100644 contrib/cvs/TESTS delete mode 100644 contrib/cvs/TODO delete mode 100644 contrib/cvs/acinclude.m4 delete mode 100644 contrib/cvs/aclocal.m4 delete mode 100755 contrib/cvs/compile delete mode 100644 contrib/cvs/config.h.in delete mode 100755 contrib/cvs/configure delete mode 100644 contrib/cvs/configure.in delete mode 100644 contrib/cvs/contrib/ChangeLog delete mode 100644 contrib/cvs/contrib/Makefile.am delete mode 100644 contrib/cvs/contrib/Makefile.in delete mode 100644 contrib/cvs/contrib/README delete mode 100644 contrib/cvs/contrib/check_cvs.in delete mode 100755 contrib/cvs/contrib/clmerge.in delete mode 100755 contrib/cvs/contrib/cln_hist.in delete mode 100755 contrib/cvs/contrib/commit_prep.in delete mode 100644 contrib/cvs/contrib/cvs2vendor.sh delete mode 100644 contrib/cvs/contrib/cvs_acls.html delete mode 100755 contrib/cvs/contrib/cvs_acls.in delete mode 100644 contrib/cvs/contrib/cvscheck.man delete mode 100644 contrib/cvs/contrib/cvscheck.sh delete mode 100644 contrib/cvs/contrib/cvshelp.man delete mode 100755 contrib/cvs/contrib/debug_check_log.sh delete mode 100644 contrib/cvs/contrib/descend.man delete mode 100644 contrib/cvs/contrib/descend.sh delete mode 100644 contrib/cvs/contrib/dirfns.shar delete mode 100644 contrib/cvs/contrib/intro.doc delete mode 100755 contrib/cvs/contrib/log.in delete mode 100755 contrib/cvs/contrib/log_accum.in delete mode 100755 contrib/cvs/contrib/mfpipe.in delete mode 100644 contrib/cvs/contrib/pvcs2rcs.in delete mode 100644 contrib/cvs/contrib/rcs-to-cvs.sh delete mode 100644 contrib/cvs/contrib/rcs2log.sh delete mode 100644 contrib/cvs/contrib/rcs2sccs.sh delete mode 100755 contrib/cvs/contrib/rcslock.in delete mode 100755 contrib/cvs/contrib/sccs2rcs.in delete mode 100644 contrib/cvs/cvs-format.el delete mode 100755 contrib/cvs/depcomp delete mode 100644 contrib/cvs/diff/ChangeLog delete mode 100644 contrib/cvs/diff/Makefile.am delete mode 100644 contrib/cvs/diff/Makefile.in delete mode 100644 contrib/cvs/diff/analyze.c delete mode 100644 contrib/cvs/diff/cmpbuf.c delete mode 100644 contrib/cvs/diff/cmpbuf.h delete mode 100644 contrib/cvs/diff/context.c delete mode 100644 contrib/cvs/diff/diff.c delete mode 100644 contrib/cvs/diff/diff.h delete mode 100644 contrib/cvs/diff/diff3.c delete mode 100644 contrib/cvs/diff/diffrun.h delete mode 100644 contrib/cvs/diff/dir.c delete mode 100644 contrib/cvs/diff/ed.c delete mode 100644 contrib/cvs/diff/ifdef.c delete mode 100644 contrib/cvs/diff/io.c delete mode 100644 contrib/cvs/diff/normal.c delete mode 100644 contrib/cvs/diff/side.c delete mode 100644 contrib/cvs/diff/system.h delete mode 100644 contrib/cvs/diff/util.c delete mode 100644 contrib/cvs/diff/version.c delete mode 100644 contrib/cvs/doc/ChangeLog delete mode 100644 contrib/cvs/doc/ChangeLog.fsf delete mode 100644 contrib/cvs/doc/HACKING.DOCS delete mode 100644 contrib/cvs/doc/Makefile.am delete mode 100644 contrib/cvs/doc/Makefile.in delete mode 100644 contrib/cvs/doc/RCSFILES delete mode 100644 contrib/cvs/doc/cvs-paper.ms delete mode 100644 contrib/cvs/doc/cvs.1 delete mode 100644 contrib/cvs/doc/cvs.man.footer delete mode 100644 contrib/cvs/doc/cvs.man.header delete mode 100644 contrib/cvs/doc/cvs.texinfo delete mode 100644 contrib/cvs/doc/cvsclient.texi delete mode 100755 contrib/cvs/doc/mdate-sh delete mode 100644 contrib/cvs/doc/mkman.pl delete mode 100644 contrib/cvs/doc/stamp-1 delete mode 100644 contrib/cvs/doc/stamp-vti delete mode 100644 contrib/cvs/doc/version-client.texi delete mode 100644 contrib/cvs/doc/version.texi delete mode 100755 contrib/cvs/install-sh delete mode 100644 contrib/cvs/lib/ChangeLog delete mode 100644 contrib/cvs/lib/ChangeLog.fsf delete mode 100644 contrib/cvs/lib/Makefile.am delete mode 100644 contrib/cvs/lib/Makefile.in delete mode 100644 contrib/cvs/lib/argmatch.c delete mode 100644 contrib/cvs/lib/dup2.c delete mode 100644 contrib/cvs/lib/fncase.c delete mode 100644 contrib/cvs/lib/fnmatch.c delete mode 100644 contrib/cvs/lib/fnmatch.h.in delete mode 100644 contrib/cvs/lib/ftruncate.c delete mode 100644 contrib/cvs/lib/getdate.y delete mode 100644 contrib/cvs/lib/gethostname.c delete mode 100644 contrib/cvs/lib/getline.c delete mode 100644 contrib/cvs/lib/getline.h delete mode 100644 contrib/cvs/lib/getopt.c delete mode 100644 contrib/cvs/lib/getopt.h delete mode 100644 contrib/cvs/lib/getopt1.c delete mode 100644 contrib/cvs/lib/getpagesize.h delete mode 100644 contrib/cvs/lib/getpass.c delete mode 100644 contrib/cvs/lib/md5.c delete mode 100644 contrib/cvs/lib/md5.h delete mode 100644 contrib/cvs/lib/memmove.c delete mode 100644 contrib/cvs/lib/mkdir.c delete mode 100644 contrib/cvs/lib/regex.c delete mode 100644 contrib/cvs/lib/regex.h delete mode 100644 contrib/cvs/lib/rename.c delete mode 100644 contrib/cvs/lib/savecwd.c delete mode 100644 contrib/cvs/lib/savecwd.h delete mode 100644 contrib/cvs/lib/sighandle.c delete mode 100644 contrib/cvs/lib/strerror.c delete mode 100644 contrib/cvs/lib/stripslash.c delete mode 100644 contrib/cvs/lib/strstr.c delete mode 100644 contrib/cvs/lib/strtoul.c delete mode 100644 contrib/cvs/lib/system.h delete mode 100755 contrib/cvs/lib/test-getdate.sh delete mode 100644 contrib/cvs/lib/valloc.c delete mode 100644 contrib/cvs/lib/wait.h delete mode 100644 contrib/cvs/lib/waitpid.c delete mode 100644 contrib/cvs/lib/xgetwd.c delete mode 100644 contrib/cvs/lib/xgssapi.h delete mode 100644 contrib/cvs/lib/xselect.h delete mode 100644 contrib/cvs/lib/xsize.h delete mode 100644 contrib/cvs/lib/xtime.h delete mode 100644 contrib/cvs/lib/yesno.c delete mode 100644 contrib/cvs/man/ChangeLog delete mode 100644 contrib/cvs/man/Makefile.am delete mode 100644 contrib/cvs/man/Makefile.in delete mode 100644 contrib/cvs/man/cvs.1 delete mode 100644 contrib/cvs/man/cvs.5 delete mode 100644 contrib/cvs/man/cvsbug.8 delete mode 100755 contrib/cvs/mdate-sh delete mode 100755 contrib/cvs/missing delete mode 100755 contrib/cvs/mkinstalldirs delete mode 100644 contrib/cvs/mktemp.sh delete mode 100644 contrib/cvs/src/ChangeLog delete mode 100644 contrib/cvs/src/ChangeLog-9194 delete mode 100644 contrib/cvs/src/ChangeLog-9395 delete mode 100644 contrib/cvs/src/ChangeLog-96 delete mode 100644 contrib/cvs/src/ChangeLog-97 delete mode 100644 contrib/cvs/src/Makefile.am delete mode 100644 contrib/cvs/src/Makefile.in delete mode 100644 contrib/cvs/src/add.c delete mode 100644 contrib/cvs/src/admin.c delete mode 100644 contrib/cvs/src/annotate.c delete mode 100644 contrib/cvs/src/buffer.c delete mode 100644 contrib/cvs/src/buffer.h delete mode 100644 contrib/cvs/src/checkin.c delete mode 100644 contrib/cvs/src/checkout.c delete mode 100644 contrib/cvs/src/classify.c delete mode 100644 contrib/cvs/src/client.c delete mode 100644 contrib/cvs/src/client.h delete mode 100644 contrib/cvs/src/commit.c delete mode 100644 contrib/cvs/src/create_adm.c delete mode 100644 contrib/cvs/src/cvs.h delete mode 100755 contrib/cvs/src/cvsbug.in delete mode 100644 contrib/cvs/src/cvsrc.c delete mode 100644 contrib/cvs/src/diff.c delete mode 100644 contrib/cvs/src/edit.c delete mode 100644 contrib/cvs/src/edit.h delete mode 100644 contrib/cvs/src/entries.c delete mode 100644 contrib/cvs/src/error.c delete mode 100644 contrib/cvs/src/error.h delete mode 100644 contrib/cvs/src/expand_path.c delete mode 100644 contrib/cvs/src/fileattr.c delete mode 100644 contrib/cvs/src/fileattr.h delete mode 100644 contrib/cvs/src/filesubr.c delete mode 100644 contrib/cvs/src/find_names.c delete mode 100644 contrib/cvs/src/hardlink.c delete mode 100644 contrib/cvs/src/hardlink.h delete mode 100644 contrib/cvs/src/hash.c delete mode 100644 contrib/cvs/src/hash.h delete mode 100644 contrib/cvs/src/history.c delete mode 100644 contrib/cvs/src/history.h delete mode 100644 contrib/cvs/src/ignore.c delete mode 100644 contrib/cvs/src/import.c delete mode 100644 contrib/cvs/src/lock.c delete mode 100644 contrib/cvs/src/log.c delete mode 100644 contrib/cvs/src/login.c delete mode 100644 contrib/cvs/src/logmsg.c delete mode 100644 contrib/cvs/src/main.c delete mode 100644 contrib/cvs/src/mkmodules.c delete mode 100644 contrib/cvs/src/modules.c delete mode 100644 contrib/cvs/src/myndbm.c delete mode 100644 contrib/cvs/src/myndbm.h delete mode 100644 contrib/cvs/src/no_diff.c delete mode 100644 contrib/cvs/src/parseinfo.c delete mode 100644 contrib/cvs/src/patch.c delete mode 100644 contrib/cvs/src/rcs.c delete mode 100644 contrib/cvs/src/rcs.h delete mode 100644 contrib/cvs/src/rcscmds.c delete mode 100644 contrib/cvs/src/recurse.c delete mode 100644 contrib/cvs/src/release.c delete mode 100644 contrib/cvs/src/remove.c delete mode 100644 contrib/cvs/src/repos.c delete mode 100644 contrib/cvs/src/root.c delete mode 100644 contrib/cvs/src/root.h delete mode 100644 contrib/cvs/src/run.c delete mode 100755 contrib/cvs/src/sanity.sh delete mode 100644 contrib/cvs/src/scramble.c delete mode 100644 contrib/cvs/src/server.c delete mode 100644 contrib/cvs/src/server.h delete mode 100644 contrib/cvs/src/stack.c delete mode 100644 contrib/cvs/src/stack.h delete mode 100644 contrib/cvs/src/status.c delete mode 100644 contrib/cvs/src/subr.c delete mode 100644 contrib/cvs/src/tag.c delete mode 100644 contrib/cvs/src/update.c delete mode 100644 contrib/cvs/src/update.h delete mode 100644 contrib/cvs/src/vers_ts.c delete mode 100644 contrib/cvs/src/version.c delete mode 100644 contrib/cvs/src/watch.c delete mode 100644 contrib/cvs/src/watch.h delete mode 100644 contrib/cvs/src/wrapper.c delete mode 100644 contrib/cvs/src/zlib.c delete mode 100644 contrib/cvs/tools/ChangeLog delete mode 100644 contrib/cvs/tools/Makefile.am delete mode 100644 contrib/cvs/tools/Makefile.in delete mode 100644 contrib/cvs/tools/README delete mode 100644 gnu/usr.bin/cvs/Makefile delete mode 100644 gnu/usr.bin/cvs/Makefile.inc delete mode 100644 gnu/usr.bin/cvs/contrib/Makefile delete mode 100644 gnu/usr.bin/cvs/contrib/easy-import.pl delete mode 100644 gnu/usr.bin/cvs/cvs/Makefile delete mode 100644 gnu/usr.bin/cvs/cvs/prepend_args.c delete mode 100644 gnu/usr.bin/cvs/cvs/prepend_args.h delete mode 100644 gnu/usr.bin/cvs/cvsbug/Makefile delete mode 100644 gnu/usr.bin/cvs/doc/Makefile delete mode 100644 gnu/usr.bin/cvs/lib/Makefile delete mode 100644 gnu/usr.bin/cvs/lib/config.h.proto delete mode 100644 gnu/usr.bin/cvs/libdiff/Makefile delete mode 100644 share/doc/psd/28.cvs/Makefile diff --git a/ObsoleteFiles.inc b/ObsoleteFiles.inc index a7f360e..b98aa22 100644 --- a/ObsoleteFiles.inc +++ b/ObsoleteFiles.inc @@ -38,6 +38,33 @@ # xargs -n1 | sort | uniq -d; # done +# 20130614: remove CVS from base +OLD_FILES+=usr/bin/cvs +OLD_FILES+=usr/bin/cvsbug +OLD_FILES+=usr/share/examples/cvs/contrib/README +OLD_FILES+=usr/share/examples/cvs/contrib/clmerge +OLD_FILES+=usr/share/examples/cvs/contrib/cln_hist +OLD_FILES+=usr/share/examples/cvs/contrib/commit_prep +OLD_FILES+=usr/share/examples/cvs/contrib/cvs2vendor +OLD_FILES+=usr/share/examples/cvs/contrib/cvs_acls +OLD_FILES+=usr/share/examples/cvs/contrib/cvscheck +OLD_FILES+=usr/share/examples/cvs/contrib/cvscheck.man +OLD_FILES+=usr/share/examples/cvs/contrib/cvshelp.man +OLD_FILES+=usr/share/examples/cvs/contrib/descend.man +OLD_FILES+=usr/share/examples/cvs/contrib/easy-import +OLD_FILES+=usr/share/examples/cvs/contrib/intro.doc +OLD_FILES+=usr/share/examples/cvs/contrib/log +OLD_FILES+=usr/share/examples/cvs/contrib/log_accum +OLD_FILES+=usr/share/examples/cvs/contrib/mfpipe +OLD_FILES+=usr/share/examples/cvs/contrib/rcs-to-cvs +OLD_FILES+=usr/share/examples/cvs/contrib/rcs2log +OLD_FILES+=usr/share/examples/cvs/contrib/rcslock +OLD_FILES+=usr/share/examples/cvs/contrib/sccs2rcs +OLD_FILES+=usr/share/info/cvs.info.gz +OLD_FILES+=usr/share/info/cvsclient.info.gz +OLD_FILES+=usr/share/man/man1/cvs.1.gz +OLD_FILES+=usr/share/man/man5/cvs.5.gz +OLD_FILES+=usr/share/man/man8/cvsbug.8.gz # 20130417: nfs fha moved from nfsserver to nfs OLD_FILES+=usr/include/nfsserver/nfs_fha.h # 20130411: new clang import which bumps version from 3.2 to 3.3. diff --git a/UPDATING b/UPDATING index 5d6711a..7aa936b 100644 --- a/UPDATING +++ b/UPDATING @@ -31,6 +31,10 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 10.x IS SLOW: disable the most expensive debugging functionality run "ln -s 'abort:false,junk:false' /etc/malloc.conf".) +20130615: + CVS has been removed from the base system. An exact copy + of the code is available from the devel/cvs port. + 20130613: Some people report the following error after the switch to bmake: diff --git a/contrib/cvs/AUTHORS b/contrib/cvs/AUTHORS deleted file mode 100644 index 938d55a..0000000 --- a/contrib/cvs/AUTHORS +++ /dev/null @@ -1,90 +0,0 @@ -Authors of GNU CVS - -The conflict-resolution algorithms and much of the administrative file -definitions of CVS were based on the original package written by Dick Grune -at Vrije Universiteit in Amsterdam , and posted to -comp.sources.unix in the volume 6 release sometime in 1986. This original -version was a collection of shell scripts. I am thankful that Dick made -his work available. - -Brian Berliner from Prisma, Inc. (now at Sun Microsystems, Inc.) - converted the original CVS shell scripts into reasonably -fast C and added many, many features to support software release control -functions. See the manual page in the "man" directory. A copy of the -USENIX article presented at the Winter 1990 USENIX Conference, Washington -D.C., is included in the "doc" directory. - -Jeff Polk from BSDI converted the CVS 1.2 -sources into much more readable and maintainable C code. He also added a -whole lot of functionality and modularity to the code in the process. -See the bottom of the NEWS file (from about 1992). - -david d `zoo' zuhn contributed the working base code -for CVS 1.4 Alpha. His work carries on from work done by K. Richard Pixley -and others at Cygnus Support. The CVS 1.4 upgrade is due in large part to -Zoo's efforts. - -David G. Grubbs contributed the CVS "history" and "release" -commands. As well as the ever-so-useful "-n" option of CVS which tells CVS -to show what it would do, without actually doing it. He also contributed -support for the .cvsignore file. - -The Free Software Foundation (GNU) contributed most of the portability -framework that CVS now uses. This can be found in the "configure" script, -the Makefile's, and basically most of the "lib" directory. - -K. Richard Pixley, Cygnus Support contributed many bug -fixes/enhancement as well as completing early reviews of the CVS 1.3 manual -pages. - -Roland Pesch, then of Cygnus Support contributed -brand new cvs(1) and cvs(5) manual pages. Thanks to him for saving us -from poor use of our language! - -Paul Sander, HaL Computer Systems, Inc. wrote and -contributed the code in lib/sighandle.c. I added support for POSIX, BSD, -and non-POSIX/non-BSD systems. - -Jim Kingdon and others at Cygnus Support wrote the -remote repository access code. - -Larry Jones and Derek Price have been maintaining and -enhancing CVS for some years. Mark D. Baushke came on in -2003. - -Conrad Pino began maintaining the Windows port in 2004. - -There have been many, many contributions not listed here. Consult the -individual ChangeLog files in each directory for a more complete idea. - -In addition to the above contributors, the following Beta testers -deserve special mention for their support. This is only a partial -list; if you have helped in this way and would like to be listed, let -bug-cvs know (as described in the Cederqvist manual). - - Mark D. Baushke - Per Cederqvist - J.T. Conklin - Vince DeMarco - Paul Eggert - Lal George - Dean E. Hardi - Mike Heath - Jim Kingdon - Bernd Leibing - Benedict Lofstedt - Dave Love - Robert Lupton the Good - Tom McAliney - Eberhard Mattes - Jim Meyering - Thomas Mohr - Thomas Nilsson - Raye Raskin - Harlan Stenn - Gunnar Tornblom - Greg A. Woods - -Many contributors have added code to the "contrib" directory. See the -README file there for a list of what is available. There is also a -contributed GNU Emacs CVS-mode in tools/pcl-cvs. diff --git a/contrib/cvs/BUGS b/contrib/cvs/BUGS deleted file mode 100644 index c7ce3fe..0000000 --- a/contrib/cvs/BUGS +++ /dev/null @@ -1,100 +0,0 @@ -See the Cederqvist manual (cvs.texinfo) for information on how to -report bugs (and what will happen to your bug reports if you do). - -The following is a list of some of the known bugs. It may or may not -be comprehensive. We would dearly love for people to volunteer to -help us keep it up to date (for starters, if you notice any -inaccuracies, please let bug-cvs know as described in the Cederqvist -manual). There are some other reported bugs in MINOR-BUGS; the -difference, at least in theory, is that those bugs are less serious. - - -* For platform-specific information (in some cases including known -bugs), see README.VMS, windows-NT/README, or os2/README. There is no -similar file for the unix-like operating systems (not yet, at least). -This file also might contain some platform-specific bugs. - - -* If your login name contains a space or various other characters -(particularly an issue on Windows), CVS will have trouble (it will -write invalid RCS files, probably). The fix would be to have CVS -change such characters to underscores before writing them to the RCS -file. Furthermore, the LOGNAME or USER environment variables usually -won't override the system login name, so this can be hard to work -around. - - -* If you specify the -w global option to client/server CVS, it only -overrides a CVSREAD environment variable set on the client, not a -CVSREAD variable which was set on the server (for example, in .bashrc -when the server was run via rsh). The fix of course will be to -provide a "Option-read-write" request which sends -w, in addition to -"Global_option -r" which sends -r. - - -* Symbolic links to files will not work with or without LockDir. In the -repository, you should avoid using symbolic links to files since this issue -can cause data loss. Symlinks are only a problem when writing files. If your -repository does not allow any write access, symlinks are not a problem. - - -* Symbolic links to directories will not work with LockDir. In the -repository, you should avoid using symbolic links to directories if -you intend to use LockDir as the correct directory will NOT be locked -by CVS during write. Directory symlinks are not recommended, but should work -as long as LockDir is not being used. Symlinks are only a problem when -writing files. If your repository does not allow any write access, symlinks -are never a problem, whether or not LockDir is in use. - - -* The -m option to "cvs add" does not work with client/server CVS. -CVS will accept the option, but it won't actually set the -file's description. - - -* cvs update walks into a user's work directory if there's a directory - of the same name in the repository even if the user's directory - doesn't yet have a CVS admin sub-directory. This can greatly confuse - users who try to add the same directory at nearly the same time. - - -* From: "Charles M. Hannum" - To: info-cvs@prep.ai.mit.edu - Subject: Still one more bug - Date: Sat, 25 Feb 1995 17:01:15 -0500 - - mycroft@duality [1]; cd /usr/src/lib/libc - mycroft@duality [1]; cvs diff -C2 '-D1 day ago' -Dnow - cvs server: Diffing . - cvs server: Diffing DB - cvs [server aborted]: could not chdir to DB: No such file or directory - mycroft@duality [1]; - - `DB' is an old directory, which no longer has files in it, and is - removed automatically when I use the `-P' option to checkout. - - This error doesn't occur when run locally. - - P.S. Is anyone working on fixing these bugs? - - -* CVS does not always seem to be waiting to the next filesystem timestamp -quanta after commits. So far this has only shown up in testing under the BSDI -OS. The symptoms are that ocassionally CVS will not notice that modified files -are modified, though the file must be modified within a short time after the -commit, probably milliseconds or seconds, for this symptom to be noticed. One -suspected cause is that one of the calls to sleep_past() is being called with -an incorrect value, though this does not explain why symptoms have only been -noticed under BSDI. - - -* Status - - /*-------. - | Stable | - `-------*/ - - /*-------------------------. - | Sane for full scale use. | - `-------------------------*/ - diff --git a/contrib/cvs/COPYING b/contrib/cvs/COPYING deleted file mode 100644 index 57da8a4..0000000 --- a/contrib/cvs/COPYING +++ /dev/null @@ -1,251 +0,0 @@ -[I have snipped the snail mail address of the FSF because it has -changed in the past and is likely to change again. The current -address should be at http://www.gnu.org/] - - GNU GENERAL PUBLIC LICENSE - Version 1, February 1989 - - Copyright (C) 1989 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The license agreements of most software companies try to keep users -at the mercy of those companies. By contrast, our General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. The -General Public License applies to the Free Software Foundation's -software and to any other program whose authors commit to using it. -You can use it for your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Specifically, the General Public License is designed to make -sure that you have the freedom to give away or sell copies of free -software, that you receive source code or can get it if you want it, -that you can change the software or use pieces of it in new free -programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of a such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must tell them their rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any program or other work which -contains a notice placed by the copyright holder saying it may be -distributed under the terms of this General Public License. The -"Program", below, refers to any such program or work, and a "work based -on the Program" means either the Program or any work containing the -Program or a portion of it, either verbatim or with modifications. Each -licensee is addressed as "you". - - 1. You may copy and distribute verbatim copies of the Program's source -code as you receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice and -disclaimer of warranty; keep intact all the notices that refer to this -General Public License and to the absence of any warranty; and give any -other recipients of the Program a copy of this General Public License -along with the Program. You may charge a fee for the physical act of -transferring a copy. - - 2. You may modify your copy or copies of the Program or any portion of -it, and copy and distribute such modifications under the terms of Paragraph -1 above, provided that you also do the following: - - a) cause the modified files to carry prominent notices stating that - you changed the files and the date of any change; and - - b) cause the whole of any work that you distribute or publish, that - in whole or in part contains the Program or any part thereof, either - with or without modifications, to be licensed at no charge to all - third parties under the terms of this General Public License (except - that you may choose to grant warranty protection to some or all - third parties, at your option). - - c) If the modified program normally reads commands interactively when - run, you must cause it, when started running for such interactive use - in the simplest and most usual way, to print or display an - announcement including an appropriate copyright notice and a notice - that there is no warranty (or else, saying that you provide a - warranty) and that users may redistribute the program under these - conditions, and telling the user how to view a copy of this General - Public License. - - d) You may charge a fee for the physical act of transferring a - copy, and you may at your option offer warranty protection in - exchange for a fee. - -Mere aggregation of another independent work with the Program (or its -derivative) on a volume of a storage or distribution medium does not bring -the other work under the scope of these terms. - - 3. You may copy and distribute the Program (or a portion or derivative of -it, under Paragraph 2) in object code or executable form under the terms of -Paragraphs 1 and 2 above provided that you also do one of the following: - - a) accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of - Paragraphs 1 and 2 above; or, - - b) accompany it with a written offer, valid for at least three - years, to give any third party free (except for a nominal charge - for the cost of distribution) a complete machine-readable copy of the - corresponding source code, to be distributed under the terms of - Paragraphs 1 and 2 above; or, - - c) accompany it with the information you received as to where the - corresponding source code may be obtained. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form alone.) - -Source code for a work means the preferred form of the work for making -modifications to it. For an executable file, complete source code means -all the source code for all modules it contains; but, as a special -exception, it need not include source code for modules which are standard -libraries that accompany the operating system on which the executable -file runs, or for standard header files or definitions files that -accompany that operating system. - - 4. You may not copy, modify, sublicense, distribute or transfer the -Program except as expressly provided under this General Public License. -Any attempt otherwise to copy, modify, sublicense, distribute or transfer -the Program is void, and will automatically terminate your rights to use -the Program under this License. However, parties who have received -copies, or rights to use copies, from you under this General Public -License will not have their licenses terminated so long as such parties -remain in full compliance. - - 5. By copying, distributing or modifying the Program (or any work based -on the Program) you indicate your acceptance of this license to do so, -and all its terms and conditions. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the original -licensor to copy, distribute or modify the Program subject to these -terms and conditions. You may not impose any further restrictions on the -recipients' exercise of the rights granted herein. - - 7. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of the license which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -the license, you may choose any version ever published by the Free Software -Foundation. - - 8. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 9. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 10. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - Appendix: How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to humanity, the best way to achieve this is to make it -free software which everyone can redistribute and change under these -terms. - - To do so, attach the following notices to the program. It is safest to -attach them to the start of each source file to most effectively convey -the exclusion of warranty; and each file should have at least the -"copyright" line and a pointer to where the full notice is found. - - - Copyright (C) 19yy - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 1, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc. - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) 19xx name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the -appropriate parts of the General Public License. Of course, the -commands you use may be called something other than `show w' and `show -c'; they could even be mouse-clicks or menu items--whatever suits your -program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - program `Gnomovision' (a program to direct compilers to make passes - at assemblers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -That's all there is to it! diff --git a/contrib/cvs/COPYING.LIB b/contrib/cvs/COPYING.LIB deleted file mode 100644 index 5e5cda2..0000000 --- a/contrib/cvs/COPYING.LIB +++ /dev/null @@ -1,484 +0,0 @@ -[I have snipped the snail mail address of the FSF because it has -changed in the past and is likely to change again. The current -address should be at http://www.gnu.org/] - - GNU LIBRARY GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1991 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - -[This is the first released version of the library GPL. It is - numbered 2 because it goes with version 2 of the ordinary GPL.] - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Library General Public License, applies to some -specially designated Free Software Foundation software, and to any -other libraries whose authors decide to use it. You can use it for -your libraries, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if -you distribute copies of the library, or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link a program with the library, you must provide -complete object files to the recipients so that they can relink them -with the library, after making changes to the library and recompiling -it. And you must show them these terms so they know their rights. - - Our method of protecting your rights has two steps: (1) copyright -the library, and (2) offer you this license which gives you legal -permission to copy, distribute and/or modify the library. - - Also, for each distributor's protection, we want to make certain -that everyone understands that there is no warranty for this free -library. If the library is modified by someone else and passed on, we -want its recipients to know that what they have is not the original -version, so that any problems introduced by others will not reflect on -the original authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that companies distributing free -software will individually obtain patent licenses, thus in effect -transforming the program into proprietary software. To prevent this, -we have made it clear that any patent must be licensed for everyone's -free use or not licensed at all. - - Most GNU software, including some libraries, is covered by the ordinary -GNU General Public License, which was designed for utility programs. This -license, the GNU Library General Public License, applies to certain -designated libraries. This license is quite different from the ordinary -one; be sure to read it in full, and don't assume that anything in it is -the same as in the ordinary license. - - The reason we have a separate public license for some libraries is that -they blur the distinction we usually make between modifying or adding to a -program and simply using it. Linking a program with a library, without -changing the library, is in some sense simply using the library, and is -analogous to running a utility program or application program. However, in -a textual and legal sense, the linked executable is a combined work, a -derivative of the original library, and the ordinary General Public License -treats it as such. - - Because of this blurred distinction, using the ordinary General -Public License for libraries did not effectively promote software -sharing, because most developers did not use the libraries. We -concluded that weaker conditions might promote sharing better. - - However, unrestricted linking of non-free programs would deprive the -users of those programs of all benefit from the free status of the -libraries themselves. This Library General Public License is intended to -permit developers of non-free programs to use free libraries, while -preserving your freedom as a user of such programs to change the free -libraries that are incorporated in them. (We have not seen how to achieve -this as regards changes in header files, but we have achieved it as regards -changes in the actual functions of the Library.) The hope is that this -will lead to faster development of free libraries. - - The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, while the latter only -works together with the library. - - Note that it is possible for a library to be covered by the ordinary -General Public License rather than by this special one. - - GNU LIBRARY GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any software library which -contains a notice placed by the copyright holder or other authorized -party saying it may be distributed under the terms of this Library -General Public License (also called "this License"). Each licensee is -addressed as "you". - - A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. - - The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".) - - "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, complete source code means -all the source code for all modules it contains, plus any associated -interface definition files, plus the scripts used to control compilation -and installation of the library. - - Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does -and what the program that uses the Library does. - - 1. You may copy and distribute verbatim copies of the Library's -complete source code as you receive it, in any medium, provided that -you conspicuously and appropriately publish on each copy an -appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the -Library. - - You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee. - - 2. You may modify your copy or copies of the Library or any portion -of it, thus forming a work based on the Library, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) The modified work must itself be a software library. - - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Library, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote -it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Library. - -In addition, mere aggregation of another work not based on the Library -with the Library (or with a work based on the Library) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so -that they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in -these notices. - - Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you accompany -it with the complete corresponding machine-readable source code, which -must be distributed under the terms of Sections 1 and 2 above on a -medium customarily used for software interchange. - - If distribution of object code is made by offering access to copy -from a designated place, then offering equivalent access to copy the -source code from the same place satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. -Section 6 states terms for distribution of such executables. - - When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law. - - If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.) - - Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, -whether or not they are linked directly with the Library itself. - - 6. As an exception to the Sections above, you may also compile or -link a "work that uses the Library" with the Library to produce a -work containing portions of the Library, and distribute that work -under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications. - - You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things: - - a) Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that - uses the Library", as object code and/or source code, so that the - user can modify the Library and then relink to produce a modified - executable containing the modified Library. (It is understood - that the user who changes the contents of definitions files in the - Library will not necessarily be able to recompile the application - to use the modified definitions.) - - b) Accompany the work with a written offer, valid for at - least three years, to give the same user the materials - specified in Subsection 6a, above, for a charge no more - than the cost of performing this distribution. - - c) If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place. - - d) Verify that the user has already received a copy of these - materials or that you have already sent this user a copy. - - For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. However, as a special exception, -the source code distributed need not include anything that is normally -distributed (in either source or binary form) with the major -components (compiler, kernel, and so on) of the operating system on -which the executable runs, unless that component itself accompanies -the executable. - - It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute. - - 7. You may place library facilities that are a work based on the -Library side-by-side in a single library together with other library -facilities not covered by this License, and distribute such a combined -library, provided that the separate distribution of the work based on -the Library and of the other library facilities is otherwise -permitted, and provided that you do these two things: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. - - b) Give prominent notice with the combined library of the fact - that part of it is a work based on the Library, and explaining - where to find the accompanying uncombined form of the same work. - - 8. You may not copy, modify, sublicense, link with, or distribute -the Library except as expressly provided under this License. Any -attempt otherwise to copy, modify, sublicense, link with, or -distribute the Library is void, and will automatically terminate your -rights under this License. However, parties who have received copies, -or rights, from you under this License will not have their licenses -terminated so long as such parties remain in full compliance. - - 9. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -subject to these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 11. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Library. - -If any portion of this section is held invalid or unenforceable under any -particular circumstance, the balance of the section is intended to apply, -and the section as a whole is intended to apply in other circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License may add -an explicit geographical distribution limitation excluding those countries, -so that distribution is permitted only in or among countries not thus -excluded. In such case, this License incorporates the limitation as if -written in the body of this License. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Library General Public License from time to time. -Such new versions will be similar in spirit to the present version, -but may differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Library -specifies a version number of this License which applies to it and -"any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. - - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -write to the author to ask for permission. For software which is -copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally. - - NO WARRANTY - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY -KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU -FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR -CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE -LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING -RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A -FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES. - - END OF TERMS AND CONDITIONS - - Appendix: How to Apply These Terms to Your New Libraries - - If you develop a new library, and you want it to be of the greatest -possible use to the public, we recommend making it free software that -everyone can redistribute and change. You can do so by permitting -redistribution under these terms (or, alternatively, under the terms of the -ordinary General Public License). - - To apply these terms, attach the following notices to the library. It is -safest to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least the -"copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free - Software Foundation, Inc. - -Also add information on how to contact you by electronic and paper mail. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the library, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - library `Frob' (a library for tweaking knobs) written by James Random Hacker. - - , 1 April 1990 - Ty Coon, President of Vice - -That's all there is to it! diff --git a/contrib/cvs/ChangeLog b/contrib/cvs/ChangeLog deleted file mode 100644 index 7e36c19..0000000 --- a/contrib/cvs/ChangeLog +++ /dev/null @@ -1,5271 +0,0 @@ -2008-03-10 Mark D. Baushke - - * NEWS: Note new IgnoreUnknownConfigKeys CVSROOT/config option. - -2008-01-30 Derek Price - - * NEWS: Note improved join of removals. - -2008-01-27 Mark D. Baushke - - * configure.in: Look for lshc rather than lsh to avoid problems - under Debian GNU/Linux. - * configure: Regenerated. - - * configure.in: Add support for --with-ssh and CVS_SSH. - * NEWS: Note that :extssh: looks to CVS_SSH rather tha CVS_RSH. - * Makefile.in, config.h.in, configure: Regenerated. - -2008-01-24 Mark D. Baushke - - * NEWS: Note that :extssh: method was fixed. New `cvs blame' as an - alias for `cvs annotate' command. New `cvs log -n' switch to undo - a `log -N' entry in a .cvsrc file. - -2007-12-14 Larry Jones - - * configure.in: Add --disable-mmap. - * configure: Regenerated. - -2007-10-19 Derek Price - - * cvs.texinfo: Update Ximbiot's address and Copyright dates. - -2007-08-22 Derek Price - - * NEWS: Note `cvs server' accepts `--allow-root=PATH'. Note further - `cvs add' stops for `CVS' dirs. - - * HACKING, NEWS: Note new Autotool versions. - -2007-08-16 Derek Price - - * NEWS: Note backport of `cvs --allow-root=PATH server'. - -2007-06-18 Derek Price - - * NEWS: Note import now keeps metadata to itself. - -2007-06-15 Derek Price - - * NEWS: Note `cvs import CVS-/CVS' fix. - -2007-05-07 Derek Price - - * NEWS: Note removal of remote `cvs init'. - -2006-09-06 Derek Price - - * NEWS: Note apply_rcs_diff speedup. - -2006-08-28 Derek Price - - * NEWS: Note strstr ("/./") assertion fix. - -2006-08-25 Derek Price - - * TODO (216): Removed. - -2006-08-24 Derek Price - - [bug #17032] - * NEWS: Note patch w/Name keyword fix. - -2006-07-17 Derek Price - - * FAQ, INSTALL, README: Update Copyright notice. - * HACKING: Ditto. Update Savannah URLs. - -2006-06-29 Derek Price - - * NEWS: Note trailing slash fix. - -2006-06-28 Larry Jones - - * HACKING, NEWS: Note new Autoconf version. - * configure.in (AC_PREREQ): Require Autoconf 2.60. - * config.h.in, configure, **/Makefile.in: Regenerated. - -2006-06-28 Derek Price - - [bug #16961] - * NEWS: Note double-free fix. - -2006-06-09 Derek Price - - * NEWS: Note client/server conflict fix. - -2006-05-25 Derek Price - - * configure.in: Accept --with-rsh argument to set RSH_DFLT in config.h. - Prefer `remsh' to `rsh' when autodetecting and comment rationale. - -2006-04-27 Derek Price - - * acinclude.m4 (ACX_WITH_GSSAPI): Detect libgss for HP-UX. - * NEWS: Note that GSSAPI builds under HP-UX. - (Report from Larry Jones .) - -2006-03-07 Derek Price - - * NEWS: Note rtag fixes. - -2006-02-26 Derek Price - - * NEWS: Note CVSADM fix as an efficiency improvement. - -2006-02-01 Derek Price - - * NEWS: Note unconditional val-tags lock removal. - - * NEWS: Note history buffer overflow fix. - -2006-01-30 Derek Price - - * NEWS: Note nonblocking flow control pipe fix. - -2005-12-09 Derek Price - - * NEWS: Note misc doc & bug fixes. - -2005-12-07 Derek Price - - * NEWS: Note recognition of :extssh:. - -2005-10-18 Derek Price - - * KEYS: New file, suggested by Antoine Lexy-Lambert . - * README: Mention KEYS file. - -2005-09-26 Derek Price - - [bug #14639] - * acinclude.m4: Find the crypto library on FreeBSD 5.x. - Patch from Serguei E. Leontiev . - - * NEWS: Note FreeBSD 5.x GSSAPI fix. - - * NEWS: Note fsync'd commits. - -2005-09-24 Derek Price - - * NEWS, HACKING: Standardize on Automake 1.9.6. - -2005-09-22 Derek Price - - * NEWS: Mention conflict fixes. - -2005-09-13 Derek Price - - * TESTS: Mention new $username8 & $anyusername variables. - -2005-09-04 Larry Jones - - * NEWS: s/bug-cvs@gnu.org/bug-cvs@nongnu.org/. - * configure.in: s/info-cvs@gnu.org/info-cvs@nongnu.org/. - * configure: Regenerated. - -2005-09-01 Derek Price - - * AUTHORS, DEVEL-CVS, HACKING, README: Update links, email addresses, - & mailing list descriptions. - -2005-09-01 Derek Price - - * FAQ: Update links. - -2005-09-01 Derek Price - - * HACKING, INSTALL, README, README.VMS, configure.in: Update links and - email addresses. - -2005-08-31 Derek Price - - * www/.htaccess: Remove this file. - -2005-08-31 Derek Price - - * cvs.spec.in: Note last spec file change in internal ChangeLog. - -2005-08-31 Derek Price - - * NEWS: Note spec file repair. - -2005-08-31 Derek Price - - * cvs.spec.in: Update links to point to Savannah. s/Copyright/License/ - for RPM 4.mumble. - -2005-08-30 Larry Jones - - * NEWS: Note import locking fix. - -2005-07-12 Derek Price - - * FAQ, HACKING, INSTALL: Add copyright notices. - -2005-07-11 Derek Price - - * FAQ, HACKING, INSTALL: Update license notices. - -2005-06-02 Derek Price - - * NEWS: Note server compression hang fix. - -2005-06-01 Conrad T. Pino - - * makewin32.cmd: Add Windows NT command file to build CVS Project. - Imported from revision 1.2 on feature branch. - -2005-05-27 Derek Price - - * NEWS: Note diff space split fix. - * BUGS: Remove diff space split note. - -2005-05-03 Derek Price - - * INSTALL: Add footnote about compiling a CVS checkout of CVS on a - case-insensitive UNIX file system like Mac OS X. - -2005-05-02 Derek Price - - * TODO (231): Renumber as... - (234): ...this to match numbering on 1.12.x. - -2005-05-02 Derek Price - - * TODO (231): New item. - (22, 30, 31): Remove completed items. - -2005-05-02 Derek Price - - * NEWS: Note new val-tags locks. - -2005-04-30 Derek Price - - * NEWS: Note new history locks. - -2005-04-20 Derek Price - - * NEWS: Note log overflow fix. - -2005-04-15 Derek Price - - * NEWS: Note Klocwork fixes. - -2005-04-14 Derek Price - - * NEWS: Note contrib Perl taint vulnerability fix. - -2005-03-23 Derek Price - - * ylwrap: New file. - -2005-03-15 Derek Price - - * HACKING, NEWS: Note new Automake version. - -2005-03-04 Jim Hyslop - - * NEWS: Note fix for compile errors on IRIX 5.3. - -2005-02-22 Derek Price - - * NEWS: Note recent watch on/off fileattr fix. - -2005-01-31 Derek Price - - * AUTHORS: Add Conrad Pino. - * README: Update copyright notice. - -2005-01-29 Derek Price - - * NEWS: Note some recent changes. - -2004-11-17 Derek Price - - * NEWS: Note "red file" fix source inclusion. - -2004-11-05 Conrad T. Pino - - * cvsnt.dep: Regenerated after complete rebuild. - * cvsnt.mak: Regenerated after complete rebuild. - -2004-11-03 Derek Price - - * HACKING, NEWS: Note new Autoconf & Automake versions. - -2004-10-29 Derek Price - - * NEWS: Note xreadlink fix. - -2004-10-26 Derek Price - - * NEWS: Note GSSAPI error message fix. - -2004-10-19 Derek Price - - * NEWS: Note resurrection fix. - -2004-10-14 Derek Price - - * NEWS: Note new import branch verification. - -2004-09-25 Derek Price - - * configure.in: Use doc/mkman.pl as source for doc/mkman. - -2004-09-08 Conrad T. Pino - - * cvsnt.dsp: Add "windows-NT/JmgStat.c" to project. Add - "windows-NT/JmgStat.h" to project. Add "lib/xsize.h" to project. - * cvsnt.dep: Regenerated for "cvsnt.dsp" change. - * cvsnt.mak: Regenerated for "cvsnt.dsp" change. - -2004-09-07 Derek Price - - * NEWS: Note Windows DST fix. - -2004-09-03 Derek Price - - * HACKING: Codify backwards compatibility conventions. Remove outdated - reference to very old MSVC++ releases. - -2004-08-30 Derek Price - - * NEWS: Note compliance of log_accum.pl with Perl 5.8.5. - -2004-08-24 Derek Price - - * TODO (24, 49, 92, 113): Remove completed/obsolescent items. - -2004-08-24 Derek Price - - * BUGS: Remove release subdir note. This was fixed with the commit on - 2004-02-25, based on Matthew Ogilvie's patch. - -2004-08-24 Derek Price - - * NEWS: Note r* . fix. - * BUGS: Remove r* . note. - -2004-08-24 Derek Price - - * NEWS: Note invalid tag fix. - -2004-08-24 Mark D. Baushke - - * NEWS: Note that modules -a bugfix has a change in behavior. - -2004-06-22 Derek Price - - * NEWS: Note Conrad's Windows fix. - -2004-06-21 Derek Price - - * .cvsignore: Ignore GPG signature files for distributions. - -2004-06-10 Derek Price - - * NEWS: Note manual update. - -2004-06-09 Derek Price - - * NEWS: Note Stefan & Sebastian's security fixes. - * acinclude.m4 (gl_SIZE_MAX, gl_XSIZE): Import from GNULIB. - * configure.in: Call gl_XSIZE. - -2004-06-09 Derek Price - - * NEWS: Note CAN-2004-0414 fix. - -2004-05-19 Derek Price - - * NEWS: Note CAN-2004-0396 fix. - -2004-05-17 Derek Price - - * BUGS: Note assertion failure of r* commands. - -2004-05-17 Derek Price - - * BUGS: Remove out of date comment about out of date Windows build - files and several bug reports that are so old, without similar recent - reports, that I'm assuming that the problems have been fixed. - -2004-05-15 Derek Price - - * cvsnt.dsp: Header file list updated. - * cvsnt.dep: Regenerated for "cvsnt.dsp" change. - * cvsnt.mak: Regenerated for "cvsnt.dsp" change. - (Patch from Conrad Pino .) - -2004-05-13 Derek Price - - * NEWS: Note MSVC++ project file regeneration. - -2004-05-13 Derek Price - - * cvsnt.dsw: Rename "zlib/zlib.*" to "zlib/libz.*". - Add project "lib/libcvs". - * cvsnt.dsp: Revised for "cvsnt.dsw" changes. Move "lib/*.c" to - project "lib/libcvs". Upgraded to Visual C++ 6.0 format. - * cvsnt.dep: Added for "cvsnt.dsp" change. - * cvsnt.mak: Regenerated for "cvsnt.dsp" change. - (Patch from Conrad Pino .) - - * configure.in: Generate windows-NT/fix-msvc-mak. - -2004-04-30 Derek Price - - * NEWS: Note that man page is generated from cvs.texinfo now. - * configure.in: Build doc/mkman. - * configure, Makefile.in: Regenerated. - -2004-04-26 Derek Price - - * NEWS: Note that :ext: no longer relies on an external transport with - a GNU argument processor. - -2004-04-20 Derek Price - - * NEWS: Note XP directory deletion fix. - -2004-04-16 Derek Price - - * NEWS: Correct CVS name for piped checkout issue now that we have one. - -2004-04-15 Derek Price - - * NEWS: Retroactively add CVE issue name for the piped etc issue. - -2004-04-15 Derek Price - - * NEWS: Retroactively add CVE issue name for the trojan server issue. - -2004-04-14 Derek Price - - * INSTALL (Building from source code under Unix): Move Autoconf & - Automake notes... - * HACKING (Regenerating Build Files): ...here. - -2004-04-13 Derek Price - - * NEWS: Note validation of paths passed to the client. - -2004-04-07 Derek Price - - * NEWS: Clarify relative-path up-reference article. - -2004-04-07 Derek Price - - * NEWS: Note ignoring of method options in CVSROOTs. - -2004-04-06 Derek Price - - * TODO (196, 217, 219, 220, 222, 226): Remove completed items. - (230): New item. - -2004-04-06 Derek Price - - * NEWS: Note this change. - * configure.in: Do not try and use TMP, TEMP, or TMPDIR as default - temporary directories. - * configure: Regenerated. - -2004-04-04 Derek Price - - * NEWS: Note Cygwin handles paths like X:\. - -2004-04-02 Derek Price - - * NEWS: Note Windows ISDIRSEP fix. - -2004-04-02 Derek Price - - * INSTALL: Instruct users to use the Workspace file and not the project - file for MSVC++. - (Patch from Conrad T. Pino .) - -2004-04-02 Derek Price - - * NEWS: Make some notes as to client/serverness of changes. - -2004-04-02 Derek Price - - * NEWS: Note relative path fix. - -2004-04-01 Derek Price - - * NEWS: Record run race removal. - -2004-03-31 Mark D. Baushke - - * cvs.spec.in (BuildRequires): Do not fail if info DIR file does - not exist. (Not everyone has an install-info that generates the - dir file that we want deleted.) - (Report from Geoff Beier .) - -2004-03-25 Derek Price - - * NEWS: Note failure of Cygwin to convert back slashes to slashes. - -2004-03-25 Derek Price - - * cvs.spec.in (BuildRoot): Use a more unique directory name. - -2004-03-22 Derek Price - - * INSTALL: Note compilation & --without-gssapi requirement for HPPA - with HP-UX 11.11. - (Report from Nicolas Vervelle .) - -2004-03-20 Derek Price - - * NEWS: Note resurrection fixes. - -2004-03-18 Derek Price - - * NEWS: Back out previous NEWS change at Larry Jones' suggestion. - -2004-03-17 Derek Price - - * configure.in (--enable-password-authentication-client): Correct - error message text. - * NEWS: Note this change. - * configure: Regenerated. - -2004-03-15 Derek Price - - * NEWS: Note cvs release + Kerberos fix. - -2004-03-15 Derek Price - - * configure.in: Correct grammar in help text. - * configure: Regenerated. - -2004-03-15 Derek Price - - * macintosh/.cvsignore: Complete pruning of directory started in 1999. - -2004-03-14 Derek Price - - * NEWS: Note resurrection fix. - -2004-03-14 Derek Price - - * NEWS: Note error & status message corrections. - -2004-03-14 Derek Price - - * NEWS: Note diff of added files against arbitrary revisions fix. - -2004-03-12 Derek Price - - * NEWS: Note Larry's recent documentation fixes. - -2004-03-03 Derek Price - - * NEWS: Note that directories and files named `CVS' are now also - rejected by import. - -2004-02-25 Derek Price - - * NEWS: Update dying gasp note. - -2004-02-25 Derek Price - - * NEWS: Note `cvs release' Entries corruption fix. - -2004-02-20 Derek Price - - * NEWS: Note that the dying gasp check has now been completely removed. - -2004-02-17 Derek Price - - * NEWS: Note spec file fix. - * cvs.spec: Update to avoid the error checking algorithm's of more - recent version of RPM. - -2004-02-17 Derek Price - - * NEWS: Note recent commenting of src/checkout.c and Mark's leak fixes. - -2004-02-12 Derek Price - - * NEWS: Note Mark D. Baushke's recent memory leak plugs. - -2004-02-12 Derek Price - - * NEWS: Note Ville Skyttä's other recent man page patch. - -2004-02-12 Derek Price - - * NEWS: Note Ville Skyttä's recent man page patch. - -2004-02-11 Derek Price - - * NEWS: Note :fork: segfault avoidance. - -2004-02-11 Derek Price - - * NEWS: Note readability improvements. - -2004-02-10 Derek Price - - * NEWS: Note dying gasp check. - -2004-02-10 Derek Price - - * NEWS: Note flow control pipe race fix. - -2004-02-10 Derek Price - - * BUGS: Note problems building with MSVC++ under Windows and - workaround. - * INSTALL: Ditto. - -2004-02-10 Derek Price - - * cvsnt.mak: Add stack.c and stack.h in order to compile under Windows. - * NEWS: Note Windows fixes. - * README: Update copyright notice. - -2004-02-09 Derek Price - - * NEWS: Note new tests in sanity.sh. - -2004-02-06 Derek Price - - * README: Undo accidental overwrite. - -2004-02-04 Derek Price - - * NEWS: Note that alias module recursion is now more comprehensive. - -2004-02-03 Derek Price - - * NEWS: Note case insensitive client directory case preservation. - -2004-02-02 Derek Price - - * NEWS: Note new join-rm tests. - -2004-02-02 Derek Price - - * NEWS: Note removal from the server of support for case insensitive - clients. - -2004-01-30 Derek Price - - * NEWS: Note man page fix. - -2004-01-30 Derek Price - - * NEWS: Note contrib/log_accum tidy. - -2004-01-25 Derek Price - - * NEWS: Note Kerberos 4 fix. - -2004-01-22 Derek Price - - * NEWS: Note recent infinite alias loop fix. - -2004-01-22 Derek Price - - * INSTALL: Remove a note about an Automake bug that has been fixed for - quite awhile. - -2004-01-22 Derek Price - - * INSTALL: s/Automake 1.7.5/Automake 1.7.9/. - -2004-01-14 Derek Price - - * NEWS: Note Larrys recent mktemp.sh inclusion, documentation reorg, - and zlib code fix. - -2003-12-23 Larry Jones - - * Makefile.am: Add mktemp.sh to EXTRA_DIST. - * Makefile.in: Regenerated. - - * configure.in: Get mktemp.sh from $srcdir. - * configure: Regenerated. - (Reported by Matt Selsky .) - -2003-12-18 Derek Price - - * NEWS: Add since 1.11.11 section. - * configure.in: Update for dev 1.11.11.1. - * configure: Regenerated. - -2003-12-18 Derek Price - - * configure.in: Update for release 1.11.11. - * configure: Regenerated. - -2003-12-18 Derek Price - - * NEWS: Note syslog of root attempts. - -2003-12-18 Derek Price - - * NEWS: Note that pserver can no longer run as root. - -2003-12-07 Mark D. Baushke - - * configure.in (AC_SYS_LARGEFILE): Remove. More work is needed - before AC_SYS_LARGEFILE will work on all platforms. - * configure, config.h.in: Regenerated. - * NEWS: Remove last note. - - * configure.in (AC_SYS_LARGEFILE): Add. The history file on - Solaris boxes can grow beyond 2GB. - * configure, config.h.in: Regenerated. - * NEWS: Note addition of --disable-largefiles option. - -2003-12-05 Derek Price - - * configure.in: Update to require Automake 1.7.9. - -2003-12-04 Derek Price - - * configure.in: Update for dev version 1.11.10.1. - * NEWS: Add Changes since 1.11.10 section. - * configure: Regenerated. - -2003-12-04 Derek Price - - * configure.in: Update for release 1.11.10. - * configure: Regenerated. - -2003-12-03 Derek Price - - * configure.in: Always AC_LIBOBJ(fncase) when filenames are found to be - case insensitive. - * configure: Regenerated. - -2003-11-26 Derek Price - - * NEWS: Note recase tests. - -2003-11-26 Derek Price - - * NEWS: Note new test suite functionality. - -2003-11-25 Derek Price - - * NEWS: Note latest case insensitivity fix. - -2003-11-19 Derek Price - - * NEWS: Rename "OTHER ISSUES" to "GENERAL USER ISSUES" and move the - note about the Autoconf upgrade to a new "DEVELOPER ISSUES" section. - Add a note about upgrading Automake. - * aclocal.m4, configure, **/Makefile.in: Regenerated with Automake - 1.7.9. - -2003-11-18 Derek Price - - * NEWS: Subdivide Changes section into "SERVER SECURITY ISSUES" and - "OTHER ISSUES". Note module abspath issue in security section. - -2003-11-10 Derek Price - - * BUGS: Add some detail to the last two notes Mark added. - -2003-11-10 Mark D. Baushke - - * BUGS: Note that symlinks to files will not work with or without - LockDir. Note that symlinks to directories will not work with - LockDir. - - * NEWS (Changes since 1.11.9): Note symlinked CVSROOT now works. - -2003-11-10 Derek Price - - * configure.in: Require Autoconf 2.58. - * INSTALL, NEWS: Note new Autoconf requirements. - - * configure: Regenerated. - -2003-11-04 Derek Price - - * configure.in: Add some more help text for --enable-case-sensitivity. - * configure: Regenerated. - -2003-11-03 Derek Price - - * configure.in: Require Automake 1.7.5. - -2003-11-03 Derek Price - - * INSTALL: Add some notes on Autoconf requirements. - -2003-10-31 Derek Price - - * INSTALL: Note Cygwin as an option for building CVS under Windows. - -2003-10-31 Derek Price - - * INSTALL: s/cvsgui/wincvs/. - -2003-10-27 Derek Price - - * configure.in: Move case sensitivity test to the enable-* section and - allow override via command line switch. - * NEWS: Update last news item to reflect new command line switch. - * configure, config.h.in: Regenerated. - -2003-10-27 Derek Price - - * configure.in: Add new test for a case insensitive file system. - * configure, config.h.in: Regenerated. - * NEWS: Note the above change. - -2003-10-24 Derek Price - - * NEWS: Update recent text about joins to reflect new behavior. - -2003-10-24 Derek Price - - * BUGS: Note that release of a project subdir does not remove the entry - from `./CVS/Entries'. - -2003-10-24 Derek Price - - * BUGS: Remove obsolete bug report. - (Patch from Paul Edwards .) - -2003-10-24 Derek Price - - * BUGS: Remove obsolete bug report. - (Patch from Paul Edwards .) - -2003-10-23 Mark D. Baushke - - * NEWS: Note behavior change for cvs update -jrev1 -jrev2. - -2003-10-21 Derek Price - - * NEWS: Note Mark's recent admin -m fix. - -2003-10-21 Derek Price - - * NEWS: Note the @email{} and @url{} fixes as misc documentation fixes. - -2003-10-14 Derek Price - - * NEWS: Note POSIX 1003.1-2001 compatibility of docs and scripts. - -2003-10-14 Derek Price - - Port to pedantic POSIX 1003.1-2001 hosts, such as Debian GNU/Linux - testing with _POSIX2_VERSION=200112 in the environment. - - * BUGS: Suggest 'diff -C2', not 'diff -c2'. - * FAQ: Suggest 'sort -k 1.2', not 'sort +0.1'. - * depcomp: Sync to the depcomp shipped with Automake 1.7.8, as - it has the bug fixed and that's better than maintaining our - own depcomp. - (Patch from Paul Eggert .) - -2003-10-14 Derek Price - - * INSTALL: Add HPPA 2.0 running HP-UX 10.20 for CVS 1.11.9. - (Report from Tom Kuiper .) - -2003-10-10 Derek Price - - * NEWS (Changes since 1.11.9): New section. - * configure.in: Update package version to 1.11.9.1. - * configure: Regenerated. - -2003-10-10 Derek Price - - * configure.in: Update package version to 1.11.9. - * configure: Regenerated. - -2003-10-08 Derek Price - - * NEWS: Note history reporting fix. - -2003-10-08 Derek Price - - * NEWS: Improve syntax and punctuation of my last entry. - -2003-10-08 Derek Price - - * NEWS: Note history fix for clients requesting `P' records. - -2003-10-07 Derek Price - - * NEWS: Note case insensitive file lookup fix. - -2003-10-03 Derek Price - - * NEWS: Note server ignoring `-l' with a warning. - -2003-10-02 Derek Price - - * NEWS (Changes since 1.11.8): Add empty section. - * configure.in: Update package version to 1.11.8.1. - * configure: Regenerated. - -2003-10-02 Derek Price - - * configure.in: Update package version to 1.11.8. - * configure: Regenerated. - -2003-10-02 Derek Price - - * NEWS: Note getpass fix. - -2003-09-29 Derek Price - - * NEWS (Changes since 1.11.7): Insert empty entry. - * configure.in: Update to 1.11.7.1. - * configure: Regenerated. - -2003-09-29 Derek Price - - * configure.in: Update package version to 1.11.7. - * configure: Regenerated. - -2003-09-29 Derek Price - - * NEWS: Note recent fix of the potential segfault during a diff. - -2003-09-26 Derek Price - - * BUGS: Note bug in options passed to diff via `cvs diff'. - -2003-09-12 Derek Price - - * NEWS: Note checkoutlist error message handling fix. - -2003-08-27 Larry Jones - - * NEWS: Note client/server messages have real command name, client/ - server updates get logged in history file, history file has "P" - record type. - -2003-07-29 Derek Price - - * configure.in: Replace my recent misuse of AH_VERBATIM with a call to - AC_DEFINE. - * config.h.in, configure: Regenerated. - -2003-07-29 Derek Price - - * configure.in: Do not check for getpassphrase. Define `getpass' to - `cvs_getpass' in config.h to avoid conflicts with system decls. - * NEWS: Note use of GNULIB getpass. - - * config.h.in, configure: Regenerated. - -2003-07-25 Derek Price - - * INSTALL: Note --without-gssapi required to configure on OS X. - -2003-07-18 Derek Price - - * BUGS: Remove mention of wrappers -t/-f since they are no longer - supported. - -2003-07-18 Derek Price - - * Makefile.am (EXTRA_DIST): Add cvs.spec so that RPMs can be built - directly from tarballs. - * Makefile.in: Regenerated. - -2003-07-18 Derek Price - - * TODO (72): Remove mention of the -i/-o in the modules file since they - have been removed. - -2003-06-27 Larry Jones - - * NEWS: Note LockDir fix. - -2003-06-23 Derek Price - - * configure.in: Debian Woody has -lkrb4, so check for that. - (Patch from Alexey Mahotkin .) - - * config.h.in: Regenerated. - * configure: Ditto. - -2003-06-20 Derek Price - - * INSTALL: Add some OS X platforms to the compile list. Correct link to - cvsgui.org -> wincvs.org. - -2003-06-09 Derek Price - - * cvsnt.mak: Rename win32.c to woe32.c in accordance with the GNU - convention to avoid implying that we consider the Microsoft Windows - Operating Environment any sort of "win". - -2003-06-09 Derek Price - - * NEWS: Note short patch fix. - -2003-06-09 Derek Price - - * TODO (45): Combine this with... - (30): ...this item (as #30). Remove reference to diff since the - modules file is only consulted for the r* commands. - -2003-06-02 Derek Price - - * NEWS: Note empty diff change text fix. - -2003-05-29 Derek Price - - * NEWS: Note removal of global -l option. - -2003-05-27 Derek Price - - * AUTHORS: Give Mark an email address. - -2003-05-27 Derek Price - - * cvs.spec.in: Add some files to doc. Remove redundant %defattr. - -2003-05-27 Derek Price - - * NEWS (Changes since 1.11.5): Add missing entry. - -2003-05-27 Derek Price - - * README (Credits): Move... - * AUTHORS: ...here and update. - -2003-05-26 Derek Price - - * configure.in: Update CVS version to 1.11.6.1. - - * configure: Regenerated. - -2003-05-25 Derek Price - - * configure.in: Update CVS version to 1.11.6. - - * configure: Regenerated. - -2003-05-25 Derek Price - - * BUGS: Note current intermittant BSDI failures. - -2003-05-22 Larry Jones - - * NEWS: Note recent administrative file changes. - -2003-05-21 Derek Price - - * INSTALL: Mention new Automake version. - * NEWS: Ditto. - - * Makefile.in: Regenerated. - * aclocal.m4: Ditto. - * config.h.in: Ditto. - * configure: Ditto. - -2003-05-20 Derek Price - - * INSTALL: Using Autoconf version 2.57. - * NEWS: Ditto. Reorder NEWS items to put the stuff which it is likely - that only developers care about last. - * configure: Regenerated with Autoconf 2.57. - -2003-05-09 Derek Price - - * configure.in: Back out all the S_ISSOCK changes I just made and move - the equivalent to lib/system.h. - - * configure.in: Regenerated. - * config.h.in: Ditto. - -2003-05-09 Derek Price - - * configure.in: Try again, with AC_TRY_LINK this time. - - * configure: Regenerated. - -2003-05-09 Derek Price - - * configure.in: Correct a typo in my last patch. - - * configure: Regenerated. - -2003-05-09 Derek Price - - * configure.in: Add some checks for S_ISSOCK to avoid a problem on - SCO OpenServer 5.0.6a. - (Reported by Boyd Lynn Gerber .) - - * config.h.in: Regenerated. - * configure: Ditto. - -2003-05-01 Derek Price - - * TODO (149): Remove reference to defunct RELATIVE_REPOS macro. - -2003-04-30 Derek Price - - * acinclude.m4 (ACX_WITH_GSSAPI): Fix typo in broken conditional. - (Thanks to Alexey Mahotkin .) - - * configure: Regenerated. - * aclocal.m4: Ditto. - -2003-04-28 Derek Price - - * NEWS (Changes since 1.11.5): Note removal of Checkin.prog and - Update.prog functionality. - -2003-04-10 Larry Jones - - * aclocal.m4 (AM_MAINTAINER_MODE): New macro to support - --enable-maintainer-mode. - * configure.in: Use it. - * configure: Regenerated. - * Makefile.in: Regenerated. - * noautomake.sh: Removed; no longer needed. - * INSTALL: Remove reference to noautomake.sh, add reference to - --enable-maintainer-mode. - * Makefile.am: Remove noautomake.sh. - * NEWS: Add note about --enable-maintainer-mode and noautomake.sh. - * README: Remove noautomake.sh. - -2003-04-01 Derek Price - - * BUGS: Remove a pcl-cvs bug. pcl-cvs is no longer part of the CVS - source distribution. - -2003-04-01 Derek Price - - * BUGS: Remove reference to cvs admin SEGV bug Larry Jones fixed - on 2003-02-19. - -2003-04-01 Derek Price - - * BUGS: Remove obsolete bug. - * configure.in: Tail the BUGS file for status. - - * configure: Regenerated. - -2003-03-28 Derek Price - - * configure.in (--with-editor): Quit with an error message when no - editor is found. Allow --with-editor to override $EDITOR from the - user's environment. Add vim to the list of defaults. - - * configure: Regenerated. - -2003-03-26 Derek Price - - * configure.in (--with-editor): Quit with an error message when - --without-editor is specified. - (Report from Jim Salter .) - - * configure: Regenerated. - -2003-03-24 Derek Price - - * configure.in: Add copyright notice. - * Makefile.am: Update copyright notice. - - * Makefile.in: Regenerated. - * configure: Ditto. - -2003-03-07 Derek Price - - * TESTS: Document some more global variables. - -2003-03-05 Mark D Baushke - - * NEWS (Changes since 1.11.5): Backout CVS_LOCAL_BRANCH_NUM feature. - - * NEWS (Changes since 1.11.5): Mention CVS_LOCAL_BRANCH_NUM - environment varaible. - -2003-02-25 Derek Price - - * configure.in (WITH_KRB4): Import KRB4 patch from Redhat 8.0's CVS - 1.11.2-5 SRPM. It's not the right fix, but it will work until I get - around to merging some of the code with WITH_GSSAPI and seperating the - bits into separate M4 files. - - * configure: Regenerated. - * config.h.in: Ditto. - -2003-02-28 Derek Price - - * acinclude.m4 (ACX_WITH_GSSAPI): Move the checkin from 1/23 to - aclocal.m4 to the source, here. - - * aclocal.m4: Regenerated. - * configure: Regenerated. - -2003-02-28 Larry Jones - - * TODO (206): Done in 1.11.3. - (226): Add comment about deadlock. - (228, 229): New items. - -2003-02-26 Derek Price - - * mktemp.sh: Actually add file this time. - * mktemp.sh: Add copyright notice, some comments, and attempt to return - success and error codes. - -2003-02-25 Derek Price - - * configure.in: Add checks for mktemp and sendmail. - * mktemp.sh: New file. - - * Makefile.in: Regenerated. - * configure: Ditto. - -2003-02-06 Derek Price - - * NEWS (Changes since 1.11.5): Note error message corrections. - -2003-01-30 Larry Jones - - * FAQ: Update URL for tkCVS info. - - * NEWS (Changes from 1.11.2 to 1.11.3): Add note about fixing watch - in server mode. - -2003-01-28 Derek Price - - * INSTALL: Remove a reference to options.h. - (Thanks to Jenn Vesperman for the report.) - -2003-01-28 Larry Jones - - * NEWS: Update for 1.11.5, add notes about bug fixes in older - versions. - -2003-01-23 Derek Price - - * aclocal.m4 (WITH_GSSAPI): Check for libcrypt before libroken to - satisfy a FreeBSD 4.6 dependency. - (Thanks to Jan Ruzicka for the bug - report and a partial fix.) - - * configure: regenerated. - -2003-01-20 Derek Price - - * NEWS: Update the news for the last release to mention that client - builds are not affected by the security vulnerability. - -2003-01-20 Derek Price - - * configure.in: Update to dev version 1.11.5.1. - * configure: Regenerated. - -2003-01-16 Derek Price - - * NEWS: Add 1.11.4 entry in regards to - . - The Common Vulnerabilities and Exposures project (cve.mitre.org) - has assigned the name CAN-2003-0015 to this issue. - * configure.in: Update to CVS version 1.11.5. - - * configure: Regenerated. - -2002-01-16 Derek Price - - * configure.in (--with-editor): Look for nano, the GNU GPL pico clone. - (Reported by Robin Cook .) - - * configure: Regenerated. - -2002-01-16 Derek Price - - * configure.in: Update to dev version (1.11.4.1). - * configure: Regenerated. - -2002-12-28 Derek Price - - * NEWS: Add since 1.11.3 entry. - * configure.in: Update to version 1.11.4. - * configure: Regenerated. - -2002-12-27 Derek Price - - * NEWS: Add dummy entry for since 1.11.3. - * configure.in: Update to dev version 1.11.3.1. - * configure: Regenerated. - -2002-12-27 Derek Price - - * .cvsignore: Add bz2. - * NEWS: Add note about options.h. - * configure.in: Set version to 1.11.3. - * cvs.spec.in: No longer need to remove config.cache between runs - of configure. - - * configure: Regenerated. - -2002-12-20 Derek Price - - * cvsnt.mak: Make previous rule more like Visual Studio expects. - -2002-12-19 Derek Price - - * cvsnt.mak: Add lib/fnmatch.h.in -> lib/fnmatch.h rule. - -2002-12-19 Derek Price - - * INSTALL: Remove references to options.h. - * cvsnt.mak: Ditto. - * FAQ: Ditto, plus some references to installing RCS & DIFF. Wow. - That was _really_ out of date. - * configure.in: Define MY_NDBM here rather than in src/options.h. - - * config.h.in: Regenerated. - * configure: Ditto. - -2002-12-16 Derek Price - - * INSTALL: Add a platform to the tested platforms list. - (Thanks to Johan Vermeire .) - -2002-12-04 Derek Price - - * configure.in: Add --with switch for specifying CVS_ADMIN_GROUP. - - * config.h.in: Regenerated. - * configure: Ditto. - -2002-11-21 Larry Jones - - * configure.in: Add contrib/check_cvs. - * configure: Regenerated. - -2002-11-12 Derek Price - - * .cvsignore: Update autom4te ignore pattern for version number - included in path name by new versions of autom4te. - -2002-10-28 Derek Price - - * configure.in: Flesh out some comments in regards to Sun Interactive - UNIX (ISC). - -2002-09-24 Derek Price - - * configure.in (WITH_KRB4): Update WITH_KRB4 output to use - AC_MSG_CHECKING and AC_MSG_RESULT for consitency. - (with-editor): Update comment. - - * configure: Regenerated. - -2002-09-24 Derek Price - - * configure.in (--enable-password-authenticated-client): New option. - (--enable-encryption): Increase the readability of the help text. - - * configure: Regenerated. - * config.h.in: Ditto. - -2002-09-24 Derek Price - - * configure.in (enable-encryption): Move to a more sensible location - and print a warning if it is specified with neither the client or the - server enabled. - (--with-editor): Move to a closer resemblance to alphabetical order. - (enables and withs): Reformat help strings for consistency. - * acinclude.m4: Ditto. - - * configure: Regenerated. - * aclocal.m4: Ditto. - -2002-09-24 Derek Price - - * configure.in (enable-force-editor): New option. - - * configure: Regenerated. - * config.h.in: Ditto. - -2002-09-24 Derek Price - - * acinclude.m4 (ACX_WITH_GSAPI): Use AC_MSG_CHECKING & AC_MSG_RESULT - instead of AS_MESSAGE for consistent appearance of the output even - though it makes the code look a little clunky. - -2002-09-24 Derek Price - - * INSTALL: Document --with-umask. - * configure.in (--with-umask): New option. - (--with-tmpdir): Move to something more closely resembling alphabetical - order of the --with- arguments. - - * configure: Regenerated. - * config.h.in: Ditto. - -2002-09-24 Derek Price - - * INSTALL: Note new Automake version. - * NEWS: Ditto. - * configure.in (AC_ISC_POSIX): Remove this obsolete call and comment - out some related code with an explanation. - - * Makefile.in: Regenerated using Automake 1.6.3. - * aclocal.m4: Ditto. - * configure: Regenerated. - -2002-09-24 Larry Jones - - * aclocal.m4: Remove no longer needed definition of AC_ISC_POSIX - from gettext-0.10.40. - * configure.in: Remove warnings about obsolete AC_STRUCT_ST_BLKSIZE - and AC_STRUCT_ST_RDEV, add check for geteuid(). - * configure, config.h.in: Regenerated. - -2002-09-24 Derek Price - - * TODO (227): New item. - -2002-09-24 Larry Jones - - * configure.in (--enable-server-flow-control): Fix nonportable code. - * configure: Regenerated. - -2002-09-24 Derek Price - - * INSTALL: Explain --with-tmpdir. - * configure.in (--with-tmpdir): New configure argument. - - * configure: Regenerated. - * config.h.in: Ditto. - -2002-09-24 Derek Price - - * INSTALL: Explain --with-editor. - * configure.in (--with-editor): New configure argument. - - * Makefile.in: Regenerated. - * configure: Ditto. - * config.h.in: Ditto. - -2002-09-24 Larry Jones - - * TODO (226): New item. - - * configure.in: Remove PATCH_PROGRAM. - * configure: Regenerated. - * config.h.in: Ditto. - -2002-09-20 Derek Price - - * INSTALL: Explain --enable-server-flow-control. - * configure.in (--enable-server-flow-control): New configure argument. - - * configure: Regenerated. - * config.h.in: Ditto. - -2002-09-20 Derek Price - - * configure.in: Set PATCH_PROGRAM as possible, autodetecting with - a user override. - - * configure: Regenerated. - * config.h.in: Ditto. - -2002-09-20 Derek Price - - * configure.in: Use AC_HELP_STRING to create pretty help strings. - Reformat some lines for legibility. - (with-krb4): Fix help strings and logging. - - * configure.in: Regenerated. - -2002-08-16 Derek Price - - * configure.in: Make CVS_BADROOT a configure option. - - * configure: Regenerated. - * config.h.in: Ditto. - -2002-08-12 Derek Price - - * configure.in: Move ftruncate from AC_CHECK_FUNC to AC_REPLACE_FUNC. - (Symptoms reported by - Andrey Aristarkhov .) - * aclocal.m4: Regenerated. - * configure: Ditto. - -2002-07-09 Larry Jones - - * NEWS (Changes since 1.11.2): Note lock message times now UTC. - -2002-06-28 Derek Price - - * INSTALL (Building [on] other platforms): Don't reference the Mac - README file since it has been missing for several releases. Mention - the UNIXness of Mac OS X and correct references to wincvs.org to point - to the new cvsgui.org . - (Reported by Sarah Gonzales .) - -2002-05-22 Larry Jones - - * TODO (173, 202): Update to reflect current state of affairs. - (207): Defunct as of 1.11.2. - - * NEWS (Changes from 1.11.1p1 to 1.11.2): Note new RereadLogAfterVerify - config option. - -2002-05-15 Larry Jones - - * NEWS (Changes from 1.11.1p1 to 1.11.2): Note log/rlog changes. - -2002-05-08 Derek Price - - * configure.in: Add code to use lib/fnmatch.h.in redirection when - necessary to avoid namespace conflicts in #includes. - * configure: Regenerated. - -2002-05-08 Derek Price - - * TODO (215): Add note. - -2002-05-08 Derek Price - - * TODO (214): Clarify item. - -2002-05-02 Derek Price - - * configure.in: Add check for fnmatch.h so we can avoid namespace - conflicts on systems where the fnmatch function is broken. Not sure - this applies to any systems but Mac OS X. - - * configure: Regenerated. - * config.h.in: Ditto. - -2002-05-02 Derek Price - - * .cvsignore: Remove config.cache and add autom4te.cache. - -2002-05-02 Derek Price - - * noautoconf.sh: Update this script for operation with the new autotools. - * stamp-h1.in: Remove this obsolete file. - -2002-05-01 Derek Price - - * TODO (224): Comment on this item. - -2002-05-01 Larry Jones - - * TODO (215 - 225): New items. - -2002-05-01 Derek Price - - * TODO (214): Add note about moving options.h options into the configure - script. - * configure.in: Remove last few references to options.h. - * configure: Regenerated. - -2002-04-30 Derek Price - - * acconfig.h: Remove this file, it is deprecated. - - * Makefile.am (AUTOMAKE_OPTIONS): Move these into configure.in. - * acinclude.m4: Some minor updates for compatibility with the new - Autotools, some reformatting for readability, and a minor bugfix or - two. - * configure.in: Add new AC_DEFINE arguments and replace some direct - assignments to LIBOBJS with calls to AC_LIBOBJ. Call AC_INIT and - AM_INIT_AUTOMAKE with the new APIs. Call AC_PACKAGE_NAME, - AC_PACKAGE_TARNAME, AC_PACKAGE_VERSION, and AC_PACKAGE_STRING to - subst/define the corresponding variables. Call AC_CONFIG_FILES with - the old AC_OUTPUT args and call AC_OUTPUT without args. Remove - references to version.h. - * cvs.spec.in: Use the new substs. - - * INSTALL: Mention new versions of Automake & Autoconf. - * NEWS: Ditto. - - * Makefile.in: Regenerated. - * aclocal.m4: Ditto. - * configure: Ditto. - * config.h.in: Ditto. - -2002-04-28 Derek Price - - * TODO (208, 209, 210, 211, 212, 213): New items. - -2002-04-27 Derek Price - - * configure.in: Set LIBOBJ for fnmatch.c and fnmatch.h using the - correct functions. Add checks for some functions whose names conflict - with functions on Mac OS X 10.1 with the most recent dev packages. - This should be removable after the Mac dev packages are fixed. - - * configure: Regenerated. - * config.h.in: Ditto. - -2002-04-18 Derek Price - - * NEWS: Add a dummy entry so automake will let me update the version. - * configure.in: Update the version number. - * configure: Regenerated. - -2002-04-17 Derek Price - - * configure.in: Update version number. - * configure: Regenerated. - -2002-04-03 Derek Price - - * cvs.spec.in: Use a lowercase "cvshome.org". Add some RedHat safety - features to avoid "rm -rf /". No need to rebuild the docs in the - distribution. Don't strip the binary. - -2002-03-26 Derek Price - - * configure.in: Add a FIXME comment. - -2002-03-21 Derek Price - - * aclocal.m4: Regenerate with recent version of Autoconf. It looks - like things changed because of some RedHat patches or the like which - didn't change the Autoconf version number, but the differences look - like useful changes so I'm going to use them for consistency. - * config.h.in: Ditto. - * configure: Ditto. - -2002-03-19 Larry Jones - - * NEWS (Changes since 1.11.1p1): Note -S flag for [r]log. - -2002-02-08 Larry Jones - - * NEWS (Changes since 1.11.1p1): Note read-only tag fix. - -2002-02-01 Larry Jones - - * NEWS (Changes from 1.9 to 1.10): Note -t/-f wrappers disabled. - -2001-12-12 Larry Jones - - * NEWS (Changes from 1.10 to 1.11): Note update -C. - -2001-12-03 Larry Jones - - * TODO (206, 207): New items. - - * NEWS (Changes since 1.11.1p1): Note -F flag for [r]annotate. - (Changes from 1.11 to 1.11.1): Note :: for log. - -2001-10-18 Derek Price - - * TESTS: Remove outdated note about tests that don't use the dotest - function and add some notes on writing tests. - * HACKING: Reference TESTS file in note about submitting test cases - with patches. - -2001-09-28 Larry Jones - - * noautomake.sh: Protect wildcards from shell expansion. - (Patch submitted by Stephen Cameron .) - -2001-09-22 Derek Price - - * INSTALL (Building from source code under Unix): Continue - noautoconf.sh note, stressing source checked out from CVS. - -2001-09-22 Derek Price - - * noautomake.sh: Correct usage. - -2001-09-13 Derek Price - - * Makefile.am (AUTOMAKE_OPTIONS): Updated to require Automake 1.5. - * NEWS (Changes since 1.11.1p1): Added note about standardizing on - Automake 1.5. - * INSTALL (Building from source code under UNIX): It's Automake version - `1.5', not `2.5'. - (Detailed information about your interaction with "configure"): Added - note about using `configure --help'. - * README (Installation): Add noautoconf.sh to the list of build and - installation commands. - - * Makefile.in: Regenerated. - -2001-09-04 Derek Price - - * Makefile.in: Regenerated with automake 1.5. - * aclocal.m4: Ditto. - * configure: Ditto. - -2001-09-04 Derek Price - - * INSTALL (Building from source code under UNIX): Add a comment about - the noautomake.sh script and autotool versions. - -2001-08-20 Derek Price - - * configure.in (AC_OUTPUT): Add src/version.h. - (Patch from Alexey Mahotkin .) - - * configure: Regenerated. - -2001-08-20 Derek Price - - * .cvsignore: Add cvs.spec. - -2001-08-14 Derek Price - - * configure.in (AC_OUTPUT): Add cvs.spec. - * Makefile.am (EXTRA_DIST): Remove cvs.spec.in and cvs.spec. - (Original patch from Alexey Mahotkin .) - - * cvs.spec.in: Use @PACKAGE@ from configure. - * cvs.spec: Remove this file. - - * configure: Regenerated. - * Makefile.in: Ditto. - -2001-08-14 Derek Price - - * DEVEL-CVS: Update mailing list addresses. - * HACKING: Ditto. - -2001-08-09 Derek Price - - * cvsnt.mak: Add entry for annotate.c. - -2001-08-07 Derek Price - - * build.com: correct name of build .com for zlib. - (Patch from Mike Marciniszyn .) - -2001-08-06 Derek Price - - * configure.in: Remove some redundant macros (they appear to be run - automatically by AC_INIT). - - * configure: Regenerated. - -2001-08-06 Derek Price - - * configure.in: Add AC_EXEEXT to get things right when under Windows. - (Report and patch from manklu@web.de.) - - * configure.in: Reorder some macros to prevent Autoconf warnings. - - * configure: Regenerated. - * Makefile.in: Ditto. - -2001-07-26 Larry Jones - - * NEWS: Fix format, add note about tag -B. - -2001-07-16 Derek Price - - * compile: New Automake file. - * configure.in: Add AM_PROG_CC_C_O to work around problems with some - compilers. - - * aclocal.m4: Regenerated. - * Makefile.in: Ditto. - * config.h.in: Ditto. - * configure: Ditto. - (Thanks to Stephen Cameron and - Tom Tromey .) - -2001-07-04 Derek Price - - * Makefile.in: Regenerated with new Automake release candidate 1.4h. - * aclocal.m4: Ditto. - -2001-07-04 Derek Price - - * configure.in: Tidy and add some comments. - - * configure: Regenerated. - -2001-07-03 Derek Price - - * HACKING (Source): Add a note about where to obtain the development - sources. - (Thanks to Bear Giles .) - -2001-07-03 Derek Price - - * configure.in: Test for mmap. - - * configure: Regenerated. - * config.h.in: Ditto. - -2001-06-28 Derek Price - - * Makefile.in: Regenerated with new version of Automake. - * aclocal.m4: Ditto. - * configure: Regenerated. - -2001-06-28 Derek Price - - * mdate-sh: New file to support doc/version.texi. - -2001-06-27 Larry Jones - - * TESTS: Note environment variables to select certain tools, - potential problems with big environments. - - * TODO: Add note about non-canonical paths. Reformat long lines. - - * NEWS (Changes since 1.11): Note new loginfo format string expansion. - Reformat some long lines. - -2001-06-11 Derek Price - - * cvsnt.dsp: Add src/annotate.c to source file list. - (Thanks to Jerzy Kaczorowski .) - -2001-05-30 Derek Price - - * configure.in (AC_OUTPUT): Change contrib/pvcs2cvs to contrib/pvcs2rcs. - - * configure: Regenerated. - -2001-05-29 Derek Price - - * configure.in (AC_OUTPUT): Add pvcs2cvs. - - * configure: Regenerated. - -2001-05-21 Derek Price - - * NEWS (Changes since 1.11): It's "noautomake.sh", not "noautoconf.sh". - * Makefile.am (EXTRA_DIST): Include noautomake.sh. - (AUTOMAKE_OPTIONS): Update required Automake version to 1.4e. - (Reported by Alexey Mahotkin ). - -2001-05-21 Derek Price - - * Makefile.am (EXTRA_DIST): Add noautoconf.sh. - -2001-05-17 Larry Jones - - * depcomp: Yet another newer (unofficial) version from Automake. - -2001-05-10 Larry Jones - - * configure.in (AC_OUTPUT): Remove -f from chmod -- not portable. - * configure: Regenerated. - -2001-05-03 Derek Price - - * TODO (204): New item. - -2001-05-02 Derek Price - - * acinclude.m4 (ACX_WITH_GSSAPI): Make krb5.h a requirement for GSSAPI. - krb5.h shouldn't be required, but CVS's GSSAPI implementation is - broken. - (Reported by Stephen Rasku .) - - * aclocal.m4: Regenerated. - * configure: Ditto. - -2001-04-29 Derek Price - - * Makefile.am (distcheck-hook): Undo last change. - (localcheck): New target. - - * Makefile.in: Regenerated. - -2001-04-29 Derek Price - - * Makefile.am: Add remotecheck to distcheck-hook. - - * Makefile.in: Regenerated. - -2001-04-27 Derek Price - - * TODO (202): Remove my claim. - (203): New item. - -2001-04-27 Derek Price - - * configure.in: Update version number. - - * configure: Regenerated. - * cvs.spec: Ditto. - -2001-04-27 Derek Price - - * configure.in: Update version number. - * NEWS (new since 1.11.1): Broke read-only fix. - (new since 1.11): Diff fix. - - * configure: Regenerated. - * cvs.spec: Ditto. - -2001-04-26 Derek Price - - * cvs.spec.in: Don't include %{_infodir}/dir. - (krb5): Remove krb5-config from dependencies. - - * cvs.spec: Regenerated. - -2001-04-25 Derek Price - - * configure.in: Update version to 1.11.1. - - * Makefile.in: Regenerated with AM 1.4e as of today at 18:10 -0400 - (EDT). - * aclocal.m4: Ditto. - * configure: Ditto. - -2001-04-25 Derek Price - - * NEWS: Correct punctuation. - -2001-04-25 Larry Jones - - * depcomp (aix, sgi): Correct previous fixes. - -2001-04-24 Larry Jones - - * depcomp (sgi): Remove stray HP-UX code. - -2001-04-18 Derek Price - - * noautoconf.sh: New shell script to touch Makefile.in files and - prevent unecessary AUtomake rebuilds after updates. - * NEWS: Note this new scipt. - -2001-04-16 Larry Jones - - * depcomp (aix): Remove stray HP-UX code. - -2001-04-12 Larry Jones - - * mkinstalldirs: Newer version from Automake. - -2001-04-12 Larry Jones - - * depcomp: Newer version from Automake. - -2001-04-04 Larry Jones - - * depcomp: Don't count on $? being set in then or else clauses. - -2001-03-30 Larry Jones - - * NEWS: Note new rlog and rannotate commands. - -2001-03-14 Derek Price - - * configure.in (AC_CHECK_FUNCS): Look for gettimeofday. - - * config.h.in: Regenerated: - * configure: Ditto. - * stamp-h1.in: Ditto. - -2001-03-14 Derek Price - - New version of Automake (1.4e). With luck it works with the quirky BSD - Make. - - * aclocal.m4: Regenerated. - * configure: Ditto. - * Makefile.in: Ditto. - * stamp-h1.in: Ditto. - -2001-02-28 Derek Price - - * acinclude.m4 (ACX_WITH_GSSAPI): Move the -L linker option back into - LIBS where it should be. LDFLAGS is a user variable. - - * aclocal.m4: Regenerated. - * configure: Regenerated. - -2001-02-23 Derek Price - - * configure.in: Comment definition of PR_PROGRAM. - - * configure: Regenerated. - -2001-02-22 Derek Price - Pavel Roskin - - * configure.in: Define PR_PROGRAM if `pr' has been found. - - * config.h.in: Regenerated. - * configure: Regenerated. - -2001-02-20 Derek Price - - * acconfig.h (HAVE_GSSAPI): Removed. Entries in acconfig.h aren't - necesary when the full functionality of AC_DEFINE is used. - (HAVE_GSS_C_NT_HOSTBASED_SERVICE): Ditto. - * acinclude.m4 (ACX_WITH_GSSAPI): New file with GSSAPI configure code. - * configure.in: Use ACX_WITH_GSSAPI instead of writing GSSAPI code in - place. - - * aclocal.m4: Regenerated. - * config.h.in: Regenerated. - * configure: Regenerated. - -2001-02-15 Derek Price - - * configure: Regenerated without beta automake macros. - -2001-02-14 Derek Price - - * configure.in (AC_CHECK_FUNCS): Alphebetize & reorganize. Add - cascading search for nanosleep, usleep, & select, in that order. - * config.h.in: Regenerated. - * configure: Regenerated. - * cvsnt.mak: List xtime.h & xselect.h dependancies. - -2001-02-14 Larry Jones - - * cvsnt.dsp: Remove references to rtag.c & rtag.obj. - * cvsnt.mak: Ditto. - -2001-02-13 Derek Price - - * TODO: Add note about merging rdiff & diff. - -2001-02-13 Derek Price - - * TODO: Add note about cvs_temp_file. - -2001-02-07 Derek Price - - * cvs.spec.in (build): Remove the info 'dir' file so it doesn't get - installed accidentally. - (post): Install info files _into_ system dir file - (preun): uninstall info files from dir file - * cvs.spec: regenerated - -2001-01-31 Derek Price - - * TODO: Add a note about 'cvs add' w/o write access - -2001-01-29 Derek Price - - * NEWS: Rewrite the comment on the new ~/.cvspass functionality - * TODO: Add a note about testing login/logout - -2001-01-29 Derek Price - - * configure.in: Rewrite args to AC_TRY_COMMAND in a form that is - acceptable to both Autoconf 1.13 and the new 1.49 beta. - - * configure: regenerated - -2001-01-29 Larry Jones - - * configure.in: Check for syslog.h. - * configure, config.h.in: Regenerated. - -2001-01-17 Derek Price - - * configure.in: add machinery to check for the BSD VPATH bug - and check for texi2dvi. - * doc/Makefile.am: use the machinery - * diff/Makefile.in: changes to support 'make dist' from a build dir - * emx/Makefile.in: changes to support 'make dist' from a build dir - * os2/Makefile.in: changes to support 'make dist' from a build dir - * zlib/Makefile.in: changes to support 'make dist' from a build dir - - * Makefile.in: regenerated - * aclocal.m4: regenerated - * configure: regenerated - * contrib/Makefile.in: regenerated - * doc/Makefile.in: regenerated - * lib/Makefile.in: regenerated - * man/Makefile.in: regenerated - * src/Makefile.in: regenerated - * tools/Makefile.in: regenerated - * vms/Makefile.in: regenerated - * windows-NT/Makefile.in: regenerated - * windows-NT/SCC/Makefile.in: regenerated - -2001-01-10 Derek Price - Rex Jolliff - - * NEWS (new since 1.11): Add comment about VMS wildcards - -2001-01-05 Derek Price - - * configure.in (AC_OUTPUT): Move some script targets here - * contrib/Makefile.am (EXTRA_DIST, SUFFIXES, .pl:, .csh:): Move some - script targets to configure.in - * src/Makefile.am (cvsbug, cvsbug_EXTRA_DIST, EXTRA_DIST): move cvsbug - target to configure.in - - * aclocal.m4: Regenerated due to change in Automake installation - - * Makefile.in: Regenerated - * configure: ditto - * contrib/Makefile.in: ditto - * doc/Makefile.in: ditto - * lib/Makefile.in: ditto - * man/Makefile.in: ditto - * src/Makefile.in: ditto - * tools/Makefile.in: ditto - * vms/Makefile.in: ditto - * windows-NT/Makefile.in: ditto - * windows-NT/SCC/Makefile.in: ditto - - * cvs.spec: updated timestamp - * stamp-h1.in: ditto - * doc/CVSvn.texi: ditto - * src/stamp-h2.in: ditto - * src/version.c: ditto - - * contrib/clmerge.in: Rename from clmerge.pl - * contrib/cln_hist.in: Rename from cln_hist.pl - * contrib/commit_prep.in: Rename from commit_prep.pl - * contrib/cvs_acls.in: Rename from cvs_acls.pl - * contrib/log.in: Rename from log.pl - * contrib/log_accum.in: Rename from log_accum.pl - * contrib/mfpipe.in: Rename from mfpipe.pl - * contrib/rcslock.in: Rename from rcslock.pl - * contrib/sccs2rcs.in: Rename from scc2rcs.csh - * src/cvsbug.in: Rename from cvsbug.sh - - * contrib/clmerge.pl: Rename to clmerge.in - * contrib/cln_hist.pl: Rename to cln_hist.in - * contrib/commit_prep.pl: Rename to commit_prep.in - * contrib/cvs_acls.pl: Rename to cvs_acls.in - * contrib/log.pl: Rename to log.in - * contrib/log_accum.pl: Rename to log_accum.in - * contrib/mfpipe.pl: Rename to mfpipe.in - * contrib/rcslock.pl: Rename to rcslock.in - * contrib/sccs2rcs.csh: Rename to sccs2rcs.in - * src/cvsbug.sh: Rename to cvsbug.in - -2001-01-03 Derek Price - - * Makefile.am (remotecheck): depend on 'all' - * Makefile.in: regenerated - -2001-01-03 Derek Price - - * Makefile.in (DEP_FILES): Regenerated with new version of Automake - (DEP_FILES_conditional patch for BSD make compatibility) - * contrib/Makefile.in: ditto - * doc/Makefile.in: ditto - * lib/Makefile.in: ditto - * man/Makefile.in: ditto - * src/Makefile.in: ditto - * tools/Makefile.in: ditto - * vms/Makefile.in: ditto - * windows-NT/Makefile.in: ditto - * windows-NT/SCC/Makefile.in: ditto - -2000-12-28 Derek Price - - * INSTALL (BUILDING FROM SOURCES): Added a couple more platforms to the - build and test list. - (Building ... under Unix): Added note about BSD make and - --disable-dependency-tracking - (Building ... under Windows ...): Added note about using MSVC++ 6.0 - (Building [on] other platforms): Added note about wincvs.org and - cvsnt.org. Added more complete note about BSD make and - --disable-dependency-tracking than the above - -2000-12-27 Derek Price - - * NEWS: Fix comments about the changes to ~/.cvspass - -2000-12-26 Derek Price - - * Makefile.am (EXTRA_DIST): Add cvs.spec.in - (cvs.spec): new target - * Makefile.in: Regenerated - * aclocal.m4: update timestamp - * configure: Regenerated - * configure.in (AC_OUTPUT): Remove cvs.spec, doc/CVSvn.texi, - & src/version.c - * stamp-h1.in: update timestamp - * contrib/Makefile.in: ditto - * lib/Makefile.in: ditto - * man/Makefile.in: ditto - * tools/Makefile.in: ditto - * vms/Makefile.in: ditto - * windows-NT/Makefile.in: ditto - * windows-NT/SCC/Makefile.in: ditto - -2000-12-22 Derek Price - - * configure.in (AC_OUTPUT): Stretched - * configure: Regenerated - -2000-12-22 Derek Price - - * aclocal.m4: Regenerated due to Automake update - -2000-12-22 Derek Price - - * Makefile.in: Regenerated - * aclocal.m4: Regenerated due to a change to AM_PROG_ETAGS - * configure: Regenerated - -2000-12-21 Derek Price - - * .cvsignore: removed newly unused files, added new stamp file, - and alphabetized. - * AUTHORS: Added this file to please Automake. Apparently, its - presence is mandated by the GNU coding standards. - * Makefile.am: New file needed by Automake - * Makefile.in: Regenerated - * NEWS: Add a comment about the Automake conversion - * aclocal.m4: Added this file for Automake - * config.h.in: Regenerated - * configure: Regenerated - * configure.in: Some changes to support Automake and support for - missing roff & ps2pdf programs. - * cvs.spec: Regenerated - * cvs.spec.in: New file leveraging Automake support - * depcomp: New Automake file - * install-sh: Newer version from Automake - * missing: New Automake file - * mkinstalldirs: Newer version from Automake - * stamp-h.in: Remove unused file - * stamp-h1.in: New Automake generated stamp file - -2000-11-30 Derek Price - Stephen Kennedy - - * cvs.spec (krb5): Require krb5-devel for a build of the krb5 target - -2000-11-29 Derek Price - Stephen Kennedy - - * cvs.spec (build, post, preun): remove an old, commented out - line and replace hardcoded paths with _infodir and _bindir as - appropriate - (files): replace file list with more generic and succinct one - -2000-11-15 Derek Price - - * TODO (198): added note about deprecating cvs_temp_name - * configure.in (AC_CHECK_FUNCS): added mkstemp to support - new cvs_temp_file function. - * config.h.in: regenerated - * configure: regenerated - -2000-11-08 Larry Jones - - * configure.in: Check for getgroups function. - * configure, config.h.in: Regenerated. - -2000-11-07 Larry Jones - - * Makefile.in (FLAGS_TO_PASS): Add INSTALL, INSTALL_DATA, and - INSTALL_PROGRAM. - (Reported by Christian Brechbuehler .) - -2000-11-03 Derek Price - - * cvs.spec (build): pass in --without-gssapi when configuring the main - package so that the Kerberized version of CVS doesn't get built when - the user happens to have Kerberos installed in the default location. - -2000-10-31 Derek Price - - * NEWS: Mention zlib was updated to 1.1.3. - -2000-10-30 Derek Price - - * cvs.spec: Fixed trapping for gssapi so that the RPM can be built - on a machine without Kerberos. Should now build standard RPM on a - machine without Kerberos and the standard RPM + the Kerberos RPM on - a machine with the Kerberos devel libraries. - -2000-10-26 Larry Jones - - * configure.in: Get path to pr for diff. - (Patch submitted by Urs Thuermann .) - * configure: Regenerated. - -2000-10-18 Derek Price - - * .cvsignore: Added .fname & .version, two temporary files used in spec - file creation. - * Makefile.in (distclean-local): clean .fname & .version - * cvs.spec: Replaced with a new version based on RedHat 6.2's spec file - for cvs 1.10.7. Edited heavily to include a krb5 subpackage for the - gssapi binary and fixed RedHat's info and man file placement. - -2000-10-17 Derek Price - - * NEWS: added a comment about the new CVSROOT format for pserver. - -2000-10-17 Derek Price - - * NEWS: added a comment about the new format of ~/.cvspass - -2000-10-09 Derek Price - - * cvsnt.mak: Some minor changes to allow CVS to compile correctly - under NT and Visual C++ 6.0. - -2000-09-07 Larry Jones - - * 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 - - * NEWS: Note additional history enhancements. - -2000-08-01 Larry Jones - - * configure.in, config.h.in: Add check for getpassphrase (Solaris). - * configure: Regenerated. - -2000-07-11 Larry Jones - - * 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 - - * NEWS: Note the new "version" command. - -2000-07-06 Larry Jones - - * NEWS: Note that admin -t works in client/server. - -2000-06-19 Larry Jones - - * 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 - - * 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 - - * TESTS: Add notes about required tools and where to get them. - -2000-05-02 Donald Sharp - and Larry Jones - - * NEWS: Note history output format change. - -2000-02-17 Larry Jones - - * NEWS: Note that PreservePermissions is disabled. - * configure.in: Don't define PRESERVE_PERMISSIONS_SUPPORT. - * configure: Regenerated. - -2000-02-01 Larry Jones - - * configure.in: Try again to handle systems that need both libsocket - and libnsl. - * configure: Regenerated. - -1999-12-09 Larry Jones - - * configure.in: Correctly handle systems that need both libsocket - and libnsl. - * configure: Regenerated. - -1999-12-06 Larry Jones - - * 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 - - * INSTALL (Tested platforms): Update info. - -1999-11-04 Jim Kingdon - - * 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 - - * NEWS: added item about anon cvs no longer needing password. - -1999-10-28 Larry Jones - - * 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 - - * TESTS: Remove suspicion that setting LC_COLLATE has fixed the - problem with Solaris sort -- people are still reporting it. - -1999-05-17 Jim Kingdon - - (These changes were run by devel-cvs; feedback was "They look fine" - from Jim Meyering and "I concur" from Noel Cragg). - * HACKING (Submitting patches): Rewrite parts to try to sketch out - a process which is less centralized and hopefully describes the - status quo better (for example, I've mostly removed the word - "submit" because it describes a process of sending your patch to a - central authority rather than to whoever wants it). Update to - reflect some of the current practices/thinking regarding quality - and other matters. Try to be more concise where feasible. - -1999-05-13 Jim Kingdon - - * BUGS: Remove item about RELATIVE_REPOS not working with - client/server CVS; it must have been fixed because the testsuite - is working fine with RELATIVE_REPOS. - -1999-05-07 Jim Kingdon - - * TESTS: Add note about send-expect style interaction. - -1999-04-26 Jim Kingdon - - * cvsnt.mak: Revert to the version before today's changes - (modulo one "because the IDE feels like it" change). I - couldn't get O'Connor's cvsnt.mak to work with MSVC 4.0 at - all (I tried the IDE, which tried to wrap the makefile and - wouldn't build even with the wrap, and the command line NMAKE). - * .cvsignore: Add back cvsnt.mdp WinDebug WinRel, accordingly. - -1999-04-26 Jim Kingdon - - * Makefile.in (DISTFILES): Add cvsnt.dsw. - -1999-04-26 (submitted 1999-03-24) John O'Connor - - * cvsnt.dsw: new file. The workspace file used by MSVC 5+ to - manage multiple projects. It contains three projects: cvsnt, - zlib and diff. - - * cvsnt.dsp: Fixed problem where CVS wouldn't build because of - file name conflicts. Removed all the files from zlib and diff - directories and moved to separate project files. - - * cvsnt.mak: Re-generated due to the changes in cvsnt.dsp. - - * .cvsignore: Removed un-used entries related to MSVC. Added - entries to cover all files generated by the NT build: *.ncb, - *.opt, *.plg, Debug and Release. - -1999-04-09 Jim Kingdon - - * HACKING: Add a sentence about sending patches somewhere other - than bug-cvs, while still granting permission for people to use - them under the GPL. - -1999-04-08 Jim Kingdon - - * configure.in (AC_OUTPUT): Remove macintosh/Makefile (overlooked - in change of 1999-02-26; thanks to Erik Bertelsen for reporting it). - * configure: Regenerated. - -1999-02-26 Jim Kingdon - - * macintosh: Remove this subdirectory and all its contents. It - contained MacCVS 2.x, but pretty much everyone has moved on to - MacCVS 3.x, MacCVS Pro, or MacCVSClient. - * Makefile.in (SUBDIRS): Remove macintosh. - -1999-02-25 Mehul N. Sanghvi (and Jim Kingdon) - - * INSTALL: Add MkLinux on PowerPC. - -1999-02-18 Jim Kingdon - - * cvsnt.mak: Remove vasprintf. Plus of course the usual - "because the IDE feels like it" changes. - -1999-02-09 Jim Kingdon - - * configure.in (AC_REPLACE_FUNCS): Remove vasprintf; see - lib/ChangeLog for rationale. - * configure: Regenerated. - -1999-01-31 Assar Westerlund of sics.se - and Jim Kingdon - - * configure.in: The GSSAPI code in CVS requires krb5.h which - Solaris 2.7 doesn't have. Check for it. - * configure: Regenerated. - -1999-01-12 Jim Kingdon - - * COPYING, COPYING.LIB: Remove obsolete snail address of the Free - Software Foundation. - -1998-12-01 Jim Kingdon - - * TODO (195): Check in a few clarifications from Andrew Tridgell, - the rsync author. - -1998-11-11 Jim Kingdon - - * HACKING: Change prep.ai.mit.edu to gnu.org. - -1998-10-26 Jim Kingdon - - * INSTALL: Add information for Sequent DYNIX/ptx4.0, from a report - by Marco Franzen. - -1998-10-14 Jim Kingdon - - * configure.in (AC_OUTPUT): Remove contrib/elib/Makefile. - * configure: Regenerated using autoconf 2.10. - -1998-10-13 Jim Kingdon - - * TODO (149): Update since -d doesn't rewrite CVS/Root any more. - -1998-10-03 Jim Kingdon - - * TODO (31): Mention the ,foo.c, and SIGINT issue. - -1998-09-25 Jim Kingdon - - * FAQ: Update from FAQ-O-Matic. This features fewer blank lines - and a few more minor formatting changes (not sure whether the - FAQ-O-Matic changed or whether this is because I upgraded Lynx). - I read through the diffs, and the real changes are: (A) In - /Advanced_Topics_/Setting_up_and_Manag/, #1, describe "cvs init", - don't describe committing modules file twice - (no longer needed now that mkmodules is not a separate program), - don't mention "cvs import" here. (B) - /Advanced_Topics_/Setting_up_and_Manag/, #5, describe special - issues with pserver and repository permissions, - (C), /Advanced_Topics_/Tricks_of_the_Trade/, renumber the question - "Why do timestamps sometimes get set to the date of the revision" - from #17 to #9. Renumber the questions between #9 and #17 - accordingly, (D) /User_Tasks_/Less_Common_User_Tas/, "8. How do I - split a file into pieces, retaining revision histories?", include - a script which may help with this, (E) - /What_is_CVS_/How_does_CVS_differ_/, correct the name of SABLIME, - (F) /What_is_CVS_/Where_do_I_find_CVS_/, "2. Is there an archive - of CVS material?", note that http://www.delos.com/cvs doesn't - exist any more. - - * NEWS: Mention :fork:. - -1998-09-24 Jim Kingdon - - * INSTALL (Tested platforms): Update SCO OpenServer information, - from a report by Robert Lipe@DIGI. - -1998-09-22 Jim Kingdon - - * NEWS: Add items about multiple roots and -d not updating - CVS/Root. - -1998-09-09 Jim Kingdon - - * configure.in (AC_OUTPUT): Remove tools/pcl-cvs/Makefile. - * configure: Regenerated using autoconf 2.10. - -1998-09-07 Jim Kingdon - - * NEWS: Add item about LockDir. - -1998-08-31 Jim Kingdon - - * INSTALL (Tested platforms): Add Solaris x86 (reported by Jeremy of - exit109.com) and Irix 6.4 (reported by Russ Allbery). - - * INSTALL (Tested platforms): Add Solaris 2.6 (reported by Russ - Allbery). - -1998-08-28 Noel Cragg - - * TODO (196): new item. - -1998-08-26 Jim Kingdon - - * TESTS: Update comments concerning Solaris sort and LC_COLLATE. - -1998-08-17 Jim Kingdon - - * INSTALL: Update Irix, Ultrix, and NetBSD/Alpha with test results - from Noel. - -1998-08-14 Jim Kingdon - - * INSTALL: Add NetBSD/mac68k (reported by Hauke Fath of melog.de). - Add alpha-dec-osf4.0 and update SunOS and linux entries (reported - by Jim Kingdon and Noel Cragg). - -1998-08-06 Jim Kingdon - - * INSTALL: Update for SCO OpenServer 5 (reported by Jeffery - Cann). - -1998-08-01 Jim Kingdon - - * INSTALL: Add Unixware 7 (reported by Phillip Porch). - -1998-07-29 Jim Kingdon - - * cvsnt.mak: For rcscmds.c, also include files from the diff - directory. Plus of course the usual voluminous "because Visual - C++ 4.0 feels like it" changes. - -Tue Jul 28 22:16:48 1998 Noel Cragg - - * Makefile.in (dist): unset the GZIP shell variable before calling - gzip to avoid invocation problems. - -Sun Jul 26 16:22:21 1998 Noel Cragg - - * NEWS: add info about TopLevelAdmin. - -1998-07-20 Jim Kingdon - - * INSTALL: Update entries for HPUX and AIX (based on a submission - from Andreas Ley). - -1998-06-25 Jim Kingdon - - * README.VMS: We generally don't need GNU patch any more. - -1998-06-03 Jim Kingdon - - * TESTS: Don't mention the version of Solaris; Mark Borges says - that it applies to Solaris 2.5 as well as 2.6. - -1998-06-02 Assar Westerlund - - * configure.in: Test for GSS_C_NT_HOSTBASED_SERVICE in gssapi.h. - * acconfig.h: Add undef for HAVE_GSS_C_NT_HOSTBASED_SERVICE. - * configure, config.h.in: Rebuild. - -1998-06-01 Assar Westerlund - and Ian Lance Taylor - - * configure.in: Check for GSSAPI headers individually. Use a - different set of GSSPI libraries if gssapi.h rather than - gssapi/gssapi.h is found. Adds Heimdal support. - * configure, config.h.in: Rebuild. - -1998-05-25 Jim Kingdon - - * cvs.spec (%description): Rewrite to be slightly more verbose - about the basic features. Don't try to mention what CVS lacks. - -1998-05-23 Jim Kingdon - - * BUGS: Remove items about binary file bugs which were fixed - approximately 6 months ago. - -1998-04-28 Jim Kingdon - - * TESTS: Add note about Solaris sort program (reported by Mark - D. Baushke). - -1998-03-16 Larry Jones - - * configure.in: Simplify test for shadow password support since - the code now handles the case where shadow passwords are supported - but are not in use. - * configure: Regenerated. - -1998-03-07 Jim Kingdon - - * TESTS: Remove note about SGI's XFS. Someone reports that it - works (I would assume due to the 13 Feb 1998, and earlier, changes - to sanity.sh). - - * NEWS: Add item about PreservePermissions. Fix unclear wording - in gserver item. - -1998-03-04 Jim Kingdon - - * acconfig.h, configure.in: Add PRESERVE_PERMISSIONS_SUPPORT and - always define it. - * configure, config.h.in: Regenerated. - -Tue Feb 17 18:32:36 1998 Ian Lance Taylor - - * configure.in: Add memmove back to AC_REPLACE_FUNCS list. - * configure: Rebuild. - -1998-02-16 Jim Kingdon - - * TODO (190): Remove "failed to check out" from commit.c from - lists of error messages suppressed by -q; it no longer is. - -4 Feb 1998 Jim Kingdon - - * cvsnt.mak: The usual "because Visual C++ feels like it" - changes. These ones seem to have to do with reordering - files and release versus debug configurations, mainly. - -Fri Jan 30 10:37:40 1998 Jim Kingdon - - * INSTALL: Update which version of CVS was tested with EMX. - -15 Jan 1998 W. L. Estes - and Jim Kingdon - - * cvs.spec, Makefile.in: Fix some problems with the spec file - distributed with cvs. RPM chokes on a build root of slash, so - that is gone now. CVS is relocatable (as far as I know) so I - added a prefix tag. The source location was incorrect and in - fixing that I had to add a `g' flag to one of the sed commands in - the Makefile.in so the spec file gets generated correctly. - -13 Jan 1998 Jim Kingdon - - * cvsnt.mak: Add lib/fncase.c. Plus of course the usual - "because Visual C++ feels like it" changes. - -Tue Jan 13 16:49:38 1998 Ian Lance Taylor - - * acconfig.h (USE_SETMODE_STDOUT): Add undef line. - (HAVE_SETMODE): Likewise. - * configure.in: If cygwin32, define USE_SETMODE_STDOUT and - HAVE_SETMODE. - * configure, config.h.in: Regenerate. - - * acconfig.h (UTIME_EXPECTS_WRITABLE): Add undef line. - * configure.in: If cygwin32, define UTIME_EXPECTS_WRITABLE. - * configure, config.h.in: Regenerate. - - * configure.in: Add test for cygwin32, and set LIBOBJS and LIBS - accordingly. - * configure: Regenerate. - -Sun Jan 11 11:43:55 1998 Jim Kingdon - - * HACKING: Add example of indentation for switch statement. I - always have to look this one up, and it seems worthwhile to - specify it here rather than be unsure which switch statement in - CVS to use as an example. - -Wed Jan 7 09:41:08 1998 Jim Kingdon - - * TODO: Revise item 149 (concerning changing CVS/Root and such). - "This whole area is a rather bad pile of individual decisions which - accumulated over time, some of them probably bad decisions with - hindsight." - -Wed Dec 31 09:25:20 1997 Jim Kingdon - - * FAQ: Re-import from FAQ-O-Matic. Features a change regarding - removing directories. - -Tue Dec 23 08:28:44 1997 Jim Kingdon - - * README.VMS, INSTALL, HACKING, BUGS, README: Change bug-cvs - address from prep.ai.mit.edu to gnu.org per email from Martin - Hamilton. When referring to bug-reporting procedure refer to - Cederqvist not README. - -Tue Dec 16 13:13:53 1997 Jim Kingdon - - * FAQ: Re-import from FAQ-O-Matic. The content is the same, but - instead of being from Mosaic, it is from "lynx -dump -nolist". - This output is somewhat better (for example, it is formatted for - 80 columns or so, rather than Mosaic which is rather - inconsistent), and also lynx is free and still maintained whereas - NCSA Mosaic is proprietary and no longer maintained. - - * FAQ: Re-import from FAQ-O-Matic. Features an update to the - Sablime question. - - * NEWS: Add item about GSSAPI. - -Fri Dec 12 14:00:57 1997 Ian Lance Taylor - - * configure.in: Add --with-gssapi option, and look for gssapi.h - and GSSAPI Kerberos v5 libraries. - * acconfig.h: Add HAVE_GSSAPI. - * configure, config.h.in: Regenerate. - -Thu Dec 11 15:58:06 1997 Eric Mumpower - - * configure.in: Let --with-krb4 override the system Kerberos - header files and libraries, if any. - * configure: Regenerate. - -Thu Dec 4 20:01:02 1997 Jim Kingdon - - * configure.in (AC_CHECK_FUNCS): Remove mempcpy per change to - src/rcs.c. - * configure: Regenerated (never was regenerated after getwd change). - -1997-12-04 Jim Meyering - - * configure.in (AC_CHECK_FUNCS): Add mempcpy. - -Thu Dec 4 10:42:32 1997 Jim Kingdon - - * BUGS: Update for kfogel .cvswrappers fix. - -Tue Dec 2 22:14:03 1997 Jim Kingdon - - * MINOR-BUGS: Update per info-cvs mail from Steve Cameron. - -1997-11-29 Jim Kingdon - - * cvsnt.mak: Remove lib/getwd.c (see lib/ChangeLog for rationale). - - * cvsnt.mak: The usual "because Developer Studio feels like - it" changes. - -Sat Nov 29 22:10:32 1997 Jim Kingdon - - * configure.in (AC_REPLACE_FUNCS): Remove getwd (see lib/ChangeLog - for rationale). - -Mon Nov 24 10:36:39 1997 Jim Kingdon - - * INSTALL: Update QNX information per email from Michael Hunter of - QNX. - -Wed Nov 19 17:44:21 1997 Jim Kingdon - - * INSTALL: Add Sequent entry per bug-cvs report. - -1997-11-17 Karl Fogel - - * BUGS: Remove item about exporting binary files to non-unix - clients; this is fixed. - -Mon Nov 17 09:07:44 1997 Jim Kingdon - - * BUGS: Add yet another binary files problem. - -1997-11-14 Karl Fogel - - * cvsnt.mak: updated for diff/ subdir. - -Fri Nov 14 12:25:10 1997 Jim Kingdon - - * BUGS: Remove item about dying gasps message. At least one known - cause has been fixed. - -Wed Nov 12 20:24:49 1997 Jim Kingdon - - * FAQ: Re-import from FAQ-O-Matic. Features a wording fix to - "What do I do first? How do I create a Repository?" and a - formatting fix (makes it clear which bullets are under what) - to "What is a module?" - - * NEWS: Add item about RCS library. Remove item about RCSBIN in - CVSROOT/config. - * INSTALL: Simplify instructions to reflect the fact that one need - not any longer install RCS and GNU diff. - * PROJECTS: Remove item about RCS library; it is done. - -Mon, 10 Nov 1997 Jim Kingdon - - * cvsnt.dsp: For diff/diff.c, also look for include files in - diff directory. This means we get diff/system.h not lib/system.h. - -Sun Nov 9 16:16:56 1997 Jim Kingdon - - * TODO (#195): New item, about rsync and such issues. - -Thu Nov 6 14:29:14 1997 Jim Kingdon - - * TODO (#194): New item, about separated metadata. - - * TODO (#186): Rewrite paragraph on CVSclusters to be clearer - about what this can do and why I think it is a cool idea. - -Sun Nov 2 19:34:30 1997 Jim Kingdon - - * DEVEL-CVS: Wording fix: want to specify that new developers are - granted checkin access and the ability to send to devel-cvs, not - specify whether this is implemented via an "account" (whatever - that is) (editorial change, not run by devel-cvs). - -Fri Oct 31 16:30:57 1997 Jim Kingdon - - * NEWS: Mention admin -o rev1::rev2. - -Wed Oct 29 08:40:05 1997 Jim Kingdon - - * TODO: Add item 193, about alternatives to timestamps in CVS/Entries. - -Tue Oct 28 19:59:48 1997 Jim Kingdon - - * TODO (190): "rcs failed" message is no longer affected by global - -q option. - -1997-10-28 Jim Kingdon - - * .cvsignore: Add Visual C++ files du jour, namely - {diff,vc50}.{pdb,idb,pch}. - - * cvsnt.dsp: Add files for diff library. The custom build - stuff for diff/version.c and diff/diff.c was to deal with - there also being a src/version.c and src/diff.c. There - might be an easier way. - -Mon Oct 27 11:21:15 1997 Jim Kingdon - - * FAQ: Re-import from FAQ-O-Matic. Features an edit from Larry - Jones regarding CVS on Windows. - -Mon Oct 20 15:23:17 1997 Jim Kingdon - - * BUGS: Add item about spaces in login names. - -Mon Oct 20 10:25:42 1997 Hannes R. Boehm - - * INSTALL (Tested platforms): Add Red Hat Linux 4.2. - -Wed Oct 15 10:55:20 1997 Jim Kingdon - - * TODO (#192): Also mention issue with opening connections to new - servers if CVSROOT changes. - - * TODO (#191): Add thoughts on external difference programs. - -1997-10-11 Noel Cragg - - * BUGS: remove note about the `-d' flag bug that was just fixed. - - * TODO: new item 192. - -Thu Oct 9 12:59:28 1997 Jim Kingdon - - * TODO: Revise item #182 to be clearer and to point to the - unofficial patch. - -Thu Sep 25 14:48:26 1997 Jim Kingdon - - * build.com: Also recurse into diff directory. - -Wed Sep 24 10:35:50 1997 Jim Kingdon - - * configure.in: Don't check for system-supplied regex matcher; see - comment for rationale. - * configure: Regenerated. - -Tue Sep 23 16:00:25 1997 Jim Kingdon - - * BUGS: Add item about cvs add and -k wrappers. - -Mon Sep 22 11:21:11 1997 Jim Kingdon - - * TODO: Revise item #191 in response to xdelta 1.10 release and a - few other random thoughts. - -Sun Sep 21 17:56:28 1997 Jim Kingdon - - * configure.in: Instead of checking for memchr, just define - HAVE_MEMCHR and HAVE_STRCHR. - Add comment about AC_FUNC_VFORK and vfork in general. - * acconfig.h: Add HAVE_MEMCHR and HAVE_STRCHR. - * configure, config.h.in: Regenerated. - - * config.h.in: Regenerate using autoheader from autoconf 2.10. - -Sat Sep 20 01:17:10 1997 Tim Pierce - - [notes: (1) includes the patches to config.h.in which he sent - (presumably generated), (2) I have omitted a change, which was - sent without a ChangeLog entry, to change re_exec to - re_compile_pattern in configure.in, (3) Also adds diff/Makefile in - AC_OUTPUT -kingdon] - - * Makefile.in (USOURCE_SUBDIRS, check, remotecheck, installcheck): - Add diff. - - Note that AC_CHECK_FUNCS(vfork) - has been replaced by AC_FUNC_VFORK... libdiff wants the more - specific test, and it seems unlikely to break CVS. - - * configure.in: Add AC_FUNC_CLOSEDIR_VOID, AC_FUNC_VFORK, - AC_STRUCT_ST_BLKSIZE. - (AC_CHECK_HEADERS): Add limits.h and sys/file.h. - (AC_REPLACE_FUNCS): Add memchr. - (AC_CHECK_FUNCS): Remove vfork. - -Fri Sep 19 09:59:33 1997 Jim Kingdon - - * TODO: Add item #191, concerning how to store binary files. - -Wed Sep 17 16:13:49 1997 Jim Kingdon - - * TESTS: Add ideas about ability to pass spaces in arguments, and - stdin, to the program under test, as something to consider for the - different test frameworks. - -Tue Sep 16 00:14:55 1997 Jim Kingdon - - * BUGS: Add item about importing binary files. - - * TODO: Adjust item #150 to reflect the fact that the client is - not quite so mean about tossing the log message as it was. - -Fri Sep 12 13:04:31 1997 Jim Kingdon - - * INSTALL: Update Windows entries per email from Greg Strockbine - . - -Thu Sep 11 15:03:21 1997 Jim Kingdon - - * TODO: New item #190, about meaning of -q and -Q global options. - -Wed Sep 10 18:48:41 1997 Jim Kingdon - - * TODO: A few more thoughts on "cvs message" (item 150). - -Tue Sep 9 22:20:15 1997 Jim Kingdon - - * README.VMS (Notes regarding compiling on VAX/VMS): Add item - about mode_t and pid_t. - -Sun Sep 7 17:34:03 1997 Jim Kingdon - - * FAQ: Re-import from FAQ-O-Matic. The metavariables are back. - - * FAQ: Re-import from FAQ-O-Matic. Features comment from - julian@whistle about update -r branch:date. It also clobbered the - metavariables (confusion about "<" as data vs. HTML tag I would - guess), which I plan on fixing in a moment. - - * configure.in: Add comment about re_exec and regexp syntax. - - * configure.in (AC_REPLACE_FUNCS): Remove strdup; CVS was long - ago converted to use its own routine xstrdup. - * configure: Regenerated. - -Sat Sep 6 00:08:20 1997 Jim Kingdon - - * FAQ: Re-import from FAQ-O-Matic. In particular: GIC info - updated, binary files updated (e.g. -kb not -ko), rename database - and rCVS info updated (refer to TODO), tweaks to section on - contributing (HACKING, DEVEL-CVS, &c), Cyclic info updated - (e.g. remove Indiana address), usenet info updated - (e.g. comp.software.config-mgmt not gnu.*). - -Fri Sep 5 20:46:26 1997 Jim Kingdon - - * FAQ: Add another introductory paragraph which talks about out of - date material from 1995 FAQ. - - * FAQ: Re-import from FAQ-O-Matic. This was mainly as a proof of - concept that I could edit the Cygnus question and have the diffs - come out looking right (which worked), but I also discovered that - the previous checkin was truncated partway through. - - * FAQ: Replace file with an introductory paragraph plus a - downloaded copy of Molli's FAQ-O-Matic. I believe the content - closely matches the 1995 Grubbs FAQ but because everything is - re-ordered it would be painstaking work to verify this. - -Thu Sep 4 17:33:53 1997 Jim Kingdon - - * BUGS: Add item about -w global option and client/server. - -Wed Sep 3 23:03:34 1997 Noel Cragg - - * TODO: Verbosify verbiage in item #189. - -Wed Sep 3 14:14:54 1997 Jim Kingdon - - * TODO: Add item #189, concerning renames. - -Sat Aug 30 03:26:57 1997 Jim Kingdon - - * TODO: Fix typo in Noel's change. - -Sat Aug 30 03:17:36 1997 Noel Cragg - - * TODO: Add a header so emacs chooses the correct editing mode. - Made several entries more verbose (expanded some of the less - well-known acronyms and/or added pointers to further - documentation). - -Wed Aug 20 09:51:52 1997 Jim Kingdon - - * INSTALL: Remove "SparcClassing" typo that has been there for - a while. - -Wed Aug 20 09:51:52 1997 Jim Kingdon - and Loren James Rittle - - * INSTALL: Update information for SunOS4, Solaris, Digital Unix, - and HPUX. - -Fri Aug 15 16:42:12 1997 Jim Kingdon - - * INSTALL: Remove the "CVS 1.6" crud; it really isn't needed. Add - paragraph about the meaning of the last three arguments to cvs - import. - -Thu Aug 14 14:42:53 1997 Jim Kingdon - and Loren James Rittle - - * INSTALL: Update information for SunOS4 and Solaris. - -Mon Aug 4 00:02:24 1997 Jim Kingdon - - * BUGS: Be specific about wrappers not working client/server. - -Sat Aug 2 09:23:50 1997 Jim Kingdon - - * INSTALL: In step 4, be more generic (the CVS sources are just an - example, and people might not have them handy). - -Fri Jul 25 17:02:30 1997 Jim Kingdon - - * INSTALL: Refer to cvs.texinfo as the Cederqvist manual; that - seems to be the description which best applies no matter how it - was obtained. Be a little more explicit about the "$" prompt - convention and setting environment variables. Use double quotes - because they work on both DOS and Unix. - -Thu Jul 24 12:22:49 1997 Jim Kingdon - - * NEWS: Also mention SystemAuth. - - * INSTALL (MIPS): Add more detailed report concerning Irix 6.2, - as reported by larry.jones@sdrc.com (Larry Jones). - -Tue Jul 22 17:35:31 1997 Jim Kingdon - - * INSTALL (PowerPC): Add item for Lynx 2.5. - -21 Jul 1997 Jim Kingdon - - * Makefile.in (DISTFILES): Add cvsnt.dsp. - -Mon Jul 21 09:40:10 1997 Jim Kingdon - - * configure.in: Adjust comment regarding version of autoconf which - introduced --bindir. - -Fri Jul 18 09:47:12 1997 Jim Kingdon - - * TODO: Remove item 161 (the comments in cvs.texinfo have a much - more complete discussion of date format issues). In item 30, - change "patch" to "rdiff" and expand discussion slightly. Remove - item 64 (the performance issues in initial checkout have probably - changed quite a bit since that was written and in any event it - isn't particularly useful without specifics of what is slow and - ideas for speeding it up). - - * INSTALL: Reorganize to separate out building/installing CVS - executables from what to do once you have them. Adjust Visual C++ - instructions to deal with Visual C++ 5.x. Add brief mentions of - platforms other than unix and Windows. - -Thu Jul 17 21:13:16 1997 Jim Kingdon - - * TODO: In item 39, talk about how PRCS 1.2 as a possible model. - -Sat Jul 12 15:43:01 1997 Jim Kingdon - - * HACKING: Rewrite paragraph on arbitrary limits to reflect the - fact that the known arbitrary limits are gone. - -8 Jul 1997 Jim Kingdon - - * cvsnt.dsp: Turn on browse information. - -Thu Jul 3 10:07:01 1997 Jim Kingdon - - * INSTALL: Sending exact suggested text is almost as good as a diff. - - * INSTALL (i386 family): Add lines about Watcom and EMX on OS/2. - - * TODO: Add notes about popt and option parsing in general. - -Wed Jul 2 13:11:03 1997 Jim Kingdon - - * TODO: Update item 149 to reflect CVS/Root. - - * TODO: Add item 187, about usage errors vs. help messages. - -Mon Jun 23 18:24:13 1997 Jim Kingdon - - * NEWS: Adjust mention of read-only access in the light of - changes to cvs.texinfo. - - * TODO: Add item 186, concerning multisite. - -Sun, 22 Jun 1997 Jim Kingdon - - * cvsnt.dsp: New file. This apparently is what Visual C++ 5.0 - uses in lieu of a .mak file (or so it seems). - * .cvsignore: Add cvsnt.opt cvsnt.dsw cvsnt.plg. These seem to - be the generated files du jour for Visual C++ 5.0. - -Thu Jun 19 17:16:39 1997 Jim Kingdon - - * NEWS: Add item about CVSROOT/config. - -Wed Jun 18 00:00:02 1997 Jim Kingdon - - * NEWS: Mention pserver --allow-root. - -Mon Jun 16 19:07:34 1997 Jim Kingdon - - * Makefile.in (SUBDIRS): Add emx. - * configure.in (AC_OUTPUT): Add emx. - * configure: Regenerated. - -Sun Jun 8 23:44:00 1997 Jim Kingdon - - * configure.in (AC_CHECK_FUNCS): Remove mkfifo; not used anywhere. - * configure, config.h.in: Regenerated. - -Thu May 29 15:53:06 1997 Jim Kingdon - - * DEVEL-CVS: Add "Policy regarding checkout-only access" to - replace parenthetical remark about checkout-only access. This is - more of a cosmetic/editorial change than a new policy. - -Wed May 21 17:02:29 1997 Jim Kingdon - - * BUGS: Add item about wrappers. - -Fri May 16 13:43:53 1997 Jim Kingdon - - * BUGS: Add item about "cvs export" and binary files. - -Sun May 11 11:38:03 1997 Jim Kingdon - - * README.VMS: Remove information about "direct TCP". Noone has - been complaining about it being broken (the code bitrotted not long - after it was written), nor has anyone complained - that contrib/listener.c was omitted from the distribution (because - it wasn't mentioned in contrib/Makefile.in DISTFILES). If there - is a desire to resurrect such a feature, it should use port 2401 - as now discussed in doc/cvsclient.texi. - -Thu May 8 12:14:40 1997 Larry Jones - and Jim Kingdon - - * INSTALL: Update MIPS/SGI Irix 6.2 - * TESTS: Add note about TESTDIR and SGI Irix 6's XFS. - -Wed May 7 12:01:21 1997 Jim Kingdon - - * TODO: Fix keywords accidentally expanded in previous checkin. - - * TODO: Add item #185, concerning keyword expansion and merges. - -Sun May 4 19:46:03 1997 Jim Kingdon - - * README: Replace section on reporting bugs with a reference to - the bug-reporting section in cvs.texinfo. - -Fri May 2 22:50:04 1997 Jim Kingdon - - * BUGS: Remove item about importing binary files; the bug is fixed. - -Sun Apr 27 19:54:34 1997 Jim Kingdon - - * INSTALL: Refer to doc/DIFFUTILS-2.7-BUG. - - * INSTALL: Don't mention GREP; CVS no longer uses it. - - * configure.in: Add comment about --bindir. - -Thu Apr 24 15:21:17 1997 Norbert Kiesel - - * configure.in (AC_CHECK_FUNCS): added tempnam and mktemp - * config.h.in, configure: Regenerated with autoconf 2.10. - -21 Apr 1997 Jim Kingdon - - * cvsnt.mak: Visual C++, as usual, wants to fiddle with this. - This time it would appear to be chiefly the dependencies. - -Mon Apr 21 01:06:31 1997 Ian Lance Taylor - - * NEWS: Document that the client no longer needs an external patch - program. - -Thu Apr 17 14:28:20 1997 Jim Kingdon - - * TODO: Combine items 150 and 181 since they are basically the same. - -Tue Apr 15 12:32:26 1997 Jim Kingdon - - * FAQ: The URL of yahoo's Configuration Management category has - changed. As it might change again, just cite their top-level page - rather than the entire URL. - -8 Apr 1997 Jim Kingdon - - * cvsnt.mak: Add windows-NT/sockerror.c. - -Wed Mar 26 15:51:33 1997 Jim Kingdon - - * BUGS: Further note on import -kb bug. - -Tue Mar 25 17:51:32 1997 Jim Kingdon - - * cvs-format.el: Add comment concerning c-label-offset. - -Wed Mar 19 14:06:40 1997 Jim Meyering - - * configure.in (test for shadow passwords): Use AC_MSG_RESULT - rather than echo, so configure obeys --quiet. - Use yes and no in message rather than yup and nope. - -19 Mar 1997 Jim Kingdon - - * cvsnt.mak: Now Visual C++ wants to add a bunch of dependencies - for the Release configuration as well as the Debug one. Why it - didn't do this before, I have no idea. - -13 Mar 1997 Jim Kingdon - - * cvsnt.mak: Recent changes have added a number of getline.h - dependencies. - -Thu Mar 13 08:43:04 1997 Jim Kingdon - - * configure.in (AC_C_CROSS): Add comment about obsolescence - thereof. - * config.h.in, configure: Regenerated with autoconf 2.10. - -Thu Mar 13 05:50:29 1997 Philippe De Muyter - - Here are the fixes I needed to make to cvs-1.9 to get it to - compile and successfully pass 'make check' on m68k-motorola-sysv. - * lib/getwd.c (getwd): Added declaration for getcwd(). - * lib/wait.h (WIFSTOPPED et al.): Macro defined if not defined. - * lib/waitpid.c (waitpid): Use wait, not wait3, if !HAVE_WAIT3. - * src/admin.c (admin): Added declaration for getgrnam(). - * src/server.c (fcntl.h): Do not include file twice. Already included - from system.h from cvs.h. - * src/sanity.sh (imported-f*): Renamed from imported-file*, that were - too long for sysv. - * configure.in (wait3): Added to AC_CHECK_FUNCS list. - -Wed Mar 12 14:32:50 1997 Jim Kingdon - - * BUGS: Add "failed assertion `rev == NULL || isdigit (*rev)'" bug. - - * TODO: Remove item 135; this is solved by %v and %V in loginfo. - - * configure.in (AC_CHECK_FUNCS): Don't check for setvbuf; - HAVE_SETVBUF is no longer used. - * config.h, configure: Regenerated with autoconf 2.10. - - * TODO: Add item 184, concerning MD5-based password hash. - Remove item 14, concerning "pathname stripper". I think that was - a reference to the late unlamented strip_path. - -Sat Mar 8 21:22:54 1997 Jim Kingdon - - * INSTALL: NT 4.0 is client and local (like other NT 3.51 & Win95). - -Fri Mar 7 16:51:13 1997 Jim Kingdon - - * INSTALL: Just talked to a NT 4.0 user; add it to the list. - -Sun Mar 2 22:01:23 1997 Jim Kingdon - - * NEWS: Add item about "cvs admin" vs. "cvs admin .". - - * TODO: Remove item #169. It doesn't really explain what an - "archive library" is or in general what the feature they discuss is - supposed to do--I mean, CVS _can_ be used to store .o's, if - that is what they are talking about. - - * TODO: Add item #183, about greater documentation/visiblity for - Entries.Static and CVS/Tag. - - * INSTALL (footnote 5): Add note about how /usr/tmp vs. /var/tmp - shouldn't be an issue anymore - -Thu Feb 20 13:53:19 1997 Jim Kingdon - - * INSTALL: Update Cray entry per mail from John Bowman - - - * configure.in: Add comments about autoconf version. - -Mon Feb 17 09:55:35 1997 Jim Kingdon - - * configure: Regenerated. - -Sat Feb 15 15:37:39 1997 Jim Kingdon - - * configure.in (AC_OUTPUT): Add windows-NT/SCC/Makefile. - -Sun Dec 15 13:12:30 1996 Michael Douglass - and Jim Kingdon - - * NEWS: Mention "cvs logout". - -1997-02-12 Jim Kingdon - - * cvsnt.mak: Visual C++ seems to want to make some cosmetic - changes (reordering *.obj files), perhaps prodded by "Save - All". I hope that putting in these changes will make it - happy... - -1997-02-11 Jim Kingdon - - * cvsnt.mak: Replace with version from Visual C++ 4.0. If someone - wants the 2.x one back, I suppose we can put them side by side, - but I won't be able to update the 2.x one any more as I won't be - having access to 2.x. - -Tue Feb 11 16:43:43 1997 Jim Kingdon - - * .cvsignore: Add cvsnt.mdp and cvsnt.ncb. They seem to be files - created by Visual C++ 4.x which were not created by Visual C++ 2.x. - -Tue Feb 4 11:42:30 1997 Jim Kingdon - - * INSTALL: OS/2 port is client only. - - * Rename devel-cvs (which had only been in the repository, not the - distribution) to DEVEL-CVS. Add "Charter for the devel-cvs - mailing list:" heading, "CVS Development Policies" title, and - one-sentence introduction (editorial changes, not run by - devel-cvs). Revise paragraph concerning membership in the list to - reflect policy change to make read-only membership different from - the ability to send to the list (the new wording was approved by - devel-cvs, as was the rename and including it in the - distribution). - * Makefile.in (DISTFILES): Add DEVEL-CVS. - * HACKING: Add "Mailing lists" section. - -Tue Jan 28 10:41:05 1997 Jim Kingdon - - * configure.in: Remove AC_CHECK_SIZEOF; no longer needed with - lib/md5.c changes. - * acconfig.h: Add HAVE_CONNECT. This is needed so that autoheader - 2.10 works; I think this has been broken since 2 Dec 1996. - * config.h.in: Regenerated with autoheader 2.10. - * configure: Regenerated with autoconf 2.10. - - * HACKING: Revise criterion for whether something goes in NEWS - again (now "user-visible change worth mentioning"--the language - from the GNU coding standards). - -Mon Jan 27 23:05:24 1997 Jim Kingdon - - * HACKING: Criterion for whether something goes in NEWS is not - whether it is user-visible; it is whether it is a bugfix or a - feature. - -Tue Jan 21 10:21:53 1997 Jim Kingdon - - * INSTALL: Warn people against pre-5.x RCS; describe how to find - out what version of RCS you have. - -Wed Jan 8 14:50:47 1997 Jim Kingdon - - * Makefile.in, NEWS, README, TODO, configure.in: Remove CVSid; we - decided to get rid of these some time ago. - -Wed Jan 8 00:17:13 1997 Jim Kingdon - - * README (Credits): Refer to NEWS not ChangeLog; the ChangeLog in - question got renamed a bit but ended up as the bottom of the NEWS - file. Eliminate use of first person in a few places where it is - unclear who it refers to. Explicitly say that the lists - of contributors are not comprehensive. - -Thu Jan 2 12:59:45 1997 Jim Kingdon - - * README, Makefile.in: Remove paragraph about writing to the Free - Software Foundation at 675 Massachusetts Avenue. (1) They are no - longer at that address; (2) the Free Software Foundation are not - the ones to write to concerning CVS licensing. bug-cvs would be a - more appropriate choice; (3) there is probably little need for - this paragraph anyway. - -Thu Jan 2 09:46:37 1997 Karl Fogel - - * NEWS: mention read-only repository access feature. - -Wed Jan 1 18:47:08 1997 Jim Kingdon - - * cvs.spec: Don't include ChangeLog and ChangeLog.zoo in %doc. - There is no point in including them without src/ChangeLog, - src/ChangeLog-96, etc., but more to the point they really belong - in the source distribution rather than a binary distribution anyway. - -Mon Dec 30 16:55:54 1996 Abe Feldman - - * NEWS: Add entry for changes to checkout command (creating CVS - directory at top of working directory) - -Tue Dec 17 13:13:30 1996 Jim Kingdon - - * NEWS: Add entry for verifymsg. - -Tue Dec 10 19:22:20 1996 Jim Kingdon - - * cvs-format.el: Revise comments to explain how to use it and - general minor tidying of comments. - -Mon Dec 2 13:05:44 1996 Ian Lance Taylor - - * configure.in: Don't call AC_CHECK_FUNCS(connect) a second time, - because the value will have been cached; instead, check whether - the library was found with connect defined. - * configure: Rebuild with autoconf 2.12. - -Sat Nov 30 23:04:52 1996 Jim Kingdon - - * BUGS: Add note about mysterious failure in test 187a3. - -Fri Nov 29 10:19:50 1996 Jim Kingdon - - * configure.in (AC_CHECK_FUNCS): Also check for readlink. - * config.h.in: Regenerated using autoheader 2.10. - -Fri Nov 22 16:30:27 1996 Brendan Kehoe - - * configure.in: Check for -lsocket, etc., before checking for - Kerberos libraries. - * configure: Rebuild. - -1996-11-19 Jim Kingdon - - * cvsnt.mak: Remove strippath.c. - -Sun Nov 3 21:54:18 1996 Jim Kingdon - - * README: Move detailed information on compatibility to - the manual; simply point to it here. - -Thu Oct 31 07:20:45 1996 Jim Kingdon - - * BUGS: Add note about cvs import of binary files on non-unix. - -Tue Oct 29 13:59:14 1996 Jim Kingdon - - * BUGS: Add note about "dying gasps" message. - -Sat Oct 26 16:17:09 1996 Jim Blandy - - * configure.in (AC_CHECK_FUNCS): Check for tzset. - -Fri Oct 25 10:27:08 1996 Jim Kingdon - - * NEWS: Mention new loginfo features. - -Thu Oct 24 08:21:48 1996 Lars.Henriksen@netman.dk - - * INSTALL: Update to "DEC Alpha running OSF/1 version 3.2 (1.9)" - -Tue Oct 22 10:34:21 1996 Noel Cragg - - * configure.in: don't check for the existence of the /etc/security - directory, because it's possible to have PAM installed without - using shadow passwords. - * configure: regenerated. - -Sat Oct 19 18:34:29 1996 Jim Kingdon - - * README: Say that the remote protocol is not interoperable before - CVS 1.5. - -Sat Oct 19 13:06:53 1996 Mark H. Wilkinson - and Jim Kingdon - - * configure.in, INSTALL: New options for configure to enable or - disable client and server code, overriding configure's defaults. - * confiugre: Regenerated. - -Sat Oct 19 13:06:53 1996 Jim Kingdon - - * INSTALL: Add note about what to do if you got a binary - distribution of CVS. Add VAX/VMS entry. - -Thu Oct 17 15:38:03 1996 Jim Kingdon - - * NEWS, README: Reinstate 30 Sep 96 changes concerning US letter - vs. A4 paper. - -Wed Oct 16 16:59:57 1996 Jim Blandy - - * configure.in: Simplify code to check for crypt. Check for - -lcrypt first, and then check for the crypt function. The old - code did slightly funky things with cache variables, which JimK's - last change disturbed. Let's just keep it simple. - * configure: Rebuilt. - -Wed Oct 16 15:01:59 1996 Jim Kingdon - - * configure.in: Don't call unset. It isn't portable to Ultrix, - but perhaps more to the point, seems like we should be using the - cached values (there was no comment explaining why we should - ignore the cached values, and none of the CVS developers were - able to provide an explanation when I asked). - * configure: Regenerated. - - * NEWS: Add item regarding export and "cvs history". - -Tue Oct 15 07:40:42 1996 Jim Kingdon - - * TESTS: Mention the fact that expr is only for the tests, not for - CVS itself. At least one person was unclear on this. - -Mon Oct 14 12:13:03 1996 Jim Kingdon - - * HACKING: Add "Submitting patches (strategy)" section and - sentence about test cases. These changes have been run by - devel-cvs and there was no objection. - -Sat Oct 12 19:43:56 1996 Jim Kingdon - - * README.VMS: Add notes about some build problems on VAX/VMS. - -Thu Oct 10 09:20:25 1996 Jim Kingdon - - * BUGS: Remove item about & in modules file and client/server; the - bug is fixed. - - * README.VMS: Rewrite sections about wildcard expansion and - calling editors to suggest technical approaches and to make it - clear that fixes will only happen if someone gets around to them. - -Sat Oct 5 15:01:22 1996 Jim Blandy - - * Version 1.9 released. - -Tue Oct 1 14:32:44 1996 Jim Kingdon - - * NEWS, README: Revert changes regarding -D, -g, and A4. They - are for new features which are not appropriate at this stage of - the release process. - -Mon Sep 30 14:51:36 1996 Greg A. Woods - - * INSTALL (sun3): 1.8.86+ builds and runs make check. - - * NEWS: describe -D and -g; DIFFBIN and GREPBIN - - * MINOR-BUGS: yet another couple of annoyances... - -Mon Sep 30 08:33:51 1996 Jim Kingdon - - * BUGS: Mention "cvs add -m" client/server bug. - - * NEWS: Document change from A4 to US letter. It may seem minor, - but it affects a *lot* of people. - - * README: Revise discussion of US letter vs. A4 to reflect recent - change to cvs.texinfo. - -Sun Sep 29 16:32:47 1996 Greg A. Woods - - * MINOR-BUGS: describe a minor annoyance or two - - * BUGS: describe a couple of new bugs - -Sun Sep 29 14:09:49 1996 Noel Cragg - - * configure.in: check for shadow password files as well as for - getspnam. Some systems (like Linux) have getspnam in the C - library, but aren't necessarily using shadow passwords. - * configure, config.h.in: Regenerate. - -Fri Sep 27 16:49:53 1996 Jim Kingdon - - * Makefile.in (TSUBDIRS): Remove comment about order of - directories mattering. That was only for an old set of hacks, - since gone, which tried to combine several tag files into one - (before emacs could use several tag files at once). - -Wed Sep 25 10:35:06 1996 Jim Kingdon - - * NEWS: Add note about "cvs log -d" date formats changing. See - comment I added to cvs.texinfo for more whining about this situation. - - * BUGS: Remove item about ~/.cvsignore on NT; it is fixed. - -Wed Sep 25 10:22:00 1996 Larry Jones - - * configure.in: Add hack for ISC crypt (the version in the posix C - library doesn't work -- why am I not surprised). Add check for - libsec.a for shadow password functions. - - * Makefile.in: Make zlib along with lib in the check targets. - -Wed Sep 25 08:34:01 1996 Jim Blandy - - Fix from Mark A. Solinski : - * cvsnt.mak: The debug configuration adds the zlib directory to - the include path but it is missing from the release configuration. - Add it to the "ADD CPP" and "CPP_PROJ" lines. - -Tue Sep 24 11:32:20 1996 Jim Kingdon - - * INSTALL: Add VMS entry. Clarify what "tested" means. - - * README: Replace section about what CVS is with the blurb from - cvs.spec (which is also the paragraph we use in the release - announcements). - Change location of pcl-cvs from contrib/pcl-cvs to tools/pcl-cvs. - - * BUGS: Remove item about version numbers; we now have version - numbers. Remove item about server using /usr/tmp; this has been - changed. Remove item about deadlocks between server and client - and file contents being interpreted as commands; I believe this - refers to the case which was fixed by Ian's 7 Aug 96 change to - receive_partial_file. Remove item about server temp directory - becoming full; I'm not sure all bugs related to that have been - fixed, but I think the ones mentioned have been. Remove item - about .# files; this is a documented behavior. Refer to - platform-specific documentation. Add bug with & in modules file - and client/server CVS. Move bug about weird use of long file - names to end; the bug report is so long people won't want to read - past it. Refer to README concerning reporting bugs. Add - introduction. Reword some bug descriptions. Add bug concerning - ~/.cvsignore on NT. - * MINOR-BUGS: Add introduction. Reword some bug descriptions. - Remove item about "premature end of file"--we've improved that - error message as much as we can figure out how. Remove item about - filenames getting truncated (with rcs2log?)--I think this is a fixed - bug although I couldn't quickly find a ChangeLog entry for the fix. - -Tue Sep 17 12:46:37 1996 Jim Kingdon - - * .cvsignore: Add cvs-*.spec. - -Mon Sep 16 17:42:30 1996 Jim Kingdon - - * TODO: In 180, mention issue of network being down. Add item - 182, about inclusiveness of "cvs log -r foo -r bar". - - * HACKING: Also mention arbitrary limits and reentrancy. - User-visible changes should be documented in cvs.texinfo as well - as NEWS. - -Thu Sep 12 16:06:33 1996 Jim Kingdon - - * README.VMS: Put authorship info at end. Add disclaimer. Say - that patch is mandatory not optional. Don't mention gzip; we - don't require it any more. Remove section on filename case; the - bugs described there are fixed. Miscellaneous tweaks and updates. - -Wed Sep 11 11:08:39 1996 Jim Blandy - - * configure.in (AC_OUTPUT): Don't forget to create vms/Makefile. - -Tue Sep 10 19:55:07 1996 Jim Kingdon - - * Makefile.in (DISTFILES): Add build.com and README.VMS. - (SUBDIRS): Add vms. - * build.com: Also recurse into zlib directory. - - * NEWS: Mention Win95. - -Fri Sep 6 11:43:26 1996 Ian Lance Taylor - - * configure.in: Add AC_ARG_ENABLE for encryption. - * acconfig.h: Add ENCRYPTION. - * configure, config.h.in: Regenerate. - * NEWS: Modify the entry on encryption to mention that you must - configure with --enable-encryption. - * INSTALL: Mention the --with-krb4 and --enable-encryption - configure options. - -Thu Sep 5 11:30:45 1996 Jim Kingdon - - * NEWS: Revise access method item to mention both :ext: and - :server:. - - * README.VMS: Change bug reporting address to bug-cvs. In - discussing filenames, don't mention a hypothetical behavior - involving folding to lowercase (I'm not sure what is meant, and it - doesn't sound right to me) and do mention that things might be - different now (as a result of recent changes to case sensitivity - code). - -Wed Sep 4 1996 Jim Kingdon - - * cvsnt.mak: Add windows-NT/ChangeLog. - -Wed Sep 4 13:55:11 1996 Jim Kingdon - - * Makefile.in (DISTFILES): Add cvs.spec. - -Mon Aug 26 15:30:13 1996 Jim Kingdon - - * TODO: Add item suggesting "cvs message" command. - -Tue Aug 20 12:22:53 1996 Jim Kingdon - - * configure.in (AC_C_INLINE): Removed; see src/ChangeLog. - * config.h.in, configure: Regenerated. - * os2/config.h, windows-NT/config.h: Remove #define of inline. - - * configure.in (AC_C_CHAR_UNSIGNED): Removed; it is not used - anywhere. - * config.h.in, configure: Regenerated. - * os2/config.h, vms/config.h, windows-NT/config.h: Likewise, - remove __CHAR_UNSIGNED__. - -Fri Aug 16 13:37:19 1996 Jim Kingdon - - * cvs.spec (%description): Replace description with one that - resembles the release announcements we have been sending out. The - previous one was out of date and not really focused on describing - what CVS does. - (%build): Don't define SERVER_FLOWCONTROL; if we are ready to make - this is the default it should be for all kinds of builds, not just - those via RPM. - -Fri Aug 16 16:09:59 1996 Norbert Kiesel - - * cvs.spec: new file. This is a template for a RPM specification - file (which is used by 'make spec'). - - * Makefile.in (installdirs-local): new (empty) target - (all install uninstall installdirs): add installdirs to list of - targets which are done for all subdirs - (spec): new target to create a rpm specification file (which can - be used to create RPM source and binary packages) - (dist): depend on spec (which now also creates .fname) - -Wed Aug 14 13:59:11 1996 Norbert Kiesel - - * configure.in (AC_REPLACE_FUNCS): add getspnam for reading shadow - password entries - * configure: regenerated - * config.h.in: regenerated - -Mon Aug 12 14:15:31 1996 Jim Kingdon - - * Makefile.in (config.status): When running config.status - --recheck, preserve the value of CFLAGS. - -Fri Aug 9 14:11:31 1996 Jim Kingdon - - * TESTS: Also mention dejagnu advantages. - -Thu Aug 8 16:00:55 1996 Jim Kingdon - - * TESTS (ABOUT STDOUT AND STDERR): New section. - (ABOUT TEST FRAMEWORKS): Add sed/cmp/diff (a la C News) as an option. - - * NEWS: Change entry regarding "cvs log" not invoking "rlog" so - that it emphasizes user-visible behaviors. - -Tue Aug 6 17:01:23 1996 Ian Lance Taylor - - * TODO: Remove item #167 (cvs log doesn't understand symbolic - branch names). It works now. - - * NEWS: Mention that "cvs log" no longer invokes "rlog". - -Wed Jul 31 16:06:03 1996 Jim Kingdon - - * HACKING: Mention rule about _ vs - in file names. - -Wed Jul 24 19:10:38 1996 Ian Lance Taylor - - * NEWS: Mention that Kerberos encryption is now supported. - -Mon Jul 22 23:48:39 1996 Ian Lance Taylor - - * NEWS: Mention that the commit message has changed slightly when - committing changes on a branch. - -Fri Jul 19 16:10:04 1996 Jim Kingdon - - * TESTS: Say that GNU expr is part of sh-utils. - -Thu Jul 18 18:16:33 1996 Jim Kingdon - - * NEWS: Mention -k wrappers option. - - * TESTS: In list of what we would like in a test framework, only - mention portable once, and other wording cleanups. - -Mon Jul 15 1996 Jim Kingdon - - * cvsnt.mak: Add src/ChangeLog (lets us edit it from within - the integrated development environment). - -Sun Jul 14 1996 Jim Kingdon - - * cvsnt.mak: Add src/zlib.c. Add zlib group containing the .c - files in zlib. Add /I "zlib" compiler options. - -Sun Jul 14 10:26:21 1996 Jim Kingdon - - * NEWS: Expand zlib item to emphasize user-visible (and - CVS-installer-visible) consequences. - -Sat Jul 13 21:11:50 1996 Ian Lance Taylor - - * NEWS: Mention that -z now uses zlib. - -Fri Jul 12 18:54:21 1996 Ian Lance Taylor - - * Makefile.in (USOURCE_SUBDIRS): Add zlib. - * configure.in (AC_OUTPUT): Add zlib/Makefile. - * configure: Regenerate. - - * zlib/*: Import zlib 1.0.3. Remove zlib/Makefile. Modify - zlib/Makefile.in for use with CVS. - -Fri Jul 12 1996 Jim Kingdon - - * cvsnt.mak: Add src/buffer.c - -Wed Jul 10 18:44:58 1996 Jim Kingdon - - * NEWS: Say that rlog is deprecated. - -Tue Jul 9 14:37:41 1996 Jim Kingdon - - * PROJECTS: Refer to comment in rcscmds.c regarding RCS library. - - * HACKING: Expand comments on portability. - -Sun Jul 7 23:21:02 1996 Jim Kingdon - - * configure.in (AC_REPLACE_FUNCS): Remove memmove; it was used by - a very old version of the CVS server for nefarious purposes and it - has been long gone. - * configure: Regenerated. - -Tue Jul 2 22:36:31 1996 Jim Kingdon - - * TESTS: Add discussion of test frameworks. - -Fri Jun 28 20:27:56 1996 Jim Kingdon - - * NEWS: Describe "cvs diff -q" removal and new diff options. - -Thu Jun 13 17:29:30 1996 Jim Kingdon - - * TODO: Remove item #67 about having cvs import create CVS - directories; I don't think it is wise to have cvs import mess with - the directory it is working in at all. Remove item #69 about - having import edit modules--in many cases there is no need for an - entry in modules. Remove item #76 about running on top of SCCS; - we are clearly not evolving in that direction. Remove item #91 - about documenting how to import sources from SCCS or RCS; this is - now documented in cvs.texinfo. Remove item #129 about "U CFTS/"; - without more information it is impossible to know what behavior is - being discussed. Remove item #157 concerning module names in cvs - release; cvs release takes a directory name, not a module name. - Remove item #159 about checking access times; this is as likely to - be an annoyance as a help, and people who are into that can just - look at the result from "cvs update" (directly or with a script). - Remove item #164 concerning variables in *info files; it is done. - Remove item #35 (it just says "cvs admin" is cheesy, which isn't - specific enough to be useful). Rewrite #39 to be specific about - what would be nice in having branches track each other. Remove - item #46--I'm not sure what it means and if it means that one - should check in with "cci" or some such instead of "cvs ci" then - that is an installation hassle and a minimal convenience. Add - item #180. - - * config.h.in: Regenerated. - -Thu Jun 13 1996 Ian Lance Taylor - and Jim Kingdon - - * configure.in: Put -L${krb_libdir} in LDFLAGS temporarily when - looking for -ldes. - * configure: Regenerated. - -Mon Jun 10 13:13:35 1996 Jim Kingdon - - * NEWS: Mention NT local. - -Fri Jun 7 18:02:36 1996 Ian Lance Taylor - and Jim Kingdon - - * NEWS: Mention new annotate options. - -Thu Jun 6 14:08:31 1996 Jim Kingdon - - * lib/savecwd.c: Revert CVS_* patch. The include files where - CVS_* is defined were not included, and the code in question was - inside HAVE_FCHDIR which isn't defined on the Mac anyway. - - * src/filesubr.c: Revert CVS_* patch in this one file. The mac - port should have its own copy of filesubr.c instead. - -Wed Jun 05 10:03:10 1996 Mike Ladwig - - * lib/{system.h,savecwd.c}, src/{add.c,checkout.c,client.c, - commit.c,create_adm.c,diff.c,edit.c,entries.c,fileattr.c, - filesubr.c,find_names.c,history.c,ignore.c,import.c,lock.c, - login.c,logmsg.c,mkmodules.c,modules.c,myndbm.c,no_diff.c, - parseinfo.c,patch.c,rcs.c,recurse.c,release.c,remove.c,root.c, - rtag.c,server.c,tag.c,update.c,vers_ts.c,wrapper.c}: - Under non-UNIX operating systems (MS-DOS, WinNT, MacOS), many - filesystem calls take only one argument; permission is handled - very differently on those systems than in UNIX. On MacOS, - the naming scheme for volumes and subdirectories is quite - different. This patch leaves hooks in the form of CVS_ACCESS, - CVS_CHDIR, CVS_CREAT, CVS_FOPEN, CVS_MKDIR, CVS_OPEN, CVS_OPENDIR, - CVS_RENAME, CVS_RMDIR, CVS_STAT, and CVS_UNLINK to accomodate - these differences. - -Thu Jun 6 11:11:53 1996 Jim Kingdon - - * NEWS: Say "changes from 1.7 to 1.8" not "changes since 1.7". - -Wed Jun 5 1996 Jim Kingdon - - * cvsnt.mak: Visual C++ 2.1 seems to want to reformat the line - breaks. No substantive changes, I think. - -Thu May 30 15:35:57 1996 Jim Kingdon - - * Makefile.in (DISTFILES): add TESTS. - -Tue May 28 13:10:42 1996 Jim Kingdon - - * src/server.c: Add comment regarding out-of-order bug. - * TESTS: Explain out-of-order bug. - - * INSTALL: Remove $CVSId$. More strongly encourage people to skip - the tests if they don't have the time to look at the results. - Move most of the discussion of tests to new file TESTS, and add - some information on interpreting check.log output. - * README: In brief summary of install, don't spell out details of - "make check" or "cvs init" steps. - -Sun May 26 17:59:46 1996 Jim Kingdon - - * NEWS: Change "up-to-date" to "not locally modified"; the file - need not match the head revision it only need match some revision. - -Sun May 26 17:02:49 1996 Norbert Kiesel - - * NEWS: document new option "-c" for tag - -Thu May 23 21:49:33 1996 Jim Kingdon - - * INSTALL: Remove footnote 10. The only kind of change suitable - for listing here is fairly easy portability stuff. - -Fri May 17 11:49:11 1996 Jim Kingdon - - * NEWS: Refer to cvs.texinfo and say "filesystem" not "fs". - -Thu May 16 17:13:56 1996 Noel Cragg - - * NEWS: Mention all access methods. - -Wed May 15 23:38:15 1996 Noel Cragg - - * NEWS: add info about access methods and document behavior change - for "cvs login." - -Mon May 13 10:37:09 1996 Greg A. Woods - - * INSTALL: updated for Sun-3 SunOS 4.1.1_U1 (1.8.2) - -Fri May 10 09:39:49 1996 Jim Kingdon - - * NEWS: Document that -d overrides CVS/Root. - -Mon May 6 06:00:10 1996 Benjamin J. Lee - - * Version 1.8.1 - -Sun May 5 17:38:21 1996 Benjamin J. Lee - - Integrated changes submitted by Ian Taylor - - * update.c (update_dirent_proc): cvs co -p doesn't print - anything when run from an empty directory. - - * import.c (import_descend_dir): Check for a file in the - repository which will be checked out to the same name as the - directory. - -Sun May 5 15:49:00 1996 Benjamin J. Lee - - * configure.in: autoconf 2.9 handles AC_CHECK_LIB in a - way that it can not be used to check for main(). Check - for printf() instead. (Reported by ian@cygnus.com) - - * configure: Regenerated. - -Thu May 2 13:34:37 1996 Benjamin J. Lee - - * Version 1.7.88 - -Thu May 2 10:42:13 1996 Jim Kingdon - - * NEWS: Clarify what happened to examples directory. - -Thu May 2 02:06:49 1996 Benjamin J. Lee - - * INSTALL: Updated for NeXTSTEP 3.3 (1.7) - -Thu May 2 01:40:55 1996 Benjamin J. Lee - - * Compatibility fixes affecting QNX, NetBSD, and SCO - - * configure.in (AC_CHECK_FUNCS): Added check for initgroups(), - (ac_cv_func_crypt) Added check for crypt() in -lcrypt; - define AUTH_SERVER_SUPPORT only if crypt() is found. - - * configure: Regenerated. - - * src/server.c (HAVE_INITGROUPS): Use initgroups() only if - located by configure. - -Wed May 1 15:38:56 1996 Jim Kingdon - - * NEWS: Remove item about reserving all-uppercase tag names. - -Wed May 01 00:18:01 1996 noel - - * cvsnt.mak: remove all of those unnecessary libraries! We only - need advapi32.lib and wsock32.lib. - -Wed Apr 24 16:48:35 1996 Jim Kingdon - - * NEWS: Document that -d overrides CVS/Root. - -Fri Apr 19 11:22:35 1996 Benjamin J. Lee - - * Version 1.7.86 - -Sun Apr 14 11:06:44 1996 Karl Fogel - - * configure.in (AC_OUTPUT): generate contrib/elib/Makefile, - tools/Makefile, and tools/pcl-cvs/Makefile. Do not any longer - generate contrib/pcl-cvs/Makefile. - - * Makefile.in: deal w/ above changes. - - * configure: regenerated. - - * Added `tools' subdir (pcl-cvs will live there, as will other - things maintained along with the CVS distribution). - -Wed Apr 10 17:15:25 1996 Jim Kingdon - - * README: Mention documentation and A4 paper in particular. - -Thu Mar 28 12:31:38 1996 Jim Kingdon - - * NEWS: Add "cvs annotate". - -Tue Mar 26 10:46:59 1996 Jim Kingdon - - * INSTALL: In example, change tag name to avoid using a tag name - reserved to CVS. - - * NEWS: Document reservation of some tag names. - -Fri Mar 22 10:45:23 1996 Jim Kingdon - - * INSTALL: Clarify that RCS is only for server or local. - -Mon Mar 18 10:15:18 1996 Jim Kingdon - - * README: Mention info@cyclic.com where we mention support - contracts, not at the end where people might be tempted to view it - as a generic help line. - -Thu Mar 14 16:34:26 1996 Jim Kingdon - - * Makefile.in (stamp-h): Don't run ./config.status --recheck. - -Thu Mar 14 1996 Jim Kingdon - - * cvsnt.mak: Regenerate dependencies. - -Thu Mar 14 13:45:11 1996 Jim Blandy - - * configure.in (AC_OUTPUT): Don't create examples/Makefile; we're - not using the examples directory any more. - -Wed Mar 13 17:02:00 1996 Jim Kingdon - - * INSTALL: Refer to cvs.texinfo rather than out-of-date cvsinit - instructions. Instead of telling everyone to update modules - whenever adding directories (which is optional), refer to the - manual regarding all administrative files. Revise "make check" - instructions to be even less encouraging about submitting bug - reports. - - * examples/*: Removed. - * Makefile.in (SUBDIRS): Remove examples. - * cvsinit.sh: Removed. - * Makefile.in: Remove all cvsinit and PROGS stuff. - * NEWS: Mention cvsinit -> cvs init change. - -Mon Mar 11 13:12:35 1996 Samuel Tardieu - - * BUGS: removed previous description from Greg Woods (3/6/96) - since the bug seems to be corrected - -Wed Mar 6 10:35:32 1996 Greg A. Woods - - * BUGS: describe a weird core-dump with 'cvs co -c'. Now I can't - even get a stack backtrace again -- dbx dumps core! - -Fri Mar 1 09:21:56 1996 Jim Kingdon - - * README.VMS: Remove distribution information (since it is no - longer different for VMS). Various wording fixes to reflect the - fact that using rsh is just one of several ways to connect to a - cvs server, not "the official" one. Say that the unsuitable rsh - is the UCX one. Clarify what rsh uses privileged ports for. - -Fri Mar 1 01:26:28 1996 Benjamin J. Lee - - * README.VMS, build.com: Added for VMS. - -Thu Feb 29 10:04:20 1996 Jim Kingdon - - * NEWS: Mention change to default ignore list. - -Thu Feb 29 00:28:08 1996 Peter Wemm - - * configure.in: correctly spell FNM_PATHNAME in fnmatch() test, - the supplied test fails on proposed POSIX.2, lib/fnmatch.*, Linux, - FreeBSD, etc. - * configure: Regenerated. - -Tue Feb 27 10:43:14 1996 Jim Kingdon - - * INSTALL: Change submission address to bug-cvs from info-cvs. - Encourage submissions to be in the form of diffs to INSTALL. - -Sun Feb 25 15:23:31 1996 Jim Kingdon - - * HACKING: Fix typo. - -Fri Feb 23 1996 Jim Kingdon - - * cvsnt.mak: Add login.c and scramble.c. - -Fri Feb 23 16:36:11 1996 Jim Kingdon - - * README: Mention comp.software.config-mgmt. Don't mention old - cyclic-cvs mailing list. - - * acconfig.h: Add AUTH_SERVER_SUPPORT. Remove DIFF and GREP (no - longer used). - * configure.in: Define AUTH_SERVER_SUPPORT. - * config.h.in, configure: Regenerated. - -Thu Feb 22 22:32:09 1996 Jim Kingdon - - * configure.in: Remove AC_FUNC_ALLOCA. - * configure: Regenerated. - -Mon Feb 19 09:39:21 1996 Jim Kingdon - - * HACKING: Add comments about portability and assert(). - -Thu Feb 15 16:40:13 1996 Jim Kingdon - - * NEWS: Mention $USER internal variable. - -Thu Feb 15 14:00:00 1996 Gary Oberbrunner - and Jim Kingdon - - * cvsnt.mak: Add vasprintf.c and mkmodules.c - -Tue Feb 13 20:05:47 1996 Jim Kingdon - - * configure.in (AC_REPLACE_FUNCS): Add strtoul. - * configure: Regenerated. - -Mon Feb 12 10:06:27 1996 Jim Kingdon - - * TODO: Remove mkmodules stuff. - * NEWS: Add item concerning mkmodules. - - * configure.in (AC_REPLACE_FUNCS): Add vasprintf. - * configure: Regenerated. - -Sun Feb 11 16:43:38 1996 Karl Fogel - - * Makefile.in (DISTFILES): added HACKING. - -Sun Feb 11 12:38:51 1996 Jim Kingdon - - * NEWS: Revise *info files feature (now user vars, not env vars). - -Fri Feb 9 23:51:39 1996 Jim Kingdon - - * NEWS: Mention env var in *info files feature. - -Fri Feb 9 02:41:50 1996 Jim Blandy - - * Makefile.in (DISTFILES): Remove config.sub and config.guess from - the list; they're not distributed any more. - -Thu Feb 1 19:47:46 1996 Jim Kingdon - - * INSTALL: Remove RM; no longer used. - -Thu Feb 1 14:38:04 1996 Karl Fogel - - * configure: re-ran autoconf. - - * Makefile.in (USOURCE_SUBDIRS, SUBDIRS): abstract unix source - subdirs to new var USOURCE_SUBDIRS, for lint's sake and possibly - etags's someday. - (lint): run in USOURCE_SUBDIRS only. - -Thu Feb 1 13:06:47 1996 Roland McGrath - - * configure.in (WITH_KRB4): Escape $ in help text. - -Wed Jan 31 19:03:37 1996 Jim Kingdon - - * HACKING: Add info about NEWS file and release process. - -Tue Jan 30 16:00:00 1996 Jim Kingdon - - * cvsnt.mak: Change save-cwd.c to savecwd.c and regenerate - dependencies to take care of save-cwd.h. - * windows-NT/README: Update information about Visual C++ 4.0. - -Tue Jan 30 16:09:53 1996 Jim Kingdon - - * Rename lib/save-cwd.c to lib/savecwd.c. Avoiding a hyphen - seems to be the only way to get Visual C++ 2.1 to generate a - cvsnt.mak which Visual C++ 4.0 will accept. - * Rename lib/save-cwd.h to lib/savecwd.h for consistency. - * os2/Makefile.in, lib/Makefile.in, lib/savecwd.c, src/add.c, - src/import.c, src/modules.c, src/recurse.c, src/tag.c: Update - accordingly. - - * INSTALL, os2/options.h, windows-NT/options.h, - macintosh/options.h, src/options.h.in: Remove SORT; it is no - longer used. - -Mon Jan 29 15:16:39 1996 Jim Kingdon - - * INSTALL: Mention -b. Don't talk about RCS 5.6.[5-7] beta - releases; this will be an issue for few if any people. Remove - stuff about diff and --with-diffutils which is no longer true. - - * README: Refer to HACKING file. Refer to cvs.texinfo not - manpage. Rewrite section about compatibility between CVS versions. - * HACKING: New file. - * INSTALL: Move -Wall section to HACKING; refer to HACKING. - -Wed Jan 24 20:26:55 1996 Jim Kingdon - - * configure.in: Remove diff stuff. Also remove AC_CANONICAL_HOST - and bindir crud as that was the only place they were used. - * config.h.in, configure: Regenerated. - * config.sub, config.guess: Removed. - * src/options.h.in (DIFF): Change to "diff" and change comment to tell - people not to use -a. - * src/sanity.sh: New test binfiles tests for above-fixed bug (see - comments in patch_file in update.c--passing -a to diff generates a - patch which patch cannot apply). - - * NEWS: Adjust to reflect existence of 1.7. - -Tue Jan 23 14:20:39 1996 Jim Blandy - - * devel-cvs: New file, not to be included in the distribution. - -Thu Jan 18 21:46:56 1996 Jim Blandy - - * BUGS: Remove all mention of the outdated cyclic-cvs@cyclic.com - and remote-cvs@cyclic.com addresses. It turns out that people see - these addresses and use them. Mention the proper way to report - bugs. - -Wed Jan 17 16:40:01 1996 Jim Kingdon - - * README: Fix typo (info-cvs-requests -> info-cvs-request). - -Fri Jan 12 13:38:12 1996 Jim Kingdon - - * configure.in, configure: Revert "Checking user's gender" change. - Sure, you only live once, but I want mine to be a *long* life, not - one interrupted by a CVS user who is not amused coming after me - with an axe. - -Fri Jan 12 12:46:23 1996 Karl Fogel - - * configure: regenerated. - - * configure.in: print "Checking user's gender... ok". I mean, - what the heck, you only live once. - -Thu Jan 11 14:00:00 1996 Jim Kingdon - - * cvsnt.mak: Update dependencies. - -Thu Jan 11 12:03:10 1996 Norbert Kiesel - - * NEWS: document loss of CVS_NOADMIN. Also, mention the - possibility to use "cvs" in .cvsrc. - -Wed Jan 10 20:40:23 1996 Karl Fogel - - * configure: regenerated. - - * configure.in (AC_OUTPUT): added `macintosh/Makefile'. - - * Makefile.in (SUBDIRS): added `macintosh'. - -Wed Jan 10 01:17:18 1996 Jim Kingdon - - * README: Remove URL of obsolete David Zuhn web page. - - * FAQ: Replace entire file with short paragraph explaining the FAQ - is dead. - - * configure.in: Don't set exec_prefix. Set bindir from prefix if - exec_prefix isn't set. - * configure: Regenerated. - - * INSTALL: Update list of machines for 1.6.85 (further changes to - the list of machines will not receive ChangeLog entries). - -Tue Jan 9 09:02:05 1996 Jim Kingdon - - * NEWS: Mention changes in default ignore list. - - * INSTALL: check.log is not in /tmp/cvs-sanity. Mention - submitting bug reports as a possibility, not a request from us. - Separate out "make check" a bit to make clear it is optional. - -Mon Jan 8 11:42:40 1996 Jim Kingdon - - * INSTALL: Remove grep stuff; no longer necessary. - Don't say that patch must understand unidiffs; no longer true. - Suggest configuring with -Wall (here until we have a "how to hack - CVS document"). - -Wed Jan 3 19:00:00 1996 Jim Kingdon - - * .cvsignore: Add cvsnt.vcp. - -Mon Jan 1 22:45:50 1996 Jim Kingdon - - * os2/Makefile.in (Makefile), windows-NT/Makefile.in (Makefile): - New rules. - -Sun Dec 31 16:52:49 1995 Karl Fogel - - * NEWS: add a blurb about password authentication. - -Sun Dec 31 16:16:38 1995 Jim Kingdon - - * README: Add "submissions will be distributed under the GPL" - language (like the newspapers have for letters to the editor). - -Thu Dec 21 16:00:00 1995 Jim Kingdon - - * cvsnt.mak: Revert to an old version, then add in recent changes - to lists of files (using Visual C++; not by hand editing--this way - it can be used as an internal project not just an external one). - -Tue Dec 19 17:13:14 1995 Jim Kingdon - - * NEWS: Mention -kb (strictly speaking a bugfix, not a new - feature, I guess, but it seems worth mentioning anyway). - -Tue Dec 19 17:00:00 1995 Jim Kingdon - - * TODO: Remove "regular TODO list:" line which accidentally got - checked in. - -Mon Dec 18 18:59:30 1995 Jim Kingdon - - * Makefile.in (TAR_VERBOSE): Default to empty, not "v". I don't - want that whole long list of files any more than jimb's daily - update script does. - -Sun Dec 17 23:59:11 1995 Jim Kingdon - - * configure.in (AC_REPLACE_FUNCS): Remove vasprintf. - * configure: Regenerated. - -Sat Dec 16 17:19:45 1995 Jim Kingdon - - * configure.in (AC_REPLACE_FUNCS): Add vasprintf. - * configure: Regenerated. - -Mon Nov 20 14:19:47 1995 Jim Kingdon - - * TODO: Remove items about developer communications; they are done. - * NEWS: Mention developer communication features. - * cvsinit.sh: Also add notify file. - -Mon Dec 11 22:44:58 1995 Karl Fogel - - * New subdir "macintosh", for Mike Ladwig's - port-in-progress. - -Thu Dec 7 14:32:49 1995 Jim Meyering (meyering@comco.com) - - * Makefile.in (check): Make sure library is built before running - make in src. - (remotecheck): Likewise. - (installcheck): Likewise. - -Wed Dec 6 11:40:37 1995 J.T. Conklin - - * configure.in: Remove leading -l from first argument of - AC_CHECK_LIB for -lkrb and -ldes checks. - -Mon Dec 4 08:06:31 1995 Jim Kingdon - - * config.h.in: Regenerated. - -Sun Dec 3 20:05:10 1995 Jim Kingdon - - * configure.in: Remove grep stuff. - * configure: Regenerated. - -Fri Dec 1 11:16:18 1995 Norbert Kiesel - - * configure, config.h.in: re-ran autoconf - - * configure.in (AC_CHECK_HEADERS): add sys/resource.h to list of - tested headers - - * Makefile.in (DISTFILES): add config.sub and config.guess - -Thu Nov 23 09:01:53 1995 Jim Kingdon - - * TODO: Remove item about doc describing undoing a change; it - already does. - -Sun Nov 19 18:12:36 1995 Jim Blandy - - * Makefile.in (dist): Pull out the 'v' in the tar command to a - variable, so I can disable it in my daily update script. - -Tue Nov 14 18:31:36 1995 Greg A. Woods - - * cvsinit.sh: - - new rcs id - - new opening comment - - read only one "word" for CVSROOT - - add checkoutlist, cvswrappers, taginfo, wrap, & unwrap to - examples install loop, special handling for latter.... - - don't do any special stuff for loginfo -- always comment out - everything in the newly installed examples - - add a wee message to suggest editing newly installed examples - - tweak some more comments, esp. regarding install of contrib - scripts.... - - make $CVSROOT/CVROOT/history group writable if it didn't exist - as it's not very useful otherwise - -Tue Nov 14 15:22:25 1995 Greg A. Woods - - * cvsinit.sh: woops! wasn't installing contrib/log! - -Tue Nov 14 12:09:11 1995 Greg A. Woods - - * INSTALL: oops, missed a couple of things about "configure" - - * configure: re-ran autoconf - -Tue Nov 14 11:06:25 1995 Greg A. Woods - - * config.guess, config.sub: first time in (from autoconf-2.4) - - * configure.in: - - updated to work with autoconf-2.4 - - call AC_CANONICAL_HOST to get host OS type right (needs - config.sub and config.guess) - - added full support for --with-diffutils and --with-gnugrep - - fixed the diff search to work almost like the one for RCS-5.7 - - fixed some quoting problems - - * README: mention optional 'make check' step - - * INSTALL: - - updated notes about working SunOS versions - - re-wrote notes about RCS, diffutils, etc. - - added notes about configuring with GNU diffutils and GNU grep - - added notes about using 'make check' - - changed bug reporiting instructions to mention cvsbug - - re-wrote notes about setting CVSROOT in shell startups - -Fri Nov 3 11:11:16 1995 Jim Kingdon - - * README: Fix typo in URL of molli's web site. - -Tue Oct 31 19:28:16 1995 Karl Fogel - - * testing something, please ignore. - -Mon Oct 23 18:37:27 1995 Karl Fogel - - * configure: re-ran autoconf. - - * configure.in (AC_OUTPUT): os2/Makefile. - - * Makefile.in (SUBDIRS): added os2 subdir. - -Mon Oct 23 12:02:51 1995 Norbert Kiesel - - * cvsnt.mak: added lib/getline.c - -Fri Oct 20 17:04:55 1995 Norbert Kiesel - - * cvsnt.mak: added src/expand_path.c, error.[ch] now in src - -Thu Oct 19 16:26:32 1995 Jim Kingdon - - * INSTALL: Remove note about RCS 5.7 and log messages - consisting only of whitespace; fixed in CVS on 11 Jul 95. - -Tue Oct 17 17:57:23 1995 Warren Jones - - * man/cvs.5, examples/modules: Document -e. - -Tue Oct 10 16:34:25 1995 Thorsten Lockert - - * configure.in: More crud looking for kerberos, this time for 4.4BSD. - * configure: Regenerated. - -Sun Oct 8 12:22:19 1995 Peter Wemm - - * configure.in: check for POSIX and BSD style reliable signals - * configure: regenerated by autoconf - * config.h.in: regenerated by autoheader - -Fri Oct 6 21:50:48 1995 Jim Kingdon - - There is little point in trying to share a file as trivial as - lib/error.c between programs. So just admit it is CVS specific: - * lib/error.c: Move from here... - * src/error.c: ...to here, and remove CVS_SUPPORT ifdefs. - * lib/error.h: Move from here... - * src/error.h: ...to here. Remove CVS_SUPPORT - ifdefs; remove unused variable error_message_count. - * src/Makefile.in (OBJECTS): Add error.o. - (SOURCES): Add error.c. - (HEADERS): Add error.h. - * lib/Makefile.in (OBJECTS): Remove error.o. - (SOURCES): Remove error.c. - (HEADERS): Remove error.h. - * acconfig.h, configure.in: Remove CVS_SUPPORT. - * configure, config.h.in: Rebuilt using autoconf and autoheader. - * windows-NT/config.h: Remove CVS_SUPPORT. - -Thu Oct 5 17:26:38 1995 Jim Kingdon - - * INSTALL: Mention Siemens-Nixdorf RM600. - -Tue Oct 3 09:32:19 1995 Jim Kingdon - - * NEWS: Remove item about -f global option; it is old news already - mentioned elsewhere in the file. - -Mon Oct 2 18:12:15 1995 Jim Blandy - - * FAQ: Updated for CVS 1.5. And now 1.6 is almost out. The FAQ - always lags the package, sigh... - -Mon Oct 2 18:10:35 1995 Larry Jones - - * configure, config.h.in: Rebuilt using autoconf and autoheader. - - * configure.in: check for ; used by src/server.c. - (ISC keeps all the stuff that BSD has in here, so - we need it for the FD_SET stuff for select().) - Moved check for gethostname() after check for connect() since if - connect() is not found, we may add librariesd and gethostname() - may well be in one of those libraries. - If connect() isn't found, look in -linet (ISC) in addition to - -lsocket and -lnsl. Also, ignore the cache since we need to - update LIBS reguardless of whether it was found before or not and - the answer may well be different afterwards. - Define CLIENT_SUPPORT and SERVER_SUPPORT only if connect() is - found. - - * INSTALL: update info for ISC 4.0.1; renumber footnotes. - -Mon Oct 2 17:01:07 1995 Jim Kingdon - - * INSTALL: Indicate CVS version tested with Solaris 2.4. - -Mon Oct 2 10:42:37 1995 Karl Fogel - - * (configure): Re-ran autoconf. - -Mon Oct 2 10:33:58 1995 Michael Finken - - * configure.in: AC_REPLACE `strstr'. - -Sun Oct 1 23:22:28 1995 Bryan O'Sullivan - - * (INSTALL): noted that CVS works fine on Solaris 2.4 with both - gcc and SPARCworks cc. - -Sun Oct 1 18:48:19 1995 Karl Fogel - - * (configure): re-ran autoconf following Peter Wemm's change - below. - -Sun Oct 1 22:24:56 1995 Peter Wemm - - * configure.in: more extensive searching for -lsocket and -lnsl - as done in Taylor-UUCP 1.06 - -Sun Oct 1 15:32:01 1995 Karl Fogel - - * (configure): re-ran autoconf. - -Sun Oct 1 11:35:17 1995 Jim Kingdon - - * TODO: Remove item about setting comment leader automatically; - RCS 5.7 does this. - -Wed Sep 27 15:34:04 1995 Peter Wemm - - * configure.in: correct detection of GNU diff's -a option for - src/options.h - * configure: regenerate with autoconf - -Fri Sep 22 14:29:31 1995 Jim Kingdon - - * TODO: Remove item about reindenting on the way in and out. - wrappers provide this functionality. - -Wed Sep 20 14:27:28 1995 Jim Blandy - - * configure.in: #define the symbols DIFF and GREP to be the paths - to the DIFF and GREP programs; their values will be edited into - src/options.h (and config.h, coincidentally). - * acconfig.h (DIFF, GREP): Add these. - * configure, config.h.in: Rebuilt using autoconf and autoheader. - -Sun Sep 10 21:38:05 1995 Jim Kingdon - - * TODO: CVS can already undo a change, suggest documenting how. - Expand slightly on mode stuff. - Remove item about not letting people check out into repository (it - is done). - Redo item about expanding env vars in *info to reflect current - thinking. - Remove item about making it hard to accidentally move tags; it is - done. - Add client/server note to suggestion regarding interactive merging. - -Fri Sep 1 12:07:02 1995 Jim Kingdon - - * BUGS: Remove items about refetching unpatchable files and options.h. - -Fri Sep 1 09:20:09 1995 Jim Blandy - - * Makefile.in (DISTFILES): Remove cvsnt.vcp; it's been deleted. - -Thu Aug 31 13:47:35 1995 Jim Kingdon - - * Makefile.in (stamp-h): Rebuild config.status before trying to - use it to build config.h. - - * Makefile.in: Change "cd foo; make" to "cd foo && make"; - otherwise we get into an infinite loop if an objdir doesn't exist. - -Thu Aug 31 11:07:06 1995 Jim Blandy - - * configure.in: Arrange not to touch options.h if we haven't - modified it. AC_CONFIG_HEADER checks if the file is unmodified, - whereas AC_OUTPUT doesn't, and they're otherwise identical, so... - (AC_CONFIG_HEADER): ... mention src/options.h here... - (AC_OUTPUT): ... not here. - Copy src/options.h to src/options.h-SAVED, don't move it. - Otherwise, configure will create it again every time. - Remove the code to compare the new src/options.h with - src/options.h-SAVED and move it back if it's unchanged; autoconf - writes that for us now. - -Wed Aug 30 18:45:28 1995 Jim Blandy - - * .cvsignore: Ignore WinDebug and WinRel directories, used by - Microsoft Visual C++ to store object files and executables. - - * acconfig.h (CVS_SUPPORT, CLIENT_SUPPORT, SERVER_SUPPORT): New - symbols, which autoheader will use to build config.h.in from - configure.in. - * configure.in (SERVER_SUPPORT, CLIENT_SUPPORT): Remove spaces - between AC_DEFINEs and opening parens of argument lists. Oops. - * configure: Rebuild using autoconf. - * config.h.in: Rebuild using autoheader. - - * Makefile.in (SUBDIRS): Uncomment windows-NT. - - * INSTALL: Added Windows NT to list of supported platforms. - Added Windows NT installation instructions. - -Tue Aug 29 16:08:01 1995 Jim Blandy - - * cvsnt.mak: Completed Windows NT port. - - * configure.in (SERVER_SUPPORT, CLIENT_SUPPORT): Arrange for these - to get #defined. In the config.h file for the Windows NT port, we - only #define CLIENT_SUPPORT. - * config.h.in (SERVER_SUPPORT, CLIENT_SUPPORT): Add #undefs for - these. - - * configure.in (AC_OUTPUT): Build the Makefile for the windows-NT - subdirectory too. - - * cvsnt.vcp: Removed. This doesn't store any information needed - to compile CVS; it seems to be mostly programmer preference stuff. - There's no need to distribute it. - - * INSTALL: Added info about Harris Nighthawk from Steve Allen --- - thanks! - -Mon Aug 21 16:08:37 1995 Jim Blandy - - Bring the saga to a close: - * configure.in: Use AC_PROG_MAKE_SET here, to decide whether we - need to set the MAKE variable in Makefile. - * Makefile.in: Use @SET_MAKE@ here, to set MAKE when appropriate. - -Mon Aug 21 15:26:29 1995 Jim Kingdon - - * Makefile.in: Add comment regarding AC_SET_MAKE. - -Sat Aug 19 21:57:51 1995 Jim Blandy - - * configure.in: Define CVS_SUPPORT, to tell certain library - functions that they're part of CVS. - * config.h.in: Add #undef for CVS_SUPPORT, for configure to chew - on. - -Fri Aug 18 22:35:34 1995 Jim Kingdon - - * Makefile.in: Don't set MAKE; apparently all makes set it and GNU - make, at least, will set it to what make was invoked as (perhaps gmake - or some such), not just "make" (which might not support VPATH, for - example). - -Sun Aug 13 23:35:47 1995 Jim Kingdon - - * INSTALL: Convert Data General entry to same format as other entries. - -Sun Aug 13 13:11:36 1995 Jim Blandy - - * cvs-format.el: Add note about set-c-style. - -Thu Aug 3 16:13:29 1995 Jim Blandy - - * INSTALL: Fixed mail address for updates. - - * INSTALL: Noted that 1.5 runs on SunOS 4.1.1 -- 4.1.3. - -Sun Jul 30 20:12:26 1995 James Kingdon - - * cvsinit.sh: Unify code for modules and loginfo with code for - other files which have checked-out and ,v files in CVSROOT. - Don't add "#" to start of lines in rcstemplate. - -Sat Jul 29 16:48:05 1995 James Kingdon - - * cvsinit.sh: If arguments are given, give version number and - usage message. Make printed messages much more concise. - - * cvsinit.sh: Rename log.pl to log. Don't install log twice. - - * Makefile.in (install-local), contrib/Makefile.in (install): - Remove "reminder" to run cvsinit; running cvsinit is not required. - -Fri Jul 28 16:46:10 1995 James Kingdon - - * Makefile.in (SUBDIRS): Comment out windows-NT. - -Fri Jul 28 02:27:54 1995 Jim Blandy - - * Makefile.in (DISTFILES): Add cvsnt.mak and cvsnt.vcp. - (SUBDIRS): Add windows-NT. - - * config.h.in: Regenerated from configure.in by autoheader. - -Wed Jul 19 18:00:00 1995 Jim Blandy - - * configure.in (AC_CHECK_HEADERS): Check for and . - -Tue Jul 18 21:18:00 1995 Jim Blandy - - * configure.in (AC_CHECK_HEADERS): Check for sys/param.h; Windows NT - doesn't have it. - - * configure.in (AC_CHECK_HEADERS): Check for sys/time.h. If you're - using AC_HEADER_TIME, it's best to check for this too. - - * cvsnt.mak: New file --- makefile equivalent for Microsoft Visual C++. - Choose this as your project when working with CVS under MSVC++. - * cvsnt.vcp: New file --- configuration info for Microsoft Visual C++. - * windows-NT: New subdirectory, containing files to be used to - build under Microsoft Windows NT. - -Wed Jul 12 23:26:24 1995 James Kingdon - - * Makefile.in: Remove duplicate install-info rule. - -Wed Jul 12 16:00:27 1995 Karl Fogel - - * Makefile.in (install-local): added rule for install-info, made - `install' depend on it. - - * README: correct mailing list addresses. - * INSTALL: same. - -Wed Jul 12 09:15:02 1995 Jim Meyering (meyering@comco.com) - - * configure.in (gdiff_path): Remove gdiff from the list of programs. - SGI's Irix includes a program named gdiff that is an X-based GUI to - diff. - - * configure.in: Add check for working fnmatch functions so that - systems providing it don't incur the space overhead of linking - with the version in lib. Cross compiling builds always use the - version in lib. - -Tue Jul 11 15:47:20 1995 Greg A. Woods - - * configure.in: add some FIXME comments - - add a hack to restore src/options.h if AC_OUTPUT() didn't modify - it. Note that this does *not* work for config.status, thus one - FIXME comment. - - add test for #! (to warn about possible failure of perl scripts - - add test for diff and grep paths (for src/options.h.in) - - fix up handling of src/options.h.in - - add checks for PERL_PATH and CSH_PATH (from previous local changes) - -Tue Jul 11 14:31:18 1995 Michael Shields - - * Makefile.in (LDFLAGS): Pick up from configure. - -Sun Jul 9 19:03:00 1995 Greg A. Woods - - * configure: re-ran autoconf-2.4 - - * cvsinit.sh: make use of xVERSIONx from the Makefile - - get rid of stuff duplicated in examples/* and use that instead - - * Makefile.in: $(VERSION) for cvsinit.sh wasn't set, so get it - from src/version.c instead. - - * cvsinit.sh: install two more example CVSROOT control/config - files: rcstemplate checkoutlist - - install useful scripts from $CVSLIB/contrib too... - (from previous local changes) - - * Makefile.in: add another reminder to run 'cvsinit' to update - repository(ies) (from previous local changes) - -Thu Jul 6 17:53:55 1995 Paul Eggert - - * Makefile.in (mostlyclean-local): Remove $(PROGS). - -Sat Jul 1 13:11:41 1995 James Kingdon - - * Version 1.5.1. - -Thu Jun 29 01:02:09 1995 James Kingdon - - * configure.in, configure: cross_compiling gets set to "no", not - empty--change test accordingly. - - * Version 1.4.93. - -Wed Jun 28 22:33:54 1995 James Kingdon - - * lib/Makefile.in, man/Makefile.in, doc/Makefile.in: Comment out - rules for configure and config.status, just like in Makefile.in or - src/Makefile.in. - -Tue Jun 27 19:53:05 1995 James Kingdon - - * configure.in (AC_REPLACE_FUNCS), configure: Remove fnmatch. - * lib/Makefile.in (OBJECTS): Add fnmatch. - Avoids buggy Solaris 2.4 libc fnmatch. - - * FAQ: Updated with new version from ftp.odi.com. - -Mon Jun 26 15:17:46 1995 James Kingdon - - * Version 1.4.92. - -Thu Jun 22 12:45:24 1995 James Kingdon - - * Version 1.4.91. - -Wed Jun 21 16:33:04 1995 James Kingdon - - * PROJECTS: New file. - * Makefile.in (DISTFILES): Add it. - -Wed Jun 21 16:12:14 1995 James Kingdon - - * Makefile.in (FLAGS_TO_PASS): Don't pass INSTALL to sub-makes. - The reason for passing it is gone now that we are using autoconf - 2.x which will set INSTALL in the sub-makefiles correctly. - -Tue Jun 20 18:14:54 1995 James Kingdon - - * configure.in, configure: Make sure src directory exists before - trying to copy options.h to it. - -Mon Jun 19 13:47:20 1995 Jim Blandy - - * Makefile.in: Add a "remotecheck" target here, for consistency; - people shouldn't have to switch to src before running the tests. - -Mon Jun 19 10:08:03 1995 Jim Kingdon (kingdon@lioth.cygnus.com) - - * INSTALL: Update list of machines tested. Remove note about - systems missing opendir--this is an autoconf issue, not something - installers should have to worry about. Refer to NEWS instead of - ChangeLog. No longer "strongly recommend" putting diff -a in - options.h. - -Fri Jun 16 22:30:03 1995 Jim Kingdon (kingdon@cyclic.com) - - * Version 1.4.90. - - * configure, configure.in (AC_OUTPUT): Add config/pcl-cvs/Makefile. - - * Makefile.in (dist): Rename dist from ccvs- to cvs-. - - * Makefile.in (dist, dist-dir), src/Makefile.in, doc/Makefile.in, - examples/Makefile.in, contrib/Makefile.in, - contrib/pcl-cvs/Makefile, man/Makefile.in, lib/Makefile.in - (dist-dir): Use srcdir where appropriate. - -Thu Jun 15 14:33:37 1995 Jim Kingdon (kingdon@cyclic.com) - - * CYCLIC-CVS-FAQ: Removed. - * Rename ChangeLog.fsf to NEWS. Add information about changes - since 1.4A2. - * Makefile.in (DISTFILES): Adjust accordingly. - * README: Revise to reflect current status of releases. - -Thu Jun 15 12:22:42 1995 Jim Kingdon (kingdon@cyclic.com) - - * TODO: Remove various items already fixed. Revise others. - -Thu Jun 15 12:24:45 1995 J.T. Conklin - - * configure.in: Use AC_C_INLINE to handle inline. - Reorganized to put compiler and OS checks first so that any - special defines they might provide are used in subsequent tests. - - * configure, config.h.in: regenerated with autoconf and - autoheader version 2.3. - -Thu Jun 8 16:33:51 1995 Jim Kingdon (kingdon@lioth.cygnus.com) - - * INSTALL (Installation): Disrecommend RCS 5.6.[5-7]. - -Tue May 30 00:07:15 1995 Jim Meyering (meyering@comco.com) - - * Makefile.in (distclean-local): Don't delete config.status here. - (distclean): Delete config.status here instead, but only after - recursive make invocations. Otherwise, the new dependencies - in */Makefile.in on ../config.status led to failure in each sub-make - because there is no rule there to make ../config.status. - Reported by Jeff Johnson . - (realclean): Likewise. - -Mon May 29 22:24:28 1995 J.T. Conklin - - * configure.in: Use AC_HEADER_DIRENT instead of AC_DIR_HEADER. - Use AC_HEADER_STAT to determine if S_FOO() macros work. - Use AC_HEADER_TIME to determine if both and - can be included as recommend by autoconf manual. - Remove AC_STRUCT_TM test, as above test is better. - - * configure, config.h.in: regenerated with autoconf and - autoheader version 2.3. - -Fri Apr 28 14:36:49 1995 Ken Raeburn (raeburn@kr-pc.cygnus.com) - - * Makefile.in: Set "all" as default target instead of ".PHONY". - Some versions of make will otherwise try building all of the phony - targets, in order. - -Mon May 1 14:02:42 1995 Jim Blandy - - * configure.in: Set up src/options.h for the user. Its defaults are - usually right. - * README, INSTALL: Adjust installation instructions appropriately. - -Fri Apr 28 22:31:26 1995 Jim Blandy - - * Makefile.in (DISTFILES): Brought up-to-date. - (dist): Rewritten to use dist-dir targets, passing DISTDIR variable. - (GZIP, GZIP_EXT): New variables. - (dist-dir): New target. - - We don't want to include a file the user has to edit in the - distribution. - * src/options.h: No longer distributed. - * src/options.h.in: Distribute this instead. - * INSTALL, README: Installation instructions updated. - -Sat Apr 8 19:02:21 1995 Roland McGrath - - * configure.in: Check for fchdir. - (connect check): Use AC_CHECK_LIB instead of (obsolete) - AC_HAVE_LIBRARY. - -Sat Apr 8 14:52:46 1995 Jim Blandy - - * Makefile.in (CFLAGS): Let configure set the default for CFLAGS. - Under GCC, we want -g -O. - -Wed Feb 8 06:49:49 1995 Roland McGrath - - * Makefile.in (stamp-h): Pass CONFIG_FILES=$@ to config.status so - the target is created. - * configure.in: Applied `autoupdate' from Autoconf 2.1 to - modernize macro usage. - (AC_RSH): Call removed. It was obsolete and not doing anything useful. - (AC_OUTPUT): Write stamp-h as the Makefile rules expect we will. - (AC_TYPE_PID_T): Add this check. - -Tue Nov 8 06:26:54 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * Add stamp-h.in. Remove it from .cvsignore. - -Fri Oct 28 11:50:51 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * Makefile.in: Comment out autoconf and autoheader rules. - -Tue Oct 25 17:44:13 1994 Ken Raeburn - - * Makefile.in (all, install, uninstall): Fail if make in - subdirectory fails. - -Tue Oct 18 13:26:15 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * Makefile.in (FLAGS_TO_PASS): Pass INSTALL*. Add comment about - why we need to. - -Tue Sep 27 08:27:06 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * Makefile.in (SUBDIRS): Reinstate "contrib". - * configure.in (AC_OUTPUT): Add contrib/Makefile. - * configure: Regenerated. - -Tue Sep 27 01:03:59 1994 John Gilmore (gnu@cygnus.com) - - * Makefile.in (SUBDIRS): Comment out "contrib". Since we don't - bother to configure it, we shouldn't make it either. - -Wed Aug 10 14:52:57 1994 Ken Raeburn (raeburn@cujo.cygnus.com) - - * Makefile.in (FLAGS_TO_PASS): Don't include LIBS or CFLAGS twice. - - * configure.in: Include waitpid and memmove in AC_REPLACE_FUNCS - list. Don't check for memmove separately. - * configure: Regenerated. - * config.h.in: Regenerated for Mark's change. - -Wed Aug 10 14:32:24 1994 Mark Eichin (eichin@cygnus.com) - - * configure.in (KRB4): recognize --with-krb4=path. Also test for - krb_get_err_text so src/main.c and src/client.c can deal - appropriately. - -Tue Aug 9 15:49:07 1994 Ken Raeburn (raeburn@cujo.cygnus.com) - - * configure.in: Check sizes of `long' and `int', needed for md5 - code. - * acconfig.h: New file. Mention HAVE_KERBEROS, to keep autoheader - happy. - * configure, config.h.in: Regenerated. - -Tue Jul 19 11:23:21 1994 Ian Lance Taylor (ian@sanguine.cygnus.com) - - * configure.in: Check not only that krb.h exists, but that it will - actually compile correctly. - * configure: Regenerated. - -Mon Jul 11 07:04:36 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * configure.in: Add comment re autoheader. - -Tue Jun 28 22:09:23 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * configure.in: Only look for -lsocket and -lnsl if we don't - already have connect. - * configure: Regenerated. - -Mon Jun 27 17:21:48 1994 Ian Lance Taylor (ian@sanguine.cygnus.com) - - * configure.in: Correct "krb_libdir" to "${krb_libdir}". - * configure: Regenerated. - -Fri Jun 3 10:15:24 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * configure.in: Check for -lsocket and -lnsl. - * configure: Regenerated. - -Fri May 27 18:12:43 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * configure.in: Add valloc to AC_REPLACE_FUNCS. Add getpagesize - to AC_HAVE_FUNCS. Check for krb.h and -lkrb. If not found, look - in /usr/kerberos if native. If found somewhere, define - HAVE_KERBEROS and also look for -ldes. Substitute includeopt. - * configure: Regenerated. - -Fri Mar 11 13:11:51 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * configure.in: Check for ; used by src/server.c. - * configure: Regenerated. - -Sun Jan 9 12:04:15 1994 Ken Raeburn (raeburn@kr-pc.cygnus.com) - - * configure.in: Check for timezone function, for NetBSD support. - * configure: Regenerated. - -Wed Dec 15 18:05:21 1993 david d `zoo' zuhn (zoo@andros.cygnus.com) - - * Makefile.in: add MAKEINFO to MDEFINES, pass down MDEFINES on all - recursive make invocations that require it; define - INSTALL_PROGRAM and use it; reorganize MDEFINES; set infodir and - add to MDEFINES; use YACC instead of BISON - - -Mon Dec 6 17:02:18 1993 K. Richard Pixley (rich@sendai.cygnus.com) - - * src/diff.c (diff_fileproc): add support for "cvs diff -N" which - allows for adding or removing files via patches. - diff --git a/contrib/cvs/ChangeLog.zoo b/contrib/cvs/ChangeLog.zoo deleted file mode 100644 index a1e1d0e..0000000 --- a/contrib/cvs/ChangeLog.zoo +++ /dev/null @@ -1,700 +0,0 @@ -Thu Sep 15 14:19:21 1994 david d `zoo' zuhn - - * Makefile.in: define TEXI2DVI, add it to FLAGS_TO_PASS; remove - old comments about parameters for DEFS - -Wed Jul 13 21:54:46 1994 david d `zoo' zuhn (zoo@monad.armadillo.com) - - * contrib/rcs-to-cvs: rewritten for Bourne shell (thanks to David - MacKenzie ) - -Wed Jul 13 21:48:38 1994 Ken Raeburn (raeburn@cujo.cygnus.com) - - * Makefile.in: Deleted line consisting of only whitespace; it - confuses some versions of make. - -Mon Jan 24 12:26:47 1994 david d zuhn (zoo@monad.armadillo.com) - - * configure.in: check for and - - * Makefile.in: define YACC and not BISON - -Sat Dec 18 00:52:04 1993 david d zuhn (zoo@monad.armadillo.com) - - * config.h.in: handle HAVE_SYS_WAIT_H, HAVE_ERRNO_H - - * configure.in: check for memmove, - - * Makefile.in (VPATH): don't use $(srcdir), but @srcdir@ instead - - * configure.in (AC_HAVE_HEADERS): check for - -Mon Nov 29 15:05:43 1993 K. Richard Pixley (rich@sendai.cygnus.com) - - * lib/Makefile.in, src/Makefile.in (CFLAGS): default to -g. - - * src/log.c (log_fileproc): if a file has been added, but not - committed, then say so rather than reporting that nothing is - known. - - * src/sanity.el: update for emacs-19. - - * src/RCS-patches, src/README-rm-add: update for rcs-5.6.6. - - * src/Makefile.in: removed some gratuitous diffs from cvs-1.3. - - * src/cvsrc.c: strdup -> xstrdup, malloc -> xmalloc, comment about - fgets lossage. - - * configure, configure.in, Makefile.in: support man and doc - directories and info and dvi targets. - - * doc/cvs.texinfo: comment out include of gpl.texinfo. - - * doc/Makefile.in: added dvi & info targets. - - * doc/cvsclient.texi: added @setfilename. - - * lib/Makefile.in: remove some extraneous diffs against the - patched cvs-1.3. - - * doc/Makefile.in, man/Makefile.in: update for autoconf. - -Fri Nov 19 12:56:34 1993 K. Richard Pixley (rich@sendai.cygnus.com) - - * Many files: added configure.in, updated configure based on - autoconf. - -Tue Jun 1 17:02:41 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com) - - * configure: add support for alloca and sys/select.h - -Wed May 19 19:34:48 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * cvs-format.el: Don't set c-tab-always-indent. - -Mon Mar 22 23:25:33 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com) - - * Makefile.in: installcheck: recurse into src directory to run tests - -Mon Jan 18 17:21:16 1993 K. Richard Pixley (rich@rtl.cygnus.com) - - * Makefile.in (check): recur into src directory in order to pick - up the sanity check. - -Thu Dec 17 19:41:22 1992 david d `zoo' zuhn (zoo at cirdan.cygnus.com) - - * Makefile.in: added blank 'dvi' target - -Tue Apr 7 15:55:25 1992 Brian Berliner (berliner at sun.com) - - * Changes between CVS 1.3 Beta-3 and official CVS 1.3! - - * A new shell script is provided, "./cvsinit", which can be run at - install time to help setup your $CVSROOT area. This can greatly - ease your entry into CVS usage. - - * The INSTALL file has been updated to include the machines on - which CVS has compiled successfully. I think CVS 1.3 is finally - portable. Thanks to all the Beta testers! - - * Support for the "editinfo" file was contributed. This file - (located in $CVSROOT/CVSROOT) can be used to specify a special - "editor" to run on a per-directory basis within the repository, - instead of the usual user's editor. As such, it can verify that - the log message entered by the user is of the appropriate form - (contains a bugid and test validation, for example). - - * The manual pages cvs(1) and cvs(5) have been updated. - - * The "mkmodules" command now informs you when your modules file - has duplicate entries. - - * The "add" command now preserves any per-directory sticky tag when - you add a new directory to your checked-out sources. - - * The "admin" command is now a fully recursive interface to the - "rcs" program which operates on your checked-out sources. It no - longer requires you to specify the full path to the RCS file. - - * The per-file sticky tags can now be effectively removed with - "cvs update -A file", even if you had checked out the whole - directory with a per-directory sticky tag. This allows a great - deal of flexibility in managing the revisions that your checked-out - sources are based upon (both per-directory and per-file sticky - tags). - - * The "cvs -n commit" command now works, to show which files are - out-of-date and will cause the real commit to fail, or which files - will fail any pre-commit checks. Also, the "cvs -n import ..." - command will now show you what it would've done without actually - doing it. - - * Doing "cvs commit modules" to checkin the modules file will no - properly run the "mkmodules" program (assuming you have setup your - $CVSROOT/CVSROOT/modules file to do so). - - * The -t option in the modules file (which specifies a program to - run when you do a "cvs rtag" operation on a module) now gets the - symbolic tag as the second argument when invoked. - - * When the source repository is locked by another user, that user's - login name will be displayed as the holder of the lock. - - * Doing "cvs checkout module/file.c" now works even if - module/file.c is in the Attic (has been removed from main-line - development). - - * Doing "cvs commit */Makefile" now works as one would expect. - Rather than trying to commit everything recursively, it will now - commit just the files specified. - - * The "cvs remove" command is now fully recursive. To schedule a - file for removal, all you have to do is "rm file" and "cvs rm". - With no arguments, "cvs rm" will schedule all files that have been - physically removed for removal from the source repository at the - next "cvs commit". - - * The "cvs tag" command now prints "T file" for each file that was - tagged by this invocation and "D file" for each file that had the - tag removed (as with "cvs tag -d"). - - * The -a option has been added to "cvs rtag" to force it to clean - up any old, matching tags for files that have been removed (in the - Attic) that may not have been touched by this tag operation. This - can help keep a consistent view with your tag, even if you re-use - it frequently. - -Sat Feb 29 16:02:05 1992 Brian Berliner (berliner at sun.com) - - * Changes between CVS 1.3 Beta-2 and CVS 1.3 Beta-3 - - * Many portability fixes, thanks to all the Beta testers! With any - luck, this Beta release will compile correctly on most anything. - Hey, what are we without our dreams. - - * CVS finally has support for doing isolated development on a - branch off the current (or previous!) revisions. This is also - extremely nice for generating patches for previously released - software while development is progressing on the next release. - Here's an example of creating a branch to fix a patch with the 2.0 - version of the "foo" module, even though we are already well into - the 3.0 release. Do: - - % cvs rtag -b -rFOO_2_0 FOO_2_0_Patch foo - % cvs checkout -rFOO_2_0_Patch foo - % cd foo - [[ hack away ]] - % cvs commit - - A physical branch will be created in the RCS file only when you - actually commit the change. As such, forking development at some - random point in time is extremely light-weight -- requiring just a - symbolic tag in each file until a commit is done. To fork - development at the currently checked out sources, do: - - % cvs tag -b Personal_Hack - % cvs update -rPersonal_Hack - [[ hack away ]] - % cvs commit - - Now, if you decide you want the changes made in the Personal_Hack - branch to be merged in with other changes made in the main-line - development, you could do: - - % cvs commit # to make Personal_Hack complete - % cvs update -A # to update sources to main-line - % cvs update -jPersonal_Hack # to merge Personal_Hack - - to update your checked-out sources, or: - - % cvs checkout -jPersonal_Hack module - - to checkout a fresh copy. - - To support this notion of forked development, CVS reserves - all even-numbered branches for its own use. In addition, CVS - reserves the ".0" and ".1" branches. So, if you intend to do your - own branches by hand with RCS, you should use odd-numbered branches - starting with ".3", as in "1.1.3", "1.1.5", 1.2.9", .... - - * The "cvs commit" command now supports a fully functional -r - option, allowing you to commit your changes to a specific numeric - revision or symbolic tag with full consistency checks. Numeric - tags are useful for bringing your sources all up to some revision - level: - - % cvs commit -r2.0 - - For symbolic tags, you can only commit to a tag that references a - branch in the RCS file. One created by "cvs rtag -b" or from - "cvs tag -b" is appropriate (see below). - - * Roland Pesch and K. Richard Pixley - were kind enough to contribute two new manual - pages for CVS: cvs(1) and cvs(5). Most of the new CVS 1.3 features - are now documented, with the exception of the new branch support - added to commit/rtag/tag/checkout/update. - - * The -j options of checkout/update have been added. The "cvs join" - command has been removed. - - With one -j option, CVS will merge the changes made between the - resulting revision and the revision that it is based on (e.g., if - the tag refers to a branch, CVS will merge all changes made in - that branch into your working file). - - With two -j options, CVS will merge in the changes between the two - respective revisions. This can be used to "remove" a certain delta - from your working file. E.g., If the file foo.c is based on - revision 1.6 and I want to remove the changes made between 1.3 and - 1.5, I might do: - - % cvs update -j1.5 -j1.3 foo.c # note the order... - - In addition, each -j option can contain on optional date - specification which, when used with branches, can limit the chosen - revision to one within a specific date. An optional date is - specified by adding a colon (:) to the tag, as in: - - -jSymbolic_Tag:Date_Specifier - - An example might be what "cvs import" tells you to do when you have - just imported sources that have conflicts with local changes: - - % cvs checkout -jTAG:yesterday -jTAG module - - which tells CVS to merge in the changes made to the branch - specified by TAG in the last 24 hours. If this is not what is - intended, substitute "yesterday" for whatever format of date that - is appropriate, like: - - % cvs checkout -jTAG:'1 week ago' -jTAG module - - * "cvs diff" now supports the special tags "BASE" and "HEAD". So, - the command: - - % cvs diff -u -rBASE -rHEAD - - will effectively show the changes made by others (in unidiff - format) that will be merged into your working sources with your - next "cvs update" command. "-rBASE" resolves to the revision that - your working file is based on. "-rHEAD" resolves to the current - head of the branch or trunk that you are working on. - - * The -P option of "cvs checkout" now means to Prune empty - directories, as with "update". The default is to not remove empty - directories. However, if you do "checkout" with any -r options, -P - will be implied. I.e., checking out with a tag will cause empty - directories to be pruned automatically. - - * The new file INSTALL describes how to install CVS, including - detailed descriptions of interfaces to "configure". - - * The example loginfo file in examples/loginfo has been updated to - use the perl script included in contrib/log.pl. The nice thing - about this log program is that it records the revision numbers of - your change in the log message. - - Example files for commitinfo and rcsinfo are now included in the - examples directory. - - * All "#if defined(__STDC__) && __STDC__ == 1" lines have been - changed to be "#if __STDC__" to fix some problems with the former. - - * The lib/regex.[ch] files have been updated to the 1.3 release of - the GNU regex package. - - * The ndbm emulation routines included with CVS 1.3 Beta-2 in the - src/ndbm.[ch] files has been moved into the src/myndbm.[ch] files - to avoid any conflict with the system header file. If - you had a previous CVS 1.3 Beta release, you will want to "cvs - remove ndbm.[ch]" form your copy of CVS as well. - - * "cvs add" and "cvs remove" are a bit more verbose, telling you - what to do to add/remove your file permanently. - - * We no longer mess with /dev/tty in "commit" and "add". - - * More things are quiet with the -Q option set. - - * New src/config.h option: If CVS_BADROOT is set, CVS will not - allow people really logged in as "root" to commit changes. - - * "cvs diff" exits with a status of 0 if there were no diffs, 1 if - there were diffs, and 2 if there were errors. - - * "cvs -n diff" is now supported so that you can still run diffs - even while in the middle of committing files. - - * Handling of the CVS/Entries file is now much more robust. - - * The default file ignore list now includes "*.so". - - * "cvs import" did not expand '@' in the log message correctly. It - does now. Also, import now uses the ignore file facility - correctly. - - Import will now tell you whether there were conflicts that need to - be resolved, and how to resolve them. - - * "cvs log" has been changed so that you can "log" things that are - not a part of the current release (in the Attic). - - * If you don't change the editor message on commit, CVS now prompts - you with the choice: - - !)reuse this message unchanged for remaining dirs - - which allows you to tell CVS that you have no intention of changing - the log message for the remainder of the commit. - - * It is no longer necessary to have CVSROOT set if you are using - the -H option to get Usage information on the commands. - - * Command argument changes: - checkout: -P handling changed as described above. - New -j option (up to 2 can be specified) - for doing rcsmerge kind of things on - checkout. - commit: -r option now supports committing to a - numeric or symbolic tags, with some - restrictions. Full consistency checks will - be done. - Added "-f logfile" option, which tells - commit to glean the log message from the - specified file, rather than invoking the - editor. - rtag: Added -b option to create a branch tag, - useful for creating a patch for a previous - release, or for forking development. - tag: Added -b option to create a branch tag, - useful for creating a patch for a previous - release, or for forking development. - update: New -j option (up to 2 can be specified) - for doing rcsmerge kind of things on - update. - -Thu Jan 9 10:51:35 MST 1992 Jeff Polk (polk at BSDI.COM) - - * Changes between CVS 1.3 Beta-1 and CVS 1.3 Beta-2 - - * Thanks to K. Richard Pixley at Cygnus we now have function - prototypes in all the files - - * Some small changes to configure for portability. There have - been other portability problems submitted that have not been fixed - (Brian will be working on those). Additionally all __STDC__ - tests have been modified to check __STDC__ against the constant 1 - (this is what the Second edition of K&R says must be true). - - * Lots of additional error checking for forked processes (run_exec) - (thanks again to K. Richard Pixley) - - * Lots of miscellaneous bug fixes - including but certainly not - limited to: - various commit core dumps - various update core dumps - bogus results from status with numeric sticky tags - commitprog used freed memory - Entries file corruption caused by No_Difference - commit to revision broken (now works if branch exists) - ignore file processing broken for * and ! - ignore processing didn't handle memory reasonably - miscellaneous bugs in the recursion processor - file descriptor leak in ParseInfo - CVSROOT.adm->CVSROOT rename bug - lots of lint fixes - - * Reformatted all the code in src (with GNU indent) and then - went back and fixed prototypes, etc since indent gets confused. The - rationale is that it is better to do it sooner than later and now - everything is consistent and will hopefully stay that way. - The basic options to indent were: "-bad -bbb -bap -cdb -d0 -bl -bli0 - -nce -pcs -cs -cli4 -di1 -nbc -psl -lp -i4 -ip4 -c41" and then - miscellaneous formatting fixes were applied. Note also that the - "-nfc1" or "-nfca" may be appropriate in files where comments have - been carefully formatted (e.g, modules.c). - -Sat Dec 14 20:35:22 1991 Brian Berliner (berliner at sun.com) - - * Changes between CVS 1.2 and CVS 1.3 Beta are described here. - - * Lots of portability work. CVS now uses the GNU "configure" - script to dynamically determine the features provided by your - system. It probably is not foolproof, but it is better than - nothing. Please let me know of any portability problems. Some - file names were changed to fit within 14-characters. - - * CVS has a new RCS parser that is much more flexible and - extensible. It should read all known RCS ",v" format files. - - * Most of the commands now are fully recursive, rather than just - operating on the current directory alone. This includes "commit", - which makes it real easy to do an "atomic" commit of all the - changes made to a CVS hierarchy of sources. Most of the commands - also correctly handle file names that are in directories other than - ".", including absolute path names. Commands now accept the "-R" - option to force recursion on (though it is always the default now) - and the "-l" option to force recursion off, doing just "." and not - any sub-directories. - - * CVS supports many of the features provided with the RCS 5.x - distribution - including the new "-k" keyword expansion options. I - recommend using RCS 5.x (5.6 is the current official RCS version) - and GNU diff 1.15 (or later) distributions with CVS. - - * Checking out files with symbolic tags/dates is now "sticky", in - that CVS remembers the tag/date used for each file (and directory) - and will use that tag/date automatically on the next "update" call. - This stickyness also holds for files checked out with the the new - RCS 5.x "-k" options. - - * The "cvs diff" command now recognizes all of the rcsdiff 5.x - options. Unidiff format is available by installing the GNU - diff 1.15 distribution. - - * The old "CVS.adm" directories created on checkout are now called - "CVS" directories, to look more like "RCS" and "SCCS". Old CVS.adm - directories are automagically converted to CVS directories. The - old "CVSROOT.adm" directory within the source repository is - automagically changed into a "CVSROOT" directory as well. - - * Symbolic links in the source repository are fully supported ONLY - if you use RCS 5.6 or later and (of course) your system supports - symlinks. - - * A history database has been contributed which maintains the - history of certain CVS operations, as well as providing a wide array - of querying options. - - * The "cvs" program has a "-n" option which can be used with the - "update" command to show what would be updated without actually - doing the update, like: "cvs -n update". All usage statements - have been cleaned up and made more verbose. - - * The module database parsing has been rewritten. The new format - is compatible with the old format, but with much more - functionality. It allows modules to be created that grab pieces or - whole directories from various different parts of your source - repository. Module-relative specifications are also correctly - recognized now, like "cvs checkout module/file.c". - - * A configurable template can be specified such that on a "commit", - certain directories can supply a template that the user must fill - before completing the commit operation. - - * A configurable pre-commit checking program can be specified which - will run to verify that a "commit" can happen. This feature can be - used to restrict certain users from changing certain pieces of the - source repository, or denying commits to the entire source - repository. - - * The new "cvs export" command is much like "checkout", but - establishes defaults suitable for exporting code to others (expands - out keywords, forces the use of a symbolic tag, and does not create - "CVS" directories within the checked out sources. - - * The new "cvs import" command replaces the deprecated "checkin" - shell script and is used to import sources into CVS control. It is - also much faster for the first-time import. Some algorithmic - improvements have also been made to reduce the number of - conflicting files on next-time imports. - - * The new "cvs admin" command is basically an interface to the - "rcs" program. (Not yet implemented very well). - - * Signal handling (on systems with BSD or POSIX signals) is much - improved. Interrupting CVS now works with a single interrupt! - - * CVS now invokes RCS commands by direct fork/exec rather than - calling system(3). This improves performance by removing a call to - the shell to parse the arguments. - - * Support for the .cvsignore file has been contributed. CVS will - now show "unknown" files as "? filename" as the result of an "update" - command. The .cvsignore file can be used to add files to the - current list of ignored files so that they won't show up as unknown. - - * Command argument changes: - cvs: Added -l to turn off history logging. - Added -n to show what would be done without actually - doing anything. - Added -q/-Q for quiet and really quiet settings. - Added -t to show debugging trace. - add: Added -k to allow RCS 5.x -k options to be specified. - admin: New command; an interface to rcs(1). - checkout: Added -A to reset sticky tags/date/options. - Added -N to not shorten module paths. - Added -R option to force recursion. - Changed -p (prune empty directories) to -P option. - Changed -f option; forcing tags match is now default. - Added -p option to checkout module to standard output. - Added -s option to cat the modules db with status. - Added -d option to checkout in the specified directory. - Added -k option to use RCS 5.x -k support. - commit: Removed -a option; use -l instead. - Removed -f option. - Added -l option to disable recursion. - Added -R option to force recursion. - If no files specified, commit is recursive. - diff: Now recognizes all RCS 5.x rcsdiff options. - Added -l option to disable recursion. - Added -R option to force recursion. - history: New command; displays info about CVS usage. - import: Replaces "checkin" shell script; imports sources - under CVS control. Ignores files on the ignore - list (see -I option or .cvsignore description above). - export: New command; like "checkout", but w/special options - turned on by default to facilitate exporting sources. - join: Added -B option to join from base of the branch; - join now defaults to only joining with the top two - revisions on the branch. - Added -k option for RCS 5.x -k support. - log: Supports all RCS 5.x options. - Added -l option to disable recursion. - Added -R option to force recursion. - patch: Changed -f option; forcing tags match is now default. - Added -c option to force context-style diffs. - Added -u option to support unidiff-style diffs. - Added -V option to support RCS specific-version - keyword expansion formats. - Added -R option to force recursion. - remove: No option changes. It's a bit more verbose. - rtag: Equivalent to the old "cvs tag" command. - No option changes. It's a lot faster for re-tag. - status: New output formats with more information. - Added -l option to disable recursion. - Added -R option to force recursion. - Added -v option to show symbolic tags for files. - tag: Functionality changed to tag checked out files - rather than modules; use "rtag" command to get the - old "cvs tag" behaviour. - update: Added -A to reset sticky tags/date/options. - Changed -p (prune empty directories) to -P option. - Changed -f option; forcing tags match is now default. - Added -p option to checkout module to standard output. - Added -I option to add files to the ignore list. - Added -R option to force recursion. - - Major Contributors: - - * Jeff Polk rewrote most of the grody code of CVS - 1.2. He made just about everything dynamic (by using malloc), - added a generic hashed list manager, re-wrote the modules database - parsing in a compatible - but extended way, generalized directory - hierarchy recursion for virtually all the commands (including - commit!), generalized the loginfo file to be used for pre-commit - checks and commit templates, wrote a new and flexible RCS parser, - fixed an uncountable number of bugs, and helped in the design of - future CVS features. If there's anything gross left in CVS, it's - probably my fault! - - * David G. Grubbs contributed the CVS "history" and - "release" commands. As well as the ever-so-useful "-n" option of - CVS which tells CVS to show what it would do, without actually - doing it. He also contributed support for the .cvsignore file. - - * Paul Sander, HaL Computer Systems, Inc. wrote and - contributed the code in lib/sighandle.c. I added support for - POSIX, BSD, and non-POSIX/non-BSD systems. - - * Free Software Foundation contributed the "configure" script and - other compatibility support in the "lib" directory, which will help - make CVS much more portable. - - * Many others have contributed bug reports and enhancement requests. - Some have even submitted actual code which I have not had time yet - to integrate into CVS. Maybe for the next release. - - * Thanks to you all! - -Wed Feb 6 10:10:58 1991 Brian Berliner (berliner at sun.com) - - * Changes from CVS 1.0 Patchlevel 1 to CVS 1.0 Patchlevel 2; also - known as "Changes from CVS 1.1 to CVS 1.2". - - * Major new support with this release is the ability to use the - recently-posted RCS 5.5 distribution with CVS 1.2. See below for - other assorted bug-fixes that have been thrown in. - - * ChangeLog (new): Added Emacs-style change-log file to CVS 1.2 - release. Chronological description of changes between release. - - * README: Small fixes to installation instructions. My email - address is now "berliner@sun.com". - - * src/Makefile: Removed "rcstime.h". Removed "depend" rule. - - * src/partime.c: Updated to RCS 5.5 version with hooks for CVS. - * src/maketime.c: Updated to RCS 5.5 version with hooks for CVS. - * src/rcstime.h: Removed from the CVS 1.2 distribution. - Thanks to Paul Eggert for these changes. - - * src/checkin.csh: Support for RCS 5.5 parsing. - Thanks to Paul Eggert for this change. - - * src/collect_sets.c (Collect_Sets): Be quieter if "-f" option is - specified. When checking out files on-top-of other files that CVS - doesn't know about, run a diff in the hopes that they are really - the same file before aborting. - - * src/commit.c (branch_number): Fix for RCS 5.5 parsing. - Thanks to Paul Eggert for this change. - - * src/commit.c (do_editor): Bug fix - fprintf missing argument - which sometimes caused core dumps. - - * src/modules.c (process_module): Properly NULL-terminate - update_dir[] in all cases. - - * src/no_difference.c (No_Difference): The wrong RCS revision was - being registered in certain (strange) cases. - - * src/patch.c (get_rcsdate): New algorithm. No need to call - maketime() any longer. - Thanks to Paul Eggert for this change. - - * src/patchlevel.h: Increased patch level to "2". - - * src/subr.c (isdir, islink): Changed to compare stat mode bits - correctly. - - * src/tag.c (tag_file): Added support for following symbolic links - that are in the master source repository when tagging. Made tag - somewhat quieter in certain cases. - - * src/update.c (update_process_lists): Unlink the user's file if it - was put on the Wlist, meaning that the user's file is not modified - and its RCS file has been removed by someone else. - - * src/update.c (update): Support for "cvs update dir" to correctly - just update the argument directory "dir". - - * src/cvs.h: Fixes for RCS 5.5 parsing. - * src/version_number.c (Version_Number): Fixes for parsing RCS 5.5 - and older RCS-format files. - Thanks to Paul Eggert for these changes. - - * src/version_number.c (Version_Number): Bug fixes for "-f" option. - Bug fixes for parsing with certain branch numbers. RCS - revision/symbol parsing is much more solid now. - -Wed Feb 14 10:01:33 1990 Brian Berliner (berliner at sun.com) - - * Changes from CVS 1.0 Patchlevel 0 to CVS 1.0 Patchlevel 1; also - known as "Changes from CVS 1.0 to CVS 1.1". - - * src/patch.c (get_rcsdate): Portability fix. Replaced call to - timelocal() with call to maketime(). - -Mon Nov 19 23:15:11 1990 Brian Berliner (berliner at prisma.com) - - * Sent CVS 1.0 release to comp.sources.unix moderator and FSF. - - * Special thanks to Dick Grune for his work on the - 1986 version of CVS and making it available to the world. Dick's - version is available on uunet.uu.net in the - comp.sources.unix/volume6/cvs directory. - -@(#)ChangeLog 1.17 92/04/10 diff --git a/contrib/cvs/DEVEL-CVS b/contrib/cvs/DEVEL-CVS deleted file mode 100644 index 3344bd1..0000000 --- a/contrib/cvs/DEVEL-CVS +++ /dev/null @@ -1,30 +0,0 @@ - CVS Development Policies - -This file, DEVEL-CVS, contains the policies by which the CVS -development group operates. Also see the HACKING file. - ----------------------------------------------------------------------- -Policies regarding the CVS source repository: - -By checking items into the repository, developers agree to permit -distribution of such items under the terms of the GNU Public License. - ----------------------------------------------------------------------- -Procedure for dealing with people who want to be developers: - -People who want checkin access are first requested to send -patches and have them reviewed by a developer. If they submit some -good ones (preferably over a period of time, to demonstrate sustained -interest), then one of the developers can ask the devel-cvs mailing -list whether it is OK to make this person a developer (after first -sending the prospective developer a copy of this file and then having -the prospective developer say they want to be a developer). If there -are no objections, the person will be made a developer. - ----------------------------------------------------------------------- -Policy regarding checkout-only access: - -Checkout-only access to the CVS repository is available to all, on an -anonymous basis (no need for registration or other complications). -The exact technical mechanisms by which it is available are not -covered by this policy. diff --git a/contrib/cvs/FAQ b/contrib/cvs/FAQ deleted file mode 100644 index 13feb52..0000000 --- a/contrib/cvs/FAQ +++ /dev/null @@ -1,8562 +0,0 @@ -------------------------------------------------------------------------------- - - CVS is Copyright (C) 1986-2006 The Free Software Foundation, Inc. - - CVS is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 1, or (at your option) - any later version. - - More details are available in the COPYING file but, in simplified - terms, this means that any distributed modifications you make to - this software must also be released under the GNU General Public - License. - - CVS 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. - -------------------------------------------------------------------------------- - -This file contains a CVS FAQ. Until 1995 it was maintained by David -Grubbs. It was out of date and not being maintained, but it had a -certain following and in 1997 Pascal Molli decided to start -maintaining it with the FAQ-O-Matic package which allows any -contributor with a web browser to help maintain it. The following -text is (mostly automatically) extracted from the FAQ-O-Matic. The -odds are good that the file that you are currently reading is out of -date with respect to the online FAQ-O-Matic, which is part of Pascal -Molli's CVS web site at http://www.loria.fr/~molli/cvs-index.html -(currently under "Documentation"). The online version is also -somewhat better in terms of things like tables of contents (at least -until someone can write some code to extract data from a FAQ-O-Matic -and insert things like tables of contents). - -The answers which are dated "6/13/1997" below are really from the 1995 -FAQ, for the most part. Many of them are out of date. The current FAQ may -be found at . If you have -some time, you are encouraged to export that FAQ as text and import it here. -If you don't have such time, take the answers in this file with at least a few -grains of salt. - -Since August, 2005, many of the existing CVS resources have been centralized on - & . - - Category: /, all questions - - Category: / - - " [INLINE] " - - 1. About FAQ-O-Matic - -This is FAQ-O-Matic, a quick-and-dirty Perl hack (aren't they all?) by -Jon Howell. - -It seems like most FAQ maintainers make a valiant initial effort, then get -a life and don't have time to keep their FAQs up to date. Also, I often -find out a solution to a problem, and feel like I could write a single -FAQ answer on it in a few minutes, but where to post it? - -Thus the FAQ-O-Matic was born. FAQ-O-Matic is a couple sleazy Perl scripts -that allow people to submit FAQ answers to this database, so it can stay -current, with just a tiny bit of work on any one person's part. - -Yes, a bad guy could come along and wipe out all the FAQ entries. Please don't. -But to give the good guys some measure of comfort, each submission is stored -in an RCS file, so if someone does tamper, we can recover the database. - -Guidelines for submissions: - -1. Please _try to be fairly unbiased in matters of opinion._ Mailing lists are -the place to start flame wars (just kidding :v), but definitely not here. - -2. Please _use HTML only conservatively_ in your entries. Links are appropriate -, -but put the URL in the plaintext also so it's useable on printed versions of -the FAQ. Inline images pointing off this site are inappropriate, as is much -fancy formatting. This is meant to be bandwidth-light and dumb-browser-friendly -. - -3. If you feel there's a place for a _new category, or a reorganization of -existing questions_, don't hesitate to mail me (molli@loria.fr). -Category changes need to be done from my end. - -4. Please _leave an email address_ at the bottom of your submission so that oth -ers -can drop you a note. - -5. _If you only have a question_, not an answer, you should probably post -it to a mailing list, not here. If there are frequently asked questions to whic -h -the answer is not forthcoming on mailing lists (or perhaps there's no -useful answer yet other than "no one knows"), then it's appropriate to -post here, in hopes that someone will see it and know the answer. - -6. Please refrain from crude or inconsiderate language. Please don't use -this as a forum for advertising. However, mention of worthy commercial -products is certainly appropriate (even if you sell said product). Just -don't overdo it. :v) - - Last modified: _6/13/1997_ - - 2. Adding a new category ? - -just send me a mail at -molli@loria.fr - - Last modified: _6/13/1997_ - - Category: /Advanced_Topics_/ - - " Advanced Topics " - - Category: /Advanced_Topics_/Branching_and_Mergin/ - - " + Branching and Merging" - - 1. What is a branch? - - Unfortunately, the word "branch" is an overloaded technical - term. It is used in too many different ways in three - categories. It might help to understand some of the issues by - going through the categories: - - How Humans use the word "branch": - - Most development starts with everyone working on the same - software, making changes and heading toward a single goal. This - is called something like "Main Line Development". Note that - though many people do main line development on CVS's "Main - Branch", that is a choice, not a requirement. - - After a release or when one or more developers want to go off - and work on some project for a while, the Software Engineers - assigned to deal with large software issues generate a "Branch - in Development" to support the release or project. (Keep in - mind that a programmer is no more a Software Engineer than a - carpenter is a Civil Engineer.) - - Essentially, the word "branch" implies a way to allow - simultaneous development on the same files by multiple people. - - The above terms are human-oriented. They refer to actions that - people would like to take. They do *not* imply any particular - implementation or set of procedures. Branches in development - can be supported in many different ways. - - How CVS uses the word "branch": - - CVS uses the word "branch" in a number of ways. The two most - important are: - - - The vendor branch holds releases from (normally) an outside - software vendor. It is implemented using a specific RCS branch - (i.e. 1.1.1). - - - The "Main Branch", which normally holds your "Main Line - Development", but is defined as the collection of revisions you - get when you "checkout" something fresh, or when you use the - '-A' option to "update". - - Important Note: The CVS "Main Branch" is *not* the same as the - RCS concept with the same name. If you are using Vendor - Branches, files you have never changed are on three branches at - the same time: - - - The RCS 1.1.1 branch. - - The CVS Vendor branch. - - The CVS "Main Branch". - - The concepts overlap, but they are not equivalent. - - In referring to CVS, "branch" can be used in four other ways: - - - A CVS working directory satisfies the definition of "branch" - for a single developer -- you are on a private "virtual branch" - that does not appear in any of the RCS files or the CVS control - files. - - - The CVS "default branch" is the Repository source for the - collection of files in your working directory. It is *not* the - same as the RCS "default branch". Normally the CVS default - branch is the same as the CVS Main branch. If you use the "-r - " option to the "checkout" command, you will record - a "sticky" tag that changes your default branch to the one you - checked out. - - - A "magic" branch can be a branch that hasn't happened yet. It - is implemented by a special tag you can check out that is not - attached to a real RCS branch. When you commit a file to a - magic branch, the branch becomes real (i.e. a physical RCS - branch). - - - And, of course, CVS uses "branch" to indicate a - human-oriented "branch in development". - - How RCS uses the word "branch": - - - The RCS "Main Branch" (Synonym: "The Trunk") contains a - series of two-part revision numbers separated by a single '.' - (e.g. 1.2). It is treated specially and is the initial default - branch. (The default default?) - - - The RCS "Default" branch starts out attached to the RCS "Main - Branch". For RCS purposes, it can be changed to point to any - branch. Within CVS, you *must*not* alter the RCS default - branch. It is used to support the CVS idea of a "Main Branch" - and it must either point to the RCS Main Branch, or the Vendor - Branch (1.1.1) if you haven't made any changes to the file - since you executed "import". - - Last modified: _6/13/1997_ - - 2. Why (or when) would I want to create a branch? - - Remember that you can think of your working directory as a "branch for - one". You can consider yourself to be on a branch all the time because - you can work without interfering with others until your project (big - or small) is done. - - The four major situations when you should create a branch: - - When you expect to take a long time or make a large set of changes - that the merging process will be difficult. Both "long" and "large" - are defined in your own environment. - - When you want to be able to "commit" and "tag" your work repeatedly - without affecting others. - - If you ever think you need Source Control for your own work, but don't - want your changes to affect others, create a private branch. (Put your - username in the branch tag, to make it obvious that it is private.) - - When you need to share code among a group of developers, but not the - whole development organization working on the files. - - Rather than trying to share a working directory, you can move onto a - branch and share your work with others by "committing" your work onto - the branch. Developers not working on the branch won't see your work - unless they switch to your branch or explicitly merge your branch into - theirs. - - When you need to make minor changes to a released system. - - Normally a "release" is labeled by a branch tag, allowing later work - on the released files. If the release is labeled by a non-branch tag, - it is easy to add a branch tag to a previously tagged module with the - "rtag" command. If the release is not tagged, you made a mistake. - Recovery requires identifying all revisions involved in the release - and adding a tag to them. - - Last modified: _6/13/1997_ - - 3. How do I create and checkout a branch? - - Suggested technique: - - Attach a non-branch tag to all the revisions you want to branch - from. (i.e. the branch point revisions) - - When you decide you really need a branch, attach a branch tag to the - same revisions marked by the non-branch tag. - - "Checkout" or "update" your working directory onto the branch. - - Suggested procedure when using modules: - - cvs rtag module - - cvs rtag -b -r - - cvs checkout -r module - - Suggested procedure when using your working directory, which - contains the revisions of your working files you want to branch from: - - cvs tag - - cvs rtag -b -r - - cvs update -r - - In each procedure above, Step #1 applies a non-branch tag to all the - branch point revisions in the module/directory. Though this is not - strictly necessary, if you don't add a non-branch tag to the revisions - you branch from, you won't be able to refer to the branch point in the - future. - - Between steps 1 & 2 you may commit changes. The result would be same - because "rtag -r " applies to the same - revision that is attached to. You can use this technique to - avoid attaching *any* branch tags until you need them. - - Step B.2 has two corollaries: - - If you plan to create the branch tag before committing anything in - your working directory, you can use "cvs tag -b " instead - of the "rtag" command. - - The can be a relative path to a directory from which your - working directory was checked out. - - If you have trouble figuring out what to use (or pathname to - use in its place), you can aim it at whatever parent directories you - believe will cover all your work. - - If you are sure the is not being used anywhere else, you - can even aim it at the whole Repository ($CVSROOT), if you have to. It - might take some extra time, but assuming that your is a unique - string and you don't use the '-f' option to "rtag -r", "rtag" will - only add a to files in which it actually *finds* the earlier - . - - In each procedure above, Step #3 may occur any time after step 2. - Unless you explicitly remove them with "tag -d", a is permanent. - - The is an unusual creature. It labels a branch in a way - that allows you to "checkout" the branch, to "commit" files to the end - of the branch and to refer to the end of the branch. It does not label - the base of the branch (the branch point). - - There are two obvious ways to choose the and - names. But keep in mind that the is typed by - any developer who wants to work on the branch -- you should make it - mean something to them. - - Style #1 presumes that the simple version string refers to a set of - designed, documented or promised features, not to a specific set of - files. In this case, you tag the branch with the generic Version - string and assume that whenever you refer to "Version", you want the - "latest" set of files associated with that Version, including all - patches. (You can substitute whatever you like for "bp_", as long as - your is some modification of the .) - - Matching - - bp_V1_3 V1_3 - bp_Release2-3-5 Release2-3-5 - bp_Production4_5 Release4_5 - - Style #2 presumes that the simple version string refers to the - specific set of files used to construct the first release of - "version". In this case, you tag the branch-point revisions with the - generic Version string and assume that whenever you refer to this - Version, you want the original set of released revisions. To get the - latest patched revisions of the release, you refer to the branch tag - "latest_". (You can substitute what ever you like - for "latest_", as long as your is some modification of - the .) - - Matching - - V1_3 latest_V1_3 - Release2-3-5 latest_Release2-3-5 - Release4_5 latest_Production4_5 - - In both styles you can find out what you had to change since the - original release of this Version by typing: - - cvs diff -r -r - - For Style 1, this is: - - cvs diff -r bp_ -r - - For Style 2, this is: - - cvs diff -r -r latest_ - - Notes on "being on a branch": - - - "update -r " tells CVS to attach a "sticky tag" to working - directory (in ./CVS/Tag) and the checked-out files (on each line of - ./CVS/Entries). - - - A "sticky" (including a ) causes most CVS commands - to act as if "-r " were on the command line. - - - A "sticky" indicates that the working directory (and - working files) are "on the branch". - - Last modified: _6/13/1997_ - - 4. Once created, how do I manage a branch? - - The most important thing you should know about managing a branch is - that the creation of a branch is not a lightweight act. When you - create a branch, you must also create a set of procedures to keep - track of it. - - Specifically, you must: - - - Remember that the branch exists. (This is non-trivial if you create - a lot of them.) - - - Plan when to merge it back into the main line of development. - - - Schedule the order that multiple branch merges are to be done. - - - If you ever intend to merge branches into each other, instead of - limiting merges of branch work back into the "main line", you must - keep careful track of which parts of which branches have merged into - which other branches. - - The simplest way to deal with branches is to limit their number, - "collapse" them back into the main line as quickly as is reasonable - and forget them. If a group wants to continue working, tell them to - create another branch off the fully merged main line. - - Remember that CVS is just a tool. Over time, it will probably handle - branching better, requiring less careful attendance. But no matter how - good it becomes, the whole idea of "branching" is a complicated - management problem. Don't take it lightly. - - Last modified: _6/13/1997_ - - 5. Are there any extra issues in managing multiple branches? - - If you plan to split from the "main line" and merge back after a time, - the only problem will be scheduling the order of branch merges. As - each branch is merged, the main line must be rebuilt and tested. - Merging multiple branches (i.e. "lines of development") before - building and testing creates more problems than you are ready for. - - If you plan to collapse some branches into others, then move the - combined branches back into the main line, you have to be careful with - the revisions and tags you hand to your "update -j" command, but it - shouldn't be much trouble. - - If you plan to allow every branch to incrementally take the work done - on other branches, you are creating an almost insurmountable - bookkeeping problem. Every developer will say "Hey, I can handle - taking just this little bit," but for the system as a whole it is - disaster. Try it once and see. If you are forced into this situation, - you will need to keep track of the beginning and end points of every - merge ever done. Good Luck. - - Last modified: _6/13/1997_ - - 6. How do I merge a whole branch back into the trunk? - - If you don't have a working directory, you can checkout and merge in - one command: - - cvs checkout -j - cd - - If you already have a working directory: - - cd - cvs update <== Optional, to bring it up to date. - cvs update -j - - CVS will print lines beginning with - - 'U' for files that you hadn't changed, but the branch did. - - 'M' for files that you changed and the branch didn't - *and* for files that you both changed that were merged - without overlaps. (This overload is unfortunate.) - - 'C' for files that you both changed in a way that conflicts - with each other. - - You need to go edit all the 'C' files and clean up the conflicts. Then - you must commit them. - - Last modified: _6/13/1997_ - - 7. How do I merge changes from the trunk into my branch or between - branches? - - The idea is similar to the above, but since CVS doesn't treat the main - branch like other branches, you'll have to be more careful. There are - 5 different ways to look at the problem. - - The way to merge *all* changes made on the trunk into a working - branch is to move to the branch you want via "checkout -r" or "update - -r": - - cvs update -r {optional files} - - Then merge the changes from the trunk into your working branch using - the pseudo-tag named "HEAD": - - cvs up -j HEAD {optional files} - - You will get everything from the branch point of the branch named - up to the HEAD of the main branch. This is still kind of - strange. If the file is on a branch, HEAD should be the latest thing - on the branch, not the HEAD of MAIN. But that's not the way CVS - (currently) works. - - If you run "cvs up -j HEAD" again after adding more revisions to the - trunk, you may get overlaps for the text you have already merged. It - depends on your version of your RCS "merge" command (actually the "co - -j" option, which depends on the version of "diff3" you configured RCS - to use). - - You can merge the difference between any two using two "-j" - options on "update" or "checkout". - - Identify the two tags on the branch you want to merge from. - - cvs update -j -j {optional files} - - This step assumes you were careful about tagging milestones. You can - use this technique for any two on the same branch, even the - trunk. It is also possible to use tags on different branches, but - you'll have to ponder the meaning of the difference between those two - tags. - - In place of one of the , you can use a to refer to - the latest revision on that branch. See 4C.11 and 4C.3 for info on - branch points. - - Merges can also be performed by handing RCS revisions to the '-j' - options, but since revision numbers aren't the same in all files, - merging by number is normally limited to one file. Sets of files with - the exact same trees of branches and revision numbers would work too, - but that's a rare situation. - - To "take" revisions from other branches instead of merging them, see - 4C.19 for an idea. - - A way to gain the effect of merging the main to the branch is to - merge the branch into the main using the normal - - cvs update -A {optional files} - cvs update -j {optional files} - cvs commit - cvs tag -F -b {optional files} - - See part B of 4D.5 - - Other oddities. - - This also works, but is probably not officially supported: - - cvs update -j N {optional files} - - where N is a number. This will merge all the changes from the branch - point up to the highest revision on the main branch starting with N. - For example, if your highest trunk revision is 1.52, you can use this - to grab revisions from the trunk: - - cvs update -j 1 {optional files} - - Another example: Say you have a branch point at rev 1.2 for a branch - named "BR1" and trunk revisions 1.3, 1.4, 2.1, 2.2, 2.3, 3.1, 3.2. - Then: - - cvs update -j 1 {optional files} - - will merge the changes from 1.2 to 1.4 - - cvs update -j 2 {optional files} - - will merge the changes from 1.2 to 2.3 - - cvs update -j 3 {optional files} - - will merge the changes from 1.2 to 3.2, which in this example, is - equivalent to the use of "-j HEAD" in part A above. - - The intuitive (at least to me): - - cvs up -j MAIN (or TRUNK) {optional files} - - doesn't work. If the trunk (i.e. "main branch") had an implicit branch - named "MAIN", you could use: - - cvs up -j MAIN:10/26 -j MAIN:now {optional files} - - and refer to date-stamped revisions on the trunk using the - : support that works on other branches. - - You might also think you could place an explicit tag on branch 1 (or - higher) (e.g. MAINHACK:1) and use it in place of the implicit "MAIN", - but I haven't found the right combination. - - [[If you find working techniques, I'll add them here.]] - - Last modified: _6/13/1997_ - - 8. How do I merge onto the Main Branch a file that exists only on a branch - other than the Main Branch? (i.e. it is in the Attic) - - For how such a file can exist, see 3A.2 and 3A.3. - - For how to avoid creating such a file, see 3A.5. - - Though you might think that the "update -j" command could perform the - "merge" of a file from the side branch to the Main Branch, it isn't - (yet) smart enough. Unfortunately, there is no single CVS command to - do this -- it takes three steps: - - To move something onto the Main Branch from the Attic, you have to - physically move the file from the Attic to the main Repository - directory associated with your working directory. - - It is exactly like resurrecting a removed file. See 3L.4 - - I use something like this: (csh-like syntax) - - set repos = `cat ./CVS/Repository` mv $repos/Attic/filename,v - $repos/filename,v - - (If you use relative paths in your Repository files, that first line - becomes: set repos = $CVSROOT/`cat ./CVS/Repository`) - - Now that the file is physically in the right place within the - Repository, "update -A" will make it appear in your working directory - on the Main Branch. Do that now. - - You now have a choice. The act of physically moving the file has - fused together the branch and the Main Branch for this - file. You can continue that way, making changes along the RCS Main - Branch which CVS will (for this type of file only) treat as both the - Main Branch and the branch. - - The other choice, which I would suggest, is to re-tag the file with - , restoring a normal-looking magic branch tag to the file: - - cvs tag -F -b - - After you have done the above, you can run "update -A" or "update -r - " to resume whatever you were doing before you started - this procedure. - - Caveat: The final result is a file whose revision tree doesn't look - like it was ever on any branch but the Main Branch until the above - "tag -F -b" command was executed. CVS and RCS have no way of saving - the history of the actions you have just performed. - - Last modified: _6/13/1997_ - - 9. How do I know what branch I'm (working) on? - - Type: - cvs status - - and look at the "Sticky Tag" field for each file. If: - - The *same* tag is on *every* file in your working tree, *and* - - That tag matches the contents of the ./CVS/Tag file, *and* - - That tag is a branch tag, - - then you know what branch you are working on. You can get sticky Tag - information directly from the ./CVS/Entries file instead of "cvs - status". - - If all the sticky Tags don't agree, then your directory is temporarily - inconsistent. This is a feature allowing you to make changes (or - perform merges) to individual files on multiple branches without - checking out the whole directory. - - The sticky Tag on each file in the ./CVS/Entries file (as displayed by - the "status" command) indicates what branch the working file is on. - New files are added to the Tag stored in ./CVS/Tag. - - To force your entire working directory onto the same branch, type: - - cvs update -r - - Last modified: _6/13/1997_ - - 10. Do I really have to know the name of the branch I'm working on? - - If a developer can't be relied on to know what branch of development - to work on, then either the developer's manager isn't planning - branches properly or the developer has serious problems. - - I have found that one of the hardest concepts to get across to - developers (and some managers) is that "a branch in development" (as - opposed to the use of RCS branches to support some other scheme) is a - heavyweight act. Every time you create a real branch in development, - you must spawn a set of managerial procedures and a schedule by which - you plan to merge each branch into each other branch. Unless you plan - to keep it simple and collapse (by merging and forgetting) branches - quickly, they are not to be created lightly. - - In other words, if you don't regularly attend group meetings in which - the branch to be worked on is a major topic of discussion, then the - group is not managing branches properly. - - We created a couple major branches a few months ago and even the - customer service people refer to the "XYZ branch" as a shorthand for - "continuing development on the XYZ project". - - Last modified: _6/13/1997_ - - 11. How do I refer to the revision where I branched so I can see what - changed since the Branch Point on another branch? - - Given the current format, there is no direct way to refer - to the branch point, which is more useful in many ways than referring - to the branch, which always refers to the latest revision on the - branch. - - When CVS adds a branch tag, it attaches an RCS symbol to a - non-existent revision number containing the revision number of the - branch point as a prefix. (See Section 3O, on the "tag" command.) RCS - can't use the CVS magic branch tag and many of the CVS commands can't - refer to it. - - To be certain of your ability to refer to a branch point, you must - create a "branch point" tag at the same time as the Branch tag. See - 4C.3. - - Last modified: _6/13/1997_ - - 12. Why didn't the command "cvs admin -bBRANCH1 *" create a branch? - - Because your command creates an RCS branch, not a CVS branch. See the - above discussion on branches. RCS branches are used to support CVS - branches, but they are not the same. You can't act as if you have - direct control over the RCS files. - - The "admin" command was placed there as a convenience to allow you to - execute raw "rcs" commands on the Repository, taking advantage of - CVS's ability to find the files in the Repository. - - But you have to remember that you are using RCS commands on a CVS - Repository, which is not generally safe unless you know exactly what - CVS depends on. - - For one thing, CVS insists on control of the default branch. It is set - either to the Main branch or the Vendor branch depending on whether - you have changed the Vendor's code. If you change the default branch, - you are monkeying with the internals and you will get unexpected - results. - - To set your "default CVS branch" to BRANCH1, you must use "checkout" - or "update" with the "-r BRANCH1" option. Then you have changed CVS's - idea of your "default branch", which has little to do with RCS's - default branch. - - Last modified: _6/13/1997_ - - 13. Is it possible to set the "default CVS branch" for everyone? - - No. It doesn't work that way. - - When using CVS, all administrative information (such as what branch - you checked out) is stored in CVS sub-directories, local to the user. - There is no global state, other than the description and logging files - in the $CVSROOT/CVSROOT directory. - - You tell "checkout" or "update" what branch you want to check out via - the "-r " option. The default is CVS's "Main Branch". - - I don't see a problem in *designing* a new way to indicate what branch - you get by default, instead of the main one, but that's not how it - currently works. - - Last modified: _6/13/1997_ - - 14. How do I perform a large merge? - - Large merges require a bit more planning to be able to track what has - happened in the inevitable cases where something goes wrong. No tool - can force a "merge" to make perfect sense. - - Though you can handle the details in many different ways, the two ends - of the spectrum of merge techniques are: gonzo and paranoid. - - The gonzo method assumes that you know everything about your sources - so that recovery from failures is "just a matter of typing." You - created the branch this way: - - cvs checkout - cd - cvs tag -b - cvs update -r - >>> Edit away. - cvs commit <<== Onto branch - - Now you want to merge your branch back into the Main branch, you are - certain you can make it work, or at least detect all the failures, so - you dive in and hack away: (For simplicity, we will assume you are - collapsing (i.e. merging and forgetting) a side-branch into the Main - branch from your single working directory.) - - cvs update -A - cvs update -j - >>> Edit the 'C' files and remove the overlaps. - >>> Edit some more to make it all compile and work. - cvs commit - - Looks simple. For more details on the output from the "update -j" - command, see 3P.2 and 4C.6. - - Note: You could also checkout a whole new working directory and - perform the merge at the same time by replacing the two - update commands with these two commands: - - cvs checkout -j - cd - - The paranoid way is more difficult, but it can catch all sorts of - problems. You created the branch this way: - - cvs checkout - cd - cvs tag - cvs tag -b - cvs update -r - >>> Edit away. - cvs commit <<== Onto branch - - The extra tag command places a non-branch tag on the Branch Point, an - act that makes it easier to do "diffs" later. Now we decide to perform - the merge: - - cvs tag - cvs update -A - *1* cvs diff -r -r - >>> *1* shows all the changes on the branch. - *2* cvs diff -r -r HEAD - >>> *2* shows the changes on the trunk since branching. - cvs tag - cvs update -j - >>> Edit the 'C' files and remove the overlaps. - *3* cvs diff - >>> Verify that *3* matches *1*, except for line numbers. - cvs commit - cvs tag - >>> Edit some more to make it all compile and work. - cvs commit - cvs tag - - The reason *3* and *1* match so closely is that they are the - differences between two pairs of starting points and ending points - after the same data was inserted. If they are significantly different, - you will want to figure out why. - - NOTE: You will have to tell everyone to stay the hell out of the - Repository while you do this. If they commit something while you are - in the middle of a merge, your job will be much more difficult. If - they "update" at the wrong time, their work will be randomized until - you finish. It's better to call a halt. - - See 3H.13 for some more information about dealing with merges after - import. The last part of the procedure is applicable to any large - merge. - - Last modified: _6/13/1997_ - - 15. Is a Vendor merge any different from a branch merge? - - No. In most ways, a Vendor branch is exactly the same as any other - branch. In a Vendor merge, the data is append to the branch by the - "import" command, rather than by hand-editing, but the merge process - is the same. - - See the "import" command in section 3H. - - Last modified: _6/13/1997_ - - 16. How do I go back to a previous version of the code on a branch? - - - - - You can avoid digging into RCS revision numbers (executing "update - -r (rev)" on each file) by trying one of these: - -Use non-branch tags as you normally would. Non-branch tags - attach to specific revisions, so a "tag (tag)" command would - mark the revisions you have in your working directory, which - are on your branch. If you need to retrieve them, use "update - -r (non-branch-tag)" - - Doing this overrides the sticky (branch-tag) attached to your - working directory with a non-branch tag, which means you won't - be able to commit until you again move forward to the end of - the branch with "update -r (branch-tag)". - -Use the "update -r (branch-tag):(date)" trick. - - This is almost like using the '-D' option, but it looks for - revisions extant on (date) only along the given branch. - - As in #1, you can't commit to this kind of working area, - because it has a sticky date referring to revisions in the - middle of a branch. - -[comment from the audience: You are dreaming.. -this does not work.. try it, you get -No such tag: "MYTAG:May 1" -or similar. I wish it did because I need it. julian@whistle.com] - - -You can branch a branch. - - If you add a branch tag to file in a working directory that was - checked out on a branch, you will branch the branch. This - works just fine, though you'll have to play some games to merge - everything back together again. You'll also create 6-part - revision numbers. (They'll be 8-part revision numbers if you - branch a branch that started out with some unmodified files on - the Vendor branch. Think about it. How does revision - 1.2.4.2.4.2.2.1 grab you?) - - -(fixed formatting, kingdon@cyclic.com) - - Last modified: _9/8/1997_ - - 17. Once I've found the files I want, how do I start changing them? I keep - getting warnings about sticky tags. - - What you probably did was type "cvs update -r " where is a - non-branch tag. "update" created a sticky tag for a specific revision, - not a branch. To start working right there, you have to create a - branch to work on. - - You have two choices. - - You can do it in place and keep working: - - cvs tag -b <<== To tag the current files. - cvs update -r <<== To move onto the branch. - - You can do it "externally" and create a new working directory: - - cvs rtag -b -r - cvs checkout -r - - can be a relative path within the Repository. - - in the above is the non-branch tag you placed earlier - that caused the error in your question. Be warned that - if is not set on all the files (or all the right - revisions) you won't get exactly what you wanted. - - Last modified: _6/13/1997_ - - 18. Why do I get the latest files on the branch when I tried to "update -r - "? - - If "update -r " always retrieves the latest files on a branch, - then is really a . A branch tag is supposed to be - used to grab a branch to work on. Since you can't modify a file in the - middle of a branch, checking out a will give you the - latest revision on the branch. - - If you want to "checkout" a specific collection of revisions, you must - use a "non-branch" tag. See the first part of 4C.16. - - Last modified: _6/13/1997_ - - 19. How can I avoid a merge? I just want to move the latest revision on my - working branch directly onto the trunk. - - There is no direct way to do this using CVS, though the technique is - not difficult using shell commands. Here's one way: - - Move your working directory to the Main Branch. - - cvs update -A - - Use "update -p" to grab the latest revision on the branch and write - it over your working files. Make sure you don't have an modified files - -- you will lose them. The following is in "csh" syntax. Change the - wildcard to grab the files you want - - foreach i (Makefile *.cc *.hh) - cvs update -p -r $i > $i - end - - Commit all the working files onto the Main Branch. - - cvs commit -m 'Moved branch onto MAIN' - - You should experiment with the above before blasting everything. - - Last modified: _6/13/1997_ - - 20. How to I avoid merge collisions in the RCS $\Log$ data? - - In short, you can't. The RCS $\Log$ keyword is handled differently - from all other RCS keywords. - - On the info-cvs mailing list, there is a periodic discussion that goes - something like this: - - Question: How do I deal with $\Log$? Answer1: You can't do much with - it. Here's how it works. . . Answer2: I've found a limited way to use - it. . . Answer3: Get rid of it. $\Log$ is an abomination. - - I tend to lean toward answer #3. There are only two sets of people who - would ever have access to logs stored within sources files, developers - and source customers. - - For developers: - - Log entries within sources files are notoriously incomplete, rushed, - poorly phrased and in many cases incorrect, making them useless for - debugging or file maintenance. I remember a maxim from "Software - Tools" (I believe): "Read the code, not the comments." No managerial - order or plan for programmer discipline will affect this in the real - world. - - Log entries are usually in an unreadable mixture of styles. Many log - entries are just plain meaningless. Some are foolish. Some are even - insulting. Examples: - - "Corrected spelling of misspelling." "Bug fix." "Reversed stupid - change in previous revisions." "If Joe could do his job, this would - already have worked." - - Log entries are not managed well by the tools. Any merge can cause - conflicts in the $\Log$ data. Branch merges produce incomplete logs. - They can be edited into chaos and they are not regenerated. They waste - space duplicating information available to the developer with a single - command. - - Even if correct when originally entered, as changes are made to the - file, log entries become false over time. Humans are not good at - reading down through a list and remembering only the last change - affecting something. Over time *most* of the log is wrong. - - Even if still correct, the log data is almost useless to developers - without the code diffs. If you can get code diffs, you can display the - log. - - For source customers the problem is even worse. The last thing you - want to show customers is a hodge-podge of tiny comments about large - changes followed by a series of emergency fixes before delivery. If - you distribute sources, then you should provide documentation, or - changelogs reviewed by people who won't let comments like "Fixed for - stupid customer." out the door. - - Conclusion: Though some people would prefer to see in this FAQ - techniques for making the $\Log$ entries the best they can be, I - believe them to be a lost cause. My suggestion is to hunt down, root - out and destroy all occurrences of $\Log$ and the unusable data - attached to it wherever you may find it. - - Last modified: _6/13/1997_ - - 21. Why should I trust automatic merges? - - Some developers have the feeling that three-way merging doesn't work. - They fear and distrust the way the "update" command automatically - merges committed changes from the Repository into the working file. - - Experience has shown that most merges are utterly painless and most of - the rest are easily resolved. The few conflicts that cause headaches - are nearly all due to poor communication between developers, a problem - no source control system can obviate. - - Some developers were troubled in the past by flaky Unix software. I - can't say that everything is perfect, but the tools CVS depends on - (RCS and diff, mainly) are fairly solid nowadays. They work. - - Since it does seem to work for most of us, the algorithm is unlikely - to change soon. Why not test it on a couple trouble spots and if it - works for you, use it for a while? Then you can make an informed - decision. - - Last modified: _6/13/1997_ - - 22. How does CVS decide if it can safely perform a merge? - - CVS can merge any text file, possibly discovering a conflict and - leaving overlaps for you to edit. Editing the conflict markers out of - the file is a moment's work, but resolving the conflict could take an - arbitrary amount of time. CVS works to determine if it *should* merge, - not if it *can*. - - See 2B.6 for how the merge proceeds. - - Last modified: _6/13/1997_ - - 23. After resolving merge conflicts in a file, what if I want to keep my - previous version, and not take any of the branch changes? - - If you want to retain your previous version, a version on the MAIN - branch greater than 1.1 (one you committed there), just throw the - merged file away and "cvs update" the file. - - You don't need to commit something to remember it. The tags you place - before and after the merge should give all the handles you need to - find various versions. You don't have to create a new version of the - file. - - If you want to retain the previous Vendor revision, you can grab a - copy of it using "cvs update -p" and commit it or use the technique - described in 3B.3 to revert back to the Vendor branch. - - Last modified: _6/13/1997_ - - Category: /Advanced_Topics_/Engineering/ - - " + Engineering" - - 1. Where can I find out about Software Engineering? - - A couple different people suggested this book: - - Software Configuration Management: Coordination for Team Productivity; - Wayne A. Babich; Addison Wesley; 1986; ISBN 0-201-10161-0 - - A number of others suggested Appendix B of the book "Decline and Fall - of the American Programmer" by Ed Yourdon, called "The Programmer's - Bookshelf". It list 87 books you are expected to have read. Since they - publish many of the books, Prentice-Hall distributes this list as - "Prentice Hall Professional Technical reference PTR-125-AA3. - - One interesting item from the Yourdon book: The total number of - professional computer books sold is less than the number of - programmers currently in the United States. It wasn't clear from the - book whether this meant "per year" or not, but it is still - frightening. - - Last modified: _6/13/1997_ - - 2. How do I flexibly arrange the modules file to describe my sources? - - An equivalent question might be, "How do I structure my sources?" This - can be a difficult question especially in the areas that are more - political than technical. - - Generally you want to think about which pieces of your system need to - be checked out together, built as one system or tagged as a consistent - whole. You should certainly create module names that correspond to - complete, buildable collections that you would tag and release as one - "product". It is also convenient to create module names for small - sections of the Repository containing files that will all be worked on - at the same time by the same person or group. - - Once you have defined the structure of your work, you can usually see - how to lay it out in a Repository. After that the modules file is - easy. You set up module names and aliases to match what you need to - check out by name. If you like relative directories, it is possible, - but not recommended, to work completely without a modules file. See - 1D.11 and 2C.7 for some info about the modules file. - - Here are a few types of modules. You should experiment to see what - kind of structure each of these produces. They all have different - uses. - - Connected projects in one group with two separate helper - directories. The helper directories can contain build tools, header - files, libraries, or whatever you like. - - These are all aliases that checkout relative pathnames. The equivalent - results could be produced by placing the selected relative pathnames - on the "cvs checkout" command line. - - pr1 -a P1 HELPERS - pr2 -a P2 HELPERS - pr3 -a P3 HELPERS - pr12 -a P1 P2 HELPERS - pr13 -a P1 P3 HELPERS - pr23 -a P2 P3 HELPERS - - P1 -a group1/proj1 - P2 -a group1/proj2 - P3 -a group1/proj3 - HELPERS -a group1/helper1 group1/helper2 MAKEFILE - MAKEFILE -a group1/Makefile - - Actual Repository directory structure: (from $CVSROOT down) - - group1/ Makefile The top level Makefile. helper1/ helper2/ Helper - files and dirs proj1/ Files and dirs proj2/ Files and dirs proj3/ - Files and dirs - - "checkout group1" produces a duplicate of the above. "checkout projX" - produces all but "projY" and "projZ". "checkout projXY" produces all - but "projZ". - - Here is the exact same set of module names describing the same - Repository layout using module names (and aliases containing module - names) instead of merely aliases for relative pathnames. - - There is one difference in the result. The name of the top level - directory in the checked out working tree will match the "module" name - (e.g. pr1) instead of always being "group1" as it was in the first - example above. - - pr1 group1 proj1 &HELPERS - pr2 group1 proj2 &HELPERS - pr3 group1 proj3 &HELPERS - pr12 group1 proj1 proj2 &HELPERS - pr13 group1 proj1 proj3 &HELPERS - pr23 group1 proj2 proj3 &HELPERS - - HELPERS -a helper1 helper2 group1-Makefile - helper1 group1/helper1 - helper2 group1/helper2 - group1-Makefile -d . group1 Makefile - - The above line (with the -d in it) says that when the module named - "group1-Makefile" is checked out, the file named Makefile file will be - found in a directory named $CVSROOT/group1 and will be checked out - into a directory named '.', which obviously already exists. - - The & references say to interpret those pathnames relative to the - directory where the whole module is stored. For the "pr1" module, that - directory is "group1", so the &HELPERS reference winds up placing - Makefile in '.' relative to "group1". - - A short one containing the basic "module" actions: - - m1 head/path file1 dir2 file3 dir4 file5 - - When checked out, a directory named "m1" appears in your current - directory. Elements named file1, dir2, file3, dir4, and file5 appear - in it. They were originally taken as relative paths from - $CVSROOT/head/path. - - Here's another way to construct a working directory out of pieces of - the Repository: - - projX projX Makefile &projX_inc &projX_src &projX_doc - - # The first line selects a single file within projX, plus - # the contents of three other modules. Those three other - # modules rename their directories. - - projX_inc -d include projX/inc projX_src -d source projX/src projX_doc - -d documentation projX/doc - - A Unix tree. This is similar to what CVS was developed for and the - way I have used it for years. - - # Top level - unix unix - u_bin unix/bin - u_etc unix/etc - u_man unix/man - usr-bin unix/usr.bin - - # Subdirs of top level dirs. (tiny subset) - ls unix/bin/ls - fsck unix/etc/fsck - man8 unix/man/man8 - - # Programs without subdirs. (tiny subset) - cat unix/bin Makefile cat.c - uniq unix/usr.bin Makefile uniq.c - - # /usr/local/src - localsrc localsrc - gnu localsrc/gnu - public localsrc/public - X11 localsrc/X11 - - # GNU and PD tools - cvs localsrc/gnu/cvs - emacs localsrc/gnu/emacs - rcs localsrc/gnu/rcs - btoa localsrc/public/btoa - tcsh localsrc/public/tcsh - - # X11 related items. - tvtwm localsrc/X11/contrib/tvtwm - - "unix" was checked out and built from the top down, using a set of - Makefiles that knew about the whole structure. "localsrc" was kept - checked out in /usr/local/src. - - At any time I could run "checkout ls" or "checkout cat" and get a - simple directory with only that tool in it, plus a subset Makefile - that knew how to build that tool against the installed (or alternate, - via environment variables) headers and libraries. - - I found it very handy to be able to run "ls" and see the three tools I - was porting that week. - - Last modified: _6/13/1997_ - - 3. Can I have multiple source repositories, one for each project? - - Yes, you can have as many Repositories as you like. But each - Repository must be managed separately, creating additional work. - - Question 4A.1 provides a short description of setting up a single - Repository. A few additional considerations: - - It is a good idea to start by creating a single Repository and split - it up (or create additional Repositories) only if you believe it is - really necessary. I would only create a new Repository if the data is - completely disconnected from the rest of the main Repository. - - If there is a lot of overlap among the developers working on the - collections of files you want to place in different Repositories, or - if there is any connection between those collections, I would go out - of my way to create a single Repository. It is much easier to manage. - - Disk space should not be a factor since you can build up a - Repository using symbolic links and/or remote mounts. - - Each Repository is completely distinct. You can't check out modules - from different Repositories at the same time. A better way of looking - at it is that if you *can* check out two modules or directories with a - single "checkout" command (without contortions or explicit absolute - pathnames), then they are in the same Repository. - - To "checkout" modules from multiple Repositories, you must use the - "cvs -d" option on all CVS commands or alter your $CVSROOT variable - when you change focus to another Repository. If you work with multiple - Repositories, it is a good idea to configure CVS to use absolute - pathnames in the ./CVS/Repository file, since most commands (other - than "checkout") will use that file rather than $CVSROOT. - - If you configure CVS to use relative pathnames in your - ./CVS/Repository files, you must always be careful to set your - $CVSROOT properly or you will get unexpected results. - - If you have two modules or directories by the same name at the same - relative path inside two different Repositories, you are asking for - disaster. You could unexpectedly update a directory with completely - unrelated files. This is not a fanciful example -- a Repository is - occasionally duplicated for release purposes in which case *all* the - paths in the two Repositories are the same. - - Last modified: _6/13/1997_ - - 4. Who should administer the Repository and manage the modules file? - - This is a "management style" question. In large or traditional groups, - the CVS procedures are warped to conform to local conventions. In - small groups, in groups with strong personalities or on new projects - the choice of source control procedures can help create some of the - working environment. Here is a taxonomy of environments I have worked - in or helped set up: - - Situation 1. - - A small number of competent developers working on a medium size - project. We all got along and we all respected each other (at least - technically). Anyone edited anything. - - Modules and Repository admin was mostly left to me. I never found a - problem in minor changes made by anyone else. - - Situation 2. - - A large number of experienced developers sprinkled with wackos. Many - of the developers didn't want to deal with any kind of source control. - They wanted a full-service source control system that caused them zero - thought. - - I learned "big stick" diplomacy here. There was a small number of - "designated" (by me) people who were allowed to do *anything* other - than "update" and "commit". Even "checkouts" were controlled. This is - where I found "history" and "release" the most useful. - - Situation 3. - - A small number of developers who wanted me to "help", but who didn't - want to deal with anything other than their favorite algorithms. - - I didn't have the time to baby-sit this group, so I designated one of - them to be my official contact and made him do it all. He felt sullied - by the requirement to pay attention to anything other than his pet - coding projects, but enjoyed the "status" of being the only one who - could touch the control files without my kicking the chair out from - under him. - - Situation 4. - - A huge number of developers of covering the whole spectrum of - competence and experience split into 20 groups, none of which - cooperated with the others, working on 57 different projects, most of - which didn't inter-operate. - - Managing it in any coherent way was not my responsibility (and beyond - my tolerance for chaos). Too many people. So I privately designated a - person in each group to be the contact and kept watch on the - Repository activity. When something went wrong, I notified the contact - for the group and told him what was happening and *he* kept his troops - in line. They were tougher with their own group that I would have - been. - - Eventually only a few people were willing to touch the control files, - since they were flamed from all directions if they screwed up. - - Situation 5. - - In a medium group of really *serious*, and seriously overworked, - people, someone else was designated the "master". I convinced the - master I knew what I was doing and went on my way. - - No one else in the world was allowed to touch anything. - - Situation 6. - - In a large amorphous group of beginners, experts and clowns, over whom - no one had official control, I was forced to employ a group of - relative beginners (who became experts rather quickly) to police the - world. The ultimate in locking the barn after the horse was stolen, we - kept Chaos from destroying us only by use of superior firepower. - - My choice, if allowed, is to let anyone touch anything. I keep backups - of important items and let people know individually whether I want - them to touch things or not. If someone on my "no touch" list touches - and succeeds, they are allowed more slack. If they screw up after - being warned, their screwup becomes public. After a few months, I - usually have no trouble keeping the world running smoothly, at least - from my (and CVS's) perspective. - - Last modified: _6/13/1997_ - - 5. Isn't disk space a big factor? CVS copies files out of the Repository, - duplicating everything. - - Everyone knows that disk space is getting cheaper. How do we reconcile - this with the equally well-known problem that *all* disk is *always* - filled up? - - In my opinion, the main reason disk space will never be an unlimited - resource is that it is the major variable in organizational time/space - tradeoffs. It isn't a problem of waste or an aspect of Murphy's law, - as some claim it is, but rather a direct consequence of good - management. Disk space is, and will always be, a limited resource. - - First, the cost of *deploying* that disk is not dropping as fast as - the cost of the storage medium. The cost of machines to hold the disks - and the networks to connect them are dropping more slowly than disk - media. And the cost of the human time necessary to manage the - machines, networks, disks, and the developers using them, is not - dropping at all. The cost of human time continues to rise. - - If management decides that expensive human time can be saved by using - all that new disk space to keep the last three releases online, then - that's what it will be used for. If each release takes up a Gigabyte - and you support 30 platforms, a simple time-saving suggestion has just - grabbed 100 Gigabytes of disk space. And we've ignored the potential - disk storage needed to support "better Customer Service", another - management refrain. - - Even at 30 cents per Megabyte (next year's price), you've just used up - $30,000 of disk space. And that doesn't count the computers, tape - drives and humans necessary to maintain and deploy all of it. Spending - money to save time has its own overhead, too. - - Binaries are getting bigger. Graphics and data collection devices can - eat up any amount of disk. There are more tools available, more - libraries, more raw data than you can ever store. My home computer has - a Gigabyte of disk on it. It could easily handle 30. - - The "economy" of disk storage media will never remove the need to - manage disk space. - - So, here's an un-reviewed suggestion originally from Graydon Dodson - , which I've altered and edited heavily. - - - Keep a directory where the whole tree is checked out. (It might be - built and tested once in a while to make sure it is worth linking to, - but that doesn't affect the source control aspect of this procedure). - Let's call it /master/build. - - - Write a tool that creates a tree of directories (like the X11 - "lndir" command) filled with links to the checked out files in the - /master/build tree. - - This tool should also provide real copies of, not symlinks to, all the - files within the CVS administrative directories. - - - You could also provide a way for the tool to take a list of whole - directories that you will never change, for which it would create a - single symlink to the directory and not a subtree of symlinks to - files. Or you could rm -r pieces of the resulting working directory - yourself and replace it with links. - - - If you want to edit a file, you have to grab a real copy and keep it - until your revision shows up in the /master/build tree. I'd create a - script to do this: cvsgrab - - #!/bin/csh -f - set f = $1 - if (! -l $f) then - echo "file $f is not a symlink" - exit 1 - endif - rm $f - set rev = `grep "^/$f/" CVS/Entries | awk -F/ '{print $3}'` - cvs update -p -r $rev $f > $f - - You can't do a plain "cvs update" since that would grab newer - revisions from the Repository, not the revision you wanted to start - with. After the file is no longer a symlink, you can work normally. - You'll have to run "update" before "commit" anyway if there are newer - revisions. - - - Presumably there would also be a tool to traverse the link tree and - revert it to links if there are no modified files and/or if all the - real files match the revision of the /master/build tree. - - - To avoid confusing CVS when the /master/build revisions are updated - but your CVS/Entries files is not, CVS would have to change to handle - symlinks. It currently causes problems with this scenario: - - ./ is a symlink. - - ./CVS/Entries says you are revision 1.2. - - The corresponding CVS/Entries file in /master/build says the latest - revision is 1.3. - - cvs update shows a 'C' conflict flag. - - Last modified: _6/13/1997_ - - Category: /Advanced_Topics_/Installing_CVS/ - - " + Installing CVS" - - 1. What do I have to do before I install CVS? - - You must decide where to set up a Repository. - - Though you can construct a Repository tree structure using links and - mount points, there must be a single copy of each real file across - your entire organization. You may not "rdist" files and expect to edit - both copies. - - CVS does not support a truly distributed Repository. You can have - multiple Repositories, but each one must be mounted (not copied or - "rdist"ed) from a single place onto all machines where it will be - used. - - Initially, a Repository takes about same amount of disk space as the - sources you want to put into it, plus a bit of overhead for the RCS - files. - - See Section 4B. For multiple Repositories, see 4G.3 - - You need a directory in everyone's $PATH variable where you can - install all the executables. /usr/local/bin is a common place. - - You need some helper tools besides CVS such as "RCS" and a good set - of "diff" and "diff3" programs. See 1B.4 for suggestions. - - Read the README, INSTALL and ChangeLog files to see what you are - getting into. - - Though you can probably muddle along without it, you should appoint - one or more "Repository Administrators" who will be responsible for - maintaining the Repository structure, administrative files and the - "modules" interface. - - Someone at your site should probably be on the info-cvs mailing list. - See 1B.5. - - Last modified: _6/13/1997_ - - 2. How do I configure the CVS programs? - - You should certainly start by reading the README file, the INSTALL - files and possibly the ChangeLogs in each directory, the Makefile.in - files and the "cvsinit.sh" program. - - Execute the ./configure command. - - Type "make". - - After running "make" you might try running the "sanity.sh" script: - ./src/sanity.sh `pwd`/src/cvs - - It writes into /tmp/cvs-sanity by default. - - Finish reading the INSTALL file and test out the system. - - Last modified: _6/13/1997_ - - 3. What do I have to install? - - Install the "cvs" executable and "mkmodules" from the CVS sources. - The man page is useful too. If you plan to report bugs, you should - also install "cvsbug". - - Set your $CVSROOT environment variable and create the Repository - (which you planned out in 4A.1) with the "cvsinit" command at the top - of the CVS sources. - - You'll need to edit the Repository control files created by - "cvsinit". - - Install any helper programs mentioned in the modules file. - - Last modified: _6/13/1997_ - - 4. How do I work around the merge problems in GNU diff version 2.1 or - later? - - See 1B.4 If you use recent versions of RCS and "diff", you won't run - into the above. If you do, see 5B.8 - - Last modified: _6/13/1997_ - - Category: /Advanced_Topics_/Internal_errors/ - - " + Internal errors" - - 1. Explain: "ci error: unexpected EOF in diff output" - - RCS versions earlier than 5.5 print the above error when a file does - not end in a newline character. It can be caused by: - - - Editing with Emacs and not using "require-final-newline". - - Committing a binary file. - - Filesystem failures (NFS!) that put nulls in your file. - - The solution is to upgrade to RCS 5.5 or later. (Of course, this won't - fix filesystem failures. It will merely allow RCS (and therefore CVS) - to handle the file without error.) - - Last modified: _6/13/1997_ - - 2. Explain: "RCS file /Repository/module/file.c,v is in use" - - This is an RCS error that occurs when its internal lock file has been - left around by an RCS command interrupted by some sort of system - crash, disk failure or SIGKILL signal. - - Go into the Repository and look for files with names similar to - "file.c,v", usually starting with ',', '_' or '#'. Make sure they are - really crash remnants and do not belong to transactions in progress -- - a recent last-modified timestamp is a good indicator of a live - transaction. Delete them if they are old. - - Last modified: _6/13/1997_ - - 3. Explain: "co error, line 2: Missing access list" - - This is an error message from RCS Version 3 when it tries to read a - file created by a later version of RCS. - - HP decided to "standardize" on an ancient version of RCS some time - ago. You can't use it for CVS. See 4H.6. - - Since the error comes from having a later version of RCS than HP - supports, you probably did install the later version but must have - recently changed your $PATH or installed the HP package that has RCS - in it. - - You should either reconfigure CVS to use absolute pathnames to the - proper versions of the RCS programs that CVS uses, or change your PATH - to look there first. If you haven't installed the latest version of - RCS, you should upgrade. See 1B.4 - - Last modified: _6/13/1997_ - - 4. Explain: "error: RCS file name `xyz .c' contains white space" - - RCS 5.6 doesn't allow white space in filenames. Apparently this - restriction will be removed in RCS 5.7, but CVS may still require that - filenames have no white space in them. - - Last modified: _6/13/1997_ - - 5. Explain: cvs checkout: warning: is not (any longer) pertinent - - This message occurs in three instances: - - When there is an entry in the ./CVS/Entries for file and there - is no RCS file in the Repository to back it up. - - If the working file exists, and hasn't changed (determined from the - timestamp) it is removed. - - When you try to check out a piece of the Repository with: - - cvs checkout some/place/in/repository/tree - - and at least the first element of the path (i.e. "some" in the above) - exists, but some part of the rest of it does not. - - The checkout command checks the modules file first for the whole path, - then for a prefix of the path as a module name. If it doesn't find - *any* portion of your path in the modules file, it says: - - cvs checkout: cannot find module `' - ignored - - If it finds some set of prefix directories, it prints the message you - see. - - In practice this is usually a spelling error. - - If the Repository files you are trying to check out or update are - not readable by you, the same problems can occur. Check the - permissions on the files involved. - - Last modified: _6/13/1997_ - - 6. Why did a Repository file change from ,v to ,,? - - This is an RCS problem, since the ,, syntax for file names is - used by RCS and not CVS. - - RCS constructs a new ,v in a temporary file named ,, - (which doubles as a lock file) then renames it to ,v when it is - done. The only way this is reliable is if your system's version of - rename(2) is an atomic, as required by POSIX. - - If your system has a non-atomic (and therefore non-POSIX) rename(2) - system call, RCS runs uses an internal version of this algorithm to - approximate the atomic rename: - - rm ,v; ln ,, ,v; rm ,, - - If the system crashes, or you lose your NFS connection between the - first "rm", but before the "ln", you can be left only with the - ,, file. If the crash or network failure occurs between the "ln" - and the final "rm", you could be left with a pair of linked names. - - Recovery: - - If only the ,, exists, rename it to ,v. - - - If both ,, and ,v exist and are linked, remove the - ,, file. - - - If both ,, and ,v exist and are separate files, look at - the dates, "diff" them and make your best guess. This sounds like the - remnants of two separate events. - - Last modified: _6/13/1997_ - - Category: /Advanced_Topics_/Other_Systems/ - - " + Other Systems" - - 1. I use a NeXT. Is there anything I need to know? - - NeXTSTEP 3.0's Interface Builder uses "nib" directories, rather than - the files used in previous revisions. It removes files it doesn't - recognize, making it impossible to place such a directory under CVS -- - the CVS admin directory will be removed. - - Some time ago, posted a palette named CVSPalette - that claimed to resolve this problem. It was intended to preserve the - CVS administrative directories within nib documents (directories) that - Interface Builder usually removes. - - CVSPalette is no longer in its announced place: - - ftp.cs.orst.edu:/pub/next/submissions - - though I did find two other interesting files on ftp.cs.orst.edu: - - /software/NeXT/sources/tools/cvs-next-2_1_1.tar.Z - - which is a port of CVS 1.3 (along with RCS and diff) and: - - /software/NeXT/sources/programming/cvs.postamble-2.4.gz - - which appears to be a set of wrappers for CVS commands that claim to - allow you to use CVS effectively (and without need for the "command - line") on a NeXT machine. - - [[Anyone know the truth about CVS and NeXT?]] - - Last modified: _6/13/1997_ - - 2. I use OS/2 and/or DOS and/or Windows. Is there anything I need to know? - - When using a local repository, be sure to specify the local access - method or CVS will interpret the drive letter as a remote host name - due to the : following it: - - WRONG: CVSROOT=C:\SRC\CVSROOT - - RIGHT: CVSROOT=:local:C:\SRC\CVSROOT - - (larry.jones@sdrc.com) - - You can share RCS files between Unix and DOS while avoiding the MS-DOS - file name limits by setting your RCSINIT environment variable to - '-x/,v'. New RCS files will be created without the standard ",v" - suffix, though files ending in ",v" will still be found if there is no - matching file in the same directory without the ",v". - - Erik van Linstee offers an OS/2 and a DOS port of CVS 1.3 in: - - ftp.informatik.tu-muenchen.de:/pub/comp/os/os2/gnu/devtools or - ftp.rrzn.uni-hannover.de:/pub/os2-local - - The files are named: - - cvs13p?[bs].zip - - Where the ? stands for the patch level (currently 8) and the b is for - the binaries, the s for the sources. - - There are three binaries. An OS/2 only one (32-bit), a DOS only one - (16-bit) and an EMX one that runs on both (32-bit). - - There are many differences between the Unix and the DOS versions of - CVS. Read the material that comes with the DOS version before using - it. - - [[Updates?]]. - - Last modified: _9/22/1997_ - - 3. I use SCO Unix. Is there anything I need to know? - - On SCO/UNIX 3.2 V2.0 POSIX signals don't work. Unfortunately the - configure program detects POSIXness and configures in the use of POSIX - signals. Workaround : Edit out the check for POSIXness in the - configure script. [[You could also remove all occurrences of - "-DPOSIX=1" from the Makefiles after configure is run. -dgg-]] - - SCO/UNIX doesn't understand #!/ syntax. This breaks the - use of log.pl as it gets invoked by /bin/sh instead of - !#/usr/local/bin/perl. WorkAround : edit log.pl and change it into a - shell script which invokes perl with log.perl (renamed from log.pl) as - input. - Contributed by Joe Drumgoole - - Last modified: _6/13/1997_ - - 4. I use AIX. Is there anything I need to know? - - The only report on AIX claims to have no trouble using it in concert - with SunOS and IRIX platforms. - - Last modified: _6/13/1997_ - - 5. I use IRIX. Is there anything I need to know? - - If you see "uid" numbers where you would expect user names, try adding - -lsun to the link line. Without it CVS is unable to retrieve "passwd" - data through NIS. - - Last modified: _6/13/1997_ - - 6. I use an HP system. Is there anything I need to know? - - HP distributes RCS version 3 (a circa 1983 release!) with HP-UX. CVS - does not work with RCS version 3; it requires RCS version 4 or later. - Your best bet is to find the latest version of RCS and install it - somewhere. - - HP-UX 8.07 has a serious bug with the mmap system call and NFS files; - the bug can crash the operating system. Make sure that you configure - RCS to avoid mmap by setting has_mmap to 0 in RCS's conf.h. This bug - is fixed in HP-UX 9. - - Contributed by Paul Eggert - - If using the setgid() trick described in 4D.13, you will have to - create an entry in the /etc/privgroup file to give the group assigned - to the cvs executable setgid permission (see setprivgrp(1m)). - Additionally, if you are restricting "read" access to the Repository - by limiting access to the executable (this requires yet another - group), then you will require that /etc/logingroup exists and is - configured correctly (usually it's just alink to /etc/group). - - Contributed by Dale Woolridge - - Last modified: _6/13/1997_ - - 7. I use AFS. Is there anything I need to know? - - There is a problem with the way CVS performs its locking when the - files are within AFS. When your current PTS id != your uid, the locks - are not deleted. The stat() system call returns the PTS id of the - owner. If that id != your uid, CVS assumes you did not lock it, and - leaves the lock files alone. The next time you try to use it, it - complains that someone has the repository locked. - - Contributed by Michael Ganzberger - - [[This was against CVS 1.3. Is it still in CVS 1.4?]] - - Last modified: _6/13/1997_ - - 8. I use A/UX. Is there anything I need to know? - - [[??]] - - Last modified: _6/13/1997_ - - Category: /Advanced_Topics_/Related_Software/ - - " + Related Software" - - 1. How do I use CVS under Emacs? Is there an Emacs cvs-mode? - - The pcl-cvs package distributed with CVS is an emacs package that - helps with the update/commit process. When you are ready to update, - you use the 'cvs-update' command within emacs. This executes "update" - and fills a cvs-mode buffer with a line for each file that changed. - The most helpful features are: descriptive words for what happened - (i.e. Merged or Conflict rather than 'U' or 'C'), single keys bound to - diffs and commits, and the ability to mark arbitrary groups of files, - possibly from different directories, for commit as a whole. - - All the developers in my group that use emacs find pcl-cvs a much - friendlier and more helpful way to update/commit than raw cvs. One vi - user even converted to emacs just to use pcl-cvs. - - Contributed by Jeffrey M Loomis - - Last modified: _6/13/1997_ - - 2. What is GIC (Graphical Interface to CVS)? - - - - - GIC provides a graphical user interface to the Concurrent Version - System (CVS), a powerful revision control system. GIC is - implemented in the Tcl/Tk programming language and is intended to - augment the sometimes cumbersome CVS command line interface. - - Note that according to the official GIC page at - http://www.cpsc.ucalgary.ca/redirect/grouplab/projects/gic/ - GIC is no longer being maintained and tkCVS is recommended - instead. - - For more on tkCVS, see - . - - kingdon@cyclic.com - - Last modified: _9/6/1997_ - - 3. What is CAVEMAN? - - CAVEMAN is a front end to CVS written in PERL providing a collection - of features desired by the site where it was developed. - - - The ability to spread a "project" over multiple Repositories. - - Optional automatic tagging after each commit. - - Additional locking of files. - - Extra before and after program hooks. - - A layer of event logging. - - All sorts of error messages. - - Many changes to the semantics of commands. - - It is available via anonymous ftp on ftp.llnl.gov [128.115.54.18] in - gnu/caveman_vX.Y.Z.tar.gz (The numbers X, Y, & Z vary.) - - contact Kathleen Dyer kdyer@llnl.gov - (510)423-6803 - (510)423-5112 FAX - - [[Does someone want to elaborate?]] - - Last modified: _6/13/1997_ - - Category: /Advanced_Topics_/Setting_up_and_Manag/ - - " + Setting up and Managing the Repository" - - 1. What do I do first? How do I create a Repository? - - First, install all the programs. (See Section 4A.) - - Then create a Repository by executing "cvs -d init". (This works with - CVS 1.9.) - - Now you can configure your repository by checking out CVSROOT: "cvs -d - checkout CVSROOT". Change into the created directory CVSROOT. Edit the - files you want to edit, and afterwards, commit the changes by typing - "cvs commit". - - You will certainly want to add modules of your own. Edit the "modules" - file and add lines to describe the items you want to "checkout" by - module name. Here's a short list that could be used for storing a - small number of GNU and PD sources: - - local local - - gnu local/gnu - emacs local/gnu/emacs - cvs local/gnu/cvs - - public local/public - pdprog1 local/public/pdprog1 - pdprog2 local/public/pdprog2 - - test test - junk test/junk - - Andreas Kostyrka - - Last modified: _4/21/1998_ - - 2. What are those files in $CVSROOT/CVSROOT? - - There are eight Repository control (or "database") files of interest - in the CVSROOT directory: - - modules contains the "modules" database. See 1D.11, 2C.7, 4B.6 and - 4B.7 for more details. - - commitinfo contains two columns: 1. a regular expression to match - against pathnames within the Repository and - - a to execute for matching pathnames. - - When you execute "commit", CVS passes the Repository pathname for each - directory (and the files to commit within that directory) to - . If exits with a non-zero status, the commit is - blocked. - - A associated with a pathname of "DEFAULT" is executed if - nothing else matches. Every associated with a pathname of - "ALL" is executed separately. - - rcsinfo contains the same first column as commitinfo, but the second - column is a template file for specifying the log entry you are - required to enter for each commit. - - "DEFAULT" and "ALL" work the same as in the commitinfo file. - - editinfo contains the same two columns as commitinfo, but the - in the second column is intended to do some consistency - checking on the commit log. - - "DEFAULT" works as in commitinfo. - - loginfo contains the same two columns as commitinfo, but the - is expected to read a log message from its standard input. - The can do anything it wants with the log information, but - normally it is appended to a log file or sent to mailing lists. - - "DEFAULT" & "ALL" work the same as in commitinfo. - - cvsignore contains "ignore" patterns that are added to the built-in - ignore list. See 2D.10. - - checkoutlist contains a list of other files kept under RCS in - $CVSROOT/CVSROOT that should be checked out by mkmodules to provide a - readable copy. - - history contains a stream of text records, one for each event that - the "history" command is interested in. Though the contents of the - history file can be read, it is intended to be read and displayed by - the "history" command. This file is the only one in the above list - that is not under RCS. - - Last modified: _6/13/1997_ - - 3. Is there any other state stored in the Repository besides in the - $CVSROOT/CVSROOT directory? - - Only in the RCS files. The Repository holds exactly two things: the - tree of RCS files (each usually ending in ",v") and the CVSROOT - directory described above. - - Last modified: _6/13/1997_ - - 4. How do I put sources into the Repository? - - There are three main ways to put files in the Repository: - - Use the "import" command described in Section 3H. - - This method is the fastest way to put trees of new code into the - Repository and the *only* way to handle source releases from a 3rd - party software vendor. - - Use "add" followed by "commit". - - This is how to add new files and directories to the Repository, a few - at a time. Directories don't need to be committed. - - You can move RCS files directly into the Repository. - - You should create a directory hierarchy to hold them, but you can just - move arbitrary ",v" files into the Repository. The only "state" in the - Repository other than within ",v" files is in the required CVSROOT - directory at the top of the Repository. - - Last modified: _6/13/1997_ - - 5. What file permissions should I use on (and in) the Repository? - - If you are using pserver (password-authenticated access), see below. - - If you run a completely open environment (which usually means that you - don't have, or don't want to waste, the time to deal with it): - - - Set all directory permissions to 777. - - - Have everyone set their umasks to 0. - - (BTW, I don't suggest this. I am merely reporting it.) - - If you are a normal Unix shop and want to use groups effectively: - - - Set all the directory permissions in the Repository to 775. - - If you are using a system that handles both System V and BSD - filesystems, you might have to set the permissions to 2775.) - - If you are using one of the many recent versions of Unix that don't - allow you to use the full octal mode, then you'll have to type: chmod - u=rwx,g=rwx,o=rx,g+s dir> - - - Change all the groups on the directories to match the groups you - want to write to various directories. - - - Make sure every user is in the appropriate groups. - - - Have everyone set their umask to 002, including root. - - If you don't want non-group members to even read the files, do the - above, but change: - - - Repository directory permissions to 770. (or 2770) - - - umasks to 007. - - If you work in an environment where people can't be trusted to set - their "umask" to something reasonable, you might want to set the umask - for them: - - mv /usr/local/bin/cvs /usr/local/bin/cvs.real - cat > /usr/local/bin/cvs - #!/bin/sh - umask 2 # Or whatever your site standard is. - exec /usr/local/bin/cvs.real ${1+"$@"} - ^D - - Pserver (Password-Authenticated Access) <blome@de.ibm.com> - - The above suggestions are not valid when you use the pserver facility. - Be sure to read and understand the manual section about this (should - be 4.6.something). Above all: do /not/ make the repository and CVSROOT - group writeable. In CVSROOT, make `history´ group or world writeable - instead. - - I suggest creating one unix group per project group. In the - repository, you would then create one directory for each group, group - writeable. New projects must then be created in these group - directories. If you don't want to say <group>/<project> on - checkout, create a <project> module and point it there. - - Last modified: _9/24/1998_ - - 6. How do I structure my Repository? - - The Repository holds your software. It can be all interrelated or it - can be a bunch of separately managed directories. - - How you break a whole system down into its component parts, while - defining interfaces between them, is one aspect of "Software - Engineering", a discipline that requires the study of dozens of - strange and wonderful areas of the computer and management worlds. - - CVS provides a way to keep track of changes to individual files, a way - to "tag" collections of files, and a way to "name" collections of - files and directories. That's all. Everything else is in the way you - apply it. - - In other words, you should structure your Repository to match your - needs, usually tied in with the other tools you use to build, install - and distribute your work. Common needs include the ability to: - - - mount (or automount) directories from many places in your - organization. - - check out just what you need and no more. - - check out multiple sections in a fixed relation to each other. - - check out large sections to match the assumptions built into your - build system. (Makefiles?) - - In my opinion, you should start small and keep everything in one tree, - placing each major sub-system into a separate directory. Later, when - you know what you are doing, you can make it more sophisticated. - - Last modified: _6/13/1997_ - - 7. Why would anyone use "modules"? They are too restrictive. I want to be - able to select just the files I want to edit. - - Any form of structure is restrictive. If you believe that total chaos - is a viable working paradigm, or if you believe you can keep track of - the interrelations between all portions of your Repository in your - head, then you can do what you please. - - If you believe that systems of files require management and structure, - then the "modules" idea is very useful. It is a way to impose a naming - scheme on a tree of files, a naming scheme that can be simpler than a - large list of relative pathnames. - - The "modules" file represents a published interface to the Repository - set up by your Repository Administrator. If s/he did a creditable job, - the modules offered will be internally consistent and will smoothly - interact with the rest of your environment. - - Last modified: _6/13/1997_ - - 8. How do I rename a file or directory? What are the consequences? - - In CVS there is no single "rename" command. - - See 2C.4 for the suggested way to rename a file or directory. - - The rest of this section covers some of the consequences of renaming. - - A "renaming database" has been proposed that would keep track of name - changes so that "update -r " would continue to work across the - renaming. But as it stands, you have to pick one of the following - options: - - Use the technique described in 2C.4. (For each file, duplicate the - file in the Repository, "remove" the old version so it winds up in the - Attic and strip all Tags off the new version.) - - - "update -r " produces the correct files. - - - The duplicated revision history can be slightly misleading. - - - A plain (i.e. without the "-r ") "checkout" or "update -d" will - create directories "renamed" this way, but you can delete it and a - plain "update" won't bring it back. - - Move the files and directories in the Repository to the new names. - - - You save the revision history under a different file name. - - - You save a little space. - - - "update -r " produces the wrong files or directories. - - This is not a good general solution, but if you plan never to look - back (someone may be gaining on you!), it is sometimes a useful - notion. - - If you are clever with Makefiles, you might be able to rework them to - handle either the new or old names, depending on which ones exist at - the time. Then you can move an old onto the new, more - sophisticated, revision of the Makefile. (Yes, this changes the - "released" file if indicates a release. But it is an option.) - - - Important Note: If you rename a directory, you must rename the - corresponding directory in every checked-out working directory. At the - same time, you must edit the pathname stored in the ./CVS/Repository - file within each of the moved directories. - - The easiest way to move a lot of directories around is to tell - everyone to remove their working directories and check them out again - from scratch. - - - The file exists in the working directory and in the ./CVS/Entries - file, but not in the Repository. For the old file, "update" prints: - - cvs update: xyz.c is no longer in the repository - - and deletes the file. If the file was modified, "update" prints: - - cvs update: conflict: xyz.c is modified but no longer in the - repository C xyz.c - - and leaves the file alone. In the new directory, you see: - - U xyz.c - - as you would if someone else executed "add" and "commit". - - For each file, copy the working file to a new name in the working - directory and use the "cvs remove" to get rid of the old old file and - "cvs add" to add the new one. Since there is no way for CVS to remove - a directory, this only works for files. - - - This is what most people think of first. Without a "rename" command, - the remove/add technique seems obvious. - - - You lose the connection of your new working file to its past - revision history. - - Last modified: _6/13/1997_ - - 9. What are "Attic" directories? - - When you use the "remove" command on a file, CVS doesn't delete the - file, it only registers your desire to delete it. - - When you "commit" a removed file, CVS moves the Repository's matching - RCS file into a sub-directory named "Attic" within the Repository. - - Attic files are examined when the '-r' or '-D' option is used on - "checkout" or "update". If the specified revision, tag or date matches - one on a file in the Attic, that file is checked out with the others. - - You can think of the Attic as a sort of dead branch, which is only - looked at when you refer to a or . - - Last modified: _6/13/1997_ - - 10. Is it OK to remove anything from the Repository? - - In general, removing anything from the Repository is a bad idea. The - information in a deleted object is lost forever. There are many ways - to skip over files, directories and revisions without deleting them. - - Here are some of the consequences of removing the following things - stored in the Repository: - - CVSROOT files (Repository control files) - - The Repository will work without any of them, but you should - understand what you are losing by deleting them. See 4B.2. - - Revisions - - The only way to remove revisions is to use the "admin -o" command (or - the equivalent RCS command "rcs -o"). - - They are lost forever. Any tags formerly attached to deleted revisions - are now pointing into the Phantom Zone. You'll need to contact Jor-el - to get them back. - - Files - - You should not remove a file unless you truly never want to see it - again. If you want to be able to check out an old revision of this - file, use "cvs remove" instead. - - Tags - - Tags take up little space and you can't recover from deleting them. If - you depend on tags for releases you will lose vital information. - - Directories - - There is no Attic for directories, so the only way to remove them is - to use "rm -r". They are gone forever. - - If you delete (or move) a directory, all checked-out versions of that - directory will cause CVS to halt. You'll have to visit each - checked-out directory and remove the matching working directory by - hand. - - Attic files - - The "remove" command sends files to the Attic. To really delete them, - you have to go into the Attic and use "rm". - - If a file in the Attic has a Tag on it that you might ever want to - check out again, you probably don't want to delete it. - - Lock files (named: "#cvs.[wr]fl.") - - These are lock files. If you are getting "lock" errors and the dates - on the lock files indicate that they are old, you can delete them. - - Deleting lock files still in use by a CVS process might produce - unusual errors. - - Last modified: _6/13/1997_ - - 11. Can I convert to CVS from RCS without losing my revision history? - - Yes, you can simply move (or copy) your RCS files into a directory - within the Repository, check out that directory and start working. - - Last modified: _6/13/1997_ - - 12. Can I move RCS files with branches in them into the Repository? - - Yes, but they may not work if you created branches in a way that - conflicts with CVS's assumptions: - - You can't use .0. branches. (They are reserved for "Magic" branch - tags.) - - If you use branch 1.1.1, you can't use the Vendor branch. - - You can use other RCS branches under CVS. There is no need to create - "magic" branch tags because the physical branch already exists. - - Last modified: _6/13/1997_ - - 13. Can I use raw RCS commands on the Repository? - - You can use raw rcs commands directly on the Repository if you take a - little care. The Repository itself contains no "CVS state" (as opposed - to RCS revision histories) outside the CVSROOT directory. - - But using raw RCS commands to change branches, tags or other things - that CVS depends on may render the files unusable. - - See 4D.7 on RCS/CVS sharing of the Repository and Section 3B on the - "admin" command. - - Last modified: _6/13/1997_ - - 14. How do I convert from SCCS to RCS? - - You'll have to execute something like "sccs2rcs" (in the CVS contrib - directory) on every file. Then you can move the resulting RCS files - into the Repository as described above. - - Last modified: _6/13/1997_ - - 15. How do I limit access to the Repository? - - There are all sorts of ways to restrict access to Repository files, - none of which are hooked directly into CVS. - - Techniques for limiting access include: - - Training, management and good backups. - - The best form of Repository control is a combination of: - - - A reliable backup scheme (verify it!) - - Enough training to ensure your developers are competent and - knowledgeable about all areas of your sources. - - Effective management of the boundaries and grey areas. - - In many cases, technical solutions to "security" problems are - inadequate. You should first try to avoid them. - - Personal Opinion: In an environment where "unknowns" are allowed to - touch important sources the "owner" of the CVS Repository must be a - large, loud, vigorous lout with a well-balanced truncheon and the - right to use it. Don't underestimate the effectiveness of letting - everyone know they will be strapped into the stocks on the Town Common - and pelted with vegetables if they break something they don't - understand without first asking the experts. - - Set Unix groups and permissions. See 4B.5. You can set different - owners, groups and permissions for each sub-directory within the - Repository if that helps. - - Catch invocations of "commit" by defining pre-commit programs in the - "commitinfo" file. This is fairly powerful, since it can block commits - based on anything you can program. Take a look at the programs in the - "contrib" directory of the CVS source tree. - - Use multiple Repositories, each with its own protection scheme. If - you use NFS (or AFS) you can even use "export" restrictions to various - groups of machines to keep (for example) the Engineering Repository - off the Customer Service machines. - - Try the "setgid" trick described in 4D.13. - - Try to use the RCS access control lists, though I don't think CVS - will handle them cleanly. - - Edit the source code to CVS to add your own access control. - - Last modified: _6/13/1997_ - - 16. What are the Repository Administrator's responsibilities? - - Generally, the Administrator should set "policy", create the - Repository and monitor its size and control files. - - Some specific responsibilities include: - - Examining the Repository once in a while to clean up: - - Trash files left by misguided developers who mistake the Repository - for a working directory. - - Non-RCS files. Other than the files CVS needs in the - $CVSROOT/CVSROOT directory, every file in the Repository should be an - RCS file. - - Lock files (both CVS '#*' and RCS ',*' files) left around after - crashes. - - Wrong permissions, groups and ownerships. - - Locked files. (RCS locks, that is.) - - Attic files that should never have been under CVS at all. Don't - blindly delete files from Attic directories -- they were mostly put - there (via the "cvs remove") for a reason. Files that should be - deleted are binary files (e.g. '*.o', 'core', executables) that were - mistakenly inserted by "import -I !". - - Maintaining the modules file. - - Storing site-specific ignore patterns in the - $CVSROOT/CVSROOT/cvsignore file. - - Storing the names of non-standard CVSROOT files (See 4B.2) in the - $CVSROOT/CVSROOT/checkoutlist - - Maintaining the other Repository control files: commitinfo, loginfo, - rcsinfo and editinfo. - - Pruning the history file every once in a while. (Try the - "cln_hist.pl" script in the "contrib" directory.) - - Staying aware of developments on the info-cvs mailing list and what - is available in the FTP and WWW archives. - - Running "ps ax" once in a while and kill off any "update" programs - not running as "root". It is too easy to leave the "cvs" off the front - of the "cvs update" command. - - Executing monitor programs to check the internal consistency of the - Repository files. Ideas: - - Files that have a default RCS branch that is not 1.1.1 (From an - abuse of "admin -b".) - - Files that have only Revisions 1.1 and 1.1.1.1, with a default - branch of "MAIN". (From an abuse of "admin -o".) - - Existing branch tags and various branch consistency checks. - - Last modified: _6/13/1997_ - - 17. How do I move the whole Repository? - - Copy or move the tree. (On Unix systems, a set of piped "tar" commands - works great. If the Repository does not contain any symlinks, which it - normally doesn't, you can also use "cp -r".) - - If you can avoid changing $CVSROOT (i.e. the "logical" pathname of the - Repository) by replacing the old location with a symbolic link to the - new location, you don't have to do anything else. - - (You could also mount the new location on top of the old location if - you are using NFS or some other filesystem that allows it.) - - If you must change $CVSROOT, you must also tell everyone to change the - CVSROOT environment variable in all running shells and in any personal - configuration files ('.' files on Unix) where it is set. - - The Repository itself contains no references to its own name, except - possibly in some of the files in the CVSROOT directory. If your - modules (or loginfo, commitinfo, etc.) file mentions helper programs - directly in the Repository, you'll have to change the pathnames to - point to the new Repository location. - - The main changes you'll have to make are to all the CVS administrative - files (./CVS/Repository and ./CVS/Root) in every working directory - ever checked out from the previous location of the Repository you just - moved. - - You have three choices: - - If all ./CVS/Repository files in all working directories contain - relative pathnames, you don't have to do anything else. - - Have everyone "release" or delete their working directories (after - committing, or just saving, their work) and check them all out again - from the new Repository after the move. - - Use "find . ( -name Repository -o -name Root )" and a PERL or shell - script to run through all the ./CVS/Repository and ./CVS/Root files - and edit the values in the files. - - Last modified: _6/13/1997_ - - 18. How do I change permissions on a file in the Repository by using a CVS - command? (i.e. without using "chmod 777 $CVSROOT/dir/file") - - When you first "import" or "add"/"commit" a file, the read and execute - bits on the Repository file are inherited from the original source - file, while the write bits on the Repository file are are turned off. - This is a standard RCS action. - - After that, there is no way to alter the permissions on a file in the - Repository using CVS (or RCS) commands. You have to change the - permissions on both your working file and on the Repository file from - which it was retrieved. - - Whenever you "checkout" the file or retrieve a new revision via - "update" (or after a "commit"), your working file is set to match the - permissions of the Repository file, minus any "umask" bits you have - set. - - Last modified: _6/13/1997_ - - Category: /Advanced_Topics_/Tricks_of_the_Trade/ - - " + Tricks of the Trade" - - 1. How can you even check in binary files, let alone allow CVS to do its - auto-merge trick on them? - - -First of all, if you want to use binary files, you should get RCS 5.7 -and CVS 1.9 or later (earlier versions had some support, but there have been -bug fixes). Secondly, follow the instructions for installing RCS very -carefully (it is easy to get it installed so it works for everything -except binary files). - -Then, specify 'cvs add -kb' instead of just 'cvs add' to add a binary -file. If you want to set an existing file to binary, run 'cvs admin --kb' (and then check in a new copy of the file). Note that old -versions of CVS used -ko instead of -kb for binary files, so if you -see a reference to -ko in the context of binary files, you should -think -kb instead. - -Of course when 'cvs update' finds that a merge is needed, it can't -do this for binary files the same way as for text files. With the -latest versions (e.g. CVS 1.9.14), it should be able to give you both -versions and let you merge manually. Another approach is to -run 'cvs admin -l' to lock files, as described in -"How can I lock files while I'm working on them the way RCS does?" -elsewhere in this FAQ. See also -"Is there any way to import binary files?" and -"How do I "add" a binary file?" elsewhere in this FAQ. - -kingdon@cyclic.com - - Last modified: _9/6/1997_ - - 2. Can I edit the RCS (",v") files in the Repository? - - Yes, but be very careful. The RCS files are not free-form files, they - have a structure that is easily broken by hand-editing. The only time - I would suggest doing this is to recover from emergency failures that - are difficult to deal with using CVS commands, including the "admin" - command, which can talk directly to RCS. - - Though no one actively encourages the editing of RCS files, many - people have succumbed to the urge to do so when pressed for time. The - reasons given, usually with evident contrition, include: - - - Editing mistakes in, or adding text to, log entries. (If you have - RCS 5.6 or later, you should use `cvs admin -m'.) - - Renaming or moving symbolic names. (You should `cvs admin -N' - instead.) - - Unlocking a file by changing the "locker" from someone else to - yourself. (It's safer to use `cvs admin -u -l'.) - - Making global changes to past history. Example: Eradicating former - employees names from old documents and Author entries. (And someone - thought the "history" command was evidence of Big Brother! I never - realized how much help a wide-open revision control system could have - provided to The Ministry of Truth.) - - Last modified: _6/13/1997_ - - 3. Can I edit the ./CVS/{Entries,Repository,Tag} files? - - Yes, but with CVS 1.3 and later, there is almost no reason to edit any - of the CVS administrative files. - - If you move pieces of your Repository around it can be faster to edit - all the ./CVS/Repository files rather than checking out a large tree. - But that is nearly the only reason to do so. - - Last modified: _6/13/1997_ - - 4. Someone executed "admin -o" and removed revisions to which tags/symbols - were attached. How do I fix them? - - It depends on what you mean by "fix". I can think of three ways to fix - your predicament: - - Remove the tags. - - Assuming you really wanted to get rid of the revision and its - associated tags, you can remove them with the "admin" command. The - "tag -d" command will only remove tags attached to existing revisions. - You can remove a tag, even if it is attached to a non-existent - revision, by typing: - - cvs admin -N - - Retrieve the outdated revision. - - You should first look in your backup system for recent versions of the - file. If you can't use them, you can carefully extract each revision - that followed the earliest outdated revision using RCS (or "cvs - admin") commands and reconstruct the file with all the right - revisions, branches and tags. This is a lot of work. - - You *can't* insert a revision into the current RCS file. - - Move the Tags to another revision in each file. - - If you want to move the tags to another valid revision, you have two - choices, both of which require that you find all the revision numbers - of the files you want to "tag" and execute the following command - sequences on each . - - Use "update" to grab the revision you want, then execute a normal - "tag" command to Tag that revision: - - cvs update -r - cvs tag - - Use "admin" to set the tag to a specific revision: - - cvs admin -N: - - Last modified: _6/13/1997_ - - 5. How do I move or rename a magic branch tag? - - (To rename a non-branch see 3O.9.) - - Before reading this, read 3M.3 and 3M.4 and understand exactly how tag - and rtag use '-r' and why it won't do the right job here. - - First, I have to explain exactly what a magic branch tag is. - - A magic is an artificial tag attached to a non-existent - revision on a non-existent branch number zero. It looks like this: - - TAG1:.0.Y - - is the "branch point revision", a normal revision with an - odd number of '.'s in it. (e.g. 1.5, 1.3.1.6, etc) - - Y is an even number (e.g. 2, 4, 6, etc.) All CVS branches, - other than the Vendor branch, are even numbered. - - TAG1 is considered by CVS to be attached to revision . The first - "update -r TAG1 " after applying TAG1 will produce a copy of - revision with a sticky tag of TAG1. The first "commit" to that - file will cause CVS to construct an RCS branch named .Y and check - in revision .Y.1 on the new branch. - - Note: TAG1 is *not* considered to be attached to by RCS, which - explains why you can't refer directly to the branch point revision for - some CVS commands. - - Moving a magic is the act of reapplying the same tag to - different revisions in the file: - - TAG1:.0.Y - to - TAG1:.0.Z or TAG1:.0.B - - You can move a magic branch tag to the revisions of your choice by - using "update" to find the revisions you want to tag and reapplying - the tag to all the files with the '-F' option to force it to move the - existing . - - cvs update -r (or '-A' for the Main Branch) - cvs tag -F -b - - If the earlier location of TAG1 refers to a physical branch within any - RCS file, moving it will make the existing branch in the file seem to - disappear from CVS's view. This is not a good idea unless you really - want to forget the existence of those RCS branches. - - If the "update" above retrieves the original branch point revision - (), the "tag" command above will create the tag: - - TAG1:.0.Z - - Where Z is 2 greater than the highest magic branch already on revision - . The TAG1 branch will still have the same branch point (i.e. - revision ), but the first commit to the new TAG1 branch will create - a different RCS branch number (.Z instead of .Y). - - Renaming a magic is the act of changing - - TAG1:.0.Y - to - TAG2:.0.Y - - There is no harm in changing a tag name as long as you forget that - TAG1 ever existed and you clean up any working directories with sticky - TAG1 tags on them by using "update -A", "update -r " or by - removing the working directories. - - On the other hand, actually changing the tag is not easy. - - See 3M.3 for why the seemingly obvious solution won't work: - - cvs tag -b -r - - The only direct way to rename a magic tag is to use the "admin" - command on each file: (You might want to use '-n'. Read "man rcs" and - look at the '-n' and '-N' options.) - - cvs admin -N: . - cvs tag -d - - But you have to be careful because "admin" is different from other CVS - commands: - - "admin" can be used recursively, but only by specifying directory - names in its argument list (e.g. '.'), - - Where "rtag -r " would interpret as - a magic CVS branch tag, "admin" is a direct interface to RCS which - sees a magic branch tag as a simple (though non-existent) RCS revision - number. - - This is good for us in this particular case, but different from normal - CVS. - - "admin" also skips the Attic and produces different kinds of errors - than CVS usually does. (Because they are coming directly from RCS.) - - The other way to rename a magic is to edit the Repository - files with a script of some kind. I've done it in the past, but I'll - leave it as an exercise for the reader. - - Last modified: _6/13/1997_ - - 6. Can I use RCS locally to record my changes without making them globally - visible by committing them? - - You can, but it will probably confuse CVS to have ",v" files in your - working directory. And you will lose all your log entries when you - finally commit it. - - Your best bet is to create your own CVS branch and work there. You can - commit as many revisions as you want, then merge it back into the main - line (or parent branch) when you are finished. - - Last modified: _6/13/1997_ - - 7. How can I allow access to the Repository by both CVS and RCS? - - The first step is to try not to. If some people are using CVS, there - is no reason for everyone not to. It is not hard to learn the basics - and CVS makes certain operations *easier* than a series of RCS - commands. Personal preference in what software tools can be applied to - a shared Repository has to take second place to system integration - needs. If you disagree, try writing some Lisp code for inclusion in - your Unix kernel and see what kind of reception you get. - - If you really must allow routine RCS access to the CVS Repository, you - can link an RCS sub-directory into a piece of the Repository: - - ln -s /Repository/some/directory/I/want RCS - - and RCS will work just fine. - - Those who are using RCS will have to keep the following in mind: - - If a file was originally added to the Repository by "import" and has - not been changed using CVS, the *RCS* default branch will remain - attached to the Vendor branch, causing revisions checked-in by "ci" to - wind up on the Vendor branch, instead of the main branch. Only CVS - moves the RCS default branch on first commit. - - The way around this is to checkin (using "ci") all the files first and - move them into the Repository. That way they won't have Vendor - branches. Then RCS will work OK. - - It is possible to use "rcs" and "ci" to make the files unusable by - CVS. The same is true of the CVS "admin" command. - - Normal RCS practice locks a file on checkout with "co -l". In such - an environment, RCS users should plan to keep survival gear and food - for at least 30 days near their desks. When faced with bizarre and - unexpected permission errors, howling mobs of slavering CVS users will - run the RCS users out of town with pitchforks and machetes. - - See 3C.8 for a way to avoid machetes aroused by lock collisions. - - Though files checked in by RCS users will correctly cause - "up-to-date" failures during CVS "commits" and they will be - auto-merged into CVS working directories during "update", the opposite - won't happen. - - RCS users will get no warning and will not be required to merge older - work into their code. They can easily checkin an old file on top of a - new revision added by CVS, discarding work committed earlier by CVS - users. - - See the howling mob scenario described above. - - RCS is great. I have used it for years. But I wouldn't mix it this - way. In a two-camp society, you are asking for real trouble, both in - technical hassles to clean up and in political hassles to soothe. - Branch merges will also be a major problem. - - Last modified: _6/13/1997_ - - 8. I "updated" a file my friend, "bubba", committed yesterday. Why doesn't - the file now have a modified date of yesterday? - - CVS restores dates from the RCS files only on first "checkout". After - that, it is more important to maintain a timestamp relative to the - other files in the working directory. - - Example: You committed a source file at 5PM. Bubba updated his copy of - the file, grabbing your changes, then changed and committed a new - revision of the file at 6PM. At 7PM, you compile your file. Then you - execute "update". If CVS sets the date to the one in the RCS file, the - file would be given a timestamp of 6PM and your Makefile wouldn't - rebuild anything that depended on it. Bad news. - - Note that the same logic applies to retrieving a revision out of the - Repository to replace a deleted file. If CVS changes your file in an - existing working directory, whether it was because a new revision was - committed by someone else or because you deleted your working file, - the timestamp on the retrieved working file *must* be set to the - current time. - - When you first retrieve a file, there is no reason to expect any - particular timestamp on the file within your working area. But later, - when dependency checking is performed during a build, it is more - important for the timestamps on the local files to be consistent with - each other than than it is for working files to match the timestamps - on the files in the Repository. See 4D.17 for some more about - timestamps. - - Last modified: _6/13/1997_ - - 9. Why do timestamps sometimes get set to the date of the revision, - sometimes not? The inconsistency causes unnecessary recompiles. - - The "checkout" command normally sets the timestamp of a working file - to match the timestamp stored on the revision in the Repository's RCS - file. - - The "commit" command retains the timestamp of the file, if the act of - checking it in didn't change it (by expanding keywords). - - The "update" command sets the time to the revision time the first time - it sees the file. After that, it sets the time of the file to the - current time. See 4D.8 for a reason why. - - Here's a two-line PERL program to set timestamps on files based on - other timestamps. I've found this program useful. When you are certain - you don't want a source file to be recompiled, you can set its - timestamp to the stamp on the object file. - - #!/usr/local/bin/perl - # - # Set timestamp of args 2nd-Last to that of the first arg. - # - ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime) - = stat(shift); - utime($atime,$mtime,@ARGV); - - Last modified: _6/13/1997_ - - 10. While in the middle of a large "commit", how do I run other commands, - like "diff" or "stat" without seeing lock errors? - - Type: - cvs -n - - The '-n' option to the main cvs command turns off lock checking, a - reasonable act for read-only commands given the promise offered by - '-n' not to alter anything. The "diff", "log" and "stat" commands - provide the same information (for files that are not being committed) - when used with and without the '-n' option. - - Warning: Ignoring locks can produce inconsistent information across a - collection of files if you are looking at the revisions affected by an - active commit. Be careful when creating "patches" from the output of - "cvs -n diff". If you are looking only at your working files, tagged - revisions, and BASE revisions (revisions whose numbers are read from - your ./CVS/Entries files), you should get consistent results. Of - course, if you catch a single file in the middle of RCS activity, you - might get some strange errors. - - Note that the suggested command is "cvs -n ". The visually - similar command "cvs -n" has no relation to the suggested - usage and has an entirely different meaning for each command. - - "cvs -n update" also works in the middle of a commit, providing - slightly different information from a plain "cvs update". But, of - course, it also avoids modifying anything. - - You could also use the RCS functions, "rlog" and "rcsdiff" to display - some of the information by referring directly to the Repository files. - - You need RCS version 5 or later for the commands described above to - work reliably. - - Last modified: _6/13/1997_ - - 11. Where did the ./CVS/Entries.Static file come from? What is it for? - - Each CVS working directory contains a ./CVS/Entries file listing the - files managed by CVS in that working directory. Normally, if the - "update" command finds a file in the Repository that is not in the - ./CVS/Entries file, "update" copies the appropriate revision of the - "new" file out of the Repository and adds the filename to the Entries - file. This happens for files: - - Added to the Repository from another working directory. - - Dragged out of the Attic when switching branches with "update -A" or - "update -r". - - Whose names were deleted from the ./CVS/Entries file. - - If the ./CVS/Entries.Static file exists, CVS will only bring out - revisions of files that are contained in either ./CVS/Entries or - ./CVS/Entries.Static. If a Repository file is found in *neither* file, - it is ignored. - - The ./CVS/Entries.Static file is created when you check out an - individual file or a module that creates working directories that - don't contain all files in the corresponding Repository directory. In - those cases, without an ./CVS/Entries.Static file, a simple "update" - would bring more files out of the Repository than the original - "checkout" wanted. - - The ./CVS/Entries.Static file can be removed by hand. It is - automatically removed if you run "update -d" to create new directories - (even if no new directories are created). (Internally, since - "checkout" turns on the '-d' flag and calls the "update" routine, a - "checkout" of a module or directory that writes into an existing - directory will also remove the ./CVS/Entries.Static file.) - - Last modified: _6/13/1997_ - - 12. Why did I get the wrong Repository in the loginfo message? - - You probably: - - Use multiple Repositories. - - Configured CVS to use absolute pathnames in the ./CVS/Repository - file. - - Configured CVS not to use the ./CVS/Root file. - - Typed the "commit" command in one Repository with your $CVSROOT - pointing at another. - - "commit" and all other CVS commands will heed an absolute pathname in - the ./CVS/Repository file (or in the "-d CVSrootdir" override), but - the log function doesn't take arguments -- it just looks at $CVSROOT. - - If you avoid even one of the four steps above, you won't see this - problem. If you configure ./CVS/Root, you won't be allowed to execute - the program causing the error. - - Last modified: _6/13/1997_ - - 13. How do I run CVS setuid so I can only allow access through the CVS - program itself? - - Setuid to root is not a great idea. Any program that modifies files - and is used by a widely distributed group of users is not a good - candidate for a setuid program. (The worst suggestion I've ever heard - was to make *Emacs* setuid to root.) - - Root access on Unix is too powerful. Also, it might not work in some - (secure?) environments. - - Running it setuid to some user other than root might work, if you add - this line to main.c near the beginning: - - setuid(geteuid()); - - Otherwise it uses *your* access rights, rather than the effective - uid's. - - Also, you have to invent a fake user whose name will show up in - various places. But many sites, especially those who might want a - setuid CVS for "security", want personal accountability -- no generic - accounts. I don't know whether accountability outweighs file security. - - And finally, unless you take action to limit the "admin" command, you - are leaving yourself unprotected anyway. - - Last modified: _6/13/1997_ - - 14. How about using groups and setgid() then? - - Here is a way to run CVS setgid in some environments: - - Stick this near the front of the main() in main.c: - - setgid(getegid()); - - This will allow "access" to work on systems where it only works on the - real gid. - - Create a group named "cvsg". (This example uses "cvsg". You can name - it as you wish.) - - Put *no* users in the "cvsg" group. You can put Repository - administrators in this group if you want to. - - Set the cvs executable to setgid (not setuid): - - cd /usr/local/bin; chown root.cvsg cvs; chmod 2755 cvs - - Make sure every file in the Repository is in group "cvsg": - - chown -R root.cvsg $CVSROOT - - Change all directory permissions to 770. This allows all access to - the files by the "cvsg" group (which has no members!) and no access at - all to anyone else. - - find $CVSROOT -type d -exec chmod 2770 {} \; - - On some systems you might have to type: - - find $CVSROOT -type d -exec chmod u=rwx,g=rwx,o=,g+s {} \; - - This should allow only the cvs program (or other "setgid to group - cvsg") programs to write into the area, but no one else. Yes the user - winds up owning the file, but s/he can't find it again later since - s/he can't traverse the tree. (If you enable the world execute bit - (mode 2771) on directories, users can traverse the tree and the user - who last wrote the file can still write to it.) - - If you want to allow read access, check out an entire tree somewhere. - You have to do this anyway to build it. - - Note: If you are using a stupid file system that can't inherit file - groups from the parent directory (even with the "setgid" (Octal 2000) - bit set), you might have to modify CVS (or RCS) to reset the group - every time you create a new file. I have not tested this. - - The setgid() method shares with the setuid() method the problem of - keeping "admin" from breaking things. - - Last modified: _6/13/1997_ - - 15. How do I use the "commitinfo" file? - - Go read 4B.2 first. - - The "commitinfo" file allows you to execute "sanity check" functions - before allowing a commit. If any function called from within the - commitinfo file exits with a non-zero status, the commit is denied. - - To fill out a "commitinfo" file, ask yourself (and those sharing your - Repository) these questions: - - - Is there anything you want to check or change before someone is - allowed to commit a file? If not, forget commitinfo. - - If you want to serialize binary files, you might consider something - like the rcslock.pl program in the contrib directory of the CVS - sources. - - - Do you want to execute the same exact thing before committing to - every file in the Repository? (This is useful if you want to program - the restrictions yourself.) If so, set up a single line in the - commitinfo: - - DEFAULT /absolute/path/to/program - - CVS executes the program once for each directory that "commit" - traverses, passing as arguments the directory and the files to be - committed within that directory. - - Write your program accordingly. Some examples exist in the contrib - directory. - - - Do you want a different kind of sanity check performed for different - directories? If so, you'll have to decide what to do for all - directories and enter lines like this: - - regexp1 /absolute/path/to/program-for-regexp1 - regexp2 /absolute/path/to/program-for-regexp2 - DEFAULT /absolute/path/to/program-for-all-else - - - Is there anything you want to happen before *all* commits, in - addition to other pattern matches? If so, include a line like this: - - ALL /absolute/path/to/program - - It is executed independently of all the above. And it's repeatable -- - you can have as many ALL lines as you like. - - Last modified: _6/13/1997_ - - 16. How do I use the "loginfo" files? - - See 4B.2 and the "commitinfo" question above. - - The "loginfo" file has the same format as the "commitinfo" file, but - its function is different. Where the "commitinfo" information is used - before a commit, the "loginfo" file is used after a commit. - - All the commands in the "loginfo" file should read data from standard - input, then either append it to a file or send a message to a mailing - list. If you want to make it simple, you can put shell (the shell used - by "popen(3)") command lines directly in the "loginfo" (or - "commitinfo") file. These seem to work: - - ^special /usr/ucb/Mail -s %s special-mailing-list ^other /usr/ucb/Mail - -s %s other-mailing-list DEFAULT (echo '===='; echo %s; cat) > - /path/name/to/log/file - - Last modified: _6/13/1997_ - - 17. How can I keep people with restrictive umask values from blocking - access to the Repository? - - If a user creates a new file with restricted permissions (e.g. 0600), - and commits it, the Repository will have a file in it that is - unreadable by everyone. The 0600 example would be unreadable by - *anyone* but root and the user who created it. - - There are 3 solutions to this: - - Let it happen. This is a valid way to protect things. If everyone is - working alone, a umask of 077 is OK. If everyone is working only in - small groups, a umask of 007 is OK. - - Train your users not to create such things if you expect to share - them. - - See 4B.5 for a small script that will reset the umask. - - I personally don't like the idea of a program automatically - *loosening* security. It would be better for you all to talk about the - issue and decide how to work together. - - Last modified: _6/13/1997_ - - Category: /Commands_/ - - " Commands " - - Category: /Commands_/add_ad_new/ - - " + "add", "ad", "new"" - - 1. What is "add" for? - - To add a new directory to the Repository or to register the desire to - add a new file to the Repository. - - The directory is created immediately, while the desire to add the file - is recorded in the local ./CVS administrative directory. To really add - the file to the Repository, you must then "commit" it. - - Last modified: _6/13/1997_ - - 2. How do I add a new file to the branch I'm working on? - - The user actions for adding a file to any branch, including the Main - Branch, are exactly the same. - - You are in a directory checked out (or updated) with the '-A' option - (to place you on the Main Branch) or the "-r " option (to - place you on a branch tagged with ). To add to the - branch you are on, you type: - - cvs add - cvs commit - - If no ./CVS/Tag file exists (the '-A' option deletes it), the file - will be added to the Main Branch. If a ./CVS/Tag file exists (the "-r - " option creates it), the file will be added to the branch - named (i.e. tagged with) . - - Unless you took steps to first add the file to the Main Branch, your - new file ends up in the Attic. - - Last modified: _6/13/1997_ - - 3. Why did my new file end up in the Attic? - - The file is thrown into the Attic to keep it from being visible when - you check out the Main Branch, since it was never committed to the - Main Branch. - - Last modified: _6/13/1997_ - - 4. Now that it's in the Attic, how do I connect it to the Main branch? - - That can be considered a kind of "merge". See 4C.8 - - Last modified: _6/13/1997_ - - 5. How do I avoid the hassle of reconnecting an Attic-only file to the Main - Branch? - - You create it on the Main Branch first, then branch it. - - If you haven't yet added the file or if you decided to delete the new - Attic file and start over, then do the following: (If you added the - file (or worse, the 157 files) to the Attic and don't want to start - over, try the procedure in 4C.8.) - - Temporarily remove the sticky branch information. Either: - - Move the whole directory back to the Main Branch. [This might not be - a good idea if you have modified files, since it will require a merge - in each direction.] - - cvs update -A - - *or* - - Move the ./CVS/Tag file out of the way. - - mv ./CVS/Tag HOLD_Tag - - Add and branch the file "normally": - - cvs add - cvs commit - cvs tag -b - - [ is the same Branch Tag as you used on all the other - files. Look at ./CVS/Entries or the output from "cvs stat" for sticky - tags.] - - Clean up the temporary step. - - If you moved the ./CVS/Tag file, put it back. Then move the new file - onto the branch where you are working. - - mv HOLD_Tag ./CVS/Tag - cvs update -r - - If you ran "update -A" rather than moving the ./CVS/Tag file, move - the whole directory (including the new file) back onto the branch - where you were working: - - cvs update -r - - Last modified: _6/13/1997_ - - 6. How do I cancel an "add"? - - If you want to remove the file entirely and cancel the "add" at the - same time, type: - - cvs remove -f - - If you want to cancel the "add", but leave the file as it was before - you typed "cvs add", then you have to fake it: - - mv .hold - cvs remove - mv .hold - - Last modified: _6/13/1997_ - - 7. What are the ./CVS/file,p and ./CVS/file,t files for? - - The ./CVS/file,p and ./CVS/file,t files are created by the "add" - command to hold command line options and message text between the time - of the "add" command and the expected "commit". - - The ./CVS/file,p file is always null, since its function was absorbed - by the "options" field in the ./CVS/Entries file. If you put something - in this file it will be used as arguments to the RCS "ci" command that - commit uses to check the file in, but CVS itself doesn't put anything - there. - - The ./CVS/file,t file is null unless you specify an initial message in - an "add -m 'message'" command. The text is handed to "rcs -i - -t./CVS/file,t" to create the initial RCS file container. - - Both files must exist to commit a newly added file. If the - ./CVS/file,p file doesn't exist, CVS prints an error and aborts the - commit. If the ./CVS/file,t file doesn't exist, RCS prints an error - and CVS gets confused, but does no harm. - - To recover from missing ,p and ,t files, just create two zero-length - files and rerun the "commit". - - Last modified: _6/13/1997_ - - 8. How do I "add" a binary file? - - If you configured CVS to use the GNU version of "diff" and "diff3", - you only need to turn off RCS keyword expansion. - - First you turn off RCS keyword expansion for the initial checkin by - using "add -ko". It works like "update -ko" in creating a "sticky" - option only for the copy of the file in the current working directory. - - cvs add -ko - - Commit the file normally. The sticky -ko option will be used. - - cvs commit - - Then mark the RCS file in the Repository so that keyword expansion is - turned off for all checked out versions of the file. - - cvs admin -ko - - Since "admin -ko" records the keyword substitution value in the - Repository's RCS file, you no longer need the sticky option. You can - turn it off with the "update -A" command, but if you were on a branch, - you'll have to follow it "update -r " to put yourself back - on the branch. - - Managing that binary file is another problem. See 4D.1. - - Last modified: _6/13/1997_ - - Category: /Commands_/admin_adm_rcs/ - - " + "admin", "adm", "rcs"" - - 1. What is "admin" for? - - To provide direct access to the underlying "rcs" command (which is not - documented in this FAQ) bypassing all safeguards and CVS assumptions. - - Last modified: _6/13/1997_ - - 2. Wow! Isn't that dangerous? - - Yes. - - Though you can't hurt the internal structure of an RCS file using its - own "rcs" command, you *can* change the underlying RCS files using - "admin" in ways that CVS can't handle. - - If you feel the need to use "admin", create some test files with the - RCS "ci" command and experiment on them with "rcs" before blasting any - CVS files. - - Last modified: _6/13/1997_ - - 3. What would I normally use "admin" for? - - Normally, you wouldn't use admin at all. In unusual circumstances, - experts can use it to set up or restore the internal RCS state that - CVS requires. - - You can use "admin -o" (for "outdate") to remove revisions you don't - care about. This has its own problems, such as leaving dangling Tags - and confusing the "update" command. - - There is some feeling among manipulators of binary files that "admin - -l" should be used to serialize access. See 3C.8. - - An interesting use for "admin" came up while maintaining CVS itself. I - import versions of CVS onto the Vendor branch of my copy of CVS, make - changes to some files and ship the diffs (created by "cvs diff -c -r - TO_BRIAN") off to Brian Berliner. After creating the diff, I retag - ("cvs tag -F TO_BRIAN") the working directory, which is then ready to - produce the next patch. - - I'll use "add.c" as an example (only because the name is short). - - When the next release came out, I discovered that the released "add.c" - (version 1.1.1.3 on the Vendor branch) was exactly the same as my - modified file (version 1.3). I didn't care about the changelog on - versions 1.2 and 1.3 (or the evidence of having done the work), so I - decided to revert the file to the state where it looked like I had not - touched the file -- where I was just using the latest on the vendor - branch after a sequence of imports. - - To do that, I removed all the revisions on the main branch, except for - the original 1.1 from which the Vendor branch sprouts: - - cvs admin -o1.2: add.c - - Then I set the RCS "default branch" back to the Vendor branch, the way - import would have created it: - - cvs admin -b1.1.1 add.c - - And I moved the "TO_BRIAN" Tag to the latest revision on the Vendor - branch, since that is the base from which further patches would be - created (if I made any): - - cvs admin -NTO_BRIAN:1.1.1.3 add.c - - Instead of 1.1.1.3, I could have used one of the "Release Tags" last - applied by "import" (3rd through Nth arguments). - - Suggestion: Practice on non-essential files. - - Last modified: _6/13/1997_ - - 4. What should I avoid when using "admin"? - - If you know exactly what you are doing, hack away. But under normal - circumstances: - - Never use "admin" to alter branches (using the '-b' option), which CVS - takes very seriously. If you change the default branch, CVS will not - work as expected. If you create new branches without using the "tag - -b" command, you may not be able to treat them as CVS branches. - - See 3C.8 for a short discussion of how to use "admin -l" for - serializing access to binary files. - - The "admin -o " allows you to delete revisions, usually a bad - idea. You should commit a correction rather than back out a revision. - Outdating a revision is prone to all sorts of problems: - - Discarding data is always a bad idea. Unless something in the - revision you just committed is a threat to your job or your life, - (like naming a function "_is_a_dweeb", or including the - combination to the local Mafioso's safe in a C comment), just leave it - there. No one cares about simple mistakes -- just commit a corrected - revision. - - The time travel paradoxes you can cause by changing history are not - worth the trouble. Even if CVS can't interfere with your parents' - introduction, it *can* log commits in at least two ways (history and - loginfo). The reports now lie -- the revision referred to in the logs - no longer exists. - - If you used "import" to place into CVS, outdating all the - revisions on the Main branch back to and including revision 1.2 (or - worse, 1.1), will produce an invalid CVS file. - - If the ,v file only contains revision 1.1 (and the connected - branch revision 1.1.1.1), then the default branch must be set to the - Vendor branch as it was when you first imported the file. Outdating - back through 1.2 doesn't restore the branch setting. Despite the above - admonition against it, "admin -b" is the only way to recover: - - cvs admin -b1.1.1 - - Although you can't outdate a physical (RCS) branch point without - removing the whole branch, you *can* outdate a revision referred to by - a magic branch tag. If you do so, you will invalidate the branch. - - If you "outdate" a tagged revision, you will invalidate all uses of - the , not just the one on . A tag is supposed to be - attached to a consistent set of files, usually a set built as a unit. - By discarding one of the files in the set, you have destroyed the - utility of the . And it leaves a dangling tag, which points to - nothing. - - And even worse, if you commit a revision already tagged, you will - alter what the pointed to without using the "tag" command. For - example, if revision 1.3 has attached to it and you "outdate" - the 1.3 revision, will point to a nonexistent revision. Although - this is annoying, it is nowhere near as much trouble as the problem - that will occur when you commit to this file again, recreating - revision 1.3. The old tag will point to the new revision, a file that - was not in existence when the was applied. And the discrepancy - is nearly undetectable. - - If you don't understand the above, you should not use the admin - command at all. - - Last modified: _6/13/1997_ - - 5. How do I restrict the "admin" command? The -i flag in the modules file - can restrict commits. What's the equivalent for "admin"? - - At this writing, to disable the "admin" command, you will have to - change the program source code, recompile and reinstall. - - Last modified: _6/13/1997_ - - 6. I backed out a revision with "admin -o" and committed a replacement. Why - doesn't "update" retrieve the new revision? - - CVS is confused because the revision in the ./CVS/Entries file matches - the latest revision in the Repository *and* the timestamp in the - ./CVS/Entries file matches your working file. CVS believes that your - file is "up-to-date" and doesn't need to be updated. - - You can cause CVS to notice the change by "touch"ing the file. - Unfortunately what CVS will tell you is that you have a "Modified" - file. If you then "commit" the file, you will bypass the normal CVS - check for "up-to-date" and will probably commit the revision that was - originally removed by "admin -o". - - Changing a file without changing the revision number confuses CVS no - matter whether you did it by replacing the revision (using "admin -o" - and "commit" or raw RCS commands) or by applying an editor directly to - a Repository (",v") file. Don't do it unless you are absolutely - certain no one has the latest revision of the file checked out. - - The best solution to this is to institute a program of deterrent - flogging of abusers of "admin -o". - - The "admin" command has other problems." See 3B.4 above. - - Last modified: _6/13/1997_ - - Category: /Commands_/checkout_co_get/ - - " + "checkout", "co", "get"" - - 1. What is "checkout" for? - - To acquire a copy of a module (or set of files) to work on. - - All work on files controlled by CVS starts with a "checkout". - - Last modified: _6/13/1997_ - - 2. What is the "module" that "checkout" takes on the command line? - - It is a name for a directory or a collection of files in the - Repository. It provides a compact name space and the ability to - execute before and after helper functions based on definitions in the - modules file. - - See 1D.11. - - Last modified: _6/13/1997_ - - 3. Isn't a CVS "checkout" just a bunch of RCS checkouts? - - Like much of CVS, a similar RCS concept is used to support a CVS - function. But a CVS checkout is *not* the same as an RCS checkout. - - Differences include: - - CVS does not lock the files. Others may access them at the same - time. - - CVS works best when you provide a name for a collection of files (a - module or a directory) rather than an explicit list of files to work - on. - - CVS remembers what revisions you checked out and what branch you are - on, simplifying later commands. - - Last modified: _6/13/1997_ - - 4. What's the difference between "update" and "checkout"? - - The "checkout" and "update" commands are nearly equivalent in how they - treat individual files. They differ in the following ways: - - The "checkout" command always creates a directory, moves into it, - then becomes equivalent to "update -d". - - The "update" command does not create directories unless you add the - '-d' option. - - "Update" is intended to be executed within a working directory - created by "checkout". It doesn't take a module or directory argument, - but figures out what Repository files to look at by reading the files - in the ./CVS administrative directory. - - The two commands generate completely different types of records in - the "history" file. - - Last modified: _6/13/1997_ - - 5. Why can't I check out a file from within my working directory? - - Though you *can* check out a file, you normally check out a module or - directory. And you normally do it only once at the beginning of a - project. - - After the initial "checkout", you can use the "update" command to - retrieve any file you want within the checked-out directory. There is - no need for further "checkout" commands. - - If you want to retrieve another module or directory to work on, you - must provide two pathnames: where to find it in the Repository and - where to put it on disk. The "modules" file and your current directory - supply two pieces of naming information. While inside a checked-out - working directory, the CVS administrative information provides most of - the rest. - - You should be careful not to confuse CVS with RCS and use "checkout" - in the RCS sense. An RCS "checkout" (which is performed by the RCS - "co" command) is closer to a "cvs update" than to a "cvs checkout". - - Last modified: _6/13/1997_ - - 6. How do I avoid dealing with those long relative pathnames? - - This question has also been phrased: - - How do I avoid all those layers of directories on checkout? or Why do - I have to go to the top of my working directory and checkout some long - pathname to get a file or two? - - This type of question occurs only among groups of people who decide - not to use "modules". The answer is to use "modules". - - When you hand the "checkout" command a relative pathname rather than a - module name, all directories in the path are created, maintaining the - same directory hierarchy as in the Repository. The same kind of - environment results if you specify a "module" that is really an alias - expanding into a list of relative pathnames rather than a list of - module names. - - If you use "module" names, "checkout" creates a single directory by - the name of the module in your current directory. This "module" - directory becomes your working directory. - - The "module" concept combines the ability to "name" a collection of - files with the ability to structure the Repository so that consistent - sets of files are checked out together. It is the responsibility of - the Repository Administrators to set up a modules file that describes - the software within the Repository. - - Last modified: _6/13/1997_ - - 7. Can I move a checked-out directory? Does CVS remember where it was - checked out? - - Yes and Yes. - - The ./CVS/Repository file in each working directory contains a - pathname pointing to the matching directory within the Repository. The - pathname is either absolute or relative to $CVSROOT, depending on how - you configured CVS. - - When you move a checked-out directory, the CVS administrative files - will move along with it. As long as you don't move the Repository - itself, or alter your $CVSROOT variable, the moved directory will - continue to be usable. - - CVS remembers where you checked out the directory in the "history" - file, which can be edited, or even ignored if you don't use the - "working directory" information displayed by the "history" command. - - Last modified: _6/13/1997_ - - 8. How can I lock files while I'm working on them the way RCS does? - - Until the day arrives of the all-powerful merge tool, there are still - files that must be accessed serially. For those instances, here's a - potential solution: - - Install a pre-commit program in the "commitinfo" file to check for - RCS locks. The program "rcslock.pl" performs this function. It can be - found in the contrib directory of the CVS source distribution. - - When you want to make a change to a file you know can't be merged, - first use "cvs admin -l" to lock the file. If you can't acquire the - lock, use the standard "locked out" protocol: go talk to the person - holding the lock. - - Make sure the pre-commit program prints a message and exits with a - non-zero status if someone besides the user running "commit" has the - file locked. This non-zero exist status will cause the "commit" to - fail cleanly. - - Make sure the pre-commit program exits with a zero status if the - file is either unlocked or locked by the user running "commit". The - "cvs commit" command that kicked off the pre-commit program will take - a zero exist status as an OK and checkin the file, which has the - side-effect of unlocking it. - - ===> The following is opinion and context. Don't read it if you are - looking for a quick fix. - - The topic of locking CVS files resurfaces on the network every so - often, producing the same results each time: - - The Big Endians: - - CVS was designed to avoid locks, using a copy-modify-merge model. - Locking is not necessary and you should take the time to learn the CVS - model which many people find workable. So why not get with the program - and learn how to think the CVS way? - - The Little Endians: - - The users determine how a tool is to be used, not the designers. We, - the users, have always used locking, our bosses demand locking, - locking is good, locking is God. I don't want to hear any more - lectures on the CVS model. Make locking work. - - Any organization making active changes to a source base will - eventually face the need to do parallel development. Parallel - development implies merges. (If you plan to keep separate copies of - everything and never merge, good luck. Tell me who you work for so I - can buy stock in your disk suppliers this year and sell your stock - short next year.) - - Merges will never go away. CVS chose to make "merges" stand front and - center as an important, common occurrence in development. It is one - way of looking at things. - - For free-format text, the merge paradigm gives you a considerable - amount of freedom. It does take a bit of management, but any project - should be ready to deal with it. - - On the other hand, there are many files that can't be merged using - text merge techniques. Straight text merge programs like "diff3" are - guaranteed to fail on executables (with relative branch statements), - files with self-referential counts stored in the file (such as TAGS - files), or files with relative motion statements in them (such as - Frame MIF files, many postscript files). They aren't all binary files. - - For these types of files, and many others, there are only two - solutions: - - Complex merge tools that are intimately aware of the contents of the - files to be merged. (ClearCase, and probably others, allow you to - define your own "files types" with associated "merge tools".) - - Serialization of access to the file. The only technical solution to - the problem of serialization is "locking". - - Since you can call a program that offers: - - "Which one do you want? A/B?" - - a "merge tool", more and more merge tools will appear which can be - hooked into a merge-intensive program like CVS. Think of a bitmap - "merge" tool that displays the bitmaps on the screen and offers a - "paint" interface to allow you to cut and paste, overlay, invert or - fuse the two images such that the result is a "merged" file. - - My conclusion is that the need for locking is temporary, awaiting - better technology. For large development groups, locking is not an - alternative to merging for text files. - - Last modified: _6/13/1997_ - - 9. What is "checkout -s"? How is it different from "checkout -c"? - - The '-c' and '-s' options to "checkout" both cause the modules file to - appear on standard output, but formatted differently. - - "checkout -c" lists the modules file alphabetized by the module name. - It also prints all data (including options like '-a' and "-o ") - specified in the modules file. - - "checkout -s" lists the modules file sorted by "status" field, then by - module name. The status field was intended to allow you to mark - modules with strings of your choice to get a quick sorted report based - on the data you chose to put in the status fields. I have used it for - priority ("Showstopper", etc as tied into a bug database), for porting - status ("Ported", "Compiled", etc. when porting a large collection of - modules), for "assignee" (the person responsible for maintenance), and - for "test suite" (which automatic test procedure to run for a - particular module). - - Last modified: _6/13/1997_ - - Category: /Commands_/commit_ci_com/ - - " + "commit", "ci", "com"" - - 1. What is "commit" for? - - To store new revisions in the Repository, making them visible to other - users. - - Last modified: _6/13/1997_ - - 2. If I edit ten files, do I have to type "commit" ten times? - - No. The "commit" command will take multiple filenames, directory names - and relative pathnames on the command line and commit them all with - the same log message. If a file is unchanged, even if it is explicitly - listed on the command line, CVS will skip it. - - Like all CVS commands, "commit" will work on the whole directory by - default. Just type "cvs commit" to tell CVS to commit all modified - files (i.e. the files that "update" would display preceded by 'M') in - the current directory and in all sub-directories. - - Last modified: _6/13/1997_ - - 3. Explain: cvs commit: Up-to-date check failed for `' - - You may not "commit" a file if your BASE revision (i.e. the revision - you last checked out, committed or retrieved via "update") doesn't - match the HEAD revision (i.e the latest revision on your branch, - usually the Main Branch). - - In other words, someone committed a revision since you last executed - "checkout", "update" or "commit". You must now execute "update" to - merge the other person's changes into your working file before - "commit" will work. You are thus protected (somewhat) from a common - form of race condition in source control systems, where a checkin of a - minor alteration of a second copy of the same base file obliterates - the changes made in the first. - - Normally, the "update" command's auto-merge should be followed by - another round of building and testing before the "commit". - - Last modified: _6/13/1997_ - - 4. What happens if two people try to "commit" conflicting changes? - - Conflicts can occur only when two developers check out the same - revision of the same file and make changes. The first developer to - commit the file has no chance of seeing the conflict. Only the second - developer runs into it, usually when faced with the "Up-to-date" error - explained in the previous question. - - There are two types of conflicts: - - When two developers make changes to the same section of code, the - auto-merge caused by "update" will print a 'C' on your terminal and - leave "overlap" markers in the file. - - You are expected to examine and clean them up before committing the - file. (That may be obvious to *some* of you, but . . .) - - A more difficult problem arises when two developers change different - sections of code, but make calls to, or somehow depend on, the old - version of each other's code. - - The auto-merge does the "right" thing, if you view the file as a - series of text lines. But as a program, the two developers have - created a problem for themselves. - - This is no different from making cross-referential changes in - *separate* files. CVS can't help you. In a perfect world, you would - each refer to the specification and resolve it independently. In the - real world you have to talk/argue, read code, test and debug until the - combined changes work again. - - Welcome to the world of parallel development. - - Last modified: _6/13/1997_ - - 5. I committed something and I don't like it. How do I remove it? - - Though you *can* use the "admin -o" (synonym: "rcs -o") command to - delete revisions, unless the file you committed is so embarrassing - that the need to eradicate it overrides the need to be careful, you - should just grab an old version of the file ("update -p -r - " might help here) and commit it on top of the offending - revision. - - See Section 3B on "admin". - - Last modified: _6/13/1997_ - - 6. Explain: cvs commit: sticky tag `V3' for file `X' is not a branch - - The message implies two things: - - You created your working directory by using "checkout -r V3", or you - recently executed "update -r V3". - - The tag named V3 is not a branch tag. - - CVS records (i.e. makes "sticky") any "-r " argument handed - to the "checkout" or "update" commands. The is recorded as - the CVS working branch, which is the branch to which "commit" will add - a new revision. - - Branch tags are created when you use the -b switch on the "tag" or - "rtag" commands. Branch tags are magic tags that don't create a - physical branch, but merely mark the revision to branch from when the - branch is needed. The first commit to a magic branch creates a - physical branch in the RCS files. - - You can commit onto the end of the Main Trunk, if you have no sticky - tag at all, or onto the end of a branch, if you have a sticky branch - tag. But you can't commit a file that has a sticky tag not pointing to - a branch. CVS assumes a sticky Tag or Revision that does not refer to - a branch is attached to the middle of a series of revisions. You can't - squeeze a new revision between two others. Sticky dates also block - commits since they never refer to a branch. - - Scenario1: - - If you don't want a branch and were just looking at an old revision, - then you can move back to the Main Branch by typing: - - cvs update -A {files or dirs, default is '.'} - - or you can move to the branch named by: - - cvs update -r {files or dirs, default is '.'} - - Scenario2: - - If you really wanted to be on a branch and made an earlier mistake by - tagging your branch point with a non-branch tag, you can recover by - adding a new branch tag to the old non-branch tag: - - cvs rtag -b -r - - (It was not a big mistake. Branch-point tags can be useful. But the - must have a different name.) - - If you don't know the name or don't use "modules", you can - also use "tag" this way: - - cvs update -r - cvs tag -b . - - Then, to put your working directory onto the branch, you type: - - cvs update -r - - You can't delete before adding , and I would not - advise deleting the at all, because it is useful in referring - to the branch point. If you must, you can delete the non-branch tag - by: - - cvs rtag -d - or - cvs tag -d . - - Scenario3: - - If you made the same mistake as in Scenario2 (of placing a non-branch - tag where you wanted a branch tag), but really want to be the - name of your branch, you can execute a slightly different series of - commands to rename it and move your working directory onto the branch. - - Warning: This is not a way to rename a branch tag. It is a way to turn - a non-branch tag into a branch tag with the same name. - - cvs rtag -r - cvs rtag -d - cvs rtag -b -r - - Then, if you really must, delete the : - - cvs rtag -d - - Note: The unwieldy mixture of "tag" and "rtag" is mostly because you - can't specify a revision (-r ) to the "tag" command. - - See 4C.3 for more info on creating a branch. - - Last modified: _6/13/1997_ - - 7. Why does "commit -r " put newly added files in the Attic? - - If you specify "-r " (where is a dotted numeric number like - 2.4), it correctly sets the initial revision to , but it also - attaches the numeric as a sticky tag and throws the file into - the Attic. This is a bug. The obvious solution is to move the file out - of the Attic into the associated Repository directory and "update -A" - the file. There are no Tags to clean up. - - If you specify "-r " to commit a newly added file, the is - treated like a , which becomes a symbolic RCS label - pointing to the string '1', which can be considered to be the "Main - branch number" when the main branch is still at revision 1.N. The file - is also thrown into the Attic. See 4C.8 for a way to recover from - this. - - In fact, a plain "commit" without the "-r" will throw a newly added - file into the Attic if you added it to a directory checked out on a - branch. See 3A.[2-5]. - - See Section 4C, on Branching, for many more details. - - Last modified: _6/13/1997_ - - 8. Why would a "commit" of a newly added file not produce rev 1.1? - - When committing a newly added file CVS looks for the highest main - branch major number in all files in the ./CVS/Entries file. Normally - it is '1', but if you have a file of revision 3.27 in your directory, - CVS will find the '3' and create revision 3.1 for the first rev of - . Normally, the first revision is 1.1. - - Last modified: _6/13/1997_ - - Category: /Commands_/diff_di_dif/ - - " + "diff", "di", "dif"" - - 1. What is "diff" for? - - To display the difference between a working file and its BASE - revision (the revision last checked out, updated or committed): - - cvs diff - - To display the difference between a working file and a committed - revision of the same file: - - cvs diff -r - - To display the difference between two committed revisions of the - same file: - - cvs diff -r -r - - You can specify any number of arguments. Without any - arguments, it compares the whole directory. - - In the examples above, "-D " may be substituted wherever "-r - " appears. The revision a refers to is the revision - that existed on that date. - - Last modified: _6/13/1997_ - - 2. Why did "diff" display nothing when I know there are later committed - revisions in the Repository? - - By default, "diff" displays the difference between your working file - and the BASE revision. If you haven't made any changes to the file - since your last "checkout", "update" or "commit" there is no - difference to display. - - To display the difference between your working file and the latest - revision committed to your current branch, type: - - cvs diff -r HEAD - - Last modified: _6/13/1997_ - - 3. How do I display what changed in the Repository since I last executed - "checkout", "update" or "commit"? - - A special tag (interpreted by CVS -- it does not appear in the Tag - list) named "BASE" always refers to the revision you last checked out, - updated or committed. Another special tag named "HEAD" always refers - to the latest revision on your working branch. - - To compare BASE and HEAD, you type: - - cvs diff -r BASE -r HEAD - - Last modified: _6/13/1997_ - - 4. How do I display the difference between my working file and what I - checked in last Thursday? - - cvs diff -D "last Thursday" - - where "last Thursday" is a date string. To be more precise, the - argument to the '-D' option is a timestamp. Many formats are accepted. - See the man page under "-D date_spec" for details. - - Last modified: _6/13/1997_ - - 5. Why can't I pass long options, like --unified, to "diff"? - - CVS only handles single character '-X' arguments, not the FSF long - options. CVS also passes through only arguments it knows about, - because a few arguments are captured and interpreted by CVS. - - If you didn't configure RCS and CVS to use the GNU version of diff, - long options wouldn't work even if future versions of CVS acquire the - ability to pass them through. - - Most of the long options have equivalent single-character options, - which do work. The "--unified" option is equivalent to '-u' in - revisions of GNU diff since 1.15. - - Last modified: _6/13/1997_ - - Category: /Commands_/export_exp_ex/ - - " + "export", "exp", "ex"" - - 1. What is "export" for? - - "export" checks out a copy of a module in a form intended for export - outside the CVS environment. The "export" command produces the same - directory and file structure as the "checkout" command, but it doesn't - create "CVS" sub-directories and it removes all the RCS keywords from - the files. - - Last modified: _6/13/1997_ - - 2. Why does it remove the RCS keywords so I can't use the "ident" command - on the source files? - - It removes the RCS keywords, so that if the recipient of the exported - sources checks them into another set of RCS files (with or without - CVS), and then makes modifications through RCS or CVS commands, the - revision numbers that they had when you exported them will be - preserved. (That ident no longer works is just an unfortunate side - effect.) - - The theory is that you are exporting the sources to someone else who - will make independent changes, and at some point you or they will want - to know what revisions from your Repository they started with - (probably to merge changes, or to try to decide whether to merge - changes). - - A better way to handle this situation would be to give them their own - branch of your Repository. They would need to remember to checkin the - exported sources with RCS IDs intact (ci -k) so that their changes - would get revision numbers from the branch, rather than starting at - 1.1 again. Perhaps a future version of CVS will provide a way to - export sources this way. - - Contributed by Dan Franklin - - Last modified: _6/13/1997_ - - 3. Can I override the '-kv' flag CVS passes to RCS? - - Not as of CVS version 1.4. - - Last modified: _6/13/1997_ - - 4. Why doesn't "export" have a '-k' flag like "import" does? - - Export is intended for a specific purpose -- to remove all trace of - revision control on the way *out* of CVS. - - Last modified: _6/13/1997_ - - 5. Why does "export -D" check out every file in the Attic? - - See 5B.3 for an explanation of the same problem with "update". - - Last modified: _6/13/1997_ - - Category: /Commands_/history_hi_his/ - - " + "history", "hi", "his"" - - 1. What is "history" for? - - To provide information difficult or impossible to extract out of the - RCS files, such as a "tag" history or a summary of module activities. - - Last modified: _6/13/1997_ - - 2. Of what use is it? - - I have found it useful in a number of ways, including: - - Providing a list of files changed since - - - A tagged release. - - Yesterday, last Thursday, or a specific date. - - Someone changed a specific file. - - Providing a list of special events: - - - Files added or removed since one of the above events. - - Merge failures since one of the above events. (Where did the - conflicts occur?) - - Has anyone (and who) grabbed the revision of this file I committed - last week, or are they still working blind? - - Telling me how often a file/directory/module has been changed. - - Dumping a summary of work done on a particular module, including who - last worked on it and what changed. - - Displaying the checked-out modules and where they are being worked - on. - - To tell me what users "joe" and "malcolm" have done this week. - - Last modified: _6/13/1997_ - - 3. What is this, Big Brother? - - War is Peace. - Freedom is Slavery. - Ignorance is Strength. - - Normally manager types and those with the power to play Big Brother - don't care about this information. The Software Engineer responsible - for integration usually wants to know who is working on what and what - changed. Use your imagination. - - Last modified: _6/13/1997_ - - 4. I deleted my working directory and "history" still says I have it - checked out. How do I fix it? - - You can use "release -f" to forcibly add a "release" record to the - history file for a working directory associated with a "module". If - your version of "release" doesn't have the '-f' option, or you checked - out the directory using a relative path, you have to edit the - $CVSROOT/CVSROOT/history file. - - You can remove the last 'O' line in the history file referring to the - module in question or add an 'F' record. - - Last modified: _6/13/1997_ - - 5. So I *can* edit the History file? - - Yes, but if you are using history at all, you should take a little - care not to lose information. I normally use Emacs on the file, since - it can detect that a file has changed out from under it. You could - also copy and zero out the history file, edit the copy and append any - new records to the edited copy before replacing it. - - Last modified: _6/13/1997_ - - 6. Why does the history file grow so quickly? - - It stores 'U' records, which come in handy sometimes when you are - tracking whether people have updated each other's code before testing. - There should (and probably will sometime) be a way to choose what - kinds of events go into the history file. - - The contributed "cln_hist.pl" script will remove all the 'U' records, - plus matching pairs of 'O' and 'F' records during your normal clean up - of the history file. - - Last modified: _6/13/1997_ - - 7. What is the difference between "cvs history -r " and "cvs - history -t "? - - The '-t' option looks for a Tag record stored by "rtag" in the history - file and limits the search to dates after the last of the given - name was added. - - The '-r' option was intended to search all files looking for the - in the RCS files. It takes forever and needs to be rewritten. - - Last modified: _6/13/1997_ - - 8. Why does "cvs history -c -t " fail to print anything? - - You have been using "tag" instead of "rtag". The "tag" command - currently doesn't store a history record. This is another remnant of - CVS's earlier firm belief in "modules". But it also has a basis in how - "rtag" and "tag" were originally used. - - "rtag" was intended for large-scale tagging of large chunks of the - Repository, an event work recording. "tag" was intended for adding and - updating tags on a few files or directories, though it could also be - used to tag the entire checked-out working tree when there is no - module defined to match the tree or when the working tree is the only - place where the right collection of revisions to tag can be found. - - Last modified: _6/13/1997_ - - 9. "cvs history -a -o" only printed one line for each checked-out module. - Shouldn't it print all the directories where the modules are checked out? - - Not as designed. - - Command Question it is supposed to answer. - ---------------- ------------------------------------------ - cvs history -o What modules do I have checked out? - cvs history -a -o - - cvs history -o -w What working directories have I created - and what modules are in them? - cvs history -a -o -w - - The -o option chooses the "checked out modules" report, which is the - default history report. - - Last modified: _6/13/1997_ - - 10. I can't figure out "history", can you give me concrete examples? - - Default output selects records only for the user who executes the - "history" command. To see records for other users, add one or more "-u - user" options or the '-a' option to select *all* users. - - To list (for the selected users): Type "cvs history" and: - - * Checked out modules: -o (the default) - * Files added since creation: -x A - * Modified files since creation: -c - * Modified files since last Friday: -c -D 'last Friday' - * Modified files since TAG was added: -c -t - * Modified files since TAG on files: -c -r - * Last modifier of file/Repository X? -c -l -[fp] X - * Modified files since string "str": -c -b str - * Tag history: (Actually "rtag".) -T - * History of file/Repository/module X: -[fpn] X - * Module report on "module": -m module - - Last modified: _6/13/1997_ - - 11. Can we merge history files when we merge Repositories? - - Assuming that the two Repositories have different sets of pathnames, - it should be possible to merge two history files by sorting them - together by the timestamp fields. - - You should be able to run: - - sort -k 1.2 ${dir1}/history ${dir2}/history > history - - If you "diff" a standard history file before and after such a sort, - you might see other differences caused by garbage (split lines, nulls, - etc) in the file. If your Repository is mounted through NFS onto - multiple machines you will also see a few differences caused by - different clocks on different machines. (Especially if you don't use - NTP to keep the clocks in sync.) - - Last modified: _6/13/1997_ - - Category: /Commands_/import_im_imp/ - - " + "import", "im", "imp"" - - 1. What is "import" for? - - The "import" command is a fast way to insert a whole tree of files - into CVS. - - The first "import" to a particular file within the Repository creates - an RCS file with a single revision on the "Vendor branch." Subsequent - "import"s of the same file within the Repository append a new revision - onto the Vendor branch. It does not, as some seem to believe, create a - new branch for each "import". All "imports" are appended to the single - Vendor branch. - - If the file hasn't changed, no new revision is created -- the new - "Release-Tag" is added to the previous revision. - - After the import is finished, files you have not changed locally are - considered to have changed in the "Main line of development". Files - you *have* changed locally must have the new Vendor code merged into - them before they are visible on the "Main line". - - See 4C.6 and 4C.15 - - Last modified: _6/13/1997_ - - 2. How am I supposed to use "import"? - - Create a source directory containing only the files you want to - import. Make sure you clean up any cruft left over from previous - builds or editing. You want to make sure that the directory contains - only what you want to call "source" from which everything else is - built. - - If this is not the first import from this "Vendor", you should also - compare the output of "find . ! -name CVS -print | sort" executed both - at the head of a checked out working directory and at the head of the - sources to be imported. If you find any deleted or renamed files, you - have to deal with them by hand. (See 4B.8 on renaming.) - - "cd" into your source directory and type: - - cvs import -m "Message" - - where is the relative directory pathname within the Repository - that corresponds to the sources you are importing. - - You might also consider using the "-I !" option to avoid ignoring - anything. It is easier to remove bogus files from the Repository than - to create a sparse tree of the ignored files and rerun "import". - - For example, if the FSF, CVS, Make and I are still active in the year - 2015, I'll import version 89.53 of GNU make this way: - - cvs import -m "GNUmake V89.53" gnu/make GNU GNUMAKE_89_53 - - See 3H.13 for more details. - - Last modified: _6/13/1997_ - - 3. Why does import put files on a branch? Why can't I work on the main - trunk instead of a Vendor branch? - - This was a Design choice. The Vendor branch is the way "import" deals - with a Vendor release. It is a solution to the Engineering problem of - how to merge multiple external releases of Vendor-supplied sources - into your ongoing work. The Vendor releases are kept on a separate, - special, "Vendor" branch and your work is kept on the RCS trunk. New - Vendor releases are imported onto the Vendor branch and then merged - into your work, if there is any, on the trunk. - - This way, you can use CVS to find out not only about your work, but - you can also find out what the Vendor changed by diffing between two - of the Release Tags you handed to "import". - - CVS was designed to work this way. If you use CVS in some other way, - you should think carefully about what you are doing. - - Note that the CVS "Main Branch" and the RCS Main Trunk are not the - same. Placing files on the Vendor Branch doesn't keep you from - creating a development branch to work on. - - See Section 4C, on Branching. - - If you are not working with 3rd party (i.e. Vendor) sources, you can - skip the "import" and avoid the Vendor branch entirely. It works just - as well to move pre-existing RCS files into Repository directories. - - You can create a whole Repository tree by copying a directory - hierarchy of normal source files directly into the Repository and - applying CVS to it. Here's an idea you should *test* before using: - - cd - set source = `pwd` - set module = xyzzy <<== Your choice of directory name - mkdir $CVSROOT/$module - cd $CVSROOT/$module - (cd $source; tar cf - .) | tar xvpBf - - find . -type f -exec ci -t-Original. {} \; - - The RCS "ci" command, without -u or -l options, will turn your source - file into an RCS (",v") and delete the original source. - - Last modified: _6/13/1997_ - - 4. Is there any way to import binary files? - - If you configured CVS to use the GNU version of "diff" and "diff3", - then you can import any kind of file. - - Binary files with RCS keywords in them are a problem, since you don't - want them to expand. - - If the tree you are about to "import" is entirely filled with binary - files, you can use the '-ko' option on "import". Otherwise, I would - run the import normally, then fix the binary files as described below - in 3H.5. - - See 4D.1 on Binary files. - - Last modified: _6/13/1997_ - - 5. Why does "import" corrupt some binary files? - - The RCS "co" command, when it is invoked by a CVS "checkout" or - "update" (or after a "commit") command, searches for and expands a - list of keywords within the file. They are documented in the RCS "co" - man page. Strings such as "$\Id$" (or "$\Id:"), or "$\Revision$" (or - "$\Revision:") are altered to the include the indicated information. - - [[Note: The keywords should appear in the text without the '\' - character I have inserted to *avoid* expansion here. The only real RCS - keywords in this document are at the top of the file, where I store - the Revision and Date.]] - - If RCS keyword strings show up in a binary file, they will be altered - unless you set the '-ko' option on the RCS files to tell RCS to keep - the original keyword values and not to expand new ones. After - "import", you can set the '-ko' option this way: - - cvs admin -ko - rm - cvs update - - After an import that didn't use '-ko' (because the whole tree wasn't - of binary files) you should fix up the binary files as described above - before checking out any new copies of the files and before updating - any working directories you checked out earlier. - - See 4D.1 on Binary files. - - Last modified: _6/13/1997_ - - 6. How do I retain the original $\Revision$ strings in the sources? - - If you want to leave old RCS keywords as they are, you can use the - '-ko' tricks described above. - - Last modified: _6/13/1997_ - - 7. I imported some files for the Yarg compiler that compiles files with a - suffix of ".yarg" and whose comment prefix is "YARG> ". When I check them - out, they will no longer compile because they have this junk in them. Why? - - YARG>YARG>YARG>YARG>YARG>YARG>YARG>YARG>YARG>YARG>YARG>YARG>YARG> - YARG> $\Log: - # Revision 1.3 1998/03/03 00:16:16 bubba - # What is 2+2 anyway? - # - # Revision 1.2 1998/03/03 00:15:15 bubba - # Added scorekeeping. - YARG> - YARG>YARG>YARG>YARG>YARG>YARG>YARG>YARG>YARG>YARG>YARG>YARG>YARG> - - Well bubba, "Yarg" hasn't hit the big time yet. Neither RCS nor CVS - know about your suffix or your comment prefix. So you have two - choices: - - Check out the Yarg-less module, and tell all the files about your - comment prefix. Visit each directory and type: - - cvs admin -c"YARG> " *.yarg - - If *all* files in the whole directory tree are Yarg files, you can use - this instead: - - cvs admin -c"YARG> " . - - Then save any changes you made, remove all the "*.yarg" files and grab - new copies from the Repository: - - rm *.yarg (or: find . -name '*.yarg' -exec rm {} ';') (or: find . - -name '*.yarg' -print | xargs rm) (or: find . -name '*.yarg' -print0 | - xargs -0 rm if you have spaces in filenames and the GNU find/xargs.) - cvs update - - It might be faster to remove the whole directory and check it out - again. - - Change the import.c file in the CVS sources and add the .yarg - suffix, along with the "YARG> " comment prefix to the "comtable" - array. - - If you ever plan to add new files with $\Log in them, you should also - go into the RCS sources and make the same change in the table - contained in the "rcsfnms.c" file. - - Then delete the imported files from the Repository and re-"import" the - sources. - - Last modified: _6/13/1997_ - - 8. How do I make "import" save the timestamps on the original files? - - Use "import -d" to save the current timestamps on the files as the RCS - revision times. - - See 4D.8 for another aspect of file timestamps. - - Last modified: _6/13/1997_ - - 9. Why can't I "import" 3 releases on different branches? - - I'll bet you typed something like this: - - cd /src/blasto.v2 - cvs import -b 1.1.2 VENDOR2 Version2 - cd /src/blasto.v3 - cvs import -b 1.1.3 VENDOR3 Version3 - cd /src/blasto.v4 - cvs import -b 1.1.4 VENDOR4 Version4 - - This is wrong, or at least it won't help you much. You have created - three separate Vendor branches, which is probably not what you wanted. - - Earlier versions of CVS, as described in Brian Berliner's Usenix - paper, tried to support multiple Vendor branches on the theory that - you might receive source for the *same* program from multiple vendors. - It turns out that this is very rare, whereas the need to branch in - *your* development, for releases and for project branches, is much - greater. - - So the model now is to use a single vendor branch to contain a series - of releases from the same vendor. Your work moves along on the Main - Trunk, or on a CVS branch to support a real "branch in development". - - To set this up, you should type this instead of the above: - - cd /src/blasto.v2 - cvs import VENDOR Version2 - cd /src/blasto.v3 - cvs import VENDOR Version3 - cd /src/blasto.v4 - cvs import VENDOR Version4 - - Last modified: _6/13/1997_ - - 10. What do I do if the Vendor adds or deletes files between releases? - - Added files show up with no extra effort. To handle "removed" files, - you should always compare the tree structure of the new release - against the one you have in your Repository. If the Vendor has removed - files since the previous release, go into a working directory - containing your current version of the sources and "cvs remove" - (followed by "cvs commit" to make it really take effect) each file - that is no longer in the latest release. - - Using this scheme will allow you to "checkout" any version of the - vendor's code, with the correct revisions and files, by using - "checkout -r Version[234]". - - Renames are harder to find, since you have to compare file contents to - determine that one has occurred. If you notice one, see 4B.8 on - renaming files. - - Last modified: _6/13/1997_ - - 11. What about if the Vendor changes the names of files or directories, or - rearranges the whole structure between releases? - - Currently CVS can't handle this cleanly. It requires "renaming" a - bunch of files or directories. - - See 4B.8 on "renaming" for more details. - - What I generally do is to close the Repository for a while and make - changes in both the Repository and in a copy of the vendor release - until the structure matches, then execute the import. - - If you ever have to check out and build an old version, you may have - to use the new, or completely different Makefiles. - - Last modified: _6/13/1997_ - - 12. I thought "import" was for Vendor releases, why would I use it for code - of my own? Do I have to use import? - - For code you produce yourself, "import" is a convenience for fast - insertion of whole trees. It is not necessary. You can just as easily - create ",v" files using the RCS "ci" command and move them directly - into the Repository. - - Other than the CVSROOT directory, the Repository consists entirely of - directories of ",v" files. The Repository contains no other state - information. - - See Section 4B, on Setting up and Managing the Repository. - - Last modified: _6/13/1997_ - - 13. How do I import a large Vendor release? - - When the sum of the changes made by the Vendor and the changes made by - local developers is small, "import" is not a big problem. But when you - are managing a large Repository, any care taken up front will save you - time later. - - First read the following, then, before executing "import", see the - questions in Section 4C dealing with branch merges and Vendor branch - merges. - - If this is not the first import of this code, before starting, rtag - the whole directory you will be changing. - - The first step is to make sure the structure of the new files - matches the structure of the current Repository. - - Run "find . -print | sort" on both trees and "diff" the output. - - Alter the "source" tree until the "diff" (of the list of filenames, - not of the whole trees) shows that the directory structures are - equivalent. - - The "comm" command, if you have it, can help figure out what has been - added or deleted between releases. - - If they deleted any files, you can handle them cleanly with "cvs - remove". The command "comm -23 files.old files.new" will show you a - list of files that need to be removed. - - You should examine the list first to see if any have been renamed - rather than simply deleted. - - If they renamed any files, see 4B.8 on renaming files. - - Remember to *SAVE* the output from the import command. - - When you have dealt with removed and renamed files, then you can - execute the import: - - cd - cvs import -I ! -m "Message" - - Where - - "-I !" is an optional argument that keeps "import" from ignoring - files. The comparison of the "find" commands above will probably avoid - the need for this, but it is easier to remove files from the - Repository than to run a subset "import" to catch just the ignored - files. [You might have to quote or backwhack the '!'.] - - Message is the log message to be stored in the RCS files. - - is a relative path to a directory within the - Repository. The directory must be at - the same relative level within the new sources as - the you give is within the Repository. (I - realize this is not obvious. Experiment first.) - - is a Tag used to identify the Vendor who sent you - the files you are importing. All "imports" into - the same *must* use the same VendorTag. - You can find it later by using the "log" command. - - is a Tag used to identify the particular release of the - software you are importing. It must be unique and should be mnemonic - -- at least include the revision number in it. (Note: you can't use - '.' characters in a Tag. Substitute '_' or '-'.) - - There will be six categories of files to deal with. (Actually there - are eight, but you have already dealt with "removed" and "renamed" - files.) - - If this is the first "import" into a given directory, only the - first three of these ('I', 'L' and 'N') can occur. - - Ignored file. - - CVS prints: I filename - - You'll need to examine it to see if it *should* have been ignored. If - you use "-I !", nothing will be ignored. - - Symbolic link. - - CVS prints: L linkname - - Links are "ignored", but you'll probably want to create a "checkout - helper" function to regenerate them. - - New file. - - CVS prints: N filename - - CVS creates a new file in the Repository. You don't have to do - anything to the file, but you might have to change Makefiles to refer - to it if this is really a new file. - - A file unchanged by the Vendor since its last release. - - CVS prints: U filename - - CVS will notice this and simply add the new ReleaseTag to the latest - rev on the Vendor branch. - - No work will be needed by you, whether you have changed the file or - not. No one will notice anything. - - A file changed by the Vendor, but not by you. - - CVS prints: U filename - - CVS should add the file onto the vendor branch and attach the Release - Tag to it. - - When you next execute "update" in any working directory you'll get the - new revision. - - A file changed by both the Vendor and by you. - - CVS prints: C filename - - These are the trouble files. For each of these files (or in groups -- - I usually do one directory at a time), you must execute: - - cvs update -j -j - or - cvs update -j -j - - It will print either 'M' (if no overlaps) or 'C', if overlaps. If a - 'C' shows up, you'll need to edit the file by hand. - - Then, for every file, you'll need to execute "cvs commit". - - See the part of Section 4C dealing with branch merges. - - If you are truly performing a large import, you will most likely - need help. Managing those people is another problem area. - - Since the merge of the Vendor branch is just like any other merge, you - should read section 4C for more info about performing and cleaning up - merges. - - The larger the import, and the larger the group of people involved, - the more often you should use "tag" and "rtag" to record even trivial - milestones. See 4C.14, especially the "paranoid" section. - - Before starting the import, you should install and test a "commitinfo" - procedure to record all commits in a file or via Email to a mail - archive. Along with the tags you placed on the Repository before the - import, this archive will help to track what was changed, if problems - occur - - There are four stages to the recovery: - - Parcel out the work -- Effective Emacs Engineering. - - As input to the assignment process, you might want to examine the tree - and record the last person who changed the file. You can also - research, if you don't already know, who is expert in each area of the - software. - - Examine the import log (you saved the output, right?), estimate how - much work is involved in each area and assign groups of files to - individual developers. Unless some directory is immense, it is easier - to manage if you assign whole directories to one person. - - Keep a list. Suggest a completion date/time. Tell them to "commit" the - file when they are finished with the merge. If you tagged the - Repository before starting the import, you should have no trouble - figuring out what happened. - - If you can, find out (or tell them) which working directory to use. - You should verify that the working directory they use is on the Main - Branch ("update -A") and without modified files. - - If you trust your crew, have them notify you by Email. Have them send - you the output from "cvs update" in their working directory. You might - have to poll some people until you are certain they have finished, or - have given up. (This is not an invention. I've heard a false, "Yeah, - sure. I finished yesterday," more times that you'd believe.) - - When all reports are in, go on to the Source Verification stage. - - Source Verification -- CVS and other Tools. - - If you didn't dictate which ones to use, find all working directories - and run "cvs -n update" in all of them. The history command and the - "commitinfo" log you set up might help to find checked out working - directories. - - Sticky conflict flags will help, but they can't recover from - sloppiness or incompetence. You might want to check everything out - into a tree and grep for the parts of the merge conflict markers CVS - doesn't look for. CVS looks for the string '^>>>>>>> '. The merge - operation also puts '^<<<<<<< ' and '^======= ' markers in the file - that careless developers might leave there. - - If you find problems simply by looking at the source files and working - directories, start the flogging now. Resolving the textual conflicts - is the easy part. Weed the turkeys out before reaching the next part - of the cleanup -- the resolution of logical conflicts. - - Then apply a set of post-commit tags. - - Logical Verification -- Diff and powerful eyeballs. - - No source control system can solve the problem of resolving - distributed conflicts in program logic. If you change the argument - template for function A (defined in file A.c) and add new calls to - function A from within function B (defined in file B.c) using the old - argument format, you are outside the realm of CVS's competence. - - Assign someone to understand what the Vendor changed by running "cvs - diff -c -r ", where the tags were - those handed to the last two invocations of "import". - - Then have the same person compare that output (logically or you can - actually diff the diffs) to the output of the similar "cvs diff -c -r - ". The two sets of differences - should be almost identical. They should both show only the work *you* - have performed. - - Product Verification -- Build and Test. - - Don't let your help off the hook until you verify that the merge - actually produced something that can compile and pass tests. Compiling - should really be part of the logical verification phase, but you - should test the output of the build system before declaring victory - and releasing the troops. - - After it is all built, apply another set of tags to mark the end of - the "import process". You can delete the intermediate tags you added - during source and logic testing, but keep the "pre-import" and - "post-import" tags forever. - - Of course, experience can tell you when to skip a step. But I'd start - out by considering each one as necessary unless you can prove - otherwise. - - Last modified: _6/13/1997_ - - 14. Explain: ERROR: cannot create link to : Permission denied - - This error appears when you try to execute a second (or later) - "import" into the same module from a directory to which you don't have - write access. - - The "link error" is caused by a feature purposely added to speed up - the import. - - Though the error message is somewhat strange, it indicates that - "import" is supposed to be executed only in writable directories. - - Last modified: _6/13/1997_ - - 15. Where does the -m go when the file doesn't change? - - The handed to import is used as an RCS log message, but only - if the imported file changed since the last version on the Vendor - branch. If the imported file hasn't changed, then no new revision is - created. The is still applied, but to the previous - revision. So the Tags are still correct, but the message is lost. - - Maybe it should be appended to the previous log message. But currently - it isn't. - - Last modified: _6/13/1997_ - - 16. How do I "import" just the files ignored by a previous "import"? - - A real answer follows, but first, an editorial: - - I am now convinced that you should always use the "-I !" option. - Removing a few extraneous files from the Repository is a lot easier - than the recovery step described below. - - Let's assume your original import procedure was: (We assume there is - enough disk space in /tmp.) - - cd - cvs import -m 'xyz 1.3' gnu/xyz GNU GNUXYZ_1_3 | tee /tmp/IMP - - To import just the files ignored by "import", I would do this: - - Create a list of the ignored files to import: - - cd awk '/^I / {print $2}' /tmp/IMP | sed - 's|^gnu/xyz/||' > /tmp/IG [Edit the IG file to contain just the files - you want.] - - Then create a sparse directory by handing your list to the GNU - version of "tar", installed in many places as "gtar": - - mkdir /tmp/FIXUP gtar -T /tmp/IG -c -f - . | (cd /tmp/FIXUP; gtar xvBf - -) - - Then rerun the import. Use the exact same command, but execute it in - the sparse directory tree you just created. And this time, tell it not - to ignore anything. - - cd /tmp/FIXUP - cvs import -I ! -m 'xyz 1.3' gnu/xyz GNU GNUXYZ_1_3 - - Last modified: _6/13/1997_ - - 17. Why did "import" ignore all the symlinks? - - This is another design choice. - - Like the Unix "tar" command, "import" could sprout an option to follow - symbolic links, but I don't think CVS will ever follow symbolic links - by default. - - Two possible future enhancements have been seriously discussed: - - Treat symbolic links as data in its parent directory (the way - ClearCase does) in some sort of per-directory control file. - - Treat symbolic links as version-controlled elements themselves, - whose data is the value of readlink(2). - - For now, they are simply ignored. - - If you want to save and reconstruct symlinks, you might want to define - a "checkout" or "update" program in the modules file which could - consult a file kept under CVS in your working directory and make sure - the specified links are in place. - - Last modified: _6/13/1997_ - - Category: /Commands_/log_lo_rlog/ - - " + "log", "lo", "rlog"" - - 1. What is "log" for? - - To provide an interface to the RCS "rlog" command, which displays - information about the underlying RCS files, including the revision - history and Tag (RCS calls it a "symbol") list. - - Last modified: _6/13/1997_ - - 2. How do I extract the log entries between two revisions? - - If both and are on the same branch, you can get what you - are looking for with: (If they aren't on the same branch you'll either - get an error or a display of the whole change log.) - - cvs log -r: - - If you want all the revisions on the branch from to the end of - the branch is on, you can use: - - cvs log -r: - - (If is a numeric RCS symbol attached to a branch revision with - an even number of '.'s in it, you get the whole branch.) - - If you want all the revisions on the branch from the beginning of the - branch is on up to revision , you can use: - - cvs log -r: - - Note: Depending on whether and are: - - - numeric or symbolic - - in the file or not - - on the same branch or not - - the RCS "rlog" (and therefore the "cvs log") command will - display some combination of: - - - error messages - - (intuitively correct) partial log listings - - a display of the entire change log. - - Last modified: _6/13/1997_ - - 3. How do I extract the log entries on a whole branch? - - cvs log -r - - where must be a branch revision (one with an even number of - dots) or a *non-branch* tag on a branch revision. Non-branch tags on a - branch revision are not normally attached by CVS, to add one you will - have to explicitly tag a physical branch number within each file. - Since these branch numbers are almost never the same in different - files, this command is not all that useful. - - The intuitive command (at least from the CVS perspective): - - cvs log -r - - does not work. - - Last modified: _6/13/1997_ - - 4. How do I generate ChangeLogs from RCS logs? - - A program called rcs2log is distributed as part of GNU Emacs 19. A - (possibly older) version of this program appears in the contrib - directory of the cvs source tree. - - Last modified: _6/13/1997_ - - 5. Why does "log" tell me a file was committed exactly 5 hours later - - than I know it was? - - I can tell by this question that you were working in a time zone that - is 5 hours behind GMT (e.g. the U.S. East Coast in winter). - - RCS file dates are stored in GMT to allow users in different time - zones to agree on the meaning of a timestamp. At first glance this - doesn't seem necessary, but many companies use distributed file - systems, such as NFS or AFS, across multiple timezones. - - Some standard form must be used. GMT, as the "grid origin", is an - obvious candidate. The only other reasonable choice is to put the - timezone information in all the time stamps, but that changes the RCS - file format incompatibly, a step which has been avoided in the last - few RCS releases. - - Last modified: _6/13/1997_ - - Category: /Commands_/patch_pa_rdiff/ - - " + "patch", "pa", "rdiff"" - - 1. What is "patch" for? - - To produce a "diff" between tagged releases to be handed to the - "patch" command at other sites. This is the standard way that source - patches are distributed on the network. - - Last modified: _6/13/1997_ - - 2. Why does "patch" include files from the Attic when I use '-D'? - - See the explanation of the same problem with "update -D" contained in - section 5B. - - Last modified: _6/13/1997_ - - 3. How do I make "patch" produce a patch for one or two files? It seems to - work only with modules. - - Patch is intended for producing patches of whole modules between - releases to be distributed to remote sites. Instead of "patch", you - can use the "diff" command with the '-c' context option: - - cvs diff -c -r -r . . . - - The patch command will be able to merge such a "diff" into the remote - source files. - - If you configured CVS to use a version of "diff" that supports the - '-u' option, you can produce a more compact "patch" in "unidiff" - format. The latest revisions of the patch command can parse and apply - patches in "unidiff" format. - - Last modified: _6/13/1997_ - - Category: /Commands_/release_re_rel/ - - " + "release", "re", "rel"" - - 1. What is "release" for? - - To register that a module is no longer in use. It is intended to - reverse the effects of a "checkout" by adding a record to the history - file to balance the checkout record and by optionally allowing you to - delete the checked-out directory associated with the module name. - - Last modified: _6/13/1997_ - - 2. Why can't I reverse a "cvs checkout path/name/subdir" with a "cvs - release path/name/subdir" without an "unknown module name"? - - A simplistic implementation. (I can say this -- I wrote it.) - - The "release" function was written for CVS 1.2 under the assumption - that the "module name" is a first class, unavoidable interface to the - Repository, allowing no way to retrieve anything other than by module - name. Though it is easier to program that way, many users of CVS - believe the modules support to be too primitive to allow such a - limitation. - - Since "release" was written, other parts of CVS broke that assumption. - It needs to be revised. - - Last modified: _6/13/1997_ - - 3. Why can't I "release" portions of a checked out directory? I should be - able to "release" any file or sub-directory within my working directory. - - This isn't really a limitation in "release", per se. CVS doesn't try - to keep track of which files in which directories are "checked out" - and which are just lying there. You can delete directories and - "update" will not bring them back unless you add a special "-d" - option. - - In other words, CVS doesn't keep track of how you adjust the partition - between files you consider part of your working set and files that - were checked out because they are part of the same module or - directory. And neither does "release". - - In future CVS releases, "release" might become sophisticated enough to - handle both the reversal of a "checkout" and the deletion of random - portions of the working directory, but it isn't that way now. - - Last modified: _6/13/1997_ - - 4. I removed the tree that I was about to start working on. How do I tell - cvs that I want to release it if I don't have it anymore? - - See 3G.4. - - Last modified: _6/13/1997_ - - 5. Why doesn't "release -d module" reverse a "checkout module"? - - It does, if you are using "module" in a way that "release" expects: a - non-alias string in the left column of the "modules" database. - - If "module" is really an alias, or if you are using a relative path in - the place of "module", or if you renamed the directory with the -d - option in the modules file or on the "checkout" command line, then the - current version of "release" won't work. - - Future versions of "release" will probably fix most of these. - - Last modified: _6/13/1997_ - - 6. Why can't I release a module renamed with "cvs checkout -d"? - - The current version of "release" doesn't know how to track the - renaming option ('-d') of the "checkout" command. It will probably be - fixed in the future. - - Last modified: _6/13/1997_ - - Category: /Commands_/remove_rm_delete/ - - " + "remove", "rm", "delete"" - - 1. What is "remove" for? - - To remove a file from the working branch. It removes a file from the - main branch by placing it in an "Attic" directory. - - Last modified: _6/13/1997_ - - 2. Why doesn't "remove" work on directories when it appears to try? - - Oversight. It should be able to delete an empty directory, but you - still don't have a way to remember when it was there and when it - disappeared to allow the "-D " option to work. - - You'll have to remove the working directory and the matching directory - in the Repository. - - Note that you want to do a _cvs remove dir_ in the working directory, - do a cvs commit, and then do a _rmdir dir_ in the Repository. - (msusrtsp.mark at eds dot com) - - Last modified: _12/18/1997_ - - 3. I don't like removing files. Is there another way to ignore them? - - There's no reason to be hasty in using the "remove" command. - - If there is a way to ignore files in your build procedures, I'd just - do that. Later, when you decide that the files are really ancient, you - can execute a "remove" command to clean up. - - The CVS "ignore" concept can't ignore files already in CVS. - - Last modified: _6/13/1997_ - - 4. I just removed a file. How do I resurrect it? - - If you executed "remove", but haven't typed "commit" (you can tell - this by the 'R' notation that "update" prints next to the file), you - can execute "add" to reverse the "remove". - - If you followed the "remove" with a "commit", you'll have to move it - back out of the Attic by hand: - - I use something like this: (csh-like syntax) - - set repos = `cat ./CVS/Repository` - mv $repos/Attic/filename,v $repos/filename,v - - (If you use relative paths in your Repository files, that first line - becomes: set repos = $CVSROOT/`cat ./CVS/Repository`) - - While a file is in the Attic, you can't "add" another file by the same - name. To add such a file you either have to move it by hand as in the - above, or delete it from the Attic. - - The main reason for the Attic is to retain files with tags in them. If - you execute: "update -r ", files with attached to - some revision will be taken from the normal Repository area and from - the Attic. That's why you can't "add" a file with the same name. - "remove" only moves a file off the main branch, it doesn't obliterate - it. - - Last modified: _6/13/1997_ - - 5. Why doesn't "remove" delete the file? Instead, it prints an error - message and tells me to remove the file by hand. - - Design choice. Unix software written within last decade, usually - requires an extra verification step, such as answering a question or - adding a flag on the command line. CVS currently requires that you - delete the file first unless you specify the '-f' (force) option, - which deletes the file before performing "cvs remove". - - Last modified: _6/13/1997_ - - Category: /Commands_/rtag_rt_rfreeze/ - - " + "rtag", "rt", "rfreeze"" - - 1. What is "rtag" for? - - To add a symbolic label (a "tag") to the last committed revisions of a - module directly in the Repository. - - Last modified: _6/13/1997_ - - 2. Why use "rtag"? It assumes no one is changing the Repository. - - Though the "tag" command is more useful in marking the revisions you - have in a particular working directory, "rtag" is much handier for - whole-Repository actions, which occur at major release boundaries. - - Last modified: _6/13/1997_ - - 3. What revision does "rtag -r " actually put the tag on? - - In short, the '-r' option is another way to select the revision to - tag. The revision is selected the same way for all commands that - accept a "-r " option. - - Depending on whether is a , or a non-branch - and on whether you use the '-b' option to "rtag", you get four - different results: - - rtag -r - - Adds the non-branch tag to the same revision that the - non-branch tag is attached to. - - Example: - --> TT1 - --> TT2 - --> Symbols: TT1:1.4 - After --> Symbols: TT1:1.4,TT2:1.4 - - rtag -r - - Adds the non-branch tag to the HEAD of (the highest revision - number on) the branch labelled with tag . - - Example: - --> BR1 - --> TT2 - --> Symbols: BR1:1.2.0.2 (1.2.2.5 is HEAD) - After --> Symbols: BR1:1.2.0.2,TT2:1.2.2.5 - - If the branch tagged by has not been created, then the - tag shows up on the branch point revision: - - Example: - --> BR1 - --> TT2 - --> Symbols: BR1:1.2.0.2 (No 1.2.X exists.) - After --> Symbols: BR1:1.2.0.2,TT2:1.2 - - rtag -b -r - - Adds the magic branch tag to the revision that the - non-branch tag is attached to, preparing it to be a branch - point. - - Example: - --> TT1 - --> BR2 - --> Symbol: TT1:1.4 - After --> Symbol: TT1:1.4, BR2:1.4.0.2 - - rtag -b -r - - Adds the magic branch tag to the revision at the HEAD of - (the highest revision number on) the branch labelled with - , preparing it to be a branch point. - - Example: - --> BR1 - --> BR2 - --> Symbol: BR1:1.2.0.2 (1.2.2.5 is HEAD) - After --> Symbol: BR1:1.2.0.2,BR2:1.2.2.5.0.2 - - If the branch tagged by has not been created, then the - tag shows up as a second branch off the same branch point revision: - - Example: - --> BR1 - --> TT2 - --> Symbols: BR1:1.2.0.2 (No 1.2.X exists.) - After --> Symbols: BR1:1.2.0.2,TT2:1.2.0.4 - - In all four cases above, if already exists on the file, you get - an error unless you specify the '-F' option. - - In all four cases, if does not exist on the file, is not - added unless you specify the '-f' option. - - Last modified: _6/13/1997_ - - 4. What happens if the tags are the same in "rtag -r "? - - Again, there are four cases depending on whether is a branch - tag, or a non-branch tag and on whether you use the '-b' option to - "rtag": - - rtag -r - - Is a no-op. It does nothing even with '-F' specified. - - If you add the '-f' option ("rtag -f -r "), then is - attached to the latest revision on the Main Branch if the file does - *not* already have on some revision. - - If the is already on the file, using "rtag -f" is still a no-op. - - rtag -r - - Produces an error, since the is already on some revision - of the file. - - But, "rtag -F -r " turns the magic branch tag - into a non-branch tag. - - Symbols: BR1:1.4.0.2 becomes Symbols: BR1:1.4 - - rtag -b -r - - Produces an error, since the is already on the file. - - But, "rtag -F -b -r " turns the non-branch tag into a magic - branch tag. - - Symbols: BR1:1.4 becomes Symbols: BR1:1.4.0.2 - - rtag -b -r - - Produces an error, since the is already on the file. - - But, "rtag -F -b -r " increments the branch - number. It essentially removes the branch and creates a new one by the - same name. - - Symbols: BR1:1.2.0.4 becomes Symbols: BR1:1.2.0.6 - - Last modified: _6/13/1997_ - - 5. Why doesn't "rtag -b -r " rename or duplicate - a magic branch tag? - - None of the "tag" or "rtag" options rename anything. They only apply - (or, with the '-F' option, move) tags to specific revisions in the - file. - - See 3M.[3-4] above for details of how it works. - - To rename a non-branch tag, see 3O.9. To rename a magic branch tag, - see 4D.5 - - Last modified: _6/13/1997_ - - Category: /Commands_/status_st_stat/ - - " + "status", "st", "stat"" - - 1. What is "status" for? - - To display the status of files, including the revision and branch you - are working on and the existence of "sticky" information. - - Last modified: _6/13/1997_ - - 2. Why does "status" limit the File: at the top to 17 characters? - - Designed that way to line up with other data. You can find the whole - filename in the line beginning with "RCS version:", which is not - limited in length. - - Last modified: _6/13/1997_ - - 3. Why does it print "Sticky" lines when the values are "(none)"? - - Oversight. It should probably elide lines without information. - - Last modified: _6/13/1997_ - - 4. Shouldn't the status "Needs Checkout" be "Needs Update"? - - Probably. - - [[Did this show up in CVS 1.4?]] - - Last modified: _6/13/1997_ - - Category: /Commands_/tag_ta_freeze/ - - " + "tag", "ta", "freeze"" - - 1. What is "tag" for? - - To add a symbolic label (a "tag") to the RCS files last checked out, - updated or committed in a working directory. - - Last modified: _6/13/1997_ - - 2. What is the difference between "tag" and "rtag"? - - The end result of both commands is that a , or symbolic name, is - attached to a single revision in each of a collection of files. - - The differences lie in: - - The collection of files they work on. - - "rtag" works on the collection of files referred to by a "module" name - as defined in the "modules" file, or a relative path within the - Repository. - - "tag" works on files and directories specified on the command line - within the user's working directory. (Default is '.') - - Both commands recursively follow directory hierarchies within the - named files and directories. - - The revisions they choose to tag. - - "rtag" places a tag on the latest committed revision of each file on - the branch specified by the '-r' option. By default it tags the Main - Branch. - - "tag" places a tag on the BASE (i.e. last checked out, updated or - committed) revision of each file found in the working directory. (The - BASE revision of a file is the one stored in the ./CVS/Entries file.) - - A different set of command line options. - - For example, "rtag" takes a "-r " option to retag an existing - tag. The "tag" command does not. - - How it is logged. - - Currently "rtag" records the and the module in the "history" - file, while "tag" does not. - - Last modified: _6/13/1997_ - - 3. Why does "tag -b" not put a tag on the Branch Point revision? How do I - refer to the Branch Point? - - This is probably an oversight, or a disbelief in the need for it. If - everything works perfectly, the "update -j" command will do the merge - you need and you don't need to check up on it by playing with the - branch point revision. - - The '-b' option attaches a magic branch tag to allow CVS later to - figure out the branch point. The actual revision that is - attached to does not exist. References to the branch tag are - equivalent to references to the latest revision on the branch. - - There is no way to refer to the branch point without adding a - non-branch tag. You might want to add non-branch tags as a habit and - add branch tags later, possibly immediate after adding the non-branch - tag. See 4C.3 on Creating a Branch. - - Last modified: _6/13/1997_ - - 4. So "{r}tag" labels a bunch of files. What do you use a Tag for? - - You use it to "checkout" the labeled collection of files as a single - object, referring to it by name. - - Anywhere a revision number can be used a Tag can be used. In fact tags - are more useful because they draw a line through a collection of - files, marking a development milestone. - - The way to think about a Tag is as a curve drawn through a matrix of - filename vs. revision number. Consider this: - - Say we have 5 files (in some arbitrary modules, some may be in 2 or - more modules by name, some may be in 2 or more modules because of the - Repository tree structure) with the following revisions: - - file1 file2 file3 file4 file5 - - 1.1 1.1 1.1 1.1 /--1.1* <-*- - 1.2*- 1.2 1.2 -1.2*- - 1.3 \- 1.3*- 1.3 / 1.3 - 1.4 \ 1.4 / 1.4 - \-1.5*- 1.5 - 1.6 - - At some time in the past, the '*' versions were tagged. Think of the - as a handle attached to the curve drawn through the tagged - revisions. When you pull on the handle, you get all the tagged - revisions. Another way to look at it is that you draw a straight line - through the set of revisions you care about and shuffle the other - revisions accordingly. Like this: - - file1 file2 file3 file4 file5 - - 1.1 - 1.2 - 1.1 1.3 _ - 1.1 1.2 1.4 1.1 / - 1.2*----1.3*----1.5*----1.2*----1.1 (--- <-- Look here - 1.3 1.6 1.3 \_ - 1.4 1.4 - 1.5 - - I find that using these visual aids, it is much easier to understand - what a is and what it is useful for. - - Last modified: _6/13/1997_ - - 5. How do I get "tag" and "rtag" to send mail the way "commit" does? - - The "commit" command is supported by two files ("commitinfo" and - "loginfo") not used by other commands. To do logging the same way for - "tag" and "rtag" would require another file like loginfo, which - currently doesn't exist. - - The "rtag" command requires a "module" entry, which can specify a - "tag" program using the "-t programname" option on the module line. - - There is no equivalent support for "tag". - - Last modified: _6/13/1997_ - - 6. Why can't "tag" handle the '-r' option that "rtag" takes? - - Oversight. The answer is probably "Fixed in a Future Release." - - Last modified: _6/13/1997_ - - 7. After a "tag " in my working directory, why doesn't "checkout -r - " somewhere else produce copies of my current files? - - The only reason this would fail, other than misspelling the - string, is that you didn't "commit" your work before "tagging" it. - Only committed revisions may be tagged. Modified files are not marked - for later tagging. - - Last modified: _6/13/1997_ - - 8. Why doesn't "tag" write a history record the way "rtag" does? - - The "rtag" command was originally intended to place major "release" - tags onto modules. The "tag" functionality was developed to *move* the - more significant tag when slight changes to individual files sneaked - in after the release tag was stamped onto the Repository. - - The significant event was the "rtag", which was recorded in the - "history" file for the "history -T" option to work. - - It turns out that "tag" is generally more useful than "rtag", so the - model has changed. Future revisions of CVS will probably store both - kinds of tags in the history file. - - Last modified: _6/13/1997_ - - 9. How do I rename a ? - - For a procedure to rename a branch tag, See section 4D.5 The following - covers only non-branch tags. - - First, pick a that is not in use. You could reuse (i.e. move) - an existing tag to the new revisions using the '-F' option, but that - will confuse matters when both tags are not already on a file. (It - will probably confuse "rtag -f" too.) - - Use "rtag" to place only on revisions attached to in - the whole Repository, then delete the old one. - - cvs rtag -r world - cvs rtag -d world. - - You can also checkout or update your working directory to the - and "tag" rather than "rtag" the result. But that will take longer and - it has the chance of producing conflicts. - - cvs update -r - cvs tag - cvs tag -d - cvs update -A (or cvs update -r ) - - Last modified: _6/13/1997_ - - Category: /Commands_/update_up_upd/ - - " + "update", "up", "upd"" - - 1. What is "update" for? - - The "update" command is by far the most important command and is - probably also the most used command. - - It has five purposes: (And many options.) - - To display the status of your working files. - - Though a plain "update" also displays the status, it does so after - possibly altering your working directory. To see the status of your - working files without changing anything, type: - - cvs -n update {optional list of files} - - To merge changes made by others to the branch you are working on - into your working files. - - Each working directory is attached to a branch, usually the Main - branch. To merge changes made on your working branch since your last - checkout, update or commit, type: - - cvs update {optional list of files} - - To merge changes made on another branch into the branch you are - working on (your "working branch"). - - If you want to grab a whole branch, from the branch point, which is - assumed to be on the Main Branch, to the end of the branch, you type: - - cvs update -j {optional files} - - If you want to grab the changes made between two tags or revisions, - you type: - - cvs update -j -j {optional files} - - (If you are working with a single file, the Tags could also be - revisions numbers. Unless you take great care to match revision - numbers across different files (a waste of time given the way Tags - work), using revision numbers in place of the Tags for multiple files - would be meaningless.) - - To move your working directory to another branch. - - A working directory is presumed to be attached to (or working on) a - particular branch, usually the Main branch. To alter what CVS believes - to be your working branch, you "move" to that branch. - - To move to a tagged branch, type: - - cvs update -r {optional files} - - To move to the Main Branch, type: - - cvs update -A {optional files} - - If you have modified files in your working directory, this is not a - clean move. CVS will attempt to merge the changes necessary to make it - look like you made the same changes to the new branch as you made in - the old one. But if you do this twice without resolving the merge - conflicts each time, you can lose work. - - To retrieve old revisions of files. - - This option is similar to 4 above but you are not restricted to using - a . You may specify any revision or with '-r' and - get the specified revision or the tagged revision: - - cvs update -r {optional files} - - Or you may specify any date with '-D': - - cvs update -D {optional files} - - The '-p' option sends the revisions to standard output (normally your - terminal) rather than setting the "sticky" tag and changing the files. - - Last modified: _6/13/1997_ - - 2. What do 'U', 'M' and 'C' mean when I type "update"? Are they different - for "cvs -n update"? - - "cvs update" merges changes made to the Repository, since your last - "checkout", "update" or "commit", into your working files. You can - think of it as changing your BASE revision. - - "cvs update" prints lines beginning with: - - 'U' after replacing your unmodified file with a different - revision from the Repository. - - 'M' for two different reasons: - - for files you have modified that have not changed in the Repository. - - after a merge, if it detected no conflicts. - - 'C' after a merge, if it detected conflicts. See 2D.7 and 3P.6 for - more info on conflict resolution and "sticky conflicts." - - "cvs -n update" shows what it *would* do, rather than doing it. Or, - another way of looking at it, "cvs -n update" displays the - relationship between your current BASE revisions (identified in your - ./CVS/Entries file) and the HEAD revisions (the latest revisions in - the Repository). - - "cvs -n update" prints lines beginning with: - - 'U' for files you have not modified that have changed in the - Repository. - - 'M' for files you have modified that have not changed in the - Repository. - - 'C' for files you have modified that have also been changed in the - Repository. - - See 4C.6 for what the letters mean when merging in from another - branch. The output is almost the same for a normal update if you - consider the Repository as the branch and your working directory as - the "trunk". - - Last modified: _6/13/1997_ - - 3. What's the difference between "update" and "checkout"? - - See 3C.4 above. - - Last modified: _6/13/1997_ - - 4. Why don't I get new files when I execute "update"? - - There are six reasons for nothing to happen during an "update": - - Nothing on your branch changed in the Repository. - - If no one has committed anything to the branch you are working on - (normally the Main branch) since the last time you executed - "checkout", "update" or "commit", nothing will happen. - - It's like shouting "xyzzy" or "plugh" in the wrong room. - - You have a "sticky" non-branch or attached to the - working files you are trying to "update". - - At some time in the past you checked out or updated your directory - with the "-r " or "-D " option. Until you do it again with - a different tag or date, or go back to the Main Branch with "update - -A", you will never again see any updates. - - The ./CVS/Entries.Static file exists and you are expecting a new - file. - - If your ./CVS administrative directory contains a file named - Entries.Static, no files will be checked out that aren't already in - the Entries or Entries.Static file. - - You forgot to use the '-d' option and are looking for new - directories. - - If you execute "update" without the '-d' option, it will not create - new directories that have been added to the Repository. - - You typed "update" instead of "cvs update". - - On most Unix systems, your disk caches are now furiously being flushed - by multiple update daemons, destroying performance and proving to - management that you need more CPU power. :-) - - On HP systems you might be asked what package you want to install from - the "update server". - - Someone removed (using "admin -o") your BASE revision (the revision - CVS thought you had in your working directory), then committed a - "replacement". CVS is now confused because the revision in the - Repository matches your BASE revision when the files themselves don't - match. See 3B.6. - - Last modified: _6/13/1997_ - - 5. Why does "update" say 'M' both for plain modified files and for - successful (i.e. conflict-free) merges? Aren't they different? - - A design choice. Yes, they are different internally, but that - shouldn't matter. Your files are in the same condition after the - "update" as they were before -- a "diff" will display only your - modifications. And you are expected to continue onward with parts two - and three of the normal development cycle: "emacs" (a synonym for - "edit" in most of the civilized world) and "commit". - - Last modified: _6/13/1997_ - - 6. What's a "sticky conflict"? How does it know a conflict occurred? - - When a "cvs update" (or an "update -j") creates a conflict, it prints - a 'C' and stores the timestamp of the file after the merge in a - special field in the ./CVS/Entries file. - - This conflict indication implies that the merge command altered your - working file to contain conflict markers surrounding the overlapping - code segments. For example, say that - - - Two developers acquire revision 1.2 of via "checkout" or - "update". - - - Developer A changes line 1 from "9999" to "5555", then commits the - file, creating revision 1.3. - - - Developer B changes line 1 from "9999" to "7777", then tries to - commit the file, but is blocked because the file is not up to date. - Developer B then runs "update" and sees the conflict marker 'C'. The - beginning of the file would look like this: - - <<<<<<< The working in question. - 7777 Change made to the working . - ======= - 5555 Change made in the first commit (1.3) - >>>>>>> 1.3 The revision created by the first commit. - - The conflict is "sticky", which means that until the conflict is - cleared, the "update" command will continue to display the file's - status as 'C' and the "status" command will show the file's status as - "Unresolved Conflict". - - Until the conflict is cleared, "commit" is blocked for this file. - - The sticky conflict indicator can be cleared by: - - Resolving the conflict by editing the file. Two things must happen - before the conflict is considered resolved: - - The timestamp of the file must change. *and* The file must contain no - conflict markers. (The string searched for in the file is the regexp: - "^>>>>>>> ".) - - After clearing the sticky conflict indicator, you may then commit the - file normally. - - Removing the file and running "update". This throws away the local - changes and accepts the latest committed file on this branch. No - commit is needed. - - Forcing the commit to happen by using "commit -f". This is probably - a mistake since there are few lines of real text that begin with - ">>>>>>> ". - - Last modified: _6/13/1997_ - - 7. Is there a feature to tell me what I have changed, added and removed - without changing anything? - - The command "cvs -n update" will do exactly that. - - Last modified: _6/13/1997_ - - 8. Why were all my files deleted when I executed "update"? - - You probably executed "update -r " some time ago, then removed - from the Repository files. "update -r " will delete a file - that doesn't contain . - - A way to fix this is to "cd" into your working directory and type: - - cvs update -A - - If you don't want the latest revisions on the Main (or Vendor) Branch, - then decide what Tag (normal or branch) you want and type: - - cvs update -r - - Another way to make a file disappear is to execute "update -D " - where is before the date stamped onto the first revision in the - RCS file. - - Last modified: _6/13/1997_ - - Category: /Past__Future_/ - - " Past & Future " - - Category: /Past__Future_/Bugs_and_Patches/ - - " + Bugs and Patches" - - 1. Why can't CVS handle deletion of directories? - - An oversight, probably. [[Fixed in a future release?]] - - Last modified: _6/13/1997_ - - 2. Why can't CVS handle the moving of sources from one place in the - - directory hierarchy to another? - - A "renaming database" has been proposed to track the history of - pathname changes in the Repository. A general solution is a difficult - problem. See 4B.8. - - Last modified: _6/13/1997_ - - 3. When I typed "cvs update -D ", why did it check out all - - sorts of ancient files from the Attic? Shouldn't it just create the - set of files and revisions that existed at that date? - - This seems to be a bug, but is really the lack of any obvious place to - store the date when a file is "removed". - - There are four ranges of dates that CVS has to deal with when trying - to determine what revision was available on : - - Dates before the earliest revision in the file. - - Dates between any two revisions in the file. - - Dates between the latest revision in the file and the date when the - file was moved to the Attic by "commit". - - Dates after moving the file to the Attic. - - Since the date when a file is moved to the Attic is not stored - anywhere, CVS can't tell the difference between #3 and #4. To avoid - not producing a file that should exist in case #3, it produces - extraneous files in case #4. - - For the above reason, if you have removed files in the Attic, it is - better to use "-r , or even "-r HEAD" than to use a date spec. - - If you must use "-D ", then you should either archive and delete - Attic files (losing some past history) or construct your Makefiles to - work with an explicit list of files and let the old source files stay - in the working directory. The contents of the revision-controlled - Makefile can then be considered to contain deletion "information". - - Last modified: _6/13/1997_ - - 4. When I typed "cvs update -D " in my branch, why did it screw up - all my files? - - Currently, the internal routine ("version_ts") that looks up info - about a file, overrides both the tag and date if *either* the tag or - date is specified on the command line. If only the date is specified, - it should not override a branch tag, but it does. - - In CVS 1.3, the documented "-D :" syntax only works - with the Main Branch and the Vendor Branch. - - [[Is this fixed in CVS 1.4? This is one item I didn't check.]] - - Last modified: _6/13/1997_ - - 5. When I executed "checkout" into an existing directory I got "No such - file or directory" errors. Why? - - Though the man page says that "checkout" turns into an "update -d" in - directories that already exist, it is referring to directories that - already exist *and* were created by CVS. - - When you try to run "checkout" on top of an existing directory - structure, some of which wasn't created by CVS, it will handle - directories and non-CVS files within directories already under CVS, - but it will display the above error on non-CVS files within non-CVS - directories. - - Last modified: _6/13/1997_ - - 6. Why does "update" send all output to the terminal after 26 files have - been updated? - - CVS uses the "tmpnam()" function to generate temporary file names. The - ANSI standard for the "tmpnam()" function says: - - "The tmpnam function generates a different string each time it is - called, up to TMP_MAX times. If it is called more than TMP_MAX times, - the behavior is implementation defined." - - Later it says that the value of "TMP_MAX shall be at least 25." - - On some platforms, the above specification is taken literally by - turning "at least 25" into "exactly 26" and by doing something foolish - (i.e. "implementation defined") after that. Some systems return the - same name repeatedly, which causes one form of trouble. Others return - NULL or garbage, which causes a different form of trouble. - - The broken systems appear to be cycling a single character through the - alphabet. SunOS cycles 3 characters through the alphabet, so it won't - cause trouble until 26 cubed or 17576 calls to "tmpnam()". - - Since CVS doesn't depend on the exact format of the tmp files, the - workaround is to provide a "tmpnam()" that doesn't have a limit on the - number of calls to it. - - Last modified: _6/13/1997_ - - 7. Why does the merge occasionally resurrect lines of code? - - The diff3 program provided by GNU diff version 1.15 has a bug that - occasionally causes text to come back from the dead. - - This is an old problem which you can avoid by upgrading to the latest - GNU "diffutils" package. If you were using GNU diff version 1.15 and - plan to upgrade to the latest GNU diff program, see the next question. - - Last modified: _6/13/1997_ - - 8. Why does the merge fail when my "rcsmerge" program is configured to use - GNU diff version 2.1 or later? - - A change in the overlap format was introduced in GNU diff3 between - versions 2.0 and 2.1 that causes RCS versions before 5.6.0.1 to fail - during a merge. - - To get consistent rcsmerge behavior, you have four choices: - - Go back to using GNU diff 1.15 or 2.0 with RCS versions 5.5 or 5.6. - If you want to use GNU diff 2.1 or later, you'll have to pick one of - the other three choices in this list. - - Grab RCS version 5.6.0.1 from an FSF archive and set the DIFF3_A - macro to '1' as it tells you to in the Makefile: - - #define DIFF3_A 1 - - Patch the RCS 5.6 source. Change line 84 in "merger.c" from: - - DIFF3, "-am", "-L", label[0], "-L", label[1], to DIFF3, "-amE", "-L", - label[0], "-L", "", "-L", label[1], - - Wait both for RCS version 5.7 to be released and for a new version - of CVS that can deal with it. - - Last modified: _6/13/1997_ - - Category: /Past__Future_/Contributors/ - - " + Contributors" - - 1. Who wrote CVS? - - Brian Berliner converted a collection of scripts - written by Dick Grune into a C program, then added all - sorts of features. He continues to maintain CVS. - - Jeff Polk wrote much of the code added between - revisions 1.2 and 1.3. Many others were involved at some level. - - david d zuhn fixed a number of bugs, added some of - the new features, reworked the whole thing to be more portable, and - provided much of the energy to push CVS 1.4 out the door. - - Jim Kingdon implemented CVS 1.5's remote repository access features, - fixed many bugs, and managed the release of version 1.5. - - Take a look at the README and the ChangeLog files in the CVS sources - for more contributors. - - Last modified: _6/13/1997_ - - 2. You didn't write all of this FAQ, did you? - - In the original hunt for questions to answer (performed in Jan/Feb, - 1993), I polled hundreds of people and I rephrased all sorts of text - found on the net. Between 2/93 and 10/93, I released about 20 - versions, with corrections and additions from the info-cvs mailing - list and private correspondence. - - Between 10/93 and 10/94 I extracted frequently asked questions from - the 1200 mail messages to the info-cvs mailing list, turned them into - focused questions and tried to answer them. - - 93/02/?? ~4000 lines 93/06/?? ~5000 lines 93/10/23 7839 lines 278K - 94/10/29 9856 lines 360K 95/05/09 9981 lines 365K - - Because there are so many posers of questions, I will list only those - who contribute answers or help significantly with the content and - structure of this document. - - If I used someone else's text verbatim, I mentioned it in the given - answer. The people whose email postings have added to this document or - who have added to my understanding are: - - Brian Berliner , CVS maintainer. Paul Eggert - , RCS maintainer. - - Gray Watson Per Cederqvist Pete - Clark - - all of whom have sent me copies of their tutorials and local CVS - documentation. - - Additional contributors, who have sent me ideas, text, corrections and - support include (in alphabetical order): - - Per Abrahamsen Donald Amby - Mark D Baushke Jim Blandy - Tom Cunningham Graydon - Dodson Joe Drumgoole - Don Dwiggins Bryant - Eastham Dan Franklin - Michael Ganzberger Steve Harris - Erik van Linstee - Jeffrey M Loomis - Barry Margolin Mark K. Mellis Chris - Moore Gary Oberbrunner - Steve Turner Dave Wolfe - Dale Woolridge - - Please send corrections. If I forgot you, remind me and I'll add your - name to the list. - - Last modified: _6/13/1997_ - - Category: /Past__Future_/Development/ - - " + Development" - - 1. Where do I send bug reports? - - First make sure it is a bug. Talk to your friends, coworkers and - anyone you know who uses CVS. Search this FAQ for related issues. Then - test it carefully. Try out variations to narrow down the problem. Make - sure it is repeatable. Look for workarounds so you can report them. - - If you are still sure it's a bug and you tried to fix it, skip to the - next question. Otherwise, send a message to the info-cvs mailing list - containing one of the following: - - If you have a good repeatable case and you think you know what is - going on, then describe the problem in detail. Include a workaround if - you have one. - - If you have no idea what is going on, go ahead and send a question - to the info-cvs mailing list. Include any information you have - describing the symptoms. - - Last modified: _6/13/1997_ - - 2. Where do I send fixes and patches? - - First make sure the "fix" does something useful. Have someone review - your fix. Spend a bit of one person's time in a detailed analysis of - your vast idea before displaying a half-vast idea to hundreds of - people. - - If you tried to fix it and the patch is small, include the patch in - your message. Make sure the patch is based on the latest released - version of CVS. - - If you tried to fix it and the patch is large, you should think about - why it is so large. Did you add a generally useful feature, or did it - grow out of hand? - - If you still believe it is solid, produce a patch file using the CVS - commands "patch" or "diff -c". [[You *are* keeping CVS under CVS, - right?]] The patch should be based on the latest released version of - CVS. Then use the "cvsbug" program (provided with the CVS sources) to - send it to the CVS maintainers. A self-contained patch that provides a - single useful feature or correction might show up independently in the - patches directory of the FTP archive. - - If careful testing reveals an RCS bug rather than a CVS bug, you can - send bug reports to: rcs-bugs@cs.purdue.edu - - Last modified: _6/13/1997_ - - 3. Where do I send ideas for future development? - - If you have a bright idea, discuss it on the info-cvs mailing list. If - you have the time to implement something you can test, send the diffs - along too as described above. - - Last modified: _6/13/1997_ - - 4. What plans are there for new features? - - - -A "rename" or "per-directory" database has been bandied about on -the net for years. Many of the goals of the rename database have -been achieved by the so-called "death support" in recent versions of -CVS (such as 1.9). For more information on what may remain to be -done, see item #189 in the TODO file of a development version of CVS. - -CVS version 1.5 supports remote repository access, but Paul -Kunz has produced another version -(rCVS) that also runs remotely. Note that as far as I know there -are no advantages to rCVS over the remote CVS in CVS 1.5 and later, -and the rCVS user community has migrated to remote CVS. -rCVS is *not* a multisite CVS (see item #186 in TODO for more on -multisite). For more on rCVS, see - -ftp://ftp.slac.stanford.edu/software/rcvs - -kingdon@cyclic.com - - Last modified: _9/6/1997_ - - 5. I have some time and I'd like to help. What can I do for you? - - - You can review this document, correct errors and fill in any of - the incomplete sections. - - You can write scripts or CVS add-ons and make them available by - web/FTP/etc. - - You could work on the regression test suite (src/sanity.sh in the - CVS source distribution). - - You can write specs for new features, fix bugs, review the - documentation or . . . - - For more information, see the files HACKING and DEVEL-CVS in the - CVS source distribution or - http://www.cyclic.com/cyclic-pages/cvsdev.html - - kingdon@cyclic.com - - Last modified: _9/6/1997_ - - Category: /Past__Future_/Professional_Support/ - - " + Professional Support" - - 1. Doesn't Cygnus support CVS? - - - - - Cygnus is a company that supports free software such as the GCC - compiler. They have never sold support for CVS, however. They - do use CVS internally and have contributed much code to CVS over - the years (for which CVS users should be grateful). - - kingdon@cyclic.com - - Last modified: _9/6/1997_ - - 2. What is Cyclic Software doing with CVS? - - -Cyclic Software exists to provide support for CVS. For details such -as prices and what this covers, see http://www.cyclic.com or ask -info@cyclic.com. - -kingdon@cyclic.com - - Last modified: _9/6/1997_ - - Category: /User_Tasks_/ - - " User Tasks " - - Category: /User_Tasks_/Common_User_Tasks/ - - " + Common User Tasks" - - 1. What is the absolute minimum I have to do to edit a file? - - Tell your Repository Administrator to create a module covering the - directory or files you care about. You will be told that your module - name is . Then type: - - cvs checkout - cd - emacs # Isn't Emacs a synonym for edit? - cvs commit - - If you don't use modules (in my opinion, a mistake), you can check out - a directory by substituting its relative path within the Repository - for in the example above. - - To work on a single file, you'll have to change "cd " to "cd - `dirname `". - - Last modified: _6/13/1997_ - - 2. If I edit multiple files, must I type "commit" for each one? - - No. You can commit a list of files and directories, including relative - paths into multiple directories. You can also commit every modified - file in the current directory or in all directories and subdirectories - from your current directory downward. See 3D.2. - - Last modified: _6/13/1997_ - - 3. How do I get rid of the directory that "checkout" created? - - Change your directory to be the same as when you executed the - "checkout" command that created . - - If you want to get rid of the CVS control information, but leave the - files and directories, type: - - cvs release - - If you want to obliterate the entire directory, type: - - cvs release -d - - ("release -d" searches through the output of "cvs -n update" and - refuses to continue if the "update" command finds any modified files - or non-ignored foreign files. Foreign directories too.) - - If you don't care about keeping "history", or checking for modified - and foreign files, you can just remove the whole directory. That's "rm - -rf " under Unix. - - Last modified: _6/13/1997_ - - 4. How do I find out what has changed since my last update? - - There are many ways to answer this. - - To find out what you've changed in your current working directory - since your last checkout, update or commit, type: - - cvs diff - - To find out what other people have added (to your branch) since you - last checked out or updated, type: - - cvs diff -r BASE -r HEAD - - To look at a revision history containing the comments for all changes, - you can use the "log" command. - - You can also use "history" to trace a wide variety of events. - - Last modified: _6/13/1997_ - - 5. I just created a new file. How do I add it to the Repository? - - The "update" command will mark files CVS doesn't know about in your - working directory with a '?' indicator. - - ? - - To add to the Repository, type: - - cvs add - cvs commit - - See 3A.[2-5] and 4C.8 for branch and merge considerations. - - Last modified: _6/13/1997_ - - 6. How do I merge changes made by others into my working directory? - - If you are asking about other branches, see Section 4C on "Branching". - You will have to use the "update -j" command. - - Retrieving changes made to the Repository on the *same* branch you are - working on is the main purpose of the "update" command. The "update" - command tries to merge work committed to the Repository by others - since you last executed "checkout", "update" or "commit" into your - working files. - - For a single file, there are six possible results when you type the - "update" command: - - If the file is lying in your working directory, but is not under - CVS, it will do nothing but print: - - ? - - If neither you nor anyone else has committed changes to , - since your last "checkout", "update" or "commit", "update" will print - nothing and do nothing. - - If you have made no changes to a working file, but you or others - have committed changes to the Repository since your last "checkout", - "update" or "commit" of this working file, CVS will remove your - working file and replace it with a copy of the latest revision of that - file in the Repository. It will print: - - U - - You might want to examine the changes (using the CVS "diff" command) - to see if they mesh with your own in related files. - - If you have made changes to a working file, but no one has changed - your BASE revision (the revision you retrieved from the Repository in - your last "checkout", "update" or "commit"), "update" will print: - - M - - Nothing changes. You were told that you have a modified file in your - directory. - - If you have made changes to your working file and you or others have - committed changes to the Repository, but in different sections of the - file, CVS will merge the changes stored in the Repository since your - last "checkout", "update" or "commit" into your working file. "update" - will print: - - RCS file: /Repository/module/ retrieving revision 1.X retrieving - revision 1.Y Merging differences between 1.X and 1.Y into M - - - If you execute "diff" before and after this step, you should see the - same output, since both the base file and your working file changed in - parallel. This is one of the few times the otherwise nonsensical - phrase "same difference" means something. - - If both you and those who committed files (since your last checkout, - update or commit) have made changes to the same section of a file, CVS - will merge the changes into your file as in #5 above, but it will - leave conflict indicators in the file. "update" will print: - - RCS file: /Repository/module/ retrieving revision 1.X retrieving - revision 1.Y Merging differences between 1.X and 1.Y into - rcsmerge warning: overlaps during merge - cvs update: conflicts found in - C - - This is a "conflict". The file will contain markers surrounding the - overlapping text. The 'C' conflict indicator is sticky -- subsequent - "update" commands will continue to show a 'C' until you edit the file. - - You must examine the overlaps with care and resolve the problem by - analyzing how to retain the features of both changes. See 2D.7 and - 3P.6 for more details on conflict resolution. - - Last modified: _6/13/1997_ - - 7. How do I label a set of revisions so I can retrieve them later? - - To "tag" the BASE revisions (the ones you last checked out, updated, - or committed) you should "cd" to the head of the working directory you - want to tag and type: - - cvs tag - - It recursively walks through your working directory tagging the BASE - revisions of all files. - - To "tag" the latest revision on the Main branch in the Repository, you - can use the following from anywhere: (No "cd" is required -- it works - directly on the Repository.) - - cvs rtag - - Last modified: _6/13/1997_ - - 8. How do I checkout an old release of a module, directory or file? - - Module names and directories are simply ways to name sets of files. - Once the names are determined, there are 6 ways to specify which - revision of a particular file to check out: - - By tag or symbolic name, via the "-r " option. - - By date, via the "-D " option. - - By branch tag (a type of tag with a magic format), via the "-r - " option. - - By date within a branch, via the "-r :" option. - - By an explicit branch revision number ("-r "), which refers to - the latest revision on the branch. This isn't really an "old" - revision, from the branch's perspective, but from the user's - perspective the whole branch might have been abandoned in the past. - - An explicit revision number: "-r " Though this works, it is - almost useless for more than one file. - - You type: - - cvs checkout - cd - - Last modified: _6/13/1997_ - - 9. What do I have to remember to do periodically? - - You should execute "cvs -n update" fairly often to keep track of what - you and others have changed. It won't change anything -- it will just - give you a report. - - Unless you are purposely delaying the inclusion of others' work, you - should execute "update" once in a while and resolve the conflicts. It - is not good to get too far out of sync with the rest of the developers - working on your branch. - - It is assumed that your system administrators have arranged for editor - backup and Unix temp files (#* and .#*) to be deleted after a few - weeks. But you might want to look around for anything else that is - ignored or hidden. Try "cvs -n update -I !" to see all the ignored - files. - - If you are the Repository Administrator, see 4B.16 on Administrator - responsibilities. - - Last modified: _6/13/1997_ - - Category: /User_Tasks_/General_Questions/ - - " + General Questions" - - 1. How do I see what CVS is trying to do? - - The '-t' option on the main "cvs" command will display every external - command (mostly RCS commands and file deletions) it executes. When - combined with the '-n' option, which prevents the execution of any - command that might modify a file, you can see what it will do before - you let it fly. The '-t' option will *not* display every internal - action, only calls to external programs. - - To see a harmless example, try typing: - - cvs -nt update - - Some systems offer a "trace" or "truss" command that will display all - system calls as they happen. This is a *very* low-level interface that - does not normally follow the execution of external commands, but it - can be useful. - - The most complete answer is to read the source, compile it with the - '-g' option and step through it under a debugger. - - Last modified: _6/13/1997_ - - 2. If I work with multiple modules, should I check them all out and commit - them occasionally? Is it OK to leave modules checked out? - - The simple answers are "Yes." - - There is no reason to remove working directories, other than to save - disk space. As long as you have committed the files you choose to make - public, your working directory is just like any other directory. - - CVS doesn't care whether you leave modules checked out or not. The - advantage of leaving them checked out is that you can quickly visit - them to make and commit changes. - - Last modified: _6/13/1997_ - - 3. What is a "sticky" tag? What makes it sticky? How do I loosen it? - - When you execute "update -r ", CVS remembers the . It has - become "sticky" in the sense that until you change it or remove it, - the tag is remembered and used in references to the file as if you had - typed "-r " on the command line. - - It is most useful for a , which is a sticky tag indicating - what branch you are working on. - - A revision number ("-r ") or date ("-D ") can also - become sticky when they are specified on the command line. - - A sticky tag, revision or date remains until you specify another tag, - revision or date the same way. The "update -A" command moves back to - the Main branch, which has the side-effect of clearing all sticky - items on the updated files. - - The "checkout" command creates sticky tags, revisions and dates the - same way "update" does. - - Also, the '-k' option records a "sticky" keyword option that is used - in further "updates until "update -A" is specified. - - Last modified: _6/13/1997_ - - 4. How do I get an old revision without updating the "sticky tag"? - - Use the '-p' option to "pipe" data to standard output. The command - "update -p -r " sends the selected revision to your standard - output (usually the terminal, unless redirected). The '-p' affects no - disk files, leaving a "sticky tag" unaltered and avoiding all other - side-effects of a normal "update". - - If you want to save the result, you can redirect "stdout" to a file - using your shell's redirection capability. In most shells the - following command works: - - cvs update -p -r filename > diskfile - - Last modified: _6/13/1997_ - - 5. What operations disregard sticky tags? - - The functions that routinely disregard sticky tags are: - - Those that work directly on the Repository or its administrative - files: - - admin rtag log status remove history - - Those that take Tags or revisions as arguments and ignore everything - else: (They also never *set* a sticky tag.) - - rdiff import export - - The "release" command itself ignores sticky tags, but it calls "cvs - -n update" (which *does* pay attention to a sticky tag) to figure out - what inconsistencies exist in the working directory. If no - discrepancies exist between the files you originally checked out - (possibly marked by a sticky tag) and what is there now, "release -d" - will delete them all. - - The "tag" command works on the revision lying in the working - directory however it got there. That the revision lying there might - happen to have a sticky tag attached to it is not the "tag" command's - concern. - - The main function that *does* read and write sticky tags is the - "update" command. You can avoid referring to or changing the sticky - tag by using the '-p' option, which sends files to your terminal, - touching nothing else. - - The "checkout" command sets sticky tags when checking out a new module - and it acts like "update" when checking out a module into an existing - directory. - - The "diff" and "commit" commands use the sticky tags, unless - overridden on the command line. They do not set sticky tags. Note that - you can only "commit" to a file checked out with a sticky tag, if the - tag identifies a branch. - - There are really two types of sticky tags, one attached to individual - files (in the ./CVS/Entries file) and one attached to each directory - (in the ./CVS/Tag file). They can differ. - - The "add" command registers the desire to add a new file. If the - "directory tag" (./CVS/Tag) file exists at the time of the "add", the - value stored in ./CVS/Tag becomes the "sticky tag" on the new file. - The file doesn't exist in the Repository until you "commit" it, but - the ./CVS/Entries file holds the sticky tag name from the time of the - "add" forward. - - Last modified: _6/13/1997_ - - 6. Is there a way to avoid reverting my Emacs buffer after committing a - file? Is there a "cvs-mode" for Emacs? - - See Section 4F.1 - - Last modified: _6/13/1997_ - - 7. How does conflict resolution work? What *really* happens if two of us - change the same file? - - While editing files, there is no conflict. You are working on separate - copies of the file stored in the virtual "branch" represented by your - working directories. After one of you commits a file, the other may - not commit the same file until "update" has merged the earlier - committed changes into the later working file. - - For example, say you both check out rev 1.2 of and make change - to your working files. Your coworker commits revision 1.3. When you - try to commit your file, CVS says: - - cvs commit: Up-to-date check failed for `' - - You must merge your coworker's changes into your working file by - typing: - - cvs update - - which will produce the output described in 2B.6. - - If a conflict occurs, the filename will be shown with a status of 'C'. - After you resolve any overlaps caused by the merging process, you may - then commit the file. See 3P.6 for info on "sticky conflicts". - - Even if you get a simple 'M', you should examine the differences - before committing the file. A smooth, error-free text merge is still - no indication that the file is in proper shape. Compile and test it at - least. - - The answer to two obvious questions is "Yes". - - Yes, the first one who commits avoids the merge. Later developers have - to merge the earlier changes into their working files before - committing the merged result. Depending on how difficult the merge is - and how important the contending projects are, the order of commits - and updates might have to be carefully staged. - - And yes, between the time you execute "update" and "commit" (while you - are fixing conflicts and testing the results) someone else may commit - another revision of . You will have to execute "update" again to - merge the new work before committing. Most organizations don't have - this problem. If you do, you might consider splitting the file. Or - hiring a manager. - - Last modified: _6/13/1997_ - - 8. How can I tell who has a module checked out? - - If you "checkout" module names (not relative pathnames) and you use - the release command, the "history" command will display active - checkouts, who has them and where they were checked out. It is - advisory only; it can be circumvented by using the '-l' option on the - main "cvs" command. - - Last modified: _6/13/1997_ - - 9. Where did the .#.1.3 file in my working directory come from? - - It was created during an "update" when CVS merged changes from the - Repository into your modified working file. - - It serves the same purpose as any "backup" file: saving your bacon - often enough to be worth retaining. It is invaluable in recovering - when things go wrong. - - Say Developers A (you) and B check out rev 1.3 of file . You - both make changes -- different changes. B commits first, so ,v - in the Repository contains revisions up through 1.4. - - At this point, there are 5 (yes, five) versions of the file of - interest to you: - - Revision 1.3 (What you originally checked out.) - - Revision 1.4 (What you need from developer B.) - - Your old working file. (Before the update.) - - Your new working file. (After the merge caused by "update".) - - Revision 1.5 (Which you will commit shortly.) - - In the case where your working file was not modified, #1 and #3 will - be the same, as will #2 and #4. In this degenerate case, there is no - need to create #5. The following assumes that your working file was - modified. - - If the merge executed by the "update" caused no overlaps, and you - commit the file immediately, #4 and #5 will be the same. But you can - make arbitrary changes before committing, so the difference between #4 - and #5 might be more than just the correction of overlaps. In general, - though, you don't need #4 after a commit. - - But #3 (which is the one saved as ".#.1.3") holds all of your - work, independent of B's work. It could represent a major effort that - you couldn't afford to lose. If you don't save it somewhere, the merge - makes #3 *disappear* under a potential blizzard of conflicts caused by - overlapping changes. - - I have been saved a few times, and others I support have been saved - hundreds of times, by the ability to "diff ", which can be done in the example above - by the Unix shell command: - - cvs update -p -r 1.3 | diff - .#.1.3 - - The assumption is that the ".#" files will be useful far beyond the - "commit" point, but not forever. You are expected to run the "normal" - Unix cleanup script from "cron", which removes "#*" and ".#*" files - older than a some period chosen by your sysadmin, usually ranging from - 7 to 30 days. - - A question was raised about the need for #3 after #5 has been - committed, under the assumption that you won't commit files until - everything is exactly as you like them. - - This assumes perfect humans, which violates one of the Cardinal rules - of Software Engineering: Never assume any form of discipline on the - part of the users of software. If restrictions are not bound into the - software, then you, the toolsmith, have to arrange a recovery path. - - In other words, I've seen every possible variety of screwup you can - imagine in #5. There is no way to make assumptions about what "should" - happen. I've seen #5 filled with zeros because of NFS failures, I've - seen emacs core dumps that leave #5 in an unreasonable state, I've - seen a foolish developer uppercase the whole file (with his "undo" - size set low so he couldn't undo it) and decide that it would be less - work to play with the uppercased file than to blow it away and start - over. I've even seen committed files with conflict markers still in - them, a sure sign of carelessness. - - There are all sorts of scenarios where having #3 is incredibly useful. - You can move it back into place and try again. - - Last modified: _6/13/1997_ - - 10. What is this "ignore" business? What is it ignoring? - - The "update" and "import" commands use collections of Unix wildcards - to skip over files and directories matching any of those patterns. - - You may add to the built-in ignore list by adding lines of - whitespace-separated wildcards to the following places: (They are read - in this order.) - - In a file named "cvsignore" in $CVSROOT/CVSROOT. - - A Repository Administrator uses this to add site-specific files and - patterns to the built-in ignore list. - - In a file named ".cvsignore" in your home directory. - - For user-specific files. For example, if you use "__" as your default - junk file prefix, you can put "__*" in your .cvsignore file. - - People who play around exclusively in directory trees where the - Makefiles are generated by "imake" or "configure" might want to put - "Makefile" in their ignore list, since they are all generated and - usually don't end up in the Repository. - - In the CVSIGNORE environment variable. - - For session-specific files. - - Via the '-I' option on "import" or "update" commands. - - For this-command-only files. - - In a file named ".cvsignore" within each directory. - - The contents of a ".cvsignore" file in each directory is temporarily - added to the ignore list. This way you can ignore files that are - peculiar to that directory, such as executables and other generated - files without known wildcard patterns. - - In any of the places listed above, a single '!' character nulls out - the ignore list. A Repository administrator can use this to override, - rather than enhance, the built-in ignore list. A user can choose to - override the system-wide ignore list. For example, if you place "! *.o - *.a" in your .cvsignore file, only *.o *.a files, plus any files a - local-directory .cvsignore file, are ignored. - - A variant of the ignore-file scheme is used internally during - checkout. "Module names" found in the modules file (or on the - "checkout" command line) that begin with a '!' are ignored during - checkout. This is useful to permanently ignore (if the '!' path is in - the modules file) or temporarily ignore (if the '!' path is on the - command line) a sub-directory within a Repository hierarchy. For - example: - - cvs checkout !gnu/emacs/tests gnu/emacs - - would checkout the module (or relative path within $CVSROOT) named - "gnu/emacs", but ignore the "tests" directory within it. - - Last modified: _6/13/1997_ - - 11. Is there a way to set user-specific configuration options? - - User-specific configuration is available through use of a ".cvsrc" - file in your home directory. - - CVS searches the first column of your ~/.cvsrc file for the cvs - command name you invoked. If the command is found, the rest of the - line is treated like a set of command line options, stuffed into the - command line before the arguments you actually typed. - - For example, if you always want to see context diffs and you never - want to have to delete a file before you run "cvs remove", then you - should create a .cvsrc file containing the following: - - diff -c - remove -f - - which will add the given options to every invocation of the given - commands. - - [[The rest of this will be removed someday, when CVS changes.]] - - I would like to stop here with a comment that the command name to use - is the full, canonical one. But the command that the cvsrc support - uses is the string you typed on the command line, not the proper - command. So to get the full effect of the above example, you should - also add all the alternate command names: - - di -c - dif -c - rm -f - delete -f - - There are two other limitations that will probably be fixed when CVS - sprouts long option names: - - It only affects options made available on the command line. - - There is a limited number of short options. With long option names, - there is no problem. You can have as many long options as you like, - affecting anything that looks malleable. - - The existing command line options do not come in on/off pairs, so - there is no easy way to override your ~/.cvsrc configuration for a - single invocation of a command. - - Choosing a good set of long option pairs would fix this. - - Last modified: _6/13/1997_ - - 12. Is it safe to interrupt CVS using Control-C? - - It depends on what you mean by "safe". ("Ah," said Arthur, "this is - obviously some strange usage of the word *safe* that I wasn't - previously aware of." -- Hitchhiker's Guide to the Galaxy) - - You won't hurt the underlying RCS files and if you are executing a - command that only *reads* data, you will have no cleanup to do. - - But you may have to hit Control-C repeatedly to stop it. CVS uses the - Unix "system" routine which blocks signals in the CVS parent process. - A single Control-C during "system" will only halt the child process, - usually some form of RCS command. - - If you don't hit another Control-C while the CVS process has control, - it is likely to continue onto the next task assuming that the earlier - one did its job. It is not enough to hit two Control-C's. You might - simply kill two child processes and not interrupt CVS at all. - Depending on the speed of your processor, your terminal and your - fingers, you might have to hit dozens of Control-C's to stop the damn - thing. - - Executing a CVS command, such as "commit" or "tag" that writes to the - files is a different matter. - - Since CVS is not a full-fledged database, with what database people - call "commit points", merely stopping the process will not back out - the "transaction" and place you back in the starting blocks. CVS has - no concept of an "atomic" transaction or of "backtracking", which - means that a command can be half-executed. - - Hitting Control-C will usually leave lock files that you have to go - clean up in the Repository. - - Example1: - - If you interrupt a multi-file "commit" in the middle of - an RCS checkin, RCS will leave the file either fully - checked-in or in its original state. But CVS might have - been half-way through the list of files to commit. The - directory or module will be inconsistent. - - To recover, you must remove the lock files, then decide - whether you want to back out or finish the job. - - To back out, you'll have to apply the "admin -o" - command, very carefully, to remove the newly committed - revisions. This is usually a bad idea, but is - occasionally necessary. - - To finish, you can simply retype the same commit command. - CVS will figure out what files are still modified and - commit them. It helps that RCS doesn't leave a file in an - intermediate state. - - Example2: - - If you interrupt a multi-file "tag" command, you have a - problem similar, but not equivalent, to interrupting a - "commit". The RCS file will still be consistent, but - unlike "commit", which only *adds* to the RCS file, "tag" - can *move* a tag and it doesn't keep a history of what - revision a tag used to be attached to. - - Normally, you have little choice but to re-execute the - command and allow it to tag everything consistently. - - You might be able to recover by carefully re-applying the - tags via the "cvs admin -N" command, but you'll still have - to dig up from outside sources the information you use to - determine what tag was on what revision in what file. - the Repository, or by using the equivalent: "cvs admin". - - Halting a new "checkout" should cause no harm. If you don't want it, - "release" (or rm -rf) it. If you do want it, re-execute the command. A - repeated "checkout" from above a directory acts like a repeated - "update -d" within it. - - Halting "update" half-way will give you an unpredictable collection of - files and revisions. To continue, you can rerun the update and it - should move you forward into in a known state. To back out, you'll - have to examine the output from the first "update" command, take a - look at each file that was modified and reconstruct the previous state - by editing the ./CVS/Entries file and by using "cvs admin". Good Luck. - - Last modified: _6/13/1997_ - - 13. How do I turn off the "admin" command? - - In the current revision, you'd have to edit the source code. - - Last modified: _6/13/1997_ - - 14. How do I turn off the ability to disable history via "cvs -l"? - - In the current revision, you'd have to edit the source code. - - Last modified: _6/13/1997_ - - 15. How do I keep certain people from accessing certain directories? - - If you don't try to run CVS set[ug]id, you can use Unix groups and - permissions to limit access to the Repository. - - If you only want to limit "commit" commands, you can write a program - to put in the "commitinfo" file. In the "contrib" directory, there are - a few scripts that might help you out. - - Last modified: _6/13/1997_ - - Category: /User_Tasks_/Getting_Started/ - - " + Getting Started" - - 1. What is the first thing I have to know? - - Your organization has most likely assigned one or more persons to - understand, baby-sit and administer the CVS programs and the data - Repository. I call these persons Repository Administrators. They - should have set up a Repository and "imported" files into it. - - If you don't believe anyone has this responsibility, or you are just - testing CVS, then *you* are the Repository Administrator. - - If you are a normal user of CVS ask your Repository Administrator what - module you should check out. - - Then you can work. - - If you *are* the Repository Administrator, you will want to read - everything you can get your hands on, including this FAQ. Source - control issues can be difficult, especially when you get to branches - and release planning. Expect to feel stupid for a few days/weeks. - - No tool in the universe avoids the need for intelligent organization. - In other words, there are all sorts of related issues you will - probably have to learn. Don't expect to dive in without any - preparation, stuff your 300 Megabytes of sources into CVS and expect - to start working. If you don't prepare first, you will probably spend - a few sleepless nights. - - Last modified: _6/13/1997_ - - 2. Where do I work? - - Wherever you have disk space. That's one of the advantages of CVS: you - use the "checkout" command to copy files from the Repository to your - working directory, which can be anywhere you have the space. - - Your local group might have conventions for where to work. Ask your - peers. - - Last modified: _6/13/1997_ - - 3. What does CVS use from my environment? - - You must set two environment variables. Some shells share these - variables with local shell variables using a different syntax. You'll - have to learn how your shell handles them. - - Variable Value (or action) - --------- --------------------- - CVSROOT Absolute pathname of the head of your Repository. - - PATH Normally set to a list of ':'-separated directory - pathnames searched to find executables. You must - make sure "cvs" is in one of the directories. - - If your CVS was built with the RCSBIN directory set - to null (""), and you don't set the RCSBIN - variable mentioned below, then the RCS commands - also must be somewhere in your PATH. - - Optional variables: (Used if set, but ignored otherwise.) - - Variable Value (or action) - --------- --------------------- - CVSEDITOR The name of your favorite fast-start editor - program. You'll be kicked into your editor to - supply revision comments if you don't specify them - via -m "Log message" on the command line. - - EDITOR Used if CVSEDITOR doesn't exist. If EDITOR - doesn't exist, CVS uses a configured constant, - usually, "vi". - - CVSREAD Sets files to read-only on "checkout". - - RCSBIN Changes where CVS finds the RCS commands. - - CVSIGNORE Adds to the ignore list. See Section 2D. - - Other variables used by CVS that are normally set upon login: - - Variable Value (or action) - --------- --------------------- - LOGNAME Used to find the real user name. - - USER Used to find the real user name if no LOGNAME. - - HOME Used to determine your home directory, if set. - Otherwise LOGNAME/USER/getuid() are used to find - your home directory from the passwd file. - - TMPDIR Used during import. It might also be used if your - platform's version of mktemp(3) is unusual, or - you have changed the source to use tmpnam(3). - - Last modified: _6/13/1997_ - - 4. OK, I've been told that CVS is set up, my module is named "ralph" and I - have to start editing. What do I type? - - cd - cvs checkout ralph - cd ralph - - And hack away. - - Last modified: _6/13/1997_ - - 5. I have been using RCS for a while. Can I convert to CVS without losing - my revision history? How about converting from SCCS? - - If you are asking such questions, you are not a mere user of CVS, but - one of its Administrators! You should take a look at Section 4A, - "Installing CVS" and Section 4B, "Setting up and Managing the - Repository". - - Last modified: _6/13/1997_ - - Category: /User_Tasks_/Less_Common_User_Tas/ - - " + Less Common User Tasks" - - 1. Can I create non-CVS sub-directories in my working directory? - - Yes. Unless the directory exists in the Repository, "update" will skip - over them and print a '?' the way it does for files you forgot to add. - You can avoid seeing the '?' by adding the name of the foreign - directory to the ./.cvsignore file, just ask you can do with files. - - If you explicitly mention a foreign directory on the "update" command - line, it will traverse the directory and waste a bit of time, but if - any directory or sub-directory lacks the ./CVS administrative - directory, CVS will print an error and abort. - - Last modified: _6/13/1997_ - - 2. How do I add new sub-directories to the Repository? - - The "add" command will work on directories. You type: - - mkdir - cvs add - - It will respond: - - Directory /Repos/ added to the repository - - and will create both a matching directory in the Repository and a - ./CVS administrative directory within the local directory. - - Last modified: _6/13/1997_ - - 3. How do I remove a file I don't need? - - (See the questions in Section 4B on removing files from the - Repository.) - - You type: - - rm - cvs remove - - CVS registers the file for removal. To complete the removal, you must - type: - - cvs commit - - CVS moves the file to the Attic associated with your working - directory. Each directory in the Repository stores its deleted files - in an Attic sub-directory. A normal "checkout" doesn't look in the - Attic, but if you specify a tag, a date or a revision, the "checkout" - (or "update") command will retrieve files from the Attic with that - tag, date or revision. - - Last modified: _6/13/1997_ - - 4. How do I rename a file? - - CVS does not offer a way to rename a file in a way that CVS can track - later. See Section 4B for more information. - - Here is the best (to some, the only acceptable) way to get the effect - of renaming, while preserving the change log: - - Copy the RCS (",v") file directly in the Repository. - - cp $CVSROOT//,v $CVSROOT//,v - - By duplicating the file, you will preserve the change history and the - ability to retrieve earlier revisions of the old file via the "-r - " or "-D " options to "checkout" and "update". - - Remove the old file using CVS. - - cd / rm - cvs remove - cvs commit - - This will move the to the Attic associated with . - - Retrieve and remove all the Tags from it. - - By stripping off all the old Tags, "checkout -r" and "update -r" won't - retrieve revisions Tagged before the renaming. - - cd / - cvs update - cvs log # Save the list of Tags - cvs tag -d - cvs tag -d - . . . - - This technique can be used to rename files within one directory or - across different directories. You can apply this idea to directories - too, as long as you apply the above to each file and don't delete the - old directory. - - Of course, you have to change your build system (e.g. Makefile) in - your to know about the name change. - - Warning: Stripping the old tags from the copied file will allow "-r - " to do the right thing, but you will still have problems with - "-D " because there is no place to store the "deletion time". - See 5B.3 for more details. - - Last modified: _6/13/1997_ - - 5. How do I make sure that all the files and directories in my working - directory are really in the Repository? - - A "cvs update", or "cvs -n update" (which won't modify your working - directory) will display foreign elements, which have no counterpart in - the Repository, preceded by a '?'. To register foreign directories, - you can use "cvs add". To register foreign files, you can use "cvs - add" followed by "cvs commit". - - You could also checkout your module, or the Repository directory - associated with your working directory, a second time into another - work area and compare it to your working directory using the (non-CVS) - "diff -r" command. - - By default many patterns of files are ignored. If you create a file - named "core" or a file ending in ".o", it is usually ignored. If you - really want to see all the files that aren't in the Repository, you - can use a special "ignore" pattern to say "ignore no files". Try - executing: (You may have to quote or backwhack (i.e. precede by '\') - the '!' in your shell.) - - cvs -n update -I ! - - The above command will display not only the normal modified, update - and conflict indicators ('M', 'U', and 'C' respectively) on files - within the Repository, but it will also display each file not in the - Repository preceded by a '?' character. - - The '-n' option will not allow "update" to alter your working - directory. - - Last modified: _6/13/1997_ - - 6. How do I create a branch? - - Type this in your working directory: - - cvs tag -b - - and you will create a branch. No files have real branches in them yet, - but if you move onto the branch by typing: - - cvs update -r - - and commit a file in the normal way: - - cvs commit - - then a branch will be created in the underlying ,v file and the - new revision of will appear only on that branch. - - See Section 4C, on Branching. - - Last modified: _6/13/1997_ - - 7. How do I modify the modules file? How about the other files in the - CVSROOT administrative area? - - A module named "modules" has been provided in the default modules - file, so you can type: - - cvs checkout modules - cd modules - - Another module named CVSROOT has been provided in the default modules - file, covering all the administrative files. Type: - - cvs checkout CVSROOT - cd CVSROOT - - Then you can edit your files, followed by: - - cvs commit - - If you start with the provided template for the "modules" file, the - CVSROOT and the "modules" module will have the "mkmodules" program as - a "commit helper". After a file is committed to such a module, - "mkmodules" will convert a number of standard files (See 4B.2) in the - CVSROOT directory inside the Repository into a form that is usable by - CVS. - - Last modified: _6/13/1997_ - - 8. How do I split a file into pieces, retaining revision histories? - - If you and a coworker find yourselves repeatedly committing the same - file, but never for changes in the same area of the file, you might - want to split the file into two or more pieces. If you are both - changing the same section of code, splitting the file is of no use. - You should talk to each other instead. - - If you decide to split the file, here's a suggestion. In many ways, it - is similar to multiple "renamings" as described in 2C.4 above. - - Say you want to split , which already in the Repository, into three - pieces, , and . - - Copy the RCS (",v") files directly in the Repository, creating the - new files, then bring readable copies of the new files into the - working directory via "update". - - cp $CVSROOT//,v $CVSROOT//,v cp $CVSROOT//,v $CVSROOT//,v - cvs update - - Then remove all the from the new files, either using: - - cvs log # Save the list of - cvs tag -d - cvs tag -d - . . . - - (eivind@freebsd.org) or using the following little script to - autmatically remove the tags directly from the repository files: - -#!/bin/sh -for file in $* -do - TAGS=`rlog $file | awk '/^symbolic names:/,/^keyword subst/' | awk 'BEG -IN {FS=":"} /^\t/ {print $1}'` - echo The tags in $file are - echo $TAGS - echo Is it OK to remove these? - read confirm - if [ "$confirm" = "y" -o "$confirm" = "yes" ] - then - for tag in $TAGS - do - echo Removing $file:$tag - rcs -n$tag $file - done - fi -done - - Edit each file until it has the data you want in it. This is a - hand-editing job, not something CVS can handle. Then commit all the - files. - - [From experience, I'd suggest making sure that only one copy of each - line of code exists among the three files, except for "include" - statements, which must be duplicated. And make sure the code - compiles.] - - emacs - cvs commit - - As in the "rename" case, by duplicating the files, you'll preserve the - change history and the ability to retrieve earlier revisions. - - Of course, you have to alter your build system (e.g. Makefiles) to - take the new names and the change in contents into account. - - Last modified: _3/11/1998_ - - Category: /What_is_CVS_/ - - " What is CVS? " - - Category: /What_is_CVS_/How_does_CVS_differ_/ - - " + How does CVS differ from other, similar software?" - - 1. How does CVS differ from RCS? - - CVS uses RCS to do much of its work and absolutely all the work of - changing the underlying RCS files in the Repository. - - RCS comprises a set of programs designed to keep track of changes to - individual files. Of course, it also allows you to refer to multiple - files on the command line, but they are handled by iterating over - individual files. There is no pretense of coordinated interaction - among groups of files. - - CVS's main intent is to provide a set of grouping functions that allow - you to treat a collection of RCS files as a single object. Of course, - CVS also has to do a lot of iteration, but it tries its best to hide - that it is doing so. In addition, CVS has some truly group-oriented - facets, such as the modules file and the CVS administrative files that - refer to a whole directory or module. - - One group aspect that can be a bit confusing is that a CVS branch is - not the same as an RCS branch. To support a CVS branch, CVS uses - "tags" (what RCS calls "symbols") and some local state, in addition to - RCS branches. - - Other features offered by CVS that are not supported directly by RCS - are - - Automatic determination of the state of a file, (e.g. modified, - up-to-date with the Repository, already tagged with the same string, - etc.) which helps in limiting the amount of displayed text you have to - wade through to figure out what changed and what to do next. - - A copy-modify-merge scheme that avoids locking the files and allows - simultaneous development on a single file. - - Serialization of commits. CVS requires you to merge all changes - committed (via "update") since you checked out your working copy of - the file. Although it is still possible to commit a file filled with - old data, it is less likely than when using raw RCS. - - Relatively easy merging of releases from external Vendors. - - Last modified: _6/13/1997_ - - 2. How does CVS differ from SCCS? - - SCCS is much closer to RCS than to CVS, so some of the previous entry - applies. - - You might want to take a look at Walter Tichy's papers on RCS, which - are referred to in the RCS man pages. - - [[More info here?]] - - Last modified: _6/13/1997_ - - 3. How does CVS differ from ClearCase? - - ClearCase is a distributed client-server version control system. - ClearCase is a variant DSEE tools, formerly available on Apollo - platforms. The ClearCase tool set includes a few X-based interface - tools, a command-line interface, and C programmer API. It is currently - available on Sun, HP, SGI and OSF/1 platforms. - - ClearCase uses a special Unix filesystem type, called "mvfs" for - "multi-version file system". Conceptually, mvfs adds another dimension - to a regular Unix filesystem. The new axis is used to store the - different versions of files and to provide a tree-hierarchical view of - a collection of objects that might be scattered across any number of - separate hosts on your local network. - - Each user acquires a "view" into the file database by creating a - special mvfs mount point on their machine. Each view has a - "configuration spec" containing a set of selection rules that specify - the particular version of each file to make visible in that view. You - can think of a "view" as a work area in CVS, except that the files - don't really exist on your local disk until you modify them. This - technique conserves disk space because it doesn't keep private copies - of read-only files. - - Another advantage is that a view is "transparent" in the sense that - all of the files in a "view" appear to be regular Unix files to other - tools and Unix system calls. An extended naming convention allows - access to particular versions of a file directly: - "test.cc@@/main/bugfix/3" identifies the third version of test.c on - the bugfix branch. - - ClearCase supports both the copy-modify-merge model of CVS (by using - what are called "unreserved checkouts" and the checkin/checkout - development model with file locking. Directories are - version-controlled objects as well as files. A graphical merge tool is - provided. Like RCS, ClearCase supports branches, symbolic tags, and - delta compression. ASCII as well as binary files are supported, and - converters from RCS, SCCS, DSEE formats are also included. - - A make-compatible build facility is provided that can identify common - object code and share it among developers. A build auditing feature - automatically records file dependencies by tracking every file that is - opened when producing a derived object, thus making explicit - dependency lists unnecessary. Pre- and post-event triggers are - available for most ClearCase operations to invoke user programs or - shell scripts. User-defined attributes can be assigned to any version - or object. Hyper-links between version controlled objects can record - their relationship. - - For more information, contact: - - Atria Software, Inc. 24 Prime Park Way Natick, MA 01760 info@atria.com - - (508) 650-1193 (phone) (508) 650-1196 (fax) - - Originally contributed by Steve Turner - Edited by the author of this FAQ. - - Last modified: _6/13/1997_ - - 4. How does CVS differ from TeamWare/SparcWorks? - - TeamWare is a configuration management tool from Sun Microsystems, a - part of SparcWorks. It uses the same copy and merge model as CVS. The - central abstraction is a workspace, which corresponds to either a CVS - branch or a checked out module. TeamWare allows you to manipulate - workspaces directly, including moving and merging code between - workspaces. You can put your workspace on tape and continue to work - with it at home, just like you can with CVS. TeamWare is built upon - and compatible with SCCS. - - TeamWare provides both a command line interface and a graphical - interface. The CodeManager tool will display the project as a tree of - workspaces, and allows you to manipulate them with drag and drop. The - other tools are VersionTool that displays and manipulates a dag with a - version history of a single file, CheckPoint that will create symbolic - tags, MakeTool, a make compatible tool with a GUI, and FileMerge which - will interactively merge files when needed (like emerge for emacs). If - you have a sun, you can try /usr/old/mergetool for an old SunView - version of FileMerge. - - Email: sunprosig@sun.com - - Originally extracted from TeamWare - Marketing literature by Per Abrahamsen. - Edited by the author of this FAQ. - - For more information, contact: - - SunExpress, Inc. P.O. Box 4426 Bridgeton, MO 63044-9863 (800)873-7869 - - Last modified: _6/13/1997_ - - 5. How does CVS differ from Aegis? - - Aegis appears to be a policy-setting tool that allows you to use other - sub-programs (make, RCS, etc.) to implement pieces of the imposed - policy. - - The initial document seems to say that most Unix tools are inadequate - for use under Aegis. - - It is not really similar to CVS and requires a different mindset. - - [[Need more info here.]] - - Last modified: _6/13/1997_ - - 6. How does CVS differ from Shapetools? - - Shapetools includes a build mechanism (called Shape, not surprisingly) - that is aware of the version mechanism, and some dependency tracking. - It is based on a file system extension called Attributed File System, - which allows arbitrary-sized "attributes" to be associated with a - file. Files are version controlled in a manner similar to RCS. - Configurations are managed through the Shapefile, an extension of the - Makefile syntax and functionality. Shape includes version selection - rules to allow sophisticated selection of component versions in a - build. - - Shapetools' concurrency control is pessimistic, in contrast to that of - CVS. Also, there's very limited support for branching and merging. It - has a built-in policy for transitioning a system from initial - development to production. - - Contributed by Don Dwiggins - - Last modified: _6/13/1997_ - - 7. How does CVS differ from TeamNet? - - TeamNet is a configuration management tool from TeamOne. - - For more information, contact: - - TeamOne 710 Lakeway Drive, Ste 100 Sunnyvale, CA 94086 (800) 442-6650 - - Contributed by Steve Turner - - Last modified: _6/13/1997_ - - 8. How does CVS differ from ProFrame? - - ProFrame is a new system integration framework from IBM. ProFrame is - compliant with the CFI (CAD Framework Initiative) industry standards, - including the Scheme extension language. - - ProFrame consists of three major components: (1) the Process Manager - that automates your local design methodology (2) the Design Data - Manager handles configuration management, and (3) Inter-tool - Communication to provide a communication path among tools running on - heterogeneous servers. - - The Design Data Manager(2) is probably the appropriate component to - compare to CVS. The Design Data Manager provides version control with - checkin/checkout capability, configuration management, and data - dependency tracking. A graphical data selection interface is provided. - Using this interface, you may create and manipulate objects and - hierarchy structures, view the revision history for an object, and - view and assign attributes to a design object. - - The ProFrame server currently runs only on RS6000, but clients may be - a wide variety of Unix platforms. Contact IBM for the latest platform - information. - - For more information, contact: - - IBM EDA Marketing and Sales P.O. Box 950, M/S P121 Poughkeepsie, NY - 12602 (800) 332-0066 - - Contributed by Steve Turner - [extracted from the ProFrame 1.1.0 datasheet] - - Last modified: _6/13/1997_ - - 9. How does CVS differ from CaseWare/CM? - - CaseWare/CM is a software configuration management product from - CaseWare, Inc. CaseWare/CM may be customized to support a wide variety - of methodologies, including various phases of the software lifecycle, - and different access rights for users. - - A GUI is provided to view version histories and configurations. A - merge tools is also included. CaseWare supports type-specific - lifecycles, which allows different types of files to move through - different lifecycles. Also provided is a build facility to support - automatic dependency analysis, parallel, distributed, and remote - builds, and variant releases. - - CaseWare/CM has been integrated with other CASE tools, including - FrameMaker, ALSYS Ada, CodeCenter/Object Center, HP SoftBench, and - Software Through Pictures. CaseWare also offers CaseWare/PT, a problem - tracking system to integrate change requests with configuration - management. - - Multiple vendors and operating systems are supported. - - For more information, contact: - - CaseWare, Inc. 108 Pacifica, 2nd Floor Irvine, CA 92718-3332 (714) - 453-2200 (phone) (714) 453-2276 (fax) - - Contributed by Steve Turner - [extracted from the CaseWare/CM data sheet] - - Last modified: _6/13/1997_ - - 10. How does CVS differ from SABLIME? - - Produced by AT&T. Sablime uses SCCS as the underlying source code - control system. It uses some other control system (called sbcs I - think) for managing binary files. It uses lock, edit, comit, unlock - mechanism. It has a motif based GUI and curses based GUI (that works - only with ksh, not tcsh, or bash) to do more common tasks. It has even - a command line interface. - - Changing source happens as a result of MR. A testing person or a - developer assigns an MR (modification request) to a group of people. - They are allowed to take out files under that MR and change them and - check them back in. You can set up dependencies between and MR and do - release management to say "I want the sources to include these MRs" - etc. It is a reasonably good maintanance system. It is bit heavy - weight though, and the interface is not too polished and does not work - on windows (though that may have changed). rama@savera.com - - Last modified: _7/30/1998_ - - 11. How does CVS differ from PVCS? - - PVCS works on single files like RCS and SCCS, CVS works on complete - subsystems. PVCS has a make utility (called a configuration builder), - CVS does not. PVCS has a GUI interface for Unix, DOS, OS/2, and MS - Windows. - - Intersolv, Inc. - 1700 NW 167th Place - OR 97006 - - Contributed by Per Abrahamsen - [Extracted from Intersolv Marketing literature.] - - Last modified: _6/13/1997_ - - 12. How does CVS differ from CMVC? - - CMVC is an IBM Configuration Management and Version Control system. - (Though I'm not certain that's the right acronym expansion.) It runs - on Suns, HPs, RS6000s, OS/2 and Windows. - - Other than revision control, it apparently has features to manage - releases, bug tracking and the connection between alterations and - reported bugs and feature requests. It is a client/server system, - based on a choice of commercial Relational Database systems, and it - provides a Motif or command line interface. - - Unlike CVS, it uses a strict locking protocol to serialize source code - alterations. - - Last modified: _6/13/1997_ - - Category: /What_is_CVS_/What_do_you_mean_by_/ - - " + What do you mean by . . .? (Definitions)" - - 1. What are "The Repository", "$CVSROOT" and "CVSROOT"? - - The Repository is a directory tree containing the CVS administrative - files and all the RCS files that constitute "imported" or "committed" - work. The Repository is kept in a shared area, separate from the - working areas of all developers. - - Users of CVS must set their "CVSROOT" environment variable to the - absolute pathname of the head of the Repository. Most command line - interpreters replace an instance of "$CVSROOT" with the value of the - "CVSROOT" environment variable. By analogy, in this document - "$CVSROOT" is used as shorthand for "the absolute pathname of the - directory at the head of the Repository". - - One of the things found in $CVSROOT is a directory named CVSROOT. It - contains all the "state", the administrative files, that CVS needs - during execution. The "modules", "history", "commitinfo", "loginfo" - and other files can be found there. See 4B.2 for more information - about CVSROOT files. - - Last modified: _6/13/1997_ - - 2. What is an RCS file? - - An RCS file is a text file containing the source text and the revision - history for all committed revisions of a source file. It is stored - separately from the working files, in a directory hierarchy, called - the Repository. - - RCS is the "Revision Control System" that CVS uses to manage - individual files. RCS file names normally end in ",v", but that can be - altered (via the RCS -x option) to conform to file naming standards on - platforms with unusual filename limitations. - - Last modified: _6/13/1997_ - - 3. What is a working file? - - A working file is a disk file containing a checked-out copy of a - source file that earlier had been placed under CVS. If the working - file has been edited, the changes since the last committed revision - are invisible to other users of CVS. - - Last modified: _6/13/1997_ - - 4. What is a working directory (or working area)? - - A working directory is the place where you work and the place from - which you "commit" files. - - The "checkout" command creates a tree of working directories, filling - them with working files. Each working directory contains a - sub-directory named ./CVS containing three administrative files, which - are created by "checkout" and are always present: - - ./CVS/Entries - contains information about working files. - - ./CVS/Repository - contains the location of the directory within the - Repository that was used to create the working directory. - - ./CVS/Root - contains the value of $CVSROOT at the time you created - the working directory. - - Other files may also appear in ./CVS depending on the state of your - working directory: - - ./CVS/Tag - contains the "sticky tag" associated with the whole - directory. See 3A.2 for its main purpose. - [Created by "checkout" or "update" when using "-r ".] - [Deleted by "checkout" or "update" when using '-A'.] - - ./CVS/Entries.Static - contains a fixed list of working files. If this file - exists, an "update" doesn't automatically bring newly - added files out of the Repository. - [Created and maintained by hand.] - - ./CVS/Checkin.prog - contains a program to run whenever anything in the - working directory is committed. - [Created by checkout if "-i " appears in the - modules file for the checked-out module.] - - ./CVS/Update.prog - contains a program to run whenever anything in the - working directory is updated. - [Created by checkout if "-u " appears in the - modules file for the checked-out module.] - - ./CVS/,p ./CVS/,t - contain (possibly zero-length) state information about an - "add" that has not been committed. - [Created by "add".] - [Deleted by "commit" or "remove".] - - Last modified: _6/13/1997_ - - 5. What is "checking out"? - - "Checking out" is the act of using the "checkout" command to copy a - particular revision from a set of RCS files into your working area. - You normally execute "checkout" only once per working directory (or - tree of working directories), maintaining them thereafter with the - "update" command. - - See section 3C on the "checkout" command. - - Last modified: _6/13/1997_ - - 6. What is a revision? - - A "revision" is a version of a file that was "committed" ("checked - in", in RCS terms) some time in the past. CVS (and RCS) can retrieve - any file that was committed by specifying its revision number or its - "tag" ("symbolic name", in RCS terms). - - In CVS, a "tag" is more useful than a revision number. It usually - marks a milestone in development represented by different revision - numbers in different files, all available as one "tagged" collection. - - Sometimes the word "revision" is used as shorthand for "the file you - get if you retrieve (via "checkout" or "update") the given revision - from the Repository." - - Last modified: _6/13/1997_ - - 7. What is a "Tag"? - - A "Tag" is a symbolic name, a synonym or alias for a particular - revision number in a file. The CVS "tag" command places the same "Tag" - on all files in a working directory, allowing you to retrieve those - files by name in the future. - - The CVS "Tag" is implemented by applying RCS "symbols" to each - individual file. The Tags on a file (or collection of files) may be - displayed using the "log" command. - - Last modified: _6/13/1997_ - - 8. What are "HEAD" and "BASE"? - - HEAD and BASE are built-in tags that don't show up in the "log" or - "status" listings. They are interpreted directly by CVS. - - "HEAD" refers to the latest revision on the current branch in the - Repository. The current branch is either the main line of development, - or a branch in development created by placing a branch tag on a set of - files and checking out that branch. - - "BASE" refers to the revision on the current branch you last checked - out, updated, or committed. If you have not modified your working - file, "BASE" is the committed revision matching it. - - Most of the time BASE and HEAD refer to the same revision. They can - become different in two ways: - - Someone else changed HEAD by committing a new revision of your file - to the Repository. You can pull BASE up to equal HEAD by executing - "update". - - You moved BASE backward by executing "checkout" or "update" with the - option "-r " or "-D ". CVS records a sticky tag and - moves your files to the specified earlier revision. You can clear the - sticky tag and pull BASE up to equal HEAD again by executing "update - -A". - - Last modified: _6/13/1997_ - - 9. What is a Branch? - - In general, a branch is any mechanism that allows one or more - developers to modify a file without affecting anyone other than those - working on the same branch. - - There are four kinds of "branch" CVS can manage: - - The Vendor Branch. - - A single vendor branch is supported. The "import" command takes a - sequence of releases from a source code vendor (called a "vendor" even - if no money is involved), placing them on a special "Vendor" branch. - The Vendor branch is considered part of the "Main line" of - development, though it must be merged into locally modified files on - the RCS Main branch before the "import" is complete. - - See Section 3H ("import"). - - Your Working directory. - - A checked-out working directory, can be treated like a private branch. - No one but you can touch your files. You have complete control over - when you include work committed by others. However, you can't commit - or tag intermediate versions of your work. - - A Development branch. - - A group of developers can share changes among the group, without - affecting the Main line of development, by creating a branch. Only - those who have checked-out the branch see the changes committed to - that branch. This kind of branch is usually temporary, collapsing - (i.e. merge and forget) into the Main line when the project requiring - the branch is completed. - - You can also create a private branch of this type, allowing an - individual to commit (and tag) intermediate revisions without changing - the Main line. It should be managed exactly like a Development Branch - -- collapsed into the Main line (or its parent branch, if that is not - the Main Branch) and forgotten when the work is done. - - A Release branch. - - At release time, a branch should be created marking what was released. - Later, small changes (sometimes called "patches") can be made to the - release without including everything else on the Main line of - development. You avoid forcing the customer to accept new, possibly - untested, features added since the release. This is also the way to - correct bugs found during testing in an environment where other - developers have continued to commit to the Main line while you are - testing and packaging the release. - - Although the internal format of this type of branch (branch tag and - RCS branches) is the same as in a development branch, its purpose and - the way it is managed are different. The major difference is that a - Release branch is normally Permanent. Once you let a release out the - door to customers, or to the next stage of whatever process you are - using, you should retain forever the branch marking that release. - - Since the branch is permanent, you cannot incorporate the branch fixes - into the Main line by "collapsing" (merging and forgetting) the - release branch. For large changes to many files on the release branch, - you will have to perform a branch merge using "update -j -j - ". (See 4C.7) - - The most common way to merge small changes back into Main line - development is to make the change in both places simultaneously. This - is faster than trying to perform a selective merge. - - See 1D.12 (merges) and Section 4C, on Branching for more info. - - Last modified: _6/13/1997_ - - 10. What is "the trunk"? - - Another name for the RCS Main Branch. The RCS Main Branch is related, - but not equivalent, to both the CVS Main branch and what developers - consider to be the Main line of development. See 3H.3 and Section 4C - on Branching. - - Last modified: _6/13/1997_ - - 11. What is a module? - - In essence, a module is a name you hand to the "checkout" command to - retrieve one or more files to work on. It was originally intended to - be a simple, unique name in the "modules" file attached to a directory - or a subset of files within a directory. - - The module idea is now a somewhat slippery concept that can be defined - in two different ways: - * A module is an argument to "checkout". There are three types: - 1. An entry in the modules file. A "module" name as described in - 'B.' below. - 2. A relative path to a directory or file in the Repository. - 3. A mixed-mode string of "modulename/relative-path". Everything - up to the first slash ('/') is looked up as a module. The - relative path is appended to the directory associated with - the module name and the resulting path is checked out as in - #2 above. - * A module is a unique (within the file) character string in the - first column of the modules file. There are five types: - 1. A name for a directory within the Repository that allows you - to ignore the parent directories above it. - Example: - emacs gnu/emacs - 2. A name for a subset of the files within such a directory. - Example: - ls unix/bin Makefile ls.c - The 2nd through Nth strings in the above can be files, - directories or module substitutions. No relative paths. - A module substitution occurs when you use a '&module-name' - reference. The module-name referred to is logically - substituted for the '&module-name' string. - 3. A relative pathname to a directory within the Repository - which, when checked out, creates an image of part of the - Repository structure in your current directory. - Example: - gnu/emacs -o /bin/emacs.helper gnu/emacs - The files checked out are exactly the same as the files - "checkout" would retrieve if the path weren't even in the - modules file. The only reason to put this kind of relative - pathname into the modules file is to hook one of the helper - functions onto it. - 4. A relative pathname to a single file within the Repository - which, when checked out, creates something you probably don't - want: It creates a directory by the name of the file and puts - the file in it. - Example: - gnu/emacs/Makefile -o /bin/emacs.helper gnu/emacs Makefile - The file checked out is the same as what you would get if you - handed the relative pathname to the "checkout" command. But - it puts it in a strange place. The only reason to do this is - to hook a helper function onto a specific file name. - 5. An alias consisting of a list of any of the above, including - other aliases, plus exceptions. - Example: - my_work -a emacs !emacs/tests gnu/bison unix/bin/ls.c - The exception "!emacs/test" above is functionally equivalent - to specifying "!emacs/tests" on the "checkout" command line. - - Another way to look at it is that the modules file is simply another - way to "name" files. The hierarchical directory structure provides - another. You should use whatever turns out to be simplest for your - development group. - - See 4G.2 for some specific ideas about how to use the modules file. - - Last modified: _11/12/1997_ - - 12. What does "merge" mean? - - A merge is a way of combining changes made in two independent copies - of a common starting file. Checking out an RCS revision produces a - file, so for the purposes of a merge "file" and "revision" are - equivalent. So, we can say there are always three "files" involved in - a merge: - - The original, starting, "base" or "branch point" file. - - A copy of the base file modified in one way. - - Another copy of the base file modified in a different way. - - Humans aren't very good at handling three things at once, so the - terminology dealing with merges can become strained. One way to think - about it is that all merges are performed by inserting the difference - between a base revision and a later revision (committed by someone - else) into your working file. Both the "later" revision and your - working file are presumed to have started life as a copy of the "base" - revision. - - In CVS, there are three main types of "merge": - - The "update" command automatically merges revisions committed by - others into your working file. In this case, the three files involved - in the merge are: - - Base: The revision you originally checked out. Later: A revision - committed onto the current branch after you checked out the Base - revision. Working: Your working file. The one lying in the working - directory containing changes you have made. - - The "update -j {optional files}" command merges changes - made on the given branch into your working files, which is presumed to - be on the Main line of development. - - See 4C.6 - - The "update -j -j {optional files}" command merges the - difference between two specified revisions into files in your working - directory. The two revisions are usually on the same branch and, - when updating multiple files, they are most useful when they are Tag - names rather than numeric revisions. - - See 4C.7 - - Last modified: _6/13/1997_ - - Category: /What_is_CVS_/What_is_CVS_Whats_it/ - - " + What is CVS? What's it for? Why CVS?" - - 1. What does CVS stand for? Can you describe it in one sentence? - - "CVS" is an acronym for the "Concurrent Versions System". - - CVS is a "Source Control" or "Revision Control" tool designed to keep - track of source changes made by groups of developers working on the - same files, allowing them to stay in sync with each other as each - individual chooses. - - Last modified: _6/13/1997_ - - 2. What is CVS for? What does it do for me? - - CVS is used to keep track of collections of files in a shared - directory called "The Repository". Each collection of files can be - given a "module" name, which is used to "checkout" that collection. - - After checkout, files can be modified (using your favorite editor), - "committed" back into the Repository and compared against earlier - revisions. Collections of files can be "tagged" with a symbolic name - for later retrieval. - - You can add new files, remove files you no longer want, ask for - information about sets of files in three different ways, produce patch - "diffs" from a base revision and merge the committed changes of other - developers into your working files. - - Last modified: _6/13/1997_ - - 3. How does CVS work? - - CVS saves its version-control information in RCS files stored in a - directory hierarchy, called the Repository, which is separate from the - user's working directory. - - Files in the Repository are stored in a format dictated by the RCS - commands CVS uses to do much of its real work. RCS files are standard - byte-stream files with an internal format described by keywords stored - in the files themselves. - - To begin work, you execute a "checkout" command, handing it a module - name or directory path (relative to the $CVSROOT variable) you want to - work on. CVS copies the latest revision of each file in the specified - module or directory out of the Repository and into a directory tree - created in your current directory. You may specify a particular branch - to work on by symbolic name if you don't want to work on the default - (main or trunk) branch. - - You may then modify files in the new directory tree, build them into - output files and test the results. When you want to make your changes - available to other developers, you "commit" them back into the - Repository. - - Other developers can check out the same files at the same time. To - merge the committed work of others into your working files you use the - "update" command. When your merged files build and test correctly, you - may commit the merged result. This method is referred to as - "copy-modify-merge", which does not require locks on the source files. - - At any time, usually at some milestone, you can "tag" the committed - files, producing a symbolic name that can be handed to a future - "checkout" command. A special form of "tag" produces a branch in - development, as usually happens at "release" time. - - When you no longer plan to modify or refer to your local copy of the - files, they can be removed. - - Last modified: _6/13/1997_ - - 4. What is CVS useful for? - - CVS is intended to handle source control for files in three major - situations: - - Multiple developers working on the same files. - - The major advantage of using CVS over the simpler tools like RCS or - SCCS is that it allows multiple developers to work on the same sources - at the same time. - - The shared Repository provides a rendezvous for committed sources that - allows developers a fair amount of flexibility in how often to publish - (via the "commit" command) changes or include work committed by others - (via the "update" command). - - Tracking a stream of releases from a source vendor. - - If you are making changes to sources distributed by someone else, the - CVS feature, called the Vendor Branch, allows you to combine local - modifications with repeated vendor releases. - - I have found this most useful when dealing with sources from three - major classes of source vendor: - - Large companies who send you tapes full of the latest release (e.g. - Unix OS vendors, database companies). - - Public Domain software which *always* requires work. - - Pseudo-Public sources which may require work. (e.g. GNU programs, X, - CVS itself, etc.) - - Branching development. - - Aside from the "Vendor Branch", there are three kinds of "branches in - development" that CVS can support: - - Your working directory can be treated as a private branch. - - A Development branch can be shared by one or more developers. - - At release time, a branch is usually created for bug fixes. - - (See 1D.9 and Section 4C for more info on branches.) - - CVS's branch support is a bit primitive, but it was designed to allow - you to create branches, work on them for while and merge them back - into the main line of development. You should also be able to merge - work performed on the main branch into the branch you are working on. - Arbitrary sharing and merging between branches is not currently - supported. - - Last modified: _6/13/1997_ - - 5. What is CVS *not* useful for? - - CVS is not a build system. - - Though the structure of your Repository and modules file interact with - your build system (e.g. a tree of Makefiles), they are essentially - independent. - - CVS does not dictate how you build anything. It merely stores files - for retrieval in a tree structure you devise. - - CVS does not dictate how to use disk space in the checked out working - directories. If you require your Makefiles or build procedures to know - the relative positions of everything else, you wind up requiring the - entire Repository to be checked out. That's simply bad planning. - - If you modularize your work, and construct a build system that will - share files (via links, mounts, VPATH in Makefiles, etc.), you can - arrange your disk usage however you like. - - But you have to remember that *any* such system is a lot of work to - construct and maintain. CVS does not address the issues involved. You - must use your brain and a collection of other tools to provide a build - scheme to match your plans. - - Of course, you should use CVS to maintain the tools created to support - such a build system (scripts, Makefiles, etc). - - CVS is not a substitute for management. - - You and your project leaders are expected to plan what you are doing. - Everyone involved must be aware of schedules, merge points, branch - names, release dates and the range of procedures needed to build - products. (If you produce it and someone else uses it, it is a - product.) CVS can't cover for a failure to manage your project. - - CVS is an instrument for making sources dance to your tune. But you - are the piper and the composer. No instrument plays itself or writes - its own music. - - CVS is not a substitute for developer communication. - - When faced with conflicts within a single file, most developers manage - to resolve them without too much effort. But a more general definition - of "conflict" includes problems too difficult to solve without - communication between developers. - - CVS cannot determine when simultaneous changes within a single file, - or across a whole collection of files, will logically conflict with - one another. Its concept of a "conflict" is purely textual, arising - when two changes to the same base file are near enough to spook the - merge command into dropping conflict markers into the merged file. - - CVS is not capable of figuring out distributed conflicts in program - logic. For example, if you change the arguments to function X defined - in file A and, at the same time, edit file B, adding new calls to - function X using the old arguments. You are outside the realm of CVS's - competence. - - Acquire the habit of reading specs and talking to your peers. - - CVS is not a configuration management system. - - CVS is a source control system. The phrase "configuration management" - is a marketing term, not an industry-recognized set of functions. - - A true "configuration management system" would contain elements of the - following: - - * Source control. - * Dependency tracking. - * Build systems (i.e. What to build and how to find - things during a build. What is shared? What is local?) - * Bug tracking. - * Automated Testing procedures. - * Release Engineering documentation and procedures. - * Tape Construction. - * Customer Installation. - * A way for users to run different versions of the same - software on the same host at the same time. - - CVS provides only the first. - - Last modified: _6/13/1997_ - - Category: /What_is_CVS_/Where_do_I_find_CVS_/ - - " + Where do I find CVS? Where can I find Help?" - - 1. How do I get more information about CVS? - - The first thing I would do is to read the Info file that comes with - the CVS sources under "doc". You can format and read the cvs.texinfo - file in two ways: 1. Use TeX to format it and a "dvips" command to - print it and 2. Install the cvs.info files that are created by the - Makefile and read them online using the Emacs "info-mode" or a - stand-alone "info" reader. - - Then I'd run "cvsinit" to set up a Repository and read the man page - while trying out the commands. - - Type "cvs -H" for general help or "cvs -H command" for - command-specific help. - - For background, you can read the original CVS paper (in the source - tree, under "doc"). It describes the purpose of CVS and some of how it - was designed. Note that the emphasis of the document (especially on - multiple vendors providing the same sources) is somewhat out of date. - - For more detailed information about "internals", read the man pages - for RCS. If you are a programmer, you can also read the source code to - CVS. - - Other information and tutorials may be available in the "doc" - directory of the FTP archive described below. - - For current information, and a fair amount of detail, join the - info-cvs mailing list described below. - - Last modified: _6/13/1997_ - - 2. Is there an archive of CVS material? - - An anonymous FTP area has been set up. It contains many of the CVS - files you might want, including extra documentation, patches and a - copy of the latest release. - - ftp ftp.delos.com - >>> User: anonymous - >>> Passwd: - cd /pub/cvs - get README - get Index - - The README has more (and more up-to-date) information. The Index - contains a terse list of what is in the archive. - - A WWW home page is also available at http://www.delos.com/cvs. - - This Didn't Exist 6/23/1998 - - Last modified: _6/24/1998_ - - 3. How do I get files out of the archive if I don't have FTP? - - Use one of the FTP<->Email servers. These are the ones I've been told - about: - - FTPMAIL service is available from the same host as the FTP server - described above. Send mail to "ftpmail@delos.com" containing "help" in - the body of the message. For example, on most Unix systems, you can - type: - - echo help | Mail ftpmail@delos.com - - The FTPMAIL server will respond with a document describing how to use - the server. If the "Mail" command doesn't exist on your system, try - "mailx", "/usr/ucb/mail" or "/bin/mail". - - If you are on BITNET, use Princeton's BITFTP server. Type - - echo 'send help' | Mail bitftp@pucc.princeton.edu - - (It is likely that only BITNET addresses can use this one.) - - Other possibilities I've heard of from the net: (Try the one closest - to you.) - - ftpmail@decwrl.dec.com ftpmail@sunsite.unc.edu ftpmail@cs.arizona.edu - ftpmail@cs.uow.edu.au ftpmail@doc.ic.ac.uk - - Last modified: _6/13/1997_ - - 4. How do I get a copy of the latest version of CVS? - - The latest released version of CVS and all the programs it depends on - should be available through anonymous FTP on any FSF archive. The main - FSF archive is at "prep.ai.mit.edu". There are mirrors of the FSF - archive on UUNET and other large Internet sites. - - Program(s) Suggested revision - ----------- ----------------------- - CVS 1.5 - RCS 5.7 (latest version available today) - GNU diff 2.7 (or later) [contained in diffutils-2.7] - GDBM 1.5 (or later) [optional] - - The GNU version of diff is suggested by both the RCS and CVS - configuration instructions because it works better than the standard - version. - - It is a good idea not to accept the versions of CVS, RCS or diff you - find lying on your system unless you have checked out their - provenance. Using inconsistent collections of tools can cause you more - trouble than you can probably afford. - - The FTP archive mentioned above should contain the latest official - release of CVS, some official and unofficial patches and possibly - complete patched versions of CVS in use somewhere. - - Last modified: _6/13/1997_ - - 5. Is there a mailing list devoted to CVS? How do I find it? - - An Internet mailing list named "info-cvs" grew out of the private - mailing list used by the CVS 1.3 alpha testers in early 1992. - Throughout 1994, the list received an average of 100 messages per - month. - - You can add yourself to the mailing list by sending an Email message - to: - - info-cvs-request@prep.ai.mit.edu - - (Don't forget the "-request" or you'll send a message to the whole - list, some of whom are capable of remote execution.) - - Mail to the whole list should be sent to: - - info-cvs@prep.ai.mit.edu - - An archive of the mailing list is maintained in the FTP archive - mentioned above. - - Last modified: _6/13/1997_ - - 6. What happened to the CVS Usenet newsgroup I heard about? - - - A Usenet newsgroup named "gnu.cvs.info" was announced in April - 1993, with an expected creation date of August, 1993. However, - nothing came of this. - - If you want to discuss CVS on usenet, the correct group is - comp.software.config-mgmt (which also covers other configuration - management systems). Someday it might be possible to create a - comp.software.config-mgmt.cvs, but only if there is sufficient - CVS traffic on comp.software.config-mgmt. - - kingdon@cyclic.com - - Last modified: _9/6/1997_ - _________________________________________________________________ - - [Add an answer to this category] - - [Category /] - _________________________________________________________________ - - _Search the FAQ-O-Matic:_ ____________________ Search - [matching all words] - Or look for questions modified in the last: [7.] Days - _________________________________________________________________ - - 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. - _________________________________________________________________ diff --git a/contrib/cvs/FREEBSD-Xlist b/contrib/cvs/FREEBSD-Xlist deleted file mode 100644 index f598106..0000000 --- a/contrib/cvs/FREEBSD-Xlist +++ /dev/null @@ -1,22 +0,0 @@ -$FreeBSD$ -*/*.com -*/*.dep -*/*.dsp -*/*.mak -*/.cvsignore -.cvsignore -README.VMS -build.com -cvs.spec* -cvsnt.* -doc/*.info* -doc/*.pdf -doc/*.ps -doc/texinfo.tex -emx -lib/getdate.c -os2 -vms -windows-NT -ylwrap -zlib diff --git a/contrib/cvs/FREEBSD-upgrade b/contrib/cvs/FREEBSD-upgrade deleted file mode 100644 index 67b13c2..0000000 --- a/contrib/cvs/FREEBSD-upgrade +++ /dev/null @@ -1,45 +0,0 @@ -$FreeBSD$ - -MAINTAINER= peter@FreeBSD.org - -This directory contains the virgin CVS source on the vendor branch. Do -not under any circumstances commit new versions onto the mainline, new -versions or official-patch versions must be imported. - -To prepare a new cvs dist for import, extract it into a fresh directory; -then delete the files and directories listed in FREEBSD-Xlist. - -CVS is imported from its top level directory something like this: - cvs -n import src/contrib/cvs CVSHOME v - -The -n option is "don't do anything" so you can see what is about to happen -first. Remove it when it looks ok. - -The initial import was done with: - cvs import src/contrib/cvs CVSHOME v1_11_22 - -When new versions are imported, cvs will give instructions on how to merge -the local and vendor changes when/if conflicts arise. - -The developers can be reached at: . Local changes -that are suitable for public consumption should be submitted for inclusion -in future releases. - -peter@freebsd.org - 20 Aug 1996 -obrien@freebsd.org - 12 Jan 2008 - -Current local changes: - - CVS_LOCAL_BRANCH_NUM environment variable support for choosing the - magic branch number. (for CVSup local-commit support) - - CVSREADONLYFS environment variable and global option -R to enable - no-locking readonly mode (eg: cvs repo is a cdrom or mirror) - - the verify message script can edit the submitted log message. - - CVSROOT/options file - - Variable keyword expansion controls including custom keywords. - - $ CVSHeader$ keyword - like Header, but with $CVSROOT stripped off. - - 'CVS_OPTIONS' environmental variable support. - - Allow -D with -r on checkout. - - Support for "diff -j", allowing tag:date based diffs. - - iso8601 option keyword. - - Comprehensive "-T" CVS/Template support. - - We use the cvs.1 manpage from man/, not the offical one in doc/ diff --git a/contrib/cvs/FREEBSD-vendstock b/contrib/cvs/FREEBSD-vendstock deleted file mode 100644 index 7d15f116..0000000 --- a/contrib/cvs/FREEBSD-vendstock +++ /dev/null @@ -1,11 +0,0 @@ -$FreeBSD$ -src/buffer.c -src/commit.c -src/filesubr.c -src/import.c -src/login.c -src/mkmodules.c -src/patch.c -src/rcscmds.c -src/recurse.c -contrib/sccs2rcs.in diff --git a/contrib/cvs/HACKING b/contrib/cvs/HACKING deleted file mode 100644 index c71d307..0000000 --- a/contrib/cvs/HACKING +++ /dev/null @@ -1,256 +0,0 @@ -How to write code for CVS - -* License of CVS - - CVS is Copyright (C) 1986-2006 The Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 1, or (at your option) - any later version. - - More details are available in the COPYING file but, in simplified - terms, this means that any distributed modifications you make to - this software must also be released under the GNU General Public - License. - - 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. - -* Source - -Patches against the development version of CVS are most likely to be accepted: - - $ cvs -z3 -d:pserver:anonymous@cvs.sv.nongnu.org:/sources/cvs co ccvs - -See the Savannah sources page for -more information. - -* Compiler options - -If you are using GCC, you'll want to configure with -Wall, which can -detect many programming errors. This is not the default because it -might cause spurious warnings, but at least on some machines, there -should be no spurious warnings. For example: - - $ CFLAGS="-g -Wall" ./configure - -Configure is not very good at remembering this setting; it will get -wiped out whenever you do a ./config.status --recheck, so you'll need -to use: - - $ CFLAGS="-g -Wall" ./config.status --recheck - -* Backwards Compatibility - -Only bug fixes are accepted into the stable branch. New features should be -applied to the trunk. - -If it is not inextricable from a bug fix, CVS's output (to stdout/stderr) -should not be changed on the stable branch in order to best support scripts and -other tools which parse CVS's output. It is ok to change output between -feature releases (on the trunk), though such changes should be noted in the -NEWS file. - -Changes in the way CVS responds to command line options, config options, etc. -should be accompanied by deprecation warnings for an entire stable series of -releases before being changed permanently, if at all possible. - -* Indentation style - -CVS mostly uses a consistent indentation style which looks like this: - -void -foo (arg) - char *arg; -{ - if (arg != NULL) - { - bar (arg); - baz (arg); - } - switch (c) - { - case 'A': - aflag = 1; - break; - } -} - -The file cvs-format.el contains settings for emacs and the NEWS file -contains a set of options for the indent program which I haven't tried -but which are correct as far as I know. You will find some code which -does not conform to this indentation style; the plan is to reindent it -as those sections of the code are changed (one function at a time, -perhaps). - -In a submitted patch it is acceptable to refrain from changing the -indentation of large blocks of code to minimize the size of the patch; -the person checking in such a patch should reindent it. - -* Portability - -The general rule for portability is that it is only worth including -portability cruft for systems on which people are actually testing and -using new CVS releases. Without testing, CVS will fail to be portable -for any number of unanticipated reasons. - -The current consequence of that general rule seems to be that if it -is in ANSI C and it is in SunOS4 (using /bin/cc), generally it is OK -to use it without ifdefs (for example, assert() and void * as long as -you add more casts to and from void * than ANSI requires. But not -function prototypes). Such constructs are generally portable enough, -including to NT, OS/2, VMS, etc. - -* Run-time behaviors - -Use assert() to check "can't happen" conditions internal to CVS. We -realize that there are functions in CVS which instead return NULL or -some such value (thus confusing the meaning of such a returned value), -but we want to fix that code. Of course, bad input data, a corrupt -repository, bad options, etc., should always print a real error -message instead. - -Do not use arbitrary limits (such as PATH_MAX) except perhaps when the -operating system or some external interface requires it. We spent a -lot of time getting rid of them, and we don't want to put them back. -If you find any that we missed, please report it as with other bugs. -In most cases such code will create security holes (for example, for -anonymous readonly access via the CVS protocol, or if a WWW cgi script -passes client-supplied arguments to CVS). - -Although this is a long-term goal, it also would be nice to move CVS -in the direction of reentrancy. This reduces the size of the data -segment and will allow a multi-threaded server if that is desirable. -It is also useful to write the code so that it can be easily be made -reentrant later. For example, if you need to pass data from a -Parse_Info caller to its callproc, you need a static variable. But -use a single pointer so that when Parse_Info is fixed to pass along a -void * argument, then the code can easily use that argument. - -* Coding standards in general - -Generally speaking the GNU coding standards are mostly used by CVS -(but see the exceptions mentioned above, such as indentation style, -and perhaps an exception or two we haven't mentioned). This is the -file standards.text at the GNU FTP sites. - -* Regenerating Build Files - -On UNIX, if you wish to change the Build files, you will need Autoconf and -Automake. - -Some combinations of Automake and Autoconf versions may break the -CVS build if file timestamps aren't set correctly and people don't -have the same versions the developers do, so the rules to run them -automatically aren't included in the generated Makefiles unless you run -configure with the --enable-maintainer-mode option. - -The CVS Makefiles and configure script were built using Automake 1.10 and -Autoconf 2.61, respectively. - -There is a known bug in Autoconf 2.57 that will prevent the configure -scripts it generates from working on some platforms. Other combinations of -autotool versions may or may not work. If you get other versions to work, -please send a report to . - -* Writing patches (strategy) - -Only some kinds of changes are suitable for inclusion in the -"official" CVS. Bugfixes, where CVS's behavior contradicts the -documentation and/or expectations that everyone agrees on, should be -OK (strategically). For features, the desirable attributes are that -the need is clear and that they fit nicely into the architecture of -CVS. Is it worth the cost (in terms of complexity or any other -tradeoffs involved)? Are there better solutions? - -If the design is not yet clear (which is true of most features), then -the design is likely to benefit from more work and community input. -Make a list of issues, or write documentation including rationales for -how one would use the feature. Discuss it with coworkers, a -newsgroup, or a mailing list, and see what other people think. -Distribute some experimental patches and see what people think. The -intention is arrive at some kind of rough community consensus before -changing the "official" CVS. Features like zlib, encryption, and -the RCS library have benefitted from this process in the past. - -If longstanding CVS behavior, that people may be relying on, is -clearly deficient, it can be changed, but only slowly and carefully. -For example, the global -q option was introduced in CVS 1.3 but the -command -q options, which the global -q replaced, were not removed -until CVS 1.6. - -* Writing patches (tactics) - -When you first distribute a patch it may be suitable to just put forth -a rough patch, or even just an idea. But before the end of the -process the following should exist: - - - ChangeLog entry (see the GNU coding standards for details). - - - Changes to the NEWS file and cvs.texinfo, if the change is a - user-visible change worth mentioning. - - - Somewhere, a description of what the patch fixes (often in - comments in the code, or maybe the ChangeLog or documentation). - - - Most of the time, a test case (see TESTS). It can be quite - frustrating to fix a bug only to see it reappear later, and adding - the case to the testsuite, where feasible, solves this and other - problems. See the TESTS file for notes on writing new tests. - -If you solve several unrelated problems, it is generally easier to -consider the desirability of the changes if there is a separate patch -for each issue. Use context diffs or unidiffs for patches. - -Include words like "I grant permission to distribute this patch under -the terms of the GNU Public License" with your patch. By sending a -patch to bug-cvs@nongnu.org, you implicitly grant this permission. - -Submitting a patch to bug-cvs is the way to reach the people who have -signed up to receive such submissions (including CVS developers), but -there may or may not be much (or any) response. If you want to pursue -the matter further, you are probably best off working with the larger -CVS community. Distribute your patch as widely as desired (mailing -lists, newsgroups, web sites, whatever). Write a web page or other -information describing what the patch is for. It is neither practical -nor desirable for all/most contributions to be distributed through the -"official" (whatever that means) mechanisms of CVS releases and CVS -developers. Now, the "official" mechanisms do try to incorporate -those patches which seem most suitable for widespread usage, together -with test cases and documentation. So if a patch becomes sufficiently -popular in the CVS community, it is likely that one of the CVS -developers will eventually try to do something with it. But dealing -with the CVS developers may be the last step of the process rather -than the first. - -* What is the schedule for the next release? - -There isn't one. That is, upcoming releases are not announced (or -even hinted at, really) until the feature freeze which is -approximately 2 weeks before the final release (at this time test -releases start appearing and are announced on info-cvs). This is -intentional, to avoid a last minute rush to get new features in. - -* Mailing lists - -In addition to the mailing lists listed in the README file, developers should -take particular note of the following mailling lists: - - bug-cvs: This is the list which users are requested to send bug reports - to. General CVS development and design discussions also take place on - this list. - info-cvs: This list is intended for user questions, but general CVS - development and design discussions sometimes take place on this list. - cvs-cvs: The only messages sent to this list are sent - automatically, via the CVS `loginfo' mechanism, when someone - checks something in to the master CVS repository. - cvs-test-results: The only messages sent to this list are sent - automatically, daily, by a script which runs "make check" - and "make remotecheck" on the master CVS sources. - -To subscribe to any of these lists, send mail to -request@nongnu.org -or visit http://savannah.nongnu.org/mail/?group=cvs and follow the instructions -for the list you wish to subscribe to. diff --git a/contrib/cvs/INSTALL b/contrib/cvs/INSTALL deleted file mode 100644 index e271fc0..0000000 --- a/contrib/cvs/INSTALL +++ /dev/null @@ -1,517 +0,0 @@ -------------------------------------------------------------------------------- - -CVS is Copyright (C) 1986-2006 The Free Software Foundation, Inc. - -CVS is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 1, or (at your option) -any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -------------------------------------------------------------------------------- - -Now back to our regularly scheduled program: - -Please read the README file before reading this INSTALL file. Then, to -install CVS: - - -First you need to obtain and install the CVS executables. If you got -a distribution which contains executables, consult the installation -instructions for that distribution. If you got source code, do not -panic. On many platforms building CVS from source code is a -straightforward process requiring no programming knowledge. See the -section BUILDING FROM SOURCE CODE at the end of this file, which -includes a list of platforms which have been tested. - -------------------------------------------------------------------------------- - -1) Take a look at the CVS documentation, if desired. For most - purposes you want doc/cvs.texinfo, also known as _Version Management - with CVS_ by Per Cederqvist et al. Looking at it might be as simple - as "info cvs" but this will depend on your installation; see README - for more details. - - See what CVS can do for you, and if it fits your environment (or can - possibly be made to fit your environment). If things look good, - continue on. Alternately, just give CVS a try first then figure out - what it is good for. - -2) Set the CVSROOT environment variable to where you want to put your - source repository. See the "Setting up the repository" section of - the Cederqvist manual for details, but the quick summary is just to - pick some directory. We'll use /src/master as an example. For - users of a POSIX shell (sh/bash/ksh) on unix, the following - commands can be placed in user's ~/.profile, ~/.bash_profile file; - or in the site-wide /etc/profile: - - CVSROOT=/src/master; export CVSROOT - - For C shell users on unix place the following commands in the - user's ~/.cshrc, ~/.login, or /etc/chsrc file: - - setenv CVSROOT /src/master - - For Windows users, supposing the repository will be in - d:\src\master, place the following line in c:\autoexec.bat. On - Windows 95, autoexec.bat might not already exist. In that case, - just create a new file containing the following line. - - set CVSROOT=:local:d:\src\master - - If these environment variables are not already set in your current - shell, set them now by typing the above line at the command prompt - (or source the login script you just edited). - The instructions for the remaining steps assume that you have set - the CVSROOT environment variable. - -3) Create the master source repository. Again, the details are in - the "Setting up the repository" section of cvs.texinfo; the - one-line summary is: - - $ cvs init - - In this and subsequent examples we use "$" to indicate the command - prompt; do not type the "$". - -4) It might be a good idea to jump right in and put some sources or - documents directly under CVS control. From within the top-level - directory of your source tree, run the following commands: - - $ cvs import -m "test distribution" ccvs CVS_DIST CVS-TEST - - (Those last three items are, respectively, a repository location, a - "vendor tag", and a "release tag". You don't need to understand - them yet, but read the section "Starting new projects" in the - Cederqvist manual for details). - -5) Having done step 4, one should be able to checkout a fresh copy of the - sources you just imported and hack away at the sources with the - following command: - - $ cd - $ cvs checkout ccvs - - This will make the directory "ccvs" in your current directory and - populate it with the appropriate files and directories. - -6) You may wish to customize the various administrative files, in particular - modules. See the Cederqvist manual for details. - -7) Read the NEWS file to see what's new. - -8) Hack away. - -------------------------------------------------------------------------------- - -BUILDING FROM SOURCE CODE - -Tested platforms - -CVS has been tested on the following platforms. The most recent -version of CVS reported to have been tested is indicated, but more -recent versions of CVS probably will work too. Please send updates to -this list to bug-cvs@nongnu.org (doing so in the form of a diff -to this file, or at least exact suggested text, is encouraged). -"tested" means, at a minimum, that CVS compiles and appears to work on -simple (manual) testing. In many cases it also means "make check" -and/or "make remotecheck" passes, but we don't try to list the -platforms for which that is true. - -Alpha: - DEC Alpha running OSF/1 version 1.3 using cc (about 1.4A2) - DEC Alpha running OSF/1 version 2.0 (1.8) - DEC Alpha running OSF/1 version 2.1 (about 1.4A2) - DEC Alpha running OSF/1 version 3.0 (1.5.95) (footnote 7) - DEC Alpha running OSF/1 version 3.2 (1.9) - Alpha running alpha-dec-osf4.0 (1.10) - DEC Alpha running Digital UNIX v4.0C using gcc 2.7.2.2 (1.9.14) - DEC Alpha running VMS 6.2 (1.8.85 client-only) - Alpha running NetBSD 1.2E (1.10) -Cray: - J90 (CVS 970215 snapshot) - T3E (CVS 970215 snapshot) -HPPA: - HP 9000/710 running HP-UX 8.07A using gcc (about 1.4A2) - HPPA running HP-UX 9 (1.8) - HPPA 1.1 running HP-UX A.09.03 (1.5.95) (footnote 8) - 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.10.7) - HPPA running HP-UX 11.11 (1.11.13) (footnote 12) - HPPA 2.0 running HP-UX 10.20 (1.10.9) (footnote 13) - NextSTEP 3.3 (1.7) -i386 family: - Solaris 2.4 using gcc (about 1.4A2) - Solaris 2.6 (1.9) - UnixWare v1.1.1 using gcc (about 1.4A2) - Unixware 2.1 (1.8.86) - Unixware 7 (1.9.29) - ISC 4.0.1 (1.8.87) - 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) - Linux (kernel 2.2.x, RedHat 6.x) (1.10.8) - Linux (kernel 2.2.x, RedHat 7.x) (1.11) - 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) - SCO OpenServer 5.0.5 (1.10.2) - Sequent DYNIX/ptx4.0 (1.10 or so) (remove -linet) - Sequent Dynix/PTX 4.1.4 (1.9.20 or so + patches) - Lynx 2.3.0 080695 (1.6.86) (footnote 9) - Windows NT 3.51 (1.8.86 client; 1.8.3 local) - Windows NT 3.51 service pack 4 (1.9) - Windows NT 3.51 service pack 5 (1.9) -- DOES NOT WORK (footnote 11) - Windows NT 4.0 (1.9 client and local) - Windows NT 4.0 (1.11 client and local - build & test, but no test suite) - Windows 95 (1.9 client and local) - QNX (1.9.1 + patches for strippath() and va_list) - OS/2 Version 3 using IBM C/C++ Tools 2.01 (1.8.86 + patches, client) - OS/2 Version 3 using EMX 0.9c (1.9.22, client) - OS/2 Version 3 using Watcom version ? (? - has this been tested?) -m68k: - Sun 3 running SunOS 4.1.1_U1 w/ bundled K&R /usr/5bin/cc (1.8.86+) - NextSTEP 3.3p1 (1.8.87) - Lynx 2.3.0 062695 (1.6.86) (footnote 9) - NetBSD/mac68k (1.9.28) -m88k: - Data General AViiON running dgux 5.4R2.10 (1.5) - Data General AViiON running dgux 5.4R3.10 (1.7.1) - Harris Nighthawk 5800 running CX/UX 7.1 (1.5) (footnote 6) -MIPS: - DECstation running Ultrix 4.2a (1.4.90) - DECstation running Ultrix 4.3 (1.10) - SGI running Irix 4.0.5H using gcc and cc (about 1.4A2) (footnote 2) - SGI running Irix 5.3 (1.10) - 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) - Linux DR3 GENERIC #6 (1.10.5.1) (presumably LinuxPPC too) - Mac OS X ALL (footnote 14) - Mac OS X Darwin 6.6 Darwin Kernel Version 6.6 (1.11.1p1) - Mac OS X Darwin 5.5 Darwin Kernel Version 5.5 (1.11.6) (footnote 12) - Mac OS X Darwin 5.5 Darwin Kernel Version 5.5 (1.12.1) (footnote 12) -SPARC: - Sun SPARC running SunOS 4.1.x (1.10) - Sun SPARCstation 10 running Solaris 2.3 using gcc and cc (about 1.4A2) - 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) - Sun UltraSPARC running Solaris 2.8 using gcc 2.95.3 -VAX: - VAX running VMS 6.2 (1.9+patches, client-only) - (see README.VMS for information on necessary hacks). - -(footnote 2) - Some Irix 4.0 systems may core dump in malloc while running - CVS. We believe this is a bug in the Irix malloc. You can - workaround this bug by linking with "-lmalloc" if necessary. - (about 1.4A2). - -(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 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. - -(footnote 7) Manoj Srivastava reports - success with this configure command: - CC=cc CFLAGS='-O2 -Olimit 2000 -std1' ./configure --verbose alpha-dec-osf - -(footnote 8) Manoj Srivastava reports - success with this configure command: - CC=cc CFLAGS='+O2 -Aa -D_HPUX_SOURCE' ./configure --verbose hppa1.1-hp-hpux - -(footnote 9) - Had to configure with ./configure --host=-lynx. - - In src/cvs.h, protected the waitpid prototype with ifdef _POSIX_SOURCE. - (I might try building with gcc -mposix -D_POSIX_SOURCE.) - - LynxOS has , but you don't want to use it. - You want to use instead. - So after running configure I had to undef HAVE_DIRENT_H and - define HAVE_SYS_DIR_H. - -(footnote 10) - Had to compile with "make LIBS=-lbsd" (to get gethostbyname - and getservbyname). - -(footnote 11) - when I do a `cvs init' I get this message: - ci: 'RCS/loginfo,v' is not a regular file - ci: RCS/loginfo,v: Invalid argument - cvs [init aborted]: failed to checkin n:/safe/CVSROOT/loginfo - -(footnote 12) - Need to `configure --without-gssapi' unless you have installed Kerberos 5 - libraries on the system yourself. For some reason Apple ships OS X with - the Kerberos 5 headers installed and not the libraries, which confuses the - current configure script. Some HP, BSD, & Sun boxes have similar problems. - -(footnote 13) - A build under HP PA-RISC 2.0 will probably not run under PA-RISC 1.1 - unless "+DAportable" is added to the HP ANSI cc compiler flags. - -(footnote 14) - Because of the case-insensitive file system on Mac OS X, you cannot build - CVS directly from a checkout from CVS. The name of the built executable, - `cvs', conflicts with name of the CVS administration directory, `CVS'. - The work-around is to build the executable from a build directory separate - from the source directory. i.e.: - - cvs co ccvs; cd ccvs - mkdir build; cd build - ../configure && make - -------------------------------------------------------------------------------- - -Building from source code under Unix: - -1) Run "configure": - - $ ./configure - - You can specify an alternate destination to override the default with - the --prefix option: - - $ ./configure --prefix=/usr/local/gnu - - or some path that is more appropriate for your site. The default prefix - value is "/usr/local", with binaries in sub-directory "bin", manual - pages in sub-directory "man", and libraries in sub-directory "lib". - - A normal build of CVS will create an executable which supports - local, server, or client CVS (if you don't know the difference, - it is described in the Repository chapter of doc/cvs.texinfo). If - you do not intend to use client or server CVS, you may want to - prevent these features from being included in the executable you - build. You can do this with the --disable-client and - --disable-server options: - - $ ./configure --disable-client --disable-server - - Typically this can reduce the size of the executable by around 30%. - - If you are building CVS with the server enabled, you can disable - server flow control using the --disable-server-flow-control - If you are working with a large remote repository and a 'cvs - checkout' is swamping your network and memory, enable flow control. - You will end up with even less probability of a consistent checkout - (see Concurrency in cvs.texinfo), but CVS doesn't try to guarantee - that anyway. The master server process will monitor how far it is - getting behind, if it reaches the high water mark, it will signal - the child process to stop generating data when convenient (ie: no - locks are held, currently at the beginning of a new directory). - Once the buffer has drained sufficiently to reach the low water - mark, it will be signalled to start again. You may override the - default hi/low watermarks here too by passing - ',', in bytes, as an argument to - --enable-server-flow-control. The low water mark defaults to one - megabyte and the high water mark defaults to two megabytes. - - $ ./configure --enable-server-flow-control=1M,2M - - The --with-tmpdir argument to configure may be used to set a - specific directory for use as a default temporary directory. If not - set, configure will pick the first directory it finds which it has - read, write, and execute permissions to from $TMPDIR, $TMP, $TEMP, - /tmp, and /var/tmp, in that order. Failing that, it will use /tmp. - - The --with-umask argument to configure can be used to change - the default umask used by the CVS server executable. - - Unlike previous versions of CVS, you do not need to install RCS - or GNU diff. - - If you are using gcc and are planning to modify CVS, you may want to - configure with -Wall; see the file HACKING for details. - - If you have Kerberos 4 installed, you can specify the location of - the header files and libraries using the --with-krb4=DIR option. - DIR should be a directory with subdirectories include and lib - holding the Kerberos 4 header files and libraries, respectively. - The default value is /usr/kerberos. - - If you want to enable support for encryption over Kerberos, use - the --enable-encryption option. This option is disabled by - default. - - If you want to disable automatic dependency tracking in the makefiles, - use the '--disable-dependency-tracking' option: - - $ ./configure --disable-dependency-tracking - - This avoids problems on some platforms. See the note at the end of this - file on BSD. - - Try './configure --help' for further information on its usage. - - NOTE ON CVS's USE OF NDBM: - - By default, CVS uses some built-in ndbm emulation code to allow - CVS to work in a heterogeneous environment. However, if you have - a very large modules database, this may not work well. You will - need to supply the --disable-cvs-ndbm option to configure to - accomplish this. If you do this, the following comments apply. If - not, you may safely skip these comments. - - If you configure CVS to use the real ndbm(3) libraries and - you do not have them installed in a "normal" place, you will - probably want to get the GNU version of ndbm (gdbm) and install - that before running the CVS configure script. Be aware that the - GDBM 1.5 release does NOT install the header file included - with the release automatically. You may have to install it by hand. - - If you configure CVS to use the ndbm(3) libraries, you cannot - compile CVS with GNU cc (gcc) on Sun-4 SPARC systems. However, gcc - 2.0 may have fixed this limitation if -fpcc-struct-return is - defined. When using gcc on other systems to compile CVS, you *may* - need to specify the -fpcc-struct-return option to gcc (you will - *know* you have to if "cvs checkout" core dumps in some ndbm - function). You can do this as follows: - - $ CC='gcc -fpcc-struct-return' ./configure - - for sh, bash, and ksh users and: - - % setenv CC 'gcc -fpcc-struct-return' - % ./configure - - for csh and tcsh users. - - END OF NOTE FOR NDBM GUNK. - -2) Try to build it: - - $ make - - This will (hopefully) make the needed CVS binaries within the - "src" directory. If something fails for your system, and you want - to submit a bug report, you may wish to include your - "config.status" file, your host type, operating system and - compiler information, make output, and anything else you think - will be helpful. - -3) Run the regression tests (optional). - - You may also wish to validate the correctness of the new binary by - running the regression tests. If they succeed, that is nice to - know. However, if they fail, it doesn't tell you much. Often it - will just be a problem with running the tests on your machine, - rather than a problem with CVS. Unless you will have the time to - determine which of the two it is in case of failure, you might - want to save yourself the time and just not run the tests. - - If you want to run the tests, see the file TESTS for more information. - -4) Install the binaries/documentation: - - $ make install - - Depending on your installation's configuration, you may need to be - root to do this. - -------------------------------------------------------------------------------- - -Detailed information about your interaction with "configure": - -The "configure" script and its interaction with its options and the -environment is described here. For more detailed documentation about -"configure", please run `./configure --help' or refer to the GNU Autoconf -documentation. - -Supported options are: - - --srcdir=DIR Useful for compiling on many different - machines sharing one source tree. - --prefix=DIR The root of where to install the - various pieces of CVS (/usr/local). - --exec_prefix=DIR If you want executables in a - host-dependent place and shared - things in a host-independent place. - -The following environment variables override configure's default -behaviour: - - CC If not set, tries to use gcc first, - then cc. Also tries to use "-g -O" - as options, backing down to -g - alone if that doesn't work. - INSTALL If not set, tries to use "install", then - "./install-sh" as a final choice. - RANLIB If not set, tries to determine if "ranlib" - is available, choosing "echo" if it doesn't - appear to be. - YACC If not set, tries to determine if "bison" - is available, choosing "yacc" if it doesn't - appear to be. - -------------------------------------------------------------------------------- - -Building from source code under Windows NT/95/98/2000: - -You may find interesting information in windows-NT/README. - -* Using Microsoft Visual C++ 5.x (this is currently broken - someone with - MVC++ 5.x needs to regenerate the project files, but the builds using `nmake' - below will work). - -1) Using Microsoft Visual C++ 5.x, open the project `cvsnt.dsw', - in the top directory of the CVS distribution. If you have an older - version of Visual C++, take a look at windows-NT/README. -2) Choose "Build cvs.exe" from the "Project" menu. -3) MSVC will place the executable file cvs.exe in WinRel, or whatever - your target directory is. - -* From the top level directory, with MSVC++ 6.0 installed, something like the -following also works: - - C:\> vcvars32 - C:\> nmake /f cvsnt.mak CFG="cvsnt - Win32 Debug" - -* Using the Cygwin development environment , Windows clients - and servers can be built using the instructions for building on UNIX. For - deploying the CVS server on Windows NT, see the `cygrunsrv' executable that - comes with Cygwin. - -* You might also try & . - -------------------------------------------------------------------------------- - -Building from source code under other platforms: - -For OS/2, see os2/README and emx/README. - -For VMS, see README.VMS - -Mac OS X: Builds fine, just like UNIX. - -For older versions of Mac OS, you might try . - -For a Java client, see jCVS (which is a separate package from CVS -itself, but which might be preferable to the Macintosh port mentioned -above, for example). - -------------------------------------------------------------------------------- diff --git a/contrib/cvs/MINOR-BUGS b/contrib/cvs/MINOR-BUGS deleted file mode 100644 index 9eb0e7b..0000000 --- a/contrib/cvs/MINOR-BUGS +++ /dev/null @@ -1,61 +0,0 @@ -Low-priority bugs go here. Actually, most every documented bug is -"low-priority"--in the sense that if it is documented it means noone -has gotten around to fixing it. - - -* "cvs update -ko -p -r REV file" doesn't seem to pay attention to the - '-ko', at least in client/server mode. A simple work around is to - temporarily change the db file with "cvs admin -ko file", then switch - it back to the original modes after the checkout (probably '-kkv'). - -* "cvs status" has a difference in its output between local and - client/server mode. Namely there's a tab character followed by a - ctime(3)-style date string at the end of the "Working revision:" - field. - -* commands which don't work in a local working directory should probably - ignore any CVS/Root values and revert to using CVSROOT alone. The - current use of CVS/Root can be very confusing if you forget you're in - a working directory for a remote module -- something that's very easy - to do since CVS hides the client operation very well, esp. for - commands which fail for this reason. The only clue might be the word - "server" in a message such as this: - cvs server: cannot find module `patch' - ignored - -* cvs init may gave a strange error at times: - ttyp4: $ cvs -d /local/src-CVS init - cvs [init aborted]: cannot open CVS/Root: No such file or directory - but it seemed to work just the same.... Note that at the time CVSROOT - was set to point to a CVS server using the ":server:" option. - -* If a ~/CVS/Root file exists on the server and you are using rsh to -connect to the server, CVS may loose its mind (this was reported in -May 1995 and I suspect the symptoms have changed, but I have no -particular reason to think the bug is fixed -kingdon, Sep 96). - -* (Jeff Johnson ) - I tried a "cvs status -v" and received the following: - - ? CVS - ? programs/CVS - ? tests/CVS - cvs server: Examining . - =================================================================== - File: Install.dec Status: Up-to-date - ... - - I claim that CVS dirs should be ignored. - (This reportedly happens if "cvs add CVS" (or "cvs add *") - is followed by "cvs status", in client/server mode - CVS 1.9). - -* On remote checkout, files don't have the right time/date stamps in - the CVS/Entries files. Doesn't look like the C/S protocol has any - way to send this information along (according to cvsclient.texi). - Perhaps we can spiff it up a bit by using the conflict field for the - stamp on the checkout/update command. Please note that this really - doesn't do very much for us even if we get it done. - -* Does the function that lists the available modules in the repository - belong under the "checkout" function? Perhaps it is more logically - grouped with the "history" function or we should create a new "info" - function? diff --git a/contrib/cvs/Makefile.am b/contrib/cvs/Makefile.am deleted file mode 100644 index 59f73de..0000000 --- a/contrib/cvs/Makefile.am +++ /dev/null @@ -1,58 +0,0 @@ -## Process this file with automake to produce Makefile.in -# Master Makefile for the GNU Concurrent Versions System. -# Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, -# 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 -# Free Software Foundation, Inc. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -## Subdirectories to run make in for the primary targets. -# Unix source subdirs, where we'll want to run lint and etags: -# This is a legacy variable from b4 Automake -USOURCE_SUBDIRS = lib zlib diff src -# All other subdirs: -SUBDIRS = $(USOURCE_SUBDIRS) man doc contrib tools \ - windows-NT os2 emx vms - -EXTRA_DIST = \ - .cvsignore \ - BUGS \ - ChangeLog.zoo \ - DEVEL-CVS \ - FAQ \ - HACKING \ - MINOR-BUGS \ - PROJECTS \ - README.VMS \ - TESTS \ - build.com \ - cvs-format.el \ - cvsnt.dep \ - cvsnt.dsp \ - cvsnt.dsw \ - cvsnt.mak \ - cvs.spec \ - mktemp.sh - - -## MAINTAINER Targets - -.PHONY: localcheck remotecheck -localcheck remotecheck: all - cd src && $(MAKE) $(AM_MAKEFLAGS) "$@" - -.PHONY: doc -doc: - cd doc && $(MAKE) $(AM_MAKEFLAGS) "$@" - -# for backwards compatibility with the old makefiles -.PHONY: realclean -realclean: maintainer-clean diff --git a/contrib/cvs/Makefile.in b/contrib/cvs/Makefile.in deleted file mode 100644 index 146448e..0000000 --- a/contrib/cvs/Makefile.in +++ /dev/null @@ -1,675 +0,0 @@ -# Makefile.in generated by automake 1.10 from Makefile.am. -# @configure_input@ - -# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006 Free Software Foundation, Inc. -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ - -# Master Makefile for the GNU Concurrent Versions System. -# Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, -# 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 -# Free Software Foundation, Inc. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -VPATH = @srcdir@ -pkgdatadir = $(datadir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -subdir = . -DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \ - $(srcdir)/Makefile.in $(srcdir)/config.h.in \ - $(srcdir)/cvs.spec.in $(top_srcdir)/configure \ - $(top_srcdir)/emx/Makefile.in $(top_srcdir)/os2/Makefile.in \ - $(top_srcdir)/zlib/Makefile.in AUTHORS COPYING COPYING.LIB \ - ChangeLog INSTALL NEWS TODO compile depcomp install-sh \ - mdate-sh missing mkinstalldirs ylwrap -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ - $(top_srcdir)/configure.in -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ - configure.lineno config.status.lineno -mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs -CONFIG_HEADER = config.h -CONFIG_CLEAN_FILES = cvs.spec emx/Makefile os2/Makefile zlib/Makefile -SOURCES = -DIST_SOURCES = -RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ - html-recursive info-recursive install-data-recursive \ - install-dvi-recursive install-exec-recursive \ - install-html-recursive install-info-recursive \ - install-pdf-recursive install-ps-recursive install-recursive \ - installcheck-recursive installdirs-recursive pdf-recursive \ - ps-recursive uninstall-recursive -RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ - distclean-recursive maintainer-clean-recursive -ETAGS = etags -CTAGS = ctags -DIST_SUBDIRS = $(SUBDIRS) -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -distdir = $(PACKAGE)-$(VERSION) -top_distdir = $(distdir) -am__remove_distdir = \ - { test ! -d $(distdir) \ - || { find $(distdir) -type d ! -perm -200 -exec chmod u+w {} ';' \ - && rm -fr $(distdir); }; } -DIST_ARCHIVES = $(distdir).tar.gz $(distdir).tar.bz2 -GZIP_ENV = --best -distuninstallcheck_listfiles = find . -type f -print -distcleancheck_listfiles = find . -type f -print -ACLOCAL = @ACLOCAL@ -AMTAR = @AMTAR@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -CC = @CC@ -CCDEPMODE = @CCDEPMODE@ -CFLAGS = @CFLAGS@ -CPP = @CPP@ -CPPFLAGS = @CPPFLAGS@ -CSH = @CSH@ -CYGPATH_W = @CYGPATH_W@ -DEFS = @DEFS@ -DEPDIR = @DEPDIR@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EDITOR = @EDITOR@ -EGREP = @EGREP@ -EXEEXT = @EXEEXT@ -GREP = @GREP@ -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -KRB4 = @KRB4@ -LDFLAGS = @LDFLAGS@ -LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ -LN_S = @LN_S@ -LTLIBOBJS = @LTLIBOBJS@ -MAINT = @MAINT@ -MAKEINFO = @MAKEINFO@ -MKDIR_P = @MKDIR_P@ -MKTEMP = @MKTEMP@ -OBJEXT = @OBJEXT@ -PACKAGE = @PACKAGE@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ -PACKAGE_NAME = @PACKAGE_NAME@ -PACKAGE_STRING = @PACKAGE_STRING@ -PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -PERL = @PERL@ -PR = @PR@ -PS2PDF = @PS2PDF@ -RANLIB = @RANLIB@ -ROFF = @ROFF@ -SENDMAIL = @SENDMAIL@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -STRIP = @STRIP@ -TEXI2DVI = @TEXI2DVI@ -VERSION = @VERSION@ -YACC = @YACC@ -YFLAGS = @YFLAGS@ -abs_builddir = @abs_builddir@ -abs_srcdir = @abs_srcdir@ -abs_top_builddir = @abs_top_builddir@ -abs_top_srcdir = @abs_top_srcdir@ -ac_ct_CC = @ac_ct_CC@ -ac_prefix_program = @ac_prefix_program@ -am__include = @am__include@ -am__leading_dot = @am__leading_dot@ -am__quote = @am__quote@ -am__tar = @am__tar@ -am__untar = @am__untar@ -bindir = @bindir@ -build_alias = @build_alias@ -builddir = @builddir@ -datadir = @datadir@ -datarootdir = @datarootdir@ -docdir = @docdir@ -dvidir = @dvidir@ -exec_prefix = @exec_prefix@ -host_alias = @host_alias@ -htmldir = @htmldir@ -includedir = @includedir@ -includeopt = @includeopt@ -infodir = @infodir@ -install_sh = @install_sh@ -libdir = @libdir@ -libexecdir = @libexecdir@ -localedir = @localedir@ -localstatedir = @localstatedir@ -mandir = @mandir@ -mkdir_p = @mkdir_p@ -oldincludedir = @oldincludedir@ -pdfdir = @pdfdir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -psdir = @psdir@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -srcdir = @srcdir@ -sysconfdir = @sysconfdir@ -target_alias = @target_alias@ -top_builddir = @top_builddir@ -top_srcdir = @top_srcdir@ -with_default_rsh = @with_default_rsh@ -with_default_ssh = @with_default_ssh@ - -# Unix source subdirs, where we'll want to run lint and etags: -# This is a legacy variable from b4 Automake -USOURCE_SUBDIRS = lib zlib diff src -# All other subdirs: -SUBDIRS = $(USOURCE_SUBDIRS) man doc contrib tools \ - windows-NT os2 emx vms - -EXTRA_DIST = \ - .cvsignore \ - BUGS \ - ChangeLog.zoo \ - DEVEL-CVS \ - FAQ \ - HACKING \ - MINOR-BUGS \ - PROJECTS \ - README.VMS \ - TESTS \ - build.com \ - cvs-format.el \ - cvsnt.dep \ - cvsnt.dsp \ - cvsnt.dsw \ - cvsnt.mak \ - cvs.spec \ - mktemp.sh - -all: config.h - $(MAKE) $(AM_MAKEFLAGS) all-recursive - -.SUFFIXES: -am--refresh: - @: -$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - echo ' cd $(srcdir) && $(AUTOMAKE) --gnu '; \ - cd $(srcdir) && $(AUTOMAKE) --gnu \ - && exit 0; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \ - cd $(top_srcdir) && \ - $(AUTOMAKE) --gnu Makefile -.PRECIOUS: Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - @case '$?' in \ - *config.status*) \ - echo ' $(SHELL) ./config.status'; \ - $(SHELL) ./config.status;; \ - *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ - esac; - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - $(SHELL) ./config.status --recheck - -$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) - cd $(srcdir) && $(AUTOCONF) -$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) - cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) - -config.h: stamp-h1 - @if test ! -f $@; then \ - rm -f stamp-h1; \ - $(MAKE) $(AM_MAKEFLAGS) stamp-h1; \ - else :; fi - -stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status - @rm -f stamp-h1 - cd $(top_builddir) && $(SHELL) ./config.status config.h -$(srcdir)/config.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) - cd $(top_srcdir) && $(AUTOHEADER) - rm -f stamp-h1 - touch $@ - -distclean-hdr: - -rm -f config.h stamp-h1 -cvs.spec: $(top_builddir)/config.status $(srcdir)/cvs.spec.in - cd $(top_builddir) && $(SHELL) ./config.status $@ -emx/Makefile: $(top_builddir)/config.status $(top_srcdir)/emx/Makefile.in - cd $(top_builddir) && $(SHELL) ./config.status $@ -os2/Makefile: $(top_builddir)/config.status $(top_srcdir)/os2/Makefile.in - cd $(top_builddir) && $(SHELL) ./config.status $@ -zlib/Makefile: $(top_builddir)/config.status $(top_srcdir)/zlib/Makefile.in - cd $(top_builddir) && $(SHELL) ./config.status $@ - -# This directory's subdirectories are mostly independent; you can cd -# into them and run `make' without going through this Makefile. -# To change the values of `make' variables: instead of editing Makefiles, -# (1) if the variable is set in `config.status', edit `config.status' -# (which will cause the Makefiles to be regenerated when you run `make'); -# (2) otherwise, pass the desired values on the `make' command line. -$(RECURSIVE_TARGETS): - @failcom='exit 1'; \ - for f in x $$MAKEFLAGS; do \ - case $$f in \ - *=* | --[!k]*);; \ - *k*) failcom='fail=yes';; \ - esac; \ - done; \ - dot_seen=no; \ - target=`echo $@ | sed s/-recursive//`; \ - list='$(SUBDIRS)'; for subdir in $$list; do \ - echo "Making $$target in $$subdir"; \ - if test "$$subdir" = "."; then \ - dot_seen=yes; \ - local_target="$$target-am"; \ - else \ - local_target="$$target"; \ - fi; \ - (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ - || eval $$failcom; \ - done; \ - if test "$$dot_seen" = "no"; then \ - $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ - fi; test -z "$$fail" - -$(RECURSIVE_CLEAN_TARGETS): - @failcom='exit 1'; \ - for f in x $$MAKEFLAGS; do \ - case $$f in \ - *=* | --[!k]*);; \ - *k*) failcom='fail=yes';; \ - esac; \ - done; \ - dot_seen=no; \ - case "$@" in \ - distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ - *) list='$(SUBDIRS)' ;; \ - esac; \ - rev=''; for subdir in $$list; do \ - if test "$$subdir" = "."; then :; else \ - rev="$$subdir $$rev"; \ - fi; \ - done; \ - rev="$$rev ."; \ - target=`echo $@ | sed s/-recursive//`; \ - for subdir in $$rev; do \ - echo "Making $$target in $$subdir"; \ - if test "$$subdir" = "."; then \ - local_target="$$target-am"; \ - else \ - local_target="$$target"; \ - fi; \ - (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ - || eval $$failcom; \ - done && test -z "$$fail" -tags-recursive: - list='$(SUBDIRS)'; for subdir in $$list; do \ - test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ - done -ctags-recursive: - list='$(SUBDIRS)'; for subdir in $$list; do \ - test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ - done - -ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ - mkid -fID $$unique -tags: TAGS - -TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - tags=; \ - here=`pwd`; \ - if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ - include_option=--etags-include; \ - empty_fix=.; \ - else \ - include_option=--include; \ - empty_fix=; \ - fi; \ - list='$(SUBDIRS)'; for subdir in $$list; do \ - if test "$$subdir" = .; then :; else \ - test ! -f $$subdir/TAGS || \ - tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \ - fi; \ - done; \ - list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ - if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ - test -n "$$unique" || unique=$$empty_fix; \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$tags $$unique; \ - fi -ctags: CTAGS -CTAGS: ctags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - tags=; \ - here=`pwd`; \ - list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ - test -z "$(CTAGS_ARGS)$$tags$$unique" \ - || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ - $$tags $$unique - -GTAGS: - here=`$(am__cd) $(top_builddir) && pwd` \ - && cd $(top_srcdir) \ - && gtags -i $(GTAGS_ARGS) $$here - -distclean-tags: - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags - -distdir: $(DISTFILES) - $(am__remove_distdir) - test -d $(distdir) || mkdir $(distdir) - @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - list='$(DISTFILES)'; \ - dist_files=`for file in $$list; do echo $$file; done | \ - sed -e "s|^$$srcdirstrip/||;t" \ - -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ - case $$dist_files in \ - */*) $(MKDIR_P) `echo "$$dist_files" | \ - sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ - sort -u` ;; \ - esac; \ - for file in $$dist_files; do \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - if test -d $$d/$$file; then \ - dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ - fi; \ - cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ - else \ - test -f $(distdir)/$$file \ - || cp -p $$d/$$file $(distdir)/$$file \ - || exit 1; \ - fi; \ - done - list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ - if test "$$subdir" = .; then :; else \ - test -d "$(distdir)/$$subdir" \ - || $(MKDIR_P) "$(distdir)/$$subdir" \ - || exit 1; \ - distdir=`$(am__cd) $(distdir) && pwd`; \ - top_distdir=`$(am__cd) $(top_distdir) && pwd`; \ - (cd $$subdir && \ - $(MAKE) $(AM_MAKEFLAGS) \ - top_distdir="$$top_distdir" \ - distdir="$$distdir/$$subdir" \ - am__remove_distdir=: \ - am__skip_length_check=: \ - distdir) \ - || exit 1; \ - fi; \ - done - -find $(distdir) -type d ! -perm -777 -exec chmod a+rwx {} \; -o \ - ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ - ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ - ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ - || chmod -R a+r $(distdir) -dist-gzip: distdir - tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz - $(am__remove_distdir) -dist-bzip2: distdir - tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2 - $(am__remove_distdir) - -dist-tarZ: distdir - tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z - $(am__remove_distdir) - -dist-shar: distdir - shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz - $(am__remove_distdir) - -dist-zip: distdir - -rm -f $(distdir).zip - zip -rq $(distdir).zip $(distdir) - $(am__remove_distdir) - -dist dist-all: distdir - tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz - tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2 - $(am__remove_distdir) - -# This target untars the dist file and tries a VPATH configuration. Then -# it guarantees that the distribution is self-contained by making another -# tarfile. -distcheck: dist - case '$(DIST_ARCHIVES)' in \ - *.tar.gz*) \ - GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(am__untar) ;;\ - *.tar.bz2*) \ - bunzip2 -c $(distdir).tar.bz2 | $(am__untar) ;;\ - *.tar.Z*) \ - uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ - *.shar.gz*) \ - GZIP=$(GZIP_ENV) gunzip -c $(distdir).shar.gz | unshar ;;\ - *.zip*) \ - unzip $(distdir).zip ;;\ - esac - chmod -R a-w $(distdir); chmod a+w $(distdir) - mkdir $(distdir)/_build - mkdir $(distdir)/_inst - chmod a-w $(distdir) - dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ - && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ - && cd $(distdir)/_build \ - && ../configure --srcdir=.. --prefix="$$dc_install_base" \ - $(DISTCHECK_CONFIGURE_FLAGS) \ - && $(MAKE) $(AM_MAKEFLAGS) \ - && $(MAKE) $(AM_MAKEFLAGS) dvi \ - && $(MAKE) $(AM_MAKEFLAGS) check \ - && $(MAKE) $(AM_MAKEFLAGS) install \ - && $(MAKE) $(AM_MAKEFLAGS) installcheck \ - && $(MAKE) $(AM_MAKEFLAGS) uninstall \ - && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ - distuninstallcheck \ - && chmod -R a-w "$$dc_install_base" \ - && ({ \ - (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ - && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ - && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ - && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ - distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ - } || { rm -rf "$$dc_destdir"; exit 1; }) \ - && rm -rf "$$dc_destdir" \ - && $(MAKE) $(AM_MAKEFLAGS) dist \ - && rm -rf $(DIST_ARCHIVES) \ - && $(MAKE) $(AM_MAKEFLAGS) distcleancheck - $(am__remove_distdir) - @(echo "$(distdir) archives ready for distribution: "; \ - list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ - sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' -distuninstallcheck: - @cd $(distuninstallcheck_dir) \ - && test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \ - || { echo "ERROR: files left after uninstall:" ; \ - if test -n "$(DESTDIR)"; then \ - echo " (check DESTDIR support)"; \ - fi ; \ - $(distuninstallcheck_listfiles) ; \ - exit 1; } >&2 -distcleancheck: distclean - @if test '$(srcdir)' = . ; then \ - echo "ERROR: distcleancheck can only run from a VPATH build" ; \ - exit 1 ; \ - fi - @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ - || { echo "ERROR: files left in build directory after distclean:" ; \ - $(distcleancheck_listfiles) ; \ - exit 1; } >&2 -check-am: all-am -check: check-recursive -all-am: Makefile config.h -installdirs: installdirs-recursive -installdirs-am: -install: install-recursive -install-exec: install-exec-recursive -install-data: install-data-recursive -uninstall: uninstall-recursive - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-recursive -install-strip: - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - `test -z '$(STRIP)' || \ - echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install -mostlyclean-generic: - -clean-generic: - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." -clean: clean-recursive - -clean-am: clean-generic mostlyclean-am - -distclean: distclean-recursive - -rm -f $(am__CONFIG_DISTCLEAN_FILES) - -rm -f Makefile -distclean-am: clean-am distclean-generic distclean-hdr distclean-tags - -dvi: dvi-recursive - -dvi-am: - -html: html-recursive - -info: info-recursive - -info-am: - -install-data-am: - -install-dvi: install-dvi-recursive - -install-exec-am: - -install-html: install-html-recursive - -install-info: install-info-recursive - -install-man: - -install-pdf: install-pdf-recursive - -install-ps: install-ps-recursive - -installcheck-am: - -maintainer-clean: maintainer-clean-recursive - -rm -f $(am__CONFIG_DISTCLEAN_FILES) - -rm -rf $(top_srcdir)/autom4te.cache - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-recursive - -mostlyclean-am: mostlyclean-generic - -pdf: pdf-recursive - -pdf-am: - -ps: ps-recursive - -ps-am: - -uninstall-am: - -.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) install-am \ - install-strip - -.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ - all all-am am--refresh check check-am clean clean-generic \ - ctags ctags-recursive dist dist-all dist-bzip2 dist-gzip \ - dist-shar dist-tarZ dist-zip distcheck distclean \ - distclean-generic distclean-hdr distclean-tags distcleancheck \ - distdir distuninstallcheck dvi dvi-am html html-am info \ - info-am install install-am install-data install-data-am \ - install-dvi install-dvi-am install-exec install-exec-am \ - install-html install-html-am install-info install-info-am \ - install-man install-pdf install-pdf-am install-ps \ - install-ps-am install-strip installcheck installcheck-am \ - installdirs installdirs-am maintainer-clean \ - maintainer-clean-generic mostlyclean mostlyclean-generic pdf \ - pdf-am ps ps-am tags tags-recursive uninstall uninstall-am - - -.PHONY: localcheck remotecheck -localcheck remotecheck: all - cd src && $(MAKE) $(AM_MAKEFLAGS) "$@" - -.PHONY: doc -doc: - cd doc && $(MAKE) $(AM_MAKEFLAGS) "$@" - -# for backwards compatibility with the old makefiles -.PHONY: realclean -realclean: maintainer-clean -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/contrib/cvs/NEWS b/contrib/cvs/NEWS deleted file mode 100644 index 81548ce..0000000 --- a/contrib/cvs/NEWS +++ /dev/null @@ -1,1905 +0,0 @@ -Changes since 1.11.22: -********************** - -NEW FEATURES - -* A new log option -n reverts the -N option which may be in a .cvsrc - file. - -* The `cvs blame' command is now a synonym for the `cvs annotate' command. - -* The :extssh: method will use $CVS_SSH if set, or fall back on "ssh" - by default (but may be explicitly set using the --with-ssh flag to - configure). - -* There is a new IgnoreUnknownConfigKeys option available for - CVSROOT/config to aid in the transition to newer versions of CVS. - -BUG FIXES - -* Merges of file removals using -j options are a little smarter. - -* `cvs add' checks more thoroughly for `CVS' directories in the argument list. - -* `cvs server' now accepts `--allow-root=PATH' options. - -* `cvs import' no longer attempts to send CVS metadata to the server. - -* `cvs import' makes more of an effort not to import paths containing files - and directories named `CVS'. - -* The CVS server will no longer allow clients to run `cvs init'. - -* Applying diffs when checking out very old revisions has been reduced from an - O(n^2) operation to an O(n) thanks to a patch from Michael J. Smith - and additional touch-up work from the CVS team. - -* Thanks to report from Paul Eggert , an assertion failure - that could occur when "." was in the path (e.g. `cvs co /cvsroot/./module') - has been removed. - -* Thanks to a report from Peter Toft , CVS server now sends - correct patch files more often when the RCS `Name' keyword is present in - a working file (bug #17302). - -* Thanks to a report from Dan Peterson , clients now send the - right set of commands to the server when asked to update directories with - trailing slashes on their name. - -* Thanks to a report and patch from , potential stack - corruption during pserver login is avoided (bug #16961). - -* The :extssh: method is now properly recognized as an alias for :ext:. - -DEVELOPER ISSUES - -* We've standardized on Autoconf version 2.61 to get a bug fix that notes - that the AIX C compiler's default mode isn't quite C89 and sets the - correct mode instead. - -* We've standardized on Autoconf version 1.10 because it lets us simplify our - sources. - -Changes from 1.11.21 to 1.11.22: -******************************** - -BUG FIXES - -* The CVS client again correctly reports files with conflicts when using - servers running CVS 1.11.20/1.12.12, or earlier (and maybe 3rd party - servers). - -* The GSSAPI server should now build under HP-UX. - -* `cvs rtag' now correctly tags files that have been removed from the trunk. - -* Code efficiency has been improved slightly. - -* A rare race condition that could leave a lock on the val-tags file has been - avoided. - -* A potential buffer overflow in the history command has been fixed. - -* Thanks to a report and patch from Garrett Rooney , paused - trigger processes no longer cause the CVS server to consume 100% CPU. - -* Thanks to a suggestion from Joseph P. Skudlarek , an - :extssh: has been added as a synonym of the :ext: access method, as a - kindness to users of old version of Eclipse. - -* Misc documentation updates and minor bug fixes. - -Changes from 1.11.20 to 1.11.21: -******************************** - -BUG FIXES - -* Thanks to Serguei E. Leontiev , CVS with Kerberos 5 GSSAPI - should automatically link on FreeBSD 5.x. (bug #14639). - -* Thanks to Rahul Bhargava , heavily loaded systems - suffering from a disk crash or power failure will not lose data they claimed - to have committed. - -* CVS server now handles conflict markers in Entry requests as documented. - -* CVS now remembers that binary file merge conflicts occurred until the - timestamp of the updated binary file changes. - -* CVS client now saves some bandwidth by not sending the contents of files - with conflicts to the server when it isn't needed. - -* CVS now does correct locking during import. - -* A problem where the server could block indefinitely waiting for an EOF from - the client when compression was enabled has been fixed. - -* `cvs diff' no longer splits its arguments on spaces. - -* Thanks to an old report and patch from Stewart Brodie , a - potential crash in response to a corrupt RCS file has been fixed. - -* CVS now locks the history and val-tags files before writing to them. - Especially with large repositories, users should no longer see new warnings - about corrupt history records when using the `cvs history' command. Existing - corrupt history records will still need to be removed manually. val-tags - corruption should have had less obvious effects, but removing the - CVSROOT/val-tags file and allowing a 1.11.21 or later version of CVS to - regenerate it may eliminate a few odd behaviors and possibly cause a slight - speed up of read transactions in large repositories over time. - -BUILD ISSUES - -* The RPM spec file works again with the most modern versions of `rpm'. - -DEVELOPER ISSUES - -* We've standardized on Automake 1.9.6 to get some at new features that make - our jobs easier. See the HACKING file for more on using the autotools with - CVS. - -Changes from 1.11.19 to 1.11.20: -******************************** - -SERVER SECURITY FIXES - -* Thanks to a report from Alen Zukich , several minor - security issues have been addressed. One was a buffer overflow that is - potentially serious but which may not be exploitable, assigned CAN-2005-0753 - by the Common Vulnerabilities and Exposures Project - . Other fixes resulting from Alen's report include - repair of an arbitrary free with no known exploit and several plugged memory - leaks and potentially freed NULL pointers which may have been exploitable for - a denial of service attack. - -* Thanks to a report from Craig Monson , minor - potential vulnerabilities in the contributed Perl scripts have been fixed. - The confirmed vulnerability could allow the execution of arbitrary code on - the CVS server, but only if a user already had commit access and if one of - the contrib scripts was installed improperly, a condition which should have - been quickly visible to any administrator. The complete description of the - problem is here: . If - you were making use of any of the contributed trigger scripts on a CVS - server, you should probably still replace them with the new versions, to be - on the safe side. - - Unfortunately, our fix is incomplete. Taint-checking has been enabled in all - the contributed Perl scripts intended to be run as trigger scripts, but no - attempt has been made to ensure that they still run in taint mode. You will - most likely have to tweak the scripts in some way to make them run. Please - send any patches you find necessary back to so that we - may again ship fully enabled scripts in the future. - - You should also make sure that any home-grown Perl scripts that you might - have installed as CVS triggers also have taint-checking enabled. This can be - done by adding `-T' on the scripts' #! lines. Please try running - `perldoc perlsec' if you would like more information on general Perl security - and taint-checking. - -BUG FIXES - -* Thanks to a report and a patch from Georg Scwharz - CVS now builds without error on IRIX 5.3 - -DEVELOPER ISSUES - -* We've standardized on Automake 1.9.5 to get some at new features that make - our jobs easier. See the HACKING file for more on using the autotools with - CVS. - -Changes from 1.11.18 to 1.11.19: -******************************** - -BUG FIXES - -* Thanks to a patch from Jim Hyslop , issuing - 'cvs watch on' or 'cvs watch off' in an empty directory no longer - clears any watchers in that directory. - -* An intermittant assertion failure in checkout has been fixed. - -* Thanks to a report from Chris Bohn , all the source files - needed for the Windows "red file" fix are actually included in the - distribution. - -* Misc bug and documentation fixes. - -Changes from 1.11.17 to 1.11.18: -******************************** - -BUG FIXES - -* Thanks to a report from Gottfried Ganssauge , CVS no - longer exits when it encounters links pointing to paths containing more - than 128 characters. - -* Thanks to a report from Dan Peterson , error messages from - GSSAPI servers are no longer truncated. - -* Thanks to a report from Dan Peterson , attempts to resurrect - a file on the trunk that was added on a branch no longer causes an assertion - failure. - -* Thanks to a report from Dan Peterson , imports to branches - like "1.1." no longer create corrupt RCS archives. - -* Thanks to a report from Chris Bohn , links from J.C. Hamlin - , and code posted by Jonathan Gilligan, we think we have - finally corrected the Windows "red-file" (daylight savings time) bug once and - for all. - -* Thanks to a patch from Jeroen Ruigrok/asmodai , the - log_accum.pl script should no longer elicit warnings from Perl 5.8.5. - -* The r* commands (rlog, rls, etc.) can once again handle requests to run - against the entire repository (e.g. `cvs rlog .'). Thanks go to Dan Peterson - for the report. - -* A problem where the attempted access of files via tags beginning with spaces - could cause the CVS server to hang has been fixed. This was a particular - problem with WinCVS clients because users would sometimes accidentally - include spaces in tags pasted into a dialog box. This fix also altered some - of the error messages generated by the use of invalid tags. Thanks go to Dan - Peterson for the report. - -* Thanks to James E Wilson for a bug fix to - modules processing "gcc-core -a !gcc/f gcc" will no longer exclude - gcc/fortran by mistake. - -* Thanks to Conrad Pino , the Windows build works once again. - -* Misc updates to the manual. - -DEVELOPER ISSUES - -* We've standardized on Automake 1.9.3 to get some at new features that make - our jobs easier. See the note below on the Autoconf upgrade for more - details. - -* We've standardized on Autoconf version 2.59 to get presumed bug fixes and - features, but nothing specific. Mostly, once we decide to upgrade one of the - autotools we just figure it'll save time later to grab the most current - versions of the others too. See the HACKING file for more on using the - autotools with CVS. - -Changes from 1.11.16 to 1.11.17: -******************************** - -SERVER SECURITY FIXES - -* Thanks to Stefan Esser & Sebastian Krahmer, several potential security - problems have been fixed. The ones which were considered dangerous enough - to catalogue were assigned issue numbers CAN-2004-0416, CAN-2004-0417, & - CAN-2004-0418 by the Common Vulnerabilities and Exposures Project. Please - see for more information. - -* A potential buffer overflow vulnerability in the server has been fixed. - This addresses the Common Vulnerabilities and Exposures Project's issue - #CAN-2004-0414. Please see for more information. - -Changes from 1.11.15 to 1.11.16: -******************************** - -SERVER SECURITY FIXES - -* A potential buffer overflow vulnerability in the server has been fixed. - Prior to this patch, a malicious client could potentially use carefully - crafted server requests to run arbitrary programs on the CVS server machine. - This addresses the Common Vulnerabilities and Exposures Project's issue - #CAN-2004-0396. Please see for more information. - -BUG FIXES - -* The Microsoft Visual C++ workspace and project files have been repaired and - regenerated with MSVC++ 6.0. - -* The cvs.1 man page is now generated automatically from a section of the CVS - Manual. - -* Thanks to a report from Mark Andrews at the Internet Systems Consortium, the - :ext: connection method no longer relies on a transparent transport that uses - an argument processor that can handle arbitrary ordering of options and other - arguments when using a username other than the caller's. - -* Thanks to Ken Raeburn at MIT, directory deletion, whether via `cvs release' - or empty directory pruning, now works on network shares under Windows XP. - -Changes from 1.11.14 to 1.11.15: -******************************** - -SERVER SECURITY ISSUES - -* Piped checkouts of paths above $CVSROOT no longer work. Previously, clients - could have requested the contents of RCS archive files anywhere on a CVS - server. This addresses CVE issue CAN-2004-0405. Please see - for more information. - -CLIENT SECURITY ISSUES - -* Clients now check paths from the server to verify that they are within one of - the sandboxes the user requested be updated. Previously, a trojan server - could have written or overwritten files anywhere the user had access, - presenting a serious security risk. This addresses CVE issue CAN-2004-1080. - Please see for more information. - -GENERAL USER ISSUES - -* Method options (used by WinCVS & CVS 1.12.7+) in CVSROOTs are ignored. - -* Configure no longer checks the $TMPDIR, $TMP, & $TEMP variables to set the - default temporary directory. - -* CVS on Cygwin correctly handles X:\ style paths. - -* Import now uses backslash rather than slash on Windows when checking for - "CVS" directories to ignore in import commands. - -* Relative paths containing up-references (`..') should now work in - client/server mode (client fix). - -* A race condition between the ordering of messages from CVS and messages from - called scripts in client/server mode has been removed (server fix). - -* Resurrected files now get their modes and timestamps set correctly and a - longstanding bug involving resurrection of an uncommitted removal has been - fixed (server fix). - -* Some resurrection (cvs add) status messages have changed slightly. - -* `cvs release' now works with Kerberos or GSSAPI encryption enabled (server - fix). - -* File resurrection from a previously existing revision no longer just reports - that it works (server fix). - -* Misc error & status message corrections. - -* Diffing of locally added files against arbitrary revisions in an RCS archive - is now allowed when a file of the same name exists or used to exist on some - branch (server fix). - -* Misc documentation fixes. - -Changes from 1.11.13 to 1.11.14: -******************************** - -GENERAL USER ISSUES - -* Imports will now always ignore directories and files named `CVS' to avoid - violating assumptions made by other parts of CVS. - -* A problem with `cvs release' of subdirs that could corrupt CVS/Entries files - has been fixed (client/server). - -* The CVS server's protocol check for unused data from the client is no longer - called automatically at program exit in order to avoid potential recursive - calls to error when the first close is due to memory allocation or similar - problems that cause calls to error() to fail. The check is still made when - the server program exits normally. - -* The spec file has been updated to work with more recent versions of RPM. - -* Several memory leaks have been plugged (client/server). - -DEVELOPER ISSUES - -* Misc cosmetic, readability, and commenting fixes. - -Changes from 1.11.12 to 1.11.13: -******************************** - -GENERAL USER ISSUES - -* Several memory leaks have been plugged. - -* Thanks to Ville Skyttä the man page has a few less spelling errors and is - slightly more accurate. - -* An unlikely potential segfault when using the :fork: connection method has - been fixed. - -* The CVS server has had the protocol check for unused data from the client - partially restored. - -* A fix has been included that should avoid a very rare race condition that - could cause a CVS server to exit with a "broken pipe" message. - -* A minor problem with the nmake build file that was preventing the source from - compiling under Windows has been fixed. - -* Tests have been added to the test suite. - -DEVELOPER ISSUES - -* Misc cosmetic, readability, and commenting fixes. - -Changes from 1.11.11 to 1.11.12: -******************************** - -GENERAL USER ISSUES - -* Infinite alias loops in the modules file are now checked for and avoided. - -* Clients on case insensitive systems now preserve the case of directories in - CVS/Entries, in addition to files, for use in communications with the CVS - server. - -* Some previously untested behavior is now being tested. - -* Server support for case insensitive clients has been removed in favor of the - server relying on the client to preserve the case of checked out files, as - per the CVS client/server protocol spec. This is not as drastic as it may - sound, as all of the current tests still pass without modification when run - from a case insensitive client to a case sensitive server. This change - disables little previous functionality, enables access to more of the - possible namespace to users on systems with case insensitive file systems, - fixes a few bugs, and in the end this should provide a major stability - improvement. - -* Thanks to Ville Skyttä the man page is a bit more accurate. - -* Thanks to Ville Skyttä some unused variables were removed from the log_accum - Perl script in contrib. - -* Thanks to Alexey Mahotkin, a bug that prevented CVS from being compiled with - Kerberos 4 authentication enabled has been fixed. - -* A minor bug that caused CVS to fail to report an inifinte alias loop in the - modules file when portions of the alias definition contained trailing slashes - has been fixed. - -* A bug in the gzip code that could cause heap corruption and segfaults in CVS - servers talking to clients less than 1.8 and some modern third-party CVS - clients has been fixed. - -* mktemp.sh is now included with the source distribution so that the rcs2log - and cvsbug executables may be run on systems which do not contain an - implementation of mktemp. - -* Misc documentation fixes. - -Changes from 1.11.10 to 1.11.11: -******************************** - -SERVER SECURITY ISSUES - -* pserver can no longer be configured to run as root via the - $CVSROOT/CVSROOT/passwd file, so if your passwd file is compromised, it no - longer leads directly to a root hack. Attempts to root will also be logged - via the syslog. - -Changes from 1.11.9 to 1.11.10: -******************************* - -SERVER SECURITY ISSUES - -* Malformed module requests could cause the CVS server to attempt to create - directories and possibly files at the root of the filesystem holding the CVS - repository. Filesystem permissions usually prevent the creation of these - misplaced directories, but nevertheless, the CVS server now rejects the - malformed requests. - -GENERAL USER ISSUES - -* Case insensitive clients using a case sensitive server can now use a - `cvs rm -f file; cvs add FILE' command sequence to add a file with the same - name in a new case. - -* CVSROOTs which contain a symlink to a real repository should work. - -* The configure script now tests whether it is building CVS on a case - insensitive file system. If it is, CVS assumes that all file systems on this - platform will be case insensitive. This is useful for getting the case - insensitivity flag set correctly when compiling on Mac OS X and under Cygwin - on Windows. Autodetection can be overridden using the - --disable-case-sensitivity and --enable-case-sensitivity arguments to - configure. - -* A behavior change in `cvs up -jrev1 -jrev2' for modified files with a base - revision of rev2 (ie, checked-out version matches rev2 and file has been - modified). The operation is no longer ignored and instead is passed to - diff3. This will potentially re-apply the diffs between the two revisions to - a modified local file. Status messages like from a standard merge have also - been added when the file would not or does not change due to this merge - request ("[file] already contains the changes between [revisions]..."). - -* A bug which could stop `cvs admin -mTAG:message' from recursing has been - fixed. - -* Misc documentation cleanup and fixes. - -* Some of the contrib scripts, some of the documentation, and sanity.sh were - modified to use and recommend more portable commands rather than using and - recommending commands which were not compatible with the POSIX 1003.1-2001 - specification. - -DEVELOPER ISSUES - -* A new set of tests to test issues specific to case insensitive clients and - servers has also been added. - -* Support has been added to the test suite to support testing over a :ext: link - to another machine, subject to some stringent requirements. This support can - be used, for instance, to test the operation of a case insensitive client - against a case sensitive server. Please see the comments in TEST and the - src/sanity.sh test script itself for more. - -* We've standardized on Automake 1.7.9 to get a bug fix. See the note below - on the Autoconf upgrade for more details. - -* We've standardized on Autoconf version 2.58 to avoid a bug and get at a few - new macros. Again, this should only really affect developers, though it is - possible that CVS will now compile on a few new platforms. Please see the - section of the INSTALL file about using the autotools if you are compiling - CVS yourself. - -Changes from 1.11.8 to 1.11.9: - -* CVS now knows how to report, as well as record, `P' record types. - -* When running the `cvs history' command, clients will now send the - long-accepted `-e' option, for all records, rather than explicitly requesting - `P' record types, a request which servers prior to 1.11.7 will reject with a - fatal error message. - -* A problem with locating files requested by case insensitive clients which was - accidentally introduced in 1.11.6 as part of a fix for a data loss problem - involving `cvs add's from case insensitive clients has been fixed. The - relevant error message was `cvs [ aborted]: filE,v is ambiguous; - could mean FILE,v or file,v'. - -* Attempts to use the global `-l' option, removed from both client and server - as of version 1.11.6, will now elicit a warning rather than a fatal error - from the server. - -Changes from 1.11.7 to 1.11.8: - -* A problem in the CVS getpass library that could cause passwords to echo on - some systems has been fixed. - -Changes from 1.11.6 to 1.11.7: - -* A segfault that could occur in very rare cases where the stat of a file - failed during a diff has been fixed. - -* Any user with write privleges to the CVSROOT/checkoutlist file could pass -arbitrary format strings directly through to a printf function. This was -probably bad and has been fixed. White space at the beginning of error strings -in checkoutlist is now ignored properly. - -* In client/server mode, most messages from CVS now contain the actual -command name rather than the generic "server". - -* A long-standing bug that prevented most client/server updates from being -logged in the history file has been fixed. - -* Updates done via a patch ("P" status) are now logged in the history file -by default and the corresponding "P" history record type is now documented. -If you're setting the LogHistory option in your CVSROOT/config file, you may -want to add "P" to the list of record types. - -* CVS now will always compile and its own getpass() function (originally from -GNULIB) in favor of any system one that may exist. This avoids some problems -with long passwords on some systems and updates us to POSIX.2 compliance, since -getpass() was removed from the POSIX.2 specification. - -* A bug that allowed a write lock to be created in a directory despite -there being existing read locks when using LockDir in CVSROOT/config has -been fixed. - -* A bug with short patches (`rdiff -s') which caused rdiff to sometimes report -differences that did not exist has been fixed. - -* Some minor corrections were made to the diff code to keep diff & rdiff from -printing diff headers with empty change texts when two files have different -revision numbers but the same content. - -* The global '-l' option, which suppressed history logging, has been removed -from both client and server. - -Changes from 1.11.5 to 1.11.6: - -* A warning message is now issued if an administrative file contains -more than one DEFAULT entry. - -* An error running a verifymsg script (such as referencing an unset user -variable or the script not existing) now causes the verification to -fail. - -* Errors in administrative files commands (like unset user variables) -are no longer reported unless the command is actually executed. - -* When a file is initially checked out, its last access time is now set -to the current time rather than being set to the time the file was last -checked in like the modification time is. - -* The Checkin.prog and Update.prog functionality has been removed. This -fuctionality previously allowed executables to be specified in the modules file -to be run at update and checkin time, but users could edit these files on a per -workspace basis, creating a security hole. - -* contrib/rcs2log and src/cvsbug now use the BSD mktemp program to create -their temp files and directories on systems which provide it. - -* Corrected the path in a failed write error message. - -* Autoconf and Automake are no longer run automatically unless you run -configure with --enable-maintainer-mode. Accordingly, noautomake.sh is -no longer needed and has been removed. - -* We've standardized on Automake version 1.7.5 and Autoconf version 2.57 to get -at a few new macros. Again, this should only really affect developers. See -the section of the INSTALL file about using the autotools if you are compiling -CVS yourself. - -Changes from 1.11.4 to 1.11.5: - -* Fixed a security hole in the CVS server by which users with read only access -could gain write access. This issue does not affect client builds. The -Common Vulnerabilities and Exposures project (cve.mitre.org) has assigned the -name CAN-2003-0015 to this issue. See - for more -information. - -* Fixed some bugs where revision numbers starting with 0 (like 0.3) -weren't correctly handled. (CVS doesn't normally use such revision -numbers, but users may be able to force it to do so and old RCS files -might.) - -Changes from 1.11.3 to 1.11.4: - -* Some minor changes to allow the code to compile on Windows platforms. - -Changes from 1.11.2 to 1.11.3: - -* The tag/rtag code has been fixed to once again lock just a single -directory at a time. - -* There was a bug where certain error conditions could cause the server -to go into an infinite loop. There was also a bug that caused a -compressed connection from an older client to hang on shutdown. These -bugs have been fixed. - -* Fixed a bug that caused the server to reject most watch commands. - -* When waiting for another user's lock, the message timestamps are now -in UTC rather than the server's local time. - -* The options.h file is no longer used. This fixes a bug that occurred when -1.11.2 was compiled on Windows platforms. - -* We've standardized on Automake version 1.6.3 and Autoconf version 2.53. -They are cleaner, less bug prone, and will hopfully allow me to start updating -sanity.sh to use Autotest and Autoshell. Again, this should only really affect -developers. See the section of the INSTALL file about using the autotools if -you are compiling CVS yourself. - -* Fixed a bug in the log/rlog code when a revision range crosses a -branch point. - -* Fixed a bug where filenames starting with - would be misinterpreted as -options when using client/server mode. - -Changes from 1.11.1p1 to 1.11.2: - -* There is a new feature, enabled by RereadLogAfterVerify in CVSROOT/config, -which tells CVS to reread the log message after running the verifymsg -script. This allows the verifymsg script to reformat or otherwise -modify the log message. - -* The interpretation of revision ranges using :: in "log" and "rlog" -has changed: a::b now excludes the log message from revision a but -includes the log message from revision b. Also, revision ranges that -cross branch points should now work. - -* zlib has been updated to version 1.4. There is a security advisory -out in regards to 1.3. This should fix that problem. - -* The "log" and "rlog" commands now have a -S option to suppress the -header information when no revisions are selected. - -* A serious error that allowed read-only users to tag files has been -corrected. - -* The "annotate" command will no longer annotate binary files unless -you specify the new -F option. - -* The "tag" and "rtag" commands will no longer move or delete branch -tags unless you use the new -B option. (This prevents accidental -changes to branch tags that are hard to undo.) - -* We've standardized on the 1.5 Automake release for the moment. Again, this -should only really affect developers. See the section of the INSTALL file -about using the autotools if you are compiling CVS yourself. - -Changes from 1.11.1 to 1.11.1p1: - -* Read only access was broken - now fixed. - -Changes from 1.11 to 1.11.1: - -* There was a locking bug in the tag/rtag code that could lose changes -made to a file while the tag operation was in progress. This has been -fixed, but all of the directories being tagged are now locked for the -entire duration of the tag operation rather than only one directory at a -time. - -* The "cvs diff" command now accepts the -y/--side=by-side and -T/ ---initial-tab options. (To use these options with a remote repository, -both the client and the server must support them.) - -* The expansion of the loginfo format string has changed slightly. -Previously, the expansion was surrounded by single quotes ('); if a file -name contained a single quote character, the string would not be parsed -as a single entity by the Unix shell (and it would not be possible to -parse it unambiguously). Now the expansion is surrounded by double -quotes (") and any embedded dollar signs ($), backticks (`), backslashes -(\), and double quotes are preceded by a backslash. This is parsed as a -single entity by the shell reguardless of content. This change should -not be noticable unless you're not using a Unix shell or you have -embedded the format string inside a double quoted string. - -* There was a bug in the diff code which sometimes caused conflicts to -be flagged which shouldn't have been. This has been fixed. - -* New "cvs rlog" and "cvs rannotate" commands have been added to get log -messages and annotations without having to have a checked-out copy. - -* Exclusive revision ranges have been added to "cvs log" using :: -(similar to "cvs admin -o"). - -* The VMS client now accepts wildcards if you're running VMS 7.x. - -* ZLIB has been updated to version 1.1.3, the most current version. This -includes mostly some optimizations and minor bug fixes. - -* The ~/.cvspass file has a slightly modified format. CVSROOTs are now -stored in a new canonical form - hostnames are now case insensitive and -port numbers are always stored in the new format. Until a new login for -a particular CVSROOT is performed with the new version of CVS, new and -old versions of CVS should interoperate invisibly. After that point, an -extra login using the old version of CVS may be necessary to continue to -allow the new and old versions of CVS to interoperate using the same -~/.cvspass file and CVSROOT. The exception to this rule occurs when the -CVSROOTs used with the different versions use case insensitively -different hostnames, for example, "empress", and "empress.2-wit.com". - -* A password and a port number may now be specified in CVSROOT for -pserver connections. The new format is: - - :pserver:[[user][:password]@]host[:[port]]/path - -Note that passwords specified in a checkout command will be saved in the -clear in the CVS/Root file in each created directory, so this is not -recommended, except perhaps when accessing anonymous repositories or the -like. - -* The distribution has been converted to use Automake. This shouldn't -affect most users except to ease some portability concerns, but if you -are building from the repository and encounter problems with the -makefiles, you might try running ./noautomake.sh after a fresh update --AC. - -Changes from 1.10 to 1.11: - -* The "cvs update" command has a new -C option to get clean copies from -the repository, abandoning any local changes. - -* 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. - -* The -d command line option no longer updates the CVS/Root file. For -one thing, the CVS 1.9/1.10 behavior never had updated CVS/Root in -subdirectories, and for another, it didn't seem that popular in -general. So this change restores the CVS 1.8 behavior (which is also -the CVS 1.9/1.10 behavior if the environment variable -CVS_IGNORE_REMOTE_ROOT is set; with this change, -CVS_IGNORE_REMOTE_ROOT no longer has any effect). - -* It is now possible for a single CVS command to recurse into several -CVS roots. This includes roots which are located on several servers, -or which are both remote and local. CVS will make connections to as -many servers as necessary. - -* It is now possible to put the CVS lock files in a directory -set by the new LockDir option in CVSROOT/config. The default -continues to be to put the lock files in the repository itself. - -Changes from 1.9 to 1.10: - -* A bug was discovered in the -t/-f wrapper support that can cause -serious data loss. Because of this (and also the fact that it doesn't -work at all in client/server mode), the -t/-f wrapper code has been -disabled until it can be fixed. - -* There is a new feature, enabled by TopLevelAdmin in CVSROOT/config, -which tells CVS to modify the behavior of the "checkout" command. The -command now creates a CVS directory at the top level of the new -working directory, in addition to CVS directories created within -checked-out directories. See the Cederqvist for details. - -* There is an optional set of features, enabled by PreservePermissions -in CVSROOT/config, which allow CVS to store unix-specific file -information such as permissions, file ownership, and links. See the -Cederqvist for details. - -* One can now authenticate and encrypt using the GSSAPI network -security interface. For details see the Cederqvist's description of -specifying :gserver: in CVSROOT, and the -a global option. - -* All access to RCS files is now implemented internally rather than by -calling RCS programs. The main user-visible consequence of this is -that there is no need to worry about making sure that CVS finds the -correct version of RCS. The -b global option and the RCSBIN setting -in CVSROOT/config are still accepted but don't do anything. The -$RCSBIN internal variable in administrative files is no longer -accepted. - -* There is a new syntax, "cvs admin -orev1::rev2", which collapses the -revisions between rev1 and rev2 without deleting rev1 or rev2 -themselves. - -* There is a new administrative file CVSROOT/config which allows one -to specify miscellaneous aspects of CVS configuration. Currently -supported here: - - - SystemAuth, allows you to prevent pserver from checking for system - usernames/passwords. - -For more information see the "config" section of cvs.texinfo. - -* When setting up the pserver server, one now must specify the -allowable CVSROOT directories in inetd.conf. See the Password -authentication server section of cvs.texinfo for details. Note that -this implies that everyone who is running a pserver server must edit -inetd.conf when upgrading their CVS. - -* The client no longer needs an external patch program (assuming both -the client and the server have been updated to the new version). - -* "cvs admin [options]" will now recurse. In previous versions of -CVS, it was an error and one needed to specify "cvs admin [options] ." -to recurse. This change brings admin in line with the other CVS -commands. - -* New "logout" command to remove the password for a remote cvs -repository from the cvspass file. - -* Read-only repository access is implemented for the -password-authenticated server (other access methods are just governed -by Unix file permissions, since they require login access to the -repository machine anyway). See the "Repository" section of -cvs.texinfo for details, including a discussion of security issues. -Note that the requirement that read-only users be able to create locks -and write the history file still applies. - -* There is a new administrative file verifymsg which is like editinfo -but merely validates the message, rather than also getting it from the -user. It therefore works with client/server CVS or if one uses the -m -or -F options to commit. See the verifymsg section of cvs.texinfo for -details. - -* The %s format formerly accepted in loginfo has been extended to -formats such as %{sVv}, so that loginfo scripts have access to the -version numbers being changed. See the Loginfo section of cvs.texinfo -for details. - -* The postscript documentation (doc/cvs.ps) shipped with CVS is now -formatted for US letter size instead of A4. This is not because we -consider this size "better" than A4, but because we believe that the -US letter version will print better on A4 paper than the other way -around. - -* The "cvs export" command is now logged in the history file and there -is a "cvs history -x E" command to select history file entries -produced by export. - -* CVS no longer uses the CVS_PASSWORD environment variable. Storing -passwords in cleartext in an environment variable is a security risk, -especially since (on BSD variants) any user on the system can display -any process's environment using 'ps'. Users should use the 'cvs -login' command instead. - - -Changes from 1.8 to 1.9: - -* Windows NT client should now work on Windows 95 as well. - -* New option "--help-synonyms" prints a list of all recognized command -synonyms. - -* The "log" command is now implemented internally rather than via the -RCS "rlog" program. The main user-visible consequence is that -symbolic branch names now work (for example "cvs log -rbranch1"). -Also, the date formats accepted by -d have changed. They previously -had been a bewildering variety of poorly-documented date formats. Now -they are the same as the date formats accepted by the -D options to -the other CVS commands, which is also a (different) bewildering -variety of poorly-documented date formats, but at least we are -consistently bewildering :-). - -* Encryption is now supported over a Kerberos client/server -connection. The new "-x" global option requests it. You must -configure with the --enable-encryption option in order to enable -encryption. - -* The format of the CVS commit message has changed slightly when -committing changes on a branch. The tag on which the commit is -ocurring is now reported correctly in all cases. - -* New flag -k in wrappers allows you to specify the keyword expansion -mode for added files based on their name. For example, you can -specify that files whose name matches *.exe are binary by default. -See the Wrappers section of cvs.texinfo for more details. - -* Remote CVS with the "-z" option now uses the zlib library (included -with CVS) to compress all communication between the client and the -server, rather than invoking gzip on each file separately. This means -that compression is better and there is no need for an external gzip -program (except to interoperate with older version of CVS). - -* The "cvs rlog" command is deprecated and running it will print a -warning; use the synonymous "cvs log" command instead. It is -confusing for rlog to mean the same as log because some other CVS -commands are in pairs consisting of a plain command which operates on -a working directory and an "r" command which does not (diff/rdiff; -tag/rtag). - -* "cvs diff" has a bunch of new options, mostly long options. Most of -these work only if rcsdiff and diff support them, and are named the -same as the corresponding options to diff. - -* The -q and -Q command options to "cvs diff" were removed (use the -global options instead). This brings "cvs diff" into line with the -rest of the CVS commands. - -* The "annotate" command can now be used to annotate a revision other -than the head revision on the trunk (see the -r, -D, and -f options in -the annotate node of cvs.texinfo for details). - -* The "tag" command has a new option "-c" which checks that all files - are not locally modified before tagging. - -* The -d command line option now overrides the cvsroot setting stored -in the CVS/Root file in each working directory, and specifying -d will -cause CVS/Root to be updated. - -* Local (non-client/server) CVS now runs on Windows NT. See -windows-NT/README for details. - -* The CVSROOT variable specification has changed to support more -access methods. In addition to "pserver," "server" (internal rsh -client), "ext" (external rsh client), "kserver" (kerberos), and -"local" (local filesystem access) can now be specified. For more -details on each method, see cvs.texinfo (there is an index entry for -:local: and each of the other access methods). - -* The "login" command no longer prompts the user for username and -hostname, since one will have to provide that information via the `-d' -flag or by setting CVSROOT. - -Changes from 1.7 to 1.8: - -* New "cvs annotate" command to display the last modification for each -line of a file, with the revision number, user checking in the -modification, and date of the modification. For more information see -the `annotate' node in cvs.texinfo. - -* The cvsinit shell script has been replaced by a cvs init command. -The cvs init command creates some example administrative files which -are similar to the files found in the examples directory (and copied -by cvsinit) in previous releases. - -* Added the patterns *.olb *.exe _$* *$ to default ignore list. - -* There is now a $USER internal variable for *info files. - -* There is no longer a separate `mkmodules' program; the functionality -is now built into `cvs'. If upgrading an old repository, it is OK to -leave in the lines in the modules file which run mkmodules (the -mkmodules actions will get done twice, but that is harmless); you will -probably want to remove them once you are no longer using the old CVS. - -* One can now specify user variables in *info files via the -${=varname} syntax; there is a -s global option to set them. See the -Variables node in cvs.texinfo for details. - -Changes from 1.6 to 1.7: - -* The default ignore list has changed slightly: *.obj has been added -and CVS* has been changed to CVS CVS.adm. - -* CVS now supports password authentication when accessing remote -repositories; this is useful for sites that can't use rsh (because of -a firewall, for example), and also don't have kerberos. See node -"Password authenticated" (in "Remote repositories", in -doc/cvs.texinfo) for more details. Note: This feature requires both -the client and server to be upgraded. - -* Using the -kb option to specify binary files now works--most cases -did not work before. See the "Binary files" section of -doc/cvs.texinfo for details. - -* New developer communication features. See the "Watches" section of -doc/cvs.texinfo for details. - -* RCS keyword "Name" supported for "cvs update -r " and "cvs -checkout -r ". - -* If there is a group whose name matches a compiled in value which -defaults to "cvsadmin", only members of that group can use "cvs -admin". This replaces the CVS_NOADMIN option. - -* CVS now sets the modes of files in the repository based on the -CVSUMASK environment variable or a compiled in value defaulting to -002. This way other developers will be able to access the files in -the repository regardless of the umask of the developer creating them. - -* The command names in .cvsrc now match the official name of the -command, not the one (possibly an alias) by which it was invoked. If -you had previously relied on "cvs di" and "cvs diff" using different -options, instead use a shell function or alias (for example "alias -cvsdi='cvs diff -u'"). You also can specify global CVS options (like -"-z") using the command name "cvs". - -Changes from 1.5 to 1.6: - -* Del updated the man page to include all of the new features -of CVS 1.6. - -* "cvs tag" now supports a "-r | -D" option for tagging an already -tagged revision / specific revision of a file. - -* There is a "taginfo" file in CVSROOT that supports filtering and -recording of tag operations. - -* Long options support added, including --help and --version options. - -* "cvs release" no longer cares whether or not the directory being -released has an entry in the `modules' file. - -* The modules file now takes a -e option which is used instead of -o -for "cvs export". If your modules file has a -o option which you want -to be used for "cvs export", change it to specify -e as well as -o. - -* "cvs export" now takes a -k option to set RCS keyword expansion. -This way you can export binary files. If you want the old behavior, -you need to specify -kv. - -* "cvs update", "cvs rdiff", "cvs checkout", "cvs import", "cvs -release", "cvs rtag", and "cvs tag" used to take -q and -Q options -after the command name (e.g. "cvs update -q"). This was confusing -because other commands, such as "cvs ci", did not. So the options -after the command name have been removed and you must now specify, for -example, "cvs -q update", which has been supported since CVS 1.3. - -* New "wrappers" feature. This allows you to set a hook which -transforms files on their way in and out of cvs (apparently on the -NeXT there is some particular usefulness in tarring things up in the -repository). It also allows you to declare files as merge-by-copy -which means that instead of trying to merge the file, CVS will merely -copy the new version. There is a CVSROOT/cvswrappers file and an -optionsl ~/.cvswrappers file to support this feature. - -* You can set CVSROOT to user@host:dir, not just host:dir, if your -username on the server host is different than on the client host. - -* VISUAL is accepted as well as EDITOR. - -* $CVSROOT is expanded in *info files. - -Changes from 1.4A2 to 1.5: - -* Remote implementation. This is very helpful when collaborating on a -project with someone across a wide-area network. This release can -also be used locally, like other CVS versions, if you have no need for -remote access. - -Here are some of the features of the remote implementation: -- It uses reliable transport protocols (TCP/IP) for remote repository - access, not NFS. NFS is unusable over long distances (and sometimes - over short distances) -- It transfers only those files that have changed in the repository or - the working directory. To save transmission time, it will transfer - patches when appropriate, and can compress data for transmission. -- The server never holds CVS locks while waiting for a reply from the client; - this makes the system robust when used over flaky networks. - -The remote features are documented in doc/cvsclient.texi in the CVS -distribution, but the main doc file, cvs.texinfo, has not yet been -updated to include the remote features. - -* Death support. See src/README-rm-add for more information on this. - -* Many speedups, especially from jtc@cygnus.com. - -* CVS 1.2 compatibility code has been removed as a speedup. If you -have working directories checked out by CVS 1.2, CVS 1.3 or 1.4A2 will -try to convert them, but CVS 1.5 and later will not (if the working -directory is up to date and contains no extraneous files, you can just -remove it, and then check out a new working directory). Likewise if -your repository contains a CVSROOT.adm directory instead of a CVSROOT -directory, you need to rename it. - -Fri Oct 21 20:58:54 1994 Brian Berliner - - * Changes between CVS 1.3 and CVS 1.4 Alpha-2 - - * A new program, "cvsbug", is provided to let you send bug reports - directly to the CVS maintainers. Please use it instead of sending - mail to the info-cvs mailing list. If your build fails, you may - have to invoke "cvsbug" directly from the "src" directory as - "src/cvsbug.sh". - - * A new User's Guide and Tutorial, written by Per Cederqvist - of Signum Support. See the "doc" directory. A - PostScript version is included as "doc/cvs.ps". - - * The Frequesntly Asked Questions file, FAQ, has been added to the - release. Unfortunately, its contents are likely out-of-date. - - * The "cvsinit" shell script is now installed in the $prefix/bin - directory like the other programs. You can now create new - CVS repositories with great ease. - - * Index: lines are now printed on output from 'diff' and 'rdiff', - in order to facilitate application of patches to multiple subdirs. - - * Support for a ~/.cvsrc file, which allows you to specify options - that are always supposed to be given to a specific command. This - feature shows the non-orthogonality of the option set, since while - there may be an option to turn something on, the option to turn - that same thing off may not exist. - - * You can now list subdirectories that you wish to ignore in a - modules listing, such as: - - gcc -a gnu/gcc, !gnu/gcc/testsuites - - which will check out everything underneath gnu/gcc, except - everything underneath gnu/gcc/testsuites. - - * It is now much harder to accidentally overwrite an existing tag - name, since attempting to move a tag name will result in a error, - unless the -F (force) flag is given to the tag subcommands. - - * Better error checking on matching of the repository used to - check code out from against the repository the current cvs - commnands would use. (Thanks to Mark Baushke ) - - * Better support for sites with multiple CVSROOT repositories has - been contributed. The file "CVS/Root" in your working directory - is created to hold the full path to the CVS repository and a - simple check is made against your current CVSROOT setting. - - * You can now specify an RCS keyword substitution value when you - import files into the repository. - - * Uses a much newer version of Autoconf, and conforms to the GNU - coding standards much more closely. No, it still doesn't have - long option names. - - * Code cleanup. Many passes through gcc -Wall helped to identify - a number of questionable constructs. Most arbitrary length limits - were removed. - - * Profiling to determine bottlenecks helped to identify the best - places to spend time speeding up the code, which was then done. A - number of performance enhancements in filename matching have sped - up checkouts. - - * Many more contributions have been added to the "contrib" - directory. See the README file in that directory for more - information. - - * "cvs commit" will try harder to not change the file's - modification time after the commit. If the file does not change - as a result of the commit operation, CVS will preserve the - original modification time, thus speeding up future make-type - builds. - - * "cvs commit" now includes any removed files in the (optional) - pre-commit checking program that may be invoked. Previously, only - added and modified files were included. - - * It is now possible to commit a file directly onto the trunk at a - specific revision level by doing "cvs commit -r3.0 file.c", where - "3.0" specifies the revision you wish to create. The file must be - up-to-date with the current head of the trunk for this to succeed. - - * "cvs commit" will now function with a pre-commit program that - has arguments specified in the "commitinfo" file. - - * The "mkmodules" program will now look within the - $CVSROOT/CVSROOT/checkoutlist" file for any additional files that - should be automatically checked out within CVSROOT; mkmodules also - tries harder to preserve any execute bits the files may have - originally had. - - * "cvs diff" is much more accurate about its exit status now. It - now returns the maximum exit status of any invoked diff. - - * The "-I !" option is now supported for the import and update - commands correctly. It will properly clear the ignore list now. - - * Some problems with "cvs import" handling of .cvsignore have been - fixed; as well, some rampant recursion problems with import have - also been fixed. - - * "cvs rdiff" (aka "cvs patch") now tries to set the modify time - of any temporary files it uses to match those specified for the - particular revision. This allows a more accurate patch image to - be created. - - * "cvs status" has improved revision descriptions. "Working - revision" is used for the revision of the working file that you - edit directly; "Repository revision" is the revision of the file - with the $CVSROOT source repository. Also, the output is clearer - with regard to sticky and branch revisions. - - * CVS no longer dumps core when given a mixture of directories and - files in sub-directories (as in "cvs ci file1 dir1/file2"). - Instead, arguments are now clumped into their respective directory - and operated on in chunks, together. - - * If the CVSEDITOR environment variable is set, that editor is - used for log messages instead of the EDITOR environment variable. - This makes it easy to substitute intelligent programs to make more - elaborate log messages. Contributed by Mark D Baushke - (mdb@cisco.com). - - * Command argument changes: - cvs: The "-f" option has been added to ignore - the ~/.cvsrc file. - commit: Renamed the "-f logfile" option to the - "-F logfile" option. Added the "-f" - option to force a commit of the specified - files (this disables recursion). - history: Added "-t timezone" option to force any - date-specific output into the specified - timezone. - import: Added "-d" option to use the file's - modification time as the time of the - import. Added "-k sub" option to set the - default RCS keyword substitution mode for - newly-created files. - remove: Added "-f" option to force the file's - automatic removal if it still exists in - the working directory (use with caution). - rtag: Added "-F" option to move the tag if it - already exists -- new default is to NOT - move tags automatically. - tag: Added "-F" option to move the tag if it - already exists -- new default is to NOT - move tags automatically. - -Tue Apr 7 15:55:25 1992 Brian Berliner (berliner at sun.com) - - * Changes between CVS 1.3 Beta-3 and official CVS 1.3! - - * A new shell script is provided, "./cvsinit", which can be run at - install time to help setup your $CVSROOT area. This can greatly - ease your entry into CVS usage. - - * The INSTALL file has been updated to include the machines on - which CVS has compiled successfully. I think CVS 1.3 is finally - portable. Thanks to all the Beta testers! - - * Support for the "editinfo" file was contributed. This file - (located in $CVSROOT/CVSROOT) can be used to specify a special - "editor" to run on a per-directory basis within the repository, - instead of the usual user's editor. As such, it can verify that - the log message entered by the user is of the appropriate form - (contains a bugid and test validation, for example). - - * The manual pages cvs(1) and cvs(5) have been updated. - - * The "mkmodules" command now informs you when your modules file - has duplicate entries. - - * The "add" command now preserves any per-directory sticky tag when - you add a new directory to your checked-out sources. - - * The "admin" command is now a fully recursive interface to the - "rcs" program which operates on your checked-out sources. It no - longer requires you to specify the full path to the RCS file. - - * The per-file sticky tags can now be effectively removed with - "cvs update -A file", even if you had checked out the whole - directory with a per-directory sticky tag. This allows a great - deal of flexibility in managing the revisions that your checked-out - sources are based upon (both per-directory and per-file sticky - tags). - - * The "cvs -n commit" command now works, to show which files are - out-of-date and will cause the real commit to fail, or which files - will fail any pre-commit checks. Also, the "cvs -n import ..." - command will now show you what it would've done without actually - doing it. - - * Doing "cvs commit modules" to checkin the modules file will no - properly run the "mkmodules" program (assuming you have setup your - $CVSROOT/CVSROOT/modules file to do so). - - * The -t option in the modules file (which specifies a program to - run when you do a "cvs rtag" operation on a module) now gets the - symbolic tag as the second argument when invoked. - - * When the source repository is locked by another user, that user's - login name will be displayed as the holder of the lock. - - * Doing "cvs checkout module/file.c" now works even if - module/file.c is in the Attic (has been removed from main-line - development). - - * Doing "cvs commit */Makefile" now works as one would expect. - Rather than trying to commit everything recursively, it will now - commit just the files specified. - - * The "cvs remove" command is now fully recursive. To schedule a - file for removal, all you have to do is "rm file" and "cvs rm". - With no arguments, "cvs rm" will schedule all files that have been - physically removed for removal from the source repository at the - next "cvs commit". - - * The "cvs tag" command now prints "T file" for each file that was - tagged by this invocation and "D file" for each file that had the - tag removed (as with "cvs tag -d"). - - * The -a option has been added to "cvs rtag" to force it to clean - up any old, matching tags for files that have been removed (in the - Attic) that may not have been touched by this tag operation. This - can help keep a consistent view with your tag, even if you re-use - it frequently. - -Sat Feb 29 16:02:05 1992 Brian Berliner (berliner at sun.com) - - * Changes between CVS 1.3 Beta-2 and CVS 1.3 Beta-3 - - * Many portability fixes, thanks to all the Beta testers! With any - luck, this Beta release will compile correctly on most anything. - Hey, what are we without our dreams. - - * CVS finally has support for doing isolated development on a - branch off the current (or previous!) revisions. This is also - extremely nice for generating patches for previously released - software while development is progressing on the next release. - Here's an example of creating a branch to fix a patch with the 2.0 - version of the "foo" module, even though we are already well into - the 3.0 release. Do: - - % cvs rtag -b -rFOO_2_0 FOO_2_0_Patch foo - % cvs checkout -rFOO_2_0_Patch foo - % cd foo - [[ hack away ]] - % cvs commit - - A physical branch will be created in the RCS file only when you - actually commit the change. As such, forking development at some - random point in time is extremely light-weight -- requiring just a - symbolic tag in each file until a commit is done. To fork - development at the currently checked out sources, do: - - % cvs tag -b Personal_Hack - % cvs update -rPersonal_Hack - [[ hack away ]] - % cvs commit - - Now, if you decide you want the changes made in the Personal_Hack - branch to be merged in with other changes made in the main-line - development, you could do: - - % cvs commit # to make Personal_Hack complete - % cvs update -A # to update sources to main-line - % cvs update -jPersonal_Hack # to merge Personal_Hack - - to update your checked-out sources, or: - - % cvs checkout -jPersonal_Hack module - - to checkout a fresh copy. - - To support this notion of forked development, CVS reserves - all even-numbered branches for its own use. In addition, CVS - reserves the ".0" and ".1" branches. So, if you intend to do your - own branches by hand with RCS, you should use odd-numbered branches - starting with ".3", as in "1.1.3", "1.1.5", 1.2.9", .... - - * The "cvs commit" command now supports a fully functional -r - option, allowing you to commit your changes to a specific numeric - revision or symbolic tag with full consistency checks. Numeric - tags are useful for bringing your sources all up to some revision - level: - - % cvs commit -r2.0 - - For symbolic tags, you can only commit to a tag that references a - branch in the RCS file. One created by "cvs rtag -b" or from - "cvs tag -b" is appropriate (see below). - - * Roland Pesch and K. Richard Pixley - were kind enough to contribute two new manual - pages for CVS: cvs(1) and cvs(5). Most of the new CVS 1.3 features - are now documented, with the exception of the new branch support - added to commit/rtag/tag/checkout/update. - - * The -j options of checkout/update have been added. The "cvs join" - command has been removed. - - With one -j option, CVS will merge the changes made between the - resulting revision and the revision that it is based on (e.g., if - the tag refers to a branch, CVS will merge all changes made in - that branch into your working file). - - With two -j options, CVS will merge in the changes between the two - respective revisions. This can be used to "remove" a certain delta - from your working file. E.g., If the file foo.c is based on - revision 1.6 and I want to remove the changes made between 1.3 and - 1.5, I might do: - - % cvs update -j1.5 -j1.3 foo.c # note the order... - - In addition, each -j option can contain on optional date - specification which, when used with branches, can limit the chosen - revision to one within a specific date. An optional date is - specified by adding a colon (:) to the tag, as in: - - -jSymbolic_Tag:Date_Specifier - - An example might be what "cvs import" tells you to do when you have - just imported sources that have conflicts with local changes: - - % cvs checkout -jTAG:yesterday -jTAG module - - which tells CVS to merge in the changes made to the branch - specified by TAG in the last 24 hours. If this is not what is - intended, substitute "yesterday" for whatever format of date that - is appropriate, like: - - % cvs checkout -jTAG:'1 week ago' -jTAG module - - * "cvs diff" now supports the special tags "BASE" and "HEAD". So, - the command: - - % cvs diff -u -rBASE -rHEAD - - will effectively show the changes made by others (in unidiff - format) that will be merged into your working sources with your - next "cvs update" command. "-rBASE" resolves to the revision that - your working file is based on. "-rHEAD" resolves to the current - head of the branch or trunk that you are working on. - - * The -P option of "cvs checkout" now means to Prune empty - directories, as with "update". The default is to not remove empty - directories. However, if you do "checkout" with any -r options, -P - will be implied. I.e., checking out with a tag will cause empty - directories to be pruned automatically. - - * The new file INSTALL describes how to install CVS, including - detailed descriptions of interfaces to "configure". - - * The example loginfo file in examples/loginfo has been updated to - use the perl script included in contrib/log.pl. The nice thing - about this log program is that it records the revision numbers of - your change in the log message. - - Example files for commitinfo and rcsinfo are now included in the - examples directory. - - * All "#if defined(__STDC__) && __STDC__ == 1" lines have been - changed to be "#if __STDC__" to fix some problems with the former. - - * The lib/regex.[ch] files have been updated to the 1.3 release of - the GNU regex package. - - * The ndbm emulation routines included with CVS 1.3 Beta-2 in the - src/ndbm.[ch] files has been moved into the src/myndbm.[ch] files - to avoid any conflict with the system header file. If - you had a previous CVS 1.3 Beta release, you will want to "cvs - remove ndbm.[ch]" form your copy of CVS as well. - - * "cvs add" and "cvs remove" are a bit more verbose, telling you - what to do to add/remove your file permanently. - - * We no longer mess with /dev/tty in "commit" and "add". - - * More things are quiet with the -Q option set. - - * New src/config.h option: If CVS_BADROOT is set, CVS will not - allow people really logged in as "root" to commit changes. - - * "cvs diff" exits with a status of 0 if there were no diffs, 1 if - there were diffs, and 2 if there were errors. - - * "cvs -n diff" is now supported so that you can still run diffs - even while in the middle of committing files. - - * Handling of the CVS/Entries file is now much more robust. - - * The default file ignore list now includes "*.so". - - * "cvs import" did not expand '@' in the log message correctly. It - does now. Also, import now uses the ignore file facility - correctly. - - Import will now tell you whether there were conflicts that need to - be resolved, and how to resolve them. - - * "cvs log" has been changed so that you can "log" things that are - not a part of the current release (in the Attic). - - * If you don't change the editor message on commit, CVS now prompts - you with the choice: - - !)reuse this message unchanged for remaining dirs - - which allows you to tell CVS that you have no intention of changing - the log message for the remainder of the commit. - - * It is no longer necessary to have CVSROOT set if you are using - the -H option to get Usage information on the commands. - - * Command argument changes: - checkout: -P handling changed as described above. - New -j option (up to 2 can be specified) - for doing rcsmerge kind of things on - checkout. - commit: -r option now supports committing to a - numeric or symbolic tags, with some - restrictions. Full consistency checks will - be done. - Added "-f logfile" option, which tells - commit to glean the log message from the - specified file, rather than invoking the - editor. - rtag: Added -b option to create a branch tag, - useful for creating a patch for a previous - release, or for forking development. - tag: Added -b option to create a branch tag, - useful for creating a patch for a previous - release, or for forking development. - update: New -j option (up to 2 can be specified) - for doing rcsmerge kind of things on - update. - -Thu Jan 9 10:51:35 MST 1992 Jeff Polk (polk at BSDI.COM) - - * Changes between CVS 1.3 Beta-1 and CVS 1.3 Beta-2 - - * Thanks to K. Richard Pixley at Cygnus we now have function - prototypes in all the files - - * Some small changes to configure for portability. There have - been other portability problems submitted that have not been fixed - (Brian will be working on those). Additionally all __STDC__ - tests have been modified to check __STDC__ against the constant 1 - (this is what the Second edition of K&R says must be true). - - * Lots of additional error checking for forked processes (run_exec) - (thanks again to K. Richard Pixley) - - * Lots of miscellaneous bug fixes - including but certainly not - limited to: - various commit core dumps - various update core dumps - bogus results from status with numeric sticky tags - commitprog used freed memory - Entries file corruption caused by No_Difference - commit to revision broken (now works if branch exists) - ignore file processing broken for * and ! - ignore processing didn't handle memory reasonably - miscellaneous bugs in the recursion processor - file descriptor leak in ParseInfo - CVSROOT.adm->CVSROOT rename bug - lots of lint fixes - - * Reformatted all the code in src (with GNU indent) and then - went back and fixed prototypes, etc since indent gets confused. The - rationale is that it is better to do it sooner than later and now - everything is consistent and will hopefully stay that way. - The basic options to indent were: "-bad -bbb -bap -cdb -d0 -bl -bli0 - -nce -pcs -cs -cli4 -di1 -nbc -psl -lp -i4 -ip4 -c41" and then - miscellaneous formatting fixes were applied. Note also that the - "-nfc1" or "-nfca" may be appropriate in files where comments have - been carefully formatted (e.g, modules.c). - -Sat Dec 14 20:35:22 1991 Brian Berliner (berliner at sun.com) - - * Changes between CVS 1.2 and CVS 1.3 Beta are described here. - - * Lots of portability work. CVS now uses the GNU "configure" - script to dynamically determine the features provided by your - system. It probably is not foolproof, but it is better than - nothing. Please let me know of any portability problems. Some - file names were changed to fit within 14-characters. - - * CVS has a new RCS parser that is much more flexible and - extensible. It should read all known RCS ",v" format files. - - * Most of the commands now are fully recursive, rather than just - operating on the current directory alone. This includes "commit", - which makes it real easy to do an "atomic" commit of all the - changes made to a CVS hierarchy of sources. Most of the commands - also correctly handle file names that are in directories other than - ".", including absolute path names. Commands now accept the "-R" - option to force recursion on (though it is always the default now) - and the "-l" option to force recursion off, doing just "." and not - any sub-directories. - - * CVS supports many of the features provided with the RCS 5.x - distribution - including the new "-k" keyword expansion options. I - recommend using RCS 5.x (5.6 is the current official RCS version) - and GNU diff 1.15 (or later) distributions with CVS. - - * Checking out files with symbolic tags/dates is now "sticky", in - that CVS remembers the tag/date used for each file (and directory) - and will use that tag/date automatically on the next "update" call. - This stickyness also holds for files checked out with the the new - RCS 5.x "-k" options. - - * The "cvs diff" command now recognizes all of the rcsdiff 5.x - options. Unidiff format is available by installing the GNU - diff 1.15 distribution. - - * The old "CVS.adm" directories created on checkout are now called - "CVS" directories, to look more like "RCS" and "SCCS". Old CVS.adm - directories are automagically converted to CVS directories. The - old "CVSROOT.adm" directory within the source repository is - automagically changed into a "CVSROOT" directory as well. - - * Symbolic links in the source repository are fully supported ONLY - if you use RCS 5.6 or later and (of course) your system supports - symlinks. - - * A history database has been contributed which maintains the - history of certain CVS operations, as well as providing a wide array - of querying options. - - * The "cvs" program has a "-n" option which can be used with the - "update" command to show what would be updated without actually - doing the update, like: "cvs -n update". All usage statements - have been cleaned up and made more verbose. - - * The module database parsing has been rewritten. The new format - is compatible with the old format, but with much more - functionality. It allows modules to be created that grab pieces or - whole directories from various different parts of your source - repository. Module-relative specifications are also correctly - recognized now, like "cvs checkout module/file.c". - - * A configurable template can be specified such that on a "commit", - certain directories can supply a template that the user must fill - before completing the commit operation. - - * A configurable pre-commit checking program can be specified which - will run to verify that a "commit" can happen. This feature can be - used to restrict certain users from changing certain pieces of the - source repository, or denying commits to the entire source - repository. - - * The new "cvs export" command is much like "checkout", but - establishes defaults suitable for exporting code to others (expands - out keywords, forces the use of a symbolic tag, and does not create - "CVS" directories within the checked out sources. - - * The new "cvs import" command replaces the deprecated "checkin" - shell script and is used to import sources into CVS control. It is - also much faster for the first-time import. Some algorithmic - improvements have also been made to reduce the number of - conflicting files on next-time imports. - - * The new "cvs admin" command is basically an interface to the - "rcs" program. (Not yet implemented very well). - - * Signal handling (on systems with BSD or POSIX signals) is much - improved. Interrupting CVS now works with a single interrupt! - - * CVS now invokes RCS commands by direct fork/exec rather than - calling system(3). This improves performance by removing a call to - the shell to parse the arguments. - - * Support for the .cvsignore file has been contributed. CVS will - now show "unknown" files as "? filename" as the result of an "update" - command. The .cvsignore file can be used to add files to the - current list of ignored files so that they won't show up as unknown. - - * Command argument changes: - cvs: Added -l to turn off history logging. - Added -n to show what would be done without actually - doing anything. - Added -q/-Q for quiet and really quiet settings. - Added -t to show debugging trace. - add: Added -k to allow RCS 5.x -k options to be specified. - admin: New command; an interface to rcs(1). - checkout: Added -A to reset sticky tags/date/options. - Added -N to not shorten module paths. - Added -R option to force recursion. - Changed -p (prune empty directories) to -P option. - Changed -f option; forcing tags match is now default. - Added -p option to checkout module to standard output. - Added -s option to cat the modules db with status. - Added -d option to checkout in the specified directory. - Added -k option to use RCS 5.x -k support. - commit: Removed -a option; use -l instead. - Removed -f option. - Added -l option to disable recursion. - Added -R option to force recursion. - If no files specified, commit is recursive. - diff: Now recognizes all RCS 5.x rcsdiff options. - Added -l option to disable recursion. - Added -R option to force recursion. - history: New command; displays info about CVS usage. - import: Replaces "checkin" shell script; imports sources - under CVS control. Ignores files on the ignore - list (see -I option or .cvsignore description above). - export: New command; like "checkout", but w/special options - turned on by default to facilitate exporting sources. - join: Added -B option to join from base of the branch; - join now defaults to only joining with the top two - revisions on the branch. - Added -k option for RCS 5.x -k support. - log: Supports all RCS 5.x options. - Added -l option to disable recursion. - Added -R option to force recursion. - patch: Changed -f option; forcing tags match is now default. - Added -c option to force context-style diffs. - Added -u option to support unidiff-style diffs. - Added -V option to support RCS specific-version - keyword expansion formats. - Added -R option to force recursion. - remove: No option changes. It's a bit more verbose. - rtag: Equivalent to the old "cvs tag" command. - No option changes. It's a lot faster for re-tag. - status: New output formats with more information. - Added -l option to disable recursion. - Added -R option to force recursion. - Added -v option to show symbolic tags for files. - tag: Functionality changed to tag checked out files - rather than modules; use "rtag" command to get the - old "cvs tag" behaviour. - update: Added -A to reset sticky tags/date/options. - Changed -p (prune empty directories) to -P option. - Changed -f option; forcing tags match is now default. - Added -p option to checkout module to standard output. - Added -I option to add files to the ignore list. - Added -R option to force recursion. - - Major Contributors: - - * Jeff Polk rewrote most of the grody code of CVS - 1.2. He made just about everything dynamic (by using malloc), - added a generic hashed list manager, re-wrote the modules database - parsing in a compatible - but extended way, generalized directory - hierarchy recursion for virtually all the commands (including - commit!), generalized the loginfo file to be used for pre-commit - checks and commit templates, wrote a new and flexible RCS parser, - fixed an uncountable number of bugs, and helped in the design of - future CVS features. If there's anything gross left in CVS, it's - probably my fault! - - * David G. Grubbs contributed the CVS "history" and - "release" commands. As well as the ever-so-useful "-n" option of - CVS which tells CVS to show what it would do, without actually - doing it. He also contributed support for the .cvsignore file. - - * Paul Sander, HaL Computer Systems, Inc. wrote and - contributed the code in lib/sighandle.c. I added support for - POSIX, BSD, and non-POSIX/non-BSD systems. - - * Free Software Foundation contributed the "configure" script and - other compatibility support in the "lib" directory, which will help - make CVS much more portable. - - * Many others have contributed bug reports and enhancement requests. - Some have even submitted actual code which I have not had time yet - to integrate into CVS. Maybe for the next release. - - * Thanks to you all! - -Wed Feb 6 10:10:58 1991 Brian Berliner (berliner at sun.com) - - * Changes from CVS 1.0 Patchlevel 1 to CVS 1.0 Patchlevel 2; also - known as "Changes from CVS 1.1 to CVS 1.2". - - * Major new support with this release is the ability to use the - recently-posted RCS 5.5 distribution with CVS 1.2. See below for - other assorted bug-fixes that have been thrown in. - - * ChangeLog (new): Added Emacs-style change-log file to CVS 1.2 - release. Chronological description of changes between release. - - * README: Small fixes to installation instructions. My email - address is now "berliner@sun.com". - - * src/Makefile: Removed "rcstime.h". Removed "depend" rule. - - * src/partime.c: Updated to RCS 5.5 version with hooks for CVS. - * src/maketime.c: Updated to RCS 5.5 version with hooks for CVS. - * src/rcstime.h: Removed from the CVS 1.2 distribution. - Thanks to Paul Eggert for these changes. - - * src/checkin.csh: Support for RCS 5.5 parsing. - Thanks to Paul Eggert for this change. - - * src/collect_sets.c (Collect_Sets): Be quieter if "-f" option is - specified. When checking out files on-top-of other files that CVS - doesn't know about, run a diff in the hopes that they are really - the same file before aborting. - - * src/commit.c (branch_number): Fix for RCS 5.5 parsing. - Thanks to Paul Eggert for this change. - - * src/commit.c (do_editor): Bug fix - fprintf missing argument - which sometimes caused core dumps. - - * src/modules.c (process_module): Properly NULL-terminate - update_dir[] in all cases. - - * src/no_difference.c (No_Difference): The wrong RCS revision was - being registered in certain (strange) cases. - - * src/patch.c (get_rcsdate): New algorithm. No need to call - maketime() any longer. - Thanks to Paul Eggert for this change. - - * src/patchlevel.h: Increased patch level to "2". - - * src/subr.c (isdir, islink): Changed to compare stat mode bits - correctly. - - * src/tag.c (tag_file): Added support for following symbolic links - that are in the master source repository when tagging. Made tag - somewhat quieter in certain cases. - - * src/update.c (update_process_lists): Unlink the user's file if it - was put on the Wlist, meaning that the user's file is not modified - and its RCS file has been removed by someone else. - - * src/update.c (update): Support for "cvs update dir" to correctly - just update the argument directory "dir". - - * src/cvs.h: Fixes for RCS 5.5 parsing. - * src/version_number.c (Version_Number): Fixes for parsing RCS 5.5 - and older RCS-format files. - Thanks to Paul Eggert for these changes. - - * src/version_number.c (Version_Number): Bug fixes for "-f" option. - Bug fixes for parsing with certain branch numbers. RCS - revision/symbol parsing is much more solid now. - -Wed Feb 14 10:01:33 1990 Brian Berliner (berliner at sun.com) - - * Changes from CVS 1.0 Patchlevel 0 to CVS 1.0 Patchlevel 1; also - known as "Changes from CVS 1.0 to CVS 1.1". - - * src/patch.c (get_rcsdate): Portability fix. Replaced call to - timelocal() with call to maketime(). - -Mon Nov 19 23:15:11 1990 Brian Berliner (berliner at prisma.com) - - * Sent CVS 1.0 release to comp.sources.unix moderator and FSF. - - * Special thanks to Dick Grune for his work on the - 1986 version of CVS and making it available to the world. Dick's - version is available on uunet.uu.net in the - comp.sources.unix/volume6/cvs directory. diff --git a/contrib/cvs/PROJECTS b/contrib/cvs/PROJECTS deleted file mode 100644 index b46eb2a..0000000 --- a/contrib/cvs/PROJECTS +++ /dev/null @@ -1,53 +0,0 @@ -This is a list of projects for CVS. In general, unlike the things in -the TODO file, these need more analysis to determine if and how -worthwhile each task is. - -I haven't gone through TODO, but it's likely that it has entries that -are actually more appropriate for this list. - -0. Improved Efficency - -* CVS uses a single doubly linked list/hash table data structure for - all of its lists. Since the back links are only used for deleting - list nodes it might be beneficial to use singly linked lists or a - tree structure. Most likely, a single list implementation will not - be appropriate for all uses. - - One easy change would be to remove the "type" field out of the list - and node structures. I have found it to be of very little use when - debugging, and each instance eats up a word of memory. This can add - up and be a problem on memory-starved machines. - - Profiles have shown that on fast machines like the Alpha, fsortcmp() - is one of the hot spots. - -* Dynamically allocated character strings are created, copied, and - destroyed throughout CVS. The overhead of malloc()/strcpy()/free() - needs to be measured. If significant, it could be minimized by using a - reference counted string "class". - -* File modification time is stored as a character string. It might be - worthwile to use a time_t internally if the time to convert a time_t - (from struct stat) to a string is greater that the time to convert a - ctime style string (from the entries file) to a time_t. time_t is - an machine-dependant type (although it's pretty standard on UN*X - systems), so we would have to have different conversion routines. - Profiles show that both operations are called about the same number - of times. - -* stat() is one of the largest performance bottlenecks on systems - without the 4.4BSD filesystem. By spliting information out of - the filesystem (perhaps the "rename database") we should be - able to improve performance. - -* Parsing RCS files is very expensive. This might be unnecessary if - RCS files are only used as containers for revisions, and tag, - revision, and date information was available in easy to read - (and modify) indexes. This becomes very apparent with files - with several hundred revisions. - -1. Improved testsuite/sanity check script - -* Need to use a code coverage tool to determine how much the sanity - script tests, and fill in the holes. - diff --git a/contrib/cvs/README b/contrib/cvs/README deleted file mode 100644 index b024db2..0000000 --- a/contrib/cvs/README +++ /dev/null @@ -1,144 +0,0 @@ - CVS Kit - - Copyright (C) 1986-2006 Free Software Foundation, Inc. - - Portions Copyright (C) 1998-2006 Derek Price, - & Ximbiot . - Portions Copyright (C) 1993-1994 Brian Berliner. - Portions Copyright (C) 1992 Brian Berliner and Jeff Polk. - Portions Copyright (C) 1989-1992 Brian Berliner. - All Rights Reserved - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 1, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - -------------------------------------------------------------------------------- - -Welcome to CVS! - -If you have problems or think you have found a bug in CVS, see the -section BUGS in the CVS manual (also known as Version Management with -CVS by Per Cederqvist et al, or cvs.texinfo--see below for details). - -If you are thinking of submitting changes to CVS, see the -file HACKING. - -Please consult the INSTALL file for information on tested -configurations. If you have a comment about an already tested -configuration, or have tried CVS on a new configuration, please let us -know as described in INSTALL. Free software only works if we all help -out. - -Finally, we cannot guarantee that this release will not completely wipe out -all of your work from your system. We do some simple testing before each -release, but you are completely on your own. We recommend testing this -release on a source repository that is not critical to your work. THIS -SOFTWARE IS SUPPLIED COMPLETELY "AS IS". NO WARRANTY.... - -Thanks for your support! - - -The CVS Team - -------------------------------------------------------------------------------- - -What Is CVS? - -CVS is a version control system, which allows you to keep old versions -of files (usually source code), keep a log of who, when, and why -changes occurred, etc., like RCS or SCCS. It handles multiple -developers, multiple directories, triggers to enable/log/control -various operations, and can work over a wide area network. The -following tasks are not included; they can be done in conjunction with -CVS but will tend to require some script-writing and software other -than CVS: bug-tracking, build management (that is, make and make-like -tools), and automated testing. - -And a whole lot more. See the manual for more information. - -------------------------------------------------------------------------------- - -Notes to people upgrading from a previous release of CVS: - -See the NEWS file for a description of features new in this version. - -See the Compatibility section of the manual for information on -compatibility between CVS versions. The quick summary is that as long -as you not using the optional watch features, there are no -compatibility problems with CVS 1.5 or later. - -------------------------------------------------------------------------------- - -Verifying the Integrity of Downloads: - -The official CVS source and binary releases are signed by the CVS maintainer -who generated them. This does not imply any sort of warranty, but it does mean -that you can verify that the file you downloaded did, in fact, come from a CVS -maintainer. - -The OpenPGP keys of the CVS maintainers who have submitted them are in the KEYS -file of the CVS distribution and are also available from many OpenPGP key -servers. It is recommended that you verify the key fingerprints against an -external source, however you obtain the key. - -------------------------------------------------------------------------------- - -Installation: - -Please read the INSTALL file for installation instructions. Brief summary: - - $ ./configure - $ make - (run the regression tests if desired) - $ make install - (create a repository if you don't already have one) - -The documentation is in the doc subdirectory. cvs.texinfo is the main -manual; cvs.info* and cvs.ps are the info and postscript versions, -respectively, generated from cvs.texinfo. The postscript version is -for US letter size paper; we do this not because we consider this size -"better" than A4, but because we believe that the US letter version -will print better on A4 paper than the other way around. If you want a -version formatted for A4, add the line @afourpaper near the start of -cvs.texinfo and re-generate cvs.ps using TeX. - -------------------------------------------------------------------------------- - -* How do I get up-to-date information and information about other -versions of CVS? - -See also - http://cvs.nongnu.org - http://www.cvsnt.org - -Anyone can add themselves to the following mailing lists: - - bug-cvs: This is the list which users are requested to send bug reports - to. General CVS development and design discussions also tend to take - place on this list. - info-cvs: This list is intended for user questions, including general - help requests. - cvs-announce: CVS release announcements and other major - announcements about the project are sent to this list. - cvs-announce-binaries: Announcements are made to this list - when binaries for various platforms are built and initially - posted for download. - -To subscribe to any of these lists, send mail to -request@nongnu.org -or visit http://savannah.nongnu.org/mail/?group=cvs and follow the instructions -for the list you wish to subscribe to. - -The newsgroup for CVS (and other configuration management systems) is -comp.software.config-mgmt. The gnu.cvs.help newsgroup is a 2-way mirror -of the info-cvs@nongnu.org mailing list and gnu.cvs.bug is similarly a 2-way -mirror of bug-cvs@nongnu.org. - -------------------------------------------------------------------------------- - -Credits: See the AUTHORS file. diff --git a/contrib/cvs/TESTS b/contrib/cvs/TESTS deleted file mode 100644 index dc904d1..0000000 --- a/contrib/cvs/TESTS +++ /dev/null @@ -1,240 +0,0 @@ -To run the tests: - - $ make check - -Note that if your /bin/sh doesn't support shell functions, you'll -have to try something like this, where "/bin/sh5" is replaced by the -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. - -The tests work in /tmp/cvs-sanity (which the tests create) by default. -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. - -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). At this writting, 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. There are environment variables you can -set to use a particular version of a tool -- see the test script -(src/sanity.sh) for details. - -Some of the tests use fairly long command lines -- this usually isn't a -problem, but if you have a very short command line length limit (or a -lot of environment variables), you may run into trouble. Also, some of -the tests expect your local timezone to be an integral number of hours -from UTC -- if you usually use a fractional timezone, use a different -(integral) timezone when running the tests to avoid spurious failures. - -If running the tests produces the output "FAIL:" followed by the name -of the test that failed, then the details on the failure are in the -file check.log. If it says "exit status is " followed by a number, -then the exit status of the command under test was not what the test -expected. If it says "** expected:" followed by a regular expression -followed by "** got:" followed by some text, then the regular -expression is the output which the test expected, and the text is the -output which the command under test actually produced. In some cases -you'll have to look closely to see how they differ. - -If output from "make remotecheck" is out of order compared to what is -expected (for example, - - a - b - cvs foo: this is a demo - -is expected and - - a - cvs foo: this is a demo - b - -is output), this is probably a well-known bug in the CVS server -(search for "out-of-order" in src/server.c for a comment explaining -the cause). It is a real pain in running the testsuite, but if you -are lucky and/or your machine is fast and/or lightly loaded, you won't -run into it. Running the tests again might succeed if the first run -failed in this manner. - -For more information on what goes in check.log, and how the tests are -run in general, you'll have to read sanity.sh. Depending on just what -you are looking for, and how familiar you are with the Bourne shell -and regular expressions, it will range from relatively straightforward -to obscure. - -If you choose to submit a bug report based on tests failing, be -aware that, as with all bug reports, you may or may not get a -response, and your odds might be better if you include enough -information to reproduce the bug, an analysis of what is going -wrong (if you have the time to provide one), etc. The check.log -file is the first place to look. - -ABOUT STDOUT AND STDERR -*********************** - -The sanity.sh test framework combines stdout and stderr and for tests -to pass requires that output appear in the given order. Some people -suggest that ordering between stdout and stderr should not be -required, or to put it another way, that the out-of-order bug referred -to above, and similar behaviors, should be considered features, or at -least tolerable. The reasoning behind the current behavior is that -having the output appear in a certain order is the correct behavior -for users using CVS interactively--that users get confused if the -order is unpredictable. - -ABOUT TEST FRAMEWORKS -********************* - -People periodically suggest using dejagnu or some other test -framework. A quick look at sanity.sh should make it clear that there -are indeed reasons to be dissatisfied with the status quo. Ideally a -replacement framework would achieve the following: - -1. Widely portable, including to a wide variety of unices, NT, Win95, -OS/2, VMS, probably DOS and Win3, etc. - -2. Nicely match extended regular expressions of unlimited length. - -3. Be freely redistributable, and if possible already the kind of -thing people might have already installed. The harder it is to get -and install the framework, the less people will run the tests. - -The various contenders are: - -* Bourne shell and GNU expr (the status quo). Falls short on #1 -(we've only tried unix and NT, although MKS might help with other DOS -mutants). #3 is pretty good (the main dependency is GNU expr which is -fairly widely available). - -* Bourne shell with a new regexp matcher we would distribute with -CVS. This means maintaining a regexp matcher and the makefiles which -go with it. Not clearly a win over Bourne shell and GNU expr. - -* Bourne shell, and use sed to remove variable portions of output, and -thus produce a form that can be compared with cmp or diff (this -sidesteps the need for a full regular expression matcher as mentioned -in #2 above). The C News tests are said to work this way. This would -appear to rely on variable portions of output having a certain syntax -and might spuriously recognize them out of context (this issue needs -more investigation; it isn't clear how big a problem it is in -practice). Same portability issues as the other choices based on the -Bourne shell. - -* Dejagnu. This is overkill; most of dejagnu is either unnecessary -(e.g. libraries for communicating with target boards) or undesirable -(e.g. the code which stats every file in sight to find the tests). On -the plus side, dejagnu is probably closer than any of the other -choices to having everything which is needed already there. - -* Write our own small framework directly in tcl and distribute with -CVS. The tests would look much like dejagnu tests, but we'd avoid the -unnecessary baggage. The only dependency would be on tcl (that is, -wish). - -* perl or python or - -It is worth thinking about how to: - -a. include spaces in arguments which we pass to the program under -test (sanity.sh dotest cannot do this; see test rcs-9 for a -workaround). - -b. pass stdin to the program under test (sanity.sh, again, handles -this by bypassing dotest). - -c. have a send-expect type dialog with the program under test - (e.g. see server-7 or pserver-4 which want to talk the CVS - protocol, or the many tests which need to answer the prompt of "cvs - release", e.g. deep-5). - -ABOUT ADDING YOUR OWN TESTS -*************************** - -As stated in the HACKING file, patches are not accepted without documentation -and tests. Many people seem to be scared off by the large size of the -sanity.sh script, but it is not really very complicated. - -You can probably ignore most of the begining of the script. This section -just sets some environment variables and finds the tools the script needs to -run. - -There is one main loop you can find by grepping for "The big loop". This loop -repeatedly calls a case statement where the individual cases are of the form: - - testname) - ... - ;; - -If you add a complete new test be sure to add it into the default list of tests -(grep for 'tests=' near the begining of the script) as well as the case -statement. During debugging, be aware that the sanity.sh usage allows for a '-f -testname' option to continue through the default list "from" a particular test -as well as interpreting everything in argv past the required options as test -names to run individual tests. - -Within each major test section, individual tests usually look like: - - dotest testname-subtestname "shell command" "optionally multiline regexp" - -Tests should always start in $testdir and create a subdirectory to operate in -and remove their cruft and end back in $testdir. The dotest functions output -failure messages and exit if the shell command exits with the wrong exit code or -its stdin/stderr output doesn't match the regexp. There are a few dotest -variations, most notably dotest_fail for expected non-zero exit codes. - -Other than that the script is mostly vanilla Bourne shell. There are a few -constructs used for versatility and portability. You can grep for the ones I -miss, but here are a few important ones. I'm leaving off long explanations -after the first few since it probably gives you the idea and the data is in -sanity.sh. - -Note that the boolean variables contain shell commands which return true or -false when executed and are intended to be used like, -"if $remote; then ... ; else ... ; fi" - - - * $testdir = the directory this test is taking place in - (CVSROOT=$testdir/cvsroot or - CVSROOT=:fork:$testdir/cvsroot) - * $testcvs = full path to the cvs executable we are testing - * $PLUS = expr dependant uninterpreted '+' since this can vary - * $DOTSTAR = expr dependant _interpreted_ .* since some exprs don't - match EOL - * $username = the username of the user running the tests - * $username8 = the first 8 characters of $username, output by some - system and CVS commands - * $anyusername = regexp to match any valid system or CVS username - * $hostname = regexp to match a hostname - * $PROG = regexp to match progname in CVS error messages - * $remote = ':' (true) or 'false', depending on whether the script is - running with a remote CVSROOT - * $keep = ':' (true) or 'false'. When set, the first test run will - leave any files and directories it created in $testdir and - exit when complete. - -And, of course, some characters like '.' in regexps need to be '\' escaped when -you mean them literally. Some characters may be interpreted by the shell, -e.g. backquotes and '$', are usually either escaped or replaced with '.'. -dotest adds the final '$' anchor to the regexp itself and all the expr -implementations I know of implicitly supply the start anchor ('^'). - -If you only make a few mistakes, the work is, of course, still usable, though we -may send the patch back to you for repair. :) diff --git a/contrib/cvs/TODO b/contrib/cvs/TODO deleted file mode 100644 index 6ee6759..0000000 --- a/contrib/cvs/TODO +++ /dev/null @@ -1,862 +0,0 @@ -The "TODO" file! -*-Indented-Text-*- - -38. Think hard about using RCS state information to allow one to checkin - a new vendor release without having it be accessed until it has been - integrated into the local changes. - -39. Think about a version of "cvs update -j" which remembers what from - that other branch is already merged. This has pitfalls--it could - easily lead to invisible state which could confuse users very - rapidly--but having to create a tag or some such mechanism to keep - track of what has been merged is a pain. Take a look at PRCS 1.2. - PRCS 1.0 was particularly bad the way it handled the "invisible - state", but 1.2 is significantly better. - -52. SCCS has a feature that I would *love* to see in CVS, as it is very - useful. One may make a private copy of SCCS suid to a particular user, - so other users in the authentication list may check files in and out of - a project directory without mucking about with groups. Is there any - plan to provide a similar functionality to CVS? Our site (and, I'd - imagine, many other sites with large user bases) has decided against - having the user-groups feature of unix available to the users, due to - perceived administrative, technical and performance headaches. A tool - such as CVS with features that provide group-like functionality would - be a huge help. - -62. Consider using revision controlled files and directories to handle the - new module format -- consider a cvs command front-end to - add/delete/modify module contents, maybe. - -63. The "import" and vendor support commands (co -j) need to be documented - better. - -66. Length of the CVS temporary files must be limited to 14 characters for - System-V stupid support. As well as the length on the CVS.adm files. - -72. Consider re-design of the module -t options to use the file system more - intuitively. - -73. Consider an option (in .cvsrc?) to automatically add files that are new - and specified to commit. - -79. Might be nice to have some sort of interface to Sun's Translucent - (?) File System and tagged revisions. - -82. Maybe the import stuff should allow an arbitrary revision to be - specified. - -84. Improve the documentation about administration of the repository and - how to add/remove files and the use of symbolic links. - -85. Make symbolic links a valid thing to put under version control. - Perhaps use one of the tag fields in the RCS file? Note that we - can only support symlinks that are relative and within the scope of - the sources being controlled. - -93. Need to think hard about release and development environments. Think - about execsets as well. - -98. If diff3 bombs out (too many differences) cvs then thinks that the file - has been updated and is OK to be commited even though the file - has not yet been merged. - -100. Checked out files should have revision control support. Maybe. - -102. Perhaps directory modes should be propagated on all import check-ins. - Not necessarily uid/gid changes. - -103. setuid/setgid on files is suspect. - -104. cvs should recover nicely on unreadable files/directories. - -105. cvs should have administrative tools to allow for changing permissions - and modes and what not. In particular, this would make cvs a - more attractive alternative to rdist. - -107. It should be possible to specify a list of symbolic revisions to - checkout such that the list is processed in reverse order looking for - matches within the RCS file for the symbolic revision. If there is - not a match, the next symbolic rev on the list is checked, and so on, - until all symbolic revs are exhausted. This would allow one to, say, - checkout "4.0" + "4.0.3" + "4.0.3Patch1" + "4.0.3Patch2" to get the - most recent 4.x stuff. This is usually handled by just specifying the - right release_tag, but most people forget to do this. - -108. If someone creates a whole new directory (i.e. adds it to the cvs - repository) and you happen to have a directory in your source farm by - the same name, when you do your cvs update -d it SILENTLY does - *nothing* to that directory. At least, I think it was silent; - certainly, it did *not* abort my cvs update, as it would have if the - same thing had happened with a file instead of a directory. - -109. I had gotten pieces of the sys directory in the past but not a - complete tree. I just did something like: - - cvs get * - - Where sys was in * and got the message - - cvs get: Executing 'sys/tools/make_links sys' - sh: sys/tools/make_links: not found - - I suspect this is because I didn't have the file in question, - but I do not understand how I could fool it into getting an - error. I think a later cvs get sys seemed to work so perhaps - something is amiss in handling multiple arguments to cvs get? - -119. When importing a directory tree that is under SCCS/RCS control, - consider an option to have import checkout the SCCS/RCS files if - necessary. (This is if someone wants to import something which - is in RCS or SCCS without preserving the history, but makes sure - they do get the latest versions. It isn't clear to me how useful - that is -kingdon, June 1996). - -122. If Name_Repository fails, it currently causes CVS to die completely. It - should instead return NULL and have the caller do something reasonable - (??? -what is reasonable? I'm not sure there is a real problem here. - -kingdon, June 1996). - -123. Add a flag to import to not build vendor branches for local code. - (See `importb' tests in src/sanity.sh for more details). - -124. Anyway, I thought you might want to add something like the following - to the cvs man pages: - - BUGS - The sum of the sizes of a module key and its contents are - limited. See ndbm(3). - -126. Do an analysis to see if CVS is forgetting to close file descriptors. - Especially when committing many files (more than the open file limit - for the particular UNIX). - -127. Look at *info files; they should all be quiet if the files are not - there. Should be able to point at a RCS directory and go. - -130. cvs diff with no -r arguments does not need to look up the current RCS - version number since it only cares about what's in the Entries file. - This should make it much faster. - - It should ParseEntries itself and access the entries list much like - Version_TS does (sticky tags and sticky options may need to be - supported here as well). Then it should only diff the things that - have the wrong time stamp (the ones that look modified). - -134. Make a statement about using hard NFS mounts to your source - repository. Look into checking NULL fgets() returns with ferror() to - see if an error had occurred. (we should be checking for errors, quite - aside from NFS issues -kingdon, June 1996). - -137. Some sites might want CVS to fsync() the RCS ,v file to protect - against nasty hardware errors. There is a slight performance hit with - doing so, though, so it should be configurable in the .cvsrc file. - Also, along with this, we should look at the places where CVS itself - could be a little more synchronous so as not to lose data. - [[ I've done some of this, but it could use much more ]] - -138. Some people have suggested that CVS use a VPATH-like environment - variable to limit the amount of sources that need to be duplicated for - sites with giant source trees and no disk space. - -141. Import should accept modules as its directory argument. If we're - going to implement this, we should think hard about how modules - might be expanded and how to handle those cases. - -143. Update the documentation to show that the source repository is - something far away from the files that you work on. (People who - come from an RCS background are used to their `repository' being - _very_ close to their working directory.) - -144. Have cvs checkout look for the environment variable CVSPREFIX - (or CVSMODPREFIX or some such). If it's set, then when looking - up an alias in the modules database, first look it up with the - value of CVSPREFIX attached, and then look for the alias itself. - This would be useful when you have several projects in a single - repository. You could have aliases abc_src and xyz_src and - tell people working on project abc to put "setenv CVSPREFIX abc_" - in their .cshrc file (or equivalent for other shells). - Then they could do "cvs co src" to get a copy of their src - directory, not xyz's. (This should create a directory called - src, not abc_src.) - -145. After you create revision 1.1.1.1 in the previous scenario, if - you do "cvs update -r1 filename" you get revision 1.1, not - 1.1.1.1. It would be nice to get the later revision. Again, - this restriction comes from RCS and is probably hard to - change in CVS. Sigh. - - |"cvs update -r1 filename" does not tell RCS to follow any branches. CVS - |tries to be consistent with RCS in this fashion, so I would not change - |this. Within CVS we do have the flexibility of extending things, like - |making a revision of the form "-r1HEAD" find the most recent revision - |(branch or not) with a "1." prefix in the RCS file. This would get what - |you want maybe. - - This would be very useful. Though I would prefer an option - such as "-v1" rather than "-r1HEAD". This option might be - used quite often. - -146. The merging of files should be controlled via a hook so that programs - other than "rcsmerge" can be used, like Sun's filemerge or emacs's - emerge.el. (but be careful in making this work client/server--it means - doing the interactive merging at the end after the server is done). - (probably best is to have CVS do the non-interactive part and - tell the user about where the files are (.#foo.c.working and - .#foo.c.1.5 or whatever), so they can do the interactive part at - that point -kingdon, June 1996). - -149. Maybe there should be an option to cvs admin that allows a user to - change the Repository/Root file with some degree of error checking? - Something like "cvs admin reposmv /old/path /new/pretty/path". Before - it does the replace it check to see that the files - /new/pretty/path// exist. - - The obvious cases are where one moves the repository to another - machine or directory. But there are other cases, like where the - user might want to change from :pserver: to :ext:, use a different - server (if there are two server machines which share the - repository using a networked file system), etc. - - The status quo is a bit of a mess (as of, say, CVS 1.9). It is - that the -d global option has two moderately different uses. One - is to use a totally different repository (in which case we'd - probably want to give an error if it disagreed with CVS/Root, as - CVS 1.8 and earlier did). The other is the "reposmv" - functionality above (in which the two repositories really are the - same, and we want to update the CVS/Root files). In CVS 1.9 and - 1.10, -d rewrites the CVS/Root file (but not in subdirectories). - This behavior was not particularly popular and has been since - reverted. - - This whole area is a rather bad pile of individual decisions which - accumulated over time, some of them probably bad decisions with - hindsight. But we didn't get into this mess overnight, and we're - not going to get out of it overnight (that is, we need to come up - with a replacement behavior, document what parts of the status - quo are deprecated, probably circulate some unofficial patches, &c). - - (this item originally added 2 Feb 1992 but revised since). - -150. I have a customer request for a way to specify log message per - file, non-interactively before the commit, such that a single, fully - recursive commit prompts for one commit message, and concatenates the - per file messages for each file. In short, one commit, one editor - session, log messages allowed to vary across files within the commit. - Also, the per file messages should be allowed to be written when the - files are changed, which may predate the commit considerably. - - A new command seems appropriate for this. The state can be saved in the - CVS directory. I.e., - - % cvs message foo.c - Enter log message for foo.c - >> fixed an uninitialized variable - >> ^D - - The text is saved as CVS/foo.c,m (or some such name) and commit - is modified to append (prepend?) the text (if found) to the log - message specified at commit time. Easy enough. (having cvs - commit be non-interactive takes care of various issues like - whether to connect to the server before or after prompting for a - message (see comment in commit.c at call to start_server). Also - would clean up the kludge for what to do with the message from - do_editor if the up-to-date check fails (see commit.c client code). - - I'm not sure about the part above about having commit prompt - for an overall message--part of the point is having commit - non-interactive and somehow combining messages seems like (excess?) - hair. - - Would be nice to do this so it allows users more flexibility in - specifying messages per-directory ("cvs message -l") or per-tree - ("cvs message") or per-file ("cvs message foo.c"), and fixes the - incompatibility between client/server (per-tree) and - non-client/server (per-directory). - - A few interesting issues with this: (1) if you do a cvs update or - some other operation which changes the working directory, do you - need to run "cvs message" again (it would, of course, bring up - the old message which you could accept)? Probably yes, after all - merging in some conflicts might change the situation. (2) How do - you change the stored messages if you change your mind before the - commit (probably run "cvs message" again, as hinted in (1))? - -151. Also, is there a flag I am missing that allows replacing Ulrtx_Build - by Ultrix_build? I.E. I would like a tag replacement to be a one step - operation rather than a two step "cvs rtag -r Ulrtx_Build Ultrix_Build" - followed by "cvs rtag -d Ulrtx_Build" - -152. The "cvs -n" option does not work as one would expect for all the - commands. In particular, for "commit" and "import", where one would - also like to see what it would do, without actually doing anything. - -153. There should be some command (maybe I just haven't figured out - which one...) to import a source directory which is already - RCS-administered without losing all prior RCS gathered data. - Thus, it would have to examine the RCS files and choose a - starting version and branch higher than previous ones used. - (Check out rcs-to-cvs and see if it addresses this issue.) - -154. When committing the modules file, a pre-commit check should be done to - verify the validity of the new modules file before allowing it to be - committed. - -155. The options for "cvs history" are mutually exclusive, even though - useful queries can be done if they are not, as in specifying both - a module and a tag. A workaround is to specify the module, then - run the output through grep to only display lines that begin with - T, which are tag lines. (Better perhaps if we redesign the whole - "history" business -- check out doc/cvs.texinfo for the entire - rant.) - -156. Also, how hard would it be to allow continuation lines in the - {commit,rcs,log}info files? It would probably be useful with all of - the various flags that are now available, or if somebody has a lot of - files to put into a module. - -158. If I do a recursive commit and find that the same RCS file is checked - out (and modified!) in two different places within my checked-out - files (but within the realm of a single "commit"), CVS will commit the - first change, then overwrite that change with the second change. We - should catch this (typically unusual) case and issue an appropriate - diagnostic and die. - -160. The checks that the commit command does should be extended to make - sure that the revision that we will lock is not already locked by - someone else. Maybe it should also lock the new revision if the old - revision was already locked by the user as well, thus moving the lock - forward after the commit. - -163. The rtag/tag commands should have an option that removes the specified - tag from any file that is in the attic. This allows one to re-use a - tag (like "Mon", "Tue", ...) all the time and still have it tag the - real main-line code. - -165. The "import" command will create RCS files automatically, but will - screw-up when trying to create long file names on short file name - file systems. Perhaps import should be a bit more cautious. - -166. There really needs to be a "Getting Started" document which describes - some of the new CVS philosophies. Folks coming straight from SCCS or - RCS might be confused by "cvs import". Also need to explain: - - How one might setup their $CVSROOT - - What all the tags mean in an "import" command - - Tags are important; revision numbers are not - -170. Is there an "info" file that can be invoked when a file is checked out, or - updated ? What I want to do is to advise users, particularly novices, of - the state of their working source whenever they check something out, as - a sanity check. - - For example, I've written a perl script which tells you what branch you're - on, if any. Hopefully this will help guard against mistaken checkins to - the trunk, or to the wrong branch. I suppose I can do this in - "commitinfo", but it'd be nice to advise people before they edit their - files. - - It would also be nice if there was some sort of "verboseness" switch to - the checkout and update commands that could turn this invocation of the - script off, for mature users. - -173. Need generic date-on-branch handling. Currently, many commands - allow both -r and -D, but that's problematic for commands like diff - that interpret that as two revisions rather than a single revision. - Checkout and update -j takes tag:date which is probably a better - solution overall. - -174. I would like to see "cvs release" modified so that it only removes files - which are known to CVS - all the files in the repository, plus those which - are listed in .cvsignore. This way, if you do leave something valuable in - a source tree you can "cvs release -d" the tree and your non-CVS goodies - are still there. If a user is going to leave non-CVS files in their source - trees, they really should have to clean them up by hand. - -175. And, in the feature request department, I'd dearly love a command-line - interface to adding a new module to the CVSROOT/modules file. - -176. If you use the -i flag in the modules file, you can control access - to source code; this is a Good Thing under certain circumstances. I - just had a nasty thought, and on experiment discovered that the - filter specified by -i is _not_ run before a cvs admin command; as - this allows a user to go behind cvs's back and delete information - (cvs admin -o1.4 file) this seems like a serious problem. - -177. We've got some external vendor source that sits under a source code - hierarchy, and when we do a cvs update, it gets wiped out because - its tag is different from the "main" distribution. I've tried to - use "-I" to ignore the directory, as well as .cvsignore, but this - doesn't work. - -179. "cvs admin" does not log its actions with loginfo, nor does it check - whether the action is allowed with commitinfo. It should. - -180. "cvs edit" should show you who is already editing the files, - probably (that is, do "cvs editors" before executing, or some - similar result). (But watch out for what happens if the network - is down!). - -182. There should be a way to show log entries corresponding to -changes from tag "foo" to tag "bar". "cvs log -rfoo:bar" doesn't cut -it, because it erroneously shows the changes associated with the -change from the revision before foo to foo. I'm not sure that is ever -a useful or logical behavior ("cvs diff -r foo -r bar" gets this -right), but is compatibility an issue? See -http://www.cyclic.com/cvs/unoff-log.txt for an unofficial patch. - -183. "cvs status" should report on Entries.Static flag and CVS/Tag (how? -maybe a "cvs status -d" to give directory status?). There should also -be more documentation of how these get set and how/when to re-set them. - -184. Would be nice to implement the FreeBSD MD5-based password hash -algorithm in pserver. For more info see "6.1. DES, MD5, and Crypt" in -the FreeBSD Handbook, and src/lib/libcrypt/crypt.c in the FreeBSD -sources. Certainly in the context of non-unix servers this algorithm -makes more sense than the traditional unix crypt() algorithm, which -suffers from export control problems. - -185. A frequent complaint is that keyword expansion causes conflicts -when merging from one branch to another. The first step is -documenting CVS's existing features in this area--what happens with -various -k options in various places? The second step is thinking -about whether there should be some new feature and if so how it should -be designed. For example, here is one thought: - - rcs' co command needs a new -k option. The new option should expand - $Log entries without expanding $Revision entries. This would - allow cvs to use rcsmerge in such a way that joining branches into - main lines would neither generate extra collisions on revisions nor - drop log lines. - -The details of this are out of date (CVS no longer invokes "co", and -any changes in this area would be done by bypassing RCS rather than -modifying it), but even as to the general idea, I don't have a clear -idea about whether it would be good (see what I mean about the need -for better documentation? I work on CVS full-time, and even I don't -understand the state of the art on this subject). - -186. There is a frequent discussion of multisite features. - -* There may be some overlap with the client/server CVS, which is good -especially when there is a single developer at each location. But by -"multisite" I mean something in which each site is more autonomous, to -one extent or another. - -* Vendor branches are the closest thing that CVS currently has for -multisite features. They have fixable drawbacks (such as poor -handling of added and removed files), and more fundamental drawbacks -(when you import a vendor branch, you are importing a set of files, -not importing any knowledge of their version history outside the -current repository). - -* One approach would be to require checkins (or other modifications to -the repository) to succeed at a write quorum of sites (51%) before -they are allowed to complete. To work well, the network should be -reliable enough that one can typically get to that many sites. When a -server which has been out of touch reconnects, it would want to update -its data before doing anything else. Any of the servers can service -all requests locally, except perhaps for a check that they are -up-to-date. The way this differs from a run-of-the-mill distributed -database is that if one only allows reversible operations via this -mechanism (exclude "cvs admin -o", "cvs tag -d", &c), then each site -can back up the others, such that failures at one site, including -something like deleting all the sources, can be recovered from. Thus -the sites need not trust each other as much as for many shared -databases, and the system may be resilient to many types of -organizational failures. Sometimes I call this design the -"CVScluster" design. - -* Another approach is a master/slave one. Checkins happen at the -master site, and slave sites need to check whether their local -repository is up to date before relying on its information. - -* Another approach is to have each site own a particular branch. This -one is the most tolerant of flaky networks; if checkins happen at each -site independently there is no particular problem. The big question -is whether merges happen only manually, as with existing CVS branches, -or whether there is a feature whereby there are circumstances in which -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. - -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 -the new regime, the error message would be followed by a one-line -message directing people to the appropriate help option ("cvs -H -" or "cvs --help-commands" or whatever, according to the -situation). I'm not sure whether this change would be controversial -(as defined in HACKING), so there might be a need for further -discussion or other actions other than just coding. - -188. Option parsing and .cvsrc has at least one notable limitation. -If you want to set a global option only for some CVS commands, there -is no way to do it (for example, if one wants to set -q only for -"rdiff"). I am told that the "popt" package from RPM -(http://www.rpm.org) could solve this and other problems (for example, -if the syntax of option stuff in .cvsrc is similar to RPM, that would -be great from a user point of view). It would at least be worth a -look (it also provides a cleaner API than getopt_long). - -Another issue which may or may not be related is the issue of -overriding .cvsrc from the command line. The cleanest solution might -be to have options in mutually exclusive sets (-l/-R being a current -example, but --foo/--no-foo is a better way to name such options). Or -perhaps there is some better solution. - -189. Renaming files and directories is a frequently discussed topic. - -Some of the problems with the status quo: - -a. "cvs annotate" cannot operate on both the old and new files in a -single run. You need to run it twice, once for the new name and once -for the old name. - -b. "cvs diff" (or "cvs diff -N") shows a rename as a removal of the -old file and an addition of the new one. Some people would like to -see the differences between the file contents (but then how would we -indicate the fact that the file has been renamed? Certainly the -notion that "patch(1)" has of renames is as a removal and addition). - -c. "cvs log" should be able to show the changes between two -tags/dates, even in the presence of adds/removes/renames (I'm not sure -what the status quo is on this; see also item #182). - -d. Renaming directories is way too hard. - -Implementations: - -It is perhaps premature to try to design implementation details -without answering some of the above questions about desired behaviors -but several general implementations get mentioned. - -i. No fundamental changes (for example, a "cvs rename" command which -operated on directories could still implement the current recommended -practice for renaming directories, which is to rename each of the -files contained therein via an add and a remove). One thing to note -that the status quo gets right is proper merges, even with adds and -removals (Well, mostly right at least. There are a *LOT* of different -cases; see the testsuite for some of them). - -ii. Rename database. In this scheme the files in the repository -would have some arbitrary name, and then a separate rename database -would indicate the current correspondence between the filename in the -working directory and the actual storage. As far as I know this has -never been designed in detail for CVS. - -iii. A modest change in which the RCS files would contain some -information such as "renamed from X" or "renamed to Y". That is, this -would be generally similar to the log messages which are suggested -when one renames via an add and a removal, but would be -computer-parseable. I don't think anyone has tried to flesh out any -details here either. - -It is interesting to note that in solution ii. version numbers in the -"new file" start where the "old file" left off, while in solutions -i. and iii., version numbers restart from 1.1 each time a file is -renamed. Except perhaps in the case where we rename a file from foo -to bar and then back to foo. I'll shut up now. - -Regardless of the method we choose, we need to address how renames -affect existing CVS behaviors. For example, what happens when you -rename a file on a branch but not the trunk and then try to merge the -two? What happens when you rename a file on one branch and delete it -on another and try to merge the two? - -Ideally, we'd come up with a way to parameterize the problem and -simply write up a lookup table to determine the correct behavior. - -190. The meaning of the -q and -Q global options is very ad hoc; -there is no clear definition of which messages are suppressed by them -and which are not. Here is a classification of the current meanings -of -q; I don't know whether anyone has done a similar investigation of --Q: - - a. The "warm fuzzies" printed upon entering each directory (for - example, "cvs update: Updating sdir"). The need for these messages - may be decreased now that most of CVS uses ->fullname instead of - ->file in messages (a project which is *still* not 100% complete, - alas). However, the issue of whether CVS can offer status as it - runs is an important one. Of course from the command line it is - hard to do this well and one ends up with options like -q. But - think about emacs, jCVS, or other environments which could flash you - the latest status line so you can see whether the system is working - or stuck. - - b. Other cases where the message just offers information (rather - than an error) and might be considered unnecessarily verbose. These - have a certain point to them, although it isn't really clear whether - it should be the same option as the warm fuzzies or whether it is - worth the conceptual hair: - - add.c: scheduling %s `%s' for addition (may be an issue) - modules.c: %s %s: Executing '%s' (I can see how that might be noise, - but...) - remove.c: scheduling `%s' for removal (analogous to the add.c one) - update.c: Checking out %s (hmm, that message is a bit on the noisy side...) - (but the similar message in annotate is not affected by -q). - - c. Suppressing various error messages. This is almost surely - bogus. - - commit.c: failed to remove tag `%s' from `%s' (Questionable. - Rationale might be that we already printed another message - elsewhere but why would it be necessary to avoid - the extra message in such an uncommon case?) - commit.c: failed to commit dead revision for `%s' (likewise) - remove.c: file `%s' still in working directory (see below about rm - -f analogy) - remove.c: nothing known about `%s' (looks dubious to me, especially in - the case where the user specified it explicitly). - remove.c: removed `%s' (seems like an obscure enough case that I fail - to see the appeal of being cryptically concise here). - remove.c: file `%s' already scheduled for removal (now it is starting - to look analogous to the infamous rm -f option). - rtag.c: cannot find tag `%s' in `%s' (more rm -f like behavior) - rtag.c: failed to remove tag `%s' from `%s' (ditto) - tag.c: failed to remove tag %s from %s (see above about whether RCS_* - has already printed an error message). - tag.c: couldn't tag added but un-commited file `%s' (more rm -f - like behavior) - tag.c: skipping removed but un-commited file `%s' (ditto) - tag.c: cannot find revision control file for `%s' (ditto, but at first - glance seems even worse, as this would seem to be a "can't happen" - condition) - -191. Storing RCS files, especially binary files, takes rather more -space than it could, typically. - - The virtue of the status quo is that it is simple to implement. - Of course it is also simplest in terms of dealing with compatibility. - - Just storing the revisions as separate gzipped files is a common - technique. It also is pretty simple (no new algorithms, CVS - already has zlib around). Of course for some files (such as files - which are already compressed) the gzip step won't help, but - something which can at least sometimes avoid rewriting the entire - RCS file for each new revision would, I would think, be a big - speedup for large files. - - Josh MacDonald has written a tool called xdelta which produces - differences (that is, sufficient information to transform the old - to the new) which looks for common sequences of bytes, like RCS - currently does, but which is not based on lines. This seems to do - quite well for some kinds of files (e.g. FrameMaker documents, - text files), and not as well for others (anything which is already - compressed, executables). xdelta 1.10 also is faster than GNU diff. - - Karl Fogel has thought some about using a difference technique - analogous to fractal compression (see the comp.compression FAQ for - more on fractal compression, including at least one patent to - watch for; I don't know how analogous Karl's ideas are to the - techniques described there). - - Quite possibly want some documented interface by which a site can - plug in their choice of external difference programs (with the - ability to choose the program based on filename, magic numbers, - or some such). - -192. "cvs update" using an absolute pathname does not work if the -working directory is not a CVS-controlled directory with the correct -CVSROOT. For example, the following will fail: - - cd /tmp - cvs -d /repos co foo - cd / - cvs update /tmp/foo - -It is possible to read the CVSROOT from the administrative files in -the directory specified by the absolute pathname argument to update. -In that case, the last command above would be equivalent to: - - cd /tmp/foo - cvs update . - -This can be problematic, however, if we ask CVS to update two -directories with different CVSROOTs. Currently, CVS has no way of -changing CVSROOT mid-stream. Consider the following: - - cd /tmp - cvs -d /repos1 co foo - cvs -d /repos2 co bar - cd / - cvs update /tmp/foo /tmp/bar - -To make that example work, we need to think hard about: - - - where and when CVSROOT-related variables get set - - who caches said variables for later use - - how the remote protocol should be extended to handle sending a new - repository mid-stream - - how the client should maintain connections to a variety of servers - in a single invocation. - -Because those issues are hairy, I suspect that having a change in -CVSROOT be an error would be a better move. - -193. The client relies on timestamps to figure out whether a file is -(maybe) modified. If something goes awry, then it ends up sending -entire files to the server to be checked, and this can be quite slow -especially over a slow network. A couple of things that can happen: -(a) other programs, like make, use timestamps, so one ends up needing -to do "touch foo" and otherwise messing with timestamps, (b) changing -the timezone offset (e.g. summer vs. winter or moving a machine) -should work on unix, but there may be problems with non-unix. - -Possible solutions: - - a. Store a checksum for each file in CVS/Entries or some such - place. What to do about hash collisions is interesting: using a - checksum, like MD5, large enough to "never" have collisions - probably works in practice (of course, if there is a collision then - all hell breaks loose because that code path was not tested, but - given the tiny, tiny probability of that I suppose this is only an - aesthetic issue). - - b. I'm not thinking of others, except storing the whole file in - CVS/Base, and I'm sure using twice the disk space would be - unpopular. - -194. CVS does not separate the "metadata" from the actual revision -history; it stores them both in the RCS files. Metadata means tags -and header information such as the number of the head revision. -Storing the metadata separately could speed up "cvs tag" enormously, -which is a big problem for large repositories. It could also probably -make CVS's locking much less in the way (see comment in do_recursion -about "two-pass design"). - -195. Many people using CVS over a slow link are interested in whether -the remote protocol could be any more efficient with network -bandwidth. This item is about one aspect of that--how the server -sends a new version of a file the client has a different version of, -or vice versa. - -a. Cases in which the status quo already sends a diff. For most text -files, this is probably already close to optimal. For binary files, -and anomalous (?) text files (e.g. those in which it would help to do -moves, as well as adds and deletes), it might be worth looking into other -difference algorithms (see item #191). - -b. Cases in which the status quo does not send a diff (e.g. "cvs -commit"). - -b1. With some frequency, people suggest rsync or a similar algorithm -(see ftp://samba.anu.edu.au/pub/rsync/). This could speed things up, -and in some ways involves the most minimal changes to the default CVS -paradigm. There are some downsides though: (1) there is an extra -network turnaround, (2) the algorithm needs to transmit some data to -discover what difference type programs can discover locally (although -this is only about 1% of the size of the files). - -b2. If one is willing to require that users use "cvs edit" before -editing a file on the client side (in some cases, a development -environment like emacs can make this fairly easy), then the Modified -request in the protocol could be extended to allow the client to just -send differences instead of entire files. In the degenerate case -(e.g. "cvs diff" without arguments) the required network traffic is -reduced to zero, and the client need not even contact the server. - -197. Analyze the difference between CVS_UNLINK & unlink_file. As far as I -can tell, unlink_file aborts in noexec mode and CVS_UNLINK does not. I'm not -sure it would be possible to remove even the use of temp files in noexec mode, -but most unlinks should probably be using unlink_file and not CVS_UNLINK. - -198. Remove references to deprecated cvs_temp_name function. - -199. Add test for login & logout functionality, including support for -backwards compatibility with old CVSROOTs. - -200. Make a 'cvs add' without write access a non-fatal error so that -the user's Entries file is updated and future 'cvs diffs' will work -properly. This should ease patch submission. - -201. cvs_temp_file should be creating temporary files in a privately owned -subdirectory of of temp due to security issues on some systems. - -202. Enable rdiff to accept most diff options. Make rdiff output look -like diff's. Make CVS diff garbage go to stderr and only standard diff -output go to stdout. - -203. Add val-tags additions to the tagging code. Don't remove the -update additions since val-tags could still be used as a cache when the -repository was imported from elsewhere (the tags weren't applied with a -version which wrote val-tags). - -204. Add test case for compression. A buf_shutdown error using compression -wasn't caught by the test suite. - -205. There are lots of cases where trailing slashes on directory names -and other non-canonical paths confuse CVS. Most of the cases that do -work are handled on an ad-hoc basis. We need to come up with a coherent -strategy to address path canonicalization and apply it consistently. - -208. Merge enhancements to the diff package back into the original GNU source. - -209. Go through this file and try to: - - a. Verify that items are still valid. - - b. Create test cases for valid items when they don't exist. - - c. Remove fixed and no longer applicable items. - -210. Explain to sanity.sh how to deal with paths with spaces and other odd -characters in them. - -211. Make sanity.sh run under the Win32 bash (cygwin) and maybe other Windex -environments (e.g. DGSS or whatever the MSVC portability environemnt is called). - -212. Autotestify (see autoconf source) sanity.sh. - -213. Examine desirability of updating the regex library (regex.{c,h}) to the -more recent versions that come with glibc and emacs. It might be worth waiting -for the emacs folks to get their act together and merge their changes into the -glibc version. - -214. Make options.h options configure script options instead. - -215. Add reditors and rwatchers commands. - - - Is an r* command abstraction layer possible here for the commands - where this makes sense? Would it be simpler? It seems to me the - major operational differences lie in the file list construction. - -218. Fix "checkout -d ." in client/server mode. - -221. Handle spaces in file/directory names. (Most, if not all, of the -internal infrastructure already handles them correctly, but most of the -administrative file interfaces do not.) - -223. Internationalization support. This probably means using some kind -of universal character set (ISO 10646?) internally and converting on -input and output, which opens the locale can of worms. - -224. Better timezone handling. Many people would like to see times -output in local time rather than UTC, but that's tricky since the -conversion from internal form is currently done by the server who has no -idea what the user's timezone even is, let alone the rules for -converting to it. - - - On the contrary, I think the MT server response should be easily adaptable -for this purpose. It is defined in cvsclient.texi as processed by the client -if it knows how and printed to stdout otherwise. A "time" tag or the like -could be the usual CVS server UTC time string. An old client could just print -the time in UTC and a new client would know that it could convert the time to a -local time string according to the localization settings before printing it. - -225. Add support for --allow-root to server command. - -227. 'cvs release' should use the CVS/Root in the directory being released -when such is specified rather than $CVSROOT. In my work directory with no CVS -dir, a release of subdirectories causes the released projects to be tested -against my $CVSROOT environment variable, which often isn't correct but which -can complete without generating error messages if the project also exists in -the other CVSROOT. This happens a lot with my copies of the ccvs project. - -228. Consider adding -d to commit ala ci. - -229. Improve the locking code to use a random delay with exponential -backoff ala Ethernet and separate the notification interval from the -wait interval. - -230. Support for options like compression as part of the CVSROOT might be -nice. This should be fairly easy to implement now using the method options. - -234. Noop commands should be logged in the history file. Information can -still be obtained with noop commands, for instance via `cvs -n up -p', and -paranoid admins might appreciate this. Similarly, perhaps diff operations -should be logged. diff --git a/contrib/cvs/acinclude.m4 b/contrib/cvs/acinclude.m4 deleted file mode 100644 index c2893df..0000000 --- a/contrib/cvs/acinclude.m4 +++ /dev/null @@ -1,361 +0,0 @@ -/* This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. */ - -AC_DEFUN([ACX_WITH_GSSAPI],[ -# -# Use --with-gssapi[=DIR] to enable GSSAPI support. -# -# defaults to enabled with DIR in default list below -# -# Search for /SUNHEA/ and read the comments about this default below. -# -AC_ARG_WITH( - [gssapi], - AC_HELP_STRING( - [--with-gssapi], - [GSSAPI directory (default autoselects)]), , - [with_gssapi=yes])dnl - -dnl -dnl FIXME - cache withval and obliterate later cache values when options change -dnl -# -# Try to locate a GSSAPI installation if no location was specified, assuming -# GSSAPI was enabled (the default). -# -if test -n "$acx_gssapi_cv_gssapi"; then - # Granted, this is a slightly ugly way to print this info, but the - # AC_CHECK_HEADER used in the search for a GSSAPI installation makes using - # AC_CACHE_CHECK worse - AC_MSG_CHECKING([for GSSAPI]) -else :; fi -AC_CACHE_VAL([acx_gssapi_cv_gssapi], [ -if test x$with_gssapi = xyes; then - # --with but no location specified - # assume a gssapi.h or gssapi/gssapi.h locates our install. - # - # This isn't always strictly true. For instance Solaris 7's SUNHEA (header) - # package installs gssapi.h whether or not the necessary libraries are - # installed. I'm still not sure whether to consider this a bug. The long - # way around is to not consider GSSPAI installed unless gss_import_name is - # found, but that brings up a lot of other hassles, like continuing to let - # gcc & ld generate the error messages when the user uses --with-gssapi=dir - # as a debugging aid. The short way around is to disable GSSAPI by default, - # but I think Sun users have been faced with this for awhile and I haven't - # heard many complaints. - acx_gssapi_save_CPPFLAGS=$CPPFLAGS - for acx_gssapi_cv_gssapi in yes /usr/kerberos /usr/cygnus/kerbnet no; do - if test x$acx_gssapi_cv_gssapi = xno; then - break - fi - if test x$acx_gssapi_cv_gssapi = xyes; then - AC_MSG_CHECKING([for GSSAPI]) - AC_MSG_RESULT([]) - else - CPPFLAGS="$acx_gssapi_save_CPPFLAGS -I$acx_gssapi_cv_gssapi/include" - AC_MSG_CHECKING([for GSSAPI in $acx_gssapi_cv_gssapi]) - AC_MSG_RESULT([]) - fi - unset ac_cv_header_gssapi_h - unset ac_cv_header_gssapi_gssapi_h - unset ac_cv_header_krb5_h - AC_CHECK_HEADERS([gssapi.h gssapi/gssapi.h krb5.h]) - if (test "$ac_cv_header_gssapi_h" = yes || - test "$ac_cv_header_gssapi_gssapi_h" = yes) && - test "$ac_cv_header_krb5_h" = yes; then - break - fi - done - CPPFLAGS=$acx_gssapi_save_CPPFLAGS -else - acx_gssapi_cv_gssapi=$with_gssapi -fi -AC_MSG_CHECKING([for GSSAPI]) -])dnl -AC_MSG_RESULT([$acx_gssapi_cv_gssapi]) - -# -# Set up GSSAPI includes for later use. We don't bother to check for -# $acx_gssapi_cv_gssapi=no here since that will be caught later. -# -if test x$acx_gssapi_cv_gssapi = xyes; then - # no special includes necessary - GSSAPI_INCLUDES="" -else - # GSSAPI at $acx_gssapi_cv_gssapi (could be 'no') - GSSAPI_INCLUDES=" -I$acx_gssapi_cv_gssapi/include" -fi - -# -# Get the rest of the information CVS needs to compile with GSSAPI support -# -if test x$acx_gssapi_cv_gssapi != xno; then - # define HAVE_GSSAPI and set up the includes - AC_DEFINE([HAVE_GSSAPI], , -[Define if you have GSSAPI with Kerberos version 5 available.]) - includeopt=$includeopt$GSSAPI_INCLUDES - - # locate any other headers - acx_gssapi_save_CPPFLAGS=$CPPFLAGS - CPPFLAGS=$CPPFLAGS$GSSAPI_INCLUDES - dnl We don't use HAVE_KRB5_H anywhere, but including it here might make it - dnl easier to spot errors by reading configure output - AC_CHECK_HEADERS([gssapi.h gssapi/gssapi.h gssapi/gssapi_generic.h krb5.h]) - # And look through them for GSS_C_NT_HOSTBASED_SERVICE or its alternatives - AC_CACHE_CHECK( - [for GSS_C_NT_HOSTBASED_SERVICE], - [acx_gssapi_cv_gss_c_nt_hostbased_service], - [ - acx_gssapi_cv_gss_c_nt_hostbased_service=no - if test "$ac_cv_header_gssapi_h" = "yes"; then - AC_EGREP_HEADER( - [GSS_C_NT_HOSTBASED_SERVICE], [gssapi.h], - [acx_gssapi_cv_gss_c_nt_hostbased_service=yes], - [ - AC_EGREP_HEADER( - [gss_nt_service_name], [gssapi.h], - [acx_gssapi_cv_gss_c_nt_hostbased_service=gss_nt_service_name]) - ]) - fi - if test $acx_gssapi_cv_gss_c_nt_hostbased_service = no && - test "$ac_cv_header_gssapi_gssapi_h" = "yes"; then - AC_EGREP_HEADER( - [GSS_C_NT_HOSTBASED_SERVICE], [gssapi/gssapi.h], - [acx_gssapi_cv_gss_c_nt_hostbased_service=yes], - [ - AC_EGREP_HEADER([gss_nt_service_name], [gssapi/gssapi.h], - [acx_gssapi_cv_gss_c_nt_hostbased_service=gss_nt_service_name]) - ]) - else :; fi - if test $acx_gssapi_cv_gss_c_nt_hostbased_service = no && - test "$ac_cv_header_gssapi_gssapi_generic_h" = "yes"; then - AC_EGREP_HEADER( - [GSS_C_NT_HOSTBASED_SERVICE], [gssapi/gssapi_generic.h], - [acx_gssapi_cv_gss_c_nt_hostbased_service=yes], - [ - AC_EGREP_HEADER( - [gss_nt_service_name], [gssapi/gssapi_generic.h], - [acx_gssapi_cv_gss_c_nt_hostbased_service=gss_nt_service_name]) - ]) - else :; fi - ]) - if test $acx_gssapi_cv_gss_c_nt_hostbased_service != yes && - test $acx_gssapi_cv_gss_c_nt_hostbased_service != no; then - # don't define for yes since that means it already means something and - # don't define for no since we'd rather the compiler catch the error - # It's debatable whether we'd prefer that the compiler catch the error - # - it seems our estranged developer is more likely to be familiar with - # the intricacies of the compiler than with those of autoconf, but by - # the same token, maybe we'd rather alert them to the fact that most - # of the support they need to fix the problem is installed if they can - # simply locate the appropriate symbol. - AC_DEFINE_UNQUOTED( - [GSS_C_NT_HOSTBASED_SERVICE], - [$acx_gssapi_cv_gss_c_nt_hostbased_service], -[Define to an alternative value if GSS_C_NT_HOSTBASED_SERVICE isn't defined -in the gssapi.h header file. MIT Kerberos 1.2.1 requires this. Only relevant -when using GSSAPI.]) - else :; fi - - CPPFLAGS=$acx_gssapi_save_CPPFLAGS - - # Expect the libs to be installed parallel to the headers - # - # We could try once with and once without, but I'm not sure it's worth the - # trouble. - if test x$acx_gssapi_cv_gssapi != xyes; then - if test -z "$LIBS"; then - LIBS="-L$acx_gssapi_cv_gssapi/lib" - else - LIBS="-L$acx_gssapi_cv_gssapi/lib $LIBS" - fi - else :; fi - - dnl What happens if we want to enable, say, krb5 and some other GSSAPI - dnl authentication method at the same time? - # - # Some of the order below is particular due to library dependencies - # - - # - # des Heimdal K 0.3d, but Heimdal seems to be set up such - # that it could have been installed from elsewhere. - # - AC_SEARCH_LIBS([des_set_odd_parity], [des]) - - # - # com_err Heimdal K 0.3d - # - # com_err MIT K5 v1.2.2-beta1 - # - AC_SEARCH_LIBS([com_err], [com_err]) - - # - # asn1 Heimdal K 0.3d -lcom_err - # - AC_SEARCH_LIBS([initialize_asn1_error_table_r], [asn1]) - - # - # resolv required, but not installed by Heimdal K 0.3d - # - # resolv MIT K5 1.2.2-beta1 - # Linux 2.2.17 - # - AC_SEARCH_LIBS([__dn_expand], [resolv]) - - # - # crypto Need by gssapi under FreeBSD 5.4 - # - AC_SEARCH_LIBS([RC4], [crypto]) - - # - # crypt Needed by roken under FreeBSD 4.6. - # - AC_SEARCH_LIBS([crypt], [crypt]) - - # - # roken Heimdal K 0.3d -lresolv - # roken FreeBSD 4.6 -lcrypt - # - AC_SEARCH_LIBS([roken_gethostbyaddr], [roken]) - - # - # k5crypto MIT K5 v1.2.2-beta1 - # - AC_SEARCH_LIBS([valid_enctype], [k5crypto]) - - # - # gen ? ? ? Needed on Irix 5.3 with some - # Irix 5.3 version of Kerberos. I'm not - # sure which since Irix didn't - # get any testing this time - # around. Original comment: - # - # This is necessary on Irix 5.3, in order to link against libkrb5 -- - # there, an_to_ln.o refers to things defined only in -lgen. - # - AC_SEARCH_LIBS([compile], [gen]) - - # - # krb5 ? ? ? -lgen -l??? - # Irix 5.3 - # - # krb5 MIT K5 v1.1.1 - # - # krb5 MIT K5 v1.2.2-beta1 -lcrypto -lcom_err - # Linux 2.2.17 - # - # krb5 MIT K5 v1.2.2-beta1 -lcrypto -lcom_err -lresolv - # - # krb5 Heimdal K 0.3d -lasn1 -lroken -ldes - # - AC_SEARCH_LIBS([krb5_free_context], [krb5]) - - # - # gss This may be the only lib needed under HP-UX, so find it - # first. - # - # gssapi_krb5 Only lib needed with MIT K5 v1.2.1, so find it first in - # order to prefer MIT Kerberos. If both MIT & Heimdal - # Kerberos are installed and in the path, this will leave - # some of the libraries above in LIBS unnecessarily, but - # noone would ever do that, right? - # - # gss HP-UX ??? - # - # gssapi_krb5 MIT K5 v1.2.2-beta1 -lkrb5 - # - # gssapi Heimdal K 0.3d -lkrb5 - # - AC_SEARCH_LIBS([gss_import_name], [gss gssapi_krb5 gssapi]) -fi -])dnl - - - -# size_max.m4 serial 2 -dnl Copyright (C) 2003 Free Software Foundation, Inc. -dnl This file is free software, distributed under the terms of the GNU -dnl General Public License. As a special exception to the GNU General -dnl Public License, this file may be distributed as part of a program -dnl that contains a configuration script generated by Autoconf, under -dnl the same distribution terms as the rest of that program. - -dnl From Bruno Haible. - -AC_DEFUN([gl_SIZE_MAX], -[ - AC_CHECK_HEADERS(stdint.h) - dnl First test whether the system already has SIZE_MAX. - AC_MSG_CHECKING([for SIZE_MAX]) - result= - AC_EGREP_CPP([Found it], [ -#include -#if HAVE_STDINT_H -#include -#endif -#ifdef SIZE_MAX -Found it -#endif -], result=yes) - if test -z "$result"; then - dnl Define it ourselves. Here we assume that the type 'size_t' is not wider - dnl than the type 'unsigned long'. - dnl The _AC_COMPUTE_INT macro works up to LONG_MAX, since it uses 'expr', - dnl which is guaranteed to work from LONG_MIN to LONG_MAX. - _AC_COMPUTE_INT([~(size_t)0 / 10], res_hi, - [#include ], result=?) - _AC_COMPUTE_INT([~(size_t)0 % 10], res_lo, - [#include ], result=?) - _AC_COMPUTE_INT([sizeof (size_t) <= sizeof (unsigned int)], fits_in_uint, - [#include ], result=?) - if test "$fits_in_uint" = 1; then - dnl Even though SIZE_MAX fits in an unsigned int, it must be of type - dnl 'unsigned long' if the type 'size_t' is the same as 'unsigned long'. - AC_TRY_COMPILE([#include - extern size_t foo; - extern unsigned long foo; - ], [], fits_in_uint=0) - fi - if test -z "$result"; then - if test "$fits_in_uint" = 1; then - result="$res_hi$res_lo"U - else - result="$res_hi$res_lo"UL - fi - else - dnl Shouldn't happen, but who knows... - result='~(size_t)0' - fi - fi - AC_MSG_RESULT([$result]) - if test "$result" != yes; then - AC_DEFINE_UNQUOTED([SIZE_MAX], [$result], - [Define as the maximum value of type 'size_t', if the system doesn't define it.]) - fi -]) - - - -# xsize.m4 serial 3 -dnl Copyright (C) 2003-2004 Free Software Foundation, Inc. -dnl This file is free software, distributed under the terms of the GNU -dnl General Public License. As a special exception to the GNU General -dnl Public License, this file may be distributed as part of a program -dnl that contains a configuration script generated by Autoconf, under -dnl the same distribution terms as the rest of that program. - -AC_DEFUN([gl_XSIZE], -[ - dnl Prerequisites of lib/xsize.h. - AC_REQUIRE([gl_SIZE_MAX]) - AC_REQUIRE([AC_C_INLINE]) - AC_CHECK_HEADERS(stdint.h) -]) diff --git a/contrib/cvs/aclocal.m4 b/contrib/cvs/aclocal.m4 deleted file mode 100644 index a2c35e1..0000000 --- a/contrib/cvs/aclocal.m4 +++ /dev/null @@ -1,938 +0,0 @@ -# generated automatically by aclocal 1.10 -*- Autoconf -*- - -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, -# 2005, 2006 Free Software Foundation, Inc. -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -m4_if(m4_PACKAGE_VERSION, [2.61],, -[m4_fatal([this file was generated for autoconf 2.61. -You have another version of autoconf. If you want to use that, -you should regenerate the build system entirely.], [63])]) - -# Copyright (C) 2002, 2003, 2005, 2006 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_AUTOMAKE_VERSION(VERSION) -# ---------------------------- -# Automake X.Y traces this macro to ensure aclocal.m4 has been -# generated from the m4 files accompanying Automake X.Y. -# (This private macro should not be called outside this file.) -AC_DEFUN([AM_AUTOMAKE_VERSION], -[am__api_version='1.10' -dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to -dnl require some minimum version. Point them to the right macro. -m4_if([$1], [1.10], [], - [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl -]) - -# _AM_AUTOCONF_VERSION(VERSION) -# ----------------------------- -# aclocal traces this macro to find the Autoconf version. -# This is a private macro too. Using m4_define simplifies -# the logic in aclocal, which can simply ignore this definition. -m4_define([_AM_AUTOCONF_VERSION], []) - -# AM_SET_CURRENT_AUTOMAKE_VERSION -# ------------------------------- -# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. -# This function is AC_REQUIREd by AC_INIT_AUTOMAKE. -AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], -[AM_AUTOMAKE_VERSION([1.10])dnl -_AM_AUTOCONF_VERSION(m4_PACKAGE_VERSION)]) - -# AM_AUX_DIR_EXPAND -*- Autoconf -*- - -# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets -# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to -# `$srcdir', `$srcdir/..', or `$srcdir/../..'. -# -# Of course, Automake must honor this variable whenever it calls a -# tool from the auxiliary directory. The problem is that $srcdir (and -# therefore $ac_aux_dir as well) can be either absolute or relative, -# depending on how configure is run. This is pretty annoying, since -# it makes $ac_aux_dir quite unusable in subdirectories: in the top -# source directory, any form will work fine, but in subdirectories a -# relative path needs to be adjusted first. -# -# $ac_aux_dir/missing -# fails when called from a subdirectory if $ac_aux_dir is relative -# $top_srcdir/$ac_aux_dir/missing -# fails if $ac_aux_dir is absolute, -# fails when called from a subdirectory in a VPATH build with -# a relative $ac_aux_dir -# -# The reason of the latter failure is that $top_srcdir and $ac_aux_dir -# are both prefixed by $srcdir. In an in-source build this is usually -# harmless because $srcdir is `.', but things will broke when you -# start a VPATH build or use an absolute $srcdir. -# -# So we could use something similar to $top_srcdir/$ac_aux_dir/missing, -# iff we strip the leading $srcdir from $ac_aux_dir. That would be: -# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` -# and then we would define $MISSING as -# MISSING="\${SHELL} $am_aux_dir/missing" -# This will work as long as MISSING is not called from configure, because -# unfortunately $(top_srcdir) has no meaning in configure. -# However there are other variables, like CC, which are often used in -# configure, and could therefore not use this "fixed" $ac_aux_dir. -# -# Another solution, used here, is to always expand $ac_aux_dir to an -# absolute PATH. The drawback is that using absolute paths prevent a -# configured tree to be moved without reconfiguration. - -AC_DEFUN([AM_AUX_DIR_EXPAND], -[dnl Rely on autoconf to set up CDPATH properly. -AC_PREREQ([2.50])dnl -# expand $ac_aux_dir to an absolute path -am_aux_dir=`cd $ac_aux_dir && pwd` -]) - -# AM_CONDITIONAL -*- Autoconf -*- - -# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006 -# Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# serial 8 - -# AM_CONDITIONAL(NAME, SHELL-CONDITION) -# ------------------------------------- -# Define a conditional. -AC_DEFUN([AM_CONDITIONAL], -[AC_PREREQ(2.52)dnl - ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], - [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl -AC_SUBST([$1_TRUE])dnl -AC_SUBST([$1_FALSE])dnl -_AM_SUBST_NOTMAKE([$1_TRUE])dnl -_AM_SUBST_NOTMAKE([$1_FALSE])dnl -if $2; then - $1_TRUE= - $1_FALSE='#' -else - $1_TRUE='#' - $1_FALSE= -fi -AC_CONFIG_COMMANDS_PRE( -[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then - AC_MSG_ERROR([[conditional "$1" was never defined. -Usually this means the macro was only invoked conditionally.]]) -fi])]) - -# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 -# Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# serial 9 - -# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be -# written in clear, in which case automake, when reading aclocal.m4, -# will think it sees a *use*, and therefore will trigger all it's -# C support machinery. Also note that it means that autoscan, seeing -# CC etc. in the Makefile, will ask for an AC_PROG_CC use... - - -# _AM_DEPENDENCIES(NAME) -# ---------------------- -# See how the compiler implements dependency checking. -# NAME is "CC", "CXX", "GCJ", or "OBJC". -# We try a few techniques and use that to set a single cache variable. -# -# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was -# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular -# dependency, and given that the user is not expected to run this macro, -# just rely on AC_PROG_CC. -AC_DEFUN([_AM_DEPENDENCIES], -[AC_REQUIRE([AM_SET_DEPDIR])dnl -AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl -AC_REQUIRE([AM_MAKE_INCLUDE])dnl -AC_REQUIRE([AM_DEP_TRACK])dnl - -ifelse([$1], CC, [depcc="$CC" am_compiler_list=], - [$1], CXX, [depcc="$CXX" am_compiler_list=], - [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'], - [$1], UPC, [depcc="$UPC" am_compiler_list=], - [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'], - [depcc="$$1" am_compiler_list=]) - -AC_CACHE_CHECK([dependency style of $depcc], - [am_cv_$1_dependencies_compiler_type], -[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then - # We make a subdir and do the tests there. Otherwise we can end up - # making bogus files that we don't know about and never remove. For - # instance it was reported that on HP-UX the gcc test will end up - # making a dummy file named `D' -- because `-MD' means `put the output - # in D'. - mkdir conftest.dir - # Copy depcomp to subdir because otherwise we won't find it if we're - # using a relative directory. - cp "$am_depcomp" conftest.dir - cd conftest.dir - # We will build objects and dependencies in a subdirectory because - # it helps to detect inapplicable dependency modes. For instance - # both Tru64's cc and ICC support -MD to output dependencies as a - # side effect of compilation, but ICC will put the dependencies in - # the current directory while Tru64 will put them in the object - # directory. - mkdir sub - - am_cv_$1_dependencies_compiler_type=none - if test "$am_compiler_list" = ""; then - am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` - fi - for depmode in $am_compiler_list; do - # Setup a source with many dependencies, because some compilers - # like to wrap large dependency lists on column 80 (with \), and - # we should not choose a depcomp mode which is confused by this. - # - # We need to recreate these files for each test, as the compiler may - # overwrite some of them when testing with obscure command lines. - # This happens at least with the AIX C compiler. - : > sub/conftest.c - for i in 1 2 3 4 5 6; do - echo '#include "conftst'$i'.h"' >> sub/conftest.c - # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with - # Solaris 8's {/usr,}/bin/sh. - touch sub/conftst$i.h - done - echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf - - case $depmode in - nosideeffect) - # after this tag, mechanisms are not by side-effect, so they'll - # only be used when explicitly requested - if test "x$enable_dependency_tracking" = xyes; then - continue - else - break - fi - ;; - none) break ;; - esac - # We check with `-c' and `-o' for the sake of the "dashmstdout" - # mode. It turns out that the SunPro C++ compiler does not properly - # handle `-M -o', and we need to detect this. - if depmode=$depmode \ - source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ - depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ - $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ - >/dev/null 2>conftest.err && - grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && - grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && - grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 && - ${MAKE-make} -s -f confmf > /dev/null 2>&1; then - # icc doesn't choke on unknown options, it will just issue warnings - # or remarks (even with -Werror). So we grep stderr for any message - # that says an option was ignored or not supported. - # When given -MP, icc 7.0 and 7.1 complain thusly: - # icc: Command line warning: ignoring option '-M'; no argument required - # The diagnosis changed in icc 8.0: - # icc: Command line remark: option '-MP' not supported - if (grep 'ignoring option' conftest.err || - grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else - am_cv_$1_dependencies_compiler_type=$depmode - break - fi - fi - done - - cd .. - rm -rf conftest.dir -else - am_cv_$1_dependencies_compiler_type=none -fi -]) -AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) -AM_CONDITIONAL([am__fastdep$1], [ - test "x$enable_dependency_tracking" != xno \ - && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) -]) - - -# AM_SET_DEPDIR -# ------------- -# Choose a directory name for dependency files. -# This macro is AC_REQUIREd in _AM_DEPENDENCIES -AC_DEFUN([AM_SET_DEPDIR], -[AC_REQUIRE([AM_SET_LEADING_DOT])dnl -AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl -]) - - -# AM_DEP_TRACK -# ------------ -AC_DEFUN([AM_DEP_TRACK], -[AC_ARG_ENABLE(dependency-tracking, -[ --disable-dependency-tracking speeds up one-time build - --enable-dependency-tracking do not reject slow dependency extractors]) -if test "x$enable_dependency_tracking" != xno; then - am_depcomp="$ac_aux_dir/depcomp" - AMDEPBACKSLASH='\' -fi -AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) -AC_SUBST([AMDEPBACKSLASH])dnl -_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl -]) - -# Generate code to set up dependency tracking. -*- Autoconf -*- - -# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 -# Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -#serial 3 - -# _AM_OUTPUT_DEPENDENCY_COMMANDS -# ------------------------------ -AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], -[for mf in $CONFIG_FILES; do - # Strip MF so we end up with the name of the file. - mf=`echo "$mf" | sed -e 's/:.*$//'` - # Check whether this is an Automake generated Makefile or not. - # We used to match only the files named `Makefile.in', but - # some people rename them; so instead we look at the file content. - # Grep'ing the first line is not enough: some people post-process - # each Makefile.in and add a new line on top of each file to say so. - # Grep'ing the whole file is not good either: AIX grep has a line - # limit of 2048, but all sed's we know have understand at least 4000. - if sed 10q "$mf" | grep '^#.*generated by automake' > /dev/null 2>&1; then - dirpart=`AS_DIRNAME("$mf")` - else - continue - fi - # Extract the definition of DEPDIR, am__include, and am__quote - # from the Makefile without running `make'. - DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` - test -z "$DEPDIR" && continue - am__include=`sed -n 's/^am__include = //p' < "$mf"` - test -z "am__include" && continue - am__quote=`sed -n 's/^am__quote = //p' < "$mf"` - # When using ansi2knr, U may be empty or an underscore; expand it - U=`sed -n 's/^U = //p' < "$mf"` - # Find all dependency output files, they are included files with - # $(DEPDIR) in their names. We invoke sed twice because it is the - # simplest approach to changing $(DEPDIR) to its actual value in the - # expansion. - for file in `sed -n " - s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ - sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do - # Make sure the directory exists. - test -f "$dirpart/$file" && continue - fdir=`AS_DIRNAME(["$file"])` - AS_MKDIR_P([$dirpart/$fdir]) - # echo "creating $dirpart/$file" - echo '# dummy' > "$dirpart/$file" - done -done -])# _AM_OUTPUT_DEPENDENCY_COMMANDS - - -# AM_OUTPUT_DEPENDENCY_COMMANDS -# ----------------------------- -# This macro should only be invoked once -- use via AC_REQUIRE. -# -# This code is only required when automatic dependency tracking -# is enabled. FIXME. This creates each `.P' file that we will -# need in order to bootstrap the dependency handling code. -AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], -[AC_CONFIG_COMMANDS([depfiles], - [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], - [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) -]) - -# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005 -# Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# serial 8 - -# AM_CONFIG_HEADER is obsolete. It has been replaced by AC_CONFIG_HEADERS. -AU_DEFUN([AM_CONFIG_HEADER], [AC_CONFIG_HEADERS($@)]) - -# Do all the work for Automake. -*- Autoconf -*- - -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, -# 2005, 2006 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# serial 12 - -# This macro actually does too much. Some checks are only needed if -# your package does certain things. But this isn't really a big deal. - -# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) -# AM_INIT_AUTOMAKE([OPTIONS]) -# ----------------------------------------------- -# The call with PACKAGE and VERSION arguments is the old style -# call (pre autoconf-2.50), which is being phased out. PACKAGE -# and VERSION should now be passed to AC_INIT and removed from -# the call to AM_INIT_AUTOMAKE. -# We support both call styles for the transition. After -# the next Automake release, Autoconf can make the AC_INIT -# arguments mandatory, and then we can depend on a new Autoconf -# release and drop the old call support. -AC_DEFUN([AM_INIT_AUTOMAKE], -[AC_PREREQ([2.60])dnl -dnl Autoconf wants to disallow AM_ names. We explicitly allow -dnl the ones we care about. -m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl -AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl -AC_REQUIRE([AC_PROG_INSTALL])dnl -if test "`cd $srcdir && pwd`" != "`pwd`"; then - # Use -I$(srcdir) only when $(srcdir) != ., so that make's output - # is not polluted with repeated "-I." - AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl - # test to see if srcdir already configured - if test -f $srcdir/config.status; then - AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) - fi -fi - -# test whether we have cygpath -if test -z "$CYGPATH_W"; then - if (cygpath --version) >/dev/null 2>/dev/null; then - CYGPATH_W='cygpath -w' - else - CYGPATH_W=echo - fi -fi -AC_SUBST([CYGPATH_W]) - -# Define the identity of the package. -dnl Distinguish between old-style and new-style calls. -m4_ifval([$2], -[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl - AC_SUBST([PACKAGE], [$1])dnl - AC_SUBST([VERSION], [$2])], -[_AM_SET_OPTIONS([$1])dnl -dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. -m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,, - [m4_fatal([AC_INIT should be called with package and version arguments])])dnl - AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl - AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl - -_AM_IF_OPTION([no-define],, -[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) - AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl - -# Some tools Automake needs. -AC_REQUIRE([AM_SANITY_CHECK])dnl -AC_REQUIRE([AC_ARG_PROGRAM])dnl -AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}) -AM_MISSING_PROG(AUTOCONF, autoconf) -AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}) -AM_MISSING_PROG(AUTOHEADER, autoheader) -AM_MISSING_PROG(MAKEINFO, makeinfo) -AM_PROG_INSTALL_SH -AM_PROG_INSTALL_STRIP -AC_REQUIRE([AM_PROG_MKDIR_P])dnl -# We need awk for the "check" target. The system "awk" is bad on -# some platforms. -AC_REQUIRE([AC_PROG_AWK])dnl -AC_REQUIRE([AC_PROG_MAKE_SET])dnl -AC_REQUIRE([AM_SET_LEADING_DOT])dnl -_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], - [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], - [_AM_PROG_TAR([v7])])]) -_AM_IF_OPTION([no-dependencies],, -[AC_PROVIDE_IFELSE([AC_PROG_CC], - [_AM_DEPENDENCIES(CC)], - [define([AC_PROG_CC], - defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl -AC_PROVIDE_IFELSE([AC_PROG_CXX], - [_AM_DEPENDENCIES(CXX)], - [define([AC_PROG_CXX], - defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl -AC_PROVIDE_IFELSE([AC_PROG_OBJC], - [_AM_DEPENDENCIES(OBJC)], - [define([AC_PROG_OBJC], - defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl -]) -]) - - -# When config.status generates a header, we must update the stamp-h file. -# This file resides in the same directory as the config header -# that is generated. The stamp files are numbered to have different names. - -# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the -# loop where config.status creates the headers, so we can generate -# our stamp files there. -AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], -[# Compute $1's index in $config_headers. -_am_stamp_count=1 -for _am_header in $config_headers :; do - case $_am_header in - $1 | $1:* ) - break ;; - * ) - _am_stamp_count=`expr $_am_stamp_count + 1` ;; - esac -done -echo "timestamp for $1" >`AS_DIRNAME([$1])`/stamp-h[]$_am_stamp_count]) - -# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_PROG_INSTALL_SH -# ------------------ -# Define $install_sh. -AC_DEFUN([AM_PROG_INSTALL_SH], -[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl -install_sh=${install_sh-"\$(SHELL) $am_aux_dir/install-sh"} -AC_SUBST(install_sh)]) - -# Copyright (C) 2003, 2005 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# serial 2 - -# Check whether the underlying file-system supports filenames -# with a leading dot. For instance MS-DOS doesn't. -AC_DEFUN([AM_SET_LEADING_DOT], -[rm -rf .tst 2>/dev/null -mkdir .tst 2>/dev/null -if test -d .tst; then - am__leading_dot=. -else - am__leading_dot=_ -fi -rmdir .tst 2>/dev/null -AC_SUBST([am__leading_dot])]) - -# Add --enable-maintainer-mode option to configure. -*- Autoconf -*- -# From Jim Meyering - -# Copyright (C) 1996, 1998, 2000, 2001, 2002, 2003, 2004, 2005 -# Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# serial 4 - -AC_DEFUN([AM_MAINTAINER_MODE], -[AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles]) - dnl maintainer-mode is disabled by default - AC_ARG_ENABLE(maintainer-mode, -[ --enable-maintainer-mode enable make rules and dependencies not useful - (and sometimes confusing) to the casual installer], - USE_MAINTAINER_MODE=$enableval, - USE_MAINTAINER_MODE=no) - AC_MSG_RESULT([$USE_MAINTAINER_MODE]) - AM_CONDITIONAL(MAINTAINER_MODE, [test $USE_MAINTAINER_MODE = yes]) - MAINT=$MAINTAINER_MODE_TRUE - AC_SUBST(MAINT)dnl -] -) - -AU_DEFUN([jm_MAINTAINER_MODE], [AM_MAINTAINER_MODE]) - -# Check to see how 'make' treats includes. -*- Autoconf -*- - -# Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# serial 3 - -# AM_MAKE_INCLUDE() -# ----------------- -# Check to see how make treats includes. -AC_DEFUN([AM_MAKE_INCLUDE], -[am_make=${MAKE-make} -cat > confinc << 'END' -am__doit: - @echo done -.PHONY: am__doit -END -# If we don't find an include directive, just comment out the code. -AC_MSG_CHECKING([for style of include used by $am_make]) -am__include="#" -am__quote= -_am_result=none -# First try GNU make style include. -echo "include confinc" > confmf -# We grep out `Entering directory' and `Leaving directory' -# messages which can occur if `w' ends up in MAKEFLAGS. -# In particular we don't look at `^make:' because GNU make might -# be invoked under some other name (usually "gmake"), in which -# case it prints its new name instead of `make'. -if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then - am__include=include - am__quote= - _am_result=GNU -fi -# Now try BSD make style include. -if test "$am__include" = "#"; then - echo '.include "confinc"' > confmf - if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then - am__include=.include - am__quote="\"" - _am_result=BSD - fi -fi -AC_SUBST([am__include]) -AC_SUBST([am__quote]) -AC_MSG_RESULT([$_am_result]) -rm -f confinc confmf -]) - -# Copyright (C) 1999, 2000, 2001, 2003, 2004, 2005 -# Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# serial 5 - -# AM_PROG_CC_C_O -# -------------- -# Like AC_PROG_CC_C_O, but changed for automake. -AC_DEFUN([AM_PROG_CC_C_O], -[AC_REQUIRE([AC_PROG_CC_C_O])dnl -AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl -AC_REQUIRE_AUX_FILE([compile])dnl -# FIXME: we rely on the cache variable name because -# there is no other way. -set dummy $CC -ac_cc=`echo $[2] | sed ['s/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/']` -if eval "test \"`echo '$ac_cv_prog_cc_'${ac_cc}_c_o`\" != yes"; then - # Losing compiler, so override with the script. - # FIXME: It is wrong to rewrite CC. - # But if we don't then we get into trouble of one sort or another. - # A longer-term fix would be to have automake use am__CC in this case, - # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" - CC="$am_aux_dir/compile $CC" -fi -dnl Make sure AC_PROG_CC is never called again, or it will override our -dnl setting of CC. -m4_define([AC_PROG_CC], - [m4_fatal([AC_PROG_CC cannot be called after AM_PROG_CC_C_O])]) -]) - -# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- - -# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005 -# Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# serial 5 - -# AM_MISSING_PROG(NAME, PROGRAM) -# ------------------------------ -AC_DEFUN([AM_MISSING_PROG], -[AC_REQUIRE([AM_MISSING_HAS_RUN]) -$1=${$1-"${am_missing_run}$2"} -AC_SUBST($1)]) - - -# AM_MISSING_HAS_RUN -# ------------------ -# Define MISSING if not defined so far and test if it supports --run. -# If it does, set am_missing_run to use it, otherwise, to nothing. -AC_DEFUN([AM_MISSING_HAS_RUN], -[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl -AC_REQUIRE_AUX_FILE([missing])dnl -test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing" -# Use eval to expand $SHELL -if eval "$MISSING --run true"; then - am_missing_run="$MISSING --run " -else - am_missing_run= - AC_MSG_WARN([`missing' script is too old or missing]) -fi -]) - -# Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_PROG_MKDIR_P -# --------------- -# Check for `mkdir -p'. -AC_DEFUN([AM_PROG_MKDIR_P], -[AC_PREREQ([2.60])dnl -AC_REQUIRE([AC_PROG_MKDIR_P])dnl -dnl Automake 1.8 to 1.9.6 used to define mkdir_p. We now use MKDIR_P, -dnl while keeping a definition of mkdir_p for backward compatibility. -dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile. -dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of -dnl Makefile.ins that do not define MKDIR_P, so we do our own -dnl adjustment using top_builddir (which is defined more often than -dnl MKDIR_P). -AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl -case $mkdir_p in - [[\\/$]]* | ?:[[\\/]]*) ;; - */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; -esac -]) - -# Helper functions for option handling. -*- Autoconf -*- - -# Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# serial 3 - -# _AM_MANGLE_OPTION(NAME) -# ----------------------- -AC_DEFUN([_AM_MANGLE_OPTION], -[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) - -# _AM_SET_OPTION(NAME) -# ------------------------------ -# Set option NAME. Presently that only means defining a flag for this option. -AC_DEFUN([_AM_SET_OPTION], -[m4_define(_AM_MANGLE_OPTION([$1]), 1)]) - -# _AM_SET_OPTIONS(OPTIONS) -# ---------------------------------- -# OPTIONS is a space-separated list of Automake options. -AC_DEFUN([_AM_SET_OPTIONS], -[AC_FOREACH([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) - -# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) -# ------------------------------------------- -# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. -AC_DEFUN([_AM_IF_OPTION], -[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) - -# Check to make sure that the build environment is sane. -*- Autoconf -*- - -# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005 -# Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# serial 4 - -# AM_SANITY_CHECK -# --------------- -AC_DEFUN([AM_SANITY_CHECK], -[AC_MSG_CHECKING([whether build environment is sane]) -# Just in case -sleep 1 -echo timestamp > conftest.file -# Do `set' in a subshell so we don't clobber the current shell's -# arguments. Must try -L first in case configure is actually a -# symlink; some systems play weird games with the mod time of symlinks -# (eg FreeBSD returns the mod time of the symlink's containing -# directory). -if ( - set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null` - if test "$[*]" = "X"; then - # -L didn't work. - set X `ls -t $srcdir/configure conftest.file` - fi - rm -f conftest.file - if test "$[*]" != "X $srcdir/configure conftest.file" \ - && test "$[*]" != "X conftest.file $srcdir/configure"; then - - # If neither matched, then we have a broken ls. This can happen - # if, for instance, CONFIG_SHELL is bash and it inherits a - # broken ls alias from the environment. This has actually - # happened. Such a system could not be considered "sane". - AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken -alias in your environment]) - fi - - test "$[2]" = conftest.file - ) -then - # Ok. - : -else - AC_MSG_ERROR([newly created file is older than distributed files! -Check your system clock]) -fi -AC_MSG_RESULT(yes)]) - -# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_PROG_INSTALL_STRIP -# --------------------- -# One issue with vendor `install' (even GNU) is that you can't -# specify the program used to strip binaries. This is especially -# annoying in cross-compiling environments, where the build's strip -# is unlikely to handle the host's binaries. -# Fortunately install-sh will honor a STRIPPROG variable, so we -# always use install-sh in `make install-strip', and initialize -# STRIPPROG with the value of the STRIP variable (set by the user). -AC_DEFUN([AM_PROG_INSTALL_STRIP], -[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl -# Installed binaries are usually stripped using `strip' when the user -# run `make install-strip'. However `strip' might not be the right -# tool to use in cross-compilation environments, therefore Automake -# will honor the `STRIP' environment variable to overrule this program. -dnl Don't test for $cross_compiling = yes, because it might be `maybe'. -if test "$cross_compiling" != no; then - AC_CHECK_TOOL([STRIP], [strip], :) -fi -INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" -AC_SUBST([INSTALL_STRIP_PROGRAM])]) - -# Copyright (C) 2006 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# _AM_SUBST_NOTMAKE(VARIABLE) -# --------------------------- -# Prevent Automake from outputing VARIABLE = @VARIABLE@ in Makefile.in. -# This macro is traced by Automake. -AC_DEFUN([_AM_SUBST_NOTMAKE]) - -# Check how to create a tarball. -*- Autoconf -*- - -# Copyright (C) 2004, 2005 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# serial 2 - -# _AM_PROG_TAR(FORMAT) -# -------------------- -# Check how to create a tarball in format FORMAT. -# FORMAT should be one of `v7', `ustar', or `pax'. -# -# Substitute a variable $(am__tar) that is a command -# writing to stdout a FORMAT-tarball containing the directory -# $tardir. -# tardir=directory && $(am__tar) > result.tar -# -# Substitute a variable $(am__untar) that extract such -# a tarball read from stdin. -# $(am__untar) < result.tar -AC_DEFUN([_AM_PROG_TAR], -[# Always define AMTAR for backward compatibility. -AM_MISSING_PROG([AMTAR], [tar]) -m4_if([$1], [v7], - [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'], - [m4_case([$1], [ustar],, [pax],, - [m4_fatal([Unknown tar format])]) -AC_MSG_CHECKING([how to create a $1 tar archive]) -# Loop over all known methods to create a tar archive until one works. -_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' -_am_tools=${am_cv_prog_tar_$1-$_am_tools} -# Do not fold the above two line into one, because Tru64 sh and -# Solaris sh will not grok spaces in the rhs of `-'. -for _am_tool in $_am_tools -do - case $_am_tool in - gnutar) - for _am_tar in tar gnutar gtar; - do - AM_RUN_LOG([$_am_tar --version]) && break - done - am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' - am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' - am__untar="$_am_tar -xf -" - ;; - plaintar) - # Must skip GNU tar: if it does not support --format= it doesn't create - # ustar tarball either. - (tar --version) >/dev/null 2>&1 && continue - am__tar='tar chf - "$$tardir"' - am__tar_='tar chf - "$tardir"' - am__untar='tar xf -' - ;; - pax) - am__tar='pax -L -x $1 -w "$$tardir"' - am__tar_='pax -L -x $1 -w "$tardir"' - am__untar='pax -r' - ;; - cpio) - am__tar='find "$$tardir" -print | cpio -o -H $1 -L' - am__tar_='find "$tardir" -print | cpio -o -H $1 -L' - am__untar='cpio -i -H $1 -d' - ;; - none) - am__tar=false - am__tar_=false - am__untar=false - ;; - esac - - # If the value was cached, stop now. We just wanted to have am__tar - # and am__untar set. - test -n "${am_cv_prog_tar_$1}" && break - - # tar/untar a dummy directory, and stop if the command works - rm -rf conftest.dir - mkdir conftest.dir - echo GrepMe > conftest.dir/file - AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) - rm -rf conftest.dir - if test -s conftest.tar; then - AM_RUN_LOG([$am__untar /dev/null 2>&1 && break - fi -done -rm -rf conftest.dir - -AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) -AC_MSG_RESULT([$am_cv_prog_tar_$1])]) -AC_SUBST([am__tar]) -AC_SUBST([am__untar]) -]) # _AM_PROG_TAR - -m4_include([acinclude.m4]) diff --git a/contrib/cvs/compile b/contrib/cvs/compile deleted file mode 100755 index 1b1d232..0000000 --- a/contrib/cvs/compile +++ /dev/null @@ -1,142 +0,0 @@ -#! /bin/sh -# Wrapper for compilers which do not understand `-c -o'. - -scriptversion=2005-05-14.22 - -# Copyright (C) 1999, 2000, 2003, 2004, 2005 Free Software Foundation, Inc. -# Written by Tom Tromey . -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - -# This file is maintained in Automake, please report -# bugs to or send patches to -# . - -case $1 in - '') - echo "$0: No command. Try \`$0 --help' for more information." 1>&2 - exit 1; - ;; - -h | --h*) - cat <<\EOF -Usage: compile [--help] [--version] PROGRAM [ARGS] - -Wrapper for compilers which do not understand `-c -o'. -Remove `-o dest.o' from ARGS, run PROGRAM with the remaining -arguments, and rename the output as expected. - -If you are trying to build a whole package this is not the -right script to run: please start by reading the file `INSTALL'. - -Report bugs to . -EOF - exit $? - ;; - -v | --v*) - echo "compile $scriptversion" - exit $? - ;; -esac - -ofile= -cfile= -eat= - -for arg -do - if test -n "$eat"; then - eat= - else - case $1 in - -o) - # configure might choose to run compile as `compile cc -o foo foo.c'. - # So we strip `-o arg' only if arg is an object. - eat=1 - case $2 in - *.o | *.obj) - ofile=$2 - ;; - *) - set x "$@" -o "$2" - shift - ;; - esac - ;; - *.c) - cfile=$1 - set x "$@" "$1" - shift - ;; - *) - set x "$@" "$1" - shift - ;; - esac - fi - shift -done - -if test -z "$ofile" || test -z "$cfile"; then - # If no `-o' option was seen then we might have been invoked from a - # pattern rule where we don't need one. That is ok -- this is a - # normal compilation that the losing compiler can handle. If no - # `.c' file was seen then we are probably linking. That is also - # ok. - exec "$@" -fi - -# Name of file we expect compiler to create. -cofile=`echo "$cfile" | sed -e 's|^.*/||' -e 's/\.c$/.o/'` - -# Create the lock directory. -# Note: use `[/.-]' here to ensure that we don't use the same name -# that we are using for the .o file. Also, base the name on the expected -# object file name, since that is what matters with a parallel build. -lockdir=`echo "$cofile" | sed -e 's|[/.-]|_|g'`.d -while true; do - if mkdir "$lockdir" >/dev/null 2>&1; then - break - fi - sleep 1 -done -# FIXME: race condition here if user kills between mkdir and trap. -trap "rmdir '$lockdir'; exit 1" 1 2 15 - -# Run the compile. -"$@" -ret=$? - -if test -f "$cofile"; then - mv "$cofile" "$ofile" -elif test -f "${cofile}bj"; then - mv "${cofile}bj" "$ofile" -fi - -rmdir "$lockdir" -exit $ret - -# Local Variables: -# mode: shell-script -# sh-indentation: 2 -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "scriptversion=" -# time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-end: "$" -# End: diff --git a/contrib/cvs/config.h.in b/contrib/cvs/config.h.in deleted file mode 100644 index 2997006..0000000 --- a/contrib/cvs/config.h.in +++ /dev/null @@ -1,520 +0,0 @@ -/* config.h.in. Generated from configure.in by autoheader. */ - -/* Enable AUTH_CLIENT_SUPPORT to enable pserver as a remote access method in - the CVS client (default) */ -#undef AUTH_CLIENT_SUPPORT - -/* Define if you want to use the password authenticated server. */ -#undef AUTH_SERVER_SUPPORT - -/* Define if you want CVS to be able to be a remote repository client. */ -#undef CLIENT_SUPPORT - -/* Define to 1 if the `closedir' function returns void instead of `int'. */ -#undef CLOSEDIR_VOID - -/* The CVS admin command is restricted to the members of the group - CVS_ADMIN_GROUP. If this group does not exist, all users are allowed to run - CVS admin. To disable the CVS admin command for all users, create an empty - CVS_ADMIN_GROUP by running configure with the --with-cvs-admin-group= - option. To disable access control for CVS admin, run configure with the - --without-cvs-admin-group option in order to comment out the define below. - */ -#undef CVS_ADMIN_GROUP - -/* When committing a permanent change, CVS and RCS make a log entry of who - committed the change. If you are committing the change logged in as "root" - (not under "su" or other root-priv giving program), CVS/RCS cannot - determine who is actually making the change. As such, by default, CVS - prohibits changes committed by users logged in as "root". You can disable - checking by passing the "--enable-rootcommit" option to configure or by - commenting out the lines below. */ -#undef CVS_BADROOT - -/* The default editor to use, if one does not specify the "-e" option to cvs, - or does not have an EDITOR environment variable. If this is not set to an - absolute path to an executable, use the shell to find where the editor - actually is. This allows sites with /usr/bin/vi or /usr/ucb/vi to work - equally well (assuming that their PATH is reasonable). */ -#undef EDITOR_DFLT - -/* Define to enable encryption support. */ -#undef ENCRYPTION - -/* Define if this executable will be running on case insensitive file systems. - In the client case, this means that it will request that the server pretend - to be case insensitive if it isn't already. */ -#undef FILENAMES_CASE_INSENSITIVE - -/* When committing or importing files, you must enter a log message. Normally, - you can do this either via the -m flag on the command line, the -F flag on - the command line, or an editor will be started for you. If you like to use - logging templates (the rcsinfo file within the $CVSROOT/CVSROOT directory), - you might want to force people to use the editor even if they specify a - message with -m or -F. Enabling FORCE_USE_EDITOR will cause the -m or -F - message to be appended to the temp file when the editor is started. */ -#undef FORCE_USE_EDITOR - -/* Define to an alternative value if GSS_C_NT_HOSTBASED_SERVICE isn't defined - in the gssapi.h header file. MIT Kerberos 1.2.1 requires this. Only - relevant when using GSSAPI. */ -#undef GSS_C_NT_HOSTBASED_SERVICE - -/* Define if you have the connect function. */ -#undef HAVE_CONNECT - -/* Define if you have the crypt function. */ -#undef HAVE_CRYPT - -/* Define to 1 if you have the header file. */ -#undef HAVE_DIRECT_H - -/* Define to 1 if you have the header file, and it defines `DIR'. - */ -#undef HAVE_DIRENT_H - -/* Define to 1 if you have the `dup2' function. */ -#undef HAVE_DUP2 - -/* Define to 1 if you have the header file. */ -#undef HAVE_ERRNO_H - -/* Define to 1 if you have the `fchdir' function. */ -#undef HAVE_FCHDIR - -/* Define to 1 if you have the `fchmod' function. */ -#undef HAVE_FCHMOD - -/* Define to 1 if you have the header file. */ -#undef HAVE_FCNTL_H - -/* Define to 1 if your system has a working POSIX `fnmatch' function. */ -#undef HAVE_FNMATCH - -/* Define to 1 if you have the header file. */ -#undef HAVE_FNMATCH_H - -/* Define to 1 if you have the `fork' function. */ -#undef HAVE_FORK - -/* Define to 1 if you have the `fsync' function. */ -#undef HAVE_FSYNC - -/* Define to 1 if you have the `ftime' function. */ -#undef HAVE_FTIME - -/* Define to 1 if you have the `ftruncate' function. */ -#undef HAVE_FTRUNCATE - -/* Define to 1 if you have the `geteuid' function. */ -#undef HAVE_GETEUID - -/* Define to 1 if you have the `getgroups' function. */ -#undef HAVE_GETGROUPS - -/* Define to 1 if you have the `gethostname' function. */ -#undef HAVE_GETHOSTNAME - -/* Define to 1 if you have the `getopt' function. */ -#undef HAVE_GETOPT - -/* Define to 1 if you have the `getpagesize' function. */ -#undef HAVE_GETPAGESIZE - -/* Define if you have the getspnam function. */ -#undef HAVE_GETSPNAM - -/* Define to 1 if you have the `gettimeofday' function. */ -#undef HAVE_GETTIMEOFDAY - -/* Define if you have GSSAPI with Kerberos version 5 available. */ -#undef HAVE_GSSAPI - -/* Define to 1 if you have the header file. */ -#undef HAVE_GSSAPI_GSSAPI_GENERIC_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_GSSAPI_GSSAPI_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_GSSAPI_H - -/* Define to 1 if you have the `initgroups' function. */ -#undef HAVE_INITGROUPS - -/* Define to 1 if you have the header file. */ -#undef HAVE_INTTYPES_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_IO_H - -/* Define if you have MIT Kerberos version 4 available. */ -#undef HAVE_KERBEROS - -/* Define to 1 if you have the header file. */ -#undef HAVE_KRB5_H - -/* Define to 1 if you have the `krb_get_err_text' function. */ -#undef HAVE_KRB_GET_ERR_TEXT - -/* Define to 1 if you have the `krb' library (-lkrb). */ -#undef HAVE_LIBKRB - -/* Define to 1 if you have the `krb4' library (-lkrb4). */ -#undef HAVE_LIBKRB4 - -/* Define to 1 if you have the `nsl' library (-lnsl). */ -#undef HAVE_LIBNSL - -/* Define to 1 if you have the header file. */ -#undef HAVE_LIMITS_H - -/* Define to 1 if you have the `login' function. */ -#undef HAVE_LOGIN - -/* Define to 1 if you have the `logout' function. */ -#undef HAVE_LOGOUT - -/* Define to 1 if you support file names longer than 14 characters. */ -#undef HAVE_LONG_FILE_NAMES - -/* Define if you have memchr (always for CVS). */ -#undef HAVE_MEMCHR - -/* Define to 1 if you have the `memmove' function. */ -#undef HAVE_MEMMOVE - -/* Define to 1 if you have the header file. */ -#undef HAVE_MEMORY_H - -/* Define to 1 if you have the `mkdir' function. */ -#undef HAVE_MKDIR - -/* Define to 1 if you have the `mknod' function. */ -#undef HAVE_MKNOD - -/* Define to 1 if you have the `mkstemp' function. */ -#undef HAVE_MKSTEMP - -/* Define to 1 if you have the `mktemp' function. */ -#undef HAVE_MKTEMP - -/* Define to 1 if you have a working `mmap' system call. */ -#undef HAVE_MMAP - -/* Define to 1 if you have the `nanosleep' function. */ -#undef HAVE_NANOSLEEP - -/* Define to 1 if you have the header file. */ -#undef HAVE_NDBM_H - -/* Define to 1 if you have the header file, and it defines `DIR'. */ -#undef HAVE_NDIR_H - -/* Define to 1 if you have the `putenv' function. */ -#undef HAVE_PUTENV - -/* Define to 1 if you have the `readlink' function. */ -#undef HAVE_READLINK - -/* Define to 1 if you have the `regcomp' function. */ -#undef HAVE_REGCOMP - -/* Define to 1 if you have the `regerror' function. */ -#undef HAVE_REGERROR - -/* Define to 1 if you have the `regexec' function. */ -#undef HAVE_REGEXEC - -/* Define to 1 if you have the `regfree' function. */ -#undef HAVE_REGFREE - -/* Define to 1 if you have the `rename' function. */ -#undef HAVE_RENAME - -/* Define to 1 if you have the `select' function. */ -#undef HAVE_SELECT - -/* Define if the diff library should use setmode for binary files. */ -#undef HAVE_SETMODE - -/* Define to 1 if you have the `sigaction' function. */ -#undef HAVE_SIGACTION - -/* Define to 1 if you have the `sigblock' function. */ -#undef HAVE_SIGBLOCK - -/* Define to 1 if you have the `sigprocmask' function. */ -#undef HAVE_SIGPROCMASK - -/* Define to 1 if you have the `sigsetmask' function. */ -#undef HAVE_SIGSETMASK - -/* Define to 1 if you have the `sigvec' function. */ -#undef HAVE_SIGVEC - -/* Define to 1 if you have the header file. */ -#undef HAVE_STDINT_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_STDLIB_H - -/* Define if you have strchr (always for CVS). */ -#undef HAVE_STRCHR - -/* Define to 1 if you have the `strerror' function. */ -#undef HAVE_STRERROR - -/* Define to 1 if you have the header file. */ -#undef HAVE_STRINGS_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_STRING_H - -/* Define to 1 if you have the `strstr' function. */ -#undef HAVE_STRSTR - -/* Define to 1 if you have the `strtoul' function. */ -#undef HAVE_STRTOUL - -/* Define to 1 if `st_blksize' is member of `struct stat'. */ -#undef HAVE_STRUCT_STAT_ST_BLKSIZE - -/* Define to 1 if `st_rdev' is member of `struct stat'. */ -#undef HAVE_STRUCT_STAT_ST_RDEV - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYSLOG_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_BSDTYPES_H - -/* Define to 1 if you have the header file, and it defines `DIR'. - */ -#undef HAVE_SYS_DIR_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_FILE_H - -/* Define to 1 if you have the header file, and it defines `DIR'. - */ -#undef HAVE_SYS_NDIR_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_PARAM_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_RESOURCE_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_SELECT_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_STAT_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_TIMEB_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_TIME_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_TYPES_H - -/* Define to 1 if you have that is POSIX.1 compatible. */ -#undef HAVE_SYS_WAIT_H - -/* Define to 1 if you have the `tempnam' function. */ -#undef HAVE_TEMPNAM - -/* Define to 1 if you have the `timezone' function. */ -#undef HAVE_TIMEZONE - -/* Define to 1 if you have the `tzset' function. */ -#undef HAVE_TZSET - -/* Define to 1 if you have the header file. */ -#undef HAVE_UNISTD_H - -/* Define to 1 if you have the `usleep' function. */ -#undef HAVE_USLEEP - -/* Define to 1 if you have the header file. */ -#undef HAVE_UTIME_H - -/* Define to 1 if `utime(file, NULL)' sets file's timestamp to the present. */ -#undef HAVE_UTIME_NULL - -/* Define to 1 if you have the `valloc' function. */ -#undef HAVE_VALLOC - -/* Define to 1 if you have the `vfork' function. */ -#undef HAVE_VFORK - -/* Define to 1 if you have the header file. */ -#undef HAVE_VFORK_H - -/* Define to 1 if you have the `vprintf' function. */ -#undef HAVE_VPRINTF - -/* Define to 1 if you have the `wait3' function. */ -#undef HAVE_WAIT3 - -/* Define to 1 if you have the `waitpid' function. */ -#undef HAVE_WAITPID - -/* Define to 1 if `fork' works. */ -#undef HAVE_WORKING_FORK - -/* Define to 1 if `vfork' works. */ -#undef HAVE_WORKING_VFORK - -/* By default, CVS stores its modules and other such items in flat text files - (MY_NDBM enables this). Turning off MY_NDBM causes CVS to look for a - system-supplied ndbm database library and use it instead. That may speed - things up, but the default setting generally works fine too. */ -#undef MY_NDBM - -/* Define to 1 if your C compiler doesn't accept -c and -o together. */ -#undef NO_MINUS_C_MINUS_O - -/* Define to the address where bug reports for this package should be sent. */ -#undef PACKAGE_BUGREPORT - -/* Define to the full name of this package. */ -#undef PACKAGE_NAME - -/* Define to the full name and version of this package. */ -#undef PACKAGE_STRING - -/* Define to the one symbol short name of this package. */ -#undef PACKAGE_TARNAME - -/* Define to the version of this package. */ -#undef PACKAGE_VERSION - -/* Path to the pr utility */ -#undef PR_PROGRAM - -/* Define to force lib/regex.c to use malloc instead of alloca. */ -#undef REGEX_MALLOC - -/* Define as the return type of signal handlers (`int' or `void'). */ -#undef RETSIGTYPE - -/* The default remote shell to use, if one does not specify the CVS_RSH - environment variable. */ -#undef RSH_DFLT - -/* If you are working with a large remote repository and a 'cvs checkout' is - swamping your network and memory, define these to enable flow control. You - will end up with even less probability of a consistent checkout (see - Concurrency in cvs.texinfo), but CVS doesn't try to guarantee that anyway. - The master server process will monitor how far it is getting behind, if it - reaches the high water mark, it will signal the child process to stop - generating data when convenient (ie: no locks are held, currently at the - beginning of a new directory). Once the buffer has drained sufficiently to - reach the low water mark, it will be signalled to start again. */ -#undef SERVER_FLOWCONTROL - -/* The high water mark in bytes for server flow control. Required if - SERVER_FLOWCONTROL is defined, and useless otherwise. */ -#undef SERVER_HI_WATER - -/* The low water mark in bytes for server flow control. Required if - SERVER_FLOWCONTROL is defined, and useless otherwise. */ -#undef SERVER_LO_WATER - -/* Define if you want CVS to be able to serve repositories to remote clients. - */ -#undef SERVER_SUPPORT - -/* Define as the maximum value of type 'size_t', if the system doesn't define - it. */ -#undef SIZE_MAX - -/* The default remote shell to use, if one does not specify the CVS_SSH - environment variable. */ -#undef SSH_DFLT - -/* Define to 1 if the `S_IS*' macros in do not work properly. */ -#undef STAT_MACROS_BROKEN - -/* Define to 1 if you have the ANSI C header files. */ -#undef STDC_HEADERS - -/* Define to 1 if you can safely include both and . */ -#undef TIME_WITH_SYS_TIME - -/* Directory used for storing temporary files, if not overridden by - environment variables or the -T global option. There should be little need - to change this (-T is a better mechanism if you need to use a different - directory for temporary files). */ -#undef TMPDIR_DFLT - -/* The default umask to use when creating or otherwise setting file or - directory permissions in the repository. Must be a value in the range of 0 - through 0777. For example, a value of 002 allows group rwx access and world - rx access; a value of 007 allows group rwx access but no world access. This - value is overridden by the value of the CVSUMASK environment variable, - which is interpreted as an octal number. */ -#undef UMASK_DFLT - -/* Define if setmode is required when writing binary data to stdout. */ -#undef USE_SETMODE_STDOUT - -/* Define if utime requires write access to the file (true on Windows, but not - Unix). */ -#undef UTIME_EXPECTS_WRITABLE - -/* Define to 1 if on AIX 3. - System headers sometimes define this. - We just want to avoid a redefinition error message. */ -#ifndef _ALL_SOURCE -# undef _ALL_SOURCE -#endif - -/* Define to 1 if on MINIX. */ -#undef _MINIX - -/* Define to 2 if the system does not provide POSIX.1 features except with - this defined. */ -#undef _POSIX_1_SOURCE - -/* Define to 1 if you need to in order for `stat' and other things to work. */ -#undef _POSIX_SOURCE - -/* Define to force lib/regex.c to define re_comp et al. */ -#undef _REGEX_RE_COMP - -/* Define to empty if `const' does not conform to ANSI C. */ -#undef const - -/* We want to always use the GNULIB version of getpass which we have in lib, - so define getpass to something that won't conflict with any existing system - declarations. */ -#undef getpass - -/* Define to `int' if doesn't define. */ -#undef gid_t - -/* Define to `__inline__' or `__inline' if that's what the C compiler - calls it, or to nothing if 'inline' is not supported under any name. */ -#ifndef __cplusplus -#undef inline -#endif - -/* Define to `int' if does not define. */ -#undef mode_t - -/* Define to `int' if does not define. */ -#undef pid_t - -/* Define to `unsigned int' if does not define. */ -#undef size_t - -/* Define to `int' if doesn't define. */ -#undef uid_t - -/* Define as `fork' if `vfork' does not work. */ -#undef vfork diff --git a/contrib/cvs/configure b/contrib/cvs/configure deleted file mode 100755 index 2e10599..0000000 --- a/contrib/cvs/configure +++ /dev/null @@ -1,14785 +0,0 @@ -#! /bin/sh -# Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.61 for Concurrent Versions System (CVS) 1.11.22.1. -# -# Report bugs to . -# -# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, -# 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. -# This configure script is free software; the Free Software Foundation -# gives unlimited permission to copy, distribute and modify it. -## --------------------- ## -## M4sh Initialization. ## -## --------------------- ## - -# Be more Bourne compatible -DUALCASE=1; export DUALCASE # for MKS sh -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then - emulate sh - NULLCMD=: - # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which - # is contrary to our usage. Disable this feature. - alias -g '${1+"$@"}'='"$@"' - setopt NO_GLOB_SUBST -else - case `(set -o) 2>/dev/null` in - *posix*) set -o posix ;; -esac - -fi - - - - -# PATH needs CR -# Avoid depending upon Character Ranges. -as_cr_letters='abcdefghijklmnopqrstuvwxyz' -as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' -as_cr_Letters=$as_cr_letters$as_cr_LETTERS -as_cr_digits='0123456789' -as_cr_alnum=$as_cr_Letters$as_cr_digits - -# The user is always right. -if test "${PATH_SEPARATOR+set}" != set; then - echo "#! /bin/sh" >conf$$.sh - echo "exit 0" >>conf$$.sh - chmod +x conf$$.sh - if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then - PATH_SEPARATOR=';' - else - PATH_SEPARATOR=: - fi - rm -f conf$$.sh -fi - -# Support unset when possible. -if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then - as_unset=unset -else - as_unset=false -fi - - -# IFS -# We need space, tab and new line, in precisely that order. Quoting is -# there to prevent editors from complaining about space-tab. -# (If _AS_PATH_WALK were called with IFS unset, it would disable word -# splitting by setting IFS to empty value.) -as_nl=' -' -IFS=" "" $as_nl" - -# Find who we are. Look in the path if we contain no directory separator. -case $0 in - *[\\/]* ) as_myself=$0 ;; - *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break -done -IFS=$as_save_IFS - - ;; -esac -# We did not find ourselves, most probably we were run as `sh COMMAND' -# in which case we are not to be found in the path. -if test "x$as_myself" = x; then - as_myself=$0 -fi -if test ! -f "$as_myself"; then - echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 - { (exit 1); exit 1; } -fi - -# Work around bugs in pre-3.0 UWIN ksh. -for as_var in ENV MAIL MAILPATH -do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var -done -PS1='$ ' -PS2='> ' -PS4='+ ' - -# NLS nuisances. -for as_var in \ - LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ - LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ - LC_TELEPHONE LC_TIME -do - if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then - eval $as_var=C; export $as_var - else - ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var - fi -done - -# Required to use basename. -if expr a : '\(a\)' >/dev/null 2>&1 && - test "X`expr 00001 : '.*\(...\)'`" = X001; then - as_expr=expr -else - as_expr=false -fi - -if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then - as_basename=basename -else - as_basename=false -fi - - -# Name of the executable. -as_me=`$as_basename -- "$0" || -$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ - X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)' \| . 2>/dev/null || -echo X/"$0" | - sed '/^.*\/\([^/][^/]*\)\/*$/{ - s//\1/ - q - } - /^X\/\(\/\/\)$/{ - s//\1/ - q - } - /^X\/\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - -# CDPATH. -$as_unset CDPATH - - -if test "x$CONFIG_SHELL" = x; then - if (eval ":") 2>/dev/null; then - as_have_required=yes -else - as_have_required=no -fi - - if test $as_have_required = yes && (eval ": -(as_func_return () { - (exit \$1) -} -as_func_success () { - as_func_return 0 -} -as_func_failure () { - as_func_return 1 -} -as_func_ret_success () { - return 0 -} -as_func_ret_failure () { - return 1 -} - -exitcode=0 -if as_func_success; then - : -else - exitcode=1 - echo as_func_success failed. -fi - -if as_func_failure; then - exitcode=1 - echo as_func_failure succeeded. -fi - -if as_func_ret_success; then - : -else - exitcode=1 - echo as_func_ret_success failed. -fi - -if as_func_ret_failure; then - exitcode=1 - echo as_func_ret_failure succeeded. -fi - -if ( set x; as_func_ret_success y && test x = \"\$1\" ); then - : -else - exitcode=1 - echo positional parameters were not saved. -fi - -test \$exitcode = 0) || { (exit 1); exit 1; } - -( - as_lineno_1=\$LINENO - as_lineno_2=\$LINENO - test \"x\$as_lineno_1\" != \"x\$as_lineno_2\" && - test \"x\`expr \$as_lineno_1 + 1\`\" = \"x\$as_lineno_2\") || { (exit 1); exit 1; } -") 2> /dev/null; then - : -else - as_candidate_shells= - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - case $as_dir in - /*) - for as_base in sh bash ksh sh5; do - as_candidate_shells="$as_candidate_shells $as_dir/$as_base" - done;; - esac -done -IFS=$as_save_IFS - - - for as_shell in $as_candidate_shells $SHELL; do - # Try only shells that exist, to save several forks. - if { test -f "$as_shell" || test -f "$as_shell.exe"; } && - { ("$as_shell") 2> /dev/null <<\_ASEOF -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then - emulate sh - NULLCMD=: - # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which - # is contrary to our usage. Disable this feature. - alias -g '${1+"$@"}'='"$@"' - setopt NO_GLOB_SUBST -else - case `(set -o) 2>/dev/null` in - *posix*) set -o posix ;; -esac - -fi - - -: -_ASEOF -}; then - CONFIG_SHELL=$as_shell - as_have_required=yes - if { "$as_shell" 2> /dev/null <<\_ASEOF -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then - emulate sh - NULLCMD=: - # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which - # is contrary to our usage. Disable this feature. - alias -g '${1+"$@"}'='"$@"' - setopt NO_GLOB_SUBST -else - case `(set -o) 2>/dev/null` in - *posix*) set -o posix ;; -esac - -fi - - -: -(as_func_return () { - (exit $1) -} -as_func_success () { - as_func_return 0 -} -as_func_failure () { - as_func_return 1 -} -as_func_ret_success () { - return 0 -} -as_func_ret_failure () { - return 1 -} - -exitcode=0 -if as_func_success; then - : -else - exitcode=1 - echo as_func_success failed. -fi - -if as_func_failure; then - exitcode=1 - echo as_func_failure succeeded. -fi - -if as_func_ret_success; then - : -else - exitcode=1 - echo as_func_ret_success failed. -fi - -if as_func_ret_failure; then - exitcode=1 - echo as_func_ret_failure succeeded. -fi - -if ( set x; as_func_ret_success y && test x = "$1" ); then - : -else - exitcode=1 - echo positional parameters were not saved. -fi - -test $exitcode = 0) || { (exit 1); exit 1; } - -( - as_lineno_1=$LINENO - as_lineno_2=$LINENO - test "x$as_lineno_1" != "x$as_lineno_2" && - test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2") || { (exit 1); exit 1; } - -_ASEOF -}; then - break -fi - -fi - - done - - if test "x$CONFIG_SHELL" != x; then - for as_var in BASH_ENV ENV - do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var - done - export CONFIG_SHELL - exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"} -fi - - - if test $as_have_required = no; then - echo This script requires a shell more modern than all the - echo shells that I found on your system. Please install a - echo modern shell, or manually run the script under such a - echo shell if you do have one. - { (exit 1); exit 1; } -fi - - -fi - -fi - - - -(eval "as_func_return () { - (exit \$1) -} -as_func_success () { - as_func_return 0 -} -as_func_failure () { - as_func_return 1 -} -as_func_ret_success () { - return 0 -} -as_func_ret_failure () { - return 1 -} - -exitcode=0 -if as_func_success; then - : -else - exitcode=1 - echo as_func_success failed. -fi - -if as_func_failure; then - exitcode=1 - echo as_func_failure succeeded. -fi - -if as_func_ret_success; then - : -else - exitcode=1 - echo as_func_ret_success failed. -fi - -if as_func_ret_failure; then - exitcode=1 - echo as_func_ret_failure succeeded. -fi - -if ( set x; as_func_ret_success y && test x = \"\$1\" ); then - : -else - exitcode=1 - echo positional parameters were not saved. -fi - -test \$exitcode = 0") || { - echo No shell found that supports shell functions. - echo Please tell autoconf@gnu.org about your system, - echo including any error possibly output before this - echo message -} - - - - as_lineno_1=$LINENO - as_lineno_2=$LINENO - test "x$as_lineno_1" != "x$as_lineno_2" && - test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { - - # Create $as_me.lineno as a copy of $as_myself, but with $LINENO - # uniformly replaced by the line number. The first 'sed' inserts a - # line-number line after each line using $LINENO; the second 'sed' - # does the real work. The second script uses 'N' to pair each - # line-number line with the line containing $LINENO, and appends - # trailing '-' during substitution so that $LINENO is not a special - # case at line end. - # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the - # scripts with optimization help from Paolo Bonzini. Blame Lee - # E. McMahon (1931-1989) for sed's syntax. :-) - sed -n ' - p - /[$]LINENO/= - ' <$as_myself | - sed ' - s/[$]LINENO.*/&-/ - t lineno - b - :lineno - N - :loop - s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ - t loop - s/-\n.*// - ' >$as_me.lineno && - chmod +x "$as_me.lineno" || - { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 - { (exit 1); exit 1; }; } - - # Don't try to exec as it changes $[0], causing all sort of problems - # (the dirname of $[0] is not the place where we might find the - # original and so on. Autoconf is especially sensitive to this). - . "./$as_me.lineno" - # Exit status is that of the last command. - exit -} - - -if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then - as_dirname=dirname -else - as_dirname=false -fi - -ECHO_C= ECHO_N= ECHO_T= -case `echo -n x` in --n*) - case `echo 'x\c'` in - *c*) ECHO_T=' ';; # ECHO_T is single tab character. - *) ECHO_C='\c';; - esac;; -*) - ECHO_N='-n';; -esac - -if expr a : '\(a\)' >/dev/null 2>&1 && - test "X`expr 00001 : '.*\(...\)'`" = X001; then - as_expr=expr -else - as_expr=false -fi - -rm -f conf$$ conf$$.exe conf$$.file -if test -d conf$$.dir; then - rm -f conf$$.dir/conf$$.file -else - rm -f conf$$.dir - mkdir conf$$.dir -fi -echo >conf$$.file -if ln -s conf$$.file conf$$ 2>/dev/null; then - as_ln_s='ln -s' - # ... but there are two gotchas: - # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. - # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. - # In both cases, we have to default to `cp -p'. - ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || - as_ln_s='cp -p' -elif ln conf$$.file conf$$ 2>/dev/null; then - as_ln_s=ln -else - as_ln_s='cp -p' -fi -rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file -rmdir conf$$.dir 2>/dev/null - -if mkdir -p . 2>/dev/null; then - as_mkdir_p=: -else - test -d ./-p && rmdir ./-p - as_mkdir_p=false -fi - -if test -x / >/dev/null 2>&1; then - as_test_x='test -x' -else - if ls -dL / >/dev/null 2>&1; then - as_ls_L_option=L - else - as_ls_L_option= - fi - as_test_x=' - eval sh -c '\'' - if test -d "$1"; then - test -d "$1/."; - else - case $1 in - -*)set "./$1";; - esac; - case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in - ???[sx]*):;;*)false;;esac;fi - '\'' sh - ' -fi -as_executable_p=$as_test_x - -# Sed expression to map a string onto a valid CPP name. -as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" - -# Sed expression to map a string onto a valid variable name. -as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" - - - -exec 7<&0 &1 - -# Name of the host. -# hostname on some systems (SVR3.2, Linux) returns a bogus exit status, -# so uname gets run too. -ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` - -# -# Initializations. -# -ac_default_prefix=/usr/local -ac_clean_files= -ac_config_libobj_dir=. -LIBOBJS= -cross_compiling=no -subdirs= -MFLAGS= -MAKEFLAGS= -SHELL=${CONFIG_SHELL-/bin/sh} - -# Identity of this package. -PACKAGE_NAME='Concurrent Versions System (CVS)' -PACKAGE_TARNAME='cvs' -PACKAGE_VERSION='1.11.22.1' -PACKAGE_STRING='Concurrent Versions System (CVS) 1.11.22.1' -PACKAGE_BUGREPORT='bug-cvs@nongnu.org' - -ac_unique_file="src/cvs.h" -# Factoring default headers for most tests. -ac_includes_default="\ -#include -#ifdef HAVE_SYS_TYPES_H -# include -#endif -#ifdef HAVE_SYS_STAT_H -# include -#endif -#ifdef STDC_HEADERS -# include -# include -#else -# ifdef HAVE_STDLIB_H -# include -# endif -#endif -#ifdef HAVE_STRING_H -# if !defined STDC_HEADERS && defined HAVE_MEMORY_H -# include -# endif -# include -#endif -#ifdef HAVE_STRINGS_H -# include -#endif -#ifdef HAVE_INTTYPES_H -# include -#endif -#ifdef HAVE_STDINT_H -# include -#endif -#ifdef HAVE_UNISTD_H -# include -#endif" - -ac_header_list= -ac_subst_vars='SHELL -PATH_SEPARATOR -PACKAGE_NAME -PACKAGE_TARNAME -PACKAGE_VERSION -PACKAGE_STRING -PACKAGE_BUGREPORT -exec_prefix -prefix -program_transform_name -bindir -sbindir -libexecdir -datarootdir -datadir -sysconfdir -sharedstatedir -localstatedir -includedir -oldincludedir -docdir -infodir -htmldir -dvidir -pdfdir -psdir -libdir -localedir -mandir -DEFS -ECHO_C -ECHO_N -ECHO_T -LIBS -build_alias -host_alias -target_alias -INSTALL_PROGRAM -INSTALL_SCRIPT -INSTALL_DATA -am__isrc -CYGPATH_W -PACKAGE -VERSION -ACLOCAL -AUTOCONF -AUTOMAKE -AUTOHEADER -MAKEINFO -install_sh -STRIP -INSTALL_STRIP_PROGRAM -mkdir_p -AWK -SET_MAKE -am__leading_dot -AMTAR -am__tar -am__untar -ac_prefix_program -MAINTAINER_MODE_TRUE -MAINTAINER_MODE_FALSE -MAINT -CC -CFLAGS -LDFLAGS -CPPFLAGS -ac_ct_CC -EXEEXT -OBJEXT -DEPDIR -am__include -am__quote -AMDEP_TRUE -AMDEP_FALSE -AMDEPBACKSLASH -CCDEPMODE -am__fastdepCC_TRUE -am__fastdepCC_FALSE -CPP -GREP -EGREP -RANLIB -YACC -YFLAGS -LN_S -PERL -CSH -MKTEMP -SENDMAIL -PR -ROFF -PS2PDF -TEXI2DVI -MAKE_TARGETS_IN_VPATH_TRUE -MAKE_TARGETS_IN_VPATH_FALSE -LIBOBJS -KRB4 -includeopt -EDITOR -with_default_ssh -with_default_rsh -LTLIBOBJS' -ac_subst_files='MKTEMP_SH_FUNCTION' - ac_precious_vars='build_alias -host_alias -target_alias -CC -CFLAGS -LDFLAGS -LIBS -CPPFLAGS -CPP -YACC -YFLAGS -EDITOR' - - -# Initialize some variables set by options. -ac_init_help= -ac_init_version=false -# The variables have the same names as the options, with -# dashes changed to underlines. -cache_file=/dev/null -exec_prefix=NONE -no_create= -no_recursion= -prefix=NONE -program_prefix=NONE -program_suffix=NONE -program_transform_name=s,x,x, -silent= -site= -srcdir= -verbose= -x_includes=NONE -x_libraries=NONE - -# Installation directory options. -# These are left unexpanded so users can "make install exec_prefix=/foo" -# and all the variables that are supposed to be based on exec_prefix -# by default will actually change. -# Use braces instead of parens because sh, perl, etc. also accept them. -# (The list follows the same order as the GNU Coding Standards.) -bindir='${exec_prefix}/bin' -sbindir='${exec_prefix}/sbin' -libexecdir='${exec_prefix}/libexec' -datarootdir='${prefix}/share' -datadir='${datarootdir}' -sysconfdir='${prefix}/etc' -sharedstatedir='${prefix}/com' -localstatedir='${prefix}/var' -includedir='${prefix}/include' -oldincludedir='/usr/include' -docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' -infodir='${datarootdir}/info' -htmldir='${docdir}' -dvidir='${docdir}' -pdfdir='${docdir}' -psdir='${docdir}' -libdir='${exec_prefix}/lib' -localedir='${datarootdir}/locale' -mandir='${datarootdir}/man' - -ac_prev= -ac_dashdash= -for ac_option -do - # If the previous option needs an argument, assign it. - if test -n "$ac_prev"; then - eval $ac_prev=\$ac_option - ac_prev= - continue - fi - - case $ac_option in - *=*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; - *) ac_optarg=yes ;; - esac - - # Accept the important Cygnus configure options, so we can diagnose typos. - - case $ac_dashdash$ac_option in - --) - ac_dashdash=yes ;; - - -bindir | --bindir | --bindi | --bind | --bin | --bi) - ac_prev=bindir ;; - -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) - bindir=$ac_optarg ;; - - -build | --build | --buil | --bui | --bu) - ac_prev=build_alias ;; - -build=* | --build=* | --buil=* | --bui=* | --bu=*) - build_alias=$ac_optarg ;; - - -cache-file | --cache-file | --cache-fil | --cache-fi \ - | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) - ac_prev=cache_file ;; - -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ - | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) - cache_file=$ac_optarg ;; - - --config-cache | -C) - cache_file=config.cache ;; - - -datadir | --datadir | --datadi | --datad) - ac_prev=datadir ;; - -datadir=* | --datadir=* | --datadi=* | --datad=*) - datadir=$ac_optarg ;; - - -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ - | --dataroo | --dataro | --datar) - ac_prev=datarootdir ;; - -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ - | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) - datarootdir=$ac_optarg ;; - - -disable-* | --disable-*) - ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null && - { echo "$as_me: error: invalid feature name: $ac_feature" >&2 - { (exit 1); exit 1; }; } - ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'` - eval enable_$ac_feature=no ;; - - -docdir | --docdir | --docdi | --doc | --do) - ac_prev=docdir ;; - -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) - docdir=$ac_optarg ;; - - -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) - ac_prev=dvidir ;; - -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) - dvidir=$ac_optarg ;; - - -enable-* | --enable-*) - ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null && - { echo "$as_me: error: invalid feature name: $ac_feature" >&2 - { (exit 1); exit 1; }; } - ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'` - eval enable_$ac_feature=\$ac_optarg ;; - - -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ - | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ - | --exec | --exe | --ex) - ac_prev=exec_prefix ;; - -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ - | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ - | --exec=* | --exe=* | --ex=*) - exec_prefix=$ac_optarg ;; - - -gas | --gas | --ga | --g) - # Obsolete; use --with-gas. - with_gas=yes ;; - - -help | --help | --hel | --he | -h) - ac_init_help=long ;; - -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) - ac_init_help=recursive ;; - -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) - ac_init_help=short ;; - - -host | --host | --hos | --ho) - ac_prev=host_alias ;; - -host=* | --host=* | --hos=* | --ho=*) - host_alias=$ac_optarg ;; - - -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) - ac_prev=htmldir ;; - -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ - | --ht=*) - htmldir=$ac_optarg ;; - - -includedir | --includedir | --includedi | --included | --include \ - | --includ | --inclu | --incl | --inc) - ac_prev=includedir ;; - -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ - | --includ=* | --inclu=* | --incl=* | --inc=*) - includedir=$ac_optarg ;; - - -infodir | --infodir | --infodi | --infod | --info | --inf) - ac_prev=infodir ;; - -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) - infodir=$ac_optarg ;; - - -libdir | --libdir | --libdi | --libd) - ac_prev=libdir ;; - -libdir=* | --libdir=* | --libdi=* | --libd=*) - libdir=$ac_optarg ;; - - -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ - | --libexe | --libex | --libe) - ac_prev=libexecdir ;; - -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ - | --libexe=* | --libex=* | --libe=*) - libexecdir=$ac_optarg ;; - - -localedir | --localedir | --localedi | --localed | --locale) - ac_prev=localedir ;; - -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) - localedir=$ac_optarg ;; - - -localstatedir | --localstatedir | --localstatedi | --localstated \ - | --localstate | --localstat | --localsta | --localst | --locals) - ac_prev=localstatedir ;; - -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ - | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) - localstatedir=$ac_optarg ;; - - -mandir | --mandir | --mandi | --mand | --man | --ma | --m) - ac_prev=mandir ;; - -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) - mandir=$ac_optarg ;; - - -nfp | --nfp | --nf) - # Obsolete; use --without-fp. - with_fp=no ;; - - -no-create | --no-create | --no-creat | --no-crea | --no-cre \ - | --no-cr | --no-c | -n) - no_create=yes ;; - - -no-recursion | --no-recursion | --no-recursio | --no-recursi \ - | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) - no_recursion=yes ;; - - -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ - | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ - | --oldin | --oldi | --old | --ol | --o) - ac_prev=oldincludedir ;; - -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ - | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ - | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) - oldincludedir=$ac_optarg ;; - - -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) - ac_prev=prefix ;; - -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) - prefix=$ac_optarg ;; - - -program-prefix | --program-prefix | --program-prefi | --program-pref \ - | --program-pre | --program-pr | --program-p) - ac_prev=program_prefix ;; - -program-prefix=* | --program-prefix=* | --program-prefi=* \ - | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) - program_prefix=$ac_optarg ;; - - -program-suffix | --program-suffix | --program-suffi | --program-suff \ - | --program-suf | --program-su | --program-s) - ac_prev=program_suffix ;; - -program-suffix=* | --program-suffix=* | --program-suffi=* \ - | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) - program_suffix=$ac_optarg ;; - - -program-transform-name | --program-transform-name \ - | --program-transform-nam | --program-transform-na \ - | --program-transform-n | --program-transform- \ - | --program-transform | --program-transfor \ - | --program-transfo | --program-transf \ - | --program-trans | --program-tran \ - | --progr-tra | --program-tr | --program-t) - ac_prev=program_transform_name ;; - -program-transform-name=* | --program-transform-name=* \ - | --program-transform-nam=* | --program-transform-na=* \ - | --program-transform-n=* | --program-transform-=* \ - | --program-transform=* | --program-transfor=* \ - | --program-transfo=* | --program-transf=* \ - | --program-trans=* | --program-tran=* \ - | --progr-tra=* | --program-tr=* | --program-t=*) - program_transform_name=$ac_optarg ;; - - -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) - ac_prev=pdfdir ;; - -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) - pdfdir=$ac_optarg ;; - - -psdir | --psdir | --psdi | --psd | --ps) - ac_prev=psdir ;; - -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) - psdir=$ac_optarg ;; - - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil) - silent=yes ;; - - -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) - ac_prev=sbindir ;; - -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ - | --sbi=* | --sb=*) - sbindir=$ac_optarg ;; - - -sharedstatedir | --sharedstatedir | --sharedstatedi \ - | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ - | --sharedst | --shareds | --shared | --share | --shar \ - | --sha | --sh) - ac_prev=sharedstatedir ;; - -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ - | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ - | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ - | --sha=* | --sh=*) - sharedstatedir=$ac_optarg ;; - - -site | --site | --sit) - ac_prev=site ;; - -site=* | --site=* | --sit=*) - site=$ac_optarg ;; - - -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) - ac_prev=srcdir ;; - -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) - srcdir=$ac_optarg ;; - - -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ - | --syscon | --sysco | --sysc | --sys | --sy) - ac_prev=sysconfdir ;; - -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ - | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) - sysconfdir=$ac_optarg ;; - - -target | --target | --targe | --targ | --tar | --ta | --t) - ac_prev=target_alias ;; - -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) - target_alias=$ac_optarg ;; - - -v | -verbose | --verbose | --verbos | --verbo | --verb) - verbose=yes ;; - - -version | --version | --versio | --versi | --vers | -V) - ac_init_version=: ;; - - -with-* | --with-*) - ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null && - { echo "$as_me: error: invalid package name: $ac_package" >&2 - { (exit 1); exit 1; }; } - ac_package=`echo $ac_package | sed 's/[-.]/_/g'` - eval with_$ac_package=\$ac_optarg ;; - - -without-* | --without-*) - ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null && - { echo "$as_me: error: invalid package name: $ac_package" >&2 - { (exit 1); exit 1; }; } - ac_package=`echo $ac_package | sed 's/[-.]/_/g'` - eval with_$ac_package=no ;; - - --x) - # Obsolete; use --with-x. - with_x=yes ;; - - -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ - | --x-incl | --x-inc | --x-in | --x-i) - ac_prev=x_includes ;; - -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ - | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) - x_includes=$ac_optarg ;; - - -x-libraries | --x-libraries | --x-librarie | --x-librari \ - | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) - ac_prev=x_libraries ;; - -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ - | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) - x_libraries=$ac_optarg ;; - - -*) { echo "$as_me: error: unrecognized option: $ac_option -Try \`$0 --help' for more information." >&2 - { (exit 1); exit 1; }; } - ;; - - *=*) - ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` - # Reject names that are not valid shell variable names. - expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && - { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 - { (exit 1); exit 1; }; } - eval $ac_envvar=\$ac_optarg - export $ac_envvar ;; - - *) - # FIXME: should be removed in autoconf 3.0. - echo "$as_me: WARNING: you should use --build, --host, --target" >&2 - expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && - echo "$as_me: WARNING: invalid host type: $ac_option" >&2 - : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} - ;; - - esac -done - -if test -n "$ac_prev"; then - ac_option=--`echo $ac_prev | sed 's/_/-/g'` - { echo "$as_me: error: missing argument to $ac_option" >&2 - { (exit 1); exit 1; }; } -fi - -# Be sure to have absolute directory names. -for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ - datadir sysconfdir sharedstatedir localstatedir includedir \ - oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ - libdir localedir mandir -do - eval ac_val=\$$ac_var - case $ac_val in - [\\/$]* | ?:[\\/]* ) continue;; - NONE | '' ) case $ac_var in *prefix ) continue;; esac;; - esac - { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 - { (exit 1); exit 1; }; } -done - -# There might be people who depend on the old broken behavior: `$host' -# used to hold the argument of --host etc. -# FIXME: To remove some day. -build=$build_alias -host=$host_alias -target=$target_alias - -# FIXME: To remove some day. -if test "x$host_alias" != x; then - if test "x$build_alias" = x; then - cross_compiling=maybe - echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. - If a cross compiler is detected then cross compile mode will be used." >&2 - elif test "x$build_alias" != "x$host_alias"; then - cross_compiling=yes - fi -fi - -ac_tool_prefix= -test -n "$host_alias" && ac_tool_prefix=$host_alias- - -test "$silent" = yes && exec 6>/dev/null - - -ac_pwd=`pwd` && test -n "$ac_pwd" && -ac_ls_di=`ls -di .` && -ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || - { echo "$as_me: error: Working directory cannot be determined" >&2 - { (exit 1); exit 1; }; } -test "X$ac_ls_di" = "X$ac_pwd_ls_di" || - { echo "$as_me: error: pwd does not report name of working directory" >&2 - { (exit 1); exit 1; }; } - - -# Find the source files, if location was not specified. -if test -z "$srcdir"; then - ac_srcdir_defaulted=yes - # Try the directory containing this script, then the parent directory. - ac_confdir=`$as_dirname -- "$0" || -$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$0" : 'X\(//\)[^/]' \| \ - X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)' \| . 2>/dev/null || -echo X"$0" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - srcdir=$ac_confdir - if test ! -r "$srcdir/$ac_unique_file"; then - srcdir=.. - fi -else - ac_srcdir_defaulted=no -fi -if test ! -r "$srcdir/$ac_unique_file"; then - test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." - { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 - { (exit 1); exit 1; }; } -fi -ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" -ac_abs_confdir=`( - cd "$srcdir" && test -r "./$ac_unique_file" || { echo "$as_me: error: $ac_msg" >&2 - { (exit 1); exit 1; }; } - pwd)` -# When building in place, set srcdir=. -if test "$ac_abs_confdir" = "$ac_pwd"; then - srcdir=. -fi -# Remove unnecessary trailing slashes from srcdir. -# Double slashes in file names in object file debugging info -# mess up M-x gdb in Emacs. -case $srcdir in -*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; -esac -for ac_var in $ac_precious_vars; do - eval ac_env_${ac_var}_set=\${${ac_var}+set} - eval ac_env_${ac_var}_value=\$${ac_var} - eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} - eval ac_cv_env_${ac_var}_value=\$${ac_var} -done - -# -# Report the --help message. -# -if test "$ac_init_help" = "long"; then - # Omit some internal or obsolete options to make the list less imposing. - # This message is too long to be a string in the A/UX 3.1 sh. - cat <<_ACEOF -\`configure' configures Concurrent Versions System (CVS) 1.11.22.1 to adapt to many kinds of systems. - -Usage: $0 [OPTION]... [VAR=VALUE]... - -To assign environment variables (e.g., CC, CFLAGS...), specify them as -VAR=VALUE. See below for descriptions of some of the useful variables. - -Defaults for the options are specified in brackets. - -Configuration: - -h, --help display this help and exit - --help=short display options specific to this package - --help=recursive display the short help of all the included packages - -V, --version display version information and exit - -q, --quiet, --silent do not print \`checking...' messages - --cache-file=FILE cache test results in FILE [disabled] - -C, --config-cache alias for \`--cache-file=config.cache' - -n, --no-create do not create output files - --srcdir=DIR find the sources in DIR [configure dir or \`..'] - -Installation directories: - --prefix=PREFIX install architecture-independent files in PREFIX - [$ac_default_prefix] - --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX - [PREFIX] - -By default, \`make install' will install all the files in -\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify -an installation prefix other than \`$ac_default_prefix' using \`--prefix', -for instance \`--prefix=\$HOME'. - -For better control, use the options below. - -Fine tuning of the installation directories: - --bindir=DIR user executables [EPREFIX/bin] - --sbindir=DIR system admin executables [EPREFIX/sbin] - --libexecdir=DIR program executables [EPREFIX/libexec] - --sysconfdir=DIR read-only single-machine data [PREFIX/etc] - --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] - --localstatedir=DIR modifiable single-machine data [PREFIX/var] - --libdir=DIR object code libraries [EPREFIX/lib] - --includedir=DIR C header files [PREFIX/include] - --oldincludedir=DIR C header files for non-gcc [/usr/include] - --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] - --datadir=DIR read-only architecture-independent data [DATAROOTDIR] - --infodir=DIR info documentation [DATAROOTDIR/info] - --localedir=DIR locale-dependent data [DATAROOTDIR/locale] - --mandir=DIR man documentation [DATAROOTDIR/man] - --docdir=DIR documentation root [DATAROOTDIR/doc/cvs] - --htmldir=DIR html documentation [DOCDIR] - --dvidir=DIR dvi documentation [DOCDIR] - --pdfdir=DIR pdf documentation [DOCDIR] - --psdir=DIR ps documentation [DOCDIR] -_ACEOF - - cat <<\_ACEOF - -Program names: - --program-prefix=PREFIX prepend PREFIX to installed program names - --program-suffix=SUFFIX append SUFFIX to installed program names - --program-transform-name=PROGRAM run sed PROGRAM on installed program names -_ACEOF -fi - -if test -n "$ac_init_help"; then - case $ac_init_help in - short | recursive ) echo "Configuration of Concurrent Versions System (CVS) 1.11.22.1:";; - esac - cat <<\_ACEOF - -Optional Features: - --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) - --enable-FEATURE[=ARG] include FEATURE [ARG=yes] - --enable-maintainer-mode enable make rules and dependencies not useful - (and sometimes confusing) to the casual installer - --disable-dependency-tracking speeds up one-time build - --enable-dependency-tracking do not reject slow dependency extractors - --enable-cvs-ndbm Use the NDBM library distributed with CVS rather - than attempting to use a system NDBM library. - Disabling this may not work. (default) - --disable-mmap Don't mmap RCS files - --enable-client Include code for running as a remote client - (default) - --enable-password-authenticated-client - Enable pserver as a remote access method in the CVS - client (default) - --enable-server Include code for running as a server (default) - --enable-server-flow-control - If you are working with a large remote repository - and a 'cvs checkout' is swamping your network and - memory, define these to enable flow control. You may - optionally pass a low water mark in bytes and a high - water mark in bytes, separated by commas. (default - is enabled 1M,2M) - --enable-case-sensitivity - Force CVS to expect a case sensitive file system. - Enabling this on a case insensitive system should - have little effect on the server or client - operation, though client users may ocassionally be - suprised that the CVS server appears to be case - sensitive. Disabling this for a case sensitive - server disables server support for case insensitive - clients, which can confuse all users of case - insensitive clients contacting the server. Disabling - this for a case sensitive client will cause the - client to ask servers to behave case insensitively, - which could cause confusion for users, but also - probably no real harm. (default autoselects based on - the case sensitivity of the file system containing - the current working directory) - --enable-encryption Enable encryption support (disabled by default) - --enable-force-editor When committing or importing files, you must enter a - log message. Normally, you can do this either via - the -m flag on the command line, the -F flag on the - command line, or an editor will be started for you. - If you like to use logging templates (the rcsinfo - file within the $CVSROOT/CVSROOT directory), you - might want to force people to use the editor even if - they specify a message with -m or -F. - --enable-force-editor will cause the -m or -F - message to be appended to the temp file when the - editor is started. (disabled by default) - --enable-rootcommit Allow the root user to commit files (disabled by - default) - -Optional Packages: - --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] - --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) - --with-krb4 Kerberos 4 directory (default /usr/kerberos) - --with-gssapi GSSAPI directory (default autoselects) - --with-editor The default text editor CVS should use for log - messages (default autoselects) - --with-ssh The default remote shell CVS will use for :extssh: - transport (default autodetects) - --with-rsh The default remote shell CVS will use for :ext: - transport (default autodetects) - --with-tmpdir The temporary directory CVS should use as a default - (default autoselects) - --with-umask Set the umask CVS will use by default in the - repository (default 002) - --with-cvs-admin-group=GROUP - The CVS admin command is restricted to the members - of this group. If this group does not exist, all - users are allowed to run CVS admin. To disable the - CVS admin command for all users, create an empty - group by specifying the --with-cvs-admin-group= - option. To disable access control for CVS admin, run - configure with the --without-cvs-admin-group option. - (default 'cvsadmin') - -Some influential environment variables: - CC C compiler command - CFLAGS C compiler flags - LDFLAGS linker flags, e.g. -L if you have libraries in a - nonstandard directory - LIBS libraries to pass to the linker, e.g. -l - CPPFLAGS C/C++/Objective C preprocessor flags, e.g. -I if - you have headers in a nonstandard directory - CPP C preprocessor - YACC The `Yet Another C Compiler' implementation to use. Defaults to - the first program found out of: `bison -y', `byacc', `yacc'. - YFLAGS The list of arguments that will be passed by default to $YACC. - This script will default YFLAGS to the empty string to avoid a - default value of `-d' given by some make applications. - EDITOR The text editor CVS will use by default for log messages. - -Use these variables to override the choices made by `configure' or to help -it to find libraries and programs with nonstandard names/locations. - -Report bugs to . -_ACEOF -ac_status=$? -fi - -if test "$ac_init_help" = "recursive"; then - # If there are subdirs, report their specific --help. - for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue - test -d "$ac_dir" || continue - ac_builddir=. - -case "$ac_dir" in -.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; -*) - ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` - # A ".." for each directory in $ac_dir_suffix. - ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'` - case $ac_top_builddir_sub in - "") ac_top_builddir_sub=. ac_top_build_prefix= ;; - *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; - esac ;; -esac -ac_abs_top_builddir=$ac_pwd -ac_abs_builddir=$ac_pwd$ac_dir_suffix -# for backward compatibility: -ac_top_builddir=$ac_top_build_prefix - -case $srcdir in - .) # We are building in place. - ac_srcdir=. - ac_top_srcdir=$ac_top_builddir_sub - ac_abs_top_srcdir=$ac_pwd ;; - [\\/]* | ?:[\\/]* ) # Absolute name. - ac_srcdir=$srcdir$ac_dir_suffix; - ac_top_srcdir=$srcdir - ac_abs_top_srcdir=$srcdir ;; - *) # Relative name. - ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix - ac_top_srcdir=$ac_top_build_prefix$srcdir - ac_abs_top_srcdir=$ac_pwd/$srcdir ;; -esac -ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix - - cd "$ac_dir" || { ac_status=$?; continue; } - # Check for guested configure. - if test -f "$ac_srcdir/configure.gnu"; then - echo && - $SHELL "$ac_srcdir/configure.gnu" --help=recursive - elif test -f "$ac_srcdir/configure"; then - echo && - $SHELL "$ac_srcdir/configure" --help=recursive - else - echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 - fi || ac_status=$? - cd "$ac_pwd" || { ac_status=$?; break; } - done -fi - -test -n "$ac_init_help" && exit $ac_status -if $ac_init_version; then - cat <<\_ACEOF -Concurrent Versions System (CVS) configure 1.11.22.1 -generated by GNU Autoconf 2.61 - -Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, -2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. -This configure script is free software; the Free Software Foundation -gives unlimited permission to copy, distribute and modify it. -_ACEOF - exit -fi -cat >config.log <<_ACEOF -This file contains any messages produced by compilers while -running configure, to aid debugging if configure makes a mistake. - -It was created by Concurrent Versions System (CVS) $as_me 1.11.22.1, which was -generated by GNU Autoconf 2.61. Invocation command line was - - $ $0 $@ - -_ACEOF -exec 5>>config.log -{ -cat <<_ASUNAME -## --------- ## -## Platform. ## -## --------- ## - -hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` -uname -m = `(uname -m) 2>/dev/null || echo unknown` -uname -r = `(uname -r) 2>/dev/null || echo unknown` -uname -s = `(uname -s) 2>/dev/null || echo unknown` -uname -v = `(uname -v) 2>/dev/null || echo unknown` - -/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` -/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` - -/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` -/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` -/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` -/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` -/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` -/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` -/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` - -_ASUNAME - -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - echo "PATH: $as_dir" -done -IFS=$as_save_IFS - -} >&5 - -cat >&5 <<_ACEOF - - -## ----------- ## -## Core tests. ## -## ----------- ## - -_ACEOF - - -# Keep a trace of the command line. -# Strip out --no-create and --no-recursion so they do not pile up. -# Strip out --silent because we don't want to record it for future runs. -# Also quote any args containing shell meta-characters. -# Make two passes to allow for proper duplicate-argument suppression. -ac_configure_args= -ac_configure_args0= -ac_configure_args1= -ac_must_keep_next=false -for ac_pass in 1 2 -do - for ac_arg - do - case $ac_arg in - -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil) - continue ;; - *\'*) - ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; - esac - case $ac_pass in - 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; - 2) - ac_configure_args1="$ac_configure_args1 '$ac_arg'" - if test $ac_must_keep_next = true; then - ac_must_keep_next=false # Got value, back to normal. - else - case $ac_arg in - *=* | --config-cache | -C | -disable-* | --disable-* \ - | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ - | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ - | -with-* | --with-* | -without-* | --without-* | --x) - case "$ac_configure_args0 " in - "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; - esac - ;; - -* ) ac_must_keep_next=true ;; - esac - fi - ac_configure_args="$ac_configure_args '$ac_arg'" - ;; - esac - done -done -$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } -$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; } - -# When interrupted or exit'd, cleanup temporary files, and complete -# config.log. We remove comments because anyway the quotes in there -# would cause problems or look ugly. -# WARNING: Use '\'' to represent an apostrophe within the trap. -# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. -trap 'exit_status=$? - # Save into config.log some information that might help in debugging. - { - echo - - cat <<\_ASBOX -## ---------------- ## -## Cache variables. ## -## ---------------- ## -_ASBOX - echo - # The following way of writing the cache mishandles newlines in values, -( - for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do - eval ac_val=\$$ac_var - case $ac_val in #( - *${as_nl}*) - case $ac_var in #( - *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5 -echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;; - esac - case $ac_var in #( - _ | IFS | as_nl) ;; #( - *) $as_unset $ac_var ;; - esac ;; - esac - done - (set) 2>&1 | - case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( - *${as_nl}ac_space=\ *) - sed -n \ - "s/'\''/'\''\\\\'\'''\''/g; - s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" - ;; #( - *) - sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" - ;; - esac | - sort -) - echo - - cat <<\_ASBOX -## ----------------- ## -## Output variables. ## -## ----------------- ## -_ASBOX - echo - for ac_var in $ac_subst_vars - do - eval ac_val=\$$ac_var - case $ac_val in - *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; - esac - echo "$ac_var='\''$ac_val'\''" - done | sort - echo - - if test -n "$ac_subst_files"; then - cat <<\_ASBOX -## ------------------- ## -## File substitutions. ## -## ------------------- ## -_ASBOX - echo - for ac_var in $ac_subst_files - do - eval ac_val=\$$ac_var - case $ac_val in - *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; - esac - echo "$ac_var='\''$ac_val'\''" - done | sort - echo - fi - - if test -s confdefs.h; then - cat <<\_ASBOX -## ----------- ## -## confdefs.h. ## -## ----------- ## -_ASBOX - echo - cat confdefs.h - echo - fi - test "$ac_signal" != 0 && - echo "$as_me: caught signal $ac_signal" - echo "$as_me: exit $exit_status" - } >&5 - rm -f core *.core core.conftest.* && - rm -f -r conftest* confdefs* conf$$* $ac_clean_files && - exit $exit_status -' 0 -for ac_signal in 1 2 13 15; do - trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal -done -ac_signal=0 - -# confdefs.h avoids OS command line length limits that DEFS can exceed. -rm -f -r conftest* confdefs.h - -# Predefined preprocessor variables. - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_NAME "$PACKAGE_NAME" -_ACEOF - - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_TARNAME "$PACKAGE_TARNAME" -_ACEOF - - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_VERSION "$PACKAGE_VERSION" -_ACEOF - - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_STRING "$PACKAGE_STRING" -_ACEOF - - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" -_ACEOF - - -# Let the site file select an alternate cache file if it wants to. -# Prefer explicitly selected file to automatically selected ones. -if test -n "$CONFIG_SITE"; then - set x "$CONFIG_SITE" -elif test "x$prefix" != xNONE; then - set x "$prefix/share/config.site" "$prefix/etc/config.site" -else - set x "$ac_default_prefix/share/config.site" \ - "$ac_default_prefix/etc/config.site" -fi -shift -for ac_site_file -do - if test -r "$ac_site_file"; then - { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 -echo "$as_me: loading site script $ac_site_file" >&6;} - sed 's/^/| /' "$ac_site_file" >&5 - . "$ac_site_file" - fi -done - -if test -r "$cache_file"; then - # Some versions of bash will fail to source /dev/null (special - # files actually), so we avoid doing that. - if test -f "$cache_file"; then - { echo "$as_me:$LINENO: loading cache $cache_file" >&5 -echo "$as_me: loading cache $cache_file" >&6;} - case $cache_file in - [\\/]* | ?:[\\/]* ) . "$cache_file";; - *) . "./$cache_file";; - esac - fi -else - { echo "$as_me:$LINENO: creating cache $cache_file" >&5 -echo "$as_me: creating cache $cache_file" >&6;} - >$cache_file -fi - -ac_header_list="$ac_header_list utime.h" -# Check that the precious variables saved in the cache have kept the same -# value. -ac_cache_corrupted=false -for ac_var in $ac_precious_vars; do - eval ac_old_set=\$ac_cv_env_${ac_var}_set - eval ac_new_set=\$ac_env_${ac_var}_set - eval ac_old_val=\$ac_cv_env_${ac_var}_value - eval ac_new_val=\$ac_env_${ac_var}_value - case $ac_old_set,$ac_new_set in - set,) - { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 -echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} - ac_cache_corrupted=: ;; - ,set) - { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 -echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} - ac_cache_corrupted=: ;; - ,);; - *) - if test "x$ac_old_val" != "x$ac_new_val"; then - { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 -echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} - { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 -echo "$as_me: former value: $ac_old_val" >&2;} - { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 -echo "$as_me: current value: $ac_new_val" >&2;} - ac_cache_corrupted=: - fi;; - esac - # Pass precious variables to config.status. - if test "$ac_new_set" = set; then - case $ac_new_val in - *\'*) ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; - *) ac_arg=$ac_var=$ac_new_val ;; - esac - case " $ac_configure_args " in - *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. - *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; - esac - fi -done -if $ac_cache_corrupted; then - { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 -echo "$as_me: error: changes in the environment can compromise the build" >&2;} - { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 -echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} - { (exit 1); exit 1; }; } -fi - - - - - - - - - - - - - - - - - - - - - - - - - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - - -am__api_version='1.10' - -ac_aux_dir= -for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do - if test -f "$ac_dir/install-sh"; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/install-sh -c" - break - elif test -f "$ac_dir/install.sh"; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/install.sh -c" - break - elif test -f "$ac_dir/shtool"; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/shtool install -c" - break - fi -done -if test -z "$ac_aux_dir"; then - { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&5 -echo "$as_me: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&2;} - { (exit 1); exit 1; }; } -fi - -# These three variables are undocumented and unsupported, -# and are intended to be withdrawn in a future Autoconf release. -# They can cause serious problems if a builder's source tree is in a directory -# whose full name contains unusual characters. -ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. -ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. -ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. - - -# Find a good install program. We prefer a C program (faster), -# so one script is as good as another. But avoid the broken or -# incompatible versions: -# SysV /etc/install, /usr/sbin/install -# SunOS /usr/etc/install -# IRIX /sbin/install -# AIX /bin/install -# AmigaOS /C/install, which installs bootblocks on floppy discs -# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag -# AFS /usr/afsws/bin/install, which mishandles nonexistent args -# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" -# OS/2's system install, which has a completely different semantic -# ./install, which can be erroneously created by make from ./install.sh. -{ echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 -echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6; } -if test -z "$INSTALL"; then -if test "${ac_cv_path_install+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - # Account for people who put trailing slashes in PATH elements. -case $as_dir/ in - ./ | .// | /cC/* | \ - /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ - ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \ - /usr/ucb/* ) ;; - *) - # OSF1 and SCO ODT 3.0 have their own names for install. - # Don't use installbsd from OSF since it installs stuff as root - # by default. - for ac_prog in ginstall scoinst install; do - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then - if test $ac_prog = install && - grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then - # AIX install. It has an incompatible calling convention. - : - elif test $ac_prog = install && - grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then - # program-specific install script used by HP pwplus--don't use. - : - else - ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" - break 3 - fi - fi - done - done - ;; -esac -done -IFS=$as_save_IFS - - -fi - if test "${ac_cv_path_install+set}" = set; then - INSTALL=$ac_cv_path_install - else - # As a last resort, use the slow shell script. Don't cache a - # value for INSTALL within a source directory, because that will - # break other packages using the cache if that directory is - # removed, or if the value is a relative name. - INSTALL=$ac_install_sh - fi -fi -{ echo "$as_me:$LINENO: result: $INSTALL" >&5 -echo "${ECHO_T}$INSTALL" >&6; } - -# Use test -z because SunOS4 sh mishandles braces in ${var-val}. -# It thinks the first close brace ends the variable substitution. -test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' - -test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' - -test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' - -{ echo "$as_me:$LINENO: checking whether build environment is sane" >&5 -echo $ECHO_N "checking whether build environment is sane... $ECHO_C" >&6; } -# Just in case -sleep 1 -echo timestamp > conftest.file -# Do `set' in a subshell so we don't clobber the current shell's -# arguments. Must try -L first in case configure is actually a -# symlink; some systems play weird games with the mod time of symlinks -# (eg FreeBSD returns the mod time of the symlink's containing -# directory). -if ( - set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null` - if test "$*" = "X"; then - # -L didn't work. - set X `ls -t $srcdir/configure conftest.file` - fi - rm -f conftest.file - if test "$*" != "X $srcdir/configure conftest.file" \ - && test "$*" != "X conftest.file $srcdir/configure"; then - - # If neither matched, then we have a broken ls. This can happen - # if, for instance, CONFIG_SHELL is bash and it inherits a - # broken ls alias from the environment. This has actually - # happened. Such a system could not be considered "sane". - { { echo "$as_me:$LINENO: error: ls -t appears to fail. Make sure there is not a broken -alias in your environment" >&5 -echo "$as_me: error: ls -t appears to fail. Make sure there is not a broken -alias in your environment" >&2;} - { (exit 1); exit 1; }; } - fi - - test "$2" = conftest.file - ) -then - # Ok. - : -else - { { echo "$as_me:$LINENO: error: newly created file is older than distributed files! -Check your system clock" >&5 -echo "$as_me: error: newly created file is older than distributed files! -Check your system clock" >&2;} - { (exit 1); exit 1; }; } -fi -{ echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6; } -test "$program_prefix" != NONE && - program_transform_name="s&^&$program_prefix&;$program_transform_name" -# Use a double $ so make ignores it. -test "$program_suffix" != NONE && - program_transform_name="s&\$&$program_suffix&;$program_transform_name" -# Double any \ or $. echo might interpret backslashes. -# By default was `s,x,x', remove it if useless. -cat <<\_ACEOF >conftest.sed -s/[\\$]/&&/g;s/;s,x,x,$// -_ACEOF -program_transform_name=`echo $program_transform_name | sed -f conftest.sed` -rm -f conftest.sed - -# expand $ac_aux_dir to an absolute path -am_aux_dir=`cd $ac_aux_dir && pwd` - -test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing" -# Use eval to expand $SHELL -if eval "$MISSING --run true"; then - am_missing_run="$MISSING --run " -else - am_missing_run= - { echo "$as_me:$LINENO: WARNING: \`missing' script is too old or missing" >&5 -echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;} -fi - -{ echo "$as_me:$LINENO: checking for a thread-safe mkdir -p" >&5 -echo $ECHO_N "checking for a thread-safe mkdir -p... $ECHO_C" >&6; } -if test -z "$MKDIR_P"; then - if test "${ac_cv_path_mkdir+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_prog in mkdir gmkdir; do - for ac_exec_ext in '' $ac_executable_extensions; do - { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; } || continue - case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( - 'mkdir (GNU coreutils) '* | \ - 'mkdir (coreutils) '* | \ - 'mkdir (fileutils) '4.1*) - ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext - break 3;; - esac - done - done -done -IFS=$as_save_IFS - -fi - - if test "${ac_cv_path_mkdir+set}" = set; then - MKDIR_P="$ac_cv_path_mkdir -p" - else - # As a last resort, use the slow shell script. Don't cache a - # value for MKDIR_P within a source directory, because that will - # break other packages using the cache if that directory is - # removed, or if the value is a relative name. - test -d ./--version && rmdir ./--version - MKDIR_P="$ac_install_sh -d" - fi -fi -{ echo "$as_me:$LINENO: result: $MKDIR_P" >&5 -echo "${ECHO_T}$MKDIR_P" >&6; } - -mkdir_p="$MKDIR_P" -case $mkdir_p in - [\\/$]* | ?:[\\/]*) ;; - */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; -esac - -for ac_prog in gawk mawk nawk awk -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } -if test "${ac_cv_prog_AWK+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$AWK"; then - ac_cv_prog_AWK="$AWK" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_prog_AWK="$ac_prog" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done -IFS=$as_save_IFS - -fi -fi -AWK=$ac_cv_prog_AWK -if test -n "$AWK"; then - { echo "$as_me:$LINENO: result: $AWK" >&5 -echo "${ECHO_T}$AWK" >&6; } -else - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } -fi - - - test -n "$AWK" && break -done - -{ echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5 -echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6; } -set x ${MAKE-make}; ac_make=`echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` -if { as_var=ac_cv_prog_make_${ac_make}_set; eval "test \"\${$as_var+set}\" = set"; }; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.make <<\_ACEOF -SHELL = /bin/sh -all: - @echo '@@@%%%=$(MAKE)=@@@%%%' -_ACEOF -# GNU make sometimes prints "make[1]: Entering...", which would confuse us. -case `${MAKE-make} -f conftest.make 2>/dev/null` in - *@@@%%%=?*=@@@%%%*) - eval ac_cv_prog_make_${ac_make}_set=yes;; - *) - eval ac_cv_prog_make_${ac_make}_set=no;; -esac -rm -f conftest.make -fi -if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then - { echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6; } - SET_MAKE= -else - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } - SET_MAKE="MAKE=${MAKE-make}" -fi - -rm -rf .tst 2>/dev/null -mkdir .tst 2>/dev/null -if test -d .tst; then - am__leading_dot=. -else - am__leading_dot=_ -fi -rmdir .tst 2>/dev/null - -if test "`cd $srcdir && pwd`" != "`pwd`"; then - # Use -I$(srcdir) only when $(srcdir) != ., so that make's output - # is not polluted with repeated "-I." - am__isrc=' -I$(srcdir)' - # test to see if srcdir already configured - if test -f $srcdir/config.status; then - { { echo "$as_me:$LINENO: error: source directory already configured; run \"make distclean\" there first" >&5 -echo "$as_me: error: source directory already configured; run \"make distclean\" there first" >&2;} - { (exit 1); exit 1; }; } - fi -fi - -# test whether we have cygpath -if test -z "$CYGPATH_W"; then - if (cygpath --version) >/dev/null 2>/dev/null; then - CYGPATH_W='cygpath -w' - else - CYGPATH_W=echo - fi -fi - - -# Define the identity of the package. - PACKAGE='cvs' - VERSION='1.11.22.1' - - -# Some tools Automake needs. - -ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} - - -AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} - - -AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} - - -AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} - - -MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} - -install_sh=${install_sh-"\$(SHELL) $am_aux_dir/install-sh"} - -# Installed binaries are usually stripped using `strip' when the user -# run `make install-strip'. However `strip' might not be the right -# tool to use in cross-compilation environments, therefore Automake -# will honor the `STRIP' environment variable to overrule this program. -if test "$cross_compiling" != no; then - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. -set dummy ${ac_tool_prefix}strip; ac_word=$2 -{ echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } -if test "${ac_cv_prog_STRIP+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$STRIP"; then - ac_cv_prog_STRIP="$STRIP" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_prog_STRIP="${ac_tool_prefix}strip" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done -IFS=$as_save_IFS - -fi -fi -STRIP=$ac_cv_prog_STRIP -if test -n "$STRIP"; then - { echo "$as_me:$LINENO: result: $STRIP" >&5 -echo "${ECHO_T}$STRIP" >&6; } -else - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_STRIP"; then - ac_ct_STRIP=$STRIP - # Extract the first word of "strip", so it can be a program name with args. -set dummy strip; ac_word=$2 -{ echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } -if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$ac_ct_STRIP"; then - ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_prog_ac_ct_STRIP="strip" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done -IFS=$as_save_IFS - -fi -fi -ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP -if test -n "$ac_ct_STRIP"; then - { echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5 -echo "${ECHO_T}$ac_ct_STRIP" >&6; } -else - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } -fi - - if test "x$ac_ct_STRIP" = x; then - STRIP=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools -whose name does not start with the host triplet. If you think this -configuration is useful to you, please write to autoconf@gnu.org." >&5 -echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools -whose name does not start with the host triplet. If you think this -configuration is useful to you, please write to autoconf@gnu.org." >&2;} -ac_tool_warned=yes ;; -esac - STRIP=$ac_ct_STRIP - fi -else - STRIP="$ac_cv_prog_STRIP" -fi - -fi -INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" - -# We need awk for the "check" target. The system "awk" is bad on -# some platforms. -# Always define AMTAR for backward compatibility. - -AMTAR=${AMTAR-"${am_missing_run}tar"} - -am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -' - - - - - - - -if test "x$prefix" = xNONE; then - echo $ECHO_N "checking for prefix by $ECHO_C" >&6 - # Extract the first word of "cvs", so it can be a program name with args. -set dummy cvs; ac_word=$2 -{ echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } -if test "${ac_cv_path_ac_prefix_program+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - case $ac_prefix_program in - [\\/]* | ?:[\\/]*) - ac_cv_path_ac_prefix_program="$ac_prefix_program" # Let the user override the test with a path. - ;; - *) - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_path_ac_prefix_program="$as_dir/$ac_word$ac_exec_ext" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done -IFS=$as_save_IFS - - ;; -esac -fi -ac_prefix_program=$ac_cv_path_ac_prefix_program -if test -n "$ac_prefix_program"; then - { echo "$as_me:$LINENO: result: $ac_prefix_program" >&5 -echo "${ECHO_T}$ac_prefix_program" >&6; } -else - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } -fi - - - if test -n "$ac_prefix_program"; then - prefix=`$as_dirname -- "$ac_prefix_program" || -$as_expr X"$ac_prefix_program" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$ac_prefix_program" : 'X\(//\)[^/]' \| \ - X"$ac_prefix_program" : 'X\(//\)$' \| \ - X"$ac_prefix_program" : 'X\(/\)' \| . 2>/dev/null || -echo X"$ac_prefix_program" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - prefix=`$as_dirname -- "$prefix" || -$as_expr X"$prefix" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$prefix" : 'X\(//\)[^/]' \| \ - X"$prefix" : 'X\(//\)$' \| \ - X"$prefix" : 'X\(/\)' \| . 2>/dev/null || -echo X"$prefix" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - fi -fi - -ac_config_headers="$ac_config_headers config.h" - -{ echo "$as_me:$LINENO: checking whether to enable maintainer-specific portions of Makefiles" >&5 -echo $ECHO_N "checking whether to enable maintainer-specific portions of Makefiles... $ECHO_C" >&6; } - # Check whether --enable-maintainer-mode was given. -if test "${enable_maintainer_mode+set}" = set; then - enableval=$enable_maintainer_mode; USE_MAINTAINER_MODE=$enableval -else - USE_MAINTAINER_MODE=no -fi - - { echo "$as_me:$LINENO: result: $USE_MAINTAINER_MODE" >&5 -echo "${ECHO_T}$USE_MAINTAINER_MODE" >&6; } - if test $USE_MAINTAINER_MODE = yes; then - MAINTAINER_MODE_TRUE= - MAINTAINER_MODE_FALSE='#' -else - MAINTAINER_MODE_TRUE='#' - MAINTAINER_MODE_FALSE= -fi - - MAINT=$MAINTAINER_MODE_TRUE - - - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. -set dummy ${ac_tool_prefix}gcc; ac_word=$2 -{ echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } -if test "${ac_cv_prog_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_prog_CC="${ac_tool_prefix}gcc" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done -IFS=$as_save_IFS - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { echo "$as_me:$LINENO: result: $CC" >&5 -echo "${ECHO_T}$CC" >&6; } -else - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_CC"; then - ac_ct_CC=$CC - # Extract the first word of "gcc", so it can be a program name with args. -set dummy gcc; ac_word=$2 -{ echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } -if test "${ac_cv_prog_ac_ct_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$ac_ct_CC"; then - ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_prog_ac_ct_CC="gcc" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done -IFS=$as_save_IFS - -fi -fi -ac_ct_CC=$ac_cv_prog_ac_ct_CC -if test -n "$ac_ct_CC"; then - { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 -echo "${ECHO_T}$ac_ct_CC" >&6; } -else - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } -fi - - if test "x$ac_ct_CC" = x; then - CC="" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools -whose name does not start with the host triplet. If you think this -configuration is useful to you, please write to autoconf@gnu.org." >&5 -echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools -whose name does not start with the host triplet. If you think this -configuration is useful to you, please write to autoconf@gnu.org." >&2;} -ac_tool_warned=yes ;; -esac - CC=$ac_ct_CC - fi -else - CC="$ac_cv_prog_CC" -fi - -if test -z "$CC"; then - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. -set dummy ${ac_tool_prefix}cc; ac_word=$2 -{ echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } -if test "${ac_cv_prog_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_prog_CC="${ac_tool_prefix}cc" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done -IFS=$as_save_IFS - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { echo "$as_me:$LINENO: result: $CC" >&5 -echo "${ECHO_T}$CC" >&6; } -else - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } -fi - - - fi -fi -if test -z "$CC"; then - # Extract the first word of "cc", so it can be a program name with args. -set dummy cc; ac_word=$2 -{ echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } -if test "${ac_cv_prog_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else - ac_prog_rejected=no -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then - if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then - ac_prog_rejected=yes - continue - fi - ac_cv_prog_CC="cc" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done -IFS=$as_save_IFS - -if test $ac_prog_rejected = yes; then - # We found a bogon in the path, so make sure we never use it. - set dummy $ac_cv_prog_CC - shift - if test $# != 0; then - # We chose a different compiler from the bogus one. - # However, it has the same basename, so the bogon will be chosen - # first if we set CC to just the basename; use the full file name. - shift - ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" - fi -fi -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { echo "$as_me:$LINENO: result: $CC" >&5 -echo "${ECHO_T}$CC" >&6; } -else - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } -fi - - -fi -if test -z "$CC"; then - if test -n "$ac_tool_prefix"; then - for ac_prog in cl.exe - do - # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. -set dummy $ac_tool_prefix$ac_prog; ac_word=$2 -{ echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } -if test "${ac_cv_prog_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_prog_CC="$ac_tool_prefix$ac_prog" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done -IFS=$as_save_IFS - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { echo "$as_me:$LINENO: result: $CC" >&5 -echo "${ECHO_T}$CC" >&6; } -else - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } -fi - - - test -n "$CC" && break - done -fi -if test -z "$CC"; then - ac_ct_CC=$CC - for ac_prog in cl.exe -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } -if test "${ac_cv_prog_ac_ct_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$ac_ct_CC"; then - ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_prog_ac_ct_CC="$ac_prog" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done -IFS=$as_save_IFS - -fi -fi -ac_ct_CC=$ac_cv_prog_ac_ct_CC -if test -n "$ac_ct_CC"; then - { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 -echo "${ECHO_T}$ac_ct_CC" >&6; } -else - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } -fi - - - test -n "$ac_ct_CC" && break -done - - if test "x$ac_ct_CC" = x; then - CC="" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools -whose name does not start with the host triplet. If you think this -configuration is useful to you, please write to autoconf@gnu.org." >&5 -echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools -whose name does not start with the host triplet. If you think this -configuration is useful to you, please write to autoconf@gnu.org." >&2;} -ac_tool_warned=yes ;; -esac - CC=$ac_ct_CC - fi -fi - -fi - - -test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH -See \`config.log' for more details." >&5 -echo "$as_me: error: no acceptable C compiler found in \$PATH -See \`config.log' for more details." >&2;} - { (exit 1); exit 1; }; } - -# Provide some information about the compiler. -echo "$as_me:$LINENO: checking for C compiler version" >&5 -ac_compiler=`set X $ac_compile; echo $2` -{ (ac_try="$ac_compiler --version >&5" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compiler --version >&5") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } -{ (ac_try="$ac_compiler -v >&5" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compiler -v >&5") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } -{ (ac_try="$ac_compiler -V >&5" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compiler -V >&5") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } - -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -ac_clean_files_save=$ac_clean_files -ac_clean_files="$ac_clean_files a.out a.exe b.out" -# Try to create an executable without -o first, disregard a.out. -# It will help us diagnose broken compilers, and finding out an intuition -# of exeext. -{ echo "$as_me:$LINENO: checking for C compiler default output file name" >&5 -echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6; } -ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` -# -# List of possible output files, starting from the most likely. -# The algorithm is not robust to junk in `.', hence go to wildcards (a.*) -# only as a last resort. b.out is created by i960 compilers. -ac_files='a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out' -# -# The IRIX 6 linker writes into existing files which may not be -# executable, retaining their permissions. Remove them first so a -# subsequent execution test works. -ac_rmfiles= -for ac_file in $ac_files -do - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;; - * ) ac_rmfiles="$ac_rmfiles $ac_file";; - esac -done -rm -f $ac_rmfiles - -if { (ac_try="$ac_link_default" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link_default") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; then - # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. -# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' -# in a Makefile. We should not override ac_cv_exeext if it was cached, -# so that the user can short-circuit this test for compilers unknown to -# Autoconf. -for ac_file in $ac_files '' -do - test -f "$ac_file" || continue - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) - ;; - [ab].out ) - # We found the default executable, but exeext='' is most - # certainly right. - break;; - *.* ) - if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; - then :; else - ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` - fi - # We set ac_cv_exeext here because the later test for it is not - # safe: cross compilers may not add the suffix if given an `-o' - # argument, so we may need to know it at that point already. - # Even if this section looks crufty: it has the advantage of - # actually working. - break;; - * ) - break;; - esac -done -test "$ac_cv_exeext" = no && ac_cv_exeext= - -else - ac_file='' -fi - -{ echo "$as_me:$LINENO: result: $ac_file" >&5 -echo "${ECHO_T}$ac_file" >&6; } -if test -z "$ac_file"; then - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -{ { echo "$as_me:$LINENO: error: C compiler cannot create executables -See \`config.log' for more details." >&5 -echo "$as_me: error: C compiler cannot create executables -See \`config.log' for more details." >&2;} - { (exit 77); exit 77; }; } -fi - -ac_exeext=$ac_cv_exeext - -# Check that the compiler produces executables we can run. If not, either -# the compiler is broken, or we cross compile. -{ echo "$as_me:$LINENO: checking whether the C compiler works" >&5 -echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6; } -# FIXME: These cross compiler hacks should be removed for Autoconf 3.0 -# If not cross compiling, check that we can run a simple program. -if test "$cross_compiling" != yes; then - if { ac_try='./$ac_file' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - cross_compiling=no - else - if test "$cross_compiling" = maybe; then - cross_compiling=yes - else - { { echo "$as_me:$LINENO: error: cannot run C compiled programs. -If you meant to cross compile, use \`--host'. -See \`config.log' for more details." >&5 -echo "$as_me: error: cannot run C compiled programs. -If you meant to cross compile, use \`--host'. -See \`config.log' for more details." >&2;} - { (exit 1); exit 1; }; } - fi - fi -fi -{ echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6; } - -rm -f a.out a.exe conftest$ac_cv_exeext b.out -ac_clean_files=$ac_clean_files_save -# Check that the compiler produces executables we can run. If not, either -# the compiler is broken, or we cross compile. -{ echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 -echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6; } -{ echo "$as_me:$LINENO: result: $cross_compiling" >&5 -echo "${ECHO_T}$cross_compiling" >&6; } - -{ echo "$as_me:$LINENO: checking for suffix of executables" >&5 -echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6; } -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; then - # If both `conftest.exe' and `conftest' are `present' (well, observable) -# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will -# work properly (i.e., refer to `conftest.exe'), while it won't with -# `rm'. -for ac_file in conftest.exe conftest conftest.*; do - test -f "$ac_file" || continue - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;; - *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` - break;; - * ) break;; - esac -done -else - { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link -See \`config.log' for more details." >&5 -echo "$as_me: error: cannot compute suffix of executables: cannot compile and link -See \`config.log' for more details." >&2;} - { (exit 1); exit 1; }; } -fi - -rm -f conftest$ac_cv_exeext -{ echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 -echo "${ECHO_T}$ac_cv_exeext" >&6; } - -rm -f conftest.$ac_ext -EXEEXT=$ac_cv_exeext -ac_exeext=$EXEEXT -{ echo "$as_me:$LINENO: checking for suffix of object files" >&5 -echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6; } -if test "${ac_cv_objext+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.o conftest.obj -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; then - for ac_file in conftest.o conftest.obj conftest.*; do - test -f "$ac_file" || continue; - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf ) ;; - *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` - break;; - esac -done -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile -See \`config.log' for more details." >&5 -echo "$as_me: error: cannot compute suffix of object files: cannot compile -See \`config.log' for more details." >&2;} - { (exit 1); exit 1; }; } -fi - -rm -f conftest.$ac_cv_objext conftest.$ac_ext -fi -{ echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 -echo "${ECHO_T}$ac_cv_objext" >&6; } -OBJEXT=$ac_cv_objext -ac_objext=$OBJEXT -{ echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 -echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6; } -if test "${ac_cv_c_compiler_gnu+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ -#ifndef __GNUC__ - choke me -#endif - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - ac_compiler_gnu=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_compiler_gnu=no -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -ac_cv_c_compiler_gnu=$ac_compiler_gnu - -fi -{ echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 -echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6; } -GCC=`test $ac_compiler_gnu = yes && echo yes` -ac_test_CFLAGS=${CFLAGS+set} -ac_save_CFLAGS=$CFLAGS -{ echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 -echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6; } -if test "${ac_cv_prog_cc_g+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_save_c_werror_flag=$ac_c_werror_flag - ac_c_werror_flag=yes - ac_cv_prog_cc_g=no - CFLAGS="-g" - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - ac_cv_prog_cc_g=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - CFLAGS="" - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - : -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_c_werror_flag=$ac_save_c_werror_flag - CFLAGS="-g" - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - ac_cv_prog_cc_g=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - ac_c_werror_flag=$ac_save_c_werror_flag -fi -{ echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 -echo "${ECHO_T}$ac_cv_prog_cc_g" >&6; } -if test "$ac_test_CFLAGS" = set; then - CFLAGS=$ac_save_CFLAGS -elif test $ac_cv_prog_cc_g = yes; then - if test "$GCC" = yes; then - CFLAGS="-g -O2" - else - CFLAGS="-g" - fi -else - if test "$GCC" = yes; then - CFLAGS="-O2" - else - CFLAGS= - fi -fi -{ echo "$as_me:$LINENO: checking for $CC option to accept ISO C89" >&5 -echo $ECHO_N "checking for $CC option to accept ISO C89... $ECHO_C" >&6; } -if test "${ac_cv_prog_cc_c89+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_cv_prog_cc_c89=no -ac_save_CC=$CC -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -#include -#include -#include -/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ -struct buf { int x; }; -FILE * (*rcsopen) (struct buf *, struct stat *, int); -static char *e (p, i) - char **p; - int i; -{ - return p[i]; -} -static char *f (char * (*g) (char **, int), char **p, ...) -{ - char *s; - va_list v; - va_start (v,p); - s = g (p, va_arg (v,int)); - va_end (v); - return s; -} - -/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has - function prototypes and stuff, but not '\xHH' hex character constants. - These don't provoke an error unfortunately, instead are silently treated - as 'x'. The following induces an error, until -std is added to get - proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an - array size at least. It's necessary to write '\x00'==0 to get something - that's true only with -std. */ -int osf4_cc_array ['\x00' == 0 ? 1 : -1]; - -/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters - inside strings and character constants. */ -#define FOO(x) 'x' -int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; - -int test (int i, double x); -struct s1 {int (*f) (int a);}; -struct s2 {int (*f) (double a);}; -int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); -int argc; -char **argv; -int -main () -{ -return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; - ; - return 0; -} -_ACEOF -for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ - -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" -do - CC="$ac_save_CC $ac_arg" - rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - ac_cv_prog_cc_c89=$ac_arg -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - -fi - -rm -f core conftest.err conftest.$ac_objext - test "x$ac_cv_prog_cc_c89" != "xno" && break -done -rm -f conftest.$ac_ext -CC=$ac_save_CC - -fi -# AC_CACHE_VAL -case "x$ac_cv_prog_cc_c89" in - x) - { echo "$as_me:$LINENO: result: none needed" >&5 -echo "${ECHO_T}none needed" >&6; } ;; - xno) - { echo "$as_me:$LINENO: result: unsupported" >&5 -echo "${ECHO_T}unsupported" >&6; } ;; - *) - CC="$CC $ac_cv_prog_cc_c89" - { echo "$as_me:$LINENO: result: $ac_cv_prog_cc_c89" >&5 -echo "${ECHO_T}$ac_cv_prog_cc_c89" >&6; } ;; -esac - - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu -DEPDIR="${am__leading_dot}deps" - -ac_config_commands="$ac_config_commands depfiles" - - -am_make=${MAKE-make} -cat > confinc << 'END' -am__doit: - @echo done -.PHONY: am__doit -END -# If we don't find an include directive, just comment out the code. -{ echo "$as_me:$LINENO: checking for style of include used by $am_make" >&5 -echo $ECHO_N "checking for style of include used by $am_make... $ECHO_C" >&6; } -am__include="#" -am__quote= -_am_result=none -# First try GNU make style include. -echo "include confinc" > confmf -# We grep out `Entering directory' and `Leaving directory' -# messages which can occur if `w' ends up in MAKEFLAGS. -# In particular we don't look at `^make:' because GNU make might -# be invoked under some other name (usually "gmake"), in which -# case it prints its new name instead of `make'. -if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then - am__include=include - am__quote= - _am_result=GNU -fi -# Now try BSD make style include. -if test "$am__include" = "#"; then - echo '.include "confinc"' > confmf - if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then - am__include=.include - am__quote="\"" - _am_result=BSD - fi -fi - - -{ echo "$as_me:$LINENO: result: $_am_result" >&5 -echo "${ECHO_T}$_am_result" >&6; } -rm -f confinc confmf - -# Check whether --enable-dependency-tracking was given. -if test "${enable_dependency_tracking+set}" = set; then - enableval=$enable_dependency_tracking; -fi - -if test "x$enable_dependency_tracking" != xno; then - am_depcomp="$ac_aux_dir/depcomp" - AMDEPBACKSLASH='\' -fi - if test "x$enable_dependency_tracking" != xno; then - AMDEP_TRUE= - AMDEP_FALSE='#' -else - AMDEP_TRUE='#' - AMDEP_FALSE= -fi - - - -depcc="$CC" am_compiler_list= - -{ echo "$as_me:$LINENO: checking dependency style of $depcc" >&5 -echo $ECHO_N "checking dependency style of $depcc... $ECHO_C" >&6; } -if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then - # We make a subdir and do the tests there. Otherwise we can end up - # making bogus files that we don't know about and never remove. For - # instance it was reported that on HP-UX the gcc test will end up - # making a dummy file named `D' -- because `-MD' means `put the output - # in D'. - mkdir conftest.dir - # Copy depcomp to subdir because otherwise we won't find it if we're - # using a relative directory. - cp "$am_depcomp" conftest.dir - cd conftest.dir - # We will build objects and dependencies in a subdirectory because - # it helps to detect inapplicable dependency modes. For instance - # both Tru64's cc and ICC support -MD to output dependencies as a - # side effect of compilation, but ICC will put the dependencies in - # the current directory while Tru64 will put them in the object - # directory. - mkdir sub - - am_cv_CC_dependencies_compiler_type=none - if test "$am_compiler_list" = ""; then - am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` - fi - for depmode in $am_compiler_list; do - # Setup a source with many dependencies, because some compilers - # like to wrap large dependency lists on column 80 (with \), and - # we should not choose a depcomp mode which is confused by this. - # - # We need to recreate these files for each test, as the compiler may - # overwrite some of them when testing with obscure command lines. - # This happens at least with the AIX C compiler. - : > sub/conftest.c - for i in 1 2 3 4 5 6; do - echo '#include "conftst'$i'.h"' >> sub/conftest.c - # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with - # Solaris 8's {/usr,}/bin/sh. - touch sub/conftst$i.h - done - echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf - - case $depmode in - nosideeffect) - # after this tag, mechanisms are not by side-effect, so they'll - # only be used when explicitly requested - if test "x$enable_dependency_tracking" = xyes; then - continue - else - break - fi - ;; - none) break ;; - esac - # We check with `-c' and `-o' for the sake of the "dashmstdout" - # mode. It turns out that the SunPro C++ compiler does not properly - # handle `-M -o', and we need to detect this. - if depmode=$depmode \ - source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ - depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ - $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ - >/dev/null 2>conftest.err && - grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && - grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && - grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 && - ${MAKE-make} -s -f confmf > /dev/null 2>&1; then - # icc doesn't choke on unknown options, it will just issue warnings - # or remarks (even with -Werror). So we grep stderr for any message - # that says an option was ignored or not supported. - # When given -MP, icc 7.0 and 7.1 complain thusly: - # icc: Command line warning: ignoring option '-M'; no argument required - # The diagnosis changed in icc 8.0: - # icc: Command line remark: option '-MP' not supported - if (grep 'ignoring option' conftest.err || - grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else - am_cv_CC_dependencies_compiler_type=$depmode - break - fi - fi - done - - cd .. - rm -rf conftest.dir -else - am_cv_CC_dependencies_compiler_type=none -fi - -fi -{ echo "$as_me:$LINENO: result: $am_cv_CC_dependencies_compiler_type" >&5 -echo "${ECHO_T}$am_cv_CC_dependencies_compiler_type" >&6; } -CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type - - if - test "x$enable_dependency_tracking" != xno \ - && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then - am__fastdepCC_TRUE= - am__fastdepCC_FALSE='#' -else - am__fastdepCC_TRUE='#' - am__fastdepCC_FALSE= -fi - - -if test "x$CC" != xcc; then - { echo "$as_me:$LINENO: checking whether $CC and cc understand -c and -o together" >&5 -echo $ECHO_N "checking whether $CC and cc understand -c and -o together... $ECHO_C" >&6; } -else - { echo "$as_me:$LINENO: checking whether cc understands -c and -o together" >&5 -echo $ECHO_N "checking whether cc understands -c and -o together... $ECHO_C" >&6; } -fi -set dummy $CC; ac_cc=`echo $2 | - sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'` -if { as_var=ac_cv_prog_cc_${ac_cc}_c_o; eval "test \"\${$as_var+set}\" = set"; }; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -# Make sure it works both with $CC and with simple cc. -# We do the test twice because some compilers refuse to overwrite an -# existing .o file with -o, though they will create one. -ac_try='$CC -c conftest.$ac_ext -o conftest2.$ac_objext >&5' -rm -f conftest2.* -if { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - test -f conftest2.$ac_objext && { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; -then - eval ac_cv_prog_cc_${ac_cc}_c_o=yes - if test "x$CC" != xcc; then - # Test first that cc exists at all. - if { ac_try='cc -c conftest.$ac_ext >&5' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_try='cc -c conftest.$ac_ext -o conftest2.$ac_objext >&5' - rm -f conftest2.* - if { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - test -f conftest2.$ac_objext && { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; - then - # cc works too. - : - else - # cc exists but doesn't like -o. - eval ac_cv_prog_cc_${ac_cc}_c_o=no - fi - fi - fi -else - eval ac_cv_prog_cc_${ac_cc}_c_o=no -fi -rm -f core conftest* - -fi -if eval test \$ac_cv_prog_cc_${ac_cc}_c_o = yes; then - { echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6; } -else - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } - -cat >>confdefs.h <<\_ACEOF -#define NO_MINUS_C_MINUS_O 1 -_ACEOF - -fi - -# FIXME: we rely on the cache variable name because -# there is no other way. -set dummy $CC -ac_cc=`echo $2 | sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'` -if eval "test \"`echo '$ac_cv_prog_cc_'${ac_cc}_c_o`\" != yes"; then - # Losing compiler, so override with the script. - # FIXME: It is wrong to rewrite CC. - # But if we don't then we get into trouble of one sort or another. - # A longer-term fix would be to have automake use am__CC in this case, - # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" - CC="$am_aux_dir/compile $CC" -fi - - - - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu -{ echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5 -echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6; } -# On Suns, sometimes $CPP names a directory. -if test -n "$CPP" && test -d "$CPP"; then - CPP= -fi -if test -z "$CPP"; then - if test "${ac_cv_prog_CPP+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - # Double quotes because CPP needs to be expanded - for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" - do - ac_preproc_ok=false -for ac_c_preproc_warn_flag in '' yes -do - # Use a header file that comes with gcc, so configuring glibc - # with a fresh cross-compiler works. - # Prefer to if __STDC__ is defined, since - # exists even on freestanding compilers. - # On the NeXT, cc -E runs the code through the compiler's parser, - # not just through cpp. "Syntax error" is here to catch this case. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#ifdef __STDC__ -# include -#else -# include -#endif - Syntax error -_ACEOF -if { (ac_try="$ac_cpp conftest.$ac_ext" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null && { - test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || - test ! -s conftest.err - }; then - : -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - # Broken: fails on valid input. -continue -fi - -rm -f conftest.err conftest.$ac_ext - - # OK, works on sane cases. Now check whether nonexistent headers - # can be detected and how. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -_ACEOF -if { (ac_try="$ac_cpp conftest.$ac_ext" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null && { - test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || - test ! -s conftest.err - }; then - # Broken: success on invalid input. -continue -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - # Passes both tests. -ac_preproc_ok=: -break -fi - -rm -f conftest.err conftest.$ac_ext - -done -# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.err conftest.$ac_ext -if $ac_preproc_ok; then - break -fi - - done - ac_cv_prog_CPP=$CPP - -fi - CPP=$ac_cv_prog_CPP -else - ac_cv_prog_CPP=$CPP -fi -{ echo "$as_me:$LINENO: result: $CPP" >&5 -echo "${ECHO_T}$CPP" >&6; } -ac_preproc_ok=false -for ac_c_preproc_warn_flag in '' yes -do - # Use a header file that comes with gcc, so configuring glibc - # with a fresh cross-compiler works. - # Prefer to if __STDC__ is defined, since - # exists even on freestanding compilers. - # On the NeXT, cc -E runs the code through the compiler's parser, - # not just through cpp. "Syntax error" is here to catch this case. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#ifdef __STDC__ -# include -#else -# include -#endif - Syntax error -_ACEOF -if { (ac_try="$ac_cpp conftest.$ac_ext" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null && { - test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || - test ! -s conftest.err - }; then - : -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - # Broken: fails on valid input. -continue -fi - -rm -f conftest.err conftest.$ac_ext - - # OK, works on sane cases. Now check whether nonexistent headers - # can be detected and how. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -_ACEOF -if { (ac_try="$ac_cpp conftest.$ac_ext" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null && { - test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || - test ! -s conftest.err - }; then - # Broken: success on invalid input. -continue -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - # Passes both tests. -ac_preproc_ok=: -break -fi - -rm -f conftest.err conftest.$ac_ext - -done -# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.err conftest.$ac_ext -if $ac_preproc_ok; then - : -else - { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check -See \`config.log' for more details." >&5 -echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check -See \`config.log' for more details." >&2;} - { (exit 1); exit 1; }; } -fi - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - -{ echo "$as_me:$LINENO: checking for grep that handles long lines and -e" >&5 -echo $ECHO_N "checking for grep that handles long lines and -e... $ECHO_C" >&6; } -if test "${ac_cv_path_GREP+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - # Extract the first word of "grep ggrep" to use in msg output -if test -z "$GREP"; then -set dummy grep ggrep; ac_prog_name=$2 -if test "${ac_cv_path_GREP+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_path_GREP_found=false -# Loop through the user's path and test for each of PROGNAME-LIST -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_prog in grep ggrep; do - for ac_exec_ext in '' $ac_executable_extensions; do - ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" - { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue - # Check for GNU ac_path_GREP and select it if it is found. - # Check for GNU $ac_path_GREP -case `"$ac_path_GREP" --version 2>&1` in -*GNU*) - ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; -*) - ac_count=0 - echo $ECHO_N "0123456789$ECHO_C" >"conftest.in" - while : - do - cat "conftest.in" "conftest.in" >"conftest.tmp" - mv "conftest.tmp" "conftest.in" - cp "conftest.in" "conftest.nl" - echo 'GREP' >> "conftest.nl" - "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break - diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break - ac_count=`expr $ac_count + 1` - if test $ac_count -gt ${ac_path_GREP_max-0}; then - # Best one so far, save it but keep looking for a better one - ac_cv_path_GREP="$ac_path_GREP" - ac_path_GREP_max=$ac_count - fi - # 10*(2^10) chars as input seems more than enough - test $ac_count -gt 10 && break - done - rm -f conftest.in conftest.tmp conftest.nl conftest.out;; -esac - - - $ac_path_GREP_found && break 3 - done -done - -done -IFS=$as_save_IFS - - -fi - -GREP="$ac_cv_path_GREP" -if test -z "$GREP"; then - { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 -echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} - { (exit 1); exit 1; }; } -fi - -else - ac_cv_path_GREP=$GREP -fi - - -fi -{ echo "$as_me:$LINENO: result: $ac_cv_path_GREP" >&5 -echo "${ECHO_T}$ac_cv_path_GREP" >&6; } - GREP="$ac_cv_path_GREP" - - -{ echo "$as_me:$LINENO: checking for egrep" >&5 -echo $ECHO_N "checking for egrep... $ECHO_C" >&6; } -if test "${ac_cv_path_EGREP+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 - then ac_cv_path_EGREP="$GREP -E" - else - # Extract the first word of "egrep" to use in msg output -if test -z "$EGREP"; then -set dummy egrep; ac_prog_name=$2 -if test "${ac_cv_path_EGREP+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_path_EGREP_found=false -# Loop through the user's path and test for each of PROGNAME-LIST -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_prog in egrep; do - for ac_exec_ext in '' $ac_executable_extensions; do - ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" - { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue - # Check for GNU ac_path_EGREP and select it if it is found. - # Check for GNU $ac_path_EGREP -case `"$ac_path_EGREP" --version 2>&1` in -*GNU*) - ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; -*) - ac_count=0 - echo $ECHO_N "0123456789$ECHO_C" >"conftest.in" - while : - do - cat "conftest.in" "conftest.in" >"conftest.tmp" - mv "conftest.tmp" "conftest.in" - cp "conftest.in" "conftest.nl" - echo 'EGREP' >> "conftest.nl" - "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break - diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break - ac_count=`expr $ac_count + 1` - if test $ac_count -gt ${ac_path_EGREP_max-0}; then - # Best one so far, save it but keep looking for a better one - ac_cv_path_EGREP="$ac_path_EGREP" - ac_path_EGREP_max=$ac_count - fi - # 10*(2^10) chars as input seems more than enough - test $ac_count -gt 10 && break - done - rm -f conftest.in conftest.tmp conftest.nl conftest.out;; -esac - - - $ac_path_EGREP_found && break 3 - done -done - -done -IFS=$as_save_IFS - - -fi - -EGREP="$ac_cv_path_EGREP" -if test -z "$EGREP"; then - { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 -echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} - { (exit 1); exit 1; }; } -fi - -else - ac_cv_path_EGREP=$EGREP -fi - - - fi -fi -{ echo "$as_me:$LINENO: result: $ac_cv_path_EGREP" >&5 -echo "${ECHO_T}$ac_cv_path_EGREP" >&6; } - EGREP="$ac_cv_path_EGREP" - - - -{ echo "$as_me:$LINENO: checking for AIX" >&5 -echo $ECHO_N "checking for AIX... $ECHO_C" >&6; } -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#ifdef _AIX - yes -#endif - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "yes" >/dev/null 2>&1; then - { echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6; } -cat >>confdefs.h <<\_ACEOF -#define _ALL_SOURCE 1 -_ACEOF - -else - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } -fi -rm -f conftest* - - -{ echo "$as_me:$LINENO: checking for ANSI C header files" >&5 -echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6; } -if test "${ac_cv_header_stdc+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -#include -#include -#include - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - ac_cv_header_stdc=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_cv_header_stdc=no -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - -if test $ac_cv_header_stdc = yes; then - # SunOS 4.x string.h does not declare mem*, contrary to ANSI. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "memchr" >/dev/null 2>&1; then - : -else - ac_cv_header_stdc=no -fi -rm -f conftest* - -fi - -if test $ac_cv_header_stdc = yes; then - # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "free" >/dev/null 2>&1; then - : -else - ac_cv_header_stdc=no -fi -rm -f conftest* - -fi - -if test $ac_cv_header_stdc = yes; then - # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. - if test "$cross_compiling" = yes; then - : -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -#include -#if ((' ' & 0x0FF) == 0x020) -# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') -# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) -#else -# define ISLOWER(c) \ - (('a' <= (c) && (c) <= 'i') \ - || ('j' <= (c) && (c) <= 'r') \ - || ('s' <= (c) && (c) <= 'z')) -# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) -#endif - -#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) -int -main () -{ - int i; - for (i = 0; i < 256; i++) - if (XOR (islower (i), ISLOWER (i)) - || toupper (i) != TOUPPER (i)) - return 2; - return 0; -} -_ACEOF -rm -f conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - : -else - echo "$as_me: program exited with status $ac_status" >&5 -echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -( exit $ac_status ) -ac_cv_header_stdc=no -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext -fi - - -fi -fi -{ echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 -echo "${ECHO_T}$ac_cv_header_stdc" >&6; } -if test $ac_cv_header_stdc = yes; then - -cat >>confdefs.h <<\_ACEOF -#define STDC_HEADERS 1 -_ACEOF - -fi - -# On IRIX 5.3, sys/types and inttypes.h are conflicting. - - - - - - - - - -for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ - inttypes.h stdint.h unistd.h -do -as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` -{ echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } -if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default - -#include <$ac_header> -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - eval "$as_ac_Header=yes" -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - eval "$as_ac_Header=no" -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -ac_res=`eval echo '${'$as_ac_Header'}'` - { echo "$as_me:$LINENO: result: $ac_res" >&5 -echo "${ECHO_T}$ac_res" >&6; } -if test `eval echo '${'$as_ac_Header'}'` = yes; then - cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 -_ACEOF - -fi - -done - - -if test "${ac_cv_header_minix_config_h+set}" = set; then - { echo "$as_me:$LINENO: checking for minix/config.h" >&5 -echo $ECHO_N "checking for minix/config.h... $ECHO_C" >&6; } -if test "${ac_cv_header_minix_config_h+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -fi -{ echo "$as_me:$LINENO: result: $ac_cv_header_minix_config_h" >&5 -echo "${ECHO_T}$ac_cv_header_minix_config_h" >&6; } -else - # Is the header compilable? -{ echo "$as_me:$LINENO: checking minix/config.h usability" >&5 -echo $ECHO_N "checking minix/config.h usability... $ECHO_C" >&6; } -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -#include -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - ac_header_compiler=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_header_compiler=no -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -echo "${ECHO_T}$ac_header_compiler" >&6; } - -# Is the header present? -{ echo "$as_me:$LINENO: checking minix/config.h presence" >&5 -echo $ECHO_N "checking minix/config.h presence... $ECHO_C" >&6; } -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -_ACEOF -if { (ac_try="$ac_cpp conftest.$ac_ext" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null && { - test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || - test ! -s conftest.err - }; then - ac_header_preproc=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_header_preproc=no -fi - -rm -f conftest.err conftest.$ac_ext -{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -echo "${ECHO_T}$ac_header_preproc" >&6; } - -# So? What about this header? -case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in - yes:no: ) - { echo "$as_me:$LINENO: WARNING: minix/config.h: accepted by the compiler, rejected by the preprocessor!" >&5 -echo "$as_me: WARNING: minix/config.h: accepted by the compiler, rejected by the preprocessor!" >&2;} - { echo "$as_me:$LINENO: WARNING: minix/config.h: proceeding with the compiler's result" >&5 -echo "$as_me: WARNING: minix/config.h: proceeding with the compiler's result" >&2;} - ac_header_preproc=yes - ;; - no:yes:* ) - { echo "$as_me:$LINENO: WARNING: minix/config.h: present but cannot be compiled" >&5 -echo "$as_me: WARNING: minix/config.h: present but cannot be compiled" >&2;} - { echo "$as_me:$LINENO: WARNING: minix/config.h: check for missing prerequisite headers?" >&5 -echo "$as_me: WARNING: minix/config.h: check for missing prerequisite headers?" >&2;} - { echo "$as_me:$LINENO: WARNING: minix/config.h: see the Autoconf documentation" >&5 -echo "$as_me: WARNING: minix/config.h: see the Autoconf documentation" >&2;} - { echo "$as_me:$LINENO: WARNING: minix/config.h: section \"Present But Cannot Be Compiled\"" >&5 -echo "$as_me: WARNING: minix/config.h: section \"Present But Cannot Be Compiled\"" >&2;} - { echo "$as_me:$LINENO: WARNING: minix/config.h: proceeding with the preprocessor's result" >&5 -echo "$as_me: WARNING: minix/config.h: proceeding with the preprocessor's result" >&2;} - { echo "$as_me:$LINENO: WARNING: minix/config.h: in the future, the compiler will take precedence" >&5 -echo "$as_me: WARNING: minix/config.h: in the future, the compiler will take precedence" >&2;} - ( cat <<\_ASBOX -## --------------------------------- ## -## Report this to bug-cvs@nongnu.org ## -## --------------------------------- ## -_ASBOX - ) | sed "s/^/$as_me: WARNING: /" >&2 - ;; -esac -{ echo "$as_me:$LINENO: checking for minix/config.h" >&5 -echo $ECHO_N "checking for minix/config.h... $ECHO_C" >&6; } -if test "${ac_cv_header_minix_config_h+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_cv_header_minix_config_h=$ac_header_preproc -fi -{ echo "$as_me:$LINENO: result: $ac_cv_header_minix_config_h" >&5 -echo "${ECHO_T}$ac_cv_header_minix_config_h" >&6; } - -fi -if test $ac_cv_header_minix_config_h = yes; then - MINIX=yes -else - MINIX= -fi - - -if test "$MINIX" = yes; then - -cat >>confdefs.h <<\_ACEOF -#define _POSIX_SOURCE 1 -_ACEOF - - -cat >>confdefs.h <<\_ACEOF -#define _POSIX_1_SOURCE 2 -_ACEOF - - -cat >>confdefs.h <<\_ACEOF -#define _MINIX 1 -_ACEOF - -fi - - -# Find the posix library needed on INTERACTIVE UNIX (ISC) -{ echo "$as_me:$LINENO: checking for library containing strerror" >&5 -echo $ECHO_N "checking for library containing strerror... $ECHO_C" >&6; } -if test "${ac_cv_search_strerror+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_func_search_save_LIBS=$LIBS -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char strerror (); -int -main () -{ -return strerror (); - ; - return 0; -} -_ACEOF -for ac_lib in '' cposix; do - if test -z "$ac_lib"; then - ac_res="none required" - else - ac_res=-l$ac_lib - LIBS="-l$ac_lib $ac_func_search_save_LIBS" - fi - rm -f conftest.$ac_objext conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then - ac_cv_search_strerror=$ac_res -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - -fi - -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ - conftest$ac_exeext - if test "${ac_cv_search_strerror+set}" = set; then - break -fi -done -if test "${ac_cv_search_strerror+set}" = set; then - : -else - ac_cv_search_strerror=no -fi -rm conftest.$ac_ext -LIBS=$ac_func_search_save_LIBS -fi -{ echo "$as_me:$LINENO: result: $ac_cv_search_strerror" >&5 -echo "${ECHO_T}$ac_cv_search_strerror" >&6; } -ac_res=$ac_cv_search_strerror -if test "$ac_res" != no; then - test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" - -fi - - - -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. -set dummy ${ac_tool_prefix}ranlib; ac_word=$2 -{ echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } -if test "${ac_cv_prog_RANLIB+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$RANLIB"; then - ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done -IFS=$as_save_IFS - -fi -fi -RANLIB=$ac_cv_prog_RANLIB -if test -n "$RANLIB"; then - { echo "$as_me:$LINENO: result: $RANLIB" >&5 -echo "${ECHO_T}$RANLIB" >&6; } -else - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_RANLIB"; then - ac_ct_RANLIB=$RANLIB - # Extract the first word of "ranlib", so it can be a program name with args. -set dummy ranlib; ac_word=$2 -{ echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } -if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$ac_ct_RANLIB"; then - ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_prog_ac_ct_RANLIB="ranlib" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done -IFS=$as_save_IFS - -fi -fi -ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB -if test -n "$ac_ct_RANLIB"; then - { echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5 -echo "${ECHO_T}$ac_ct_RANLIB" >&6; } -else - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } -fi - - if test "x$ac_ct_RANLIB" = x; then - RANLIB=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools -whose name does not start with the host triplet. If you think this -configuration is useful to you, please write to autoconf@gnu.org." >&5 -echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools -whose name does not start with the host triplet. If you think this -configuration is useful to you, please write to autoconf@gnu.org." >&2;} -ac_tool_warned=yes ;; -esac - RANLIB=$ac_ct_RANLIB - fi -else - RANLIB="$ac_cv_prog_RANLIB" -fi - -for ac_prog in 'bison -y' byacc -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } -if test "${ac_cv_prog_YACC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$YACC"; then - ac_cv_prog_YACC="$YACC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_prog_YACC="$ac_prog" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done -IFS=$as_save_IFS - -fi -fi -YACC=$ac_cv_prog_YACC -if test -n "$YACC"; then - { echo "$as_me:$LINENO: result: $YACC" >&5 -echo "${ECHO_T}$YACC" >&6; } -else - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } -fi - - - test -n "$YACC" && break -done -test -n "$YACC" || YACC="yacc" - -{ echo "$as_me:$LINENO: checking whether ln -s works" >&5 -echo $ECHO_N "checking whether ln -s works... $ECHO_C" >&6; } -LN_S=$as_ln_s -if test "$LN_S" = "ln -s"; then - { echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6; } -else - { echo "$as_me:$LINENO: result: no, using $LN_S" >&5 -echo "${ECHO_T}no, using $LN_S" >&6; } -fi - - - -# Extract the first word of "perl", so it can be a program name with args. -set dummy perl; ac_word=$2 -{ echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } -if test "${ac_cv_path_PERL+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - case $PERL in - [\\/]* | ?:[\\/]*) - ac_cv_path_PERL="$PERL" # Let the user override the test with a path. - ;; - *) - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_path_PERL="$as_dir/$ac_word$ac_exec_ext" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done -IFS=$as_save_IFS - - test -z "$ac_cv_path_PERL" && ac_cv_path_PERL="no" - ;; -esac -fi -PERL=$ac_cv_path_PERL -if test -n "$PERL"; then - { echo "$as_me:$LINENO: result: $PERL" >&5 -echo "${ECHO_T}$PERL" >&6; } -else - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } -fi - - -# Extract the first word of "csh", so it can be a program name with args. -set dummy csh; ac_word=$2 -{ echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } -if test "${ac_cv_path_CSH+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - case $CSH in - [\\/]* | ?:[\\/]*) - ac_cv_path_CSH="$CSH" # Let the user override the test with a path. - ;; - *) - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_path_CSH="$as_dir/$ac_word$ac_exec_ext" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done -IFS=$as_save_IFS - - test -z "$ac_cv_path_CSH" && ac_cv_path_CSH="no" - ;; -esac -fi -CSH=$ac_cv_path_CSH -if test -n "$CSH"; then - { echo "$as_me:$LINENO: result: $CSH" >&5 -echo "${ECHO_T}$CSH" >&6; } -else - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } -fi - - -# for contrib/rcs2log.sh & src/cvsbug.in. -# Extract the first word of "mktemp", so it can be a program name with args. -set dummy mktemp; ac_word=$2 -{ echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } -if test "${ac_cv_path_MKTEMP+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - case $MKTEMP in - [\\/]* | ?:[\\/]*) - ac_cv_path_MKTEMP="$MKTEMP" # Let the user override the test with a path. - ;; - *) - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_path_MKTEMP="$as_dir/$ac_word$ac_exec_ext" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done -IFS=$as_save_IFS - - test -z "$ac_cv_path_MKTEMP" && ac_cv_path_MKTEMP="mktemp" - ;; -esac -fi -MKTEMP=$ac_cv_path_MKTEMP -if test -n "$MKTEMP"; then - { echo "$as_me:$LINENO: result: $MKTEMP" >&5 -echo "${ECHO_T}$MKTEMP" >&6; } -else - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } -fi - - -if test x"$MKTEMP" = xmktemp; then - MKTEMP_SH_FUNCTION=$srcdir/mktemp.sh -else - MKTEMP_SH_FUNCTION=/dev/null -fi - -# for src/cvsbug.in -# Extract the first word of "sendmail", so it can be a program name with args. -set dummy sendmail; ac_word=$2 -{ echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } -if test "${ac_cv_path_SENDMAIL+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - case $SENDMAIL in - [\\/]* | ?:[\\/]*) - ac_cv_path_SENDMAIL="$SENDMAIL" # Let the user override the test with a path. - ;; - *) - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -as_dummy="$PATH:/usr/sbin:/usr/lib" -for as_dir in $as_dummy -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_path_SENDMAIL="$as_dir/$ac_word$ac_exec_ext" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done -IFS=$as_save_IFS - - test -z "$ac_cv_path_SENDMAIL" && ac_cv_path_SENDMAIL="no" - ;; -esac -fi -SENDMAIL=$ac_cv_path_SENDMAIL -if test -n "$SENDMAIL"; then - { echo "$as_me:$LINENO: result: $SENDMAIL" >&5 -echo "${ECHO_T}$SENDMAIL" >&6; } -else - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } -fi - - -# For diff/util.c -# Extract the first word of "pr", so it can be a program name with args. -set dummy pr; ac_word=$2 -{ echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } -if test "${ac_cv_path_PR+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - case $PR in - [\\/]* | ?:[\\/]*) - ac_cv_path_PR="$PR" # Let the user override the test with a path. - ;; - *) - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_path_PR="$as_dir/$ac_word$ac_exec_ext" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done -IFS=$as_save_IFS - - test -z "$ac_cv_path_PR" && ac_cv_path_PR="no" - ;; -esac -fi -PR=$ac_cv_path_PR -if test -n "$PR"; then - { echo "$as_me:$LINENO: result: $PR" >&5 -echo "${ECHO_T}$PR" >&6; } -else - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } -fi - - -if test x"$PR" != xno; then - -cat >>confdefs.h <<_ACEOF -#define PR_PROGRAM "$PR" -_ACEOF - -fi - -missing_dir=`cd $ac_aux_dir && pwd` -glocs="$PATH:/usr/local/bin:/usr/contrib/bin:/usr/gnu/bin:/local/bin:/local/gnu/bin:/gnu/bin" -for ac_prog in groff roff -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } -if test "${ac_cv_path_ROFF+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - case $ROFF in - [\\/]* | ?:[\\/]*) - ac_cv_path_ROFF="$ROFF" # Let the user override the test with a path. - ;; - *) - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $glocs -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_path_ROFF="$as_dir/$ac_word$ac_exec_ext" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done -IFS=$as_save_IFS - - ;; -esac -fi -ROFF=$ac_cv_path_ROFF -if test -n "$ROFF"; then - { echo "$as_me:$LINENO: result: $ROFF" >&5 -echo "${ECHO_T}$ROFF" >&6; } -else - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } -fi - - - test -n "$ROFF" && break -done -test -n "$ROFF" || ROFF="$missing_dir/missing roff" - -# Extract the first word of "ps2pdf", so it can be a program name with args. -set dummy ps2pdf; ac_word=$2 -{ echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } -if test "${ac_cv_path_PS2PDF+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - case $PS2PDF in - [\\/]* | ?:[\\/]*) - ac_cv_path_PS2PDF="$PS2PDF" # Let the user override the test with a path. - ;; - *) - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_path_PS2PDF="$as_dir/$ac_word$ac_exec_ext" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done -IFS=$as_save_IFS - - test -z "$ac_cv_path_PS2PDF" && ac_cv_path_PS2PDF="$missing_dir/missing ps2pdf" - ;; -esac -fi -PS2PDF=$ac_cv_path_PS2PDF -if test -n "$PS2PDF"; then - { echo "$as_me:$LINENO: result: $PS2PDF" >&5 -echo "${ECHO_T}$PS2PDF" >&6; } -else - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } -fi - - -# Extract the first word of "texi2dvi", so it can be a program name with args. -set dummy texi2dvi; ac_word=$2 -{ echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } -if test "${ac_cv_path_TEXI2DVI+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - case $TEXI2DVI in - [\\/]* | ?:[\\/]*) - ac_cv_path_TEXI2DVI="$TEXI2DVI" # Let the user override the test with a path. - ;; - *) - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_path_TEXI2DVI="$as_dir/$ac_word$ac_exec_ext" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done -IFS=$as_save_IFS - - test -z "$ac_cv_path_TEXI2DVI" && ac_cv_path_TEXI2DVI="$missing_dir/missing texi2dvi" - ;; -esac -fi -TEXI2DVI=$ac_cv_path_TEXI2DVI -if test -n "$TEXI2DVI"; then - { echo "$as_me:$LINENO: result: $TEXI2DVI" >&5 -echo "${ECHO_T}$TEXI2DVI" >&6; } -else - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } -fi - - - -{ echo "$as_me:$LINENO: checking whether #! works in shell scripts" >&5 -echo $ECHO_N "checking whether #! works in shell scripts... $ECHO_C" >&6; } -if test "${ac_cv_sys_interpreter+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - echo '#! /bin/cat -exit 69 -' >conftest -chmod u+x conftest -(SHELL=/bin/sh; export SHELL; ./conftest >/dev/null 2>&1) -if test $? -ne 69; then - ac_cv_sys_interpreter=yes -else - ac_cv_sys_interpreter=no -fi -rm -f conftest -fi -{ echo "$as_me:$LINENO: result: $ac_cv_sys_interpreter" >&5 -echo "${ECHO_T}$ac_cv_sys_interpreter" >&6; } -interpval=$ac_cv_sys_interpreter - -if test X"$ac_cv_sys_interpreter" != X"yes" ; then - # silly trick to avoid problems in AC macros... - ac_msg='perl scripts using #! may not be invoked properly' - { echo "$as_me:$LINENO: WARNING: $ac_msg" >&5 -echo "$as_me: WARNING: $ac_msg" >&2;} -fi - -# BSD's logo is a devil for a reason, hey? -{ echo "$as_me:$LINENO: checking for BSD VPATH bug in make" >&5 -echo $ECHO_N "checking for BSD VPATH bug in make... $ECHO_C" >&6; } -if test "${ccvs_cv_bsd_make_vpath_bug+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test ! -d ac_test_dir ; then - { ac_try='mkdir ac_test_dir' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } -fi -cat >conftestmake <&2 -ac_test_dep: ac_test_dep_dep -EOF -touch ac_test_dir/ac_test_dep_dep -touch ac_test_dir/ac_test_dep -touch ac_test_target -# Don't know why, but the following test doesn't work under FreeBSD 4.2 -# without this sleep command -sleep 1 -if { ac_try='make -f conftestmake 2>&1 >/dev/null |grep ^BSD\ VPATH\ bug\ present\$ >/dev/null' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } ; then - ccvs_cv_bsd_make_vpath_bug=yes -else - ccvs_cv_bsd_make_vpath_bug=no -fi -{ ac_try='rm -rf ac_test_dir ac_test_target conftestmake' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } -fi -{ echo "$as_me:$LINENO: result: $ccvs_cv_bsd_make_vpath_bug" >&5 -echo "${ECHO_T}$ccvs_cv_bsd_make_vpath_bug" >&6; } -# We also don't need to worry about the bug when $srcdir = $builddir - if \ - test $ccvs_cv_bsd_make_vpath_bug = no \ - || test $srcdir = .; then - MAKE_TARGETS_IN_VPATH_TRUE= - MAKE_TARGETS_IN_VPATH_FALSE='#' -else - MAKE_TARGETS_IN_VPATH_TRUE='#' - MAKE_TARGETS_IN_VPATH_FALSE= -fi - - - - - - - -ac_header_dirent=no -for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h; do - as_ac_Header=`echo "ac_cv_header_dirent_$ac_hdr" | $as_tr_sh` -{ echo "$as_me:$LINENO: checking for $ac_hdr that defines DIR" >&5 -echo $ECHO_N "checking for $ac_hdr that defines DIR... $ECHO_C" >&6; } -if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -#include <$ac_hdr> - -int -main () -{ -if ((DIR *) 0) -return 0; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - eval "$as_ac_Header=yes" -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - eval "$as_ac_Header=no" -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -ac_res=`eval echo '${'$as_ac_Header'}'` - { echo "$as_me:$LINENO: result: $ac_res" >&5 -echo "${ECHO_T}$ac_res" >&6; } -if test `eval echo '${'$as_ac_Header'}'` = yes; then - cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_hdr" | $as_tr_cpp` 1 -_ACEOF - -ac_header_dirent=$ac_hdr; break -fi - -done -# Two versions of opendir et al. are in -ldir and -lx on SCO Xenix. -if test $ac_header_dirent = dirent.h; then - { echo "$as_me:$LINENO: checking for library containing opendir" >&5 -echo $ECHO_N "checking for library containing opendir... $ECHO_C" >&6; } -if test "${ac_cv_search_opendir+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_func_search_save_LIBS=$LIBS -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char opendir (); -int -main () -{ -return opendir (); - ; - return 0; -} -_ACEOF -for ac_lib in '' dir; do - if test -z "$ac_lib"; then - ac_res="none required" - else - ac_res=-l$ac_lib - LIBS="-l$ac_lib $ac_func_search_save_LIBS" - fi - rm -f conftest.$ac_objext conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then - ac_cv_search_opendir=$ac_res -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - -fi - -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ - conftest$ac_exeext - if test "${ac_cv_search_opendir+set}" = set; then - break -fi -done -if test "${ac_cv_search_opendir+set}" = set; then - : -else - ac_cv_search_opendir=no -fi -rm conftest.$ac_ext -LIBS=$ac_func_search_save_LIBS -fi -{ echo "$as_me:$LINENO: result: $ac_cv_search_opendir" >&5 -echo "${ECHO_T}$ac_cv_search_opendir" >&6; } -ac_res=$ac_cv_search_opendir -if test "$ac_res" != no; then - test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" - -fi - -else - { echo "$as_me:$LINENO: checking for library containing opendir" >&5 -echo $ECHO_N "checking for library containing opendir... $ECHO_C" >&6; } -if test "${ac_cv_search_opendir+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_func_search_save_LIBS=$LIBS -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char opendir (); -int -main () -{ -return opendir (); - ; - return 0; -} -_ACEOF -for ac_lib in '' x; do - if test -z "$ac_lib"; then - ac_res="none required" - else - ac_res=-l$ac_lib - LIBS="-l$ac_lib $ac_func_search_save_LIBS" - fi - rm -f conftest.$ac_objext conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then - ac_cv_search_opendir=$ac_res -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - -fi - -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ - conftest$ac_exeext - if test "${ac_cv_search_opendir+set}" = set; then - break -fi -done -if test "${ac_cv_search_opendir+set}" = set; then - : -else - ac_cv_search_opendir=no -fi -rm conftest.$ac_ext -LIBS=$ac_func_search_save_LIBS -fi -{ echo "$as_me:$LINENO: result: $ac_cv_search_opendir" >&5 -echo "${ECHO_T}$ac_cv_search_opendir" >&6; } -ac_res=$ac_cv_search_opendir -if test "$ac_res" != no; then - test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" - -fi - -fi - -{ echo "$as_me:$LINENO: checking for ANSI C header files" >&5 -echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6; } -if test "${ac_cv_header_stdc+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -#include -#include -#include - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - ac_cv_header_stdc=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_cv_header_stdc=no -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - -if test $ac_cv_header_stdc = yes; then - # SunOS 4.x string.h does not declare mem*, contrary to ANSI. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "memchr" >/dev/null 2>&1; then - : -else - ac_cv_header_stdc=no -fi -rm -f conftest* - -fi - -if test $ac_cv_header_stdc = yes; then - # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "free" >/dev/null 2>&1; then - : -else - ac_cv_header_stdc=no -fi -rm -f conftest* - -fi - -if test $ac_cv_header_stdc = yes; then - # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. - if test "$cross_compiling" = yes; then - : -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -#include -#if ((' ' & 0x0FF) == 0x020) -# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') -# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) -#else -# define ISLOWER(c) \ - (('a' <= (c) && (c) <= 'i') \ - || ('j' <= (c) && (c) <= 'r') \ - || ('s' <= (c) && (c) <= 'z')) -# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) -#endif - -#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) -int -main () -{ - int i; - for (i = 0; i < 256; i++) - if (XOR (islower (i), ISLOWER (i)) - || toupper (i) != TOUPPER (i)) - return 2; - return 0; -} -_ACEOF -rm -f conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - : -else - echo "$as_me: program exited with status $ac_status" >&5 -echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -( exit $ac_status ) -ac_cv_header_stdc=no -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext -fi - - -fi -fi -{ echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 -echo "${ECHO_T}$ac_cv_header_stdc" >&6; } -if test $ac_cv_header_stdc = yes; then - -cat >>confdefs.h <<\_ACEOF -#define STDC_HEADERS 1 -_ACEOF - -fi - -{ echo "$as_me:$LINENO: checking for sys/wait.h that is POSIX.1 compatible" >&5 -echo $ECHO_N "checking for sys/wait.h that is POSIX.1 compatible... $ECHO_C" >&6; } -if test "${ac_cv_header_sys_wait_h+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -#include -#ifndef WEXITSTATUS -# define WEXITSTATUS(stat_val) ((unsigned int) (stat_val) >> 8) -#endif -#ifndef WIFEXITED -# define WIFEXITED(stat_val) (((stat_val) & 255) == 0) -#endif - -int -main () -{ - int s; - wait (&s); - s = WIFEXITED (s) ? WEXITSTATUS (s) : 1; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - ac_cv_header_sys_wait_h=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_cv_header_sys_wait_h=no -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -{ echo "$as_me:$LINENO: result: $ac_cv_header_sys_wait_h" >&5 -echo "${ECHO_T}$ac_cv_header_sys_wait_h" >&6; } -if test $ac_cv_header_sys_wait_h = yes; then - -cat >>confdefs.h <<\_ACEOF -#define HAVE_SYS_WAIT_H 1 -_ACEOF - -fi - - - - - - - - - - - - - - - - - - - - -for ac_header in \ - errno.h \ - direct.h \ - fcntl.h \ - fnmatch.h \ - io.h \ - limits.h \ - memory.h \ - ndbm.h \ - string.h \ - syslog.h \ - sys/bsdtypes.h \ - sys/file.h \ - sys/param.h \ - sys/resource.h \ - sys/select.h \ - sys/time.h \ - sys/timeb.h \ - unistd.h \ - utime.h\ - -do -as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` -if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then - { echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } -if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -fi -ac_res=`eval echo '${'$as_ac_Header'}'` - { echo "$as_me:$LINENO: result: $ac_res" >&5 -echo "${ECHO_T}$ac_res" >&6; } -else - # Is the header compilable? -{ echo "$as_me:$LINENO: checking $ac_header usability" >&5 -echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -#include <$ac_header> -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - ac_header_compiler=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_header_compiler=no -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -echo "${ECHO_T}$ac_header_compiler" >&6; } - -# Is the header present? -{ echo "$as_me:$LINENO: checking $ac_header presence" >&5 -echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include <$ac_header> -_ACEOF -if { (ac_try="$ac_cpp conftest.$ac_ext" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null && { - test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || - test ! -s conftest.err - }; then - ac_header_preproc=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_header_preproc=no -fi - -rm -f conftest.err conftest.$ac_ext -{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -echo "${ECHO_T}$ac_header_preproc" >&6; } - -# So? What about this header? -case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in - yes:no: ) - { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 -echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 -echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} - ac_header_preproc=yes - ;; - no:yes:* ) - { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 -echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 -echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 -echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 -echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 -echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} - ( cat <<\_ASBOX -## --------------------------------- ## -## Report this to bug-cvs@nongnu.org ## -## --------------------------------- ## -_ASBOX - ) | sed "s/^/$as_me: WARNING: /" >&2 - ;; -esac -{ echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } -if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - eval "$as_ac_Header=\$ac_header_preproc" -fi -ac_res=`eval echo '${'$as_ac_Header'}'` - { echo "$as_me:$LINENO: result: $ac_res" >&5 -echo "${ECHO_T}$ac_res" >&6; } - -fi -if test `eval echo '${'$as_ac_Header'}'` = yes; then - cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 -_ACEOF - -fi - -done - -{ echo "$as_me:$LINENO: checking whether stat file-mode macros are broken" >&5 -echo $ECHO_N "checking whether stat file-mode macros are broken... $ECHO_C" >&6; } -if test "${ac_cv_header_stat_broken+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -#include - -#if defined S_ISBLK && defined S_IFDIR -extern char c1[S_ISBLK (S_IFDIR) ? -1 : 1]; -#endif - -#if defined S_ISBLK && defined S_IFCHR -extern char c2[S_ISBLK (S_IFCHR) ? -1 : 1]; -#endif - -#if defined S_ISLNK && defined S_IFREG -extern char c3[S_ISLNK (S_IFREG) ? -1 : 1]; -#endif - -#if defined S_ISSOCK && defined S_IFREG -extern char c4[S_ISSOCK (S_IFREG) ? -1 : 1]; -#endif - -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - ac_cv_header_stat_broken=no -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_cv_header_stat_broken=yes -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -{ echo "$as_me:$LINENO: result: $ac_cv_header_stat_broken" >&5 -echo "${ECHO_T}$ac_cv_header_stat_broken" >&6; } -if test $ac_cv_header_stat_broken = yes; then - -cat >>confdefs.h <<\_ACEOF -#define STAT_MACROS_BROKEN 1 -_ACEOF - -fi - -{ echo "$as_me:$LINENO: checking whether time.h and sys/time.h may both be included" >&5 -echo $ECHO_N "checking whether time.h and sys/time.h may both be included... $ECHO_C" >&6; } -if test "${ac_cv_header_time+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -#include -#include - -int -main () -{ -if ((struct tm *) 0) -return 0; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - ac_cv_header_time=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_cv_header_time=no -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -{ echo "$as_me:$LINENO: result: $ac_cv_header_time" >&5 -echo "${ECHO_T}$ac_cv_header_time" >&6; } -if test $ac_cv_header_time = yes; then - -cat >>confdefs.h <<\_ACEOF -#define TIME_WITH_SYS_TIME 1 -_ACEOF - -fi - - -{ echo "$as_me:$LINENO: checking for an ANSI C-conforming const" >&5 -echo $ECHO_N "checking for an ANSI C-conforming const... $ECHO_C" >&6; } -if test "${ac_cv_c_const+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ -/* FIXME: Include the comments suggested by Paul. */ -#ifndef __cplusplus - /* Ultrix mips cc rejects this. */ - typedef int charset[2]; - const charset cs; - /* SunOS 4.1.1 cc rejects this. */ - char const *const *pcpcc; - char **ppc; - /* NEC SVR4.0.2 mips cc rejects this. */ - struct point {int x, y;}; - static struct point const zero = {0,0}; - /* AIX XL C 1.02.0.0 rejects this. - It does not let you subtract one const X* pointer from another in - an arm of an if-expression whose if-part is not a constant - expression */ - const char *g = "string"; - pcpcc = &g + (g ? g-g : 0); - /* HPUX 7.0 cc rejects these. */ - ++pcpcc; - ppc = (char**) pcpcc; - pcpcc = (char const *const *) ppc; - { /* SCO 3.2v4 cc rejects this. */ - char *t; - char const *s = 0 ? (char *) 0 : (char const *) 0; - - *t++ = 0; - if (s) return 0; - } - { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ - int x[] = {25, 17}; - const int *foo = &x[0]; - ++foo; - } - { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ - typedef const int *iptr; - iptr p = 0; - ++p; - } - { /* AIX XL C 1.02.0.0 rejects this saying - "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ - struct s { int j; const int *ap[3]; }; - struct s *b; b->j = 5; - } - { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ - const int foo = 10; - if (!foo) return 0; - } - return !cs[0] && !zero.x; -#endif - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - ac_cv_c_const=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_cv_c_const=no -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -{ echo "$as_me:$LINENO: result: $ac_cv_c_const" >&5 -echo "${ECHO_T}$ac_cv_c_const" >&6; } -if test $ac_cv_c_const = no; then - -cat >>confdefs.h <<\_ACEOF -#define const -_ACEOF - -fi - -{ echo "$as_me:$LINENO: checking for uid_t in sys/types.h" >&5 -echo $ECHO_N "checking for uid_t in sys/types.h... $ECHO_C" >&6; } -if test "${ac_cv_type_uid_t+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "uid_t" >/dev/null 2>&1; then - ac_cv_type_uid_t=yes -else - ac_cv_type_uid_t=no -fi -rm -f conftest* - -fi -{ echo "$as_me:$LINENO: result: $ac_cv_type_uid_t" >&5 -echo "${ECHO_T}$ac_cv_type_uid_t" >&6; } -if test $ac_cv_type_uid_t = no; then - -cat >>confdefs.h <<\_ACEOF -#define uid_t int -_ACEOF - - -cat >>confdefs.h <<\_ACEOF -#define gid_t int -_ACEOF - -fi - -{ echo "$as_me:$LINENO: checking for mode_t" >&5 -echo $ECHO_N "checking for mode_t... $ECHO_C" >&6; } -if test "${ac_cv_type_mode_t+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -typedef mode_t ac__type_new_; -int -main () -{ -if ((ac__type_new_ *) 0) - return 0; -if (sizeof (ac__type_new_)) - return 0; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - ac_cv_type_mode_t=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_cv_type_mode_t=no -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -{ echo "$as_me:$LINENO: result: $ac_cv_type_mode_t" >&5 -echo "${ECHO_T}$ac_cv_type_mode_t" >&6; } -if test $ac_cv_type_mode_t = yes; then - : -else - -cat >>confdefs.h <<_ACEOF -#define mode_t int -_ACEOF - -fi - -{ echo "$as_me:$LINENO: checking for pid_t" >&5 -echo $ECHO_N "checking for pid_t... $ECHO_C" >&6; } -if test "${ac_cv_type_pid_t+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -typedef pid_t ac__type_new_; -int -main () -{ -if ((ac__type_new_ *) 0) - return 0; -if (sizeof (ac__type_new_)) - return 0; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - ac_cv_type_pid_t=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_cv_type_pid_t=no -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -{ echo "$as_me:$LINENO: result: $ac_cv_type_pid_t" >&5 -echo "${ECHO_T}$ac_cv_type_pid_t" >&6; } -if test $ac_cv_type_pid_t = yes; then - : -else - -cat >>confdefs.h <<_ACEOF -#define pid_t int -_ACEOF - -fi - -{ echo "$as_me:$LINENO: checking for size_t" >&5 -echo $ECHO_N "checking for size_t... $ECHO_C" >&6; } -if test "${ac_cv_type_size_t+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -typedef size_t ac__type_new_; -int -main () -{ -if ((ac__type_new_ *) 0) - return 0; -if (sizeof (ac__type_new_)) - return 0; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - ac_cv_type_size_t=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_cv_type_size_t=no -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -{ echo "$as_me:$LINENO: result: $ac_cv_type_size_t" >&5 -echo "${ECHO_T}$ac_cv_type_size_t" >&6; } -if test $ac_cv_type_size_t = yes; then - : -else - -cat >>confdefs.h <<_ACEOF -#define size_t unsigned int -_ACEOF - -fi - -{ echo "$as_me:$LINENO: checking return type of signal handlers" >&5 -echo $ECHO_N "checking return type of signal handlers... $ECHO_C" >&6; } -if test "${ac_cv_type_signal+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -#include - -int -main () -{ -return *(signal (0, 0)) (0) == 1; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - ac_cv_type_signal=int -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_cv_type_signal=void -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -{ echo "$as_me:$LINENO: result: $ac_cv_type_signal" >&5 -echo "${ECHO_T}$ac_cv_type_signal" >&6; } - -cat >>confdefs.h <<_ACEOF -#define RETSIGTYPE $ac_cv_type_signal -_ACEOF - - - -{ echo "$as_me:$LINENO: checking for struct stat.st_blksize" >&5 -echo $ECHO_N "checking for struct stat.st_blksize... $ECHO_C" >&6; } -if test "${ac_cv_member_struct_stat_st_blksize+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -int -main () -{ -static struct stat ac_aggr; -if (ac_aggr.st_blksize) -return 0; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - ac_cv_member_struct_stat_st_blksize=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -int -main () -{ -static struct stat ac_aggr; -if (sizeof ac_aggr.st_blksize) -return 0; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - ac_cv_member_struct_stat_st_blksize=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_cv_member_struct_stat_st_blksize=no -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -{ echo "$as_me:$LINENO: result: $ac_cv_member_struct_stat_st_blksize" >&5 -echo "${ECHO_T}$ac_cv_member_struct_stat_st_blksize" >&6; } -if test $ac_cv_member_struct_stat_st_blksize = yes; then - -cat >>confdefs.h <<_ACEOF -#define HAVE_STRUCT_STAT_ST_BLKSIZE 1 -_ACEOF - - -fi - -{ echo "$as_me:$LINENO: checking for struct stat.st_rdev" >&5 -echo $ECHO_N "checking for struct stat.st_rdev... $ECHO_C" >&6; } -if test "${ac_cv_member_struct_stat_st_rdev+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -int -main () -{ -static struct stat ac_aggr; -if (ac_aggr.st_rdev) -return 0; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - ac_cv_member_struct_stat_st_rdev=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -int -main () -{ -static struct stat ac_aggr; -if (sizeof ac_aggr.st_rdev) -return 0; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - ac_cv_member_struct_stat_st_rdev=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_cv_member_struct_stat_st_rdev=no -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -{ echo "$as_me:$LINENO: result: $ac_cv_member_struct_stat_st_rdev" >&5 -echo "${ECHO_T}$ac_cv_member_struct_stat_st_rdev" >&6; } -if test $ac_cv_member_struct_stat_st_rdev = yes; then - -cat >>confdefs.h <<_ACEOF -#define HAVE_STRUCT_STAT_ST_RDEV 1 -_ACEOF - - -fi - - - - - - - - - - - - - -for ac_func in \ - dup2 \ - ftruncate \ - gethostname \ - memmove \ - mkdir \ - rename \ - strerror \ - strstr \ - strtoul\ - valloc \ - waitpid \ - -do -as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` -{ echo "$as_me:$LINENO: checking for $ac_func" >&5 -echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } -if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -/* Define $ac_func to an innocuous variant, in case declares $ac_func. - For example, HP-UX 11i declares gettimeofday. */ -#define $ac_func innocuous_$ac_func - -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char $ac_func (); below. - Prefer to if __STDC__ is defined, since - exists even on freestanding compilers. */ - -#ifdef __STDC__ -# include -#else -# include -#endif - -#undef $ac_func - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char $ac_func (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined __stub_$ac_func || defined __stub___$ac_func -choke me -#endif - -int -main () -{ -return $ac_func (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then - eval "$as_ac_var=yes" -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - eval "$as_ac_var=no" -fi - -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ - conftest$ac_exeext conftest.$ac_ext -fi -ac_res=`eval echo '${'$as_ac_var'}'` - { echo "$as_me:$LINENO: result: $ac_res" >&5 -echo "${ECHO_T}$ac_res" >&6; } -if test `eval echo '${'$as_ac_var'}'` = yes; then - cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 -_ACEOF - -else - case " $LIBOBJS " in - *" $ac_func.$ac_objext "* ) ;; - *) LIBOBJS="$LIBOBJS $ac_func.$ac_objext" - ;; -esac - -fi -done - - - - - - - -for ac_header in stdint.h -do -as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` -if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then - { echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } -if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -fi -ac_res=`eval echo '${'$as_ac_Header'}'` - { echo "$as_me:$LINENO: result: $ac_res" >&5 -echo "${ECHO_T}$ac_res" >&6; } -else - # Is the header compilable? -{ echo "$as_me:$LINENO: checking $ac_header usability" >&5 -echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -#include <$ac_header> -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - ac_header_compiler=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_header_compiler=no -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -echo "${ECHO_T}$ac_header_compiler" >&6; } - -# Is the header present? -{ echo "$as_me:$LINENO: checking $ac_header presence" >&5 -echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include <$ac_header> -_ACEOF -if { (ac_try="$ac_cpp conftest.$ac_ext" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null && { - test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || - test ! -s conftest.err - }; then - ac_header_preproc=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_header_preproc=no -fi - -rm -f conftest.err conftest.$ac_ext -{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -echo "${ECHO_T}$ac_header_preproc" >&6; } - -# So? What about this header? -case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in - yes:no: ) - { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 -echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 -echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} - ac_header_preproc=yes - ;; - no:yes:* ) - { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 -echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 -echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 -echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 -echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 -echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} - ( cat <<\_ASBOX -## --------------------------------- ## -## Report this to bug-cvs@nongnu.org ## -## --------------------------------- ## -_ASBOX - ) | sed "s/^/$as_me: WARNING: /" >&2 - ;; -esac -{ echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } -if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - eval "$as_ac_Header=\$ac_header_preproc" -fi -ac_res=`eval echo '${'$as_ac_Header'}'` - { echo "$as_me:$LINENO: result: $ac_res" >&5 -echo "${ECHO_T}$ac_res" >&6; } - -fi -if test `eval echo '${'$as_ac_Header'}'` = yes; then - cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 -_ACEOF - -fi - -done - - { echo "$as_me:$LINENO: checking for SIZE_MAX" >&5 -echo $ECHO_N "checking for SIZE_MAX... $ECHO_C" >&6; } - result= - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -#include -#if HAVE_STDINT_H -#include -#endif -#ifdef SIZE_MAX -Found it -#endif - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "Found it" >/dev/null 2>&1; then - result=yes -fi -rm -f conftest* - - if test -z "$result"; then - if test "$cross_compiling" = yes; then - # Depending upon the size, compute the lo and hi bounds. -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -int -main () -{ -static int test_array [1 - 2 * !((~(size_t)0 / 10) >= 0)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - ac_lo=0 ac_mid=0 - while :; do - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -int -main () -{ -static int test_array [1 - 2 * !((~(size_t)0 / 10) <= $ac_mid)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - ac_hi=$ac_mid; break -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_lo=`expr $ac_mid + 1` - if test $ac_lo -le $ac_mid; then - ac_lo= ac_hi= - break - fi - ac_mid=`expr 2 '*' $ac_mid + 1` -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - done -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -int -main () -{ -static int test_array [1 - 2 * !((~(size_t)0 / 10) < 0)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - ac_hi=-1 ac_mid=-1 - while :; do - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -int -main () -{ -static int test_array [1 - 2 * !((~(size_t)0 / 10) >= $ac_mid)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - ac_lo=$ac_mid; break -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_hi=`expr '(' $ac_mid ')' - 1` - if test $ac_mid -le $ac_hi; then - ac_lo= ac_hi= - break - fi - ac_mid=`expr 2 '*' $ac_mid` -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - done -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_lo= ac_hi= -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -# Binary search between lo and hi bounds. -while test "x$ac_lo" != "x$ac_hi"; do - ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo` - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -int -main () -{ -static int test_array [1 - 2 * !((~(size_t)0 / 10) <= $ac_mid)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - ac_hi=$ac_mid -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_lo=`expr '(' $ac_mid ')' + 1` -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -done -case $ac_lo in -?*) res_hi=$ac_lo;; -'') result=? ;; -esac -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -static long int longval () { return ~(size_t)0 / 10; } -static unsigned long int ulongval () { return ~(size_t)0 / 10; } -#include -#include -int -main () -{ - - FILE *f = fopen ("conftest.val", "w"); - if (! f) - return 1; - if ((~(size_t)0 / 10) < 0) - { - long int i = longval (); - if (i != (~(size_t)0 / 10)) - return 1; - fprintf (f, "%ld\n", i); - } - else - { - unsigned long int i = ulongval (); - if (i != (~(size_t)0 / 10)) - return 1; - fprintf (f, "%lu\n", i); - } - return ferror (f) || fclose (f) != 0; - - ; - return 0; -} -_ACEOF -rm -f conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - res_hi=`cat conftest.val` -else - echo "$as_me: program exited with status $ac_status" >&5 -echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -( exit $ac_status ) -result=? -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext -fi -rm -f conftest.val - - if test "$cross_compiling" = yes; then - # Depending upon the size, compute the lo and hi bounds. -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -int -main () -{ -static int test_array [1 - 2 * !((~(size_t)0 % 10) >= 0)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - ac_lo=0 ac_mid=0 - while :; do - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -int -main () -{ -static int test_array [1 - 2 * !((~(size_t)0 % 10) <= $ac_mid)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - ac_hi=$ac_mid; break -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_lo=`expr $ac_mid + 1` - if test $ac_lo -le $ac_mid; then - ac_lo= ac_hi= - break - fi - ac_mid=`expr 2 '*' $ac_mid + 1` -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - done -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -int -main () -{ -static int test_array [1 - 2 * !((~(size_t)0 % 10) < 0)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - ac_hi=-1 ac_mid=-1 - while :; do - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -int -main () -{ -static int test_array [1 - 2 * !((~(size_t)0 % 10) >= $ac_mid)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - ac_lo=$ac_mid; break -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_hi=`expr '(' $ac_mid ')' - 1` - if test $ac_mid -le $ac_hi; then - ac_lo= ac_hi= - break - fi - ac_mid=`expr 2 '*' $ac_mid` -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - done -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_lo= ac_hi= -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -# Binary search between lo and hi bounds. -while test "x$ac_lo" != "x$ac_hi"; do - ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo` - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -int -main () -{ -static int test_array [1 - 2 * !((~(size_t)0 % 10) <= $ac_mid)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - ac_hi=$ac_mid -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_lo=`expr '(' $ac_mid ')' + 1` -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -done -case $ac_lo in -?*) res_lo=$ac_lo;; -'') result=? ;; -esac -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -static long int longval () { return ~(size_t)0 % 10; } -static unsigned long int ulongval () { return ~(size_t)0 % 10; } -#include -#include -int -main () -{ - - FILE *f = fopen ("conftest.val", "w"); - if (! f) - return 1; - if ((~(size_t)0 % 10) < 0) - { - long int i = longval (); - if (i != (~(size_t)0 % 10)) - return 1; - fprintf (f, "%ld\n", i); - } - else - { - unsigned long int i = ulongval (); - if (i != (~(size_t)0 % 10)) - return 1; - fprintf (f, "%lu\n", i); - } - return ferror (f) || fclose (f) != 0; - - ; - return 0; -} -_ACEOF -rm -f conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - res_lo=`cat conftest.val` -else - echo "$as_me: program exited with status $ac_status" >&5 -echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -( exit $ac_status ) -result=? -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext -fi -rm -f conftest.val - - if test "$cross_compiling" = yes; then - # Depending upon the size, compute the lo and hi bounds. -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -int -main () -{ -static int test_array [1 - 2 * !((sizeof (size_t) <= sizeof (unsigned int)) >= 0)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - ac_lo=0 ac_mid=0 - while :; do - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -int -main () -{ -static int test_array [1 - 2 * !((sizeof (size_t) <= sizeof (unsigned int)) <= $ac_mid)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - ac_hi=$ac_mid; break -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_lo=`expr $ac_mid + 1` - if test $ac_lo -le $ac_mid; then - ac_lo= ac_hi= - break - fi - ac_mid=`expr 2 '*' $ac_mid + 1` -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - done -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -int -main () -{ -static int test_array [1 - 2 * !((sizeof (size_t) <= sizeof (unsigned int)) < 0)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - ac_hi=-1 ac_mid=-1 - while :; do - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -int -main () -{ -static int test_array [1 - 2 * !((sizeof (size_t) <= sizeof (unsigned int)) >= $ac_mid)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - ac_lo=$ac_mid; break -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_hi=`expr '(' $ac_mid ')' - 1` - if test $ac_mid -le $ac_hi; then - ac_lo= ac_hi= - break - fi - ac_mid=`expr 2 '*' $ac_mid` -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - done -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_lo= ac_hi= -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -# Binary search between lo and hi bounds. -while test "x$ac_lo" != "x$ac_hi"; do - ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo` - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -int -main () -{ -static int test_array [1 - 2 * !((sizeof (size_t) <= sizeof (unsigned int)) <= $ac_mid)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - ac_hi=$ac_mid -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_lo=`expr '(' $ac_mid ')' + 1` -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -done -case $ac_lo in -?*) fits_in_uint=$ac_lo;; -'') result=? ;; -esac -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -static long int longval () { return sizeof (size_t) <= sizeof (unsigned int); } -static unsigned long int ulongval () { return sizeof (size_t) <= sizeof (unsigned int); } -#include -#include -int -main () -{ - - FILE *f = fopen ("conftest.val", "w"); - if (! f) - return 1; - if ((sizeof (size_t) <= sizeof (unsigned int)) < 0) - { - long int i = longval (); - if (i != (sizeof (size_t) <= sizeof (unsigned int))) - return 1; - fprintf (f, "%ld\n", i); - } - else - { - unsigned long int i = ulongval (); - if (i != (sizeof (size_t) <= sizeof (unsigned int))) - return 1; - fprintf (f, "%lu\n", i); - } - return ferror (f) || fclose (f) != 0; - - ; - return 0; -} -_ACEOF -rm -f conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - fits_in_uint=`cat conftest.val` -else - echo "$as_me: program exited with status $ac_status" >&5 -echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -( exit $ac_status ) -result=? -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext -fi -rm -f conftest.val - - if test "$fits_in_uint" = 1; then - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include - extern size_t foo; - extern unsigned long foo; - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - fits_in_uint=0 -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - fi - if test -z "$result"; then - if test "$fits_in_uint" = 1; then - result="$res_hi$res_lo"U - else - result="$res_hi$res_lo"UL - fi - else - result='~(size_t)0' - fi - fi - { echo "$as_me:$LINENO: result: $result" >&5 -echo "${ECHO_T}$result" >&6; } - if test "$result" != yes; then - -cat >>confdefs.h <<_ACEOF -#define SIZE_MAX $result -_ACEOF - - fi - -{ echo "$as_me:$LINENO: checking for inline" >&5 -echo $ECHO_N "checking for inline... $ECHO_C" >&6; } -if test "${ac_cv_c_inline+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_cv_c_inline=no -for ac_kw in inline __inline__ __inline; do - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#ifndef __cplusplus -typedef int foo_t; -static $ac_kw foo_t static_foo () {return 0; } -$ac_kw foo_t foo () {return 0; } -#endif - -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - ac_cv_c_inline=$ac_kw -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - test "$ac_cv_c_inline" != no && break -done - -fi -{ echo "$as_me:$LINENO: result: $ac_cv_c_inline" >&5 -echo "${ECHO_T}$ac_cv_c_inline" >&6; } - - -case $ac_cv_c_inline in - inline | yes) ;; - *) - case $ac_cv_c_inline in - no) ac_val=;; - *) ac_val=$ac_cv_c_inline;; - esac - cat >>confdefs.h <<_ACEOF -#ifndef __cplusplus -#define inline $ac_val -#endif -_ACEOF - ;; -esac - - - - - -for ac_header in stdint.h -do -as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` -if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then - { echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } -if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -fi -ac_res=`eval echo '${'$as_ac_Header'}'` - { echo "$as_me:$LINENO: result: $ac_res" >&5 -echo "${ECHO_T}$ac_res" >&6; } -else - # Is the header compilable? -{ echo "$as_me:$LINENO: checking $ac_header usability" >&5 -echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -#include <$ac_header> -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - ac_header_compiler=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_header_compiler=no -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -echo "${ECHO_T}$ac_header_compiler" >&6; } - -# Is the header present? -{ echo "$as_me:$LINENO: checking $ac_header presence" >&5 -echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include <$ac_header> -_ACEOF -if { (ac_try="$ac_cpp conftest.$ac_ext" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null && { - test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || - test ! -s conftest.err - }; then - ac_header_preproc=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_header_preproc=no -fi - -rm -f conftest.err conftest.$ac_ext -{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -echo "${ECHO_T}$ac_header_preproc" >&6; } - -# So? What about this header? -case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in - yes:no: ) - { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 -echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 -echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} - ac_header_preproc=yes - ;; - no:yes:* ) - { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 -echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 -echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 -echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 -echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 -echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} - ( cat <<\_ASBOX -## --------------------------------- ## -## Report this to bug-cvs@nongnu.org ## -## --------------------------------- ## -_ASBOX - ) | sed "s/^/$as_me: WARNING: /" >&2 - ;; -esac -{ echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } -if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - eval "$as_ac_Header=\$ac_header_preproc" -fi -ac_res=`eval echo '${'$as_ac_Header'}'` - { echo "$as_me:$LINENO: result: $ac_res" >&5 -echo "${ECHO_T}$ac_res" >&6; } - -fi -if test `eval echo '${'$as_ac_Header'}'` = yes; then - cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 -_ACEOF - -fi - -done - - - - -cat >>confdefs.h <<\_ACEOF -#define getpass cvs_getpass -_ACEOF - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -for ac_func in \ - fchdir \ - fchmod \ - fsync \ - ftime \ - geteuid \ - getgroups \ - getopt \ - getpagesize \ - gettimeofday \ - initgroups \ - login \ - logout \ - mknod \ - mkstemp \ - mktemp \ - putenv \ - readlink \ - regcomp \ - regerror \ - regexec \ - regfree \ - sigaction \ - sigblock \ - sigprocmask \ - sigsetmask \ - sigvec \ - tempnam \ - timezone \ - tzset \ - vprintf \ - wait3 \ - -do -as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` -{ echo "$as_me:$LINENO: checking for $ac_func" >&5 -echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } -if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -/* Define $ac_func to an innocuous variant, in case declares $ac_func. - For example, HP-UX 11i declares gettimeofday. */ -#define $ac_func innocuous_$ac_func - -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char $ac_func (); below. - Prefer to if __STDC__ is defined, since - exists even on freestanding compilers. */ - -#ifdef __STDC__ -# include -#else -# include -#endif - -#undef $ac_func - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char $ac_func (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined __stub_$ac_func || defined __stub___$ac_func -choke me -#endif - -int -main () -{ -return $ac_func (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then - eval "$as_ac_var=yes" -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - eval "$as_ac_var=no" -fi - -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ - conftest$ac_exeext conftest.$ac_ext -fi -ac_res=`eval echo '${'$as_ac_var'}'` - { echo "$as_me:$LINENO: result: $ac_res" >&5 -echo "${ECHO_T}$ac_res" >&6; } -if test `eval echo '${'$as_ac_var'}'` = yes; then - cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 -_ACEOF - -fi -done - -# we only need one of the following - - - -for ac_func in \ - nanosleep \ - usleep \ - select \ - -do -as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` -{ echo "$as_me:$LINENO: checking for $ac_func" >&5 -echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } -if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -/* Define $ac_func to an innocuous variant, in case declares $ac_func. - For example, HP-UX 11i declares gettimeofday. */ -#define $ac_func innocuous_$ac_func - -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char $ac_func (); below. - Prefer to if __STDC__ is defined, since - exists even on freestanding compilers. */ - -#ifdef __STDC__ -# include -#else -# include -#endif - -#undef $ac_func - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char $ac_func (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined __stub_$ac_func || defined __stub___$ac_func -choke me -#endif - -int -main () -{ -return $ac_func (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then - eval "$as_ac_var=yes" -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - eval "$as_ac_var=no" -fi - -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ - conftest$ac_exeext conftest.$ac_ext -fi -ac_res=`eval echo '${'$as_ac_var'}'` - { echo "$as_me:$LINENO: result: $ac_res" >&5 -echo "${ECHO_T}$ac_res" >&6; } -if test `eval echo '${'$as_ac_var'}'` = yes; then - cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 -_ACEOF - break -fi -done - - - -cat >>confdefs.h <<\_ACEOF -#define HAVE_STRCHR 1 -_ACEOF - - -cat >>confdefs.h <<\_ACEOF -#define HAVE_MEMCHR 1 -_ACEOF - - - -cat >>confdefs.h <<\_ACEOF -#define REGEX_MALLOC 1 -_ACEOF - - -cat >>confdefs.h <<\_ACEOF -#define _REGEX_RE_COMP 1 -_ACEOF - - -for ac_header in vfork.h -do -as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` -if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then - { echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } -if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -fi -ac_res=`eval echo '${'$as_ac_Header'}'` - { echo "$as_me:$LINENO: result: $ac_res" >&5 -echo "${ECHO_T}$ac_res" >&6; } -else - # Is the header compilable? -{ echo "$as_me:$LINENO: checking $ac_header usability" >&5 -echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -#include <$ac_header> -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - ac_header_compiler=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_header_compiler=no -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -echo "${ECHO_T}$ac_header_compiler" >&6; } - -# Is the header present? -{ echo "$as_me:$LINENO: checking $ac_header presence" >&5 -echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include <$ac_header> -_ACEOF -if { (ac_try="$ac_cpp conftest.$ac_ext" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null && { - test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || - test ! -s conftest.err - }; then - ac_header_preproc=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_header_preproc=no -fi - -rm -f conftest.err conftest.$ac_ext -{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -echo "${ECHO_T}$ac_header_preproc" >&6; } - -# So? What about this header? -case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in - yes:no: ) - { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 -echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 -echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} - ac_header_preproc=yes - ;; - no:yes:* ) - { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 -echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 -echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 -echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 -echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 -echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} - ( cat <<\_ASBOX -## --------------------------------- ## -## Report this to bug-cvs@nongnu.org ## -## --------------------------------- ## -_ASBOX - ) | sed "s/^/$as_me: WARNING: /" >&2 - ;; -esac -{ echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } -if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - eval "$as_ac_Header=\$ac_header_preproc" -fi -ac_res=`eval echo '${'$as_ac_Header'}'` - { echo "$as_me:$LINENO: result: $ac_res" >&5 -echo "${ECHO_T}$ac_res" >&6; } - -fi -if test `eval echo '${'$as_ac_Header'}'` = yes; then - cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 -_ACEOF - -fi - -done - - - -for ac_func in fork vfork -do -as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` -{ echo "$as_me:$LINENO: checking for $ac_func" >&5 -echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } -if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -/* Define $ac_func to an innocuous variant, in case declares $ac_func. - For example, HP-UX 11i declares gettimeofday. */ -#define $ac_func innocuous_$ac_func - -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char $ac_func (); below. - Prefer to if __STDC__ is defined, since - exists even on freestanding compilers. */ - -#ifdef __STDC__ -# include -#else -# include -#endif - -#undef $ac_func - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char $ac_func (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined __stub_$ac_func || defined __stub___$ac_func -choke me -#endif - -int -main () -{ -return $ac_func (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then - eval "$as_ac_var=yes" -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - eval "$as_ac_var=no" -fi - -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ - conftest$ac_exeext conftest.$ac_ext -fi -ac_res=`eval echo '${'$as_ac_var'}'` - { echo "$as_me:$LINENO: result: $ac_res" >&5 -echo "${ECHO_T}$ac_res" >&6; } -if test `eval echo '${'$as_ac_var'}'` = yes; then - cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 -_ACEOF - -fi -done - -if test "x$ac_cv_func_fork" = xyes; then - { echo "$as_me:$LINENO: checking for working fork" >&5 -echo $ECHO_N "checking for working fork... $ECHO_C" >&6; } -if test "${ac_cv_func_fork_works+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test "$cross_compiling" = yes; then - ac_cv_func_fork_works=cross -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -int -main () -{ - - /* By Ruediger Kuhlmann. */ - return fork () < 0; - - ; - return 0; -} -_ACEOF -rm -f conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_func_fork_works=yes -else - echo "$as_me: program exited with status $ac_status" >&5 -echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -( exit $ac_status ) -ac_cv_func_fork_works=no -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext -fi - - -fi -{ echo "$as_me:$LINENO: result: $ac_cv_func_fork_works" >&5 -echo "${ECHO_T}$ac_cv_func_fork_works" >&6; } - -else - ac_cv_func_fork_works=$ac_cv_func_fork -fi -if test "x$ac_cv_func_fork_works" = xcross; then - case $host in - *-*-amigaos* | *-*-msdosdjgpp*) - # Override, as these systems have only a dummy fork() stub - ac_cv_func_fork_works=no - ;; - *) - ac_cv_func_fork_works=yes - ;; - esac - { echo "$as_me:$LINENO: WARNING: result $ac_cv_func_fork_works guessed because of cross compilation" >&5 -echo "$as_me: WARNING: result $ac_cv_func_fork_works guessed because of cross compilation" >&2;} -fi -ac_cv_func_vfork_works=$ac_cv_func_vfork -if test "x$ac_cv_func_vfork" = xyes; then - { echo "$as_me:$LINENO: checking for working vfork" >&5 -echo $ECHO_N "checking for working vfork... $ECHO_C" >&6; } -if test "${ac_cv_func_vfork_works+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test "$cross_compiling" = yes; then - ac_cv_func_vfork_works=cross -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -/* Thanks to Paul Eggert for this test. */ -$ac_includes_default -#include -#ifdef HAVE_VFORK_H -# include -#endif -/* On some sparc systems, changes by the child to local and incoming - argument registers are propagated back to the parent. The compiler - is told about this with #include , but some compilers - (e.g. gcc -O) don't grok . Test for this by using a - static variable whose address is put into a register that is - clobbered by the vfork. */ -static void -#ifdef __cplusplus -sparc_address_test (int arg) -# else -sparc_address_test (arg) int arg; -#endif -{ - static pid_t child; - if (!child) { - child = vfork (); - if (child < 0) { - perror ("vfork"); - _exit(2); - } - if (!child) { - arg = getpid(); - write(-1, "", 0); - _exit (arg); - } - } -} - -int -main () -{ - pid_t parent = getpid (); - pid_t child; - - sparc_address_test (0); - - child = vfork (); - - if (child == 0) { - /* Here is another test for sparc vfork register problems. This - test uses lots of local variables, at least as many local - variables as main has allocated so far including compiler - temporaries. 4 locals are enough for gcc 1.40.3 on a Solaris - 4.1.3 sparc, but we use 8 to be safe. A buggy compiler should - reuse the register of parent for one of the local variables, - since it will think that parent can't possibly be used any more - in this routine. Assigning to the local variable will thus - munge parent in the parent process. */ - pid_t - p = getpid(), p1 = getpid(), p2 = getpid(), p3 = getpid(), - p4 = getpid(), p5 = getpid(), p6 = getpid(), p7 = getpid(); - /* Convince the compiler that p..p7 are live; otherwise, it might - use the same hardware register for all 8 local variables. */ - if (p != p1 || p != p2 || p != p3 || p != p4 - || p != p5 || p != p6 || p != p7) - _exit(1); - - /* On some systems (e.g. IRIX 3.3), vfork doesn't separate parent - from child file descriptors. If the child closes a descriptor - before it execs or exits, this munges the parent's descriptor - as well. Test for this by closing stdout in the child. */ - _exit(close(fileno(stdout)) != 0); - } else { - int status; - struct stat st; - - while (wait(&status) != child) - ; - return ( - /* Was there some problem with vforking? */ - child < 0 - - /* Did the child fail? (This shouldn't happen.) */ - || status - - /* Did the vfork/compiler bug occur? */ - || parent != getpid() - - /* Did the file descriptor bug occur? */ - || fstat(fileno(stdout), &st) != 0 - ); - } -} -_ACEOF -rm -f conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_func_vfork_works=yes -else - echo "$as_me: program exited with status $ac_status" >&5 -echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -( exit $ac_status ) -ac_cv_func_vfork_works=no -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext -fi - - -fi -{ echo "$as_me:$LINENO: result: $ac_cv_func_vfork_works" >&5 -echo "${ECHO_T}$ac_cv_func_vfork_works" >&6; } - -fi; -if test "x$ac_cv_func_fork_works" = xcross; then - ac_cv_func_vfork_works=$ac_cv_func_vfork - { echo "$as_me:$LINENO: WARNING: result $ac_cv_func_vfork_works guessed because of cross compilation" >&5 -echo "$as_me: WARNING: result $ac_cv_func_vfork_works guessed because of cross compilation" >&2;} -fi - -if test "x$ac_cv_func_vfork_works" = xyes; then - -cat >>confdefs.h <<\_ACEOF -#define HAVE_WORKING_VFORK 1 -_ACEOF - -else - -cat >>confdefs.h <<\_ACEOF -#define vfork fork -_ACEOF - -fi -if test "x$ac_cv_func_fork_works" = xyes; then - -cat >>confdefs.h <<\_ACEOF -#define HAVE_WORKING_FORK 1 -_ACEOF - -fi - -{ echo "$as_me:$LINENO: checking whether closedir returns void" >&5 -echo $ECHO_N "checking whether closedir returns void... $ECHO_C" >&6; } -if test "${ac_cv_func_closedir_void+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test "$cross_compiling" = yes; then - ac_cv_func_closedir_void=yes -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -#include <$ac_header_dirent> -#ifndef __cplusplus -int closedir (); -#endif - -int -main () -{ -return closedir (opendir (".")) != 0; - ; - return 0; -} -_ACEOF -rm -f conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_func_closedir_void=no -else - echo "$as_me: program exited with status $ac_status" >&5 -echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -( exit $ac_status ) -ac_cv_func_closedir_void=yes -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext -fi - - -fi -{ echo "$as_me:$LINENO: result: $ac_cv_func_closedir_void" >&5 -echo "${ECHO_T}$ac_cv_func_closedir_void" >&6; } -if test $ac_cv_func_closedir_void = yes; then - -cat >>confdefs.h <<\_ACEOF -#define CLOSEDIR_VOID 1 -_ACEOF - -fi - - -{ echo "$as_me:$LINENO: checking for library containing getspnam" >&5 -echo $ECHO_N "checking for library containing getspnam... $ECHO_C" >&6; } -if test "${ac_cv_search_getspnam+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_func_search_save_LIBS=$LIBS -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char getspnam (); -int -main () -{ -return getspnam (); - ; - return 0; -} -_ACEOF -for ac_lib in '' sec gen; do - if test -z "$ac_lib"; then - ac_res="none required" - else - ac_res=-l$ac_lib - LIBS="-l$ac_lib $ac_func_search_save_LIBS" - fi - rm -f conftest.$ac_objext conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then - ac_cv_search_getspnam=$ac_res -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - -fi - -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ - conftest$ac_exeext - if test "${ac_cv_search_getspnam+set}" = set; then - break -fi -done -if test "${ac_cv_search_getspnam+set}" = set; then - : -else - ac_cv_search_getspnam=no -fi -rm conftest.$ac_ext -LIBS=$ac_func_search_save_LIBS -fi -{ echo "$as_me:$LINENO: result: $ac_cv_search_getspnam" >&5 -echo "${ECHO_T}$ac_cv_search_getspnam" >&6; } -ac_res=$ac_cv_search_getspnam -if test "$ac_res" != no; then - test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" - -cat >>confdefs.h <<\_ACEOF -#define HAVE_GETSPNAM 1 -_ACEOF - -fi - - - - - - -for ac_header in $ac_header_list -do -as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` -if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then - { echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } -if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -fi -ac_res=`eval echo '${'$as_ac_Header'}'` - { echo "$as_me:$LINENO: result: $ac_res" >&5 -echo "${ECHO_T}$ac_res" >&6; } -else - # Is the header compilable? -{ echo "$as_me:$LINENO: checking $ac_header usability" >&5 -echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -#include <$ac_header> -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - ac_header_compiler=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_header_compiler=no -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -echo "${ECHO_T}$ac_header_compiler" >&6; } - -# Is the header present? -{ echo "$as_me:$LINENO: checking $ac_header presence" >&5 -echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include <$ac_header> -_ACEOF -if { (ac_try="$ac_cpp conftest.$ac_ext" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null && { - test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || - test ! -s conftest.err - }; then - ac_header_preproc=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_header_preproc=no -fi - -rm -f conftest.err conftest.$ac_ext -{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -echo "${ECHO_T}$ac_header_preproc" >&6; } - -# So? What about this header? -case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in - yes:no: ) - { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 -echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 -echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} - ac_header_preproc=yes - ;; - no:yes:* ) - { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 -echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 -echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 -echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 -echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 -echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} - ( cat <<\_ASBOX -## --------------------------------- ## -## Report this to bug-cvs@nongnu.org ## -## --------------------------------- ## -_ASBOX - ) | sed "s/^/$as_me: WARNING: /" >&2 - ;; -esac -{ echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } -if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - eval "$as_ac_Header=\$ac_header_preproc" -fi -ac_res=`eval echo '${'$as_ac_Header'}'` - { echo "$as_me:$LINENO: result: $ac_res" >&5 -echo "${ECHO_T}$ac_res" >&6; } - -fi -if test `eval echo '${'$as_ac_Header'}'` = yes; then - cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 -_ACEOF - -fi - -done - - - - - - - - - -{ echo "$as_me:$LINENO: checking whether utime accepts a null argument" >&5 -echo $ECHO_N "checking whether utime accepts a null argument... $ECHO_C" >&6; } -if test "${ac_cv_func_utime_null+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - rm -f conftest.data; >conftest.data -# Sequent interprets utime(file, 0) to mean use start of epoch. Wrong. -if test "$cross_compiling" = yes; then - ac_cv_func_utime_null=no -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default - #ifdef HAVE_UTIME_H - # include - #endif -int -main () -{ -struct stat s, t; - return ! (stat ("conftest.data", &s) == 0 - && utime ("conftest.data", 0) == 0 - && stat ("conftest.data", &t) == 0 - && t.st_mtime >= s.st_mtime - && t.st_mtime - s.st_mtime < 120); - ; - return 0; -} -_ACEOF -rm -f conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_func_utime_null=yes -else - echo "$as_me: program exited with status $ac_status" >&5 -echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -( exit $ac_status ) -ac_cv_func_utime_null=no -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext -fi - - -fi -{ echo "$as_me:$LINENO: result: $ac_cv_func_utime_null" >&5 -echo "${ECHO_T}$ac_cv_func_utime_null" >&6; } -if test $ac_cv_func_utime_null = yes; then - -cat >>confdefs.h <<\_ACEOF -#define HAVE_UTIME_NULL 1 -_ACEOF - -fi -rm -f conftest.data - -{ echo "$as_me:$LINENO: checking for long file names" >&5 -echo $ECHO_N "checking for long file names... $ECHO_C" >&6; } -if test "${ac_cv_sys_long_file_names+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_cv_sys_long_file_names=yes -# Test for long file names in all the places we know might matter: -# . the current directory, where building will happen -# $prefix/lib where we will be installing things -# $exec_prefix/lib likewise -# $TMPDIR if set, where it might want to write temporary files -# /tmp where it might want to write temporary files -# /var/tmp likewise -# /usr/tmp likewise -for ac_dir in . "$TMPDIR" /tmp /var/tmp /usr/tmp "$prefix/lib" "$exec_prefix/lib"; do - # Skip $TMPDIR if it is empty or bogus, and skip $exec_prefix/lib - # in the usual case where exec_prefix is '${prefix}'. - case $ac_dir in #( - . | /* | ?:[\\/]*) ;; #( - *) continue;; - esac - test -w "$ac_dir/." || continue # It is less confusing to not echo anything here. - ac_xdir=$ac_dir/cf$$ - (umask 077 && mkdir "$ac_xdir" 2>/dev/null) || continue - ac_tf1=$ac_xdir/conftest9012345 - ac_tf2=$ac_xdir/conftest9012346 - touch "$ac_tf1" 2>/dev/null && test -f "$ac_tf1" && test ! -f "$ac_tf2" || - ac_cv_sys_long_file_names=no - rm -f -r "$ac_xdir" 2>/dev/null - test $ac_cv_sys_long_file_names = no && break -done -fi -{ echo "$as_me:$LINENO: result: $ac_cv_sys_long_file_names" >&5 -echo "${ECHO_T}$ac_cv_sys_long_file_names" >&6; } -if test $ac_cv_sys_long_file_names = yes; then - -cat >>confdefs.h <<\_ACEOF -#define HAVE_LONG_FILE_NAMES 1 -_ACEOF - -fi - - -{ echo "$as_me:$LINENO: checking for working POSIX fnmatch" >&5 -echo $ECHO_N "checking for working POSIX fnmatch... $ECHO_C" >&6; } -if test "${ac_cv_func_fnmatch_works+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - # Some versions of Solaris, SCO, and the GNU C Library - # have a broken or incompatible fnmatch. - # So we run a test program. If we are cross-compiling, take no chance. - # Thanks to John Oleynick, Franc,ois Pinard, and Paul Eggert for this test. - if test "$cross_compiling" = yes; then - ac_cv_func_fnmatch_works=cross -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -# define y(a, b, c) (fnmatch (a, b, c) == 0) -# define n(a, b, c) (fnmatch (a, b, c) == FNM_NOMATCH) - -int -main () -{ -return - (!(y ("a*", "abc", 0) - && n ("d*/*1", "d/s/1", FNM_PATHNAME) - && y ("a\\\\bc", "abc", 0) - && n ("a\\\\bc", "abc", FNM_NOESCAPE) - && y ("*x", ".x", 0) - && n ("*x", ".x", FNM_PERIOD) - && 1)); - ; - return 0; -} -_ACEOF -rm -f conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_func_fnmatch_works=yes -else - echo "$as_me: program exited with status $ac_status" >&5 -echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -( exit $ac_status ) -ac_cv_func_fnmatch_works=no -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext -fi - - -fi -{ echo "$as_me:$LINENO: result: $ac_cv_func_fnmatch_works" >&5 -echo "${ECHO_T}$ac_cv_func_fnmatch_works" >&6; } -if test $ac_cv_func_fnmatch_works = yes; then - -cat >>confdefs.h <<\_ACEOF -#define HAVE_FNMATCH 1 -_ACEOF - -fi - - - -if test "$ac_cv_func_fnmatch_works" = no; then - case " $LIBOBJS " in - *" fnmatch.$ac_objext "* ) ;; - *) LIBOBJS="$LIBOBJS fnmatch.$ac_objext" - ;; -esac - - ac_config_links="$ac_config_links lib/fnmatch.h:lib/fnmatch.h.in" - - -fi - -# Try to find connect and gethostbyname. - -{ echo "$as_me:$LINENO: checking for main in -lnsl" >&5 -echo $ECHO_N "checking for main in -lnsl... $ECHO_C" >&6; } -if test "${ac_cv_lib_nsl_main+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lnsl $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - - -int -main () -{ -return main (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then - ac_cv_lib_nsl_main=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_cv_lib_nsl_main=no -fi - -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ echo "$as_me:$LINENO: result: $ac_cv_lib_nsl_main" >&5 -echo "${ECHO_T}$ac_cv_lib_nsl_main" >&6; } -if test $ac_cv_lib_nsl_main = yes; then - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBNSL 1 -_ACEOF - - LIBS="-lnsl $LIBS" - -fi - -{ echo "$as_me:$LINENO: checking for library containing connect" >&5 -echo $ECHO_N "checking for library containing connect... $ECHO_C" >&6; } -if test "${ac_cv_search_connect+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_func_search_save_LIBS=$LIBS -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char connect (); -int -main () -{ -return connect (); - ; - return 0; -} -_ACEOF -for ac_lib in '' xnet socket inet; do - if test -z "$ac_lib"; then - ac_res="none required" - else - ac_res=-l$ac_lib - LIBS="-l$ac_lib $ac_func_search_save_LIBS" - fi - rm -f conftest.$ac_objext conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then - ac_cv_search_connect=$ac_res -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - -fi - -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ - conftest$ac_exeext - if test "${ac_cv_search_connect+set}" = set; then - break -fi -done -if test "${ac_cv_search_connect+set}" = set; then - : -else - ac_cv_search_connect=no -fi -rm conftest.$ac_ext -LIBS=$ac_func_search_save_LIBS -fi -{ echo "$as_me:$LINENO: result: $ac_cv_search_connect" >&5 -echo "${ECHO_T}$ac_cv_search_connect" >&6; } -ac_res=$ac_cv_search_connect -if test "$ac_res" != no; then - test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" - -cat >>confdefs.h <<\_ACEOF -#define HAVE_CONNECT 1 -_ACEOF - -fi - -{ echo "$as_me:$LINENO: checking for library containing gethostbyname" >&5 -echo $ECHO_N "checking for library containing gethostbyname... $ECHO_C" >&6; } -if test "${ac_cv_search_gethostbyname+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_func_search_save_LIBS=$LIBS -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char gethostbyname (); -int -main () -{ -return gethostbyname (); - ; - return 0; -} -_ACEOF -for ac_lib in '' netinet; do - if test -z "$ac_lib"; then - ac_res="none required" - else - ac_res=-l$ac_lib - LIBS="-l$ac_lib $ac_func_search_save_LIBS" - fi - rm -f conftest.$ac_objext conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then - ac_cv_search_gethostbyname=$ac_res -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - -fi - -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ - conftest$ac_exeext - if test "${ac_cv_search_gethostbyname+set}" = set; then - break -fi -done -if test "${ac_cv_search_gethostbyname+set}" = set; then - : -else - ac_cv_search_gethostbyname=no -fi -rm conftest.$ac_ext -LIBS=$ac_func_search_save_LIBS -fi -{ echo "$as_me:$LINENO: result: $ac_cv_search_gethostbyname" >&5 -echo "${ECHO_T}$ac_cv_search_gethostbyname" >&6; } -ac_res=$ac_cv_search_gethostbyname -if test "$ac_res" != no; then - test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" - -fi - - - - -KRB4=/usr/kerberos - - -# Check whether --with-krb4 was given. -if test "${with_krb4+set}" = set; then - withval=$with_krb4; KRB4=$with_krb4 -fi -{ echo "$as_me:$LINENO: checking for KRB4 in $KRB4" >&5 -echo $ECHO_N "checking for KRB4 in $KRB4... $ECHO_C" >&6; } -{ echo "$as_me:$LINENO: result: " >&5 -echo "${ECHO_T}" >&6; } - - -krb_h= -{ echo "$as_me:$LINENO: checking for krb.h" >&5 -echo $ECHO_N "checking for krb.h... $ECHO_C" >&6; } -if test "$cross_compiling" != yes && test -r $KRB4/include/krb.h; then - hold_cflags=$CFLAGS - CFLAGS="$CFLAGS -I$KRB4/include" - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -int -main () -{ -int i; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then - krb_h=yes krb_incdir=$KRB4/include -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - CFLAGS=$hold_cflags - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -int -main () -{ -int i; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then - krb_h=yes krb_incdir= -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - -fi - -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ - conftest$ac_exeext conftest.$ac_ext -fi - -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ - conftest$ac_exeext conftest.$ac_ext - CFLAGS=$hold_cflags -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -int -main () -{ -int i; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then - krb_h=yes krb_incdir= -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - -fi - -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ - conftest$ac_exeext conftest.$ac_ext -fi -if test -z "$krb_h"; then - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -int -main () -{ -int i; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then - krb_h=yes krb_incdir= -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - if test "$cross_compiling" != yes && test -r $KRB4/include/kerberosIV/krb.h; then - hold_cflags=$CFLAGS - CFLAGS="$CFLAGS -I$KRB4/include/kerberosIV" - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -int -main () -{ -int i; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then - krb_h=yes krb_incdir=$KRB4/include/kerberosIV -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - -fi - -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ - conftest$ac_exeext conftest.$ac_ext - CFLAGS=$hold_cflags - fi -fi - -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ - conftest$ac_exeext conftest.$ac_ext -fi -{ echo "$as_me:$LINENO: result: $krb_h" >&5 -echo "${ECHO_T}$krb_h" >&6; } - -includeopt= - -if test -n "$krb_h"; then - krb_lib= - if test "$cross_compiling" != yes && test -r $KRB4/lib/libkrb.a; then - hold_ldflags=$LDFLAGS - LDFLAGS="-L${KRB4}/lib $LDFLAGS" - { echo "$as_me:$LINENO: checking for printf in -lkrb" >&5 -echo $ECHO_N "checking for printf in -lkrb... $ECHO_C" >&6; } -if test "${ac_cv_lib_krb_printf+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lkrb $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char printf (); -int -main () -{ -return printf (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then - ac_cv_lib_krb_printf=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_cv_lib_krb_printf=no -fi - -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ echo "$as_me:$LINENO: result: $ac_cv_lib_krb_printf" >&5 -echo "${ECHO_T}$ac_cv_lib_krb_printf" >&6; } -if test $ac_cv_lib_krb_printf = yes; then - krb_lib=yes krb_libdir=${KRB4}/lib -else - LDFLAGS=$hold_ldflags - # Using open here instead of printf so we don't - # get confused by the cached value for printf from above. - { echo "$as_me:$LINENO: checking for open in -lkrb" >&5 -echo $ECHO_N "checking for open in -lkrb... $ECHO_C" >&6; } -if test "${ac_cv_lib_krb_open+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lkrb $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char open (); -int -main () -{ -return open (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then - ac_cv_lib_krb_open=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_cv_lib_krb_open=no -fi - -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ echo "$as_me:$LINENO: result: $ac_cv_lib_krb_open" >&5 -echo "${ECHO_T}$ac_cv_lib_krb_open" >&6; } -if test $ac_cv_lib_krb_open = yes; then - krb_lib=yes krb_libdir= -fi - -fi - - LDFLAGS=$hold_ldflags - else - { echo "$as_me:$LINENO: checking for printf in -lkrb" >&5 -echo $ECHO_N "checking for printf in -lkrb... $ECHO_C" >&6; } -if test "${ac_cv_lib_krb_printf+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lkrb $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char printf (); -int -main () -{ -return printf (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then - ac_cv_lib_krb_printf=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_cv_lib_krb_printf=no -fi - -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ echo "$as_me:$LINENO: result: $ac_cv_lib_krb_printf" >&5 -echo "${ECHO_T}$ac_cv_lib_krb_printf" >&6; } -if test $ac_cv_lib_krb_printf = yes; then - krb_lib=yes krb_libdir= -fi - - { echo "$as_me:$LINENO: checking for krb_recvauth" >&5 -echo $ECHO_N "checking for krb_recvauth... $ECHO_C" >&6; } -if test "${ac_cv_func_krb_recvauth+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -/* Define krb_recvauth to an innocuous variant, in case declares krb_recvauth. - For example, HP-UX 11i declares gettimeofday. */ -#define krb_recvauth innocuous_krb_recvauth - -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char krb_recvauth (); below. - Prefer to if __STDC__ is defined, since - exists even on freestanding compilers. */ - -#ifdef __STDC__ -# include -#else -# include -#endif - -#undef krb_recvauth - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char krb_recvauth (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined __stub_krb_recvauth || defined __stub___krb_recvauth -choke me -#endif - -int -main () -{ -return krb_recvauth (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then - ac_cv_func_krb_recvauth=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_cv_func_krb_recvauth=no -fi - -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ - conftest$ac_exeext conftest.$ac_ext -fi -{ echo "$as_me:$LINENO: result: $ac_cv_func_krb_recvauth" >&5 -echo "${ECHO_T}$ac_cv_func_krb_recvauth" >&6; } -if test $ac_cv_func_krb_recvauth = yes; then - krb_lib=yes krb_libdir= -fi - - fi - if test -n "$krb_lib"; then - -cat >>confdefs.h <<\_ACEOF -#define HAVE_KERBEROS 1 -_ACEOF - - test -n "${krb_libdir}" && LIBS="${LIBS} -L${krb_libdir}" - # Put -L${krb_libdir} in LDFLAGS temporarily so that it appears before - # -ldes in the command line. Don't do it permanently so that we honor - # the user's setting for LDFLAGS - hold_ldflags=$LDFLAGS - test -n "${krb_libdir}" && LDFLAGS="$LDFLAGS -L${krb_libdir}" - { echo "$as_me:$LINENO: checking for printf in -ldes" >&5 -echo $ECHO_N "checking for printf in -ldes... $ECHO_C" >&6; } -if test "${ac_cv_lib_des_printf+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-ldes $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char printf (); -int -main () -{ -return printf (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then - ac_cv_lib_des_printf=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_cv_lib_des_printf=no -fi - -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ echo "$as_me:$LINENO: result: $ac_cv_lib_des_printf" >&5 -echo "${ECHO_T}$ac_cv_lib_des_printf" >&6; } -if test $ac_cv_lib_des_printf = yes; then - LIBS="${LIBS} -ldes" -fi - - -{ echo "$as_me:$LINENO: checking for krb_recvauth in -lkrb" >&5 -echo $ECHO_N "checking for krb_recvauth in -lkrb... $ECHO_C" >&6; } -if test "${ac_cv_lib_krb_krb_recvauth+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lkrb $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char krb_recvauth (); -int -main () -{ -return krb_recvauth (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then - ac_cv_lib_krb_krb_recvauth=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_cv_lib_krb_krb_recvauth=no -fi - -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ echo "$as_me:$LINENO: result: $ac_cv_lib_krb_krb_recvauth" >&5 -echo "${ECHO_T}$ac_cv_lib_krb_krb_recvauth" >&6; } -if test $ac_cv_lib_krb_krb_recvauth = yes; then - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBKRB 1 -_ACEOF - - LIBS="-lkrb $LIBS" - -fi - - -{ echo "$as_me:$LINENO: checking for krb_recvauth in -lkrb4" >&5 -echo $ECHO_N "checking for krb_recvauth in -lkrb4... $ECHO_C" >&6; } -if test "${ac_cv_lib_krb4_krb_recvauth+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lkrb4 $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char krb_recvauth (); -int -main () -{ -return krb_recvauth (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then - ac_cv_lib_krb4_krb_recvauth=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_cv_lib_krb4_krb_recvauth=no -fi - -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ echo "$as_me:$LINENO: result: $ac_cv_lib_krb4_krb_recvauth" >&5 -echo "${ECHO_T}$ac_cv_lib_krb4_krb_recvauth" >&6; } -if test $ac_cv_lib_krb4_krb_recvauth = yes; then - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBKRB4 1 -_ACEOF - - LIBS="-lkrb4 $LIBS" - -fi - - LDFLAGS=$hold_ldflags - if test -n "$krb_incdir"; then - includeopt="${includeopt} -I$krb_incdir" - fi - fi -fi - -for ac_func in krb_get_err_text -do -as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` -{ echo "$as_me:$LINENO: checking for $ac_func" >&5 -echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } -if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -/* Define $ac_func to an innocuous variant, in case declares $ac_func. - For example, HP-UX 11i declares gettimeofday. */ -#define $ac_func innocuous_$ac_func - -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char $ac_func (); below. - Prefer to if __STDC__ is defined, since - exists even on freestanding compilers. */ - -#ifdef __STDC__ -# include -#else -# include -#endif - -#undef $ac_func - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char $ac_func (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined __stub_$ac_func || defined __stub___$ac_func -choke me -#endif - -int -main () -{ -return $ac_func (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then - eval "$as_ac_var=yes" -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - eval "$as_ac_var=no" -fi - -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ - conftest$ac_exeext conftest.$ac_ext -fi -ac_res=`eval echo '${'$as_ac_var'}'` - { echo "$as_me:$LINENO: result: $ac_res" >&5 -echo "${ECHO_T}$ac_res" >&6; } -if test `eval echo '${'$as_ac_var'}'` = yes; then - cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 -_ACEOF - -fi -done - - - - -# -# Use --with-gssapi[=DIR] to enable GSSAPI support. -# -# defaults to enabled with DIR in default list below -# -# Search for /SUNHEA/ and read the comments about this default below. -# - -# Check whether --with-gssapi was given. -if test "${with_gssapi+set}" = set; then - withval=$with_gssapi; -else - with_gssapi=yes -fi - -# -# Try to locate a GSSAPI installation if no location was specified, assuming -# GSSAPI was enabled (the default). -# -if test -n "$acx_gssapi_cv_gssapi"; then - # Granted, this is a slightly ugly way to print this info, but the - # AC_CHECK_HEADER used in the search for a GSSAPI installation makes using - # AC_CACHE_CHECK worse - { echo "$as_me:$LINENO: checking for GSSAPI" >&5 -echo $ECHO_N "checking for GSSAPI... $ECHO_C" >&6; } -else :; fi -if test "${acx_gssapi_cv_gssapi+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - -if test x$with_gssapi = xyes; then - # --with but no location specified - # assume a gssapi.h or gssapi/gssapi.h locates our install. - # - # This isn't always strictly true. For instance Solaris 7's SUNHEA (header) - # package installs gssapi.h whether or not the necessary libraries are - # installed. I'm still not sure whether to consider this a bug. The long - # way around is to not consider GSSPAI installed unless gss_import_name is - # found, but that brings up a lot of other hassles, like continuing to let - # gcc & ld generate the error messages when the user uses --with-gssapi=dir - # as a debugging aid. The short way around is to disable GSSAPI by default, - # but I think Sun users have been faced with this for awhile and I haven't - # heard many complaints. - acx_gssapi_save_CPPFLAGS=$CPPFLAGS - for acx_gssapi_cv_gssapi in yes /usr/kerberos /usr/cygnus/kerbnet no; do - if test x$acx_gssapi_cv_gssapi = xno; then - break - fi - if test x$acx_gssapi_cv_gssapi = xyes; then - { echo "$as_me:$LINENO: checking for GSSAPI" >&5 -echo $ECHO_N "checking for GSSAPI... $ECHO_C" >&6; } - { echo "$as_me:$LINENO: result: " >&5 -echo "${ECHO_T}" >&6; } - else - CPPFLAGS="$acx_gssapi_save_CPPFLAGS -I$acx_gssapi_cv_gssapi/include" - { echo "$as_me:$LINENO: checking for GSSAPI in $acx_gssapi_cv_gssapi" >&5 -echo $ECHO_N "checking for GSSAPI in $acx_gssapi_cv_gssapi... $ECHO_C" >&6; } - { echo "$as_me:$LINENO: result: " >&5 -echo "${ECHO_T}" >&6; } - fi - unset ac_cv_header_gssapi_h - unset ac_cv_header_gssapi_gssapi_h - unset ac_cv_header_krb5_h - - - -for ac_header in gssapi.h gssapi/gssapi.h krb5.h -do -as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` -if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then - { echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } -if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -fi -ac_res=`eval echo '${'$as_ac_Header'}'` - { echo "$as_me:$LINENO: result: $ac_res" >&5 -echo "${ECHO_T}$ac_res" >&6; } -else - # Is the header compilable? -{ echo "$as_me:$LINENO: checking $ac_header usability" >&5 -echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -#include <$ac_header> -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - ac_header_compiler=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_header_compiler=no -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -echo "${ECHO_T}$ac_header_compiler" >&6; } - -# Is the header present? -{ echo "$as_me:$LINENO: checking $ac_header presence" >&5 -echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include <$ac_header> -_ACEOF -if { (ac_try="$ac_cpp conftest.$ac_ext" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null && { - test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || - test ! -s conftest.err - }; then - ac_header_preproc=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_header_preproc=no -fi - -rm -f conftest.err conftest.$ac_ext -{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -echo "${ECHO_T}$ac_header_preproc" >&6; } - -# So? What about this header? -case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in - yes:no: ) - { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 -echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 -echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} - ac_header_preproc=yes - ;; - no:yes:* ) - { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 -echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 -echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 -echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 -echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 -echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} - ( cat <<\_ASBOX -## --------------------------------- ## -## Report this to bug-cvs@nongnu.org ## -## --------------------------------- ## -_ASBOX - ) | sed "s/^/$as_me: WARNING: /" >&2 - ;; -esac -{ echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } -if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - eval "$as_ac_Header=\$ac_header_preproc" -fi -ac_res=`eval echo '${'$as_ac_Header'}'` - { echo "$as_me:$LINENO: result: $ac_res" >&5 -echo "${ECHO_T}$ac_res" >&6; } - -fi -if test `eval echo '${'$as_ac_Header'}'` = yes; then - cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 -_ACEOF - -fi - -done - - if (test "$ac_cv_header_gssapi_h" = yes || - test "$ac_cv_header_gssapi_gssapi_h" = yes) && - test "$ac_cv_header_krb5_h" = yes; then - break - fi - done - CPPFLAGS=$acx_gssapi_save_CPPFLAGS -else - acx_gssapi_cv_gssapi=$with_gssapi -fi -{ echo "$as_me:$LINENO: checking for GSSAPI" >&5 -echo $ECHO_N "checking for GSSAPI... $ECHO_C" >&6; } - -fi -{ echo "$as_me:$LINENO: result: $acx_gssapi_cv_gssapi" >&5 -echo "${ECHO_T}$acx_gssapi_cv_gssapi" >&6; } - -# -# Set up GSSAPI includes for later use. We don't bother to check for -# $acx_gssapi_cv_gssapi=no here since that will be caught later. -# -if test x$acx_gssapi_cv_gssapi = xyes; then - # no special includes necessary - GSSAPI_INCLUDES="" -else - # GSSAPI at $acx_gssapi_cv_gssapi (could be 'no') - GSSAPI_INCLUDES=" -I$acx_gssapi_cv_gssapi/include" -fi - -# -# Get the rest of the information CVS needs to compile with GSSAPI support -# -if test x$acx_gssapi_cv_gssapi != xno; then - # define HAVE_GSSAPI and set up the includes - -cat >>confdefs.h <<\_ACEOF -#define HAVE_GSSAPI -_ACEOF - - includeopt=$includeopt$GSSAPI_INCLUDES - - # locate any other headers - acx_gssapi_save_CPPFLAGS=$CPPFLAGS - CPPFLAGS=$CPPFLAGS$GSSAPI_INCLUDES - - - - -for ac_header in gssapi.h gssapi/gssapi.h gssapi/gssapi_generic.h krb5.h -do -as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` -if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then - { echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } -if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -fi -ac_res=`eval echo '${'$as_ac_Header'}'` - { echo "$as_me:$LINENO: result: $ac_res" >&5 -echo "${ECHO_T}$ac_res" >&6; } -else - # Is the header compilable? -{ echo "$as_me:$LINENO: checking $ac_header usability" >&5 -echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -#include <$ac_header> -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - ac_header_compiler=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_header_compiler=no -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -echo "${ECHO_T}$ac_header_compiler" >&6; } - -# Is the header present? -{ echo "$as_me:$LINENO: checking $ac_header presence" >&5 -echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include <$ac_header> -_ACEOF -if { (ac_try="$ac_cpp conftest.$ac_ext" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null && { - test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || - test ! -s conftest.err - }; then - ac_header_preproc=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_header_preproc=no -fi - -rm -f conftest.err conftest.$ac_ext -{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -echo "${ECHO_T}$ac_header_preproc" >&6; } - -# So? What about this header? -case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in - yes:no: ) - { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 -echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 -echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} - ac_header_preproc=yes - ;; - no:yes:* ) - { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 -echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 -echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 -echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 -echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 -echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} - ( cat <<\_ASBOX -## --------------------------------- ## -## Report this to bug-cvs@nongnu.org ## -## --------------------------------- ## -_ASBOX - ) | sed "s/^/$as_me: WARNING: /" >&2 - ;; -esac -{ echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } -if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - eval "$as_ac_Header=\$ac_header_preproc" -fi -ac_res=`eval echo '${'$as_ac_Header'}'` - { echo "$as_me:$LINENO: result: $ac_res" >&5 -echo "${ECHO_T}$ac_res" >&6; } - -fi -if test `eval echo '${'$as_ac_Header'}'` = yes; then - cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 -_ACEOF - -fi - -done - - # And look through them for GSS_C_NT_HOSTBASED_SERVICE or its alternatives - { echo "$as_me:$LINENO: checking for GSS_C_NT_HOSTBASED_SERVICE" >&5 -echo $ECHO_N "checking for GSS_C_NT_HOSTBASED_SERVICE... $ECHO_C" >&6; } -if test "${acx_gssapi_cv_gss_c_nt_hostbased_service+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - - acx_gssapi_cv_gss_c_nt_hostbased_service=no - if test "$ac_cv_header_gssapi_h" = "yes"; then - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "GSS_C_NT_HOSTBASED_SERVICE" >/dev/null 2>&1; then - acx_gssapi_cv_gss_c_nt_hostbased_service=yes -else - - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "gss_nt_service_name" >/dev/null 2>&1; then - acx_gssapi_cv_gss_c_nt_hostbased_service=gss_nt_service_name -fi -rm -f conftest* - - -fi -rm -f conftest* - - fi - if test $acx_gssapi_cv_gss_c_nt_hostbased_service = no && - test "$ac_cv_header_gssapi_gssapi_h" = "yes"; then - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "GSS_C_NT_HOSTBASED_SERVICE" >/dev/null 2>&1; then - acx_gssapi_cv_gss_c_nt_hostbased_service=yes -else - - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "gss_nt_service_name" >/dev/null 2>&1; then - acx_gssapi_cv_gss_c_nt_hostbased_service=gss_nt_service_name -fi -rm -f conftest* - - -fi -rm -f conftest* - - else :; fi - if test $acx_gssapi_cv_gss_c_nt_hostbased_service = no && - test "$ac_cv_header_gssapi_gssapi_generic_h" = "yes"; then - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "GSS_C_NT_HOSTBASED_SERVICE" >/dev/null 2>&1; then - acx_gssapi_cv_gss_c_nt_hostbased_service=yes -else - - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "gss_nt_service_name" >/dev/null 2>&1; then - acx_gssapi_cv_gss_c_nt_hostbased_service=gss_nt_service_name -fi -rm -f conftest* - - -fi -rm -f conftest* - - else :; fi - -fi -{ echo "$as_me:$LINENO: result: $acx_gssapi_cv_gss_c_nt_hostbased_service" >&5 -echo "${ECHO_T}$acx_gssapi_cv_gss_c_nt_hostbased_service" >&6; } - if test $acx_gssapi_cv_gss_c_nt_hostbased_service != yes && - test $acx_gssapi_cv_gss_c_nt_hostbased_service != no; then - # don't define for yes since that means it already means something and - # don't define for no since we'd rather the compiler catch the error - # It's debatable whether we'd prefer that the compiler catch the error - # - it seems our estranged developer is more likely to be familiar with - # the intricacies of the compiler than with those of autoconf, but by - # the same token, maybe we'd rather alert them to the fact that most - # of the support they need to fix the problem is installed if they can - # simply locate the appropriate symbol. - -cat >>confdefs.h <<_ACEOF -#define GSS_C_NT_HOSTBASED_SERVICE $acx_gssapi_cv_gss_c_nt_hostbased_service -_ACEOF - - else :; fi - - CPPFLAGS=$acx_gssapi_save_CPPFLAGS - - # Expect the libs to be installed parallel to the headers - # - # We could try once with and once without, but I'm not sure it's worth the - # trouble. - if test x$acx_gssapi_cv_gssapi != xyes; then - if test -z "$LIBS"; then - LIBS="-L$acx_gssapi_cv_gssapi/lib" - else - LIBS="-L$acx_gssapi_cv_gssapi/lib $LIBS" - fi - else :; fi - - # - # Some of the order below is particular due to library dependencies - # - - # - # des Heimdal K 0.3d, but Heimdal seems to be set up such - # that it could have been installed from elsewhere. - # - { echo "$as_me:$LINENO: checking for library containing des_set_odd_parity" >&5 -echo $ECHO_N "checking for library containing des_set_odd_parity... $ECHO_C" >&6; } -if test "${ac_cv_search_des_set_odd_parity+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_func_search_save_LIBS=$LIBS -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char des_set_odd_parity (); -int -main () -{ -return des_set_odd_parity (); - ; - return 0; -} -_ACEOF -for ac_lib in '' des; do - if test -z "$ac_lib"; then - ac_res="none required" - else - ac_res=-l$ac_lib - LIBS="-l$ac_lib $ac_func_search_save_LIBS" - fi - rm -f conftest.$ac_objext conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then - ac_cv_search_des_set_odd_parity=$ac_res -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - -fi - -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ - conftest$ac_exeext - if test "${ac_cv_search_des_set_odd_parity+set}" = set; then - break -fi -done -if test "${ac_cv_search_des_set_odd_parity+set}" = set; then - : -else - ac_cv_search_des_set_odd_parity=no -fi -rm conftest.$ac_ext -LIBS=$ac_func_search_save_LIBS -fi -{ echo "$as_me:$LINENO: result: $ac_cv_search_des_set_odd_parity" >&5 -echo "${ECHO_T}$ac_cv_search_des_set_odd_parity" >&6; } -ac_res=$ac_cv_search_des_set_odd_parity -if test "$ac_res" != no; then - test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" - -fi - - - # - # com_err Heimdal K 0.3d - # - # com_err MIT K5 v1.2.2-beta1 - # - { echo "$as_me:$LINENO: checking for library containing com_err" >&5 -echo $ECHO_N "checking for library containing com_err... $ECHO_C" >&6; } -if test "${ac_cv_search_com_err+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_func_search_save_LIBS=$LIBS -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char com_err (); -int -main () -{ -return com_err (); - ; - return 0; -} -_ACEOF -for ac_lib in '' com_err; do - if test -z "$ac_lib"; then - ac_res="none required" - else - ac_res=-l$ac_lib - LIBS="-l$ac_lib $ac_func_search_save_LIBS" - fi - rm -f conftest.$ac_objext conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then - ac_cv_search_com_err=$ac_res -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - -fi - -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ - conftest$ac_exeext - if test "${ac_cv_search_com_err+set}" = set; then - break -fi -done -if test "${ac_cv_search_com_err+set}" = set; then - : -else - ac_cv_search_com_err=no -fi -rm conftest.$ac_ext -LIBS=$ac_func_search_save_LIBS -fi -{ echo "$as_me:$LINENO: result: $ac_cv_search_com_err" >&5 -echo "${ECHO_T}$ac_cv_search_com_err" >&6; } -ac_res=$ac_cv_search_com_err -if test "$ac_res" != no; then - test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" - -fi - - - # - # asn1 Heimdal K 0.3d -lcom_err - # - { echo "$as_me:$LINENO: checking for library containing initialize_asn1_error_table_r" >&5 -echo $ECHO_N "checking for library containing initialize_asn1_error_table_r... $ECHO_C" >&6; } -if test "${ac_cv_search_initialize_asn1_error_table_r+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_func_search_save_LIBS=$LIBS -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char initialize_asn1_error_table_r (); -int -main () -{ -return initialize_asn1_error_table_r (); - ; - return 0; -} -_ACEOF -for ac_lib in '' asn1; do - if test -z "$ac_lib"; then - ac_res="none required" - else - ac_res=-l$ac_lib - LIBS="-l$ac_lib $ac_func_search_save_LIBS" - fi - rm -f conftest.$ac_objext conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then - ac_cv_search_initialize_asn1_error_table_r=$ac_res -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - -fi - -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ - conftest$ac_exeext - if test "${ac_cv_search_initialize_asn1_error_table_r+set}" = set; then - break -fi -done -if test "${ac_cv_search_initialize_asn1_error_table_r+set}" = set; then - : -else - ac_cv_search_initialize_asn1_error_table_r=no -fi -rm conftest.$ac_ext -LIBS=$ac_func_search_save_LIBS -fi -{ echo "$as_me:$LINENO: result: $ac_cv_search_initialize_asn1_error_table_r" >&5 -echo "${ECHO_T}$ac_cv_search_initialize_asn1_error_table_r" >&6; } -ac_res=$ac_cv_search_initialize_asn1_error_table_r -if test "$ac_res" != no; then - test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" - -fi - - - # - # resolv required, but not installed by Heimdal K 0.3d - # - # resolv MIT K5 1.2.2-beta1 - # Linux 2.2.17 - # - { echo "$as_me:$LINENO: checking for library containing __dn_expand" >&5 -echo $ECHO_N "checking for library containing __dn_expand... $ECHO_C" >&6; } -if test "${ac_cv_search___dn_expand+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_func_search_save_LIBS=$LIBS -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char __dn_expand (); -int -main () -{ -return __dn_expand (); - ; - return 0; -} -_ACEOF -for ac_lib in '' resolv; do - if test -z "$ac_lib"; then - ac_res="none required" - else - ac_res=-l$ac_lib - LIBS="-l$ac_lib $ac_func_search_save_LIBS" - fi - rm -f conftest.$ac_objext conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then - ac_cv_search___dn_expand=$ac_res -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - -fi - -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ - conftest$ac_exeext - if test "${ac_cv_search___dn_expand+set}" = set; then - break -fi -done -if test "${ac_cv_search___dn_expand+set}" = set; then - : -else - ac_cv_search___dn_expand=no -fi -rm conftest.$ac_ext -LIBS=$ac_func_search_save_LIBS -fi -{ echo "$as_me:$LINENO: result: $ac_cv_search___dn_expand" >&5 -echo "${ECHO_T}$ac_cv_search___dn_expand" >&6; } -ac_res=$ac_cv_search___dn_expand -if test "$ac_res" != no; then - test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" - -fi - - - # - # crypto Need by gssapi under FreeBSD 5.4 - # - { echo "$as_me:$LINENO: checking for library containing RC4" >&5 -echo $ECHO_N "checking for library containing RC4... $ECHO_C" >&6; } -if test "${ac_cv_search_RC4+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_func_search_save_LIBS=$LIBS -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char RC4 (); -int -main () -{ -return RC4 (); - ; - return 0; -} -_ACEOF -for ac_lib in '' crypto; do - if test -z "$ac_lib"; then - ac_res="none required" - else - ac_res=-l$ac_lib - LIBS="-l$ac_lib $ac_func_search_save_LIBS" - fi - rm -f conftest.$ac_objext conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then - ac_cv_search_RC4=$ac_res -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - -fi - -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ - conftest$ac_exeext - if test "${ac_cv_search_RC4+set}" = set; then - break -fi -done -if test "${ac_cv_search_RC4+set}" = set; then - : -else - ac_cv_search_RC4=no -fi -rm conftest.$ac_ext -LIBS=$ac_func_search_save_LIBS -fi -{ echo "$as_me:$LINENO: result: $ac_cv_search_RC4" >&5 -echo "${ECHO_T}$ac_cv_search_RC4" >&6; } -ac_res=$ac_cv_search_RC4 -if test "$ac_res" != no; then - test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" - -fi - - - # - # crypt Needed by roken under FreeBSD 4.6. - # - { echo "$as_me:$LINENO: checking for library containing crypt" >&5 -echo $ECHO_N "checking for library containing crypt... $ECHO_C" >&6; } -if test "${ac_cv_search_crypt+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_func_search_save_LIBS=$LIBS -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char crypt (); -int -main () -{ -return crypt (); - ; - return 0; -} -_ACEOF -for ac_lib in '' crypt; do - if test -z "$ac_lib"; then - ac_res="none required" - else - ac_res=-l$ac_lib - LIBS="-l$ac_lib $ac_func_search_save_LIBS" - fi - rm -f conftest.$ac_objext conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then - ac_cv_search_crypt=$ac_res -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - -fi - -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ - conftest$ac_exeext - if test "${ac_cv_search_crypt+set}" = set; then - break -fi -done -if test "${ac_cv_search_crypt+set}" = set; then - : -else - ac_cv_search_crypt=no -fi -rm conftest.$ac_ext -LIBS=$ac_func_search_save_LIBS -fi -{ echo "$as_me:$LINENO: result: $ac_cv_search_crypt" >&5 -echo "${ECHO_T}$ac_cv_search_crypt" >&6; } -ac_res=$ac_cv_search_crypt -if test "$ac_res" != no; then - test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" - -fi - - - # - # roken Heimdal K 0.3d -lresolv - # roken FreeBSD 4.6 -lcrypt - # - { echo "$as_me:$LINENO: checking for library containing roken_gethostbyaddr" >&5 -echo $ECHO_N "checking for library containing roken_gethostbyaddr... $ECHO_C" >&6; } -if test "${ac_cv_search_roken_gethostbyaddr+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_func_search_save_LIBS=$LIBS -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char roken_gethostbyaddr (); -int -main () -{ -return roken_gethostbyaddr (); - ; - return 0; -} -_ACEOF -for ac_lib in '' roken; do - if test -z "$ac_lib"; then - ac_res="none required" - else - ac_res=-l$ac_lib - LIBS="-l$ac_lib $ac_func_search_save_LIBS" - fi - rm -f conftest.$ac_objext conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then - ac_cv_search_roken_gethostbyaddr=$ac_res -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - -fi - -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ - conftest$ac_exeext - if test "${ac_cv_search_roken_gethostbyaddr+set}" = set; then - break -fi -done -if test "${ac_cv_search_roken_gethostbyaddr+set}" = set; then - : -else - ac_cv_search_roken_gethostbyaddr=no -fi -rm conftest.$ac_ext -LIBS=$ac_func_search_save_LIBS -fi -{ echo "$as_me:$LINENO: result: $ac_cv_search_roken_gethostbyaddr" >&5 -echo "${ECHO_T}$ac_cv_search_roken_gethostbyaddr" >&6; } -ac_res=$ac_cv_search_roken_gethostbyaddr -if test "$ac_res" != no; then - test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" - -fi - - - # - # k5crypto MIT K5 v1.2.2-beta1 - # - { echo "$as_me:$LINENO: checking for library containing valid_enctype" >&5 -echo $ECHO_N "checking for library containing valid_enctype... $ECHO_C" >&6; } -if test "${ac_cv_search_valid_enctype+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_func_search_save_LIBS=$LIBS -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char valid_enctype (); -int -main () -{ -return valid_enctype (); - ; - return 0; -} -_ACEOF -for ac_lib in '' k5crypto; do - if test -z "$ac_lib"; then - ac_res="none required" - else - ac_res=-l$ac_lib - LIBS="-l$ac_lib $ac_func_search_save_LIBS" - fi - rm -f conftest.$ac_objext conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then - ac_cv_search_valid_enctype=$ac_res -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - -fi - -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ - conftest$ac_exeext - if test "${ac_cv_search_valid_enctype+set}" = set; then - break -fi -done -if test "${ac_cv_search_valid_enctype+set}" = set; then - : -else - ac_cv_search_valid_enctype=no -fi -rm conftest.$ac_ext -LIBS=$ac_func_search_save_LIBS -fi -{ echo "$as_me:$LINENO: result: $ac_cv_search_valid_enctype" >&5 -echo "${ECHO_T}$ac_cv_search_valid_enctype" >&6; } -ac_res=$ac_cv_search_valid_enctype -if test "$ac_res" != no; then - test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" - -fi - - - # - # gen ? ? ? Needed on Irix 5.3 with some - # Irix 5.3 version of Kerberos. I'm not - # sure which since Irix didn't - # get any testing this time - # around. Original comment: - # - # This is necessary on Irix 5.3, in order to link against libkrb5 -- - # there, an_to_ln.o refers to things defined only in -lgen. - # - { echo "$as_me:$LINENO: checking for library containing compile" >&5 -echo $ECHO_N "checking for library containing compile... $ECHO_C" >&6; } -if test "${ac_cv_search_compile+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_func_search_save_LIBS=$LIBS -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char compile (); -int -main () -{ -return compile (); - ; - return 0; -} -_ACEOF -for ac_lib in '' gen; do - if test -z "$ac_lib"; then - ac_res="none required" - else - ac_res=-l$ac_lib - LIBS="-l$ac_lib $ac_func_search_save_LIBS" - fi - rm -f conftest.$ac_objext conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then - ac_cv_search_compile=$ac_res -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - -fi - -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ - conftest$ac_exeext - if test "${ac_cv_search_compile+set}" = set; then - break -fi -done -if test "${ac_cv_search_compile+set}" = set; then - : -else - ac_cv_search_compile=no -fi -rm conftest.$ac_ext -LIBS=$ac_func_search_save_LIBS -fi -{ echo "$as_me:$LINENO: result: $ac_cv_search_compile" >&5 -echo "${ECHO_T}$ac_cv_search_compile" >&6; } -ac_res=$ac_cv_search_compile -if test "$ac_res" != no; then - test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" - -fi - - - # - # krb5 ? ? ? -lgen -l??? - # Irix 5.3 - # - # krb5 MIT K5 v1.1.1 - # - # krb5 MIT K5 v1.2.2-beta1 -lcrypto -lcom_err - # Linux 2.2.17 - # - # krb5 MIT K5 v1.2.2-beta1 -lcrypto -lcom_err -lresolv - # - # krb5 Heimdal K 0.3d -lasn1 -lroken -ldes - # - { echo "$as_me:$LINENO: checking for library containing krb5_free_context" >&5 -echo $ECHO_N "checking for library containing krb5_free_context... $ECHO_C" >&6; } -if test "${ac_cv_search_krb5_free_context+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_func_search_save_LIBS=$LIBS -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char krb5_free_context (); -int -main () -{ -return krb5_free_context (); - ; - return 0; -} -_ACEOF -for ac_lib in '' krb5; do - if test -z "$ac_lib"; then - ac_res="none required" - else - ac_res=-l$ac_lib - LIBS="-l$ac_lib $ac_func_search_save_LIBS" - fi - rm -f conftest.$ac_objext conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then - ac_cv_search_krb5_free_context=$ac_res -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - -fi - -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ - conftest$ac_exeext - if test "${ac_cv_search_krb5_free_context+set}" = set; then - break -fi -done -if test "${ac_cv_search_krb5_free_context+set}" = set; then - : -else - ac_cv_search_krb5_free_context=no -fi -rm conftest.$ac_ext -LIBS=$ac_func_search_save_LIBS -fi -{ echo "$as_me:$LINENO: result: $ac_cv_search_krb5_free_context" >&5 -echo "${ECHO_T}$ac_cv_search_krb5_free_context" >&6; } -ac_res=$ac_cv_search_krb5_free_context -if test "$ac_res" != no; then - test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" - -fi - - - # - # gss This may be the only lib needed under HP-UX, so find it - # first. - # - # gssapi_krb5 Only lib needed with MIT K5 v1.2.1, so find it first in - # order to prefer MIT Kerberos. If both MIT & Heimdal - # Kerberos are installed and in the path, this will leave - # some of the libraries above in LIBS unnecessarily, but - # noone would ever do that, right? - # - # gss HP-UX ??? - # - # gssapi_krb5 MIT K5 v1.2.2-beta1 -lkrb5 - # - # gssapi Heimdal K 0.3d -lkrb5 - # - { echo "$as_me:$LINENO: checking for library containing gss_import_name" >&5 -echo $ECHO_N "checking for library containing gss_import_name... $ECHO_C" >&6; } -if test "${ac_cv_search_gss_import_name+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_func_search_save_LIBS=$LIBS -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char gss_import_name (); -int -main () -{ -return gss_import_name (); - ; - return 0; -} -_ACEOF -for ac_lib in '' gss gssapi_krb5 gssapi; do - if test -z "$ac_lib"; then - ac_res="none required" - else - ac_res=-l$ac_lib - LIBS="-l$ac_lib $ac_func_search_save_LIBS" - fi - rm -f conftest.$ac_objext conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then - ac_cv_search_gss_import_name=$ac_res -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - -fi - -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ - conftest$ac_exeext - if test "${ac_cv_search_gss_import_name+set}" = set; then - break -fi -done -if test "${ac_cv_search_gss_import_name+set}" = set; then - : -else - ac_cv_search_gss_import_name=no -fi -rm conftest.$ac_ext -LIBS=$ac_func_search_save_LIBS -fi -{ echo "$as_me:$LINENO: result: $ac_cv_search_gss_import_name" >&5 -echo "${ECHO_T}$ac_cv_search_gss_import_name" >&6; } -ac_res=$ac_cv_search_gss_import_name -if test "$ac_res" != no; then - test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" - -fi - -fi - - - - - - -# Let the confiscator request a specific editor - -# Check whether --with-editor was given. -if test "${with_editor+set}" = set; then - withval=$with_editor; -else - with_editor=yes -fi - - -# If --with-editor was supplied with an argument, let it override $EDITOR from -# the user's environment. We need to unset EDITOR here because AC_CHECK_PROGS -# will let the value of EDITOR ride when it is set rather than searching. We -# ignore the --without-editor case since it will be caught below. -if test -n "$EDITOR" && test yes != $with_editor; then - $as_unset EDITOR || test "${EDITOR+set}" != set || { EDITOR=; export EDITOR; } -fi - -# Set the default when --with-editor wasn't supplied or when it was supplied -# without an argument. -if test yes = $with_editor; then - with_editor="vim vi emacs nano pico edit" -fi - -if echo $with_editor |grep ^/ >/dev/null; then - # If $with_editor is an absolute path, issue a warning if the executable - # doesn't exist or isn't usable, but then trust the user and use it - # regardless - EDITOR=$with_editor - { echo "$as_me:$LINENO: checking for an editor" >&5 -echo $ECHO_N "checking for an editor... $ECHO_C" >&6; } - { echo "$as_me:$LINENO: result: $EDITOR" >&5 -echo "${ECHO_T}$EDITOR" >&6; } - if ! test -f $with_editor \ - || ! test -x $with_editor; then - # warn the user that they may encounter problems - { echo "$as_me:$LINENO: WARNING: \`$with_editor' is not a path to an executable file" >&5 -echo "$as_me: WARNING: \`$with_editor' is not a path to an executable file" >&2;} - fi -elif test no != "${with_editor}"; then - # Search for an editor - for ac_prog in $with_editor -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } -if test "${ac_cv_prog_EDITOR+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$EDITOR"; then - ac_cv_prog_EDITOR="$EDITOR" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_prog_EDITOR="$ac_prog" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done -IFS=$as_save_IFS - -fi -fi -EDITOR=$ac_cv_prog_EDITOR -if test -n "$EDITOR"; then - { echo "$as_me:$LINENO: result: $EDITOR" >&5 -echo "${ECHO_T}$EDITOR" >&6; } -else - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } -fi - - - test -n "$EDITOR" && break -done -test -n "$EDITOR" || EDITOR="no" - - if test no = "${EDITOR}"; then - { { echo "$as_me:$LINENO: error: - Failed to find a text file editor. CVS cannot be compiled - without a default log message editor. Searched for - \`$with_editor'. Try \`configure --with-editor'." >&5 -echo "$as_me: error: - Failed to find a text file editor. CVS cannot be compiled - without a default log message editor. Searched for - \`$with_editor'. Try \`configure --with-editor'." >&2;} - { (exit 1); exit 1; }; } - fi -else - { { echo "$as_me:$LINENO: error: - CVS cannot be compiled without a default log message editor. - Try \`configure --with-editor'." >&5 -echo "$as_me: error: - CVS cannot be compiled without a default log message editor. - Try \`configure --with-editor'." >&2;} - { (exit 1); exit 1; }; } -fi - - -cat >>confdefs.h <<_ACEOF -#define EDITOR_DFLT "$EDITOR" -_ACEOF - - - - -# What remote shell transport should the :extssh: client cvs default to using? - -# Check whether --with-ssh was given. -if test "${with_ssh+set}" = set; then - withval=$with_ssh; -else - with_ssh="ssh lshc ssh2" -fi - - -if test no = "$with_ssh"; then - { echo "$as_me:$LINENO: WARNING: Failed to find usable remote shell. Using 'ssh'." >&5 -echo "$as_me: WARNING: Failed to find usable remote shell. Using 'ssh'." >&2;} - with_ssh=ssh -elif test yes = "$with_ssh"; then - # Make --with-ssh mean the same thing as --with-ssh=ssh - with_ssh=ssh -fi - -if echo $with_ssh |grep ^/ >/dev/null; then - # If $with_ssh is an absolute path, issue a warning if the executable - # doesn't exist or isn't usable, but then trust the user and use it - # regardless - with_default_ssh=$with_ssh - { echo "$as_me:$LINENO: checking for a remote shell" >&5 -echo $ECHO_N "checking for a remote shell... $ECHO_C" >&6; } - if ! test -f $with_ssh \ - || ! test -x $with_ssh; then - # warn the user that they may encounter problems - { echo "$as_me:$LINENO: WARNING: $with_ssh is not a path to an executable file" >&5 -echo "$as_me: WARNING: $with_ssh is not a path to an executable file" >&2;} - fi -else - # Search for a remote shell - for ac_prog in $with_ssh -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } -if test "${ac_cv_prog_with_default_ssh+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$with_default_ssh"; then - ac_cv_prog_with_default_ssh="$with_default_ssh" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_prog_with_default_ssh="$ac_prog" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done -IFS=$as_save_IFS - -fi -fi -with_default_ssh=$ac_cv_prog_with_default_ssh -if test -n "$with_default_ssh"; then - { echo "$as_me:$LINENO: result: $with_default_ssh" >&5 -echo "${ECHO_T}$with_default_ssh" >&6; } -else - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } -fi - - - test -n "$with_default_ssh" && break -done -test -n "$with_default_ssh" || with_default_ssh=""ssh"" - -fi - - -cat >>confdefs.h <<_ACEOF -#define SSH_DFLT "$with_default_ssh" -_ACEOF - - - - -# What remote shell transport should our client cvs default to using? - -# Check whether --with-rsh was given. -if test "${with_rsh+set}" = set; then - withval=$with_rsh; -else - with_rsh="remsh rsh ssh lshc ssh2" -fi - - -if test no = "$with_rsh"; then - { echo "$as_me:$LINENO: WARNING: Failed to find usable remote shell. Using 'rsh'." >&5 -echo "$as_me: WARNING: Failed to find usable remote shell. Using 'rsh'." >&2;} - with_rsh=rsh -elif test yes = "$with_rsh"; then - # Make --with-rsh mean the same thing as --with-rsh=rsh - with_rsh=rsh -fi - -if echo $with_rsh |grep ^/ >/dev/null; then - # If $with_rsh is an absolute path, issue a warning if the executable - # doesn't exist or isn't usable, but then trust the user and use it - # regardless - with_default_rsh=$with_rsh - { echo "$as_me:$LINENO: checking for a remote shell" >&5 -echo $ECHO_N "checking for a remote shell... $ECHO_C" >&6; } - if ! test -f $with_rsh \ - || ! test -x $with_rsh; then - # warn the user that they may encounter problems - { echo "$as_me:$LINENO: WARNING: $with_rsh is not a path to an executable file" >&5 -echo "$as_me: WARNING: $with_rsh is not a path to an executable file" >&2;} - fi -else - # Search for a remote shell - for ac_prog in $with_rsh -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } -if test "${ac_cv_prog_with_default_rsh+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$with_default_rsh"; then - ac_cv_prog_with_default_rsh="$with_default_rsh" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_prog_with_default_rsh="$ac_prog" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done -IFS=$as_save_IFS - -fi -fi -with_default_rsh=$ac_cv_prog_with_default_rsh -if test -n "$with_default_rsh"; then - { echo "$as_me:$LINENO: result: $with_default_rsh" >&5 -echo "${ECHO_T}$with_default_rsh" >&6; } -else - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } -fi - - - test -n "$with_default_rsh" && break -done -test -n "$with_default_rsh" || with_default_rsh=""rsh"" - -fi - - -cat >>confdefs.h <<_ACEOF -#define RSH_DFLT "$with_default_rsh" -_ACEOF - - - - -# Check whether --with-tmpdir was given. -if test "${with_tmpdir+set}" = set; then - withval=$with_tmpdir; -fi - - -{ echo "$as_me:$LINENO: checking for temporary directory" >&5 -echo $ECHO_N "checking for temporary directory... $ECHO_C" >&6; } -if test -z "$with_tmpdir" || test yes = "$with_tmpdir"; then - for with_tmpdir in /tmp /var/tmp no; do - if test -d "$with_tmpdir" && test -x "$with_tmpdir" \ - && test -w "$with_tmpdir" && test -r "$with_tmpdir"; then - break - fi - done - if test no = "$with_tmpdir"; then - { echo "$as_me:$LINENO: WARNING: Failed to find usable temporary directory. Using '/tmp'." >&5 -echo "$as_me: WARNING: Failed to find usable temporary directory. Using '/tmp'." >&2;} - with_tmpdir=/tmp - fi - { echo "$as_me:$LINENO: result: $with_tmpdir" >&5 -echo "${ECHO_T}$with_tmpdir" >&6; } -elif ! echo "$with_tmpdir" |grep '^[\\/]'; then - { echo "$as_me:$LINENO: result: $with_tmpdir" >&5 -echo "${ECHO_T}$with_tmpdir" >&6; } - { { echo "$as_me:$LINENO: error: --with-tmpdir requires an absolute path." >&5 -echo "$as_me: error: --with-tmpdir requires an absolute path." >&2;} - { (exit 1); exit 1; }; } -elif ! test -d "$with_tmpdir" || ! test -x "$with_tmpdir" \ - || ! test -w "$with_tmpdir" || ! test -r "$with_tmpdir"; then - { echo "$as_me:$LINENO: result: $with_tmpdir" >&5 -echo "${ECHO_T}$with_tmpdir" >&6; } - { echo "$as_me:$LINENO: WARNING: User supplied temporary directory ('$with_tmpdir') does not - exist or lacks sufficient permissions for read/write." >&5 -echo "$as_me: WARNING: User supplied temporary directory ('$with_tmpdir') does not - exist or lacks sufficient permissions for read/write." >&2;} -fi - - -cat >>confdefs.h <<_ACEOF -#define TMPDIR_DFLT "$with_tmpdir" -_ACEOF - - - - - - -# Check whether --with-umask was given. -if test "${with_umask+set}" = set; then - withval=$with_umask; -fi - - -if test -z "$with_umask" || test yes = "$with_umask"; then - with_umask=002 -elif test no = "$with_umask"; then - with_umask=000 -fi - - -cat >>confdefs.h <<_ACEOF -#define UMASK_DFLT $with_umask -_ACEOF - - - - -# Check whether --with-cvs-admin-group was given. -if test "${with_cvs_admin_group+set}" = set; then - withval=$with_cvs_admin_group; -else - with_cvs_admin_group=cvsadmin -fi - - -if test yes = "$with_cvs_admin_group"; then - with_cvs_admin_group=cvsadmin -fi -if test no != "$with_cvs_admin_group"; then - -cat >>confdefs.h <<_ACEOF -#define CVS_ADMIN_GROUP "$with_cvs_admin_group" -_ACEOF - -fi - - - - -# Check whether --enable-cvs-ndbm was given. -if test "${enable_cvs_ndbm+set}" = set; then - enableval=$enable_cvs_ndbm; -else - enable_cvs_ndbm=yes -fi - -if test no != "$enable_cvs_ndbm"; then - -cat >>confdefs.h <<\_ACEOF -#define MY_NDBM 1 -_ACEOF - -fi - - - - - - -# Check whether --enable-mmap was given. -if test "${enable_mmap+set}" = set; then - enableval=$enable_mmap; -fi - - -if test no != "$enable_mmap"; then - - -for ac_header in stdlib.h unistd.h -do -as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` -if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then - { echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } -if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -fi -ac_res=`eval echo '${'$as_ac_Header'}'` - { echo "$as_me:$LINENO: result: $ac_res" >&5 -echo "${ECHO_T}$ac_res" >&6; } -else - # Is the header compilable? -{ echo "$as_me:$LINENO: checking $ac_header usability" >&5 -echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -#include <$ac_header> -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - ac_header_compiler=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_header_compiler=no -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -echo "${ECHO_T}$ac_header_compiler" >&6; } - -# Is the header present? -{ echo "$as_me:$LINENO: checking $ac_header presence" >&5 -echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include <$ac_header> -_ACEOF -if { (ac_try="$ac_cpp conftest.$ac_ext" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null && { - test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || - test ! -s conftest.err - }; then - ac_header_preproc=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_header_preproc=no -fi - -rm -f conftest.err conftest.$ac_ext -{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -echo "${ECHO_T}$ac_header_preproc" >&6; } - -# So? What about this header? -case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in - yes:no: ) - { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 -echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 -echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} - ac_header_preproc=yes - ;; - no:yes:* ) - { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 -echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 -echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 -echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 -echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 -echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} - ( cat <<\_ASBOX -## --------------------------------- ## -## Report this to bug-cvs@nongnu.org ## -## --------------------------------- ## -_ASBOX - ) | sed "s/^/$as_me: WARNING: /" >&2 - ;; -esac -{ echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } -if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - eval "$as_ac_Header=\$ac_header_preproc" -fi -ac_res=`eval echo '${'$as_ac_Header'}'` - { echo "$as_me:$LINENO: result: $ac_res" >&5 -echo "${ECHO_T}$ac_res" >&6; } - -fi -if test `eval echo '${'$as_ac_Header'}'` = yes; then - cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 -_ACEOF - -fi - -done - - -for ac_func in getpagesize -do -as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` -{ echo "$as_me:$LINENO: checking for $ac_func" >&5 -echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } -if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -/* Define $ac_func to an innocuous variant, in case declares $ac_func. - For example, HP-UX 11i declares gettimeofday. */ -#define $ac_func innocuous_$ac_func - -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char $ac_func (); below. - Prefer to if __STDC__ is defined, since - exists even on freestanding compilers. */ - -#ifdef __STDC__ -# include -#else -# include -#endif - -#undef $ac_func - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char $ac_func (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined __stub_$ac_func || defined __stub___$ac_func -choke me -#endif - -int -main () -{ -return $ac_func (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then - eval "$as_ac_var=yes" -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - eval "$as_ac_var=no" -fi - -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ - conftest$ac_exeext conftest.$ac_ext -fi -ac_res=`eval echo '${'$as_ac_var'}'` - { echo "$as_me:$LINENO: result: $ac_res" >&5 -echo "${ECHO_T}$ac_res" >&6; } -if test `eval echo '${'$as_ac_var'}'` = yes; then - cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 -_ACEOF - -fi -done - -{ echo "$as_me:$LINENO: checking for working mmap" >&5 -echo $ECHO_N "checking for working mmap... $ECHO_C" >&6; } -if test "${ac_cv_func_mmap_fixed_mapped+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test "$cross_compiling" = yes; then - ac_cv_func_mmap_fixed_mapped=no -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -/* malloc might have been renamed as rpl_malloc. */ -#undef malloc - -/* Thanks to Mike Haertel and Jim Avera for this test. - Here is a matrix of mmap possibilities: - mmap private not fixed - mmap private fixed at somewhere currently unmapped - mmap private fixed at somewhere already mapped - mmap shared not fixed - mmap shared fixed at somewhere currently unmapped - mmap shared fixed at somewhere already mapped - For private mappings, we should verify that changes cannot be read() - back from the file, nor mmap's back from the file at a different - address. (There have been systems where private was not correctly - implemented like the infamous i386 svr4.0, and systems where the - VM page cache was not coherent with the file system buffer cache - like early versions of FreeBSD and possibly contemporary NetBSD.) - For shared mappings, we should conversely verify that changes get - propagated back to all the places they're supposed to be. - - Grep wants private fixed already mapped. - The main things grep needs to know about mmap are: - * does it exist and is it safe to write into the mmap'd area - * how to use it (BSD variants) */ - -#include -#include - -#if !defined STDC_HEADERS && !defined HAVE_STDLIB_H -char *malloc (); -#endif - -/* This mess was copied from the GNU getpagesize.h. */ -#ifndef HAVE_GETPAGESIZE -/* Assume that all systems that can run configure have sys/param.h. */ -# ifndef HAVE_SYS_PARAM_H -# define HAVE_SYS_PARAM_H 1 -# endif - -# ifdef _SC_PAGESIZE -# define getpagesize() sysconf(_SC_PAGESIZE) -# else /* no _SC_PAGESIZE */ -# ifdef HAVE_SYS_PARAM_H -# include -# ifdef EXEC_PAGESIZE -# define getpagesize() EXEC_PAGESIZE -# else /* no EXEC_PAGESIZE */ -# ifdef NBPG -# define getpagesize() NBPG * CLSIZE -# ifndef CLSIZE -# define CLSIZE 1 -# endif /* no CLSIZE */ -# else /* no NBPG */ -# ifdef NBPC -# define getpagesize() NBPC -# else /* no NBPC */ -# ifdef PAGESIZE -# define getpagesize() PAGESIZE -# endif /* PAGESIZE */ -# endif /* no NBPC */ -# endif /* no NBPG */ -# endif /* no EXEC_PAGESIZE */ -# else /* no HAVE_SYS_PARAM_H */ -# define getpagesize() 8192 /* punt totally */ -# endif /* no HAVE_SYS_PARAM_H */ -# endif /* no _SC_PAGESIZE */ - -#endif /* no HAVE_GETPAGESIZE */ - -int -main () -{ - char *data, *data2, *data3; - int i, pagesize; - int fd; - - pagesize = getpagesize (); - - /* First, make a file with some known garbage in it. */ - data = (char *) malloc (pagesize); - if (!data) - return 1; - for (i = 0; i < pagesize; ++i) - *(data + i) = rand (); - umask (0); - fd = creat ("conftest.mmap", 0600); - if (fd < 0) - return 1; - if (write (fd, data, pagesize) != pagesize) - return 1; - close (fd); - - /* Next, try to mmap the file at a fixed address which already has - something else allocated at it. If we can, also make sure that - we see the same garbage. */ - fd = open ("conftest.mmap", O_RDWR); - if (fd < 0) - return 1; - data2 = (char *) malloc (2 * pagesize); - if (!data2) - return 1; - data2 += (pagesize - ((long int) data2 & (pagesize - 1))) & (pagesize - 1); - if (data2 != mmap (data2, pagesize, PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_FIXED, fd, 0L)) - return 1; - for (i = 0; i < pagesize; ++i) - if (*(data + i) != *(data2 + i)) - return 1; - - /* Finally, make sure that changes to the mapped area do not - percolate back to the file as seen by read(). (This is a bug on - some variants of i386 svr4.0.) */ - for (i = 0; i < pagesize; ++i) - *(data2 + i) = *(data2 + i) + 1; - data3 = (char *) malloc (pagesize); - if (!data3) - return 1; - if (read (fd, data3, pagesize) != pagesize) - return 1; - for (i = 0; i < pagesize; ++i) - if (*(data + i) != *(data3 + i)) - return 1; - close (fd); - return 0; -} -_ACEOF -rm -f conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_func_mmap_fixed_mapped=yes -else - echo "$as_me: program exited with status $ac_status" >&5 -echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -( exit $ac_status ) -ac_cv_func_mmap_fixed_mapped=no -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext -fi - - -fi -{ echo "$as_me:$LINENO: result: $ac_cv_func_mmap_fixed_mapped" >&5 -echo "${ECHO_T}$ac_cv_func_mmap_fixed_mapped" >&6; } -if test $ac_cv_func_mmap_fixed_mapped = yes; then - -cat >>confdefs.h <<\_ACEOF -#define HAVE_MMAP 1 -_ACEOF - -fi -rm -f conftest.mmap - -fi - -# Check for options requesting client and server feature. If none are -# given and we have connect(), we want the full client & server arrangement. -# Check whether --enable-client was given. -if test "${enable_client+set}" = set; then - enableval=$enable_client; -else - if test "$ac_cv_search_connect" != no; then - enable_client=yes - fi -fi - -if test no != "$enable_client"; then - -cat >>confdefs.h <<\_ACEOF -#define CLIENT_SUPPORT 1 -_ACEOF - -fi - -# Check whether --enable-password-authenticated-client was given. -if test "${enable_password_authenticated_client+set}" = set; then - enableval=$enable_password_authenticated_client; -fi - - -if test no != "$enable_password_authenticated_client"; then - if test no != "$enable_client"; then - -cat >>confdefs.h <<\_ACEOF -#define AUTH_CLIENT_SUPPORT 1 -_ACEOF - - else - { echo "$as_me:$LINENO: WARNING: --enable-password-authenticated-client is meaningless with - the CVS client disabled (--disable-client)" >&5 -echo "$as_me: WARNING: --enable-password-authenticated-client is meaningless with - the CVS client disabled (--disable-client)" >&2;} - fi -fi - - -# Check whether --enable-server was given. -if test "${enable_server+set}" = set; then - enableval=$enable_server; -else - if test "$ac_cv_search_connect" != no; then - enable_server=yes - fi -fi - - -if test no != "$enable_server"; then - -cat >>confdefs.h <<\_ACEOF -#define SERVER_SUPPORT 1 -_ACEOF - - - { echo "$as_me:$LINENO: checking for library containing crypt" >&5 -echo $ECHO_N "checking for library containing crypt... $ECHO_C" >&6; } -if test "${ac_cv_search_crypt+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_func_search_save_LIBS=$LIBS -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char crypt (); -int -main () -{ -return crypt (); - ; - return 0; -} -_ACEOF -for ac_lib in '' crypt; do - if test -z "$ac_lib"; then - ac_res="none required" - else - ac_res=-l$ac_lib - LIBS="-l$ac_lib $ac_func_search_save_LIBS" - fi - rm -f conftest.$ac_objext conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then - ac_cv_search_crypt=$ac_res -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - -fi - -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ - conftest$ac_exeext - if test "${ac_cv_search_crypt+set}" = set; then - break -fi -done -if test "${ac_cv_search_crypt+set}" = set; then - : -else - ac_cv_search_crypt=no -fi -rm conftest.$ac_ext -LIBS=$ac_func_search_save_LIBS -fi -{ echo "$as_me:$LINENO: result: $ac_cv_search_crypt" >&5 -echo "${ECHO_T}$ac_cv_search_crypt" >&6; } -ac_res=$ac_cv_search_crypt -if test "$ac_res" != no; then - test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" - -cat >>confdefs.h <<\_ACEOF -#define HAVE_CRYPT 1 -_ACEOF - - -cat >>confdefs.h <<\_ACEOF -#define AUTH_SERVER_SUPPORT 1 -_ACEOF - -fi - - # Check whether --enable-server-flow-control was given. -if test "${enable_server_flow_control+set}" = set; then - enableval=$enable_server_flow_control; if test yes = $enable_server_flow_control; then - enable_server_flow_control=1M,2M - fi -else - enable_server_flow_control=1M,2M -fi - - if test no != $enable_server_flow_control; then - ccvs_lwm=`expr "$enable_server_flow_control" : '\(.*\),'` - ccvs_hwm=`expr "$enable_server_flow_control" : '.*,\(.*\)'` - ccvs_lwm_E=`expr "$ccvs_lwm" : '[0-9][0-9]*\(.*\)'` - ccvs_lwm=`expr "$ccvs_lwm" : '\([0-9][0-9]*\)'` - test "" != "$ccvs_lwm" || ccvs_lwm_E="?" - case $ccvs_lwm_E in - G) ccvs_lwm="$ccvs_lwm * 1024 * 1024 * 1024";; - M) ccvs_lwm="$ccvs_lwm * 1024 * 1024";; - k) ccvs_lwm="$ccvs_lwm * 1024";; - b | '') ;; - *) { { echo "$as_me:$LINENO: error: Can't parse argument to --enable-server-flow-control - ('$enable_server_flow_control') as ," >&5 -echo "$as_me: error: Can't parse argument to --enable-server-flow-control - ('$enable_server_flow_control') as ," >&2;} - { (exit 1); exit 1; }; } - esac - ccvs_hwm_E=`expr "$ccvs_hwm" : '[0-9][0-9]*\(.*\)'` - ccvs_hwm=`expr "$ccvs_hwm" : '\([0-9][0-9]*\).*'` - test "" != "$ccvs_hwm" || ccvs_hwm_E="?" - case $ccvs_hwm_E in - G) ccvs_hwm="$ccvs_hwm * 1024 * 1024 * 1024";; - M) ccvs_hwm="$ccvs_hwm * 1024 * 1024";; - k) ccvs_hwm="$ccvs_hwm * 1024";; - b | '') ccvs_hwm="$ccvs_hwm";; - *) { { echo "$as_me:$LINENO: error: Can't parse argument to --enable-server-flow-control - ('$enable_server_flow_control') as ," >&5 -echo "$as_me: error: Can't parse argument to --enable-server-flow-control - ('$enable_server_flow_control') as ," >&2;} - { (exit 1); exit 1; }; } - esac - - -cat >>confdefs.h <<\_ACEOF -#define SERVER_FLOWCONTROL 1 -_ACEOF - - -cat >>confdefs.h <<_ACEOF -#define SERVER_LO_WATER ($ccvs_lwm) -_ACEOF - - -cat >>confdefs.h <<_ACEOF -#define SERVER_HI_WATER ($ccvs_hwm) -_ACEOF - - fi # enable_server_flow_control -fi # enable_server - - - -# Check whether --enable-case-sensitivity was given. -if test "${enable_case_sensitivity+set}" = set; then - enableval=$enable_case_sensitivity; case "$enable_case_sensitivity" in - yes | no | auto) ;; - *) - { { echo "$as_me:$LINENO: error: Unrecognized argument to --enable-case-sensitivity: \`$enable_case_sensitivity'. Acceptable values are \`yes', \`no', and \`auto'." >&5 -echo "$as_me: error: Unrecognized argument to --enable-case-sensitivity: \`$enable_case_sensitivity'. Acceptable values are \`yes', \`no', and \`auto'." >&2;} - { (exit 1); exit 1; }; } - ;; - esac -else - enable_case_sensitivity=auto -fi - - -acx_forced=' (forced)' -{ echo "$as_me:$LINENO: checking for a case sensitive file system" >&5 -echo $ECHO_N "checking for a case sensitive file system... $ECHO_C" >&6; } -if test $enable_case_sensitivity = auto; then - if test "${acx_cv_case_sensitive+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - rm -f ac_TEST_filenames_CASE_sensitive - echo foo >ac_test_filenames_case_sensitive - if test -f ac_TEST_filenames_CASE_sensitive; then - acx_cv_case_sensitive=no - else - acx_cv_case_sensitive=yes - fi - rm ac_test_filenames_case_sensitive - -fi - - enable_case_sensitivity=$acx_cv_case_sensitive - acx_forced= -fi -{ echo "$as_me:$LINENO: result: $enable_case_sensitivity$acx_forced" >&5 -echo "${ECHO_T}$enable_case_sensitivity$acx_forced" >&6; } -if test $enable_case_sensitivity = no; then - -cat >>confdefs.h <<\_ACEOF -#define FILENAMES_CASE_INSENSITIVE 1 -_ACEOF - - case " $LIBOBJS " in - *" fncase.$ac_objext "* ) ;; - *) LIBOBJS="$LIBOBJS fncase.$ac_objext" - ;; -esac - -fi - - - - -# Check whether --enable-encryption was given. -if test "${enable_encryption+set}" = set; then - enableval=$enable_encryption; -else - enable_encryption=no -fi - -if test "$enable_encryption" = yes; then - if test no != "$with_client" || test no != "$with_server"; then - -cat >>confdefs.h <<\_ACEOF -#define ENCRYPTION 1 -_ACEOF - - else - { echo "$as_me:$LINENO: WARNING: --enable-encryption is meaningless when neither the CVS client - nor the CVS server is enabled (--disable-client and --disable-server)." >&5 -echo "$as_me: WARNING: --enable-encryption is meaningless when neither the CVS client - nor the CVS server is enabled (--disable-client and --disable-server)." >&2;} - fi -fi - - - - -# Check whether --enable-force-editor was given. -if test "${enable_force_editor+set}" = set; then - enableval=$enable_force_editor; -else - enable_force_editor=no -fi - - -if test yes = "$enable_force_editor"; then - -cat >>confdefs.h <<\_ACEOF -#define FORCE_USE_EDITOR 1 -_ACEOF - -fi - - - - -# Check whether --enable-rootcommit was given. -if test "${enable_rootcommit+set}" = set; then - enableval=$enable_rootcommit; -else - enable_rootcommit=no -fi - -if test "$enable_rootcommit" = no; then - -cat >>confdefs.h <<\_ACEOF -#define CVS_BADROOT 1 -_ACEOF - -fi - - - - - - - - -{ echo "$as_me:$LINENO: checking for cygwin32" >&5 -echo $ECHO_N "checking for cygwin32... $ECHO_C" >&6; } -if test "${ccvs_cv_sys_cygwin32+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ -return __CYGWIN32__; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_compile") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - ccvs_cv_sys_cygwin32=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ccvs_cv_sys_cygwin32=no -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -{ echo "$as_me:$LINENO: result: $ccvs_cv_sys_cygwin32" >&5 -echo "${ECHO_T}$ccvs_cv_sys_cygwin32" >&6; } -if test $ccvs_cv_sys_cygwin32 = yes; then - LIBS="$LIBS -ladvapi32" - - -cat >>confdefs.h <<\_ACEOF -#define UTIME_EXPECTS_WRITABLE 1 -_ACEOF - - - -cat >>confdefs.h <<\_ACEOF -#define USE_SETMODE_STDOUT 1 -_ACEOF - - -cat >>confdefs.h <<\_ACEOF -#define HAVE_SETMODE 1 -_ACEOF - -fi - -ac_config_files="$ac_config_files contrib/check_cvs" - -ac_config_files="$ac_config_files contrib/clmerge" - -ac_config_files="$ac_config_files contrib/cln_hist" - -ac_config_files="$ac_config_files contrib/commit_prep" - -ac_config_files="$ac_config_files contrib/cvs_acls" - -ac_config_files="$ac_config_files contrib/log" - -ac_config_files="$ac_config_files contrib/log_accum" - -ac_config_files="$ac_config_files contrib/mfpipe" - -ac_config_files="$ac_config_files contrib/pvcs2rcs" - -ac_config_files="$ac_config_files contrib/rcs2log:contrib/rcs2log.sh" - -ac_config_files="$ac_config_files contrib/rcslock" - -ac_config_files="$ac_config_files contrib/sccs2rcs" - -ac_config_files="$ac_config_files doc/mkman:doc/mkman.pl" - -ac_config_files="$ac_config_files src/cvsbug" - -ac_config_files="$ac_config_files windows-NT/fix-msvc-mak:windows-NT/fix-msvc-mak-head.pl:windows-NT/fix-msvc-mak.pl" - - -ac_config_files="$ac_config_files Makefile contrib/Makefile cvs.spec diff/Makefile doc/Makefile emx/Makefile lib/Makefile man/Makefile os2/Makefile src/Makefile tools/Makefile vms/Makefile windows-NT/Makefile windows-NT/SCC/Makefile zlib/Makefile" - - -cat >confcache <<\_ACEOF -# This file is a shell script that caches the results of configure -# tests run on this system so they can be shared between configure -# scripts and configure runs, see configure's option --config-cache. -# It is not useful on other systems. If it contains results you don't -# want to keep, you may remove or edit it. -# -# config.status only pays attention to the cache file if you give it -# the --recheck option to rerun configure. -# -# `ac_cv_env_foo' variables (set or unset) will be overridden when -# loading this file, other *unset* `ac_cv_foo' will be assigned the -# following values. - -_ACEOF - -# The following way of writing the cache mishandles newlines in values, -# but we know of no workaround that is simple, portable, and efficient. -# So, we kill variables containing newlines. -# Ultrix sh set writes to stderr and can't be redirected directly, -# and sets the high bit in the cache file unless we assign to the vars. -( - for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do - eval ac_val=\$$ac_var - case $ac_val in #( - *${as_nl}*) - case $ac_var in #( - *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5 -echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;; - esac - case $ac_var in #( - _ | IFS | as_nl) ;; #( - *) $as_unset $ac_var ;; - esac ;; - esac - done - - (set) 2>&1 | - case $as_nl`(ac_space=' '; set) 2>&1` in #( - *${as_nl}ac_space=\ *) - # `set' does not quote correctly, so add quotes (double-quote - # substitution turns \\\\ into \\, and sed turns \\ into \). - sed -n \ - "s/'/'\\\\''/g; - s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" - ;; #( - *) - # `set' quotes correctly as required by POSIX, so do not add quotes. - sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" - ;; - esac | - sort -) | - sed ' - /^ac_cv_env_/b end - t clear - :clear - s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ - t end - s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ - :end' >>confcache -if diff "$cache_file" confcache >/dev/null 2>&1; then :; else - if test -w "$cache_file"; then - test "x$cache_file" != "x/dev/null" && - { echo "$as_me:$LINENO: updating cache $cache_file" >&5 -echo "$as_me: updating cache $cache_file" >&6;} - cat confcache >$cache_file - else - { echo "$as_me:$LINENO: not updating unwritable cache $cache_file" >&5 -echo "$as_me: not updating unwritable cache $cache_file" >&6;} - fi -fi -rm -f confcache - -test "x$prefix" = xNONE && prefix=$ac_default_prefix -# Let make expand exec_prefix. -test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' - -DEFS=-DHAVE_CONFIG_H - -ac_libobjs= -ac_ltlibobjs= -for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue - # 1. Remove the extension, and $U if already installed. - ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' - ac_i=`echo "$ac_i" | sed "$ac_script"` - # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR - # will be set to the directory where LIBOBJS objects are built. - ac_libobjs="$ac_libobjs \${LIBOBJDIR}$ac_i\$U.$ac_objext" - ac_ltlibobjs="$ac_ltlibobjs \${LIBOBJDIR}$ac_i"'$U.lo' -done -LIBOBJS=$ac_libobjs - -LTLIBOBJS=$ac_ltlibobjs - - -if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then - { { echo "$as_me:$LINENO: error: conditional \"MAINTAINER_MODE\" was never defined. -Usually this means the macro was only invoked conditionally." >&5 -echo "$as_me: error: conditional \"MAINTAINER_MODE\" was never defined. -Usually this means the macro was only invoked conditionally." >&2;} - { (exit 1); exit 1; }; } -fi -if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then - { { echo "$as_me:$LINENO: error: conditional \"AMDEP\" was never defined. -Usually this means the macro was only invoked conditionally." >&5 -echo "$as_me: error: conditional \"AMDEP\" was never defined. -Usually this means the macro was only invoked conditionally." >&2;} - { (exit 1); exit 1; }; } -fi -if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then - { { echo "$as_me:$LINENO: error: conditional \"am__fastdepCC\" was never defined. -Usually this means the macro was only invoked conditionally." >&5 -echo "$as_me: error: conditional \"am__fastdepCC\" was never defined. -Usually this means the macro was only invoked conditionally." >&2;} - { (exit 1); exit 1; }; } -fi -if test -z "${MAKE_TARGETS_IN_VPATH_TRUE}" && test -z "${MAKE_TARGETS_IN_VPATH_FALSE}"; then - { { echo "$as_me:$LINENO: error: conditional \"MAKE_TARGETS_IN_VPATH\" was never defined. -Usually this means the macro was only invoked conditionally." >&5 -echo "$as_me: error: conditional \"MAKE_TARGETS_IN_VPATH\" was never defined. -Usually this means the macro was only invoked conditionally." >&2;} - { (exit 1); exit 1; }; } -fi - -: ${CONFIG_STATUS=./config.status} -ac_clean_files_save=$ac_clean_files -ac_clean_files="$ac_clean_files $CONFIG_STATUS" -{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 -echo "$as_me: creating $CONFIG_STATUS" >&6;} -cat >$CONFIG_STATUS <<_ACEOF -#! $SHELL -# Generated by $as_me. -# Run this file to recreate the current configuration. -# Compiler output produced by configure, useful for debugging -# configure, is in config.log if it exists. - -debug=false -ac_cs_recheck=false -ac_cs_silent=false -SHELL=\${CONFIG_SHELL-$SHELL} -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF -## --------------------- ## -## M4sh Initialization. ## -## --------------------- ## - -# Be more Bourne compatible -DUALCASE=1; export DUALCASE # for MKS sh -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then - emulate sh - NULLCMD=: - # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which - # is contrary to our usage. Disable this feature. - alias -g '${1+"$@"}'='"$@"' - setopt NO_GLOB_SUBST -else - case `(set -o) 2>/dev/null` in - *posix*) set -o posix ;; -esac - -fi - - - - -# PATH needs CR -# Avoid depending upon Character Ranges. -as_cr_letters='abcdefghijklmnopqrstuvwxyz' -as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' -as_cr_Letters=$as_cr_letters$as_cr_LETTERS -as_cr_digits='0123456789' -as_cr_alnum=$as_cr_Letters$as_cr_digits - -# The user is always right. -if test "${PATH_SEPARATOR+set}" != set; then - echo "#! /bin/sh" >conf$$.sh - echo "exit 0" >>conf$$.sh - chmod +x conf$$.sh - if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then - PATH_SEPARATOR=';' - else - PATH_SEPARATOR=: - fi - rm -f conf$$.sh -fi - -# Support unset when possible. -if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then - as_unset=unset -else - as_unset=false -fi - - -# IFS -# We need space, tab and new line, in precisely that order. Quoting is -# there to prevent editors from complaining about space-tab. -# (If _AS_PATH_WALK were called with IFS unset, it would disable word -# splitting by setting IFS to empty value.) -as_nl=' -' -IFS=" "" $as_nl" - -# Find who we are. Look in the path if we contain no directory separator. -case $0 in - *[\\/]* ) as_myself=$0 ;; - *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break -done -IFS=$as_save_IFS - - ;; -esac -# We did not find ourselves, most probably we were run as `sh COMMAND' -# in which case we are not to be found in the path. -if test "x$as_myself" = x; then - as_myself=$0 -fi -if test ! -f "$as_myself"; then - echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 - { (exit 1); exit 1; } -fi - -# Work around bugs in pre-3.0 UWIN ksh. -for as_var in ENV MAIL MAILPATH -do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var -done -PS1='$ ' -PS2='> ' -PS4='+ ' - -# NLS nuisances. -for as_var in \ - LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ - LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ - LC_TELEPHONE LC_TIME -do - if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then - eval $as_var=C; export $as_var - else - ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var - fi -done - -# Required to use basename. -if expr a : '\(a\)' >/dev/null 2>&1 && - test "X`expr 00001 : '.*\(...\)'`" = X001; then - as_expr=expr -else - as_expr=false -fi - -if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then - as_basename=basename -else - as_basename=false -fi - - -# Name of the executable. -as_me=`$as_basename -- "$0" || -$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ - X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)' \| . 2>/dev/null || -echo X/"$0" | - sed '/^.*\/\([^/][^/]*\)\/*$/{ - s//\1/ - q - } - /^X\/\(\/\/\)$/{ - s//\1/ - q - } - /^X\/\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - -# CDPATH. -$as_unset CDPATH - - - - as_lineno_1=$LINENO - as_lineno_2=$LINENO - test "x$as_lineno_1" != "x$as_lineno_2" && - test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { - - # Create $as_me.lineno as a copy of $as_myself, but with $LINENO - # uniformly replaced by the line number. The first 'sed' inserts a - # line-number line after each line using $LINENO; the second 'sed' - # does the real work. The second script uses 'N' to pair each - # line-number line with the line containing $LINENO, and appends - # trailing '-' during substitution so that $LINENO is not a special - # case at line end. - # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the - # scripts with optimization help from Paolo Bonzini. Blame Lee - # E. McMahon (1931-1989) for sed's syntax. :-) - sed -n ' - p - /[$]LINENO/= - ' <$as_myself | - sed ' - s/[$]LINENO.*/&-/ - t lineno - b - :lineno - N - :loop - s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ - t loop - s/-\n.*// - ' >$as_me.lineno && - chmod +x "$as_me.lineno" || - { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 - { (exit 1); exit 1; }; } - - # Don't try to exec as it changes $[0], causing all sort of problems - # (the dirname of $[0] is not the place where we might find the - # original and so on. Autoconf is especially sensitive to this). - . "./$as_me.lineno" - # Exit status is that of the last command. - exit -} - - -if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then - as_dirname=dirname -else - as_dirname=false -fi - -ECHO_C= ECHO_N= ECHO_T= -case `echo -n x` in --n*) - case `echo 'x\c'` in - *c*) ECHO_T=' ';; # ECHO_T is single tab character. - *) ECHO_C='\c';; - esac;; -*) - ECHO_N='-n';; -esac - -if expr a : '\(a\)' >/dev/null 2>&1 && - test "X`expr 00001 : '.*\(...\)'`" = X001; then - as_expr=expr -else - as_expr=false -fi - -rm -f conf$$ conf$$.exe conf$$.file -if test -d conf$$.dir; then - rm -f conf$$.dir/conf$$.file -else - rm -f conf$$.dir - mkdir conf$$.dir -fi -echo >conf$$.file -if ln -s conf$$.file conf$$ 2>/dev/null; then - as_ln_s='ln -s' - # ... but there are two gotchas: - # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. - # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. - # In both cases, we have to default to `cp -p'. - ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || - as_ln_s='cp -p' -elif ln conf$$.file conf$$ 2>/dev/null; then - as_ln_s=ln -else - as_ln_s='cp -p' -fi -rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file -rmdir conf$$.dir 2>/dev/null - -if mkdir -p . 2>/dev/null; then - as_mkdir_p=: -else - test -d ./-p && rmdir ./-p - as_mkdir_p=false -fi - -if test -x / >/dev/null 2>&1; then - as_test_x='test -x' -else - if ls -dL / >/dev/null 2>&1; then - as_ls_L_option=L - else - as_ls_L_option= - fi - as_test_x=' - eval sh -c '\'' - if test -d "$1"; then - test -d "$1/."; - else - case $1 in - -*)set "./$1";; - esac; - case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in - ???[sx]*):;;*)false;;esac;fi - '\'' sh - ' -fi -as_executable_p=$as_test_x - -# Sed expression to map a string onto a valid CPP name. -as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" - -# Sed expression to map a string onto a valid variable name. -as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" - - -exec 6>&1 - -# Save the log message, to keep $[0] and so on meaningful, and to -# report actual input values of CONFIG_FILES etc. instead of their -# values after options handling. -ac_log=" -This file was extended by Concurrent Versions System (CVS) $as_me 1.11.22.1, which was -generated by GNU Autoconf 2.61. Invocation command line was - - CONFIG_FILES = $CONFIG_FILES - CONFIG_HEADERS = $CONFIG_HEADERS - CONFIG_LINKS = $CONFIG_LINKS - CONFIG_COMMANDS = $CONFIG_COMMANDS - $ $0 $@ - -on `(hostname || uname -n) 2>/dev/null | sed 1q` -" - -_ACEOF - -cat >>$CONFIG_STATUS <<_ACEOF -# Files that config.status was made for. -config_files="$ac_config_files" -config_headers="$ac_config_headers" -config_links="$ac_config_links" -config_commands="$ac_config_commands" - -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF -ac_cs_usage="\ -\`$as_me' instantiates files from templates according to the -current configuration. - -Usage: $0 [OPTIONS] [FILE]... - - -h, --help print this help, then exit - -V, --version print version number and configuration settings, then exit - -q, --quiet do not print progress messages - -d, --debug don't remove temporary files - --recheck update $as_me by reconfiguring in the same conditions - --file=FILE[:TEMPLATE] - instantiate the configuration file FILE - --header=FILE[:TEMPLATE] - instantiate the configuration header FILE - -Configuration files: -$config_files - -Configuration headers: -$config_headers - -Configuration links: -$config_links - -Configuration commands: -$config_commands - -Report bugs to ." - -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF -ac_cs_version="\\ -Concurrent Versions System (CVS) config.status 1.11.22.1 -configured by $0, generated by GNU Autoconf 2.61, - with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" - -Copyright (C) 2006 Free Software Foundation, Inc. -This config.status script is free software; the Free Software Foundation -gives unlimited permission to copy, distribute and modify it." - -ac_pwd='$ac_pwd' -srcdir='$srcdir' -INSTALL='$INSTALL' -MKDIR_P='$MKDIR_P' -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF -# If no file are specified by the user, then we need to provide default -# value. By we need to know if files were specified by the user. -ac_need_defaults=: -while test $# != 0 -do - case $1 in - --*=*) - ac_option=`expr "X$1" : 'X\([^=]*\)='` - ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` - ac_shift=: - ;; - *) - ac_option=$1 - ac_optarg=$2 - ac_shift=shift - ;; - esac - - case $ac_option in - # Handling of the options. - -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) - ac_cs_recheck=: ;; - --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) - echo "$ac_cs_version"; exit ;; - --debug | --debu | --deb | --de | --d | -d ) - debug=: ;; - --file | --fil | --fi | --f ) - $ac_shift - CONFIG_FILES="$CONFIG_FILES $ac_optarg" - ac_need_defaults=false;; - --header | --heade | --head | --hea ) - $ac_shift - CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg" - ac_need_defaults=false;; - --he | --h) - # Conflict between --help and --header - { echo "$as_me: error: ambiguous option: $1 -Try \`$0 --help' for more information." >&2 - { (exit 1); exit 1; }; };; - --help | --hel | -h ) - echo "$ac_cs_usage"; exit ;; - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil | --si | --s) - ac_cs_silent=: ;; - - # This is an error. - -*) { echo "$as_me: error: unrecognized option: $1 -Try \`$0 --help' for more information." >&2 - { (exit 1); exit 1; }; } ;; - - *) ac_config_targets="$ac_config_targets $1" - ac_need_defaults=false ;; - - esac - shift -done - -ac_configure_extra_args= - -if $ac_cs_silent; then - exec 6>/dev/null - ac_configure_extra_args="$ac_configure_extra_args --silent" -fi - -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF -if \$ac_cs_recheck; then - echo "running CONFIG_SHELL=$SHELL $SHELL $0 "$ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6 - CONFIG_SHELL=$SHELL - export CONFIG_SHELL - exec $SHELL "$0"$ac_configure_args \$ac_configure_extra_args --no-create --no-recursion -fi - -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF -exec 5>>config.log -{ - echo - sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX -## Running $as_me. ## -_ASBOX - echo "$ac_log" -} >&5 - -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF -# -# INIT-COMMANDS -# -AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" - -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF - -# Handling of arguments. -for ac_config_target in $ac_config_targets -do - case $ac_config_target in - "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; - "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; - "lib/fnmatch.h") CONFIG_LINKS="$CONFIG_LINKS lib/fnmatch.h:lib/fnmatch.h.in" ;; - "contrib/check_cvs") CONFIG_FILES="$CONFIG_FILES contrib/check_cvs" ;; - "contrib/clmerge") CONFIG_FILES="$CONFIG_FILES contrib/clmerge" ;; - "contrib/cln_hist") CONFIG_FILES="$CONFIG_FILES contrib/cln_hist" ;; - "contrib/commit_prep") CONFIG_FILES="$CONFIG_FILES contrib/commit_prep" ;; - "contrib/cvs_acls") CONFIG_FILES="$CONFIG_FILES contrib/cvs_acls" ;; - "contrib/log") CONFIG_FILES="$CONFIG_FILES contrib/log" ;; - "contrib/log_accum") CONFIG_FILES="$CONFIG_FILES contrib/log_accum" ;; - "contrib/mfpipe") CONFIG_FILES="$CONFIG_FILES contrib/mfpipe" ;; - "contrib/pvcs2rcs") CONFIG_FILES="$CONFIG_FILES contrib/pvcs2rcs" ;; - "contrib/rcs2log") CONFIG_FILES="$CONFIG_FILES contrib/rcs2log:contrib/rcs2log.sh" ;; - "contrib/rcslock") CONFIG_FILES="$CONFIG_FILES contrib/rcslock" ;; - "contrib/sccs2rcs") CONFIG_FILES="$CONFIG_FILES contrib/sccs2rcs" ;; - "doc/mkman") CONFIG_FILES="$CONFIG_FILES doc/mkman:doc/mkman.pl" ;; - "src/cvsbug") CONFIG_FILES="$CONFIG_FILES src/cvsbug" ;; - "windows-NT/fix-msvc-mak") CONFIG_FILES="$CONFIG_FILES windows-NT/fix-msvc-mak:windows-NT/fix-msvc-mak-head.pl:windows-NT/fix-msvc-mak.pl" ;; - "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; - "contrib/Makefile") CONFIG_FILES="$CONFIG_FILES contrib/Makefile" ;; - "cvs.spec") CONFIG_FILES="$CONFIG_FILES cvs.spec" ;; - "diff/Makefile") CONFIG_FILES="$CONFIG_FILES diff/Makefile" ;; - "doc/Makefile") CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;; - "emx/Makefile") CONFIG_FILES="$CONFIG_FILES emx/Makefile" ;; - "lib/Makefile") CONFIG_FILES="$CONFIG_FILES lib/Makefile" ;; - "man/Makefile") CONFIG_FILES="$CONFIG_FILES man/Makefile" ;; - "os2/Makefile") CONFIG_FILES="$CONFIG_FILES os2/Makefile" ;; - "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;; - "tools/Makefile") CONFIG_FILES="$CONFIG_FILES tools/Makefile" ;; - "vms/Makefile") CONFIG_FILES="$CONFIG_FILES vms/Makefile" ;; - "windows-NT/Makefile") CONFIG_FILES="$CONFIG_FILES windows-NT/Makefile" ;; - "windows-NT/SCC/Makefile") CONFIG_FILES="$CONFIG_FILES windows-NT/SCC/Makefile" ;; - "zlib/Makefile") CONFIG_FILES="$CONFIG_FILES zlib/Makefile" ;; - - *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 -echo "$as_me: error: invalid argument: $ac_config_target" >&2;} - { (exit 1); exit 1; }; };; - esac -done - - -# If the user did not use the arguments to specify the items to instantiate, -# then the envvar interface is used. Set only those that are not. -# We use the long form for the default assignment because of an extremely -# bizarre bug on SunOS 4.1.3. -if $ac_need_defaults; then - test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files - test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers - test "${CONFIG_LINKS+set}" = set || CONFIG_LINKS=$config_links - test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands -fi - -# Have a temporary directory for convenience. Make it in the build tree -# simply because there is no reason against having it here, and in addition, -# creating and moving files from /tmp can sometimes cause problems. -# Hook for its removal unless debugging. -# Note that there is a small window in which the directory will not be cleaned: -# after its creation but before its name has been assigned to `$tmp'. -$debug || -{ - tmp= - trap 'exit_status=$? - { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status -' 0 - trap '{ (exit 1); exit 1; }' 1 2 13 15 -} -# Create a (secure) tmp directory for tmp files. - -{ - tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && - test -n "$tmp" && test -d "$tmp" -} || -{ - tmp=./conf$$-$RANDOM - (umask 077 && mkdir "$tmp") -} || -{ - echo "$me: cannot create a temporary directory in ." >&2 - { (exit 1); exit 1; } -} - -# -# Set up the sed scripts for CONFIG_FILES section. -# - -# No need to generate the scripts if there are no CONFIG_FILES. -# This happens for instance when ./config.status config.h -if test -n "$CONFIG_FILES"; then - -_ACEOF - -# Create sed commands to just substitute file output variables. - -# Remaining file output variables are in a fragment that also has non-file -# output varibles. - - - -ac_delim='%!_!# ' -for ac_last_try in false false false false false :; do - cat >conf$$subs.sed <<_ACEOF -SHELL!$SHELL$ac_delim -PATH_SEPARATOR!$PATH_SEPARATOR$ac_delim -PACKAGE_NAME!$PACKAGE_NAME$ac_delim -PACKAGE_TARNAME!$PACKAGE_TARNAME$ac_delim -PACKAGE_VERSION!$PACKAGE_VERSION$ac_delim -PACKAGE_STRING!$PACKAGE_STRING$ac_delim -PACKAGE_BUGREPORT!$PACKAGE_BUGREPORT$ac_delim -exec_prefix!$exec_prefix$ac_delim -prefix!$prefix$ac_delim -program_transform_name!$program_transform_name$ac_delim -bindir!$bindir$ac_delim -sbindir!$sbindir$ac_delim -libexecdir!$libexecdir$ac_delim -datarootdir!$datarootdir$ac_delim -datadir!$datadir$ac_delim -sysconfdir!$sysconfdir$ac_delim -sharedstatedir!$sharedstatedir$ac_delim -localstatedir!$localstatedir$ac_delim -includedir!$includedir$ac_delim -oldincludedir!$oldincludedir$ac_delim -docdir!$docdir$ac_delim -infodir!$infodir$ac_delim -htmldir!$htmldir$ac_delim -dvidir!$dvidir$ac_delim -pdfdir!$pdfdir$ac_delim -psdir!$psdir$ac_delim -libdir!$libdir$ac_delim -localedir!$localedir$ac_delim -mandir!$mandir$ac_delim -DEFS!$DEFS$ac_delim -ECHO_C!$ECHO_C$ac_delim -ECHO_N!$ECHO_N$ac_delim -ECHO_T!$ECHO_T$ac_delim -LIBS!$LIBS$ac_delim -build_alias!$build_alias$ac_delim -host_alias!$host_alias$ac_delim -target_alias!$target_alias$ac_delim -INSTALL_PROGRAM!$INSTALL_PROGRAM$ac_delim -INSTALL_SCRIPT!$INSTALL_SCRIPT$ac_delim -INSTALL_DATA!$INSTALL_DATA$ac_delim -am__isrc!$am__isrc$ac_delim -CYGPATH_W!$CYGPATH_W$ac_delim -PACKAGE!$PACKAGE$ac_delim -VERSION!$VERSION$ac_delim -ACLOCAL!$ACLOCAL$ac_delim -AUTOCONF!$AUTOCONF$ac_delim -AUTOMAKE!$AUTOMAKE$ac_delim -AUTOHEADER!$AUTOHEADER$ac_delim -MAKEINFO!$MAKEINFO$ac_delim -install_sh!$install_sh$ac_delim -STRIP!$STRIP$ac_delim -INSTALL_STRIP_PROGRAM!$INSTALL_STRIP_PROGRAM$ac_delim -mkdir_p!$mkdir_p$ac_delim -AWK!$AWK$ac_delim -SET_MAKE!$SET_MAKE$ac_delim -am__leading_dot!$am__leading_dot$ac_delim -AMTAR!$AMTAR$ac_delim -am__tar!$am__tar$ac_delim -am__untar!$am__untar$ac_delim -ac_prefix_program!$ac_prefix_program$ac_delim -MAINTAINER_MODE_TRUE!$MAINTAINER_MODE_TRUE$ac_delim -MAINTAINER_MODE_FALSE!$MAINTAINER_MODE_FALSE$ac_delim -MAINT!$MAINT$ac_delim -CC!$CC$ac_delim -CFLAGS!$CFLAGS$ac_delim -LDFLAGS!$LDFLAGS$ac_delim -CPPFLAGS!$CPPFLAGS$ac_delim -ac_ct_CC!$ac_ct_CC$ac_delim -EXEEXT!$EXEEXT$ac_delim -OBJEXT!$OBJEXT$ac_delim -DEPDIR!$DEPDIR$ac_delim -am__include!$am__include$ac_delim -am__quote!$am__quote$ac_delim -AMDEP_TRUE!$AMDEP_TRUE$ac_delim -AMDEP_FALSE!$AMDEP_FALSE$ac_delim -AMDEPBACKSLASH!$AMDEPBACKSLASH$ac_delim -CCDEPMODE!$CCDEPMODE$ac_delim -am__fastdepCC_TRUE!$am__fastdepCC_TRUE$ac_delim -am__fastdepCC_FALSE!$am__fastdepCC_FALSE$ac_delim -CPP!$CPP$ac_delim -GREP!$GREP$ac_delim -EGREP!$EGREP$ac_delim -RANLIB!$RANLIB$ac_delim -YACC!$YACC$ac_delim -YFLAGS!$YFLAGS$ac_delim -LN_S!$LN_S$ac_delim -PERL!$PERL$ac_delim -CSH!$CSH$ac_delim -MKTEMP!$MKTEMP$ac_delim -SENDMAIL!$SENDMAIL$ac_delim -PR!$PR$ac_delim -ROFF!$ROFF$ac_delim -PS2PDF!$PS2PDF$ac_delim -TEXI2DVI!$TEXI2DVI$ac_delim -_ACEOF - - if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 94; then - break - elif $ac_last_try; then - { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 -echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} - { (exit 1); exit 1; }; } - else - ac_delim="$ac_delim!$ac_delim _$ac_delim!! " - fi -done - -ac_eof=`sed -n '/^CEOF[0-9]*$/s/CEOF/0/p' conf$$subs.sed` -if test -n "$ac_eof"; then - ac_eof=`echo "$ac_eof" | sort -nru | sed 1q` - ac_eof=`expr $ac_eof + 1` -fi - -cat >>$CONFIG_STATUS <<_ACEOF -cat >"\$tmp/subs-1.sed" <<\CEOF$ac_eof -/@[a-zA-Z_][a-zA-Z_0-9]*@/!b -/^[ ]*@MKTEMP_SH_FUNCTION@[ ]*$/{ -r $MKTEMP_SH_FUNCTION -d -} -_ACEOF -sed ' -s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g -s/^/s,@/; s/!/@,|#_!!_#|/ -:n -t n -s/'"$ac_delim"'$/,g/; t -s/$/\\/; p -N; s/^.*\n//; s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g; b n -' >>$CONFIG_STATUS >$CONFIG_STATUS <<_ACEOF -CEOF$ac_eof -_ACEOF - - -ac_delim='%!_!# ' -for ac_last_try in false false false false false :; do - cat >conf$$subs.sed <<_ACEOF -MAKE_TARGETS_IN_VPATH_TRUE!$MAKE_TARGETS_IN_VPATH_TRUE$ac_delim -MAKE_TARGETS_IN_VPATH_FALSE!$MAKE_TARGETS_IN_VPATH_FALSE$ac_delim -LIBOBJS!$LIBOBJS$ac_delim -KRB4!$KRB4$ac_delim -includeopt!$includeopt$ac_delim -EDITOR!$EDITOR$ac_delim -with_default_ssh!$with_default_ssh$ac_delim -with_default_rsh!$with_default_rsh$ac_delim -LTLIBOBJS!$LTLIBOBJS$ac_delim -_ACEOF - - if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 9; then - break - elif $ac_last_try; then - { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 -echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} - { (exit 1); exit 1; }; } - else - ac_delim="$ac_delim!$ac_delim _$ac_delim!! " - fi -done - -ac_eof=`sed -n '/^CEOF[0-9]*$/s/CEOF/0/p' conf$$subs.sed` -if test -n "$ac_eof"; then - ac_eof=`echo "$ac_eof" | sort -nru | sed 1q` - ac_eof=`expr $ac_eof + 1` -fi - -cat >>$CONFIG_STATUS <<_ACEOF -cat >"\$tmp/subs-2.sed" <<\CEOF$ac_eof -/@[a-zA-Z_][a-zA-Z_0-9]*@/!b end -_ACEOF -sed ' -s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g -s/^/s,@/; s/!/@,|#_!!_#|/ -:n -t n -s/'"$ac_delim"'$/,g/; t -s/$/\\/; p -N; s/^.*\n//; s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g; b n -' >>$CONFIG_STATUS >$CONFIG_STATUS <<_ACEOF -:end -s/|#_!!_#|//g -CEOF$ac_eof -_ACEOF - - -# VPATH may cause trouble with some makes, so we remove $(srcdir), -# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and -# trailing colons and then remove the whole line if VPATH becomes empty -# (actually we leave an empty line to preserve line numbers). -if test "x$srcdir" = x.; then - ac_vpsub='/^[ ]*VPATH[ ]*=/{ -s/:*\$(srcdir):*/:/ -s/:*\${srcdir}:*/:/ -s/:*@srcdir@:*/:/ -s/^\([^=]*=[ ]*\):*/\1/ -s/:*$// -s/^[^=]*=[ ]*$// -}' -fi - -cat >>$CONFIG_STATUS <<\_ACEOF -fi # test -n "$CONFIG_FILES" - - -for ac_tag in :F $CONFIG_FILES :H $CONFIG_HEADERS :L $CONFIG_LINKS :C $CONFIG_COMMANDS -do - case $ac_tag in - :[FHLC]) ac_mode=$ac_tag; continue;; - esac - case $ac_mode$ac_tag in - :[FHL]*:*);; - :L* | :C*:*) { { echo "$as_me:$LINENO: error: Invalid tag $ac_tag." >&5 -echo "$as_me: error: Invalid tag $ac_tag." >&2;} - { (exit 1); exit 1; }; };; - :[FH]-) ac_tag=-:-;; - :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; - esac - ac_save_IFS=$IFS - IFS=: - set x $ac_tag - IFS=$ac_save_IFS - shift - ac_file=$1 - shift - - case $ac_mode in - :L) ac_source=$1;; - :[FH]) - ac_file_inputs= - for ac_f - do - case $ac_f in - -) ac_f="$tmp/stdin";; - *) # Look for the file first in the build tree, then in the source tree - # (if the path is not absolute). The absolute path cannot be DOS-style, - # because $ac_f cannot contain `:'. - test -f "$ac_f" || - case $ac_f in - [\\/$]*) false;; - *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; - esac || - { { echo "$as_me:$LINENO: error: cannot find input file: $ac_f" >&5 -echo "$as_me: error: cannot find input file: $ac_f" >&2;} - { (exit 1); exit 1; }; };; - esac - ac_file_inputs="$ac_file_inputs $ac_f" - done - - # Let's still pretend it is `configure' which instantiates (i.e., don't - # use $as_me), people would be surprised to read: - # /* config.h. Generated by config.status. */ - configure_input="Generated from "`IFS=: - echo $* | sed 's|^[^:]*/||;s|:[^:]*/|, |g'`" by configure." - if test x"$ac_file" != x-; then - configure_input="$ac_file. $configure_input" - { echo "$as_me:$LINENO: creating $ac_file" >&5 -echo "$as_me: creating $ac_file" >&6;} - fi - - case $ac_tag in - *:-:* | *:-) cat >"$tmp/stdin";; - esac - ;; - esac - - ac_dir=`$as_dirname -- "$ac_file" || -$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$ac_file" : 'X\(//\)[^/]' \| \ - X"$ac_file" : 'X\(//\)$' \| \ - X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || -echo X"$ac_file" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - { as_dir="$ac_dir" - case $as_dir in #( - -*) as_dir=./$as_dir;; - esac - test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || { - as_dirs= - while :; do - case $as_dir in #( - *\'*) as_qdir=`echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #( - *) as_qdir=$as_dir;; - esac - as_dirs="'$as_qdir' $as_dirs" - as_dir=`$as_dirname -- "$as_dir" || -$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$as_dir" : 'X\(//\)[^/]' \| \ - X"$as_dir" : 'X\(//\)$' \| \ - X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || -echo X"$as_dir" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - test -d "$as_dir" && break - done - test -z "$as_dirs" || eval "mkdir $as_dirs" - } || test -d "$as_dir" || { { echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5 -echo "$as_me: error: cannot create directory $as_dir" >&2;} - { (exit 1); exit 1; }; }; } - ac_builddir=. - -case "$ac_dir" in -.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; -*) - ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` - # A ".." for each directory in $ac_dir_suffix. - ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'` - case $ac_top_builddir_sub in - "") ac_top_builddir_sub=. ac_top_build_prefix= ;; - *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; - esac ;; -esac -ac_abs_top_builddir=$ac_pwd -ac_abs_builddir=$ac_pwd$ac_dir_suffix -# for backward compatibility: -ac_top_builddir=$ac_top_build_prefix - -case $srcdir in - .) # We are building in place. - ac_srcdir=. - ac_top_srcdir=$ac_top_builddir_sub - ac_abs_top_srcdir=$ac_pwd ;; - [\\/]* | ?:[\\/]* ) # Absolute name. - ac_srcdir=$srcdir$ac_dir_suffix; - ac_top_srcdir=$srcdir - ac_abs_top_srcdir=$srcdir ;; - *) # Relative name. - ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix - ac_top_srcdir=$ac_top_build_prefix$srcdir - ac_abs_top_srcdir=$ac_pwd/$srcdir ;; -esac -ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix - - - case $ac_mode in - :F) - # - # CONFIG_FILE - # - - case $INSTALL in - [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; - *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; - esac - ac_MKDIR_P=$MKDIR_P - case $MKDIR_P in - [\\/$]* | ?:[\\/]* ) ;; - */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; - esac -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF -# If the template does not know about datarootdir, expand it. -# FIXME: This hack should be removed a few years after 2.60. -ac_datarootdir_hack=; ac_datarootdir_seen= - -case `sed -n '/datarootdir/ { - p - q -} -/@datadir@/p -/@docdir@/p -/@infodir@/p -/@localedir@/p -/@mandir@/p -' $ac_file_inputs` in -*datarootdir*) ac_datarootdir_seen=yes;; -*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) - { echo "$as_me:$LINENO: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 -echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF - ac_datarootdir_hack=' - s&@datadir@&$datadir&g - s&@docdir@&$docdir&g - s&@infodir@&$infodir&g - s&@localedir@&$localedir&g - s&@mandir@&$mandir&g - s&\\\${datarootdir}&$datarootdir&g' ;; -esac -_ACEOF - -# Neutralize VPATH when `$srcdir' = `.'. -# Shell code in configure.ac might set extrasub. -# FIXME: do we really want to maintain this feature? -cat >>$CONFIG_STATUS <<_ACEOF - sed "$ac_vpsub -$extrasub -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF -:t -/@[a-zA-Z_][a-zA-Z_0-9]*@/!b -s&@configure_input@&$configure_input&;t t -s&@top_builddir@&$ac_top_builddir_sub&;t t -s&@srcdir@&$ac_srcdir&;t t -s&@abs_srcdir@&$ac_abs_srcdir&;t t -s&@top_srcdir@&$ac_top_srcdir&;t t -s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t -s&@builddir@&$ac_builddir&;t t -s&@abs_builddir@&$ac_abs_builddir&;t t -s&@abs_top_builddir@&$ac_abs_top_builddir&;t t -s&@INSTALL@&$ac_INSTALL&;t t -s&@MKDIR_P@&$ac_MKDIR_P&;t t -$ac_datarootdir_hack -" $ac_file_inputs | sed -f "$tmp/subs-1.sed" | sed -f "$tmp/subs-2.sed" >$tmp/out - -test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && - { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } && - { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } && - { echo "$as_me:$LINENO: WARNING: $ac_file contains a reference to the variable \`datarootdir' -which seems to be undefined. Please make sure it is defined." >&5 -echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' -which seems to be undefined. Please make sure it is defined." >&2;} - - rm -f "$tmp/stdin" - case $ac_file in - -) cat "$tmp/out"; rm -f "$tmp/out";; - *) rm -f "$ac_file"; mv "$tmp/out" $ac_file;; - esac - ;; - :H) - # - # CONFIG_HEADER - # -_ACEOF - -# Transform confdefs.h into a sed script `conftest.defines', that -# substitutes the proper values into config.h.in to produce config.h. -rm -f conftest.defines conftest.tail -# First, append a space to every undef/define line, to ease matching. -echo 's/$/ /' >conftest.defines -# Then, protect against being on the right side of a sed subst, or in -# an unquoted here document, in config.status. If some macros were -# called several times there might be several #defines for the same -# symbol, which is useless. But do not sort them, since the last -# AC_DEFINE must be honored. -ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* -# These sed commands are passed to sed as "A NAME B PARAMS C VALUE D", where -# NAME is the cpp macro being defined, VALUE is the value it is being given. -# PARAMS is the parameter list in the macro definition--in most cases, it's -# just an empty string. -ac_dA='s,^\\([ #]*\\)[^ ]*\\([ ]*' -ac_dB='\\)[ (].*,\\1define\\2' -ac_dC=' ' -ac_dD=' ,' - -uniq confdefs.h | - sed -n ' - t rset - :rset - s/^[ ]*#[ ]*define[ ][ ]*// - t ok - d - :ok - s/[\\&,]/\\&/g - s/^\('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/ '"$ac_dA"'\1'"$ac_dB"'\2'"${ac_dC}"'\3'"$ac_dD"'/p - s/^\('"$ac_word_re"'\)[ ]*\(.*\)/'"$ac_dA"'\1'"$ac_dB$ac_dC"'\2'"$ac_dD"'/p - ' >>conftest.defines - -# Remove the space that was appended to ease matching. -# Then replace #undef with comments. This is necessary, for -# example, in the case of _POSIX_SOURCE, which is predefined and required -# on some systems where configure will not decide to define it. -# (The regexp can be short, since the line contains either #define or #undef.) -echo 's/ $// -s,^[ #]*u.*,/* & */,' >>conftest.defines - -# Break up conftest.defines: -ac_max_sed_lines=50 - -# First sed command is: sed -f defines.sed $ac_file_inputs >"$tmp/out1" -# Second one is: sed -f defines.sed "$tmp/out1" >"$tmp/out2" -# Third one will be: sed -f defines.sed "$tmp/out2" >"$tmp/out1" -# et cetera. -ac_in='$ac_file_inputs' -ac_out='"$tmp/out1"' -ac_nxt='"$tmp/out2"' - -while : -do - # Write a here document: - cat >>$CONFIG_STATUS <<_ACEOF - # First, check the format of the line: - cat >"\$tmp/defines.sed" <<\\CEOF -/^[ ]*#[ ]*undef[ ][ ]*$ac_word_re[ ]*\$/b def -/^[ ]*#[ ]*define[ ][ ]*$ac_word_re[( ]/b def -b -:def -_ACEOF - sed ${ac_max_sed_lines}q conftest.defines >>$CONFIG_STATUS - echo 'CEOF - sed -f "$tmp/defines.sed"' "$ac_in >$ac_out" >>$CONFIG_STATUS - ac_in=$ac_out; ac_out=$ac_nxt; ac_nxt=$ac_in - sed 1,${ac_max_sed_lines}d conftest.defines >conftest.tail - grep . conftest.tail >/dev/null || break - rm -f conftest.defines - mv conftest.tail conftest.defines -done -rm -f conftest.defines conftest.tail - -echo "ac_result=$ac_in" >>$CONFIG_STATUS -cat >>$CONFIG_STATUS <<\_ACEOF - if test x"$ac_file" != x-; then - echo "/* $configure_input */" >"$tmp/config.h" - cat "$ac_result" >>"$tmp/config.h" - if diff $ac_file "$tmp/config.h" >/dev/null 2>&1; then - { echo "$as_me:$LINENO: $ac_file is unchanged" >&5 -echo "$as_me: $ac_file is unchanged" >&6;} - else - rm -f $ac_file - mv "$tmp/config.h" $ac_file - fi - else - echo "/* $configure_input */" - cat "$ac_result" - fi - rm -f "$tmp/out12" -# Compute $ac_file's index in $config_headers. -_am_stamp_count=1 -for _am_header in $config_headers :; do - case $_am_header in - $ac_file | $ac_file:* ) - break ;; - * ) - _am_stamp_count=`expr $_am_stamp_count + 1` ;; - esac -done -echo "timestamp for $ac_file" >`$as_dirname -- $ac_file || -$as_expr X$ac_file : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X$ac_file : 'X\(//\)[^/]' \| \ - X$ac_file : 'X\(//\)$' \| \ - X$ac_file : 'X\(/\)' \| . 2>/dev/null || -echo X$ac_file | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'`/stamp-h$_am_stamp_count - ;; - :L) - # - # CONFIG_LINK - # - - { echo "$as_me:$LINENO: linking $srcdir/$ac_source to $ac_file" >&5 -echo "$as_me: linking $srcdir/$ac_source to $ac_file" >&6;} - - if test ! -r "$srcdir/$ac_source"; then - { { echo "$as_me:$LINENO: error: $srcdir/$ac_source: file not found" >&5 -echo "$as_me: error: $srcdir/$ac_source: file not found" >&2;} - { (exit 1); exit 1; }; } - fi - rm -f "$ac_file" - - # Try a relative symlink, then a hard link, then a copy. - case $srcdir in - [\\/$]* | ?:[\\/]* ) ac_rel_source=$srcdir/$ac_source ;; - *) ac_rel_source=$ac_top_build_prefix$srcdir/$ac_source ;; - esac - ln -s "$ac_rel_source" "$ac_file" 2>/dev/null || - ln "$srcdir/$ac_source" "$ac_file" 2>/dev/null || - cp -p "$srcdir/$ac_source" "$ac_file" || - { { echo "$as_me:$LINENO: error: cannot link or copy $srcdir/$ac_source to $ac_file" >&5 -echo "$as_me: error: cannot link or copy $srcdir/$ac_source to $ac_file" >&2;} - { (exit 1); exit 1; }; } - ;; - :C) { echo "$as_me:$LINENO: executing $ac_file commands" >&5 -echo "$as_me: executing $ac_file commands" >&6;} - ;; - esac - - - case $ac_file$ac_mode in - "depfiles":C) test x"$AMDEP_TRUE" != x"" || for mf in $CONFIG_FILES; do - # Strip MF so we end up with the name of the file. - mf=`echo "$mf" | sed -e 's/:.*$//'` - # Check whether this is an Automake generated Makefile or not. - # We used to match only the files named `Makefile.in', but - # some people rename them; so instead we look at the file content. - # Grep'ing the first line is not enough: some people post-process - # each Makefile.in and add a new line on top of each file to say so. - # Grep'ing the whole file is not good either: AIX grep has a line - # limit of 2048, but all sed's we know have understand at least 4000. - if sed 10q "$mf" | grep '^#.*generated by automake' > /dev/null 2>&1; then - dirpart=`$as_dirname -- "$mf" || -$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$mf" : 'X\(//\)[^/]' \| \ - X"$mf" : 'X\(//\)$' \| \ - X"$mf" : 'X\(/\)' \| . 2>/dev/null || -echo X"$mf" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - else - continue - fi - # Extract the definition of DEPDIR, am__include, and am__quote - # from the Makefile without running `make'. - DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` - test -z "$DEPDIR" && continue - am__include=`sed -n 's/^am__include = //p' < "$mf"` - test -z "am__include" && continue - am__quote=`sed -n 's/^am__quote = //p' < "$mf"` - # When using ansi2knr, U may be empty or an underscore; expand it - U=`sed -n 's/^U = //p' < "$mf"` - # Find all dependency output files, they are included files with - # $(DEPDIR) in their names. We invoke sed twice because it is the - # simplest approach to changing $(DEPDIR) to its actual value in the - # expansion. - for file in `sed -n " - s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ - sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do - # Make sure the directory exists. - test -f "$dirpart/$file" && continue - fdir=`$as_dirname -- "$file" || -$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$file" : 'X\(//\)[^/]' \| \ - X"$file" : 'X\(//\)$' \| \ - X"$file" : 'X\(/\)' \| . 2>/dev/null || -echo X"$file" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - { as_dir=$dirpart/$fdir - case $as_dir in #( - -*) as_dir=./$as_dir;; - esac - test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || { - as_dirs= - while :; do - case $as_dir in #( - *\'*) as_qdir=`echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #( - *) as_qdir=$as_dir;; - esac - as_dirs="'$as_qdir' $as_dirs" - as_dir=`$as_dirname -- "$as_dir" || -$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$as_dir" : 'X\(//\)[^/]' \| \ - X"$as_dir" : 'X\(//\)$' \| \ - X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || -echo X"$as_dir" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - test -d "$as_dir" && break - done - test -z "$as_dirs" || eval "mkdir $as_dirs" - } || test -d "$as_dir" || { { echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5 -echo "$as_me: error: cannot create directory $as_dir" >&2;} - { (exit 1); exit 1; }; }; } - # echo "creating $dirpart/$file" - echo '# dummy' > "$dirpart/$file" - done -done - ;; - "contrib/check_cvs":F) chmod +x contrib/check_cvs ;; - "contrib/clmerge":F) chmod +x contrib/clmerge ;; - "contrib/cln_hist":F) chmod +x contrib/cln_hist ;; - "contrib/commit_prep":F) chmod +x contrib/commit_prep ;; - "contrib/cvs_acls":F) chmod +x contrib/cvs_acls ;; - "contrib/log":F) chmod +x contrib/log ;; - "contrib/log_accum":F) chmod +x contrib/log_accum ;; - "contrib/mfpipe":F) chmod +x contrib/mfpipe ;; - "contrib/pvcs2rcs":F) chmod +x contrib/pvcs2rcs ;; - "contrib/rcs2log":F) chmod +x contrib/rcs2log ;; - "contrib/rcslock":F) chmod +x contrib/rcslock ;; - "contrib/sccs2rcs":F) chmod +x contrib/sccs2rcs ;; - "doc/mkman":F) chmod +x doc/mkman ;; - "src/cvsbug":F) chmod +x src/cvsbug ;; - "windows-NT/fix-msvc-mak":F) chmod +x windows-NT/fix-msvc-mak ;; - - esac -done # for ac_tag - - -{ (exit 0); exit 0; } -_ACEOF -chmod +x $CONFIG_STATUS -ac_clean_files=$ac_clean_files_save - - -# configure is writing to config.log, and then calls config.status. -# config.status does its own redirection, appending to config.log. -# Unfortunately, on DOS this fails, as config.log is still kept open -# by configure, so config.status won't be able to write to it; its -# output is simply discarded. So we exec the FD to /dev/null, -# effectively closing config.log, so it can be properly (re)opened and -# appended to by config.status. When coming back to configure, we -# need to make the FD available again. -if test "$no_create" != yes; then - ac_cs_success=: - ac_config_status_args= - test "$silent" = yes && - ac_config_status_args="$ac_config_status_args --quiet" - exec 5>/dev/null - $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false - exec 5>>config.log - # Use ||, not &&, to avoid exiting from the if with $? = 1, which - # would make configure fail if this is the last instruction. - $ac_cs_success || { (exit 1); exit 1; } -fi - - - - -# Report the state of this version of CVS if this is from dev. - cat <. - -Below you will find information on the status of this version of CVS. - - -EOF - sed -n '/^\* Status/,$p' $srcdir/BUGS - diff --git a/contrib/cvs/configure.in b/contrib/cvs/configure.in deleted file mode 100644 index 8c83397..0000000 --- a/contrib/cvs/configure.in +++ /dev/null @@ -1,1172 +0,0 @@ -dnl configure.in for cvs -AC_INIT([Concurrent Versions System (CVS)],[1.11.22.1], - [bug-cvs@nongnu.org],[cvs]) -AC_CONFIG_SRCDIR(src/cvs.h) -AM_INIT_AUTOMAKE([gnu 1.7.9 dist-bzip2 no-define]) -AC_PREREQ(2.60) - -AC_PREFIX_PROGRAM(cvs) -AM_CONFIG_HEADER(config.h) -AM_MAINTAINER_MODE - -AC_PROG_CC -AM_PROG_CC_C_O - -dnl FIXME the next three calls should be avoided according to autoconf -dnl philosophy. for example, AC_CHECK_LIB should be used to look for crypt. -dnl -dnl These are here instead of later because they want to be called before -dnl anything that calls a C compiler. -AC_AIX -AC_MINIX - -# Find the posix library needed on INTERACTIVE UNIX (ISC) -dnl -dnl From the Autoconf 2.53 manual (AC_ISC_POSIX): -dnl -dnl For INTERACTIVE UNIX (ISC), add `-lcposix' to output variable -dnl `LIBS' if necessary for POSIX facilities. Call this after -dnl `AC_PROG_CC' and before any other macros that use POSIX -dnl interfaces. INTERACTIVE UNIX is no longer sold, and Sun says that -dnl they will drop support for it on 2006-07-23, so this macro is -dnl becoming obsolescent. -dnl -AC_SEARCH_LIBS([strerror], [cposix]) - -dnl -dnl Autoconf stopped setting $ISC sometime before 2.53 -dnl -dnl If this is still important, someone should come up with a generic test -dnl for whether _SYSV3 needs to be defined. Removed code below: -dnl -dnl if test "$ISC" = yes; then -dnl CFLAGS="$CFLAGS -D_SYSV3" -dnl # And I don't like this... In theory it should be found later if server is -dnl # enabled, but maybe something on INTERACTIVE UNIX (ISC) we didn't ask to -dnl # link with crypt tries? Anyhow, the autoconf manual says we can delete -dnl # this ISC stuff on or after 2006-07-23 when Sun discontinues support and -dnl # ISC becomes obsolescent, but I suppose that is probably a matter of -dnl # opinion. -dnl # -dnl # N.B. The reason for doing this is that some moron decided to put a stub -dnl # for crypt in libc that always returns NULL. Without this here, the later -dnl # check will find the stub instead of the real thing, resulting in a server -dnl # that can't process crypted passwords correctly. -dnl -dnl # again, if we have to try and reenable this for ISC, someone should come -dnl # up with a generic test that figures out whether crypt is good or not - -dnl # Is it always returning NULL? -dnl LIBS="-lcrypt $LIBS" -dnl fi -dnl -dnl FIXME - This has been broken for at least a few months anyhow, so I'm -dnl removing the crypt lib define above, but the correct fix would be to -dnl provide a CRYPT_WORKS macro or the like that gets called sometime after -dnl the AC_SEARCH_LIBS call that normally finds crypt, and if crypt doesn't -dnl work, the macro should be retried with LIBS="-lcrypt $LIBS" forced. -dnl - -AC_PROG_RANLIB -AC_PROG_YACC -AC_PROG_LN_S -AC_EXEEXT - -AC_PATH_PROG(PERL, perl, no) -AC_PATH_PROG(CSH, csh, no) -# for contrib/rcs2log.sh & src/cvsbug.in. -AC_PATH_PROG(MKTEMP, mktemp, mktemp) -if test x"$MKTEMP" = xmktemp; then - MKTEMP_SH_FUNCTION=$srcdir/mktemp.sh -else - MKTEMP_SH_FUNCTION=/dev/null -fi -AC_SUBST_FILE(MKTEMP_SH_FUNCTION) -# for src/cvsbug.in -AC_PATH_PROG(SENDMAIL, sendmail, no, [$PATH:/usr/sbin:/usr/lib]) -# For diff/util.c -AC_PATH_PROG(PR, pr, no) -if test x"$PR" != xno; then - AC_DEFINE_UNQUOTED([PR_PROGRAM], ["$PR"], [Path to the pr utility]) -fi - -dnl FIXME This is truly gross. -missing_dir=`cd $ac_aux_dir && pwd` -dnl FIXME I pulled this default list from sanity.sh. Perhaps these lists -dnl can be stored in one location? -dnl -dnl Yeah, put the value in a variable add it to the substitution list -dnl then have configure create sanity.sh from sanity.sh.in... -glocs="$PATH:/usr/local/bin:/usr/contrib/bin:/usr/gnu/bin:/local/bin:/local/gnu/bin:/gnu/bin" -AC_PATH_PROGS(ROFF, groff roff, $missing_dir/missing roff, $glocs) -AC_PATH_PROG(PS2PDF, ps2pdf, $missing_dir/missing ps2pdf) -AC_PATH_PROG(TEXI2DVI, texi2dvi, $missing_dir/missing texi2dvi) - -AC_SYS_INTERPRETER -if test X"$ac_cv_sys_interpreter" != X"yes" ; then - # silly trick to avoid problems in AC macros... - ac_msg='perl scripts using #! may not be invoked properly' - AC_MSG_WARN($ac_msg) -fi - -# BSD's logo is a devil for a reason, hey? -AC_CACHE_CHECK(for BSD VPATH bug in make, ccvs_cv_bsd_make_vpath_bug, -[if test ! -d ac_test_dir ; then - AC_TRY_COMMAND([mkdir ac_test_dir]) -fi -cat >conftestmake <&2 -ac_test_dep: ac_test_dep_dep -EOF -touch ac_test_dir/ac_test_dep_dep -touch ac_test_dir/ac_test_dep -touch ac_test_target -# Don't know why, but the following test doesn't work under FreeBSD 4.2 -# without this sleep command -sleep 1 -if AC_TRY_COMMAND([make -f conftestmake 2>&1 >/dev/null |grep ^BSD\ VPATH\ bug\ present\$ >/dev/null]) ; then - ccvs_cv_bsd_make_vpath_bug=yes -else - ccvs_cv_bsd_make_vpath_bug=no -fi -AC_TRY_COMMAND([rm -rf ac_test_dir ac_test_target conftestmake])]) -# We also don't need to worry about the bug when $srcdir = $builddir -AM_CONDITIONAL(MAKE_TARGETS_IN_VPATH, \ - test $ccvs_cv_bsd_make_vpath_bug = no \ - || test $srcdir = .) - -AC_HEADER_DIRENT -AC_HEADER_STDC -AC_HEADER_SYS_WAIT -AC_CHECK_HEADERS(\ - errno.h \ - direct.h \ - fcntl.h \ - fnmatch.h \ - io.h \ - limits.h \ - memory.h \ - ndbm.h \ - string.h \ - syslog.h \ - sys/bsdtypes.h \ - sys/file.h \ - sys/param.h \ - sys/resource.h \ - sys/select.h \ - sys/time.h \ - sys/timeb.h \ - unistd.h \ - utime.h\ -) -AC_HEADER_STAT -AC_HEADER_TIME - -AC_C_CONST -AC_TYPE_UID_T -AC_TYPE_MODE_T -AC_TYPE_PID_T -AC_TYPE_SIZE_T -AC_TYPE_SIGNAL - -AC_CHECK_MEMBERS([struct stat.st_blksize]) -AC_CHECK_MEMBERS([struct stat.st_rdev]) - -AC_REPLACE_FUNCS(\ - dup2 \ - ftruncate \ - gethostname \ - memmove \ - mkdir \ - rename \ - strerror \ - strstr \ - strtoul\ - valloc \ - waitpid \ -) - - - -dnl -dnl Begin GNULIB stuff. -dnl -gl_XSIZE - -dnl We always want to use the GNULIB getpass, so define its name to something -dnl that won't conflict with system declarations. -AC_DEFINE([getpass], [cvs_getpass], - [We want to always use the GNULIB version of getpass which we have in lib, - so define getpass to something that won't conflict with any existing system - declarations.]) - -dnl -dnl End GNULIB stuff. -dnl - - - -AC_CHECK_FUNCS(\ - fchdir \ - fchmod \ - fsync \ - ftime \ - geteuid \ - getgroups \ - getopt \ - getpagesize \ - gettimeofday \ - initgroups \ - login \ - logout \ - mknod \ - mkstemp \ - mktemp \ - putenv \ - readlink \ - regcomp \ - regerror \ - regexec \ - regfree \ - sigaction \ - sigblock \ - sigprocmask \ - sigsetmask \ - sigvec \ - tempnam \ - timezone \ - tzset \ - vprintf \ - wait3 \ -) -# we only need one of the following -AC_CHECK_FUNCS([\ - nanosleep \ - usleep \ - select \ -], [break]) - -dnl -dnl The CVS coding standard (as specified in HACKING) is that if it exists -dnl in SunOS4 and ANSI, we use it. CVS itself, of course, therefore doesn't -dnl need HAVE_* defines for such functions, but diff wants them. -dnl -AC_DEFINE(HAVE_STRCHR, 1, -[Define if you have strchr (always for CVS).]) -AC_DEFINE(HAVE_MEMCHR, 1, -[Define if you have memchr (always for CVS).]) - -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, 1, -[Define to force lib/regex.c to use malloc instead of alloca.]) -AC_DEFINE(_REGEX_RE_COMP, 1, -[Define to force lib/regex.c to define re_comp et al.]) -dnl -dnl AC_FUNC_FORK([]) is rather baroque. It seems to be rather more picky -dnl than, say, the Single Unix Specification (version 2), which simplifies -dnl a lot of cases by saying that the child process can't set any variables -dnl (thus avoiding problems with register allocation) or call any functions -dnl (thus avoiding problems with whether file descriptors are shared). -dnl It would be nice if we could just write to the Single Unix Specification. -dnl I think the only way to do redirection this way is by doing it in the -dnl parent, and then undoing it afterwards (analogous to windows-NT/run.c). -dnl That would appear to have a race condition if the user hits ^C (or -dnl some other signal) at the wrong time, as main_cleanup will try to use -dnl stdout/stderr. So maybe we are stuck with AC_FUNC_FORK([]). -dnl -AC_FUNC_FORK([]) -AC_FUNC_CLOSEDIR_VOID - -dnl -dnl Check for shadow password support. -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_SEARCH_LIBS(getspnam, sec gen, AC_DEFINE(HAVE_GETSPNAM, 1, -[Define if you have the getspnam function.])) - -AC_FUNC_UTIME_NULL -AC_SYS_LONG_FILE_NAMES - -AC_FUNC_FNMATCH -if test "$ac_cv_func_fnmatch_works" = no; then - AC_LIBOBJ(fnmatch) - AC_CONFIG_LINKS(lib/fnmatch.h:lib/fnmatch.h.in) - AC_LIBSOURCE(fnmatch.h.in) -fi - -# Try to find connect and gethostbyname. -AC_CHECK_LIB(nsl, main) -AC_SEARCH_LIBS(connect, xnet socket inet, - AC_DEFINE(HAVE_CONNECT, 1, -[Define if you have the connect function.])) -dnl no need to search nsl for gethostbyname here since we should have -dnl just added libnsl above if we found it. -AC_SEARCH_LIBS(gethostbyname, netinet) - - -dnl -dnl begin --with-* -dnl - -dnl -dnl set $(KRB4) from --with-krb4=value -- WITH_KRB4 -dnl -dnl If you change this, keep in mind that some systems have a bogus -dnl libkrb in the system libraries, so --with-krb4=value needs to -dnl override the system -lkrb. -dnl -KRB4=/usr/kerberos -define(WITH_KRB4,[ -AC_ARG_WITH( - [krb4], - AC_HELP_STRING( - [--with-krb4], - [Kerberos 4 directory (default /usr/kerberos)]), - [KRB4=$with_krb4], -)dnl -AC_MSG_CHECKING([for KRB4 in $KRB4]) -AC_MSG_RESULT([]) -AC_SUBST(KRB4)])dnl -WITH_KRB4 - -krb_h= -AC_MSG_CHECKING([for krb.h]) -if test "$cross_compiling" != yes && test -r $KRB4/include/krb.h; then - hold_cflags=$CFLAGS - CFLAGS="$CFLAGS -I$KRB4/include" - AC_TRY_LINK([#include ],[int i;], - [krb_h=yes krb_incdir=$KRB4/include], - [CFLAGS=$hold_cflags - AC_TRY_LINK([#include ],[int i;], - [krb_h=yes krb_incdir=])]) - CFLAGS=$hold_cflags -else - AC_TRY_LINK([#include ],[int i;], - [krb_h=yes krb_incdir=]) -fi -if test -z "$krb_h"; then - AC_TRY_LINK([#include ],[int i;], - [krb_h=yes krb_incdir=], - [if test "$cross_compiling" != yes && test -r $KRB4/include/kerberosIV/krb.h; then - hold_cflags=$CFLAGS - CFLAGS="$CFLAGS -I$KRB4/include/kerberosIV" - AC_TRY_LINK([#include ],[int i;], - [krb_h=yes krb_incdir=$KRB4/include/kerberosIV]) - CFLAGS=$hold_cflags - fi]) -fi -AC_MSG_RESULT($krb_h) - -includeopt= -AC_SUBST(includeopt) -if test -n "$krb_h"; then - krb_lib= - if test "$cross_compiling" != yes && test -r $KRB4/lib/libkrb.a; then - hold_ldflags=$LDFLAGS - LDFLAGS="-L${KRB4}/lib $LDFLAGS" - AC_CHECK_LIB(krb,printf,[krb_lib=yes krb_libdir=${KRB4}/lib], - [LDFLAGS=$hold_ldflags - # Using open here instead of printf so we don't - # get confused by the cached value for printf from above. - AC_CHECK_LIB(krb,open,[krb_lib=yes krb_libdir=])]) - LDFLAGS=$hold_ldflags - else - AC_CHECK_LIB(krb,printf,[krb_lib=yes krb_libdir=]) - AC_CHECK_FUNC(krb_recvauth,[krb_lib=yes krb_libdir=]) - fi - if test -n "$krb_lib"; then - AC_DEFINE([HAVE_KERBEROS], 1, - [Define if you have MIT Kerberos version 4 available.]) - test -n "${krb_libdir}" && LIBS="${LIBS} -L${krb_libdir}" - # Put -L${krb_libdir} in LDFLAGS temporarily so that it appears before - # -ldes in the command line. Don't do it permanently so that we honor - # the user's setting for LDFLAGS - hold_ldflags=$LDFLAGS - test -n "${krb_libdir}" && LDFLAGS="$LDFLAGS -L${krb_libdir}" - AC_CHECK_LIB(des,printf,[LIBS="${LIBS} -ldes"]) - AC_CHECK_LIB(krb,krb_recvauth) - AC_CHECK_LIB(krb4,krb_recvauth) - LDFLAGS=$hold_ldflags - if test -n "$krb_incdir"; then - includeopt="${includeopt} -I$krb_incdir" - fi - fi -fi -AC_CHECK_FUNCS(krb_get_err_text) - - -dnl -dnl WITH_GSSAPI is external -dnl -dnl TODO - I tried to put these in alphabetical order, but ACX_WITH_GSSAPI -dnl fails unless called after the KRB4 stuff. I don't know why. -dnl -ACX_WITH_GSSAPI - - -dnl -dnl begin --with-editor -dnl -dnl Set the default editor to use for log messages -dnl - -AC_ARG_VAR( - [EDITOR], - [The text editor CVS will use by default for log messages.]) - -# Let the confiscator request a specific editor -AC_ARG_WITH( - [editor], - AC_HELP_STRING( - [--with-editor], - [The default text editor CVS should use for log messages - (default autoselects)]), , - [with_editor=yes]) - -# If --with-editor was supplied with an argument, let it override $EDITOR from -# the user's environment. We need to unset EDITOR here because AC_CHECK_PROGS -# will let the value of EDITOR ride when it is set rather than searching. We -# ignore the --without-editor case since it will be caught below. -if test -n "$EDITOR" && test yes != $with_editor; then - AS_UNSET([EDITOR]) -fi - -# Set the default when --with-editor wasn't supplied or when it was supplied -# without an argument. -if test yes = $with_editor; then - with_editor="vim vi emacs nano pico edit" -fi - -if echo $with_editor |grep ^/ >/dev/null; then - # If $with_editor is an absolute path, issue a warning if the executable - # doesn't exist or isn't usable, but then trust the user and use it - # regardless - EDITOR=$with_editor - AC_MSG_CHECKING([for an editor]) - AC_MSG_RESULT([$EDITOR]) - if ! test -f $with_editor \ - || ! test -x $with_editor; then - # warn the user that they may encounter problems - AC_MSG_WARN([\`$with_editor' is not a path to an executable file]) - fi -elif test no != "${with_editor}"; then - # Search for an editor - AC_CHECK_PROGS([EDITOR], [$with_editor], [no]) - if test no = "${EDITOR}"; then - AC_MSG_ERROR([ - Failed to find a text file editor. CVS cannot be compiled - without a default log message editor. Searched for - \`$with_editor'. Try \`configure --with-editor'.]) - fi -else - AC_MSG_ERROR([ - CVS cannot be compiled without a default log message editor. - Try \`configure --with-editor'.]) -fi - -dnl FIXME - Using --without-editor will probably break a compile at -dnl the moment, but maybe it is reasonable for someone to want to -dnl compile a CVS executable that refuses to run if no $EDITOR, -dnl $CVS_EDITOR, or -e option is specified? Making a preliminary -dnl design decision in this direction, subject to discussion. -dnl -dnl Still don't know if the above would be useful, but we shouldn't -dnl be able to get here any longer without $EDITOR defined due to the -dnl error checking above. -AC_DEFINE_UNQUOTED( - [EDITOR_DFLT], ["$EDITOR"], - [The default editor to use, if one does not specify the "-e" option - to cvs, or does not have an EDITOR environment variable. If this - is not set to an absolute path to an executable, use the shell to - find where the editor actually is. This allows sites with - /usr/bin/vi or /usr/ucb/vi to work equally well (assuming that their - PATH is reasonable).]) - -dnl -dnl done finding an editor -dnl -dnl end --with-editor -dnl - -dnl -dnl begin --with-ssh -dnl - -# What remote shell transport should the :extssh: client cvs default to using? -AC_ARG_WITH( - [ssh], - AC_HELP_STRING( - [--with-ssh], - [The default remote shell CVS will use for :extssh: transport - (default autodetects)]), , - [with_ssh="ssh lshc ssh2"]) - -if test no = "$with_ssh"; then - AC_MSG_WARN([Failed to find usable remote shell. Using 'ssh'.]) - with_ssh=ssh -elif test yes = "$with_ssh"; then - # Make --with-ssh mean the same thing as --with-ssh=ssh - with_ssh=ssh -fi - -if echo $with_ssh |grep ^/ >/dev/null; then - # If $with_ssh is an absolute path, issue a warning if the executable - # doesn't exist or isn't usable, but then trust the user and use it - # regardless - with_default_ssh=$with_ssh - AC_MSG_CHECKING([for a remote shell]) - if ! test -f $with_ssh \ - || ! test -x $with_ssh; then - # warn the user that they may encounter problems - AC_MSG_WARN([$with_ssh is not a path to an executable file]) - fi -else - # Search for a remote shell - AC_CHECK_PROGS([with_default_ssh], [$with_ssh], "ssh") -fi - -AC_DEFINE_UNQUOTED( - [SSH_DFLT], ["$with_default_ssh"], - [The default remote shell to use, if one does not specify the - CVS_SSH environment variable.]) -dnl done with finding a default CVS_SSH value -dnl -dnl end --with-ssh -dnl - - -dnl -dnl begin --with-rsh -dnl -dnl Many sites no longer desire the use of "rsh" as the default -dnl remote shell program. They typically favor "ssh" as the default - -# What remote shell transport should our client cvs default to using? -AC_ARG_WITH( - [rsh], - AC_HELP_STRING( - [--with-rsh], - [The default remote shell CVS will use for :ext: transport - (default autodetects)]), , - dnl `remsh' is only useful on HP-UX, where `rsh' is the `restricted shell' - dnl and `remsh' is the remote shell, but look for it first since it - dnl probably won't exist on any platform where it shouldn't be preferred - dnl to `rsh'. - [with_rsh="remsh rsh ssh lshc ssh2"]) - -if test no = "$with_rsh"; then - AC_MSG_WARN([Failed to find usable remote shell. Using 'rsh'.]) - with_rsh=rsh -elif test yes = "$with_rsh"; then - # Make --with-rsh mean the same thing as --with-rsh=rsh - with_rsh=rsh -fi - -if echo $with_rsh |grep ^/ >/dev/null; then - # If $with_rsh is an absolute path, issue a warning if the executable - # doesn't exist or isn't usable, but then trust the user and use it - # regardless - with_default_rsh=$with_rsh - AC_MSG_CHECKING([for a remote shell]) - if ! test -f $with_rsh \ - || ! test -x $with_rsh; then - # warn the user that they may encounter problems - AC_MSG_WARN([$with_rsh is not a path to an executable file]) - fi -else - # Search for a remote shell - AC_CHECK_PROGS([with_default_rsh], [$with_rsh], "rsh") -fi - -AC_DEFINE_UNQUOTED( - [RSH_DFLT], ["$with_default_rsh"], - [The default remote shell to use, if one does not specify the - CVS_RSH environment variable.]) -dnl done with finding a default CVS_RSH value -dnl -dnl end --with-rsh -dnl - - -dnl -dnl Find a temporary directory -dnl -AC_ARG_WITH( - [tmpdir], - AC_HELP_STRING( - [--with-tmpdir], - [The temporary directory CVS should use as a default - (default autoselects)])) - -AC_MSG_CHECKING([for temporary directory]) -if test -z "$with_tmpdir" || test yes = "$with_tmpdir"; then - for with_tmpdir in /tmp /var/tmp no; do - if test -d "$with_tmpdir" && test -x "$with_tmpdir" \ - && test -w "$with_tmpdir" && test -r "$with_tmpdir"; then - break - fi - done - if test no = "$with_tmpdir"; then - AC_MSG_WARN([Failed to find usable temporary directory. Using '/tmp'.]) - with_tmpdir=/tmp - fi - AC_MSG_RESULT([$with_tmpdir]) -elif ! echo "$with_tmpdir" |grep '^[[\\/]]'; then - AC_MSG_RESULT([$with_tmpdir]) - AC_MSG_ERROR([--with-tmpdir requires an absolute path.]) -elif ! test -d "$with_tmpdir" || ! test -x "$with_tmpdir" \ - || ! test -w "$with_tmpdir" || ! test -r "$with_tmpdir"; then - AC_MSG_RESULT([$with_tmpdir]) - AC_MSG_WARN( - [User supplied temporary directory ('$with_tmpdir') does not - exist or lacks sufficient permissions for read/write.]) -fi - -AC_DEFINE_UNQUOTED( - [TMPDIR_DFLT], ["$with_tmpdir"], - [Directory used for storing temporary files, if not overridden by - environment variables or the -T global option. There should be little - need to change this (-T is a better mechanism if you need to use a - different directory for temporary files).]) - -dnl -dnl done finding tmpdir -dnl - - -dnl -dnl Get default umask -dnl - -AC_ARG_WITH( - [umask], - AC_HELP_STRING( - [--with-umask], - [Set the umask CVS will use by default in the repository (default 002)])) - -if test -z "$with_umask" || test yes = "$with_umask"; then - with_umask=002 -elif test no = "$with_umask"; then - with_umask=000 -fi - -AC_DEFINE_UNQUOTED( - [UMASK_DFLT], [$with_umask], - [The default umask to use when creating or otherwise setting file or - directory permissions in the repository. Must be a value in the - range of 0 through 0777. For example, a value of 002 allows group - rwx access and world rx access; a value of 007 allows group rwx - access but no world access. This value is overridden by the value - of the CVSUMASK environment variable, which is interpreted as an - octal number.]) - -dnl -dnl Done setting default umask -dnl - -dnl -dnl Set CVS Administrator Group -dnl -AC_ARG_WITH( - [cvs-admin-group], - AC_HELP_STRING( - [--with-cvs-admin-group=GROUP], - [The CVS admin command is restricted to the members of this group. - If this group does not exist, all users are allowed to run CVS admin. - To disable the CVS admin command for all users, create an empty group - by specifying the --with-cvs-admin-group= option. To disable access - control for CVS admin, run configure with the --without-cvs-admin-group - option. (default 'cvsadmin')]), , - [with_cvs_admin_group=cvsadmin]) - -if test yes = "$with_cvs_admin_group"; then - with_cvs_admin_group=cvsadmin -fi -if test no != "$with_cvs_admin_group"; then - dnl FIXME We should warn if the group doesn't exist - AC_DEFINE_UNQUOTED( - [CVS_ADMIN_GROUP], ["$with_cvs_admin_group"], - [The CVS admin command is restricted to the members of the group - CVS_ADMIN_GROUP. If this group does not exist, all users are - allowed to run CVS admin. To disable the CVS admin command for - all users, create an empty CVS_ADMIN_GROUP by running configure - with the --with-cvs-admin-group= option. To disable access control - for CVS admin, run configure with the --without-cvs-admin-group - option in order to comment out the define below.]) -fi - -dnl -dnl Done setting CVS Administrator Group -dnl - -dnl -dnl end --with-* -dnl - - -dnl -dnl Set the NDBM library to use. -dnl -dnl XXX - FIXME - FIXME - FIXME - XXX -dnl -dnl This is very bad. It should really autodetect an appropriate NDBM library -dnl and, if it doesn't find one, decide to use MY_NDBM. I'm am defining -dnl this here since this is no worse than it worked when it was in options.h -dnl and I am cleaning out options.h so that the Windows version of CVS will -dnl compile properly for the next release. -dnl -dnl That's why this option is in the --with-* section rather than the -dnl --enable-* section. -dnl -dnl XXX - FIXME - FIXME - FIXME - XXX -dnl -AC_ARG_ENABLE( - [cvs-ndbm], - AC_HELP_STRING( - [--enable-cvs-ndbm], - [Use the NDBM library distributed with CVS rather than attempting to use - a system NDBM library. Disabling this may not work. (default)]), , - [enable_cvs_ndbm=yes]) -if test no != "$enable_cvs_ndbm"; then - AC_DEFINE( - [MY_NDBM], [1], - [By default, CVS stores its modules and other such items in flat - text files (MY_NDBM enables this). Turning off MY_NDBM causes CVS - to look for a system-supplied ndbm database library and use it - instead. That may speed things up, but the default setting - generally works fine too.]) -fi - -dnl -dnl Done selecting NDBM library. -dnl - - -dnl -dnl begin --enables -dnl - - -dnl Allow mmap for the buffer routine replacements to be disabled in -dnl case of problems. - -AC_ARG_ENABLE( - [mmap], - AC_HELP_STRING( - [--disable-mmap], - [Don't mmap RCS files])) - -if test no != "$enable_mmap"; then - AC_FUNC_MMAP -fi - -# Check for options requesting client and server feature. If none are -# given and we have connect(), we want the full client & server arrangement. -AC_ARG_ENABLE( - [client], - AC_HELP_STRING( - [--enable-client], - [Include code for running as a remote client (default)]), , - [if test "$ac_cv_search_connect" != no; then - enable_client=yes - fi]) -if test no != "$enable_client"; then - AC_DEFINE( - [CLIENT_SUPPORT], [1], - [Define if you want CVS to be able to be a remote repository client.]) -fi - -AC_ARG_ENABLE( - [password-authenticated-client], - AC_HELP_STRING( - [--enable-password-authenticated-client], - [Enable pserver as a remote access method in the CVS client - (default)])) - -if test no != "$enable_password_authenticated_client"; then - if test no != "$enable_client"; then - AC_DEFINE( - [AUTH_CLIENT_SUPPORT], [1], - [Enable AUTH_CLIENT_SUPPORT to enable pserver as a remote access - method in the CVS client (default)]) - else - AC_MSG_WARN( - [--enable-password-authenticated-client is meaningless with - the CVS client disabled (--disable-client)]) - fi -fi - - -dnl -dnl Give the confiscator control over whether the server code is compiled -dnl -AC_ARG_ENABLE( - [server], - AC_HELP_STRING( - [--enable-server], - [Include code for running as a server (default)]), , - [if test "$ac_cv_search_connect" != no; then - enable_server=yes - fi]) - -if test no != "$enable_server"; then - AC_DEFINE( - [SERVER_SUPPORT], [1], - [Define if you want CVS to be able to serve repositories to remote - clients.]) - - dnl - 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. - dnl - AC_SEARCH_LIBS( - [crypt], [crypt], - [AC_DEFINE( - [HAVE_CRYPT], [1], - [Define if you have the crypt function.]) - AC_DEFINE( - [AUTH_SERVER_SUPPORT], [1], - [Define if you want to use the password authenticated server.])dnl - ])dnl AC_SEARCH_LIBS - - dnl - dnl Allow the configurer to enable server flowcontrol. Read the help - dnl strings below for a full explanation. - dnl - AC_ARG_ENABLE( - [server-flow-control], - AC_HELP_STRING( - [--enable-server-flow-control], - [If you are working with a large remote repository and a 'cvs - checkout' is swamping your network and memory, define these to - enable flow control. You may optionally pass a low water mark - in bytes and a high water mark in bytes, separated by commas. - (default is enabled 1M,2M)]), - [if test yes = $enable_server_flow_control; then - enable_server_flow_control=1M,2M - fi], - [enable_server_flow_control=1M,2M]) - if test no != $enable_server_flow_control; then - ccvs_lwm=`expr "$enable_server_flow_control" : '\(.*\),'` - ccvs_hwm=`expr "$enable_server_flow_control" : '.*,\(.*\)'` - ccvs_lwm_E=`expr "$ccvs_lwm" : '[[0-9]][[0-9]]*\(.*\)'` - ccvs_lwm=`expr "$ccvs_lwm" : '\([[0-9]][[0-9]]*\)'` - test "" != "$ccvs_lwm" || ccvs_lwm_E="?" - case $ccvs_lwm_E in - G) ccvs_lwm="$ccvs_lwm * 1024 * 1024 * 1024";; - M) ccvs_lwm="$ccvs_lwm * 1024 * 1024";; - k) ccvs_lwm="$ccvs_lwm * 1024";; - b | '') ;; - *) AC_MSG_ERROR([Can't parse argument to --enable-server-flow-control - ('$enable_server_flow_control') as ,]) - esac - ccvs_hwm_E=`expr "$ccvs_hwm" : '[[0-9]][[0-9]]*\(.*\)'` - ccvs_hwm=`expr "$ccvs_hwm" : '\([[0-9]][[0-9]]*\).*'` - test "" != "$ccvs_hwm" || ccvs_hwm_E="?" - case $ccvs_hwm_E in - G) ccvs_hwm="$ccvs_hwm * 1024 * 1024 * 1024";; - M) ccvs_hwm="$ccvs_hwm * 1024 * 1024";; - k) ccvs_hwm="$ccvs_hwm * 1024";; - b | '') ccvs_hwm="$ccvs_hwm";; - *) AC_MSG_ERROR([Can't parse argument to --enable-server-flow-control - ('$enable_server_flow_control') as ,]) - esac - - AC_DEFINE( - [SERVER_FLOWCONTROL], [1], - [If you are working with a large remote repository and a 'cvs - checkout' is swamping your network and memory, define these to - enable flow control. You will end up with even less probability of - a consistent checkout (see Concurrency in cvs.texinfo), but CVS - doesn't try to guarantee that anyway. The master server process - will monitor how far it is getting behind, if it reaches the high - water mark, it will signal the child process to stop generating - data when convenient (ie: no locks are held, currently at the - beginning of a new directory). Once the buffer has drained - sufficiently to reach the low water mark, it will be signalled to - start again.]) - AC_DEFINE_UNQUOTED( - [SERVER_LO_WATER], [($ccvs_lwm)], - [The low water mark in bytes for server flow control. Required if - SERVER_FLOWCONTROL is defined, and useless otherwise.]) - AC_DEFINE_UNQUOTED( - [SERVER_HI_WATER], [($ccvs_hwm)], - [The high water mark in bytes for server flow control. Required if - SERVER_FLOWCONTROL is defined, and useless otherwise.]) - fi # enable_server_flow_control -fi # enable_server - - -dnl -dnl begin --enable-case-sensitivity -dnl - -AC_ARG_ENABLE( - [case-sensitivity], - AC_HELP_STRING( - [--enable-case-sensitivity], - [Force CVS to expect a case sensitive file system. Enabling this on a case - insensitive system should have little effect on the server or client - operation, though client users may ocassionally be suprised that the CVS - server appears to be case sensitive. Disabling this for a case sensitive - server disables server support for case insensitive clients, which can - confuse all users of case insensitive clients contacting the server. - Disabling this for a case sensitive client will cause the client to ask - servers to behave case insensitively, which could cause confusion for - users, but also probably no real harm. (default autoselects based on the - case sensitivity of the file system containing the current working - directory)]), - [case "$enable_case_sensitivity" in - yes | no | auto) ;; - *) - AC_MSG_ERROR([Unrecognized argument to --enable-case-sensitivity: \`$enable_case_sensitivity'. Acceptable values are \`yes', \`no', and \`auto'.]) - ;; - esac], - [enable_case_sensitivity=auto]) - -acx_forced=' (forced)' -AC_MSG_CHECKING([for a case sensitive file system]) -if test $enable_case_sensitivity = auto; then - dnl - dnl Check for a case insensitive filesystem, like Mac OS X and Windows have. - dnl - AC_CACHE_VAL([acx_cv_case_sensitive], - [ rm -f ac_TEST_filenames_CASE_sensitive - echo foo >ac_test_filenames_case_sensitive - if test -f ac_TEST_filenames_CASE_sensitive; then - acx_cv_case_sensitive=no - else - acx_cv_case_sensitive=yes - fi - rm ac_test_filenames_case_sensitive - ]) - enable_case_sensitivity=$acx_cv_case_sensitive - acx_forced= -fi -AC_MSG_RESULT([$enable_case_sensitivity$acx_forced]) -if test $enable_case_sensitivity = no; then - AC_DEFINE([FILENAMES_CASE_INSENSITIVE], [1], - [Define if this executable will be running on case insensitive - file systems. In the client case, this means that it will request - that the server pretend to be case insensitive if it isn't - already.]) - dnl Compile fncase.c (containing fncase() & fncmp()) to handle file name - dnl comparisons on case insensitive filesystems. - AC_LIBOBJ(fncase) -fi - -dnl -dnl end --enable-case-sensitivity -dnl - - -dnl -dnl begin --enable-encryption -dnl - -dnl -dnl Use --enable-encryption to turn on encryption support, but ignore this -dnl option unless either client or server is enabled. -dnl -AC_ARG_ENABLE( - [encryption], - AC_HELP_STRING( - [--enable-encryption], - [Enable encryption support (disabled by default)]), , - [enable_encryption=no]) -if test "$enable_encryption" = yes; then - if test no != "$with_client" || test no != "$with_server"; then - AC_DEFINE( - [ENCRYPTION], [1], - [Define to enable encryption support.]) - else - AC_MSG_WARN( - [--enable-encryption is meaningless when neither the CVS client - nor the CVS server is enabled (--disable-client and --disable-server).]) - fi -fi - -dnl -dnl end --enable-encryption -dnl - - -dnl -dnl begin --enable-force-editor -dnl - -AC_ARG_ENABLE( - [force-editor], - AC_HELP_STRING( - [--enable-force-editor], - [When committing or importing files, you must enter a log message. - Normally, you can do this either via the -m flag on the command - line, the -F flag on the command line, or an editor will be started - for you. If you like to use logging templates (the rcsinfo file - within the $CVSROOT/CVSROOT directory), you might want to force - people to use the editor even if they specify a message with -m or - -F. --enable-force-editor will cause the -m or -F message to be - appended to the temp file when the editor is started. (disabled - by default)]), , - [enable_force_editor=no]) - -if test yes = "$enable_force_editor"; then - AC_DEFINE( - [FORCE_USE_EDITOR], [1], - [When committing or importing files, you must enter a log message. - Normally, you can do this either via the -m flag on the command - line, the -F flag on the command line, or an editor will be started - for you. If you like to use logging templates (the rcsinfo file - within the $CVSROOT/CVSROOT directory), you might want to force - people to use the editor even if they specify a message with -m or - -F. Enabling FORCE_USE_EDITOR will cause the -m or -F message to be - appended to the temp file when the editor is started.]) -fi - -dnl -dnl end --enable-force-editor -dnl - - -dnl -dnl begin --enable-rootcommit -dnl - -dnl -dnl I don't like this here, but I don't really like options.h, either. -dnl Besides, this is causing some problems currently when compiling under -dnl Windows and moving it here should avoid the issue (the wrong options.h -dnl is being used). -dnl -dnl I don't like making this a runtime option either. I think I just don't -dnl like making it easy to get to, but putting it here goes along with the -dnl Autoconf ideal. -dnl -AC_ARG_ENABLE( - [rootcommit], - AC_HELP_STRING( - [--enable-rootcommit], - [Allow the root user to commit files (disabled by default)]), , - [enable_rootcommit=no]) -if test "$enable_rootcommit" = no; then - AC_DEFINE( - [CVS_BADROOT], [1], - [When committing a permanent change, CVS and RCS make a log entry of - who committed the change. If you are committing the change logged - in as "root" (not under "su" or other root-priv giving program), - CVS/RCS cannot determine who is actually making the change. - - As such, by default, CVS prohibits changes committed by users - logged in as "root". You can disable checking by passing the - "--enable-rootcommit" option to configure or by commenting out the - lines below.]) -fi - -dnl -dnl end --enable-rootcommit -dnl - - - -dnl -dnl end --enable-* -dnl - - - -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. -dnl AC_DEFINE(PRESERVE_PERMISSIONS_SUPPORT, 1, -dnl [Define if this system supports chown(), link(), and friends.]) - -dnl On cygwin32, we configure like a Unix system, but we need some support -dnl libraries. We do this at the end so that the new libraries are added at -dnl the end of LIBS. -dnl -dnl FIXME: We should be trying to meet the autoconf ideal of checking for -dnl the properties of the system rather than the name of the os here. In other -dnl words, we should check the case sensitivty of the system and then for -dnl the support functions we are using and which library we find them in. -AC_CACHE_CHECK(for cygwin32, ccvs_cv_sys_cygwin32, -[AC_TRY_COMPILE([], [return __CYGWIN32__;], -ccvs_cv_sys_cygwin32=yes, ccvs_cv_sys_cygwin32=no)]) -if test $ccvs_cv_sys_cygwin32 = yes; then - LIBS="$LIBS -ladvapi32" - - dnl On Windows you can only change file times if you can write to - dnl the file. cygwin32 should really handle this for us, but as of - dnl January 1998 it doesn't. - AC_DEFINE(UTIME_EXPECTS_WRITABLE, 1, -[Define if utime requires write access to the file (true on Windows, -but not Unix).]) - - dnl On Windows we must use setmode to change between binary and text - dnl mode. This probably doesn't really require two macro definitions - AC_DEFINE(USE_SETMODE_STDOUT, 1, -[Define if setmode is required when writing binary data to stdout.]) - AC_DEFINE(HAVE_SETMODE, 1, -[Define if the diff library should use setmode for binary files.]) -fi - -dnl associate the setting of the execute bit with the individual scripts -AC_CONFIG_FILES(contrib/check_cvs, [chmod +x contrib/check_cvs]) -AC_CONFIG_FILES(contrib/clmerge, [chmod +x contrib/clmerge]) -AC_CONFIG_FILES(contrib/cln_hist, [chmod +x contrib/cln_hist]) -AC_CONFIG_FILES(contrib/commit_prep, [chmod +x contrib/commit_prep]) -AC_CONFIG_FILES(contrib/cvs_acls, [chmod +x contrib/cvs_acls]) -AC_CONFIG_FILES(contrib/log, [chmod +x contrib/log]) -AC_CONFIG_FILES(contrib/log_accum, [chmod +x contrib/log_accum]) -AC_CONFIG_FILES(contrib/mfpipe, [chmod +x contrib/mfpipe]) -AC_CONFIG_FILES(contrib/pvcs2rcs, [chmod +x contrib/pvcs2rcs]) -AC_CONFIG_FILES(contrib/rcs2log:contrib/rcs2log.sh, [chmod +x contrib/rcs2log]) -AC_CONFIG_FILES(contrib/rcslock, [chmod +x contrib/rcslock]) -AC_CONFIG_FILES(contrib/sccs2rcs, [chmod +x contrib/sccs2rcs]) -AC_CONFIG_FILES(doc/mkman:doc/mkman.pl, [chmod +x doc/mkman]) -AC_CONFIG_FILES(src/cvsbug, [chmod +x src/cvsbug]) -AC_CONFIG_FILES(windows-NT/fix-msvc-mak:windows-NT/fix-msvc-mak-head.pl:windows-NT/fix-msvc-mak.pl, - [chmod +x windows-NT/fix-msvc-mak]) - -dnl the bulk files -AC_CONFIG_FILES([Makefile \ - contrib/Makefile \ - cvs.spec \ - diff/Makefile \ - doc/Makefile \ - emx/Makefile \ - lib/Makefile \ - man/Makefile \ - os2/Makefile \ - src/Makefile \ - tools/Makefile \ - vms/Makefile \ - windows-NT/Makefile \ - windows-NT/SCC/Makefile \ - zlib/Makefile]) - -dnl and we're done -AC_OUTPUT - - - -# Report the state of this version of CVS if this is from dev. -m4_bmatch(m4_defn([AC_PACKAGE_VERSION]), [[0-9]*\.[0-9]*\.[0-9]*\.[0-9]], -[ cat <. - -Below you will find information on the status of this version of CVS. - - -EOF - sed -n '/^\* Status/,$p' $srcdir/BUGS -]) diff --git a/contrib/cvs/contrib/ChangeLog b/contrib/cvs/contrib/ChangeLog deleted file mode 100644 index 5238832..0000000 --- a/contrib/cvs/contrib/ChangeLog +++ /dev/null @@ -1,765 +0,0 @@ -2005-09-01 Derek Price - - * cvs_acls.html, cvs_acls.in, log_accum.in: Update links. - -2005-09-01 Derek Price - - * commit_prep.in, cvs_acls.in, log.in, log_accum.in, mfpipe.in, - pvcs2rcs.in, rcslock.in: Update links and email addresses. - -2005-07-12 Derek Price - - * clmerge.in, cln_hist.in, commit_prep.in, cvs2vendor.sh, cvs_acls.in, - cvscheck.sh, debug_check_log.sh, descend.sh, log.in, log_accum.in, - mfpipe.in, rcs-to-cvs.sh, rcs2log.sh, rcs2sccs.sh, rcslock.in, - sccs2rcs.in: Add copyright notices. - -2005-07-11 Derek Price - - * clmerge.in, cln_hist.in, commit_prep.in, cvs2vendor.sh, cvs_acls.in, - cvscheck.sh, debug_check_log.sh, descend.sh, log.in, log_accum.in, - mfpipe.in, rcs-to-cvs.sh, rcs2log.sh, rcs2sccs.sh, rcslock.in, - sccs2rcs.in: Update license notices. - -2005-04-14 Derek Price - - * commit_prep.in, cvs_acls.in, log.in, log_accum.in, mfpipe.in, - rcslock.in: Enable taint checking and comment. This closes cvshome.org - Issue #224. - -2005-04-08 Derek Price - - * README: Correct my email address. - -2005-01-31 Derek Price - - * Makefile.am: Update copyright notices. - -2005-01-25 Mark D. Baushke - - * cvs_acls.in: New version from - "Peter Connolly" . - * cvs_acls.html: New file from - "Peter Connolly" . - * Makefile.am (EXTRA_DIST): Add cvs_acls.html - * Makefile.in: Regenerated. - -2004-08-30 Derek Price - - * log_accum.in: Changes to supress warnings under Perl 5.8.5. - (Patch from Jeroen Ruigrok/asmodai .) - -2004-01-30 Derek Price - - Close issue #155. - * log_accum.in: Remove unused variables. - (Patch from Ville Skyttä .) - -2003-10-14 Derek Price - - Port to pedantic POSIX 1003.1-2001 hosts, such as Debian GNU/Linux - testing with _POSIX2_VERSION=200112 in the environment. - - * cvs2vendor.sh: Work with POSIX sort as well as with - traditional sort. - * rcs2sccs.sh, sccs2rcs.in: Likewise. - (Patch from Paul Eggert .) - -2003-09-26 Mark D. Baushke - - * sccs2rcs.in: Use @AWK@ to avoid ancient Solaris awk (no support - for the "?" operator). Add support for handling binary SCCS files. - (Suggestion from Allan Schrum .) - -2003-08-06 Derek Price - - * commit_prep.in, log_accum.in: Port copious changes from Karl Fogel - and CollabNet. These changes add features, generalize, and organize. - -2003-07-07 Larry Jones - - * rcs2log.1: New file from Paul Eggert - via Eric Seidel . - -2003-06-20 Derek Price - - * Don't call CVS with the -l option since CVS no longer accepts it. - (Suggestion from Matt Doar .) - -2003-05-21 Derek Price - - * Makefile.in: Regenerate with Automake version 1.7.5. - -2003-04-10 Larry Jones - - * Makefile.in: Regenerated. - -2003-03-24 Derek Price - - * Makefile.am: Update copyright notice. - - * Makefile.in: Regenerated. - -2003-02-25 Derek Price - - * rcs2log.sh: Import RedHat 8.0's use of mktemp from the CVS 1.11.2 - RPM. Use new MKTEMP variable from configure. - * Makefile.in: Regenerated. - -2003-02-24 Larry Jones - and Donald Sharp - - * check_cvs.in: Filenames with funky characters need to be quoted - correctly. Also needed to modify regex due to locked revisions of - files cause output to be different. - - * check_cvs.in: Fixed multiple symlinks in your cvsroot, - improved CVSROOT/CVSROOT handling (Patch from Shlomo Reinstein - - - * cvs_acls.in: Fix split loop error with Perl 5.8.0. - (Patch from Ville Skyttä .) - -2002-12-11 Larry Jones - - * Makefile.am (install-data-local): test -e isn't portable: use -f. - * Makefile.in: Regenerated. - (Reported by Philip Brown .) - -2002-11-21 Larry Jones - - * .cvsignore: Add check_cvs. - - * check_cvs.in: New script contributed by Donald Sharp. - * Makefile.am (contrib_SCRIPTS): Add check_cvs. - * Makefile.in: Regenerated. - * README: Add check_cvs and other missing scripts, alphabetize. - -2002-11-08 Derek Price - - * debug_check_log.sh: Simplify some code. Attempt to default to - src/check.log before falling back to ./check.log. - -2002-09-24 Derek Price - - * Makefile.in: Regenerated using Automake 1.6.3. - -2002-09-24 Derek Price - - * Makefile.in: Regenerated. - -2002-05-20 Derek Price - - * cvs_acls.in: Add note about using checkoutlist with avail - in the commentary's INSTALLATION section. - (Original patch from Ville Skyttä .) - -2002-04-30 Derek Price - - * Makefile.in: Regenerated with automake 1.6. - -2002-03-21 Derek Price - - * Makefile.am (install-data-local): Import a patch from RedHat which - was no longer necessary but causes a FIXME to print - maybe someone - will see it and fix it. - * Makefile.in: Regenerated. - -2001-12-06 Derek Price - - * cvs_acls.in: Allow ACL specification based on branch matching. - (Patch from Aaron Voisine .) - -2001-10-16 Derek Price - - * sccs2rcs.in: Replace Y2K bug fix with something more succint. - (Suggested by SAKAI Hiroaki .) - -2001-10-16 Derek Price - - * rcs2sccs.in: Fix Y2K bug. - (Patch from SAKAI Hiroaki .) - -2001-09-06 Larry Jones - for Paul Eggert - - Sync with revision 1.48 of the GNU Emacs sources. This - incorporates the following changes: - - * rcs2log (Help, mainline code): Add new option -L FILE. - (Copyright): Update year. - - (LANG, LANGUAGE, LC_ALL, LC_COLLATE, LC_CTYPE, LC_MESSAGES, - LC_NUMERIC, LC_TIME): New shell vars, to make sure we live in the C locale. - - (mainline code): Handle nonstandard -u option differently, by - transforming it to standard form. Check for "Working file: ", not - "Working file:". Allow file names with spaces. - - (SOH, rlogfile): New shell vars. - (rlogout): Remove. Its old functionality is mostly migrated to rlogfile. - - Append ';;' to the last arm of every case statement, for portability to - ancient broken BSD shells. - - (logins): Fix bug; was not being computed at all, lowering performance. - - (pository): New var. This fixes some bugs where repositories are - remote, or have trailing slashes. - - (authors): $llogout is never an empty shell var, so don't worry about that - possibility. - - (printlogline, mainline code): Fix bug with SOH's being put into the output. - - - 2001-07-20 Gerd Moellmann - - * rcs2log: Update copyright notice. - - - 2001-01-03 Paul Eggert - - * rcs2log: Avoid security hole allowing attacker to - cause user of rcs2log to overwrite arbitrary files, fixing - a bug reported by Morten Welinder. - - Don't put "exit 1" at the end of the exit trap; it's - ineffective in POSIX shells. - -2001-09-04 Derek Price - - * Makefile.in: Regenerated with automake 1.5. - -2001-08-21 Larry Jones - - * sccs2rcs.in: Fix typo: missing quote. - (Patch submitted by "Mark D. Baushke" .) - -2001-08-06 Derek Price - - * Makefile.in: Regenerated. - -2001-07-04 Derek Price - - * Makefile.in: Regenerated with new Automake release candidate 1.4h. - -2001-06-28 Derek Price - - * Makefile.in: Regenerated with new version of Automake. - -2001-05-30 Derek Price - - * pvcs2cvs.in: Rename to... - * pvcs2rcs.in: here. - * .cvsignore: Add pvcs2rcs. - * Makefile.am (contrib_SCRIPTS): Change pvcs2cvs to pvcs2rcs. - - * Makefile.in: Regenerated. - -2001-05-29 Derek Price - patch from Pavel Roskin - - * Makefile.am (install-data-local): Double hash comment in rule since - single hash comments are not portable. - - * Makefile.in: Regenerated. - -2001-05-29 Derek Price - - * pvcs2cvs.in: New file. - * Makefile.am (contrib_SCRIPTS): Add pcvs2cvs. - - * Makefile.in: Regenerated. - -2001-05-23 Larry Jones - - * sccs2rcs.in: No need for grep when you're already using awk. - - * sccs2rcs.in: Fix y2k bug correctly. - (Reported by "Hayes, Ted (London)" .) - -2001-04-25 Derek Price - - * Makefile.in: Regenerated using AM 1.4e as of today at 18:10 -0400. - -2001-04-16 Derek Price - - * log.pl: Accept new '-V' option for non-verbose status messages. - -2001-03-14 Derek Price - - * Makefile.in: Regenerated - -2001-01-05 Derek Price - - * contrib/Makefile.am (EXTRA_DIST, SUFFIXES, .pl:, .csh:): Move some - script targets to configure.in - see ../ChangeLog for more - - * contrib/clmerge.in: Rename from clmerge.pl - * contrib/cln_hist.in: Rename from cln_hist.pl - * contrib/commit_prep.in: Rename from commit_prep.pl - * contrib/cvs_acls.in: Rename from cvs_acls.pl - * contrib/log.in: Rename from log.pl - * contrib/log_accum.in: Rename from log_accum.pl - * contrib/mfpipe.in: Rename from mfpipe.pl - * contrib/rcslock.in: Rename from rcslock.pl - * contrib/sccs2rcs.in: Rename from scc2rcs.csh - - * contrib/clmerge.pl: Rename to clmerge.in - * contrib/cln_hist.pl: Rename to cln_hist.in - * contrib/commit_prep.pl: Rename to commit_prep.in - * contrib/cvs_acls.pl: Rename to cvs_acls.in - * contrib/log.pl: Rename to log.in - * contrib/log_accum.pl: Rename to log_accum.in - * contrib/mfpipe.pl: Rename to mfpipe.in - * contrib/rcslock.pl: Rename to rcslock.in - * contrib/sccs2rcs.csh: Rename to sccs2rcs.in - -2000-12-22 Derek Price - - * Makefile.in: Regenerated - -2000-12-21 Derek Price - - * Makefile.am: New file needed by Automake - * Makefile.in: Regenerated - -2000-12-14 Derek Price - Thomas Maeder - - * sccs2rcs.csh: unkludge a Y2k workaround - -2000-10-23 Derek Price - - * debug_check_log.sh: added this script for analyzing sanity.sh output - * Makefile.in: add above file to DISTFILES and CONTRIB_PROGS - * .cvsignore: add debug_check_log - -2000-09-07 Larry Jones - - * Makefile.in: Use @bindir@, @libdir@, @infodir@, and @mandir@ - from autoconf. - -2000-02-25 Larry Jones - - * 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 - - * sccs2rcs.csh: fixed a y2k bug. This was submitted - by Ceri Davies , and looks - okay to me. - -1999-01-19 Graham Stoney - - * log.pl: The author commited the canonical perl "localtime" Y2K - offence, of printing "19$year" instead of (1900 + $year). Of - course, the result is non-compliance in year 2000. Fix it. - -1998-10-14 Jim Kingdon - - * ccvs-rsh.pl: Removed; it was not in DISTFILES so it didn't - actually get distributed. I'm going to move it to the web on the - theory that the web is a better place for such things. - * README: Don't mention it. - - * Makefile.in (dist-dir, distclean): Remove references to elib. - * elib: Remove this subdirectory and all its contents. It went - with pcl-cvs, which is no longer distributed with CVS. - -1998-09-22 Jim Kingdon - - * pvcs_to_rcs: Removed; it was not in DISTFILES so it didn't - actually get distributed. I'm going to move it to the web on the - theory that the web is a better place for such things. - * README: Don't mention it. - -1998-09-10 Jim Kingdon - - Check in Paul Eggert 's submission of - 1998-08-15. I also ran "cvs admin -ko" on this file so that his - version number would be intact (not an ideal solution, because - people will import it into other repositories, but I don't feel - like hacking the master version). - * rcs2log.sh: Sync with master version at gnu.org. - -1998-08-15 Jim Kingdon - - * README: Don't mention listener, since it was removed a while - ago. - * listen2.c, listen2.mak: Removed; because there is no easy way to - pass a socket (as opposed to file descriptor) from one process to - another on Windows, this isn't a promising approach (at least not - in this form). - * Makefile.in (DISTFILES): Remove them. - * .cvsignore: Remove listen2.ncb listen2.mdp Debug. - -1998-05-11 W. Bradley Rubenstein - - * log.pl: Check for errors from open and exec. - -Sat Feb 21 21:59:45 1998 Ian Lance Taylor - - * Makefile.in (clean): Change "/bin/rm" to "rm". - -Thu Aug 7 22:42:23 1997 Jim Kingdon - - * pvcs_to_rcs: Remove RCS keywords. Remove $Log and move the data - to this ChangeLog (below). Add paragraph that David Martin - emailed along with the script. - - Revision 1.6 1997/03/07 16:21:28 divad - Need to explicitly state archive name in PVCS get command for - those cases where the case of the workfile and the case of the - archive file are different (OS/2) - - Revision 1.5 1997/03/07 00:31:04 divad - Added capitalized extensions and framemaker files as binaries; - also overriding any path specification for workfiles at PVCS - checkout (most annoying). - - Revision 1.4 1997/03/06 21:04:55 divad - Added \n to the end of each comment line to prevent multi-line - comments for a single revision from "merging" - - Revision 1.3 1997/03/06 19:50:25 divad - Corrected bug in binary extensions; correcting processing - comment strings with double quotes - - Revision 1.2 1997/03/06 17:29:10 divad - Provided list of extensions (rather than using Unix file - command) to determine which files are binary; also printing - version label as they are applied - - Revision 1.1 1997/02/26 00:04:29 divad - Perl script to convert pvcs archives to rcs archives - - * README: mention pvcs_to_rcs. - * pvcs_to_rcs: New file. This is the file as I got it from David - Martin. Will be checking in the tweaks shortly. - -17 May 1997 Jim Kingdon - - * listen2.c: Failed attempt at making this do what it was - intended to do. Will need to rethink the approach. - * listen2.mak: The usual involuntary tweaks. - * .cvsignore: Add listen2.ncb listen2.mdp. - -Mon May 12 11:59:23 1997 Jim Kingdon - - * listener.c: Removed; see ../ChangeLog for rationale. - -10 May 1997 Jim Kingdon - - * listen2.c, listen2.mak: New files. - * Makefile.in (DISTFILES): Add them. - * .cvsignore: Add Debug. - -Thu Feb 20 22:43:45 1997 David J MacKenzie - - * rcs-to-cvs.sh: Put temporary files in /var/tmp or /usr/tmp - whichever one exists. Just call "vi" not "/usr/ucb/vi". - -Mon Feb 17 08:51:37 1997 Greg A. Woods - - * .cvsignore: added 'cvs2vendor' target from Feb. 12 changes. - - * log_accum.pl (build_header): added "Repository:" to the report - header to show the first argument supplied to the script by CVS. - [[this value seems spuriously to be wrong when client is used]] - ($hostdomain): correct order of initialization from the Feb. 12 - changes. - ($modulename): add more commentary about using '-M' to to get a - meaningful string here. - Tweak a few other comments from the Feb. 12 changes. - -Wed Feb 12 10:27:48 1997 Jim Kingdon - - * cln_hist.pl, commit_prep.pl, cvs2vendor.sh, cvs_acls.pl, - cvscheck.man, cvscheck.sh, cvshelp.man, descend.man, descend.sh, - log_accum.pl, mfpipe.pl, rcs-to-cvs.sh, rcs2log.sh, rcs2sccs.sh, - sccs2rcs.csh: Remove $Id; we decided to get rid of these some - time ago. - -Wed Feb 12 00:24:33 1997 Greg A. Woods - - * cvs2vendor.sh: new script. - * README: noted new cvs2vendor script. - * Makefile.in (DISTFILES): added cvs2vendor.sh. - (CONTRIB_PROGS): added cvs2vendor. - - * log_accum.pl (show_wd): new variable, initialized to 0. - - set $show_wd if '-w' option found while parsing @ARGV. - - don't add 'In directory' line to report header unless $show_wd - is set. - (domainname): prepend a leading '.' if none there so that - concatenation with $hostname works (those with a FQDN hostname - *and* a domainname still lose). - (mail_notification): don't set a "From:" header -- the mailer will. - -Wed Jan 8 14:48:58 1997 Jim Kingdon - - * Makefile.in, README, log.pl: Remove CVSid; we decided to get rid - of these some time ago. - -Thu Jan 2 13:30:56 1997 Jim Kingdon - - * Makefile.in: Remove "675" paragraph; see ../ChangeLog for rationale. - -Thu Oct 17 18:28:25 1996 Jim Kingdon - - * patch-2.1-.new-fix: Removed; it was not in DISTFILES so it never - made it into distributions. It also isn't clear what it has to do - with CVS. It is available from - ftp://ftp.weird.com/pub/patch-2.1-.new-fix - * README: Remove entry for patch-2.1-.new-fix. - -Wed Oct 16 10:22:44 1996 Jim Blandy - - * rcs2log.sh: Change date output format to something CVS 1.9 - accepts. I think this breaks the Sep 29 change, but I don't have - a copy of CVS 1.5 handy, so I can't find a format that works with - both, and I think it's more important that it work with the - version it's distributed with. - -Sat Oct 12 21:18:19 1996 Jim Kingdon - - * README: Don't mention pcl-cvs; it isn't here any more. - -Sun Sep 29 19:45:19 1996 Greg A. Woods - - * README: add entry for patch-2.1-.new-fix. - - * README: re-write the top section a bit. - - * patch-2.1-.new-fix: re-generated using fixed "cvs patch" command. - - * patch-2.1-.new-fix: new file. - -Sun Sep 29 14:25:28 1996 Dave Love - - * rcs2log.sh (month_data): Make default date format acceptable to - CVS post v1.8 as well as earlier CVSs and RCS. - Message-Id: <199609291546.QAA25531@mserv1.dl.ac.uk> - To: bug-gnu-emacs@prep.ai.mit.edu - -Thu Aug 29 11:58:03 1996 Jim Blandy - - * rcs2log: Update FSF address. - - * rcs2log: Be more aggressive about finding the author's full - name; try nismatch and ypmatch. - - * rcs2log: If the hostname appears not to be fully qualified, see - if domainname provides any useful information. - -Fri Aug 16 16:02:36 1996 Norbert Kiesel - - * Makefile.in (installdirs): support this target - -Mon May 6 13:04:57 1996 Jim Kingdon - - * Makefile.in (install): Don't tell user to run cvsinit. It isn't - called cvsinit anymore, and it isn't necessary (repositories are, - and need to be, compatible between cvs versions). - -Sun Apr 14 11:30:36 1996 Karl Fogel - - * Removed pcl-cvs/ subdir; see tools/ subdir in the top-level from - now on. - Added elib/ subdir. - - * Makefile.in (dist-dir): Removed all references to pcl-cvs/ - subdir. - -Wed Mar 6 10:20:28 1996 Greg A. Woods - - * log_accum.pl: ($MAILER): use sendmail directly to allow other - headers to be included - * log_accum.pl (mail_notification): add support to allow settting - of Reply-To and Date header fields in the sent mail; remove $mailto - argument and use the global variable (as with $replyto). - * log_accum.pl: add -R option for mail_notification()'s optional - Reply-To value [default to $login] - -Fri Mar 1 01:51:56 1996 Benjamin J. Lee - - * listener.c: added as mentioned in ../README.VMS - -Mon Feb 19 13:37:36 1996 Jim Kingdon - - * README: Don't just tell people "we don't want your script"; tell - them what to do instead. - -Thu Feb 1 14:28:16 1996 Karl Fogel - - * Makefile.in (DISTFILES): added `rcs2sccs.sh', as mentioned in - README. - -Thu Jan 18 09:39:16 1996 Jim Kingdon - - * README: Talk about submitting changes to contrib directory. - -Tue Nov 14 15:28:25 1995 Greg A. Woods - - * README: fix some spelling and other typos - - * Makefile.in: if I need reminding to run cvsinit.... - -Tue Nov 14 13:47:40 1995 Greg A. Woods - - * log_accum.pl: - - Fix 'cvs status' to use global -Qq options - - fix up a couple of comments, incl., my proper address - - * log.pl: add a CVSid and fix a couple of comments - -Sun Oct 1 02:02:57 1995 Peter Wemm - - * Makefile.in: supply a suffix rule to deal with .sh "source" - -Sat Jul 29 17:29:13 1995 James Kingdon - - * log.pl: Use global options -Qq, not command options -Qq. - - * Makefile.in (install): Look for $(PROGS) and - $(CONTRIB_PROGS) in build dir, not srcdir. - -Fri Jul 28 19:48:45 1995 Paul Eggert - - * rcs2log.sh: Sync with latest Emacs snapshot. - -Thu Jul 27 20:29:30 1995 Jim Blandy - - * rcs2log.sh: import of initial WNT port work - -Fri Jul 14 22:38:44 1995 Jim Blandy - - * rcs-to-cvs.sh: Changes from David J. Mackenzie. - Set permissions on new repository files correctly. - Ignore *~ files. - -Thu Jul 13 23:04:12 CDT 1995 Jim Meyering (meyering@comco.com) - - * Makefile.in (.pl, .csh): *Never* redirect output directly to - the target (usu $@) of a rule. Instead, redirect to a temporary - file, and then move that temporary to the target. I chose to - name temporary files $@-t. Remember to be careful that the length - of the temporary file name not exceed the 14-character limit. - -Sun Jul 9 21:16:53 1995 Karl Fogel - - These are actually Greg Woods' changes: - - * clmerge.pl, cvscheck.sh, descend.sh, dirfns.shar, rcs-to-cvs.sh, - rcs2log.sh, sccs2rcs.csh: renamed from the corresponding files - sans extensions. - - * rcs2sccs.sh: new file. - -Sun Jul 9 19:03:00 1995 Greg A. Woods - - * rcs2log.sh: oops, one more thing that should not have been - there. - - fix interpreter file syntax. - - remove "fix" for separating filenames and comments - - * Makefile.in: hmm... thought rcs2log was in RCS-5.7 for some - reason -- it's not, so we'll install it from here.... - - fix typo -- that's what you get for re-doing changes by hand! - - updates to support proper transformation and installation of - renamed files (from previous local changes) - - * .cvsignore: one more target noted... - - * sccs2rcs.csh: set up the interpreter file for updating by - Makefile (from previous local changes) - - * log_accum.pl, log.pl, commit_prep.pl: - - set up the interpreter file for updating by Makefile - - various modifications, updates, and enhancements - (from previous local changes) - - * rcslock.pl, mfpipe.pl, cvs_acls.pl, cln_hist.pl, clmerge.pl: - - set up the interpreter file for updating by Makefile - (from previous local changes) - - include changes from 1.5 here too, if any - - * README: - - remove extensions from filenames to match installed names - (from previous local changes) - - * .cvsignore: - added $(CONTRIB_PROGS) (from previous local changes) - - -Thu Jun 29 10:43:07 1995 James Kingdon - - * Makefile.in (distclean): Also remove pcl-cvs/Makefile. - -Thu Jun 8 15:32:29 1995 Jim Kingdon (kingdon@lioth.cygnus.com) - - * intro.doc: Added. - * Makefile.in (DISTFILES): Add intro.doc. - -Sat May 27 08:46:00 1995 Jim Meyering (meyering@comco.com) - - * Makefile.in (Makefile): Regenerate only Makefile in current - directory when Makefile.in is out of date. Depend on ../config.status. - -Mon May 8 13:06:29 1995 Bryan O'Sullivan - - * README: added an entry for ccvs-rsh.pl. - -Sun Apr 30 23:50:32 1995 Bryan O'Sullivan - - * ccvs-rsh.pl: fixed a typo and added more flexible use of - CVS_PROXY_USER. - -Sun Apr 30 14:56:21 1995 Jim Blandy - - * clmerge: Changes from Tom Tromey --- fix bug in date comparison - function. - -Sat Apr 29 20:53:08 1995 Bryan O'Sullivan - - * ccvs-rsh.pl: created. See the file itself for documentation. - - * Makefile.in (DISTFILES): added ccvs-rsh.pl to the list of - files to install. - -Fri Apr 28 22:32:45 1995 Jim Blandy - - * Makefile.in (DISTFILES): Brought up-to-date with current - directory contents. - (dist-dir): Renamed from dist-dir; use DISTDIR variable, passed - from parent. - -Mon Feb 13 13:32:07 1995 Jim Blandy - - * rcs2log: rcs2log was originally in this tree; how did it get - deleted? Anyway, this is the version distributed with Emacs - 19.28, hacked to support CVS and Remote CVS. - -Mon Jul 26 13:18:23 1993 David J. Mackenzie (djm@thepub.cygnus.com) - - * rcs-to-cvs: Rewrite in sh. - -Wed Jul 14 21:16:40 1993 David J. Mackenzie (djm@thepub.cygnus.com) - - * rcs-to-cvs: Don't source .cshrc or hardcode paths. - Make respository dir if needed. Don't suppress errors - (such as prompts) from co. - -Wed Feb 26 18:04:40 1992 K. Richard Pixley (rich@cygnus.com) - - * Makefile.in, configure.in: removed traces of namesubdir, - -subdirs, $(subdir), $(unsubdir), some rcs triggers. Forced - copyrights to '92, changed some from Cygnus to FSF. - diff --git a/contrib/cvs/contrib/Makefile.am b/contrib/cvs/contrib/Makefile.am deleted file mode 100644 index f70dbc5..0000000 --- a/contrib/cvs/contrib/Makefile.am +++ /dev/null @@ -1,103 +0,0 @@ -## Process this file with automake to produce Makefile.in -# Makefile for GNU CVS contributed sources. -# Do not use this makefile directly, but only from `../Makefile'. -# -# Copyright (C) 1986-2005 The Free Software Foundation, Inc. -# -# Portions Copyright (C) 1998-2005 Derek Price, Ximbiot , -# and others. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -contribdir = $(pkgdatadir)/contrib - -contrib_SCRIPTS = \ - check_cvs \ - clmerge \ - cln_hist \ - commit_prep \ - cvs2vendor \ - cvs_acls \ - cvscheck \ - debug_check_log \ - log \ - log_accum \ - mfpipe \ - pvcs2rcs \ - rcs-to-cvs \ - rcs2log \ - rcslock \ - sccs2rcs - -contrib_DATA = \ - README \ - intro.doc - -contrib_MANS = \ - cvscheck.man - -bin_LINKS = \ - rcs2log - -EXTRA_DIST = \ - .cvsignore \ - $(contrib_DATA) \ - $(contrib_MANS) \ - cvs2vendor.sh \ - cvscheck.sh \ - cvshelp.man \ - cvs_acls.html \ - debug_check_log.sh \ - descend.sh \ - descend.man \ - dirfns.shar \ - rcs-to-cvs.sh \ - rcs2log.sh \ - rcs2sccs.sh - -CLEANFILES = $(bin_SCRIPTS) $(contrib_SCRIPTS) - -# we'd rather have a link here rather than two copies of a script -install-data-local: - : FIXME - this path should be determined dynamically from bindir - : and contribdir - @$(NORMAL_INSTALL) - $(mkinstalldirs) $(DESTDIR)$(bindir) - @list='$(bin_LINKS)'; for p in $$list; do \ - echo "test ! -f $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`"; \ - echo " && cd $(DESTDIR)$(bindir) && $(LN_S) ../share/$(PACKAGE)/contrib/`echo $$p|sed '$(transform)'` ."; \ - (test ! -f $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'` \ - && cd $(DESTDIR)$(bindir) && $(LN_S) ../share/$(PACKAGE)/contrib/`echo $$p|sed '$(transform)'` .) \ - || (echo "Link creation failed" && if test -f $$p; then \ - echo " $(INSTALL_SCRIPT) $$p $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`"; \ - $(INSTALL_SCRIPT) $$p $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`; \ - else if test -f $(srcdir)/$$p; then \ - echo " $(INSTALL_SCRIPT) $(srcdir)/$$p $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`"; \ - $(INSTALL_SCRIPT) $(srcdir)/$$p $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`; \ - else :; fi; fi); \ - done - -uninstall-local: - @$(NORMAL_UNINSTALL) - list='$(bin_LINKS)'; for p in $$list; do \ - rm -f $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`; \ - done - -SUFFIXES = .sh - -.sh: - rm -f $@ - cp $< $@ - chmod +x $@ - -# for backwards compatibility with the old makefiles -realclean: maintainer-clean -.PHONY: realclean diff --git a/contrib/cvs/contrib/Makefile.in b/contrib/cvs/contrib/Makefile.in deleted file mode 100644 index 965c181..0000000 --- a/contrib/cvs/contrib/Makefile.in +++ /dev/null @@ -1,497 +0,0 @@ -# Makefile.in generated by automake 1.10 from Makefile.am. -# @configure_input@ - -# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006 Free Software Foundation, Inc. -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ - -# Makefile for GNU CVS contributed sources. -# Do not use this makefile directly, but only from `../Makefile'. -# -# Copyright (C) 1986-2005 The Free Software Foundation, Inc. -# -# Portions Copyright (C) 1998-2005 Derek Price, Ximbiot , -# and others. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - - -VPATH = @srcdir@ -pkgdatadir = $(datadir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -subdir = contrib -DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ - $(srcdir)/check_cvs.in $(srcdir)/clmerge.in \ - $(srcdir)/cln_hist.in $(srcdir)/commit_prep.in \ - $(srcdir)/cvs_acls.in $(srcdir)/log.in $(srcdir)/log_accum.in \ - $(srcdir)/mfpipe.in $(srcdir)/pvcs2rcs.in $(srcdir)/rcs2log.sh \ - $(srcdir)/rcslock.in $(srcdir)/sccs2rcs.in ChangeLog -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ - $(top_srcdir)/configure.in -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs -CONFIG_HEADER = $(top_builddir)/config.h -CONFIG_CLEAN_FILES = check_cvs clmerge cln_hist commit_prep cvs_acls \ - log log_accum mfpipe pvcs2rcs rcs2log rcslock sccs2rcs -am__installdirs = "$(DESTDIR)$(contribdir)" "$(DESTDIR)$(contribdir)" -contribSCRIPT_INSTALL = $(INSTALL_SCRIPT) -SCRIPTS = $(contrib_SCRIPTS) -SOURCES = -DIST_SOURCES = -am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; -am__vpath_adj = case $$p in \ - $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ - *) f=$$p;; \ - esac; -am__strip_dir = `echo $$p | sed -e 's|^.*/||'`; -contribDATA_INSTALL = $(INSTALL_DATA) -DATA = $(contrib_DATA) -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -ACLOCAL = @ACLOCAL@ -AMTAR = @AMTAR@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -CC = @CC@ -CCDEPMODE = @CCDEPMODE@ -CFLAGS = @CFLAGS@ -CPP = @CPP@ -CPPFLAGS = @CPPFLAGS@ -CSH = @CSH@ -CYGPATH_W = @CYGPATH_W@ -DEFS = @DEFS@ -DEPDIR = @DEPDIR@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EDITOR = @EDITOR@ -EGREP = @EGREP@ -EXEEXT = @EXEEXT@ -GREP = @GREP@ -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -KRB4 = @KRB4@ -LDFLAGS = @LDFLAGS@ -LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ -LN_S = @LN_S@ -LTLIBOBJS = @LTLIBOBJS@ -MAINT = @MAINT@ -MAKEINFO = @MAKEINFO@ -MKDIR_P = @MKDIR_P@ -MKTEMP = @MKTEMP@ -OBJEXT = @OBJEXT@ -PACKAGE = @PACKAGE@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ -PACKAGE_NAME = @PACKAGE_NAME@ -PACKAGE_STRING = @PACKAGE_STRING@ -PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -PERL = @PERL@ -PR = @PR@ -PS2PDF = @PS2PDF@ -RANLIB = @RANLIB@ -ROFF = @ROFF@ -SENDMAIL = @SENDMAIL@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -STRIP = @STRIP@ -TEXI2DVI = @TEXI2DVI@ -VERSION = @VERSION@ -YACC = @YACC@ -YFLAGS = @YFLAGS@ -abs_builddir = @abs_builddir@ -abs_srcdir = @abs_srcdir@ -abs_top_builddir = @abs_top_builddir@ -abs_top_srcdir = @abs_top_srcdir@ -ac_ct_CC = @ac_ct_CC@ -ac_prefix_program = @ac_prefix_program@ -am__include = @am__include@ -am__leading_dot = @am__leading_dot@ -am__quote = @am__quote@ -am__tar = @am__tar@ -am__untar = @am__untar@ -bindir = @bindir@ -build_alias = @build_alias@ -builddir = @builddir@ -datadir = @datadir@ -datarootdir = @datarootdir@ -docdir = @docdir@ -dvidir = @dvidir@ -exec_prefix = @exec_prefix@ -host_alias = @host_alias@ -htmldir = @htmldir@ -includedir = @includedir@ -includeopt = @includeopt@ -infodir = @infodir@ -install_sh = @install_sh@ -libdir = @libdir@ -libexecdir = @libexecdir@ -localedir = @localedir@ -localstatedir = @localstatedir@ -mandir = @mandir@ -mkdir_p = @mkdir_p@ -oldincludedir = @oldincludedir@ -pdfdir = @pdfdir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -psdir = @psdir@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -srcdir = @srcdir@ -sysconfdir = @sysconfdir@ -target_alias = @target_alias@ -top_builddir = @top_builddir@ -top_srcdir = @top_srcdir@ -with_default_rsh = @with_default_rsh@ -with_default_ssh = @with_default_ssh@ -contribdir = $(pkgdatadir)/contrib -contrib_SCRIPTS = \ - check_cvs \ - clmerge \ - cln_hist \ - commit_prep \ - cvs2vendor \ - cvs_acls \ - cvscheck \ - debug_check_log \ - log \ - log_accum \ - mfpipe \ - pvcs2rcs \ - rcs-to-cvs \ - rcs2log \ - rcslock \ - sccs2rcs - -contrib_DATA = \ - README \ - intro.doc - -contrib_MANS = \ - cvscheck.man - -bin_LINKS = \ - rcs2log - -EXTRA_DIST = \ - .cvsignore \ - $(contrib_DATA) \ - $(contrib_MANS) \ - cvs2vendor.sh \ - cvscheck.sh \ - cvshelp.man \ - cvs_acls.html \ - debug_check_log.sh \ - descend.sh \ - descend.man \ - dirfns.shar \ - rcs-to-cvs.sh \ - rcs2log.sh \ - rcs2sccs.sh - -CLEANFILES = $(bin_SCRIPTS) $(contrib_SCRIPTS) -SUFFIXES = .sh -all: all-am - -.SUFFIXES: -.SUFFIXES: .sh -$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ - && exit 0; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu contrib/Makefile'; \ - cd $(top_srcdir) && \ - $(AUTOMAKE) --gnu contrib/Makefile -.PRECIOUS: Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - @case '$?' in \ - *config.status*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ - *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ - esac; - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh - -$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -check_cvs: $(top_builddir)/config.status $(srcdir)/check_cvs.in - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ -clmerge: $(top_builddir)/config.status $(srcdir)/clmerge.in - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ -cln_hist: $(top_builddir)/config.status $(srcdir)/cln_hist.in - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ -commit_prep: $(top_builddir)/config.status $(srcdir)/commit_prep.in - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ -cvs_acls: $(top_builddir)/config.status $(srcdir)/cvs_acls.in - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ -log: $(top_builddir)/config.status $(srcdir)/log.in - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ -log_accum: $(top_builddir)/config.status $(srcdir)/log_accum.in - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ -mfpipe: $(top_builddir)/config.status $(srcdir)/mfpipe.in - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ -pvcs2rcs: $(top_builddir)/config.status $(srcdir)/pvcs2rcs.in - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ -rcs2log: $(top_builddir)/config.status $(srcdir)/rcs2log.sh - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ -rcslock: $(top_builddir)/config.status $(srcdir)/rcslock.in - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ -sccs2rcs: $(top_builddir)/config.status $(srcdir)/sccs2rcs.in - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ -install-contribSCRIPTS: $(contrib_SCRIPTS) - @$(NORMAL_INSTALL) - test -z "$(contribdir)" || $(MKDIR_P) "$(DESTDIR)$(contribdir)" - @list='$(contrib_SCRIPTS)'; for p in $$list; do \ - if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ - if test -f $$d$$p; then \ - f=`echo "$$p" | sed 's|^.*/||;$(transform)'`; \ - echo " $(contribSCRIPT_INSTALL) '$$d$$p' '$(DESTDIR)$(contribdir)/$$f'"; \ - $(contribSCRIPT_INSTALL) "$$d$$p" "$(DESTDIR)$(contribdir)/$$f"; \ - else :; fi; \ - done - -uninstall-contribSCRIPTS: - @$(NORMAL_UNINSTALL) - @list='$(contrib_SCRIPTS)'; for p in $$list; do \ - f=`echo "$$p" | sed 's|^.*/||;$(transform)'`; \ - echo " rm -f '$(DESTDIR)$(contribdir)/$$f'"; \ - rm -f "$(DESTDIR)$(contribdir)/$$f"; \ - done -install-contribDATA: $(contrib_DATA) - @$(NORMAL_INSTALL) - test -z "$(contribdir)" || $(MKDIR_P) "$(DESTDIR)$(contribdir)" - @list='$(contrib_DATA)'; for p in $$list; do \ - if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ - f=$(am__strip_dir) \ - echo " $(contribDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(contribdir)/$$f'"; \ - $(contribDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(contribdir)/$$f"; \ - done - -uninstall-contribDATA: - @$(NORMAL_UNINSTALL) - @list='$(contrib_DATA)'; for p in $$list; do \ - f=$(am__strip_dir) \ - echo " rm -f '$(DESTDIR)$(contribdir)/$$f'"; \ - rm -f "$(DESTDIR)$(contribdir)/$$f"; \ - done -tags: TAGS -TAGS: - -ctags: CTAGS -CTAGS: - - -distdir: $(DISTFILES) - @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - list='$(DISTFILES)'; \ - dist_files=`for file in $$list; do echo $$file; done | \ - sed -e "s|^$$srcdirstrip/||;t" \ - -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ - case $$dist_files in \ - */*) $(MKDIR_P) `echo "$$dist_files" | \ - sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ - sort -u` ;; \ - esac; \ - for file in $$dist_files; do \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - if test -d $$d/$$file; then \ - dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ - fi; \ - cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ - else \ - test -f $(distdir)/$$file \ - || cp -p $$d/$$file $(distdir)/$$file \ - || exit 1; \ - fi; \ - done -check-am: all-am -check: check-am -all-am: Makefile $(SCRIPTS) $(DATA) -installdirs: - for dir in "$(DESTDIR)$(contribdir)" "$(DESTDIR)$(contribdir)"; do \ - test -z "$$dir" || $(MKDIR_P) "$$dir"; \ - done -install: install-am -install-exec: install-exec-am -install-data: install-data-am -uninstall: uninstall-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-am -install-strip: - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - `test -z '$(STRIP)' || \ - echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install -mostlyclean-generic: - -clean-generic: - -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." -clean: clean-am - -clean-am: clean-generic mostlyclean-am - -distclean: distclean-am - -rm -f Makefile -distclean-am: clean-am distclean-generic - -dvi: dvi-am - -dvi-am: - -html: html-am - -info: info-am - -info-am: - -install-data-am: install-contribDATA install-contribSCRIPTS \ - install-data-local - -install-dvi: install-dvi-am - -install-exec-am: - -install-html: install-html-am - -install-info: install-info-am - -install-man: - -install-pdf: install-pdf-am - -install-ps: install-ps-am - -installcheck-am: - -maintainer-clean: maintainer-clean-am - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-am - -mostlyclean-am: mostlyclean-generic - -pdf: pdf-am - -pdf-am: - -ps: ps-am - -ps-am: - -uninstall-am: uninstall-contribDATA uninstall-contribSCRIPTS \ - uninstall-local - -.MAKE: install-am install-strip - -.PHONY: all all-am check check-am clean clean-generic distclean \ - distclean-generic distdir dvi dvi-am html html-am info info-am \ - install install-am install-contribDATA install-contribSCRIPTS \ - install-data install-data-am install-data-local install-dvi \ - install-dvi-am install-exec install-exec-am install-html \ - install-html-am install-info install-info-am install-man \ - install-pdf install-pdf-am install-ps install-ps-am \ - install-strip installcheck installcheck-am installdirs \ - maintainer-clean maintainer-clean-generic mostlyclean \ - mostlyclean-generic pdf pdf-am ps ps-am uninstall uninstall-am \ - uninstall-contribDATA uninstall-contribSCRIPTS uninstall-local - - -# we'd rather have a link here rather than two copies of a script -install-data-local: - : FIXME - this path should be determined dynamically from bindir - : and contribdir - @$(NORMAL_INSTALL) - $(mkinstalldirs) $(DESTDIR)$(bindir) - @list='$(bin_LINKS)'; for p in $$list; do \ - echo "test ! -f $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`"; \ - echo " && cd $(DESTDIR)$(bindir) && $(LN_S) ../share/$(PACKAGE)/contrib/`echo $$p|sed '$(transform)'` ."; \ - (test ! -f $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'` \ - && cd $(DESTDIR)$(bindir) && $(LN_S) ../share/$(PACKAGE)/contrib/`echo $$p|sed '$(transform)'` .) \ - || (echo "Link creation failed" && if test -f $$p; then \ - echo " $(INSTALL_SCRIPT) $$p $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`"; \ - $(INSTALL_SCRIPT) $$p $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`; \ - else if test -f $(srcdir)/$$p; then \ - echo " $(INSTALL_SCRIPT) $(srcdir)/$$p $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`"; \ - $(INSTALL_SCRIPT) $(srcdir)/$$p $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`; \ - else :; fi; fi); \ - done - -uninstall-local: - @$(NORMAL_UNINSTALL) - list='$(bin_LINKS)'; for p in $$list; do \ - rm -f $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`; \ - done - -.sh: - rm -f $@ - cp $< $@ - chmod +x $@ - -# for backwards compatibility with the old makefiles -realclean: maintainer-clean -.PHONY: realclean -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/contrib/cvs/contrib/README b/contrib/cvs/contrib/README deleted file mode 100644 index 360f59f..0000000 --- a/contrib/cvs/contrib/README +++ /dev/null @@ -1,132 +0,0 @@ -This "contrib" directory is a place holder for code/scripts sent to me -by contributors around the world. This README file will be kept -up-to-date from release to release. BUT, we must point out that these -contributions are really, REALLY UNSUPPORTED. In fact, we probably -don't even know what some of them really do. We certainly do not -guarantee to have tried them, or ported them to work with this CVS -distribution. If you have questions, your best bet is to contact the -original author, but you should not necessarily expect a reply, since -the author may not be available at the address given. - -USE AT YOUR OWN RISK -- and all that stuff. - -"Unsupported" also means that no one has volunteered to accept and check -in changes to this directory. So submissions for new scripts to add -here are unlikely to be accepted. Suggested changes to the existing -scripts here conceivably might, but that isn't clear either, unless of -course they come from the original author of the script. - -If you have some software that works with CVS that you wish to offer it -is suggested that you make it available by FTP or HTTP and then announce -it on the info-cvs mailing list. - -There is a web page of software related to CVS at the following URL which -would presumably be willing to list your software. - - http://www.loria.fr/~molli/cvs-index.html - -An attempt at a table of Contents for this directory: - - README This file. - - check_cvs A perl script to check an entire repository for - corruption. - Contributed by Donald Sharp . - - clmerge A perl script to handle merge conflicts in GNU - style ChangeLog files . - Contributed by Tom Tromey . - - cln_hist A perl script to compress your - $CVSROOT/CVSROOT/history file, as it can grow quite - large after extended use. - Contributed by David G. Grubbs - - commit_prep A perl script, to be combined with log_accum.pl, to - log_accum provide for a way to combine the individual log - messages of a multi-directory "commit" into a - single log message, and mail the result somewhere. - Can also do other checks for $Id and that you are - committing the correct revision of the file. - Read the comments carefully. - Contributed by David Hampton . - - cvs2vendor A shell script to move changes from a repository - that was started without a vendor branch to one - that has a vendor branch. - Contributed by Greg A. Woods . - - cvs_acls A perl script that implements Access Control Lists - by using the "commitinfo" hook provided with the - "cvs commit" command. - Contributed by David G. Grubbs . - - cvscheck Identifies files added, changed, or removed in a - cvscheck.man checked out CVS tree; also notices unknown files. - Contributed by Lowell Skoog - - cvshelp.man An introductory manual page written by Lowell Skoog - . It is most likely - out-of-date relative to CVS 1.3, but still may be - useful. - - debug_check_log A shell script to help analyze sanity check failures. - Contributed by Derek R. Price . - - descend A shell script that can be used to recursively - descend.man descend through a directory. In CVS 1.2, this was - very useful, since many of the commands were not - recursive. In CVS 1.3 (and later), however, most of - the commands are recursive. However, this may still - come in handy. - Contributed by Lowell Skoog - - dirfns A shar file which contains some code that might - help your system support opendir/readdir/closedir, - if it does not already. - Copied from the C-News distribution. - - intro.doc A user's view of what you need to know to get - started with CVS. - Contributed by . - - log A perl script suitable for including in your - $CVSROOT/CVSROOT/loginfo file for logging commit - changes. Includes the RCS revision of the change - as part of the log. - Contributed by Kevin Samborn . - - log_accum See commit_prep. - - mfpipe Another perl script for logging. Allows you to - pipe the log message to a file and/or send mail - to some alias. - Contributed by John Clyne . - - pvcs2rcs A perl script to convert a PVCS tree to an RCS tree. - - rcs-to-cvs Script to import sources that may have been under - RCS control already. - Contributed by Per Cederqvist . - - rcs2log A shell script to create a ChangeLog-format file - given only a set of RCS files. - Contributed by Paul Eggert . - - rcs2sccs A shell script to convert simple RCS files into - SCCS files, originally gleaned off the network - somewhere (originally by "kenc") and modified by - Jerry Jelinek and - Brian Berliner to increase - robustness and add support for one-level of branches. - - rcslock A perl script that can be added to your commitinfo - file that tries to determine if your RCS file is - currently locked by someone else, as might be the - case for a binary file. - Contributed by John Rouillard . - - sccs2rcs A C-shell script that can convert (some) SCCS files - into RCS files, retaining the info contained in the - SCCS file (like dates, author, and log message). - Contributed by Ken Cox . diff --git a/contrib/cvs/contrib/check_cvs.in b/contrib/cvs/contrib/check_cvs.in deleted file mode 100644 index 740f329..0000000 --- a/contrib/cvs/contrib/check_cvs.in +++ /dev/null @@ -1,822 +0,0 @@ -#! @PERL@ -w -######################################################################## -# Copyright (c) 2000, 2001 by Donald Sharp -# All Rights Reserved -# -# Permission is granted to copy and/or distribute this file, with or -# without modifications, provided this notice is preserved. -# -######################################################################## - -=head1 check_cvs.pl - - Script to check the integrity of the Repository - -=head1 SYNOPSIS - - check_cvs.pl - -=head1 DESCRIPTION - - This script will search through a repository and determine if - any of the files in it are corrupted. - - Please do not run this script inside of the repository itself, - it will cause it too fail. - - Also it currently can only be run over the entire repository, - so only point your CVSROOT at the actual CVSROOT. - -=head1 OPTIONS - - There are no options. - -=head1 EXAMPLES - - setenv CVSROOT /release/111/cvs - - # To see more verbose output - setenv CVSDEBUGEDIT 1 - - check_cvs.pl - -=head1 SEE ALSO - - None - -=cut - -###################################################################### -# MODULES # -###################################################################### -use strict; - -use File::Find; -use File::Basename; -use File::Path; -use Cwd; - -###################################################################### -# GLOBALS # -###################################################################### - -my @list_of_broken_files; -my @extra_files; -my $verbose = 0; - -my $total_revisions; -my $total_interesting_revisions; -my $total_files; -my @ignore_files; - -###################################################################### -# SUBROUTINES # -###################################################################### - -###################################################################### -# -# NAME : -# main -# -# PURPOSE : -# To search the repository for broken files -# -# PARAMETERS : -# NONE -# -# GLOBALS : -# $ENV{ CVSROOT } - The CVS repository to search through -# $ENV{ CVSDEBUGEDIT } - Turn on Debugging. -# @list_of_broken_files - The list of files that need to -# be fixed. -# $verbose - is verbose mode on? -# $total_revisions - The number of revisions considered -# $total_interesting_revisions - The number of revisions used -# $total_files - The total number of files looked at. -# -# RETURNS : -# A list of broken files -# -# COMMENTS : -# Do not run this script inside the repository. Choose -# a nice safe spot( like /tmp ) outside of the repository. -# -###################################################################### -my $directory_to_look_at; - -select (STDOUT); $| = 1; # make unbuffered - -$total_revisions = 0; -$total_interesting_revisions = 0; -$total_files = 0; - -if( !exists( $ENV{ CVSROOT } ) ) -{ - die( "The script should be run with the CVSROOT environment variable set" ); -} - -if( exists( $ENV{ CVSDEBUGEDIT } ) ) -{ - $verbose = 1; - print( "Verbose Mode Turned On\n" ); -} - -$directory_to_look_at = $ENV{ CVSROOT }; -my $sym_count = 0; -while( -l $directory_to_look_at ) -{ - $directory_to_look_at = readlink( $directory_to_look_at ); - $sym_count += 1; - if( $sym_count > 5 ) - { - die( "Encountered too many symlinks for $ENV{ CVSROOT }\n" ); - } -} - -print( "Processing: $directory_to_look_at\n" ) if( $verbose ); -@ignore_files = &get_ignore_files_from_cvsroot( $directory_to_look_at ); -find( \&process_file, $directory_to_look_at ); - -my $num_files = @list_of_broken_files; -print( "List of corrupted files\n" ) if( $num_files > 0 ); -foreach my $broken ( @list_of_broken_files ) -{ - print( "**** File: $broken\n" ); -} - -$num_files = @extra_files; -print( "List of Files That Don't belong in Repository:\n" ) if( $num_files > 0 ); -foreach my $extra ( @extra_files ) -{ - print( "**** File: $extra\n" ); -} -print( "Total Files: $total_files\n" ); -print( "Total Revisions: $total_revisions Interesting Revisions: $total_interesting_revisions\n" ); - -###################################################################### -# -# NAME : -# process_file -# -# PURPOSE : -# This function is called by the find function, it's purpose -# is to decide if it is important to look at a file or not. -# We only care about files that have the ,v at the end. -# -# PARAMETERS : -# NONE -# -# GLOBALS : -# $ENV{ CVSROOT } - The CVS repository to search through -# -# RETURNS : -# NONE -# -# COMMENTS : -# NONE -# -###################################################################### -sub process_file -{ - my $path = $File::Find::name; - - $total_files += 1; - $path =~ s/^$directory_to_look_at\///; - - print( "\tProcessing File: $path\n" ) if( $verbose ); - if( $path =~ /,v$/ ) - { - $path =~ s/,v$//; - look_at_cvs_file( $path ); - } - elsif( ! -d $File::Find::name ) - { - my $save = 0; - - foreach my $ignore ( @ignore_files ) - { - if( $path =~ /$ignore/ ) - { - $save = 1; - last; - } - } - - if( !$save ) - { - push( @extra_files, $path ); - } - } -} - -###################################################################### -# -# NAME : -# look_at_cvs_file -# -# PURPOSE : -# To decide if a file is broken or not. The algorithm is: -# a) Get the revision history for the file. -# - If that fails the file is broken, save the fact -# and continue processing other files. -# - If that succeeds we have a list of revisions. -# b) For Each revision try to retrieve that version -# - If that fails the file is broken, save the fact -# and continue processing other files. -# c) Continue on -# -# PARAMETERS : -# $file - The file to look at. -# -# GLOBALS : -# NONE -# -# RETURNS : -# NONE -# -# COMMENTS : -# We have to handle Attic files in a special manner. -# Basically remove the Attic from the string if it -# exists at the end of the $path variable. -# -###################################################################### -sub look_at_cvs_file -{ - my( $file ) = @_; - my( $name, $path, $suffix ) = fileparse( $file ); - - if( $path =~ s/Attic\/$// ) - { - $file = $path . $name; - } - - my $revisions = get_history( $name ); - - if( !defined( $revisions ) ) - { - print( "\t$file is corrupted, this was determined via a cvs log command\n" ) if( $verbose ); - push( @list_of_broken_files, $file ); - return(); - } - - my @int_revisions = find_interesting_revisions( @$revisions ); - - foreach my $revision ( @int_revisions ) - { - print( "\t\tLooking at Revision: $revision\n" ) if( $verbose ); - if( !check_revision( $file, $revision ) ) - { - print( "\t$file is corrupted in revision: $revision\n" ) if( $verbose ); - push( @list_of_broken_files, $file ); - return(); - } - } - -} - -###################################################################### -# -# NAME : -# get_history -# -# PURPOSE : -# To retrieve a array of revision numbers. -# -# PARAMETERS : -# $file - The file to retrieve the revision numbers for -# -# GLOBALS : -# NONE -# -# RETURNS : -# On Success - Reference to the list of revision numbers -# On Failure - undef. -# -# COMMENTS : -# The $_ is saved off because The File::find functionality -# expects the $_ to not have been changed. -# The -N option for the rlog command means to spit out -# tags or branch names. -# -###################################################################### -sub get_history -{ - my( $file ) = @_; - $file =~ s/(["\$`\\])/\\$1/g; - my @revisions; - my $revision; - my $ignore = 1; - my $save_ = $_; - - open( FILE, "rlog -N \"$file\" 2>&1 |" ) or die( "unable to run rlog, help" ); - - while( ) - { - #rlog outputs a "----" line before the actual revision - #without this we'll pick up peoples comments if they - #happen to start with revision - if( /^----------------------------$/ ) - { - $ignore = 0; - next; - } - - if( ( !$ignore ) && ( ( $revision ) = m/^revision (\S+)/ ) ) - { - push( @revisions, $revision ); - $ignore = 1; - } - } - - $_ = $save_; - - if( !close( FILE ) ) - { - return( undef ); - } - - return( \@revisions ); -} - -###################################################################### -# -# NAME : -# check_revision -# -# PURPOSE : -# Given a file and a revision number ensure that we can -# check out that file -# -# PARAMETERS : -# $file - The file to look at. -# $revision - The revision to look at. -# -# GLOBALS : -# NONE -# -# RETURNS : -# If we can get the File - 1 -# If we can not get the File - 0 -# -# COMMENTS : -# cvs command line options are as followed: -# -n - Do not run any checkout program as specified by the -o -# option in the modules file -# -p - Put all output to standard out. -# -r - The revision of the file that we would like to look at. -# Please note that cvs will return 0 for being able to successfully -# read the file and 1 for failure to read the file. -# -###################################################################### -sub check_revision -{ - my( $file, $revision ) = @_; - $file =~ s/(["\$`\\])/\\$1/g; - - my $cwd = getcwd(); - chdir( "/tmp" ); - - my $ret_code = 0xffff & system( "cvs co -n -p -r $revision \"$file\" > /dev/null 2>&1" ); - - chdir( $cwd ); - return( 1 ) if ( $ret_code == 0 ); - return( 0 ); - - return( $ret_code ); -} - -###################################################################### -# -# NAME : -# find_interesting_revisions -# -# PURPOSE : -# CVS stores information in a logical manner. We only really -# need to look at some interestin revisions. These are: -# The first version -# And the last version on every branch. -# This is because cvs stores changes descending from -# main line. ie suppose the last version on mainline is 1.6 -# version 1.6 of the file is stored in toto. version 1.5 -# is stored as a diff between 1.5 and 1.6. 1.4 is stored -# as a diff between 1.5 and 1.4. -# branches are stored a little differently. They are -# stored in ascending order. Suppose there is a branch -# on 1.4 of the file. The first branches revision number -# would be 1.4.1.1. This is stored as a diff between -# version 1.4 and 1.4.1.1. The 1.4.1.2 version is stored -# as a diff between 1.4.1.1 and 1.4.1.2. Therefore -# we are only interested in the earliest revision number -# and the highest revision number on a branch. -# -# PARAMETERS : -# @revisions - The list of revisions to find interesting ones -# -# GLOBALS : -# NONE -# -# RETURNS : -# @new_revisions - The list of revisions that we find interesting -# -# COMMENTS : -# -###################################################################### -sub find_interesting_revisions -{ - my( @revisions ) = @_; - my @new_revisions; - my %branch_revision; - my $branch_number; - my $branch_rev; - my $key; - my $value; - - START_OVER: - foreach my $revision( @revisions ) - { - my $start_over = 0; - ( $branch_number, $branch_rev ) = branch_split( $revision ); - - #if the number of elements in the branch is 1 - #and the new branch is less than the old branch - if( elements_in_branch( $branch_number ) == 1 ) - { - ( $start_over, - %branch_revision ) = find_int_mainline_revision( $branch_number, - $branch_rev, - %branch_revision ); - next START_OVER if( $start_over ); - } - - %branch_revision = find_int_branch_revision( $branch_number, - $branch_rev, - %branch_revision ); - - } - - %branch_revision = remove_duplicate_branches( %branch_revision ); - - while( ( $key, $value ) = each ( %branch_revision ) ) - { - push( @new_revisions, $key . "." . $value ); - } - - my $nrc; - my $rc; - - $rc = @revisions; - $nrc = @new_revisions; - - $total_revisions += $rc; - $total_interesting_revisions += $nrc; - - print( "\t\tTotal Revisions: $rc Interesting Revisions: $nrc\n" ) if( $verbose ); - - return( @new_revisions ); -} - -######################################################################## -# -# NAME : -# remove_duplicate_branches -# -# PURPOSE : -# To remove from the list of branches that we are interested -# in duplication that will cause cvs to check a revision multiple -# times. For Instance revision 1.1.1.1 should be prefered -# to be checked over revision 1.1, as that v1.1.1.1 can -# only be retrieved by going through v1.1. Therefore -# we should remove v1.1 from the list of branches that -# are interesting. -# -# PARAMETERS : -# %branch_revisions - The hash of the interesting revisions -# -# GLOBALS : -# NONE -# -# RETURNS : -# %branch_revisions - The hash of the modified interesting revisions -# -# COMMENTS : -# NONE -# -######################################################################## -sub remove_duplicate_branches -{ - my( %branch_revisions ) = @_; - my $key; - my $value; - my $branch_comp; - my $branch; - - - RESTART: - { - my @keys = keys( %branch_revisions ); - while( ( $key, $value ) = each ( %branch_revisions ) ) - { - $branch_comp = $key . "." . $value; - foreach $branch ( @keys ) - { - if( $branch eq $key ) - { - next; - } - if( elements_in_branch( $branch_comp ) == - elements_in_branch( $branch ) - 1 ) - { - if( $branch =~ /^$branch_comp/ ) - { - delete( $branch_revisions{ $key } ); - goto RESTART; - } - } - } - } - } - - return( %branch_revisions ); -} - -###################################################################### -# -# NAME : -# find_int_branch_revision -# -# PURPOSE : -# To Find a interesting branch revision. -# Algorithm: -# If the $branch_revision exists in the interesting branch -# hash and the new $branch_rev is less than currently saved -# one replace it with the new $branch_rev. -# else if the $branch_revision doesn't exist in the interesting -# branch hash, then just store the $branch_number and $branch_rev -# -# PARAMETERS : -# $branch_number - The branch that we are looking at -# $branch_rev - The particular revision we are looking -# at on the $branch_number. -# %branch_revision - The hash storing the interesting branches -# and the revisions on them. -# -# GLOBALS : -# NONE -# -# RETURNS : -# %branch_revision - The modified hash that stores interesting -# branches. -# -# COMMENTS : -# NONE -# -###################################################################### -sub find_int_branch_revision -{ - my( $branch_number, $branch_rev, %branch_revision ) = @_; - - if( exists( $branch_revision{ $branch_number } ) ) - { - if( $branch_rev > $branch_revision{ $branch_number } ) - { - $branch_revision{ $branch_number } = $branch_rev; - } - } - else - { - $branch_revision{ $branch_number } = $branch_rev; - } - - return( %branch_revision ); -} - -###################################################################### -# -# NAME : -# find_int_mainline_revision -# -# PURPOSE : -# To Find a interesting mainline revision. -# Algorithm: -# if the $branch_number is less then a branch number -# with one element in it, then delete the old branch_number -# and return. -# if the $branch_number is greater than a branch number -# then return, and tell the calling function that we -# should skip this element, as that it's not important. -# if the $branch_number is the same as a branch number -# with one element in it, then check to see if the -# $branch_rev is less than the stored branch rev if -# it is replace with new $branch_rev. Else ignore revision -# -# PARAMETERS : -# $branch_number - The branch that we are looking at -# $branch_rev - The particular revision we are looking -# at on the $branch_number. -# %branch_revision - The hash storing the interesting branches -# and the revisions on them. -# -# GLOBALS : -# NONE -# -# RETURNS : -# ( $skip, %branch_revision ) - -# $skip - 1 if we need to ignore this particular $branch_number -# $branch_rev combo. Else 0. -# %branch_revision - The modified hash that stores interesting -# branches. -# -# COMMENTS : -# NONE -# -###################################################################### -sub find_int_mainline_revision -{ - my( $branch_number, $branch_rev, %branch_revision ) = @_; - - foreach my $key ( keys %branch_revision ) - { - if( elements_in_branch( $key ) == 1 ) - { - if( $branch_number < $key ) - { - delete( $branch_revision{ $key } ); - next; - } - - if( $branch_number > $key ) - { - return( 1, %branch_revision ); - } - if( ( exists( $branch_revision{ $branch_number } ) ) && - ( $branch_rev < $branch_revision{ $branch_number } ) ) - { - $branch_revision{ $branch_number } = $branch_rev; - return( 1, %branch_revision ); - } - } - } - - return( 0, %branch_revision ); -} - -###################################################################### -# -# NAME : -# elements_in_branch -# -# PURPOSE : -# Determine the number of elements in a revision number -# Elements are defined by numbers seperated by ".". -# the revision 1.2.3.4 would have 4 elements -# the revision 1.2.4.5.6.7 would have 6 elements -# -# PARAMETERS : -# $branch - The revision to look at. -# -# GLOBALS : -# NONE -# -# RETURNS : -# $count - The number of elements -# -# COMMENTS : -# NONE -# -###################################################################### -sub elements_in_branch -{ - my( $branch ) = @_; - my @split_rev; - - @split_rev = split /\./, $branch; - - my $count = @split_rev; - return( $count ); -} - -###################################################################### -# -# NAME : -# branch_split -# -# PURPOSE : -# To split up a revision number up into the branch part and -# the number part. For Instance: -# 1.1.1.1 - is split 1.1.1 and 1 -# 2.1 - is split 2 and 1 -# 1.3.4.5.7.8 - is split 1.3.4.5.7 and 8 -# -# PARAMETERS : -# $revision - The revision to look at. -# -# GLOBALS : -# NONE -# -# RETURNS : -# ( $branch, $revision ) - -# $branch - The branch part of the revision number -# $revision - The revision part of the revision number -# -# COMMENTS : -# NONE -# -###################################################################### -sub branch_split -{ - my( $revision ) = @_; - my $branch; - my $version; - my @split_rev; - my $count; - - @split_rev = split /\./, $revision; - - my $numbers = @split_rev; - @split_rev = reverse( @split_rev ); - $branch = pop( @split_rev ); - for( $count = 0; $count < $numbers - 2 ; $count++ ) - { - $branch .= "." . pop( @split_rev ); - } - - return( $branch, pop( @split_rev ) ); -} - -###################################################################### -# -# NAME : -# get_ignore_files_from_cvsroot -# -# PURPOSE : -# Retrieve the list of files from the CVSROOT/ directory -# that should be ignored. -# These are the regular files (e.g., commitinfo, loginfo) -# and those specified in the checkoutlist file. -# -# PARAMETERS : -# The CVSROOT -# -# GLOBALS : -# NONE -# -# RETURNS : -# @ignore - the list of files to ignore -# -# COMMENTS : -# NONE -# -###################################################################### -sub get_ignore_files_from_cvsroot { - my( $cvsroot ) = @_; - my @ignore = ( 'CVS\/fileattr$', - '^CVSROOT\/loginfo', - '^CVSROOT\/.#loginfo', - '^CVSROOT\/rcsinfo', - '^CVSROOT\/.#rcsinfo', - '^CVSROOT\/editinfo', - '^CVSROOT\/.#editinfo', - '^CVSROOT\/verifymsg', - '^CVSROOT\/.#verifymsg', - '^CVSROOT\/commitinfo', - '^CVSROOT\/.#commitinfo', - '^CVSROOT\/taginfo', - '^CVSROOT\/.#taginfo', - '^CVSROOT\/cvsignore', - '^CVSROOT\/.#cvsignore', - '^CVSROOT\/checkoutlist', - '^CVSROOT\/.#checkoutlist', - '^CVSROOT\/cvswrappers', - '^CVSROOT\/.#cvswrappers', - '^CVSROOT\/notify', - '^CVSROOT\/.#notify', - '^CVSROOT\/modules', - '^CVSROOT\/.#modules', - '^CVSROOT\/readers', - '^CVSROOT\/.#readers', - '^CVSROOT\/writers', - '^CVSROOT\/.#writers', - '^CVSROOT\/passwd', - '^CVSROOT\/config', - '^CVSROOT\/.#config', - '^CVSROOT\/val-tags', - '^CVSROOT\/.#val-tags', - '^CVSROOT\/history' ); - my $checkoutlist_file = "$cvsroot\/CVSROOT\/checkoutlist"; - open( CHECKOUTLIST, "<$cvsroot\/CVSROOT\/checkoutlist" ) - or die( "Unable to read checkoutlist file: $!\n" ); - - my @list = ; - chomp( @list ); - close( CHECKOUTLIST ) - or die( "Unable to close checkoutlist file: $!\n" ); - - foreach my $line( @list ) - { - next if( $line =~ /^#/ || $line =~ /^$/ ); - if( $line =~ /^\s*(\S*)\s*/ ) { $line = $1 }; - push( @ignore, "^CVSROOT\/$line", "^CVSROOT\/\.#$line" ); - } - - return @ignore; -} diff --git a/contrib/cvs/contrib/clmerge.in b/contrib/cvs/contrib/clmerge.in deleted file mode 100755 index f2163e5..0000000 --- a/contrib/cvs/contrib/clmerge.in +++ /dev/null @@ -1,164 +0,0 @@ -#! @PERL@ - -# Copyright (C) 1995-2005 The Free Software Foundation, Inc. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -# Merge conflicted ChangeLogs -# tromey Mon Aug 15 1994 - -# Usage is: -# -# cl-merge [-i] file ... -# -# With -i, it works in place (backups put in a ~ file). Otherwise the -# merged ChangeLog is printed to stdout. - -# Please report any bugs to me. I wrote this yesterday, so there are no -# guarantees about its performance. I recommend checking its output -# carefully. If you do send a bug report, please include the failing -# ChangeLog, so I can include it in my test suite. -# -# Tom -# --- -# tromey@busco.lanl.gov Member, League for Programming Freedom -# Sadism and farce are always inexplicably linked. -# -- Alexander Theroux - - -# Month->number mapping. Used for sorting. -%months = ('Jan', 0, - 'Feb', 1, - 'Mar', 2, - 'Apr', 3, - 'May', 4, - 'Jun', 5, - 'Jul', 6, - 'Aug', 7, - 'Sep', 8, - 'Oct', 9, - 'Nov', 10, - 'Dec', 11); - -# If '-i' is given, do it in-place. -if ($ARGV[0] eq '-i') { - shift (@ARGV); - $^I = '~'; -} - -$lastkey = ''; -$lastval = ''; -$conf = 0; -%conflist = (); - -$tjd = 0; - -# Simple state machine. The states: -# -# 0 Not in conflict. Just copy input to output. -# 1 Beginning an entry. Next non-blank line is key. -# 2 In entry. Entry beginner transitions to state 1. -while (<>) { - if (/^<<<>>>/) { - # End of conflict. Output. - - # Copy last key into array. - if ($lastkey ne '') { - $conflist{$lastkey} = $lastval; - - $lastkey = ''; - $lastval = ''; - } - - foreach (reverse sort clcmp keys %conflist) { - print STDERR "doing $_" if $tjd; - print $_; - print $conflist{$_}; - } - - $lastkey = ''; - $lastval = ''; - $conf = 0; - %conflist = (); - } elsif ($conf == 1) { - # Beginning an entry. Skip empty lines. Error if not a real - # beginner. - if (/^$/) { - # Empty line; just skip at this point. - } elsif (/^[MTWFS]/) { - # Looks like the name of a day; assume opener and move to - # "in entry" state. - $lastkey = $_; - $conf = 2; - print STDERR "found $_" if $tjd; - } else { - die ("conflict crosses entry boundaries: $_"); - } - } elsif ($conf == 2) { - # In entry. Copy into variable until we see beginner line. - if (/^[MTWFS]/) { - # Entry beginner line. - - # Copy last key into array. - if ($lastkey ne '') { - $conflist{$lastkey} = $lastval; - - $lastkey = ''; - $lastval = ''; - } - - $lastkey = $_; - print STDERR "found $_" if $tjd; - $lastval = ''; - } else { - $lastval .= $_; - } - } else { - # Just copy. - print; - } -} - -# Compare ChangeLog time strings like <=>. -# -# 0 1 2 3 -# Thu Aug 11 13:22:42 1994 Tom Tromey (tromey@creche.colorado.edu) -# 0123456789012345678901234567890 -# -sub clcmp { - # First check year. - $r = substr ($a, 20, 4) <=> substr ($b, 20, 4); - - # Now check month. - $r = $months{substr ($a, 4, 3)} <=> $months{substr ($b, 4, 3)} if !$r; - - # Now check day. - $r = substr ($a, 8, 2) <=> substr ($b, 8, 2) if !$r; - - # Now check time (3 parts). - $r = substr ($a, 11, 2) <=> substr ($b, 11, 2) if !$r; - $r = substr ($a, 14, 2) <=> substr ($b, 14, 2) if !$r; - $r = substr ($a, 17, 2) <=> substr ($b, 17, 2) if !$r; - - $r; -} diff --git a/contrib/cvs/contrib/cln_hist.in b/contrib/cvs/contrib/cln_hist.in deleted file mode 100755 index ba03a27..0000000 --- a/contrib/cvs/contrib/cln_hist.in +++ /dev/null @@ -1,103 +0,0 @@ -#! @PERL@ -# -*-Perl-*- - -# Copyright (C) 1995-2005 The Free Software Foundation, Inc. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# Contributed by David G. Grubbs -# -# Clean up the history file. 10 Record types: MAR OFT WUCG -# -# WUCG records are thrown out. -# MAR records are retained. -# T records: retain only last tag with same combined tag/module. -# -# Two passes: Walk through the first time and remember the -# 1. Last Tag record with same "tag" and "module" names. -# 2. Last O record with unique user/module/directory, unless followed -# by a matching F record. -# - -$r = $ENV{"CVSROOT"}; -$c = "$r/CVSROOT"; -$h = "$c/history"; - -eval "print STDERR \$die='Unknown parameter $1\n' if !defined \$$1; \$$1=\$';" - while ($ARGV[0] =~ /^(\w+)=/ && shift(@ARGV)); -exit 255 if $die; # process any variable=value switches - -%tags = (); -%outs = (); - -# -# Move history file to safe place and re-initialize a new one. -# -rename($h, "$h.bak"); -open(XX, ">$h"); -close(XX); - -# -# Pass1 -- remember last tag and checkout. -# -open(HIST, "$h.bak"); -while () { - next if /^[MARWUCG]/; - - # Save whole line keyed by tag|module - if (/^T/) { - @tmp = split(/\|/, $_); - $tags{$tmp[4] . '|' . $tmp[5]} = $_; - } - # Save whole line - if (/^[OF]/) { - @tmp = split(/\|/, $_); - $outs{$tmp[1] . '|' . $tmp[2] . '|' . $tmp[5]} = $_; - } -} - -# -# Pass2 -- print out what we want to save. -# -open(SAVE, ">$h.work"); -open(HIST, "$h.bak"); -while () { - next if /^[FWUCG]/; - - # If whole line matches saved (i.e. "last") one, print it. - if (/^T/) { - @tmp = split(/\|/, $_); - next if $tags{$tmp[4] . '|' . $tmp[5]} ne $_; - } - # Save whole line - if (/^O/) { - @tmp = split(/\|/, $_); - next if $outs{$tmp[1] . '|' . $tmp[2] . '|' . $tmp[5]} ne $_; - } - - print SAVE $_; -} - -# -# Put back the saved stuff -# -system "cat $h >> $h.work"; - -if (-s $h) { - rename ($h, "$h.interim"); - print "history.interim has non-zero size.\n"; -} else { - unlink($h); -} - -rename ("$h.work", $h); - -exit(0); diff --git a/contrib/cvs/contrib/commit_prep.in b/contrib/cvs/contrib/commit_prep.in deleted file mode 100755 index c795533..0000000 --- a/contrib/cvs/contrib/commit_prep.in +++ /dev/null @@ -1,86 +0,0 @@ -#! @PERL@ -T -# -*-Perl-*- - -# Copyright (C) 1994-2005 The Free Software Foundation, Inc. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -############################################################################### -############################################################################### -############################################################################### -# -# THIS SCRIPT IS PROBABLY BROKEN. REMOVING THE -T SWITCH ON THE #! LINE ABOVE -# WOULD FIX IT, BUT THIS IS INSECURE. WE RECOMMEND FIXING THE ERRORS WHICH THE -# -T SWITCH WILL CAUSE PERL TO REPORT BEFORE RUNNING THIS SCRIPT FROM A CVS -# SERVER TRIGGER. PLEASE SEND PATCHES CONTAINING THE CHANGES YOU FIND -# NECESSARY TO RUN THIS SCRIPT WITH THE TAINT-CHECKING ENABLED BACK TO THE -# <@PACKAGE_BUGREPORT@> MAILING LIST. -# -# For more on general Perl security and taint-checking, please try running the -# `perldoc perlsec' command. -# -############################################################################### -############################################################################### -############################################################################### - -# Perl filter to handle pre-commit checking of files. This program -# records the last directory where commits will be taking place for -# use by the log_accum.pl script. -# -# IMPORTANT: this script interacts with log_accum, they have to agree -# on the tmpfile name to use. See $LAST_FILE below. -# -# Contributed by David Hampton -# Stripped to minimum by Roy Fielding -# -############################################################ -$TMPDIR = $ENV{'TMPDIR'} || '/tmp'; -$FILE_PREFIX = '#cvs.'; - -# If see a "-u $USER" argument, then destructively remove it from the -# argument list, so $ARGV[0] will be the repository dir again, as it -# used to be before we added the -u flag. -if ($ARGV[0] eq '-u') { - shift @ARGV; - $CVS_USERNAME = shift (@ARGV); -} - -# This needs to match the corresponding var in log_accum.pl, including -# the appending of the pgrp and username suffixes (see uses of this -# var farther down). -$LAST_FILE = "$TMPDIR/${FILE_PREFIX}lastdir"; - -sub write_line { - my ($filename, $line) = @_; - -# A check of some kind is needed here, but the rules aren't apparent -# at the moment: - -# foreach($filename, $line){ -# $_ =~ m#^([-\@\w.\#]+)$#; -# $_ = $1; -# } - - open(FILE, ">$filename") || die("Cannot open $filename: $!\n"); - print(FILE $line, "\n"); - close(FILE); -} - -# -# Record this directory as the last one checked. This will be used -# by the log_accumulate script to determine when it is processing -# the final directory of a multi-directory commit. -# -$id = getpgrp(); - -&write_line("$LAST_FILE.$id.$CVS_USERNAME", $ARGV[0]); - -exit(0); diff --git a/contrib/cvs/contrib/cvs2vendor.sh b/contrib/cvs/contrib/cvs2vendor.sh deleted file mode 100644 index 166544d..0000000 --- a/contrib/cvs/contrib/cvs2vendor.sh +++ /dev/null @@ -1,159 +0,0 @@ -#! /bin/sh -# -# Copyright (C) 1997-2005 The Free Software Foundation, Inc. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# cvs2vendor - move revsisions from files in A to files in B -# -# The primary reason for this script is to move deltas from a -# non-vendor branched repository onto a fresh vendor branched one, -# skipping the initial checkin in assumption that it is the same in -# both repositories. This way you can take a project that was moved -# into CVS without the benefit of the vendor branch and for all -# intents and purposes add the vendor branch underneath the existing -# deltas. -# -# This script is also a decent example of repository maintenance using -# raw RCS commands (if I do say so myself! ;-). -# -# Tags are preserved. -# -# The timestamp of the initial vendor branch revision will be adjusted -# to be the same as the 1.1 revision of each source file. -# -# Extra branches in the source directory will cause breakage. -# -# Intermediate files are created in the current working directory -# where this script is started. -# -# Written by Greg A. Woods , based on rcs2sccs -# (retains some of the rlog parsing from it). -# -# The copyright is in the Public Domain. -# - -if [ $# -ne 2 ]; then - echo USAGE: $0 srcdir dstdir - exit 2 -fi -tsrcdir=$1 -tdstdir=$2 - -revfile=/tmp/cvs2vendor_$$_rev -rm -f $revfile - -commentfile=/tmp/cvs2vendor_$$_comment -rm -f $commentfile - -if sort -k 1,1 /dev/null 2>/dev/null -then sort_each_field='-k 1 -k 2 -k 3 -k 4 -k 5 -k 6 -k 7 -k 8 -k 9' -else sort_each_field='+0 +1 +2 +3 +4 +5 +6 +7 +8' -fi - -srcdirs=`cd $tsrcdir && find . -type d -print | sed 's~^\.[/]*~~'` - -# the "" is a trick to get $tsrcdir itself without resorting to '.' -for ldir in "" $srcdirs; do - - srcdir=$tsrcdir/$ldir - dstdir=$tdstdir/$ldir - - # Loop over every RCS file in srcdir - # - for vfile in $srcdir/*,v; do - # get rid of the ",v" at the end of the name - file=`echo $vfile | sed -e 's/,v$//'` - bfile=`basename $file` - - if [ ! -d $dstdir ]; then - echo "making locally added directory $dstdir" - mkdir -p $dstdir - fi - if [ ! -f $dstdir/$bfile,v ]; then - echo "copying locally added file $dstdir/$bfile ..." - cp $vfile $dstdir - continue; - fi - - # work on each rev of that file in ascending order - rlog $file | grep "^revision [0-9][0-9]*\." | awk '{print $2}' | sed -e 's/\./ /g' | sort -n -u $sort_each_field | sed -e 's/ /./g' > $revfile - - for rev in `cat $revfile`; do - - case "$rev" in - 1.1) - newdate=`rlog -r$rev $file | grep "^date: " | awk '{printf("%s.%s\n",$2,$3); exit}' | sed -e 's~/~.~g' -e 's/:/./g' -e 's/;//' -e 's/^19//'` - olddate=`rlog -r1.1.1.1 $dstdir/$bfile | grep "^date: " | awk '{printf("%s.%s\n",$2,$3); exit}' | sed -e 's~/~.~g' -e 's/:/./g' -e 's/;//' -e 's/^19//'` - sed "s/$olddate/$newdate/" < $dstdir/$bfile,v > $dstdir/$bfile.x - mv -f $dstdir/$bfile.x $dstdir/$bfile,v - chmod -w $dstdir/$bfile,v - symname=`rlog -h $file | sed -e '1,/^symbolic names:/d' -e 's/[ ]*//g' | awk -F: '$2 == "'"$rev"'" {printf("-n%s:1.1.1.1\n",$1)}'` - if [ -n "$symname" ]; then - echo "tagging $file with $symname ..." - rcs $symname $dstdir/$bfile,v - if [ $? != 0 ]; then - echo ERROR - rcs $symname $dstdir/$bfile,v - exit 1 - fi - fi - continue # skip first rev.... - ;; - esac - - # get a lock on the destination local branch tip revision - co -r1 -l $dstdir/$bfile - if [ $? != 0 ]; then - echo ERROR - co -r1 -l $dstdir/$bfile - exit 1 - fi - rm -f $dstdir/$bfile - - # get file into current dir and get stats - date=`rlog -r$rev $file | grep "^date: " | awk '{printf("%s %s\n",$2,$3); exit}' | sed -e 's/;//'` - author=`rlog -r$rev $file | grep "^date: " | awk '{print $5; exit}' | sed -e 's/;//'` - - symname=`rlog -h $file | sed -e '1,/^symbolic names:/d' -e 's/[ ]*//g' | awk -F: '$2 == "'"$rev"'" {printf("-n%s\n",$1)}'` - - rlog -r$rev $file | sed -e '/^branches: /d' -e '1,/^date: /d' -e '/^===========/d' | awk '{if ((total += length($0) + 1) < 510) print $0}' > $commentfile - - echo "==> file $file, rev=$rev, date=$date, author=$author $symname" - - co -p -r$rev $file > $bfile - if [ $? != 0 ]; then - echo ERROR - co -p -r$rev $file - exit 1 - fi - - # check file into vendor repository... - ci -f -m"`cat $commentfile`" -d"$date" $symname -w"$author" $bfile $dstdir/$bfile,v - if [ $? != 0 ]; then - echo ERROR - ci -f -m"`cat $commentfile`" -d"$date" $symname -w"$author" $bfile $dstdir/$bfile,v - exit 1 - fi - rm -f $bfile - - # set the default branch to the trunk... - # XXX really only need to do this once.... - rcs -b1 $dstdir/$bfile - if [ $? != 0 ]; then - echo ERROR - rcs -b1 $dstdir/$bfile - exit 1 - fi - done - done -done - -echo cleaning up... -rm -f $commentfile -echo " Conversion Completed Successfully" - -exit 0 diff --git a/contrib/cvs/contrib/cvs_acls.html b/contrib/cvs/contrib/cvs_acls.html deleted file mode 100644 index 6e5722f..0000000 --- a/contrib/cvs/contrib/cvs_acls.html +++ /dev/null @@ -1,459 +0,0 @@ - - - -cvs_acls - - - - - -

- - - - - -
-

-

-

Name

-

cvs_acls - Access Control List for CVS

-

-

-
-

Synopsis

-

In 'commitinfo':

-
-  repository/path/to/restrict $CVSROOT/CVSROOT/cvs_acls [-d][-u $USER][-f <logfile>]
-

where:

-
-  -d  turns on debug information
-  -u  passes the client-side userId to the cvs_acls script
-  -f  specifies an alternate filename for the restrict_log file
-

In 'cvsacl':

-
-  {allow.*,deny.*} [|user,user,... [|repos,repos,... [|branch,branch,...]]]
-

where:

-
-  allow|deny - allow: commits are allowed; deny: prohibited
-  user          - userId to be allowed or restricted
-  repos         - file or directory to be allowed or restricted
-  branch        - branch to be allowed or restricted
-

See below for examples.

-

-

-
-

Licensing

-

cvs_acls - provides access control list functionality for CVS -

-
-
-Copyright (c) 2004 by Peter Connolly <peter.connolly@cnet.com>  
-All rights reserved.
-

This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version.

-

This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details.

-

You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

-

-

-
-

Description

-

This script--cvs_acls--is invoked once for each directory within a -``cvs commit''. The set of files being committed for that directory as -well as the directory itself, are passed to this script. This script -checks its 'cvsacl' file to see if any of the files being committed -are on the 'cvsacl' file's restricted list. If any of the files are -restricted, then the cvs_acls script passes back an exit code of 1 -which disallows the commits for that directory.

-

Messages are returned to the committer indicating the file(s) that -he/she are not allowed to committ. Additionally, a site-specific -set of messages (e.g., contact information) can be included in these -messages.

-

When a commit is prohibited, log messages are written to a restrict_log -file in $CVSROOT/CVSROOT. This default file can be redirected to -another destination.

-

The script is triggered from the 'commitinfo' file in $CVSROOT/CVSROOT/.

-

-

-
-

Enhancements

-

This section lists the bug fixes and enhancements added to cvs_acls -that make up the current cvs_acls.

-

-

-

Fixed Bugs

-

This version attempts to get rid the following bugs from the -original version of cvs_acls:

- -

-

-

Enhancements

- -

-

-

ToDoS

- -

-

-
-

Version Information

-

This is not offered as a fix to the original 'cvs_acls' script since it -differs substantially in goals and methods from the original and there -are probably a significant number of people out there that still require -the original version's functionality.

-

The 'cvsacl' file flags of 'allow' and 'deny' were intentionally -changed to 'allow' and 'deny' because there are enough differences -between the original script's behavior and this one's that we wanted to -make sure that users will rethink their 'cvsacl' file formats before -plugging in this newer script.

-

Please note that there has been very limited cross-platform testing of -this script!!! (We did not have the time or resources to do exhaustive -cross-platform testing.)

-

It was developed and tested under Red Hat Linux 9.0 using PERL 5.8.0. -Additionally, it was built and tested under Red Hat Linux 7.3 using -PERL 5.6.1.

-

$Id: cvs_acls.html,v 1.1.2.2 2005/09/01 13:44:49 dprice Exp $

-

This version is based on the 1.11.13 version of cvs_acls -peter.connolly@cnet.com (Peter Connolly)

-
-  Access control lists for CVS.  dgg@ksr.com (David G. Grubbs)
-  Branch specific controls added by voisine@bytemobile.com (Aaron Voisine)
-

-

-
-

Installation

-

To use this program, do the following four things:

-

0. Install PERL, version 5.6.1 or 5.8.0.

-

1. Admin Setup:

-
-   There are two choices here.
-
-   a) The first option is to use the $ENV{"USER"}, server-side userId
-      (from the third column of your pserver 'passwd' file) as the basis for 
-      your restrictions.  In this case, you will (at a minimum) want to set
-      up a new "cvsadmin" userId and group on the pserver machine.  
-      CVS administrators will then set up their 'passwd' file entries to
-      run either as "cvs" (for regular users) or as "cvsadmin" (for power 
-      users).  Correspondingly, your 'cvsacl' file will only list 'cvs'
-      and 'cvsadmin' as the userIds in the second column.
-
-      Commentary: A potential weakness of this is that the xinetd 
-      cvspserver process will need to run as 'root' in order to switch 
-      between the 'cvs' and the 'cvsadmin' userIds.  Some sysadmins don't
-      like situations like this and may want to chroot the process.
-      Talk to them about this point...
-
-   b) The second option is to use the client-side userId as the basis for
-      your restrictions.  In this case, all the xinetd cvspserver processes 
-      can run as userId 'cvs' and no 'root' userId is required.  If you have
-      a 'passwd' file that lists 'cvs' as the effective run-time userId for
-      all your users, then no changes to this file are needed.  Your 'cvsacl'
-      file will use the individual, client-side userIds in its 2nd column.
-
-      As long as the userIds in pserver's 'passwd' file match those userIds 
-      that your Linux server know about, this approach is ideal if you are 
-      planning to move from pserver to SSH access at some later point in time.
-      Just by switching the CVSROOT var from CVSROOT=:pserver:<userId>... to 
-      CVSROOT=:ext:<userId>..., users can switch over to SSH access without
-      any other administrative changes.  When all users have switched over to
-      SSH, the inherently insecure xinetd cvspserver process can be disabled.
-      [http://ximbiot.com/cvs/manual/cvs-1.11.17/cvs_2.html#SEC32]
-
-      :TODO: The only potential glitch with the SSH approach is the possibility 
-      that each user can have differing umasks that might interfere with one 
-      another, especially during a transition from pserver to SSH.  As noted
-      in the ToDo section, this needs a good strategy and set of tests for that 
-      yet...
-

2. Put two lines, as the *only* non-comment lines, in your commitinfo file:

-
-   ALL $CVSROOT/CVSROOT/commit_prep 
-   ALL $CVSROOT/CVSROOT/cvs_acls [-d][-u $USER ][-f <logfilename>]
-
-   where "-d" turns on debug trace
-         "-u $USER" passes the client-side userId to cvs_acls 
-         "-f <logfilename"> overrides the default filename used to log
-                            restricted commit attempts.
-
-   (These are handled in the processArgs() subroutine.)
-

If you are using client-side userIds to restrict access to your -repository, make sure that they are in this order since the commit_prep -script is required in order to pass the $USER parameter.

-

A final note about the repository matching pattern. The example above -uses ``ALL'' but note that this means that the cvs_acls script will run -for each and every commit in your repository. Obviously, in a large -repository this adds up to a lot of overhead that may not be necesary. -A better strategy is to use a repository pattern that is more specific -to the areas that you wish to secure.

-

3. Install this file as $CVSROOT/CVSROOT/cvs_acls and make it executable.

-

4. Create a file named CVSROOT/cvsacl and optionally add it to - CVSROOT/checkoutlist and check it in. See the CVS manual's - administrative files section about checkoutlist. Typically:

-
-   $ cvs checkout CVSROOT
-   $ cd CVSROOT
-   [ create the cvsacl file, include 'commitinfo' line ]
-   [ add cvsacl to checkoutlist ]
-   $ cvs add cvsacl
-   $ cvs commit -m 'Added cvsacl for use with cvs_acls.' cvsacl checkoutlist
-

Note: The format of the 'cvsacl' file is described in detail immediately -below but here is an important set up point:

-
-   Make sure to include a line like the following:
-
-     deny||CVSROOT/commitinfo CVSROOT/cvsacl
-     allow|cvsadmin|CVSROOT/commitinfo CVSROOT/cvsacl
-
-   that restricts access to commitinfo and cvsacl since this would be one of
-   the easiest "end runs" around this ACL approach. ('commitinfo' has the 
-   line that executes the cvs_acls script and, of course, all the 
-   restrictions are in 'cvsacl'.)
-

5. (Optional) Create a 'restrict_msg' file in the $CVSROOT/CVSROOT directory. - Whenever there is a restricted file or dir message, cvs_acls will look - for this file and, if it exists, print its contents as part of the - commit-denial message. This gives you a chance to print any site-specific - information (e.g., who to call, what procedures to look up,...) whenever - a commit is denied.

-

-

-
-

Format of the cvsacl file

-

The 'cvsacl' file determines whether you may commit files. It contains lines -read from top to bottom, keeping track of whether a given user, repository -and branch combination is ``allowed'' or ``denied.'' The script will assume -``allowed'' on all repository paths until 'allow' and 'deny' rules change -that default.

-

The normal pattern is to specify an 'deny' rule to turn off -access to ALL users, then follow it with a matching 'allow' rule that will -turn on access for a select set of users. In the case of multiple rules for -the same user, repository and branch, the last one takes precedence.

-

Blank lines and lines with only comments are ignored. Any other lines not -beginning with ``allow'' or ``deny'' are logged to the restrict_log file.

-

Lines beginning with ``allow'' or ``deny'' are assumed to be '|'-separated -triples: (All spaces and tabs are ignored in a line.)

-
-  {allow.*,deny.*} [|user,user,... [|repos,repos,... [|branch,branch,...]]]
-
-   1. String starting with "allow" or "deny".
-   2. Optional, comma-separated list of usernames.
-   3. Optional, comma-separated list of repository pathnames.
-      These are pathnames relative to $CVSROOT.  They can be directories or
-      filenames.  A directory name allows or restricts access to all files and
-      directories below it. One line can have either directories or filenames
-      but not both.
-   4. Optional, comma-separated list of branch tags.
-      If not specified, all branches are assumed. Use HEAD to reference the
-      main branch.
-

Example: (Note: No in-line comments.)

-
-   # ----- Make whole repository unavailable.
-   deny
-
-   # ----- Except for user "dgg".
-   allow|dgg
-
-   # ----- Except when "fred" or "john" commit to the 
-   #       module whose repository is "bin/ls"
-   allow|fred, john|bin/ls
-
-   # ----- Except when "ed" commits to the "stable" 
-   #       branch of the "bin/ls" repository
-   allow|ed|/bin/ls|stable
-

-

-
-

Program Logic

-

CVS passes to @ARGV an absolute directory pathname (the repository -appended to your $CVSROOT variable), followed by a list of filenames -within that directory that are to be committed.

-

The script walks through the 'cvsacl' file looking for matches on -the username, repository and branch.

-

A username match is simply the user's name appearing in the second -column of the cvsacl line in a space-or-comma separate list. If -blank, then any user will match.

-

A repository match:

- -

-

-

Pseudocode

-
-     read CVS/Entries file and create branch{file}->{branch} hash table
-   + for each 'allow' and 'deny' line in the 'cvsacl' file:
-   |   user match?   
-   |     - Yes: set $user_match       = 1;
-   |   repository and branch match?
-   |     - Yes: add to %repository_matches;
-   |   did user, repository match?
-   |     - Yes: if 'deny' then 
-   |                add %repository_matches -> %restricted_entries
-   |            if 'allow'   then 
-   |                remove %repository_matches <- %restricted_entries
-   + end for loop
-     any saved restrictions?
-       no:  exit, 
-            set exit code allowing commits and exit
-       yes: report restrictions, 
-            set exit code prohibiting commits and exit
-

-

-

Sanity Check

-
-  1) file allow trumps a dir deny
-     deny||java/lib
-     allow||java/lib/README
-  2) dir allow can undo a file deny
-     deny||java/lib/README
-     allow||java/lib
-  3) file deny trumps a dir allow
-     allow||java/lib
-     deny||java/lib/README
-  4) dir deny trumps a file allow
-     allow||java/lib/README
-     deny||java/lib
-  ... so last match always takes precedence
- - - - diff --git a/contrib/cvs/contrib/cvs_acls.in b/contrib/cvs/contrib/cvs_acls.in deleted file mode 100755 index 8ee8bb3..0000000 --- a/contrib/cvs/contrib/cvs_acls.in +++ /dev/null @@ -1,963 +0,0 @@ -#! @PERL@ -T -# -*-Perl-*- - -# Copyright (C) 1994-2005 The Free Software Foundation, Inc. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -############################################################################### -############################################################################### -############################################################################### -# -# THIS SCRIPT IS PROBABLY BROKEN. REMOVING THE -T SWITCH ON THE #! LINE ABOVE -# WOULD FIX IT, BUT THIS IS INSECURE. WE RECOMMEND FIXING THE ERRORS WHICH THE -# -T SWITCH WILL CAUSE PERL TO REPORT BEFORE RUNNING THIS SCRIPT FROM A CVS -# SERVER TRIGGER. PLEASE SEND PATCHES CONTAINING THE CHANGES YOU FIND -# NECESSARY TO RUN THIS SCRIPT WITH THE TAINT-CHECKING ENABLED BACK TO THE -# <@PACKAGE_BUGREPORT@> MAILING LIST. -# -# For more on general Perl security and taint-checking, please try running the -# `perldoc perlsec' command. -# -############################################################################### -############################################################################### -############################################################################### - -=head1 Name - -cvs_acls - Access Control List for CVS - -=head1 Synopsis - -In 'commitinfo': - - repository/path/to/restrict $CVSROOT/CVSROOT/cvs_acls [-d][-u $USER][-f ] - -where: - - -d turns on debug information - -u passes the client-side userId to the cvs_acls script - -f specifies an alternate filename for the restrict_log file - -In 'cvsacl': - - {allow.*,deny.*} [|user,user,... [|repos,repos,... [|branch,branch,...]]] - -where: - - allow|deny - allow: commits are allowed; deny: prohibited - user - userId to be allowed or restricted - repos - file or directory to be allowed or restricted - branch - branch to be allowed or restricted - -See below for examples. - -=head1 Licensing - -cvs_acls - provides access control list functionality for CVS - -Copyright (c) 2004 by Peter Connolly -All rights reserved. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -=head1 Description - -This script--cvs_acls--is invoked once for each directory within a -"cvs commit". The set of files being committed for that directory as -well as the directory itself, are passed to this script. This script -checks its 'cvsacl' file to see if any of the files being committed -are on the 'cvsacl' file's restricted list. If any of the files are -restricted, then the cvs_acls script passes back an exit code of 1 -which disallows the commits for that directory. - -Messages are returned to the committer indicating the file(s) that -he/she are not allowed to committ. Additionally, a site-specific -set of messages (e.g., contact information) can be included in these -messages. - -When a commit is prohibited, log messages are written to a restrict_log -file in $CVSROOT/CVSROOT. This default file can be redirected to -another destination. - -The script is triggered from the 'commitinfo' file in $CVSROOT/CVSROOT/. - -=head1 Enhancements - -This section lists the bug fixes and enhancements added to cvs_acls -that make up the current cvs_acls. - -=head2 Fixed Bugs - -This version attempts to get rid the following bugs from the -original version of cvs_acls: - -=over 2 - -=item * -Multiple entries on an 'cvsacl' line will be matched individually, -instead of requiring that all commit files *exactly* match all -'cvsacl' entries. Commiting a file not in the 'cvsacl' list would -allow *all* files (including a restricted file) to be committed. - -[IMO, this basically made the original script unuseable for our -situation since any arbitrary combination of committed files could -avoid matching the 'cvsacl's entries.] - -=item * -Handle specific filename restrictions. cvs_acls didn't restrict -individual files specified in 'cvsacl'. - -=item * -Correctly handle multiple, specific filename restrictions - -=item * -Prohibit mix of dirs and files on a single 'cvsacl' line -[To simplify the logic and because this would be normal usage.] - -=item * -Correctly handle a mixture of branch restrictions within one work -directory - -=item * -$CVSROOT existence is checked too late - -=item * -Correctly handle the CVSROOT=:local:/... option (useful for -interactive testing) - -=item * -Replacing shoddy "$universal_off" logic -(Thanks to Karl-Konig Konigsson for pointing this out.) - -=back - -=head2 Enhancements - -=over 2 - -=item * -Checks modules in the 'cvsacl' file for valid files and directories - -=item * -Accurately report restricted entries and their matching patterns - -=item * -Simplified and commented overly complex PERL REGEXPs for readability -and maintainability - -=item * -Skip the rest of processing if a mismatch on portion of the 'cvsacl' line - -=item * -Get rid of opaque "karma" messages in favor of user-friendly messages -that describe which user, file(s) and branch(es) were disallowed. - -=item * -Add optional 'restrict_msg' file for additional, site-specific -restriction messages. - -=item * -Take a "-u" parameter for $USER from commit_prep so that the script -can do restrictions based on the client-side userId rather than the -server-side userId (usually 'cvs'). - -(See discussion below on "Admin Setup" for more on this point.) - -=item * -Added a lot more debug trace - -=item * -Tested these restrictions with concurrent use of pserver and SSH -access to model our transition from pserver to ext access. - -=item * -Added logging of restricted commit attempts. -Restricted commits can be sent to a default file: -$CVSROOT/CVSROOT/restrictlog or to one passed to the script -via the -f command parameter. - -=back - -=head2 ToDoS - -=over 2 - -=item * -Need to deal with pserver/SSH transition with conflicting umasks? - -=item * -Use a CPAN module to handle command parameters. - -=item * -Use a CPAN module to clone data structures. - -=back - -=head1 Version Information - -This is not offered as a fix to the original 'cvs_acls' script since it -differs substantially in goals and methods from the original and there -are probably a significant number of people out there that still require -the original version's functionality. - -The 'cvsacl' file flags of 'allow' and 'deny' were intentionally -changed to 'allow' and 'deny' because there are enough differences -between the original script's behavior and this one's that we wanted to -make sure that users will rethink their 'cvsacl' file formats before -plugging in this newer script. - -Please note that there has been very limited cross-platform testing of -this script!!! (We did not have the time or resources to do exhaustive -cross-platform testing.) - -It was developed and tested under Red Hat Linux 9.0 using PERL 5.8.0. -Additionally, it was built and tested under Red Hat Linux 7.3 using -PERL 5.6.1. - -$Id: cvs_acls.in,v 1.4.4.6 2005/09/01 13:44:49 dprice Exp $ - -This version is based on the 1.11.13 version of cvs_acls -peter.connolly@cnet.com (Peter Connolly) - - Access control lists for CVS. dgg@ksr.com (David G. Grubbs) - Branch specific controls added by voisine@bytemobile.com (Aaron Voisine) - -=head1 Installation - -To use this program, do the following four things: - -0. Install PERL, version 5.6.1 or 5.8.0. - -1. Admin Setup: - - There are two choices here. - - a) The first option is to use the $ENV{"USER"}, server-side userId - (from the third column of your pserver 'passwd' file) as the basis for - your restrictions. In this case, you will (at a minimum) want to set - up a new "cvsadmin" userId and group on the pserver machine. - CVS administrators will then set up their 'passwd' file entries to - run either as "cvs" (for regular users) or as "cvsadmin" (for power - users). Correspondingly, your 'cvsacl' file will only list 'cvs' - and 'cvsadmin' as the userIds in the second column. - - Commentary: A potential weakness of this is that the xinetd - cvspserver process will need to run as 'root' in order to switch - between the 'cvs' and the 'cvsadmin' userIds. Some sysadmins don't - like situations like this and may want to chroot the process. - Talk to them about this point... - - b) The second option is to use the client-side userId as the basis for - your restrictions. In this case, all the xinetd cvspserver processes - can run as userId 'cvs' and no 'root' userId is required. If you have - a 'passwd' file that lists 'cvs' as the effective run-time userId for - all your users, then no changes to this file are needed. Your 'cvsacl' - file will use the individual, client-side userIds in its 2nd column. - - As long as the userIds in pserver's 'passwd' file match those userIds - that your Linux server know about, this approach is ideal if you are - planning to move from pserver to SSH access at some later point in time. - Just by switching the CVSROOT var from CVSROOT=:pserver:... to - CVSROOT=:ext:..., users can switch over to SSH access without - any other administrative changes. When all users have switched over to - SSH, the inherently insecure xinetd cvspserver process can be disabled. - [http://ximbiot.com/cvs/manual/cvs-1.11.17/cvs_2.html#SEC32] - - :TODO: The only potential glitch with the SSH approach is the possibility - that each user can have differing umasks that might interfere with one - another, especially during a transition from pserver to SSH. As noted - in the ToDo section, this needs a good strategy and set of tests for that - yet... - -2. Put two lines, as the *only* non-comment lines, in your commitinfo file: - - ALL $CVSROOT/CVSROOT/commit_prep - ALL $CVSROOT/CVSROOT/cvs_acls [-d][-u $USER ][-f ] - - where "-d" turns on debug trace - "-u $USER" passes the client-side userId to cvs_acls - "-f overrides the default filename used to log - restricted commit attempts. - - (These are handled in the processArgs() subroutine.) - -If you are using client-side userIds to restrict access to your -repository, make sure that they are in this order since the commit_prep -script is required in order to pass the $USER parameter. - -A final note about the repository matching pattern. The example above -uses "ALL" but note that this means that the cvs_acls script will run -for each and every commit in your repository. Obviously, in a large -repository this adds up to a lot of overhead that may not be necesary. -A better strategy is to use a repository pattern that is more specific -to the areas that you wish to secure. - -3. Install this file as $CVSROOT/CVSROOT/cvs_acls and make it executable. - -4. Create a file named CVSROOT/cvsacl and optionally add it to - CVSROOT/checkoutlist and check it in. See the CVS manual's - administrative files section about checkoutlist. Typically: - - $ cvs checkout CVSROOT - $ cd CVSROOT - [ create the cvsacl file, include 'commitinfo' line ] - [ add cvsacl to checkoutlist ] - $ cvs add cvsacl - $ cvs commit -m 'Added cvsacl for use with cvs_acls.' cvsacl checkoutlist - -Note: The format of the 'cvsacl' file is described in detail immediately -below but here is an important set up point: - - Make sure to include a line like the following: - - deny||CVSROOT/commitinfo CVSROOT/cvsacl - allow|cvsadmin|CVSROOT/commitinfo CVSROOT/cvsacl - - that restricts access to commitinfo and cvsacl since this would be one of - the easiest "end runs" around this ACL approach. ('commitinfo' has the - line that executes the cvs_acls script and, of course, all the - restrictions are in 'cvsacl'.) - -5. (Optional) Create a 'restrict_msg' file in the $CVSROOT/CVSROOT directory. - Whenever there is a restricted file or dir message, cvs_acls will look - for this file and, if it exists, print its contents as part of the - commit-denial message. This gives you a chance to print any site-specific - information (e.g., who to call, what procedures to look up,...) whenever - a commit is denied. - -=head1 Format of the cvsacl file - -The 'cvsacl' file determines whether you may commit files. It contains lines -read from top to bottom, keeping track of whether a given user, repository -and branch combination is "allowed" or "denied." The script will assume -"allowed" on all repository paths until 'allow' and 'deny' rules change -that default. - -The normal pattern is to specify an 'deny' rule to turn off -access to ALL users, then follow it with a matching 'allow' rule that will -turn on access for a select set of users. In the case of multiple rules for -the same user, repository and branch, the last one takes precedence. - -Blank lines and lines with only comments are ignored. Any other lines not -beginning with "allow" or "deny" are logged to the restrict_log file. - -Lines beginning with "allow" or "deny" are assumed to be '|'-separated -triples: (All spaces and tabs are ignored in a line.) - - {allow.*,deny.*} [|user,user,... [|repos,repos,... [|branch,branch,...]]] - - 1. String starting with "allow" or "deny". - 2. Optional, comma-separated list of usernames. - 3. Optional, comma-separated list of repository pathnames. - These are pathnames relative to $CVSROOT. They can be directories or - filenames. A directory name allows or restricts access to all files and - directories below it. One line can have either directories or filenames - but not both. - 4. Optional, comma-separated list of branch tags. - If not specified, all branches are assumed. Use HEAD to reference the - main branch. - -Example: (Note: No in-line comments.) - - # ----- Make whole repository unavailable. - deny - - # ----- Except for user "dgg". - allow|dgg - - # ----- Except when "fred" or "john" commit to the - # module whose repository is "bin/ls" - allow|fred, john|bin/ls - - # ----- Except when "ed" commits to the "stable" - # branch of the "bin/ls" repository - allow|ed|/bin/ls|stable - -=head1 Program Logic - -CVS passes to @ARGV an absolute directory pathname (the repository -appended to your $CVSROOT variable), followed by a list of filenames -within that directory that are to be committed. - -The script walks through the 'cvsacl' file looking for matches on -the username, repository and branch. - -A username match is simply the user's name appearing in the second -column of the cvsacl line in a space-or-comma separate list. If -blank, then any user will match. - -A repository match: - -=over 2 - -=item * -Each entry in the modules section of the current 'cvsacl' line is -examined to see if it is a dir or a file. The line must have -either files or dirs, but not both. (To simplify the logic.) - -=item * -If neither, then assume the 'cvsacl' file was set up in error and -skip that 'allow' line. - -=item * -If a dir, then each dir pattern is matched separately against the -beginning of each of the committed files in @ARGV. - -=item * -If a file, then each file pattern is matched exactly against each -of the files to be committed in @ARGV. - -=item * -Repository and branch must BOTH match together. This is to cover -the use case where a user has multiple branches checked out in -a single work directory. Commit files can be from different -branches. - -A branch match is either: - -=over 4 - -=item * -When no branches are listed in the fourth column. ("Match any.") - -=item * -All elements from the fourth column are matched against each of -the tag names for $ARGV[1..$#ARGV] found in the %branches file. - -=back - -=item * -'allow' match remove that match from the tally map. - -=item * -Restricted ('deny') matches are saved in the %repository_matches -table. - -=item * -If there is a match on user, repository and branch: - - If repository, branch and user match - if 'deny' - add %repository_matches entries to %restricted_entries - else if 'allow' - remove %repository_matches entries from %restricted_entries - -=item * -At the end of all the 'cvsacl' line checks, check to see if there -are any entries in the %restricted_entries. If so, then deny the -commit. - -=back - -=head2 Pseudocode - - read CVS/Entries file and create branch{file}->{branch} hash table - + for each 'allow' and 'deny' line in the 'cvsacl' file: - | user match? - | - Yes: set $user_match = 1; - | repository and branch match? - | - Yes: add to %repository_matches; - | did user, repository match? - | - Yes: if 'deny' then - | add %repository_matches -> %restricted_entries - | if 'allow' then - | remove %repository_matches <- %restricted_entries - + end for loop - any saved restrictions? - no: exit, - set exit code allowing commits and exit - yes: report restrictions, - set exit code prohibiting commits and exit - -=head2 Sanity Check - - 1) file allow trumps a dir deny - deny||java/lib - allow||java/lib/README - 2) dir allow can undo a file deny - deny||java/lib/README - allow||java/lib - 3) file deny trumps a dir allow - allow||java/lib - deny||java/lib/README - 4) dir deny trumps a file allow - allow||java/lib/README - deny||java/lib - ... so last match always takes precedence - -=cut - -$debug = 0; # Set to 1 for debug messages - -%repository_matches = (); # hash of match file and pattern from 'cvsacl' - # repository_matches --> [branch, matching-pattern] - # (Used during module/branch matching loop) - -%restricted_entries = (); # hash table of restricted commit files (from @ARGV) - # restricted_entries --> branch - # (If user/module/branch all match on an 'deny' - # line, then entries added to this map.) - -%branch; # hash table of key: commit file; value: branch - # Built from ".../CVS/Entries" file of directory - # currently being examined - -# ---------------------------------------------------------------- get CVSROOT -$cvsroot = $ENV{'CVSROOT'}; -die "Must set CVSROOT\n" if !$cvsroot; -if ($cvsroot =~ /:([\/\w]*)$/) { # Filter ":pserver:", ":local:"-type prefixes - $cvsroot = $1; -} - -# ------------------------------------------------------------- set file paths -$entries = "CVS/Entries"; # client-side file??? -$cvsaclfile = $cvsroot . "/CVSROOT/cvsacl"; -$restrictfile = $cvsroot . "/CVSROOT/restrict_msg"; -$restrictlog = $cvsroot . "/CVSROOT/restrict_log"; - -# --------------------------------------------------------------- process args -$user_name = processArgs(\@ARGV); - -print("$$ \@ARGV after processArgs is: @ARGV.\n") if $debug; -print("$$ ========== Begin $PROGRAM_NAME for \"$ARGV[0]\" repository. ========== \n") if $debug; - -# --------------------------------------------------------------- filter @ARGV -eval "print STDERR \$die='Unknown parameter $1\n' if !defined \$$1; \$$1=\$';" - while ($ARGV[0] =~ /^(\w+)=/ && shift(@ARGV)); -exit 255 if $die; # process any variable=value switches - -print("$$ \@ARGV after shift processing contains:",join("\, ",@ARGV),".\n") if $debug; - -# ---------------------------------------------------------------- get cvsroot -($repository = shift) =~ s:^$cvsroot/::; -grep($_ = $repository . '/' . $_, @ARGV); - -print("$$ \$cvsroot is: $cvsroot.\n") if $debug; -print "$$ Repos: $repository\n","$$ ==== ",join("\n$$ ==== ",@ARGV),"\n" if $debug; - -$exit_val = 0; # presume good exit value for commit - -# ---------------------------------------------------------------------------- -# ---------------------------------- create hash table $branch{file -> branch} -# ---------------------------------------------------------------------------- - -# Here's a typical Entries file: -# -# /checkoutlist/1.4/Wed Feb 4 23:51:23 2004// -# /cvsacl/1.3/Tue Feb 24 23:05:43 2004// -# ... -# /verifymsg/1.1/Fri Mar 16 19:56:24 2001// -# D/backup//// -# D/temp//// - -open(ENTRIES, $entries) || die("Cannot open $entries.\n"); -print("$$ File / Branch\n") if $debug; -my $i = 0; -while() { - chop; - next if /^\s*$/; # Skip blank lines - $i = $i + 1; - if (m| - / # 1st slash - ([\w.-]*) # file name -> $1 - / # 2nd slash - .* # revision number - / # 3rd slash - .* # date and time - / # 4th slash - .* # keyword - / # 5th slash - T? # 'T' constant - (\w*) # branch -> #2 - |x) { - $branch{$repository . '/' . $1} = ($2) ? $2 : "HEAD"; - print "$$ CVS Entry $i: $1/$2\n" if $debug; - } -} -close(ENTRIES); - -# ---------------------------------------------------------------------------- -# ------------------------------------- evaluate each active line from 'cvsacl' -# ---------------------------------------------------------------------------- -open (CVSACL, $cvsaclfile) || exit(0); # It is ok for cvsacl file not to exist -while () { - chop; - next if /^\s*\#/; # skip comments - next if /^\s*$/; # skip blank lines - # --------------------------------------------- parse current 'cvsacl' line - print("$$ ==========\n$$ Processing \'cvsacl\' line: $_.\n") if $debug; - ($cvsacl_flag, $cvsacl_userIds, $cvsacl_modules, $cvsacl_branches) = split(/[\s,]*\|[\s,]*/, $_); - - # ------------------------------ Validate 'allow' or 'deny' line prefix - if ($cvsacl_flag !~ /^allow/ && $cvsacl_flag !~ /^deny/) { - print ("Bad cvsacl line: $_\n") if $debug; - $log_text = sprintf "Bad cvsacl line: %s", $_; - write_restrictlog_record($log_text); - next; - } - - # -------------------------------------------------- init loop match flags - $user_match = 0; - %repository_matches = (); - - # ------------------------------------------------------------------------ - # ---------------------------------------------------------- user matching - # ------------------------------------------------------------------------ - # $user_name considered "in user list" if actually in list or is NULL - $user_match = (!$cvsacl_userIds || grep ($_ eq $user_name, split(/[\s,]+/,$cvsacl_userIds))); - print "$$ \$user_name: $user_name \$user_match match flag is: $user_match.\n" if $debug; - if (!$user_match) { - next; # no match, skip to next 'cvsacl' line - } - - # ------------------------------------------------------------------------ - # ---------------------------------------------------- repository matching - # ------------------------------------------------------------------------ - if (!$cvsacl_modules) { # blank module list = all modules - if (!$cvsacl_branches) { # blank branch list = all branches - print("$$ Adding all modules to \%repository_matches; null " . - "\$cvsacl_modules and \$cvsacl_branches.\n") if $debug; - for $commit_object (@ARGV) { - $repository_matches{$commit_object} = [$branch{$commit_object}, $cvsacl_modules]; - print("$$ \$repository_matches{$commit_object} = " . - "[$branch{$commit_object}, $cvsacl_modules].\n") if $debug; - } - } - else { # need to check for repository match - @branch_list = split (/[\s,]+/,$cvsacl_branches); - print("$$ Branches from \'cvsacl\' record: ", join(", ",@branch_list),".\n") if $debug; - for $commit_object (@ARGV) { - if (grep($branch{$commit_object}, @branch_list)) { - $repository_matches{$commit_object} = [$branch{$commit_object}, $cvsacl_modules]; - print("$$ \$repository_matches{$commit_object} = " . - "[$branch{$commit_object}, $cvsacl_modules].\n") if $debug; - } - } - } - } - else { - # ----------------------------------- check every argument combination - # parse 'cvsacl' modules to array - my @module_list = split(/[\s,]+/,$cvsacl_modules); - # ------------- Check all modules in list for either file or directory - my $fileType = ""; - if (($fileType = checkFileness(@module_list)) eq "") { - next; # skip bad file types - } - # ---------- Check each combination of 'cvsacl' modules vs. @ARGV files - print("$$ Checking matches for \@module_list: ", join("\, ",@module_list), ".\n") if $debug; - # loop thru all command-line commit objects - for $commit_object (@ARGV) { - # loop thru all modules on 'cvsacl' line - for $cvsacl_module (@module_list) { - print("$$ Is \'cvsacl\': $cvsacl_modules pattern in: \@ARGV " . - "\$commit_object: $commit_object?\n") if $debug; - # Do match of beginning of $commit_object - checkModuleMatch($fileType, $commit_object, $cvsacl_module); - } # end for commit objects - } # end for cvsacl modules - } # end if - - print("$$ Matches for: \%repository_matches: ", join("\, ", (keys %repository_matches)), ".\n") if $debug; - - # ------------------------------------------------------------------------ - # ----------------------------------------------------- setting exit value - # ------------------------------------------------------------------------ - if ($user_match && %repository_matches) { - print("$$ An \"$cvsacl_flag\" match on User(s): $cvsacl_userIds; Module(s):" . - " $cvsacl_modules; Branch(es): $cvsacl_branches.\n") if $debug; - if ($cvsacl_flag eq "deny") { - # Add all matches to the hash of restricted modules - foreach $commitFile (keys %repository_matches) { - print("$$ Adding \%repository_matches entry: $commitFile.\n") if $debug; - $restricted_entries{$commitFile} = $repository_matches{$commitFile}[0]; - } - } - else { - # Remove all matches from the restricted modules hash - foreach $commitFile (keys %repository_matches) { - print("$$ Removing \%repository_matches entry: $commitFile.\n") if $debug; - delete $restricted_entries{$commitFile}; - } - } - } - print "$$ ==== End of processing for \'cvsacl\' line: $_.\n" if $debug; -} -close(CVSACL); - -# ---------------------------------------------------------------------------- -# --------------------------------------- determine final 'commit' disposition -# ---------------------------------------------------------------------------- -if (%restricted_entries) { # any restricted entries? - $exit_val = 1; # don't commit - print("**** Access denied: Insufficient authority for user: '$user_name\' " . - "to commit to \'$repository\'.\n**** Contact CVS Administrators if " . - "you require update access to these directories or files.\n"); - print("**** file(s)/dir(s) restricted were:\n\t", join("\n\t",keys %restricted_entries), "\n"); - printOptionalRestrictionMessage(); - write_restrictlog(); -} -elsif (!$exit_val && $debug) { - print "**** Access allowed: Sufficient authority for commit.\n"; -} - -print "$$ ==== \$exit_val = $exit_val\n" if $debug; -exit($exit_val); - -# ---------------------------------------------------------------------------- -# -------------------------------------------------------------- end of "main" -# ---------------------------------------------------------------------------- - - -# ---------------------------------------------------------------------------- -# -------------------------------------------------------- process script args -# ---------------------------------------------------------------------------- -sub processArgs { - -# This subroutine is passed a reference to @ARGV. - -# If @ARGV contains a "-u" entry, use that as the effective userId. In this -# case, the userId is the client-side userId that has been passed to this -# script by the commit_prep script. (This is why the commit_prep script must -# be placed *before* the cvs_acls script in the commitinfo admin file.) - -# Otherwise, pull the userId from the server-side environment. - - my $userId = ""; - my ($argv) = shift; # pick up ref to @ARGV - my @argvClone = (); # immutable copy for foreach loop - for ($i=0; $i<(scalar @{$argv}); $i++) { - $argvClone[$i]=$argv->[$i]; - } - - print("$$ \@_ to processArgs is: @_.\n") if $debug; - - # Parse command line arguments (file list is seen as one arg) - foreach $arg (@argvClone) { - print("$$ \$arg for processArgs loop is: $arg.\n") if $debug; - # Set $debug flag? - if ($arg eq '-d') { - shift @ARGV; - $debug = 1; - print("$$ \$debug flag set on.\n") if $debug; - print STDERR "Debug turned on...\n"; - } - # Passing in a client-side userId? - elsif ($arg eq '-u') { - shift @ARGV; - $userId = shift @ARGV; - print("$$ client-side \$userId set to: $userId.\n") if $debug; - } - # An override for the default restrictlog file? - elsif ($arg eq '-f') { - shift @ARGV; - $restrictlog = shift @ARGV; - } - else { - next; - } - } - - # No client-side userId passed? then get from server env - if (!$userId) { - $userId = $ENV{"USER"} if !($userId = $ENV{"LOGNAME"}); - print("$$ server-side \$userId set to: $userId.\n") if $debug; - } - - print("$$ processArgs returning \$userId: $userId.\n") if $debug; - return $userId; - -} - - -# ---------------------------------------------------------------------------- -# --------------------- Check all modules in list for either file or directory -# ---------------------------------------------------------------------------- -sub checkFileness { - -# Module patterns on the 'cvsacl' record can be files or directories. -# If it's a directory, we pattern-match the directory name from 'cvsacl' -# against the left side of the committed filename to see if the file is in -# that hierarchy. By contrast, files use an explicit match. If the entries -# are neither files nor directories, then the cvsacl file has been set up -# incorrectly; we return a "" and the caller skips that line as invalid. -# -# This function determines whether the entries on the 'cvsacl' record are all -# directories or all files; it cannot be a mixture. This restriction put in -# to simplify the logic (without taking away much functionality). - - my @module_list = @_; - print("$$ Checking \"fileness\" or \"dir-ness\" for \@module_list entries.\n") if $debug; - print("$$ Entries are: ", join("\, ",@module_list), ".\n") if $debug; - my $filetype = ""; - for $cvsacl_module (@module_list) { - my $reposDirName = $cvsroot . '/' . $cvsacl_module; - my $reposFileName = $reposDirName . "\,v"; - print("$$ In checkFileness: \$reposDirName: $reposDirName; \$reposFileName: $reposFileName.\n") if $debug; - if (((-d $reposDirName) && ($filetype eq "file")) || ((-f $reposFileName) && ($filetype eq "dir"))) { - print("Can\'t mix files and directories on single \'cvsacl\' file record; skipping entry.\n"); - print(" Please contact a CVS administrator.\n"); - $filetype = ""; - last; - } - elsif (-d $reposDirName) { - $filetype = "dir"; - print("$$ $reposDirName is a directory.\n") if $debug; - } - elsif (-f $reposFileName) { - $filetype = "file"; - print("$$ $reposFileName is a regular file.\n") if $debug; - } - else { - print("***** Item to commit was neither a regular file nor a directory.\n"); - print("***** Current \'cvsacl\' line ignored.\n"); - print("***** Possible problem with \'cvsacl\' admin file. Please contact a CVS administrator.\n"); - $filetype = ""; - $text = sprintf("Module entry on cvsacl line: %s is not a valid file or directory.\n", $cvsacl_module); - write_restrictlog_record($text); - last; - } # end if - } # end for - - print("$$ checkFileness will return \$filetype: $filetype.\n") if $debug; - return $filetype; -} - - -# ---------------------------------------------------------------------------- -# ----------------------------------------------------- check for module match -# ---------------------------------------------------------------------------- -sub checkModuleMatch { - -# This subroutine checks for a match between the directory or file pattern -# specified in the 'cvsacl' file (i.e., $cvsacl_modules) versus the commit file -# objects passed into the script via @ARGV (i.e., $commit_object). - -# The directory pattern only has to match the beginning portion of the commit -# file's name for a match since all files under that directory are considered -# a match. File patterns must exactly match. - -# Since (theoretically, if not normally in practice) a working directory can -# contain a mixture of files from different branches, this routine checks to -# see if there is also a match on branch before considering the file -# comparison a match. - - my $match_flag = ""; - - print("$$ \@_ in checkModuleMatch is: @_.\n") if $debug; - my ($type,$commit_object,$cvsacl_module) = @_; - - if ($type eq "file") { # Do exact file match of $commit_object - if ($commit_object eq $cvsacl_module) { - $match_flag = "file"; - } # Do dir match at beginning of $commit_object - } - elsif ($commit_object =~ /^$cvsacl_module\//) { - $match_flag = "dir"; - } - - if ($match_flag) { - print("$$ \$repository: $repository matches \$commit_object: $commit_object.\n") if $debug; - if (!$cvsacl_branches) { # empty branch pattern matches all - print("$$ blank \'cvsacl\' branch matches all commit files.\n") if $debug; - $repository_matches{$commit_object} = [$branch{$commit_object}, $cvsacl_module]; - print("$$ \$repository_matches{$commit_object} = [$branch{$commit_object}, $cvsacl_module].\n") if $debug; - } - else { # otherwise check branch hash table - @branch_list = split (/[\s,]+/,$cvsacl_branches); - print("$$ Branches from \'cvsacl\' record: ", join(", ",@branch_list),".\n") if $debug; - if (grep(/$branch{$commit_object}/, @branch_list)) { - $repository_matches{$commit_object} = [$branch{$commit_object}, $cvsacl_module]; - print("$$ \$repository_matches{$commit_object} = [$branch{$commit_object}, " . - "$cvsacl_module].\n") if $debug; - } - } - } - -} - -# ---------------------------------------------------------------------------- -# ------------------------------------------------------- check for file match -# ---------------------------------------------------------------------------- -sub printOptionalRestrictionMessage { - -# This subroutine optionally prints site-specific file restriction information -# whenever a restriction condition is met. If the file 'restrict_msg' does -# not exist, the routine immediately exits. If there is a 'restrict_msg' file -# then all the contents are printed at the end of the standard restriction -# message. - -# As seen from examining the definition of $restrictfile, the default filename -# is: $CVSROOT/CVSROOT/restrict_msg. - - open (RESTRICT, $restrictfile) || return; # It is ok for cvsacl file not to exist - while () { - chop; - # print out each line - print("**** $_\n"); - } - -} - -# ---------------------------------------------------------------------------- -# ---------------------------------------------------------- write log message -# ---------------------------------------------------------------------------- -sub write_restrictlog { - -# This subroutine iterates through the list of restricted entries and logs -# each one to the error logfile. - - # write each line in @text out separately - foreach $commitfile (keys %restricted_entries) { - $log_text = sprintf "Commit attempt by: %s for: %s on branch: %s", - $user_name, $commitfile, $branch{$commitfile}; - write_restrictlog_record($log_text); - } - -} - -# ---------------------------------------------------------------------------- -# ---------------------------------------------------------- write log message -# ---------------------------------------------------------------------------- -sub write_restrictlog_record { - -# This subroutine receives a scalar string and writes it out to the -# $restrictlog file as a separate line. Each line is prepended with the date -# and time in the format: "2004/01/30 12:00:00 ". - - $text = shift; - - # return quietly if there is a problem opening the log file. - open(FILE, ">>$restrictlog") || return; - - (@time) = localtime(); - - # write each line in @text out separately - $log_record = sprintf "%04d/%02d/%02d %02d:%02d:%02d %s.\n", - $time[5]+1900, $time[4]+1, $time[3], $time[2], $time[1], $time[0], $text; - print FILE $log_record; - print("$$ restrict_log record being written: $log_record to $restrictlog.\n") if $debug; - - close(FILE); -} diff --git a/contrib/cvs/contrib/cvscheck.man b/contrib/cvs/contrib/cvscheck.man deleted file mode 100644 index 2b90b49..0000000 --- a/contrib/cvs/contrib/cvscheck.man +++ /dev/null @@ -1,52 +0,0 @@ -.\" Contributed by Lowell Skoog -.TH CVSCHECK LOCAL "4 March 1991" FLUKE -.SH NAME -cvscheck \- identify files added, changed, or removed in a CVS working -directory -.SH SYNOPSIS -.B cvscheck -.SH DESCRIPTION -This command is a housekeeping aid. It should be run in a working -directory that has been checked out using CVS. It identifies files -that have been added, changed, or removed in the working directory, but -not CVS -.BR commit ted. -It also determines whether the files have been CVS -.BR add ed -or CVS -.BR remove d. -For directories, this command determines only whether they have been -.BR add ed. -It operates in the current directory only. -.LP -This command provides information that is available using CVS -.B status -and CVS -.BR diff . -The advantage of -.B cvscheck -is that its output is very concise. It saves you the strain (and -potential error) of interpreting the output of CVS -.B status -and -.BR diff . -.LP -See -.BR cvs (local) -or -.BR cvshelp (local) -for instructions on how to add or remove a file or directory in a -CVS-controlled package. -.SH DIAGNOSTICS -The exit status is 0 if no files have been added, changed, or removed -from the current directory. Otherwise, the command returns a count of -the adds, changes, and deletes. -.SH SEE ALSO -.BR cvs (local), -.BR cvshelp (local) -.SH AUTHOR -Lowell Skoog -.br -Software Technology Group -.br -Technical Computing diff --git a/contrib/cvs/contrib/cvscheck.sh b/contrib/cvs/contrib/cvscheck.sh deleted file mode 100644 index b3da696..0000000 --- a/contrib/cvs/contrib/cvscheck.sh +++ /dev/null @@ -1,95 +0,0 @@ -#! /bin/sh -# -# Copyright (C) 1995-2005 The Free Software Foundation, Inc. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# cvscheck - identify files added, changed, or removed -# in CVS working directory -# -# Contributed by Lowell Skoog -# -# This program should be run in a working directory that has been -# checked out using CVS. It identifies files that have been added, -# changed, or removed in the working directory, but not "cvs -# committed". It also determines whether the files have been "cvs -# added" or "cvs removed". For directories, it is only practical to -# determine whether they have been added. - -name=cvscheck -changes=0 - -# If we can't run CVS commands in this directory -cvs status . > /dev/null 2>&1 -if [ $? != 0 ] ; then - - # Bail out - echo "$name: there is no version here; bailing out" 1>&2 - exit 1 -fi - -# Identify files added to working directory -for file in .* * ; do - - # Skip '.' and '..' - if [ $file = '.' -o $file = '..' ] ; then - continue - fi - - # If a regular file - if [ -f $file ] ; then - if cvs status $file | grep -s '^From:[ ]*New file' ; then - echo "file added: $file - not CVS committed" - changes=`expr $changes + 1` - elif cvs status $file | grep -s '^From:[ ]*no entry for' ; then - echo "file added: $file - not CVS added, not CVS committed" - changes=`expr $changes + 1` - fi - - # Else if a directory - elif [ -d $file -a $file != CVS.adm ] ; then - - # Move into it - cd $file - - # If CVS commands don't work inside - cvs status . > /dev/null 2>&1 - if [ $? != 0 ] ; then - echo "directory added: $file - not CVS added" - changes=`expr $changes + 1` - fi - - # Move back up - cd .. - fi -done - -# Identify changed files -changedfiles=`cvs diff | egrep '^diff' | awk '{print $3}'` -for file in $changedfiles ; do - echo "file changed: $file - not CVS committed" - changes=`expr $changes + 1` -done - -# Identify files removed from working directory -removedfiles=`cvs status | egrep '^File:[ ]*no file' | awk '{print $4}'` - -# Determine whether each file has been cvs removed -for file in $removedfiles ; do - if cvs status $file | grep -s '^From:[ ]*-' ; then - echo "file removed: $file - not CVS committed" - else - echo "file removed: $file - not CVS removed, not CVS committed" - fi - changes=`expr $changes + 1` -done - -exit $changes diff --git a/contrib/cvs/contrib/cvshelp.man b/contrib/cvs/contrib/cvshelp.man deleted file mode 100644 index b166af6..0000000 --- a/contrib/cvs/contrib/cvshelp.man +++ /dev/null @@ -1,561 +0,0 @@ -.\" Contributed by Lowell Skoog -.\" Full space in nroff; half space in troff -.de SP -.if n .sp -.if t .sp .5 -.. -.\" Start a command example -.de XS -.SP -.in +.5i -.ft B -.nf -.. -.\" End a command example -.de XE -.fi -.ft P -.in -.5i -.SP -.. -.TH CVSHELP LOCAL "17 March 1991" FLUKE -.SH NAME -cvshelp \- advice on using the Concurrent Versions System -.SH DESCRIPTION -This man page is based on experience using CVS. -It is bound to change as we gain more experience. -If you come up with better advice than is found here, -contact the Software Technology -Group and we will add it to this page. -.SS "Getting Started" -Use the following steps to prepare to use CVS: -.TP -\(bu -Take a look at the CVS manual page to see what it can do for you, and -if it fits your environment (or can possibly be made to fit your -environment). -.XS -man cvs -.XE -If things look good, continue on... -.TP -\(bu -Setup the master source repository. Choose a directory with -ample disk space available for source files. This is where the RCS -`,v' files will be stored. Say you choose -.B /src/master -as the root -of your source repository. Make the -.SB CVSROOT.adm -directory in the root of the source repository: -.XS -mkdir /src/master/CVSROOT.adm -.XE -.TP -\(bu -Populate this directory with the -.I loginfo -and -.I modules -files from the -.B "/usr/doc/local/cvs" -directory. Edit these files to reflect your local source repository -environment \- they may be quite small initially, but will grow as -sources are added to your source repository. Turn these files into -RCS controlled files: -.XS -cd /src/master/CVSROOT.adm -ci \-m'Initial loginfo file' loginfo -ci \-m'Initial modules file' modules -.XE -.TP -\(bu -Run the command: -.XS -mkmodules /src/master/CVSROOT.adm -.XE -This will build the -.BR ndbm (3) -file for the modules database. -.TP -\(bu -Remember to edit the -.I modules -file manually when sources are checked -in with -.B checkin -or CVS -.BR add . -A copy of the -.I modules -file for editing can be retrieved with the command: -.XS -cvs checkout CVSROOT.adm -.XE -.TP -\(bu -Have all users of the CVS system set the -.SM CVSROOT -environment variable appropriately to reflect the placement of your -source repository. If the above example is used, the following -commands can be placed in a -.I .login -or -.I .profile -file: -.XS -setenv CVSROOT /src/master -.XE -for csh users, and -.XS -CVSROOT=/src/master; export CVSROOT -.XE -for sh users. -.SS "Placing Locally Written Sources Under CVS Control" -Say you want to place the `whizbang' sources under -CVS control. Say further that the sources have never -been under revision control before. -.TP -\(bu -Move the source hierarchy (lock, stock, and barrel) -into the master source repository: -.XS -mv ~/whizbang $CVSROOT -.XE -.TP -\(bu -Clean out unwanted object files: -.XS -cd $CVSROOT/whizbang -make clean -.XE -.TP -\(bu -Turn every file in the hierarchy into an RCS controlled file: -.XS -descend \-f 'ci \-t/dev/null \-m"Placed under CVS control" \-nV\fR\fIx\fR\fB_\fR\fIy\fR\fB *' -.XE -In this example, the initial release tag is \fBV\fIx\fB_\fIy\fR, -representing version \fIx\fR.\fIy\fR. -.LP -You can use CVS on sources that are already under RCS control. -The following example shows how. -In this example, the source package is called `skunkworks'. -.TP -\(bu -Move the source hierarchy into the master source -repository: -.XS -mv ~/skunkworks $CVSROOT -.XE -.TP -\(bu -Clean out unwanted object files: -.XS -cd $CVSROOT/skunkworks -make clean -.XE -.TP -\(bu -Clean out unwanted working files, leaving only the RCS `,v' files: -.XS -descend \-r rcsclean -.XE -Note: If any working files have been checked out and changed, -.B rcsclean -will fail. Check in the modified working files -and run the command again. -.TP -\(bu -Get rid of -.SB RCS -subdirectories. CVS does not use them. -.XS -descend \-r \-f 'mv RCS/*,v .' -descend \-r \-f 'rmdir RCS' -.XE -.TP -\(bu -Delete any unwanted files that remain in the source hierarchy. Then -make sure all files are under RCS control: -.XS -descend \-f 'ci \-t/dev/null \-m"Placed under CVS control" \-n\fR\fItag\fR\fB *' -.XE -.I tag -is the latest symbolic revision tag that you applied to your package -(if any). Note: This command will probably generate lots of error -messages (for directories and existing RCS files) that you can -ignore. -.SS "Placing a Third-Party Source Distribution Under CVS Control" -The -.B checkin -command checks third-party sources into CVS. The -difference between third-party sources and locally -written sources is that third-party sources must be checked into a -separate branch (called the -.IR "vendor branch" ) -of the RCS tree. This makes it possible to merge local changes to -the sources with later releases from the vendor. -.TP -\(bu -Save the original distribution kit somewhere. For example, if the -master source repository is -.B /src/master -the distribution kit could be saved in -.BR /src/dist . -Organize the distribution directory so that each release -is clearly identifiable. -.TP -\(bu -Unpack the package in a scratch directory, for example -.BR ~/scratch . -.TP -\(bu -Create a repository for the package. -In this example, the package is called `Bugs-R-Us 4.3'. -.XS -mkdir $CVSROOT/bugs -.XE -.TP -\(bu -Check in the unpacked files: -.XS -cd ~/scratch -checkin \-m 'Bugs-R-Us 4.3 distribution' bugs VENDOR V4_3 -.XE -There is nothing magic about the tag `VENDOR', which is applied to -the vendor branch. You can use whatever tag you want. `VENDOR' is a -useful convention. -.TP -\(bu -Never modify vendor files before checking them in. -Check in the files -.I exactly -as you unpacked them. -If you check in locally modified files, future vendor releases may -wipe out your local changes. -.SS "Working With CVS-Controlled Sources" -To use or edit the sources, you must check out a private copy. -For the following examples, the master files are assumed to reside in -.BR "$CVSROOT/behemoth" . -The working directory is -.BR "~/work" . -See -.BR cvs (local) -for more details on the commands mentioned below. -.TP -.I "To Check Out Working Files -Use CVS -.BR checkout : -.XS -cd ~/work -cvs checkout behemoth -.XE -There is nothing magic about the working directory. CVS will check -out sources anywhere you like. Once you have a working copy of the -sources, you can compile or edit them as desired. -.TP -.I "To Display Changes You Have Made" -Use CVS -.BR diff -to display detailed changes, equivalent to -.BR rcsdiff (local). -You can also use -.BR cvscheck (local) -to list files added, changed, and removed in -the directory, but not yet -.BR commit ted. -You must be in a directory containing working files. -.TP -.I "To Display Revision Information" -Use CVS -.BR log , -which is equivalent to -.BR rlog (local). -You must be in a directory containing working files. -.TP -.I "To Update Working Files" -Use CVS -.BR update -in a directory containing working files. -This command brings your working files up -to date with changes checked into the -master repository since you last checked out or updated -your files. -.TP -.I "To Check In Your Changes" -Use CVS -.BR commit -in a directory containing working files. -This command checks your changes into the master repository. -You can specify files by name or use -.XS -cvs commit \-a -.XE -to -.B commit -all the files you have changed. -.TP -.I "To Add a File" -Add the file to the working directory. -Use CVS -.B add -to mark the file as added. -Use CVS -.B commit -to add the file to the master repository. -.TP -.I "To Remove a File" -Remove the file from the working directory. -Use CVS -.B remove -to mark the file as removed. -Use CVS -.B commit -to move the file from its current location in the master repository -to the CVS -.IR Attic -directory. -.TP -.I "To Add a Directory" -Add the directory to the working directory. -Use CVS -.B add -to add the directory to the master repository. -.TP -.I "To Remove a Directory" -.br -You shouldn't remove directories under CVS. You should instead remove -their contents and then prune them (using the -.B \-f -and -.B \-p -options) when you -.B checkout -or -.B update -your working files. -.TP -.I "To Tag a Release" -Use CVS -.B tag -to apply a symbolic tag to the latest revision of each file in the -master repository. For example: -.XS -cvs tag V2_1 behemoth -.XE -.TP -.I "To Retrieve an Exact Copy of a Previous Release" -During a CVS -.B checkout -or -.BR update , -use the -.B \-r -option to retrieve revisions associated with a symbolic tag. -Use the -.B \-f -option to ignore all RCS files that do not contain the -tag. -Use the -.B \-p -option to prune directories that wind up empty because none -of their files matched the tag. Example: -.XS -cd ~/work -cvs checkout \-r V2_1 \-f \-p behemoth -.XE -.SS "Logging Changes" -It is a good idea to keep a change log together with the -sources. As a minimum, the change log should name and describe each -tagged release. The change log should also be under CVS control and -should be tagged along with the sources. -.LP -.BR cvslog (local) -can help. This command logs -changes reported during CVS -.B commit -operations. It automatically -updates a change log file in your working directory. When you are -finished making changes, you (optionally) edit the change log file and -then commit it to the master repository. -.LP -Note: You must edit the change log to describe a new release -and -.B commit -it to the master repository -.I before -.BR tag ging -the release using CVS. Otherwise, the release description will not be -included in the tagged package. -.LP -See -.BR cvslog (local) -for more information. -.SS "Merging a Subsequent Third-Party Distribution" -The initial steps in this process are identical to placing a -third-party distribution under CVS for the first time: save the -distribution kit and unpack the package in a scratch directory. From -that point the steps diverge. -The following example considers release 5.0 of the -Bugs-R-Us package. -.TP -\(bu -Check in the sources after unpacking them: -.XS -cd ~/scratch -checkin \-m 'Bugs-R-Us 5.0 distribution' bugs VENDOR V5_0 \\ - | tee ~/WARNINGS -.XE -It is important to save the output of -.B checkin -in a file -because it lists the sources that have been locally modified. -It is best to save the file in a different directory (for example, -your home directory). Otherwise, -.B checkin -will try to check it into the master repository. -.TP -\(bu -In your usual working directory, check out a fresh copy of the -distribution that you just checked in. -.XS -cd ~/work -cvs checkout \-r VENDOR bugs -.XE -The -.B checkout -command shown above retrieves the latest revision on the vendor branch. -.TP -\(bu -See the `WARNINGS' file for a list of all locally modified -sources. -For each locally modified source, -look at the differences between -the new distribution and the latest local revision: -.XS -cvs diff \-r \fR\fILocalRev file\fR\fB -.XE -In this command, -.I LocalRev -is the latest -numeric or symbolic revision -on the RCS trunk of -.IR file . -You can use CVS -.B log -to get the revision history. -.TP -\(bu -If your local modifications to a file have been incorporated into -the vendor's distribution, then you should reset the default RCS -branch for that file to the vendor branch. CVS doesn't provide a -mechanism to do this. You have to do it by hand in the master -repository: -.XS -rcs \-bVENDOR \fR\fIfile\fR\fB,v -.XE -.TP -\(bu -If your local modifications need to be merged with the -new distribution, use CVS -.B join -to do it: -.XS -cvs join \-r VENDOR \fR\fIfile\fR\fB -.XE -The resulting file will be placed in your working directory. -Edit it to resolve any overlaps. -.TP -\(bu -Test the merged package. -.TP -\(bu -Commit all modified files to the repository: -.XS -cvs commit \-a -.XE -.TP -\(bu -Tag the repository with a new local tag. -.SS "Applying Patches to Third-Party Sources" -Patches are handled in a manner very similar to complete -third-party distributions. This example considers patches applied to -Bugs-R-Us release 5.0. -.TP -\(bu -Save the patch files together with the distribution kit -to which they apply. -The patch file names should clearly indicate the patch -level. -.TP -\(bu -In a scratch directory, check out the last `clean' vendor copy \- the -highest revision on the vendor branch with -.IR "no local changes" : -.XS -cd ~/scratch -cvs checkout \-r VENDOR bugs -.XE -.TP -\(bu -Use -.BR patch (local) -to apply the patches. You should now have an image of the -vendor's software just as though you had received a complete, -new release. -.TP -\(bu -Proceed with the steps described for merging a subsequent third-party -distribution. -.TP -\(bu -Note: When you get to the step that requires you -to check out the new distribution after you have -checked it into the vendor branch, you should move to a different -directory. Do not attempt to -.B checkout -files in the directory in -which you applied the patches. If you do, CVS will try to merge the -changes that you made during patching with the version being checked -out and things will get very confusing. Instead, -go to a different directory (like your working directory) and -check out the files there. -.SS "Advice to Third-Party Source Hackers" -As you can see from the preceding sections, merging local changes -into third-party distributions remains difficult, and probably -always will. This fact suggests some guidelines: -.TP -\(bu -Minimize local changes. -.I Never -make stylistic changes. -Change makefiles only as much as needed for installation. Avoid -overhauling anything. Pray that the vendor does the same. -.TP -\(bu -Avoid renaming files or moving them around. -.TP -\(bu -Put independent, locally written files like help documents, local -tools, or man pages in a sub-directory called `local-additions'. -Locally written files that are linked into an existing executable -should be added right in with the vendor's sources (not in a -`local-additions' directory). -If, in the future, -the vendor distributes something -equivalent to your locally written files -you can CVS -.B remove -the files from the `local-additions' directory at that time. -.SH SEE ALSO -.BR cvs (local), -.BR checkin (local), -.BR cvslog (local), -.BR cvscheck (local) -.SH AUTHOR -Lowell Skoog -.br -Software Technology Group -.br -Technical Computing diff --git a/contrib/cvs/contrib/debug_check_log.sh b/contrib/cvs/contrib/debug_check_log.sh deleted file mode 100755 index ea55344..0000000 --- a/contrib/cvs/contrib/debug_check_log.sh +++ /dev/null @@ -1,201 +0,0 @@ -#!/bin/sh - -# Copyright (C) 2000-2005 The Free Software Foundation, Inc. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -# -# This program is intended to take a check.log file generated by a failed run of -# sanity.sh as input and run expr line by line on it. It seems a much easier -# way of spotting a single failed line in a 100 line test result. -# - -# -# Contributed by Derek R. Price -# - - - -usage () -{ - echo "\ -usage: $0 [-afh] [file...] - - -a process alternate pattern - -f process first pattern (default) - -h print this text - - file files to process (default = check.log)" -} - -# Do a line by line match with expr -# -# INPUTS -# $1 = text file name -# $2 = pattern file name -expr_line_by_line () -{ - dcl_line=0 - dcl_wrong= - # We are assuming a newline at the end of the file. The way sanity.sh - # uses echo to create the log message guarantees this newline and since - # expr ignores the last newline when the anchor is present anyhow, no - # information is being lost in the transition - while test $dcl_line -lt `wc -l <$1` -a $dcl_line -lt `wc -l <$2`; do - dcl_line=`expr $dcl_line + 1` - if test `sed -ne${dcl_line}p <$1 |wc -c` -eq 1 \ - -a `sed -ne${dcl_line}p <$2 |wc -c` -eq 1; then - # This is a workaround for what I am calling a bug in GNU - # expr - it won't match the empty string to the empty - # string. In this case the assumption is that a single - # character is always a newline. Since we already checked - # for the end of the file, we know sed will echo the - # newline. - : - elif expr "`sed -ne${dcl_line}p <$1`" : \ - "`sed -ne${dcl_line}p <$2`\$" >/dev/null; then - : - else - echo "$dcl_line: `sed -ne${dcl_line}p <$1`" - echo "$dcl_line: `sed -ne${dcl_line}p <$2`\$" - dcl_wrong="$dcl_wrong $dcl_line" - fi - done - if test `wc -l <$1` -ne `wc -l <$2`; then - echo "output & pattern contain differing number of lines" - elif test -z "$dcl_wrong"; then - echo "no mismatched lines" - else - echo "mismatched lines: $dcl_wrong" - fi -} - -# Process a single check.log file -# -# INPUTS -# $1 = filename -process_check_log () -{ - # abort if we can't find any expressions - if grep '^\*\* got: $' <$1 >/dev/null; then - : - else - echo "WARNING: No expressions in file: $1" >&2 - echo " Either not a check.log or sanity.sh exited for some other reason," >&2 - echo " like bad exit status. Try tail." >&2 - return - fi - - dcl_exprfiles="" - if grep '^\*\* or: $' <$1 >/dev/null; then - # file contains a second regex - if test $dcl_dofirst -eq 1; then - # get the first pattern - sed -ne '/^\*\* expected: $/,/^\*\* or: $/p' <$1 >/tmp/dcle$$ - dcl_exprfiles="$dcl_exprfiles /tmp/dcle$$" - fi - if test $dcl_doalternate -eq 1; then - # get the alternate pattern - sed -ne '/^\*\* or: $/,/^\*\* got: $/p' <$1 >/tmp/dclo$$ - dcl_exprfiles="$dcl_exprfiles /tmp/dclo$$" - else - echo "WARNING: Ignoring alternate pattern in file: $1" >&2 - fi - else - # file doesn't contain a second regex - if test $dcl_dofirst = 1; then - # get the only pattern - sed -ne '/^\*\* expected: $/,/^\*\* got: $/p' <$1 >/tmp/dcle$$ - dcl_exprfiles="$dcl_exprfiles /tmp/dcle$$" - fi - if test $dcl_doalternate -eq 1; then - echo "WARNING: No alternate pattern in file: $1" >&2 - fi - fi - - # and get the actual output - sed -ne '/^\*\* got: $/,$p' <$1 >/tmp/dclg$$ - sed -ne '1D -$D -p' /tmp/dclh$$ - mv /tmp/dclh$$ /tmp/dclg$$ - - # compare the output against each pattern requested - for dcl_f in $dcl_exprfiles; do - sed -ne '1D -$D -p' <$dcl_f >/tmp/dclp$$ - mv /tmp/dclp$$ $dcl_f - - case $dcl_f in - /tmp/dcle*) - echo "********** $1 : Primary **********" - ;; - /tmp/dclo*) - echo "********** $1 : Alternate **********" - ;; - esac - - expr_line_by_line /tmp/dclg$$ $dcl_f - - rm $dcl_f - done - - rm /tmp/dclg$$ -} - -### -### MAIN -### - -# set up defaults -dcl_doalternate=0 -dcl_dofirst=0 - -# process options -while getopts afh arg; do - case $arg in - a) - dcl_doalternate=1 - ;; - f) - dcl_dofirst=1 - ;; - \?|h) - usage - exit 1 - ;; - esac -done - -# dispose of processed args -shift `expr $OPTIND - 1` -OPTIND=1 - -# set the default mode -if test $dcl_doalternate -eq 0; then - dcl_dofirst=1 -fi - -# set default arg -if test $# -eq 0; then - if test -f src/check.log && test -r src/check.log; then - set src/check.log - else - set check.log - fi -fi - -for file in "$@"; do - process_check_log $file; -done - -exit 0 diff --git a/contrib/cvs/contrib/descend.man b/contrib/cvs/contrib/descend.man deleted file mode 100644 index 0434ca8..0000000 --- a/contrib/cvs/contrib/descend.man +++ /dev/null @@ -1,114 +0,0 @@ -.TH DESCEND 1 "31 March 1992" -.SH NAME -descend \- walk directory tree and execute a command at each node -.SH SYNOPSIS -.B descend -[ -.B \-afqrv -] -.I command -[ -.I directory -\&.\|.\|. -] -.SH DESCRIPTION -.B descend -walks down a directory tree and executes a command at each node. It -is not as versatile as -.BR find (1), -but it has a simpler syntax. If no -.I directory -is specified, -.B descend -starts at the current one. -.LP -Unlike -.BR find , -.B descend -can be told to skip the special directories associated with RCS, -CVS, and SCCS. This makes -.B descend -especially handy for use with these packages. It can be used with -other commands too, of course. -.LP -.B descend -is a poor man's way to make any command recursive. Note: -.B descend -does not follow symbolic links to directories unless they are -specified on the command line. -.SH OPTIONS -.TP 15 -.B \-a -.I All. -Descend into directories that begin with '.'. -.TP -.B \-f -.I Force. -Ignore errors during descent. Normally, -.B descend -quits when an error occurs. -.TP -.B \-q -.I Quiet. -Suppress the message `In directory -.IR directory ' -that is normally printed during the descent. -.TP -.B \-r -.I Restricted. -Don't descend into the special directories -.SB RCS, -.SB CVS, -.SB CVS.adm, -and -.SB SCCS. -.TP -.B \-v -.I Verbose. -Print -.I command -before executing it. -.SH EXAMPLES -.TP 15 -.B "descend ls" -Cheap substitute for `ls -R'. -.TP 15 -.B "descend -f 'rm *' tree" -Strip `tree' of its leaves. This command descends the `tree' -directory, removing all regular files. Since -.BR rm (1) -does not remove directories, this command leaves the directory -structure of `tree' intact, but denuded. The -.B \-f -option is required to keep -.B descend -from quitting. You could use `rm \-f' instead. -.TP -.B "descend -r 'co RCS/*'" /project/src/ -Check out every RCS file under the directory -.BR "/project/src" . -.TP -.B "descend -r 'cvs diff'" -Perform CVS `diff' operation on every directory below (and including) -the current one. -.SH DIAGNOSTICS -Returns 1 if errors occur (and the -.B \-f -option is not used). Otherwise returns 0. -.SH SEE ALSO -.BR find (1), -.BR rcsintro (1), -.BR cvs (1), -.BR sccs (1) -.SH AUTHOR -Lowell Skoog -.br -Software Technology Group -.br -John Fluke Mfg. Co., Inc. -.SH BUGS -Shell metacharacters in -.I command -may have bizarre effects. In particular, compound commands -(containing ';', '[', and ']' characters) will not work. It is best -to enclose complicated commands in single quotes \(aa\ \(aa. diff --git a/contrib/cvs/contrib/descend.sh b/contrib/cvs/contrib/descend.sh deleted file mode 100644 index 0b30e114..0000000 --- a/contrib/cvs/contrib/descend.sh +++ /dev/null @@ -1,127 +0,0 @@ -#! /bin/sh -# -# Copyright (C) 1995-2005 The Free Software Foundation, Inc. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# descend - walk down a directory tree and execute a command at each node - -fullname=$0 -name=descend -usage="Usage: $name [-afqrv] command [directory ...]\n -\040\040-a\040\040All: descend into directories starting with '.'\n -\040\040-f\040\040Force: ignore errors during descent\n -\040\040-q\040\040Quiet: don't print directory names\n -\040\040-r\040\040Restricted: don't descend into RCS, CVS.adm, SCCS directories\n -\040\040-v\040\040Verbose: print command before executing it" - -# Scan for options -while getopts afqrv option; do - case $option in - a) - alldirs=$option - options=$options" "-$option - ;; - f) - force=$option - options=$options" "-$option - ;; - q) - verbose= - quiet=$option - options=$options" "-$option - ;; - r) - restricted=$option - options=$options" "-$option - ;; - v) - verbose=$option - quiet= - options=$options" "-$option - ;; - \?) - /usr/5bin/echo $usage 1>&2 - exit 1 - ;; - esac -done -shift `expr $OPTIND - 1` - -# Get command to execute -if [ $# -lt 1 ] ; then - /usr/5bin/echo $usage 1>&2 - exit 1 -else - command=$1 - shift -fi - -# If no directory specified, use '.' -if [ $# -lt 1 ] ; then - default_dir=. -fi - -# For each directory specified -for dir in $default_dir "$@" ; do - - # Spawn sub-shell so we return to starting directory afterward - (cd $dir - - # Execute specified command - if [ -z "$quiet" ] ; then - echo In directory `hostname`:`pwd` - fi - if [ -n "$verbose" ] ; then - echo $command - fi - eval "$command" || if [ -z "$force" ] ; then exit 1; fi - - # Collect dot file names if necessary - if [ -n "$alldirs" ] ; then - dotfiles=.* - else - dotfiles= - fi - - # For each file in current directory - for file in $dotfiles * ; do - - # Skip '.' and '..' - if [ "$file" = "." -o "$file" = ".." ] ; then - continue - fi - - # If a directory but not a symbolic link - if [ -d "$file" -a ! -h "$file" ] ; then - - # If not skipping this type of directory - if [ \( "$file" != "RCS" -a \ - "$file" != "SCCS" -a \ - "$file" != "CVS" -a \ - "$file" != "CVS.adm" \) \ - -o -z "$restricted" ] ; then - - # Recursively descend into it - $fullname $options "$command" "$file" \ - || if [ -z "$force" ] ; then exit 1; fi - fi - - # Else if a directory AND a symbolic link - elif [ -d "$file" -a -h "$file" ] ; then - - if [ -z "$quiet" ] ; then - echo In directory `hostname`:`pwd`/$file: symbolic link: skipping - fi - fi - done - ) || if [ -z "$force" ] ; then exit 1; fi -done diff --git a/contrib/cvs/contrib/dirfns.shar b/contrib/cvs/contrib/dirfns.shar deleted file mode 100644 index 8324c41..0000000 --- a/contrib/cvs/contrib/dirfns.shar +++ /dev/null @@ -1,481 +0,0 @@ -echo 'directory.3': -sed 's/^X//' >'directory.3' <<'!' -X.TH DIRECTORY 3 imported -X.DA 9 Oct 1985 -X.SH NAME -Xopendir, readdir, telldir, seekdir, rewinddir, closedir \- high-level directory operations -X.SH SYNOPSIS -X.B #include -X.br -X.B #include -X.PP -X.SM -X.B DIR -X.B *opendir(filename) -X.br -X.B char *filename; -X.PP -X.SM -X.B struct direct -X.B *readdir(dirp) -X.br -X.B DIR *dirp; -X.PP -X.SM -X.B long -X.B telldir(dirp) -X.br -X.B DIR *dirp; -X.PP -X.SM -X.B seekdir(dirp, loc) -X.br -X.B DIR *dirp; -X.br -X.B long loc; -X.PP -X.SM -X.B rewinddir(dirp) -X.br -X.B DIR *dirp; -X.PP -X.SM -X.B closedir(dirp) -X.br -X.B DIR *dirp; -X.SH DESCRIPTION -XThis library provides high-level primitives for directory scanning, -Xsimilar to those available for 4.2BSD's (very different) directory system. -X.\"The purpose of this library is to simulate -X.\"the new flexible length directory names of 4.2bsd UNIX -X.\"on top of the old directory structure of v7. -XIt incidentally provides easy portability to and from 4.2BSD (insofar -Xas such portability is not compromised by other 4.2/VAX dependencies). -X.\"It allows programs to be converted immediately -X.\"to the new directory access interface, -X.\"so that they need only be relinked -X.\"when moved to 4.2bsd. -X.\"It is obtained with the loader option -X.\".BR \-lndir . -X.PP -X.I Opendir -Xopens the directory named by -X.I filename -Xand associates a -X.I directory stream -Xwith it. -X.I Opendir -Xreturns a pointer to be used to identify the -X.I directory stream -Xin subsequent operations. -XThe pointer -X.SM -X.B NULL -Xis returned if -X.I filename -Xcannot be accessed or is not a directory. -X.PP -X.I Readdir -Xreturns a pointer to the next directory entry. -XIt returns -X.B NULL -Xupon reaching the end of the directory or detecting -Xan invalid -X.I seekdir -Xoperation. -X.PP -X.I Telldir -Xreturns the current location associated with the named -X.I directory stream. -X.PP -X.I Seekdir -Xsets the position of the next -X.I readdir -Xoperation on the -X.I directory stream. -XThe new position reverts to the one associated with the -X.I directory stream -Xwhen the -X.I telldir -Xoperation was performed. -XValues returned by -X.I telldir -Xare good only for the lifetime of the DIR pointer from -Xwhich they are derived. -XIf the directory is closed and then reopened, -Xthe -X.I telldir -Xvalue may be invalidated -Xdue to undetected directory compaction in 4.2BSD. -XIt is safe to use a previous -X.I telldir -Xvalue immediately after a call to -X.I opendir -Xand before any calls to -X.I readdir. -X.PP -X.I Rewinddir -Xresets the position of the named -X.I directory stream -Xto the beginning of the directory. -X.PP -X.I Closedir -Xcauses the named -X.I directory stream -Xto be closed, -Xand the structure associated with the DIR pointer to be freed. -X.PP -XA -X.I direct -Xstructure is as follows: -X.PP -X.RS -X.nf -Xstruct direct { -X /* unsigned */ long d_ino; /* inode number of entry */ -X unsigned short d_reclen; /* length of this record */ -X unsigned short d_namlen; /* length of string in d_name */ -X char d_name[MAXNAMLEN + 1]; /* name must be no longer than this */ -X}; -X.fi -X.RE -X.PP -XThe -X.I d_reclen -Xfield is meaningless in non-4.2BSD systems and should be ignored. -XThe use of a -X.I long -Xfor -X.I d_ino -Xis also a 4.2BSDism; -X.I ino_t -X(see -X.IR types (5)) -Xshould be used elsewhere. -XThe macro -X.I DIRSIZ(dp) -Xgives the minimum memory size needed to hold the -X.I direct -Xvalue pointed to by -X.IR dp , -Xwith the minimum necessary allocation for -X.IR d_name . -X.PP -XThe preferred way to search the current directory for entry ``name'' is: -X.PP -X.RS -X.nf -X len = strlen(name); -X dirp = opendir("."); -X if (dirp == NULL) { -X fprintf(stderr, "%s: can't read directory .\\n", argv[0]); -X return NOT_FOUND; -X } -X while ((dp = readdir(dirp)) != NULL) -X if (dp->d_namlen == len && strcmp(dp->d_name, name) == 0) { -X closedir(dirp); -X return FOUND; -X } -X closedir(dirp); -X return NOT_FOUND; -X.RE -X.\".SH LINKING -X.\"This library is accessed by specifying ``-lndir'' as the -X.\"last argument to the compile line, e.g.: -X.\".PP -X.\" cc -I/usr/include/ndir -o prog prog.c -lndir -X.SH "SEE ALSO" -Xopen(2), -Xclose(2), -Xread(2), -Xlseek(2) -X.SH HISTORY -XWritten by -XKirk McKusick at Berkeley (ucbvax!mckusick). -XMiscellaneous bug fixes from elsewhere. -XThe size of the data structure has been decreased to avoid excessive -Xspace waste under V7 (where filenames are 14 characters at most). -XFor obscure historical reasons, the include file is also available -Xas -X.IR . -XThe Berkeley version lived in a separate library (\fI\-lndir\fR), -Xwhereas ours is -Xpart of the C library, although the separate library is retained to -Xmaximize compatibility. -X.PP -XThis manual page has been substantially rewritten to be informative in -Xthe absence of a 4.2BSD manual. -X.SH BUGS -XThe -X.I DIRSIZ -Xmacro actually wastes a bit of space due to some padding requirements -Xthat are an artifact of 4.2BSD. -X.PP -XThe returned value of -X.I readdir -Xpoints to a static area that will be overwritten by subsequent calls. -X.PP -XThere are some unfortunate name conflicts with the \fIreal\fR V7 -Xdirectory structure definitions. -! -echo 'dir.h': -sed 's/^X//' >'dir.h' <<'!' -X/* dir.h 4.4 82/07/25 */ -X -X/* -X * A directory consists of some number of blocks of DIRBLKSIZ -X * bytes, where DIRBLKSIZ is chosen such that it can be transferred -X * to disk in a single atomic operation (e.g. 512 bytes on most machines). -X * -X * Each DIRBLKSIZ byte block contains some number of directory entry -X * structures, which are of variable length. Each directory entry has -X * a struct direct at the front of it, containing its inode number, -X * the length of the entry, and the length of the name contained in -X * the entry. These are followed by the name padded to a 4 byte boundary -X * with null bytes. All names are guaranteed null terminated. -X * The maximum length of a name in a directory is MAXNAMLEN. -X * -X * The macro DIRSIZ(dp) gives the amount of space required to represent -X * a directory entry. Free space in a directory is represented by -X * entries which have dp->d_reclen >= DIRSIZ(dp). All DIRBLKSIZ bytes -X * in a directory block are claimed by the directory entries. This -X * usually results in the last entry in a directory having a large -X * dp->d_reclen. When entries are deleted from a directory, the -X * space is returned to the previous entry in the same directory -X * block by increasing its dp->d_reclen. If the first entry of -X * a directory block is free, then its dp->d_ino is set to 0. -X * Entries other than the first in a directory do not normally have -X * dp->d_ino set to 0. -X */ -X#define DIRBLKSIZ 512 -X#ifdef VMUNIX -X#define MAXNAMLEN 255 -X#else -X#define MAXNAMLEN 14 -X#endif -X -Xstruct direct { -X /* unsigned */ long d_ino; /* inode number of entry */ -X unsigned short d_reclen; /* length of this record */ -X unsigned short d_namlen; /* length of string in d_name */ -X char d_name[MAXNAMLEN + 1]; /* name must be no longer than this */ -X}; -X -X/* -X * The DIRSIZ macro gives the minimum record length which will hold -X * the directory entry. This requires the amount of space in struct direct -X * without the d_name field, plus enough space for the name with a terminating -X * null byte (dp->d_namlen+1), rounded up to a 4 byte boundary. -X */ -X#undef DIRSIZ -X#define DIRSIZ(dp) \ -X ((sizeof (struct direct) - (MAXNAMLEN+1)) + (((dp)->d_namlen+1 + 3) &~ 3)) -X -X#ifndef KERNEL -X/* -X * Definitions for library routines operating on directories. -X */ -Xtypedef struct _dirdesc { -X int dd_fd; -X long dd_loc; -X long dd_size; -X char dd_buf[DIRBLKSIZ]; -X} DIR; -X#ifndef NULL -X#define NULL 0 -X#endif -Xextern DIR *opendir(); -Xextern struct direct *readdir(); -Xextern long telldir(); -X#ifdef void -Xextern void seekdir(); -Xextern void closedir(); -X#endif -X#define rewinddir(dirp) seekdir((dirp), (long)0) -X#endif KERNEL -! -echo 'makefile': -sed 's/^X//' >'makefile' <<'!' -XDIR = closedir.o opendir.o readdir.o seekdir.o telldir.o -XCFLAGS=-O -I. -Dvoid=int -XDEST=.. -X -Xall: $(DIR) -X -Xmv: $(DIR) -X mv $(DIR) $(DEST) -X -Xcpif: dir.h -X cp dir.h /usr/include/ndir.h -X -Xclean: -X rm -f *.o -! -echo 'closedir.c': -sed 's/^X//' >'closedir.c' <<'!' -Xstatic char sccsid[] = "@(#)closedir.c 4.2 3/10/82"; -X -X#include -X#include -X -X/* -X * close a directory. -X */ -Xvoid -Xclosedir(dirp) -X register DIR *dirp; -X{ -X close(dirp->dd_fd); -X dirp->dd_fd = -1; -X dirp->dd_loc = 0; -X free((char *)dirp); -X} -! -echo 'opendir.c': -sed 's/^X//' >'opendir.c' <<'!' -X/* Copyright (c) 1982 Regents of the University of California */ -X -Xstatic char sccsid[] = "@(#)opendir.c 4.4 11/12/82"; -X -X#include -X#include -X#include -X -X/* -X * open a directory. -X */ -XDIR * -Xopendir(name) -X char *name; -X{ -X register DIR *dirp; -X register int fd; -X struct stat statbuf; -X char *malloc(); -X -X if ((fd = open(name, 0)) == -1) -X return NULL; -X if (fstat(fd, &statbuf) == -1 || !(statbuf.st_mode & S_IFDIR)) { -X close(fd); -X return NULL; -X } -X if ((dirp = (DIR *)malloc(sizeof(DIR))) == NULL) { -X close (fd); -X return NULL; -X } -X dirp->dd_fd = fd; -X dirp->dd_loc = 0; -X dirp->dd_size = 0; /* so that telldir will work before readdir */ -X return dirp; -X} -! -echo 'readdir.c': -sed 's/^X//' >'readdir.c' <<'!' -X/* Copyright (c) 1982 Regents of the University of California */ -X -Xstatic char sccsid[] = "@(#)readdir.c 4.3 8/8/82"; -X -X#include -X#include -X -X/* -X * read an old stlye directory entry and present it as a new one -X */ -X#define ODIRSIZ 14 -X -Xstruct olddirect { -X ino_t od_ino; -X char od_name[ODIRSIZ]; -X}; -X -X/* -X * get next entry in a directory. -X */ -Xstruct direct * -Xreaddir(dirp) -X register DIR *dirp; -X{ -X register struct olddirect *dp; -X static struct direct dir; -X -X for (;;) { -X if (dirp->dd_loc == 0) { -X dirp->dd_size = read(dirp->dd_fd, dirp->dd_buf, -X DIRBLKSIZ); -X if (dirp->dd_size <= 0) { -X dirp->dd_size = 0; -X return NULL; -X } -X } -X if (dirp->dd_loc >= dirp->dd_size) { -X dirp->dd_loc = 0; -X continue; -X } -X dp = (struct olddirect *)(dirp->dd_buf + dirp->dd_loc); -X dirp->dd_loc += sizeof(struct olddirect); -X if (dp->od_ino == 0) -X continue; -X dir.d_ino = dp->od_ino; -X strncpy(dir.d_name, dp->od_name, ODIRSIZ); -X dir.d_name[ODIRSIZ] = '\0'; /* insure null termination */ -X dir.d_namlen = strlen(dir.d_name); -X dir.d_reclen = DIRBLKSIZ; -X return (&dir); -X } -X} -! -echo 'seekdir.c': -sed 's/^X//' >'seekdir.c' <<'!' -Xstatic char sccsid[] = "@(#)seekdir.c 4.9 3/25/83"; -X -X#include -X#include -X -X/* -X * seek to an entry in a directory. -X * Only values returned by "telldir" should be passed to seekdir. -X */ -Xvoid -Xseekdir(dirp, loc) -X register DIR *dirp; -X long loc; -X{ -X long curloc, base, offset; -X struct direct *dp; -X extern long lseek(); -X -X curloc = telldir(dirp); -X if (loc == curloc) -X return; -X base = loc & ~(DIRBLKSIZ - 1); -X offset = loc & (DIRBLKSIZ - 1); -X (void) lseek(dirp->dd_fd, base, 0); -X dirp->dd_size = 0; -X dirp->dd_loc = 0; -X while (dirp->dd_loc < offset) { -X dp = readdir(dirp); -X if (dp == NULL) -X return; -X } -X} -! -echo 'telldir.c': -sed 's/^X//' >'telldir.c' <<'!' -Xstatic char sccsid[] = "@(#)telldir.c 4.1 2/21/82"; -X -X#include -X#include -X -X/* -X * return a pointer into a directory -X */ -Xlong -Xtelldir(dirp) -X DIR *dirp; -X{ -X long lseek(); -X -X return (lseek(dirp->dd_fd, 0L, 1) - dirp->dd_size + dirp->dd_loc); -X} -! -echo done diff --git a/contrib/cvs/contrib/intro.doc b/contrib/cvs/contrib/intro.doc deleted file mode 100644 index a6d4ec1..0000000 --- a/contrib/cvs/contrib/intro.doc +++ /dev/null @@ -1,112 +0,0 @@ -Date: Tue, 16 Jun 1992 17:05:23 +0200 -From: Steven.Pemberton@cwi.nl -Message-Id: <9206161505.AA06927.steven@sijs.cwi.nl> -To: berliner@Sun.COM -Subject: cvs - -INTRODUCTION TO USING CVS - - CVS is a system that lets groups of people work simultaneously on - groups of files (for instance program sources). - - It works by holding a central 'repository' of the most recent version - of the files. You may at any time create a personal copy of these - files; if at a later date newer versions of the files are put in the - repository, you can 'update' your copy. - - You may edit your copy of the files freely. If new versions of the - files have been put in the repository in the meantime, doing an update - merges the changes in the central copy into your copy. - (It can be that when you do an update, the changes in the - central copy clash with changes you have made in your own - copy. In this case cvs warns you, and you have to resolve the - clash in your copy.) - - When you are satisfied with the changes you have made in your copy of - the files, you can 'commit' them into the central repository. - (When you do a commit, if you haven't updated to the most - recent version of the files, cvs tells you this; then you have - to first update, resolve any possible clashes, and then redo - the commit.) - -USING CVS - - Suppose that a number of repositories have been stored in - /usr/src/cvs. Whenever you use cvs, the environment variable - CVSROOT must be set to this (for some reason): - - CVSROOT=/usr/src/cvs - export CVSROOT - -TO CREATE A PERSONAL COPY OF A REPOSITORY - - Suppose you want a copy of the files in repository 'views' to be - created in your directory src. Go to the place where you want your - copy of the directory, and do a 'checkout' of the directory you - want: - - cd $HOME/src - cvs checkout views - - This creates a directory called (in this case) 'views' in the src - directory, containing a copy of the files, which you may now work - on to your heart's content. - -TO UPDATE YOUR COPY - - Use the command 'cvs update'. - - This will update your copy with any changes from the central - repository, telling you which files have been updated (their names - are displayed with a U before them), and which have been modified - by you and not yet committed (preceded by an M). You will be - warned of any files that contain clashes, the clashes will be - marked in the file surrounded by lines of the form <<<< and >>>>. - -TO COMMIT YOUR CHANGES - - Use the command 'cvs commit'. - - You will be put in an editor to make a message that describes the - changes that you have made (for future reference). Your changes - will then be added to the central copy. - -ADDING AND REMOVING FILES - - It can be that the changes you want to make involve a completely - new file, or removing an existing one. The commands to use here - are: - - cvs add - cvs remove - - You still have to do a commit after these commands. You may make - any number of new files in your copy of the repository, but they - will not be committed to the central copy unless you do a 'cvs add'. - -OTHER USEFUL COMMANDS AND HINTS - - To see the commit messages for files, and who made them, use: - - cvs log [filenames] - - To see the differences between your version and the central version: - - cvs diff [filenames] - - To give a file a new name, rename it and do an add and a remove. - - To lose your changes and go back to the version from the - repository, delete the file and do an update. - - After an update where there have been clashes, your original - version of the file is saved as .#file.version. - - All the cvs commands mentioned accept a flag '-n', that doesn't do - the action, but lets you see what would happen. For instance, you - can use 'cvs -n update' to see which files would be updated. - -MORE INFORMATION - - This is necessarily a very brief introduction. See the manual page - (man cvs) for full details. diff --git a/contrib/cvs/contrib/log.in b/contrib/cvs/contrib/log.in deleted file mode 100755 index f12d338..0000000 --- a/contrib/cvs/contrib/log.in +++ /dev/null @@ -1,238 +0,0 @@ -#! @PERL@ -T -# -*-Perl-*- - -# Copyright (C) 1994-2005 The Free Software Foundation, Inc. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -############################################################################### -############################################################################### -############################################################################### -# -# THIS SCRIPT IS PROBABLY BROKEN. REMOVING THE -T SWITCH ON THE #! LINE ABOVE -# WOULD FIX IT, BUT THIS IS INSECURE. WE RECOMMEND FIXING THE ERRORS WHICH THE -# -T SWITCH WILL CAUSE PERL TO REPORT BEFORE RUNNING THIS SCRIPT FROM A CVS -# SERVER TRIGGER. PLEASE SEND PATCHES CONTAINING THE CHANGES YOU FIND -# NECESSARY TO RUN THIS SCRIPT WITH THE TAINT-CHECKING ENABLED BACK TO THE -# <@PACKAGE_BUGREPORT@> MAILING LIST. -# -# For more on general Perl security and taint-checking, please try running the -# `perldoc perlsec' command. -# -############################################################################### -############################################################################### -############################################################################### - -# XXX: FIXME: handle multiple '-f logfile' arguments -# -# XXX -- I HATE Perl! This *will* be re-written in shell/awk/sed soon! -# - -# Usage: log.pl [-u user] [[-m mailto] ...] [-s] [-V] -f logfile 'dirname file ...' -# -# -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 -# -V - without '-s', don't pass '-v' to cvs status -# -f logfile - for the logfile to append to (mandatory, -# but only one logfile can be specified). - -# here is what the output looks like: -# -# From: woods@kuma.domain.top -# Subject: CVS update: testmodule -# -# Date: Wednesday November 23, 1994 @ 14:15 -# Author: woods -# -# Update of /local/src-CVS/testmodule -# In directory kuma:/home/kuma/woods/work.d/testmodule -# -# Modified Files: -# test3 -# Added Files: -# test6 -# Removed Files: -# test4 -# Log Message: -# - wow, what a test -# -# (and for each file the "cvs status -v" output is appended unless -s is used) -# -# ================================================================== -# File: test3 Status: Up-to-date -# -# Working revision: 1.41 Wed Nov 23 14:15:59 1994 -# Repository revision: 1.41 /local/src-CVS/cvs/testmodule/test3,v -# Sticky Options: -ko -# -# Existing Tags: -# local-v2 (revision: 1.7) -# local-v1 (revision: 1.1.1.2) -# CVS-1_4A2 (revision: 1.1.1.2) -# local-v0 (revision: 1.2) -# CVS-1_4A1 (revision: 1.1.1.1) -# CVS (branch: 1.1.1) - -use strict; -use IO::File; - -my $cvsroot = $ENV{'CVSROOT'}; - -# turn off setgid -# -$) = $(; - -my $dostatus = 1; -my $verbosestatus = 1; -my $users; -my $login; -my $donefiles; -my $logfile; -my @files; - -# parse command line arguments -# -while (@ARGV) { - my $arg = shift @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; - } elsif ($arg eq '-s') { - $dostatus = 0; - } elsif ($arg eq '-V') { - $verbosestatus = 0; - } else { - ($donefiles) && die "Too many arguments!\n"; - $donefiles = 1; - @files = split(/ /, $arg); - } -} - -# the first argument is the module location relative to $CVSROOT -# -my $modulepath = shift @files; - -my $mailcmd = "| Mail -s 'CVS update: $modulepath'"; - -# Initialise some date and time arrays -# -my @mos = ('January','February','March','April','May','June','July', - 'August','September','October','November','December'); -my @days = ('Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'); - -my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime; -$year += 1900; - -# get a login name for the guy doing the commit.... -# -if ($login eq '') { - $login = getlogin || (getpwuid($<))[0] || "nobody"; -} - -# open log file for appending -# -my $logfh = new IO::File ">>" . $logfile - or die "Could not open(" . $logfile . "): $!\n"; - -# send mail, if there's anyone to send to! -# -my $mailfh; -if ($users) { - $mailcmd = "$mailcmd $users"; - $mailfh = new IO::File $mailcmd - or die "Could not Exec($mailcmd): $!\n"; -} - -# print out the log Header -# -$logfh->print ("\n"); -$logfh->print ("****************************************\n"); -$logfh->print ("Date:\t$days[$wday] $mos[$mon] $mday, $year @ $hour:" . sprintf("%02d", $min) . "\n"); -$logfh->print ("Author:\t$login\n\n"); - -if ($mailfh) { - $mailfh->print ("\n"); - $mailfh->print ("Date:\t$days[$wday] $mos[$mon] $mday, $year @ $hour:" . sprintf("%02d", $min) . "\n"); - $mailfh->print ("Author:\t$login\n\n"); -} - -# print the stuff from logmsg that comes in on stdin to the logfile -# -my $infh = new IO::File "< -"; -foreach ($infh->getlines) { - $logfh->print; - if ($mailfh) { - $mailfh->print ($_); - } -} -undef $infh; - -$logfh->print ("\n"); - -# after log information, do an 'cvs -Qq status -v' on each file in the arguments. -# -if ($dostatus != 0) { - while (@files) { - my $file = shift @files; - if ($file eq "-") { - $logfh->print ("[input file was '-']\n"); - if ($mailfh) { - $mailfh->print ("[input file was '-']\n"); - } - last; - } - my $rcsfh = new IO::File; - my $pid = $rcsfh->open ("-|"); - if ( !defined $pid ) - { - die "fork failed: $!"; - } - if ($pid == 0) - { - my @command = ('cvs', '-nQq', 'status'); - if ($verbosestatus) - { - push @command, '-v'; - } - push @command, $file; - exec @command; - die "cvs exec failed: $!"; - } - my $line; - while ($line = $rcsfh->getline) { - $logfh->print ($line); - if ($mailfh) { - $mailfh->print ($line); - } - } - undef $rcsfh; - } -} - -$logfh->close() - or die "Write to $logfile failed: $!"; - -if ($mailfh) -{ - $mailfh->close; - die "Pipe to $mailcmd failed" if $?; -} - -## must exit cleanly -## -exit 0; diff --git a/contrib/cvs/contrib/log_accum.in b/contrib/cvs/contrib/log_accum.in deleted file mode 100755 index dbd18f1..0000000 --- a/contrib/cvs/contrib/log_accum.in +++ /dev/null @@ -1,749 +0,0 @@ -#! @PERL@ -T -# -*-Perl-*- - -# Copyright (C) 1994-2005 The Free Software Foundation, Inc. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -############################################################################### -############################################################################### -############################################################################### -# -# THIS SCRIPT IS PROBABLY BROKEN. REMOVING THE -T SWITCH ON THE #! LINE ABOVE -# WOULD FIX IT, BUT THIS IS INSECURE. WE RECOMMEND FIXING THE ERRORS WHICH THE -# -T SWITCH WILL CAUSE PERL TO REPORT BEFORE RUNNING THIS SCRIPT FROM A CVS -# SERVER TRIGGER. PLEASE SEND PATCHES CONTAINING THE CHANGES YOU FIND -# NECESSARY TO RUN THIS SCRIPT WITH THE TAINT-CHECKING ENABLED BACK TO THE -# <@PACKAGE_BUGREPORT@> MAILING LIST. -# -# For more on general Perl security and taint-checking, please try running the -# `perldoc perlsec' command. -# -############################################################################### -############################################################################### -############################################################################### - -# Perl filter to handle the log messages from the checkin of files in -# a directory. This script will group the lists of files by log -# message, and mail a single consolidated log message at the end of -# the commit. -# -# This file assumes a pre-commit checking program that leaves the -# names of the first and last commit directories in a temporary file. -# -# IMPORTANT: what the above means is, this script interacts with -# commit_prep, in that they have to agree on the tmpfile name to use. -# See $LAST_FILE below. -# -# How this works: CVS triggers this script once for each directory -# involved in the commit -- in other words, a single commit can invoke -# this script N times. It knows when it's on the last invocation by -# examining the contents of $LAST_FILE. Between invocations, it -# caches information for its future incarnations in various temporary -# files in /tmp, which are named according to the process group and -# the committer (by themselves, neither of these are unique, but -# together they almost always are, unless the same user is doing two -# commits simultaneously). The final invocation is the one that -# actually sends the mail -- it gathers up the cached information, -# combines that with what it found out on this pass, and sends a -# commit message to the appropriate mailing list. -# -# (Ask Karl Fogel if questions.) -# -# Contributed by David Hampton -# Roy Fielding removed useless code and added log/mail of new files -# Ken Coar added special processing (i.e., no diffs) for binary files -# - -############################################################ -# -# Configurable options -# -############################################################ -# -# Where do you want the RCS ID and delta info? -# 0 = none, -# 1 = in mail only, -# 2 = in both mail and logs. -# -$rcsidinfo = 2; - -#if you are using CVS web then set this to some value... if not set it to "" -# -# When set properly, this will cause links to aspects of the project to -# print in the commit emails. -#$CVSWEB_SCHEME = "http"; -#$CVSWEB_DOMAIN = "nongnu.org"; -#$CVSWEB_PORT = "80"; -#$CVSWEB_URI = "source/browse/"; -#$SEND_URL = "true"; -$SEND_DIFF = "true"; - - -# Set this to a domain to have CVS pretend that all users who make -# commits have mail accounts within that domain. -#$EMULATE_LOCAL_MAIL_USER="nongnu.org"; - -# Set this to '-c' for context diffs; defaults to '-u' for unidiff format. -$difftype = '-uN'; - -############################################################ -# -# Constants -# -############################################################ -$STATE_NONE = 0; -$STATE_CHANGED = 1; -$STATE_ADDED = 2; -$STATE_REMOVED = 3; -$STATE_LOG = 4; - -$TMPDIR = $ENV{'TMPDIR'} || '/tmp'; -$FILE_PREFIX = '#cvs.'; - -$LAST_FILE = "$TMPDIR/${FILE_PREFIX}lastdir"; # Created by commit_prep! -$ADDED_FILE = "$TMPDIR/${FILE_PREFIX}files.added"; -$REMOVED_FILE = "$TMPDIR/${FILE_PREFIX}files.removed"; -$LOG_FILE = "$TMPDIR/${FILE_PREFIX}files.log"; -$BRANCH_FILE = "$TMPDIR/${FILE_PREFIX}files.branch"; -$MLIST_FILE = "$TMPDIR/${FILE_PREFIX}files.mlist"; -$SUMMARY_FILE = "$TMPDIR/${FILE_PREFIX}files.summary"; - -$CVSROOT = $ENV{'CVSROOT'}; - -$MAIL_CMD = "| /usr/lib/sendmail -i -t"; -#$MAIL_CMD = "| /var/qmail/bin/qmail-inject"; -$MAIL_FROM = 'commitlogger'; #not needed if EMULATE_LOCAL_MAIL_USER -$SUBJECT_PRE = 'CVS update:'; - - -############################################################ -# -# Subroutines -# -############################################################ - -sub format_names { - local($dir, @files) = @_; - local(@lines); - - $lines[0] = sprintf(" %-08s", $dir); - foreach $file (@files) { - if (length($lines[$#lines]) + length($file) > 60) { - $lines[++$#lines] = sprintf(" %8s", " "); - } - $lines[$#lines] .= " ".$file; - } - @lines; -} - -sub cleanup_tmpfiles { - local(@files); - - opendir(DIR, $TMPDIR); - push(@files, grep(/^${FILE_PREFIX}.*\.${id}\.${cvs_user}$/, readdir(DIR))); - closedir(DIR); - foreach (@files) { - unlink "$TMPDIR/$_"; - } -} - -sub write_logfile { - local($filename, @lines) = @_; - - open(FILE, ">$filename") || die ("Cannot open log file $filename: $!\n"); - print(FILE join("\n", @lines), "\n"); - close(FILE); -} - -sub append_to_file { - local($filename, $dir, @files) = @_; - - if (@files) { - local(@lines) = &format_names($dir, @files); - open(FILE, ">>$filename") || die ("Cannot open file $filename: $!\n"); - print(FILE join("\n", @lines), "\n"); - close(FILE); - } -} - -sub write_line { - local($filename, $line) = @_; - - open(FILE, ">$filename") || die("Cannot open file $filename: $!\n"); - print(FILE $line, "\n"); - close(FILE); -} - -sub append_line { - local($filename, $line) = @_; - - open(FILE, ">>$filename") || die("Cannot open file $filename: $!\n"); - print(FILE $line, "\n"); - close(FILE); -} - -sub read_line { - local($filename) = @_; - local($line); - - open(FILE, "<$filename") || die("Cannot open file $filename: $!\n"); - $line = ; - close(FILE); - chomp($line); - $line; -} - -sub read_line_nodie { - local($filename) = @_; - local($line); - open(FILE, "<$filename") || return (""); - - $line = ; - close(FILE); - chomp($line); - $line; -} - -sub read_file_lines { - local($filename) = @_; - local(@text) = (); - - open(FILE, "<$filename") || return (); - while () { - chomp; - push(@text, $_); - } - close(FILE); - @text; -} - -sub read_file { - local($filename, $leader) = @_; - local(@text) = (); - - open(FILE, "<$filename") || return (); - while () { - chomp; - push(@text, sprintf(" %-10s %s", $leader, $_)); - $leader = ""; - } - close(FILE); - @text; -} - -sub read_logfile { - local($filename, $leader) = @_; - local(@text) = (); - - open(FILE, "<$filename") || die ("Cannot open log file $filename: $!\n"); - while () { - chomp; - push(@text, $leader.$_); - } - close(FILE); - @text; -} - -# -# do an 'cvs -Qn status' on each file in the arguments, and extract info. -# -sub change_summary { - local($out, @filenames) = @_; - local(@revline); - local($file, $rev, $rcsfile, $line, $vhost, $cvsweb_base); - - while (@filenames) { - $file = shift @filenames; - - if ("$file" eq "") { - next; - } - - open(RCS, "-|") || exec "$cvsbin/cvs", '-Qn', 'status', '--', $file; - - $rev = ""; - $delta = ""; - $rcsfile = ""; - - - while () { - if (/^[ \t]*Repository revision/) { - chomp; - @revline = split(' ', $_); - $rev = $revline[2]; - $rcsfile = $revline[3]; - $rcsfile =~ s,^$CVSROOT/,,; - $rcsfile =~ s/,v$//; - } - } - close(RCS); - - - if ($rev ne '' && $rcsfile ne '') { - open(RCS, "-|") || exec "$cvsbin/cvs", '-Qn', 'log', "-r$rev", - '--', $file; - while () { - if (/^date:/) { - chomp; - $delta = $_; - $delta =~ s/^.*;//; - $delta =~ s/^[\s]+lines://; - } - } - close(RCS); - } - - $diff = "\n\n"; - $vhost = $path[0]; - if ($CVSWEB_PORT eq "80") { - $cvsweb_base = "$CVSWEB_SCHEME://$vhost.$CVSWEB_DOMAIN/$CVSWEB_URI"; - } - else { - $cvsweb_base = "$CVSWEB_SCHEME://$vhost.$CVSWEB_DOMAIN:$CVSWEB_PORT/$CVSWEB_URI"; - } - if ($SEND_URL eq "true") { - $diff .= $cvsweb_base . join("/", @path) . "/$file"; - } - - # - # If this is a binary file, don't try to report a diff; not only is - # it meaningless, but it also screws up some mailers. We rely on - # Perl's 'is this binary' algorithm; it's pretty good. But not - # perfect. - # - if (($file =~ /\.(?:pdf|gif|jpg|mpg)$/i) || (-B $file)) { - if ($SEND_URL eq "true") { - $diff .= "?rev=$rev&content-type=text/x-cvsweb-markup\n\n"; - } - if ($SEND_DIFF eq "true") { - $diff .= "\t<>\n\n"; - } - } - else { - # - # Get the differences between this and the previous revision, - # being aware that new files always have revision '1.1' and - # new branches always end in '.n.1'. - # - if ($rev =~ /^(.*)\.([0-9]+)$/) { - $prev = $2 - 1; - $prev_rev = $1 . '.' . $prev; - - $prev_rev =~ s/\.[0-9]+\.0$//;# Truncate if first rev on branch - - if ($rev eq '1.1') { - if ($SEND_URL eq "true") { - $diff .= "?rev=$rev&content-type=text/x-cvsweb-markup\n\n"; - } - if ($SEND_DIFF eq "true") { - open(DIFF, "-|") - || exec "$cvsbin/cvs", '-Qn', 'update', '-p', '-r1.1', - '--', $file; - $diff .= "Index: $file\n==================================" - . "=================================\n"; - } - } - else { - if ($SEND_URL eq "true") { - $diff .= ".diff?r1=$prev_rev&r2=$rev\n\n"; - } - if ($SEND_DIFF eq "true") { - $diff .= "(In the diff below, changes in quantity " - . "of whitespace are not shown.)\n\n"; - open(DIFF, "-|") - || exec "$cvsbin/cvs", '-Qn', 'diff', "$difftype", - '-b', "-r$prev_rev", "-r$rev", '--', $file; - } - } - - if ($SEND_DIFF eq "true") { - while () { - $diff .= $_; - } - close(DIFF); - } - $diff .= "\n\n"; - } - } - - &append_line($out, sprintf("%-9s%-12s%s%s", $rev, $delta, - $rcsfile, $diff)); - } -} - - -sub build_header { - local($header); - delete $ENV{'TZ'}; - local($sec,$min,$hour,$mday,$mon,$year) = localtime(time); - - $header = sprintf(" User: %-8s\n Date: %02d/%02d/%02d %02d:%02d:%02d", - $cvs_user, $year%100, $mon+1, $mday, - $hour, $min, $sec); -# $header = sprintf("%-8s %02d/%02d/%02d %02d:%02d:%02d", -# $login, $year%100, $mon+1, $mday, -# $hour, $min, $sec); -} - -# !!! Destination Mailing-list and history file mappings here !!! - -#sub mlist_map -#{ -# local($path) = @_; -# my $domain = "nongnu.org"; -# -# if ($path =~ /^([^\/]+)/) { -# return "cvs\@$1.$domain"; -# } else { -# return "cvs\@$domain"; -# } -#} - -sub derive_subject_from_changes_file () -{ - my $subj = ""; - - for ($i = 0; ; $i++) - { - open (CH, "<$CHANGED_FILE.$i.$id.$cvs_user") or last; - - while (my $change = ) - { - # A changes file looks like this: - # - # src foo.c newfile.html - # www index.html project_nav.html - # - # Each line is " Dir File1 File2 ..." - # We only care about Dir, since the subject line should - # summarize. - - $change =~ s/^[ \t]*//; - $change =~ /^([^ \t]+)[ \t]*/; - my $dir = $1; - # Fold to rightmost directory component - $dir =~ /([^\/]+)$/; - $dir = $1; - if ($subj eq "") { - $subj = $dir; - } else { - $subj .= ", $dir"; - } - } - close (CH); - } - - if ($subj ne "") { - $subj = "MODIFIED: $subj ..."; - } - else { - # NPM: See if there's any file-addition notifications. - my $added = &read_line_nodie("$ADDED_FILE.$i.$id.$cvs_user"); - if ($added ne "") { - $subj .= "ADDED: $added "; - } - -# print "derive_subject_from_changes_file().. added== $added \n"; - - ## NPM: See if there's any file-removal notications. - my $removed = &read_line_nodie("$REMOVED_FILE.$i.$id.$cvs_user"); - if ($removed ne "") { - $subj .= "REMOVED: $removed "; - } - -# print "derive_subject_from_changes_file().. removed== $removed \n"; - - ## NPM: See if there's any branch notifications. - my $branched = &read_line_nodie("$BRANCH_FILE.$i.$id.$cvs_user"); - if ($branched ne "") { - $subj .= "BRANCHED: $branched"; - } - -# print "derive_subject_from_changes_file().. branched== $branched \n"; - - ## NPM: DEFAULT: DIRECTORY CREATION (c.f. "Check for a new directory first" in main mody) - if ($subj eq "") { - my $subject = join("/", @path); - $subj = "NEW: $subject"; - } - } - - return $subj; -} - -sub mail_notification -{ - local($addr_list, @text) = @_; - local($mail_to); - - my $subj = &derive_subject_from_changes_file (); - - if ($EMULATE_LOCAL_MAIL_USER ne "") { - $MAIL_FROM = "$cvs_user\@$EMULATE_LOCAL_MAIL_USER"; - } - - $mail_to = join(", ", @{$addr_list}); - - print "Mailing the commit message to $mail_to (from $MAIL_FROM)\n"; - - $ENV{'MAILUSER'} = $MAIL_FROM; - # Commented out on hocus, so comment it out here. -kff - # $ENV{'QMAILINJECT'} = 'f'; - - open(MAIL, "$MAIL_CMD -f$MAIL_FROM"); - print MAIL "From: $MAIL_FROM\n"; - print MAIL "To: $mail_to\n"; - print MAIL "Subject: $SUBJECT_PRE $subj\n\n"; - print(MAIL join("\n", @text)); - close(MAIL); -# print "Mailing the commit message to $MAIL_TO...\n"; -# -# #added by jrobbins@collab.net 1999/12/15 -# # attempt to get rid of anonymous -# $ENV{'MAILUSER'} = 'commitlogger'; -# $ENV{'QMAILINJECT'} = 'f'; -# -# open(MAIL, "| /var/qmail/bin/qmail-inject"); -# print(MAIL "To: $MAIL_TO\n"); -# print(MAIL "Subject: cvs commit: $ARGV[0]\n"); -# print(MAIL join("\n", @text)); -# close(MAIL); -} - -## process the command line arguments sent to this script -## it returns an array of files, %s, sent from the loginfo -## command -sub process_argv -{ - local(@argv) = @_; - local(@files); - local($arg); - print "Processing log script arguments...\n"; - - while (@argv) { - $arg = shift @argv; - - if ($arg eq '-u') { - $cvs_user = shift @argv; - } else { - ($donefiles) && die "Too many arguments!\n"; - $donefiles = 1; - $ARGV[0] = $arg; - @files = split(' ', $arg); - } - } - return @files; -} - - -############################################################# -# -# Main Body -# -############################################################ -# -# Setup environment -# -umask (002); - -# Connect to the database -$cvsbin = "/usr/bin"; - -# -# Initialize basic variables -# -$id = getpgrp(); -$state = $STATE_NONE; -$cvs_user = $ENV{'USER'} || getlogin || (getpwuid($<))[0] || sprintf("uid#%d",$<); -@files = process_argv(@ARGV); -@path = split('/', $files[0]); -if ($#path == 0) { - $dir = "."; -} else { - $dir = join('/', @path[1..$#path]); -} -#print("ARGV - ", join(":", @ARGV), "\n"); -#print("files - ", join(":", @files), "\n"); -#print("path - ", join(":", @path), "\n"); -#print("dir - ", $dir, "\n"); -#print("id - ", $id, "\n"); - -# -# Map the repository directory to an email address for commitlogs to be sent -# to. -# -#$mlist = &mlist_map($files[0]); - -########################## -# -# Check for a new directory first. This will always appear as a -# single item in the argument list, and an empty log message. -# -if ($ARGV[0] =~ /New directory/) { - $header = &build_header; - @text = (); - push(@text, $header); - push(@text, ""); - push(@text, " ".$ARGV[0]); - &mail_notification([ $mlist ], @text); - exit 0; -} - -# -# Iterate over the body of the message collecting information. -# -while () { - chomp; # Drop the newline - if (/^Revision\/Branch:/) { - s,^Revision/Branch:,,; - push (@branch_lines, split); - next; - } -# next if (/^[ \t]+Tag:/ && $state != $STATE_LOG); - if (/^Modified Files/) { $state = $STATE_CHANGED; next; } - if (/^Added Files/) { $state = $STATE_ADDED; next; } - if (/^Removed Files/) { $state = $STATE_REMOVED; next; } - if (/^Log Message/) { $state = $STATE_LOG; next; } - s/[ \t\n]+$//; # delete trailing space - - push (@changed_files, split) if ($state == $STATE_CHANGED); - push (@added_files, split) if ($state == $STATE_ADDED); - push (@removed_files, split) if ($state == $STATE_REMOVED); - if ($state == $STATE_LOG) { - if (/^PR:$/i || - /^Reviewed by:$/i || - /^Submitted by:$/i || - /^Obtained from:$/i) { - next; - } - push (@log_lines, $_); - } -} - -# -# Strip leading and trailing blank lines from the log message. Also -# compress multiple blank lines in the body of the message down to a -# single blank line. -# (Note, this only does the mail and changes log, not the rcs log). -# -while ($#log_lines > -1) { - last if ($log_lines[0] ne ""); - shift(@log_lines); -} -while ($#log_lines > -1) { - last if ($log_lines[$#log_lines] ne ""); - pop(@log_lines); -} -for ($i = $#log_lines; $i > 0; $i--) { - if (($log_lines[$i - 1] eq "") && ($log_lines[$i] eq "")) { - splice(@log_lines, $i, 1); - } -} - -# -# Find the log file that matches this log message -# -for ($i = 0; ; $i++) { - last if (! -e "$LOG_FILE.$i.$id.$cvs_user"); - @text = &read_logfile("$LOG_FILE.$i.$id.$cvs_user", ""); - last if ($#text == -1); - last if (join(" ", @log_lines) eq join(" ", @text)); -} - -# -# Spit out the information gathered in this pass. -# -&write_logfile("$LOG_FILE.$i.$id.$cvs_user", @log_lines); -&append_to_file("$BRANCH_FILE.$i.$id.$cvs_user", $dir, @branch_lines); -&append_to_file("$ADDED_FILE.$i.$id.$cvs_user", $dir, @added_files); -&append_to_file("$CHANGED_FILE.$i.$id.$cvs_user", $dir, @changed_files); -&append_to_file("$REMOVED_FILE.$i.$id.$cvs_user", $dir, @removed_files); -&append_line("$MLIST_FILE.$i.$id.$cvs_user", $mlist); -if ($rcsidinfo) { - &change_summary("$SUMMARY_FILE.$i.$id.$cvs_user", (@changed_files, @added_files)); -} - -# -# Check whether this is the last directory. If not, quit. -# -if (-e "$LAST_FILE.$id.$cvs_user") { - $_ = &read_line("$LAST_FILE.$id.$cvs_user"); - $tmpfiles = $files[0]; - $tmpfiles =~ s,([^a-zA-Z0-9_/]),\\$1,g; - if (! grep(/$tmpfiles$/, $_)) { - print "More commits to come...\n"; - exit 0 - } -} - -# -# This is it. The commits are all finished. Lump everything together -# into a single message, fire a copy off to the mailing list, and drop -# it on the end of the Changes file. -# -$header = &build_header; - -# -# Produce the final compilation of the log messages -# -@text = (); -@mlist_list = (); -push(@text, $header); -push(@text, ""); -for ($i = 0; ; $i++) { - last if (! -e "$LOG_FILE.$i.$id.$cvs_user"); - push(@text, &read_file("$BRANCH_FILE.$i.$id.$cvs_user", "Branch:")); - push(@text, &read_file("$CHANGED_FILE.$i.$id.$cvs_user", "Modified:")); - push(@text, &read_file("$ADDED_FILE.$i.$id.$cvs_user", "Added:")); - push(@text, &read_file("$REMOVED_FILE.$i.$id.$cvs_user", "Removed:")); - push(@text, " Log:"); - push(@text, &read_logfile("$LOG_FILE.$i.$id.$cvs_user", " ")); - push(@mlist_list, &read_file_lines("$MLIST_FILE.$i.$id.$cvs_user")); - if ($rcsidinfo == 2) { - if (-e "$SUMMARY_FILE.$i.$id.$cvs_user") { - push(@text, " "); - push(@text, " Revision Changes Path"); - push(@text, &read_logfile("$SUMMARY_FILE.$i.$id.$cvs_user", " ")); - } - } - push(@text, ""); -} - -# -# Now generate the extra info for the mail message.. -# -if ($rcsidinfo == 1) { - $revhdr = 0; - for ($i = 0; ; $i++) { - last if (! -e "$LOG_FILE.$i.$id.$cvs_user"); - if (-e "$SUMMARY_FILE.$i.$id.$cvs_user") { - if (!$revhdr++) { - push(@text, "Revision Changes Path"); - } - push(@text, &read_logfile("$SUMMARY_FILE.$i.$id.$cvs_user", "")); - } - } - if ($revhdr) { - push(@text, ""); # consistancy... - } -} - -%mlist_hash = (); - -foreach (@mlist_list) { $mlist_hash{ $_ } = 1; } - -# -# Mail out the notification. -# -&mail_notification([ keys(%mlist_hash) ], @text); -&cleanup_tmpfiles; -exit 0; diff --git a/contrib/cvs/contrib/mfpipe.in b/contrib/cvs/contrib/mfpipe.in deleted file mode 100755 index 0461a0c..0000000 --- a/contrib/cvs/contrib/mfpipe.in +++ /dev/null @@ -1,115 +0,0 @@ -#! @PERL@ -T -# -*-Perl-*- - -# Copyright (C) 1994-2005 The Free Software Foundation, Inc. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -############################################################################### -############################################################################### -############################################################################### -# -# THIS SCRIPT IS PROBABLY BROKEN. REMOVING THE -T SWITCH ON THE #! LINE ABOVE -# WOULD FIX IT, BUT THIS IS INSECURE. WE RECOMMEND FIXING THE ERRORS WHICH THE -# -T SWITCH WILL CAUSE PERL TO REPORT BEFORE RUNNING THIS SCRIPT FROM A CVS -# SERVER TRIGGER. PLEASE SEND PATCHES CONTAINING THE CHANGES YOU FIND -# NECESSARY TO RUN THIS SCRIPT WITH THE TAINT-CHECKING ENABLED BACK TO THE -# <@PACKAGE_BUGREPORT@> MAILING LIST. -# -# For more on general Perl security and taint-checking, please try running the -# `perldoc perlsec' command. -# -############################################################################### -############################################################################### -############################################################################### - -# From: clyne@niwot.scd.ucar.EDU (John Clyne) -# Date: Fri, 28 Feb 92 09:54:21 MST -# -# BTW, i wrote a perl script that is similar to 'nfpipe' except that in -# addition to logging to a file it provides a command line option for mailing -# change notices to a group of users. Obviously you probably wouldn't want -# to mail every change. But there may be certain directories that are commonly -# accessed by a group of users who would benefit from an email notice. -# Especially if they regularly beat on the same directory. Anyway if you -# think anyone would be interested here it is. -# -# File: mfpipe -# -# Author: John Clyne -# National Center for Atmospheric Research -# PO 3000, Boulder, Colorado -# -# Date: Wed Feb 26 18:34:53 MST 1992 -# -# Description: Tee standard input to mail a list of users and to -# a file. Used by CVS logging. -# -# Usage: mfpipe [-f file] [user@host...] -# -# Environment: CVSROOT -# Path to CVS root. -# -# Files: -# -# -# Options: -f file -# Capture output to 'file' -# - -$header = "Log Message:\n"; - -$mailcmd = "| mail -s 'CVS update notice'"; -$whoami = `whoami`; -chop $whoami; -$date = `date`; -chop $date; - -$cvsroot = $ENV{'CVSROOT'}; - -while (@ARGV) { - $arg = shift @ARGV; - - if ($arg eq '-f') { - $file = shift @ARGV; - } - else { - $users = "$users $arg"; - } -} - -if ($users) { - $mailcmd = "$mailcmd $users"; - open(MAIL, $mailcmd) || die "Execing $mail: $!\n"; -} - -if ($file) { - $logfile = "$cvsroot/LOG/$file"; - open(FILE, ">> $logfile") || die "Opening $logfile: $!\n"; -} - -print FILE "$whoami $date--------BEGIN LOG ENTRY-------------\n" if ($logfile); - -while (<>) { - print FILE $log if ($log && $logfile); - - print FILE $_ if ($logfile); - print MAIL $_ if ($users); - - $log = "log: " if ($_ eq $header); -} - -close FILE; -die "Write failed" if $?; -close MAIL; -die "Mail failed" if $?; - -exit 0; diff --git a/contrib/cvs/contrib/pvcs2rcs.in b/contrib/cvs/contrib/pvcs2rcs.in deleted file mode 100644 index 82f7f7b..0000000 --- a/contrib/cvs/contrib/pvcs2rcs.in +++ /dev/null @@ -1,1150 +0,0 @@ -#! @PERL@ -# --------------------------------- -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -########################################################################### -# FUNCTION: -# To recursively walk through a PVCS archive directory tree (archives -# located in VCS/ or vcs/ subdirectories) and convert them to RCS archives. -# The RCS archive name is the PVCS workfile name with ",v" appended. -# -# SYNTAX: -# pvcs_to_rcs.pl --help -# -# where -l indicates the operation is to be performed only in the current -# directory (no recursion) -# -# EXAMPLE: -# pvcs_to_rcs -# Would walk through every VCS or vcs subdir starting at the current directory, -# and produce corresponding RCS archives one level above the VCS or vcs subdir. -# (VCS/../RCS/) -# -# NOTES: -# * This script performs little error checking and logging -# (i.e. USE AT YOUR OWN RISK) -# * This script was last tested using ActiveState's port of Perl 5.005_02 -# (internalcut #507) under Win95, though it does compile under Perl-5.00404 -# for Solaris 2.4 run on a Solaris 2.6 system. The script crashed -# occasionally under ActiveState's port of Perl 5.003_07 but this stopped -# happening with the update so if you are having problems, try updating Perl. -# Upgrading to cut #507 also seemed to coincide with a large speed -# improvement, so try and keep up, hey? :) It was executed from MKS's -# UNIX tools version 6.1 for Win32's sh. ALWAYS redirect your output to -# a log!!! -# * PVCS archives are left intact -# * RCS archives are created in VCS/../RCS/ (or ./RCS using '-pflat') -# * Branch labels in this script will be attached to the CVS magic -# revision number. For branch a.b.c of a particular file, this means -# the label will be attached to revision a.b.0.c of the converted -# file. If you use the TrunkTip (1.*) label, be aware that it will convert -# to RCS revision 0.1, which is useless to RCS and CVS. You'll probably -# have to delete these. -# * All revisions are saved with correct "metadata" (i.e. check-in date, -# author, and log message). Any blank log message is replaced with -# "no comment". This is because RCS does not allow non-interactive -# check in of a new revision without a comment string. -# * Revision numbers are incremented by 1 during the conversion (since -# RCS does not allow revision 1.0). -# * All converted branch numbers are even (the CVS paradigm) -# * Version labels are assigned to the appropriate (incremented) revision -# numbers. PVCS allows spaces and periods in version labels while RCS -# does not. A global search and replace converts " " and "." to "_" -# There may be other cases that ought to be added. -# * Any working (checked-out) copies of PVCS archives -# within the VCS/../ or vcs/../ (or possibly ./ with '-pflat') -# will be deleted (or overwritten) depending on your mode of -# operation since the current ./ is used in the checkout of each revision. -# I suppose if development continues these files could be redirected to -# temp space rather than ./ . -# * Locks on PVCS archives should be removed (or the workfiles should be -# checked-in) prior to conversion, although the script will blaze through -# the archive nonetheless (But you would lose any checked out revision(s)) -# * The -kb option is added to the RCS archive for workfiles with the following -# extensions: .bin .out .btl .rom .a07 .lib .exe .tco .obj .t8u .c8u .o .lku -# .a and a few others. The %bin_ext variable holds these values in regexp -# form. -# * the --force-binary option can be used to convert binary files which don't -# have proper extensions, but I'd *probably* edit the %bin_ext variable. -# * This script will abort occasionally with the error "invalid revision -# number". This is known to happen when a revision comment has -# /^\s*Rev/ (Perl regexp notation) in it. Fix the comment and start over. -# (The directory locks and existance checking make this a fairly quick -# process.) -# * This script writes lockfiles in the RCS/ directories. It will also not -# convert an archive if it finds the RCS Archive existant in the RCS/ -# directory. This enables the conversion to quickly pick up where it left -# off after errors or interrupts occur. If you interrupt the script make -# sure you delete the last RCS Archive File which was being written. -# If you recieve the "Invalid revision number" error, then the RCS archive -# file for that particular PVCS file will not have been created yet. -# * This script will not create lockfiles when processing single -# filenames passed into the script, for hopefully obvious reasons. -# (lockfiles lock directories - DRP) -# * Log the output to a file. That makes it real easy to grep for errors -# later. (grep for "^[ \t]*(rcs|ci):" and be aware I might have missed -# a few cases (get? vcs?) !!!) *** Also note that this script will -# exibit some harmless RCS errors. Namely, it will attempt to lock -# branches which haven't been created yet. *** -# * I tried to keep the error and warning info up to date, but it seems -# to mean very little. This script almost always exits with a warning -# or an error that didn't seem to cause any harm. I didn't trace it -# and our imported source checks out and builds... -# It is probably happening when trying to convert empty directories -# or read files (possibly checked out workfiles ) which are not -# pvcs_archives. -# * You must use the -pflat option when processing single filenames -# passed as arguments to the script. This is probably a bug. -# * questions, comments, additions can be sent to info-cvs@nongnu.org -######################################################################### - - - -# -# USER Configurables -# - -# %bin_ext should be editable from the command line. -# -# NOTE: Each possible binary extension is listed as a Perl regexp -# -# The value associated with each regexp key is used to print a log -# message when a binary file is found. -my %bin_ext = - ( - '\.(?i)bin$' => "Binary", - '\.(?i)out$' => "Default Compiler Output", - '\.(?i)btl$' => "", - '\.(?i)rom$' => "", - '\.(?i)a07$' => "", - '\.(?i)lib$' => "DOS/Wintel/Netware Compiler Library", - '\.(?i)lif$' => "Netware Binary File", - '\.(?i)exe$' => "DOS/Wintel Executable", - '\.(?i)tco$' => "", - '\.(?i)obj$' => "DOS/Wintel Compiler Object", - '\.(?i)res$' => "DOS/Wintel Resource File", - '\.(?i)ico$' => "DOS/Wintel Icon File", - '\.(?i)nlm$' => "Netware Loadable Module", - '\.(?i)t8u$' => "", - '\.(?i)c8u$' => "", - '\.(?i)lku$' => "", - '\.(?i)(bmp|gif|jpg|jpeg|jfif|tif|tiff|xbm)$' => "Image", - '\.(?i)dll$' => "DOS/Wintel Dynamically Linked Library", - '\.o$' => "UNIX Compiler Object", - '\.a$' => "UNIX Compiler Library", - '\.so(\.\d+\.\d+)?$' => "UNIX Shared Library" - ); - -# The binaries this script is dependant on: -my @bin_dependancies = ("vcs", "vlog", "rcs", "ci"); - -# Where we should put temporary files -my $tmpdir = $ENV{TMPDIR} ? $ENV{TMPDIR} : "/var/tmp"; - -# We use these... -use strict; - -use Cwd; -use File::Path; -use IO::File; -use Getopt::Long; - $Getopt::Long::bundling = 1; -# $Getopt::Long::ignorecase = 0; - -my $usage = "\ -usage: $0 -h - $0 [-lt] [-i vcsid] [-r flat|leaf] [-p flat|leaf] [-x rcs_extension] - [-v none|locks|exists] [options] [path...] -"; - -my $help = "\ -$usage - ---------------------------- ----------------------------------- - -h | --Help Print this text - - General Settings - ---------------------------- ----------------------------------- - --Recurse Recurse through directories - (default) - -l | --NORecurse Process only . - --Errorfiles Save a count of conversion errors - in the RCS archive directory - (default) (unimplemented) - --NOErrorfiles Don't save a count of conversion - errors (unimplemented) - ( -m | --Mode ) Convert Convert PVCS files to RCS files - (default) - ( -m | --Mode ) Verify Perform verification ONLY (unimplemented) - ( -v | --VERIfy ) None Always replace existing RCS files - ( -v | --VERIfy ) LOCKS Same as exists unless a #conv.done - file exists in the RCS directory. - In that case, only the #conv.done - file's existance is verified for - that directory. (default) - ( -v | --VERIfy ) Exists Don't replace existing RCS files - ( -v | --VERIfy ) LOCKDates Verify that an existing RCS file's - last modification date is older - than that of the lockfile - (unimplemented) - ( -v | --VERIfy ) Revs Verify that the PVCS archive files - and RCS archive file contain the - same number of corresponding - revisions. Add only new revisions - to the RCS file. (unimplemented) - ( -v | --VERIfy ) Full Perform --verify=Revs and confirm - that the text of the revisions is - identical. Add only new revisions - unless an error is found. Then - erase the RCS archive and recreate - it. (unimplemented) - -t | --Test-binaries Use 'which' to check \$PATH for - the binaries required by this - script (default) - --NOTest-binaries Don't check for binaries - --VERBose Enable verbose output - --NOVerbose Disable verbose output (default) - -w | --Warnings Print warning messages (default) - --NOWarnings Don't print warning messages - - RCS Settings - ---------------------------- ----------------------------------- - ( -r | --RCS-Dirs ) leaf RCS files stored in ./RCS (default) - ( -r | --RCS-Dirs ) flat RCS files stored in . - (unimplemented) - ( -x | --RCS-Extension ) Set RCS file extension - (default = ',v') - --Force-binary Pass '-kb' to 'rcs -i' regardless of - the file extension - --NOForce-binary Only use '-kb' when the file has - a binary extension (default) - --Cvs-branch-labels Use CVS magic branch revision - numbers when attaching branch - labels (default) - --NOCvs-branch-labels Attach branch labels to RCS branch - revision numbers (unimplemented) - - PVCS Settings - ---------------------------- ----------------------------------- - ( -p | --Pvcs-dirs ) leaf PVCS files expected in ./VCS - (default) - ( -p | --Pvcs-dirs ) flat PVCS files expected in . - ( -i | --VCsid ) vcsid Use vcsid instead of \$VCSID - - -------------------------------------------------------------------------- - The optional path argument should contain the name of a file or directory - to convert. If not given, it will default to '.'. - -------------------------------------------------------------------------- -"; - - - -# -# Initialize globals -# - -my ($errors, $warnings) = (0, 0); -my ($curlevel, $maxlevel); -my ($rcs_base_command, $ci_base_command); -my ($donefile_name, $errorfile_name); - -# set up the default options -my %options = ( - recurse => 1, - mode => "convert", - errorfiles => 1, - 'rcs-dirs' => "leaf", - 'rcs-extension' => ",v", - 'force-binary' => 0, - 'cvs-branch-labels' => 1, - 'pvcs-dirs' => "leaf", - verify => "locks", - 'test-binaries' => 1, - vcsid => $ENV{VCSID} || "", - verbose => 0, - debug => 0, - warnings => 1 - ); - - - -# This is untested except under Solaris 2.4 or 2.6 and -# may not be portable -# -# I think the readline lib or some such has an interface -# which may enable this now. The perl installer sure looks -# like it's testing this kind of thing, anyhow. -sub hit_any_key - { - STDOUT->autoflush; - system "stty", "-icanon", "min", "1"; - - print "Hit any key to continue..."; - getc; - - system "stty", "icanon", "min", "0"; - STDOUT->autoflush (0); - - print "\nI always wondered where that key was...\n"; - } - - - -# print the usage -sub print_usage - { - my $fh = shift; - unless (ref $fh) - { - my $fdn = $fh ? $fh : "STDERR"; - $fh = new IO::File; - $fh->fdopen ($fdn, "w"); - } - - $fh->print ($usage); - } - -# print the help -sub print_help - { - my $fh = shift; - unless (ref $fh) - { - my $fdn = $fh ? $fh : "STDOUT"; - $fh = new IO::File; - $fh->fdopen ($fdn, "w"); - } - - $fh->print ($help); - } - -# print the help and exit $_[0] || 0 -sub exit_help - { - print_help; - exit shift || 0; - } - -sub error_count - { - my $type = shift or die "$0: error - error_count usage: error_count type [, ref] [, LIST]\n"; - my $error_count_ref; - my $outstring; - - if (ref ($_[0]) && ref ($_[0]) == "SCALAR") - { - $error_count_ref = shift; - } - else - { - $error_count_ref = \$errors; - } - $$error_count_ref++; - - push @_, "something wrong.\n" unless ( @_ > 0 ); - - $outstring = sprintf "$0: $type - " . join ("", @_); - $outstring .= sprintf " - $!\n" unless ($outstring =~ /\n$/); - - print STDERR $outstring; - - if ($options{errorfiles}) - { - my $fh = new IO::File ">>$errorfile_name" or new IO::File ">$errorfile_name"; - if ($fh) - { - $fh->print ($$error_count_ref . "\n"); - $fh->print ($outstring); - $fh->close; - } - else - { - my $cd = cwd; - print STDERR "$0: error - failed to open errorfile $cd/$errorfile_name - $!\n" - if ($options{debug}); - } - } - - return $$error_count_ref; - } - - - -# the main procedure that is run once in each directory -sub execdir - { - my $dir = shift; - my ($errors, $warnings) = (0, 0); # We return these error counters - my $old_dir = cwd; - - local ($_, @_); - - my $i; # Generic counter - my ($pvcsarchive, $workfile, $rcsarchive); # .??v, checked out file, and ,v files, - # respectively - my ($rev_count, $first_vl, $last_vl, $description, - $rev_index, @rev_num, %checked_in, %author, - $relative_comment_index, @comment_string, - %comment); - my ($num_version_labels, $label_index, @label_revision, $label, - @new_label, $rcs_rev); - my ($revision, %rcs_rev_num); - my ($get_output, $rcs_output, $ci_output, $mv_output); - my ($ci_command, $rcs_command, $wtr); - my @hits; - my ($num_fields); - my $skipdirlock; # if true, don't write conv.out - # used only for single file operations - # at the moment - my $cd; - - my @filenames; - # We may have recieved a single file name to process... - if ( -d $dir ) - { - # change into the directory to be processed - # open the current directory for listing - # initialize the list of filenames - # and set filenames equal to directory listing - unless ( ( chdir $dir ) and ( opendir CURDIR, "." ) and ( @filenames = readdir CURDIR ) ) - { - $cd = cwd; - error_count 'error', \$errors, "skipping directory $dir from $cd"; - chdir $old_dir or die "Failed to restore original directory ($old_dir): ", $!, ", stopped"; - return ($errors, $warnings); - } - - # clean up by closing the directory - closedir(CURDIR); - } - elsif ( -f $dir ) # we recieved a single file - { - push @filenames, $dir; - $skipdirlock = 1; - } - else - { - $cd = cwd; - error_count 'error', \$errors, "no such directory/file $dir from $cd\n"; - # chdir $old_dir or die "Failed to restore original directory ($old_dir): ", $!, ", stopped"; - return ($errors, $warnings); - } - - # save the current directory - $cd = cwd; - - # increment the global $curlevel variable - $curlevel = $curlevel +1; - - # initialize a list for any subdirectories and any files - # we need to process - my $vcsdir = ""; - my (@subdirs, $fn, $file, @files, @pvcsarchives); - - # print "$cd: " . join (", ", @filenames) . "\n"; - # hit_any_key; - - (@files, @pvcsarchives) = ( (), () ); - # begin a for loop to execute on each filename in the list @filename - foreach $fn (@filenames) - { - # if the file is a directory... - if (-d $fn) - { - # then if we are not expecting a flat arrangement of pvcs files - # and we found a vcs directory add its files to @pvcsarchives - if (!$options{'pvcs-dirs-flat'} and $fn =~ /^vcs$/i) - { - if ($options{verify} =~ /^locks$/ ) { - if ( -f $donefile_name ) { - print "Verified existence of lockfile $cd/$donefile_name." - . ( ($options{mode} =~ /^convert$/) ? " Skipping directory." : "" ) - . "\n" if ($options{verbose}); - next; - } elsif ( $options{mode} =~ /^verify$/ ) { - print "No lockfile found for $cd .\n"; - next; - } - } - - # else add the files in the vcs dir to our list of files to process - error_count 'warning', \$warnings, "Found two vcs dirs in directory $cd.\n" - if ($vcsdir and $options{warnings}); - - $vcsdir = $fn; - - unless ( ( opendir VCSDIR, $vcsdir ) and ( @files = readdir VCSDIR ) ) - { - error_count 'error', \$errors, "skipping directory &cd/$fn"; - next; - } - closedir VCSDIR; - - # and so we don't need to worry about where these - # files came from later... - foreach $file (@files) - { - push @pvcsarchives, "$vcsdir/$file" if (-f "$vcsdir/$file"); - } - - # don't want recursion here... - @pvcsarchives = grep !/^\.\.?$/, @pvcsarchives; - } - elsif ($fn !~ /^\.\.?$/) - { - next if (!$options{'rcs-dirs-flat'} and $fn =~ /^rcs$/i); - # include it in @subdir if it's not a parent directory - push(@subdirs,$fn); - } - } - # else if we are processing a flat arrangement of pvcs files... - elsif ($options{'pvcs-dirs-flat'} and -f $fn) - { - if ($options{verify} =~ /^locks$/) { - if ( -f $donefile_name) { - print "Found lockfile $cd/$donefile_name." - . ( ($options{mode} =~ /^convert$/) ? " Skipping directory." : "" ) - . "\n" if ($options{verbose}); - last; - } elsif ($options{mode} =~ /^verify$/) { - print "No lockfile found for $cd .\n"; - last; - } - } - # else add this to the list of files to process - push (@pvcsarchives, $fn); - } - } - - # print "pvcsarchives: " . join (", ", @pvcsarchives) . "\n"; - # print "subdirs: " . join (", ", @subdirs) . "\n"; - # hit_any_key; - - # for loop of subdirs - foreach (@subdirs) - { - # run execdir on each sub dir - if ($maxlevel >= $curlevel) - { - my ($e, $w) = execdir ($_); - $errors += $e; - $warnings += $w; - } - } - - # Print output header for each directory - print("Directory: $cd\n"); - - # the @files variable should already contain the list of files - # we should attempt to process - if ( @pvcsarchives && ( $options{mode} =~ /^convert$/ ) ) - { - # create an RCS directory in parent to store RCS files in - if ( !( $options{'rcs-dirs-flat'} or (-d "RCS") or mkpath ( "RCS" ) ) ) - { - error_count 'error', \$errors, "failed to make directory $cd/RCS - skipping directory $cd"; - @pvcsarchives = (); - # after all, we have nowhere to put them... - } - } - - # begin a for loop to execute on each filename in the list @files - foreach $pvcsarchive (@pvcsarchives) - { - my $got_workfile = 0; - my $got_version_labels = 0; - my $got_description = 0; - my $got_rev_count = 0; - - my $abs_file = $cd . "/" . $pvcsarchive; - - print("Verifying $abs_file...\n") if ($options{verbose}); - - print "vlog $pvcsarchive\n"; - my $vlog_output = `vlog $pvcsarchive`; - $_ = $vlog_output; - - # Split the vcs status output into individual lines - my @vlog_strings = split /\n/; - my $num_vlog_strings = @vlog_strings; - $_ = $vlog_strings[0]; - if ( /^\s*$/ || /^vlog: warning/ ) - { - error_count 'warning', \$warnings, "$abs_file is NOT a valid PVCS archive!!!\n"; - next; - } - - my $num; - # Collect all vlog output into appropriate variables - # - # This will ignore at the very least the /^\s*Archive:\s*/ field - # and maybe more. This should not be a problem. - for ( $num = 0; $num < $num_vlog_strings; $num++ ) - { - # print("$vlog_strings[$num]\n"); - $_ = $vlog_strings[$num]; - - if( ( /^Workfile:\s*/ ) && (!$got_workfile ) ) - { - my $num_fields; - - $got_workfile = 1; - # get the string to the right of the above search (with any path stripped) - $workfile = $'; - $_ = $workfile; - $num_fields = split /[\/\\]/; - if ( $num_fields > 1 ) - { - $workfile = $_[$num_fields - 1 ]; - } - - $rcsarchive = $options{'rcs-dirs-flat'} ? "" : "RCS/"; - $rcsarchive .= $workfile; - $rcsarchive .= $options{'rcs-extension'} if ($options{'rcs-extension'}); - print "Workfile is $workfile\n" if ($options{debug}); - } - - elsif ( ( /^Rev count:\s*/ ) && (!$got_rev_count ) ) - { - $got_rev_count = 1; - # get the string to the right of the above search - $rev_count = $'; - print "Revision count is $rev_count\n"; - } - - elsif ( ( /^Version labels:\s*/ ) && (!$got_version_labels ) ) - { - $got_version_labels = 1; - $first_vl = $num+1; - print "Version labels start at $first_vl\n" if ($options{debug}); - } - - elsif ( ( /^Description:\s*/ ) && (!$got_description ) ) - { - $got_description = 1; - $description = "\"" . $vlog_strings[$num+1] . "\""; - print "Description is $description\n" if ($options{debug}); - $last_vl = $num - 1; - } - - elsif ( /^Rev\s+/ ) # get all the revision information at once - { - $rev_index = 0; - @rev_num = (); - while ( $rev_index < $rev_count ) - { - $_ = $vlog_strings[$num]; - /^\s*Rev\s+(\d+\.(\d+\.\d+\.)*\d+)$/; - $rev_num[$rev_index] = $1; - print "Found revision: $rev_num[$rev_index]\n" if ($options{debug}); - die "Not a valid revision ($rev_num[$rev_index]).\n" - if ($rev_num[$rev_index] !~ /^(\d+\.)(\d+\.\d+\.)*\d+$/); - - $_ = $vlog_strings[$num+1]; - /^\s*Locked\s*/ and $num++; - - $_ = $vlog_strings[$num+1]; - /^\s*Checked in:\s*/; - $checked_in{$rev_num[$rev_index]} = "\"" . $' . "\""; - print "Checked in: $checked_in{$rev_num[$rev_index]}\n" if ($options{debug}); - - $_ = $vlog_strings[$num+3]; - /^\s*Author id:\s*/; - split; - $author{$rev_num[$rev_index]} = "\"" . $_[2] . "\""; - print "Author: $author{$rev_num[$rev_index]}\n" if ($options{debug}); - - my @branches = (); - $_ = $vlog_strings[$num+1]; - if (/^\s*Branches:\s*/) - { - $num++; - @branches = split /\s+/, $'; - } - - $relative_comment_index = 0; - @comment_string = (); - while( ( ( $num + 4 + $relative_comment_index ) < @vlog_strings) - && ( $vlog_strings[$num+4+$relative_comment_index] - !~ /^\s*Rev\s+(\d+\.(\d+\.\d+\.)*\d+)$/ ) ) - { - # We need the \n added for multi-line comments. There is no effect for - # single-line comments since RCS inserts the \n if it doesn't exist already - # print "Found commment line: $vlog_strings[$num+4+$relative_comment_index]\n" - # if ($options{debug}); - push @comment_string, $vlog_strings[$num+4+$relative_comment_index], "\n"; - $relative_comment_index += 1; - } - # print "Popped from comment: " . join ("", splice (@comment_string, -2)) - # . "\n" - # if ($options{debug}); - # Pop the "-+" or "=+" line from the comment - while ( (pop @comment_string) !~ /^-{35}|={35}$/ ) - {} - $comment{$rev_num[$rev_index]} = join "", @comment_string; - - $num += ( 4 + $relative_comment_index ); - print "Got comment for $rev_num[$rev_index]\n" if ($options{debug}); - print "comment string: $comment{$rev_num[$rev_index]}\n" if ($options{debug}); - $rev_index += 1; - } # while ( $rev_index < $rev_count ) - $num -= 1; #although there should be nothing left for this to matter - } # Get Rev information - } # for ($num = 0; $num < $num_vlog_strings; $num++) - # hit_any_key if ($options{debug}); - # Create RCS revision numbers corresponding to PVCS version numbers - foreach $revision (@rev_num) - { - $rcs_rev_num{ $revision } = &pvcs_to_rcs_rev_number( $revision ); - print"PVCS revision is $revision; RCS revision is $rcs_rev_num{ $revision }\n" - if ($options{debug}); - } - - # Sort the revision numbers - PVCS and RCS store them in different orders - # Clear @_ so we don't pass anything in by accident... - @_ = (); - @rev_num = sort revisions @rev_num; - print "Sorted rev_nums:\n" . join ("\n", @rev_num) . "\n" if ($options{debug}); - # hit_any_key; - - # Loop through each version label, checking for need to relabel ' ' with '_'. - $num_version_labels = $last_vl - $first_vl + 1; - print "Version label count is $num_version_labels\n"; - for( $i = $first_vl; $i <= $last_vl; $i += 1 ) - { - # print("$vlog_strings[$i]\n"); - $label_index = $i - $first_vl; - $_=$vlog_strings[$i]; - print "Starting with string '$_'\n" if ($options{debug}); - split /\"/; - $label = $_[1]; - print "Got label '$label'\n" if ($options{debug}); - split /\s+/, $_[2]; - $label_revision[$label_index] = $_[2]; - print "Original label is $label_revision[$label_index]\n" if ($options{debug}); - - # Create RCS revision numbers corresponding to PVCS version numbers by - # adding 1 to the revision number (# after last .) - $label_revision[ $label_index ] = pvcs_to_rcs_rev_number( $label_revision [ $label_index ] ); - # replace ' ' with '_', if needed - $_=$label; - $new_label[$label_index] = $label; - $new_label[$label_index] =~ s/ /_/g; - $new_label[$label_index] =~ s/\./_/g; - $new_label[$label_index] = "\"" . $new_label[$label_index] . "\""; - print"Label $new_label[$label_index] is for revision $label_revision[$label_index]\n" if ($options{debug}); - } - - ########## - # - # See if the RCS archive is up to date with the PVCS archive - # - ########## - if ($options{verify} =~ /^locks|exists$/ and -f $rcsarchive) - { - print "Verified existence of $cd/$rcsarchive." - . ( ($options{mode} =~ /^convert$/) ? " Skipping." : "" ) - . "\n" if ($options{verbose}); - next; - } - - # Create RCS archive and check in all revisions, then label. - my $first_time = 1; - foreach $revision (@rev_num) - { - # print "get -p$revision $pvcsarchive >$workfile\n"; - print "get -r$revision $pvcsarchive\n"; - # $vcs_output = `vcs -u -r$revision $pvcsarchive`; - # $get_output = `get -p$revision $pvcsarchive >$workfile`; - $get_output = `get -r$revision $pvcsarchive`; - - # if this is the first time, delete the rcs archive if it exists - # need for $options{verify} == none - unlink $rcsarchive if ($first_time and $options{verify} =~ /^none$/ and -f $rcsarchive); - - # Also check here whether this file ought to be "binary" - if ( $first_time ) - { - $rcs_command = "$rcs_base_command -i"; - if ( ( @hits = grep { $workfile =~ /$_/ } keys %bin_ext ) || $options{'force-binary'} ) - { - $rcs_command .= " -kb"; - $workfile =~ /$hits[0]/ if (@hits); - print "Binary attribute -kb added (" - . (@hits ? "file type is '$bin_ext{$hits[0]}' for extension '$&'" : "forced") - . ")\n"; - } - $first_time and $ci_command .= " -t-$description"; - - $rcs_command .= " $workfile"; - - # print and execute the rcs archive initialization command - print "$rcs_command\n"; - $wtr = new IO::File "|$rcs_command"; - $wtr->print ($description); - $wtr->print ("\n") unless ($description =~ /\n$/s); - $wtr->print (".\n"); - $wtr->close; - - # $rcs_output = `$rcs_base_command -i -kb $workfile`; - } - - # if this isn't the first time, we need to lock the rcs branch - # - # This is a little messy, but it works. Some extra locking is attempted. - # (This happens the first time a branch is used, at the least) - my $branch = ""; - my @branch; - @branch = split /\./, $rcs_rev_num{$revision}; - pop @branch; - $branch = join ".", @branch; - - $rcs_output = `$rcs_base_command -l$branch $workfile` if (!$first_time); - - # If an empty comment is specified, RCS will not check in the file; - # check for this case. (but an empty -t- description is fine - go figure!) - # Since RCS will pause and ask for a comment if one is not given, - # substitute a dummy comment "no comment". - $comment{$revision} =~ /^\s*$/ and $comment{$revision} = "no comment\n"; - - $ci_command = $ci_base_command; - $ci_command .= " -f -r$rcs_rev_num{$revision} -d$checked_in{$revision}" - . " -w$author{$revision}"; - - $ci_command .= " $workfile"; - - # print and execute the ci command - print "$ci_command\n"; - $wtr = new IO::File "|$ci_command"; - $wtr->print ($comment{$revision}); - $wtr->print ("\n") unless ($comment{$revision} =~ /\n$/s); - $wtr->print (".\n"); - $wtr->close; - # $ci_output = `$ci_command`; - # $ci_output = `cat $tmpdir/ci.out`; - - $first_time = 0 if ($first_time); - } # foreach revision - - # Attach version labels - for( $i = $num_version_labels - 1; $i >= 0; $i -= 1 ) - { - # print "rcs -x,v -n$new_label[$i]:$label_revision[$i] $workfile\n"; - $rcs_output = `$rcs_base_command -n$new_label[$i]:$label_revision[$i] $workfile`; - print "Version label $new_label[$i] added to revision $label_revision[$i]\n"; - } # foreach label - - # hit_any_key; - } # foreach pvcs archive file - - # We processed a vcs directory, so if there were any files, lock it. - # We are guaranteed to have made the attempt at - # - # $skipdirlock gets set if a single file name was passed to this function to enable - # a '$0 *' operation... - if ( @pvcsarchives && !$skipdirlock) - { - my $fh = new IO::File ">>$donefile_name" or new IO::File ">$donefile_name"; - if ($fh) - { - $fh->close; - } - else - { - error_count 'error', \$errors, "couldn't create lockfile $cd/$donefile_name"; - } - } - - $curlevel = $curlevel - 1; - - chdir $old_dir or die "Failed to restore original directory ($old_dir): ", $!, ", stopped"; - return ($errors, $warnings); - } - - - -# -# This function effectively does a cmp between two revision numbers -# It is intended to be passed into Perl's sort routine. -# -# the pvcs_out is not implemented well. It should probably be -# returnning $b[0] <=> $a[0] rather than $a[0] <=> $b[0] -# -# The @_ argument implementation was going to be used for revision -# comparison as an aid to remove the /^\sRev/ in revision comment -# error. The effort was fruitless at the time. -sub revisions - { - my @a = split /\./, (defined $a) ? $a : shift; - my @b = split /\./, (defined $b) ? $b : shift; - my $function = @_ ? shift : 'rcs_in'; - my ($i, $ret_val); - - die "Not enough arguments to revisions : a = ", join (".", @a), - "; b = ", join (".", @b), ", stopped" - unless (@a and @b); - - for ($i = 0; $i < scalar( @a ) && $i < scalar( @b ); $i++) - { - $a[$i] == $b[$i] or return ($a[$i] <=> $b[$i]); - } - - return 0 if (scalar (@a) == scalar (@b)); - - if ($function eq 'rcs_in') - { - return (($i == @b) || -1); - } - elsif ($function eq 'pvcs_out') - { - return (($i == @a) || -1); - } - else - { - die "error - Invalid function type passed to revisions ($function)", ", stopped"; - } - } - - - -sub pvcs_to_rcs_rev_number - { - my($input, $num_fields, @rev_string, $return_rev_num, $i); - - $input = $_[0]; - $_ = $input; - $num_fields = split /\./; - @rev_string = @_; - # @rev_string[$num_fields-1] += 1; - - for( $i = 1; $i < $num_fields; $i += 1 ) - { - if ( $i % 2 ) - { - # DRP: 10/1 - # RCS does not allow revision zero - $rev_string[ $i ] += 1; - } - elsif ( $i ) - { - # DRP: 10/1 - # Branches must have even references for compatibility - # with CVS's magic branch numbers. - # (Indexes 2, 4, 6...) - $rev_string[ $i ] *= 2; - } - } - - # If this is a branch revision # (PVCS: a.b.c.*) then we want the CVS - # revision # instead. It's okay to do this conversion here since we - # never commit to branches. We'll only get a PVCS revision # in that - # form when looking through the revision labels. - if ($input =~ /\*$/) - { - pop @rev_string; - push @rev_string, splice (@rev_string, -1, 1, "0"); - } - - $return_rev_num = join ".", @rev_string; - return $return_rev_num; - } - - - - - -### -### -### -### -### -### MAIN program: checks to see if there are command line parameters -### -### -### -### -### - - - - - -# and read the options -die $usage unless GetOptions (\%options, "h|help" => \&exit_help, - "recurse!", "mode|m=s", "errorfiles!", "l", "rcs-dirs|rcs-directories|r=s", - "pvcs-dirs|pvcs-directories|p=s", "test-binaries|t!", - "rcs-extension=s", "verify|v=s", "vcsid|i=s", "verbose!", "debug!", - "force-binary!", "cvs-branch-labels!", "warnings|w!"); - - - -# -# Special processing for -l !^#%$^@#$%#$ -# -# At the moment, -l overrides --recurse, regardless of the order the -# options were passed in -# -$options{recurse} = 0 if defined $options{l}; -delete $options{l}; - - - -# Make sure we got acceptable values for rcs-dirs and pvcs-dirs -my @hits = grep /^$options{'rcs-dirs'}/i, ("leaf", "flat"); -@hits == 1 or die - "$0: $options{'rcs-dirs'} invalid argument to --rcs-dirs or ambiguous\n" - . " abbreviation.\n" - . " Must be one of: 'leaf' or 'flat'.\n" - . $usage; -$options{'rcs-dirs'} = $hits[0]; -$options{'rcs-dirs-flat'} = ($options{'rcs-dirs'} =~ /flat/); -delete $options{'rcs-dirs'}; - -@hits = grep /^$options{'pvcs-dirs'}/i, ("leaf", "flat"); -@hits == 1 or die - "$0: $options{'pvcs-dirs'} invalid argument to --pvcs-dirs or ambiguous\n" - . " abbreviation.\n" - . " Must be one of: 'leaf' or 'flat'.\n" - . $usage; -$options{'pvcs-dirs'} = $hits[0]; -$options{'pvcs-dirs-flat'} = ($options{'pvcs-dirs'} =~ /flat/); -delete $options{'pvcs-dirs'}; - -# and for verify -@hits = grep /^$options{verify}/i, ("none", "locks", "exists", "lockdates", "revs", "full"); -@hits == 1 or die - "$0: $options{verify} invalid argument to --verify or ambiguous\n" - . " abbreviation.\n" - . " Must be one of: 'none', 'locks', 'exists', 'lockdates', 'revs',\n" - . " or 'full'.\n" - . $usage; -$options{verify} = $hits[0]; -$options{verify} =~ /^none|locks|exists$/ or die - "$0: --verify=$options{verify} unimplemented.\n" - . $usage; - -# and mode -@hits = grep /^$options{mode}/i, ("convert", "verify"); -@hits == 1 or die - "$0: $options{mode} invalid argument to --mode or ambiguous abbreviation.\n" - . " Must be 'convert' or 'verify'.\n" - . $usage; -$options{mode} = $hits[0]; - -$options{'cvs-branch-labels'} or die - "$0: RCS Branch Labels unimplemented.\n" - . $usage; - -# export VCSID into th environment for ourselves and our children -$ENV{VCSID} = $options{vcsid}; - - - -# -# Verify we have all the binary executables we need to run this script -# -# Allowed this feature to be disabled in case which is missing or we are -# running on a system which does not return error codes properly (e.g. WIN95) -# -# -- i.e. I don't feel like grepping output yet. -- -# -my @missing_binaries = (); -if ($options{'test-binaries'}) - { - foreach (@bin_dependancies) - { - if (system "which", $_) - { - push @missing_binaries, $_; - } - } - - if (scalar @missing_binaries) - { - print STDERR "The following executables were not found in your PATH: " - . join ( " ", @missing_binaries ) - . "\n" - . "You must correct this before continuing.\n"; - exit 1; - } - } -delete $options{'test-binaries'}; - - - -# -# set up our base archive manipulation commands -# - -# set up our rcs_command mods -$rcs_base_command = "rcs"; -$rcs_base_command .= " -x$options{'rcs-extension'}" if ($options{'rcs-extension'}); - -# set up our rcs_command mods -$ci_base_command = "ci"; -$ci_base_command .= " -x$options{'rcs-extension'}" if ($options{'rcs-extension'}); - - - -# -# So our logs fill in a manner we can monitor with 'tail -f' fairly easily: -# -STDERR->autoflush (1); -STDOUT->autoflush (1); - - - -# Initialize the globals we use to keep track of recursion -if ($options{recurse}) - { - $maxlevel = 10000; # Arbitrary recursion limit - } -else - { - $maxlevel = 1; - } -delete $options{recurse}; - -# So we can lock the directories behind us -$donefile_name = $options{'rcs-dirs-flat'} ? "" : "RCS/"; -$errorfile_name = $donefile_name . "#conv.errors"; -$donefile_name .= "#conv.done"; - - - -# -# start the whole thing and drop the return code on exit -# -push (@ARGV, ".") unless (@ARGV); -while ($_ = shift) - { - # reset the recursion level (corresponds to directory depth) - # level 0 is the first directory we enter... - $curlevel = -1; - my ($e, $w) = execdir($_); - $errors += $e; - $warnings += $w; - } - - - -print STDERR "$0: " . ($errors ? "Aborted" : "Done") . ".\n"; -print STDERR "$0: "; -print STDERR ($errors ? $errors : "No") . " error" . (($errors != 1) ? "s" : ""); -print STDERR ", " . ($warnings ? $warnings : "no") . " warning" . (($warnings != 1) ? "s" : "") - if ($options{warnings}); -print STDERR ".\n"; - - - -# -# Woo-hoo! We made it! -# -exit $errors; diff --git a/contrib/cvs/contrib/rcs-to-cvs.sh b/contrib/cvs/contrib/rcs-to-cvs.sh deleted file mode 100644 index 4db2578..0000000 --- a/contrib/cvs/contrib/rcs-to-cvs.sh +++ /dev/null @@ -1,193 +0,0 @@ -#! /bin/sh -# -# Copyright (c) 1989-2005 The Free Software Foundation, Inc. -# Portions Copyright (c) 1989, Brian Berliner -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# Based on the CVS 1.0 checkin csh script. -# Contributed by Per Cederqvist . -# Rewritten in sh by David MacKenzie . -# -############################################################################# -# -# Check in sources that previously were under RCS or no source control system. -# -# The repository is the directory where the sources should be deposited. -# -# Traverses the current directory, ensuring that an -# identical directory structure exists in the repository directory. It -# then checks the files in in the following manner: -# -# 1) If the file doesn't yet exist, check it in as revision 1.1 -# -# The script also is somewhat verbose in letting the user know what is -# going on. It prints a diagnostic when it creates a new file, or updates -# a file that has been modified on the trunk. -# -# Bugs: doesn't put the files in branch 1.1.1 -# doesn't put in release and vendor tags -# -############################################################################# - -usage="Usage: rcs-to-cvs [-v] [-m message] [-f message_file] repository" -vbose=0 -message="" -if [ -d /var/tmp ]; then message_file=/var/tmp/checkin.$$; else message_file=/usr/tmp/checkin.$$; fi -got_one=0 - -if [ $# -lt 1 ]; then - echo "$usage" >&2 - exit 1 -fi - -while [ $# -ne 0 ]; do - case "$1" in - -v) - vbose=1 - ;; - -m) - shift - echo $1 > $message_file - got_one=1 - ;; - -f) - shift - message_file=$1 - got_one=2 - ;; - *) - break - esac - shift -done - -if [ $# -lt 1 ]; then - echo "$usage" >&2 - exit 1 -fi - -repository=$1 -shift - -if [ -z "$CVSROOT" ]; then - echo "Please the environmental variable CVSROOT to the root" >&2 - echo " of the tree you wish to update" >&2 - exit 1 -fi - -if [ $got_one -eq 0 ]; then - echo "Please Edit this file to contain the RCS log information" >$message_file - echo "to be associated with this directory (please remove these lines)">>$message_file - ${EDITOR-vi} $message_file - got_one=1 -fi - -# Ya gotta share. -umask 0 - -update_dir=${CVSROOT}/${repository} -[ ! -d ${update_dir} ] && mkdir $update_dir - -if [ -d SCCS ]; then - echo SCCS files detected! >&2 - exit 1 -fi -if [ -d RCS ]; then - co RCS/* -fi - -for name in * .[a-zA-Z0-9]* -do - case "$name" in - RCS | *~ | \* | .\[a-zA-Z0-9\]\* ) continue ;; - esac - echo $name - if [ $vbose -ne 0 ]; then - echo "Updating ${repository}/${name}" - fi - if [ -d "$name" ]; then - if [ ! -d "${update_dir}/${name}" ]; then - echo "WARNING: Creating new directory ${repository}/${name}" - mkdir "${update_dir}/${name}" - if [ $? -ne 0 ]; then - echo "ERROR: mkdir failed - aborting" >&2 - exit 1 - fi - fi - cd "$name" - if [ $? -ne 0 ]; then - echo "ERROR: Couldn\'t cd to $name - aborting" >&2 - exit 1 - fi - if [ $vbose -ne 0 ]; then - $0 -v -f $message_file "${repository}/${name}" - else - $0 -f $message_file "${repository}/${name}" - fi - if [ $? -ne 0 ]; then - exit 1 - fi - cd .. - else # if not directory - if [ ! -f "$name" ]; then - echo "WARNING: $name is neither a regular file" - echo " nor a directory - ignored" - continue - fi - file="${update_dir}/${name},v" - comment="" - if grep -s '\$Log.*\$' "${name}"; then # If $Log keyword - myext=`echo $name | sed 's,.*\.,,'` - [ "$myext" = "$name" ] && myext= - case "$myext" in - c | csh | e | f | h | l | mac | me | mm | ms | p | r | red | s | sh | sl | cl | ml | el | tex | y | ye | yr | "" ) - ;; - - * ) - echo "For file ${file}:" - grep '\$Log.*\$' "${name}" - echo -n "Please insert a comment leader for file ${name} > " - read comment - ;; - esac - fi - if [ ! -f "$file" ]; then # If not exists in repository - if [ ! -f "${update_dir}/Attic/${name},v" ]; then - echo "WARNING: Creating new file ${repository}/${name}" - if [ -f RCS/"${name}",v ]; then - echo "MSG: Copying old rcs file." - cp RCS/"${name}",v "$file" - else - if [ -n "${comment}" ]; then - rcs -q -i -c"${comment}" -t${message_file} -m'.' "$file" - fi - ci -q -u1.1 -t${message_file} -m'.' "$file" - if [ $? -ne 0 ]; then - echo "ERROR: Initial check-in of $file failed - aborting" >&2 - exit 1 - fi - fi - else - file="${update_dir}/Attic/${name},v" - echo "WARNING: IGNORED: ${repository}/Attic/${name}" - continue - fi - else # File existed - echo "ERROR: File exists in repository: Ignored: $file" - continue - fi - fi -done - -[ $got_one -eq 1 ] && rm -f $message_file - -exit 0 diff --git a/contrib/cvs/contrib/rcs2log.sh b/contrib/cvs/contrib/rcs2log.sh deleted file mode 100644 index 29049b4..0000000 --- a/contrib/cvs/contrib/rcs2log.sh +++ /dev/null @@ -1,742 +0,0 @@ -#! /bin/sh - -# Copyright (C) 1995-2005 The Free Software Foundation, Inc. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -# RCS to ChangeLog generator - -# Generate a change log prefix from RCS files (perhaps in the CVS repository) -# and the ChangeLog (if any). -# Output the new prefix to standard output. -# You can edit this prefix by hand, and then prepend it to ChangeLog. - -# Ignore log entries that start with `#'. -# Clump together log entries that start with `{topic} ', -# where `topic' contains neither white space nor `}'. - -Help='The default FILEs are the files registered under the working directory. -Options: - - -c CHANGELOG Output a change log prefix to CHANGELOG (default ChangeLog). - -h HOSTNAME Use HOSTNAME in change log entries (default current host). - -i INDENT Indent change log lines by INDENT spaces (default 8). - -l LENGTH Try to limit log lines to LENGTH characters (default 79). - -L FILE Use rlog-format FILE for source of logs. - -R If no FILEs are given and RCS is used, recurse through working directory. - -r OPTION Pass OPTION to subsidiary log command. - -t TABWIDTH Tab stops are every TABWIDTH characters (default 8). - -u "LOGINFULLNAMEMAILADDR" Assume LOGIN has FULLNAME and MAILADDR. - -v Append RCS revision to file names in log lines. - --help Output help. - --version Output version number. - -Report bugs to .' - -Id='$Id: rcs2log,v 1.48 2001/09/05 23:07:46 eggert Exp $' - -# Copyright 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2001, 2003 -# Free Software Foundation, Inc. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; see the file COPYING. If not, write to the -# Free Software Foundation, Inc., 59 Temple Place - Suite 330, -# Boston, MA 02111-1307, USA. - -Copyright='Copyright 1992-2003 Free Software Foundation, Inc. -This program comes with NO WARRANTY, to the extent permitted by law. -You may redistribute copies of this program -under the terms of the GNU General Public License. -For more information about these matters, see the files named COPYING. -Author: Paul Eggert ' - -# functions -@MKTEMP_SH_FUNCTION@ - -# Use the traditional C locale. -LANG=C -LANGUAGE=C -LC_ALL=C -LC_COLLATE=C -LC_CTYPE=C -LC_MESSAGES=C -LC_NUMERIC=C -LC_TIME=C -export LANG LANGUAGE LC_ALL LC_COLLATE LC_CTYPE LC_MESSAGES LC_NUMERIC LC_TIME - -# These variables each contain a single ASCII character. -# Unfortunately, there's no portable way of writing these characters -# in older Unix implementations, other than putting them directly into -# this text file. -SOH='' # SOH, octal code 001 -tab=' ' -nl=' -' - -# Parse options. - -# defaults -: ${MKTEMP="@MKTEMP@"} -: ${AWK=awk} -: ${TMPDIR=/tmp} - -changelog=ChangeLog # change log file name -datearg= # rlog date option -hostname= # name of local host (if empty, will deduce it later) -indent=8 # indent of log line -length=79 # suggested max width of log line -logins= # login names for people we know fullnames and mailaddrs of -loginFullnameMailaddrs= # loginfullnamemailaddr triplets -logTZ= # time zone for log dates (if empty, use local time) -recursive= # t if we want recursive rlog -revision= # t if we want revision numbers -rlog_options= # options to pass to rlog -rlogfile= # log file to read from -tabwidth=8 # width of horizontal tab - -while : -do - case $1 in - -c) changelog=${2?}; shift;; - -i) indent=${2?}; shift;; - -h) hostname=${2?}; shift;; - -l) length=${2?}; shift;; - -L) rlogfile=${2?}; shift;; - -[nu]) # -n is obsolescent; it is replaced by -u. - case $1 in - -n) case ${2?}${3?}${4?} in - *"$tab"* | *"$nl"*) - echo >&2 "$0: -n '$2' '$3' '$4': tabs, newlines not allowed" - exit 1;; - esac - login=$2 - lfm=$2$tab$3$tab$4 - shift; shift; shift;; - -u) - # If $2 is not tab-separated, use colon for separator. - case ${2?} in - *"$nl"*) - echo >&2 "$0: -u '$2': newlines not allowed" - exit 1;; - *"$tab"*) - t=$tab;; - *) - t=':';; - esac - case $2 in - *"$t"*"$t"*"$t"*) - echo >&2 "$0: -u '$2': too many fields" - exit 1;; - *"$t"*"$t"*) - uf="[^$t]*$t" # An unselected field, followed by a separator. - sf="\\([^$t]*\\)" # The selected field. - login=`expr "X$2" : "X$sf"` - lfm="$login$tab"` - expr "X$2" : "$uf$sf" - `"$tab"` - expr "X$2" : "$uf$uf$sf" - `;; - *) - echo >&2 "$0: -u '$2': not enough fields" - exit 1;; - esac - shift;; - esac - case $logins in - '') logins=$login;; - ?*) logins=$logins$nl$login;; - esac - case $loginFullnameMailaddrs in - '') loginFullnameMailaddrs=$lfm;; - ?*) loginFullnameMailaddrs=$loginFullnameMailaddrs$nl$lfm;; - esac;; - -r) - case $rlog_options in - '') rlog_options=${2?};; - ?*) rlog_options=$rlog_options$nl${2?};; - esac - shift;; - -R) recursive=t;; - -t) tabwidth=${2?}; shift;; - -v) revision=t;; - --version) - set $Id - rcs2logVersion=$3 - echo >&2 "rcs2log (GNU Emacs) $rcs2logVersion$nl$Copyright" - exit 0;; - -*) echo >&2 "Usage: $0 [OPTION]... [FILE ...]$nl$Help" - case $1 in - --help) exit 0;; - *) exit 1;; - esac;; - *) break;; - esac - shift -done - -month_data=' - m[0]="Jan"; m[1]="Feb"; m[2]="Mar" - m[3]="Apr"; m[4]="May"; m[5]="Jun" - m[6]="Jul"; m[7]="Aug"; m[8]="Sep" - m[9]="Oct"; m[10]="Nov"; m[11]="Dec" -' - -logdir=`$MKTEMP -d $TMPDIR/rcs2log.XXXXXX` -test -n "$logdir" || exit -llogout=$logdir/l -trap exit 1 2 13 15 -trap "rm -fr $logdir 2>/dev/null" 0 - -# If no rlog-format log file is given, generate one into $rlogfile. -case $rlogfile in -'') - rlogfile=$logdir/r - - # If no rlog options are given, - # log the revisions checked in since the first ChangeLog entry. - # Since ChangeLog is only by date, some of these revisions may be duplicates of - # what's already in ChangeLog; it's the user's responsibility to remove them. - case $rlog_options in - '') - if test -s "$changelog" - then - e=' - /^[0-9]+-[0-9][0-9]-[0-9][0-9]/{ - # ISO 8601 date - print $1 - exit - } - /^... ... [ 0-9][0-9] [ 0-9][0-9]:[0-9][0-9]:[0-9][0-9] [0-9]+ /{ - # old-fashioned date and time (Emacs 19.31 and earlier) - '"$month_data"' - year = $5 - for (i=0; i<=11; i++) if (m[i] == $2) break - dd = $3 - printf "%d-%02d-%02d\n", year, i+1, dd - exit - } - ' - d=`$AWK "$e" <"$changelog"` || exit - case $d in - ?*) datearg="-d>$d";; - esac - fi;; - esac - - # Use TZ specified by ChangeLog local variable, if any. - if test -s "$changelog" - then - extractTZ=' - /^.*change-log-time-zone-rule['"$tab"' ]*:['"$tab"' ]*"\([^"]*\)".*/{ - s//\1/; p; q - } - /^.*change-log-time-zone-rule['"$tab"' ]*:['"$tab"' ]*t.*/{ - s//UTC0/; p; q - } - ' - logTZ=`tail "$changelog" | sed -n "$extractTZ"` - case $logTZ in - ?*) TZ=$logTZ; export TZ;; - esac - fi - - # If CVS is in use, examine its repository, not the normal RCS files. - if test ! -f CVS/Repository - then - rlog=rlog - repository= - else - rlog='cvs -q log' - repository=`sed 1q &2 "$0: $CVSROOT: CVSROOT has multiple ':/'s" - exit 1;; - *:/*) - # remote repository - pository=`expr "X$repository" : '.*:\(/.*\)'`;; - *) - # local repository - case $repository in - /*) ;; - *) repository=${CVSROOT?}/$repository;; - esac - if test ! -d "$repository" - then - echo >&2 "$0: $repository: bad repository (see CVS/Repository)" - exit 1 - fi - pository=$repository;; - esac - - # Ensure that $pository ends in exactly one slash. - while : - do - case $pository in - *//) pository=`expr "X$pository" : 'X\(.*\)/'`;; - */) break;; - *) pository=$pository/; break;; - esac - done - - fi - - # Use $rlog's -zLT option, if $rlog supports it. - case `$rlog -zLT 2>&1` in - *' option'*) ;; - *) - case $rlog_options in - '') rlog_options=-zLT;; - ?*) rlog_options=-zLT$nl$rlog_options;; - esac;; - esac - - # With no arguments, examine all files under the RCS directory. - case $# in - 0) - case $repository in - '') - oldIFS=$IFS - IFS=$nl - case $recursive in - t) - RCSdirs=`find . -name RCS -type d -print` - filesFromRCSfiles='s|,v$||; s|/RCS/|/|; s|^\./||' - files=` - { - case $RCSdirs in - ?*) find $RCSdirs \ - -type f \ - ! -name '*_' \ - ! -name ',*,' \ - ! -name '.*_' \ - ! -name .rcsfreeze.log \ - ! -name .rcsfreeze.ver \ - -print;; - esac - find . -name '*,v' -print - } | - sort -u | - sed "$filesFromRCSfiles" - `;; - *) - files= - for file in RCS/.* RCS/* .*,v *,v - do - case $file in - RCS/. | RCS/.. | RCS/,*, | RCS/*_) continue;; - RCS/.rcsfreeze.log | RCS/.rcsfreeze.ver) continue;; - RCS/.\* | RCS/\* | .\*,v | \*,v) test -f "$file" || continue;; - RCS/*,v | RCS/.*,v) ;; - RCS/* | RCS/.*) test -f "$file" || continue;; - esac - case $files in - '') files=$file;; - ?*) files=$files$nl$file;; - esac - done - case $files in - '') exit 0;; - esac;; - esac - set x $files - shift - IFS=$oldIFS;; - esac;; - esac - - case $datearg in - ?*) $rlog $rlog_options "$datearg" ${1+"$@"} >$rlogfile;; - '') $rlog $rlog_options ${1+"$@"} >$rlogfile;; - esac || exit;; -esac - - -# Get the full name of each author the logs mention, and set initialize_fullname -# to awk code that initializes the `fullname' awk associative array. -# Warning: foreign authors (i.e. not known in the passwd file) are mishandled; -# you have to fix the resulting output by hand. - -initialize_fullname= -initialize_mailaddr= - -case $loginFullnameMailaddrs in -?*) - case $loginFullnameMailaddrs in - *\"* | *\\*) - sed 's/["\\]/\\&/g' >$llogout <$llogout || exit - -output_authors='/^date: / { - if ($2 ~ /^[0-9]*[-\/][0-9][0-9][-\/][0-9][0-9]$/ && $3 ~ /^[0-9][0-9]:[0-9][0-9]:[0-9][0-9][-+0-9:]*;$/ && $4 == "author:" && $5 ~ /^[^;]*;$/) { - print substr($5, 1, length($5)-1) - } -}' -authors=` - $AWK "$output_authors" <"$rlogfile" | sort -u | comm -23 - $llogout -` -case $authors in -?*) - cat >$llogout </dev/null | - $AWK -F: "$awkscript" - `$initialize_fullname;; -esac - - -# Function to print a single log line. -# We don't use awk functions, to stay compatible with old awk versions. -# `Log' is the log message. -# `files' contains the affected files. -printlogline='{ - - # Following the GNU coding standards, rewrite - # * file: (function): comment - # to - # * file (function): comment - if (Log ~ /^\([^)]*\): /) { - i = index(Log, ")") - filefunc = substr(Log, 1, i) - while ((j = index(filefunc, "\n"))) { - files = files " " substr(filefunc, 1, j-1) - filefunc = substr(filefunc, j+1) - } - files = files " " filefunc - Log = substr(Log, i+3) - } - - # If "label: comment" is too long, break the line after the ":". - sep = " " - i = index(Log, "\n") - if ('"$length"' <= '"$indent"' + 1 + length(files) + i) sep = "\n" indent_string - - # Print the label. - printf "%s*%s:", indent_string, files - - # Print each line of the log. - while (i) { - logline = substr(Log, 1, i-1) - if (logline ~ /[^'"$tab"' ]/) { - printf "%s%s\n", sep, logline - } else { - print "" - } - sep = indent_string - Log = substr(Log, i+1) - i = index(Log, "\n") - } -}' - -# Pattern to match the `revision' line of rlog output. -rlog_revision_pattern='^revision [0-9]+\.[0-9]+(\.[0-9]+\.[0-9]+)*(['"$tab"' ]+locked by: [^'"$tab"' $,.0-9:;@]*[^'"$tab"' $,:;@][^'"$tab"' $,.0-9:;@]*;)?['"$tab"' ]*$' - -case $hostname in -'') - hostname=`( - hostname || uname -n || uuname -l || cat /etc/whoami - ) 2>/dev/null` || { - echo >&2 "$0: cannot deduce hostname" - exit 1 - } - - case $hostname in - *.*) ;; - *) - domainname=`(domainname) 2>/dev/null` && - case $domainname in - *.*) hostname=$hostname.$domainname;; - esac;; - esac;; -esac - - -# Process the rlog output, generating ChangeLog style entries. - -# First, reformat the rlog output so that each line contains one log entry. -# Transliterate \n to SOH so that multiline entries fit on a single line. -# Discard irrelevant rlog output. -$AWK ' - BEGIN { - pository = "'"$pository"'" - SOH="'"$SOH"'" - } - /^RCS file: / { - if (pository != "") { - filename = substr($0, 11) - if (substr(filename, 1, length(pository)) == pository) { - filename = substr(filename, length(pository) + 1) - } - if (filename ~ /,v$/) { - filename = substr(filename, 1, length(filename) - 2) - } - if (filename ~ /(^|\/)Attic\/[^\/]*$/) { - i = length(filename) - while (substr(filename, i, 1) != "/") i-- - filename = substr(filename, 1, i - 6) substr(filename, i + 1) - } - } - rev = "?" - } - /^Working file: / { if (repository == "") filename = substr($0, 15) } - /'"$rlog_revision_pattern"'/, /^(-----------*|===========*)$/ { - line = $0 - if (line ~ /'"$rlog_revision_pattern"'/) { - rev = $2 - next - } - if (line ~ /^date: [0-9][- +\/0-9:]*;/) { - date = $2 - if (date ~ /\//) { - # This is a traditional RCS format date YYYY/MM/DD. - # Replace "/"s with "-"s to get ISO format. - newdate = "" - while ((i = index(date, "/")) != 0) { - newdate = newdate substr(date, 1, i-1) "-" - date = substr(date, i+1) - } - date = newdate date - } - time = substr($3, 1, length($3) - 1) - author = substr($5, 1, length($5)-1) - printf "%s%s%s%s%s%s%s%s%s%s", filename, SOH, rev, SOH, date, SOH, time, SOH, author, SOH - rev = "?" - next - } - if (line ~ /^branches: /) { next } - if (line ~ /^(-----------*|===========*)$/) { print ""; next } - if (line == "Initial revision" || line ~ /^file .+ was initially added on branch .+\.$/) { - line = "New file." - } - printf "%s%s", line, SOH - } -' <"$rlogfile" | - -# Now each line is of the form -# FILENAME@REVISION@YYYY-MM-DD@HH:MM:SS[+-TIMEZONE]@AUTHOR@LOG -# where @ stands for an SOH (octal code 001), -# and each line of LOG is terminated by SOH instead of \n. -# Sort the log entries, first by date+time (in reverse order), -# then by author, then by log entry, and finally by file name and revision -# (just in case). -sort -t"$SOH" +2 -4r +4 +0 | - -# Finally, reformat the sorted log entries. -$AWK -F"$SOH" ' - BEGIN { - logTZ = "'"$logTZ"'" - revision = "'"$revision"'" - - # Initialize the fullname and mailaddr associative arrays. - '"$initialize_fullname"' - '"$initialize_mailaddr"' - - # Initialize indent string. - indent_string = "" - i = '"$indent"' - if (0 < '"$tabwidth"') - for (; '"$tabwidth"' <= i; i -= '"$tabwidth"') - indent_string = indent_string "\t" - while (1 <= i--) - indent_string = indent_string " " - } - - { - newlog = "" - for (i = 6; i < NF; i++) newlog = newlog $i "\n" - - # Ignore log entries prefixed by "#". - if (newlog ~ /^#/) { next } - - if (Log != newlog || date != $3 || author != $5) { - - # The previous log and this log differ. - - # Print the old log. - if (date != "") '"$printlogline"' - - # Logs that begin with "{clumpname} " should be grouped together, - # and the clumpname should be removed. - # Extract the new clumpname from the log header, - # and use it to decide whether to output a blank line. - newclumpname = "" - sep = "\n" - if (date == "") sep = "" - if (newlog ~ /^\{[^'"$tab"' }]*}['"$tab"' ]/) { - i = index(newlog, "}") - newclumpname = substr(newlog, 1, i) - while (substr(newlog, i+1) ~ /^['"$tab"' ]/) i++ - newlog = substr(newlog, i+1) - if (clumpname == newclumpname) sep = "" - } - printf sep - clumpname = newclumpname - - # Get ready for the next log. - Log = newlog - if (files != "") - for (i in filesknown) - filesknown[i] = 0 - files = "" - } - if (date != $3 || author != $5) { - # The previous date+author and this date+author differ. - # Print the new one. - date = $3 - time = $4 - author = $5 - - zone = "" - if (logTZ && ((i = index(time, "-")) || (i = index(time, "+")))) - zone = " " substr(time, i) - - # Print "date[ timezone] fullname ". - # Get fullname and email address from associative arrays; - # default to author and author@hostname if not in arrays. - if (fullname[author]) - auth = fullname[author] - else - auth = author - printf "%s%s %s ", date, zone, auth - if (mailaddr[author]) - printf "<%s>\n\n", mailaddr[author] - else - printf "<%s@%s>\n\n", author, "'"$hostname"'" - } - if (! filesknown[$1]) { - filesknown[$1] = 1 - if (files == "") files = " " $1 - else files = files ", " $1 - if (revision && $2 != "?") files = files " " $2 - } - } - END { - # Print the last log. - if (date != "") { - '"$printlogline"' - printf "\n" - } - } -' && - - -# Exit successfully. - -exec rm -fr $logdir - -# Local Variables: -# tab-width:4 -# End: diff --git a/contrib/cvs/contrib/rcs2sccs.sh b/contrib/cvs/contrib/rcs2sccs.sh deleted file mode 100644 index 535ebd0..0000000 --- a/contrib/cvs/contrib/rcs2sccs.sh +++ /dev/null @@ -1,156 +0,0 @@ -#! /bin/sh -# -# Copyright (C) 1995-2005 The Free Software Foundation, Inc. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# - -############################################################ -# Error checking -# -if [ ! -d SCCS ] ; then - mkdir SCCS -fi - -logfile=/tmp/rcs2sccs_$$_log -rm -f $logfile -tmpfile=/tmp/rcs2sccs_$$_tmp -rm -f $tmpfile -emptyfile=/tmp/rcs2sccs_$$_empty -echo -n "" > $emptyfile -initialfile=/tmp/rcs2sccs_$$_init -echo "Initial revision" > $initialfile -sedfile=/tmp/rcs2sccs_$$_sed -rm -f $sedfile -revfile=/tmp/rcs2sccs_$$_rev -rm -f $revfile -commentfile=/tmp/rcs2sccs_$$_comment -rm -f $commentfile - -# create the sed script -cat > $sedfile << EOF -s,;Id;,%Z%%M% %I% %E%,g -s,;SunId;,%Z%%M% %I% %E%,g -s,;RCSfile;,%M%,g -s,;Revision;,%I%,g -s,;Date;,%E%,g -s,;Id:.*;,%Z%%M% %I% %E%,g -s,;SunId:.*;,%Z%%M% %I% %E%,g -s,;RCSfile:.*;,%M%,g -s,;Revision:.*;,%I%,g -s,;Date:.*;,%E%,g -EOF -sed -e 's/;/\\$/g' $sedfile > $tmpfile -cp $tmpfile $sedfile -############################################################ -# Loop over every RCS file in RCS dir -# -if sort -k 1,1 /dev/null 2>/dev/null -then sort_each_field='-k 1 -k 2 -k 3 -k 4 -k 5 -k 6 -k 7 -k 8 -k 9' -else sort_each_field='+0 +1 +2 +3 +4 +5 +6 +7 +8' -fi -for vfile in *,v; do - # get rid of the ",v" at the end of the name - file=`echo $vfile | sed -e 's/,v$//'` - - # work on each rev of that file in ascending order - firsttime=1 - rlog $file | grep "^revision [0-9][0-9]*\." | awk '{print $2}' | sed -e 's/\./ /g' | sort -n -u $sort_each_field | sed -e 's/ /./g' > $revfile - for rev in `cat $revfile`; do - if [ $? != 0 ]; then - echo ERROR - revision - exit - fi - # get file into current dir and get stats - date=`rlog -r$rev $file | grep "^date: " | awk '{print $2; exit}' | sed -e 's/^19\|^20//'` - time=`rlog -r$rev $file | grep "^date: " | awk '{print $3; exit}' | sed -e 's/;//'` - author=`rlog -r$rev $file | grep "^date: " | awk '{print $5; exit}' | sed -e 's/;//'` - date="$date $time" - echo "" - rlog -r$rev $file | sed -e '/^branches: /d' -e '1,/^date: /d' -e '/^===========/d' -e 's/$/\\/' | awk '{if ((total += length($0) + 1) < 510) print $0}' > $commentfile - echo "==> file $file, rev=$rev, date=$date, author=$author" - rm -f $file - co -r$rev $file >> $logfile 2>&1 - if [ $? != 0 ]; then - echo ERROR - co - exit - fi - echo checked out of RCS - - # add SCCS keywords in place of RCS keywords - sed -f $sedfile $file > $tmpfile - if [ $? != 0 ]; then - echo ERROR - sed - exit - fi - echo performed keyword substitutions - rm -f $file - cp $tmpfile $file - - # check file into SCCS - if [ "$firsttime" = "1" ]; then - firsttime=0 - echo about to do sccs admin - echo sccs admin -n -i$file $file < $commentfile - sccs admin -n -i$file $file < $commentfile >> $logfile 2>&1 - if [ $? != 0 ]; then - echo ERROR - sccs admin - exit - fi - echo initial rev checked into SCCS - else - case $rev in - *.*.*.*) - brev=`echo $rev | sed -e 's/\.[0-9]*$//'` - sccs admin -fb $file 2>>$logfile - echo sccs get -e -p -r$brev $file - sccs get -e -p -r$brev $file >/dev/null 2>>$logfile - ;; - *) - echo sccs get -e -p $file - sccs get -e -p $file >/dev/null 2>> $logfile - ;; - esac - if [ $? != 0 ]; then - echo ERROR - sccs get - exit - fi - sccs delta $file < $commentfile >> $logfile 2>&1 - if [ $? != 0 ]; then - echo ERROR - sccs delta -r$rev $file - exit - fi - echo checked into SCCS - fi - sed -e "s;^d D $rev ../../.. ..:..:.. [^ ][^ ]*;d D $rev $date $author;" SCCS/s.$file > $tmpfile - rm -f SCCS/s.$file - cp $tmpfile SCCS/s.$file - chmod 444 SCCS/s.$file - sccs admin -z $file - if [ $? != 0 ]; then - echo ERROR - sccs admin -z - exit - fi - done - rm -f $file -done - - -############################################################ -# Clean up -# -echo cleaning up... -rm -f $tmpfile $emptyfile $initialfile $sedfile $commentfile -echo =================================================== -echo " Conversion Completed Successfully" -echo =================================================== - -rm -f *,v diff --git a/contrib/cvs/contrib/rcslock.in b/contrib/cvs/contrib/rcslock.in deleted file mode 100755 index be86f81..0000000 --- a/contrib/cvs/contrib/rcslock.in +++ /dev/null @@ -1,265 +0,0 @@ -#! @PERL@ -T -# -*-Perl-*- - -# Copyright (C) 1994-2005 The Free Software Foundation, Inc. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -############################################################################### -############################################################################### -############################################################################### -# -# THIS SCRIPT IS PROBABLY BROKEN. REMOVING THE -T SWITCH ON THE #! LINE ABOVE -# WOULD FIX IT, BUT THIS IS INSECURE. WE RECOMMEND FIXING THE ERRORS WHICH THE -# -T SWITCH WILL CAUSE PERL TO REPORT BEFORE RUNNING THIS SCRIPT FROM A CVS -# SERVER TRIGGER. PLEASE SEND PATCHES CONTAINING THE CHANGES YOU FIND -# NECESSARY TO RUN THIS SCRIPT WITH THE TAINT-CHECKING ENABLED BACK TO THE -# <@PACKAGE_BUGREPORT@> MAILING LIST. -# -# For more on general Perl security and taint-checking, please try running the -# `perldoc perlsec' command. -# -############################################################################### -############################################################################### -############################################################################### - -# Author: John Rouillard (rouilj@cs.umb.edu) -# Supported: Yeah right. (Well what do you expect for 2 hours work?) -# Blame-to: rouilj@cs.umb.edu -# Complaints to: Anybody except Brian Berliner, he's blameless for -# this script. -# Acknowlegements: The base code for this script has been acquired -# from the log.pl script. - -# rcslock.pl - A program to prevent commits when a file to be ckecked -# in is locked in the repository. - -# There are times when you need exclusive access to a file. This -# often occurs when binaries are checked into the repository, since -# cvs's (actually rcs's) text based merging mechanism won't work. This -# script allows you to use the rcs lock mechanism (rcs -l) to make -# sure that no changes to a repository are able to be committed if -# those changes would result in a locked file being changed. - -# WARNING: -# This script will work only if locking is set to strict. -# - -# Setup: -# Add the following line to the commitinfo file: - -# ALL /local/location/for/script/lockcheck [options] - -# Where ALL is replaced by any suitable regular expression. -# Options are -v for verbose info, or -d for debugging info. -# The %s will provide the repository directory name and the names of -# all changed files. - -# Use: -# When a developer needs exclusive access to a version of a file, s/he -# should use "rcs -l" in the repository tree to lock the version they -# are working on. CVS will automagically release the lock when the -# commit is performed. - -# Method: -# An "rlog -h" is exec'ed to give info on all about to be -# committed files. This (header) information is parsed to determine -# if any locks are outstanding and what versions of the file are -# locked. This filename, version number info is used to index an -# associative array. All of the files to be committed are checked to -# see if any locks are outstanding. If locks are outstanding, the -# version number of the current file (taken from the CVS/Entries -# subdirectory) is used in the key to determine if that version is -# locked. If the file being checked in is locked by the person doing -# the checkin, the commit is allowed, but if the lock is held on that -# version of a file by another person, the commit is not allowed. - -$ext = ",v"; # The extension on your rcs files. - -$\="\n"; # I hate having to put \n's at the end of my print statements -$,=' '; # Spaces should occur between arguments to print when printed - -# turn off setgid -# -$) = $(; - -# -# parse command line arguments -# -require 'getopts.pl'; - -&Getopts("vd"); # verbose or debugging - -# Verbose is useful when debugging -$opt_v = $opt_d if defined $opt_d; - -# $files[0] is really the name of the subdirectory. -# @files = split(/ /,$ARGV[0]); -@files = @ARGV[0..$#ARGV]; -$cvsroot = $ENV{'CVSROOT'}; - -# -# get login name -# -$login = getlogin || (getpwuid($<))[0] || "nobody"; - -# -# save the current directory since we have to return here to parse the -# CVS/Entries file if a lock is found. -# -$pwd = `/bin/pwd`; -chop $pwd; - -print "Starting directory is $pwd" if defined $opt_d ; - -# -# cd to the repository directory and check on the files. -# -print "Checking directory ", $files[0] if defined $opt_v ; - -if ( $files[0] =~ /^\// ) -{ - print "Directory path is $files[0]" if defined $opt_d ; - chdir $files[0] || die "Can't change to repository directory $files[0]" ; -} -else -{ - print "Directory path is $cvsroot/$files[0]" if defined $opt_d ; - chdir ($cvsroot . "/" . $files[0]) || - die "Can't change to repository directory $files[0] in $cvsroot" ; -} - - -# Open the rlog process and apss all of the file names to that one -# process to cut down on exec overhead. This may backfire if there -# are too many files for the system buffer to handle, but if there are -# that many files, chances are that the cvs repository is not set up -# cleanly. - -print "opening rlog -h @files[1..$#files] |" if defined $opt_d; - -open( RLOG, "rlog -h @files[1..$#files] |") || die "Can't run rlog command" ; - -# Create the locks associative array. The elements in the array are -# of two types: -# -# The name of the RCS file with a value of the total number of locks found -# for that file, -# or -# -# The name of the rcs file concatenated with the version number of the lock. -# The value of this element is the name of the locker. - -# The regular expressions used to split the rcs info may have to be changed. -# The current ones work for rcs 5.6. - -$lock = 0; - -while () -{ - chop; - next if /^$/; # ditch blank lines - - if ( $_ =~ /^RCS file: (.*)$/ ) - { - $curfile = $1; - next; - } - - if ( $_ =~ /^locks: strict$/ ) - { - $lock = 1 ; - next; - } - - if ( $lock ) - { - # access list: is the line immediately following the list of locks. - if ( /^access list:/ ) - { # we are done getting lock info for this file. - $lock = 0; - } - else - { # We are accumulating lock info. - - # increment the lock count - $locks{$curfile}++; - # save the info on the version that is locked. $2 is the - # version number $1 is the name of the locker. - $locks{"$curfile" . "$2"} = $1 - if /[ ]*([a-zA-Z._]*): ([0-9.]*)$/; - - print "lock by $1 found on $curfile version $2" if defined $opt_d; - - } - } -} - -# Lets go back to the starting directory and see if any locked files -# are ones we are interested in. - -chdir $pwd; - -# fo all of the file names (remember $files[0] is the directory name -foreach $i (@files[1..$#files]) -{ - if ( defined $locks{$i . $ext} ) - { # well the file has at least one lock outstanding - - # find the base version number of our file - &parse_cvs_entry($i,*entry); - - # is our version of this file locked? - if ( defined $locks{$i . $ext . $entry{"version"}} ) - { # if so, it is by us? - if ( $login ne ($by = $locks{$i . $ext . $entry{"version"}}) ) - {# crud somebody else has it locked. - $outstanding_lock++ ; - print "$by has file $i locked for version " , $entry{"version"}; - } - else - { # yeah I have it locked. - print "You have a lock on file $i for version " , $entry{"version"} - if defined $opt_v; - } - } - } -} - -exit $outstanding_lock; - - -### End of main program - -sub parse_cvs_entry -{ # a very simple minded hack at parsing an entries file. -local ( $file, *entry ) = @_; -local ( @pp ); - - -open(ENTRIES, "< CVS/Entries") || die "Can't open entries file"; - -while () - { - if ( $_ =~ /^\/$file\// ) - { - @pp = split('/'); - - $entry{"name"} = $pp[1]; - $entry{"version"} = $pp[2]; - $entry{"dates"} = $pp[3]; - $entry{"name"} = $pp[4]; - $entry{"name"} = $pp[5]; - $entry{"sticky"} = $pp[6]; - return; - } - } -} diff --git a/contrib/cvs/contrib/sccs2rcs.in b/contrib/cvs/contrib/sccs2rcs.in deleted file mode 100755 index 3be8e53..0000000 --- a/contrib/cvs/contrib/sccs2rcs.in +++ /dev/null @@ -1,327 +0,0 @@ -#! @CSH@ -f - -# Copyright (C) 1995-2005 The Free Software Foundation, Inc. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# Sccs2rcs is a script to convert an existing SCCS -# history into an RCS history without losing any of -# the information contained therein. -# It has been tested under the following OS's: -# SunOS 3.5, 4.0.3, 4.1 -# Ultrix-32 2.0, 3.1 -# -# Things to note: -# + It will NOT delete or alter your ./SCCS history under any circumstances. -# -# + Run in a directory where ./SCCS exists and where you can -# create ./RCS -# -# + /usr/local/bin is put in front of the default path. -# (SCCS under Ultrix is set-uid sccs, bad bad bad, so -# /usr/local/bin/sccs here fixes that) -# -# + Date, time, author, comments, branches, are all preserved. -# -# + If a command fails somewhere in the middle, it bombs with -# a message -- remove what it's done so far and try again. -# "rm -rf RCS; sccs unedit `sccs tell`; sccs clean" -# There is no recovery and exit is far from graceful. -# If a particular module is hanging you up, consider -# doing it separately; move it from the current area so that -# the next run will have a better chance or working. -# Also (for the brave only) you might consider hacking -# the s-file for simpler problems: I've successfully changed -# the date of a delta to be in sync, then run "sccs admin -z" -# on the thing. -# -# + After everything finishes, ./SCCS will be moved to ./old-SCCS. -# -# This file may be copied, processed, hacked, mutilated, and -# even destroyed as long as you don't tell anyone you wrote it. -# -# Ken Cox -# Viewlogic Systems, Inc. -# kenstir@viewlogic.com -# ...!harvard!cg-atla!viewlog!kenstir -# -# Various hacks made by Brian Berliner before inclusion in CVS contrib area. -# -# Modified to detect SCCS binary files. If binary, skip the keyword -# substitution and flag the RCS file as binary (using rcs -i -kb). -# -Allan G. Schrum schrum@ofsoptics.com agschrum@mindspring.com -# Fri Sep 26 10:40:40 EDT 2003 -# -# $FreeBSD$ - - -#we'll assume the user set up the path correctly -# for the Pmax, /usr/ucb/sccs is suid sccs, what a pain -# /usr/local/bin/sccs should override /usr/ucb/sccs there -set path = (/usr/local/bin $path) - - -############################################################ -# Error checking -# -if (! -w .) then - echo "Error: ./ not writeable by you." - exit 1 -endif -if (! -d SCCS) then - echo "Error: ./SCCS directory not found." - exit 1 -endif -set edits = (`sccs tell`) -if ($#edits) then - echo "Error: $#edits file(s) out for edit...clean up before converting." - exit 1 -endif -if (-d RCS) then - echo "Warning: RCS directory exists" - if (`ls -a RCS | wc -l` > 2) then - echo "Error: RCS directory not empty" - exit 1 - endif -else - mkdir RCS -endif - -sccs clean - -set logfile = /tmp/sccs2rcs_$$_log -rm -f $logfile -set tmpfile = /tmp/sccs2rcs_$$_tmp -rm -f $tmpfile -set emptyfile = /tmp/sccs2rcs_$$_empty -echo -n "" > $emptyfile -set initialfile = /tmp/sccs2rcs_$$_init -echo "Initial revision" > $initialfile -set sedfile = /tmp/sccs2rcs_$$_sed -rm -f $sedfile -set revfile = /tmp/sccs2rcs_$$_rev -rm -f $revfile - -# the quotes surround the dollar signs to fool RCS when I check in this script -set sccs_keywords = (\ - '%W%[ ]*%G%'\ - '%W%[ ]*%E%'\ - '%W%'\ - '%Z%%M%[ ]*%I%[ ]*%G%'\ - '%Z%%M%[ ]*%I%[ ]*%E%'\ - '%M%[ ]*%I%[ ]*%G%'\ - '%M%[ ]*%I%[ ]*%E%'\ - '%M%'\ - '%I%'\ - '%G%'\ - '%E%'\ - '%U%') -set rcs_keywords = (\ - '$'Id'$'\ - '$'Id'$'\ - '$'Id'$'\ - '$'SunId'$'\ - '$'SunId'$'\ - '$'Id'$'\ - '$'Id'$'\ - '$'RCSfile'$'\ - '$'Revision'$'\ - '$'Date'$'\ - '$'Date'$'\ - '') - - -############################################################ -# Get some answers from user -# -echo "" -echo "Do you want to be prompted for a description of each" -echo "file as it is checked in to RCS initially?" -echo -n "(y=prompt for description, n=null description) [y] ?" -set ans = $< -if ((_$ans == _) || (_$ans == _y) || (_$ans == _Y)) then - set nodesc = 0 -else - set nodesc = 1 -endif -echo "" -echo "The default keyword substitutions are as follows and are" -echo "applied in the order specified:" -set i = 1 -while ($i <= $#sccs_keywords) -# echo ' '\"$sccs_keywords[$i]\"' ==> '\"$rcs_keywords[$i]\" - echo " $sccs_keywords[$i] ==> $rcs_keywords[$i]" - @ i = $i + 1 -end -echo "" -echo -n "Do you want to change them [n] ?" -set ans = $< -if ((_$ans != _) && (_$ans != _n) && (_$ans != _N)) then - echo "You can't always get what you want." - echo "Edit this script file and change the variables:" - echo ' $sccs_keywords' - echo ' $rcs_keywords' -else - echo "good idea." -endif - -# create the sed script -set i = 1 -while ($i <= $#sccs_keywords) - echo "s,$sccs_keywords[$i],$rcs_keywords[$i],g" >> $sedfile - @ i = $i + 1 -end - -onintr ERROR - -sort -k 1,1 /dev/null >& /dev/null -if ($status == 0) then - set sort_each_field = '-k 1 -k 2 -k 3 -k 4 -k 5 -k 6 -k 7 -k 8 -k 9' -else - set sort_each_field = '+0 +1 +2 +3 +4 +5 +6 +7 +8' -endif - -############################################################ -# Loop over every s-file in SCCS dir -# -foreach sfile (SCCS/s.*) - # get rid of the "s." at the beginning of the name - set file = `echo $sfile:t | sed -e "s/^..//"` - - # work on each rev of that file in ascending order - set firsttime = 1 - - # Only scan the file up to the "I" keyword, then see if - # the "f" keyword is set to binary. The SCCS file has - # -aI denoting the start of the file (or end of header). - set binary = (`sed -e '/^.I/,$d' < $sfile | grep '^.f e 1$'`) - #if ($#binary) then - # echo This is a binary file - #else - # echo This is not a binary file - #endif - - sccs prs $file | grep "^D " | @AWK@ '{print $2}' | sed -e 's/\./ /g' | sort -n -u $sort_each_field | sed -e 's/ /./g' > $revfile - foreach rev (`cat $revfile`) - if ($status != 0) goto ERROR - - # get file into current dir and get stats - - # Is the substr stuff and the +0 in the following awk script really - # necessary? It seems to me that if we didn't find the date format - # we expected in the output we have other problems. - # Note: Solaris awk does not like the following line. Use gawk - # mawk, or nawk instead. - set date = `sccs prs -r$rev $file | @AWK@ '/^D / {print (substr($3,0,2)+0<70?20:19) $3, $4; exit}'` - set author = `sccs prs -r$rev $file | @AWK@ '/^D / {print $5; exit}'` - echo "" - echo "==> file $file, rev=$rev, date=$date, author=$author" - sccs edit -r$rev $file >>& $logfile - if ($status != 0) goto ERROR - echo checked out of SCCS - - # add RCS keywords in place of SCCS keywords (only if not binary) - if ($#binary == 0) then - sed -f $sedfile $file > $tmpfile - if ($status != 0) goto ERROR - echo performed keyword substitutions - cp $tmpfile $file - endif - - # check file into RCS - if ($firsttime) then - set firsttime = 0 - - if ($#binary) then - echo this is a binary file - # Mark initial, empty file as binary - rcs -i -kb -t$emptyfile $file - endif - - if ($nodesc) then - echo about to do ci - echo ci -f -r$rev -d"$date" -w$author -t$emptyfile $file - ci -f -r$rev -d"$date" -w$author -t$emptyfile $file < $initialfile >>& $logfile - if ($status != 0) goto ERROR - echo initial rev checked into RCS without description - else - echo "" - echo Enter a brief description of the file $file \(end w/ Ctrl-D\): - cat > $tmpfile - ci -f -r$rev -d"$date" -w$author -t$tmpfile $file < $initialfile >>& $logfile - if ($status != 0) goto ERROR - echo initial rev checked into RCS - endif - else - # get RCS lock - set lckrev = `echo $rev | sed -e 's/\.[0-9]*$//'` - if ("$lckrev" =~ [0-9]*.*) then - # need to lock the brach -- it is OK if the lock fails - rcs -l$lckrev $file >>& $logfile - else - # need to lock the trunk -- must succeed - rcs -l $file >>& $logfile - if ($status != 0) goto ERROR - endif - echo got lock - sccs prs -r$rev $file | grep "." > $tmpfile - # it's OK if grep fails here and gives status == 1 - # put the delta message in $tmpfile - ed $tmpfile >>& $logfile <>& $logfile - if ($status != 0) goto ERROR - echo checked into RCS - endif - sccs unedit $file >>& $logfile - if ($status != 0) goto ERROR - end - rm -f $file -end - - -############################################################ -# Clean up -# -echo cleaning up... -mv SCCS old-SCCS -rm -f $tmpfile $emptyfile $initialfile $sedfile -echo =================================================== -echo " Conversion Completed Successfully" -echo "" -echo " SCCS history now in old-SCCS/" -echo =================================================== -set exitval = 0 -goto cleanup - -ERROR: -foreach f (`sccs tell`) - sccs unedit $f -end -echo "" -echo "" -echo Danger\! Danger\! -echo Some command exited with a non-zero exit status. -echo Log file exists in $logfile. -echo "" -echo Incomplete history in ./RCS -- remove it -echo Original unchanged history in ./SCCS -set exitval = 1 - -cleanup: -# leave log file -rm -f $tmpfile $emptyfile $initialfile $sedfile $revfile - -exit $exitval diff --git a/contrib/cvs/cvs-format.el b/contrib/cvs/cvs-format.el deleted file mode 100644 index 06dcc62..0000000 --- a/contrib/cvs/cvs-format.el +++ /dev/null @@ -1,93 +0,0 @@ -;; -*- lisp-interaction -*- -;; -*- emacs-lisp -*- -;; -;; Set emacs up for editing code using CVS indentation conventions. -;; See HACKING for more on what those conventions are. -;; To use, put in your .emacs: -;; (load "c-mode") -;; (load "cvs-format.el") -;; You need to load c-mode first or else when c-mode autoloads it will -;; clobber the settings from cvs-format.el. Using c-mode-hook perhaps would -;; be a cleaner way to handle that. Or see below about (set-c-style "BSD"). -;; -;; Credits: Originally from the personal .emacs file of Rich Pixley, -;; then rich@cygnus.com, circa 1992. He sez "feel free to copy." -;; - -;; -;; -;; This section sets constants used by c-mode for formating -;; -;; - -;; If `c-auto-newline' is non-`nil', newlines are inserted both -;;before and after braces that you insert, and after colons and semicolons. -;;Correct C indentation is done on all the lines that are made this way. - -(setq c-auto-newline nil) - - -;;*Non-nil means TAB in C mode should always reindent the current line, -;;regardless of where in the line point is when the TAB command is used. -;;It might be desirable to set this to nil for CVS, since unlike GNU -;; CVS often uses comments over to the right separated by TABs. -;; Depends some on whether you're in the habit of using TAB to -;; reindent. -;(setq c-tab-always-indent nil) - -;;; It seems to me that -;;; `M-x set-c-style BSD RET' -;;; or -;;; (set-c-style "BSD") -;;; takes care of the indentation parameters correctly. - - -;; C does not have anything analogous to particular function names for which -;;special forms of indentation are desirable. However, it has a different -;;need for customization facilities: many different styles of C indentation -;;are in common use. -;; -;; There are six variables you can set to control the style that Emacs C -;;mode will use. -;; -;;`c-indent-level' -;; Indentation of C statements within surrounding block. The surrounding -;; block's indentation is the indentation of the line on which the -;; open-brace appears. - -(setq c-indent-level 4) - -;;`c-continued-statement-offset' -;; Extra indentation given to a substatement, such as the then-clause of -;; an if or body of a while. - -(setq c-continued-statement-offset 4) - -;;`c-brace-offset' -;; Extra indentation for line if it starts with an open brace. - -(setq c-brace-offset -4) - -;;`c-brace-imaginary-offset' -;; An open brace following other text is treated as if it were this far -;; to the right of the start of its line. - -(setq c-brace-imaginary-offset 0) - -;;`c-argdecl-indent' -;; Indentation level of declarations of C function arguments. - -(setq c-argdecl-indent 4) - -;;`c-label-offset' -;; Extra indentation for line that is a label, or case or default. -;; This doesn't quite do the right thing for CVS switches, which use the -;; switch (foo) -;; { -;; case 0: -;; break; -;; style. But if one manually aligns the first case, then the rest -;; should work OK. -(setq c-label-offset -4) - -;;;; eof diff --git a/contrib/cvs/depcomp b/contrib/cvs/depcomp deleted file mode 100755 index ca5ea4e..0000000 --- a/contrib/cvs/depcomp +++ /dev/null @@ -1,584 +0,0 @@ -#! /bin/sh -# depcomp - compile a program generating dependencies as side-effects - -scriptversion=2006-10-15.18 - -# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006 Free Software -# Foundation, Inc. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -# 02110-1301, USA. - -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - -# Originally written by Alexandre Oliva . - -case $1 in - '') - echo "$0: No command. Try \`$0 --help' for more information." 1>&2 - exit 1; - ;; - -h | --h*) - cat <<\EOF -Usage: depcomp [--help] [--version] PROGRAM [ARGS] - -Run PROGRAMS ARGS to compile a file, generating dependencies -as side-effects. - -Environment variables: - depmode Dependency tracking mode. - source Source file read by `PROGRAMS ARGS'. - object Object file output by `PROGRAMS ARGS'. - DEPDIR directory where to store dependencies. - depfile Dependency file to output. - tmpdepfile Temporary file to use when outputing dependencies. - libtool Whether libtool is used (yes/no). - -Report bugs to . -EOF - exit $? - ;; - -v | --v*) - echo "depcomp $scriptversion" - exit $? - ;; -esac - -if test -z "$depmode" || test -z "$source" || test -z "$object"; then - echo "depcomp: Variables source, object and depmode must be set" 1>&2 - exit 1 -fi - -# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. -depfile=${depfile-`echo "$object" | - sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} -tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} - -rm -f "$tmpdepfile" - -# Some modes work just like other modes, but use different flags. We -# parameterize here, but still list the modes in the big case below, -# to make depend.m4 easier to write. Note that we *cannot* use a case -# here, because this file can only contain one case statement. -if test "$depmode" = hp; then - # HP compiler uses -M and no extra arg. - gccflag=-M - depmode=gcc -fi - -if test "$depmode" = dashXmstdout; then - # This is just like dashmstdout with a different argument. - dashmflag=-xM - depmode=dashmstdout -fi - -case "$depmode" in -gcc3) -## gcc 3 implements dependency tracking that does exactly what -## we want. Yay! Note: for some reason libtool 1.4 doesn't like -## it if -MD -MP comes after the -MF stuff. Hmm. -## Unfortunately, FreeBSD c89 acceptance of flags depends upon -## the command line argument order; so add the flags where they -## appear in depend2.am. Note that the slowdown incurred here -## affects only configure: in makefiles, %FASTDEP% shortcuts this. - for arg - do - case $arg in - -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;; - *) set fnord "$@" "$arg" ;; - esac - shift # fnord - shift # $arg - done - "$@" - stat=$? - if test $stat -eq 0; then : - else - rm -f "$tmpdepfile" - exit $stat - fi - mv "$tmpdepfile" "$depfile" - ;; - -gcc) -## There are various ways to get dependency output from gcc. Here's -## why we pick this rather obscure method: -## - Don't want to use -MD because we'd like the dependencies to end -## up in a subdir. Having to rename by hand is ugly. -## (We might end up doing this anyway to support other compilers.) -## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like -## -MM, not -M (despite what the docs say). -## - Using -M directly means running the compiler twice (even worse -## than renaming). - if test -z "$gccflag"; then - gccflag=-MD, - fi - "$@" -Wp,"$gccflag$tmpdepfile" - stat=$? - if test $stat -eq 0; then : - else - rm -f "$tmpdepfile" - exit $stat - fi - rm -f "$depfile" - echo "$object : \\" > "$depfile" - alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz -## The second -e expression handles DOS-style file names with drive letters. - sed -e 's/^[^:]*: / /' \ - -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" -## This next piece of magic avoids the `deleted header file' problem. -## The problem is that when a header file which appears in a .P file -## is deleted, the dependency causes make to die (because there is -## typically no way to rebuild the header). We avoid this by adding -## dummy dependencies for each header file. Too bad gcc doesn't do -## this for us directly. - tr ' ' ' -' < "$tmpdepfile" | -## Some versions of gcc put a space before the `:'. On the theory -## that the space means something, we add a space to the output as -## well. -## Some versions of the HPUX 10.20 sed can't process this invocation -## correctly. Breaking it into two sed invocations is a workaround. - sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" - rm -f "$tmpdepfile" - ;; - -hp) - # This case exists only to let depend.m4 do its work. It works by - # looking at the text of this script. This case will never be run, - # since it is checked for above. - exit 1 - ;; - -sgi) - if test "$libtool" = yes; then - "$@" "-Wp,-MDupdate,$tmpdepfile" - else - "$@" -MDupdate "$tmpdepfile" - fi - stat=$? - if test $stat -eq 0; then : - else - rm -f "$tmpdepfile" - exit $stat - fi - rm -f "$depfile" - - if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files - echo "$object : \\" > "$depfile" - - # Clip off the initial element (the dependent). Don't try to be - # clever and replace this with sed code, as IRIX sed won't handle - # lines with more than a fixed number of characters (4096 in - # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; - # the IRIX cc adds comments like `#:fec' to the end of the - # dependency line. - tr ' ' ' -' < "$tmpdepfile" \ - | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \ - tr ' -' ' ' >> $depfile - echo >> $depfile - - # The second pass generates a dummy entry for each header file. - tr ' ' ' -' < "$tmpdepfile" \ - | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ - >> $depfile - else - # The sourcefile does not contain any dependencies, so just - # store a dummy comment line, to avoid errors with the Makefile - # "include basename.Plo" scheme. - echo "#dummy" > "$depfile" - fi - rm -f "$tmpdepfile" - ;; - -aix) - # The C for AIX Compiler uses -M and outputs the dependencies - # in a .u file. In older versions, this file always lives in the - # current directory. Also, the AIX compiler puts `$object:' at the - # start of each line; $object doesn't have directory information. - # Version 6 uses the directory in both cases. - stripped=`echo "$object" | sed 's/\(.*\)\..*$/\1/'` - tmpdepfile="$stripped.u" - if test "$libtool" = yes; then - "$@" -Wc,-M - else - "$@" -M - fi - stat=$? - - if test -f "$tmpdepfile"; then : - else - stripped=`echo "$stripped" | sed 's,^.*/,,'` - tmpdepfile="$stripped.u" - fi - - if test $stat -eq 0; then : - else - rm -f "$tmpdepfile" - exit $stat - fi - - if test -f "$tmpdepfile"; then - outname="$stripped.o" - # Each line is of the form `foo.o: dependent.h'. - # Do two passes, one to just change these to - # `$object: dependent.h' and one to simply `dependent.h:'. - sed -e "s,^$outname:,$object :," < "$tmpdepfile" > "$depfile" - sed -e "s,^$outname: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile" - else - # The sourcefile does not contain any dependencies, so just - # store a dummy comment line, to avoid errors with the Makefile - # "include basename.Plo" scheme. - echo "#dummy" > "$depfile" - fi - rm -f "$tmpdepfile" - ;; - -icc) - # Intel's C compiler understands `-MD -MF file'. However on - # icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c - # ICC 7.0 will fill foo.d with something like - # foo.o: sub/foo.c - # foo.o: sub/foo.h - # which is wrong. We want: - # sub/foo.o: sub/foo.c - # sub/foo.o: sub/foo.h - # sub/foo.c: - # sub/foo.h: - # ICC 7.1 will output - # foo.o: sub/foo.c sub/foo.h - # and will wrap long lines using \ : - # foo.o: sub/foo.c ... \ - # sub/foo.h ... \ - # ... - - "$@" -MD -MF "$tmpdepfile" - stat=$? - if test $stat -eq 0; then : - else - rm -f "$tmpdepfile" - exit $stat - fi - rm -f "$depfile" - # Each line is of the form `foo.o: dependent.h', - # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. - # Do two passes, one to just change these to - # `$object: dependent.h' and one to simply `dependent.h:'. - sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" - # Some versions of the HPUX 10.20 sed can't process this invocation - # correctly. Breaking it into two sed invocations is a workaround. - sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" | - sed -e 's/$/ :/' >> "$depfile" - rm -f "$tmpdepfile" - ;; - -hp2) - # The "hp" stanza above does not work with aCC (C++) and HP's ia64 - # compilers, which have integrated preprocessors. The correct option - # to use with these is +Maked; it writes dependencies to a file named - # 'foo.d', which lands next to the object file, wherever that - # happens to be. - # Much of this is similar to the tru64 case; see comments there. - dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` - test "x$dir" = "x$object" && dir= - base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` - if test "$libtool" = yes; then - tmpdepfile1=$dir$base.d - tmpdepfile2=$dir.libs/$base.d - "$@" -Wc,+Maked - else - tmpdepfile1=$dir$base.d - tmpdepfile2=$dir$base.d - "$@" +Maked - fi - stat=$? - if test $stat -eq 0; then : - else - rm -f "$tmpdepfile1" "$tmpdepfile2" - exit $stat - fi - - for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" - do - test -f "$tmpdepfile" && break - done - if test -f "$tmpdepfile"; then - sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile" - # Add `dependent.h:' lines. - sed -ne '2,${; s/^ *//; s/ \\*$//; s/$/:/; p;}' "$tmpdepfile" >> "$depfile" - else - echo "#dummy" > "$depfile" - fi - rm -f "$tmpdepfile" "$tmpdepfile2" - ;; - -tru64) - # The Tru64 compiler uses -MD to generate dependencies as a side - # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'. - # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put - # dependencies in `foo.d' instead, so we check for that too. - # Subdirectories are respected. - dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` - test "x$dir" = "x$object" && dir= - base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` - - if test "$libtool" = yes; then - # With Tru64 cc, shared objects can also be used to make a - # static library. This mechanism is used in libtool 1.4 series to - # handle both shared and static libraries in a single compilation. - # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d. - # - # With libtool 1.5 this exception was removed, and libtool now - # generates 2 separate objects for the 2 libraries. These two - # compilations output dependencies in $dir.libs/$base.o.d and - # in $dir$base.o.d. We have to check for both files, because - # one of the two compilations can be disabled. We should prefer - # $dir$base.o.d over $dir.libs/$base.o.d because the latter is - # automatically cleaned when .libs/ is deleted, while ignoring - # the former would cause a distcleancheck panic. - tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4 - tmpdepfile2=$dir$base.o.d # libtool 1.5 - tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5 - tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504 - "$@" -Wc,-MD - else - tmpdepfile1=$dir$base.o.d - tmpdepfile2=$dir$base.d - tmpdepfile3=$dir$base.d - tmpdepfile4=$dir$base.d - "$@" -MD - fi - - stat=$? - if test $stat -eq 0; then : - else - rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" - exit $stat - fi - - for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" - do - test -f "$tmpdepfile" && break - done - if test -f "$tmpdepfile"; then - sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" - # That's a tab and a space in the []. - sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" - else - echo "#dummy" > "$depfile" - fi - rm -f "$tmpdepfile" - ;; - -#nosideeffect) - # This comment above is used by automake to tell side-effect - # dependency tracking mechanisms from slower ones. - -dashmstdout) - # Important note: in order to support this mode, a compiler *must* - # always write the preprocessed file to stdout, regardless of -o. - "$@" || exit $? - - # Remove the call to Libtool. - if test "$libtool" = yes; then - while test $1 != '--mode=compile'; do - shift - done - shift - fi - - # Remove `-o $object'. - IFS=" " - for arg - do - case $arg in - -o) - shift - ;; - $object) - shift - ;; - *) - set fnord "$@" "$arg" - shift # fnord - shift # $arg - ;; - esac - done - - test -z "$dashmflag" && dashmflag=-M - # Require at least two characters before searching for `:' - # in the target name. This is to cope with DOS-style filenames: - # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise. - "$@" $dashmflag | - sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile" - rm -f "$depfile" - cat < "$tmpdepfile" > "$depfile" - tr ' ' ' -' < "$tmpdepfile" | \ -## Some versions of the HPUX 10.20 sed can't process this invocation -## correctly. Breaking it into two sed invocations is a workaround. - sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" - rm -f "$tmpdepfile" - ;; - -dashXmstdout) - # This case only exists to satisfy depend.m4. It is never actually - # run, as this mode is specially recognized in the preamble. - exit 1 - ;; - -makedepend) - "$@" || exit $? - # Remove any Libtool call - if test "$libtool" = yes; then - while test $1 != '--mode=compile'; do - shift - done - shift - fi - # X makedepend - shift - cleared=no - for arg in "$@"; do - case $cleared in - no) - set ""; shift - cleared=yes ;; - esac - case "$arg" in - -D*|-I*) - set fnord "$@" "$arg"; shift ;; - # Strip any option that makedepend may not understand. Remove - # the object too, otherwise makedepend will parse it as a source file. - -*|$object) - ;; - *) - set fnord "$@" "$arg"; shift ;; - esac - done - obj_suffix="`echo $object | sed 's/^.*\././'`" - touch "$tmpdepfile" - ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" - rm -f "$depfile" - cat < "$tmpdepfile" > "$depfile" - sed '1,2d' "$tmpdepfile" | tr ' ' ' -' | \ -## Some versions of the HPUX 10.20 sed can't process this invocation -## correctly. Breaking it into two sed invocations is a workaround. - sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" - rm -f "$tmpdepfile" "$tmpdepfile".bak - ;; - -cpp) - # Important note: in order to support this mode, a compiler *must* - # always write the preprocessed file to stdout. - "$@" || exit $? - - # Remove the call to Libtool. - if test "$libtool" = yes; then - while test $1 != '--mode=compile'; do - shift - done - shift - fi - - # Remove `-o $object'. - IFS=" " - for arg - do - case $arg in - -o) - shift - ;; - $object) - shift - ;; - *) - set fnord "$@" "$arg" - shift # fnord - shift # $arg - ;; - esac - done - - "$@" -E | - sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ - -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' | - sed '$ s: \\$::' > "$tmpdepfile" - rm -f "$depfile" - echo "$object : \\" > "$depfile" - cat < "$tmpdepfile" >> "$depfile" - sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" - rm -f "$tmpdepfile" - ;; - -msvisualcpp) - # Important note: in order to support this mode, a compiler *must* - # always write the preprocessed file to stdout, regardless of -o, - # because we must use -o when running libtool. - "$@" || exit $? - IFS=" " - for arg - do - case "$arg" in - "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") - set fnord "$@" - shift - shift - ;; - *) - set fnord "$@" "$arg" - shift - shift - ;; - esac - done - "$@" -E | - sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile" - rm -f "$depfile" - echo "$object : \\" > "$depfile" - . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile" - echo " " >> "$depfile" - . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile" - rm -f "$tmpdepfile" - ;; - -none) - exec "$@" - ;; - -*) - echo "Unknown depmode $depmode" 1>&2 - exit 1 - ;; -esac - -exit 0 - -# Local Variables: -# mode: shell-script -# sh-indentation: 2 -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "scriptversion=" -# time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-end: "$" -# End: diff --git a/contrib/cvs/diff/ChangeLog b/contrib/cvs/diff/ChangeLog deleted file mode 100644 index abe3471..0000000 --- a/contrib/cvs/diff/ChangeLog +++ /dev/null @@ -1,534 +0,0 @@ -2005-09-04 Derek Price - - * Makefile.am (EXTRA_DIST): Add .cvsignore. - -2004-11-05 Conrad T. Pino - - * libdiff.dep: Regenerated after complete rebuild. - -2004-05-15 Derek Price - - * libdiff.dsp: Header file list updated. - * libdiff.dep: Regenerated for "libdiff.dsp" changes. - * libdiff.mak: Regenerated for "libdiff.dsp" changes. - (Patch from Conrad Pino .) - -2004-05-13 Derek Price - - * .cvsignore: Changed for "libdiff.dsp" changes. - * libdiff.dep: Added for "../cvsnt.dsw" changes. - * libdiff.dsp: Changed for "../cvsnt.dsw" changes. - * libdiff.mak: Regenerated for "../cvsnt.dsw" changes. - (Patch from Conrad Pino .) - -2004-03-20 Derek Price - - * diff.c (diff_run): Update string arg to const. - * diffrun.h: Update prototype to match. - -2003-07-12 Larry Jones - - * io.c (find_identical_ends): Update to match current diffutils - code and improve handling of files with no newline at end. - (Patch from Andrew Moise .) - -2003-06-13 Derek Price - - * diff3.c (read_diff): Fix memory leak. - (Patch from Kenneth Lorber .) - -2003-05-21 Derek Price - - * Makefile.in: Regenerate with Automake version 1.7.5. - -2003-05-09 Derek Price - - * system.h: Define S_ISSOCK on SCO OpenServer. - -2003-04-10 Larry Jones - - * Makefile.in: Regenerated. - -2003-02-25 Derek Price - - * Makefile.in: Regenerated. - -2003-02-01 Larry Jones - - * util.c (finish_output): Handle EINTR from waitpid. - -2002-09-24 Derek Price - - * Makefile.in: Regenerated using Automake 1.6.3. - -2002-09-24 Larry Jones - - * system.h: Use HAVE_STRUCT_STAT_ST_BLKSIZE instead of the - obsolete HAVE_ST_BLKSIZE. - -2002-09-24 Derek Price - - * Makefile.in: Regenerated. - -2002-04-30 Derek Price - - * Makefile.in: Regenerated with automake 1.6. - -2002-04-28 Derek Price - - * diff.c: Use the system fnmatch.h when present. - -2001-09-04 Derek Price - - * Makefile.in: Regenerated with automake 1.5. - -2001-08-09 Derek Price - - * system.h: Source some header files when present to eliminate warning - messages under Windows. - (Patch from "Manfred Klug" .) - -2001-08-07 Derek Price - - * build_diff.com: Turn on verify to get a better trace of the DCL. - * diff3.c: Eliminate compiler warning. The VMS read rval is ssize_t - (signed). The VMS size_t appears to be unsigned. - * io.c: Eliminate compiler warning (ssize_t). - (Patch from Mike Marciniszyn .) - -2001-08-06 Derek Price - - * Makefile.in: Regenerated. - -2001-07-04 Derek Price - - * Makefile.in: Regenerated with new Automake release candidate 1.4h. - -2001-06-28 Derek Price - - * Makefile.in: Regenerated with new version of Automake. - -2001-05-07 Larry Jones - - * diff3.c (diff3_run): Put the name of the output file in the error - message instead of "could not open output file" to aid in debugging. - -2001-04-25 Derek Price - - * Makefile.in: Regenerated using AM 1.4e as of today at 18:10 -0400. - -2001-03-24 Noel Cragg - - * diff.c: fix typo in usage string. - -2001-03-20 Derek Price - for Karl Tomlinson - - * diff3.c (main): changed the common file of the two diffs to - OLDFILE for merges and edscripts so that the diffs are more likely - to contain the intended changes. Not changing the horizon-lines - arg for the second diff. If the two diffs have the same parameters - equal changes in each diff are more likely to appear the same. - - * analyze.c (shift_boundaries): undid Paul Eggert's patch to fix - the diff3 merge bug described in ccvs/doc/DIFFUTILS-2.7-BUG. The - patch is no longer necessary now that diff3 does its differences - differently. I think the hunk merges provide a better indication - of the area modified by the user now that the diffs are actually - done between the appropriate revisions. - -2001-03-15 Derek Price - - * Makefile.am (INCLUDES): Add -I$(top_srcdir)/lib for platforms which - need the regex library there. - - * Makefile.in: Regenerated. - -2001-03-14 Derek Price - - * .cvsignore: Added '.deps'. - - Pavel Roskin - - * Makefile.am: New file. - * Makefile.in: Regenerated. - -2001-02-22 Derek Price - Pavel Roskin - - * Makefile.in: Don't define PR_PROGRAM - it's defined by configure. - Remove separate rule for util.c. - -2001-02-06 Derek Price - Rex Jolliff - Shawn Smith - - * dir.c: Replace opendir, closedir, & readdir calls with CVS_OPENDIR, - CVS_CLOSEDIR, & CVS_READDIR in support of changes to handle VMS DEC C - 5.7 {open,read,close}dir problems. Check today's entry in the vms - subdir for more. - * system.h: definitions of CVS_*DIR provided here. - -2000-12-21 Derek Price - - * Makefile.in: Some changes to support Automake targets - -2000-10-26 Larry Jones - - * Makefile.in: Get PR_PROGRAM from autoconf instead of hard coding. - (Patch submitted by Urs Thuermann .) - Also add a dependency for util.o on Makefile since PR_PROGRAM gets - compiled in. - -2000-08-03 Larry Jones - - * 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 - - * util.c (printf_output): Fix type clashes. - -2000-06-15 Larry Jones - - * diff3.c (diff3_run, make_3way_diff): Plug memory leaks. - -1999-12-29 Jim Kingdon - - * diff.c (compare_files): Use explicit braces with if-if-else, per - GNU coding standards and gcc -Wall. - -1999-11-23 Larry Jones - - * diff3.c: Explicitly initialize zero_diff3 to placate neurotic - compilers that gripe about implicitly initialized const variables. - Reported by Eric Veum . - -1999-09-15 Larry Jones - - * 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 - - * Makefile.in (DISTFILES): Remove libdiff.mak. - * libdiff.mak: Removed; we are back to a single makefile for - Visual C++ version 4. - -1999-04-29 Jim Kingdon - - * diff.c (diff_run): Use separate statement for setjmp call and if - statement. This is better style in general (IMHO) but in the case - of setjmp the UNICOS compiler apparently cares (I don't have the - standard handy, but there are lots of legitimate restrictions on - how you can call setjmp). - -1999-04-26 Jim Kingdon - - * Makefile.in (DISTFILES): Add libdiff.dsp libdiff.mak .cvsignore. - -1999-04-26 (submitted 1999-03-24) John O'Connor - - * libdiff.dsp: new file. MSVC project file used to build the library. - - * libdiff.mak: new file. Makefile for building from the command-line. - - * .cvsignore: Removed un-used entries related to MSVC. Added - entries to ignore directories generated by the NT build, Debug - and Release. - -1999-03-24 Larry Jones - and Olaf Brandes - - * diff3.c (diff3_run): Use a separate stream for the input to - output_diff3_merge instead of reopening stdin to avoid problems - with leaving it open. - -1999-02-17 Jim Kingdon - and Hallvard B Furuseth. - - * util.c: Use __STDC__ consistently with ./system.h. - * system.h: Add comment about PARAMS. - -1999-01-12 Jim Kingdon - - * Makefile.in, analyze.c, cmpbuf.c, cmpbuf.h, context.c, diff.c, - diff.h, diff3.c, diffrun.h, dir.c, ed.c, io.c, normal.c, system.h, - util.c: Remove paragraph containing the old snail mail address of - the Free Software Foundation. - -1998-09-21 Jim Kingdon - - * util.c (printf_output): Make msg static; avoids auto - initializer, which is not portable to SunOS4 /bin/cc. - Reported by Mike Sutton@SAIC. - -1998-09-14 Jim Kingdon - - * Makefile.in (DISTFILES): Add diagmeet.note. - -1998-08-15 Jim Kingdon - - * diffrun.h (struct diff_callbacks): Change calling convention of - write_output so that a zero length means to output zero bytes. - The cvs_output convention is just too ugly/error-prone. - * util.c (printf_output): Rewrite to parse format string - overselves rather than calling vasprintf, which cannot be - implemented in portable C. - -1998-08-06 David Masterson of kla-tencor.com - - * util.c (flush_output): Don't prototype. - -Thu Jul 2 16:34:38 1998 Ian Lance Taylor - - Simplify the callback interface: - * diffrun.h: Don't include or . - (struct diff_callbacks): Remove printf_output field. - * util.c: Include or . - (printf_output): Use vasprintf and write_output callback rather - than printf_output callback. - * diff3.c (read_diff): Don't set my_callbacks.printf_output. - -Thu Jun 18 12:43:53 1998 Ian Lance Taylor - - * diffrun.h: New file. - * diff.h: Include diffrun.h. - (callbacks): New EXTERN variable. - (write_output, printf_output, flush_output): Declare. - * diff.c (diff_run): Add parameter callbacks_arg. Use callback - functions rather than writing to stdout. Don't open a file if - there is a write_output callback. Call perror_with_name rather - than perror. - (usage): Use callbacks if defined rather than writing to stdout. - (compare_files): Call flush_output rather than fflush (outfile). - * diff3.c: Include diffrun.h. Change several functions to use - output functions from util.c rather than direct printing. Use - diff_error and friends rather than printing to stderr. Set global - variable outfile. - (outfile, callbacks): Declare. - (write_output, printf_output, flush_output): Declare. - (diff3_run): Add parameter callbacks_arg. Use callback functions - rather than writing to stdout. - (usage): Use callbacks if defined rather than writing to stdout. - (read_diff): Preserve callbacks and outfile around call to - diff_run. - * util.c (perror_with_name): Use error callback if defined. - (pfatal_with_name, diff_error): Likewise. - (message5): Use printf_output and write_output. - (print_message_queue, print_1_line, output_1_line): Likewise. - (begin_output): Reject paginate_flag if there are output - callbacks. - (write_output, printf_output, flush_output): New functions. - * context.c: Change all output to outfile to use printf_output and - write_output. - * ed.c: Likewise. - * ifdef.c: Likewise. - * normal.c: Likewise. - * side.c: Likewise. - * Makefile.in (SOURCES): Add diffrun.h. - ($(OBJECTS)): Depend upon diffrun.h. - -Fri Jan 16 14:58:19 1998 Larry Jones - - * diff.c, diff3.c: Plug memory leaks. - -Thu Jan 15 13:36:46 1998 Jim Kingdon - - * Makefile.in (installdirs): New rule, for when ../Makefile - recurses into this directory (bug reported by W. L. Estes). - -Tue Nov 11 10:48:19 1997 Jim Kingdon - - * diff.c (diff_run): Change #ifdef on HAVE_SETMODE to #if to match - the other uses (fixes compilation error on unix). - - * diff.c (diff_run): Don't set stdout to binary mode. - -Mon, 10 Nov 1997 Jim Kingdon - - * diff.c (run_diff): Open outfile in binary mode if --binary. - -Thu Nov 6 12:42:12 1997 Karl Fogel - and Paul Eggert - - * analyze.c: applied Paul Eggert's patch to fix the diff3 merge - bug described in ccvs/doc/DIFFUTILS-2.7-BUG: - (shift_boundaries): new var `inhibit_hunk_merge'; use it to - control something important that I don't quite understand, but - Paul apparently does, so that's okay. - -Sat Nov 1 14:17:57 1997 Michael L.H. Brouwer - - * Makefile.in: Add call to ranlib to build a table of contents for - the library since some systems seem to require this. - -1997-10-28 Jim Kingdon - - * .cvsignore: Add files du jour for Visual C++, vc50.pdb and vc50.idb. - - * system.h: Define HAVE_TIME_H. - * dir.c [_WIN32]: Define CLOSEDIR_VOID. - -1997-10-18 Jim Kingdon - - * build_diff.com: Add diff3.c - -Fri Sep 26 14:24:42 1997 Tim Pierce - - * diff.c (diff_run): Save old value of optind before calling - getopt_long, then restore before returning. Eventually it would - be nice if diff_run were fully reentrant. - - New diff3 library for CVS. - * Makefile.in (SOURCES): Add diff3.c. - (OBJECTS): Add diff3.o. - * diff3.c: New file, copied from diffutils-2.7. See diffutils for - earlier ChangeLogs. Undefine initialize_main macro. Remove . - (diff3_run): Renamed from main(). Add `outfile' argument. Remove - SIGCLD handling; we do not fork. Save optind and reset to 0 - before calling getopt_long; restore after option processing done. - (read_diff): Use diff_run with a temporary output file, - instead of forking a diff subprocess and reading from a pipe. - Change DIFF_PROGRAM to "diff"; this argument is now used only for - diagnostic reporting. - (xmalloc, xrealloc): Removed. - (diff_program): Removed. - (diff_program_name): Made extern, so it may be used in other - library calls like `error'. - (initialize_main): New function. - - Namespace munging. util.c defines both fatal() and - perror_with_exit(), but these cannot be used to abort diff3: both - attempt to longjmp() to a buffer set in diff.c, used only by - diff_run. This is an awful solution, but necessary until the code - can be cleaned up. (These functions do not *have* to be renamed, - since both are declared static to diff3.c and should not clash - with libdiff.a, but it reduces potential confusion.) - * diff3.c (diff3_fatal): Renamed from fatal. - (diff3_perror_with_exit): Renamed from perror_with_exit. - - Eliminate exit calls. - (try_help): Change from `void' to `int'. Return, do not exit. - (diff3_fatal, diff3_perror_with_exit, process_diff): Change `exit' - to DIFF3_ABORT. - (diff3_run): Initialize jump buffer for nonlocal exits. Change - exit calls to returns. Change `perror_with_exit' to - `perror_with_name' and add a return. Change `fatal' to - `diff_error' and add a return. The reasoning is that we shouldn't - rely on setjmp/longjmp any more than necessary. - - Redirect stdout. - (check_output): Renamed from check_stdout. Take stream argument - instead of blindly checking stdout. Do not close stream, but - merely fflush it. - (diff3_run): Initialize outstream, and close when done. Pass this - stream (instead of stdout) to output_diff3_edscript, - output_diff3_merge, and output_diff3. - -Thu Sep 25 14:34:22 1997 Jim Kingdon - - * util.c (begin_output, finish_output): If PR_PROGRAM is not - defined (VMS), just give a fatal error if --paginate specified. - - * Makefile.in (DISTFILES): Add ChangeLog build_diff.com - Makefile.in. - * build_diff.com: New file. - -Wed Sep 24 10:27:00 1997 Jim Kingdon - - * Makefile.in: Also set top_srcdir. Needed to make today's other - Makefile.in change work. - - * .cvsignore: New file. - - * Makefile.in (COMPILE): Add -I options for srcdir (perhaps - unneeded) and change -I option for lib to use top_srcdir (needed - to avoid mixups with CVS's regex.h vs. the system one). - -Sun Sep 21 19:44:42 1997 Jim Kingdon - - * Makefile.in (util.o): Change util.c to $<, needed for srcdir. - -Sat Sep 20 12:06:41 1997 Tim Pierce - - New diff library for CVS, based on diffutils-2.7. See diffutils - for earlier ChangeLogs. - * Makefile.in, analyze.c, cmpbuf.c, cmpbuf.h, config.hin, - context.c, diagmeet.note, diff.c, diff.h, dir.c, ed.c, ifdef.c, - io.c, normal.c, side.c, stamp-h.in, system.h, util.c, version.c: - New files. - (COMPILE): Add -I../lib, so we can get getopt.h. - - * Makefile.in: Removed anything not related to libdiff.a. - (dist-dir): New target, copied from ../lib/Makefile.in. - (DISTFILES): New variable. - (SOURCES): Renamed from `srcs'. - (OBJECTS): Renamed from `libdiff_o'. - (Makefile): Changed dependencies to reflect - new, shallow config directory structure. - (stamp-h.in, config.h.in, config.h, stamp-h): Removed. - * stamp-h.in, config.h.in: Removed. - - * system.h: Remove dup2 macro (provided by ../lib/dup2.c). - Include stdlib.h if STDC_HEADERS is defined (not just - HAVE_STDLIB_H). - -Sat Sep 20 05:32:18 1997 Tim Pierce - - Diff librarification. - - * diff.c (diff_run): New function, renamed from `main'. - Initialize `outfile' based on the value of the new `out' filename - argument. - (initialize_main): New function. - * system.h: Removed initialize_main macro. - * diffmain.c: New file. - * Makefile.in (diff): Added diffmain.o. - (libdiff): New target. - (AR, libdiff_o): New variables. libdiff_o does not include - xmalloc.o, fnmatch.o, getopt.o, getopt1.o, regex.o or error.o, - because these functions are already present in CVS. It will take - some work to make this more general-purpose. - - Redirect standard output. - * util.c: Redirect stdout to outfile: change all naked `printf' - and `putchar' statements to `fprintf (outfile)' and `putc (..., - outfile)' throughout. This should permit redirecting diff output - by changing `outfile' just once in `diff_run'. - (output_in_progress): New variable. - (begin_output, finish_output): Use `output_in_progress', rather than - `outfile', as a semaphore to avoid reentrancy problems. - (finish_output): Close `outfile' only if paginate_flag is set. - * diff.c (check_output): New function, was check_stdout. Take a - `file' argument, and flush it instead of closing it. - (diff_run): Change check_stdout to check_output. - (compare_files): Fflush outfile, not stdout. - - Eliminate exit statements. - * diff.h: Include setjmp.h. - (diff_abort_buf): New variable. - (DIFF_ABORT): New macro. - * diff.c (diff_run): Change all `exit' statements to `return'. - Set up diff_abort_buf, so we can abort diff without - terminating (for libdiff.a). - (try_help): Return int instead of void; do not exit. - * util.c (fatal): Use DIFF_ABORT instead of exit. - (pfatal_with_name): Use DIFF_ABORT instead of exit. - - Namespace cleanup (rudimentary). Strictly speaking, this is not - necessary to make diff into a library. However, namespace - clashes between diff and CVS must be resolved immediately, since - CVS is the first application targeted for use with difflib. - - * analyze.c, diff.c, diff.h, util.c (diff_error): Renamed from `error'. - - * version.c, diff.c, diff.h, cmp.c, diff3.c, sdiff.c - (diff_version_string): Renamed from version_string. - * diff.c, util.c, diff.h, diff3.c, error.c (diff_program_name): - Renamed from program_name. - - * util.c (xmalloc, xrealloc): Removed. - * Makefile.in (diff_o): Added error.o and xmalloc.o. - diff --git a/contrib/cvs/diff/Makefile.am b/contrib/cvs/diff/Makefile.am deleted file mode 100644 index 96d665b..0000000 --- a/contrib/cvs/diff/Makefile.am +++ /dev/null @@ -1,25 +0,0 @@ -## Makefile.am for GNU DIFF -## Copyright (C) 2001 Free Software Foundation, Inc. -## -## This file is part of GNU DIFF. -## -## GNU DIFF is free software; you can redistribute it and/or modify -## it under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 2, or (at your option) -## any later version. -## -## GNU DIFF 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. - -INCLUDES = -I$(top_srcdir)/lib - -noinst_LIBRARIES = libdiff.a - -libdiff_a_SOURCES = diff.c diff3.c analyze.c cmpbuf.c cmpbuf.h io.c \ - context.c ed.c normal.c ifdef.c util.c dir.c version.c diff.h \ - side.c system.h diffrun.h - -EXTRA_DIST = ChangeLog build_diff.com diagmeet.note \ - libdiff.dep libdiff.dsp libdiff.mak .cvsignore diff --git a/contrib/cvs/diff/Makefile.in b/contrib/cvs/diff/Makefile.in deleted file mode 100644 index 0203d12..0000000 --- a/contrib/cvs/diff/Makefile.in +++ /dev/null @@ -1,429 +0,0 @@ -# Makefile.in generated by automake 1.10 from Makefile.am. -# @configure_input@ - -# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006 Free Software Foundation, Inc. -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ - -VPATH = @srcdir@ -pkgdatadir = $(datadir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -subdir = diff -DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ChangeLog -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ - $(top_srcdir)/configure.in -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs -CONFIG_HEADER = $(top_builddir)/config.h -CONFIG_CLEAN_FILES = -LIBRARIES = $(noinst_LIBRARIES) -AR = @AR@ -ARFLAGS = @ARFLAGS@ -libdiff_a_AR = $(AR) $(ARFLAGS) -libdiff_a_LIBADD = -am_libdiff_a_OBJECTS = diff.$(OBJEXT) diff3.$(OBJEXT) \ - analyze.$(OBJEXT) cmpbuf.$(OBJEXT) io.$(OBJEXT) \ - context.$(OBJEXT) ed.$(OBJEXT) normal.$(OBJEXT) \ - ifdef.$(OBJEXT) util.$(OBJEXT) dir.$(OBJEXT) version.$(OBJEXT) \ - side.$(OBJEXT) -libdiff_a_OBJECTS = $(am_libdiff_a_OBJECTS) -DEFAULT_INCLUDES = -I. -I$(top_builddir)@am__isrc@ -depcomp = $(SHELL) $(top_srcdir)/depcomp -am__depfiles_maybe = depfiles -COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ - $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -CCLD = $(CC) -LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ -SOURCES = $(libdiff_a_SOURCES) -DIST_SOURCES = $(libdiff_a_SOURCES) -ETAGS = etags -CTAGS = ctags -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -ACLOCAL = @ACLOCAL@ -AMTAR = @AMTAR@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -CC = @CC@ -CCDEPMODE = @CCDEPMODE@ -CFLAGS = @CFLAGS@ -CPP = @CPP@ -CPPFLAGS = @CPPFLAGS@ -CSH = @CSH@ -CYGPATH_W = @CYGPATH_W@ -DEFS = @DEFS@ -DEPDIR = @DEPDIR@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EDITOR = @EDITOR@ -EGREP = @EGREP@ -EXEEXT = @EXEEXT@ -GREP = @GREP@ -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -KRB4 = @KRB4@ -LDFLAGS = @LDFLAGS@ -LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ -LN_S = @LN_S@ -LTLIBOBJS = @LTLIBOBJS@ -MAINT = @MAINT@ -MAKEINFO = @MAKEINFO@ -MKDIR_P = @MKDIR_P@ -MKTEMP = @MKTEMP@ -OBJEXT = @OBJEXT@ -PACKAGE = @PACKAGE@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ -PACKAGE_NAME = @PACKAGE_NAME@ -PACKAGE_STRING = @PACKAGE_STRING@ -PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -PERL = @PERL@ -PR = @PR@ -PS2PDF = @PS2PDF@ -RANLIB = @RANLIB@ -ROFF = @ROFF@ -SENDMAIL = @SENDMAIL@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -STRIP = @STRIP@ -TEXI2DVI = @TEXI2DVI@ -VERSION = @VERSION@ -YACC = @YACC@ -YFLAGS = @YFLAGS@ -abs_builddir = @abs_builddir@ -abs_srcdir = @abs_srcdir@ -abs_top_builddir = @abs_top_builddir@ -abs_top_srcdir = @abs_top_srcdir@ -ac_ct_CC = @ac_ct_CC@ -ac_prefix_program = @ac_prefix_program@ -am__include = @am__include@ -am__leading_dot = @am__leading_dot@ -am__quote = @am__quote@ -am__tar = @am__tar@ -am__untar = @am__untar@ -bindir = @bindir@ -build_alias = @build_alias@ -builddir = @builddir@ -datadir = @datadir@ -datarootdir = @datarootdir@ -docdir = @docdir@ -dvidir = @dvidir@ -exec_prefix = @exec_prefix@ -host_alias = @host_alias@ -htmldir = @htmldir@ -includedir = @includedir@ -includeopt = @includeopt@ -infodir = @infodir@ -install_sh = @install_sh@ -libdir = @libdir@ -libexecdir = @libexecdir@ -localedir = @localedir@ -localstatedir = @localstatedir@ -mandir = @mandir@ -mkdir_p = @mkdir_p@ -oldincludedir = @oldincludedir@ -pdfdir = @pdfdir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -psdir = @psdir@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -srcdir = @srcdir@ -sysconfdir = @sysconfdir@ -target_alias = @target_alias@ -top_builddir = @top_builddir@ -top_srcdir = @top_srcdir@ -with_default_rsh = @with_default_rsh@ -with_default_ssh = @with_default_ssh@ -INCLUDES = -I$(top_srcdir)/lib -noinst_LIBRARIES = libdiff.a -libdiff_a_SOURCES = diff.c diff3.c analyze.c cmpbuf.c cmpbuf.h io.c \ - context.c ed.c normal.c ifdef.c util.c dir.c version.c diff.h \ - side.c system.h diffrun.h - -EXTRA_DIST = ChangeLog build_diff.com diagmeet.note \ - libdiff.dep libdiff.dsp libdiff.mak .cvsignore - -all: all-am - -.SUFFIXES: -.SUFFIXES: .c .o .obj -$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ - && exit 0; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu diff/Makefile'; \ - cd $(top_srcdir) && \ - $(AUTOMAKE) --gnu diff/Makefile -.PRECIOUS: Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - @case '$?' in \ - *config.status*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ - *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ - esac; - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh - -$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh - -clean-noinstLIBRARIES: - -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) -libdiff.a: $(libdiff_a_OBJECTS) $(libdiff_a_DEPENDENCIES) - -rm -f libdiff.a - $(libdiff_a_AR) libdiff.a $(libdiff_a_OBJECTS) $(libdiff_a_LIBADD) - $(RANLIB) libdiff.a - -mostlyclean-compile: - -rm -f *.$(OBJEXT) - -distclean-compile: - -rm -f *.tab.c - -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/analyze.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmpbuf.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/context.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/diff.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/diff3.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dir.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ed.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ifdef.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/io.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/normal.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/side.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/util.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/version.Po@am__quote@ - -.c.o: -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(COMPILE) -c $< - -.c.obj: -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` -@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` - -ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ - mkid -fID $$unique -tags: TAGS - -TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - tags=; \ - here=`pwd`; \ - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ - if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ - test -n "$$unique" || unique=$$empty_fix; \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$tags $$unique; \ - fi -ctags: CTAGS -CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - tags=; \ - here=`pwd`; \ - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ - test -z "$(CTAGS_ARGS)$$tags$$unique" \ - || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ - $$tags $$unique - -GTAGS: - here=`$(am__cd) $(top_builddir) && pwd` \ - && cd $(top_srcdir) \ - && gtags -i $(GTAGS_ARGS) $$here - -distclean-tags: - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags - -distdir: $(DISTFILES) - @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - list='$(DISTFILES)'; \ - dist_files=`for file in $$list; do echo $$file; done | \ - sed -e "s|^$$srcdirstrip/||;t" \ - -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ - case $$dist_files in \ - */*) $(MKDIR_P) `echo "$$dist_files" | \ - sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ - sort -u` ;; \ - esac; \ - for file in $$dist_files; do \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - if test -d $$d/$$file; then \ - dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ - fi; \ - cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ - else \ - test -f $(distdir)/$$file \ - || cp -p $$d/$$file $(distdir)/$$file \ - || exit 1; \ - fi; \ - done -check-am: all-am -check: check-am -all-am: Makefile $(LIBRARIES) -installdirs: -install: install-am -install-exec: install-exec-am -install-data: install-data-am -uninstall: uninstall-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-am -install-strip: - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - `test -z '$(STRIP)' || \ - echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install -mostlyclean-generic: - -clean-generic: - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." -clean: clean-am - -clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am - -distclean: distclean-am - -rm -rf ./$(DEPDIR) - -rm -f Makefile -distclean-am: clean-am distclean-compile distclean-generic \ - distclean-tags - -dvi: dvi-am - -dvi-am: - -html: html-am - -info: info-am - -info-am: - -install-data-am: - -install-dvi: install-dvi-am - -install-exec-am: - -install-html: install-html-am - -install-info: install-info-am - -install-man: - -install-pdf: install-pdf-am - -install-ps: install-ps-am - -installcheck-am: - -maintainer-clean: maintainer-clean-am - -rm -rf ./$(DEPDIR) - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-am - -mostlyclean-am: mostlyclean-compile mostlyclean-generic - -pdf: pdf-am - -pdf-am: - -ps: ps-am - -ps-am: - -uninstall-am: - -.MAKE: install-am install-strip - -.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ - clean-noinstLIBRARIES ctags distclean distclean-compile \ - distclean-generic distclean-tags distdir dvi dvi-am html \ - html-am info info-am install install-am install-data \ - install-data-am install-dvi install-dvi-am install-exec \ - install-exec-am install-html install-html-am install-info \ - install-info-am install-man install-pdf install-pdf-am \ - install-ps install-ps-am install-strip installcheck \ - installcheck-am installdirs maintainer-clean \ - maintainer-clean-generic mostlyclean mostlyclean-compile \ - mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \ - uninstall-am - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/contrib/cvs/diff/analyze.c b/contrib/cvs/diff/analyze.c deleted file mode 100644 index 3262444..0000000 --- a/contrib/cvs/diff/analyze.c +++ /dev/null @@ -1,1082 +0,0 @@ -/* Analyze file differences for GNU DIFF. - Copyright (C) 1988, 1989, 1992, 1993, 1997 Free Software Foundation, Inc. - -This file is part of GNU DIFF. - -GNU DIFF is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU DIFF 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. - -*/ - -/* The basic algorithm is described in: - "An O(ND) Difference Algorithm and its Variations", Eugene Myers, - Algorithmica Vol. 1 No. 2, 1986, pp. 251-266; - see especially section 4.2, which describes the variation used below. - Unless the --minimal option is specified, this code uses the TOO_EXPENSIVE - heuristic, by Paul Eggert, to limit the cost to O(N**1.5 log N) - at the price of producing suboptimal output for large inputs with - many differences. - - The basic algorithm was independently discovered as described in: - "Algorithms for Approximate String Matching", E. Ukkonen, - Information and Control Vol. 64, 1985, pp. 100-118. */ - -#include "diff.h" -#include "cmpbuf.h" - -extern int no_discards; - -static int *xvec, *yvec; /* Vectors being compared. */ -static int *fdiag; /* Vector, indexed by diagonal, containing - 1 + the X coordinate of the point furthest - along the given diagonal in the forward - search of the edit matrix. */ -static int *bdiag; /* Vector, indexed by diagonal, containing - the X coordinate of the point furthest - along the given diagonal in the backward - search of the edit matrix. */ -static int too_expensive; /* Edit scripts longer than this are too - expensive to compute. */ - -#define SNAKE_LIMIT 20 /* Snakes bigger than this are considered `big'. */ - -struct partition -{ - int xmid, ymid; /* Midpoints of this partition. */ - int lo_minimal; /* Nonzero if low half will be analyzed minimally. */ - int hi_minimal; /* Likewise for high half. */ -}; - -static int diag PARAMS((int, int, int, int, int, struct partition *)); -static struct change *add_change PARAMS((int, int, int, int, struct change *)); -static struct change *build_reverse_script PARAMS((struct file_data const[])); -static struct change *build_script PARAMS((struct file_data const[])); -static void briefly_report PARAMS((int, struct file_data const[])); -static void compareseq PARAMS((int, int, int, int, int)); -static void discard_confusing_lines PARAMS((struct file_data[])); -static void shift_boundaries PARAMS((struct file_data[])); - -/* Find the midpoint of the shortest edit script for a specified - portion of the two files. - - Scan from the beginnings of the files, and simultaneously from the ends, - doing a breadth-first search through the space of edit-sequence. - When the two searches meet, we have found the midpoint of the shortest - edit sequence. - - If MINIMAL is nonzero, find the minimal edit script regardless - of expense. Otherwise, if the search is too expensive, use - heuristics to stop the search and report a suboptimal answer. - - Set PART->(XMID,YMID) to the midpoint (XMID,YMID). The diagonal number - XMID - YMID equals the number of inserted lines minus the number - of deleted lines (counting only lines before the midpoint). - Return the approximate edit cost; this is the total number of - lines inserted or deleted (counting only lines before the midpoint), - unless a heuristic is used to terminate the search prematurely. - - Set PART->LEFT_MINIMAL to nonzero iff the minimal edit script for the - left half of the partition is known; similarly for PART->RIGHT_MINIMAL. - - This function assumes that the first lines of the specified portions - of the two files do not match, and likewise that the last lines do not - match. The caller must trim matching lines from the beginning and end - of the portions it is going to specify. - - If we return the "wrong" partitions, - the worst this can do is cause suboptimal diff output. - It cannot cause incorrect diff output. */ - -static int -diag (xoff, xlim, yoff, ylim, minimal, part) - int xoff, xlim, yoff, ylim, minimal; - struct partition *part; -{ - int *const fd = fdiag; /* Give the compiler a chance. */ - int *const bd = bdiag; /* Additional help for the compiler. */ - int const *const xv = xvec; /* Still more help for the compiler. */ - int const *const yv = yvec; /* And more and more . . . */ - int const dmin = xoff - ylim; /* Minimum valid diagonal. */ - int const dmax = xlim - yoff; /* Maximum valid diagonal. */ - int const fmid = xoff - yoff; /* Center diagonal of top-down search. */ - int const bmid = xlim - ylim; /* Center diagonal of bottom-up search. */ - int fmin = fmid, fmax = fmid; /* Limits of top-down search. */ - int bmin = bmid, bmax = bmid; /* Limits of bottom-up search. */ - int c; /* Cost. */ - int odd = (fmid - bmid) & 1; /* True if southeast corner is on an odd - diagonal with respect to the northwest. */ - - fd[fmid] = xoff; - bd[bmid] = xlim; - - for (c = 1;; ++c) - { - int d; /* Active diagonal. */ - int big_snake = 0; - - /* Extend the top-down search by an edit step in each diagonal. */ - fmin > dmin ? fd[--fmin - 1] = -1 : ++fmin; - fmax < dmax ? fd[++fmax + 1] = -1 : --fmax; - for (d = fmax; d >= fmin; d -= 2) - { - int x, y, oldx, tlo = fd[d - 1], thi = fd[d + 1]; - - if (tlo >= thi) - x = tlo + 1; - else - x = thi; - oldx = x; - y = x - d; - while (x < xlim && y < ylim && xv[x] == yv[y]) - ++x, ++y; - if (x - oldx > SNAKE_LIMIT) - big_snake = 1; - fd[d] = x; - if (odd && bmin <= d && d <= bmax && bd[d] <= x) - { - part->xmid = x; - part->ymid = y; - part->lo_minimal = part->hi_minimal = 1; - return 2 * c - 1; - } - } - - /* Similarly extend the bottom-up search. */ - bmin > dmin ? bd[--bmin - 1] = INT_MAX : ++bmin; - bmax < dmax ? bd[++bmax + 1] = INT_MAX : --bmax; - for (d = bmax; d >= bmin; d -= 2) - { - int x, y, oldx, tlo = bd[d - 1], thi = bd[d + 1]; - - if (tlo < thi) - x = tlo; - else - x = thi - 1; - oldx = x; - y = x - d; - while (x > xoff && y > yoff && xv[x - 1] == yv[y - 1]) - --x, --y; - if (oldx - x > SNAKE_LIMIT) - big_snake = 1; - bd[d] = x; - if (!odd && fmin <= d && d <= fmax && x <= fd[d]) - { - part->xmid = x; - part->ymid = y; - part->lo_minimal = part->hi_minimal = 1; - return 2 * c; - } - } - - if (minimal) - continue; - - /* Heuristic: check occasionally for a diagonal that has made - lots of progress compared with the edit distance. - If we have any such, find the one that has made the most - progress and return it as if it had succeeded. - - With this heuristic, for files with a constant small density - of changes, the algorithm is linear in the file size. */ - - if (c > 200 && big_snake && heuristic) - { - int best; - - best = 0; - for (d = fmax; d >= fmin; d -= 2) - { - int dd = d - fmid; - int x = fd[d]; - int y = x - d; - int v = (x - xoff) * 2 - dd; - if (v > 12 * (c + (dd < 0 ? -dd : dd))) - { - if (v > best - && xoff + SNAKE_LIMIT <= x && x < xlim - && yoff + SNAKE_LIMIT <= y && y < ylim) - { - /* We have a good enough best diagonal; - now insist that it end with a significant snake. */ - int k; - - for (k = 1; xv[x - k] == yv[y - k]; k++) - if (k == SNAKE_LIMIT) - { - best = v; - part->xmid = x; - part->ymid = y; - break; - } - } - } - } - if (best > 0) - { - part->lo_minimal = 1; - part->hi_minimal = 0; - return 2 * c - 1; - } - - best = 0; - for (d = bmax; d >= bmin; d -= 2) - { - int dd = d - bmid; - int x = bd[d]; - int y = x - d; - int v = (xlim - x) * 2 + dd; - if (v > 12 * (c + (dd < 0 ? -dd : dd))) - { - if (v > best - && xoff < x && x <= xlim - SNAKE_LIMIT - && yoff < y && y <= ylim - SNAKE_LIMIT) - { - /* We have a good enough best diagonal; - now insist that it end with a significant snake. */ - int k; - - for (k = 0; xv[x + k] == yv[y + k]; k++) - if (k == SNAKE_LIMIT - 1) - { - best = v; - part->xmid = x; - part->ymid = y; - break; - } - } - } - } - if (best > 0) - { - part->lo_minimal = 0; - part->hi_minimal = 1; - return 2 * c - 1; - } - } - - /* Heuristic: if we've gone well beyond the call of duty, - give up and report halfway between our best results so far. */ - if (c >= too_expensive) - { - int fxybest, fxbest; - int bxybest, bxbest; - - fxbest = bxbest = 0; /* Pacify `gcc -Wall'. */ - - /* Find forward diagonal that maximizes X + Y. */ - fxybest = -1; - for (d = fmax; d >= fmin; d -= 2) - { - int x = min (fd[d], xlim); - int y = x - d; - if (ylim < y) - x = ylim + d, y = ylim; - if (fxybest < x + y) - { - fxybest = x + y; - fxbest = x; - } - } - - /* Find backward diagonal that minimizes X + Y. */ - bxybest = INT_MAX; - for (d = bmax; d >= bmin; d -= 2) - { - int x = max (xoff, bd[d]); - int y = x - d; - if (y < yoff) - x = yoff + d, y = yoff; - if (x + y < bxybest) - { - bxybest = x + y; - bxbest = x; - } - } - - /* Use the better of the two diagonals. */ - if ((xlim + ylim) - bxybest < fxybest - (xoff + yoff)) - { - part->xmid = fxbest; - part->ymid = fxybest - fxbest; - part->lo_minimal = 1; - part->hi_minimal = 0; - } - else - { - part->xmid = bxbest; - part->ymid = bxybest - bxbest; - part->lo_minimal = 0; - part->hi_minimal = 1; - } - return 2 * c - 1; - } - } -} - -/* Compare in detail contiguous subsequences of the two files - which are known, as a whole, to match each other. - - The results are recorded in the vectors files[N].changed_flag, by - storing a 1 in the element for each line that is an insertion or deletion. - - The subsequence of file 0 is [XOFF, XLIM) and likewise for file 1. - - Note that XLIM, YLIM are exclusive bounds. - All line numbers are origin-0 and discarded lines are not counted. - - If MINIMAL is nonzero, find a minimal difference no matter how - expensive it is. */ - -static void -compareseq (xoff, xlim, yoff, ylim, minimal) - int xoff, xlim, yoff, ylim, minimal; -{ - int * const xv = xvec; /* Help the compiler. */ - int * const yv = yvec; - - /* Slide down the bottom initial diagonal. */ - while (xoff < xlim && yoff < ylim && xv[xoff] == yv[yoff]) - ++xoff, ++yoff; - /* Slide up the top initial diagonal. */ - while (xlim > xoff && ylim > yoff && xv[xlim - 1] == yv[ylim - 1]) - --xlim, --ylim; - - /* Handle simple cases. */ - if (xoff == xlim) - while (yoff < ylim) - files[1].changed_flag[files[1].realindexes[yoff++]] = 1; - else if (yoff == ylim) - while (xoff < xlim) - files[0].changed_flag[files[0].realindexes[xoff++]] = 1; - else - { - int c; - struct partition part; - - /* Find a point of correspondence in the middle of the files. */ - - c = diag (xoff, xlim, yoff, ylim, minimal, &part); - - if (c == 1) - { - /* This should be impossible, because it implies that - one of the two subsequences is empty, - and that case was handled above without calling `diag'. - Let's verify that this is true. */ - abort (); -#if 0 - /* The two subsequences differ by a single insert or delete; - record it and we are done. */ - if (part.xmid - part.ymid < xoff - yoff) - files[1].changed_flag[files[1].realindexes[part.ymid - 1]] = 1; - else - files[0].changed_flag[files[0].realindexes[part.xmid]] = 1; -#endif - } - else - { - /* Use the partitions to split this problem into subproblems. */ - compareseq (xoff, part.xmid, yoff, part.ymid, part.lo_minimal); - compareseq (part.xmid, xlim, part.ymid, ylim, part.hi_minimal); - } - } -} - -/* Discard lines from one file that have no matches in the other file. - - A line which is discarded will not be considered by the actual - comparison algorithm; it will be as if that line were not in the file. - The file's `realindexes' table maps virtual line numbers - (which don't count the discarded lines) into real line numbers; - this is how the actual comparison algorithm produces results - that are comprehensible when the discarded lines are counted. - - When we discard a line, we also mark it as a deletion or insertion - so that it will be printed in the output. */ - -static void -discard_confusing_lines (filevec) - struct file_data filevec[]; -{ - unsigned int f, i; - char *discarded[2]; - int *equiv_count[2]; - int *p; - - /* Allocate our results. */ - p = (int *) xmalloc ((filevec[0].buffered_lines + filevec[1].buffered_lines) - * (2 * sizeof (int))); - for (f = 0; f < 2; f++) - { - filevec[f].undiscarded = p; p += filevec[f].buffered_lines; - filevec[f].realindexes = p; p += filevec[f].buffered_lines; - } - - /* Set up equiv_count[F][I] as the number of lines in file F - that fall in equivalence class I. */ - - p = (int *) xmalloc (filevec[0].equiv_max * (2 * sizeof (int))); - equiv_count[0] = p; - equiv_count[1] = p + filevec[0].equiv_max; - bzero (p, filevec[0].equiv_max * (2 * sizeof (int))); - - for (i = 0; i < filevec[0].buffered_lines; ++i) - ++equiv_count[0][filevec[0].equivs[i]]; - for (i = 0; i < filevec[1].buffered_lines; ++i) - ++equiv_count[1][filevec[1].equivs[i]]; - - /* Set up tables of which lines are going to be discarded. */ - - discarded[0] = xmalloc (sizeof (char) - * (filevec[0].buffered_lines - + filevec[1].buffered_lines)); - discarded[1] = discarded[0] + filevec[0].buffered_lines; - bzero (discarded[0], sizeof (char) * (filevec[0].buffered_lines - + filevec[1].buffered_lines)); - - /* Mark to be discarded each line that matches no line of the other file. - If a line matches many lines, mark it as provisionally discardable. */ - - for (f = 0; f < 2; f++) - { - unsigned int end = filevec[f].buffered_lines; - char *discards = discarded[f]; - int *counts = equiv_count[1 - f]; - int *equivs = filevec[f].equivs; - unsigned int many = 5; - unsigned int tem = end / 64; - - /* Multiply MANY by approximate square root of number of lines. - That is the threshold for provisionally discardable lines. */ - while ((tem = tem >> 2) > 0) - many *= 2; - - for (i = 0; i < end; i++) - { - int nmatch; - if (equivs[i] == 0) - continue; - nmatch = counts[equivs[i]]; - if (nmatch == 0) - discards[i] = 1; - else if (nmatch > many) - discards[i] = 2; - } - } - - /* Don't really discard the provisional lines except when they occur - in a run of discardables, with nonprovisionals at the beginning - and end. */ - - for (f = 0; f < 2; f++) - { - unsigned int end = filevec[f].buffered_lines; - register char *discards = discarded[f]; - - for (i = 0; i < end; i++) - { - /* Cancel provisional discards not in middle of run of discards. */ - if (discards[i] == 2) - discards[i] = 0; - else if (discards[i] != 0) - { - /* We have found a nonprovisional discard. */ - register int j; - unsigned int length; - unsigned int provisional = 0; - - /* Find end of this run of discardable lines. - Count how many are provisionally discardable. */ - for (j = i; j < end; j++) - { - if (discards[j] == 0) - break; - if (discards[j] == 2) - ++provisional; - } - - /* Cancel provisional discards at end, and shrink the run. */ - while (j > i && discards[j - 1] == 2) - discards[--j] = 0, --provisional; - - /* Now we have the length of a run of discardable lines - whose first and last are not provisional. */ - length = j - i; - - /* If 1/4 of the lines in the run are provisional, - cancel discarding of all provisional lines in the run. */ - if (provisional * 4 > length) - { - while (j > i) - if (discards[--j] == 2) - discards[j] = 0; - } - else - { - register unsigned int consec; - unsigned int minimum = 1; - unsigned int tem = length / 4; - - /* MINIMUM is approximate square root of LENGTH/4. - A subrun of two or more provisionals can stand - when LENGTH is at least 16. - A subrun of 4 or more can stand when LENGTH >= 64. */ - while ((tem = tem >> 2) > 0) - minimum *= 2; - minimum++; - - /* Cancel any subrun of MINIMUM or more provisionals - within the larger run. */ - for (j = 0, consec = 0; j < length; j++) - if (discards[i + j] != 2) - consec = 0; - else if (minimum == ++consec) - /* Back up to start of subrun, to cancel it all. */ - j -= consec; - else if (minimum < consec) - discards[i + j] = 0; - - /* Scan from beginning of run - until we find 3 or more nonprovisionals in a row - or until the first nonprovisional at least 8 lines in. - Until that point, cancel any provisionals. */ - for (j = 0, consec = 0; j < length; j++) - { - if (j >= 8 && discards[i + j] == 1) - break; - if (discards[i + j] == 2) - consec = 0, discards[i + j] = 0; - else if (discards[i + j] == 0) - consec = 0; - else - consec++; - if (consec == 3) - break; - } - - /* I advances to the last line of the run. */ - i += length - 1; - - /* Same thing, from end. */ - for (j = 0, consec = 0; j < length; j++) - { - if (j >= 8 && discards[i - j] == 1) - break; - if (discards[i - j] == 2) - consec = 0, discards[i - j] = 0; - else if (discards[i - j] == 0) - consec = 0; - else - consec++; - if (consec == 3) - break; - } - } - } - } - } - - /* Actually discard the lines. */ - for (f = 0; f < 2; f++) - { - char *discards = discarded[f]; - unsigned int end = filevec[f].buffered_lines; - unsigned int j = 0; - for (i = 0; i < end; ++i) - if (no_discards || discards[i] == 0) - { - filevec[f].undiscarded[j] = filevec[f].equivs[i]; - filevec[f].realindexes[j++] = i; - } - else - filevec[f].changed_flag[i] = 1; - filevec[f].nondiscarded_lines = j; - } - - free (discarded[0]); - free (equiv_count[0]); -} - -/* Adjust inserts/deletes of identical lines to join changes - as much as possible. - - We do something when a run of changed lines include a - line at one end and have an excluded, identical line at the other. - We are free to choose which identical line is included. - `compareseq' usually chooses the one at the beginning, - but usually it is cleaner to consider the following identical line - to be the "change". */ - -int inhibit; - -static void -shift_boundaries (filevec) - struct file_data filevec[]; -{ - int f; - - if (inhibit) - return; - - for (f = 0; f < 2; f++) - { - char *changed = filevec[f].changed_flag; - char const *other_changed = filevec[1-f].changed_flag; - int const *equivs = filevec[f].equivs; - int i = 0; - int j = 0; - int i_end = filevec[f].buffered_lines; - - while (1) - { - int runlength, start, corresponding; - - /* Scan forwards to find beginning of another run of changes. - Also keep track of the corresponding point in the other file. */ - - while (i < i_end && changed[i] == 0) - { - while (other_changed[j++]) - continue; - i++; - } - - if (i == i_end) - break; - - start = i; - - /* Find the end of this run of changes. */ - - while (changed[++i]) - continue; - while (other_changed[j]) - j++; - - do - { - /* Record the length of this run of changes, so that - we can later determine whether the run has grown. */ - runlength = i - start; - - /* Move the changed region back, so long as the - previous unchanged line matches the last changed one. - This merges with previous changed regions. */ - - while (start && equivs[start - 1] == equivs[i - 1]) - { - changed[--start] = 1; - changed[--i] = 0; - while (changed[start - 1]) - start--; - while (other_changed[--j]) - continue; - } - - /* Set CORRESPONDING to the end of the changed run, at the last - point where it corresponds to a changed run in the other file. - CORRESPONDING == I_END means no such point has been found. */ - corresponding = other_changed[j - 1] ? i : i_end; - - /* Move the changed region forward, so long as the - first changed line matches the following unchanged one. - This merges with following changed regions. - Do this second, so that if there are no merges, - the changed region is moved forward as far as possible. */ - - while (i != i_end && equivs[start] == equivs[i]) - { - changed[start++] = 0; - changed[i++] = 1; - while (changed[i]) - i++; - while (other_changed[++j]) - corresponding = i; - } - } - while (runlength != i - start); - - /* If possible, move the fully-merged run of changes - back to a corresponding run in the other file. */ - - while (corresponding < i) - { - changed[--start] = 1; - changed[--i] = 0; - while (other_changed[--j]) - continue; - } - } - } -} - -/* Cons an additional entry onto the front of an edit script OLD. - LINE0 and LINE1 are the first affected lines in the two files (origin 0). - DELETED is the number of lines deleted here from file 0. - INSERTED is the number of lines inserted here in file 1. - - If DELETED is 0 then LINE0 is the number of the line before - which the insertion was done; vice versa for INSERTED and LINE1. */ - -static struct change * -add_change (line0, line1, deleted, inserted, old) - int line0, line1, deleted, inserted; - struct change *old; -{ - struct change *new = (struct change *) xmalloc (sizeof (struct change)); - - new->line0 = line0; - new->line1 = line1; - new->inserted = inserted; - new->deleted = deleted; - new->link = old; - return new; -} - -/* Scan the tables of which lines are inserted and deleted, - producing an edit script in reverse order. */ - -static struct change * -build_reverse_script (filevec) - struct file_data const filevec[]; -{ - struct change *script = 0; - char *changed0 = filevec[0].changed_flag; - char *changed1 = filevec[1].changed_flag; - int len0 = filevec[0].buffered_lines; - int len1 = filevec[1].buffered_lines; - - /* Note that changedN[len0] does exist, and contains 0. */ - - int i0 = 0, i1 = 0; - - while (i0 < len0 || i1 < len1) - { - if (changed0[i0] || changed1[i1]) - { - int line0 = i0, line1 = i1; - - /* Find # lines changed here in each file. */ - while (changed0[i0]) ++i0; - while (changed1[i1]) ++i1; - - /* Record this change. */ - script = add_change (line0, line1, i0 - line0, i1 - line1, script); - } - - /* We have reached lines in the two files that match each other. */ - i0++, i1++; - } - - return script; -} - -/* Scan the tables of which lines are inserted and deleted, - producing an edit script in forward order. */ - -static struct change * -build_script (filevec) - struct file_data const filevec[]; -{ - struct change *script = 0; - char *changed0 = filevec[0].changed_flag; - char *changed1 = filevec[1].changed_flag; - int i0 = filevec[0].buffered_lines, i1 = filevec[1].buffered_lines; - - /* Note that changedN[-1] does exist, and contains 0. */ - - while (i0 >= 0 || i1 >= 0) - { - if (changed0[i0 - 1] || changed1[i1 - 1]) - { - int line0 = i0, line1 = i1; - - /* Find # lines changed here in each file. */ - while (changed0[i0 - 1]) --i0; - while (changed1[i1 - 1]) --i1; - - /* Record this change. */ - script = add_change (i0, i1, line0 - i0, line1 - i1, script); - } - - /* We have reached lines in the two files that match each other. */ - i0--, i1--; - } - - return script; -} - -/* If CHANGES, briefly report that two files differed. */ -static void -briefly_report (changes, filevec) - int changes; - struct file_data const filevec[]; -{ - if (changes) - message (no_details_flag ? "Files %s and %s differ\n" - : "Binary files %s and %s differ\n", - filevec[0].name, filevec[1].name); -} - -/* Report the differences of two files. DEPTH is the current directory - depth. */ -int -diff_2_files (filevec, depth) - struct file_data filevec[]; - int depth; -{ - int diags; - int i; - struct change *e, *p; - struct change *script; - int changes; - - - /* If we have detected that either file is binary, - compare the two files as binary. This can happen - only when the first chunk is read. - Also, --brief without any --ignore-* options means - we can speed things up by treating the files as binary. */ - - if (read_files (filevec, no_details_flag & ~ignore_some_changes)) - { - /* Files with different lengths must be different. */ - if (filevec[0].stat.st_size != filevec[1].stat.st_size - && (filevec[0].desc < 0 || S_ISREG (filevec[0].stat.st_mode)) - && (filevec[1].desc < 0 || S_ISREG (filevec[1].stat.st_mode))) - changes = 1; - - /* Standard input equals itself. */ - else if (filevec[0].desc == filevec[1].desc) - changes = 0; - - else - /* Scan both files, a buffer at a time, looking for a difference. */ - { - /* Allocate same-sized buffers for both files. */ - size_t buffer_size = buffer_lcm (STAT_BLOCKSIZE (filevec[0].stat), - STAT_BLOCKSIZE (filevec[1].stat)); - for (i = 0; i < 2; i++) - filevec[i].buffer = xrealloc (filevec[i].buffer, buffer_size); - - for (;; filevec[0].buffered_chars = filevec[1].buffered_chars = 0) - { - /* Read a buffer's worth from both files. */ - for (i = 0; i < 2; i++) - if (0 <= filevec[i].desc) - while (filevec[i].buffered_chars != buffer_size) - { - int r = read (filevec[i].desc, - filevec[i].buffer - + filevec[i].buffered_chars, - buffer_size - filevec[i].buffered_chars); - if (r == 0) - break; - if (r < 0) - pfatal_with_name (filevec[i].name); - filevec[i].buffered_chars += r; - } - - /* If the buffers differ, the files differ. */ - if (filevec[0].buffered_chars != filevec[1].buffered_chars - || (filevec[0].buffered_chars != 0 - && memcmp (filevec[0].buffer, - filevec[1].buffer, - filevec[0].buffered_chars) != 0)) - { - changes = 1; - break; - } - - /* If we reach end of file, the files are the same. */ - if (filevec[0].buffered_chars != buffer_size) - { - changes = 0; - break; - } - } - } - - briefly_report (changes, filevec); - } - else - { - /* Allocate vectors for the results of comparison: - a flag for each line of each file, saying whether that line - is an insertion or deletion. - Allocate an extra element, always zero, at each end of each vector. */ - - size_t s = filevec[0].buffered_lines + filevec[1].buffered_lines + 4; - filevec[0].changed_flag = xmalloc (s); - bzero (filevec[0].changed_flag, s); - filevec[0].changed_flag++; - filevec[1].changed_flag = filevec[0].changed_flag - + filevec[0].buffered_lines + 2; - - /* Some lines are obviously insertions or deletions - because they don't match anything. Detect them now, and - avoid even thinking about them in the main comparison algorithm. */ - - discard_confusing_lines (filevec); - - /* Now do the main comparison algorithm, considering just the - undiscarded lines. */ - - xvec = filevec[0].undiscarded; - yvec = filevec[1].undiscarded; - diags = filevec[0].nondiscarded_lines + filevec[1].nondiscarded_lines + 3; - fdiag = (int *) xmalloc (diags * (2 * sizeof (int))); - bdiag = fdiag + diags; - fdiag += filevec[1].nondiscarded_lines + 1; - bdiag += filevec[1].nondiscarded_lines + 1; - - /* Set TOO_EXPENSIVE to be approximate square root of input size, - bounded below by 256. */ - too_expensive = 1; - for (i = filevec[0].nondiscarded_lines + filevec[1].nondiscarded_lines; - i != 0; i >>= 2) - too_expensive <<= 1; - too_expensive = max (256, too_expensive); - - files[0] = filevec[0]; - files[1] = filevec[1]; - - compareseq (0, filevec[0].nondiscarded_lines, - 0, filevec[1].nondiscarded_lines, no_discards); - - free (fdiag - (filevec[1].nondiscarded_lines + 1)); - - /* Modify the results slightly to make them prettier - in cases where that can validly be done. */ - - shift_boundaries (filevec); - - /* Get the results of comparison in the form of a chain - of `struct change's -- an edit script. */ - - if (output_style == OUTPUT_ED) - script = build_reverse_script (filevec); - else - script = build_script (filevec); - - /* Set CHANGES if we had any diffs. - If some changes are ignored, we must scan the script to decide. */ - if (ignore_blank_lines_flag || ignore_regexp_list) - { - struct change *next = script; - changes = 0; - - while (next && changes == 0) - { - struct change *this, *end; - int first0, last0, first1, last1, deletes, inserts; - - /* Find a set of changes that belong together. */ - this = next; - end = find_change (next); - - /* Disconnect them from the rest of the changes, making them - a hunk, and remember the rest for next iteration. */ - next = end->link; - end->link = 0; - - /* Determine whether this hunk is really a difference. */ - analyze_hunk (this, &first0, &last0, &first1, &last1, - &deletes, &inserts); - - /* Reconnect the script so it will all be freed properly. */ - end->link = next; - - if (deletes || inserts) - changes = 1; - } - } - else - changes = (script != 0); - - if (no_details_flag) - briefly_report (changes, filevec); - else - { - if (changes || ! no_diff_means_no_output) - { - /* Record info for starting up output, - to be used if and when we have some output to print. */ - setup_output (files[0].name, files[1].name, depth); - - switch (output_style) - { - case OUTPUT_CONTEXT: - print_context_script (script, 0); - break; - - case OUTPUT_UNIFIED: - print_context_script (script, 1); - break; - - case OUTPUT_ED: - print_ed_script (script); - break; - - case OUTPUT_FORWARD_ED: - pr_forward_ed_script (script); - break; - - case OUTPUT_RCS: - print_rcs_script (script); - break; - - case OUTPUT_NORMAL: - print_normal_script (script); - break; - - case OUTPUT_IFDEF: - print_ifdef_script (script); - break; - - case OUTPUT_SDIFF: - print_sdiff_script (script); - } - - finish_output (); - } - } - - free (filevec[0].undiscarded); - - free (filevec[0].changed_flag - 1); - - for (i = 1; i >= 0; --i) - free (filevec[i].equivs); - - for (i = 0; i < 2; ++i) - free (filevec[i].linbuf + filevec[i].linbuf_base); - - for (e = script; e; e = p) - { - p = e->link; - free (e); - } - - if (! ROBUST_OUTPUT_STYLE (output_style)) - for (i = 0; i < 2; ++i) - if (filevec[i].missing_newline) - { - diff_error ("No newline at end of file %s", filevec[i].name, ""); - changes = 2; - } - } - - if (filevec[0].buffer != filevec[1].buffer) - free (filevec[0].buffer); - free (filevec[1].buffer); - - return changes; -} diff --git a/contrib/cvs/diff/cmpbuf.c b/contrib/cvs/diff/cmpbuf.c deleted file mode 100644 index 2820dfa..0000000 --- a/contrib/cvs/diff/cmpbuf.c +++ /dev/null @@ -1,38 +0,0 @@ -/* Buffer primitives for comparison operations. - Copyright (C) 1993 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - */ - -#include "system.h" -#include "cmpbuf.h" - -/* Least common multiple of two buffer sizes A and B. */ - -size_t -buffer_lcm (a, b) - size_t a, b; -{ - size_t m, n, r; - - /* Yield reasonable values if buffer sizes are zero. */ - if (!a) - return b ? b : 8 * 1024; - if (!b) - return a; - - /* n = gcd (a, b) */ - for (m = a, n = b; (r = m % n) != 0; m = n, n = r) - continue; - - return a/n * b; -} diff --git a/contrib/cvs/diff/cmpbuf.h b/contrib/cvs/diff/cmpbuf.h deleted file mode 100644 index b7b965d..0000000 --- a/contrib/cvs/diff/cmpbuf.h +++ /dev/null @@ -1,18 +0,0 @@ -/* Buffer primitives for comparison operations. - Copyright (C) 1993 Free Software Foundation, Inc. - -This file is part of GNU DIFF. - -GNU DIFF is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU DIFF 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. - -*/ - -size_t buffer_lcm PARAMS((size_t, size_t)); diff --git a/contrib/cvs/diff/context.c b/contrib/cvs/diff/context.c deleted file mode 100644 index c4562c9..0000000 --- a/contrib/cvs/diff/context.c +++ /dev/null @@ -1,462 +0,0 @@ -/* Context-format output routines for GNU DIFF. - Copyright (C) 1988,1989,1991,1992,1993,1994,1998 Free Software Foundation, Inc. - -This file is part of GNU DIFF. - -GNU DIFF is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU DIFF 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. - -*/ - -#include "diff.h" - -static struct change *find_hunk PARAMS((struct change *)); -static void find_function PARAMS((struct file_data const *, int, char const **, size_t *)); -static void mark_ignorable PARAMS((struct change *)); -static void pr_context_hunk PARAMS((struct change *)); -static void pr_unidiff_hunk PARAMS((struct change *)); -static void print_context_label PARAMS ((char const *, struct file_data *, char const *)); -static void print_context_number_range PARAMS((struct file_data const *, int, int)); -static void print_unidiff_number_range PARAMS((struct file_data const *, int, int)); - -/* Last place find_function started searching from. */ -static int find_function_last_search; - -/* The value find_function returned when it started searching there. */ -static int find_function_last_match; - -/* Print a label for a context diff, with a file name and date or a label. */ - -static void -print_context_label (mark, inf, label) - char const *mark; - struct file_data *inf; - char const *label; -{ - if (label) - printf_output ("%s %s\n", mark, label); - else - { - char const *ct = ctime (&inf->stat.st_mtime); - if (!ct) - ct = "?\n"; - /* See Posix.2 section 4.17.6.1.4 for this format. */ - printf_output ("%s %s\t%s", mark, inf->name, ct); - } -} - -/* Print a header for a context diff, with the file names and dates. */ - -void -print_context_header (inf, unidiff_flag) - struct file_data inf[]; - int unidiff_flag; -{ - if (unidiff_flag) - { - print_context_label ("---", &inf[0], file_label[0]); - print_context_label ("+++", &inf[1], file_label[1]); - } - else - { - print_context_label ("***", &inf[0], file_label[0]); - print_context_label ("---", &inf[1], file_label[1]); - } -} - -/* Print an edit script in context format. */ - -void -print_context_script (script, unidiff_flag) - struct change *script; - int unidiff_flag; -{ - if (ignore_blank_lines_flag || ignore_regexp_list) - mark_ignorable (script); - else - { - struct change *e; - for (e = script; e; e = e->link) - e->ignore = 0; - } - - find_function_last_search = - files[0].prefix_lines; - find_function_last_match = find_function_last_search - 1; - - if (unidiff_flag) - print_script (script, find_hunk, pr_unidiff_hunk); - else - print_script (script, find_hunk, pr_context_hunk); -} - -/* Print a pair of line numbers with a comma, translated for file FILE. - If the second number is not greater, use the first in place of it. - - Args A and B are internal line numbers. - We print the translated (real) line numbers. */ - -static void -print_context_number_range (file, a, b) - struct file_data const *file; - int a, b; -{ - int trans_a, trans_b; - translate_range (file, a, b, &trans_a, &trans_b); - - /* Note: we can have B < A in the case of a range of no lines. - In this case, we should print the line number before the range, - which is B. */ - if (trans_b > trans_a) - printf_output ("%d,%d", trans_a, trans_b); - else - printf_output ("%d", trans_b); -} - -/* Print a portion of an edit script in context format. - HUNK is the beginning of the portion to be printed. - The end is marked by a `link' that has been nulled out. - - Prints out lines from both files, and precedes each - line with the appropriate flag-character. */ - -static void -pr_context_hunk (hunk) - struct change *hunk; -{ - int first0, last0, first1, last1, show_from, show_to, i; - struct change *next; - char const *prefix; - char const *function; - size_t function_length; - - /* Determine range of line numbers involved in each file. */ - - analyze_hunk (hunk, &first0, &last0, &first1, &last1, &show_from, &show_to); - - if (!show_from && !show_to) - return; - - /* Include a context's width before and after. */ - - i = - files[0].prefix_lines; - first0 = max (first0 - context, i); - first1 = max (first1 - context, i); - last0 = min (last0 + context, files[0].valid_lines - 1); - last1 = min (last1 + context, files[1].valid_lines - 1); - - /* If desired, find the preceding function definition line in file 0. */ - function = 0; - if (function_regexp_list) - find_function (&files[0], first0, &function, &function_length); - - begin_output (); - - /* If we looked for and found a function this is part of, - include its name in the header of the diff section. */ - printf_output ("***************"); - - if (function) - { - printf_output (" "); - write_output (function, min (function_length - 1, 40)); - } - - printf_output ("\n*** "); - print_context_number_range (&files[0], first0, last0); - printf_output (" ****\n"); - - if (show_from) - { - next = hunk; - - for (i = first0; i <= last0; i++) - { - /* Skip past changes that apply (in file 0) - only to lines before line I. */ - - while (next && next->line0 + next->deleted <= i) - next = next->link; - - /* Compute the marking for line I. */ - - prefix = " "; - if (next && next->line0 <= i) - /* The change NEXT covers this line. - If lines were inserted here in file 1, this is "changed". - Otherwise it is "deleted". */ - prefix = (next->inserted > 0 ? "!" : "-"); - - print_1_line (prefix, &files[0].linbuf[i]); - } - } - - printf_output ("--- "); - print_context_number_range (&files[1], first1, last1); - printf_output (" ----\n"); - - if (show_to) - { - next = hunk; - - for (i = first1; i <= last1; i++) - { - /* Skip past changes that apply (in file 1) - only to lines before line I. */ - - while (next && next->line1 + next->inserted <= i) - next = next->link; - - /* Compute the marking for line I. */ - - prefix = " "; - if (next && next->line1 <= i) - /* The change NEXT covers this line. - If lines were deleted here in file 0, this is "changed". - Otherwise it is "inserted". */ - prefix = (next->deleted > 0 ? "!" : "+"); - - print_1_line (prefix, &files[1].linbuf[i]); - } - } -} - -/* Print a pair of line numbers with a comma, translated for file FILE. - If the second number is smaller, use the first in place of it. - If the numbers are equal, print just one number. - - Args A and B are internal line numbers. - We print the translated (real) line numbers. */ - -static void -print_unidiff_number_range (file, a, b) - struct file_data const *file; - int a, b; -{ - int trans_a, trans_b; - translate_range (file, a, b, &trans_a, &trans_b); - - /* Note: we can have B < A in the case of a range of no lines. - In this case, we should print the line number before the range, - which is B. */ - if (trans_b <= trans_a) - printf_output (trans_b == trans_a ? "%d" : "%d,0", trans_b); - else - printf_output ("%d,%d", trans_a, trans_b - trans_a + 1); -} - -/* Print a portion of an edit script in unidiff format. - HUNK is the beginning of the portion to be printed. - The end is marked by a `link' that has been nulled out. - - Prints out lines from both files, and precedes each - line with the appropriate flag-character. */ - -static void -pr_unidiff_hunk (hunk) - struct change *hunk; -{ - int first0, last0, first1, last1, show_from, show_to, i, j, k; - struct change *next; - char const *function; - size_t function_length; - - /* Determine range of line numbers involved in each file. */ - - analyze_hunk (hunk, &first0, &last0, &first1, &last1, &show_from, &show_to); - - if (!show_from && !show_to) - return; - - /* Include a context's width before and after. */ - - i = - files[0].prefix_lines; - first0 = max (first0 - context, i); - first1 = max (first1 - context, i); - last0 = min (last0 + context, files[0].valid_lines - 1); - last1 = min (last1 + context, files[1].valid_lines - 1); - - /* If desired, find the preceding function definition line in file 0. */ - function = 0; - if (function_regexp_list) - find_function (&files[0], first0, &function, &function_length); - - begin_output (); - - printf_output ("@@ -"); - print_unidiff_number_range (&files[0], first0, last0); - printf_output (" +"); - print_unidiff_number_range (&files[1], first1, last1); - printf_output (" @@"); - - /* If we looked for and found a function this is part of, - include its name in the header of the diff section. */ - - if (function) - { - write_output (" ", 1); - write_output (function, min (function_length - 1, 40)); - } - write_output ("\n", 1); - - next = hunk; - i = first0; - j = first1; - - while (i <= last0 || j <= last1) - { - - /* If the line isn't a difference, output the context from file 0. */ - - if (!next || i < next->line0) - { - write_output (tab_align_flag ? "\t" : " ", 1); - print_1_line (0, &files[0].linbuf[i++]); - j++; - } - else - { - /* For each difference, first output the deleted part. */ - - k = next->deleted; - while (k--) - { - write_output ("-", 1); - if (tab_align_flag) - write_output ("\t", 1); - print_1_line (0, &files[0].linbuf[i++]); - } - - /* Then output the inserted part. */ - - k = next->inserted; - while (k--) - { - write_output ("+", 1); - if (tab_align_flag) - write_output ("\t", 1); - print_1_line (0, &files[1].linbuf[j++]); - } - - /* We're done with this hunk, so on to the next! */ - - next = next->link; - } - } -} - -/* Scan a (forward-ordered) edit script for the first place that more than - 2*CONTEXT unchanged lines appear, and return a pointer - to the `struct change' for the last change before those lines. */ - -static struct change * -find_hunk (start) - struct change *start; -{ - struct change *prev; - int top0, top1; - int thresh; - - do - { - /* Compute number of first line in each file beyond this changed. */ - top0 = start->line0 + start->deleted; - top1 = start->line1 + start->inserted; - prev = start; - start = start->link; - /* Threshold distance is 2*CONTEXT between two non-ignorable changes, - but only CONTEXT if one is ignorable. */ - thresh = ((prev->ignore || (start && start->ignore)) - ? context - : 2 * context + 1); - /* It is not supposed to matter which file we check in the end-test. - If it would matter, crash. */ - if (start && start->line0 - top0 != start->line1 - top1) - abort (); - } while (start - /* Keep going if less than THRESH lines - elapse before the affected line. */ - && start->line0 < top0 + thresh); - - return prev; -} - -/* Set the `ignore' flag properly in each change in SCRIPT. - It should be 1 if all the lines inserted or deleted in that change - are ignorable lines. */ - -static void -mark_ignorable (script) - struct change *script; -{ - while (script) - { - struct change *next = script->link; - int first0, last0, first1, last1, deletes, inserts; - - /* Turn this change into a hunk: detach it from the others. */ - script->link = 0; - - /* Determine whether this change is ignorable. */ - analyze_hunk (script, &first0, &last0, &first1, &last1, &deletes, &inserts); - /* Reconnect the chain as before. */ - script->link = next; - - /* If the change is ignorable, mark it. */ - script->ignore = (!deletes && !inserts); - - /* Advance to the following change. */ - script = next; - } -} - -/* Find the last function-header line in FILE prior to line number LINENUM. - This is a line containing a match for the regexp in `function_regexp'. - Store the address of the line text into LINEP and the length of the - line into LENP. - Do not store anything if no function-header is found. */ - -static void -find_function (file, linenum, linep, lenp) - struct file_data const *file; - int linenum; - char const **linep; - size_t *lenp; -{ - int i = linenum; - int last = find_function_last_search; - find_function_last_search = i; - - while (--i >= last) - { - /* See if this line is what we want. */ - struct regexp_list *r; - char const *line = file->linbuf[i]; - size_t len = file->linbuf[i + 1] - line; - - for (r = function_regexp_list; r; r = r->next) - if (0 <= re_search (&r->buf, line, len, 0, len, 0)) - { - *linep = line; - *lenp = len; - find_function_last_match = i; - return; - } - } - /* If we search back to where we started searching the previous time, - find the line we found last time. */ - if (find_function_last_match >= - file->prefix_lines) - { - i = find_function_last_match; - *linep = file->linbuf[i]; - *lenp = file->linbuf[i + 1] - *linep; - return; - } - return; -} diff --git a/contrib/cvs/diff/diff.c b/contrib/cvs/diff/diff.c deleted file mode 100644 index c1324c6..0000000 --- a/contrib/cvs/diff/diff.c +++ /dev/null @@ -1,1266 +0,0 @@ -/* GNU DIFF entry routine. - Copyright (C) 1988, 1989, 1992, 1993, 1994, 1997, 1998 Free Software Foundation, Inc. - -This file is part of GNU DIFF. - -GNU DIFF is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU DIFF 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 DIFF was written by Mike Haertel, David Hayes, - Richard Stallman, Len Tower, and Paul Eggert. */ - -#define GDIFF_MAIN -#include "diff.h" -#include -#include "getopt.h" - -#ifdef HAVE_FNMATCH -# include /* This is supposed to be available on Posix systems */ -#else /* HAVE_FNMATCH */ -# include "fnmatch.h" /* Our substitute */ -#endif /* HAVE_FNMATCH */ - -#ifndef DEFAULT_WIDTH -#define DEFAULT_WIDTH 130 -#endif - -#ifndef GUTTER_WIDTH_MINIMUM -#define GUTTER_WIDTH_MINIMUM 3 -#endif - -/* diff.c has a real initialize_main function. */ -#ifdef initialize_main -#undef initialize_main -#endif - -static char const *filetype PARAMS((struct stat const *)); -static char *option_list PARAMS((char **, int)); -static int add_exclude_file PARAMS((char const *)); -static int ck_atoi PARAMS((char const *, int *)); -static int compare_files PARAMS((char const *, char const *, char const *, char const *, int)); -static int specify_format PARAMS((char **, char *)); -static void add_exclude PARAMS((char const *)); -static void add_regexp PARAMS((struct regexp_list **, char const *)); -static void specify_style PARAMS((enum output_style)); -static int try_help PARAMS((char const *)); -static void check_output PARAMS((FILE *)); -static void usage PARAMS((void)); -static void initialize_main PARAMS((int *, char ***)); - -/* Nonzero for -r: if comparing two directories, - compare their common subdirectories recursively. */ - -static int recursive; - -/* For debugging: don't do discard_confusing_lines. */ - -int no_discards; - -#if HAVE_SETMODE -/* I/O mode: nonzero only if using binary input/output. */ -static int binary_I_O; -#endif - -/* Return a string containing the command options with which diff was invoked. - Spaces appear between what were separate ARGV-elements. - There is a space at the beginning but none at the end. - If there were no options, the result is an empty string. - - Arguments: OPTIONVEC, a vector containing separate ARGV-elements, and COUNT, - the length of that vector. */ - -static char * -option_list (optionvec, count) - char **optionvec; /* Was `vector', but that collides on Alliant. */ - int count; -{ - int i; - size_t length = 0; - char *result; - - for (i = 0; i < count; i++) - length += strlen (optionvec[i]) + 1; - - result = xmalloc (length + 1); - result[0] = 0; - - for (i = 0; i < count; i++) - { - strcat (result, " "); - strcat (result, optionvec[i]); - } - - return result; -} - -/* Convert STR to a positive integer, storing the result in *OUT. - If STR is not a valid integer, return -1 (otherwise 0). */ -static int -ck_atoi (str, out) - char const *str; - int *out; -{ - char const *p; - for (p = str; *p; p++) - if (*p < '0' || *p > '9') - return -1; - - *out = atoi (optarg); - return 0; -} - -/* Keep track of excluded file name patterns. */ - -static char const **exclude; -static int exclude_alloc, exclude_count; - -int -excluded_filename (f) - char const *f; -{ - int i; - for (i = 0; i < exclude_count; i++) - if (fnmatch (exclude[i], f, 0) == 0) - return 1; - return 0; -} - -static void -add_exclude (pattern) - char const *pattern; -{ - if (exclude_alloc <= exclude_count) - exclude = (char const **) - (exclude_alloc == 0 - ? xmalloc ((exclude_alloc = 64) * sizeof (*exclude)) - : xrealloc (exclude, (exclude_alloc *= 2) * sizeof (*exclude))); - - exclude[exclude_count++] = pattern; -} - -static int -add_exclude_file (name) - char const *name; -{ - struct file_data f; - char *p, *q, *lim; - - f.name = optarg; - f.desc = (strcmp (optarg, "-") == 0 - ? STDIN_FILENO - : open (optarg, O_RDONLY, 0)); - if (f.desc < 0 || fstat (f.desc, &f.stat) != 0) - return -1; - - sip (&f, 1); - slurp (&f); - - for (p = f.buffer, lim = p + f.buffered_chars; p < lim; p = q) - { - q = (char *) memchr (p, '\n', lim - p); - if (!q) - q = lim; - *q++ = 0; - add_exclude (p); - } - - return close (f.desc); -} - -/* The numbers 129- that appear in the fourth element of some entries - tell the big switch in `diff_run' how to process those options. */ - -static struct option const longopts[] = -{ - {"ignore-blank-lines", 0, 0, 'B'}, - {"context", 2, 0, 'C'}, - {"ifdef", 1, 0, 'D'}, - {"show-function-line", 1, 0, 'F'}, - {"speed-large-files", 0, 0, 'H'}, - {"ignore-matching-lines", 1, 0, 'I'}, - {"label", 1, 0, 'L'}, - {"file-label", 1, 0, 'L'}, /* An alias, no longer recommended */ - {"new-file", 0, 0, 'N'}, - {"entire-new-file", 0, 0, 'N'}, /* An alias, no longer recommended */ - {"unidirectional-new-file", 0, 0, 'P'}, - {"starting-file", 1, 0, 'S'}, - {"initial-tab", 0, 0, 'T'}, - {"width", 1, 0, 'W'}, - {"text", 0, 0, 'a'}, - {"ascii", 0, 0, 'a'}, /* An alias, no longer recommended */ - {"ignore-space-change", 0, 0, 'b'}, - {"minimal", 0, 0, 'd'}, - {"ed", 0, 0, 'e'}, - {"forward-ed", 0, 0, 'f'}, - {"ignore-case", 0, 0, 'i'}, - {"paginate", 0, 0, 'l'}, - {"print", 0, 0, 'l'}, /* An alias, no longer recommended */ - {"rcs", 0, 0, 'n'}, - {"show-c-function", 0, 0, 'p'}, - {"brief", 0, 0, 'q'}, - {"recursive", 0, 0, 'r'}, - {"report-identical-files", 0, 0, 's'}, - {"expand-tabs", 0, 0, 't'}, - {"version", 0, 0, 'v'}, - {"ignore-all-space", 0, 0, 'w'}, - {"exclude", 1, 0, 'x'}, - {"exclude-from", 1, 0, 'X'}, - {"side-by-side", 0, 0, 'y'}, - {"unified", 2, 0, 'U'}, - {"left-column", 0, 0, 129}, - {"suppress-common-lines", 0, 0, 130}, - {"sdiff-merge-assist", 0, 0, 131}, - {"old-line-format", 1, 0, 132}, - {"new-line-format", 1, 0, 133}, - {"unchanged-line-format", 1, 0, 134}, - {"line-format", 1, 0, 135}, - {"old-group-format", 1, 0, 136}, - {"new-group-format", 1, 0, 137}, - {"unchanged-group-format", 1, 0, 138}, - {"changed-group-format", 1, 0, 139}, - {"horizon-lines", 1, 0, 140}, - {"help", 0, 0, 141}, - {"binary", 0, 0, 142}, - {0, 0, 0, 0} -}; - - - -int -diff_run (argc, argv, out, callbacks_arg) - int argc; - char *argv[]; - const char *out; - const struct diff_callbacks *callbacks_arg; -{ - int val; - int c; - int prev = -1; - int width = DEFAULT_WIDTH; - int show_c_function = 0; - int optind_old; - int opened_file = 0; - - callbacks = callbacks_arg; - - /* Do our initializations. */ - initialize_main (&argc, &argv); - 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) - { - switch (c) - { - /* All digits combine in decimal to specify the context-size. */ - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - case '0': - if (context == -1) - context = 0; - /* If a context length has already been specified, - more digits allowed only if they follow right after the others. - Reject two separate runs of digits, or digits after -C. */ - else if (prev < '0' || prev > '9') - fatal ("context length specified twice"); - - context = context * 10 + c - '0'; - break; - - case 'a': - /* Treat all files as text files; never treat as binary. */ - always_text_flag = 1; - break; - - case 'b': - /* Ignore changes in amount of white space. */ - ignore_space_change_flag = 1; - ignore_some_changes = 1; - ignore_some_line_changes = 1; - break; - - case 'B': - /* Ignore changes affecting only blank lines. */ - ignore_blank_lines_flag = 1; - ignore_some_changes = 1; - break; - - case 'C': /* +context[=lines] */ - case 'U': /* +unified[=lines] */ - if (optarg) - { - if (context >= 0) - fatal ("context length specified twice"); - - if (ck_atoi (optarg, &context)) - fatal ("invalid context length argument"); - } - - /* Falls through. */ - case 'c': - /* Make context-style output. */ - specify_style (c == 'U' ? OUTPUT_UNIFIED : OUTPUT_CONTEXT); - break; - - case 'd': - /* Don't discard lines. This makes things slower (sometimes much - slower) but will find a guaranteed minimal set of changes. */ - no_discards = 1; - break; - - case 'D': - /* Make merged #ifdef output. */ - specify_style (OUTPUT_IFDEF); - { - int i, err = 0; - static char const C_ifdef_group_formats[] = - "#ifndef %s\n%%<#endif /* not %s */\n%c#ifdef %s\n%%>#endif /* %s */\n%c%%=%c#ifndef %s\n%%<#else /* %s */\n%%>#endif /* %s */\n"; - char *b = xmalloc (sizeof (C_ifdef_group_formats) - + 7 * strlen(optarg) - 14 /* 7*"%s" */ - - 8 /* 5*"%%" + 3*"%c" */); - sprintf (b, C_ifdef_group_formats, - optarg, optarg, 0, - optarg, optarg, 0, 0, - optarg, optarg, optarg); - for (i = 0; i < 4; i++) - { - err |= specify_format (&group_format[i], b); - b += strlen (b) + 1; - } - if (err) - diff_error ("conflicting #ifdef formats", 0, 0); - } - break; - - case 'e': - /* Make output that is a valid `ed' script. */ - specify_style (OUTPUT_ED); - break; - - case 'f': - /* Make output that looks vaguely like an `ed' script - but has changes in the order they appear in the file. */ - specify_style (OUTPUT_FORWARD_ED); - break; - - case 'F': - /* Show, for each set of changes, the previous line that - matches the specified regexp. Currently affects only - context-style output. */ - add_regexp (&function_regexp_list, optarg); - break; - - case 'h': - /* Split the files into chunks of around 1500 lines - for faster processing. Usually does not change the result. - - This currently has no effect. */ - break; - - case 'H': - /* Turn on heuristics that speed processing of large files - with a small density of changes. */ - heuristic = 1; - break; - - case 'i': - /* Ignore changes in case. */ - ignore_case_flag = 1; - ignore_some_changes = 1; - ignore_some_line_changes = 1; - break; - - case 'I': - /* Ignore changes affecting only lines that match the - specified regexp. */ - add_regexp (&ignore_regexp_list, optarg); - ignore_some_changes = 1; - break; - - case 'l': - /* Pass the output through `pr' to paginate it. */ - paginate_flag = 1; -#if !defined(SIGCHLD) && defined(SIGCLD) -#define SIGCHLD SIGCLD -#endif -#ifdef SIGCHLD - /* Pagination requires forking and waiting, and - System V fork+wait does not work if SIGCHLD is ignored. */ - signal (SIGCHLD, SIG_DFL); -#endif - break; - - case 'L': - /* Specify file labels for `-c' output headers. */ - if (!file_label[0]) - file_label[0] = optarg; - else if (!file_label[1]) - file_label[1] = optarg; - else - fatal ("too many file label options"); - break; - - case 'n': - /* Output RCS-style diffs, like `-f' except that each command - specifies the number of lines affected. */ - specify_style (OUTPUT_RCS); - break; - - case 'N': - /* When comparing directories, if a file appears only in one - directory, treat it as present but empty in the other. */ - entire_new_file_flag = 1; - break; - - case 'p': - /* Make context-style output and show name of last C function. */ - show_c_function = 1; - add_regexp (&function_regexp_list, "^[_a-zA-Z$]"); - break; - - case 'P': - /* When comparing directories, if a file appears only in - the second directory of the two, - treat it as present but empty in the other. */ - unidirectional_new_file_flag = 1; - break; - - case 'q': - no_details_flag = 1; - break; - - case 'r': - /* When comparing directories, - recursively compare any subdirectories found. */ - recursive = 1; - break; - - case 's': - /* Print a message if the files are the same. */ - print_file_same_flag = 1; - break; - - case 'S': - /* When comparing directories, start with the specified - file name. This is used for resuming an aborted comparison. */ - dir_start_file = optarg; - break; - - case 't': - /* Expand tabs to spaces in the output so that it preserves - the alignment of the input files. */ - tab_expand_flag = 1; - break; - - case 'T': - /* Use a tab in the output, rather than a space, before the - text of an input line, so as to keep the proper alignment - in the input line without changing the characters in it. */ - tab_align_flag = 1; - break; - - case 'u': - /* Output the context diff in unidiff format. */ - specify_style (OUTPUT_UNIFIED); - break; - - case 'v': - if (callbacks && callbacks->write_stdout) - { - (*callbacks->write_stdout) ("diff - GNU diffutils version "); - (*callbacks->write_stdout) (diff_version_string); - (*callbacks->write_stdout) ("\n"); - } - else - printf ("diff - GNU diffutils version %s\n", diff_version_string); - return 0; - - case 'w': - /* Ignore horizontal white space when comparing lines. */ - ignore_all_space_flag = 1; - ignore_some_changes = 1; - ignore_some_line_changes = 1; - break; - - case 'x': - add_exclude (optarg); - break; - - case 'X': - if (add_exclude_file (optarg) != 0) - pfatal_with_name (optarg); - break; - - case 'y': - /* Use side-by-side (sdiff-style) columnar output. */ - specify_style (OUTPUT_SDIFF); - break; - - case 'W': - /* Set the line width for OUTPUT_SDIFF. */ - if (ck_atoi (optarg, &width) || width <= 0) - fatal ("column width must be a positive integer"); - break; - - case 129: - sdiff_left_only = 1; - break; - - case 130: - sdiff_skip_common_lines = 1; - break; - - case 131: - /* sdiff-style columns output. */ - specify_style (OUTPUT_SDIFF); - sdiff_help_sdiff = 1; - break; - - case 132: - case 133: - case 134: - specify_style (OUTPUT_IFDEF); - if (specify_format (&line_format[c - 132], optarg) != 0) - diff_error ("conflicting line format", 0, 0); - break; - - case 135: - specify_style (OUTPUT_IFDEF); - { - int i, err = 0; - for (i = 0; i < sizeof (line_format) / sizeof (*line_format); i++) - err |= specify_format (&line_format[i], optarg); - if (err) - diff_error ("conflicting line format", 0, 0); - } - break; - - case 136: - case 137: - case 138: - case 139: - specify_style (OUTPUT_IFDEF); - if (specify_format (&group_format[c - 136], optarg) != 0) - diff_error ("conflicting group format", 0, 0); - break; - - case 140: - if (ck_atoi (optarg, &horizon_lines) || horizon_lines < 0) - fatal ("horizon must be a nonnegative integer"); - break; - - case 141: - usage (); - if (! callbacks || ! callbacks->write_stdout) - check_output (stdout); - return 0; - - case 142: - /* Use binary I/O when reading and writing data. - On Posix hosts, this has no effect. */ -#if HAVE_SETMODE - binary_I_O = 1; -# if 0 - /* Because this code is leftover from pre-library days, - there is no way to set stdout back to the default mode - when we are done. As it turns out, I think the only - parts of CVS that pass out == NULL, and thus cause diff - to write to stdout, are "cvs diff" and "cvs rdiff". So - I'm not going to worry about this too much yet. */ - setmode (STDOUT_FILENO, O_BINARY); -# else - if (out == NULL) - error (0, 0, "warning: did not set stdout to binary mode"); -# endif -#endif - break; - - default: - return try_help (0); - } - prev = c; - } - - if (argc - optind != 2) - return try_help (argc - optind < 2 ? "missing operand" : "extra operand"); - - { - /* - * We maximize first the half line width, and then the gutter width, - * according to the following constraints: - * 1. Two half lines plus a gutter must fit in a line. - * 2. If the half line width is nonzero: - * a. The gutter width is at least GUTTER_WIDTH_MINIMUM. - * b. If tabs are not expanded to spaces, - * a half line plus a gutter is an integral number of tabs, - * so that tabs in the right column line up. - */ - int t = tab_expand_flag ? 1 : TAB_WIDTH; - int off = (width + t + GUTTER_WIDTH_MINIMUM) / (2*t) * t; - sdiff_half_width = max (0, min (off - GUTTER_WIDTH_MINIMUM, width - off)), - sdiff_column2_offset = sdiff_half_width ? off : width; - } - - if (show_c_function && output_style != OUTPUT_UNIFIED) - specify_style (OUTPUT_CONTEXT); - - if (output_style != OUTPUT_CONTEXT && output_style != OUTPUT_UNIFIED) - context = 0; - else if (context == -1) - /* Default amount of context for -c. */ - context = 3; - - if (output_style == OUTPUT_IFDEF) - { - /* Format arrays are char *, not char const *, - because integer formats are temporarily modified. - But it is safe to assign a constant like "%=" to a format array, - since "%=" does not format any integers. */ - int i; - for (i = 0; i < sizeof (line_format) / sizeof (*line_format); i++) - if (!line_format[i]) - line_format[i] = "%l\n"; - if (!group_format[OLD]) - group_format[OLD] - = group_format[UNCHANGED] ? group_format[UNCHANGED] : "%<"; - if (!group_format[NEW]) - group_format[NEW] - = group_format[UNCHANGED] ? group_format[UNCHANGED] : "%>"; - if (!group_format[UNCHANGED]) - group_format[UNCHANGED] = "%="; - if (!group_format[CHANGED]) - group_format[CHANGED] = concat (group_format[OLD], - group_format[NEW], ""); - } - - no_diff_means_no_output = - (output_style == OUTPUT_IFDEF ? - (!*group_format[UNCHANGED] - || (strcmp (group_format[UNCHANGED], "%=") == 0 - && !*line_format[UNCHANGED])) - : output_style == OUTPUT_SDIFF ? sdiff_skip_common_lines : 1); - - switch_string = option_list (argv + 1, optind - 1); - - if (callbacks && callbacks->write_output) - { - if (out != NULL) - { - diff_error ("write callback with output file", 0, 0); - return 2; - } - } - else - { - if (out == NULL) - outfile = stdout; - else - { -#if HAVE_SETMODE - /* A diff which is full of ^Z and such isn't going to work - very well in text mode. */ - if (binary_I_O) - outfile = fopen (out, "wb"); - else -#endif - outfile = fopen (out, "w"); - if (outfile == NULL) - { - perror_with_name ("could not open output file"); - return 2; - } - opened_file = 1; - } - } - - val = compare_files (0, argv[optind], 0, argv[optind + 1], 0); - - /* Print any messages that were saved up for last. */ - print_message_queue (); - - free (switch_string); - - optind = optind_old; - - if (! callbacks || ! callbacks->write_output) - check_output (outfile); - - if (opened_file) - if (fclose (outfile) != 0) - perror_with_name ("close error on output file"); - - return val; -} - -/* Add the compiled form of regexp PATTERN to REGLIST. */ - -static void -add_regexp (reglist, pattern) - struct regexp_list **reglist; - char const *pattern; -{ - struct regexp_list *r; - char const *m; - - r = (struct regexp_list *) xmalloc (sizeof (*r)); - bzero (r, sizeof (*r)); - r->buf.fastmap = xmalloc (256); - m = re_compile_pattern (pattern, strlen (pattern), &r->buf); - if (m != 0) - diff_error ("%s: %s", pattern, m); - - /* Add to the start of the list, since it's easier than the end. */ - r->next = *reglist; - *reglist = r; -} - -static int -try_help (reason) - char const *reason; -{ - if (reason) - diff_error ("%s", reason, 0); - diff_error ("Try `%s --help' for more information.", diff_program_name, 0); - return 2; -} - -static void -check_output (file) - FILE *file; -{ - if (ferror (file) || fflush (file) != 0) - fatal ("write error"); -} - -static char const * const option_help[] = { -"-i --ignore-case Consider upper- and lower-case to be the same.", -"-w --ignore-all-space Ignore all white space.", -"-b --ignore-space-change Ignore changes in the amount of white space.", -"-B --ignore-blank-lines Ignore changes whose lines are all blank.", -"-I RE --ignore-matching-lines=RE Ignore changes whose lines all match RE.", -#if HAVE_SETMODE -"--binary Read and write data in binary mode.", -#endif -"-a --text Treat all files as text.\n", -"-c -C NUM --context[=NUM] Output NUM (default 2) lines of copied context.", -"-u -U NUM --unified[=NUM] Output NUM (default 2) lines of unified context.", -" -NUM Use NUM context lines.", -" -L LABEL --label LABEL Use LABEL instead of file name.", -" -p --show-c-function Show which C function each change is in.", -" -F RE --show-function-line=RE Show the most recent line matching RE.", -"-q --brief Output only whether files differ.", -"-e --ed Output an ed script.", -"-n --rcs Output an RCS format diff.", -"-y --side-by-side Output in two columns.", -" -W NUM --width=NUM Output at most NUM (default 130) characters per line.", -" --left-column Output only the left column of common lines.", -" --suppress-common-lines Do not output common lines.", -"-DNAME --ifdef=NAME Output merged file to show `#ifdef NAME' diffs.", -"--GTYPE-group-format=GFMT Similar, but format GTYPE input groups with GFMT.", -"--line-format=LFMT Similar, but format all input lines with LFMT.", -"--LTYPE-line-format=LFMT Similar, but format LTYPE input lines with LFMT.", -" LTYPE is `old', `new', or `unchanged'. GTYPE is LTYPE or `changed'.", -" GFMT may contain:", -" %< lines from FILE1", -" %> lines from FILE2", -" %= lines common to FILE1 and FILE2", -" %[-][WIDTH][.[PREC]]{doxX}LETTER printf-style spec for LETTER", -" LETTERs are as follows for new group, lower case for old group:", -" F first line number", -" L last line number", -" N number of lines = L-F+1", -" E F-1", -" M L+1", -" LFMT may contain:", -" %L contents of line", -" %l contents of line, excluding any trailing newline", -" %[-][WIDTH][.[PREC]]{doxX}n printf-style spec for input line number", -" Either GFMT or LFMT may contain:", -" %% %", -" %c'C' the single character C", -" %c'\\OOO' the character with octal code OOO\n", -"-l --paginate Pass the output through `pr' to paginate it.", -"-t --expand-tabs Expand tabs to spaces in output.", -"-T --initial-tab Make tabs line up by prepending a tab.\n", -"-r --recursive Recursively compare any subdirectories found.", -"-N --new-file Treat absent files as empty.", -"-P --unidirectional-new-file Treat absent first files as empty.", -"-s --report-identical-files Report when two files are the same.", -"-x PAT --exclude=PAT Exclude files that match PAT.", -"-X FILE --exclude-from=FILE Exclude files that match any pattern in FILE.", -"-S FILE --starting-file=FILE Start with FILE when comparing directories.\n", -"--horizon-lines=NUM Keep NUM lines of the common prefix and suffix.", -"-d --minimal Try hard to find a smaller set of changes.", -"-H --speed-large-files Assume large files and many scattered small changes.\n", -"-v --version Output version info.", -"--help Output this help.", -0 -}; - -static void -usage () -{ - char const * const *p; - - if (callbacks && callbacks->write_stdout) - { - (*callbacks->write_stdout) ("Usage: "); - (*callbacks->write_stdout) (diff_program_name); - (*callbacks->write_stdout) (" [OPTION]... FILE1 FILE2\n\n"); - for (p = option_help; *p; p++) - { - (*callbacks->write_stdout) (" "); - (*callbacks->write_stdout) (*p); - (*callbacks->write_stdout) ("\n"); - } - (*callbacks->write_stdout) - ("\nIf FILE1 or FILE2 is `-', read standard input.\n"); - } - else - { - printf ("Usage: %s [OPTION]... FILE1 FILE2\n\n", diff_program_name); - for (p = option_help; *p; p++) - printf (" %s\n", *p); - printf ("\nIf FILE1 or FILE2 is `-', read standard input.\n"); - } -} - -static int -specify_format (var, value) - char **var; - char *value; -{ - int err = *var ? strcmp (*var, value) : 0; - *var = value; - return err; -} - -static void -specify_style (style) - enum output_style style; -{ - if (output_style != OUTPUT_NORMAL - && output_style != style) - diff_error ("conflicting specifications of output style", 0, 0); - output_style = style; -} - -static char const * -filetype (st) - struct stat const *st; -{ - /* See Posix.2 section 4.17.6.1.1 and Table 5-1 for these formats. - To keep diagnostics grammatical, the returned string must start - with a consonant. */ - - if (S_ISREG (st->st_mode)) - { - if (st->st_size == 0) - return "regular empty file"; - /* Posix.2 section 5.14.2 seems to suggest that we must read the file - and guess whether it's C, Fortran, etc., but this is somewhat useless - and doesn't reflect historical practice. We're allowed to guess - wrong, so we don't bother to read the file. */ - return "regular file"; - } - if (S_ISDIR (st->st_mode)) return "directory"; - - /* other Posix.1 file types */ -#ifdef S_ISBLK - if (S_ISBLK (st->st_mode)) return "block special file"; -#endif -#ifdef S_ISCHR - if (S_ISCHR (st->st_mode)) return "character special file"; -#endif -#ifdef S_ISFIFO - if (S_ISFIFO (st->st_mode)) return "fifo"; -#endif - - /* other Posix.1b file types */ -#ifdef S_TYPEISMQ - if (S_TYPEISMQ (st)) return "message queue"; -#endif -#ifdef S_TYPEISSEM - if (S_TYPEISSEM (st)) return "semaphore"; -#endif -#ifdef S_TYPEISSHM - if (S_TYPEISSHM (st)) return "shared memory object"; -#endif - - /* other popular file types */ - /* S_ISLNK is impossible with `fstat' and `stat'. */ -#ifdef S_ISSOCK - if (S_ISSOCK (st->st_mode)) return "socket"; -#endif - - return "weird file"; -} - -/* Compare two files (or dirs) with specified names - DIR0/NAME0 and DIR1/NAME1, at level DEPTH in directory recursion. - (if DIR0 is 0, then the name is just NAME0, etc.) - This is self-contained; it opens the files and closes them. - - Value is 0 if files are the same, 1 if different, - 2 if there is a problem opening them. */ - -static int -compare_files (dir0, name0, dir1, name1, depth) - char const *dir0, *dir1; - char const *name0, *name1; - int depth; -{ - struct file_data inf[2]; - register int i; - int val; - int same_files; - int failed = 0; - char *free0 = 0, *free1 = 0; - - /* If this is directory comparison, perhaps we have a file - that exists only in one of the directories. - If so, just print a message to that effect. */ - - if (! ((name0 != 0 && name1 != 0) - || (unidirectional_new_file_flag && name1 != 0) - || entire_new_file_flag)) - { - char const *name = name0 == 0 ? name1 : name0; - char const *dir = name0 == 0 ? dir1 : dir0; - message ("Only in %s: %s\n", dir, name); - /* Return 1 so that diff_dirs will return 1 ("some files differ"). */ - return 1; - } - - bzero (inf, sizeof (inf)); - - /* Mark any nonexistent file with -1 in the desc field. */ - /* Mark unopened files (e.g. directories) with -2. */ - - inf[0].desc = name0 == 0 ? -1 : -2; - inf[1].desc = name1 == 0 ? -1 : -2; - - /* Now record the full name of each file, including nonexistent ones. */ - - if (name0 == 0) - name0 = name1; - if (name1 == 0) - name1 = name0; - - inf[0].name = dir0 == 0 ? name0 : (free0 = dir_file_pathname (dir0, name0)); - inf[1].name = dir1 == 0 ? name1 : (free1 = dir_file_pathname (dir1, name1)); - - /* Stat the files. Record whether they are directories. */ - - for (i = 0; i <= 1; i++) - { - if (inf[i].desc != -1) - { - int stat_result; - - if (i && filename_cmp (inf[i].name, inf[0].name) == 0) - { - inf[i].stat = inf[0].stat; - stat_result = 0; - } - else if (strcmp (inf[i].name, "-") == 0) - { - inf[i].desc = STDIN_FILENO; - stat_result = fstat (STDIN_FILENO, &inf[i].stat); - if (stat_result == 0 && S_ISREG (inf[i].stat.st_mode)) - { - off_t pos = lseek (STDIN_FILENO, (off_t) 0, SEEK_CUR); - if (pos == -1) - stat_result = -1; - else - { - if (pos <= inf[i].stat.st_size) - inf[i].stat.st_size -= pos; - else - inf[i].stat.st_size = 0; - /* Posix.2 4.17.6.1.4 requires current time for stdin. */ - time (&inf[i].stat.st_mtime); - } - } - } - else - stat_result = stat (inf[i].name, &inf[i].stat); - - if (stat_result != 0) - { - perror_with_name (inf[i].name); - failed = 1; - } - else - { - inf[i].dir_p = S_ISDIR (inf[i].stat.st_mode) && inf[i].desc != 0; - if (inf[1 - i].desc == -1) - { - inf[1 - i].dir_p = inf[i].dir_p; - inf[1 - i].stat.st_mode = inf[i].stat.st_mode; - } - } - } - } - - if (! failed && depth == 0 && inf[0].dir_p != inf[1].dir_p) - { - /* If one is a directory, and it was specified in the command line, - use the file in that dir with the other file's basename. */ - - int fnm_arg = inf[0].dir_p; - int dir_arg = 1 - fnm_arg; - char const *fnm = inf[fnm_arg].name; - char const *dir = inf[dir_arg].name; - char const *p = filename_lastdirchar (fnm); - char const *filename = inf[dir_arg].name - = dir_file_pathname (dir, p ? p + 1 : fnm); - - if (strcmp (fnm, "-") == 0) - fatal ("can't compare - to a directory"); - - if (stat (filename, &inf[dir_arg].stat) != 0) - { - perror_with_name (filename); - failed = 1; - } - else - inf[dir_arg].dir_p = S_ISDIR (inf[dir_arg].stat.st_mode); - } - - if (failed) - { - - /* If either file should exist but does not, return 2. */ - - val = 2; - - } - else if ((same_files = inf[0].desc != -1 && inf[1].desc != -1 - && 0 < same_file (&inf[0].stat, &inf[1].stat)) - && no_diff_means_no_output) - { - /* The two named files are actually the same physical file. - We know they are identical without actually reading them. */ - - val = 0; - } - else if (inf[0].dir_p & inf[1].dir_p) - { - if (output_style == OUTPUT_IFDEF) - fatal ("-D option not supported with directories"); - - /* If both are directories, compare the files in them. */ - - if (depth > 0 && !recursive) - { - /* But don't compare dir contents one level down - unless -r was specified. */ - message ("Common subdirectories: %s and %s\n", - inf[0].name, inf[1].name); - val = 0; - } - else - { - val = diff_dirs (inf, compare_files, depth); - } - - } - else if ((inf[0].dir_p | inf[1].dir_p) - || (depth > 0 - && (! S_ISREG (inf[0].stat.st_mode) - || ! S_ISREG (inf[1].stat.st_mode)))) - { - /* Perhaps we have a subdirectory that exists only in one directory. - If so, just print a message to that effect. */ - - if (inf[0].desc == -1 || inf[1].desc == -1) - { - if ((inf[0].dir_p | inf[1].dir_p) - && recursive - && (entire_new_file_flag - || (unidirectional_new_file_flag && inf[0].desc == -1))) - val = diff_dirs (inf, compare_files, depth); - else - { - char const *dir = (inf[0].desc == -1) ? dir1 : dir0; - /* See Posix.2 section 4.17.6.1.1 for this format. */ - message ("Only in %s: %s\n", dir, name0); - val = 1; - } - } - else - { - /* We have two files that are not to be compared. */ - - /* See Posix.2 section 4.17.6.1.1 for this format. */ - message5 ("File %s is a %s while file %s is a %s\n", - inf[0].name, filetype (&inf[0].stat), - inf[1].name, filetype (&inf[1].stat)); - - /* This is a difference. */ - val = 1; - } - } - else if ((no_details_flag & ~ignore_some_changes) - && inf[0].stat.st_size != inf[1].stat.st_size - && (inf[0].desc == -1 || S_ISREG (inf[0].stat.st_mode)) - && (inf[1].desc == -1 || S_ISREG (inf[1].stat.st_mode))) - { - message ("Files %s and %s differ\n", inf[0].name, inf[1].name); - val = 1; - } - else - { - /* Both exist and neither is a directory. */ - - /* Open the files and record their descriptors. */ - - if (inf[0].desc == -2) - if ((inf[0].desc = open (inf[0].name, O_RDONLY, 0)) < 0) - { - perror_with_name (inf[0].name); - 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 HAVE_SETMODE - if (binary_I_O) - for (i = 0; i <= 1; i++) - if (0 <= inf[i].desc) - setmode (inf[i].desc, O_BINARY); -#endif - - /* Compare the files, if no error was found. */ - - val = failed ? 2 : diff_2_files (inf, depth); - - /* Close the file descriptors. */ - - if (inf[0].desc >= 0 && close (inf[0].desc) != 0) - { - perror_with_name (inf[0].name); - val = 2; - } - if (inf[1].desc >= 0 && inf[0].desc != inf[1].desc - && close (inf[1].desc) != 0) - { - perror_with_name (inf[1].name); - val = 2; - } - } - - /* Now the comparison has been done, if no error prevented it, - and VAL is the value this function will return. */ - - if (val == 0 && !inf[0].dir_p) - { - if (print_file_same_flag) - message ("Files %s and %s are identical\n", - inf[0].name, inf[1].name); - } - else - flush_output (); - - if (free0) - free (free0); - if (free1) - free (free1); - - return val; -} - -/* Initialize status variables and flag variables used in libdiff, - to permit repeated calls to diff_run. */ - -static void -initialize_main (argcp, argvp) - int *argcp; - char ***argvp; -{ - /* These variables really must be reset each time diff_run is called. */ - output_style = OUTPUT_NORMAL; - context = -1; - file_label[0] = NULL; - file_label[1] = NULL; - diff_program_name = (*argvp)[0]; - outfile = NULL; - - /* Reset these also, just for safety's sake. (If one invocation turns - on ignore_case_flag, it must be turned off before diff_run is called - again. But it is possible to make many diffs before encountering - such a problem. */ - recursive = 0; - no_discards = 0; -#if HAVE_SETMODE - binary_I_O = 0; -#endif - no_diff_means_no_output = 0; - always_text_flag = 0; - horizon_lines = 0; - ignore_space_change_flag = 0; - ignore_all_space_flag = 0; - ignore_blank_lines_flag = 0; - ignore_some_line_changes = 0; - ignore_some_changes = 0; - ignore_case_flag = 0; - function_regexp_list = NULL; - ignore_regexp_list = NULL; - no_details_flag = 0; - print_file_same_flag = 0; - tab_align_flag = 0; - tab_expand_flag = 0; - dir_start_file = NULL; - entire_new_file_flag = 0; - unidirectional_new_file_flag = 0; - paginate_flag = 0; - bzero (group_format, sizeof (group_format)); - bzero (line_format, sizeof (line_format)); - sdiff_help_sdiff = 0; - sdiff_left_only = 0; - sdiff_skip_common_lines = 0; - sdiff_half_width = 0; - sdiff_column2_offset = 0; - switch_string = NULL; - heuristic = 0; - bzero (files, sizeof (files)); -} diff --git a/contrib/cvs/diff/diff.h b/contrib/cvs/diff/diff.h deleted file mode 100644 index 642138d..0000000 --- a/contrib/cvs/diff/diff.h +++ /dev/null @@ -1,354 +0,0 @@ -/* Shared definitions for GNU DIFF - Copyright (C) 1988, 89, 91, 92, 93, 97, 1998 Free Software Foundation, Inc. - -This file is part of GNU DIFF. - -GNU DIFF is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU DIFF 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. - -*/ - -#include "system.h" -#include -#include -#include "regex.h" -#include "diffrun.h" - -#define TAB_WIDTH 8 - -/* Variables for command line options */ - -#ifndef GDIFF_MAIN -#define EXTERN extern -#else -#define EXTERN -#endif - -/* The callbacks to use for output. */ -EXTERN const struct diff_callbacks *callbacks; - -enum output_style { - /* Default output style. */ - OUTPUT_NORMAL, - /* Output the differences with lines of context before and after (-c). */ - OUTPUT_CONTEXT, - /* Output the differences in a unified context diff format (-u). */ - OUTPUT_UNIFIED, - /* Output the differences as commands suitable for `ed' (-e). */ - OUTPUT_ED, - /* Output the diff as a forward ed script (-f). */ - OUTPUT_FORWARD_ED, - /* Like -f, but output a count of changed lines in each "command" (-n). */ - OUTPUT_RCS, - /* Output merged #ifdef'd file (-D). */ - OUTPUT_IFDEF, - /* Output sdiff style (-y). */ - OUTPUT_SDIFF -}; - -/* True for output styles that are robust, - i.e. can handle a file that ends in a non-newline. */ -#define ROBUST_OUTPUT_STYLE(S) ((S) != OUTPUT_ED && (S) != OUTPUT_FORWARD_ED) - -EXTERN enum output_style output_style; - -/* Nonzero if output cannot be generated for identical files. */ -EXTERN int no_diff_means_no_output; - -/* Number of lines of context to show in each set of diffs. - This is zero when context is not to be shown. */ -EXTERN int context; - -/* Consider all files as text files (-a). - Don't interpret codes over 0177 as implying a "binary file". */ -EXTERN int always_text_flag; - -/* Number of lines to keep in identical prefix and suffix. */ -EXTERN int horizon_lines; - -/* Ignore changes in horizontal white space (-b). */ -EXTERN int ignore_space_change_flag; - -/* Ignore all horizontal white space (-w). */ -EXTERN int ignore_all_space_flag; - -/* Ignore changes that affect only blank lines (-B). */ -EXTERN int ignore_blank_lines_flag; - -/* 1 if lines may match even if their contents do not match exactly. - This depends on various options. */ -EXTERN int ignore_some_line_changes; - -/* 1 if files may match even if their contents are not byte-for-byte identical. - This depends on various options. */ -EXTERN int ignore_some_changes; - -/* Ignore differences in case of letters (-i). */ -EXTERN int ignore_case_flag; - -/* File labels for `-c' output headers (-L). */ -EXTERN char *file_label[2]; - -struct regexp_list -{ - struct re_pattern_buffer buf; - struct regexp_list *next; -}; - -/* Regexp to identify function-header lines (-F). */ -EXTERN struct regexp_list *function_regexp_list; - -/* Ignore changes that affect only lines matching this regexp (-I). */ -EXTERN struct regexp_list *ignore_regexp_list; - -/* Say only whether files differ, not how (-q). */ -EXTERN int no_details_flag; - -/* Report files compared that match (-s). - Normally nothing is output when that happens. */ -EXTERN int print_file_same_flag; - -/* Output the differences with exactly 8 columns added to each line - so that any tabs in the text line up properly (-T). */ -EXTERN int tab_align_flag; - -/* Expand tabs in the output so the text lines up properly - despite the characters added to the front of each line (-t). */ -EXTERN int tab_expand_flag; - -/* In directory comparison, specify file to start with (-S). - All file names less than this name are ignored. */ -EXTERN char *dir_start_file; - -/* If a file is new (appears in only one dir) - include its entire contents (-N). - Then `patch' would create the file with appropriate contents. */ -EXTERN int entire_new_file_flag; - -/* If a file is new (appears in only the second dir) - include its entire contents (-P). - Then `patch' would create the file with appropriate contents. */ -EXTERN int unidirectional_new_file_flag; - -/* Pipe each file's output through pr (-l). */ -EXTERN int paginate_flag; - -enum line_class { - /* Lines taken from just the first file. */ - OLD, - /* Lines taken from just the second file. */ - NEW, - /* Lines common to both files. */ - UNCHANGED, - /* A hunk containing both old and new lines (line groups only). */ - CHANGED -}; - -/* Line group formats for old, new, unchanged, and changed groups. */ -EXTERN char *group_format[CHANGED + 1]; - -/* Line formats for old, new, and unchanged lines. */ -EXTERN char *line_format[UNCHANGED + 1]; - -/* If using OUTPUT_SDIFF print extra information to help the sdiff filter. */ -EXTERN int sdiff_help_sdiff; - -/* Tell OUTPUT_SDIFF to show only the left version of common lines. */ -EXTERN int sdiff_left_only; - -/* Tell OUTPUT_SDIFF to not show common lines. */ -EXTERN int sdiff_skip_common_lines; - -/* The half line width and column 2 offset for OUTPUT_SDIFF. */ -EXTERN unsigned sdiff_half_width; -EXTERN unsigned sdiff_column2_offset; - -/* String containing all the command options diff received, - with spaces between and at the beginning but none at the end. - If there were no options given, this string is empty. */ -EXTERN char * switch_string; - -/* Nonzero means use heuristics for better speed. */ -EXTERN int heuristic; - -/* Name of program the user invoked (for error messages). */ -EXTERN char *diff_program_name; - -/* Jump buffer for nonlocal exits. */ -EXTERN jmp_buf diff_abort_buf; -#define DIFF_ABORT(retval) longjmp(diff_abort_buf, retval) - -/* The result of comparison is an "edit script": a chain of `struct change'. - Each `struct change' represents one place where some lines are deleted - and some are inserted. - - LINE0 and LINE1 are the first affected lines in the two files (origin 0). - DELETED is the number of lines deleted here from file 0. - INSERTED is the number of lines inserted here in file 1. - - If DELETED is 0 then LINE0 is the number of the line before - which the insertion was done; vice versa for INSERTED and LINE1. */ - -struct change -{ - struct change *link; /* Previous or next edit command */ - int inserted; /* # lines of file 1 changed here. */ - int deleted; /* # lines of file 0 changed here. */ - int line0; /* Line number of 1st deleted line. */ - int line1; /* Line number of 1st inserted line. */ - char ignore; /* Flag used in context.c */ -}; - -/* Structures that describe the input files. */ - -/* Data on one input file being compared. */ - -struct file_data { - int desc; /* File descriptor */ - char const *name; /* File name */ - struct stat stat; /* File status from fstat() */ - int dir_p; /* nonzero if file is a directory */ - - /* Buffer in which text of file is read. */ - char * buffer; - /* Allocated size of buffer. */ - size_t bufsize; - /* Number of valid characters now in the buffer. */ - size_t buffered_chars; - - /* Array of pointers to lines in the file. */ - char const **linbuf; - - /* linbuf_base <= buffered_lines <= valid_lines <= alloc_lines. - linebuf[linbuf_base ... buffered_lines - 1] are possibly differing. - linebuf[linbuf_base ... valid_lines - 1] contain valid data. - linebuf[linbuf_base ... alloc_lines - 1] are allocated. */ - int linbuf_base, buffered_lines, valid_lines, alloc_lines; - - /* Pointer to end of prefix of this file to ignore when hashing. */ - char const *prefix_end; - - /* Count of lines in the prefix. - There are this many lines in the file before linbuf[0]. */ - int prefix_lines; - - /* Pointer to start of suffix of this file to ignore when hashing. */ - char const *suffix_begin; - - /* Vector, indexed by line number, containing an equivalence code for - each line. It is this vector that is actually compared with that - of another file to generate differences. */ - int *equivs; - - /* Vector, like the previous one except that - the elements for discarded lines have been squeezed out. */ - int *undiscarded; - - /* Vector mapping virtual line numbers (not counting discarded lines) - to real ones (counting those lines). Both are origin-0. */ - int *realindexes; - - /* Total number of nondiscarded lines. */ - int nondiscarded_lines; - - /* Vector, indexed by real origin-0 line number, - containing 1 for a line that is an insertion or a deletion. - The results of comparison are stored here. */ - char *changed_flag; - - /* 1 if file ends in a line with no final newline. */ - int missing_newline; - - /* 1 more than the maximum equivalence value used for this or its - sibling file. */ - int equiv_max; -}; - -/* Describe the two files currently being compared. */ - -EXTERN struct file_data files[2]; - -/* Stdio stream to output diffs to. */ - -EXTERN FILE *outfile; - -/* Declare various functions. */ - -/* analyze.c */ -int diff_2_files PARAMS((struct file_data[], int)); - -/* context.c */ -void print_context_header PARAMS((struct file_data[], int)); -void print_context_script PARAMS((struct change *, int)); - -/* diff.c */ -int excluded_filename PARAMS((char const *)); - -/* dir.c */ -int diff_dirs PARAMS((struct file_data const[], int (*) PARAMS((char const *, char const *, char const *, char const *, int)), int)); - -/* ed.c */ -void print_ed_script PARAMS((struct change *)); -void pr_forward_ed_script PARAMS((struct change *)); - -/* ifdef.c */ -void print_ifdef_script PARAMS((struct change *)); - -/* io.c */ -int read_files PARAMS((struct file_data[], int)); -int sip PARAMS((struct file_data *, int)); -void slurp PARAMS((struct file_data *)); - -/* normal.c */ -void print_normal_script PARAMS((struct change *)); - -/* rcs.c */ -void print_rcs_script PARAMS((struct change *)); - -/* side.c */ -void print_sdiff_script PARAMS((struct change *)); - -/* util.c */ -VOID *xmalloc PARAMS((size_t)); -VOID *xrealloc PARAMS((VOID *, size_t)); -char *concat PARAMS((char const *, char const *, char const *)); -char *dir_file_pathname PARAMS((char const *, char const *)); -int change_letter PARAMS((int, int)); -int line_cmp PARAMS((char const *, char const *)); -int translate_line_number PARAMS((struct file_data const *, int)); -struct change *find_change PARAMS((struct change *)); -struct change *find_reverse_change PARAMS((struct change *)); -void analyze_hunk PARAMS((struct change *, int *, int *, int *, int *, int *, int *)); -void begin_output PARAMS((void)); -void debug_script PARAMS((struct change *)); -void diff_error PARAMS((char const *, char const *, char const *)); -void fatal PARAMS((char const *)); -void finish_output PARAMS((void)); -void write_output PARAMS((char const *, size_t)); -void printf_output PARAMS((char const *, ...)) -#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 6) - __attribute__ ((__format__ (__printf__, 1, 2))) -#endif - ; -void flush_output PARAMS((void)); -void message PARAMS((char const *, char const *, char const *)); -void message5 PARAMS((char const *, char const *, char const *, char const *, char const *)); -void output_1_line PARAMS((char const *, char const *, char const *, char const *)); -void perror_with_name PARAMS((char const *)); -void pfatal_with_name PARAMS((char const *)); -void print_1_line PARAMS((char const *, char const * const *)); -void print_message_queue PARAMS((void)); -void print_number_range PARAMS((int, struct file_data *, int, int)); -void print_script PARAMS((struct change *, struct change * (*) PARAMS((struct change *)), void (*) PARAMS((struct change *)))); -void setup_output PARAMS((char const *, char const *, int)); -void translate_range PARAMS((struct file_data const *, int, int, int *, int *)); - -/* version.c */ -extern char const diff_version_string[]; diff --git a/contrib/cvs/diff/diff3.c b/contrib/cvs/diff/diff3.c deleted file mode 100644 index 109e66e..0000000 --- a/contrib/cvs/diff/diff3.c +++ /dev/null @@ -1,1930 +0,0 @@ -/* Three way file comparison program (diff3) for Project GNU. - Copyright (C) 1988, 1989, 1992, 1993, 1994, 1997, 1998 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - */ -/* - * $FreeBSD$ - */ - -/* Written by Randy Smith */ -/* Librarification by Tim Pierce */ - -#include "system.h" -#include -#include -#include "getopt.h" -#include "diffrun.h" - -/* diff3.c has a real initialize_main function. */ -#ifdef initialize_main -#undef initialize_main -#endif - -extern char const diff_version_string[]; - -extern FILE *outfile; - -extern const struct diff_callbacks *callbacks; - -void write_output PARAMS((char const *, size_t)); -void printf_output PARAMS((char const *, ...)) -#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 6) - __attribute__ ((__format__ (__printf__, 1, 2))) -#endif - ; -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. - */ - -/* Different files within a three way diff. */ -#define FILE0 0 -#define FILE1 1 -#define FILE2 2 - -/* - * A three way diff is built from two two-way diffs; the file which - * the two two-way diffs share is: - */ -#define FILEC FILE2 - -/* - * Different files within a two way diff. - * FC is the common file, FO the other file. - */ -#define FO 0 -#define FC 1 - -/* The ranges are indexed by */ -#define START 0 -#define END 1 - -enum diff_type { - ERROR, /* Should not be used */ - ADD, /* Two way diff add */ - CHANGE, /* Two way diff change */ - DELETE, /* Two way diff delete */ - DIFF_ALL, /* All three are different */ - DIFF_1ST, /* Only the first is different */ - DIFF_2ND, /* Only the second */ - DIFF_3RD /* Only the third */ -}; - -/* Two way diff */ -struct diff_block { - int ranges[2][2]; /* Ranges are inclusive */ - char **lines[2]; /* The actual lines (may contain nulls) */ - size_t *lengths[2]; /* Line lengths (including newlines, if any) */ - struct diff_block *next; -}; - -/* Three way diff */ - -struct diff3_block { - enum diff_type correspond; /* Type of diff */ - int ranges[3][2]; /* Ranges are inclusive */ - char **lines[3]; /* The actual lines (may contain nulls) */ - size_t *lengths[3]; /* Line lengths (including newlines, if any) */ - struct diff3_block *next; -}; - -/* - * Access the ranges on a diff block. - */ -#define D_LOWLINE(diff, filenum) \ - ((diff)->ranges[filenum][START]) -#define D_HIGHLINE(diff, filenum) \ - ((diff)->ranges[filenum][END]) -#define D_NUMLINES(diff, filenum) \ - (D_HIGHLINE (diff, filenum) - D_LOWLINE (diff, filenum) + 1) - -/* - * Access the line numbers in a file in a diff by relative line - * numbers (i.e. line number within the diff itself). Note that these - * are lvalues and can be used for assignment. - */ -#define D_RELNUM(diff, filenum, linenum) \ - ((diff)->lines[filenum][linenum]) -#define D_RELLEN(diff, filenum, linenum) \ - ((diff)->lengths[filenum][linenum]) - -/* - * And get at them directly, when that should be necessary. - */ -#define D_LINEARRAY(diff, filenum) \ - ((diff)->lines[filenum]) -#define D_LENARRAY(diff, filenum) \ - ((diff)->lengths[filenum]) - -/* - * Next block. - */ -#define D_NEXT(diff) ((diff)->next) - -/* - * Access the type of a diff3 block. - */ -#define D3_TYPE(diff) ((diff)->correspond) - -/* - * Line mappings based on diffs. The first maps off the top of the - * diff, the second off of the bottom. - */ -#define D_HIGH_MAPLINE(diff, fromfile, tofile, lineno) \ - ((lineno) \ - - D_HIGHLINE ((diff), (fromfile)) \ - + D_HIGHLINE ((diff), (tofile))) - -#define D_LOW_MAPLINE(diff, fromfile, tofile, lineno) \ - ((lineno) \ - - D_LOWLINE ((diff), (fromfile)) \ - + D_LOWLINE ((diff), (tofile))) - -/* - * General memory allocation function. - */ -#define ALLOCATE(number, type) \ - (type *) xmalloc ((number) * sizeof (type)) - -/* Options variables for flags set on command line. */ - -/* If nonzero, treat all files as text files, never as binary. */ -static int always_text; - -/* If nonzero, write out an ed script instead of the standard diff3 format. */ -static int edscript; - -/* If nonzero, in the case of overlapping diffs (type DIFF_ALL), - preserve the lines which would normally be deleted from - file 1 with a special flagging mechanism. */ -static int flagging; - -/* Number of lines to keep in identical prefix and suffix. */ -static int const horizon_lines = 10; - -/* Use a tab to align output lines (-T). */ -static int tab_align_flag; - -/* If nonzero, do not output information for overlapping diffs. */ -static int simple_only; - -/* If nonzero, do not output information for non-overlapping diffs. */ -static int overlap_only; - -/* If nonzero, show information for DIFF_2ND diffs. */ -static int show_2nd; - -/* If nonzero, include `:wq' at the end of the script - to write out the file being edited. */ -static int finalwrite; - -/* If nonzero, output a merged file. */ -static int merge; - -extern char *diff_program_name; - -static char *read_diff PARAMS((char const *, char const *, char **)); -static char *scan_diff_line PARAMS((char *, char **, size_t *, char *, int)); -static enum diff_type process_diff_control PARAMS((char **, struct diff_block *)); -static int compare_line_list PARAMS((char * const[], size_t const[], char * const[], size_t const[], int)); -static int copy_stringlist PARAMS((char * const[], size_t const[], char *[], size_t[], int)); -static int dotlines PARAMS((struct diff3_block *, int)); -static int output_diff3_edscript PARAMS((struct diff3_block *, int const[3], int const[3], char const *, char const *, char const *)); -static int output_diff3_merge PARAMS((FILE *, struct diff3_block *, int const[3], int const[3], char const *, char const *, char const *)); -static size_t myread PARAMS((int, char *, size_t)); -static struct diff3_block *create_diff3_block PARAMS((int, int, int, int, int, int)); -static struct diff3_block *make_3way_diff PARAMS((struct diff_block *, struct diff_block *)); -static struct diff3_block *reverse_diff3_blocklist PARAMS((struct diff3_block *)); -static struct diff3_block *using_to_diff3_block PARAMS((struct diff_block *[2], struct diff_block *[2], int, int, struct diff3_block const *)); -static struct diff_block *process_diff PARAMS((char const *, char const *, struct diff_block **, char **)); -static void check_output PARAMS((FILE *)); -static void diff3_fatal PARAMS((char const *)); -static void output_diff3 PARAMS((struct diff3_block *, int const[3], int const[3])); -static void diff3_perror_with_exit PARAMS((char const *)); -static int try_help PARAMS((char const *)); -static void undotlines PARAMS((int, int, int)); -static void usage PARAMS((void)); -static void initialize_main PARAMS((int *, char ***)); -static void free_diff_blocks PARAMS((struct diff_block *)); -static void free_diff3_blocks PARAMS((struct diff3_block *)); - -/* Functions provided in libdiff.a or other external sources. */ -VOID *xmalloc PARAMS((size_t)); -VOID *xrealloc PARAMS((VOID *, size_t)); -void perror_with_name PARAMS((char const *)); -void diff_error PARAMS((char const *, char const *, char const *)); - -/* Permit non-local exits from diff3. */ -static jmp_buf diff3_abort_buf; -#define DIFF3_ABORT(retval) longjmp(diff3_abort_buf, retval) - -static struct option const longopts[] = -{ - {"text", 0, 0, 'a'}, - {"show-all", 0, 0, 'A'}, - {"ed", 0, 0, 'e'}, - {"show-overlap", 0, 0, 'E'}, - {"label", 1, 0, 'L'}, - {"merge", 0, 0, 'm'}, - {"initial-tab", 0, 0, 'T'}, - {"overlap-only", 0, 0, 'x'}, - {"easy-only", 0, 0, '3'}, - {"version", 0, 0, 'v'}, - {"help", 0, 0, 129}, - {0, 0, 0, 0} -}; - -/* - * Main program. Calls diff twice on two pairs of input files, - * combines the two diffs, and outputs them. - */ -int -diff3_run (argc, argv, out, callbacks_arg) - int argc; - char **argv; - char *out; - const struct diff_callbacks *callbacks_arg; -{ - int c, i; - int mapping[3]; - int rev_mapping[3]; - int incompat = 0; - int conflicts_found; - int status; - struct diff_block *thread0, *thread1, *last_block; - char *content0, *content1; - struct diff3_block *diff3; - int tag_count = 0; - char *tag_strings[3]; - char *commonname; - char **file; - struct stat statb; - int optind_old; - int opened_file = 0; - - callbacks = callbacks_arg; - - initialize_main (&argc, &argv); - - optind_old = optind; - optind = 0; - while ((c = getopt_long (argc, argv, "aeimvx3AEL:TX", longopts, 0)) != EOF) - { - switch (c) - { - case 'a': - always_text = 1; - break; - case 'A': - show_2nd = 1; - flagging = 1; - incompat++; - break; - case 'x': - overlap_only = 1; - incompat++; - break; - case '3': - simple_only = 1; - incompat++; - break; - case 'i': - finalwrite = 1; - break; - case 'm': - merge = 1; - break; - case 'X': - overlap_only = 1; - /* Falls through */ - case 'E': - flagging = 1; - /* Falls through */ - case 'e': - incompat++; - break; - case 'T': - tab_align_flag = 1; - break; - case 'v': - if (callbacks && callbacks->write_stdout) - { - (*callbacks->write_stdout) ("diff3 - GNU diffutils version "); - (*callbacks->write_stdout) (diff_version_string); - (*callbacks->write_stdout) ("\n"); - } - else - printf ("diff3 - GNU diffutils version %s\n", diff_version_string); - return 0; - case 129: - usage (); - if (! callbacks || ! callbacks->write_stdout) - check_output (stdout); - return 0; - case 'L': - /* Handle up to three -L options. */ - if (tag_count < 3) - { - tag_strings[tag_count++] = optarg; - break; - } - return try_help ("Too many labels were given. The limit is 3."); - default: - return try_help (0); - } - } - - edscript = incompat & ~merge; /* -AeExX3 without -m implies ed script. */ - show_2nd |= ~incompat & merge; /* -m without -AeExX3 implies -A. */ - flagging |= ~incompat & merge; - - if (incompat > 1 /* Ensure at most one of -AeExX3. */ - || finalwrite & merge /* -i -m would rewrite input file. */ - || (tag_count && ! flagging)) /* -L requires one of -AEX. */ - return try_help ("incompatible options"); - - if (argc - optind != 3) - return try_help (argc - optind < 3 ? "missing operand" : "extra operand"); - - file = &argv[optind]; - - optind = optind_old; - - for (i = tag_count; i < 3; i++) - tag_strings[i] = file[i]; - - /* Always compare file1 to file2, even if file2 is "-". - This is needed for -mAeExX3. Using the file0 as - the common file would produce wrong results, because if the - file0-file1 diffs didn't line up with the file0-file2 diffs - (which is entirely possible since we don't use diff's -n option), - diff3 might report phantom changes from file1 to file2. */ - /* Also try to compare file0 to file1 because this is the where - changes are expected to come from. Diffing between these pairs - of files is is most likely to return the intended changes. There - can also be the same problem with phantom changes from file0 to - file1. */ - /* Historically, the default common file was file2. Ediff for emacs - and possibly other applications, have therefore made file2 the - ancestor. So, for compatibility, if this is simply a three - way diff (not a merge or edscript) then use the old way with - file2 as the common file. */ - - { - int common; - if (edscript || merge ) - { - common = 1; - } - else - { - common = 2; - } - if (strcmp (file[common], "-") == 0) - { - /* Sigh. We've got standard input as the arg corresponding to - the desired common file. We can't call diff twice on - stdin. Use another arg as the common file instead. */ - common = 3 - common; - if (strcmp (file[0], "-") == 0 || strcmp (file[common], "-") == 0) - { - diff_error ("%s", "`-' specified for more than one input file", 0); - return 2; - } - } - - mapping[0] = 0; - mapping[1] = 3 - common; - mapping[2] = common; - } - - for (i = 0; i < 3; i++) - rev_mapping[mapping[i]] = i; - - for (i = 0; i < 3; i++) - if (strcmp (file[i], "-") != 0) - { - if (stat (file[i], &statb) < 0) - { - perror_with_name (file[i]); - return 2; - } - else if (S_ISDIR(statb.st_mode)) - { - diff_error ("%s: Is a directory", file[i], 0); - return 2; - } - } - - if (callbacks && callbacks->write_output) - { - if (out != NULL) - { - diff_error ("write callback with output file", 0, 0); - return 2; - } - } - else - { - if (out == NULL) - outfile = stdout; - else - { - outfile = fopen (out, "w"); - if (outfile == NULL) - { - perror_with_name (out); - return 2; - } - opened_file = 1; - } - } - - /* Set the jump buffer, so that diff may abort execution without - terminating the process. */ - status = setjmp (diff3_abort_buf); - if (status != 0) - return status; - - commonname = file[rev_mapping[FILEC]]; - thread1 = process_diff (file[rev_mapping[FILE1]], commonname, &last_block, - &content1); - /* What is the intention behind determining horizon_lines from first - diff? I think it is better to use the same parameters for each - diff so that equal differences in each diff will appear the - same. */ - /* - if (thread1) - for (i = 0; i < 2; i++) - { - horizon_lines = max (horizon_lines, D_NUMLINES (thread1, i)); - horizon_lines = max (horizon_lines, D_NUMLINES (last_block, i)); - } - */ - thread0 = process_diff (file[rev_mapping[FILE0]], commonname, &last_block, - &content0); - diff3 = make_3way_diff (thread0, thread1); - if (edscript) - conflicts_found - = output_diff3_edscript (diff3, mapping, rev_mapping, - tag_strings[0], tag_strings[1], tag_strings[2]); - else if (merge) - { - FILE *mfp = fopen (file[rev_mapping[FILE0]], "r"); - if (! mfp) - diff3_perror_with_exit (file[rev_mapping[FILE0]]); - conflicts_found = output_diff3_merge (mfp, diff3, mapping, rev_mapping, - tag_strings[0], tag_strings[1], tag_strings[2]); - if (ferror (mfp)) - diff3_fatal ("read error"); - if (fclose(mfp) != 0) - perror_with_name (file[rev_mapping[FILE0]]); - } - else - { - output_diff3 (diff3, mapping, rev_mapping); - conflicts_found = 0; - } - - free(content0); - free(content1); - free_diff3_blocks(diff3); - - if (! callbacks || ! callbacks->write_output) - check_output (outfile); - - if (opened_file) - if (fclose (outfile) != 0) - perror_with_name ("close error on output file"); - - return conflicts_found; -} - -static int -try_help (reason) - char const *reason; -{ - if (reason) - diff_error ("%s", reason, 0); - diff_error ("Try `%s --help' for more information.", diff_program_name, 0); - return 2; -} - -static void -check_output (stream) - FILE *stream; -{ - if (ferror (stream) || fflush (stream) != 0) - diff3_fatal ("write error"); -} - -/* - * Explain, patiently and kindly, how to use this program. - */ -static void -usage () -{ - if (callbacks && callbacks->write_stdout) - { - (*callbacks->write_stdout) ("Usage: "); - (*callbacks->write_stdout) (diff_program_name); - (*callbacks->write_stdout) (" [OPTION]... MYFILE OLDFILE YOURFILE\n\n"); - - (*callbacks->write_stdout) ("\ - -e --ed Output unmerged changes from OLDFILE to YOURFILE into MYFILE.\n\ - -E --show-overlap Output unmerged changes, bracketing conflicts.\n\ - -A --show-all Output all changes, bracketing conflicts.\n\ - -x --overlap-only Output overlapping changes.\n\ - -X Output overlapping changes, bracketing them.\n\ - -3 --easy-only Output unmerged nonoverlapping changes.\n\n"); - (*callbacks->write_stdout) ("\ - -m --merge Output merged file instead of ed script (default -A).\n\ - -L LABEL --label=LABEL Use LABEL instead of file name.\n\ - -i Append `w' and `q' commands to ed scripts.\n\ - -a --text Treat all files as text.\n\ - -T --initial-tab Make tabs line up by prepending a tab.\n\n"); - (*callbacks->write_stdout) ("\ - -v --version Output version info.\n\ - --help Output this help.\n\n"); - (*callbacks->write_stdout) ("If a FILE is `-', read standard input.\n"); - } - else - { - printf ("Usage: %s [OPTION]... MYFILE OLDFILE YOURFILE\n\n", diff_program_name); - - printf ("%s", "\ - -e --ed Output unmerged changes from OLDFILE to YOURFILE into MYFILE.\n\ - -E --show-overlap Output unmerged changes, bracketing conflicts.\n\ - -A --show-all Output all changes, bracketing conflicts.\n\ - -x --overlap-only Output overlapping changes.\n\ - -X Output overlapping changes, bracketing them.\n\ - -3 --easy-only Output unmerged nonoverlapping changes.\n\n"); - printf ("%s", "\ - -m --merge Output merged file instead of ed script (default -A).\n\ - -L LABEL --label=LABEL Use LABEL instead of file name.\n\ - -i Append `w' and `q' commands to ed scripts.\n\ - -a --text Treat all files as text.\n\ - -T --initial-tab Make tabs line up by prepending a tab.\n\n"); - printf ("%s", "\ - -v --version Output version info.\n\ - --help Output this help.\n\n"); - printf ("If a FILE is `-', read standard input.\n"); - } -} - -/* - * Routines that combine the two diffs together into one. The - * algorithm used follows: - * - * File2 is shared in common between the two diffs. - * Diff02 is the diff between 0 and 2. - * Diff12 is the diff between 1 and 2. - * - * 1) Find the range for the first block in File2. - * a) Take the lowest of the two ranges (in File2) in the two - * current blocks (one from each diff) as being the low - * water mark. Assign the upper end of this block as - * being the high water mark and move the current block up - * one. Mark the block just moved over as to be used. - * b) Check the next block in the diff that the high water - * mark is *not* from. - * - * *If* the high water mark is above - * the low end of the range in that block, - * - * mark that block as to be used and move the current - * block up. Set the high water mark to the max of - * the high end of this block and the current. Repeat b. - * - * 2) Find the corresponding ranges in File0 (from the blocks - * in diff02; line per line outside of diffs) and in File1. - * Create a diff3_block, reserving space as indicated by the ranges. - * - * 3) Copy all of the pointers for file2 in. At least for now, - * do memcmp's between corresponding strings in the two diffs. - * - * 4) Copy all of the pointers for file0 and 1 in. Get what you - * need from file2 (when there isn't a diff block, it's - * identical to file2 within the range between diff blocks). - * - * 5) If the diff blocks you used came from only one of the two - * strings of diffs, then that file (i.e. the one other than - * the common file in that diff) is the odd person out. If you used - * diff blocks from both sets, check to see if files 0 and 1 match: - * - * Same number of lines? If so, do a set of memcmp's (if a - * memcmp matches; copy the pointer over; it'll be easier later - * if you have to do any compares). If they match, 0 & 1 are - * the same. If not, all three different. - * - * Then you do it again, until you run out of blocks. - * - */ - -/* - * This routine makes a three way diff (chain of diff3_block's) from two - * two way diffs (chains of diff_block's). It is assumed that each of - * the two diffs passed are onto the same file (i.e. that each of the - * diffs were made "to" the same file). The three way diff pointer - * returned will have numbering FILE0--the other file in diff02, - * FILE1--the other file in diff12, and FILEC--the common file. - */ -static struct diff3_block * -make_3way_diff (thread0, thread1) - struct diff_block *thread0, *thread1; -{ -/* - * This routine works on the two diffs passed to it as threads. - * Thread number 0 is diff02, thread number 1 is diff12. The USING - * array is set to the base of the list of blocks to be used to - * construct each block of the three way diff; if no blocks from a - * particular thread are to be used, that element of the using array - * is set to 0. The elements LAST_USING array are set to the last - * elements on each of the using lists. - * - * The HIGH_WATER_MARK is set to the highest line number in the common file - * described in any of the diffs in either of the USING lists. The - * HIGH_WATER_THREAD names the thread. Similarly the BASE_WATER_MARK - * and BASE_WATER_THREAD describe the lowest line number in the common file - * described in any of the diffs in either of the USING lists. The - * HIGH_WATER_DIFF is the diff from which the HIGH_WATER_MARK was - * taken. - * - * The HIGH_WATER_DIFF should always be equal to LAST_USING - * [HIGH_WATER_THREAD]. The OTHER_DIFF is the next diff to check for - * higher water, and should always be equal to - * CURRENT[HIGH_WATER_THREAD ^ 0x1]. The OTHER_THREAD is the thread - * in which the OTHER_DIFF is, and hence should always be equal to - * HIGH_WATER_THREAD ^ 0x1. - * - * The variable LAST_DIFF is kept set to the last diff block produced - * by this routine, for line correspondence purposes between that diff - * and the one currently being worked on. It is initialized to - * ZERO_DIFF before any blocks have been created. - */ - - struct diff_block - *using[2], - *last_using[2], - *current[2]; - - int - high_water_mark; - - int - high_water_thread, - base_water_thread, - other_thread; - - struct diff_block - *high_water_diff, - *other_diff; - - struct diff3_block - *result, - *tmpblock, - **result_end; - - struct diff3_block const *last_diff3; - - static struct diff3_block const zero_diff3 = { 0 }; - - /* Initialization */ - result = 0; - result_end = &result; - current[0] = thread0; current[1] = thread1; - last_diff3 = &zero_diff3; - - /* Sniff up the threads until we reach the end */ - - while (current[0] || current[1]) - { - using[0] = using[1] = last_using[0] = last_using[1] = 0; - - /* Setup low and high water threads, diffs, and marks. */ - if (!current[0]) - base_water_thread = 1; - else if (!current[1]) - base_water_thread = 0; - else - base_water_thread = - (D_LOWLINE (current[0], FC) > D_LOWLINE (current[1], FC)); - - high_water_thread = base_water_thread; - - high_water_diff = current[high_water_thread]; - -#if 0 - /* low and high waters start off same diff */ - base_water_mark = D_LOWLINE (high_water_diff, FC); -#endif - - high_water_mark = D_HIGHLINE (high_water_diff, FC); - - /* Make the diff you just got info from into the using class */ - using[high_water_thread] - = last_using[high_water_thread] - = high_water_diff; - current[high_water_thread] = high_water_diff->next; - last_using[high_water_thread]->next = 0; - - /* And mark the other diff */ - other_thread = high_water_thread ^ 0x1; - other_diff = current[other_thread]; - - /* Shuffle up the ladder, checking the other diff to see if it - needs to be incorporated. */ - while (other_diff - && D_LOWLINE (other_diff, FC) <= high_water_mark + 1) - { - - /* Incorporate this diff into the using list. Note that - this doesn't take it off the current list */ - if (using[other_thread]) - last_using[other_thread]->next = other_diff; - else - using[other_thread] = other_diff; - last_using[other_thread] = other_diff; - - /* Take it off the current list. Note that this following - code assumes that other_diff enters it equal to - current[high_water_thread ^ 0x1] */ - current[other_thread] = current[other_thread]->next; - other_diff->next = 0; - - /* Set the high_water stuff - If this comparison is equal, then this is the last pass - through this loop; since diff blocks within a given - thread cannot overlap, the high_water_mark will be - *below* the range_start of either of the next diffs. */ - - if (high_water_mark < D_HIGHLINE (other_diff, FC)) - { - high_water_thread ^= 1; - high_water_diff = other_diff; - high_water_mark = D_HIGHLINE (other_diff, FC); - } - - /* Set the other diff */ - other_thread = high_water_thread ^ 0x1; - other_diff = current[other_thread]; - } - - /* The using lists contain a list of all of the blocks to be - included in this diff3_block. Create it. */ - - 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"); - - /* Put it on the list. */ - *result_end = tmpblock; - result_end = &tmpblock->next; - - /* Set up corresponding lines correctly. */ - last_diff3 = tmpblock; - } - return result; -} - -/* - * using_to_diff3_block: - * This routine takes two lists of blocks (from two separate diff - * threads) and puts them together into one diff3 block. - * It then returns a pointer to this diff3 block or 0 for failure. - * - * All arguments besides using are for the convenience of the routine; - * they could be derived from the using array. - * LAST_USING is a pair of pointers to the last blocks in the using - * structure. - * LOW_THREAD and HIGH_THREAD tell which threads contain the lowest - * and highest line numbers for File0. - * last_diff3 contains the last diff produced in the calling routine. - * This is used for lines mappings which would still be identical to - * the state that diff ended in. - * - * A distinction should be made in this routine between the two diffs - * that are part of a normal two diff block, and the three diffs that - * are part of a diff3_block. - */ -static struct diff3_block * -using_to_diff3_block (using, last_using, low_thread, high_thread, last_diff3) - struct diff_block - *using[2], - *last_using[2]; - int low_thread, high_thread; - struct diff3_block const *last_diff3; -{ - int low[2], high[2]; - struct diff3_block *result; - struct diff_block *ptr; - int d, i; - - /* Find the range in the common file. */ - int lowc = D_LOWLINE (using[low_thread], FC); - int highc = D_HIGHLINE (last_using[high_thread], FC); - - /* Find the ranges in the other files. - If using[d] is null, that means that the file to which that diff - refers is equivalent to the common file over this range. */ - - for (d = 0; d < 2; d++) - if (using[d]) - { - low[d] = D_LOW_MAPLINE (using[d], FC, FO, lowc); - high[d] = D_HIGH_MAPLINE (last_using[d], FC, FO, highc); - } - else - { - low[d] = D_HIGH_MAPLINE (last_diff3, FILEC, FILE0 + d, lowc); - high[d] = D_HIGH_MAPLINE (last_diff3, FILEC, FILE0 + d, highc); - } - - /* Create a block with the appropriate sizes */ - result = create_diff3_block (low[0], high[0], low[1], high[1], lowc, highc); - - /* Copy information for the common file. - Return with a zero if any of the compares failed. */ - - for (d = 0; d < 2; d++) - for (ptr = using[d]; ptr; ptr = D_NEXT (ptr)) - { - int result_offset = D_LOWLINE (ptr, FC) - lowc; - - if (!copy_stringlist (D_LINEARRAY (ptr, FC), - D_LENARRAY (ptr, FC), - D_LINEARRAY (result, FILEC) + result_offset, - D_LENARRAY (result, FILEC) + result_offset, - D_NUMLINES (ptr, FC))) - return 0; - } - - /* Copy information for file d. First deal with anything that might be - before the first diff. */ - - for (d = 0; d < 2; d++) - { - struct diff_block *u = using[d]; - int lo = low[d], hi = high[d]; - - for (i = 0; - i + lo < (u ? D_LOWLINE (u, FO) : hi + 1); - i++) - { - D_RELNUM (result, FILE0 + d, i) = D_RELNUM (result, FILEC, i); - D_RELLEN (result, FILE0 + d, i) = D_RELLEN (result, FILEC, i); - } - - for (ptr = u; ptr; ptr = D_NEXT (ptr)) - { - int result_offset = D_LOWLINE (ptr, FO) - lo; - int linec; - - if (!copy_stringlist (D_LINEARRAY (ptr, FO), - D_LENARRAY (ptr, FO), - D_LINEARRAY (result, FILE0 + d) + result_offset, - D_LENARRAY (result, FILE0 + d) + result_offset, - D_NUMLINES (ptr, FO))) - return 0; - - /* Catch the lines between here and the next diff */ - linec = D_HIGHLINE (ptr, FC) + 1 - lowc; - for (i = D_HIGHLINE (ptr, FO) + 1 - lo; - i < (D_NEXT (ptr) ? D_LOWLINE (D_NEXT (ptr), FO) : hi + 1) - lo; - i++) - { - D_RELNUM (result, FILE0 + d, i) = D_RELNUM (result, FILEC, linec); - D_RELLEN (result, FILE0 + d, i) = D_RELLEN (result, FILEC, linec); - linec++; - } - } - } - - /* Set correspond */ - if (!using[0]) - D3_TYPE (result) = DIFF_2ND; - else if (!using[1]) - D3_TYPE (result) = DIFF_1ST; - else - { - int nl0 = D_NUMLINES (result, FILE0); - int nl1 = D_NUMLINES (result, FILE1); - - if (nl0 != nl1 - || !compare_line_list (D_LINEARRAY (result, FILE0), - D_LENARRAY (result, FILE0), - D_LINEARRAY (result, FILE1), - D_LENARRAY (result, FILE1), - nl0)) - D3_TYPE (result) = DIFF_ALL; - else - D3_TYPE (result) = DIFF_3RD; - } - - return result; -} - -/* - * This routine copies pointers from a list of strings to a different list - * of strings. If a spot in the second list is already filled, it - * makes sure that it is filled with the same string; if not it - * returns 0, the copy incomplete. - * Upon successful completion of the copy, it returns 1. - */ -static int -copy_stringlist (fromptrs, fromlengths, toptrs, tolengths, copynum) - char * const fromptrs[]; - char *toptrs[]; - size_t const fromlengths[]; - size_t tolengths[]; - int copynum; -{ - register char * const *f = fromptrs; - register char **t = toptrs; - register size_t const *fl = fromlengths; - register size_t *tl = tolengths; - - while (copynum--) - { - if (*t) - { if (*fl != *tl || memcmp (*f, *t, *fl)) return 0; } - else - { *t = *f ; *tl = *fl; } - - t++; f++; tl++; fl++; - } - return 1; -} - -/* - * Create a diff3_block, with ranges as specified in the arguments. - * Allocate the arrays for the various pointers (and zero them) based - * on the arguments passed. Return the block as a result. - */ -static struct diff3_block * -create_diff3_block (low0, high0, low1, high1, low2, high2) - register int low0, high0, low1, high1, low2, high2; -{ - struct diff3_block *result = ALLOCATE (1, struct diff3_block); - int numlines; - - D3_TYPE (result) = ERROR; - D_NEXT (result) = 0; - - /* Assign ranges */ - D_LOWLINE (result, FILE0) = low0; - D_HIGHLINE (result, FILE0) = high0; - D_LOWLINE (result, FILE1) = low1; - D_HIGHLINE (result, FILE1) = high1; - D_LOWLINE (result, FILE2) = low2; - D_HIGHLINE (result, FILE2) = high2; - - /* Allocate and zero space */ - numlines = D_NUMLINES (result, FILE0); - if (numlines) - { - D_LINEARRAY (result, FILE0) = ALLOCATE (numlines, char *); - D_LENARRAY (result, FILE0) = ALLOCATE (numlines, size_t); - bzero (D_LINEARRAY (result, FILE0), (numlines * sizeof (char *))); - bzero (D_LENARRAY (result, FILE0), (numlines * sizeof (size_t))); - } - else - { - D_LINEARRAY (result, FILE0) = 0; - D_LENARRAY (result, FILE0) = 0; - } - - numlines = D_NUMLINES (result, FILE1); - if (numlines) - { - D_LINEARRAY (result, FILE1) = ALLOCATE (numlines, char *); - D_LENARRAY (result, FILE1) = ALLOCATE (numlines, size_t); - bzero (D_LINEARRAY (result, FILE1), (numlines * sizeof (char *))); - bzero (D_LENARRAY (result, FILE1), (numlines * sizeof (size_t))); - } - else - { - D_LINEARRAY (result, FILE1) = 0; - D_LENARRAY (result, FILE1) = 0; - } - - numlines = D_NUMLINES (result, FILE2); - if (numlines) - { - D_LINEARRAY (result, FILE2) = ALLOCATE (numlines, char *); - D_LENARRAY (result, FILE2) = ALLOCATE (numlines, size_t); - bzero (D_LINEARRAY (result, FILE2), (numlines * sizeof (char *))); - bzero (D_LENARRAY (result, FILE2), (numlines * sizeof (size_t))); - } - else - { - D_LINEARRAY (result, FILE2) = 0; - D_LENARRAY (result, FILE2) = 0; - } - - /* Return */ - return result; -} - -/* - * Compare two lists of lines of text. - * Return 1 if they are equivalent, 0 if not. - */ -static int -compare_line_list (list1, lengths1, list2, lengths2, nl) - char * const list1[], * const list2[]; - size_t const lengths1[], lengths2[]; - int nl; -{ - char - * const *l1 = list1, - * const *l2 = list2; - size_t const - *lgths1 = lengths1, - *lgths2 = lengths2; - - while (nl--) - if (!*l1 || !*l2 || *lgths1 != *lgths2++ - || memcmp (*l1++, *l2++, *lgths1++)) - return 0; - return 1; -} - -/* - * Routines to input and parse two way diffs. - */ - -extern char **environ; - -static struct diff_block * -process_diff (filea, fileb, last_block, diff_contents) - char const *filea, *fileb; - struct diff_block **last_block; - char **diff_contents; -{ - char *diff_limit; - char *scan_diff; - enum diff_type dt; - int i; - struct diff_block *block_list, **block_list_end, *bptr; - - diff_limit = read_diff (filea, fileb, diff_contents); - scan_diff = *diff_contents; - block_list_end = &block_list; - bptr = 0; /* Pacify `gcc -W'. */ - - while (scan_diff < diff_limit) - { - bptr = ALLOCATE (1, struct diff_block); - bptr->lines[0] = bptr->lines[1] = 0; - bptr->lengths[0] = bptr->lengths[1] = 0; - - dt = process_diff_control (&scan_diff, bptr); - if (dt == ERROR || *scan_diff != '\n') - { - char *serr; - - for (serr = scan_diff; *serr != '\n'; serr++) - ; - *serr = '\0'; - diff_error ("diff error: %s", scan_diff, 0); - *serr = '\n'; - DIFF3_ABORT (2); - } - scan_diff++; - - /* Force appropriate ranges to be null, if necessary */ - switch (dt) - { - case ADD: - bptr->ranges[0][0]++; - break; - case DELETE: - bptr->ranges[1][0]++; - break; - case CHANGE: - break; - default: - diff3_fatal ("internal error: invalid diff type in process_diff"); - break; - } - - /* Allocate space for the pointers for the lines from filea, and - parcel them out among these pointers */ - if (dt != ADD) - { - int numlines = D_NUMLINES (bptr, 0); - bptr->lines[0] = ALLOCATE (numlines, char *); - bptr->lengths[0] = ALLOCATE (numlines, size_t); - for (i = 0; i < numlines; i++) - scan_diff = scan_diff_line (scan_diff, - &(bptr->lines[0][i]), - &(bptr->lengths[0][i]), - diff_limit, - '<'); - } - - /* Get past the separator for changes */ - if (dt == CHANGE) - { - if (strncmp (scan_diff, "---\n", 4)) - diff3_fatal ("invalid diff format; invalid change separator"); - scan_diff += 4; - } - - /* Allocate space for the pointers for the lines from fileb, and - parcel them out among these pointers */ - if (dt != DELETE) - { - int numlines = D_NUMLINES (bptr, 1); - bptr->lines[1] = ALLOCATE (numlines, char *); - bptr->lengths[1] = ALLOCATE (numlines, size_t); - for (i = 0; i < numlines; i++) - scan_diff = scan_diff_line (scan_diff, - &(bptr->lines[1][i]), - &(bptr->lengths[1][i]), - diff_limit, - '>'); - } - - /* Place this block on the blocklist. */ - *block_list_end = bptr; - block_list_end = &bptr->next; - } - - *block_list_end = 0; - *last_block = bptr; - return block_list; -} - -/* - * This routine will parse a normal format diff control string. It - * returns the type of the diff (ERROR if the format is bad). All of - * the other important information is filled into to the structure - * pointed to by db, and the string pointer (whose location is passed - * to this routine) is updated to point beyond the end of the string - * parsed. Note that only the ranges in the diff_block will be set by - * this routine. - * - * If some specific pair of numbers has been reduced to a single - * number, then both corresponding numbers in the diff block are set - * to that number. In general these numbers are interpetted as ranges - * inclusive, unless being used by the ADD or DELETE commands. It is - * assumed that these will be special cased in a superior routine. - */ - -static enum diff_type -process_diff_control (string, db) - char **string; - struct diff_block *db; -{ - char *s = *string; - int holdnum; - enum diff_type type; - -/* These macros are defined here because they can use variables - defined in this function. Don't try this at home kids, we're - trained professionals! - - Also note that SKIPWHITE only recognizes tabs and spaces, and - that READNUM can only read positive, integral numbers */ - -#define SKIPWHITE(s) { while (*s == ' ' || *s == '\t') s++; } -#define READNUM(s, num) \ - { unsigned char c = *s; if (!ISDIGIT (c)) return ERROR; holdnum = 0; \ - do { holdnum = (c - '0' + holdnum * 10); } \ - while (ISDIGIT (c = *++s)); (num) = holdnum; } - - /* Read first set of digits */ - SKIPWHITE (s); - READNUM (s, db->ranges[0][START]); - - /* Was that the only digit? */ - SKIPWHITE (s); - if (*s == ',') - { - /* Get the next digit */ - s++; - READNUM (s, db->ranges[0][END]); - } - else - db->ranges[0][END] = db->ranges[0][START]; - - /* Get the letter */ - SKIPWHITE (s); - switch (*s) - { - case 'a': - type = ADD; - break; - case 'c': - type = CHANGE; - break; - case 'd': - type = DELETE; - break; - default: - return ERROR; /* Bad format */ - } - s++; /* Past letter */ - - /* Read second set of digits */ - SKIPWHITE (s); - READNUM (s, db->ranges[1][START]); - - /* Was that the only digit? */ - SKIPWHITE (s); - if (*s == ',') - { - /* Get the next digit */ - s++; - READNUM (s, db->ranges[1][END]); - SKIPWHITE (s); /* To move to end */ - } - else - db->ranges[1][END] = db->ranges[1][START]; - - *string = s; - return type; -} - -static char * -read_diff (filea, fileb, output_placement) - char const *filea, *fileb; - char **output_placement; -{ - char *diff_result; - size_t bytes, current_chunk_size, total; - int fd, wstatus; - struct stat pipestat; - FILE *outfile_hold; - const struct diff_callbacks *callbacks_hold; - struct diff_callbacks my_callbacks; - struct diff_callbacks *my_callbacks_arg; - - /* 302 / 1000 is log10(2.0) rounded up. Subtract 1 for the sign bit; - add 1 for integer division truncation; add 1 more for a minus sign. */ -#define INT_STRLEN_BOUND(type) ((sizeof(type)*CHAR_BIT - 1) * 302 / 1000 + 2) - - char const *argv[7]; - char horizon_arg[17 + INT_STRLEN_BOUND (int)]; - char const **ap; - char *diffout; - - ap = argv; - *ap++ = "diff"; - if (always_text) - *ap++ = "-a"; - sprintf (horizon_arg, "--horizon-lines=%d", horizon_lines); - *ap++ = horizon_arg; - *ap++ = "--"; - *ap++ = filea; - *ap++ = fileb; - *ap = 0; - - diffout = cvs_temp_name (); - - outfile_hold = outfile; - callbacks_hold = callbacks; - - /* We want to call diff_run preserving any stdout and stderr - callbacks, but discarding any callbacks to handle file output, - since we want the file output to go to our temporary file. - FIXME: We should use callbacks to just read it into a memory - buffer; that's we do with the temporary file just below anyhow. */ - if (callbacks == NULL) - my_callbacks_arg = NULL; - else - { - my_callbacks = *callbacks; - my_callbacks.write_output = NULL; - my_callbacks.flush_output = NULL; - my_callbacks_arg = &my_callbacks; - } - - wstatus = diff_run (ap - argv, (char **) argv, diffout, my_callbacks_arg); - - outfile = outfile_hold; - callbacks = callbacks_hold; - - if (wstatus == 2) - diff3_fatal ("subsidiary diff failed"); - - if (-1 == (fd = open (diffout, O_RDONLY))) - diff3_fatal ("could not open temporary diff file"); - - current_chunk_size = 8 * 1024; - if (fstat (fd, &pipestat) == 0) - current_chunk_size = max (current_chunk_size, STAT_BLOCKSIZE (pipestat)); - - diff_result = xmalloc (current_chunk_size); - total = 0; - do { - bytes = myread (fd, - diff_result + total, - current_chunk_size - total); - total += bytes; - if (total == current_chunk_size) - { - if (current_chunk_size < 2 * current_chunk_size) - current_chunk_size = 2 * current_chunk_size; - else if (current_chunk_size < (size_t) -1) - current_chunk_size = (size_t) -1; - else - diff3_fatal ("files are too large to fit into memory"); - diff_result = xrealloc (diff_result, (current_chunk_size *= 2)); - } - } while (bytes); - - if (total != 0 && diff_result[total-1] != '\n') - diff3_fatal ("invalid diff format; incomplete last line"); - - *output_placement = diff_result; - - if (close (fd) != 0) - diff3_perror_with_exit ("pipe close"); - unlink (diffout); - free( diffout ); - - return diff_result + total; -} - - -/* - * Scan a regular diff line (consisting of > or <, followed by a - * space, followed by text (including nulls) up to a newline. - * - * This next routine began life as a macro and many parameters in it - * are used as call-by-reference values. - */ -static char * -scan_diff_line (scan_ptr, set_start, set_length, limit, leadingchar) - char *scan_ptr, **set_start; - size_t *set_length; - char *limit; - int leadingchar; -{ - char *line_ptr; - - if (!(scan_ptr[0] == leadingchar - && scan_ptr[1] == ' ')) - diff3_fatal ("invalid diff format; incorrect leading line chars"); - - *set_start = line_ptr = scan_ptr + 2; - while (*line_ptr++ != '\n') - ; - - /* Include newline if the original line ended in a newline, - or if an edit script is being generated. - Copy any missing newline message to stderr if an edit script is being - generated, because edit scripts cannot handle missing newlines. - Return the beginning of the next line. */ - *set_length = line_ptr - *set_start; - if (line_ptr < limit && *line_ptr == '\\') - { - if (! edscript) - { - --*set_length; - line_ptr++; - while (*line_ptr++ != '\n') - ; - } - else - { - char *serr; - - line_ptr++; - serr = line_ptr; - while (*line_ptr++ != '\n') - ; - line_ptr[-1] = '\0'; - diff_error ("%s", serr, 0); - line_ptr[-1] = '\n'; - } - } - - return line_ptr; -} - -/* - * This routine outputs a three way diff passed as a list of - * diff3_block's. - * The argument MAPPING is indexed by external file number (in the - * argument list) and contains the internal file number (from the - * diff passed). This is important because the user expects his - * outputs in terms of the argument list number, and the diff passed - * may have been done slightly differently (if the last argument - * was "-", for example). - * REV_MAPPING is the inverse of MAPPING. - */ -static void -output_diff3 (diff, mapping, rev_mapping) - struct diff3_block *diff; - int const mapping[3], rev_mapping[3]; -{ - int i; - int oddoneout; - char *cp; - struct diff3_block *ptr; - int line; - size_t length; - int dontprint; - static int skew_increment[3] = { 2, 3, 1 }; /* 0==>2==>1==>3 */ - char const *line_prefix = tab_align_flag ? "\t" : " "; - - for (ptr = diff; ptr; ptr = D_NEXT (ptr)) - { - char x[2]; - - switch (ptr->correspond) - { - case DIFF_ALL: - x[0] = '\0'; - dontprint = 3; /* Print them all */ - oddoneout = 3; /* Nobody's odder than anyone else */ - break; - case DIFF_1ST: - case DIFF_2ND: - case DIFF_3RD: - oddoneout = rev_mapping[(int) ptr->correspond - (int) DIFF_1ST]; - - x[0] = oddoneout + '1'; - x[1] = '\0'; - dontprint = oddoneout==0; - break; - default: - diff3_fatal ("internal error: invalid diff type passed to output"); - } - printf_output ("====%s\n", x); - - /* Go 0, 2, 1 if the first and third outputs are equivalent. */ - for (i = 0; i < 3; - i = (oddoneout == 1 ? skew_increment[i] : i + 1)) - { - int realfile = mapping[i]; - int - lowt = D_LOWLINE (ptr, realfile), - hight = D_HIGHLINE (ptr, realfile); - - printf_output ("%d:", i + 1); - switch (lowt - hight) - { - case 1: - printf_output ("%da\n", lowt - 1); - break; - case 0: - printf_output ("%dc\n", lowt); - break; - default: - printf_output ("%d,%dc\n", lowt, hight); - break; - } - - if (i == dontprint) continue; - - if (lowt <= hight) - { - line = 0; - do - { - printf_output (line_prefix); - cp = D_RELNUM (ptr, realfile, line); - length = D_RELLEN (ptr, realfile, line); - write_output (cp, length); - } - while (++line < hight - lowt + 1); - if (cp[length - 1] != '\n') - printf_output ("\n\\ No newline at end of file\n"); - } - } - } -} - - -/* - * Output the lines of B taken from FILENUM. - * Double any initial '.'s; yield nonzero if any initial '.'s were doubled. - */ -static int -dotlines (b, filenum) - struct diff3_block *b; - int filenum; -{ - int i; - int leading_dot = 0; - - for (i = 0; - i < D_NUMLINES (b, filenum); - i++) - { - char *line = D_RELNUM (b, filenum, i); - if (line[0] == '.') - { - leading_dot = 1; - write_output (".", 1); - } - write_output (line, D_RELLEN (b, filenum, i)); - } - - return leading_dot; -} - -/* - * Output to OUTPUTFILE a '.' line. If LEADING_DOT is nonzero, - * also output a command that removes initial '.'s - * starting with line START and continuing for NUM lines. - */ -static void -undotlines (leading_dot, start, num) - int leading_dot, start, num; -{ - write_output (".\n", 2); - if (leading_dot) - if (num == 1) - printf_output ("%ds/^\\.//\n", start); - else - printf_output ("%d,%ds/^\\.//\n", start, start + num - 1); -} - -/* - * This routine outputs a diff3 set of blocks as an ed script. This - * script applies the changes between file's 2 & 3 to file 1. It - * takes the precise format of the ed script to be output from global - * variables set during options processing. Note that it does - * destructive things to the set of diff3 blocks it is passed; it - * reverses their order (this gets around the problems involved with - * changing line numbers in an ed script). - * - * Note that this routine has the same problem of mapping as the last - * one did; the variable MAPPING maps from file number according to - * the argument list to file number according to the diff passed. All - * files listed below are in terms of the argument list. - * REV_MAPPING is the inverse of MAPPING. - * - * The arguments FILE0, FILE1 and FILE2 are the strings to print - * as the names of the three files. These may be the actual names, - * or may be the arguments specified with -L. - * - * Returns 1 if conflicts were found. - */ - -static int -output_diff3_edscript (diff, mapping, rev_mapping, file0, file1, file2) - struct diff3_block *diff; - int const mapping[3], rev_mapping[3]; - char const *file0, *file1, *file2; -{ - int leading_dot; - int conflicts_found = 0, conflict; - struct diff3_block *b; - - for (b = reverse_diff3_blocklist (diff); b; b = b->next) - { - /* Must do mapping correctly. */ - enum diff_type type - = ((b->correspond == DIFF_ALL) ? - DIFF_ALL : - ((enum diff_type) - (((int) DIFF_1ST) - + rev_mapping[(int) b->correspond - (int) DIFF_1ST]))); - - /* If we aren't supposed to do this output block, skip it. */ - switch (type) - { - default: continue; - case DIFF_2ND: if (!show_2nd) continue; conflict = 1; break; - case DIFF_3RD: if (overlap_only) continue; conflict = 0; break; - case DIFF_ALL: if (simple_only) continue; conflict = flagging; break; - } - - if (conflict) - { - conflicts_found = 1; - - - /* Mark end of conflict. */ - - printf_output ("%da\n", D_HIGHLINE (b, mapping[FILE0])); - leading_dot = 0; - if (type == DIFF_ALL) - { - if (show_2nd) - { - /* Append lines from FILE1. */ - printf_output ("||||||| %s\n", file1); - leading_dot = dotlines (b, mapping[FILE1]); - } - /* Append lines from FILE2. */ - printf_output ("=======\n"); - leading_dot |= dotlines (b, mapping[FILE2]); - } - printf_output (">>>>>>> %s\n", file2); - undotlines (leading_dot, - D_HIGHLINE (b, mapping[FILE0]) + 2, - (D_NUMLINES (b, mapping[FILE1]) - + D_NUMLINES (b, mapping[FILE2]) + 1)); - - - /* Mark start of conflict. */ - - printf_output ("%da\n<<<<<<< %s\n", - D_LOWLINE (b, mapping[FILE0]) - 1, - type == DIFF_ALL ? file0 : file1); - leading_dot = 0; - if (type == DIFF_2ND) - { - /* Prepend lines from FILE1. */ - leading_dot = dotlines (b, mapping[FILE1]); - printf_output ("=======\n"); - } - undotlines (leading_dot, - D_LOWLINE (b, mapping[FILE0]) + 1, - D_NUMLINES (b, mapping[FILE1])); - } - else if (D_NUMLINES (b, mapping[FILE2]) == 0) - /* Write out a delete */ - { - if (D_NUMLINES (b, mapping[FILE0]) == 1) - printf_output ("%dd\n", D_LOWLINE (b, mapping[FILE0])); - else - printf_output ("%d,%dd\n", - D_LOWLINE (b, mapping[FILE0]), - D_HIGHLINE (b, mapping[FILE0])); - } - else - /* Write out an add or change */ - { - switch (D_NUMLINES (b, mapping[FILE0])) - { - case 0: - printf_output ("%da\n", D_HIGHLINE (b, mapping[FILE0])); - break; - case 1: - printf_output ("%dc\n", D_HIGHLINE (b, mapping[FILE0])); - break; - default: - printf_output ("%d,%dc\n", - D_LOWLINE (b, mapping[FILE0]), - D_HIGHLINE (b, mapping[FILE0])); - break; - } - - undotlines (dotlines (b, mapping[FILE2]), - D_LOWLINE (b, mapping[FILE0]), - D_NUMLINES (b, mapping[FILE2])); - } - } - if (finalwrite) printf_output ("w\nq\n"); - return conflicts_found; -} - -/* - * Read from INFILE and output to the standard output file a set of - * diff3_ blocks DIFF as a merged file. This acts like 'ed file0 - * <[output_diff3_edscript]', except that it works even for binary - * data or incomplete lines. - * - * As before, MAPPING maps from arg list file number to diff file number, - * REV_MAPPING is its inverse, - * and FILE0, FILE1, and FILE2 are the names of the files. - * - * Returns 1 if conflicts were found. - */ - -static int -output_diff3_merge (infile, diff, mapping, rev_mapping, - file0, file1, file2) - FILE *infile; - struct diff3_block *diff; - int const mapping[3], rev_mapping[3]; - char const *file0, *file1, *file2; -{ - int c, i; - char cc; - int conflicts_found = 0, conflict; - struct diff3_block *b; - int linesread = 0; - - for (b = diff; b; b = b->next) - { - /* Must do mapping correctly. */ - enum diff_type type - = ((b->correspond == DIFF_ALL) ? - DIFF_ALL : - ((enum diff_type) - (((int) DIFF_1ST) - + rev_mapping[(int) b->correspond - (int) DIFF_1ST]))); - char const *format_2nd = "<<<<<<< %s\n"; - - /* If we aren't supposed to do this output block, skip it. */ - switch (type) - { - default: continue; - case DIFF_2ND: if (!show_2nd) continue; conflict = 1; break; - case DIFF_3RD: if (overlap_only) continue; conflict = 0; break; - case DIFF_ALL: if (simple_only) continue; conflict = flagging; - format_2nd = "||||||| %s\n"; - break; - } - - /* Copy I lines from file 0. */ - i = D_LOWLINE (b, FILE0) - linesread - 1; - linesread += i; - while (0 <= --i) - do - { - c = getc (infile); - if (c == EOF) - if (ferror (infile)) - diff3_perror_with_exit ("input file"); - else if (feof (infile)) - diff3_fatal ("input file shrank"); - cc = c; - write_output (&cc, 1); - } - while (c != '\n'); - - if (conflict) - { - conflicts_found = 1; - - if (type == DIFF_ALL) - { - /* Put in lines from FILE0 with bracket. */ - printf_output ("<<<<<<< %s\n", file0); - for (i = 0; - i < D_NUMLINES (b, mapping[FILE0]); - i++) - write_output (D_RELNUM (b, mapping[FILE0], i), - D_RELLEN (b, mapping[FILE0], i)); - } - - if (show_2nd) - { - /* Put in lines from FILE1 with bracket. */ - printf_output (format_2nd, file1); - for (i = 0; - i < D_NUMLINES (b, mapping[FILE1]); - i++) - write_output (D_RELNUM (b, mapping[FILE1], i), - D_RELLEN (b, mapping[FILE1], i)); - } - - printf_output ("=======\n"); - } - - /* Put in lines from FILE2. */ - for (i = 0; - i < D_NUMLINES (b, mapping[FILE2]); - i++) - write_output (D_RELNUM (b, mapping[FILE2], i), - D_RELLEN (b, mapping[FILE2], i)); - - if (conflict) - printf_output (">>>>>>> %s\n", file2); - - /* Skip I lines in file 0. */ - i = D_NUMLINES (b, FILE0); - linesread += i; - while (0 <= --i) - while ((c = getc (infile)) != '\n') - if (c == EOF) - if (ferror (infile)) - diff3_perror_with_exit ("input file"); - else if (feof (infile)) - { - if (i || b->next) - diff3_fatal ("input file shrank"); - return conflicts_found; - } - } - /* Copy rest of common file. */ - while ((c = getc (infile)) != EOF || !(ferror (infile) | feof (infile))) - { - cc = c; - write_output (&cc, 1); - } - return conflicts_found; -} - -/* - * Reverse the order of the list of diff3 blocks. - */ -static struct diff3_block * -reverse_diff3_blocklist (diff) - struct diff3_block *diff; -{ - register struct diff3_block *tmp, *next, *prev; - - for (tmp = diff, prev = 0; tmp; tmp = next) - { - next = tmp->next; - tmp->next = prev; - prev = tmp; - } - - return prev; -} - -static size_t -myread (fd, ptr, size) - int fd; - char *ptr; - size_t size; -{ - ssize_t result = read (fd, ptr, size); - if (result == -1) - diff3_perror_with_exit ("read failed"); - return (size_t)result; -} - -static void -diff3_fatal (string) - char const *string; -{ - diff_error ("%s", string, 0); - DIFF3_ABORT (2); -} - -static void -diff3_perror_with_exit (string) - char const *string; -{ - perror_with_name (string); - DIFF3_ABORT (2); -} - -static void -initialize_main (argcp, argvp) - int *argcp; - char ***argvp; -{ - always_text = 0; - edscript = 0; - flagging = 0; - tab_align_flag = 0; - simple_only = 0; - overlap_only = 0; - show_2nd = 0; - finalwrite = 0; - merge = 0; - diff_program_name = (*argvp)[0]; - outfile = NULL; -} - -static void -free_diff_blocks(p) - struct diff_block *p; -{ - register struct diff_block *next; - - while (p) - { - next = p->next; - if (p->lines[0]) free(p->lines[0]); - if (p->lines[1]) free(p->lines[1]); - if (p->lengths[0]) free(p->lengths[0]); - if (p->lengths[1]) free(p->lengths[1]); - free(p); - p = next; - } -} - -static void -free_diff3_blocks(p) - struct diff3_block *p; -{ - register struct diff3_block *next; - - while (p) - { - next = p->next; - if (p->lines[0]) free(p->lines[0]); - if (p->lines[1]) free(p->lines[1]); - if (p->lines[2]) free(p->lines[2]); - if (p->lengths[0]) free(p->lengths[0]); - if (p->lengths[1]) free(p->lengths[1]); - if (p->lengths[2]) free(p->lengths[2]); - free(p); - p = next; - } -} diff --git a/contrib/cvs/diff/diffrun.h b/contrib/cvs/diff/diffrun.h deleted file mode 100644 index 9ee804b..0000000 --- a/contrib/cvs/diff/diffrun.h +++ /dev/null @@ -1,69 +0,0 @@ -/* Interface header file for GNU DIFF library. - Copyright (C) 1998 Free Software Foundation, Inc. - -This file is part of GNU DIFF. - -GNU DIFF is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU DIFF 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. - -*/ - -#ifndef DIFFRUN_H -#define DIFFRUN_H - -/* This header file defines the interfaces used by the diff library. - It should be included by programs which use the diff library. */ - -#include - -#if defined __STDC__ && __STDC__ -#define DIFFPARAMS(args) args -#else -#define DIFFPARAMS(args) () -#endif - -/* The diff_callbacks structure is used to handle callbacks from the - diff library. All output goes through these callbacks. When a - pointer to this structure is passed in, it may be NULL. Also, any - of the individual callbacks may be NULL. This means that the - default action should be taken. */ - -struct diff_callbacks -{ - /* Write output. This function just writes a string of a given - length to the output file. The default is to fwrite to OUTFILE. - If this callback is defined, flush_output must also be defined. - If the length is zero, output zero bytes. */ - void (*write_output) DIFFPARAMS((char const *, size_t)); - /* Flush output. The default is to fflush OUTFILE. If this - callback is defined, write_output must also be defined. */ - void (*flush_output) DIFFPARAMS((void)); - /* Write a '\0'-terminated string to stdout. - This is called for version and help messages. */ - void (*write_stdout) DIFFPARAMS((char const *)); - /* Print an error message. The first argument is a printf format, - and the next two are parameters. The default is to print a - message on stderr. */ - void (*error) DIFFPARAMS((char const *, char const *, char const *)); -}; - -/* Run a diff. */ - -extern int diff_run DIFFPARAMS((int, char **, const char *, - const struct diff_callbacks *)); - -/* Run a diff3. */ - -extern int diff3_run DIFFPARAMS((int, char **, char *, - const struct diff_callbacks *)); - -#undef DIFFPARAMS - -#endif /* DIFFRUN_H */ diff --git a/contrib/cvs/diff/dir.c b/contrib/cvs/diff/dir.c deleted file mode 100644 index da497dc..0000000 --- a/contrib/cvs/diff/dir.c +++ /dev/null @@ -1,218 +0,0 @@ -/* Read, sort and compare two directories. Used for GNU DIFF. - Copyright (C) 1988, 1989, 1992, 1993, 1994 Free Software Foundation, Inc. - -This file is part of GNU DIFF. - -GNU DIFF is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU DIFF 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. - -*/ - -#include "diff.h" - -/* Read the directory named by DIR and store into DIRDATA a sorted vector - of filenames for its contents. DIR->desc == -1 means this directory is - known to be nonexistent, so set DIRDATA to an empty vector. - Return -1 (setting errno) if error, 0 otherwise. */ - -struct dirdata -{ - char const **names; /* Sorted names of files in dir, 0-terminated. */ - char *data; /* Allocated storage for file names. */ -}; - -static int compare_names PARAMS((void const *, void const *)); -static int dir_sort PARAMS((struct file_data const *, struct dirdata *)); - -#ifdef _WIN32 -#define CLOSEDIR_VOID 1 -#endif - -static int -dir_sort (dir, dirdata) - struct file_data const *dir; - struct dirdata *dirdata; -{ - register struct dirent *next; - register int i; - - /* Address of block containing the files that are described. */ - char const **names; - - /* Number of files in directory. */ - size_t nnames; - - /* Allocated and used storage for file name data. */ - char *data; - size_t data_alloc, data_used; - - dirdata->names = 0; - dirdata->data = 0; - nnames = 0; - data = 0; - - if (dir->desc != -1) - { - /* Open the directory and check for errors. */ - register DIR *reading = CVS_OPENDIR (dir->name); - if (!reading) - return -1; - - /* Initialize the table of filenames. */ - - data_alloc = max (1, (size_t) dir->stat.st_size); - data_used = 0; - dirdata->data = data = xmalloc (data_alloc); - - /* Read the directory entries, and insert the subfiles - into the `data' table. */ - - while ((errno = 0, (next = CVS_READDIR (reading)) != 0)) - { - char *d_name = next->d_name; - size_t d_size = NAMLEN (next) + 1; - - /* Ignore the files `.' and `..' */ - if (d_name[0] == '.' - && (d_name[1] == 0 || (d_name[1] == '.' && d_name[2] == 0))) - continue; - - if (excluded_filename (d_name)) - continue; - - while (data_alloc < data_used + d_size) - dirdata->data = data = xrealloc (data, data_alloc *= 2); - memcpy (data + data_used, d_name, d_size); - data_used += d_size; - nnames++; - } - if (errno) - { - int e = errno; - CVS_CLOSEDIR (reading); - errno = e; - return -1; - } -#if CLOSEDIR_VOID - CVS_CLOSEDIR (reading); -#else - if (CVS_CLOSEDIR (reading) != 0) - return -1; -#endif - } - - /* Create the `names' table from the `data' table. */ - dirdata->names = names = (char const **) xmalloc (sizeof (char *) - * (nnames + 1)); - for (i = 0; i < nnames; i++) - { - names[i] = data; - data += strlen (data) + 1; - } - names[nnames] = 0; - - /* Sort the table. */ - qsort (names, nnames, sizeof (char *), compare_names); - - return 0; -} - -/* Sort the files now in the table. */ - -static int -compare_names (file1, file2) - void const *file1, *file2; -{ - return filename_cmp (* (char const *const *) file1, - * (char const *const *) file2); -} - -/* Compare the contents of two directories named in FILEVEC[0] and FILEVEC[1]. - This is a top-level routine; it does everything necessary for diff - on two directories. - - FILEVEC[0].desc == -1 says directory FILEVEC[0] doesn't exist, - but pretend it is empty. Likewise for FILEVEC[1]. - - HANDLE_FILE is a caller-provided subroutine called to handle each file. - It gets five operands: dir and name (rel to original working dir) of file - in dir 0, dir and name pathname of file in dir 1, and the recursion depth. - - For a file that appears in only one of the dirs, one of the name-args - to HANDLE_FILE is zero. - - DEPTH is the current depth in recursion, used for skipping top-level - files by the -S option. - - Returns the maximum of all the values returned by HANDLE_FILE, - or 2 if trouble is encountered in opening files. */ - -int -diff_dirs (filevec, handle_file, depth) - struct file_data const filevec[]; - int (*handle_file) PARAMS((char const *, char const *, char const *, char const *, int)); - int depth; -{ - struct dirdata dirdata[2]; - int val = 0; /* Return value. */ - int i; - - /* Get sorted contents of both dirs. */ - for (i = 0; i < 2; i++) - if (dir_sort (&filevec[i], &dirdata[i]) != 0) - { - perror_with_name (filevec[i].name); - val = 2; - } - - if (val == 0) - { - register char const * const *names0 = dirdata[0].names; - register char const * const *names1 = dirdata[1].names; - char const *name0 = filevec[0].name; - char const *name1 = filevec[1].name; - - /* If `-S name' was given, and this is the topmost level of comparison, - ignore all file names less than the specified starting name. */ - - if (dir_start_file && depth == 0) - { - while (*names0 && filename_cmp (*names0, dir_start_file) < 0) - names0++; - while (*names1 && filename_cmp (*names1, dir_start_file) < 0) - names1++; - } - - /* Loop while files remain in one or both dirs. */ - while (*names0 || *names1) - { - /* Compare next name in dir 0 with next name in dir 1. - At the end of a dir, - pretend the "next name" in that dir is very large. */ - int nameorder = (!*names0 ? 1 : !*names1 ? -1 - : filename_cmp (*names0, *names1)); - int v1 = (*handle_file) (name0, 0 < nameorder ? 0 : *names0++, - name1, nameorder < 0 ? 0 : *names1++, - depth + 1); - if (v1 > val) - val = v1; - } - } - - for (i = 0; i < 2; i++) - { - if (dirdata[i].names) - free (dirdata[i].names); - if (dirdata[i].data) - free (dirdata[i].data); - } - - return val; -} diff --git a/contrib/cvs/diff/ed.c b/contrib/cvs/diff/ed.c deleted file mode 100644 index 74fc2a4..0000000 --- a/contrib/cvs/diff/ed.c +++ /dev/null @@ -1,198 +0,0 @@ -/* Output routines for ed-script format. - Copyright (C) 1988, 89, 91, 92, 93, 1998 Free Software Foundation, Inc. - -This file is part of GNU DIFF. - -GNU DIFF is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU DIFF 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. - -*/ - -#include "diff.h" - -static void print_ed_hunk PARAMS((struct change *)); -static void print_rcs_hunk PARAMS((struct change *)); -static void pr_forward_ed_hunk PARAMS((struct change *)); - -/* Print our script as ed commands. */ - -void -print_ed_script (script) - struct change *script; -{ - print_script (script, find_reverse_change, print_ed_hunk); -} - -/* Print a hunk of an ed diff */ - -static void -print_ed_hunk (hunk) - struct change *hunk; -{ - int f0, l0, f1, l1; - int deletes, inserts; - -#if 0 - hunk = flip_script (hunk); -#endif -#ifdef DEBUG - debug_script (hunk); -#endif - - /* Determine range of line numbers involved in each file. */ - analyze_hunk (hunk, &f0, &l0, &f1, &l1, &deletes, &inserts); - if (!deletes && !inserts) - return; - - begin_output (); - - /* Print out the line number header for this hunk */ - print_number_range (',', &files[0], f0, l0); - printf_output ("%c\n", change_letter (inserts, deletes)); - - /* Print new/changed lines from second file, if needed */ - if (inserts) - { - int i; - int inserting = 1; - for (i = f1; i <= l1; i++) - { - /* Resume the insert, if we stopped. */ - if (! inserting) - printf_output ("%da\n", - i - f1 + translate_line_number (&files[0], f0) - 1); - inserting = 1; - - /* If the file's line is just a dot, it would confuse `ed'. - So output it with a double dot, and set the flag LEADING_DOT - so that we will output another ed-command later - to change the double dot into a single dot. */ - - if (files[1].linbuf[i][0] == '.' - && files[1].linbuf[i][1] == '\n') - { - printf_output ("..\n"); - printf_output (".\n"); - /* Now change that double dot to the desired single dot. */ - printf_output ("%ds/^\\.\\././\n", - i - f1 + translate_line_number (&files[0], f0)); - inserting = 0; - } - else - /* Line is not `.', so output it unmodified. */ - print_1_line ("", &files[1].linbuf[i]); - } - - /* End insert mode, if we are still in it. */ - if (inserting) - printf_output (".\n"); - } -} - -/* Print change script in the style of ed commands, - but print the changes in the order they appear in the input files, - which means that the commands are not truly useful with ed. */ - -void -pr_forward_ed_script (script) - struct change *script; -{ - print_script (script, find_change, pr_forward_ed_hunk); -} - -static void -pr_forward_ed_hunk (hunk) - struct change *hunk; -{ - int i; - int f0, l0, f1, l1; - int deletes, inserts; - - /* Determine range of line numbers involved in each file. */ - analyze_hunk (hunk, &f0, &l0, &f1, &l1, &deletes, &inserts); - if (!deletes && !inserts) - return; - - begin_output (); - - printf_output ("%c", change_letter (inserts, deletes)); - print_number_range (' ', files, f0, l0); - printf_output ("\n"); - - /* If deletion only, print just the number range. */ - - if (!inserts) - return; - - /* For insertion (with or without deletion), print the number range - and the lines from file 2. */ - - for (i = f1; i <= l1; i++) - print_1_line ("", &files[1].linbuf[i]); - - printf_output (".\n"); -} - -/* Print in a format somewhat like ed commands - except that each insert command states the number of lines it inserts. - This format is used for RCS. */ - -void -print_rcs_script (script) - struct change *script; -{ - print_script (script, find_change, print_rcs_hunk); -} - -/* Print a hunk of an RCS diff */ - -static void -print_rcs_hunk (hunk) - struct change *hunk; -{ - int i; - int f0, l0, f1, l1; - int deletes, inserts; - int tf0, tl0, tf1, tl1; - - /* Determine range of line numbers involved in each file. */ - analyze_hunk (hunk, &f0, &l0, &f1, &l1, &deletes, &inserts); - if (!deletes && !inserts) - return; - - begin_output (); - - translate_range (&files[0], f0, l0, &tf0, &tl0); - - if (deletes) - { - printf_output ("d"); - /* For deletion, print just the starting line number from file 0 - and the number of lines deleted. */ - printf_output ("%d %d\n", - tf0, - (tl0 >= tf0 ? tl0 - tf0 + 1 : 1)); - } - - if (inserts) - { - printf_output ("a"); - - /* Take last-line-number from file 0 and # lines from file 1. */ - translate_range (&files[1], f1, l1, &tf1, &tl1); - printf_output ("%d %d\n", - tl0, - (tl1 >= tf1 ? tl1 - tf1 + 1 : 1)); - - /* Print the inserted lines. */ - for (i = f1; i <= l1; i++) - print_1_line ("", &files[1].linbuf[i]); - } -} diff --git a/contrib/cvs/diff/ifdef.c b/contrib/cvs/diff/ifdef.c deleted file mode 100644 index 94fcfb5..0000000 --- a/contrib/cvs/diff/ifdef.c +++ /dev/null @@ -1,436 +0,0 @@ -/* #ifdef-format output routines for GNU DIFF. - Copyright (C) 1989, 1991, 1992, 1993, 1994, 1998 Free Software Foundation, Inc. - -This file is part of GNU DIFF. - -GNU DIFF is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY. No author or distributor -accepts responsibility to anyone for the consequences of using it -or for whether it serves any particular purpose or works at all, -unless he says so in writing. Refer to the GNU DIFF General Public -License for full details. - -Everyone is granted permission to copy, modify and redistribute -GNU DIFF, but only under the conditions described in the -GNU DIFF General Public License. A copy of this license is -supposed to have been given to you along with GNU DIFF so you -can know your rights and responsibilities. It should be in a -file named COPYING. Among other things, the copyright notice -and this notice must be preserved on all copies. */ - - -#include "diff.h" - -struct group -{ - struct file_data const *file; - int from, upto; /* start and limit lines for this group of lines */ -}; - -static char *format_group PARAMS((int, char *, int, struct group const *)); -static char *scan_char_literal PARAMS((char *, int *)); -static char *scan_printf_spec PARAMS((char *)); -static int groups_letter_value PARAMS((struct group const *, int)); -static void format_ifdef PARAMS((char *, int, int, int, int)); -static void print_ifdef_hunk PARAMS((struct change *)); -static void print_ifdef_lines PARAMS((int, char *, struct group const *)); - -static int next_line; - -/* Print the edit-script SCRIPT as a merged #ifdef file. */ - -void -print_ifdef_script (script) - struct change *script; -{ - next_line = - files[0].prefix_lines; - print_script (script, find_change, print_ifdef_hunk); - if (next_line < files[0].valid_lines) - { - begin_output (); - format_ifdef (group_format[UNCHANGED], next_line, files[0].valid_lines, - next_line - files[0].valid_lines + files[1].valid_lines, - files[1].valid_lines); - } -} - -/* Print a hunk of an ifdef diff. - This is a contiguous portion of a complete edit script, - describing changes in consecutive lines. */ - -static void -print_ifdef_hunk (hunk) - struct change *hunk; -{ - int first0, last0, first1, last1, deletes, inserts; - char *format; - - /* Determine range of line numbers involved in each file. */ - analyze_hunk (hunk, &first0, &last0, &first1, &last1, &deletes, &inserts); - if (inserts) - format = deletes ? group_format[CHANGED] : group_format[NEW]; - else if (deletes) - format = group_format[OLD]; - else - return; - - begin_output (); - - /* Print lines up to this change. */ - if (next_line < first0) - format_ifdef (group_format[UNCHANGED], next_line, first0, - next_line - first0 + first1, first1); - - /* Print this change. */ - next_line = last0 + 1; - format_ifdef (format, first0, next_line, first1, last1 + 1); -} - -/* Print a set of lines according to FORMAT. - Lines BEG0 up to END0 are from the first file; - lines BEG1 up to END1 are from the second file. */ - -static void -format_ifdef (format, beg0, end0, beg1, end1) - char *format; - int beg0, end0, beg1, end1; -{ - struct group groups[2]; - - groups[0].file = &files[0]; - groups[0].from = beg0; - groups[0].upto = end0; - groups[1].file = &files[1]; - groups[1].from = beg1; - groups[1].upto = end1; - format_group (1, format, '\0', groups); -} - -/* If DOIT is non-zero, output a set of lines according to FORMAT. - The format ends at the first free instance of ENDCHAR. - Yield the address of the terminating character. - GROUPS specifies which lines to print. - If OUT is zero, do not actually print anything; just scan the format. */ - -static char * -format_group (doit, format, endchar, groups) - int doit; - char *format; - int endchar; - struct group const *groups; -{ - register char c; - register char *f = format; - - while ((c = *f) != endchar && c != 0) - { - f++; - if (c == '%') - { - char *spec = f; - switch ((c = *f++)) - { - case '%': - break; - - case '(': - /* Print if-then-else format e.g. `%(n=1?thenpart:elsepart)'. */ - { - int i, value[2]; - int thendoit, elsedoit; - - for (i = 0; i < 2; i++) - { - unsigned char f0 = f[0]; - if (ISDIGIT (f0)) - { - value[i] = atoi (f); - while (ISDIGIT ((unsigned char) *++f)) - continue; - } - else - { - value[i] = groups_letter_value (groups, f0); - if (value[i] < 0) - goto bad_format; - f++; - } - if (*f++ != "=?"[i]) - goto bad_format; - } - if (value[0] == value[1]) - thendoit = doit, elsedoit = 0; - else - thendoit = 0, elsedoit = doit; - f = format_group (thendoit, f, ':', groups); - if (*f) - { - f = format_group (elsedoit, f + 1, ')', groups); - if (*f) - f++; - } - } - continue; - - case '<': - /* Print lines deleted from first file. */ - print_ifdef_lines (doit, line_format[OLD], &groups[0]); - continue; - - case '=': - /* Print common lines. */ - print_ifdef_lines (doit, line_format[UNCHANGED], &groups[0]); - continue; - - case '>': - /* Print lines inserted from second file. */ - print_ifdef_lines (doit, line_format[NEW], &groups[1]); - continue; - - default: - { - int value; - char *speclim; - - f = scan_printf_spec (spec); - if (!f) - goto bad_format; - speclim = f; - c = *f++; - switch (c) - { - case '\'': - f = scan_char_literal (f, &value); - if (!f) - goto bad_format; - break; - - default: - value = groups_letter_value (groups, c); - if (value < 0) - goto bad_format; - break; - } - if (doit) - { - /* Temporarily replace e.g. "%3dnx" with "%3d\0x". */ - *speclim = 0; - printf_output (spec - 1, value); - /* Undo the temporary replacement. */ - *speclim = c; - } - } - continue; - - bad_format: - c = '%'; - f = spec; - break; - } - } - if (doit) - { - /* Don't take the address of a register variable. */ - char cc = c; - write_output (&cc, 1); - } - } - return f; -} - -/* For the line group pair G, return the number corresponding to LETTER. - Return -1 if LETTER is not a group format letter. */ -static int -groups_letter_value (g, letter) - struct group const *g; - int letter; -{ - if (ISUPPER (letter)) - { - g++; - letter = tolower (letter); - } - switch (letter) - { - case 'e': return translate_line_number (g->file, g->from) - 1; - case 'f': return translate_line_number (g->file, g->from); - case 'l': return translate_line_number (g->file, g->upto) - 1; - case 'm': return translate_line_number (g->file, g->upto); - case 'n': return g->upto - g->from; - default: return -1; - } -} - -/* Output using FORMAT to print the line group GROUP. - But do nothing if DOIT is zero. */ -static void -print_ifdef_lines (doit, format, group) - int doit; - char *format; - struct group const *group; -{ - struct file_data const *file = group->file; - char const * const *linbuf = file->linbuf; - int from = group->from, upto = group->upto; - - if (!doit) - return; - - /* If possible, use a single fwrite; it's faster. */ - if (!tab_expand_flag && format[0] == '%') - { - if (format[1] == 'l' && format[2] == '\n' && !format[3]) - { - write_output (linbuf[from], - (linbuf[upto] + (linbuf[upto][-1] != '\n') - - linbuf[from])); - return; - } - if (format[1] == 'L' && !format[2]) - { - write_output (linbuf[from], - linbuf[upto] - linbuf[from]); - return; - } - } - - for (; from < upto; from++) - { - register char c; - register char *f = format; - char cc; - - while ((c = *f++) != 0) - { - if (c == '%') - { - char *spec = f; - switch ((c = *f++)) - { - case '%': - break; - - case 'l': - output_1_line (linbuf[from], - linbuf[from + 1] - - (linbuf[from + 1][-1] == '\n'), 0, 0); - continue; - - case 'L': - output_1_line (linbuf[from], linbuf[from + 1], 0, 0); - continue; - - default: - { - int value; - char *speclim; - - f = scan_printf_spec (spec); - if (!f) - goto bad_format; - speclim = f; - c = *f++; - switch (c) - { - case '\'': - f = scan_char_literal (f, &value); - if (!f) - goto bad_format; - break; - - case 'n': - value = translate_line_number (file, from); - break; - - default: - goto bad_format; - } - /* Temporarily replace e.g. "%3dnx" with "%3d\0x". */ - *speclim = 0; - printf_output (spec - 1, value); - /* Undo the temporary replacement. */ - *speclim = c; - } - continue; - - bad_format: - c = '%'; - f = spec; - break; - } - } - - /* Don't take the address of a register variable. */ - cc = c; - write_output (&cc, 1); - } - } -} - -/* Scan the character literal represented in the string LIT; LIT points just - after the initial apostrophe. Put the literal's value into *INTPTR. - Yield the address of the first character after the closing apostrophe, - or zero if the literal is ill-formed. */ -static char * -scan_char_literal (lit, intptr) - char *lit; - int *intptr; -{ - register char *p = lit; - int value, digits; - char c = *p++; - - switch (c) - { - case 0: - case '\'': - return 0; - - case '\\': - value = 0; - while ((c = *p++) != '\'') - { - unsigned digit = c - '0'; - if (8 <= digit) - return 0; - value = 8 * value + digit; - } - digits = p - lit - 2; - if (! (1 <= digits && digits <= 3)) - return 0; - break; - - default: - value = c; - if (*p++ != '\'') - return 0; - break; - } - *intptr = value; - return p; -} - -/* Scan optional printf-style SPEC of the form `-*[0-9]*(.[0-9]*)?[cdoxX]'. - Return the address of the character following SPEC, or zero if failure. */ -static char * -scan_printf_spec (spec) - register char *spec; -{ - register unsigned char c; - - while ((c = *spec++) == '-') - continue; - while (ISDIGIT (c)) - c = *spec++; - if (c == '.') - while (ISDIGIT (c = *spec++)) - continue; - switch (c) - { - case 'c': case 'd': case 'o': case 'x': case 'X': - return spec; - - default: - return 0; - } -} diff --git a/contrib/cvs/diff/io.c b/contrib/cvs/diff/io.c deleted file mode 100644 index 31581cd..0000000 --- a/contrib/cvs/diff/io.c +++ /dev/null @@ -1,711 +0,0 @@ -/* File I/O for GNU DIFF. - Copyright (C) 1988, 1989, 1992, 1993, 1994 Free Software Foundation, Inc. - -This file is part of GNU DIFF. - -GNU DIFF is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU DIFF 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. - -*/ - -#include "diff.h" - -/* Rotate a value n bits to the left. */ -#define UINT_BIT (sizeof (unsigned) * CHAR_BIT) -#define ROL(v, n) ((v) << (n) | (v) >> (UINT_BIT - (n))) - -/* Given a hash value and a new character, return a new hash value. */ -#define HASH(h, c) ((c) + ROL (h, 7)) - -/* Guess remaining number of lines from number N of lines so far, - size S so far, and total size T. */ -#define GUESS_LINES(n,s,t) (((t) - (s)) / ((n) < 10 ? 32 : (s) / ((n)-1)) + 5) - -/* Type used for fast prefix comparison in find_identical_ends. */ -#ifndef word -#define word int -#endif - -/* Lines are put into equivalence classes (of lines that match in line_cmp). - Each equivalence class is represented by one of these structures, - but only while the classes are being computed. - Afterward, each class is represented by a number. */ -struct equivclass -{ - int next; /* Next item in this bucket. */ - unsigned hash; /* Hash of lines in this class. */ - char const *line; /* A line that fits this class. */ - size_t length; /* That line's length, not counting its newline. */ -}; - -/* Hash-table: array of buckets, each being a chain of equivalence classes. - buckets[-1] is reserved for incomplete lines. */ -static int *buckets; - -/* Number of buckets in the hash table array, not counting buckets[-1]. */ -static int nbuckets; - -/* Array in which the equivalence classes are allocated. - The bucket-chains go through the elements in this array. - The number of an equivalence class is its index in this array. */ -static struct equivclass *equivs; - -/* Index of first free element in the array `equivs'. */ -static int equivs_index; - -/* Number of elements allocated in the array `equivs'. */ -static int equivs_alloc; - -static void find_and_hash_each_line PARAMS((struct file_data *)); -static void find_identical_ends PARAMS((struct file_data[])); -static void prepare_text_end PARAMS((struct file_data *)); - -/* Check for binary files and compare them for exact identity. */ - -/* Return 1 if BUF contains a non text character. - SIZE is the number of characters in BUF. */ - -#define binary_file_p(buf, size) (memchr (buf, '\0', size) != 0) - -/* Get ready to read the current file. - Return nonzero if SKIP_TEST is zero, - and if it appears to be a binary file. */ - -int -sip (current, skip_test) - struct file_data *current; - int skip_test; -{ - /* If we have a nonexistent file at this stage, treat it as empty. */ - if (current->desc < 0) - { - /* Leave room for a sentinel. */ - current->bufsize = sizeof (word); - current->buffer = xmalloc (current->bufsize); - } - else - { - current->bufsize = STAT_BLOCKSIZE (current->stat); - current->buffer = xmalloc (current->bufsize); - - if (! skip_test) - { - /* Check first part of file to see if it's a binary file. */ -#if HAVE_SETMODE - int oldmode = setmode (current->desc, O_BINARY); -#endif - ssize_t n = read (current->desc, current->buffer, current->bufsize); - if (n == -1) - pfatal_with_name (current->name); - current->buffered_chars = n; -#if HAVE_SETMODE - if (oldmode != O_BINARY) - { - if (lseek (current->desc, - (off_t) n, SEEK_CUR) == -1) - pfatal_with_name (current->name); - setmode (current->desc, oldmode); - current->buffered_chars = 0; - } -#endif - return binary_file_p (current->buffer, n); - } - } - - current->buffered_chars = 0; - return 0; -} - -/* Slurp the rest of the current file completely into memory. */ - -void -slurp (current) - struct file_data *current; -{ - ssize_t cc; - - if (current->desc < 0) - /* The file is nonexistent. */ - ; - else if (S_ISREG (current->stat.st_mode)) - { - /* It's a regular file; slurp in the rest all at once. */ - - /* Get the size out of the stat block. - Allocate enough room for appended newline and sentinel. */ - cc = current->stat.st_size + 1 + sizeof (word); - if (current->bufsize < cc) - { - current->bufsize = cc; - current->buffer = xrealloc (current->buffer, cc); - } - - if (current->buffered_chars < current->stat.st_size) - { - cc = read (current->desc, - current->buffer + current->buffered_chars, - current->stat.st_size - current->buffered_chars); - if (cc == -1) - pfatal_with_name (current->name); - current->buffered_chars += cc; - } - } - /* It's not a regular file; read it, growing the buffer as needed. */ - else if (always_text_flag || current->buffered_chars != 0) - { - for (;;) - { - if (current->buffered_chars == current->bufsize) - { - current->bufsize = current->bufsize * 2; - current->buffer = xrealloc (current->buffer, current->bufsize); - } - cc = read (current->desc, - current->buffer + current->buffered_chars, - current->bufsize - current->buffered_chars); - if (cc == 0) - break; - if (cc == -1) - pfatal_with_name (current->name); - current->buffered_chars += cc; - } - /* Allocate just enough room for appended newline and sentinel. */ - current->bufsize = current->buffered_chars + 1 + sizeof (word); - current->buffer = xrealloc (current->buffer, current->bufsize); - } -} - -/* Split the file into lines, simultaneously computing the equivalence class for - each line. */ - -static void -find_and_hash_each_line (current) - struct file_data *current; -{ - unsigned h; - unsigned char const *p = (unsigned char const *) current->prefix_end; - unsigned char c; - int i, *bucket; - size_t length; - - /* Cache often-used quantities in local variables to help the compiler. */ - char const **linbuf = current->linbuf; - int alloc_lines = current->alloc_lines; - int line = 0; - int linbuf_base = current->linbuf_base; - int *cureqs = (int *) xmalloc (alloc_lines * sizeof (int)); - struct equivclass *eqs = equivs; - int eqs_index = equivs_index; - int eqs_alloc = equivs_alloc; - char const *suffix_begin = current->suffix_begin; - char const *bufend = current->buffer + current->buffered_chars; - int use_line_cmp = ignore_some_line_changes; - - while ((char const *) p < suffix_begin) - { - char const *ip = (char const *) p; - - /* Compute the equivalence class for this line. */ - - h = 0; - - /* Hash this line until we find a newline. */ - if (ignore_case_flag) - { - if (ignore_all_space_flag) - while ((c = *p++) != '\n') - { - if (! ISSPACE (c)) - h = HASH (h, ISUPPER (c) ? tolower (c) : c); - } - else if (ignore_space_change_flag) - while ((c = *p++) != '\n') - { - if (ISSPACE (c)) - { - for (;;) - { - c = *p++; - if (!ISSPACE (c)) - break; - if (c == '\n') - goto hashing_done; - } - h = HASH (h, ' '); - } - /* C is now the first non-space. */ - h = HASH (h, ISUPPER (c) ? tolower (c) : c); - } - else - while ((c = *p++) != '\n') - h = HASH (h, ISUPPER (c) ? tolower (c) : c); - } - else - { - if (ignore_all_space_flag) - while ((c = *p++) != '\n') - { - if (! ISSPACE (c)) - h = HASH (h, c); - } - else if (ignore_space_change_flag) - while ((c = *p++) != '\n') - { - if (ISSPACE (c)) - { - for (;;) - { - c = *p++; - if (!ISSPACE (c)) - break; - if (c == '\n') - goto hashing_done; - } - h = HASH (h, ' '); - } - /* C is now the first non-space. */ - h = HASH (h, c); - } - else - while ((c = *p++) != '\n') - h = HASH (h, c); - } - hashing_done:; - - bucket = &buckets[h % nbuckets]; - length = (char const *) p - ip - 1; - - if ((char const *) p == bufend - && current->missing_newline - && ROBUST_OUTPUT_STYLE (output_style)) - { - /* This line is incomplete. If this is significant, - put the line into bucket[-1]. */ - if (! (ignore_space_change_flag | ignore_all_space_flag)) - bucket = &buckets[-1]; - - /* Omit the inserted newline when computing linbuf later. */ - p--; - bufend = suffix_begin = (char const *) p; - } - - for (i = *bucket; ; i = eqs[i].next) - if (!i) - { - /* Create a new equivalence class in this bucket. */ - i = eqs_index++; - if (i == eqs_alloc) - eqs = (struct equivclass *) - xrealloc (eqs, (eqs_alloc*=2) * sizeof(*eqs)); - eqs[i].next = *bucket; - eqs[i].hash = h; - eqs[i].line = ip; - eqs[i].length = length; - *bucket = i; - break; - } - else if (eqs[i].hash == h) - { - char const *eqline = eqs[i].line; - - /* Reuse existing equivalence class if the lines are identical. - This detects the common case of exact identity - faster than complete comparison would. */ - if (eqs[i].length == length && memcmp (eqline, ip, length) == 0) - break; - - /* Reuse existing class if line_cmp reports the lines equal. */ - if (use_line_cmp && line_cmp (eqline, ip) == 0) - break; - } - - /* Maybe increase the size of the line table. */ - if (line == alloc_lines) - { - /* Double (alloc_lines - linbuf_base) by adding to alloc_lines. */ - alloc_lines = 2 * alloc_lines - linbuf_base; - cureqs = (int *) xrealloc (cureqs, alloc_lines * sizeof (*cureqs)); - linbuf = (char const **) xrealloc (linbuf + linbuf_base, - (alloc_lines - linbuf_base) - * sizeof (*linbuf)) - - linbuf_base; - } - linbuf[line] = ip; - cureqs[line] = i; - ++line; - } - - current->buffered_lines = line; - - for (i = 0; ; i++) - { - /* Record the line start for lines in the suffix that we care about. - Record one more line start than lines, - so that we can compute the length of any buffered line. */ - if (line == alloc_lines) - { - /* Double (alloc_lines - linbuf_base) by adding to alloc_lines. */ - alloc_lines = 2 * alloc_lines - linbuf_base; - linbuf = (char const **) xrealloc (linbuf + linbuf_base, - (alloc_lines - linbuf_base) - * sizeof (*linbuf)) - - linbuf_base; - } - linbuf[line] = (char const *) p; - - if ((char const *) p == bufend) - break; - - if (context <= i && no_diff_means_no_output) - break; - - line++; - - while (*p++ != '\n') - ; - } - - /* Done with cache in local variables. */ - current->linbuf = linbuf; - current->valid_lines = line; - current->alloc_lines = alloc_lines; - current->equivs = cureqs; - equivs = eqs; - equivs_alloc = eqs_alloc; - equivs_index = eqs_index; -} - -/* Prepare the end of the text. Make sure it's initialized. - Make sure text ends in a newline, - but remember that we had to add one. */ - -static void -prepare_text_end (current) - struct file_data *current; -{ - size_t buffered_chars = current->buffered_chars; - char *p = current->buffer; - - if (buffered_chars == 0 || p[buffered_chars - 1] == '\n') - current->missing_newline = 0; - else - { - p[buffered_chars++] = '\n'; - current->buffered_chars = buffered_chars; - current->missing_newline = 1; - } - - /* Don't use uninitialized storage when planting or using sentinels. */ - if (p) - bzero (p + buffered_chars, sizeof (word)); -} - -/* Given a vector of two file_data objects, find the identical - prefixes and suffixes of each object. */ - -static void -find_identical_ends (filevec) - struct file_data filevec[]; -{ - word *w0, *w1; - char *p0, *p1, *buffer0, *buffer1; - char const *end0, *beg0; - char const **linbuf0, **linbuf1; - int i, lines; - size_t n0, n1, tem; - int alloc_lines0, alloc_lines1; - int buffered_prefix, prefix_count, prefix_mask; - - slurp (&filevec[0]); - if (filevec[0].desc != filevec[1].desc) - slurp (&filevec[1]); - else - { - filevec[1].buffer = filevec[0].buffer; - filevec[1].bufsize = filevec[0].bufsize; - filevec[1].buffered_chars = filevec[0].buffered_chars; - } - for (i = 0; i < 2; i++) - prepare_text_end (&filevec[i]); - - /* Find identical prefix. */ - - p0 = buffer0 = filevec[0].buffer; - p1 = buffer1 = filevec[1].buffer; - - n0 = filevec[0].buffered_chars; - n1 = filevec[1].buffered_chars; - - if (p0 == p1) - /* The buffers are the same; sentinels won't work. */ - p0 = p1 += n1; - else - { - /* Insert end sentinels, in this case characters that are guaranteed - to make the equality test false, and thus terminate the loop. */ - - if (n0 < n1) - p0[n0] = ~p1[n0]; - else - p1[n1] = ~p0[n1]; - - /* Loop until first mismatch, or to the sentinel characters. */ - - /* Compare a word at a time for speed. */ - w0 = (word *) p0; - w1 = (word *) p1; - while (*w0++ == *w1++) - ; - --w0, --w1; - - /* Do the last few bytes of comparison a byte at a time. */ - p0 = (char *) w0; - p1 = (char *) w1; - while (*p0++ == *p1++) - ; - --p0, --p1; - - /* Don't mistakenly count missing newline as part of prefix. */ - if (ROBUST_OUTPUT_STYLE (output_style) - && (buffer0 + n0 - filevec[0].missing_newline < p0) - != - (buffer1 + n1 - filevec[1].missing_newline < p1)) - --p0, --p1; - } - - /* Now P0 and P1 point at the first nonmatching characters. */ - - /* Skip back to last line-beginning in the prefix, - and then discard up to HORIZON_LINES lines from the prefix. */ - i = horizon_lines; - while (p0 != buffer0 && (p0[-1] != '\n' || i--)) - --p0, --p1; - - /* Record the prefix. */ - filevec[0].prefix_end = p0; - filevec[1].prefix_end = p1; - - /* Find identical suffix. */ - - /* P0 and P1 point beyond the last chars not yet compared. */ - p0 = buffer0 + n0; - p1 = buffer1 + n1; - - if (! ROBUST_OUTPUT_STYLE (output_style) - || filevec[0].missing_newline == filevec[1].missing_newline) - { - end0 = p0; /* Addr of last char in file 0. */ - - /* Get value of P0 at which we should stop scanning backward: - this is when either P0 or P1 points just past the last char - of the identical prefix. */ - beg0 = filevec[0].prefix_end + (n0 < n1 ? 0 : n0 - n1); - - /* Scan back until chars don't match or we reach that point. */ - for (; p0 != beg0; p0--, p1--) - if (*p0 != *p1) - { - /* Point at the first char of the matching suffix. */ - beg0 = p0; - break; - } - - /* Are we at a line-beginning in both files? If not, add the rest of - this line to the main body. Discard up to HORIZON_LINES lines from - the identical suffix. Also, discard one extra line, - because shift_boundaries may need it. */ - i = horizon_lines + !((buffer0 == p0 || p0[-1] == '\n') - && - (buffer1 == p1 || p1[-1] == '\n')); - while (i-- && p0 != end0) - while (*p0++ != '\n') - ; - - p1 += p0 - beg0; - } - - /* Record the suffix. */ - filevec[0].suffix_begin = p0; - filevec[1].suffix_begin = p1; - - /* Calculate number of lines of prefix to save. - - prefix_count == 0 means save the whole prefix; - we need this with for options like -D that output the whole file. - We also need it for options like -F that output some preceding line; - at least we will need to find the last few lines, - but since we don't know how many, it's easiest to find them all. - - Otherwise, prefix_count != 0. Save just prefix_count lines at start - of the line buffer; they'll be moved to the proper location later. - Handle 1 more line than the context says (because we count 1 too many), - rounded up to the next power of 2 to speed index computation. */ - - if (no_diff_means_no_output && ! function_regexp_list) - { - for (prefix_count = 1; prefix_count < context + 1; prefix_count *= 2) - ; - prefix_mask = prefix_count - 1; - alloc_lines0 - = prefix_count - + GUESS_LINES (0, 0, p0 - filevec[0].prefix_end) - + context; - } - else - { - prefix_count = 0; - prefix_mask = ~0; - alloc_lines0 = GUESS_LINES (0, 0, n0); - } - - lines = 0; - linbuf0 = (char const **) xmalloc (alloc_lines0 * sizeof (*linbuf0)); - - /* If the prefix is needed, find the prefix lines. */ - if (! (no_diff_means_no_output - && filevec[0].prefix_end == p0 - && filevec[1].prefix_end == p1)) - { - p0 = buffer0; - end0 = filevec[0].prefix_end; - while (p0 != end0) - { - int l = lines++ & prefix_mask; - if (l == alloc_lines0) - linbuf0 = (char const **) xrealloc (linbuf0, (alloc_lines0 *= 2) - * sizeof(*linbuf0)); - linbuf0[l] = p0; - while (*p0++ != '\n') - ; - } - } - buffered_prefix = prefix_count && context < lines ? context : lines; - - /* Allocate line buffer 1. */ - tem = prefix_count ? filevec[1].suffix_begin - buffer1 : n1; - - alloc_lines1 - = (buffered_prefix - + GUESS_LINES (lines, filevec[1].prefix_end - buffer1, tem) - + context); - linbuf1 = (char const **) xmalloc (alloc_lines1 * sizeof (*linbuf1)); - - if (buffered_prefix != lines) - { - /* Rotate prefix lines to proper location. */ - for (i = 0; i < buffered_prefix; i++) - linbuf1[i] = linbuf0[(lines - context + i) & prefix_mask]; - for (i = 0; i < buffered_prefix; i++) - linbuf0[i] = linbuf1[i]; - } - - /* Initialize line buffer 1 from line buffer 0. */ - for (i = 0; i < buffered_prefix; i++) - linbuf1[i] = linbuf0[i] - buffer0 + buffer1; - - /* Record the line buffer, adjusted so that - linbuf*[0] points at the first differing line. */ - filevec[0].linbuf = linbuf0 + buffered_prefix; - filevec[1].linbuf = linbuf1 + buffered_prefix; - filevec[0].linbuf_base = filevec[1].linbuf_base = - buffered_prefix; - filevec[0].alloc_lines = alloc_lines0 - buffered_prefix; - filevec[1].alloc_lines = alloc_lines1 - buffered_prefix; - filevec[0].prefix_lines = filevec[1].prefix_lines = lines; -} - -/* Largest primes less than some power of two, for nbuckets. Values range - from useful to preposterous. If one of these numbers isn't prime - after all, don't blame it on me, blame it on primes (6) . . . */ -static int const primes[] = -{ - 509, - 1021, - 2039, - 4093, - 8191, - 16381, - 32749, -#if 32767 < INT_MAX - 65521, - 131071, - 262139, - 524287, - 1048573, - 2097143, - 4194301, - 8388593, - 16777213, - 33554393, - 67108859, /* Preposterously large . . . */ - 134217689, - 268435399, - 536870909, - 1073741789, - 2147483647, -#endif - 0 -}; - -/* Given a vector of two file_data objects, read the file associated - with each one, and build the table of equivalence classes. - Return 1 if either file appears to be a binary file. - If PRETEND_BINARY is nonzero, pretend they are binary regardless. */ - -int -read_files (filevec, pretend_binary) - struct file_data filevec[]; - int pretend_binary; -{ - int i; - int skip_test = always_text_flag | pretend_binary; - int appears_binary = pretend_binary | sip (&filevec[0], skip_test); - - if (filevec[0].desc != filevec[1].desc) - appears_binary |= sip (&filevec[1], skip_test | appears_binary); - else - { - filevec[1].buffer = filevec[0].buffer; - filevec[1].bufsize = filevec[0].bufsize; - filevec[1].buffered_chars = filevec[0].buffered_chars; - } - if (appears_binary) - { -#if HAVE_SETMODE - setmode (filevec[0].desc, O_BINARY); - setmode (filevec[1].desc, O_BINARY); -#endif - return 1; - } - - find_identical_ends (filevec); - - equivs_alloc = filevec[0].alloc_lines + filevec[1].alloc_lines + 1; - equivs = (struct equivclass *) xmalloc (equivs_alloc * sizeof (struct equivclass)); - /* Equivalence class 0 is permanently safe for lines that were not - hashed. Real equivalence classes start at 1. */ - equivs_index = 1; - - for (i = 0; primes[i] < equivs_alloc / 3; i++) - if (! primes[i]) - abort (); - nbuckets = primes[i]; - - buckets = (int *) xmalloc ((nbuckets + 1) * sizeof (*buckets)); - bzero (buckets++, (nbuckets + 1) * sizeof (*buckets)); - - for (i = 0; i < 2; i++) - find_and_hash_each_line (&filevec[i]); - - filevec[0].equiv_max = filevec[1].equiv_max = equivs_index; - - free (equivs); - free (buckets - 1); - - return 0; -} diff --git a/contrib/cvs/diff/normal.c b/contrib/cvs/diff/normal.c deleted file mode 100644 index b1f4955..0000000 --- a/contrib/cvs/diff/normal.c +++ /dev/null @@ -1,69 +0,0 @@ -/* Normal-format output routines for GNU DIFF. - Copyright (C) 1988, 1989, 1993, 1998 Free Software Foundation, Inc. - -This file is part of GNU DIFF. - -GNU DIFF is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU DIFF 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. - -*/ - - -#include "diff.h" - -static void print_normal_hunk PARAMS((struct change *)); - -/* Print the edit-script SCRIPT as a normal diff. - INF points to an array of descriptions of the two files. */ - -void -print_normal_script (script) - struct change *script; -{ - print_script (script, find_change, print_normal_hunk); -} - -/* Print a hunk of a normal diff. - This is a contiguous portion of a complete edit script, - describing changes in consecutive lines. */ - -static void -print_normal_hunk (hunk) - struct change *hunk; -{ - int first0, last0, first1, last1, deletes, inserts; - register int i; - - /* Determine range of line numbers involved in each file. */ - analyze_hunk (hunk, &first0, &last0, &first1, &last1, &deletes, &inserts); - if (!deletes && !inserts) - return; - - begin_output (); - - /* Print out the line number header for this hunk */ - print_number_range (',', &files[0], first0, last0); - printf_output ("%c", change_letter (inserts, deletes)); - print_number_range (',', &files[1], first1, last1); - printf_output ("\n"); - - /* Print the lines that the first file has. */ - if (deletes) - for (i = first0; i <= last0; i++) - print_1_line ("<", &files[0].linbuf[i]); - - if (inserts && deletes) - printf_output ("---\n"); - - /* Print the lines that the second file has. */ - if (inserts) - for (i = first1; i <= last1; i++) - print_1_line (">", &files[1].linbuf[i]); -} diff --git a/contrib/cvs/diff/side.c b/contrib/cvs/diff/side.c deleted file mode 100644 index d776e77..0000000 --- a/contrib/cvs/diff/side.c +++ /dev/null @@ -1,294 +0,0 @@ -/* sdiff-format output routines for GNU DIFF. - Copyright (C) 1991, 1992, 1993, 1998 Free Software Foundation, Inc. - -This file is part of GNU DIFF. - -GNU DIFF is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY. No author or distributor -accepts responsibility to anyone for the consequences of using it -or for whether it serves any particular purpose or works at all, -unless he says so in writing. Refer to the GNU DIFF General Public -License for full details. - -Everyone is granted permission to copy, modify and redistribute -GNU DIFF, but only under the conditions described in the -GNU DIFF General Public License. A copy of this license is -supposed to have been given to you along with GNU DIFF so you -can know your rights and responsibilities. It should be in a -file named COPYING. Among other things, the copyright notice -and this notice must be preserved on all copies. */ - - -#include "diff.h" - -static unsigned print_half_line PARAMS((char const * const *, unsigned, unsigned)); -static unsigned tab_from_to PARAMS((unsigned, unsigned)); -static void print_1sdiff_line PARAMS((char const * const *, int, char const * const *)); -static void print_sdiff_common_lines PARAMS((int, int)); -static void print_sdiff_hunk PARAMS((struct change *)); - -/* Next line number to be printed in the two input files. */ -static int next0, next1; - -/* Print the edit-script SCRIPT as a sdiff style output. */ - -void -print_sdiff_script (script) - struct change *script; -{ - begin_output (); - - next0 = next1 = - files[0].prefix_lines; - print_script (script, find_change, print_sdiff_hunk); - - print_sdiff_common_lines (files[0].valid_lines, files[1].valid_lines); -} - -/* Tab from column FROM to column TO, where FROM <= TO. Yield TO. */ - -static unsigned -tab_from_to (from, to) - unsigned from, to; -{ - unsigned tab; - - if (! tab_expand_flag) - for (tab = from + TAB_WIDTH - from % TAB_WIDTH; tab <= to; tab += TAB_WIDTH) - { - write_output ("\t", 1); - from = tab; - } - while (from++ < to) - write_output (" ", 1); - return to; -} - -/* - * Print the text for half an sdiff line. This means truncate to width - * observing tabs, and trim a trailing newline. Returns the last column - * written (not the number of chars). - */ -static unsigned -print_half_line (line, indent, out_bound) - char const * const *line; - unsigned indent, out_bound; -{ - register unsigned in_position = 0, out_position = 0; - register char const - *text_pointer = line[0], - *text_limit = line[1]; - - while (text_pointer < text_limit) - { - register unsigned char c = *text_pointer++; - /* We use CC to avoid taking the address of the register - variable C. */ - char cc; - - switch (c) - { - case '\t': - { - unsigned spaces = TAB_WIDTH - in_position % TAB_WIDTH; - if (in_position == out_position) - { - unsigned tabstop = out_position + spaces; - if (tab_expand_flag) - { - if (out_bound < tabstop) - tabstop = out_bound; - for (; out_position < tabstop; out_position++) - write_output (" ", 1); - } - else - if (tabstop < out_bound) - { - out_position = tabstop; - cc = c; - write_output (&cc, 1); - } - } - in_position += spaces; - } - break; - - case '\r': - { - cc = c; - write_output (&cc, 1); - tab_from_to (0, indent); - in_position = out_position = 0; - } - break; - - case '\b': - if (in_position != 0 && --in_position < out_bound) - if (out_position <= in_position) - /* Add spaces to make up for suppressed tab past out_bound. */ - for (; out_position < in_position; out_position++) - write_output (" ", 1); - else - { - out_position = in_position; - cc = c; - write_output (&cc, 1); - } - break; - - case '\f': - case '\v': - control_char: - if (in_position < out_bound) - { - cc = c; - write_output (&cc, 1); - } - break; - - default: - if (! ISPRINT (c)) - goto control_char; - /* falls through */ - case ' ': - if (in_position++ < out_bound) - { - out_position = in_position; - cc = c; - write_output (&cc, 1); - } - break; - - case '\n': - return out_position; - } - } - - return out_position; -} - -/* - * Print side by side lines with a separator in the middle. - * 0 parameters are taken to indicate white space text. - * Blank lines that can easily be caught are reduced to a single newline. - */ - -static void -print_1sdiff_line (left, sep, right) - char const * const *left; - int sep; - char const * const *right; -{ - unsigned hw = sdiff_half_width, c2o = sdiff_column2_offset; - unsigned col = 0; - int put_newline = 0; - - if (left) - { - if (left[1][-1] == '\n') - put_newline = 1; - col = print_half_line (left, 0, hw); - } - - if (sep != ' ') - { - char cc; - - col = tab_from_to (col, (hw + c2o - 1) / 2) + 1; - if (sep == '|' && put_newline != (right[1][-1] == '\n')) - sep = put_newline ? '/' : '\\'; - cc = sep; - write_output (&cc, 1); - } - - if (right) - { - if (right[1][-1] == '\n') - put_newline = 1; - if (**right != '\n') - { - col = tab_from_to (col, c2o); - print_half_line (right, col, hw); - } - } - - if (put_newline) - write_output ("\n", 1); -} - -/* Print lines common to both files in side-by-side format. */ -static void -print_sdiff_common_lines (limit0, limit1) - int limit0, limit1; -{ - int i0 = next0, i1 = next1; - - if (! sdiff_skip_common_lines && (i0 != limit0 || i1 != limit1)) - { - if (sdiff_help_sdiff) - printf_output ("i%d,%d\n", limit0 - i0, limit1 - i1); - - if (! sdiff_left_only) - { - while (i0 != limit0 && i1 != limit1) - print_1sdiff_line (&files[0].linbuf[i0++], ' ', &files[1].linbuf[i1++]); - while (i1 != limit1) - print_1sdiff_line (0, ')', &files[1].linbuf[i1++]); - } - while (i0 != limit0) - print_1sdiff_line (&files[0].linbuf[i0++], '(', 0); - } - - next0 = limit0; - next1 = limit1; -} - -/* Print a hunk of an sdiff diff. - This is a contiguous portion of a complete edit script, - describing changes in consecutive lines. */ - -static void -print_sdiff_hunk (hunk) - struct change *hunk; -{ - int first0, last0, first1, last1, deletes, inserts; - register int i, j; - - /* Determine range of line numbers involved in each file. */ - analyze_hunk (hunk, &first0, &last0, &first1, &last1, &deletes, &inserts); - if (!deletes && !inserts) - return; - - /* Print out lines up to this change. */ - print_sdiff_common_lines (first0, first1); - - if (sdiff_help_sdiff) - printf_output ("c%d,%d\n", last0 - first0 + 1, last1 - first1 + 1); - - /* Print ``xxx | xxx '' lines */ - if (inserts && deletes) - { - for (i = first0, j = first1; i <= last0 && j <= last1; ++i, ++j) - print_1sdiff_line (&files[0].linbuf[i], '|', &files[1].linbuf[j]); - deletes = i <= last0; - inserts = j <= last1; - next0 = first0 = i; - next1 = first1 = j; - } - - - /* Print `` > xxx '' lines */ - if (inserts) - { - for (j = first1; j <= last1; ++j) - print_1sdiff_line (0, '>', &files[1].linbuf[j]); - next1 = j; - } - - /* Print ``xxx < '' lines */ - if (deletes) - { - for (i = first0; i <= last0; ++i) - print_1sdiff_line (&files[0].linbuf[i], '<', 0); - next0 = i; - } -} diff --git a/contrib/cvs/diff/system.h b/contrib/cvs/diff/system.h deleted file mode 100644 index d383ea1..0000000 --- a/contrib/cvs/diff/system.h +++ /dev/null @@ -1,304 +0,0 @@ -/* System dependent declarations. - Copyright (C) 1988, 1989, 1992, 1993, 1994 Free Software Foundation, Inc. - -This file is part of GNU DIFF. - -GNU DIFF is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU DIFF 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. - -*/ - -/* We must define `volatile' and `const' first (the latter inside config.h), - so that they're used consistently in all system includes. */ -#if !__STDC__ -#ifndef volatile -#define volatile -#endif -#endif -#include - -#include -#include - -/* Note that PARAMS is just internal to the diff library; diffrun.h - has its own mechanism, which will hopefully be less likely to - conflict with the library's caller's namespace. */ -#if __STDC__ -#define PARAMS(args) args -#define VOID void -#else -#define PARAMS(args) () -#define VOID char -#endif - -#if STAT_MACROS_BROKEN -#undef S_ISBLK -#undef S_ISCHR -#undef S_ISDIR -#undef S_ISFIFO -#undef S_ISREG -#undef S_ISSOCK -#endif -#ifndef S_ISDIR -#define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR) -#endif -#ifndef S_ISREG -#define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG) -#endif -#if !defined(S_ISBLK) && defined(S_IFBLK) -#define S_ISBLK(mode) (((mode) & S_IFMT) == S_IFBLK) -#endif -#if !defined(S_ISCHR) && defined(S_IFCHR) -#define S_ISCHR(mode) (((mode) & S_IFMT) == S_IFCHR) -#endif -#if !defined(S_ISFIFO) && defined(S_IFFIFO) -#define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFFIFO) -#endif - -#ifndef S_ISSOCK -# if defined( S_IFSOCK ) -# ifdef S_IFMT -# define S_ISSOCK(mode) (((mode) & S_IFMT) == S_IFSOCK) -# else -# define S_ISSOCK(mode) ((mode) & S_IFSOCK) -# endif /* S_IFMT */ -# elif defined( S_ISNAM ) - /* SCO OpenServer 5.0.6a */ -# define S_ISSOCK S_ISNAM -# endif /* !S_IFSOCK && S_ISNAM */ -#endif /* !S_ISSOCK */ - -#if HAVE_UNISTD_H -#include -#endif - -#ifdef HAVE_IO_H -# include -#endif - -#ifdef HAVE_FCNTL_H -# include -#else -# include -#endif - -#ifndef SEEK_SET -#define SEEK_SET 0 -#endif -#ifndef SEEK_CUR -#define SEEK_CUR 1 -#endif - -#ifndef STDIN_FILENO -#define STDIN_FILENO 0 -#endif -#ifndef STDOUT_FILENO -#define STDOUT_FILENO 1 -#endif -#ifndef STDERR_FILENO -#define STDERR_FILENO 2 -#endif - -/* I believe that all relevant systems have - time.h. It is in ANSI, for example. The - code below looks quite bogus as I don't think - sys/time.h is ever a substitute for time.h; - it is something different. */ -#define HAVE_TIME_H 1 - -#if HAVE_TIME_H -#include -#else -#include -#endif - -#if HAVE_FCNTL_H -#include -#else -#if HAVE_SYS_FILE_H -#include -#endif -#endif - -#ifndef O_RDONLY -#define O_RDONLY 0 -#endif - -#if HAVE_SYS_WAIT_H -#include -#endif -#ifndef WEXITSTATUS -#define WEXITSTATUS(stat_val) ((unsigned) (stat_val) >> 8) -#endif -#ifndef WIFEXITED -#define WIFEXITED(stat_val) (((stat_val) & 255) == 0) -#endif - -#ifndef STAT_BLOCKSIZE -#if HAVE_STRUCT_STAT_ST_BLKSIZE -#define STAT_BLOCKSIZE(s) (s).st_blksize -#else -#define STAT_BLOCKSIZE(s) (8 * 1024) -#endif -#endif - -#if HAVE_DIRENT_H -# include -# define NAMLEN(dirent) strlen((dirent)->d_name) -#else -# define dirent direct -# define NAMLEN(dirent) ((dirent)->d_namlen) -# if HAVE_SYS_NDIR_H -# include -# endif -# if HAVE_SYS_DIR_H -# include -# endif -# if HAVE_NDIR_H -# include -# endif -#endif - -#if HAVE_VFORK_H -#include -#endif - -#if HAVE_STDLIB_H || defined(STDC_HEADERS) -#include -#else -VOID *malloc (); -VOID *realloc (); -#endif -#ifndef getenv -char *getenv (); -#endif - -#if HAVE_LIMITS_H -#include -#endif -#ifndef INT_MAX -#define INT_MAX 2147483647 -#endif -#ifndef CHAR_BIT -#define CHAR_BIT 8 -#endif - -#if STDC_HEADERS || HAVE_STRING_H -# include -# ifndef bzero -# define bzero(s, n) memset (s, 0, n) -# endif -#else -# if !HAVE_STRCHR -# define strchr index -# define strrchr rindex -# endif -char *strchr (), *strrchr (); -# if !HAVE_MEMCHR -# define memcmp(s1, s2, n) bcmp (s1, s2, n) -# define memcpy(d, s, n) bcopy (s, d, n) -void *memchr (); -# endif -#endif - -#include -/* CTYPE_DOMAIN (C) is nonzero if the unsigned char C can safely be given - as an argument to macros like `isspace'. */ -#if STDC_HEADERS -#define CTYPE_DOMAIN(c) 1 -#else -#define CTYPE_DOMAIN(c) ((unsigned) (c) <= 0177) -#endif -#ifndef ISPRINT -#define ISPRINT(c) (CTYPE_DOMAIN (c) && isprint (c)) -#endif -#ifndef ISSPACE -#define ISSPACE(c) (CTYPE_DOMAIN (c) && isspace (c)) -#endif -#ifndef ISUPPER -#define ISUPPER(c) (CTYPE_DOMAIN (c) && isupper (c)) -#endif - -#ifndef ISDIGIT -#define ISDIGIT(c) ((unsigned) (c) - '0' <= 9) -#endif - -#include -#if !STDC_HEADERS -extern int errno; -#endif - -#ifdef min -#undef min -#endif -#ifdef max -#undef max -#endif -#define min(a,b) ((a) <= (b) ? (a) : (b)) -#define max(a,b) ((a) >= (b) ? (a) : (b)) - -/* This section contains Posix-compliant defaults for macros - that are meant to be overridden by hand in config.h as needed. */ - -#ifndef filename_cmp -#define filename_cmp(a, b) strcmp (a, b) -#endif - -#ifndef filename_lastdirchar -#define filename_lastdirchar(filename) strrchr (filename, '/') -#endif - -#ifndef HAVE_FORK -#define HAVE_FORK 1 -#endif - -#ifndef HAVE_SETMODE -#define HAVE_SETMODE 0 -#endif - -#ifndef initialize_main -#define initialize_main(argcp, argvp) -#endif - -/* Do struct stat *S, *T describe the same file? Answer -1 if unknown. */ -#ifndef same_file -#define same_file(s,t) ((s)->st_ino==(t)->st_ino && (s)->st_dev==(t)->st_dev) -#endif - -/* Place into Q a quoted version of A suitable for `popen' or `system', - incrementing Q and junking A. - Do not increment Q by more than 4 * strlen (A) + 2. */ -#ifndef SYSTEM_QUOTE_ARG -#define SYSTEM_QUOTE_ARG(q, a) \ - { \ - *(q)++ = '\''; \ - for (; *(a); *(q)++ = *(a)++) \ - if (*(a) == '\'') \ - { \ - *(q)++ = '\''; \ - *(q)++ = '\\'; \ - *(q)++ = '\''; \ - } \ - *(q)++ = '\''; \ - } -#endif - -/* these come from CVS's lib/system.h, but I wasn't sure how to include that - * properly or even if I really should - */ -#ifndef CVS_OPENDIR -#define CVS_OPENDIR opendir -#endif -#ifndef CVS_READDIR -#define CVS_READDIR readdir -#endif -#ifndef CVS_CLOSEDIR -#define CVS_CLOSEDIR closedir -#endif diff --git a/contrib/cvs/diff/util.c b/contrib/cvs/diff/util.c deleted file mode 100644 index 744cf51..0000000 --- a/contrib/cvs/diff/util.c +++ /dev/null @@ -1,849 +0,0 @@ -/* Support routines for GNU DIFF. - Copyright (C) 1988, 1989, 1992, 1993, 1994, 1997, 1998 Free Software Foundation, Inc. - -This file is part of GNU DIFF. - -GNU DIFF is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU DIFF 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. - -*/ - -#include "diff.h" - -#if __STDC__ -#include -#else -#include -#endif - -#ifndef strerror -extern char *strerror (); -#endif - -/* Queue up one-line messages to be printed at the end, - when -l is specified. Each message is recorded with a `struct msg'. */ - -struct msg -{ - struct msg *next; - char const *format; - char const *arg1; - char const *arg2; - char const *arg3; - char const *arg4; -}; - -/* Head of the chain of queues messages. */ - -static struct msg *msg_chain; - -/* Tail of the chain of queues messages. */ - -static struct msg **msg_chain_end = &msg_chain; - -/* Use when a system call returns non-zero status. - TEXT should normally be the file name. */ - -void -perror_with_name (text) - char const *text; -{ - int e = errno; - - if (callbacks && callbacks->error) - (*callbacks->error) ("%s: %s", text, strerror (e)); - else - { - fprintf (stderr, "%s: ", diff_program_name); - errno = e; - perror (text); - } -} - -/* Use when a system call returns non-zero status and that is fatal. */ - -void -pfatal_with_name (text) - char const *text; -{ - int e = errno; - print_message_queue (); - if (callbacks && callbacks->error) - (*callbacks->error) ("%s: %s", text, strerror (e)); - else - { - fprintf (stderr, "%s: ", diff_program_name); - errno = e; - perror (text); - } - DIFF_ABORT (2); -} - -/* Print an error message from the format-string FORMAT - with args ARG1 and ARG2. */ - -void -diff_error (format, arg, arg1) - char const *format, *arg, *arg1; -{ - if (callbacks && callbacks->error) - (*callbacks->error) (format, arg, arg1); - else - { - fprintf (stderr, "%s: ", diff_program_name); - fprintf (stderr, format, arg, arg1); - fprintf (stderr, "\n"); - } -} - -/* Print an error message containing the string TEXT, then exit. */ - -void -fatal (m) - char const *m; -{ - print_message_queue (); - diff_error ("%s", m, 0); - DIFF_ABORT (2); -} - -/* Like printf, except if -l in effect then save the message and print later. - This is used for things like "binary files differ" and "Only in ...". */ - -void -message (format, arg1, arg2) - char const *format, *arg1, *arg2; -{ - message5 (format, arg1, arg2, 0, 0); -} - -void -message5 (format, arg1, arg2, arg3, arg4) - char const *format, *arg1, *arg2, *arg3, *arg4; -{ - if (paginate_flag) - { - struct msg *new = (struct msg *) xmalloc (sizeof (struct msg)); - new->format = format; - new->arg1 = concat (arg1, "", ""); - new->arg2 = concat (arg2, "", ""); - new->arg3 = arg3 ? concat (arg3, "", "") : 0; - new->arg4 = arg4 ? concat (arg4, "", "") : 0; - new->next = 0; - *msg_chain_end = new; - msg_chain_end = &new->next; - } - else - { - if (sdiff_help_sdiff) - write_output (" ", 1); - printf_output (format, arg1, arg2, arg3, arg4); - } -} - -/* Output all the messages that were saved up by calls to `message'. */ - -void -print_message_queue () -{ - struct msg *m; - - for (m = msg_chain; m; m = m->next) - printf_output (m->format, m->arg1, m->arg2, m->arg3, m->arg4); -} - -/* Call before outputting the results of comparing files NAME0 and NAME1 - to set up OUTFILE, the stdio stream for the output to go to. - - Usually, OUTFILE is just stdout. But when -l was specified - we fork off a `pr' and make OUTFILE a pipe to it. - `pr' then outputs to our stdout. */ - -static char const *current_name0; -static char const *current_name1; -static int current_depth; - -static int output_in_progress = 0; - -void -setup_output (name0, name1, depth) - char const *name0, *name1; - int depth; -{ - current_name0 = name0; - current_name1 = name1; - current_depth = depth; -} - -#if HAVE_FORK && defined (PR_PROGRAM) -static pid_t pr_pid; -#endif - -void -begin_output () -{ - char *name; - - if (output_in_progress) - return; - output_in_progress = 1; - - /* Construct the header of this piece of diff. */ - name = xmalloc (strlen (current_name0) + strlen (current_name1) - + strlen (switch_string) + 7); - /* Posix.2 section 4.17.6.1.1 specifies this format. But there is a - bug in the first printing (IEEE Std 1003.2-1992 p 251 l 3304): - it says that we must print only the last component of the pathnames. - This requirement is silly and does not match historical practice. */ - sprintf (name, "diff%s %s %s", switch_string, current_name0, current_name1); - - if (paginate_flag && callbacks && callbacks->write_output) - fatal ("can't paginate when using library callbacks"); - - if (paginate_flag) - { - /* Make OUTFILE a pipe to a subsidiary `pr'. */ - -#ifdef PR_PROGRAM - -# if HAVE_FORK - int pipes[2]; - - if (pipe (pipes) != 0) - pfatal_with_name ("pipe"); - - fflush (stdout); - - pr_pid = vfork (); - if (pr_pid < 0) - pfatal_with_name ("vfork"); - - if (pr_pid == 0) - { - close (pipes[1]); - if (pipes[0] != STDIN_FILENO) - { - if (dup2 (pipes[0], STDIN_FILENO) < 0) - pfatal_with_name ("dup2"); - close (pipes[0]); - } - - execl (PR_PROGRAM, PR_PROGRAM, "-f", "-h", name, 0); - pfatal_with_name (PR_PROGRAM); - } - else - { - close (pipes[0]); - outfile = fdopen (pipes[1], "w"); - if (!outfile) - pfatal_with_name ("fdopen"); - } -# else /* ! HAVE_FORK */ - char *command = xmalloc (4 * strlen (name) + strlen (PR_PROGRAM) + 10); - char *p; - char const *a = name; - sprintf (command, "%s -f -h ", PR_PROGRAM); - p = command + strlen (command); - SYSTEM_QUOTE_ARG (p, a); - *p = 0; - outfile = popen (command, "w"); - if (!outfile) - pfatal_with_name (command); - free (command); -# endif /* ! HAVE_FORK */ -#else - fatal ("This port does not support the --paginate option to diff."); -#endif - } - else - { - - /* If -l was not specified, output the diff straight to `stdout'. */ - - /* If handling multiple files (because scanning a directory), - print which files the following output is about. */ - if (current_depth > 0) - printf_output ("%s\n", name); - } - - free (name); - - /* A special header is needed at the beginning of context output. */ - switch (output_style) - { - case OUTPUT_CONTEXT: - print_context_header (files, 0); - break; - - case OUTPUT_UNIFIED: - print_context_header (files, 1); - break; - - default: - break; - } -} - -/* Call after the end of output of diffs for one file. - If -l was given, close OUTFILE and get rid of the `pr' subfork. */ - -void -finish_output () -{ - if (paginate_flag && outfile != 0 && outfile != stdout) - { -#ifdef PR_PROGRAM - int wstatus, w; - if (ferror (outfile)) - fatal ("write error"); -# if ! HAVE_FORK - wstatus = pclose (outfile); -# else /* HAVE_FORK */ - if (fclose (outfile) != 0) - pfatal_with_name ("write error"); - while ((w = waitpid (pr_pid, &wstatus, 0)) < 0 && errno == EINTR) - ; - if (w < 0) - pfatal_with_name ("waitpid"); -# endif /* HAVE_FORK */ - if (wstatus != 0) - fatal ("subsidiary pr failed"); -#else - fatal ("internal error in finish_output"); -#endif - } - - output_in_progress = 0; -} - -/* Write something to the output file. */ - -void -write_output (text, len) - char const *text; - size_t len; -{ - if (callbacks && callbacks->write_output) - (*callbacks->write_output) (text, len); - else if (len == 1) - putc (*text, outfile); - else - fwrite (text, sizeof (char), len, outfile); -} - -/* Printf something to the output file. */ - -#if __STDC__ -#define VA_START(args, lastarg) va_start(args, lastarg) -#else /* ! __STDC__ */ -#define VA_START(args, lastarg) va_start(args) -#endif /* __STDC__ */ - -void -#if __STDC__ -printf_output (const char *format, ...) -#else -printf_output (format, va_alist) - char const *format; - va_dcl -#endif -{ - va_list args; - - VA_START (args, format); - if (callbacks && callbacks->write_output) - { - /* We implement our own limited printf-like functionality (%s, %d, - and %c only). Callers who want something fancier can use - sprintf. */ - const char *p = format; - char *q; - char *str; - int num; - int ch; - char buf[100]; - - while ((q = strchr (p, '%')) != NULL) - { - static const char msg[] = - "\ninternal error: bad % in printf_output\n"; - (*callbacks->write_output) (p, q - p); - - switch (q[1]) - { - case 's': - str = va_arg (args, char *); - (*callbacks->write_output) (str, strlen (str)); - break; - case 'd': - num = va_arg (args, int); - sprintf (buf, "%d", num); - (*callbacks->write_output) (buf, strlen (buf)); - break; - case 'c': - ch = va_arg (args, int); - buf[0] = ch; - (*callbacks->write_output) (buf, 1); - break; - default: - (*callbacks->write_output) (msg, sizeof (msg) - 1); - /* Don't just keep going, because q + 1 might point to the - terminating '\0'. */ - goto out; - } - p = q + 2; - } - (*callbacks->write_output) (p, strlen (p)); - } - else - vfprintf (outfile, format, args); - out: - va_end (args); -} - -/* Flush the output file. */ - -void -flush_output () -{ - if (callbacks && callbacks->flush_output) - (*callbacks->flush_output) (); - else - fflush (outfile); -} - -/* Compare two lines (typically one from each input file) - according to the command line options. - For efficiency, this is invoked only when the lines do not match exactly - but an option like -i might cause us to ignore the difference. - Return nonzero if the lines differ. */ - -int -line_cmp (s1, s2) - char const *s1, *s2; -{ - register unsigned char const *t1 = (unsigned char const *) s1; - register unsigned char const *t2 = (unsigned char const *) s2; - - while (1) - { - register unsigned char c1 = *t1++; - register unsigned char c2 = *t2++; - - /* Test for exact char equality first, since it's a common case. */ - if (c1 != c2) - { - /* Ignore horizontal white space if -b or -w is specified. */ - - if (ignore_all_space_flag) - { - /* For -w, just skip past any white space. */ - while (ISSPACE (c1) && c1 != '\n') c1 = *t1++; - while (ISSPACE (c2) && c2 != '\n') c2 = *t2++; - } - else if (ignore_space_change_flag) - { - /* For -b, advance past any sequence of white space in line 1 - and consider it just one Space, or nothing at all - if it is at the end of the line. */ - if (ISSPACE (c1)) - { - while (c1 != '\n') - { - c1 = *t1++; - if (! ISSPACE (c1)) - { - --t1; - c1 = ' '; - break; - } - } - } - - /* Likewise for line 2. */ - if (ISSPACE (c2)) - { - while (c2 != '\n') - { - c2 = *t2++; - if (! ISSPACE (c2)) - { - --t2; - c2 = ' '; - break; - } - } - } - - if (c1 != c2) - { - /* If we went too far when doing the simple test - for equality, go back to the first non-white-space - character in both sides and try again. */ - if (c2 == ' ' && c1 != '\n' - && (unsigned char const *) s1 + 1 < t1 - && ISSPACE(t1[-2])) - { - --t1; - continue; - } - if (c1 == ' ' && c2 != '\n' - && (unsigned char const *) s2 + 1 < t2 - && ISSPACE(t2[-2])) - { - --t2; - continue; - } - } - } - - /* Lowercase all letters if -i is specified. */ - - if (ignore_case_flag) - { - if (ISUPPER (c1)) - c1 = tolower (c1); - if (ISUPPER (c2)) - c2 = tolower (c2); - } - - if (c1 != c2) - break; - } - if (c1 == '\n') - return 0; - } - - return (1); -} - -/* Find the consecutive changes at the start of the script START. - Return the last link before the first gap. */ - -struct change * -find_change (start) - struct change *start; -{ - return start; -} - -struct change * -find_reverse_change (start) - struct change *start; -{ - return start; -} - -/* Divide SCRIPT into pieces by calling HUNKFUN and - print each piece with PRINTFUN. - Both functions take one arg, an edit script. - - HUNKFUN is called with the tail of the script - and returns the last link that belongs together with the start - of the tail. - - PRINTFUN takes a subscript which belongs together (with a null - link at the end) and prints it. */ - -void -print_script (script, hunkfun, printfun) - struct change *script; - struct change * (*hunkfun) PARAMS((struct change *)); - void (*printfun) PARAMS((struct change *)); -{ - struct change *next = script; - - while (next) - { - struct change *this, *end; - - /* Find a set of changes that belong together. */ - this = next; - end = (*hunkfun) (next); - - /* Disconnect them from the rest of the changes, - making them a hunk, and remember the rest for next iteration. */ - next = end->link; - end->link = 0; -#ifdef DEBUG - debug_script (this); -#endif - - /* Print this hunk. */ - (*printfun) (this); - - /* Reconnect the script so it will all be freed properly. */ - end->link = next; - } -} - -/* Print the text of a single line LINE, - flagging it with the characters in LINE_FLAG (which say whether - the line is inserted, deleted, changed, etc.). */ - -void -print_1_line (line_flag, line) - char const *line_flag; - char const * const *line; -{ - char const *text = line[0], *limit = line[1]; /* Help the compiler. */ - char const *flag_format = 0; - - /* If -T was specified, use a Tab between the line-flag and the text. - Otherwise use a Space (as Unix diff does). - Print neither space nor tab if line-flags are empty. */ - - if (line_flag && *line_flag) - { - flag_format = tab_align_flag ? "%s\t" : "%s "; - printf_output (flag_format, line_flag); - } - - output_1_line (text, limit, flag_format, line_flag); - - if ((!line_flag || line_flag[0]) && limit[-1] != '\n') - printf_output ("\n\\ No newline at end of file\n"); -} - -/* Output a line from TEXT up to LIMIT. Without -t, output verbatim. - With -t, expand white space characters to spaces, and if FLAG_FORMAT - is nonzero, output it with argument LINE_FLAG after every - internal carriage return, so that tab stops continue to line up. */ - -void -output_1_line (text, limit, flag_format, line_flag) - char const *text, *limit, *flag_format, *line_flag; -{ - if (!tab_expand_flag) - write_output (text, limit - text); - else - { - register unsigned char c; - register char const *t = text; - register unsigned column = 0; - /* CC is used to avoid taking the address of the register - variable C. */ - char cc; - - while (t < limit) - switch ((c = *t++)) - { - case '\t': - { - unsigned spaces = TAB_WIDTH - column % TAB_WIDTH; - column += spaces; - do - write_output (" ", 1); - while (--spaces); - } - break; - - case '\r': - write_output ("\r", 1); - if (flag_format && t < limit && *t != '\n') - printf_output (flag_format, line_flag); - column = 0; - break; - - case '\b': - if (column == 0) - continue; - column--; - write_output ("\b", 1); - break; - - default: - if (ISPRINT (c)) - column++; - cc = c; - write_output (&cc, 1); - break; - } - } -} - -int -change_letter (inserts, deletes) - int inserts, deletes; -{ - if (!inserts) - return 'd'; - else if (!deletes) - return 'a'; - else - return 'c'; -} - -/* Translate an internal line number (an index into diff's table of lines) - into an actual line number in the input file. - The internal line number is LNUM. FILE points to the data on the file. - - Internal line numbers count from 0 starting after the prefix. - Actual line numbers count from 1 within the entire file. */ - -int -translate_line_number (file, lnum) - struct file_data const *file; - int lnum; -{ - return lnum + file->prefix_lines + 1; -} - -void -translate_range (file, a, b, aptr, bptr) - struct file_data const *file; - int a, b; - int *aptr, *bptr; -{ - *aptr = translate_line_number (file, a - 1) + 1; - *bptr = translate_line_number (file, b + 1) - 1; -} - -/* Print a pair of line numbers with SEPCHAR, translated for file FILE. - If the two numbers are identical, print just one number. - - Args A and B are internal line numbers. - We print the translated (real) line numbers. */ - -void -print_number_range (sepchar, file, a, b) - int sepchar; - struct file_data *file; - int a, b; -{ - int trans_a, trans_b; - translate_range (file, a, b, &trans_a, &trans_b); - - /* Note: we can have B < A in the case of a range of no lines. - In this case, we should print the line number before the range, - which is B. */ - if (trans_b > trans_a) - printf_output ("%d%c%d", trans_a, sepchar, trans_b); - else - printf_output ("%d", trans_b); -} - -/* Look at a hunk of edit script and report the range of lines in each file - that it applies to. HUNK is the start of the hunk, which is a chain - of `struct change'. The first and last line numbers of file 0 are stored in - *FIRST0 and *LAST0, and likewise for file 1 in *FIRST1 and *LAST1. - Note that these are internal line numbers that count from 0. - - If no lines from file 0 are deleted, then FIRST0 is LAST0+1. - - Also set *DELETES nonzero if any lines of file 0 are deleted - and set *INSERTS nonzero if any lines of file 1 are inserted. - If only ignorable lines are inserted or deleted, both are - set to 0. */ - -void -analyze_hunk (hunk, first0, last0, first1, last1, deletes, inserts) - struct change *hunk; - int *first0, *last0, *first1, *last1; - int *deletes, *inserts; -{ - int l0, l1, show_from, show_to; - int i; - int trivial = ignore_blank_lines_flag || ignore_regexp_list; - struct change *next; - - show_from = show_to = 0; - - *first0 = hunk->line0; - *first1 = hunk->line1; - - next = hunk; - do - { - l0 = next->line0 + next->deleted - 1; - l1 = next->line1 + next->inserted - 1; - show_from += next->deleted; - show_to += next->inserted; - - for (i = next->line0; i <= l0 && trivial; i++) - if (!ignore_blank_lines_flag || files[0].linbuf[i][0] != '\n') - { - struct regexp_list *r; - char const *line = files[0].linbuf[i]; - int len = files[0].linbuf[i + 1] - line; - - for (r = ignore_regexp_list; r; r = r->next) - if (0 <= re_search (&r->buf, line, len, 0, len, 0)) - break; /* Found a match. Ignore this line. */ - /* If we got all the way through the regexp list without - finding a match, then it's nontrivial. */ - if (!r) - trivial = 0; - } - - for (i = next->line1; i <= l1 && trivial; i++) - if (!ignore_blank_lines_flag || files[1].linbuf[i][0] != '\n') - { - struct regexp_list *r; - char const *line = files[1].linbuf[i]; - int len = files[1].linbuf[i + 1] - line; - - for (r = ignore_regexp_list; r; r = r->next) - if (0 <= re_search (&r->buf, line, len, 0, len, 0)) - break; /* Found a match. Ignore this line. */ - /* If we got all the way through the regexp list without - finding a match, then it's nontrivial. */ - if (!r) - trivial = 0; - } - } - while ((next = next->link) != 0); - - *last0 = l0; - *last1 = l1; - - /* If all inserted or deleted lines are ignorable, - tell the caller to ignore this hunk. */ - - if (trivial) - show_from = show_to = 0; - - *deletes = show_from; - *inserts = show_to; -} - -/* Concatenate three strings, returning a newly malloc'd string. */ - -char * -concat (s1, s2, s3) - char const *s1, *s2, *s3; -{ - size_t len = strlen (s1) + strlen (s2) + strlen (s3); - char *new = xmalloc (len + 1); - sprintf (new, "%s%s%s", s1, s2, s3); - return new; -} - -/* Yield the newly malloc'd pathname - of the file in DIR whose filename is FILE. */ - -char * -dir_file_pathname (dir, file) - char const *dir, *file; -{ - char const *p = filename_lastdirchar (dir); - return concat (dir, "/" + (p && !p[1]), file); -} - -void -debug_script (sp) - struct change *sp; -{ - fflush (stdout); - for (; sp; sp = sp->link) - fprintf (stderr, "%3d %3d delete %d insert %d\n", - sp->line0, sp->line1, sp->deleted, sp->inserted); - fflush (stderr); -} diff --git a/contrib/cvs/diff/version.c b/contrib/cvs/diff/version.c deleted file mode 100644 index 343a098..0000000 --- a/contrib/cvs/diff/version.c +++ /dev/null @@ -1,5 +0,0 @@ -/* Version number of GNU diff. */ - -#include - -char const diff_version_string[] = "2.7"; diff --git a/contrib/cvs/doc/ChangeLog b/contrib/cvs/doc/ChangeLog deleted file mode 100644 index e00073b..0000000 --- a/contrib/cvs/doc/ChangeLog +++ /dev/null @@ -1,4762 +0,0 @@ -2008-03-10 Mark D. Baushke - - * cvs.texinfo (config): Document the IgnoreUnknownConfigKeys - option. - -2008-01-27 Mark D. Baushke - - * cvs.texinfo: Document use of --with-ssh flag to configure and - how :extssh: uses the CVS_SSH environment variable or "ssh". - * stamp-vti, version.texi: Regenerated. - - * cvs.texinfo: Update copyright for 2008. - -2008-01-24 Mark D. Baushke - - * cvs.texinfo (log options): Document the new cvs log -n - switch to reverse the -N switch. - * cvs.texinfo (annotate & rannotate): Document "blame" as a - synonym for the "annotate" command. - (Patch suggested by "David O'Brien" ) - - * cvs.1, stamp-1, stamp-vti, version-client.texi, version.texi: - Regenerated. - -2007-05-07 Derek Price - - * cvsclient.text: Remove references to remote `init' command. - -2006-08-25 Derek Price - - * cvsclient.texi (Requests, Responses): Remove reference to the - obsolete checkin & update programs. - -2006-08-21 Derek Price - - * cvs.texinfo (man page nodes): Tweak grammar, especially refs. - (Original patch from Kevin R. Bulgrien .) - - * mkman.pl (do_keyword): Process ref and p?xref differently. - (Original patch from Kevin R. Bulgrien .) - -2006-08-11 Mark D. Baushke - - * cvs.texinfo, cvsclient.texi: Fix some typos. - (inspired by Ralf Wildenhues ) - -2006-07-16 Derek Price - - * cvs.texinfo (File permissions): Correct punctuation. - -2006-07-11 Larry Jones - - * cvs.texinfo (log options): -b is a revision selection option, not - a header field option. - -2006-06-22 Larry Jones - - * cvs.texinfo (user-defined logging, Informing others): Remove - references to the obsolete -i module option. - -2006-06-08 Derek Price - - * cvsclient.texi (Requests): Add Empty-conflicts. - -2006-03-20 Mark D. Baushke - - [patch #4965] - * cvs.texinfo (Sticky tags, Merging and keywords) - (checkout options, update options): The -A switch - does not reset sticky -k options on modified files. - * cvs.1, stamp-1, stamp-vti, version.texi: Regenerated. - -2006-02-28 Derek Price - - * cvs.texinfo (Editing administrative files): Import changes from Wiki. - -2005-12-09 Derek Price - - [patch #4634] - * cvsclient.texi (Root request): Clarify. - -2005-11-10 Larry Jones - - * cvs.texinfo (Common options): -n no longer applies to commit. - (commit): Remove reference to the defunct -n option. - * cvs.1, stamp-vti, version.texi: Regenerated - -2005-10-12 Derek Price - - * cvs.texinfo: Remove text that created unintentional cross-references - in generated info files. - -2005-10-04 Derek Price - - * cvs.texinfo: s/visa versa/vice versa/. (From Wiki.) - -2005-09-26 Derek Price - - * Makefile.am (cvs-paper.ps, cvs-paper.pdf): Remove implicit sources. - Add comments about why implicit rules won't work for these targets. - Make sure the distributed cvs-paper.pdf is created in $(srcdir). Make - cvs-paper.pdf directly from cvs-paper.ms to avoid building it just - because cvs-paper.ps is missing. - - * Makefile.am (EXTRA_DIST): Restore PDFs. - * cvs-paper.ps: Removed. - * texinfo.tex: Update from GNULIB. - -2005-09-25 Derek Price - - * Makefile.am (doc): Finish removing PSs. - - * Makefile.am (EXTRA_DIST): Remove PDFs too until errors go away. - - * Makefile.am (EXTRA_DIST): Dist PDFs rather than PSs. - -2005-09-22 Larry Jones - - * cvs.texinfo (rdiff options): Document -k. - * cvs.1, stamp-vti, version.texi: Regenerated. - -2005-09-20 Larry Jones - - * cvs.texinfo: Move summary and detail contents to the front - where they belong. - -2005-09-14 Derek Price - - * Makefile.am: s#cvs.1#$(srcdir)/cvs.1#. - -2005-09-11 Larry Jones - - * cvs.texinfo (Common options): Note that -r branch for a revision - means the head of the branch. - -2005-09-10 Larry Jones - - * cvs.texinfo (Error messages): Add suggested messages. - -2005-09-09 Larry Jones - - * cvs.texinfo (Error messages): Add signal 11 message. - -2005-09-01 Derek Price - - * cvs.man.footer: Update links. - -2005-09-01 Derek Price - - * cvs.texinfo: Update links and email addresses. - -2005-08-29 Derek Price - - * cvs.texinfo (From scratch): Add checkout to import example, from - wiki. - -2005-08-29 Derek Price - - * cvs.texinfo (Removing directories): Correct grammar, from wiki. - -2005-08-29 Derek Price - - * cvs.texinfo (From scratch): Clarify note on `cvs add', inspired from - wiki. - -2005-08-22 Derek Price - - Address bug #13882, submitted by Fred Maranhao. - * cvs.texinfo (log options, admin options, Invoking CVS): Add cross - references for clarity about possible states. - -2005-08-22 Derek Price - - * cvs.texinfo (Updating a file): Add note about update -d, inspired by - wiki. - -2005-08-12 Derek Price - - * cvs.texinfo (What is CVS?): Rephrase for clarity, imported from - Wiki. - -2005-08-02 Derek Price - - * cvs.texinfo (What is CVS?, BUGS): s/cvshome/nongnu/. Remove - obsolete Pascal Molli link. - -2005-06-22 Derek Price - - * cvs.texinfo (Builds): Update Gunnar Tornblom's email at his request. - -2005-05-03 Derek Price - - * cvsclient.texi (Goals): Remove typo. Resolves cvshome issue #236. - -2005-05-03 Derek Price - - * cvs.texinfo (Creating a repository): Provide xref to the remote - repositries section. Resolves issue #203 on cvshome.org. - -2005-05-03 Derek Price - - * cvs.texinfo (Moving directories): Clarify instructions on renaming a - directory. Partially resolves issue #246 on cvshome.org. - -2005-05-03 Derek Price - - * cvs.texinfo (update output): Use "working directory" in place of - "source" for clarity. Closes issue #245 on cvshome.org. - -2005-04-28 Derek Price - - * mkman.pl: Minor changes to accomodate Perl 5.8.4. Improve - commenting. - ($nk, $ret, $debug): New globals. - (debug_print): New function. - -2005-04-14 Derek Price - - * cvs.texinfo (Administrative files): Add "Trigger Scripts" node to - the menu. - (Trigger Scripts, Trigger Script Security): New nodes. - (syntax): Move under Trigger scripts node. - (commit files, taginfo): Rewrite to reference Trigger Script node. - -2005-04-06 Derek Price - - * Makefile.am (MAINTAINERCLEANFILES): Add cvs.1. - (cvs.1): Create intermediate file so that the original isn't emptied on - error. - -2005-01-31 Derek Price - - * Makefile.am, cvs.man.header, cvs.texinfo: Update copyright notices. - -2005-01-29 Derek Price - - * cvs.texinfo (log options): Note quirky interaction of log options. - (Suggestion from Dan Peterson .) - -2004-10-29 Mark D. Baushke - - * cvs.texinfo (Common options): The -r TAG option works with - the cvs annotate command. - (Original patch from Ville Skytta .) - -2004-09-25 Derek Price - - * mkman.in: Move to... - * mkman.pl: ...here. - * Makefile.am (cvs.1): mkman is in build dir, not src dir. - -2004-07-17 Derek Price - - * cvs.texinfo (Update imports, import): Add notes on requirement that - release tags be unique. - (Original patch from Ilya N. Golubev .) - -2004-06-10 Derek Price - - * cvs.texinfo (commit files): Remove reference to the obsolete -i - module option. - -2004-05-28 Derek Price - - * cvs.texinfo (Global options): Remove reference to global -l option. - (Report from Kevin Bulgrien .) - -2004-05-14 Mark D. Baushke - - * cvs.texinfo: Fix makeinfo error. - - * cvs.texinfo (Adding files): Minor cleanup. - (Using keywords): Minor cleanup. - (annotate): Move into the manual section, split into three nodes. - (annotate options): New node. - (annotate example): New node. - (based on patch from Steve McIntyre .) - (Locks, GSSAPI authenticated): Minor cleanup. - (Sticky tags): Clarify operation. - (Locks): Spelling fix. - (Merging adds and removals): Ditto. - (Invoking CVS): Ditto - (Builds): Grammar fix. - (Line group formats): Ditto - (Line group formats, Line formats): Ditto - (commit files): Ditto. - * cvs.1, stamp-vti, version.texi: Regenerated - -2004-05-12 Derek Price - - * mkman.in: Clarify status messages. - -2004-05-10 Derek Price - - * mkman.in: Organize & tidy comments. Check for unprocessed texinfo - commands. Output better error messages on finding unprocessed texinfo - commands. - (do_keyword, keyword_mode): Accept $file argument for error messages. - -2004-05-06 Derek Price - - * mkman.in: Require Perl 5.005. Add comments. Remove duplicate s///. - Handle @:. - -2004-05-06 Derek Price - - * cvs.man.header: Minor text correction. - * mkman.in: Ignore @need keyword. Restore previous font for nested - keywords. - (do_keyword): Ditto on fonts. Move some functionality to... - (keyword_mode): ...this new function. - -2004-05-06 Derek Price - - * mkman.in: Handle keywords that cross multiple lines. - (do_keyword): New function. - -2004-05-04 Derek Price - - * cvs.man.header, cvs.man.footer: Reference `info CVS' rather than - `info cvs' to send users to the top node. - -2004-05-03 Derek Price - - * Makefile.am: mkman is built in the build dir, not $(srcdir). - (Report from Mark D. Baushke .) - -2004-05-03 Derek Price - - * HACKING.DOCS: Fix spelling error. Add reference for @strong. - (Report from Mark D. Baushke .) - - * HACKING.DOCS: Note dependency on `makeinfo' 3.11 & greater. - -2004-04-30 Derek Price - - * mkman.in: Handle single quotes better. Parse out some redundancy - from node and section names. - * cvs.man.footer: Replace some quotes with the usual bold font. - Reformat links in the SEE ALSO section. - * cvs.1: Regenerated. - -2004-04-30 Derek Price - - * mkman.in: Handle examples better. Protect a few more characters. - * cvs.1, stamp-vti, version.texi: Regenerated. - -2004-04-30 Derek Price - - * cvs.man.header: Add copyright notice. - * cvs.1: Regenerated. - -2004-04-30 Derek Price - - * mkman.in: Add copyright and license notice. - -2004-04-30 Derek Price - - * mkman.in: Handle @@. - * cvs.1: Regenerated. - -2004-04-30 Derek Price - - First pass at closing issue #3 on cvshome.org. - * .cvsignore: Ignore mkman. - * cvs.1, mkman.in, cvs.man.header, cvs.man.footer: New files. - * cvs.texinfo: Add cut tags for mkman. - * Makefile.in (man_MANS): Add cvs.1. - (EXTRA_DIST): Add cvs.man.header & cvs.man.footer. - (cvs.1, mkman): New targets. - * Makefile.in: Regenerated. - -2004-04-23 Derek Price - - * cvs.texinfo: Update years in Copyright. - * stamp-vti, version.texi: Regenerated. - -2004-04-21 Derek Price - - * cvs.texinfo: Use splitrcskeyword macro consistently in a failed - attempt to avoid a warning during PDF generation. - * stamp-vti, version.texi: Regenerated. - -2004-04-18 Derek Price - - * cvs.texinfo: Various spelling, typo, and capitalization fixes. - (Patch from Ville Skyttä .) - -2004-04-06 Larry Jones - - * cvs.texinfo (Assigning revisions): Note that client/server mode - only considers files sent to the server to determine the major - revision for new files. - (Reported by Krzysztof GORBIEL .) - * stamp-vti, version.texi: Regenerated. - -2004-03-15 Derek Price - - * stamp-vti, version.texi: Regenerated. - -2004-03-11 Larry Jones - - * cvs.texinfo (loginfo, Error messages): Note that not reading all of - the log info can result in a broken pipe signal. - (Reported by Steven Nicoloso .) - * stamp-vti, version.texi: Regenerated. - -2004-02-04 Derek Price - - * cvs.texinfo (File Permissions): Clarify index entry. - * stamp-vti, version.texi: Regenerated. - -2004-01-22 Derek Price - - * stamp-vti, version.texi: Regenerated. - -2004-01-08 Larry Jones - - * cvs.texinfo (user-defined logging): Move taginfo stuff from here... - (Administrative files): ...to its own node under here. - -2003-12-18 Derek Price - - * stamp-1, stamp-vti, version-client.texi, version.texi: Regenerated - for 1.11.11.1. - -2003-12-18 Derek Price - - * stamp-1, stamp-vti, version-client.texi, version.texi: Regenerated - for 1.11.11. - -2003-12-05 Derek Price - - * stamp-1, stamp-vti, version-client.texi, version.texi: Regenerated. - -2003-12-04 Derek Price - - * stamp-1, stamp-vti, version-client.texi, version.texi: Regenerated - for 1.11.10.1. - -2003-12-04 Derek Price - - * stamp-1, stamp-vti, version-client.texi, version.texi: Regenerated - for 1.11.10. - -2003-11-18 Derek Price - - * stamp-vti, version.texi: Regenerated. - -2003-11-13 Larry Jones - - * cvs.texinfo (Reverting local changes): Use the same vendor tag - in the admin command as was used in the previous import commands. - -2003-11-10 Derek Price - - * stamp-vti, version.texi: Regenerated. - -2003-11-07 Mark D. Baushke - - * cvs.texinfo (CVS commands): Fix typo. - (FreeBSD PR docs/58669 reported by Ceri Davies .) - -2003-10-30 Derek Price - - * stamp-vti, version.texi: Regenerated. - -2003-10-30 Derek Price - - * cvs.texinfo (File permissions, Error messages): Add index entries for - CVSROOT/val-tags file. - -2003-10-21 Derek Price - - * cvs.texinfo: Note gnu.cvs.* usenet mirrors of the email lists. - (Suggestion from Paul Edwards, from somewhere in Australia.) - - * cvs.texinfo: Put email addresses in @email{} tags and URLs in @url{} - tags rather than relying on markup like @code{}. - * stamp-vti, version.texi: Regenerated. - -2003-10-14 Derek Price - - * stamp-vti, version.texi: Regenerated. - -2003-10-14 Derek Price - - Port to pedantic POSIX 1003.1-2001 hosts, such as Debian GNU/Linux - testing with _POSIX2_VERSION=200112 in the environment. - - * cvs.texinfo: Suggest 'sed 1q', not 'head -1'. - (Patch from Paul Eggert .) - -2003-10-10 Derek Price - - * stamp-1, stamp-vti, version-client.texi, version.texi: Regenerated - for 1.11.9.1. - -2003-10-10 Derek Price - - * stamp-1, stamp-vti, version-client.texi, version.texi: Regenerated - for 1.11.9. - -2003-10-06 Derek Price - - * cvsclient.texi (Requests): Add recommendation to client developers to - avoid the `Case' request. - * stamp-1, version-client.texi: Regenerated. - -2003-10-02 Derek Price - - * stamp-1, stamp-vti, version-client.texi, version.texi: Regenerated - for 1.11.8.1. - -2003-10-02 Derek Price - - * stamp-1, stamp-vti, version-client.texi, version.texi: Regenerated - for 1.11.8. - -2003-09-29 Derek Price - - * stamp-1, stamp-vti, version-client.texi, version.texi: Regenerated - for 1.11.7.1. - -2003-09-29 Derek Price - - * stamp-1, stamp-vti, version-client.texi, version.texi: Regenerated - for 1.11.7. - -2003-09-12 Derek Price - - * cvs.texinfo (checkoutlist): Document the error messages which may be - specified in this file. - * stamp-vti, version.texi: Regenerated. - -2003-08-27 Larry Jones - - * cvs.texinfo (history options): Note the 'P' record type which - has been around for a long time but never actually appeared in - the history file due to bugs in the code. - (Invoking CVS): Ditto. - (config): Ditto. - * stamp-vti, version.texi: Regenerated. - -2003-08-07 Derek Price - - * .cvsignore: Ignore {cvs,cvsclient}.txt. - -2003-08-07 Derek Price - - * cvs.texinfo: Use the @dircategory and @direntry commands from texinfo - rather than rolling our own. - - * stamp-vti, version.texi: Regenerated. - -2003-08-07 Derek Price - - * Makefile.am (POSTSCRIPTS): Rename to... - (PSS): ...to sync with and override Automakes default targets. - (PDFS): Reorder to match PSS. - (SUFFIXES): Remove .pdf and .aux. - (cvs.aux, cvs.pdf, cvsclient.aux, cvsclient.pdf): Remove these targets. - .aux weren't being generated anyhow and .pdf no longer need to be - supplied explicitly. - (cvs-paper.pdf: cvs-paper.ps): Provide ps2pdf rule explicitly. - (.{texinfo,texi,txy}.pdf): Remove these suffix rules - they are now - provided by Automake. - -2003-08-06 Derek Price - - * Makefile.am (CLEANFILES): Move... - (MOSTLYCLEANFILES): ...here and drop PDFs since this is where Automake - cleans PDFs & PSs by default. - (MAINTAINERCLEANFILES): Clean all PostScripts even though they will - have been removed in mostlyclean. That is a bug in Automake. - (doc): Depend on info & ps. - (pdf, ps): Removed in favor of Automake's default targets for these - types. - (cvsclient.* targets): Depened on version-client.texi. - (cvs-paper.pdf): Remove in favor of Automake's default target. - (.{texinfo,texi,txi}.{pdf,txt}): Update these targets based on - Automake's similar treatment of dvi, ps, and info targets. - * .cvsignore: Add cvs.tmp, a `make pdf' generated file. - - * Makefile.in: Regenerated. - -2003-07-18 Derek Price - - * cvs.texinfo: Put a few errant references to bug-cvs inside @code{} - for consistancy. - -2003-07-18 Derek Price - - * cvs.texinfo: Update WARNINGs and Notes for a more consistent - appearance. Remove some obsolete comments. - * stamp-vti: Regenerated. - * version.texi: Regenerated. - -2003-07-12 Larry Jones - - * cvs.texinfo (Binary howto): Add note about how to determine whether - a file is marked as binary or not. - (Suggested by Erik Sigra .) - * stamp-vti: Regenerated. - * version.texi: Regenerated. - -2003-06-23 Derek Price - - * stamp-vti: Regenerated. - * version.texi: Ditto. - -2003-06-16 Derek Price - - * cvs.texinfo (splitrcskeyword): New macro, now that @ifhtml will work - properly with texi2html (as of version 1.68), to cause output HTML to - contain where we used to have @asis{} and prevent RCS keyword - substitution in generated HTML. - (Original patch from Patrice Dumas .) - -2003-06-11 Derek Price - - * cvs.texinfo (Invoking CVS): Remove `-P' from the list of `cvs export' - options. - (Patch from Alexander Taler .) - -2003-06-11 Derek Price - - * cvs.texinfo (Top): Remove out-of-date (by at least 5 years) comment. - (Patch from Alexander Taler .) - -2003-05-27 Derek Price - - * cvs.texinfo: Consolidate copyright notices into a single macro that - is called elsewhere to avoid needing three of them. Update copyright - notice. - (BUGS): Suggest Ximbiot rather than the defunct Signum Support as CVS - consultants. - - * stamp-vti: Regenerated. - * version.texi: Ditto. - -2003-05-26 Derek Price - - * stamp-1: Regenerated for 1.11.6.1. - * stamp-vti: Ditto. - * version-client.texi: Ditto. - * version.texi: Ditto. - -2003-05-25 Derek Price - - * stamp-1: Regenerated for 1.11.6. - * stamp-vti: Ditto. - * version-client.texi: Ditto. - * version.texi: Ditto. - -2003-05-21 Derek Price - - * Makefile.in: Regenerate with Automake version 1.7.5. - -2003-04-28 Derek Price - - * cvs.texinfo (Working directory storage, Module options, Module - program options): Remove references to Checkin.prog and Update.prog. - (commit options): Remove reference to -n option. - - * stamp-vti: Regenerated. - * version.texi: Ditto. - -2003-04-10 Larry Jones - - * Makefile.in: Regenerated. - -2003-03-26 Derek Price - - * stamp-vti: Regenerated. - * version.texi: Ditto. - -2003-03-25 Larry Jones - - * cvs.texinfo (Server temporary directory): Reorder list of places - to match code. - (Connection): Add additional example error message and note about - firewall software. - * stamp-vti: Regenerated. - * version.texi: Ditto. - -2003-03-24 Derek Price - - * Makefile.am: Update copyright notice. - - * Makefile.in: Regenerated. - -2003-03-06 Derek Price - - * cvs.texinfo (What is CVS?): Correct date of first post of CVS by - Dick Grune from December to July based on the archive posted on - Google: - . - (Thanks to David A Wheeler .) - - * stamp-vti: Regenerated. - * version.texi: Ditto. - -2003-03-05 Mark D. Baushke - - * cvs.texinfo (CVS_LOCAL_BRANCH_NUM): Backout CVS_LOCAL_BRANCH_NUM - feature. - - * cvs.texinfo (CVS_LOCAL_BRANCH_NUM): Document new environment - variable. - -2003-02-27 Derek Price - - * cvs.texinfo (Environment variables): Make the information on - CVS_CLIENT_PORT slightly clearer. - (Kerberos authenticated): XREF the Environment variables node. - - * stamp-vti: Regenerated. - * version.texi: Ditto. - -2003-02-25 Derek Price - - * Makefile.in: Regenerated. - * stamp-1: Ditto. - * version-client.texi: Ditto. - -2003-02-06 Derek Price - - * cvs.texinfo (Working directory storage, Module options, - Module program options): Correct description of where Checkin.prog - and Update.prog are run. Provide more index entries and cross - references. Remove some FIXME comments. Add a FIXCVS THEN FIXME. - (Thanks to Art Manion at the CERT Coordination Center .) - -2003-02-04 Derek Price - - * cvs.texinfo (File status): Mention the "Unresolved Conflict" status - which was apparently and erroneously removed from the doc at some - point in the past. - -2003-02-03 Derek Price - - * cvs.texinfo (Merging a branch): Mention the GCA as opposed to the - "branch point" as the implicit revision when merging a branch. - -2003-02-03 Derek Price - - * cvs.texinfo (Remote repositories): :METHOD: is optional. - -2003-02-03 Derek Price - - * cvs.texinfo (Committing your changes): Move index entries closer to - their corresponding references. - (Environment variables): Include $VISUAL in order of - preference. Add index entries. Reference Global options node. - (Variables): Change order of list to match the Env. Variables node - mentioned above. - - * stamp-1: Regenerated. - * stamp-vti: Ditto. - * version-client.texi: Ditto. - * version.texi: Ditto. - -2003-02-14 Derek Price - - * cvs.texinfo (Watch Information, Editing files, Getting Notified, - Setting a watch): Edit usage specs for correctness and uniformity. - (Sticky tags): Use ref rather than xref to avoid a warning from - makeinfo. - - * stamp-vti: Regenerated. - * version.texi: Ditto. - -2003-01-23 Derek Price - - * stamp-1: Regenerated. - * stamp-vti: Ditto. - * version-client.texi: Ditto. - * version.texi: Ditto. - -2003-01-22 Larry Jones - - * cvs.texinfo (config): Correct LogHistory default (U was omitted). - -2003-01-16 Derek Price - - * stamp-1: Regenerated for version (1.11.5). - * stamp-vti: Ditto. - * version-client.texi: Ditto. - * version.texi: Ditto. - -2003-01-16 Derek Price - - * stamp-1: Regenerated for dev version (1.11.4.1). - * stamp-vti: Ditto. - * version-client.texi: Ditto. - * version.texi: Ditto. - -2002-12-28 Derek Price - - * stamp-1: Regenerated for version 1.11.4. - * stamp-vti: Ditto. - * version-client.texi: Ditto. - * version.texi: Ditto. - -2002-12-27 Derek Price - - * stamp-1: Regenerated for dev version 1.11.3.1. - * stamp-vti: Ditto. - * version-client.texi: Ditto. - * version.texi: Ditto. - -2002-12-27 Derek Price - - * stamp-1: Regenerated. - * stamp-vti: Ditto. - * version-client.texi: Ditto. - * version.texi: Ditto. - -2002-11-18 Derek Price - - * cvs.texinfo (commitinfo): Explain the environment of commands - run by commitinfo a little more fully. - (Original patch from Fred L. Drake, Jr. .) - - * cvs.texinfo: Change the wording of some of the commit index entries - for consistency and clarity. - * stamp-vti: Regenerated. - * version.texi: Ditto. - -2002-09-24 Derek Price - - * Makefile.in: Regenerated using Automake 1.6.3. - -2002-09-24 Derek Price - - * Makefile.in: Regenerated. - -2002-09-20 Derek Price - - * stamp-vti: Regenerated. - * version.texi: Ditto. - -2002-08-16 Derek Price - - * cvs.texinfo (Error messages): Update CVS_BADROOT notes to specify - new configure option instead. - - * stamp-vti: Regenerated. - * version.texi: Ditto. - -2002-08-12 Derek Price - - * stamp-vti: Regenerated. - * version.texi: Ditto. - -2002-08-06 Derek Price - - * stamp-vti: Regenerated. - * version.texi: Ditto. - -2002-08-05 Derek Price - - * cvs.texinfo: Correct typo. - (Thanks to Chandra Mouleeswaran .) - -2002-04-30 Derek Price - - * Makefile.in: Regenerated with automake 1.6. - -2002-04-18 Derek Price - - * Makefile.am: Add FIXME comment about an automake bug. - * Makefile.in: Regenerated. - -2002-04-18 Derek Price - - * stamp-1: Regenerated for 1.11.2.1 version update. - * stamp-vti: Ditto. - * version-client.texi: Ditto. - * version.texi: Ditto. - -2002-04-17 Derek Price - - * stamp-vti: Regenerated. - * version.texi: Ditto. - -2002-04-17 Derek Price - - * cvs.texinfo: Add index entries for inetd and xinetd. - -2002-03-26 Derek Price - - * stamp-vti: Regenerated. - * version.texi: Ditto. - -2002-03-17 Larry Jones - - * cvs.texinfo (log options): Add new -S option. - -2002-03-12 Larry Jones - - * cvs.texinfo (diff options): Add missing menu for new subsections. - (Patch from Pavel Roskin .) - -2002-03-09 Larry Jones - - * cvs.texinfo (Update imports): Suggest merging with two rel tags - instead of the branch tag and a date and explain why. - -2002-02-26 Larry Jones - - * cvs.texinfo (diff options): Document all the diff options. - -2002-01-10 Larry Jones - - * cvs.texinfo (log options): Update -r :: to match code changes. - (Variables): Document LOGNAME and USER environment variables. - -2001-12-03 Larry Jones - - * cvs.texinfo (Invoking CVS): Add -F option for annotate and - rannotate. - -2001-11-28 Larry Jones - - * cvs.texinfo (File permissions): Add note about SGID being required - on some systems. Add note about LockDir. - -2001-10-18 Derek Price - - * Makefile.am: Add --batch to texi2dvi invocations. - (Thanks to Akim Demaille for the suggestion.) - - * Makefile.in: Regenerated. - -2001-10-04 Larry Jones - - * cvs.texinfo (Connecting via rsh): Add : between host name and - root directory in example since some versions of CVS require it. - (Reported by Trevor Jim .) - -2001-09-14 Larry Jones - - * cvs.texinfo (commit files): Make following sections (commitinfo, - verifymsg, editinfo, and loginfo) subsections of this one. - -2001-09-06 Derek Price - - * cvs.texinfo (Watch information): Cleanup some watch/edit - explanations and discourage the belief that files should be - releasable. - - * stamp-vti: Regenerated. - * version.texi: Ditto. - (Patch from Eric Siegerman .) - -2001-09-05 Derek Price - - * cvsclient.texi: Use version-client.texi instead of version.texi so - cvsclient.* can have a different build date than cvs.texinfo. - - * Makefile.in: Regenerated. - * stamp-1: New file. - * version-client.texi: Ditto. - (Reported by Alexey Mahotkin .) - -2001-09-04 Derek Price - - * Makefile.in: Regenerated with automake 1.5. - * version.texi: Ditto. - -2001-08-24 Larry Jones - - * cvs.texinfo (Error messages): Add new message about root not - being allowed to do commit. - -2001-08-24 Derek Price - - * cvs.texinfo (config): Add a new RereadLogAfterVerify - CVSROOT/config option to control how verifymsg scripts deal with - read-write log messages. - (Patch from Mark D. Baushke .) - - * cvs.texinfo (verifymsg): The verification script may now modify - the log message. - (Patch from Mark D. Baushke .) - - * cvs.texinfo (config, verifymsg): Correct default, changes for clarity, - and add a warning about `stat' and large repositories. - - * version.texi: Regenerated. - * stamp-vti: Ditto. - -2001-08-20 Derek Price - - * Makefile.am: Reformat comment for 80 chars. - - * Makefile.in: Regenerated. - -2001-08-10 Derek Price - - * cvs.texinfo (Default options and the ~/.cvsrc file): Added a few more - "standard" options to the example. - - * stamp-vti: Regenerated. - * version.texi: Ditto. - -2001-08-06 Derek Price - - * Makefile.in: Regenerated. - -2001-07-17 Derek Price - - * version.texi: Regenerated. - * stamp-vti: Ditto. - -2001-07-06 Larry Jones - - * cvs.texinfo (Variables): Add index entry for CVS_USER. - (Reported by Jens Schweikhardt .) - (Working directory storage): Fix Emptydir index entry: Emptydir - is a directory, not a file. - -2001-07-05 Larry Jones - - * cvs.texinfo (Working directory storage): Add Emptydir to index. - -2001-07-04 Derek Price - - * Makefile.in: Regenerated with new Automake release candidate 1.4h. - -2001-06-28 Derek Price - - * Makefile.am: Reference to CVSvn.texi removed. - * cvs.texinfo: @include version.texi and change CVSVN to VERSION. - * cvsclient.texi: Ditto. - - * version.texi: New file. - * stamp-vti: Ditto. - * mdate-sh: New File. Work-around bug in Automake 1.4f by copying - top-level mdate-sh here. - - * CVSvn.texi.in: Removed. - * CVSvn.texi: Ditto. - - * Makefile.in: Regenerated. - (Patch from Alexey Mahotkin .) - -2001-06-27 Larry Jones - - * cvs.texinfo (loginfo): Note that format string expansion is - quoted and contains escapes. - -2001-06-22 Derek Price - - * cvs.texinfo (checkout options): Fix transliteration typo in co - example. - (Patch from Adrian Aichner .) - -2001-06-12 Larry Jones - - * cvs.texinfo (Global options): Note that -T only affects the local - process in client/server mode. - (Environment variables): Note that CVS_SERVER can include arguments - as well as a program name, and note that it applies to :fork: as well - as to :ext: and :server:, although the default value is different. - -2001-06-08 Larry Jones - - * cvs.texinfo (config): Mention using LockDir on in-memory - filesystem to speed up locking. - -2001-06-07 Derek Price - - * Makefile.am (EXTRA_DIST): Remove *.aux. - (MOSTLYCLEAN_FILES): Remove this macro since the Automake bug it was - working around has been fixed. - -2001-06-07 Derek Price - - * HACKING.DOCS: Add link to the main texinfo documentation. - -2001-06-07 Derek Price - - * README.DOCS: Rename to - * HACKING.DOCS: this. - -2001-06-07 Derek Price - - * README.DOCS: New file attempting to document some of our texinfo - conventions. - -2001-06-06 Derek Price - - (Reformatting, rewording, & additions to a patch from - Stephen Cameron .) - - * cvs.texinfo (Invoking cvs, Modifying tags) - document new -B option of rtag and tag commands. - -2001-06-04 Derek Price - - * Makefile.am: Remove commented out DISTFILES & - AUTOMAKE_OPTIONS=no-texinfo.tex. - (Reported by Alexey Mahotkin .) - * Makefile.in: Regenerated. - -2001-06-04 Larry Jones - - * Makefile.am: Fix rules for cvs-paper (.pdf rule actually generated - .ps and vice versa). - (Reported by Alexey Mahotkin .) - * Makefile.in: Regenerated. - -2001-05-29 Derek Price - - * cvs.texinfo (Repository): Fix explanation of CVSROOT parsing - algorithm. - -2001-05-29 Derek Price - patch from Pavel Roskin - - * Makefile.am (CVSvn.texi): Double hash comment in rule since single - hash comments are not portable. - - * Makefile.in: Regenerated. - -2001-05-21 Larry Jones - - * cvs.texinfo (Error messages): Fix ordering; add "cannot commit - files as root". - - * cvs.texinfo (Invoking CVS): Add entries for kserver, pserver, - rannotate, rlog, and server. - - * cvs.texinfo: Lots of minor editorial corrections. Mostly adding - @noindent after examples where the following text is intended to - be a continuation of the preceding text, not a new paragraph. - - * cvs.texinfo (Connection): Replace information about unsetting - $HOME for people with old releases. - - - * cvs.texinfo (Connecting via rsh): Use @samp{} instead of @file{} - where it seemed appropriate. - (Patch from Alexey Mahotkin ). - -2001-05-18 Larry Jones - - * cvs.texinfo (Password authentication server): Add xinetd info. - (Connection): Add "broken pipe" to possible error messages. - -2001-05-18 Derek Price - - * cvs.texinfo (update output): Change wording to something that sounds - a bit more like english. - -2001-05-02 Derek Price - - * cvs.texinfo (Top): Change @ifinfo to @ifnottex to placate HTML - generators. - -2001-04-27 Derek Price - - * CVSvn.texi: Regenerated. - -2001-04-27 Derek Price - - * CVSvn.texi: Regenerated. - -2001-04-25 Derek Price - - * Makefile.in: Regenerated using AM 1.4e as of today at 18:10 -0400. - * CVSvn.texi: Regenerated. - -2001-03-30 Larry Jones - - * cvsclient.texi (Dates, Requests): Add rannotate and rlog. - -2001-03-26 Larry Jones - - * cvs.texinfo (admin options): Fix typo: should be @pxref, not @xref. - -2001-03-26 Larry Jones - - * cvs.texinfo (admin options): Update description of -u option to - refer back to notify. - -2001-03-23 Derek Price - - * Makefile.am (ps): Make 'ps' an alias for 'doc'. - (doc, pdf, ps, txt): declare as '.PHONY'. - - * Makefile.in: Regenerated. - -2001-03-23 Derek Price - - * Makefile.am (MOSTLYCLEANFILES): Add cvs.cps & cvs.fns as a temporary - workaround for an Automake deficiency. - - * Makefile.in: Regenerated. - -2001-03-14 Derek Price - - * Makefile.in: Regenerated - -2001-02-20 Larry Jones - - * cvs.texinfo (BUGS): There's only one company listed now, not two. - -2001-02-13 Larry Jones - - * cvs.texinfo (Password authentication server, First import): Use - @ref instead of @xref when not at the beginning of a sentence. - -2001-02-01 Larry Jones - - * cvs.texinfo (Connection): Add still more notes about common - pserver error messages. - -2001-01-18 Derek Price - - * cvs.texinfo (Quick reference to CVS commands): add index entry for - version subcommand - -2001-01-18 Larry Jones - - * cvs.texinfo (log options): Document new :: syntax for -r. - -2001-01-10 Derek Price - - * Makefile.am (CVSvn.texi): specify $(srcdir) explicitly in target rule - so CVSvn.texi gets built properly for all makes. - (cvs_TEXINFOS): specify $(srcdir) explicitly for CVSvn.texi - (cvsclient_TEXINFOS): ditto - * Makefile.in: regenerated - -2000-12-26 Derek Price - - * Makefile.in: update timestamp - * CVSvn.texi: ditto - -2000-12-26 Derek Price - - * Makefile.am: new target for creation of CVSvn.texi - (EXTRA_DIST): add CVSvn.texi.in & CVSvn.texi - * Makefile.in: Regenerated - * CVSvn.texi: new file - * .cvsignore: remove CVSvn.texi since it is now included in dist - -2000-12-22 Derek Price - - * Makefile.in: Regenerated - -2000-12-21 Derek Price - - * cvs-paper.ps: Backout accidental regeneration. - -2000-12-21 Derek Price - - * .cvsignore: Added *.pdf versions of the *.ps docs - * CVSvn.texi.in: Use configure to generate CVSvn.texi - * Makefile.am: New file needed by Automake - * Makefile.in: Regenerated - * cvs-paper.ps: Regenerated - * texinfo.tex: New file added to placate Automake. Apparently, its - inclusion is mandated by the GNU coding standards. - -2000-12-14 Derek Price - Linus Tolke - - * cvs.texinfo (Merging a branch): changed some references to "BRANCH" - to "BRANCHNAME" for consistancy. Add a warning about merging using a - single tagname reference with an xref to "Merging adds and removals" - for the long explanation - (Merging adds and removals): Add the long explanation of why merging - from a single tagname can be tricky - (update): Add a warning about merging using a single tagname reference - with an xref to "Merging adds and removals" for the long explanation - -2000-11-13 Derek Price - - * cvs.texinfo: use '@sc{cvs}' instead of 'CVS' in various locations - -2000-11-08 Derek Price - - * cvs.texinfo (settitle): stick a 'v' in front of the version number - to make it harder to confuse with chapter, section, and page numbers. - -2000-11-08 Derek Price - - * cvs.texinfo (settitle): add the version number to the title string - so that it is easier to find on HTML pages and the like. - -2000-10-20 Jim Kingdon - - * cvs.texinfo (Variables): Document CVS_USER. - -2000-10-17 Derek Price - - * cvs.texinfo (Remote repositories): added a comment about specifying - a password in the repository name when performaing a checkout. - -2000-10-17 Derek Price - - * cvs.texinfo (Remote repositories, password authenticated, GSSAPI - authenticated, Kerberos authenticated, Environment variables): - Documented CVSROOT spec change & CVS_CLIENT_PORT. - -2000-10-10 Larry Jones - - * cvs.texinfo (Connection): Add additional notes about common - pserver error messages. Remove information about unsetting $HOME - since CVS no longer pays any attention to it in server mode. - -2000-09-07 Larry Jones - - * Makefile.in: Use @bindir@, @libdir@, @infodir@, and @mandir@ - from autoconf. - -2000-08-21 Larry Jones - - * 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 - - * cvsclient.texi (Requests): Ensure that all rootless requests say - that they're rootless. - -2000-07-12 Larry Jones - - * 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 - - * cvs.texinfo (Invoking CVS): Document new version command. - * cvsclient.texi (Requests): Document new version request. - -2000-07-06 Larry Jones - - * cvs.texinfo (admin options): Remove note about -t not working - in client/server. - -2000-04-03 Pavel Roskin - - * cvs.texinfo (Telling CVS to notify you): Remove backslashes - before quotes. - -2000-05-24 Larry Jones - - * cvs.texinfo (From files): Clean up @var{wdir}/@var{rdir} vs. - @var{dir} usage. - -2000-05-19 Larry Jones - - * cvsclient.texi (Requests): Note that Global_option is now - valid without Root. - -2000-04-17 Larry Jones - - * cvs.texinfo (Variables): Clarify what USER means in pserver. - -2000-03-08 Larry Jones - - * cvs.texinfo (Connection): Add note about inetd rate limit. - (ErrorMessages): Add root home directory permission messages. - -2000-02-12 Larry Jones - - * cvs.texinfo: Clean up text/formatting of previous change. - -2000-02-21 K.J. Paradise - - * 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 - - * cvs.texinfo: Remove references to PreservePermissions. - - * cvs.texinfo (history options): Note default report type. - -2000-01-18 Larry Jones - - * cvs.texinfo (Global options): Document compression levels. - -2000-01-18 Larry Jones - - * cvs.texinfo: Minor editorial changes from Ken Foskey - . - -2000-01-11 Larry Jones - - * 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 - - * cvs.texinfo (loginfo): correctly describe CVSROOT/loginfo's - %-expansion behavior. Thanks to Karl Heinz Marbaise - for noticing the error. - -2000-01-07 Larry Jones - - * 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 - - * cvs.texinfo: document new -C option to update, now that it works - both remotely and locally. - (Re-applied by Karl Fogel .) - -1999-12-11 Karl Fogel - - * Revert previous change -- it doesn't work remotely yet. - -1999-12-10 John P Cavanaugh - - * cvs.texinfo: document new -C option to update. - (Applied by Karl Fogel .) - -1999-11-20 Larry Jones - - * cvs.texinfo(history options): Document -f, -n, and -z. - -1999-11-09 Jim Kingdon - - * 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 - - * 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 - - * 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 - - * 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 - - * cvs.texinfo (Password authentication server, Password - authentication client): Rewritten to accommodate the [new] - possibility of empty passwords. - -1999-11-03 Karl Fogel - - * cvs.texinfo (Invoking CVS): correct documentation for -d and -s - options (as did elsewhere, earlier today). - -1999-11-03 Karl Fogel - - * cvs.texinfo (Setting a watch): describe `watch off' behavior - more accurately. - -1999-11-03 Karl Fogel - - * 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 - - * cvs.texinfo: Misc. formatting cleanups. - -1999-07-16 Tom Tromey - - * cvs.texinfo (admin): Mention admin -k exception. Add cvsadmin - to index. - -1999-07-14 Larry Jones - - * cvs.texinfo (Password authentication server): Note inetd limits - and suggest using shell script to avoid. - -1999-06-01 Jim Kingdon - - * cvsclient.texi (Requests): For the import command, the - repository given to the Directory requests is ignored. - -1999-05-27 Jim Kingdon - - * cvsclient.texi (Requests): Clarify that Modified, Is-modified, - Notify and Unchanged must specify a file within the current - directory. - -1999-05-24 Jim Kingdon - - * cvs.texinfo (checkoutlist): New node, contains more complete - documentation of this feature. - (CVSROOT storage): Refer to the new node when mentioning - checkoutlist. - (Administrative files): Update the menu entry for Wrappers. - -1999-05-17 Jim Kingdon - - * cvsclient.texi (Requests): For Notify request, strike duplicate - "Response expected: no" and fix "a edit" -> "an edit". - -1999-05-14 Jim Kingdon - - * cvs.texinfo (Working directory storage): Try to be more clear - about the conflict field. - -1999-05-11 Jim Kingdon - - * cvs.texinfo (config): Use comma after @xref (thanks to Pavel - Roskin for the report/fix). - -1999-05-10 Jim Kingdon - - * cvsclient.texi (Requests): Document restrictions on characters - in Notify requests. - -1999-05-04 Jim Kingdon - - * cvs.texinfo (Password authentication security): Remove sentence - about how no one has audited pserver for holes; a lot of holes - have been closed, looking for, &c, since that was written. - In the summary, reword to reflect the fact that sniffing a - readonly password does not imply general system access (as far as - I know, of course). - - * cvs.texinfo (Connection): Also suggest inetd -d. - -1999-04-28 Jim Kingdon - - * cvsclient.texi (Requests): Say what goes in the "watches" field - of the "Notify" request. - - * cvs.texinfo (Common options): -r is for branches too. - - * cvs.texinfo (Error messages): Add "no such tag" message. - (Common options): -f does not override val-tags check. - -1999-04-26 Jim Kingdon - - * cvs.texinfo (Locks): #cvs.rfl locks must start with "#cvs.rfl." - not just "#cvs.rfl". As far as I know CVS has always implemented - the former behavior, and this just fixes the documentation. - -1999-04-23 Yoshiki Hayashi of u-tokyo.ac.jp - - * cvs.texinfo (verifymsg): Correct wrong file name (bugid.edit -> - bugid.verify). - -1999-04-22 Jim Kingdon - - * cvsclient.texi (Responses): The text in the "M" response is not - designed for machine parsing. Likewise for "error" in regular - protocol. Likewise for "E" and "error" in authentication protocol. - -1999-04-19 Jim Kingdon - - * cvs.texinfo (Error messages): Add "Cannot check out files into - the repository itself". - -1999-04-16 Jim Kingdon - - * cvs.texinfo (Other problems): Add the Windows problem with home - directory ending in a slash. - -1999-04-14 Jim Kingdon - - * cvs.texinfo (CVS in repository): Include the format of the - fileattr file here, rather than referring to the CVS source code. - -1999-04-09 Jim Kingdon - - * cvs.texinfo (Working directory storage): Whether the timestamp - in CVS/Entries is local or universal actually depends on the system. - -1999-04-05 Derek Price - - - * cvs.texinfo (export options): Remove notation that the -r - tag is sticky. 'cvs export' doesn't store that data. - -1999-04-08 Jim Kingdon - - * cvs.texinfo (Error messages): Add "EOF in RCS file" and - "unexpected EOF" (in RCS file) messages. - -1999-03-25 Jim Kingdon - - * cvs.texinfo (admin options): Say there can be no space between - -e and its argument (since the previous sentence said the argument - can be omitted, this is the only possibility). - -1999-02-26 Jim Kingdon - - * cvs.texinfo (Merging and keywords): When including conflict - markers, put @asis{} at the start of the line, in case this file - itself is in CVS. Thanks to Derek Price for pointing this out. - -1999-02-25 Jim Kingdon - - * cvs.texinfo: Refer to "keywords" not "RCS keywords". We had - only used the latter term in a few places, and it seems like a - somewhat odd term in that this style of keyword is by no means - specific to RCS. - (Merging a branch): Remove spurious ")". Use ref, not xref, after - "see". - (Merging a branch, Substitution modes): Make sure that @ref is - followed by comma, since info wants that. - (Merging and keywords): Use samp not code for "-kk". Something of - a judgement call, but the rest of the manual uses samp and that - seems better to me. - (Merging and keywords): Rewrite, to (a) better motivate the - discussion based on what the user wants to do, (b) fix up lots of - convoluted sentences, (c) move the discussion of the binary files - to the end, that is get across the basic idea first and then - embellish it. Remove a few unnecessary index entries. Expand - example. Just tell people to avoid -kk with binary files (comment - out the discussion of using -A after the commit). - -1999-01-29 Derek Price - - - * cvs.texinfo: Added new node/section on merging and keywords. It - contains advice on how to avoid RCS keyword conflicts when merging - and avoid corrupting your binary files while doing it. - -1999-02-24 Jim Kingdon - - * cvsclient.texi (Request intro): Add paragraph about transmitting - more than one command. - -1999-01-29 Jim Kingdon - - * cvs.texinfo: Use EXAMPLE.COM EXAMPLE.ORG and EXAMPLE.NET instead - of domains which might conflict with actual (current or future) - domains. The EXAMPLE domains are registered for this purpose. - -1999-01-22 Jim Kingdon - - * cvs.texinfo (Sticky tags): Refer to -j as the better way to undo - a change. - (Merging two revisions): Also talk about undoing removals and - adds. Move the index entries to here. - -1999-01-21 Jim Kingdon - - * cvs.texinfo (Error messages): Add "waiting for USER's lock". - -1999-01-16 Jim Kingdon - - * cvs.texinfo (Wrappers): Comment out all the -t/-f documentation, - since that feature is currently disabled. - -1999-01-14 Jim Kingdon - - * cvs.texinfo (Connecting via rsh): Add some more index entries so - that people who want to use SSH and such are slightly less lost. - -1999-01-12 Jim Kingdon - - * cvs-paper.ms: Remove comments which contained the FSF's old - address; it has changed. - -1998-12-29 Jim Kingdon - - * cvsclient.texi (Dates): Numeric timezones are preferred. - Also mention the Checkin-time request. - -1998-12-23 Jim Kingdon - - * RCSFILES: Add clarification about certain character set issues - from Paul Eggert, the RCS maintainer. The last paragraph and the - change from Shift-JIS to JIS as an example of a character set - which contains 0x40 bytes which are not '@' characters are mine; - the rest is directly from Paul Eggert. - -1998-12-22 Martin Buchholz - - * cvs.texinfo: Fixed various trivial typos. - -1998-12-17 Jim Kingdon - - * cvsclient.texi (Responses): Explicitly say that Mod-time need - not be sent for all files. - -1998-12-16 Jim Kingdon - - Thanks to Ram Rajadhyaksha of the MacCVS Pro team for raising the - following issues. - * cvs.texinfo (Working directory storage): The deal about storing - files as text files applies to all the CVS/* files, not just - CVS/Entries. State the rationale too. - Document CVSROOT/Emptydir in CVS/Repository. - There is no set order in CVS/Entries. - Explicitly say that writing Entries.Log is optional. - -1998-12-03 Jim Kingdon - - * cvs.texinfo (Error messages): Add "unrecognized auth response". - (Password authentication server): Remove comment about - "unrecognized auth response" and link to the troubleshooting - section. - -1998-12-02 Jim Kingdon - - * cvs.texinfo (Multiple repositories): Add an example. - -1998-11-18 Jim Kingdon - - * cvs.texinfo (Invoking CVS): Change "-r tag" to "-r rev". We - already use "tag" as the name of the tag we are adding. - -1998-11-13 Jim Kingdon - - * cvs.texinfo (CVS commands): Add comment about whether part of - the manual should be organized by command. - -1998-11-06 Jim Kingdon - - Clean up various confusions between modules and directories: - * cvs.texinfo: In "are you sure you want to release" message, - change module to directory. CVS was changed some time ago. - (Tags): "working copy of the module" -> "working directory". - (Merging two revisions): Remove unnecessary text "that make up a - module". - (Recursive behavior): Change "module" to "directory". - (Removing files): Likewise. - (Tracking sources): Remove "a module" from titles. - (Moving directories): Change "module" to "parent-dir". - (Inside): Remove "of the module". - (Inside): Change "module" to "dir". - (Rename by copying): Change "module" to "dir". - (Rename by copying): Remove "of the module". - (Moving directories): "copy of the module" -> "checked out copy of - the directory"; remove second "of the module". Change "check out - the module" to " check out again". - (Moving directories): Remove "of the module". - (Keyword substitution): "your working copy of a module" -> "a - working directory". - (CVS commands): Change "module" to "directory". - (release examples): "module" -> "tc directory". - (commitinfo): "relative path to the module" -> "directory in the - repository". - (verifymsg): Change "module" to "directory". - (Updating a file): "working copy of a module" -> "working directory". - -1998-10-25 Jim Kingdon - - * cvs.texinfo (Branches and revisions): Fix error in branch - numbering which was introduced with change of 4 May 1997. - -1998-10-20 Jim Kingdon - - * cvs.texinfo (Tags): Point to Invoking CVS node so people aren't - left wondering what the syntax is. When introducing -r option, - warn people about sticky tags right off. - (Tagging the working directory, Tagging by date/tag, Modifying - tags, Tagging add/remove): New sections. - (Invoking CVS): Adjust tag and rtag to point to the new sections, - and to add tag -c which had been omitted. Delete tag -n; there is - no such option. - (rtag, tag): Removed; no longer needed. - (commit examples): Update xref. - -1998-10-15 Jim Kingdon - - * cvsclient.texi (Requests): It is OK to send Set before Root. - -1998-10-13 Jim Kingdon - - * cvsclient.texi (Protocol Notes): Remove item about "cvs update" - sending modified files to the server; there are some better ideas - at http://www.cyclic.com/cvs/dev-update.txt - Add mention of www.cyclic.com. - -1998-09-30 Jim Kingdon - - * cvs.texinfo (Committing your changes, Environment variables): - Document VISUAL. - -1998-09-27 Jim Kingdon - - * cvs.texinfo (Password authentication server): Say explicitly - that you edit passwd directly, many users get confused by this. - -1998-09-24 Jim Kingdon - - * cvs.texinfo (Connecting via fork): :fork: may be of interest to - users, for example those who prefer CVS to prompt for one log - message per checkin, rather than one per directory. - (Connecting via fork): Document CVS_SERVER. - -1998-09-24 Noel Cragg - - * cvs.texinfo (Connecting via fork): new node about the fork - access method. - -1998-09-22 Jim Kingdon - - * cvs.texinfo (Environment variables): Document - CVS_IGNORE_REMOTE_ROOT in the CVS 1.10 context. - (Moving a repository): Update comments concerning surgery on - CVS/Root and CVS/Repository files. - -1998-09-21 Noel Cragg - - * cvs.texinfo (Environment variables): remove information about - CVS_IGNORE_REMOTE_ROOT, since it's no longer used. - -1998-09-21 Jim Kingdon - - * cvs.texinfo (config): Mention that CVS 1.10 doesn't have - LockDir. - -1998-09-18 Jim Kingdon - - * cvs.texinfo (Keyword list): Describe $Name and checking out with - a revision. - -1998-09-16 Jim Kingdon - - * cvs.texinfo: RFC2346 is out; update comment. - -1998-09-13 Jim Kingdon - - * cvs.texinfo (Keyword list, Substitution modes): In describing - $Locker and -kkvl, refer to cvs admin -l. - - * cvsclient.texi (Requests): Re-word description of Sticky to - allow room for "Ntagname" (or other, future, values). - - * cvs.texinfo (tag): Remove confusing wording about supplying - revision numbers "implicitly". - -1998-09-10 Jim Kingdon - - * cvs.texinfo (rdiff options): Thanks to the diff library, -u is - supported regardless of your diff program. - -1998-09-07 Jim Kingdon - - * cvs.texinfo (config): Add LockDir. - -1998-09-01 Jim Kingdon - - * cvsclient.texi (Requests): "Directory" and "Argument" are - requests, not commands. Likewise for "other-request". A command, - roughly, is a request that uses "Argument"s, but we might want to - phase out the use of that term more so than codify it, I'm not sure. - -1998-09-01 Noel Cragg - - * cvsclient.texi (Requests): added a detailed explanation of the - Directory request and how it is handled, both for pre-1.10 and - post-1.10 servers. - -1998-09-01 Jim Kingdon - - * cvs.texinfo (Multiple repositories): Also describe the CVS 1.10 - behavior. Looking at a mismatched version of the manual seems to - be a reasonably common occurrence. - - * cvs.texinfo (Environment variables): Revert change regarding - CVS_SERVER_SLEEP*; having that kind of debugging code in the main - CVS is getting out of hand. - -1998-09-01 Noel Cragg - - * cvs.texinfo (Multiple repositories): brief mention that cvs now - handles a working directory composed of multiple repositories. - (Environment variables): add note about CVS_SERVER_SLEEP2. - -1998-08-21 Ian Lance Taylor - - * cvsclient.texi (Text tags): Document importmergecmd tag. - -1998-08-20 Jim Kingdon - - * cvs.texinfo (Common options): Replace out of date URL concerning - ISO8601 dates with a more general statement and a few comments. - -1998-08-18 Jim Kingdon - - * cvsclient.texi (Requests): Add "Checkin-time" request. - -Sun Jul 26 02:42:20 1998 Noel Cragg - - * cvs.texinfo (config): TopLevelAdmin variable. - - * cvsclient.texi (Requests): fix typo. - -1998-07-14 Jim Kingdon - - * cvsclient.texi (Requests): "remove" is like "add" in the sense - that it is the "ci" request which does most of the work. - -1998-06-23 Jim Kingdon - - * cvs.texinfo (Excluding directories): Fix order of - "!first-dir/sdir" and "first-dir" to match what CVS actually - accepts. Reported by Tim McIntosh of sterling.com. - -1998-06-09 Jim Kingdon - - * cvs.texinfo (Using keywords): Rewrite to be less specific to - source code in C. The old text was worse than that; it was - specific to certain versions of GCC (not even current GCC's, I - don't think) (reported most recently by Mitchell Perilstein; - if memory serves by others before that). - -1998-06-08 Jim Kingdon - - * cvs.texinfo (Concurrency): Also mention #cvs.lock. Don't - mention #cvs.tfl; it is quite old (before CVS 1.5). - (Locks, Backing up, Concurrency): Add more index entries. - -1998-06-03 Ian Lance Taylor - - * cvs.texinfo (Tracking sources): Clarify that the vendor branch - is only made the head revision when you import a new file, not any - time you import a file. - -1998-05-23 Jim Kingdon - - * cvs.texinfo (What is CVS?): info-cvs-request is now at gnu.org - and is no longer handled by a human (hallelujah). - -1998-05-12 Jim Meyering - - * cvs.texinfo: Add an info dir entry. - Remove trailing white space. - -1998-05-05 Jim Kingdon - - * cvs.texinfo (Wrappers): Be more explicit that -m 'COPY' has no - effect on binary files. - -1998-05-02 Jim Kingdon - - * RCSFILES: Add more discussion of the order of the revisions. - -1998-04-27 Jim Kingdon - - * cvs.texinfo (loginfo example): Also give example of sending - mail. Use internal variable $USER rather than expecting CVS to - set the environment variable $USER. Change unnecessary 'sed' - invocation to 'cat' (it suffered from the same problem in terms of - internal variables versus environment variables). - - * cvs.texinfo (Error messages): Add "conflict: removed FILE was - modified by second party". - -1998-04-20 Jim Kingdon - - * cvs.texinfo (Common options): Update comment about meaning of - HEAD in cvs diff. - -1998-04-12 Jim Kingdon - - * cvsclient.texi (Dates): Also mention log -d. - - * cvs.texinfo (Invoking CVS): No space is allowed between -r or -w - and its argument, for the log command. - -1998-04-11 Jim Kingdon - - * cvsclient.texi (Dates): New section, explaining the deal with - date formats. - -1998-04-09 Jim Kingdon - - * cvs.texinfo (Global options, Invoking CVS): Fix typo - ("files files" -> "files"). - (Invoking CVS): Make -q and -Q more concise. - (Invoking CVS): Use @var for metavariables in "diff -r". - -1998-03-17 Jim Kingdon - - * cvs.texinfo (~/.cvsrc): In example, put "checkout" rather than - "co" into .cvsrc; we just finished explaining that only the former - works! Thanks to Lenny Foner for reporting this. - - * cvs.texinfo (Copying): Remove this node. This basically - restores the status quo prior to 18 Oct 1996 (before then the node - existed but was empty). - (before Top): Adjust copyright notice accordingly. - -1998-03-12 Tim Pierce - - * RCSFILES: Updated description of `hardlinks' newphrases. - -1998-03-07 Jim Kingdon - - * cvs.texinfo (Tags, Sticky tags, Creating a branch, Accessing - branches): Rename release-0-1 tag to rel-0-1 and likewise for - release-0-1-patches and release-0-4. This fixes an overfull hbox. - (diff options): Reformat table to fix underfull hboxes and such. - -1998-03-07 Tim Pierce - - * cvs.texinfo (Editing files, Special Files): Document hardlinks. - Various cleanups to PreservePermissions text. - * RCSFILES: Document PreservePermissions newphrases. - -1998-03-04 Jim Kingdon - - * cvs.texinfo (Special Files): Add notes about client/server CVS - and hard links across directories. - -1998-03-01 Jim Kingdon - - * cvs.texinfo (Keeping a checked out copy): The magic loginfo - incantation isn't too likely to work except on unix. - -1998-02-23 Jim Kingdon - - * cvs.texinfo (user-defined logging): Double "@" literal. - -1998-02-18 Jim Kingdon - - * cvs.texinfo (user-defined logging): Add taginfo example. - -1998-02-04 Tim Pierce - - * cvs.texinfo (config): PreservePermissions variable. - (Special Files): New. - (Editing files): Add note about PreservePermissions. - -Tue Feb 10 18:07:35 1998 Jim Kingdon - - * cvs.texinfo (Connection): New node. - - * cvsclient.texi (Protocol): Fix typo (lots -> lost). - -Sun Feb 8 21:39:22 1998 Jim Kingdon - - * cvs.texinfo (Invoking CVS): For admin -b, point to the section - where we talk about reverting to vendor branch. - - * cvs.texinfo (Invoking CVS, rdiff options): Document rdiff -V - option as obsolete, since it was made a fatal error some time ago. - - * cvs.texinfo (Invoking CVS): Add global options, keywords, and - keyword substitution modes. Wording fix in reference to --help - and Index. - -Wed Jan 28 23:09:39 1998 Jim Kingdon - - * cvs.texinfo (Excluding directories): Add index entry for "!". - -28 Jan 1998 Karl Fogel and Jim Kingdon - - * cvsclient.texi (Requests, Responses): document - "wrapper-sendme-rcsOptions" and "Wrapper-rcsOption". - -Tue Jan 27 18:37:37 1998 Ian Lance Taylor - - * cvs.texinfo (Excluding directories): New node, documenting how - to exclude directories using ! in an alias module. - -Sun Jan 18 18:23:02 1998 Jim Kingdon - - * cvsclient.texi (Requests): Add Kopt request. - -Thu Jan 1 17:36:42 1998 Jim Kingdon - - * cvs.texinfo (BUGS, Credits): Change @unnumbered to @appendix now - that these are moved from the start to the end. - -Sat Dec 27 10:06:56 1997 Jim Kingdon - - * cvs.texinfo (Error messages): Add "Too many arguments!". - -Fri Dec 26 18:30:26 1997 Jim Kingdon - - * cvs.texinfo (What is CVS?): Just point to the two canonical web - sites (Pascal Molli and Cyclic) concerning CVS downloads. The GNU - URL was out of date and GNU only has source distributions anyway. - - * cvs.texinfo: Change bug-cvs address to gnu.org per email from - Martin Hamilton. - -Tue Dec 23 18:04:09 1997 Jim Kingdon - - * cvs.texinfo (Sticky tags): Further cleanups. Fix thinko - (s/subsequent cvs update/& commands/). Remove "vi driver.c" and - commit from example (totally vestigial). Reword start of - paragraph on non-branch sticky tags, so that it better alludes - to branch sticky tags. When introducing sticky tags, make it - clear that even people who aren't trying to use sticky tags - may need to know how to avoid them. Restore comment about - CVS/Tag files. - (Accessing branches): Don't xref to merging here; that is a much - more advanced topic and the "but see" wording didn't tell us what - to see the xref about. - -Tue Dec 23 14:39:08 1997 Karl Fogel - and Jim Kingdon - - * cvs.texinfo (Creating a branch): Rewritten. Introduce with - `tag', then discuss `rtag' and `-r'. - -Tue Dec 23 10:03:37 1997 Karl Fogel - and Jim Kingdon - - * cvs.texinfo: Changes to dehairify the "Sticky tags" situation: - (Revisions): "Sticky tags" moved here, description in menu changed - to be a little more informative. - (Sticky tags): Moved from "Branching and merging" to "Revisions". - (Accessing branches): New node in "Branching and merging", - explains how to use checkout vs update to retrieve a branch. - Text and example inherited from "Sticky tags", but text mostly - rewritten. - (Sticky tags): Moved under "Revisions", rewritten somewhat (more - rewrites to follow). - Don't use "-v" in "cvs status" example. - -Mon Dec 22 11:46:05 1997 Karl Fogel - and Jim Kingdon - - Cleanups related to recent separation of revisions from - branching/merging: - * cvs.texinfo (Revisions): Take paragraph introducing branches, - rewrite it and move it to "Branching and merging". - (Branching and merging): Also rewrite merging intro. - (Revision numbers): Don't go into detail about branch revision - numbers here, just mention that they happen and refer to new - node "Branches and revisions". - (Branches and revisions): New node under "Branching and merging", - inherits text from "Revision numbers". - (Creating a branch): Refer to "Branches and revisions" now, not - "Revision numbers". - (Binary why): Rewrite sentence which refers to merging, so that - it isn't specific to branch merging. - (Branches motivation): Fix typo (select -> elect). Add comment - about what this node is accomplishing, in general. - -Sun Dec 21 20:57:24 1997 Karl Fogel - and Jim Kingdon - - This is just moving text; related cleanups to follow. - * cvs.texinfo: Changes to put branching and merging together, and - keep it all separate from revisions: - (Revisions): Renamed from "Revisions and branches". - (Branching and merging): Renamed from "Merging". - (Branches motivation, Creating a branch, Sticky tags, Magic branch - numbers): these subnodes moved to "Branching and merging" from - "Revisions". - everywhere: Adjusted cross-references to cope with above. - -Sun Dec 21 20:36:39 1997 Karl Fogel - and Jim Kingdon - - Note that this is just moving text, not changing it: - * cvs.texinfo: divide top-level menu into sections. - (Multiple developers, Builds, Tracking sources, Keyword - substitution): moved to be in "CVS and the Real World" section. - (Compatibility): moved to be in "References" section. - -Mon Dec 22 08:54:31 1997 Jim Kingdon - - * cvsclient.texi (Example): In comment, in citing the BNF style - used in many RFCs, cite RFC2234 not RFC822 (now that the former is - out). - -Sun Dec 21 17:42:22 1997 Karl Fogel - - * cvs.texinfo (Overview): New node. - (What is CVS?, A sample session): Put under Overview. - (What is CVS not?): New node under Overview. - [text previously was part of "What is CVS?" -kingdon] - (Preface): Removed this node and its contents. - (Checklist): Removed this node and its contents. - (Credits): Now toward end of top-level menu (was under Preface). - (BUGS): Now toward end of top-level menu (was under Preface). - -Sun Dec 14 10:14:25 1997 Jim Kingdon - - * cvsclient.texi (Responses): Add MT response. - (Text tags): New node. - - * cvs.texinfo (loginfo): Add comment about which commands run - loginfo. - -Sat Dec 13 08:41:13 1997 Jim Kingdon - - * cvsclient.texi (Connection and Authentication): State that - GSSAPI is preferred to kserver. Try to be clearer about what - the term "pserver" means. Introduce GSSAPI and cite the relevant - RFCs. Discuss the limitations of the existing features in - preventing hijacking. - - * cvs.texinfo (GSSAPI authenticated, Kerberos authenticated): - Briefly introduce what GSSAPI and Kerberos are. Be slightly more - emphatic about protecting against downgrade attacks. - -Fri Dec 12 17:36:46 1997 Ian Lance Taylor - - * cvs.texinfo (GSSAPI authenticated): New node. - (Global options): Document -a. Mention GSSAPI in -x - documentation. - * cvsclient.texi (Connection and Authentication): Document GSSAPI - authentication. - (Requests): Add Gssapi-encrypt and Gssapi-authenticate. - -Fri Dec 12 09:27:38 1997 Jim Kingdon - - * cvs.texinfo (cvsignore): Add note about comments and the - space-separated nature of the syntax. - -Sun Dec 7 09:33:11 1997 Jim Kingdon - - * cvs.texinfo (checkout): Clarify issues regarding updating - existing working directories. - -Sun Nov 30 20:38:17 1997 Jim Kingdon - - * cvs.texinfo (Wrappers): Add comment: we don't document %s. - -Mon Nov 24 23:00:09 1997 Karl Fogel - and Jim Kingdon - - * cvsclient.texi: Move Protocol Notes node to the end. - - * cvsclient.texi (Request intro): new node/section. - (Protocol): added some introductory material. - Rearranged menu into General Conventions, Protocol specification, - and Example etc sections. - (File Modes): replaces Modes, for consistency. - -Sat Nov 22 12:29:58 1997 Jim Kingdon - - * cvsclient.texi (Entries Lines): Clarify options in entries line. - -Tue Nov 18 09:23:15 1997 Jim Kingdon - - * cvsclient.texi (Requests): Be more explicit about "export" and - entries lines. - - * Makefile.in (DISTFILES): Remove DIFFUTILS-2.7-BUG. - -Mon Nov 17 18:20:47 1997 Jim Kingdon - - * cvs.texinfo (tag options): Expand comment with reference to FAQ. - -Fri Nov 14 11:02:37 1997 Jim Kingdon - - * cvs.texinfo (Error messages): Update discussion of "dying gasps". - - * cvs.texinfo (tag options): Add FIXME comment about renaming tags. - -Thu Nov 13 10:20:39 1997 Jim Kingdon - - * cvs.texinfo (Common options): Remove also has a -f option with a - different meaning than most. - -Wed Nov 12 21:57:40 1997 Jim Kingdon - - * cvs.texinfo (File permissions, Connecting via rsh, Environment - variables): When putting an environment variable in the index, say - it is an environment variable. Don't index the same name twice. - - * cvs.texinfo: Many edits to reflect the fact that CVS no longer - invokes external RCS programs. - -Tue Nov 11 15:15:49 1997 Jim Kingdon - - * cvs.texinfo (Locks, CVS in repository): New nodes, document the - locking scheme and briefly outline CVS and CVS/fileattr. - -Sun Nov 9 17:39:41 1997 Jim Kingdon - - * DIFFUTILS-2.7-BUG: Removed; the bug is fixed and the testcases - are incorporated into sanity.sh. - -Sat Nov 8 09:49:38 1997 Jim Kingdon - - * cvs.texinfo (Binary why): Try to be a little clearer about how - merges fit into CVS. Say it may be error prone to have developers - doing merges manually. - -Tue Nov 4 13:02:22 1997 Jim Kingdon - - * cvs.texinfo (admin options): Add discussion of what happens if - there are tags. - -Fri Oct 31 00:04:09 1997 Jim Kingdon - - * cvs.texinfo (admin options): Rewrite discussion of -o to - hopefully be clearer and to also document the new :: syntax. - (admin examples): Removed; incorporated into admin options. - (Invoking CVS): Wording fix for admin -o. - - * cvs.texinfo (Binary why): New node, talks about diff and merge. - (Binary howto): Renamed from Binary files. - (Binary files): Now just contains an introduction. - - * cvs.texinfo (Error messages): Add "could not merge" message. In - discussion of "Binary files . . . differ" message, mention that - this is only an issue with old verisons of CVS. - -Thu Oct 30 15:55:21 1997 Jim Kingdon - - * cvs.texinfo (Error messages): Add "authorization failed" message. - -Wed Oct 29 11:52:05 1997 Jim Kingdon - - * cvs.texinfo: Remove fake RCSid; we decided to remove rcsid's a - while ago. Cleanups suggested by Stephen Gildea (CVSROOT/passwd - has 2 or 3 fields; /user -> /usr; noone -> no one; in used -> in - use). Add comment about making compilers happy about rcsids. - -Sat Oct 25 00:58:24 1997 Jim Kingdon - - * RCSFILES: rcsfile.5 is correct about {num} after next being - optional. - -Wed Oct 22 10:08:27 1997 Jim Kingdon - - * cvs.texinfo (Error messages): Add message about unrecognized - response from cvs server. - -1997-10-11 Noel Cragg - - * cvs.texinfo (checkout options): describe how the `-d' and `-N' - flags really work. Give examples. - (export options): refer the reader to the descriptions for `-d' - and `-N' in checkout options, since the behavior is the same. - -Thu Oct 9 12:01:35 1997 Jim Kingdon - - * cvs.texinfo (log options): Add comment about "cvs log -r". - -Wed Oct 8 10:24:19 1997 Jim Kingdon - - * cvs.texinfo (rtag options): Add comment about how this is - confusing. - -Tue Sep 30 12:31:25 1997 Jim Kingdon - - * cvs.texinfo (Working directory storage): Add comment about - Entries.Static. - -Thu Sep 25 23:52:57 1997 Noel Cragg - - * cvsclient.texi (Responses): description of Module-expansion was - missing a carriage return after the @item clause. - -Wed Sep 24 12:04:42 1997 Jim Kingdon - - * cvs.texinfo (Remote repositories): Add comment about pserver - vs. having users create their own repositories. - -Sat Sep 20 00:59:53 1997 Jim Kingdon - - * cvs.texinfo (Keyword list): Change title from "RCS Keywords" to - "Keyword list" as it is CVS that expands them. - (Avoiding substitution): Change "rcs" to "cvs", in the context of - the program which expands keywords. - -Fri Sep 19 22:57:24 1997 Jim Kingdon - - * RCSFILES: Grammar fix in first paragraph. Re-word section on - dead newphrase. Add item about what it means if "expand" is omitted. - - * cvs.texinfo (Magic branch numbers): Change example branch number - from 1.2.3 to 1.2.4; CVS assigns even branch numbers and I don't - think vendor branches are very relevant to this example. - -Wed Sep 17 17:21:33 1997 Jim Kingdon - - * cvs.texinfo (admin options): Add comment about "cvs admin -b" - (with no argument to the -b). - - * RCSFILES: "next" is optional, not required. - -Tue Sep 16 15:13:22 1997 Jim Kingdon - - * cvs.texinfo (Binary files): Add comment about another possible - way to auto-detect binary files. - -Sun Sep 14 12:38:56 1997 Jim Kingdon - - * cvs.texinfo (Conflicts example): Adjust text and comments - regarding conflict markers to reflect change in CVS. - -Wed Sep 10 12:44:04 1997 Jim Kingdon - - * cvs.texinfo (Server requirements): Add comment about server - disk usage in /tmp. - - * cvs.texinfo (Common options): More comments about date formats: - "now", "yesterday", and the "3 weeks ago" family. - -Tue Sep 9 13:09:58 1997 Jim Kingdon - - * DIFFUTILS-2.7-BUG: Eggert patch is preferred to Rittle one. - -Sun Sep 7 18:38:23 1997 Jim Kingdon - - * cvs.texinfo (history options): Revise -e to say that it includes - future record types (and remove out of date list of what record - types it implies). - - * cvs.texinfo (Environment variables): Expand/correct discussion - of HOME, HOMEDRIVE, and HOMEPATH. - (Error messages): Add "could not find out home directory". - - * cvs.texinfo (update options): Reword -r doc to hopefully be - clearer that it takes either numeric or symbolic revision. - - * cvs.texinfo (syntax): Add comment about how regexp syntax may - be, er, creatively altered, by configure.in. - -Sat Sep 6 11:29:15 1997 Jim Kingdon - - * cvs.texinfo (Working directory storage): Document Baserev and - Baserev.tmp. - (Working directory storage): Adjust comment regarding CVS/* being - text files. - -Fri Sep 5 14:42:39 1997 Jim Kingdon - - * cvs.texinfo (BUGS): Remove mention of unsupported resources page - on http://www.cyclic.com, as it might go away in a future - reorganization. - - * DIFFUTILS-2.7-BUG: Further info from Eggert. - -1997-09-05 Paul Eggert - - * DIFFUTILS-2.7-BUG: Explain how this bug will probably be - fixed in the next diffutils release. - -Thu Sep 4 17:09:57 1997 Jim Kingdon - - * cvs.texinfo (Binary files): Reword the section on what you need - to do with cvs admin -kb to hopefully be a bit clearer. Still not - ideal (see comment). - - * cvs.texinfo (modules): Break node into separate nodes for alias - modules, regular modules, ampersand modules, and options. Expand - text with more examples and explanations. Add index entries. - -Wed Sep 3 14:49:43 1997 Jim Kingdon - - * cvs.texinfo (Multiple developers): Add idea about cvs editors - and reserved checkouts. - -Sun Aug 31 19:36:21 1997 Jim Kingdon - - * cvsclient.texi (Requests): Rewrite paragraph on cvs add on a - filename containing '/'. - -Thu Aug 28 14:13:50 1997 Jim Kingdon - - * cvs.texinfo (diff options): Add comment about "cvs diff" - vs. "cvs diff -r HEAD". - - * cvs.texinfo (Global options): Add comment about -w not - overriding cvs watch on. - -Wed Aug 27 08:09:31 1997 Jim Kingdon - - * cvs.texinfo (Password authentication server): Grammar fix ("under - as the username" -> "as the username"). - - * cvs.texinfo: Fix doubled 'the the' typos. Reported by - karlb@atg.com. - -Tue Aug 26 12:25:42 1997 Jim Kingdon - - * cvs.texinfo (Checklist): Reword xref to point to Binary files - rather than Keyword expansion. Credit goes to jeff@alum.mit.edu - (Jeff Breidenbach) for reporting the problem. - -Mon Aug 18 17:23:18 1997 Jim Kingdon - - * cvs.texinfo (modules): Suggest taginfo instead of -t. Add - comment with some of the reasons. Add comment about -u and -i - problems. - -Sat Aug 16 10:19:06 1997 Jim Kingdon - - * cvs.texinfo (Error messages): Add note about how "could not - check out foo.c" seems to also have been observed on Irix. - -Fri Aug 15 17:28:01 1997 Jim Kingdon - - * cvs.texinfo (Error messages): Add "could not check out foo.c". - -Thu Aug 14 23:57:53 1997 Jim Kingdon - - * cvs.texinfo (Wrappers): Document new -m 'COPY' behavior. - -Tue Aug 12 20:56:40 1997 Jim Kingdon - - * cvs.texinfo (Sticky tags): Add comment about how we should be - documenting sticky tags. - -Fri Aug 8 10:01:03 1997 Jim Kingdon - - * cvs.texinfo (File status): Add comment about "working revision" - in cvs status for a locally removed file. - -Thu Aug 7 22:53:45 1997 Jim Kingdon - - * cvs.texinfo (From other version control systems): Mention - pvcs_to_rcs alongside sccs2rcs. - -Tue Aug 5 17:22:50 1997 Jim Kingdon - - * cvs.texinfo (Compatibility): Add comment about how CVS probably - could be detecting the case of dead files killed by CVS 1.3. - - * cvs.texinfo (From other version control systems): Add paragraph - about converting from systems which don't export RCS files. - -Sun Aug 3 21:03:14 1997 Jim Kingdon - - * cvsclient.texi (Responses): Cite RFC1321 for MD5. - - * cvs.texinfo (A sample session): Nuke index entry for "A sample - session". The fact that this isn't "sample session" is totally - bogus, but in general the table of contents is probably better for - this entry. - - * cvs.texinfo (Error messages): Add comment about wording of error - concerning unknown -x option. - - * cvs.texinfo (Wrappers): Add comment about absolute filter pathname. - -Thu Jul 31 14:40:15 1997 Jim Kingdon - - * cvs.texinfo: Use @ref not @xref when reference is not at the - start of a sentence. Avoids capitalizing "See" when we shouldn't. - Fixes to other similar xref problems. - -Wed Jul 30 19:30:31 1997 Jim Kingdon - - * cvsclient.texi (Connection and Authentication): Don't use @samp - on BEGIN AUTH REQUEST and friends. Avoids overfull hbox. - -Fri Jul 25 10:40:22 1997 Jim Kingdon - - * cvsclient.texi (Requests): Remove obsolete sentence regarding - using Directory instead of Repository enabling alternate response - syntax. - - * cvsclient.texi (Response intro): Add discussing of file updating - responses and file update modifying responses. - (Responses): Refer to this description rather than trying to - describe it in each place. The descriptions in each place were - somewhat incomplete and didn't get updated when new file updating - responses were added. - - * cvsclient.texi: Split node Responses into Response intro, - Response pathnames, and Responses. - -Thu Jul 24 23:13:24 1997 Jim Kingdon - - * cvs.texinfo (config): Document SystemAuth. - (Password authentication server): Mention SystemAuth. - -Mon Jul 21 08:57:04 1997 Jim Kingdon - - * Makefile.in (DISTFILES): Add DIFFUTILS-2.7-BUG. - -Sun Jul 20 17:55:52 1997 Jim Kingdon - - * cvs.texinfo (admin options): For options with optional - arguments, specify that there can be no space between the option - and its argument. For -N, add xref to Magic branch numbers. For - -t, talk about reading from stdin. Comment changes. - -Sat Jul 19 22:28:47 1997 Jim Kingdon - - * cvs.texinfo (Preface): Make section titles more verbose. - Likewise for the menu. - -Fri Jul 18 08:41:11 1997 Jim Kingdon - - * cvs.texinfo (Error messages): No need for an external patch if - server and client are current. Add comment with more thoughts - about messages specific to old versions of CVS. - - * cvs.texinfo (Error messages): Add "cannot start server via rcmd". - - * cvs.texinfo (Error messages): Add "cannot open CVS/Root" for cvs - init. - - * cvs.texinfo (Error messages): Add "missing author". - -Tue Jul 15 16:47:08 1997 Jim Kingdon - - * cvs.texinfo (Keyword list): Fix documentation of $Log to reflect - the fact that we no longer use the comment leader. - (admin options): Fix documentation of $Log. - (admin examples): Remove example concerning comment leader, since - the example no longer does what it claims to. - (admin, admin options): Fix various parts of the documentation to - not refer to this being implemented via RCS. Say nastier things - about -I and -x. Add comments about options to "rcs" which we - don't document. - -Mon Jul 14 00:04:32 1997 Jim Kingdon - - * cvs.texinfo (Error messages): The "cannot change permissions on - temporary directory" error has been happening in various test cases. - -Sat Jul 12 11:12:18 1997 Jim Kingdon - - * cvs.texinfo (Repository files): Further comments about leading - "-" in filenames. - -Fri Jul 11 21:30:11 1997 Jim Kingdon - - * cvs.texinfo (Repository files): Add comment about legal - filenames. - -Wed Jul 9 18:05:26 1997 Jim Kingdon - - * cvsclient.texi (Responses): Add Mbinary response. - -Mon Jul 7 12:04:01 1997 Jim Kingdon - - * cvsclient.texi (Goals): Add previously unwritten goal about only - one way to do each operation. - - * cvs.texinfo (File permissions): Rewrite paragraph on setuid to - be more verbose and less unix-specific. - -Sat Jul 5 03:16:38 1997 Jim Kingdon - - * cvsclient.texi (Connection and Authentication): When we said to - "ignore" an unrecogized code we mean to treat it as nonspecific, - not to ignore the response. - - * cvsclient.texi (Example): Refer to RFC2119 when referring to - terminology of MUST, SHALL, &c. - - * cvs.texinfo (Windows permissions): New node. - -Fri Jul 4 15:27:43 1997 Ian Lance Taylor - - * cvs.texinfo (Common options): Fix typo (avaliable for - available). - -Tue Jul 1 09:19:02 1997 Jim Kingdon - - * cvs.texinfo (Server requirements): Discuss memory used by diff. - - * cvs.texinfo (Substitution modes): Add comment about -A resetting - both sticky tags/dates and sticky options. - - * cvs.texinfo (File permissions): Add paragraph concerning - ownership of the RCS files. - - * cvs.texinfo (Working directory storage): Relative repositories - in CVS/Repository are legal. - -Mon Jun 30 10:48:21 1997 Jim Kingdon - - * cvsclient.texi (Top): Add menu item for Password scrambling. - - * cvs.texinfo (Committing your changes): Add comment concerning - documentation of message prompting. - -Fri Jun 27 11:20:34 1997 Jim Kingdon - - * cvsclient.texi (Password scrambling): New node. - (Connection and Authentication): Adjust accordingly. - (Protocol Notes): Add long discussion of character sets and - password scrambling. - - * cvs.texinfo (Repository files): Also mention doc/RCSFILES in - documenting RCS file format. - (CVSROOT, storage of files): New node. - -Thu Jun 26 09:18:15 1997 Jim Kingdon - - * cvs.texinfo (File permissions): xref to the pserver thing about - permissions in CVSROOT. - (Kerberos authenticated): Explicitly mention kerberos rsh. - Add various index entries for "security, ". - -Wed Jun 25 13:39:16 1997 Jim Kingdon - - * cvs.texinfo (Common options): Rewrite comments concerning HEAD - and testcases and solution. Changing HEAD might be too big a - change; might be better to phase it out. - (Common options, Tags): Add index entries for HEAD and BASE. - -Tue Jun 24 09:37:26 1997 Jim Kingdon - - * cvs.texinfo (Error messages): Add assertion failed. - - * cvsclient.texi (Connection and Authentication): Add "E" and - "error" as responses in authentication protocol. The server - already was in the (formerly bad) habit of sending them, and we - might as well implement this in the client and document it. - - * cvs.texinfo (Password authentication security): Note about - permissions on $CVSROOT also applies to its parent and so on up to - /. - -Mon Jun 23 18:28:18 1997 Jim Kingdon - - * cvs.texinfo (Creating a repository): xref to Server requirements - for more details on memory, CPU. - (Server requirements): Add xref to Creating a repository regarding - disk space. - - * cvs.texinfo (Read-only access, Password authentication - security): The known holes which let a read-only user execute - arbitrary programs on the server are gone. - - * cvsclient.texi (Protocol Notes): Remove multisite item; it is - replaced by item 186 in TODO. Add a general reference to TODO. - Rewrite accordingly the sentence about multisite in the item - concerning sending modified files in "cvs update". - -Fri Jun 20 17:00:20 1997 Jim Kingdon - - * cvs.texinfo (Error messages): Add "binary files differ" when - trying to check in a binary file. - -Fri Jun 20 14:01:23 1997 David J MacKenzie - and Jim Kingdon - - * cvs.texinfo: Fix various formatting, spelling, stylistic, and - factual errors. - -Thu Jun 19 07:11:33 1997 Jim Kingdon - - * cvs.texinfo (config): New node. - (Password authentication server): Talk about RCSBIN in config as - an alternative to -b global option. - * cvsclient.texi (Requests): Specify when Root can/must be used. - - * cvs.texinfo (Error messages): Add - "*PANIC* administration files missing". - - * cvs.texinfo (Password authentication server): Mention - permissions on $CVSROOT and $CVSROOT/CVSROOT as part of the - installation process. - (Password authentication security): Clarify that permissions issue - applies to $CVSROOT as well as $CVSROOT/CVSROOT. - -Wed Jun 18 00:03:25 1997 Jim Kingdon - - * cvs.texinfo (Password authentication security): Add paragraph - on write permissions of $CVSROOT/CVSROOT. - - * cvs.texinfo (Adding and removing): New node. Move Adding files, - Removing files, Removing directories, Moving files, and Moving - directories under it. - - * cvs.texinfo (Removing directories): Add sentence about how - one doesn't remove the directory itself. - - * cvs.texinfo (Password authentication server): Document - --allow-root. - -Tue Jun 17 09:58:03 1997 Jim Kingdon - - * cvs.texinfo (Error messages): Add "unknown option" from RCS. - -Fri Jun 13 12:11:09 1997 Jim Kingdon - - * cvs.texinfo (Global options): Add note about how -n might affect - CVS's output. - -Thu Jun 12 09:33:40 1997 Jim Kingdon - - * cvs.texinfo (Other problems): New node. Add discussion of - problem with old rcsmerge. - - * cvs.texinfo (Environment variables): Add CVSUMASK. - -Mon Jun 2 18:39:57 1997 Jim Kingdon - - * cvs.texinfo (Moving a repository): New node. - -Tue May 27 18:27:57 1997 Jim Kingdon - - * cvs.texinfo (Working directory storage): Add comment about - timestamps. - * cvsclient.texi (Responses): Add Mod-time. - -Mon May 26 10:04:32 1997 Jim Kingdon - - * cvs.texinfo (Wrappers): Add comment concerning -t/-f and - client/server. - -Sun May 25 00:08:39 1997 Jim Kingdon - - * cvs.texinfo (Multiple vendor branches): New node. - (First import, import options, Invoking CVS): xref to it. - -Sat May 24 23:47:47 1997 Jim Kingdon - - * cvs.texinfo (File permissions): Add comment about group - ownership in repository and setgid bit on directories. - -Fri May 23 17:14:05 1997 Jim Kingdon - - * RCSFILES: Fix typo in dead newphrase description ("an" -> "a"). - -Fri May 23 16:33:38 1997 Ian Lance Taylor - - * RCSFILES: Mention dead as a newphrase. - -Fri May 23 09:45:39 1997 Jim Kingdon - - * cvs.texinfo (Builds): In comment, update URL of mk. - -Thu May 22 09:25:56 1997 Jim Kingdon - - * cvs.texinfo (Error messages): Add comment about yet another way - to produce a "cannot open CVS/Entries for reading" error. - -Tue May 20 17:54:55 1997 Jim Kingdon - - * cvs.texinfo (Error messages): Add item about EINVAL in rename. - -Mon May 19 00:21:49 1997 Jim Kingdon - - * cvs.texinfo (Keywords in imports): New node. - (Tracking sources): Add comment about what a "vendor" is. - - * cvs.texinfo (Keyword substitution): Where it refers to RCS - having a certain behavior, rewrite to not pass the buck like - that. Saying "RCS file" is still OK; that is a legit CVS - concept. A few other minor edits. - -Sun May 18 10:24:57 1997 Jim Kingdon - - * RCSFILES: Add list of known newphrase extensions. - - * cvs.texinfo (From other version control systems): Fix typo - ("systesm" -> "systems"). - - * cvs.texinfo (Exit status): New node. - (diff): Replace text on exit status with an xref to that node. - The previous text documented a behavior which CVS no longer - implements. - (user-defined logging, commitinfo, verifymsg, Error messages): - Add index entries for "exit status, of ". - - * cvs.texinfo (Administrative files): Add comment concerning - writing triggers and particularly performance issues. - - * cvs.texinfo (rtag options, tag options): Don't discuss what old - versions did with respect to the behavior now controlled by -F; we - don't try to document old versions here. Add comments concerning - how -F should be documented. Add index entries for "renaming - tags" and such pointing to "tag -F". - -Wed May 14 12:16:19 1997 Jim Kingdon - - * cvs.texinfo (Binary files): Add text and comment about - automatically detecting binary files. - -Mon May 12 11:55:07 1997 Jim Kingdon - - * cvsclient.texi (Connection and Authentication): Add item about - future expansion. - -Thu May 8 11:08:34 1997 Jim Kingdon - - * cvs.texinfo (Update imports): Add comment about wdiff - vs. fsf/wdiff in example. - -Wed May 7 13:52:47 1997 Jim Kingdon - - * cvs.texinfo (checkout): Add comment about need for example - regarding what the "module" argument means. - -Tue May 6 18:02:27 1997 Jim Kingdon - - * cvs.texinfo (History browsing): Add comment about looking at old - revisions. - -Tue May 06 15:05:00 1997 Larry Jones - - * cvs.texinfo: More additions/corrections for -R due to recent - changes. - -Mon Dec 16 15:18:00 1996 Larry Jones - - * cvs.texinfo: Added/corrected documentation for -R. (Minor edits - by Jim Kingdon to reflect recent changes in cvs.texinfo) - -Sun May 4 14:38:35 1997 Jim Kingdon - - * cvs.texinfo (Compatibility): Add comment about "D" lines in - Entries. - - * cvs.texinfo (CVS commands, diff): Change "run diffs" to "show - differences"; the former is jargon. - (CVS commands): Don't refer to "rlog" in describing what log does. - - * Makefile.in (cvsclient.dvi cvsclient.aux): Run texi2dvi rather - than (poorly) emulating it ourself. - - Fix overfull and underfull hboxes: - * cvs.texinfo (What is CVS?): Add words "the newsgroup" before - "comp.sources.unix". - (Credits): Put list of people in @display. - (Repository files): Put /usr/local/cvsroot in @example. - (Connecting via rsh): Change "anklet" to "toe" in example. - (Kerberos authenticated, Password authentication client, Password - authentication server): Change "brickyard" to "yard" in example. - (Read-only access): Use @example and refer to files with a shorter - pathname. - (Server temporary directory): Use @example for pathname. - (Watches Compatibility): Add phony line break. - (Revision numbers): Remove revision 1.2.2.2 and tighten up the - spacing for "the main trunk". - (Tags, Creating a branch): Change /usr/local/cvsroot to /u/cvsroot. - (Merging more than once): Tighten up spacing for "the main trunk". - (Recursive behavior): Put long command in @example. - (First import): Remove word "called". - (Common options): Put long URL in @example. - (loginfo example): Use fewer hyphens in example. - (Variables): Put long command name in @example. - (Copying): Add line break. - (Administrative files): Remove "the" from title. - (Copying): Change "@unnumberedsec" to two "@heading"s. - * cvsclient.texi (Requests): Change /home/kingdon/zwork/cvsroot to - /u/cvsroot. - (Example): Add word "file". - (Example): Change line breaks in example log message. - (Example): Change /home/kingdon/testing/cvsroot to /u/cvsroot. - - * cvs.texinfo (Credits): Don't refer to appendix A and B, they - have been renumbered. Reword so that it works whether the text in - question has since been rewritten or not. - - * cvs.texinfo (BUGS): Rewrite to reflect the many different ways - that one might want to handle bugs. Move information on Signum - and Cyclic from Preface to here. Remove information on known - deficiencies in the manual (some of them I'm not sure were really - things in need of improvement; others were too general to be - useful). For the most part FIXME comments are probably better for - this. Remove "Linkoping, October 1993, Per Cederqvist"--many - parts of the manual are now from other people, dates, and places. - (What is CVS): For the most part, just refer to BUGS concerning - bug-cvs. Also tell people how to subscribe to bug-cvs. - (Credits): Say that list is not comprehensive and refer to - ChangeLog. - -Sat May 3 10:51:58 1997 Jim Kingdon - - * cvs.texinfo (rcsinfo): Add comment about checkoutlist and - related topics. - - * cvs.texinfo (Server temporary directory): New node. - - * cvs.texinfo (Backing up): New node. - - * cvs.texinfo (Repository): Be more explicit about the repository - and the working directory not being subdirectories of each other. - -Mon Apr 28 11:12:56 1997 Jim Kingdon - - * cvs.texinfo (Removing files): Use "*.c" not "?.c" in example; - the former should be good for both unix and DOS-like operating - systems. Document -f option. Refer to Invoking CVS for a full - list of options. Add a few comments. - - * cvs.texinfo (Invoking CVS): For checkout and update, call them - "sticky options" not "sticky kopts". - - * cvs.texinfo (Editing files): Add additional comments on get - vs. checkout. - -Sun Apr 27 16:17:06 1997 Jim Kingdon - - * cvs.texinfo (commit): Only document the current flags (where -f - is force and -F file gets the message from a log file). We had - partly made this change on 9 Feb 1997, but some places got missed. - - * RCSFILES: Add discussion of the common concern regarding - applying deltas to get to a branch head. - - * DIFFUTILS-2.7-BUG: New file. - - * cvs.texinfo (File status): Refer to "Invoking CVS", not - "status", for status options. Add paragraph about how "cvs -n -q - update" is another way to display file status. - (update examples): Removed; it had contained the "cvs -n -q - update" material. - (Invoking CVS): xref to "File status" and "Tags", not "status" and - "status options". - (status, status options): Removed. - (update options, checkout options): xref to "Invoking CVS" - not "status". - - * cvsclient.texi (Requests): Clarify how long-lived Sticky and - Static-directory are. - - * cvs.texinfo: Add @finalout. - - * cvs.texinfo (Error messages): Add "cannot change permissions on - temporary directory" message. - -Wed Apr 23 12:53:45 1997 Jim Kingdon - - * cvsclient.texi (Requests): Document "add" in much more detail. - -Wed Apr 23 00:38:17 1997 Ian Lance Taylor - - * cvsclient.texi (Requests): Correct small typo (`a' for `as'). - -Tue Apr 22 14:23:32 1997 Jim Kingdon - - * cvsclient.texi (Protocol Notes): Expand ideas on multisite - features somewhat. Add items about the network turnarounds for - pserver authentication and for protocol negotiation. - -Mon Apr 21 08:54:48 1997 Jim Kingdon - - * cvs.texinfo (Working directory storage): Describe what to do - with Entries.Log in more detail. - - * cvsclient.texi (Responses): Say "CVS 1.9 and earlier" rather - than "pre version 1.10". The latter increases confusion by - referring to a version which doesn't exist yet. - -Mon Apr 21 01:02:53 1997 Ian Lance Taylor - - * cvsclient.texi (Responses): Document Rcs-diff. Indicate that - Patched is now deprecated in favor of Rcs-diff. - -Sun Apr 20 23:42:03 1997 Jim Kingdon - - * cvs.texinfo (Working directory storage): Add note about format - of timestamp and the "Result of merge" concept. - -Sat Apr 19 13:42:33 1997 Jim Kingdon - - * cvsclient.texi (Responses): It is OK for Copy-file to implement - a rename instead of a copy. - -Fri Apr 18 12:05:48 1997 Jim Kingdon - - * cvs.texinfo (Assigning revisions): Say that -r implies -f. - -Thu Apr 17 16:34:14 1997 Jim Kingdon - - * cvs.texinfo (From other version control systems): Add comment - about CMZ and PATCHY. - -Wed Apr 16 12:35:25 1997 Jim Kingdon - - * cvsclient.texi (Responses): Add paragraph describing how - Copy-file relates to Merged. - (Responses): Add paragraph about how it is the server which - worries about not clobbering the user's file. - -Tue Apr 15 00:57:31 1997 Jim Kingdon - - * RCSFILES: Add notes on keyword expansion. - - * cvs.texinfo (Rename by copying): Comment out seemingly erroneous - text regarding the revision number that the new file starts with. - -Mon Apr 14 12:37:35 1997 Jim Kingdon - - * cvsclient.texi (Requests): Clients should try to send - notifications right away. - - * cvsclient.texi (Requests): For Notify request, clarify a few - future expansion situations. Specify the format of the time. - - * cvsclient.texi (Requests): Clarify that arguments to co, rdiff, - and rtag are module names (and how that differs from file/directory - names). - - * cvsclient.texi (Responses): Say that servers need to create - directories one at a time. - -Sat Apr 12 09:32:58 1997 Jim Kingdon - - * cvs.texinfo (Committing your changes): Say that editor default - is notepad (not vi) for Windows NT/95. Be more clear about what - "cvs commit" does. Add paragraph about timestamps. - (Environment variables, Global options, editinfo): - Add xrefs to that node. - -Thu Apr 10 15:48:39 1997 Jim Kingdon - - * cvs.texinfo (Error messages): Add "could not patch; will refetch". - -Wed Apr 9 15:21:11 1997 Jim Kingdon - - * cvs.texinfo (Working directory storage): New node. - - * cvs.texinfo (Error messages): Add comment about "cvs co ." on - NT. - -Tue Apr 8 14:44:26 1997 Jim Kingdon - - * cvs.texinfo (Error messages): Add diff3 usage message. - -Sun Apr 6 19:03:01 1997 Jim Kingdon - - * cvs.texinfo (Removing files): Add comment about undoing a "cvs - remove". - - * cvsclient.texi (Requests): Explicitly mention the idea of - deferring "Notify" requests. - -Tue Apr 1 07:51:38 1997 Jim Kingdon - - * cvsclient.texi (Responses): Add paragraph about directory - creation and empty directories. - - * cvs.texinfo (Binary files): Add comment about binary files and - merges. - - * cvsclient.texi (Requests): Add discussion of when to send - Is-modified. - - * cvsclient.texi (Requests): Sending Is-modified is enough to - prevent the file from being considered "lost". - -Sun Mar 30 00:31:47 1997 Jim Kingdon - - * cvsclient.texi (Requests): Add Is-modified request. Clarify - order of Entry relative to Unchanged or Is-modified (might as well - specify the same thing vis-a-vis Modified while we are at it). - -Sat Mar 29 12:32:40 1997 Jim Kingdon - - * cvsclient.texi: Change "newline" to "linefeed". Most of the - document already reads "linefeed" and that is what is intended. - (File transmissions): New node, moved here from Requests. - (Goals, Filenames, File transmissions, new node Strings): Add - discussion of character sets and what we expect from the transport - protocol we run on. - - * cvsclient.texi (Requests): Add paragraph about each Directory - request specifying a new local-directory and repository. - - * cvsclient.texi (Requests): Add paragraph about renaming - local-directory in Directory request. Use "local-directory" - consistently instead of "working directory", for clarity. - -Fri Mar 28 13:59:59 1997 Jim Kingdon - - * cvsclient.texi (Requests): Make it clear that there is no - guarantee that one will get Clear-sticky instead of another - response. Also clarify that clients will tend to store the - repository in a long-term way. - - * cvsclient.texi (Requests): Further clarify Directory example. - - * cvsclient.texi (Requests): Add example and further explanation - of what expand-modules is for. - - * cvsclient.texi (Requests): Add example, hopefully making it - clearer what REPOSITORY and LOCAL-DIRECTORY mean to Directory. - - * cvs.texinfo (Attic): New node. - (rtag options): Adjust discussion of -a accordingly. - (Repository files): Adjust accordingly. - -Thu Mar 27 09:57:05 1997 Jim Kingdon - - * cvs.texinfo (Error messages): Give exact wording of broken pipe - error message. - - * cvs.texinfo (history database): Add comment about various - problems with the history file. - - * cvs.texinfo (Common options): The ISO8601 web page we had - mentioned in a comment is no more. Replace it with a new one. - - * cvs.texinfo (Common options): "cvs history" also outputs dates. - -Wed Mar 26 10:54:21 1997 Jim Kingdon - - * cvs.texinfo (Common options): "cvs editors" also outputs dates. - - * cvs.texinfo (Outside): Fix paragraph which said that revision - numbers start at 1.0. First of all, it is 1.1. Second of all, it - is sometimes 2.1, 3.1, etc. Third of all, the xref should be to - Assigning revisions not commit options. - - * cvs.texinfo (Outside): Comment out sentence which incorrectly - stated that "cvs add" can operate on "foo/bar.c". - -Tue Mar 25 22:21:29 1997 Jim Kingdon - - * cvs.texinfo (Error messages): New node. - (Magic branch numbers): Move from Troubleshooting to Revisions and - branches. The former placement never made any sense to me. - (Revision numbers): Remove "Main trunk (intro)" index entry now - that this node is right next to the other "main trunk" index - entry. - (BUGS): Very briefly mention reporting bugs in CVS. - - * cvs.texinfo (Compatibility): Add comment about "Nfoo" in CVS/Tag. - -Mon Mar 24 13:50:24 1997 Jim Kingdon - - * cvs.texinfo (Creating a branch): Add comment about -r in branch - example. - - * cvsclient.texi (Responses): Discuss meaning of tagspec and - future expansion in Set-sticky. The behavior described is the one - which CVS has always implemented. - -Fri Mar 21 14:19:05 1997 Jim Kingdon - - * cvsclient.texi (Requests): Revise meaning of "Case" per change - to CVS. - -Tue Mar 18 15:50:47 1997 Jim Kingdon - - The following reorganization hopefully presents numeric revisions - in a slightly more coherent fashion. The only new material is the - paragraph about assigning revisions for added files. - * cvs.texinfo (A sample session): Bring in a sentence from Basic - concepts node, defining a repository. - (Revisions and branches): Renamed from Branches (it has always - covered non-branch tags too). Bring in nodes "Revision numbers" and - "Versions revisions releases" from Basic concepts, the former in - particular was way too detailed for an intro section. - (A sample session): Add comment about how we need an introduction - and what might go into one. Also bring in the paragraph from - Basic concepts introducing modules, but comment it out. - (Viewing differences): Add comment about - (Basic concepts): Removed; its content has been farmed out as - described above, and as the comment said, it was fundamentally - flawed. - (Assigning revisions): New node. Incorporates the "New major - release number" subsubsec which was in "commit examples". Add - paragraph concerning how CVS assigns revisions on added files. - (commit options): Refer to that node under -r. - (Invoking CVS): Add comment about text for -r. - -Tue Mar 18 13:04:30 1997 Jim Meyering - - * Makefile.in: (install-info): Depend on installdirs. - -Sun Mar 16 12:37:12 1997 Jim Kingdon - - * cvs.texinfo (File permissions): CVSUMASK now works for RCS - files; but it is (still) awkward for client/server CVS. - -Sat Mar 15 17:41:12 1997 Jim Kingdon - - * cvs.texinfo (Magic branch numbers): Add comment about where this - should go. - -Thu Mar 13 09:11:36 1997 Jim Kingdon - - * cvs.texinfo (Credits): Fix grammatical mistake ("manual about" - -> "manual is about"). Reported by Philippe De Muyter. - -Sun Mar 9 09:06:40 1997 Jim Kingdon - - * cvs.texinfo (File permissions): Add comment about val-tags and - CVSUMASK. - -Sun Mar 2 12:33:26 1997 Jim Kingdon - - * cvs.texinfo (From scratch): Add comment about creating - directories with add rather than import. - - * cvs.texinfo (Creating a repository): Add comment about how this - somewhat duplicates Server requirements. - - * cvs.texinfo (Connecting via rsh): Add comment about rsh - vs. remsh. Also wording fix ("incorrect" -> "inapplicable"). - - * cvs.texinfo (Outside): Add comment about renames and annotate. - - * cvs.texinfo (Server requirements): New node. - -Thu Feb 27 15:20:49 1997 Jim Kingdon - - * cvs.texinfo (Multiple developers): Reword section on "cvs admin - -l". As nearly as I can tell based on when it came up on info-cvs - and other contexts, people who are into reserved checkouts - generally find that cvs admin -l is OK. Add a bunch more notes - (inside @ignore) about reserved checkout implementation ideas. - -Sun Feb 23 16:12:03 1997 Jim Kingdon - - * cvs.texinfo (Common options): Add various additional comments - about date formats. - - * RCSFILES: Remove diff for Id and explain it in words instead. - The previous values for Id had been clobbered by keyword expansion - on the RCSFILES file itself. - -Sat Feb 22 14:16:28 1997 Jim Kingdon - - * Makefile.in (DISTFILES): Fix typo (missing backslash). - -Fri Feb 21 23:08:38 1997 Jim Kingdon - - * RCSFILES: New file. - * Makefile.in (DISTFILES): Add RCSFILES. - -20 Feb 1997 Lenny Foner - - * cvs.texinfo (Checklist): Fix typo ("keword" -> "keyword"). - -Thu Feb 20 21:57:05 1997 Jim Kingdon - - * cvs.texinfo (Keeping a checked out copy): Add "web" to index. - -Wed Feb 12 18:44:16 1997 Jim Kingdon - - * cvs.texinfo (Password authentication client, Invoking CVS): - Document "cvs logout" command. - -Tue Feb 11 20:42:45 1997 Ian Lance Taylor - - * cvs.texinfo (commit options): Document that the -f option to - commit disables recursion. - -Sun Feb 9 13:58:59 1997 Jim Kingdon - - * cvs.texinfo (diff options): Document all the options we pass - through to diff. Remove paragraph about -D sometimes meaning - --ifdef since that is no longer true. - - * cvs.texinfo (Multiple developers): Add lengthy comment about - reserved checkout design issues. - - * cvs.texinfo (Wrappers): Add paragraph about timestamps. - - * cvs.texinfo (commit options): Don't try to document what CVS 1.3 - does with -f and how recent versions differ: 1.3 is pretty old - anyway, we generally only try to document the current version, and - the way it was described here was pretty confusing. - (Environment variables): Likewise for CVSEDITOR. - - * cvs.texinfo (import output): Add index entries for symbolic - links. Add brief mention of whether behavior should be - different. Add comments on other symbolic link issues. - -Wed Feb 5 13:02:37 1997 Jim Kingdon - - * cvs.texinfo (Concurrency): Add comment about commit/commit - atomicity. - -Mon Feb 3 10:55:41 1997 joel boutros - - * cvs.texinfo (Connecting via rsh): Fix typo (programs -> problems). - -Fri Jan 31 12:18:47 1997 Ian Lance Taylor - - * cvsclient.texi (Connection and Authentication): Correct typo - (``sent'' for ``send''), and rewrite sentence for clarity. - -Fri Jan 24 10:31:57 1997 Jim Kingdon - - * cvs.texinfo (File status): Change "Unresolved Conflict" to "File - had conflicts on merge" per change to CVS. - -Sun Jan 19 16:21:17 1997 Jim Kingdon - - * cvs.texinfo (admin): Add comments about "group" and "compiled in - value". At least one info-cvs poster was confused by this. - -Thu Jan 16 17:54:51 1997 Jim Kingdon - - * cvs.texinfo (Wrappers): It is just -t/-f which doesn't work - client/server. -k *does* (well, except for the problem with - import noted in BUGS). -m I don't know and I doubt anyone cares. - -Mon Jan 13 15:41:02 1997 Karl Fogel - - * cvs.texinfo (Read-only access): rephrase to imply that there may - be other administrative files, besides history and locks, which - read-only users can also affect (in the future, for example, the - `passwd' file). - -Wed Jan 8 14:50:47 1997 Jim Kingdon - - * Makefile.in: Remove CVSid; we decided to get rid - of these some time ago. - -Wed Jan 8 09:08:36 1997 Jim Kingdon - - * cvsclient.texi (Connection and Authentication): Document - restriction that cvs root sent in the cvs protocol and in the - pserver authentication protocol must be identical. - -Thu Jan 2 13:30:56 1997 Jim Kingdon - - * Makefile.in, cvs.texinfo: Remove "675" paragraph; - see ../ChangeLog for rationale. - -Thu Jan 2 09:34:51 1997 Karl Fogel - - * cvs.texinfo (Read-only access): new node. - (Repository): new menu item for above new node. - (Password authentication server): document the user-aliasing - feature. Why was this undocumented before? - -Wed Jan 1 18:12:11 1997 Jim Kingdon - - * cvs.texinfo (Conflicts example): Use @asis in example to prevent - starting a line with a conflict marker. This means that when - maintaining the file with CVS itself, CVS will not think there is - a conflict merely because of the conflict marker in the example. - IMHO, this is totally bogus and CVS needs a better way of figuring - out whether a conflict is resolved (see comments elsewhere in this - node), but until then.... Credit to Fred Fish for reporting the - problem. - - * cvs.texinfo (cvsignore): Add paragraph about how .cvsignore - files in the sources being imported by "cvs import" override - "-I !". Credit goes to Fred Fish for pointing out this problem. - -Thu Dec 19 12:36:46 1996 Jim Kingdon - - * cvs.texinfo (Credits): Update Roland Pesch email address per his - request. - -Tue Dec 17 12:57:56 1996 Jim Kingdon - - * cvs.texinfo (verifymsg): In example, remove text "and reedit if - necessary"; it was copied from editinfo and doesn't apply here. - Fix syntax of if statement; remove unnecessary attempt at loop; - don't use -n with echo. Add @appendixsec at start of node. - Add note about how verifymsg cannot change log message. - (editinfo): In paragraph saying editinfo is obsolete, fix various - typos and formatting glitches. Mention -e as well as EDITOR. - (editinfo): In saying that editinfo doesn't get consulted with -m, - -F or client/server, recommend verifymsg. Remove comment which - says, in effect, "we need a feature like verifymsg". - (editinfo example): Change "verifymsg" back to "editinfo" here; - the example is of editinfo not verifymsg. - -Tue Dec 17 12:45:32 1996 Abe Feldman - - * cvs.texinfo (verifymsg): New node. - various places: Say that editinfo is obsolete, or refer to - verifymsg instead of editinfo - -Wed Dec 11 08:55:26 1996 Jim Kingdon - - * cvs.texinfo (Compatibility): Add comment about 1.3 and file death. - - * cvs.texinfo (update output, release output): Document "P" as - well as "U". - -Tue Dec 10 16:23:40 1996 Jim Kingdon - - * cvs.texinfo (Builds): Change "make" to "implement" and "build"; - in this context "make" is ambiguous. - (Builds): Add new URL of mk web page. - -Mon Dec 9 11:03:37 1996 Jim Blandy - - * cvs.texinfo (Password authentication client, Environment - variables): Remove mention of CVS_PASSWORD. - -Sun Dec 8 22:38:34 1996 Jim Kingdon - - * cvs.texinfo (Repository files): Mention differences between RCS - files in RCS and in CVS. - (Tags): Tag names must start with a letter. - -Fri Dec 6 09:08:18 1996 Jim Kingdon - - * cvs.texinfo (syntax): Expand discussion of regular expression - syntax. - -Fri Nov 29 09:06:41 1996 fnf@ninemoons.com (Fred Fish) - and Jim Kingdon - - * cvs.texinfo, cvsclient.texi: Make sure @ref and friends are - followed by "," or "." as described in the texinfo manual. This - is a dubious practice as texi2html and texinfo.tex don't require - it, and makeinfo could insert them as needed, but since makeinfo - doesn't do that yet, cope. - - * cvs.texinfo (From files): Suggest "diff -r" rather than "ls -R" - as the way to see that the sources seem to have been imported - correctly. - (Common options): -k is also available with import. - (admin options): Fix typo ("interrested" -> "interested"). - -Mon Nov 25 10:03:56 1996 Jim Kingdon - - * cvs.texinfo (Common options): Add comments about two digit - years, year 2000, and ambiguous/nonexistent dates. - -Sun Nov 24 17:27:24 1996 Jim Kingdon - - * cvs.texinfo (First import): Don't say what the wdiff program we - are using as an example does--that is confusing. Also don't show - untarring it--people might be familiar with cpio, ZIP, VMS BACKUP, - etc., instead of tar. - - * cvs.texinfo (Adding files): Update comment about "cvs add -m". - - * cvs.texinfo (Common options): Remove -H; -H is not a command - option. - (Global options): Also list --help and --version. Don't say that - -H gives a list of commands; it doesn't any more (directly). - - * cvs.texinfo: Add comment pointing to paper size web page. - - * cvs.texinfo (Common options): Rewrite section on date formats. - Executive summary is that RFC822 and ISO8601 are now preferred. - -Wed Nov 20 08:39:45 1996 Jim Kingdon - - * cvs.texinfo (Getting Notified): Add paragraph clarifying that - watches happen per user, not per working directory. - -Tue Nov 19 09:39:08 1996 Jim Kingdon - - * cvs.texinfo (Tags): Suggest that future special tag names might - start with ".". Fix typo. - - * cvs.texinfo (Removing directories): -P is also available with - export. - (Moving directories): Rewrite first paragraph; now says that you - must use -P for the directory to disappear from working - directories. Thanks to Martin Lorentzon - for reporting this bug. - (various): Where we mention -P, point to Removing directories - node. - -Sat Nov 16 18:03:22 1996 Jim Kingdon - - * cvsclient.texi (Example): Rewrite to actually be based on a real - live example (and therefore reflect the way the protocol currently - works). Add comment about formatting of the document itself. - -Thu Nov 14 10:22:58 1996 Jim Kingdon - - * cvsclient.texi (Introduction): Use @ref, not @xref, after "see". - (Goals): Rewrite items about locking, about uploading in big - chunks, and about atomicity to be focused more on the protocol - than the current implementation. - (Notes): Remove this node. The attempt to describe the basic - model has pretty much been replaced by the Introduction. - The material about how to start the client is incomplete and - better left to cvs.texinfo. And the item about the lack of - SERVER_FLOWCONTROL is obsolete now that SERVER_FLOWCONTROL is the - default. - (Protocol Notes): Add comment about multisite features. - (Requirements): Use @code for requests and responses. - - * cvs.texinfo (Remote repositories): Add a few sentences defining - "client" and "server"; before we had been using the terms without - defining them. - - * cvs.texinfo (What is CVS?): Add paragraph about reporting bugs. - Reword and expand comp.software.config-mgmt description (and add - comments about other newsgroup facts). Point people at GNU list - of FTP sites rather than directly at prep.ai.mit.edu. - -Wed Nov 6 09:45:08 1996 Jim Kingdon - - * cvs.texinfo (Tracking sources): Add comment regarding added and - removed files. - -Tue Nov 5 14:00:31 1996 Jim Kingdon - - * cvs.texinfo: Rename node "Invoking CVS" to "CVS commands". - Rewrite the intro and comments to reflect addition of the new - Invoking CVS. - (Invoking CVS): New node, a quick summary of each command. - (annotate): Don't list the options; refer to Invoking CVS and - Common options instead. - -Sun Nov 3 21:22:42 1996 Jim Kingdon - - * cvs.texinfo (Compatibility): New node, moved from ../README. - - * cvs.texinfo (Common options): Add comment about how tar manual - contains documentation for getdate date formats. - -Fri Nov 1 14:00:31 1996 Jim Kingdon - - * cvs.texinfo (commit examples): Rewrite "New major release - number" section to tighten up the wording, better motivate the - discussion, and replace the term "rcs revision number" with - "numeric revision". - -Fri Oct 25 07:49:21 1996 Jim Kingdon - - * cvs.texinfo (loginfo): Don't say "a la printf"; the syntax is - only vaguely similar to printf. - - * cvs.texinfo (loginfo): To get just the repository name, suggest - %{} instead of % "standing alone"; the latter is now an error. - -Tue Oct 22 13:08:54 1996 Noel Cragg - - * cvs.texinfo (loginfo): add information on the new loginfo format - string specification. - -Mon Oct 21 17:33:44 1996 Jim Kingdon - - * cvs.texinfo (Builds): New node. - (What is CVS?): Refer to it. - -Sat Oct 19 14:32:21 1996 Jim Meyering - and Jim Kingdon - - * cvs.texinfo (Choosing a model): Wording/grammar fix. - -Sat Oct 19 14:32:21 1996 Jim Kingdon - - * cvsclient.texi (Obsolete): New node. - (Requests): Remove Repository and Lost and adjust Directory, - UseUnchanged, and other places accordingly. - (Required): Directory and Unchanged are now required. - - * cvs.texinfo (Removing files): Don't talk about modules; they are - not relevant in this context. - (Removing directories): New node. - (Common options): Refer to it instead of duplicating information. - -Fri Oct 18 11:05:06 1996 Jim Kingdon - - * cvs.texinfo (First import, import): Add paragraph about the fact - that import doesn't modify the directory which it imports from. - - * cvs.texinfo (Creating a repository): Add paragraph about - resource requirements. - - * cvs.texinfo (Copying): Replace empty node with a copy of the GPL. - -Thu Oct 17 12:10:55 1996 Jim Kingdon - - * cvs.texinfo (Adding files): Revise comment to more accurately - reflect the functioning/nonfunctioning status of cvs add -m. - - * cvs.texinfo (Reverting local changes): New node, somewhat based - on the version of this node from 30 Sep 96 change. - (admin options): Refer to it. - - * cvs.texinfo: Reinstate 30 Sep 96 change from A4 to US letter. - - * cvs.texinfo (Concurrency): When telling people how to clean up - locks, tell them to make sure the locks are owned by the person - who has the stale locks. - (update output, release output): Remove text about how CVS doesn't - print "? foo" for directories; CVS has since been changed (see - conflicts-130 in sanity.sh). - -Wed Oct 16 15:01:42 1996 Jim Kingdon - - * cvs.texinfo (history options): Mention new option -x E. - -Mon Oct 14 15:21:25 1996 Jim Kingdon - - * cvs.texinfo (Tags): Add paragraph on choosing a convention for - naming tags. - -Thu Oct 10 16:05:26 1996 Jim Kingdon - - * cvs.texinfo (modules): Describe what & does. - -Mon Oct 7 17:20:11 1996 Ian Lance Taylor - - * cvs.texinfo (Removing files): Correct apparent cut and paste - error: refer to the removed file, not the added file. - -Tue Oct 1 14:15:33 1996 Jim Kingdon - - * cvs.texinfo: Revert all recent changes (the last unscathed one - is the CVSUMASK one from Sunday). For the most part said changes - are for new features which are not appropriate at this stage of - the release process. None of the changes being reverted need to - go into 1.9, that is for sure. - -Mon Sep 30 18:17:34 1996 Greg A. Woods - - * cvs.texinfo (Credits): add comment asking if we should update. - Add more detail about printing Letter on A4. - Add some comments about internal comments. - (From files): describe "cvs import -b 1" for importing existing - projects onto the main branch. - (First import): add a couple of helpful hints about naming vendor - and release tags, etc., and regularize the examples with this. - (Tracking sources): noted some reasons why you might use vendor - branches with "cvs import". - (Update imports): mention using "update" in place of "checkout" if - you have an existing working directory. - (Binary files in imports): add sub-menu separator comment. - (Tracking sources): new menu entry "Reverting to vendor release". - (Reverting to vendor release): new node to describe reverting - local changes and optionally using patch(1) to move local changes - forward. - (Global options): describe -D and -g, as well as DIFFBIN and - GREPBIN. - (export examples): add one. - (import options): describe the effect of '-b 1'. - -Mon Sep 30 08:09:53 1996 Jim Kingdon - - * cvs.texinfo: Adjust comments concerning A4 vs. US letter, - referring to ../README. - - * cvs.texinfo (Common options): Add comment about dates which CVS - uses in output. - -Sun Sep 29 11:14:16 1996 Jim Kingdon - - * cvs.texinfo (Keyword list): Don't mention Name twice. - - * cvs.texinfo (File permissions): Expand CVSUMASK stuff a bit. - (Setting a watch, Environment variables, Global options): Update - index entries for "read-only files, and ...". - - * cvsclient.texi (Requests): State that Gzip-stream is preferred - to gzip-file-contents. Cite RFC1952/1951 rather than just "gzip". - Say that RFC1950/1951 compression is also known as "zlib". - -Sat Sep 28 09:31:45 1996 Jim Kingdon - - * cvs.texinfo (Repository): Move all information about the - internal structure of the repository to User modules node. Rename - it to "Repository storage" ("User modules" wasn't particularly - clear). Mention CVSUMASK. Much clarification and - reorganization. - (Basic concepts): Remove material which duplicates what is now in - Repository. Rewrite paragraph introducing modules. - - * cvs.texinfo (Starting a new project): In discussing difficulty - in renaming files, don't refer to "cvs 1.x"--there is no - non-vaporous "cvs 2.x". Reword to reflect that part of the reason - to avoid renames (where possible) is not because of CVS at all, and - to try to give a general impression of how bad CVS issues involved in - renaming are. - -Fri Sep 27 04:23:44 1996 Jim Kingdon - - * cvs.texinfo (Adding files): Talk about directories, not modules, - since that is what is meant. Suggest using -kb option to add - rather than running cvs admin after the fact and xref to Binary - files not admin examples. Incorporate information which had been - in "add" node (there was a lot of duplication). Don't document - use of "add" on a directory to take the place of "cvs update -d"; - the latter is simpler and more logical. - (add, add options, add examples): Removed. - (release output, release options): Update xrefs accordingly. - (Adding files, Removing files): Mention the fact that adds and - removes are branch-specific. - (Merging adds and removals): New node. - - * cvs.texinfo (Concurrency): When mentioning RCS locks, use the - term reserved checkouts and xref to the place where we discuss - them in more depth. - -Thu Sep 26 08:26:01 1996 Jim Kingdon - - * cvs.texinfo (log): Add comments about timezones. - (log, Common options): Add index entries for timezone and zone, time. - -Wed Sep 25 11:05:30 1996 Jim Kingdon - - * cvs.texinfo (log options): Add xref to where we describe the - date formats that -d accepts. - (Common options): Don't refer to date formats accepted by co(1); - CVS's rules have never been the same. Add long whiny comment - about what a mess date formats are. - -Tue Sep 24 11:49:02 1996 Jim Kingdon - - * cvs.texinfo (From other version control systems): The RCS file - must not be locked when you copy it to the CVS repository. - - * cvs.texinfo (Editing files): Also discuss how to revert in the - non-watch case. Add some index entries. - - * cvs.texinfo (update output): Add comment about how we *should* - be handling .# files. Mention fact that it is different under - VMS. Add .# to index. - -Fri Sep 20 13:08:33 1996 Jim Kingdon - - * cvs.texinfo (Multiple developers): Revise text on reserved - versus unreserved checkouts extensively. Move index entries for - "reserved checkouts" and "RCS-style locking" to here. Add - cross-reference to cvs admin -l. Add new section "Choosing a - model". - (Editing files): Add note about use of the word "checkout". - -Tue Sep 17 00:54:57 1996 Jim Kingdon - - * cvs.texinfo (Defining the module): Don't suggest "cvs co - modules"; that depends on a "modules" module being defined which - is not the default which is created by "cvs init". Instead - suggest "cvs co CVSROOT/modules" which should always work. - -Tue Sep 17 00:43:49 1996 VaX#n8 - and Jim Kingdon - - * cvs.texinfo (Rename by copying): Suggest "cvs tag -d" on the file - "new", not on everything. Also don't suggest deleting branch tags. - -Tue Sep 17 00:34:39 1996 David A. Swierczek - - * Makefile.in (install-info): Note whether files are in srcdir and - deal with it rather than cd'ing into srcdir. - -Mon Sep 16 23:33:36 1996 Jim Kingdon - - * cvs.texinfo (Wrappers): Add comment about using wrappers to - compress files in the repository. - - * cvs.texinfo (modules): Add comments about how we should be - documenting how -i and friends operate in client/server CVS. - - * cvs.texinfo (File permissions): Describe the need for write - permissions for locks and val-tags. - - * cvs.texinfo (commitinfo): Add comment about using commitinfo to - enforce who has access. - -Wed Jul 24 17:01:41 1996 Larry Jones - and Jim Kingdon - - * cvs.texinfo (checkout): Refer to "update output" node. - (import): Add new import output node. - (release): Correct release output menu entry (used to be - release options instead). - (update output): Say this is output from checkout as well as - update. - -Mon Sep 16 16:18:38 1996 Jim Kingdon - - * cvs.texinfo (Common options): Clarify that CVS uses MM/DD/YY dates. - - * cvs.texinfo (Common options): Add comment about what HEAD means. - -Mon Sep 16 10:52:04 1996 Norbert Kiesel - - * cvs.texinfo (Global options): Document global '-T' option. - -Sat Sep 14 10:46:58 1996 Jim Kingdon - - * cvs.texinfo (Keeping a checked out copy): New node. - -Fri Sep 13 23:55:42 1996 Jim Kingdon - - * cvs.texinfo (Magic branch numbers): Delete song and dance about - how cvs log can't cope with magic branches because rlog doesn't - know about them; cvs log no longer calls rlog. Delete item about - how you can't specify a symbolic branch to cvs log; that is fixed. - -Wed Sep 11 22:48:21 1996 Jim Kingdon - - * cvs.texinfo (Password authentication server): Add comments - regarding port numbers and troubleshooting. - -Tue Sep 10 10:36:00 1996 Jim Kingdon - - * cvs.texinfo (What is CVS?): Reword text regarding info-cvs, - to avoid overfull hbox. - - * cvs.texinfo (Binary files): Add comment about further issues - with recovering from failure to use -kb. - - * cvs.texinfo (Conflicts example): Describe the "feature" by which - CVS won't check in files with conflicts. - (File status): Expand and revise to document all the possible - statuses from cvs status. Also document "Working revision" and - "Repository revision". Refer to other sections for other aspects - of cvs status. - (status options): Refer to other sections as appropriate. - (update output): Refer user to Conflicts example node. Add - comment regarding purging of .# files. - -Fri Sep 6 11:47:14 1996 Ian Lance Taylor - - * cvs.texinfo (Kerberos authenticated): Mention need for - --enable-encryption option in order to use encryption. - (Global options): Likewise, in description of -x option. - -Thu Sep 5 14:31:42 1996 Jim Kingdon - - * cvs.texinfo (Connecting via rsh): Discuss :ext:, :server:, and - CVS_RSH. - (Remote repositories): Mention what default is if no access method - is specified. - (Environment variables): Don't discuss CVS_RSH at length here; - rely on reference to "Connecting via rsh" node. - -Mon Aug 26 15:39:18 1996 Jim Kingdon - - * cvsclient.texi (Protocol Notes): When talking about having the - client know the original contents of files, suggest cvs edit as a - solution. - -Thu Aug 22 10:44:40 1996 Jim Kingdon - - * cvs.texinfo (Keyword list): Document Name keyword. - - * cvs.texinfo (Tags): Revise comment regarding legal tag names. - -Mon Aug 12 14:58:54 1996 Jim Kingdon - - * cvs.texinfo (Password authentication security): Add comment - about how some of this is not pserver-specific. - -Tue Aug 6 16:48:53 1996 Ian Lance Taylor - - * cvs.texinfo (log, log options): Update for changes to cvs log - now that it no longer invokes rlog. - -Thu Jul 25 10:10:16 1996 Jim Kingdon - - * cvsclient.texi (Requests): Fix typo (Kerberos-request -> - Kerberos-encrypt). - -Wed Jul 24 18:53:13 1996 Ian Lance Taylor - - * cvs.texinfo (Kerberos authenticated): Change the note that the - Kerberos connection is not encrypted. - (Global options): Add documentation for -x. - * cvsclient.texi (Protocol Notes): Remove enhancement note about - Kerberos encryption. - (Requests): Add documentation for Kerberos-encrypt request. - -Thu Jul 18 18:27:40 1996 Jim Kingdon - - * cvs.texinfo (Creating a repository): Mention need to be able to - create lock files in the repository. - - * cvsclient.texi (Responses): In F response, make at least a - minimal attempt to define "flush". - - * cvs.texinfo (Wrappers): Document -k. - (From files, Binary files in imports): Say that imports can deal - with binary files and refer to Wrappers node for details. - (Binary files): Likewise for imports and adds. - -Sat Jul 13 18:29:10 1996 Jim Kingdon - - * cvs.texinfo (Binary files): Add paragraph concerning the fact - that the keyword expansion mode is not versioned, and why this is - a problem. - -Fri Jul 12 18:55:06 1996 Ian Lance Taylor - - * cvsclient.texi (Requests): Document Gzip-stream. - -Thu Jul 11 21:51:45 1996 Ian Lance Taylor - - * cvsclient.texi (Responses): Document new "F" response. - -Wed Jul 10 18:46:39 1996 Jim Kingdon - - * cvs.texinfo (log): Don't document "rlog"; it is deprecated. - -Sat Jul 6 22:07:45 1996 Jim Kingdon - - * cvs.texinfo (Environment variables): Document more temp - directory nonsense, this time with "patch". - -Fri Jul 5 23:27:40 1996 Jim Kingdon - - * cvsclient.texi (Responses): Add comment regarding "/." ending. - -Fri Sep 13 10:52:09 1996 Greg A. Woods - - * cvs.texinfo: don't force afourpaper -- Letter prints much better - on A4 than the other way around, believe you me! - (rdiff options): describe -k and new -K. - (RCS keywords): add description of $Name. - (Using keywords): add description of #ident and example of using - $Name. - - also fixed cross references to Substitution modes in various - places. - (import options): mention that -b 1 imports to the trunk. - -Tue Jul 2 22:40:39 1996 Jim Kingdon - - * cvs.texinfo (Sticky tags): Update to reflect change in - "resurrected" message. - -Fri Jun 28 10:48:33 1996 Jim Kingdon - - * cvs.texinfo (Connecting via rsh): Add comment about what we - might be saying about troubleshooting. - -Sun Jun 23 10:07:45 1996 Jim Kingdon - - * cvs.texinfo (Password authentication security): Add comment - regarding anoncvs as practised by OpenBSD. - -Wed Jun 19 15:41:11 1996 Jim Kingdon - - * cvs.texinfo (Administrative files): Add xref to Intro - administrative files. - (Intro administrative files): Add comment suggesting future - reorganizations of this material. - (syntax): Add comment regarding this node. - (Getting Notified): Actually document the notify file. It hadn't - really been documented to speak of. - (editinfo,loginfo,rcsfino,cvsignore): Make the index entries - follow the standard "foo (admin file)" format. - -Fri Jun 14 18:14:32 1996 Jim Kingdon - - * cvs.texinfo (editinfo): Discuss the way editinfo falls down in - the face of -m or -F options to commit, or remote CVS. - -Thu Jun 13 15:08:27 1996 Jim Kingdon - - * cvs.texinfo (Watches): Add comment discussing the - fact that using cvs edit instead of chmod is not enforced. - - * cvs.texinfo (Setting up): Add index entry for "init (subcommand)". - (Creating a repository): Move contents of node Setting up here... - (Setting up): ...and remove this node. - (Creating a repository): Don't refer to the INSTALL file (it just - refers back to us!). - - * cvsclient.texi (Responses): Document the fact that the server - should send data only when the client is expecting responses. - -Wed Jun 12 16:04:48 1996 Jim Kingdon - - * cvsclient.texi (Entries Lines): Add comment regarding specifying - the meaning of "any other" data, in the conflict field. - (Example): Make it clear that using a separate connection for each - command is not required by the protocol. Add some comments - regarding ways in which the example is out of date or wrong. - -Fri Jun 7 18:02:36 1996 Ian Lance Taylor - and Jim Kingdon - - * cvs.texinfo (annotate): Document new -r, -D, and -f options. - -Fri Jun 7 16:59:47 1996 Jim Kingdon - - * cvs.texinfo (Invoking CVS): Add comment describing why only some - commands are listed here. - (Structure, Environment variables): Don't describe CVS as a - front-end to RCS. - -Tue Jun 4 21:19:42 1996 Jim Kingdon - - * cvsclient.texi (Responses): Document Created and Update-existing. - -Mon Jun 3 17:01:02 1996 Jim Kingdon - - * cvsclient.texi (Responses): Clarify "diff -c" versus "diff -u" - format in Patched response. Don't specify how the client must - implement its patch-applying functionality. - -Sun May 26 17:12:24 1996 Norbert Kiesel - - * cvs.texinfo (tag options) Document option "-c". - -Thu May 23 21:11:56 1996 Jim Kingdon - - * cvs.texinfo (Credits): Rewrite section on FAQ to reflect the - fact that FAQ is no longer maintained. - (What is CVS?): Mention comp.software.config-mgmt as well as - info-cvs. Mention the fact that info-cvs-request can be slow in - responding. - (What is CVS?): Rather than say that cvs is not a configuration - mangement system, say specifically what it lacks (change control, - etc.). I added process control (which was sorely lacking from the - list of configuration management functionality), and deleted some - functions such as tape construction which are not provided by the - well-known configuration management systems. - - * cvs.texinfo (checkout options): Add comment regarding - subdirectories (lack of clarity pointed out by ian@cygnus.com). - Add comment about that infernal "short as possible" wording. - - * cvs.texinfo (Global options): Fix error ("diff" -> "log") - (reported by ian@cygnus.com). - Remove footnote "Yes, this really should be fixed, and it's being - worked on"--it isn't clear what "this" is, and I doubt anyone is - working on it. - -Tue May 21 17:22:18 1996 Jim Kingdon - - * cvsclient.texi (Requests): Clarify Directory with "." as local - directory, and that filename for Questionable cannot contain "/". - -Mon May 20 13:15:25 1996 Greg A. Woods - - * cvs.texinfo (rdiff): description from main.c:cmd_usage - (rtag): description from main.c:cmd_usage - (status): description from main.c:cmd_usage - (tag): description from main.c:cmd_usage - [all for the sake of consistency] - -Fri May 17 11:42:46 1996 Jim Kingdon - - * cvs.texinfo: Add index entries for :local:, etc. - (Password authentication server): Revert erroneous change - regarding the format of CVSROOT/passwd file. - -Thu May 16 17:06:46 1996 Noel Cragg - - * cvsclient.texi (Notes): Removed paragraphs about various server - invocations which are now described in full in node "Connection - and Authentication." - (Requests): Include a note that "gzip-file-contents" doesn't - follow the upper/lowercase convention and that unknown reqests - always elicit a response, regardless of capitalization. - - * cvs.texinfo (Kerberos authenticated): Removed bogus version - number. - (Repository): explain the ":local:" access method. - -Wed May 15 23:43:04 1996 Noel Cragg - - * cvsclient.texi (Goals): mention access methods. - (Requests): add note about convention: requests starting with a - captial letter don't have any expected response. Made sure each - request has a "Response expected" note. - - * cvs.texinfo (Remote repositories): add info about access - methods; fix pserver info. - -Tue May 14 08:56:41 1996 Jim Kingdon - - * cvs.texinfo (Environment variables): Try to document somewhat - more accurately where we put temporary files. - - * cvs.texinfo (From files): Say directory tree instead of module - where that is what we mean. Use @var{wdir} and @var{rdir} in the - example instead of using @var{dir} for two different things. - (From files): Say directory tree instead of module - where that is what we mean. - (Binary files): When using cvs admin -kb, one needs an extra - commit step on non-unix systems. - (Binary files in imports): New node. - (Wrappers): Add comment regarding indent example. - (Top): Don't refer to modules when that is not what we mean. - -Fri May 10 09:39:49 1996 Jim Kingdon - - * cvs.texinfo (Sticky tags): Explain what sticky dates and - non-branch sticky tags are good for. - - * cvs.texinfo (Repository): Document that -d overrides CVS/Root. - -Wed May 1 15:38:26 1996 Jim Kingdon - - * cvs.texinfo (Tags): Document un-revision of all-uppercase tag - names. - -Wed Apr 24 08:41:51 1996 Jim Kingdon - - * cvs.texinfo (Password authentication security): Rewrite sentence - on complex and unknown security bugs to clarify that it is - referring to people who have been give access to cvs, not to holes - in the authentication method (which is relatively simple). - -Tue Apr 23 09:31:29 1996 Jim Kingdon - - * cvs.texinfo (Wrappers): Talk about what -m does (and does not - do). Other minor edits. - -Wed Apr 17 15:27:03 1996 Jim Kingdon - - * cvs.texinfo (rcsinfo): Rewrite paragraph concerning remote CVS. - * cvsclient.texi (Responses): Document Template response. - -Sun Apr 14 16:01:39 1996 Karl Fogel - - * .cvsignore: added CVSvn.texi. - -Wed Apr 10 16:56:21 1996 Jim Kingdon - - * cvs.texinfo (~/.cvsrc): Mention setting global options with "cvs". - - * cvs.texinfo (release): Change "modules" to "directories". - Release does not take module names as arguments. - - * cvs.texinfo (Creating a branch): Add comments about how we - should better document tagging the branchpoint. - -Tue Apr 9 19:59:45 1996 Jim Kingdon - - * cvs.texinfo (Top): Use @value{CVSVN}, not a vague refenece to 1.4. - - * cvs.texinfo (From other version control systems): New node. - -Mon Apr 8 15:59:37 1996 Jim Kingdon - - * cvsclient.texi (Connection and Authentication): Revise kerberos - and pserver sections to reflect the fact that port 2401 is now - officially registered. - -Thu Mar 28 09:51:13 1996 Jim Kingdon - - * cvs.texinfo (History browsing): Reinstate this node. Try to get - it into some minimally useful state (it still needs a lot of - work). - (annotate): New node, subnode of History browing. - - * cvsclient.texi (Requests): Add annotate request. - -Tue Mar 26 08:46:39 1996 Jim Kingdon - - * cvs.texinfo: In various examples, change tag names to avoid tag - names reserved to CVS. - - * cvs.texinfo (Tags): Document what is a valid tag name. - - * cvs.texinfo (Substitution modes): Try to describe how the - various keyword expansion settings interract. - (Binary files): Suggest cvs update -A, not removing file and then - updating it, to get effect of new keyword expansion options. - - * cvs.texinfo (admin options): Mention CVS's use of `dead' state. - -Thu Mar 21 08:25:17 1996 Jim Kingdon - - * cvs.texinfo (Environment variables): Expand introduction to RCS - environment variables. Expand and correct CVS_SERVER_SLEEP. - - * cvs.texinfo (Environment variables): Remove POSIXLY_CORRECT; cvs - requires options to precede arguments regardless of it. - -Thu Mar 21 08:18:42 1996 Norbert Kiesel - - * cvs.texinfo: Remove paragrahps about a forthcoming CVS - newsgroup and about sending patches to think.com. - (Environment): Document some more (all?) used environment - variables. - -Wed Mar 20 09:44:21 1996 Jim Kingdon - - * cvsclient.texi (Introduction): New node. - * Makefile.in: Add cruft to reflect fact that cvsclient.texi now - uses CVSvn.texi. - -Mon Mar 18 14:43:53 1996 Jim Kingdon - - * cvsclient.texi (Requests): Add Case request. - -Wed Mar 13 16:01:47 1996 Jim Kingdon - - * cvsclient.texi (Connection and Authentication): New node. - - * cvsclient.texi (Requests): Expand discussion of Root a bit. - - * cvs.texinfo (Setting up): Don't refer to INSTALL file; revise to - reflect some information which had been in the INSTALL file. - - * cvs.texinfo (history file): Update to reflect cvsinit -> cvs - init. Adjust discussion of whether history file format is - documented. - (Setting up): Update to reflect cvsinit -> cvs init. - - * cvsclient.texi (Requests): Document init request. - -Thu Feb 29 10:08:31 1996 Jim Kingdon - - * cvs.texinfo (loginfo example): Adjust example to reflect the way - that CVS actually works. Add comments questioning whether that is - the best behavior. - - * cvs.texinfo (cvsignore): Document additions to default ignore list. - -Mon Feb 26 13:48:01 1996 Jim Kingdon - - * cvsclient.texi (Filenames): New node, documents / vs \, etc. - -Wed Feb 24 1996 Marcus Daniels - - * cvs.texinfo (Password authentication server): Mention - support for imaginary usernames. - -Thu Feb 15 16:34:56 1996 Jim Kingdon - - * cvs.texinfo (Variables): Add new internal variable $USER. - -Wed Feb 14 22:52:58 1996 Jim Kingdon - - * cvs.texinfo (export, admin): Document -k option to cvs export. - - * cvs.texinfo (admin options): Mention using -l, -u, -L, and -U in - conjunction with rcslock.pl. - -Mon Feb 12 16:38:41 1996 Jim Kingdon - - * cvs.texinfo: Remove references to mkmodules. - -Sun Feb 11 12:31:36 1996 Jim Kingdon - - * cvsclient.texi: Add Set request. - - * cvs.texinfo (Variables): Rewrite to reflect user variables - replacing environment variables; motivate the discussion better. - (Global options): Add -s option. - -Sat Feb 10 11:18:37 1996 Jim Blandy - - * cvs.texinfo (Variables): Fix @table commands. - -Fri Feb 9 17:31:18 1996 Jim Kingdon - - * cvs.texinfo (Variables): New node. - - * Makefile.in (CVSvn.texi): New rule. - (OBJDIR_DISTFILES): Add CVSvn.texi. - (cvs.dvi,cvs.info): Add cruft to deal with it being in build dir - or srcdir. - * cvs.texinfo: Include CVSvn.texi and use the version number from - it instead of a hardcoded version number and date. - -Thu Feb 1 13:28:03 1996 Jim Kingdon - - * cvs.texinfo (Sticky tags): Expand so it really documents the - features it is talking about rather than referring to "Appendix - A". Add example of how to restore the old version of a dead - file. In various other parts of the manual refer to this node, in - some cases deleting duplicative text. In the case of cvs admin - -b, mention vendor branch usage. - (Removing files): Discuss removing files (in user-visible terms, - not in terms of the Attic and such). - (remove): Remove node; merge contents into Removing files. - -Tue Jan 30 17:52:06 1996 Jim Blandy - - * cvs.texinfo: Tweak @top node, to make file compatible with both - makeinfo and texinfo-format-buffer. Perhaps we should fix the - formatters to agree on what constitutes valid texinfo. - -Mon Jan 29 16:38:33 1996 Jim Kingdon - - * cvsclient.texi (Requirements): New node, to talk about required - versus optional parts of the protocol. - -Sun Jan 28 09:00:34 1996 Jim Kingdon - - * cvsclient.texi (Modes): Add discussion what what the mode really - means (across diverse operating systems). - -Tue Jan 23 12:54:57 1996 Jim Kingdon - - * cvs.texinfo: Per mail from Per Cederqvist, change author to "Per - Cederqvist et al". Also remove sentence about Signum shipping - hardcopy manuals and add information on Cyclic. Change version - number to 1.6.87. - -Fri Jan 12 15:29:39 1996 Vince Demarco - - * cvs.texinfo: Fix the documentation for the com/uncom change - to wrap/unwrap. make everything consistant - -Wed Jan 10 16:11:54 1996 Jim Kingdon - - * cvs.texinfo (Concurrency): Add index entries; minor clarification. - -Tue Jan 9 16:03:39 1996 Jim Kingdon - - * cvs.texinfo (Getting Notified): Document users file. - - * cvs.texinfo (cvsignore): Add *.obj to list of ignored files. - -Wed Jan 3 17:01:58 1996 Jim Kingdon - - * cvs.texinfo (import): Adjust list of ignored files to match - recent change to CVS (CVS* -> CVS CVS.adm). Consolidate - discussion of ignored files in one place (with xrefs from others). - - * cvsclient.texi: Remove How To node. It was out of date - (again!), and I am getting sick of trying to update it (internals - documentation should be in the comments, where it at least has a - fighting chance of staying up to date). - (Protocol): Say what \n and \t mean in this document. - -Tue Jan 2 23:39:32 1996 Jim Kingdon - - * cvs.texinfo (Wrappers): Change comb/uncom to wrap/unwrap. - -Mon Jan 2 23:00:00 1996 Vince Demarco - - * cvs.texinfo: update the Wrappers documentation so it isn't - so NEXTSTEP centric. The wrappers code has alot of other - general uses. The new version of the documentation tryes - to show that to the reader. - -Mon Jan 1 13:09:39 1996 Jim Kingdon - - * cvsclient.texi (Responses): Clarify that Module-expansion is not - suitable for passing to co. - -Sun Dec 31 10:53:47 1995 Jim Kingdon - - * cvs.texinfo (Password authentication server): Suggest specifying - -b in inetd.conf. - - * cvs.texinfo (Password authentication): Variety of cleanups and - minor fixes, including shorter node names. - -Sun Dec 24 02:37:51 1995 Karl Fogel - - * cvs.texinfo (Using the client with password authentication): - tixed fypos. - -Sun Dec 24 00:00:16 1995 Karl Fogel - - * cvs.texinfo (Remote repositories): use @code{rsh} most places, - because it is the name of a program, and because I am a pedant. - Refer to new node "Password authenticated". - (Password authenticated): new node. - (Setting up the server for password authentication): new node. - (Using the client with password authentication): new node. - (Security considerations with password authentication): new node. - - These are all really long node names, but it seems necessary that - they be descriptive in case they're referenced elsewhere. If you - can think of a way out of this, please change them. - -Thu Dec 21 12:09:34 1995 Jim Kingdon - - * cvsclient.texi (Requests): Add Questionable. Revise - documentation of export and update to explain role of -I option. - -Tue Dec 19 16:44:18 1995 Jim Kingdon - - * cvs.texinfo: Update binary files info for -kb. - -Mon Dec 11 12:20:55 1995 Jim Kingdon - - * cvsclient.texi (Responses): Add Notified and Mode. - (Requests): Add Notify, noop, watch-on, watch-off, watch-add, - watch-remove, watchers, and editors. - * cvs.texinfo (Watches): New node, to describe new developer - communication features. - -Thu Nov 23 08:59:09 1995 Jim Kingdon - - * cvs.texinfo (admin options): In saying that cvs admin -o is not - such a good way to undo a change, refer to the section which - describes the preferred way. - -Thu Nov 13 16:39:03 1995 Fred Fish - - * Makefile.in: Remove extraneous tab from empty line. - -Mon Nov 13 15:00:26 1995 Jim Kingdon - - * cvs.texinfo (Concurrency): New node, to describe user-visible - behaviors associated with cvs locks. - - * cvs.texinfo (Remote repositories): Add more details of how to - set things up (with rsh and kerberos). - -Thu Nov 9 11:41:37 1995 Jim Kingdon - - * cvs.texinfo: Remove -Q and -q options from command synopses. - -Wed Nov 8 09:38:00 1995 Jim Kingdon - - * cvsclient.texi (Notes): Revise paragraph on server memory use - problem. - -Tue Nov 7 16:26:39 1995 Jim Kingdon - - * cvs.texinfo: Document merging more than once from a branch; - miscellaneous cleanups. - -Mon Oct 30 13:12:53 1995 Jim Kingdon - - * cvs.texinfo (modules): Document -e. - -Thu Oct 26 11:15:40 1995 Jim Kingdon - - * cvs.texinfo (Tags): Update "version" vs. "revision" for CVS 1.5. - (Index,BUGS): Change bug reporting address from Per Cederqvist to - bug-cvs@prep.ai.mit.edu. - -Wed Oct 25 15:37:05 1995 Jim Kingdon - - * cvs.texinfo: Miscellaneous minor changes (clean up CVS/Root - stuff, don't say release requires a module entry, etc.). - -Tue Oct 24 11:01:22 1995 Jim Kingdon - - * cvs.texinfo: More precisely describe scope of document. - * cvsclient.texi: Describe scope of document - -Thu Oct 12 11:25:40 1995 Karl Fogel - - * cvs.texinfo: cover page now refers to CVS 1.6, and "last - updated" date has been upped to today. - -Wed Oct 11 22:30:10 1995 Jim Kingdon - - * Makefile.in (info): Look for *.info* either in build dir or in - srcdir. - -Mon Oct 2 17:10:49 1995 Norbert Kiesel - - * cvs.texinfo (admin): Describe usage of CVS_ADMIN_GROUP to - restrict usage of admin. - -Fri Oct 6 21:17:50 1995 Jim Kingdon - - * cvs.texinfo (~/.cvsrc): Document change to command name matching. - -Thu Oct 5 18:03:41 1995 Jim Kingdon - - * Makefile.in (install-info): Add comment about srcdir. - -Wed Sep 13 12:45:53 1995 Jim Kingdon - - * cvs.texinfo (Moving files): Rewrite "Outside" node to clarify - that history is still there and describe how to get it. Assorted - cleanups. - -Tue Sep 12 19:02:47 1995 Jim Kingdon - - * cvs.texinfo (Removing files): Remove section on limitations - which are gone now that we have death support. - -Wed Aug 30 12:32:29 1995 Karl Fogel - - * cvs.texinfo (Remote Repositories): new node, referred to from - `Basics' and `Repository'. - (Repository): documented new `-d' vs. `$CVSROOT' vs. `CVS/Root' - behavior. - (commitinfo): document client/server-case behavior. - (editinfo): document client/server-case behavior. - (loginfo): document client/server-case behavior. - (rcsinfo): document client/server-case behavior. - -Mon Aug 21 00:23:45 1995 Jim Kingdon - - * cvsclient.texi (How To): The way to force rsh is to set - CVS_CLIENT_PORT to -1, not to some bogus value. - -Tue Aug 15 17:12:08 1995 Karl Fogel - - * cvs.texinfo - (Basic concepts): talk about remote repositories. - (Repository): same. - -Mon Jul 24 19:09:12 1995 James Kingdon - - * cvs.texinfo: Remove references to -q and -Q command options. - -Fri Jul 21 10:33:07 1995 Vince DeMarco - - * cvs.texinfo: Changes for CVSEDITOR and wrappers. - -Thu Jul 13 23:04:12 CDT 1995 Jim Meyering (meyering@comco.com) - - * Makefile.in (cvs-paper.ps): *Never* redirect output directly to - the target (usu $@) of a rule. Instead, redirect to a temporary - file, and then move that temporary to the target. I chose to - name temporary files $@-t. Remember to be careful that the length - of the temporary file name not exceed the 14-character limit. - -Sun Jul 9 19:03:00 1995 Greg A. Woods - - * doc/cvs.texinfo: - - document '-q' for 'cvs status' - - correction to regexp use in *info files - - correction to use of 'cvsinit' script - (from previous local changes) - -Tue Jun 20 18:57:55 1995 James Kingdon - - * Makefile.in (dist-dir): Depend on $(OBJDIR_DISTFILES). - -Fri Jun 16 21:56:16 1995 Karl Fogel - and Jim Meyering - - * update.c (update_file_proc): If noexec, just write 'C', don't merge. - -Fri Jun 16 07:56:04 1995 Jim Kingdon (kingdon@cyclic.com) - - * cvs-paper.ps: Added. - -Sat May 27 08:46:00 1995 Jim Meyering (meyering@comco.com) - - * Makefile.in (Makefile): Regenerate only Makefile in current - directory when Makefile.in is out of date. Depend on ../config.status. - -Sat May 27 08:08:18 1995 Jim Meyering (meyering@comco.com) - - * doc/Makefile.in (realclean): Remove more postscript and info files. - -Fri Apr 28 22:44:06 1995 Jim Blandy - - * Makefile.in (DISTFILES): Updated. - (doc): Depend on cvsclient.ps too. - (cvs.aux, cvsclient.aux): Add target. - (cvsclient.dvi): Don't nuke the aux file. They're small and - helpful. - (cvsclient.ps): New target. - (dist-dir): Renamed from dist; changed to work with DISTDIR - variable from parent. - -Sun Apr 23 22:13:18 1995 Noel Cragg - - * Makefile: Added more files to the `clean' target. - * .cvsignore: Added the same files. - -Mon Nov 28 10:22:46 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * cvsclient.texi (Notes): Remove item about commit options; now - fixed. Rewrite paragraph about server memory usage. - - * cvsclient.texi (Responses): Add Set-checkin-prog and - Set-update-prog. - (Requests): Add Checkin-prog and Update-prog. - * cvsclient.texi (TODO): Remove last item (it is fixed) and node. - -Fri Nov 18 16:51:36 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * cvsclient.texi (Requests): Add Max-dotdot. - -Thu Nov 3 07:04:24 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * cvsclient.texi (Protocol): Add Directory request. - (TODO): Remove item about renaming directories. - (Protocol): Change @subheading to @node/@section. - -Fri Oct 28 07:51:13 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * cvsclient.texi (Protocol): Add expand-module request and - Module-expansion response. - (Protocol Notes, TODO): Remove items about cvs co funkiness. - -Wed Oct 12 19:49:36 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * cvsclient.texi (Protocol): Add Copy-file response. - - * cvsclient.texi (How To): Correct item about where declaration - of cvs commands go. - - * cvsclient.texi (Protocol): Add new commands. Merge description - of how commands work which was duplicated among the various - commands. Formatting cleanups. - (TODO): Remove item about bad error message on checking in a - nonexistent file; this works now (presumably fixed by the - Unchanged stuff). - (Notes): Remove thing about trying unsupported commands via NFS, - rdist, etc. Also remove item about some commands not being - supported. There are no unsupported commands anymore. - -Tue Sep 13 13:28:52 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * cvsclient.texi (Protocol): Document New-entry response. - -Mon Sep 12 06:35:15 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * cvsclient.texi (Protocol): Clarify that checksum is of patched - file, not patch itself. Fix typo (valid-requests -> Valid-requests). - - * cvsclient.texi (Protocol): Document Sticky request and - Set-sticky and Clear-sticky responses. - (Notes): Remove sticky tags from todo list. - -Thu Sep 8 14:23:58 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * cvsclient.texi (Protocol): Document Static-directory requests - and Set-static-directory and Clear-static-directory responses. - (Notes): Remove Entries.Static support from todo list. - - * cvsclient.texi (Protocol): Document Unchanged and UseUnchanged - requests. Update documentation of Entry and Lost accordingly. - -Mon Aug 22 14:08:21 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * cvsclient.texi (Goals): Remove mention of rsh. - (Protocol Notes, TODO): Remove compression item. - (Protocol): Document "status" request. - (TODO): Remove suggestion to add "cvs status". - -Tue Jul 19 10:02:53 1994 Ian Lance Taylor (ian@sanguine.cygnus.com) - - * Makefile.in (install-info): Do not depend upon installdirs. - -Fri Jul 15 12:56:53 1994 Ian Lance Taylor (ian@sanguine.cygnus.com) - - * Makefile.in (all): Do not depend upon info. - (install): Do not depend upon install-info. - -Thu Jul 7 20:43:12 1994 Ian Lance Taylor (ian@sanguine.cygnus.com) - - * cvsclient.texi (Protocol): Add Checksum response. - -Thu Jun 30 15:16:50 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * cvsclient.texi (Protocol): Add Global_option request. - -Wed Jun 29 14:09:42 1994 Ian Lance Taylor (ian@sanguine.cygnus.com) - - * cvsclient.texi: Describe sending patches, including the dummy - update-patches request and the Patched response. Mention Kerberos - authentication using ``cvs kserver''. Some other minor changes. - -Tue Jun 28 15:21:06 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * cvsclient.texi (Protocol Notes): Remove note about sending diffs - in Updated; Ian did it. Remove note about adding encryption to rsh. - -Sat May 7 10:44:30 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * cvsclient.texi (Protocol): Document Modified without Entry. Add - `add' and `remove' and `Remove-entry'. Formatting cleanups. - -Tue Apr 19 01:29:04 1994 John Gilmore (gnu@cygnus.com) - - * cvsclient.texi: New node How To; cleanups throughout. - * Makefile.in: Add dependencies on cvsclient.texi. - diff --git a/contrib/cvs/doc/ChangeLog.fsf b/contrib/cvs/doc/ChangeLog.fsf deleted file mode 100644 index 2f14099..0000000 --- a/contrib/cvs/doc/ChangeLog.fsf +++ /dev/null @@ -1,38 +0,0 @@ -Thu Sep 15 14:19:50 1994 david d `zoo' zuhn - - * Makefile.in: define TEXI2DVI - -Sat Dec 18 01:23:39 1993 david d zuhn (zoo@monad.armadillo.com) - - * cvs.texinfo: document -k SUBST options to 'cvs import'; - regularize use @sc{cvs} - - * Makefile.in (VPATH): don't use $(srcdir), but @srcdir@ instead - (install-info): grab all info files, not just *.info - -Mon Oct 11 16:23:54 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * cvsclient.texi: New node TODO; various other changes. - -Wed Feb 26 18:04:40 1992 K. Richard Pixley (rich@cygnus.com) - - * Makefile.in, configure.in: removed traces of namesubdir, - -subdirs, $(subdir), $(unsubdir), some rcs triggers. Forced - copyrights to '92, changed some from Cygnus to FSF. - -Tue Dec 10 04:07:10 1991 K. Richard Pixley (rich at rtl.cygnus.com) - - * Makefile.in: infodir belongs in datadir. - -Thu Dec 5 22:46:01 1991 K. Richard Pixley (rich at rtl.cygnus.com) - - * Makefile.in: idestdir and ddestdir go away. Added copyrights - and shift gpl to v2. Added ChangeLog if it didn't exist. docdir - and mandir now keyed off datadir by default. - -Wed Nov 27 02:45:18 1991 K. Richard Pixley (rich at sendai) - - * brought Makefile.in's up to standards.text. - - * fresh changelog. - diff --git a/contrib/cvs/doc/HACKING.DOCS b/contrib/cvs/doc/HACKING.DOCS deleted file mode 100644 index adf6077..0000000 --- a/contrib/cvs/doc/HACKING.DOCS +++ /dev/null @@ -1,46 +0,0 @@ -Here's some of the texinfo conventions the CVS documentation uses: - -@code{ ... } command usage & command snippets, including - command names. -@var{ ... } variables - text which the user is expected to - replace with some meaningful text of their own - in actual usage. -@file{ ... } file names -@samp{ ... } for most anything else you need quotes around - (often still misused for command snippets) -@example ... @end example example command usage and output, etc. -@emph{ ... } emphasis - warnings, stress, etc. This will be - bracketed by underline characters in info files - (_ ... _) and in italics in PDF & probably in - postscript & HTML. -@strong{ ... } Similar to @emph{}, but the effect is to - bracket with asterisks in info files (* ... *) - and in bold in PDF & probably in postscript & - HTML. -@noindent Suppresses indentation of the following - paragraph. This can ocassionally be useful - after examples and the like. -@cindex ... Add a tag to the index. -@pxref{ ... } Cross reference in parentheses. -@xref{ ... } Cross reference. - -Preformatted text should be marked as such (use @example... there may be other -ways) since many of the final output formats can use relational fonts otherwise -and marking it as formatted should restrict it to a fixed width font. Keep -this sort of text to 80 characters or less per line since larger may not be -properly viewable for some info users. - -There are dictionary lists and function definition markers. Scan cvs.texinfo -for their usage. There may be table definitions as well but I haven't used -them. - -Use lots of index markers. Scan the index for the current style. Try to reuse -an existing entry if the meaning is similar. - -`makeinfo' 3.11 or greater is required for output generation since earlier -versions do not support the @ifnottex & @ifnothtml commands. There may be -other commands used in `cvs.texinfo' that are unsupported by earlier versions -of `makeinfo' by the time you read this. - -For more on using texinfo docs, see the `info texinfo' documentation or -http://www.gnu.org/manual/texinfo/texinfo.html . diff --git a/contrib/cvs/doc/Makefile.am b/contrib/cvs/doc/Makefile.am deleted file mode 100644 index 38d719c..0000000 --- a/contrib/cvs/doc/Makefile.am +++ /dev/null @@ -1,121 +0,0 @@ -## Process this file with automake to produce Makefile.in -# Makefile for GNU CVS documentation (excluding man pages - see ../man). -# -# Copyright (C) 1986-2005 The Free Software Foundation, Inc. -# -# Portions Copyright (C) 1998-2005 Derek Price, Ximbiot , -# and others. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -info_TEXINFOS = cvs.texinfo cvsclient.texi -man_MANS = $(srcdir)/cvs.1 - -PSS = \ - cvs.ps \ - cvs-paper.ps \ - cvsclient.ps - -PDFS = \ - cvs.pdf \ - $(srcdir)/cvs-paper.pdf \ - cvsclient.pdf - -TXTS = \ - cvs.txt \ - cvsclient.txt - -EXTRA_DIST = \ - .cvsignore \ - ChangeLog.fsf \ - RCSFILES \ - mdate-sh \ - $(srcdir)/cvs.1 \ - cvs-paper.ms \ - cvs.man.header \ - cvs.man.footer \ - $(PDFS) - -MOSTLYCLEANFILES = - -CLEANFILES = \ - $(PSS) \ - $(TXTS) - -MAINTAINERCLEANFILES = \ - $(PDFS) \ - $(srcdir)/cvs.1 - -doc: info pdf -.PHONY: doc - -txt: $(TXTS) -.PHONY: txt - -dvi: cvs.dvi cvsclient.dvi -.PHONY: dvi - -# FIXME-AUTOMAKE: -# For some reason if I remove version.texi, it doesn't get built automatically. -# This needs to be fixed in automake. -cvs.txt: cvs.texinfo $(srcdir)/version.texi -cvsclient.txt: cvsclient.texi $(srcdir)/version-client.texi - -# The cvs-paper.pdf target needs to be very specific so that the other PDFs get -# generated correctly. If a more generic .ps.pdf implicit target is defined, -# and cvs.ps is made before cvs.pdf, then cvs.pdf can be generated from the -# .ps.pdf target and the PS source, which contains less information (hyperlinks -# and such) than the usual texinfo source. -# -# It is possible that an implicit .ms.ps target could be safely defined. I -# don't recall looking into it. -cvs-paper.ps: cvs-paper.ms - $(ROFF) -t -p -ms -Tps $(srcdir)/cvs-paper.ms >cvs-paper.ps-t - cp cvs-paper.ps-t $@ - -@rm -f cvs-paper.ps-t - -# This rule introduces some redundancy, but `make distcheck' requires that -# Nothing in $(srcdir) be rebuilt, and this will always be rebuilt when it -# is dependant on cvs-paper.ps and cvs-paper.ps isn't distributed. -$(srcdir)/cvs-paper.pdf: cvs-paper.ms - $(ROFF) -t -p -ms -Tps $(srcdir)/cvs-paper.ms >cvs-paper.ps-t - ps2pdf cvs-paper.ps-t cvs-paper.pdf-t - cp cvs-paper.pdf-t $@ - -@rm -f cvs-paper.pdf-t cvs-paper.ps-t - -MOSTLYCLEANFILES += cvs-paper.pdf-t cvs-paper.ps-t - -# Targets to build a man page from cvs.texinfo. -$(srcdir)/cvs.1: @MAINTAINER_MODE_TRUE@ mkman cvs.man.header cvs.texinfo cvs.man.footer - $(PERL) ./mkman $(srcdir)/cvs.man.header $(srcdir)/cvs.texinfo \ - $(srcdir)/cvs.man.footer >cvs.tmp - cp cvs.tmp $(srcdir)/cvs.1 - -@rm -f cvs.tmp - -# texinfo based targets automake neglects to include -SUFFIXES = .txt -.texinfo.txt: - $(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) \ - --no-headers -o $@ `test -f '$<' || echo '$(srcdir)/'`$< -.txi.txt: - $(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) \ - --no-headers -o $@ `test -f '$<' || echo '$(srcdir)/'`$< -.texi.txt: - $(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) \ - --no-headers -o $@ `test -f '$<' || echo '$(srcdir)/'`$< - -## -## MAINTAINER Targets -## - -# for backwards compatibility with the old makefiles -realclean: maintainer-clean -.PHONY: realclean diff --git a/contrib/cvs/doc/Makefile.in b/contrib/cvs/doc/Makefile.in deleted file mode 100644 index f3a2087..0000000 --- a/contrib/cvs/doc/Makefile.in +++ /dev/null @@ -1,816 +0,0 @@ -# Makefile.in generated by automake 1.10 from Makefile.am. -# @configure_input@ - -# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006 Free Software Foundation, Inc. -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ - -# Makefile for GNU CVS documentation (excluding man pages - see ../man). -# -# Copyright (C) 1986-2005 The Free Software Foundation, Inc. -# -# Portions Copyright (C) 1998-2005 Derek Price, Ximbiot , -# and others. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -VPATH = @srcdir@ -pkgdatadir = $(datadir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -subdir = doc -DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ - $(srcdir)/mkman.pl $(srcdir)/stamp-1 $(srcdir)/stamp-vti \ - $(srcdir)/version-client.texi $(srcdir)/version.texi ChangeLog \ - mdate-sh texinfo.tex -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ - $(top_srcdir)/configure.in -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs -CONFIG_HEADER = $(top_builddir)/config.h -CONFIG_CLEAN_FILES = mkman -SOURCES = -DIST_SOURCES = -INFO_DEPS = $(srcdir)/cvs.info $(srcdir)/cvsclient.info -am__TEXINFO_TEX_DIR = $(srcdir) -DVIS = cvs.dvi cvsclient.dvi -HTMLS = cvs.html cvsclient.html -TEXINFOS = cvs.texinfo cvsclient.texi -TEXI2PDF = $(TEXI2DVI) --pdf --batch -MAKEINFOHTML = $(MAKEINFO) --html -AM_MAKEINFOHTMLFLAGS = $(AM_MAKEINFOFLAGS) -DVIPS = dvips -am__installdirs = "$(DESTDIR)$(infodir)" "$(DESTDIR)$(man1dir)" -am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; -am__vpath_adj = case $$p in \ - $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ - *) f=$$p;; \ - esac; -am__strip_dir = `echo $$p | sed -e 's|^.*/||'`; -man1dir = $(mandir)/man1 -NROFF = nroff -MANS = $(man_MANS) -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -ACLOCAL = @ACLOCAL@ -AMTAR = @AMTAR@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -CC = @CC@ -CCDEPMODE = @CCDEPMODE@ -CFLAGS = @CFLAGS@ -CPP = @CPP@ -CPPFLAGS = @CPPFLAGS@ -CSH = @CSH@ -CYGPATH_W = @CYGPATH_W@ -DEFS = @DEFS@ -DEPDIR = @DEPDIR@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EDITOR = @EDITOR@ -EGREP = @EGREP@ -EXEEXT = @EXEEXT@ -GREP = @GREP@ -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -KRB4 = @KRB4@ -LDFLAGS = @LDFLAGS@ -LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ -LN_S = @LN_S@ -LTLIBOBJS = @LTLIBOBJS@ -MAINT = @MAINT@ -MAKEINFO = @MAKEINFO@ -MKDIR_P = @MKDIR_P@ -MKTEMP = @MKTEMP@ -OBJEXT = @OBJEXT@ -PACKAGE = @PACKAGE@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ -PACKAGE_NAME = @PACKAGE_NAME@ -PACKAGE_STRING = @PACKAGE_STRING@ -PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -PERL = @PERL@ -PR = @PR@ -PS2PDF = @PS2PDF@ -RANLIB = @RANLIB@ -ROFF = @ROFF@ -SENDMAIL = @SENDMAIL@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -STRIP = @STRIP@ -TEXI2DVI = @TEXI2DVI@ -VERSION = @VERSION@ -YACC = @YACC@ -YFLAGS = @YFLAGS@ -abs_builddir = @abs_builddir@ -abs_srcdir = @abs_srcdir@ -abs_top_builddir = @abs_top_builddir@ -abs_top_srcdir = @abs_top_srcdir@ -ac_ct_CC = @ac_ct_CC@ -ac_prefix_program = @ac_prefix_program@ -am__include = @am__include@ -am__leading_dot = @am__leading_dot@ -am__quote = @am__quote@ -am__tar = @am__tar@ -am__untar = @am__untar@ -bindir = @bindir@ -build_alias = @build_alias@ -builddir = @builddir@ -datadir = @datadir@ -datarootdir = @datarootdir@ -docdir = @docdir@ -dvidir = @dvidir@ -exec_prefix = @exec_prefix@ -host_alias = @host_alias@ -htmldir = @htmldir@ -includedir = @includedir@ -includeopt = @includeopt@ -infodir = @infodir@ -install_sh = @install_sh@ -libdir = @libdir@ -libexecdir = @libexecdir@ -localedir = @localedir@ -localstatedir = @localstatedir@ -mandir = @mandir@ -mkdir_p = @mkdir_p@ -oldincludedir = @oldincludedir@ -pdfdir = @pdfdir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -psdir = @psdir@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -srcdir = @srcdir@ -sysconfdir = @sysconfdir@ -target_alias = @target_alias@ -top_builddir = @top_builddir@ -top_srcdir = @top_srcdir@ -with_default_rsh = @with_default_rsh@ -with_default_ssh = @with_default_ssh@ -info_TEXINFOS = cvs.texinfo cvsclient.texi -man_MANS = $(srcdir)/cvs.1 -PSS = \ - cvs.ps \ - cvs-paper.ps \ - cvsclient.ps - -PDFS = \ - cvs.pdf \ - $(srcdir)/cvs-paper.pdf \ - cvsclient.pdf - -TXTS = \ - cvs.txt \ - cvsclient.txt - -EXTRA_DIST = \ - .cvsignore \ - ChangeLog.fsf \ - RCSFILES \ - mdate-sh \ - $(srcdir)/cvs.1 \ - cvs-paper.ms \ - cvs.man.header \ - cvs.man.footer \ - $(PDFS) - -MOSTLYCLEANFILES = cvs-paper.pdf-t cvs-paper.ps-t -CLEANFILES = \ - $(PSS) \ - $(TXTS) - -MAINTAINERCLEANFILES = \ - $(PDFS) \ - $(srcdir)/cvs.1 - - -# texinfo based targets automake neglects to include -SUFFIXES = .txt -all: all-am - -.SUFFIXES: -.SUFFIXES: .txt .dvi .html .info .pdf .ps .texi .texinfo .txi -$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ - && exit 0; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu doc/Makefile'; \ - cd $(top_srcdir) && \ - $(AUTOMAKE) --gnu doc/Makefile -.PRECIOUS: Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - @case '$?' in \ - *config.status*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ - *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ - esac; - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh - -$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -mkman: $(top_builddir)/config.status $(srcdir)/mkman.pl - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ - -.texinfo.info: - restore=: && backupdir="$(am__leading_dot)am$$$$" && \ - am__cwd=`pwd` && cd $(srcdir) && \ - rm -rf $$backupdir && mkdir $$backupdir && \ - if ($(MAKEINFO) --version) >/dev/null 2>&1; then \ - for f in $@ $@-[0-9] $@-[0-9][0-9] $(@:.info=).i[0-9] $(@:.info=).i[0-9][0-9]; do \ - if test -f $$f; then mv $$f $$backupdir; restore=mv; else :; fi; \ - done; \ - else :; fi && \ - cd "$$am__cwd"; \ - if $(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) \ - -o $@ $<; \ - then \ - rc=0; \ - cd $(srcdir); \ - else \ - rc=$$?; \ - cd $(srcdir) && \ - $$restore $$backupdir/* `echo "./$@" | sed 's|[^/]*$$||'`; \ - fi; \ - rm -rf $$backupdir; exit $$rc - -.texinfo.dvi: - TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \ - MAKEINFO='$(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir)' \ - $(TEXI2DVI) $< - -.texinfo.pdf: - TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \ - MAKEINFO='$(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir)' \ - $(TEXI2PDF) $< - -.texinfo.html: - rm -rf $(@:.html=.htp) - if $(MAKEINFOHTML) $(AM_MAKEINFOHTMLFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) \ - -o $(@:.html=.htp) $<; \ - then \ - rm -rf $@; \ - if test ! -d $(@:.html=.htp) && test -d $(@:.html=); then \ - mv $(@:.html=) $@; else mv $(@:.html=.htp) $@; fi; \ - else \ - if test ! -d $(@:.html=.htp) && test -d $(@:.html=); then \ - rm -rf $(@:.html=); else rm -Rf $(@:.html=.htp) $@; fi; \ - exit 1; \ - fi -$(srcdir)/cvs.info: cvs.texinfo $(srcdir)/version.texi -cvs.dvi: cvs.texinfo $(srcdir)/version.texi -cvs.pdf: cvs.texinfo $(srcdir)/version.texi -cvs.html: cvs.texinfo $(srcdir)/version.texi -$(srcdir)/version.texi: @MAINTAINER_MODE_TRUE@ $(srcdir)/stamp-vti -$(srcdir)/stamp-vti: cvs.texinfo $(top_srcdir)/configure - @(dir=.; test -f ./cvs.texinfo || dir=$(srcdir); \ - set `$(SHELL) $(srcdir)/mdate-sh $$dir/cvs.texinfo`; \ - echo "@set UPDATED $$1 $$2 $$3"; \ - echo "@set UPDATED-MONTH $$2 $$3"; \ - echo "@set EDITION $(VERSION)"; \ - echo "@set VERSION $(VERSION)") > vti.tmp - @cmp -s vti.tmp $(srcdir)/version.texi \ - || (echo "Updating $(srcdir)/version.texi"; \ - cp vti.tmp $(srcdir)/version.texi) - -@rm -f vti.tmp - @cp $(srcdir)/version.texi $@ - -mostlyclean-vti: - -rm -f vti.tmp - -maintainer-clean-vti: -@MAINTAINER_MODE_TRUE@ -rm -f $(srcdir)/stamp-vti $(srcdir)/version.texi - -.texi.info: - restore=: && backupdir="$(am__leading_dot)am$$$$" && \ - am__cwd=`pwd` && cd $(srcdir) && \ - rm -rf $$backupdir && mkdir $$backupdir && \ - if ($(MAKEINFO) --version) >/dev/null 2>&1; then \ - for f in $@ $@-[0-9] $@-[0-9][0-9] $(@:.info=).i[0-9] $(@:.info=).i[0-9][0-9]; do \ - if test -f $$f; then mv $$f $$backupdir; restore=mv; else :; fi; \ - done; \ - else :; fi && \ - cd "$$am__cwd"; \ - if $(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) \ - -o $@ $<; \ - then \ - rc=0; \ - cd $(srcdir); \ - else \ - rc=$$?; \ - cd $(srcdir) && \ - $$restore $$backupdir/* `echo "./$@" | sed 's|[^/]*$$||'`; \ - fi; \ - rm -rf $$backupdir; exit $$rc - -.texi.dvi: - TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \ - MAKEINFO='$(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir)' \ - $(TEXI2DVI) $< - -.texi.pdf: - TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \ - MAKEINFO='$(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir)' \ - $(TEXI2PDF) $< - -.texi.html: - rm -rf $(@:.html=.htp) - if $(MAKEINFOHTML) $(AM_MAKEINFOHTMLFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) \ - -o $(@:.html=.htp) $<; \ - then \ - rm -rf $@; \ - if test ! -d $(@:.html=.htp) && test -d $(@:.html=); then \ - mv $(@:.html=) $@; else mv $(@:.html=.htp) $@; fi; \ - else \ - if test ! -d $(@:.html=.htp) && test -d $(@:.html=); then \ - rm -rf $(@:.html=); else rm -Rf $(@:.html=.htp) $@; fi; \ - exit 1; \ - fi -$(srcdir)/cvsclient.info: cvsclient.texi $(srcdir)/version-client.texi -cvsclient.dvi: cvsclient.texi $(srcdir)/version-client.texi -cvsclient.pdf: cvsclient.texi $(srcdir)/version-client.texi -cvsclient.html: cvsclient.texi $(srcdir)/version-client.texi -$(srcdir)/version-client.texi: @MAINTAINER_MODE_TRUE@ $(srcdir)/stamp-1 -$(srcdir)/stamp-1: cvsclient.texi $(top_srcdir)/configure - @(dir=.; test -f ./cvsclient.texi || dir=$(srcdir); \ - set `$(SHELL) $(srcdir)/mdate-sh $$dir/cvsclient.texi`; \ - echo "@set UPDATED $$1 $$2 $$3"; \ - echo "@set UPDATED-MONTH $$2 $$3"; \ - echo "@set EDITION $(VERSION)"; \ - echo "@set VERSION $(VERSION)") > 1.tmp - @cmp -s 1.tmp $(srcdir)/version-client.texi \ - || (echo "Updating $(srcdir)/version-client.texi"; \ - cp 1.tmp $(srcdir)/version-client.texi) - -@rm -f 1.tmp - @cp $(srcdir)/version-client.texi $@ - -mostlyclean-1: - -rm -f 1.tmp - -maintainer-clean-1: -@MAINTAINER_MODE_TRUE@ -rm -f $(srcdir)/stamp-1 $(srcdir)/version-client.texi -.dvi.ps: - TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \ - $(DVIPS) -o $@ $< - -uninstall-dvi-am: - @$(NORMAL_UNINSTALL) - @list='$(DVIS)'; for p in $$list; do \ - f=$(am__strip_dir) \ - echo " rm -f '$(DESTDIR)$(dvidir)/$$f'"; \ - rm -f "$(DESTDIR)$(dvidir)/$$f"; \ - done - -uninstall-html-am: - @$(NORMAL_UNINSTALL) - @list='$(HTMLS)'; for p in $$list; do \ - f=$(am__strip_dir) \ - echo " rm -rf '$(DESTDIR)$(htmldir)/$$f'"; \ - rm -rf "$(DESTDIR)$(htmldir)/$$f"; \ - done - -uninstall-info-am: - @$(PRE_UNINSTALL) - @if test -d '$(DESTDIR)$(infodir)' && \ - (install-info --version && \ - install-info --version 2>&1 | sed 1q | grep -i -v debian) >/dev/null 2>&1; then \ - list='$(INFO_DEPS)'; \ - for file in $$list; do \ - relfile=`echo "$$file" | sed 's|^.*/||'`; \ - echo " install-info --info-dir='$(DESTDIR)$(infodir)' --remove '$(DESTDIR)$(infodir)/$$relfile'"; \ - install-info --info-dir="$(DESTDIR)$(infodir)" --remove "$(DESTDIR)$(infodir)/$$relfile"; \ - done; \ - else :; fi - @$(NORMAL_UNINSTALL) - @list='$(INFO_DEPS)'; \ - for file in $$list; do \ - relfile=`echo "$$file" | sed 's|^.*/||'`; \ - relfile_i=`echo "$$relfile" | sed 's|\.info$$||;s|$$|.i|'`; \ - (if test -d "$(DESTDIR)$(infodir)" && cd "$(DESTDIR)$(infodir)"; then \ - echo " cd '$(DESTDIR)$(infodir)' && rm -f $$relfile $$relfile-[0-9] $$relfile-[0-9][0-9] $$relfile_i[0-9] $$relfile_i[0-9][0-9]"; \ - rm -f $$relfile $$relfile-[0-9] $$relfile-[0-9][0-9] $$relfile_i[0-9] $$relfile_i[0-9][0-9]; \ - else :; fi); \ - done - -uninstall-pdf-am: - @$(NORMAL_UNINSTALL) - @list='$(PDFS)'; for p in $$list; do \ - f=$(am__strip_dir) \ - echo " rm -f '$(DESTDIR)$(pdfdir)/$$f'"; \ - rm -f "$(DESTDIR)$(pdfdir)/$$f"; \ - done - -uninstall-ps-am: - @$(NORMAL_UNINSTALL) - @list='$(PSS)'; for p in $$list; do \ - f=$(am__strip_dir) \ - echo " rm -f '$(DESTDIR)$(psdir)/$$f'"; \ - rm -f "$(DESTDIR)$(psdir)/$$f"; \ - done - -dist-info: $(INFO_DEPS) - @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ - list='$(INFO_DEPS)'; \ - for base in $$list; do \ - case $$base in \ - $(srcdir)/*) base=`echo "$$base" | sed "s|^$$srcdirstrip/||"`;; \ - esac; \ - if test -f $$base; then d=.; else d=$(srcdir); fi; \ - base_i=`echo "$$base" | sed 's|\.info$$||;s|$$|.i|'`; \ - for file in $$d/$$base $$d/$$base-[0-9] $$d/$$base-[0-9][0-9] $$d/$$base_i[0-9] $$d/$$base_i[0-9][0-9]; do \ - if test -f $$file; then \ - relfile=`expr "$$file" : "$$d/\(.*\)"`; \ - test -f $(distdir)/$$relfile || \ - cp -p $$file $(distdir)/$$relfile; \ - else :; fi; \ - done; \ - done - -mostlyclean-aminfo: - -rm -rf cvs.aux cvs.cp cvs.cps cvs.fn cvs.fns cvs.ky cvs.kys cvs.log cvs.pg \ - cvs.pgs cvs.tmp cvs.toc cvs.tp cvs.tps cvs.vr cvs.vrs \ - cvs.dvi cvs.pdf cvs.ps cvs.html cvsclient.aux cvsclient.cp \ - cvsclient.cps cvsclient.fn cvsclient.fns cvsclient.ky \ - cvsclient.kys cvsclient.log cvsclient.pg cvsclient.pgs \ - cvsclient.tmp cvsclient.toc cvsclient.tp cvsclient.tps \ - cvsclient.vr cvsclient.vrs cvsclient.dvi cvsclient.pdf \ - cvsclient.ps cvsclient.html - -maintainer-clean-aminfo: - @list='$(INFO_DEPS)'; for i in $$list; do \ - i_i=`echo "$$i" | sed 's|\.info$$||;s|$$|.i|'`; \ - echo " rm -f $$i $$i-[0-9] $$i-[0-9][0-9] $$i_i[0-9] $$i_i[0-9][0-9]"; \ - rm -f $$i $$i-[0-9] $$i-[0-9][0-9] $$i_i[0-9] $$i_i[0-9][0-9]; \ - done -install-man1: $(man1_MANS) $(man_MANS) - @$(NORMAL_INSTALL) - test -z "$(man1dir)" || $(MKDIR_P) "$(DESTDIR)$(man1dir)" - @list='$(man1_MANS) $(dist_man1_MANS) $(nodist_man1_MANS)'; \ - l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \ - for i in $$l2; do \ - case "$$i" in \ - *.1*) list="$$list $$i" ;; \ - esac; \ - done; \ - for i in $$list; do \ - if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \ - else file=$$i; fi; \ - ext=`echo $$i | sed -e 's/^.*\\.//'`; \ - case "$$ext" in \ - 1*) ;; \ - *) ext='1' ;; \ - esac; \ - inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ - inst=`echo $$inst | sed -e 's/^.*\///'`; \ - inst=`echo $$inst | sed '$(transform)'`.$$ext; \ - echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \ - $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst"; \ - done -uninstall-man1: - @$(NORMAL_UNINSTALL) - @list='$(man1_MANS) $(dist_man1_MANS) $(nodist_man1_MANS)'; \ - l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \ - for i in $$l2; do \ - case "$$i" in \ - *.1*) list="$$list $$i" ;; \ - esac; \ - done; \ - for i in $$list; do \ - ext=`echo $$i | sed -e 's/^.*\\.//'`; \ - case "$$ext" in \ - 1*) ;; \ - *) ext='1' ;; \ - esac; \ - inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ - inst=`echo $$inst | sed -e 's/^.*\///'`; \ - inst=`echo $$inst | sed '$(transform)'`.$$ext; \ - echo " rm -f '$(DESTDIR)$(man1dir)/$$inst'"; \ - rm -f "$(DESTDIR)$(man1dir)/$$inst"; \ - done -tags: TAGS -TAGS: - -ctags: CTAGS -CTAGS: - - -distdir: $(DISTFILES) - @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - list='$(DISTFILES)'; \ - dist_files=`for file in $$list; do echo $$file; done | \ - sed -e "s|^$$srcdirstrip/||;t" \ - -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ - case $$dist_files in \ - */*) $(MKDIR_P) `echo "$$dist_files" | \ - sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ - sort -u` ;; \ - esac; \ - for file in $$dist_files; do \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - if test -d $$d/$$file; then \ - dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ - fi; \ - cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ - else \ - test -f $(distdir)/$$file \ - || cp -p $$d/$$file $(distdir)/$$file \ - || exit 1; \ - fi; \ - done - $(MAKE) $(AM_MAKEFLAGS) \ - top_distdir="$(top_distdir)" distdir="$(distdir)" \ - dist-info -check-am: all-am -check: check-am -all-am: Makefile $(INFO_DEPS) $(MANS) -installdirs: - for dir in "$(DESTDIR)$(infodir)" "$(DESTDIR)$(man1dir)"; do \ - test -z "$$dir" || $(MKDIR_P) "$$dir"; \ - done -install: install-am -install-exec: install-exec-am -install-data: install-data-am -uninstall: uninstall-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-am -install-strip: - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - `test -z '$(STRIP)' || \ - echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install -mostlyclean-generic: - -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) - -clean-generic: - -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." - -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) -clean: clean-am - -clean-am: clean-generic mostlyclean-am - -distclean: distclean-am - -rm -f Makefile -distclean-am: clean-am distclean-generic - -dvi-am: $(DVIS) - -html: html-am - -html-am: $(HTMLS) - -info: info-am - -info-am: $(INFO_DEPS) - -install-data-am: install-info-am install-man - -install-dvi: install-dvi-am - -install-dvi-am: $(DVIS) - @$(NORMAL_INSTALL) - test -z "$(dvidir)" || $(MKDIR_P) "$(DESTDIR)$(dvidir)" - @list='$(DVIS)'; for p in $$list; do \ - if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ - f=$(am__strip_dir) \ - echo " $(INSTALL_DATA) '$$d$$p' '$(DESTDIR)$(dvidir)/$$f'"; \ - $(INSTALL_DATA) "$$d$$p" "$(DESTDIR)$(dvidir)/$$f"; \ - done -install-exec-am: - -install-html: install-html-am - -install-html-am: $(HTMLS) - @$(NORMAL_INSTALL) - test -z "$(htmldir)" || $(MKDIR_P) "$(DESTDIR)$(htmldir)" - @list='$(HTMLS)'; for p in $$list; do \ - if test -f "$$p" || test -d "$$p"; then d=; else d="$(srcdir)/"; fi; \ - f=$(am__strip_dir) \ - if test -d "$$d$$p"; then \ - echo " $(MKDIR_P) '$(DESTDIR)$(htmldir)/$$f'"; \ - $(MKDIR_P) "$(DESTDIR)$(htmldir)/$$f" || exit 1; \ - echo " $(INSTALL_DATA) '$$d$$p'/* '$(DESTDIR)$(htmldir)/$$f'"; \ - $(INSTALL_DATA) "$$d$$p"/* "$(DESTDIR)$(htmldir)/$$f"; \ - else \ - echo " $(INSTALL_DATA) '$$d$$p' '$(DESTDIR)$(htmldir)/$$f'"; \ - $(INSTALL_DATA) "$$d$$p" "$(DESTDIR)$(htmldir)/$$f"; \ - fi; \ - done -install-info: install-info-am - -install-info-am: $(INFO_DEPS) - @$(NORMAL_INSTALL) - test -z "$(infodir)" || $(MKDIR_P) "$(DESTDIR)$(infodir)" - @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ - list='$(INFO_DEPS)'; \ - for file in $$list; do \ - case $$file in \ - $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ - esac; \ - if test -f $$file; then d=.; else d=$(srcdir); fi; \ - file_i=`echo "$$file" | sed 's|\.info$$||;s|$$|.i|'`; \ - for ifile in $$d/$$file $$d/$$file-[0-9] $$d/$$file-[0-9][0-9] \ - $$d/$$file_i[0-9] $$d/$$file_i[0-9][0-9] ; do \ - if test -f $$ifile; then \ - relfile=`echo "$$ifile" | sed 's|^.*/||'`; \ - echo " $(INSTALL_DATA) '$$ifile' '$(DESTDIR)$(infodir)/$$relfile'"; \ - $(INSTALL_DATA) "$$ifile" "$(DESTDIR)$(infodir)/$$relfile"; \ - else : ; fi; \ - done; \ - done - @$(POST_INSTALL) - @if (install-info --version && \ - install-info --version 2>&1 | sed 1q | grep -i -v debian) >/dev/null 2>&1; then \ - list='$(INFO_DEPS)'; \ - for file in $$list; do \ - relfile=`echo "$$file" | sed 's|^.*/||'`; \ - echo " install-info --info-dir='$(DESTDIR)$(infodir)' '$(DESTDIR)$(infodir)/$$relfile'";\ - install-info --info-dir="$(DESTDIR)$(infodir)" "$(DESTDIR)$(infodir)/$$relfile" || :;\ - done; \ - else : ; fi -install-man: install-man1 - -install-pdf: install-pdf-am - -install-pdf-am: $(PDFS) - @$(NORMAL_INSTALL) - test -z "$(pdfdir)" || $(MKDIR_P) "$(DESTDIR)$(pdfdir)" - @list='$(PDFS)'; for p in $$list; do \ - if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ - f=$(am__strip_dir) \ - echo " $(INSTALL_DATA) '$$d$$p' '$(DESTDIR)$(pdfdir)/$$f'"; \ - $(INSTALL_DATA) "$$d$$p" "$(DESTDIR)$(pdfdir)/$$f"; \ - done -install-ps: install-ps-am - -install-ps-am: $(PSS) - @$(NORMAL_INSTALL) - test -z "$(psdir)" || $(MKDIR_P) "$(DESTDIR)$(psdir)" - @list='$(PSS)'; for p in $$list; do \ - if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ - f=$(am__strip_dir) \ - echo " $(INSTALL_DATA) '$$d$$p' '$(DESTDIR)$(psdir)/$$f'"; \ - $(INSTALL_DATA) "$$d$$p" "$(DESTDIR)$(psdir)/$$f"; \ - done -installcheck-am: - -maintainer-clean: maintainer-clean-am - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-1 \ - maintainer-clean-aminfo maintainer-clean-generic \ - maintainer-clean-vti - -mostlyclean: mostlyclean-am - -mostlyclean-am: mostlyclean-1 mostlyclean-aminfo mostlyclean-generic \ - mostlyclean-vti - -pdf: pdf-am - -pdf-am: $(PDFS) - -ps: ps-am - -ps-am: $(PSS) - -uninstall-am: uninstall-dvi-am uninstall-html-am uninstall-info-am \ - uninstall-man uninstall-pdf-am uninstall-ps-am - -uninstall-man: uninstall-man1 - -.MAKE: install-am install-strip - -.PHONY: all all-am check check-am clean clean-generic dist-info \ - distclean distclean-generic distdir dvi dvi-am html html-am \ - info info-am install install-am install-data install-data-am \ - install-dvi install-dvi-am install-exec install-exec-am \ - install-html install-html-am install-info install-info-am \ - install-man install-man1 install-pdf install-pdf-am install-ps \ - install-ps-am install-strip installcheck installcheck-am \ - installdirs maintainer-clean maintainer-clean-1 \ - maintainer-clean-aminfo maintainer-clean-generic \ - maintainer-clean-vti mostlyclean mostlyclean-1 \ - mostlyclean-aminfo mostlyclean-generic mostlyclean-vti pdf \ - pdf-am ps ps-am uninstall uninstall-am uninstall-dvi-am \ - uninstall-html-am uninstall-info-am uninstall-man \ - uninstall-man1 uninstall-pdf-am uninstall-ps-am - - -doc: info pdf -.PHONY: doc - -txt: $(TXTS) -.PHONY: txt - -dvi: cvs.dvi cvsclient.dvi -.PHONY: dvi - -# FIXME-AUTOMAKE: -# For some reason if I remove version.texi, it doesn't get built automatically. -# This needs to be fixed in automake. -cvs.txt: cvs.texinfo $(srcdir)/version.texi -cvsclient.txt: cvsclient.texi $(srcdir)/version-client.texi - -# The cvs-paper.pdf target needs to be very specific so that the other PDFs get -# generated correctly. If a more generic .ps.pdf implicit target is defined, -# and cvs.ps is made before cvs.pdf, then cvs.pdf can be generated from the -# .ps.pdf target and the PS source, which contains less information (hyperlinks -# and such) than the usual texinfo source. -# -# It is possible that an implicit .ms.ps target could be safely defined. I -# don't recall looking into it. -cvs-paper.ps: cvs-paper.ms - $(ROFF) -t -p -ms -Tps $(srcdir)/cvs-paper.ms >cvs-paper.ps-t - cp cvs-paper.ps-t $@ - -@rm -f cvs-paper.ps-t - -# This rule introduces some redundancy, but `make distcheck' requires that -# Nothing in $(srcdir) be rebuilt, and this will always be rebuilt when it -# is dependant on cvs-paper.ps and cvs-paper.ps isn't distributed. -$(srcdir)/cvs-paper.pdf: cvs-paper.ms - $(ROFF) -t -p -ms -Tps $(srcdir)/cvs-paper.ms >cvs-paper.ps-t - ps2pdf cvs-paper.ps-t cvs-paper.pdf-t - cp cvs-paper.pdf-t $@ - -@rm -f cvs-paper.pdf-t cvs-paper.ps-t - -# Targets to build a man page from cvs.texinfo. -$(srcdir)/cvs.1: @MAINTAINER_MODE_TRUE@ mkman cvs.man.header cvs.texinfo cvs.man.footer - $(PERL) ./mkman $(srcdir)/cvs.man.header $(srcdir)/cvs.texinfo \ - $(srcdir)/cvs.man.footer >cvs.tmp - cp cvs.tmp $(srcdir)/cvs.1 - -@rm -f cvs.tmp -.texinfo.txt: - $(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) \ - --no-headers -o $@ `test -f '$<' || echo '$(srcdir)/'`$< -.txi.txt: - $(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) \ - --no-headers -o $@ `test -f '$<' || echo '$(srcdir)/'`$< -.texi.txt: - $(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) \ - --no-headers -o $@ `test -f '$<' || echo '$(srcdir)/'`$< - -# for backwards compatibility with the old makefiles -realclean: maintainer-clean -.PHONY: realclean -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/contrib/cvs/doc/RCSFILES b/contrib/cvs/doc/RCSFILES deleted file mode 100644 index 4650337..0000000 --- a/contrib/cvs/doc/RCSFILES +++ /dev/null @@ -1,276 +0,0 @@ -It would be nice if the RCS file format (which is implemented by a -great many tools, both free and non-free, both by calling GNU RCS and -by reimplementing access to RCS files) were documented in some -standard separate from any one tool. But as far as I know no such -standard exists. Hence this file. - -The place to start is the rcsfile.5 manpage in the GNU RCS 5.7 -distribution. Then look at the diff at the end of this file (which -contains a few fixes and clarifications to that manpage). - -If you are interested in MKS RCS, src/ci.c in GNU RCS 5.7 has a -comment about their date format. However, as far as we know there -isn't really any document describing MKS's changes to the RCS file -format. - -The rcsfile.5 manpage does not document what goes in the "text" field -for each revision. The answer is that the head revision contains the -contents of that revision and every other revision contain a bunch of -edits to produce that revision ("a" and "d" lines). The GNU diff -manual (the version I looked at was for GNU diff 2.4) documents this -format somewhat (as the "RCS output format"), but the presentation is -a bit confusing as it is all tangled up with the documentation of -several other output formats. If you just want some source code to -look at, the part of CVS which applies these is RCS_deltas in -src/rcs.c. - -The rcsfile.5 documentation only _very_ briefly touches on the order -of the revisions. The order _is_ important and CVS relies on it. -Here is an example of what I was able to find, based on the join3 -sanity.sh testcase (and the behavior I am documenting here seems to be -the same for RCS 5.7 and CVS 1.9.27): - - 1.1 -----------------> 1.2 - \---> 1.1.2.1 \---> 1.2.2.1 - -Here is how this shows up in the RCS file (omitting irrelevant parts): - - admin: head 1.2; - deltas: - 1.2 branches 1.2.2.1; next 1.1; - 1.1 branches 1.1.2.1; next; - 1.1.2.1 branches; next; - 1.2.2.1 branches; next; - deltatexts: - 1.2 - 1.2.2.1 - 1.1 - 1.1.2.1 - -Yes, the order seems to differ between the deltas and the deltatexts. -I have no idea how much of this should actually be considered part of -the RCS file format, and how much programs reading it should expect to -encounter any order. - -The rcsfile.5 grammar shows the {num} after "next" as optional; if it -is omitted then there is no next delta node (for example 1.1 or the -head of a branch will typically have no next). - -There is one case where CVS uses CVS-specific, non-compatible changes -to the RCS file format, and this is magic branches. See cvs.texinfo -for more information on them. CVS also sets the RCS state to "dead" -to indicate that a file does not exist in a given revision (this is -stored just as any other RCS state is). - -The RCS file format allows quite a variety of extensions to be added -in a compatible manner by use of the "newphrase" feature documented in -rcsfile.5. We won't try to document extensions not used by CVS in any -detail, but we will briefly list them. Each occurrence of a newphrase -begins with an identifier, which is what we list here. Future -designers of extensions are strongly encouraged to pick -non-conflicting identifiers. Note that newphrase occurs several -places in the RCS grammar, and a given extension may not be legal in -all locations. However, it seems better to reserve a particular -identifier for all locations, to avoid confusion and complicated -rules. - - Identifier Used by - ---------- ------- - namespace RCS library done at Silicon Graphics Inc. (SGI) in 1996 - (a modified RCS 5.7--not sure it has any other name). - dead A set of RCS patches developed by Rich Pixley at - Cygnus about 1992. These were for CVS, and predated - the current CVS death support, which uses a state "dead" - rather than a "dead" newphrase. - -CVS does use newphrases to implement the `PreservePermissions' -extension introduced in CVS 1.9.26. The following new keywords are -defined when PreservePermissions=yes: - - owner - group - permissions - special - symlink - hardlinks - -The contents of the `owner' and `group' field should be a numeric uid -and a numeric gid, respectively, representing the user and group who -own the file. The `permissions' field contains an octal integer, -representing the permissions that should be applied to the file. The -`special' field contains two words; the first must be either `block' -or `character', and the second is the file's device number. The -`symlink' field should be present only in files which are symbolic -links to other files, and absent on all regular files. The -`hardlinks' field contains a list of filenames to which the current -file is linked, in alphabetical order. Because files often contain -characters special to RCS, like `.' and sometimes even contain spaces -or eight-bit characters, the filenames in the hardlinks field will -usually be enclosed in RCS strings. For example: - - hardlinks README @install.txt@ @Installation Notes@; - -The hardlinks field should always include the name of the current -file. That is, in the repository file README,v, any hardlinks fields -in the delta nodes should include `README'; CVS will not operate -properly if this is not done. - -The rules regarding keyword expansion are not documented along with -the rest of the RCS file format; they are documented in the co(1) -manpage in the RCS 5.7 distribution. See also the "Keyword -substitution" chapter of cvs.texinfo. The co(1) manpage refers to -special behavior if the log prefix for the $Log keyword is /* or (*. -RCS 5.7 produces a warning whenever it behaves that way, and current -versions of CVS do not handle this case in a special way (CVS 1.9 and -earlier invoke RCS to perform keyword expansion). - -Note that if the "expand" keyword is omitted from the RCS file, the -default is "kv". - -Note that the "comment {string};" syntax from rcsfile.5 specifies a -comment leader, which affects expansion of the $Log keyword for old -versions of RCS. The comment leader is not used by RCS 5.7 or current -versions of CVS. - -Both RCS 5.7 and current versions of CVS handle the $Log keyword in a -different way if the log message starts with "checked in with -k by ". -I don't think this behavior is documented anywhere. - -Here is a clarification regarding characters versus bytes in certain -character sets like JIS and Big5: - - The RCS file format, as described in the rcsfile(5) man page, is - actually byte-oriented, not character-oriented, despite hints to - the contrary in the man page. This distinction is important for - multibyte characters. For example, if a multibyte character - contains a `@' byte, the `@' must be doubled within strings in RCS - files, since RCS uses `@' bytes as escapes. - - This point is not an issue for encodings like ISO 8859, which do - not have multibyte characters. Nor is it an issue for encodings - like UTF-8 and EUC-JIS, which never uses ASCII bytes within a - multibyte character. It is an issue only for multibyte encodings - like JIS and BIG5, which _do_ usurp ASCII bytes. - - If `@' doubling occurs within a multibyte char, the resulting RCS - file is not a properly encoded text file. Instead, it is a byte - stream that does not use a consistent character encoding that can - be understood by the usual text tools, since doubling `@' messes - up the encoding. This point affects only programs that examine - the RCS files -- it doesn't affect the external RCS interface, as - the RCS commands always give you the properly encoded text files - and logs (assuming that you always check in properly encoded - text). - - CVS 1.10 (and earlier) probably has some bugs in this area on - systems where a C "char" is signed and where the data contains - bytes with the eighth bit set. - -One common concern about the RCS file format is the fact that to get -the head of a branch, one must apply deltas from the head of the trunk -to the branchpoint, and then from the branchpoint to the head of the -branch. While more detailed analyses might be worth doing, we will -note: - - * The performance bottleneck for CVS generally is figuring out which - files to operate on and that sort of thing, not applying deltas. - - * Here is one quick test (probably not a very good test; a better test - would use a normally sized file (say 50-200K) instead of a small one): - - I just did a quick test with a small file (on a Sun Ultra 1/170E - running Solaris 5.5.1), with 1000 revisions on the main branch and - 1000 revisions on branch that forked at the root (i.e., RCS revisions - 1.1, 1.2, ..., 1.1000, and branch revisions 1.1.1.1, 1.1.1.2, ..., - 1.1.1.1000). It took about 0.15 seconds real time to check in the - first revision, and about 0.6 seconds to check in and 0.3 seconds to - retrieve revision 1.1.1.1000 (the worst case). - - * Any attempt to "fix" this problem should be careful not to interfere - with other features, such as lightweight creation of branches - (particularly using CVS magic branches). - -Diff follows: - -(Note that in the following diff the old value for the Id keyword was: - Id: rcsfile.5in,v 5.6 1995/06/05 08:28:35 eggert Exp -and the new one was: - Id: rcsfile.5in,v 5.7 1996/12/09 17:31:44 eggert Exp -but since this file itself might be subject to keyword expansion I -haven't included a diff for that fact). - -=================================================================== -RCS file: RCS/rcsfile.5in,v -retrieving revision 5.6 -retrieving revision 5.7 -diff -u -r5.6 -r5.7 ---- rcsfile.5in 1995/06/05 08:28:35 5.6 -+++ rcsfile.5in 1996/12/09 17:31:44 5.7 -@@ -85,7 +85,8 @@ - .LP - \f2sym\fP ::= {\f2digit\fP}* \f2idchar\fP {\f2idchar\fP | \f2digit\fP}* - .LP --\f2idchar\fP ::= any visible graphic character except \f2special\fP -+\f2idchar\fP ::= any visible graphic character, -+ except \f2digit\fP or \f2special\fP - .LP - \f2special\fP ::= \f3$\fP | \f3,\fP | \f3.\fP | \f3:\fP | \f3;\fP | \f3@\fP - .LP -@@ -119,12 +120,23 @@ - the minute (00\-59), - and - .I ss --the second (00\-60). -+the second (00\-59). -+If - .I Y --contains just the last two digits of the year --for years from 1900 through 1999, --and all the digits of years thereafter. --Dates use the Gregorian calendar; times use UTC. -+contains exactly two digits, -+they are the last two digits of a year from 1900 through 1999; -+otherwise, -+.I Y -+contains all the digits of the year. -+Dates use the Gregorian calendar. -+Times use UTC, except that for portability's sake leap seconds are not allowed; -+implementations that support leap seconds should output -+.B 59 -+for -+.I ss -+during an inserted leap second, and should accept -+.B 59 -+for a deleted leap second. - .PP - The - .I newphrase -@@ -144,16 +156,23 @@ - field in order of decreasing numbers. - The - .B head --field in the --.I admin --node points to the head of that sequence (i.e., contains -+field points to the head of that sequence (i.e., contains - the highest pair). - The - .B branch --node in the admin node indicates the default -+field indicates the default - branch (or revision) for most \*r operations. - If empty, the default - branch is the highest branch on the trunk. -+The -+.B symbols -+field associates symbolic names with revisions. -+For example, if the file contains -+.B "symbols rr:1.1;" -+then -+.B rr -+is a name for revision -+.BR 1.1 . - .PP - All - .I delta - diff --git a/contrib/cvs/doc/cvs-paper.ms b/contrib/cvs/doc/cvs-paper.ms deleted file mode 100644 index ea9445a..0000000 --- a/contrib/cvs/doc/cvs-paper.ms +++ /dev/null @@ -1,1069 +0,0 @@ -.\" soelim cvs.ms | pic | tbl | troff -ms -.\" @(#)cvs.ms 1.2 92/01/30 -.\" -.\" troff source to the cvs USENIX article, Winter 1990, Washington, D.C. -.\" Copyright (c) 1989, Brian Berliner -.\" -.\" This program is free software; you can redistribute it and/or modify -.\" it under the terms of the GNU General Public License as published by -.\" the Free Software Foundation; either version 1, or (at your option) -.\" any later version. -.\" -.\" This program is distributed in the hope that it will be useful, -.\" but WITHOUT ANY WARRANTY; without even the implied warranty of -.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -.\" GNU General Public License for more details. -.\" -.\" The author can be reached at: berliner@prisma.com -.\" -.de SP -.if n .sp -.if t .sp .5 -.. -.de hl -.br -.in +0.5i -\l'\\n(LLu-1i' -.in -0.5i -.sp -.. -.OH "" -.nr PS 11 -.nr PO 1.25i -.pl -0.2i -.TL -.ps 14 -.ft B -.nf -CVS II: -Parallelizing Software Development -.fi -.ft -.ps -.AU -.ps 12 -.ft I -Brian Berliner -.ft -.ps -.AI -.ps 12 -.ft I -Prisma, Inc. -5465 Mark Dabling Blvd. -Colorado Springs, CO 80918 -berliner@prisma.com -.ft -.ps -.AB -The program described in this paper fills a need in the UNIX -community for a freely available tool to manage software revision and -release control in a multi-developer, multi-directory, multi-group -environment. -This tool also addresses the increasing need for tracking third-party vendor -source distributions while trying to maintain local modifications to -earlier releases. -.AE -.NH -Background -.PP -In large software development projects, it is usually necessary for more -than one software developer to be modifying (usually different) modules of the -code at the same time. -Some of these code modifications are done in an -experimental sense, at least until the code functions correctly, and some -testing of the entire program is usually necessary. -Then, the modifications are returned to a master source repository -so that others in the project can -enjoy the new bug-fix or functionality. -In order to manage such a project, some sort of revision control system is -necessary. -.PP -Specifically, UNIX\** -.FS -UNIX is a registered trademark of AT&T. -.FE -kernel development is an excellent example of the -problems that an adequate revision control system must address. -The SunOS\** -.FS -SunOS is a trademark of Sun Microsystems, Inc. -.FE -kernel is composed of over a thousand files spread across a -hierarchy of dozens of directories.\** -.FS -Yes, the SunOS 4.0 kernel is composed of over a \fIthousand\fP files! -.FE -Pieces of the kernel must be edited -by many software developers within an organization. -While undesirable in -theory, it is not uncommon to have two or more people making -modifications to the same file within the kernel sources in -order to facilitate a desired change. -Existing revision control systems like -.SM -RCS -.LG -[Tichy] or -.SM -SCCS -.LG -[Bell] serialize file modifications by -allowing only one developer to have a writable copy of a particular file at -any one point in time. -That developer is said to -have \*Qlocked\*U the file for his exclusive use, and no other developer is -allowed to check out a writable copy of the file until the locking -developer has finished impeding others' productivity. -Development pressures of productivity and deadlines -often force organizations to require that multiple developers be able to -simultaneously edit -copies of the same revision controlled file. -.PP -The necessity for multiple developers to modify the same file concurrently -questions the value of serialization-based policies in traditional revision -control. -This paper discusses the approach that -Prisma took in adapting a standard revision control system, -.SM -RCS\c -.LG -, along with an existing public-domain collection of shell scripts that sits -atop -.SM -RCS -.LG -and provides the basic conflict-resolution algorithms. -The resulting -program, \fBcvs\fP, addresses not only the issue of conflict-resolution in -a multi-developer open-editing environment, but also the issues of -software release control and vendor source support and integration. -.NH -The CVS Program -.PP -\fBcvs\fP -(Concurrent Versions System) -is a front end to the -.SM -RCS -.LG -revision control system which extends -the notion of revision control from a collection of files in a single -directory to a hierarchical collection of directories each containing -revision controlled files. -Directories and files in the \fBcvs\fP system can be combined together in -many ways to form a software release. -\fBcvs\fP -provides the functions necessary to manage these software releases and to -control the concurrent editing of source files among multiple software -developers. -.PP -The six major features of \fBcvs\fP are listed below, and will be -described in more detail in the following sections: -.RS -.IP 1. -Concurrent access and conflict-resolution algorithms to guarantee that -source changes are not \*Qlost.\*U -.IP 2. -Support for tracking third-party vendor source distributions while -maintaining the local modifications made to those sources. -.IP 3. -A flexible module database that provides a symbolic mapping of names to -components of a larger software distribution. -This symbolic mapping provides for location independence within the software -release and, for example, allows one to check out a copy of the \*Qdiff\*U -program without ever knowing that the sources to \*Qdiff\*U actually reside -in the \*Qbin/diff\*U directory. -.IP 4. -Configurable logging support allows all \*Qcommitted\*U source file changes -to be logged using an arbitrary program to save the log messages in a file, -notesfile, or news database. -.IP 5. -A software release can be symbolically tagged and checked out at any time -based on that tag. -An exact copy of a previous software release can be checked out at -any time, \fIregardless\fP of whether files or directories have been -added/removed from the \*Qcurrent\*U software release. -As well, -a \*Qdate\*U can be used to check out the \fIexact\fP version of the software -release as of the specified date. -.IP 6. -A \*Qpatch\*U format file [Wall] can be produced between two software -releases, even if the releases span multiple directories. -.RE -.PP -The sources maintained by \fBcvs\fP are kept within a single directory -hierarchy known as the \*Qsource repository.\*U -This \*Qsource repository\*U holds the actual -.SM -RCS -.LG -\*Q,v\*U files directly, as well as a special per-repository directory -(\c -.SM -CVSROOT.adm\c -.LG -) which contains a small number of administrative files that describe the -repository and how it can be accessed. -See Figure 1 for a picture of the \fBcvs\fP tree. -.KF -.hl -.DS B -.PS -line from 4.112,9.200 to 5.550,8.887 -line from 5.447,8.884 to 5.550,8.887 to 5.458,8.933 -line from 4.112,9.200 to 4.550,8.950 -line from 4.451,8.978 to 4.550,8.950 to 4.476,9.021 -line from 4.112,9.200 to 3.737,8.887 -line from 3.798,8.971 to 3.737,8.887 to 3.830,8.932 -line from 3.612,8.762 to 4.737,8.137 -line from 4.638,8.164 to 4.737,8.137 to 4.662,8.208 -line from 3.612,8.762 to 3.737,8.137 -line from 3.693,8.231 to 3.737,8.137 to 3.742,8.240 -line from 3.612,8.762 to 2.612,8.200 -line from 2.687,8.271 to 2.612,8.200 to 2.712,8.227 -line from 2.362,9.262 to 2.737,8.950 -line from 2.645,8.995 to 2.737,8.950 to 2.677,9.033 -line from 2.362,9.262 to 1.925,8.950 -line from 1.992,9.028 to 1.925,8.950 to 2.021,8.988 -line from 3.362,9.762 to 4.050,9.387 -line from 3.950,9.413 to 4.050,9.387 to 3.974,9.457 -line from 3.362,9.762 to 2.487,9.387 -line from 2.570,9.450 to 2.487,9.387 to 2.589,9.404 -.ps 11 -"newfs.c,v" at 4.487,8.043 ljust -.ps 11 -"mkfs.c,v" at 3.487,8.043 ljust -.ps 11 -"Makefile,v" at 2.237,8.043 ljust -.ps 11 -"newfs" at 3.487,8.793 ljust -.ps 11 -"halt.c,v" at 5.487,8.793 ljust -.ps 11 -"Makefile,v" at 4.237,8.793 ljust -.ps 11 -"modules,v" at 2.487,8.793 ljust -.ps 11 -"loginfo,v" at 1.488,8.793 ljust -.ps 11 -"etc" at 3.987,9.293 ljust -.ps 11 -"CVSROOT.adm" at 1.988,9.293 ljust -.ps 11 -"/src/master" at 2.987,9.793 ljust -.PE -.DE -.hl -.ce 100 -.LG -\fBFigure 1.\fP -.SM -\fBcvs\fP Source Repository -.ce 0 -.sp -.KE -.NH 2 -Software Conflict Resolution\** -.FS -The basic conflict-resolution algorithms -used in the \fBcvs\fP program find their roots -in the original work done by Dick Grune at Vrije Universiteit in Amsterdam -and posted to \fBcomp.sources.unix\fP in the volume 6 release sometime in 1986. -This original version of \fBcvs\fP was a collection of shell scripts that -combined to form a front end to the -.SM -RCS -.LG -programs. -.FE -.PP -\fBcvs\fP allows several software developers to edit personal copies of a -revision controlled file concurrently. -The revision number of each checked out file is maintained independently -for each user, and \fBcvs\fP forces the checked out file to be current with -the \*Qhead\*U revision before it can be \*Qcommitted\*U as a permanent change. -A checked out file is brought up-to-date with the \*Qhead\*U revision using -the \*Qupdate\*U command of \fBcvs\fP. -This command compares the \*Qhead\*U revision number with that of the user's -file and performs an -.SM -RCS -.LG -merge operation if they are not the same. -The result of the merge is a file that contains the user's modifications -and those modifications that were \*Qcommitted\*U after the user -checked out his version of the file (as well as a backup copy of the -user's original file). -\fBcvs\fP points out any conflicts during the merge. -It is the user's responsibility to resolve these conflicts -and to \*Qcommit\*U his/her changes when ready. -.PP -Although the \fBcvs\fP conflict-resolution algorithm was defined in 1986, -it is remarkably similar to the \*QCopy-Modify-Merge\*U scenario included -with NSE\** -.FS -NSE is the Network Software Environment, a product of Sun Microsystems, Inc. -.FE -and described in [Honda] and [Courington]. -The following explanation from [Honda] also applies to \fBcvs\fP: -.QP -Simply stated, a developer copies an object without locking it, modifies -the copy, and then merges the modified copy with the original. -This paradigm allows developers to work in isolation from one another since -changes are made to copies of objects. -Because locks are not used, development is not serialized and can proceed -in parallel. -Developers, however, must merge objects after the changes have been made. -In particular, a developer must resolve conflicts when the same object has -been modified by someone else. -.PP -In practice, Prisma has found that conflicts that occur when the same -object has been modified by someone else are quite rare. -When they do happen, the changes made by the other developer are usually -easily resolved. -This practical use has shown that the \*QCopy-Modify-Merge\*U paradigm is a -correct and useful one. -.NH 2 -Tracking Third-Party Source Distributions -.PP -Currently, a large amount of software is based on source -distributions from a third-party distributor. -It is often the case that local modifications are to be made to this -distribution, \fIand\fP that the vendor's future releases should be -tracked. -Rolling your local modifications forward into the new vendor release is a -time-consuming task, but \fBcvs\fP can ease this burden somewhat. -The \fBcheckin\fP program of \fBcvs\fP initially sets up a source -repository by integrating the source modules directly from the vendor's -release, preserving the directory hierarchy of the vendor's distribution. -The branch support of -.SM -RCS -.LG -is used to build this vendor release as a branch of the main -.SM -RCS -.LG -trunk. -Figure 2 shows how the \*Qhead\*U tracks a sample vendor -branch when no local modifications have been made to the file. -.KF -.hl -.DS B -.PS -ellipse at 3.237,6.763 wid 1.000 ht 0.500 -dashwid = 0.050i -line dashed from 3.237,7.513 to 3.737,7.513 to 3.737,9.762 to 4.237,9.762 -line from 4.138,9.737 to 4.237,9.762 to 4.138,9.787 -line dashed from 2.237,8.262 to 3.237,8.262 to 3.237,7.013 -line from 3.212,7.112 to 3.237,7.013 to 3.262,7.112 -line from 3.737,6.763 to 4.237,6.763 -line from 4.138,6.737 to 4.237,6.763 to 4.138,6.788 -line from 2.237,6.763 to 2.737,6.763 -line from 2.637,6.737 to 2.737,6.763 to 2.637,6.788 -line from 1.738,6.013 to 1.738,6.513 -line from 1.762,6.413 to 1.738,6.513 to 1.713,6.413 -line from 1.238,7.013 to 2.237,7.013 to 2.237,6.513 to 1.238,6.513 to 1.238,7.013 -line from 4.237,9.012 to 5.237,9.012 to 5.237,8.512 to 4.237,8.512 to 4.237,9.012 -line from 4.237,8.012 to 5.237,8.012 to 5.237,7.513 to 4.237,7.513 to 4.237,8.012 -line from 4.237,7.013 to 5.237,7.013 to 5.237,6.513 to 4.237,6.513 to 4.237,7.013 -line from 4.737,7.013 to 4.737,7.513 -line from 4.763,7.413 to 4.737,7.513 to 4.712,7.413 -line from 4.737,8.012 to 4.737,8.512 -line from 4.763,8.412 to 4.737,8.512 to 4.712,8.412 -line from 4.237,10.012 to 5.237,10.012 to 5.237,9.512 to 4.237,9.512 to 4.237,10.012 -line from 4.737,9.012 to 4.737,9.512 -line from 4.763,9.412 to 4.737,9.512 to 4.712,9.412 -line from 5.987,5.013 to 5.987,6.013 to 0.988,6.013 to 0.988,5.013 to 5.987,5.013 -.ps 11 -"\"HEAD\"" at 1.550,8.231 ljust -.ps 11 -"'SunOS'" at 2.987,6.293 ljust -.ps 11 -"1.1.1" at 3.050,6.793 ljust -.ps 11 -"1.1" at 1.613,6.793 ljust -.ps 11 -"1.1.1.1" at 4.487,6.793 ljust -.ps 11 -"1.1.1.2" at 4.487,7.793 ljust -.ps 11 -"1.1.1.3" at 4.487,8.793 ljust -.ps 11 -"1.1.1.4" at 4.487,9.793 ljust -.ps 11 -"'SunOS_4_0'" at 5.487,6.793 ljust -.ps 11 -"'SunOS_4_0_1'" at 5.487,7.793 ljust -.ps 11 -"'YAPT_5_5C'" at 5.487,8.793 ljust -.ps 11 -"'SunOS_4_0_3'" at 5.487,9.793 ljust -.ps 11 -"rcsfile.c,v" at 2.987,5.543 ljust -.PE -.DE -.hl -.ce 100 -.LG -\fBFigure 2.\fP -.SM -\fBcvs\fP Vendor Branch Example -.ce 0 -.sp .3 -.KE -Once this is done, developers can check out files and make local changes to -the vendor's source distribution. -These local changes form a new branch to the tree which is then used as the -source for future check outs. -Figure 3 shows how the \*Qhead\*U moves to the main -.SM -RCS -.LG -trunk when a local modification is made. -.KF -.hl -.DS B -.PS -ellipse at 3.237,6.763 wid 1.000 ht 0.500 -dashwid = 0.050i -line dashed from 2.800,9.075 to 1.738,9.075 to 1.738,8.012 -line from 1.713,8.112 to 1.738,8.012 to 1.762,8.112 -line from 1.738,7.013 to 1.738,7.513 -line from 1.762,7.413 to 1.738,7.513 to 1.713,7.413 -line from 1.238,8.012 to 2.237,8.012 to 2.237,7.513 to 1.238,7.513 to 1.238,8.012 -line from 3.737,6.763 to 4.237,6.763 -line from 4.138,6.737 to 4.237,6.763 to 4.138,6.788 -line from 2.237,6.763 to 2.737,6.763 -line from 2.637,6.737 to 2.737,6.763 to 2.637,6.788 -line from 1.738,6.013 to 1.738,6.513 -line from 1.762,6.413 to 1.738,6.513 to 1.713,6.413 -line from 1.238,7.013 to 2.237,7.013 to 2.237,6.513 to 1.238,6.513 to 1.238,7.013 -line from 4.237,9.012 to 5.237,9.012 to 5.237,8.512 to 4.237,8.512 to 4.237,9.012 -line from 4.237,8.012 to 5.237,8.012 to 5.237,7.513 to 4.237,7.513 to 4.237,8.012 -line from 4.237,7.013 to 5.237,7.013 to 5.237,6.513 to 4.237,6.513 to 4.237,7.013 -line from 4.737,7.013 to 4.737,7.513 -line from 4.763,7.413 to 4.737,7.513 to 4.712,7.413 -line from 4.737,8.012 to 4.737,8.512 -line from 4.763,8.412 to 4.737,8.512 to 4.712,8.412 -line from 4.237,10.012 to 5.237,10.012 to 5.237,9.512 to 4.237,9.512 to 4.237,10.012 -line from 4.737,9.012 to 4.737,9.512 -line from 4.763,9.412 to 4.737,9.512 to 4.712,9.412 -line from 5.987,5.013 to 5.987,6.013 to 0.988,6.013 to 0.988,5.013 to 5.987,5.013 -.ps 11 -"1.2" at 1.613,7.793 ljust -.ps 11 -"\"HEAD\"" at 2.862,9.043 ljust -.ps 11 -"'SunOS'" at 2.987,6.293 ljust -.ps 11 -"1.1.1" at 3.050,6.793 ljust -.ps 11 -"1.1" at 1.613,6.793 ljust -.ps 11 -"1.1.1.1" at 4.487,6.793 ljust -.ps 11 -"1.1.1.2" at 4.487,7.793 ljust -.ps 11 -"1.1.1.3" at 4.487,8.793 ljust -.ps 11 -"1.1.1.4" at 4.487,9.793 ljust -.ps 11 -"'SunOS_4_0'" at 5.487,6.793 ljust -.ps 11 -"'SunOS_4_0_1'" at 5.487,7.793 ljust -.ps 11 -"'YAPT_5_5C'" at 5.487,8.793 ljust -.ps 11 -"'SunOS_4_0_3'" at 5.487,9.793 ljust -.ps 11 -"rcsfile.c,v" at 2.987,5.543 ljust -.PE -.DE -.hl -.ce 100 -.LG -\fBFigure 3.\fP -.SM -\fBcvs\fP Local Modification to Vendor Branch -.ce 0 -.sp -.KE -.PP -When a new version of the vendor's source distribution arrives, the -\fBcheckin\fP program adds the new and changed vendor's files to the -already existing source repository. -For files that have not been changed locally, the new file from the -vendor becomes the current \*Qhead\*U revision. -For files that have been modified locally, \fBcheckin\fP warns that the -file must be merged with the new vendor release. -The \fBcvs\fP \*Qjoin\*U command is a useful tool that aids this process by -performing the necessary -.SM -RCS -.LG -merge, as is done above when performing an \*Qupdate.\*U -.PP -There is also limited support for \*Qdual\*U derivations for source files. -See Figure 4 for a sample dual-derived file. -.KF -.hl -.DS B -.PS -ellipse at 2.337,8.575 wid 0.700 ht 0.375 -ellipse at 2.312,9.137 wid 0.700 ht 0.375 -line from 1.225,9.012 to 1.225,9.363 -line from 1.250,9.263 to 1.225,9.363 to 1.200,9.263 -line from 0.875,9.725 to 1.600,9.725 to 1.600,9.363 to 0.875,9.363 to 0.875,9.725 -line from 0.875,9.012 to 1.600,9.012 to 1.600,8.650 to 0.875,8.650 to 0.875,9.012 -line from 4.050,10.200 to 4.775,10.200 to 4.775,9.850 to 4.050,9.850 to 4.050,10.200 -line from 4.050,9.475 to 4.775,9.475 to 4.775,9.113 to 4.050,9.113 to 4.050,9.475 -line from 4.050,8.762 to 4.775,8.762 to 4.775,8.400 to 4.050,8.400 to 4.050,8.762 -line from 4.425,8.762 to 4.425,9.113 -line from 4.450,9.013 to 4.425,9.113 to 4.400,9.013 -line from 4.425,9.475 to 4.425,9.850 -line from 4.450,9.750 to 4.425,9.850 to 4.400,9.750 -line from 3.050,10.000 to 3.775,10.000 to 3.775,9.637 to 3.050,9.637 to 3.050,10.000 -line from 3.050,9.312 to 3.775,9.312 to 3.775,8.950 to 3.050,8.950 to 3.050,9.312 -line from 0.713,7.325 to 0.713,8.075 to 4.925,8.075 to 4.925,7.325 to 0.713,7.325 -line from 1.238,8.075 to 1.238,8.637 -line from 1.262,8.537 to 1.238,8.637 to 1.213,8.537 -line from 1.613,8.825 to 1.975,8.575 -line from 1.878,8.611 to 1.975,8.575 to 1.907,8.652 -line from 2.675,8.575 to 4.050,8.575 -line from 3.950,8.550 to 4.050,8.575 to 3.950,8.600 -line from 2.675,9.137 to 3.050,9.137 -line from 2.950,9.112 to 3.050,9.137 to 2.950,9.162 -line from 3.425,9.325 to 3.425,9.637 -line from 3.450,9.537 to 3.425,9.637 to 3.400,9.537 -line from 1.613,8.825 to 1.925,9.137 -line from 1.872,9.049 to 1.925,9.137 to 1.837,9.084 -.ps 11 -"'BSD'" at 2.138,9.481 ljust -.ps 11 -"1.2" at 1.113,9.543 ljust -.ps 11 -"1.1" at 1.125,8.831 ljust -.ps 11 -"1.1.1.1" at 4.175,8.543 ljust -.ps 11 -"1.1.1.2" at 4.175,9.281 ljust -.ps 11 -"1.1.1.3" at 4.175,9.993 ljust -.ps 11 -"1.1.2.2" at 3.175,9.793 ljust -.ps 11 -"1.1.2.1" at 3.175,9.106 ljust -.ps 11 -"rcsfile.c,v" at 2.425,7.706 ljust -.ps 11 -"1.1.1" at 2.175,8.568 ljust -.ps 11 -"'SunOS'" at 2.125,8.243 ljust -.ps 11 -"1.1.2" at 2.163,9.131 ljust -.PE -.DE -.hl -.ce 100 -.LG -\fBFigure 4.\fP -.SM -\fBcvs\fP Support For \*QDual\*U Derivations -.ce 0 -.sp -.KE -This example tracks the SunOS distribution but includes major changes from -Berkeley. -These BSD files are saved directly in the -.SM -RCS -.LG -file off a new branch. -.NH 2 -Location Independent Module Database -.PP -\fBcvs\fP contains support for a simple, yet powerful, \*Qmodule\*U database. -For reasons of efficiency, this database is stored in \fBndbm\fP\|(3) format. -The module database is used to apply names to collections of directories -and files as a matter of convenience for checking out pieces of a large -software distribution. -The database records the physical location of the sources as a form of -information hiding, allowing one to check out whole directory hierarchies -or individual files without regard for their actual location within the -global source distribution. -.PP -Consider the following small sample of a module database, which must be -tailored manually to each specific source repository environment: -.DS -\f(CW #key [-option argument] directory [files...] - diff bin/diff - libc lib/libc - sys -o sys/tools/make_links sys - modules -i mkmodules CVSROOT.adm modules - kernel -a sys lang/adb - ps bin Makefile ps.c\fP -.DE -.PP -The \*Qdiff\*U and \*Qlibc\*U modules refer to whole directory hierarchies that -are extracted on check out. -The \*Qsys\*U module extracts the \*Qsys\*U hierarchy, and runs the -\*Qmake_links\*U program at the end of the check out process (the \fI-o\fP -option specifies a program to run on check\fIo\fPut). -The \*Qmodules\*U module allows one to edit the module database file and -runs the \*Qmkmodules\*U program on check\fIi\fPn to regenerate the -\fBndbm\fP database that \fBcvs\fP uses. -The \*Qkernel\*U module is an alias (as the \fI-a\fP option specifies) -which causes the remaining arguments after the \fI-a\fP to be interpreted -exactly as if they had been specified on the command line. -This is useful for objects that require shared pieces of code from far away -places to be compiled (as is the case with the kernel debugger, \fBkadb\fP, -which shares code with the standard \fBadb\fP debugger). -The \*Qps\*U module shows that the source for \*Qps\*U lives in the \*Qbin\*U -directory, but only \fIMakefile\fP and \fIps.c\fP are required to build the -object. -.PP -The module database at Prisma is now populated for the entire UNIX -distribution and thereby allows us to issue the -following convenient commands to check out components of the UNIX -distribution without regard for their actual location within the master source -repository: -.DS -\f(CW example% cvs checkout diff - example% cvs checkout libc ps - example% cd diff; make\fP -.DE -.PP -In building the module database file, it is quite possible to have name -conflicts within a global software distribution. -For example, SunOS provides two \fBcat\fP programs: -one for the standard environment, \fI/bin/cat\fP, and one for the System V -environment, \fI/usr/5bin/cat\fP. -We resolved this conflict by naming the standard \fBcat\fP module -\*Qcat\*U, and the System V \fBcat\fP module \*Q5cat\*U. -Similar name modifications must be applied to other conflicting names, as -might be found between a utility program and a library function, though -Prisma chose not to include individual library functions within the module -database at this time. -.NH 2 -Configurable Logging Support -.PP -The \fBcvs\fP \*Qcommit\*U command is used to make a permanent change to the -master source repository (where the -.SM -RCS -.LG -\*Q,v\*U files live). -Whenever a \*Qcommit\*U is done, the log message for the change is carefully -logged by an arbitrary program (in a file, notesfile, news database, or -mail). -For example, a collection of these updates can be used to produce release -notices. -\fBcvs\fP can be configured to send log updates through one or more filter -programs, based on a regular expression match on the directory that is -being changed. -This allows multiple related or unrelated projects to exist within a single -\fBcvs\fP source repository tree, with each different project sending its -\*Qcommit\*U reports to a unique log device. -.PP -A sample logging configuration file might look as follows: -.DS -\f(CW #regex filter-program - DEFAULT /usr/local/bin/nfpipe -t %s utils.updates - ^diag /usr/local/bin/nfpipe -t %s diag.updates - ^local /usr/local/bin/nfpipe -t %s local.updates - ^perf /usr/local/bin/nfpipe -t %s perf.updates - ^sys /usr/local/bin/nfpipe -t %s kernel.updates\fP -.DE -.PP -This sample allows the diagnostics and performance groups to -share the same source repository with the kernel and utilities groups. -Changes that they make are sent directly to their own notesfile [Essick] -through the \*Qnfpipe\*U program. -A sufficiently simple title is substituted for the \*Q%s\*U argument before -the filter program is executed. -This logging configuration file is tailored manually to each specific -source repository environment. -.NH 2 -Tagged Releases and Dates -.PP -Any release can be given a symbolic tag name that is stored directly in the -.SM -RCS -.LG -files. -This tag can be used at any time to get an exact copy of any previous -release. -With equal ease, one can also extract an exact copy of the source files as -of any arbitrary date in the past as well. -Thus, all that's required to tag the current kernel, and to tag the kernel -as of the Fourth of July is: -.DS -\f(CW example% cvs tag TEST_KERNEL kernel - example% cvs tag -D 'July 4' PATRIOTIC_KERNEL kernel\fP -.DE -The following command would retrieve an exact copy of the test kernel at -some later date: -.DS -\f(CW example% cvs checkout -fp -rTEST_KERNEL kernel\fP -.DE -The \fI-f\fP option causes only files that match the specified tag to be -extracted, while the \fI-p\fP option automatically prunes empty directories. -Consequently, directories added to the kernel after the test kernel was -tagged are not included in the newly extracted copy of the test kernel. -.PP -The \fBcvs\fP date support has exactly the same interface as that provided -with -.SM -RCS\c -.LG -, however \fBcvs\fP must process the \*Q,v\*U files directly due to the -special handling required by the vendor branch support. -The standard -.SM -RCS -.LG -date handling only processes one branch (or the main trunk) when checking -out based on a date specification. -\fBcvs\fP must instead process the current \*Qhead\*U branch and, if a -match is not found, proceed to look for a match on the vendor branch. -This, combined with reasons of performance, is why \fBcvs\fP processes -revision (symbolic and numeric) and date specifications directly from the -\*Q,v\*U files. -.NH 2 -Building \*Qpatch\*U Source Distributions -.PP -\fBcvs\fP can produce a \*Qpatch\*U format [Wall] output file which can be -used to bring a previously released software distribution current with the -newest release. -This patch file supports an entire directory hierarchy within a single -patch, as well as being able to add whole new files to the previous -release. -One can combine symbolic revisions and dates together to display changes in -a very generic way: -.DS -\f(CW example% cvs patch -D 'December 1, 1988' \e - -D 'January 1, 1989' sys\fP -.DE -This example displays the kernel changes made in the month of December, -1988. -To release a patch file, for example, to take the \fBcvs\fP distribution -from version 1.0 to version 1.4 might be done as follows: -.DS -\f(CW example% cvs patch -rCVS_1_0 -rCVS_1_4 cvs\fP -.DE -.NH -CVS Experience -.NH 2 -Statistics -.PP -A quick summary of the scale that \fBcvs\fP is addressing today -can be found in Table 1. -.KF -.TS -box center tab(:); -c s -c s -c | c -l | n . -\fB\s+2Revision Control Statistics at Prisma -as of 11/11/89\fP\s-2 -_ -How Many...:Total -= -Files:17243 -Directories:1005 -Lines of code:3927255 -Removed files:131 -Software developers:14 -Software groups:6 -Megabytes of source:128 -.TE -.ce 100 -.LG -\fBTable 1.\fP -.SM -\fBcvs\fP Statistics -.ce 0 -.sp .3 -.KE -Table 2 shows the history of files changed or added and the number -of source lines affected by the change at Prisma. -Only changes made to the kernel sources are included. -.KF -.TS -box center tab(:); -c s s s s -c s s s s -c || c | c || c | c -c || c | c || c | c -l || n | n || n | n. -\fB\s+2Prisma Kernel Source File Changes -By Month, 1988-1989\fP\s-2 -_ -Month:# Changed:# Lines:# Added:# Lines -\^:Files:Changed:Files:Added -= -Dec:87:3619:68:9266 -Jan:39:4324:0:0 -Feb:73:1578:5:3550 -Mar:99:5301:18:11461 -Apr:112:7333:11:5759 -May:138:5371:17:13986 -Jun:65:2261:27:12875 -Jul:34:2000:1:58 -Aug:65:6378:8:4724 -Sep:266:23410:113:39965 -Oct:22:621:1:155 -Total:1000:62196:269:101799 -.TE -.ce 100 -.LG -\fBTable 2.\fP -.SM -\fBcvs\fP Usage History for the Kernel -.ce 0 -.sp -.KE -The large number of source file changes made in September are the result of -merging the SunOS 4.0.3 sources into the kernel. -This merge process is described in section 3.3. -.NH 2 -Performance -.PP -The performance of \fBcvs\fP is currently quite reasonable. -Little effort has been expended on tuning \fBcvs\fP, although performance -related decisions were made during the \fBcvs\fP design. -For example, \fBcvs\fP parses the -.SM -RCS -.LG -\*Q,v\*U files directly instead of running an -.SM -RCS -.LG -process. -This includes following branches as well as integrating with the vendor -source branches and the main trunk when checking out files based on a date. -.PP -Checking out the entire kernel source tree (1223 files/59 directories) -currently takes 16 wall clock minutes on a Sun-4/280. -However, bringing the tree up-to-date with the current kernel sources, once -it has been checked out, takes only 1.5 wall clock minutes. -Updating the \fIcomplete\fP 128 MByte source tree under \fBcvs\fP control -(17243 files/1005 directories) takes roughly 28 wall clock minutes and -utilizes one-third of the machine. -For now this is entirely acceptable; improvements on these numbers will -possibly be made in the future. -.NH 2 -The SunOS 4.0.3 Merge -.PP -The true test of the \fBcvs\fP vendor branch support came with the arrival -of the SunOS 4.0.3 source upgrade tape. -As described above, the \fBcheckin\fP program was used to install the new -sources and the resulting output file listed the files that had been -locally modified, needing to be merged manually. -For the kernel, there were 94 files in conflict. -The \fBcvs\fP \*Qjoin\*U command was used on each of the 94 conflicting -files, and the remaining conflicts were resolved. -.PP -The \*Qjoin\*U command performs an \fBrcsmerge\fP operation. -This in turn uses \fI/usr/lib/diff3\fP to produce a three-way diff file. -As it happens, the \fBdiff3\fP program has a hard-coded limit of 200 -source-file changes maximum. -This proved to be too small for a few of the kernel files that needed -merging by hand, due to the large number of local changes that Prisma had -made. -The \fBdiff3\fP problem was solved by increasing the hard-coded limit by an -order of magnitude. -.PP -The SunOS 4.0.3 kernel source upgrade distribution contained -346 files, 233 of which were modifications to previously released files, -and 113 of which were newly added files. -\fBcheckin\fP added the 113 new files to the source repository -without intervention. -Of the 233 modified files, 139 dropped in cleanly by \fBcheckin\fP, since -Prisma had not made any local changes to them, and 94 required manual -merging due to local modifications. -The 233 modified files consisted of 20,766 lines of differences. -It took one developer two days to manually merge the 94 files using the -\*Qjoin\*U command and resolving conflicts manually. -An additional day was required for kernel debugging. -The entire process of merging over 20,000 lines of differences was -completed in less than a week. -This one time-savings alone was justification enough for the \fBcvs\fP -development effort; we expect to gain even more when tracking future SunOS -releases. -.NH -Future Enhancements and Current Bugs -.PP -Since \fBcvs\fP was designed to be incomplete, for reasons of design -simplicity, there are naturally a good -number of enhancements that can be made to make it more useful. -As well, some nuisances exist in the current implementation. -.RS -.IP \(bu 3 -\fBcvs\fP does not currently \*Qremember\*U who has a checked out a copy of a -module. -As a result, it is impossible to know who might be working on the same -module that you are. -A simple-minded database that is updated nightly would likely suffice. -.IP \(bu 3 -Signal processing, keyboard interrupt handling in particular, is currently -somewhat weak. -This is due to the heavy use of the \fBsystem\fP\|(3) library -function to execute -.SM -RCS -.LG -programs like \fBco\fP and \fBci\fP. -It sometimes takes multiple interrupts to make \fBcvs\fP quit. -This can be fixed by using a home-grown \fBsystem\fP\|() replacement. -.IP \(bu 3 -Security of the source repository is currently not dealt with directly. -The usual UNIX approach of user-group-other security permissions through -the file system is utilized, but nothing else. -\fBcvs\fP could likely be a set-group-id executable that checks a -protected database to verify user access permissions for particular objects -before allowing any operations to affect those objects. -.IP \(bu 3 -With every checked-out directory, \fBcvs\fP maintains some administrative -files that record the current revision numbers of the checked-out files as -well as the location of the respective source repository. -\fBcvs\fP does not recover nicely at all if these administrative files are -removed. -.IP \(bu 3 -The source code for \fBcvs\fP has been tested extensively on Sun-3 and -Sun-4 systems, all running SunOS 4.0 or later versions of the operating -system. -Since the code has not yet been compiled under other platforms, the overall -portability of the code is still questionable. -.IP \(bu 3 -As witnessed in the previous section, the \fBcvs\fP method for tracking -third party vendor source distributions can work quite nicely. -However, if the vendor changes the directory structure or the file names -within the source distribution, \fBcvs\fP has no way of matching the old -release with the new one. -It is currently unclear as to how to solve this, though it is certain to -happen in practice. -.RE -.NH -Availability -.PP -The \fBcvs\fP program sources can be found in a recent posting to the -\fBcomp.sources.unix\fP newsgroup. -It is also currently available via anonymous ftp from \*Qprisma.com\*U. -Copying rights for \fBcvs\fP will be covered by the GNU General Public -License. -.NH -Summary -.PP -Prisma has used \fBcvs\fP since December, 1988. -It has evolved to meet our specific needs of revision and release control. -We will make our code freely available so that others can -benefit from our work, and can enhance \fBcvs\fP to meet broader needs yet. -.PP -Many of the other software release and revision control systems, like the -one described in [Glew], appear to use a collection of tools that are -geared toward specific environments \(em one set of tools for the kernel, -one set for \*Qgeneric\*U software, one set for utilities, and one set for -kernel and utilities. -Each of these tool sets apparently handle some specific aspect of the -problem uniquely. -\fBcvs\fP took a somewhat different approach. -File sharing through symbolic or hard links is not addressed; instead, the -disk space is simply burned since it is \*Qcheap.\*U -Support for producing objects for multiple architectures is not addressed; -instead, a parallel checked-out source tree must be used for each -architecture, again wasting disk space to simplify complexity and ease of -use \(em punting on this issue allowed \fIMakefile\fPs to remain -unchanged, unlike the approach taken in [Mahler], thereby maintaining closer -compatibility with the third-party vendor sources. -\fBcvs\fP is essentially a source-file server, making no assumptions or -special handling of the sources that it controls. -To \fBcvs\fP: -.QP -A source is a source, of course, of course, unless of course the source is -Mr. Ed.\** -.FS -\fBcvs\fP, of course, does not really discriminate against Mr. Ed.\** -.FE -.FS -Yet. -.FE -.LP -Sources are maintained, saved, and retrievable at any time based on -symbolic or numeric revision or date in the past. -It is entirely up to \fBcvs\fP wrapper programs to provide for release -environments and such. -.PP -The major advantage of \fBcvs\fP over the -many other similar systems that have already been designed is the -simplicity of \fBcvs\fP. -\fBcvs\fP contains only three programs that do all the work of release -and revision control, and two manually-maintained administrative -files for each source repository. -Of course, the deciding factor of any tool is whether people use it, and if -they even \fIlike\fP to use it. -At Prisma, \fBcvs\fP prevented members of the kernel -group from killing each other. -.NH -Acknowledgements -.PP -Many thanks to Dick Grune at Vrije Universiteit in Amsterdam for his work -on the original version of \fBcvs\fP and for making it available to the -world. -Thanks to Jeff Polk of Prisma for helping with the design of the module -database, vendor branch support, and for writing the \fBcheckin\fP shell -script. -Thanks also to the entire software group at Prisma for taking the -time to review the paper and correct my grammar. -.NH -References -.IP [Bell] 12 -Bell Telephone Laboratories. -\*QSource Code Control System User's Guide.\*U -\fIUNIX System III Programmer's Manual\fP, October 1981. -.IP [Courington] 12 -Courington, W. -\fIThe Network Software Environment\fP, -Sun Technical Report FE197-0, Sun Microsystems Inc, February 1989. -.IP [Essick] 12 -Essick, Raymond B. and Robert Bruce Kolstad. -\fINotesfile Reference Manual\fP, -Department of Computer Science Technical Report #1081, -University of Illinois at Urbana-Champaign, Urbana, Illinois, -1982, p. 26. -.IP [Glew] 12 -Glew, Andy. -\*QBoxes, Links, and Parallel Trees: -Elements of a Configuration Management System.\*U -\fIWorkshop Proceedings of the Software Management Conference\fP, USENIX, -New Orleans, April 1989. -.IP [Grune] 12 -Grune, Dick. -Distributed the original shell script version of \fBcvs\fP in the -\fBcomp.sources.unix\fP volume 6 release in 1986. -.IP [Honda] 12 -Honda, Masahiro and Terrence Miller. -\*QSoftware Management Using a CASE Environment.\*U -\fIWorkshop Proceedings of the Software Management Conference\fP, USENIX, -New Orleans, April 1989. -.IP [Mahler] 12 -Mahler, Alex and Andreas Lampen. -\*QAn Integrated Toolset for Engineering Software Configurations.\*U -\fIProceedings of the ACM SIGSOFT/SIGPLAN Software Engineering Symposium on -Practical Software Development Environments\fP, ACM, Boston, November 1988. -Described is the \fBshape\fP toolkit posted to the -\fBcomp.sources.unix\fP newsgroup in the volume 19 release. -.IP [Tichy] 12 -Tichy, Walter F. -\*QDesign, Implementation, and Evaluation of a Revision Control System.\*U -\fIProceedings of the 6th International Conference on Software -Engineering\fP, IEEE, Tokyo, September 1982. -.IP [Wall] 12 -Wall, Larry. -The \fBpatch\fP program is an indispensable tool for applying a diff file -to an original. -Can be found on uunet.uu.net in ~ftp/pub/patch.tar. diff --git a/contrib/cvs/doc/cvs.1 b/contrib/cvs/doc/cvs.1 deleted file mode 100644 index 70f2bec..0000000 --- a/contrib/cvs/doc/cvs.1 +++ /dev/null @@ -1,3968 +0,0 @@ -.\" This is the man page for CVS. It is auto-generated from the -.\" cvs.man.header, cvs.texinfo, & cvs.man.footer files. Please make changes -.\" there. A full copyright & license notice may also be found in cvs.texinfo. -.\" -.\" Man page autogeneration, including this header file, is -.\" Copyright 2004-2005 The Free Software Foundation, Inc., -.\" Derek R. Price, & Ximbiot . -.\" -.\" This documentation is free software; you can redistribute it and/or modify -.\" it under the terms of the GNU General Public License as published by -.\" the Free Software Foundation; either version 2, or (at your option) -.\" any later version. -.\" -.\" This documentation is distributed in the hope that it will be useful, -.\" but WITHOUT ANY WARRANTY; without even the implied warranty of -.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -.\" GNU General Public License for more details. -.\" -.\" You should have received a copy of the GNU General Public License -.\" along with this documentation; if not, write to the Free Software -.\" Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -.de Id -.ds Rv \\$3 -.ds Dt \\$4 -.. -.TH CVS 1 "\*(Dt" -.\" Full space in nroff; half space in troff -.de SP -.if n .sp -.if t .sp .5 -.. -.\" quoted command -.de ` -.RB ` "\|\\$1\|" '\\$2 -.. -.SH "NAME" -cvs \- Concurrent Versions System -.SH "SYNOPSIS" -.TP -\fBcvs\fP [ \fIcvs_options\fP ] -.I cvs_command -[ -.I command_options -] [ -.I command_args -] -.SH "NOTE" -.IX "revision control system" "\fLcvs\fR" -.IX cvs "" "\fLcvs\fP \- concurrent versions system" -.IX "concurrent versions system \- \fLcvs\fP" -.IX "release control system" "cvs command" "" "\fLcvs\fP \- concurrent versions system" -.IX "source control system" "cvs command" "" "\fLcvs\fP \- concurrent versions system" -.IX revisions "cvs command" "" "\fLcvs\fP \- source control" -This manpage is a summary of some of the features of -\fBcvs\fP. It is auto-generated from an appendix of the CVS manual. -For more in-depth documentation, please consult the -Cederqvist manual (via the -.B info CVS -command or otherwise, -as described in the SEE ALSO section of this manpage). Cross-references -in this man page refer to nodes in the same. -.SH "CVS commands" -.SS "Guide to CVS commands" -.SP -This appendix describes the overall structure of -\fBcvs\fR commands, and describes some commands in -detail (others are described elsewhere; for a quick -reference to \fBcvs\fR commands, see node `Invoking CVS\(aq in the CVS manual). -.SP -.SH "Structure" -.SS "Overall structure of CVS commands" -.IX "Structure" -.IX "CVS command structure" -.IX "Command structure" -.IX "Format of CVS commands" -.SP -The overall format of all \fBcvs\fR commands is: -.SP -.PD 0 -.SP -.IP "" 2 -cvs [ cvs_options ] cvs_command [ command_options ] [ command_args ] - -.PD -.IP "" 0 -.SP -.IP "" 0 -\fBcvs\fR -.IP "" 2 -The name of the \fBcvs\fR program. -.SP -.IP "" 0 -\fBcvs_options\fR -.IP "" 2 -Some options that affect all sub-commands of \fBcvs\fR. These are -described below. -.SP -.IP "" 0 -\fBcvs_command\fR -.IP "" 2 -One of several different sub-commands. Some of the commands have -aliases that can be used instead; those aliases are noted in the -reference manual for that command. There are only two situations -where you may omit \fBcvs_command\fR: \fBcvs -H\fR elicits a -list of available commands, and \fBcvs -v\fR displays version -information on \fBcvs\fR itself. -.SP -.IP "" 0 -\fBcommand_options\fR -.IP "" 2 -Options that are specific for the command. -.SP -.IP "" 0 -\fBcommand_args\fR -.IP "" 2 -Arguments to the commands. -.SP -There is unfortunately some confusion between -\fBcvs_options\fR and \fBcommand_options\fR. -When given as a \fBcvs_option\fR, some options only -affect some of the commands. When given as a -\fBcommand_option\fR it may have a different meaning, and -be accepted by more commands. In other words, do not -take the above categorization too seriously. Look at -the documentation instead. -.SP -.SH "Exit status" -.SS "CVS\(aqs exit status" -.IX "Exit status, of CVS" -.SP -\fBcvs\fR can indicate to the calling environment whether it -succeeded or failed by setting its \fIexit status\fR. -The exact way of testing the exit status will vary from -one operating system to another. For example in a unix -shell script the \fB$?\fR variable will be 0 if the -last command returned a successful exit status, or -greater than 0 if the exit status indicated failure. -.SP -If \fBcvs\fR is successful, it returns a successful status; -if there is an error, it prints an error message and -returns a failure status. The one exception to this is -the \fBcvs diff\fR command. It will return a -successful status if it found no differences, or a -failure status if there were differences or if there -was an error. Because this behavior provides no good -way to detect errors, in the future it is possible that -\fBcvs diff\fR will be changed to behave like the -other \fBcvs\fR commands. -.SP -.SH "~/.cvsrc" -.SS "Default options and the ~/.cvsrc file" -.IX "\&.cvsrc file" -.IX "Option defaults" -.SP -There are some \fBcommand_options\fR that are used so -often that you might have set up an alias or some other -means to make sure you always specify that option. One -example (the one that drove the implementation of the -\fB.cvsrc\fR support, actually) is that many people find the -default output of the \fBdiff\fR command to be very -hard to read, and that either context diffs or unidiffs -are much easier to understand. -.SP -The \fB~/.cvsrc\fR file is a way that you can add -default options to \fBcvs_commands\fR within cvs, -instead of relying on aliases or other shell scripts. -.SP -The format of the \fB~/.cvsrc\fR file is simple. The -file is searched for a line that begins with the same -name as the \fBcvs_command\fR being executed. If a -match is found, then the remainder of the line is split -up (at whitespace characters) into separate options and -added to the command arguments \fIbefore\fR any -options from the command line. -.SP -If a command has two names (e.g., \fBcheckout\fR and -\fBco\fR), the official name, not necessarily the one -used on the command line, will be used to match against -the file. So if this is the contents of the user\(aqs -\fB~/.cvsrc\fR file: -.SP -.PD 0 -.SP -.IP "" 2 -log -N -.IP "" 2 -diff -uN -.IP "" 2 -rdiff -u -.IP "" 2 -update -Pd -.IP "" 2 -checkout -P -.IP "" 2 -release -d - -.PD -.IP "" 0 -.SP -the command \fBcvs checkout foo\fR would have the -\fB-P\fR option added to the arguments, as well as -\fBcvs co foo\fR. -.SP -With the example file above, the output from \fBcvs -diff foobar\fR will be in unidiff format. \fBcvs diff --c foobar\fR will provide context diffs, as usual. -Getting "old" format diffs would be slightly more -complicated, because \fBdiff\fR doesn\(aqt have an option -to specify use of the "old" format, so you would need -\fBcvs -f diff foobar\fR. -.SP -In place of the command name you can use \fBcvs\fR to -specify global options (see node `Global options\(aq in the CVS manual). For -example the following line in \fB.cvsrc\fR -.SP -.PD 0 -.SP -.IP "" 2 -cvs -z6 - -.PD -.IP "" 0 -.SP -causes \fBcvs\fR to use compression level 6. -.SP -.SH "Global options" -.IX "Options, global" -.IX "Global options" -.IX "Left-hand options" -.SP -The available \fBcvs_options\fR (that are given to the -left of \fBcvs_command\fR) are: -.SP -.IP "" 0 -\fB--allow-root=\fIrootdir\fB\fR -.IP "" 2 -Specify legal \fBcvsroot\fR directory. See -`Password authentication server\(aq in the CVS manual. -.SP -.IX "Authentication, stream" -.IX "Stream authentication" -.IP "" 0 -\fB-a\fR -.IP "" 2 -Authenticate all communication between the client and -the server. Only has an effect on the \fBcvs\fR client. -As of this writing, this is only implemented when using -a GSSAPI connection (see node `GSSAPI authenticated\(aq in the CVS manual). -Authentication prevents certain sorts of attacks -involving hijacking the active \fBtcp\fR connection. -Enabling authentication does not enable encryption. -.SP -.IX "RCSBIN, overriding" -.IX "Overriding RCSBIN" -.IP "" 0 -\fB-b \fIbindir\fB\fR -.IP "" 2 -In \fBcvs\fR 1.9.18 and older, this specified that -\fBrcs\fR programs are in the \fIbindir\fR directory. -Current versions of \fBcvs\fR do not run \fBrcs\fR -programs; for compatibility this option is accepted, -but it does nothing. -.SP -.IX "TMPDIR, overriding" -.IX "Overriding TMPDIR" -.IP "" 0 -\fB-T \fItempdir\fB\fR -.IP "" 2 -Use \fItempdir\fR as the directory where temporary files are -located. Overrides the setting of the \fB$TMPDIR\fR environment -variable and any precompiled directory. This parameter should be -specified as an absolute pathname. -(When running client/server, \fB-T\fR affects only the local process; -specifying \fB-T\fR for the client has no effect on the server and -vice versa.) -.SP -.IX "CVSROOT, overriding" -.IX "Overriding CVSROOT" -.IP "" 0 -\fB-d \fIcvs_root_directory\fB\fR -.IP "" 2 -Use \fIcvs_root_directory\fR as the root directory -pathname of the repository. Overrides the setting of -the \fB$CVSROOT\fR environment variable. See `Repository\(aq in the CVS manual. -.SP -.IX "EDITOR, overriding" -.IX "Overriding EDITOR" -.IP "" 0 -\fB-e \fIeditor\fB\fR -.IP "" 2 -Use \fIeditor\fR to enter revision log information. Overrides the -setting of the \fB$CVSEDITOR\fR and \fB$EDITOR\fR -environment variables. For more information, see -`Committing your changes\(aq in the CVS manual. -.SP -.IP "" 0 -\fB-f\fR -.IP "" 2 -Do not read the \fB~/.cvsrc\fR file. This -option is most often used because of the -non-orthogonality of the \fBcvs\fR option set. For -example, the \fBcvs log\fR option \fB-N\fR (turn off -display of tag names) does not have a corresponding -option to turn the display on. So if you have -\fB-N\fR in the \fB~/.cvsrc\fR entry for \fBlog\fR, -you may need to use \fB-f\fR to show the tag names. -.SP -.IP "" 0 -\fB-H\fR -.IP "" 2 -.IP "" 0 -\fB--help\fR -.IP "" 2 -Display usage information about the specified \fBcvs_command\fR -(but do not actually execute the command). If you don\(aqt specify -a command name, \fBcvs -H\fR displays overall help for -\fBcvs\fR, including a list of other help options. -.SP -.IX "Read-only mode" -.IP "" 0 -\fB-n\fR -.IP "" 2 -Do not change any files. Attempt to execute the -\fBcvs_command\fR, but only to issue reports; do not remove, -update, or merge any existing files, or create any new files. -.SP -Note that \fBcvs\fR will not necessarily produce exactly -the same output as without \fB-n\fR. In some cases -the output will be the same, but in other cases -\fBcvs\fR will skip some of the processing that would -have been required to produce the exact same output. -.SP -.IP "" 0 -\fB-Q\fR -.IP "" 2 -Cause the command to be really quiet; the command will only -generate output for serious problems. -.SP -.IP "" 0 -\fB-q\fR -.IP "" 2 -Cause the command to be somewhat quiet; informational messages, -such as reports of recursion through subdirectories, are -suppressed. -.SP -.IX "Read-only files, and -r" -.IP "" 0 -\fB-r\fR -.IP "" 2 -Make new working files read-only. Same effect -as if the \fB$CVSREAD\fR environment variable is set -(see node `Environment variables\(aq in the CVS manual). The default is to -make working files writable, unless watches are on -(see node `Watches\(aq in the CVS manual). -.SP -.IP "" 0 -\fB-s \fIvariable\fB=\fIvalue\fB\fR -.IP "" 2 -Set a user variable (see node `Variables\(aq in the CVS manual). -.SP -.IX "Trace" -.IP "" 0 -\fB-t\fR -.IP "" 2 -Trace program execution; display messages showing the steps of -\fBcvs\fR activity. Particularly useful with \fB-n\fR to explore the -potential impact of an unfamiliar command. -.SP -.IP "" 0 -\fB-v\fR -.IP "" 2 -.IP "" 0 -\fB--version\fR -.IP "" 2 -Display version and copyright information for \fBcvs\fR. -.SP -.IX "CVSREAD, overriding" -.IX "Overriding CVSREAD" -.IP "" 0 -\fB-w\fR -.IP "" 2 -Make new working files read-write. Overrides the -setting of the \fB$CVSREAD\fR environment variable. -Files are created read-write by default, unless \fB$CVSREAD\fR is -set or \fB-r\fR is given. -.SP -.IP "" 0 -\fB-x\fR -.IP "" 2 -.IX "Encryption" -Encrypt all communication between the client and the -server. Only has an effect on the \fBcvs\fR client. As -of this writing, this is only implemented when using a -GSSAPI connection (see node `GSSAPI authenticated\(aq in the CVS manual) or a -Kerberos connection (see node `Kerberos authenticated\(aq in the CVS manual). -Enabling encryption implies that message traffic is -also authenticated. Encryption support is not -available by default; it must be enabled using a -special configure option, \fB--enable-encryption\fR, -when you build \fBcvs\fR. -.SP -.IP "" 0 -\fB-z \fIgzip-level\fB\fR -.IP "" 2 -.IX "Compression" -.IX "Gzip" -Set the compression level. -Valid levels are 1 (high speed, low compression) to -9 (low speed, high compression), or 0 to disable -compression (the default). -Only has an effect on the \fBcvs\fR client. -.SP -.SP -.SH "Common options" -.SS "Common command options" -.IX "Common options" -.IX "Right-hand options" -.SP -This section describes the \fBcommand_options\fR that -are available across several \fBcvs\fR commands. These -options are always given to the right of -\fBcvs_command\fR. Not all -commands support all of these options; each option is -only supported for commands where it makes sense. -However, when a command has one of these options you -can almost always count on the same behavior of the -option as in other commands. (Other command options, -which are listed with the individual commands, may have -different behavior from one \fBcvs\fR command to the other). -.SP -\fBThe \fBhistory\fB command is an exception; it supports -many options that conflict even with these standard options.\fR -.SP -.IX "Dates" -.IX "Time" -.IX "Specifying dates" -.IP "" 0 -\fB-D \fIdate_spec\fB\fR -.IP "" 2 -Use the most recent revision no later than \fIdate_spec\fR. -\fIdate_spec\fR is a single argument, a date description -specifying a date in the past. -.SP -The specification is \fIsticky\fR when you use it to make a -private copy of a source file; that is, when you get a working -file using \fB-D\fR, \fBcvs\fR records the date you specified, so that -further updates in the same directory will use the same date -(for more information on sticky tags/dates, see node `Sticky tags\(aq in the CVS manual). -.SP -\fB-D\fR is available with the \fBannotate\fR, \fBcheckout\fR, -\fBdiff\fR, \fBexport\fR, \fBhistory\fR, -\fBrdiff\fR, \fBrtag\fR, and \fBupdate\fR commands. -(The \fBhistory\fR command uses this option in a -slightly different way; see node `history options\(aq in the CVS manual). -.SP -.IX "Timezone, in input" -.IX "Zone, time, in input" -A wide variety of date formats are supported by -\fBcvs\fR. The most standard ones are ISO8601 (from the -International Standards Organization) and the Internet -e-mail standard (specified in RFC822 as amended by -RFC1123). -.SP -ISO8601 dates have many variants but a few examples -are: -.SP -.PD 0 -.SP -.IP "" 4 -1972-09-24 -.IP "" 4 -1972-09-24 20:05 - -.PD -.IP "" 2 -.SP -There are a lot more ISO8601 date formats, and \fBcvs\fR -accepts many of them, but you probably don\(aqt want to -hear the \fIwhole\fR long story :-). -.SP -In addition to the dates allowed in Internet e-mail -itself, \fBcvs\fR also allows some of the fields to be -omitted. For example: -.SP -.PD 0 -.SP -.IP "" 4 -24 Sep 1972 20:05 -.IP "" 4 -24 Sep - -.PD -.IP "" 2 -.SP -The date is interpreted as being in the -local timezone, unless a specific timezone is -specified. -.SP -These two date formats are preferred. However, -\fBcvs\fR currently accepts a wide variety of other date -formats. They are intentionally not documented here in -any detail, and future versions of \fBcvs\fR might not -accept all of them. -.SP -One such format is -\fB\fImonth\fB/\fIday\fB/\fIyear\fB\fR. This may -confuse people who are accustomed to having the month -and day in the other order; \fB1/4/96\fR is January 4, -not April 1. -.SP -Remember to quote the argument to the \fB-D\fR -flag so that your shell doesn\(aqt interpret spaces as -argument separators. A command using the \fB-D\fR -flag can look like this: -.SP -.PD 0 -.SP -.IP "" 4 -$ cvs diff -D "1 hour ago" cvs.texinfo - -.PD -.IP "" 2 -.SP -.IX "Forcing a tag match" -.IP "" 0 -\fB-f\fR -.IP "" 2 -When you specify a particular date or tag to \fBcvs\fR commands, they -normally ignore files that do not contain the tag (or did not -exist prior to the date) that you specified. Use the \fB-f\fR option -if you want files retrieved even when there is no match for the -tag or date. (The most recent revision of the file -will be used). -.SP -Note that even with \fB-f\fR, a tag that you specify -must exist (that is, in some file, not necessary in -every file). This is so that \fBcvs\fR will continue to -give an error if you mistype a tag name. -.SP -\fB-f\fR is available with these commands: -\fBannotate\fR, \fBcheckout\fR, \fBexport\fR, -\fBrdiff\fR, \fBrtag\fR, and \fBupdate\fR. -.SP -\fBWARNING: The \fBcommit\fB and \fBremove\fB -commands also have a -\fB-f\fB option, but it has a different behavior for -those commands. See `commit options\(aq in the CVS manual, and -`Removing files\(aq in the CVS manual.\fR -.SP -.IP "" 0 -\fB-k \fIkflag\fB\fR -.IP "" 2 -Alter the default processing of keywords. -See `Keyword substitution\(aq in the CVS manual, for the meaning of -\fIkflag\fR. Your \fIkflag\fR specification is -\fIsticky\fR when you use it to create a private copy -of a source file; that is, when you use this option -with the \fBcheckout\fR or \fBupdate\fR commands, -\fBcvs\fR associates your selected \fIkflag\fR with the -file, and continues to use it with future update -commands on the same file until you specify otherwise. -.SP -The \fB-k\fR option is available with the \fBadd\fR, -\fBcheckout\fR, \fBdiff\fR, \fBrdiff\fR, \fBimport\fR and -\fBupdate\fR commands. -.SP -.IP "" 0 -\fB-l\fR -.IP "" 2 -Local; run only in current working directory, rather than -recursing through subdirectories. -.SP -Available with the following commands: \fBannotate\fR, \fBcheckout\fR, -\fBcommit\fR, \fBdiff\fR, \fBedit\fR, \fBeditors\fR, \fBexport\fR, -\fBlog\fR, \fBrdiff\fR, \fBremove\fR, \fBrtag\fR, -\fBstatus\fR, \fBtag\fR, \fBunedit\fR, \fBupdate\fR, \fBwatch\fR, -and \fBwatchers\fR. -.SP -.IX "Editor, avoiding invocation of" -.IX "Avoiding editor invocation" -.IP "" 0 -\fB-m \fImessage\fB\fR -.IP "" 2 -Use \fImessage\fR as log information, instead of -invoking an editor. -.SP -Available with the following commands: \fBadd\fR, -\fBcommit\fR and \fBimport\fR. -.SP -.IP "" 0 -\fB-n\fR -.IP "" 2 -Do not run any tag program. (A program can be -specified to run in the modules -database (see node `modules\(aq in the CVS manual); this option bypasses it). -.SP -\fBThis is not the same as the \fBcvs -n\fB -program option, which you can specify to the left of a cvs command!\fR -.SP -Available with the \fBcheckout\fR, \fBexport\fR, -and \fBrtag\fR commands. -.SP -.IP "" 0 -\fB-P\fR -.IP "" 2 -Prune empty directories. See `Removing directories\(aq in the CVS manual. -.SP -.IP "" 0 -\fB-p\fR -.IP "" 2 -Pipe the files retrieved from the repository to standard output, -rather than writing them in the current directory. Available -with the \fBcheckout\fR and \fBupdate\fR commands. -.SP -.IP "" 0 -\fB-R\fR -.IP "" 2 -Process directories recursively. This is on by default. -.SP -Available with the following commands: \fBannotate\fR, \fBcheckout\fR, -\fBcommit\fR, \fBdiff\fR, \fBedit\fR, \fBeditors\fR, \fBexport\fR, -\fBrdiff\fR, \fBremove\fR, \fBrtag\fR, -\fBstatus\fR, \fBtag\fR, \fBunedit\fR, \fBupdate\fR, \fBwatch\fR, -and \fBwatchers\fR. -.SP -.IP "" 0 -\fB-r \fItag\fB\fR -.IP "" 2 -.IX "HEAD, special tag" -.IX "BASE, special tag" -Use the revision specified by the \fItag\fR argument instead of the -default \fIhead\fR revision. As well as arbitrary tags defined -with the \fBtag\fR or \fBrtag\fR command, two special tags are -always available: \fBHEAD\fR refers to the most recent version -available in the repository, and \fBBASE\fR refers to the -revision you last checked out into the current working directory. -.SP -The tag specification is sticky when you use this -with \fBcheckout\fR or \fBupdate\fR to make your own -copy of a file: \fBcvs\fR remembers the tag and continues to use it on -future update commands, until you specify otherwise (for more information -on sticky tags/dates, see node `Sticky tags\(aq in the CVS manual). -.SP -The tag can be either a symbolic or numeric tag, as -described in `Tags\(aq in the CVS manual, or the name of a branch, as -described in `Branching and merging\(aq in the CVS manual. -When a command expects a specific revision, -the name of a branch is interpreted as the most recent -revision on that branch. -.SP -Specifying the \fB-q\fR global option along with the -\fB-r\fR command option is often useful, to suppress -the warning messages when the \fBrcs\fR file -does not contain the specified tag. -.SP -\fBThis is not the same as the overall \fBcvs -r\fB option, -which you can specify to the left of a \fBcvs\fB command!\fR -.SP -\fB-r\fR is available with the \fBannotate\fR, \fBcheckout\fR, -\fBcommit\fR, \fBdiff\fR, \fBhistory\fR, \fBexport\fR, \fBrdiff\fR, -\fBrtag\fR, and \fBupdate\fR commands. -.SP -.IP "" 0 -\fB-W\fR -.IP "" 2 -Specify file names that should be filtered. You can -use this option repeatedly. The spec can be a file -name pattern of the same type that you can specify in -the \fB.cvswrappers\fR file. -Available with the following commands: \fBimport\fR, -and \fBupdate\fR. -.SP -.SP -.SH "add" -.SS "Add files and directories to the repository" -.IX "add (subcommand)" -.SP -.IP "\(bu" 2 -Synopsis: add [-k rcs-kflag] [-m message] files... -.IP "\(bu" 2 -Requires: repository, working directory. -.IP "\(bu" 2 -Changes: repository, working directory. -.SP -The \fBadd\fR command is used to present new files -and directories for addition into the \fBcvs\fR -repository. When \fBadd\fR is used on a directory, -a new directory is created in the repository -immediately. When used on a file, only the working -directory is updated. Changes to the repository are -not made until the \fBcommit\fR command is used on -the newly added file. -.SP -The \fBadd\fR command also resurrects files that -have been previously removed. This can be done -before or after the \fBcommit\fR command is used -to finalize the removal of files. Resurrected files -are restored into the working directory at the time -the \fBadd\fR command is executed. -.SP -.SH "add options" -.SP -These standard options are supported by \fBadd\fR -(see node `Common options\(aq in the CVS manual, for a complete description of -them): -.SP -.IP "" 0 -\fB-k \fIkflag\fB\fR -.IP "" 2 -Process keywords according to \fIkflag\fR. See -`Keyword substitution\(aq in the CVS manual. -This option is sticky; future updates of -this file in this working directory will use the same -\fIkflag\fR. The \fBstatus\fR command can be viewed -to see the sticky options. For more information on -the \fBstatus\fR command, see node `Invoking CVS\(aq in the CVS manual. -.SP -.IP "" 0 -\fB-m \fImessage\fB\fR -.IP "" 2 -Use \fImessage\fR as the log message, instead of -invoking an editor. -.SP -.SH "add examples" -.SP -.SS "Adding a directory" -.SP -.PD 0 -.SP -.IP "" 2 -$ mkdir doc -.IP "" 2 -$ cvs add doc -.IP "" 2 -Directory /path/to/repository/doc added to the repository - -.PD -.IP "" 0 -.SP -.SS "Adding a file" -.SP -.PD 0 -.SP -.SP -.IP "" 2 -$ >TODO -.IP "" 2 -$ cvs add TODO -.IP "" 2 -cvs add: scheduling file \`TODO\(aq for addition -.IP "" 2 -cvs add: use \(aqcvs commit\(aq to add this file permanently - -.PD -.IP "" 0 -.SP -.SS "Undoing a \fBremove\fR command" -.SP -.PD 0 -.SP -.IP "" 2 -$ rm -f makefile -.IP "" 2 -$ cvs remove makefile -.IP "" 2 -cvs remove: scheduling \`makefile\(aq for removal -.IP "" 2 -cvs remove: use \(aqcvs commit\(aq to remove this file permanently -.IP "" 2 -$ cvs add makefile -.IP "" 2 -U makefile -.IP "" 2 -cvs add: makefile, version 1.2, resurrected - -.PD -.IP "" 0 -.SP -.SH "admin" -.SS "Administration" -.IX "Admin (subcommand)" -.SP -.IP "\(bu" 2 -Requires: repository, working directory. -.IP "\(bu" 2 -Changes: repository. -.IP "\(bu" 2 -Synonym: rcs -.SP -This is the \fBcvs\fR interface to assorted -administrative facilities. Some of them have -questionable usefulness for \fBcvs\fR but exist for -historical purposes. Some of the questionable options -are likely to disappear in the future. This command -\fIdoes\fR work recursively, so extreme care should be -used. -.SP -.IX "cvsadmin" -On unix, if there is a group named \fBcvsadmin\fR, -only members of that group can run \fBcvs admin\fR -(except for the \fBcvs admin -k\fR command, which can -be run by anybody). This group should exist on the -server, or any system running the non-client/server -\fBcvs\fR. To disallow \fBcvs admin\fR for all users, -create a group with no users in it. On NT, the -\fBcvsadmin\fR feature does not exist and all users -can run \fBcvs admin\fR. -.SP -.SH "admin options" -.SP -Some of these options have questionable usefulness for -\fBcvs\fR but exist for historical purposes. Some even -make it impossible to use \fBcvs\fR until you undo the -effect! -.SP -.IP "" 0 -\fB-A\fIoldfile\fB\fR -.IP "" 2 -Might not work together with \fBcvs\fR. Append the -access list of \fIoldfile\fR to the access list of the -\fBrcs\fR file. -.SP -.IP "" 0 -\fB-a\fIlogins\fB\fR -.IP "" 2 -Might not work together with \fBcvs\fR. Append the -login names appearing in the comma-separated list -\fIlogins\fR to the access list of the \fBrcs\fR file. -.SP -.IP "" 0 -\fB-b[\fIrev\fB]\fR -.IP "" 2 -Set the default branch to \fIrev\fR. In \fBcvs\fR, you -normally do not manipulate default branches; sticky -tags (see node `Sticky tags\(aq in the CVS manual) are a better way to decide -which branch you want to work on. There is one reason -to run \fBcvs admin -b\fR: to revert to the vendor\(aqs -version when using vendor branches (see node `Reverting -local changes\(aq in the CVS manual). -There can be no space between \fB-b\fR and its argument. -.SP -.IX "Comment leader" -.IP "" 0 -\fB-c\fIstring\fB\fR -.IP "" 2 -Sets the comment leader to \fIstring\fR. The comment -leader is not used by current versions of \fBcvs\fR or -\fBrcs\fR 5.7. Therefore, you can almost surely not -worry about it. See `Keyword substitution\(aq in the CVS manual. -.SP -.IP "" 0 -\fB-e[\fIlogins\fB]\fR -.IP "" 2 -Might not work together with \fBcvs\fR. Erase the login -names appearing in the comma-separated list -\fIlogins\fR from the access list of the RCS file. If -\fIlogins\fR is omitted, erase the entire access list. -There can be no space between \fB-e\fR and its argument. -.SP -.IP "" 0 -\fB-I\fR -.IP "" 2 -Run interactively, even if the standard input is not a -terminal. This option does not work with the -client/server \fBcvs\fR and is likely to disappear in -a future release of \fBcvs\fR. -.SP -.IP "" 0 -\fB-i\fR -.IP "" 2 -Useless with \fBcvs\fR. This creates and initializes a -new \fBrcs\fR file, without depositing a revision. With -\fBcvs\fR, add files with the \fBcvs add\fR command -(see node `Adding files\(aq in the CVS manual). -.SP -.IP "" 0 -\fB-k\fIsubst\fB\fR -.IP "" 2 -Set the default keyword -substitution to \fIsubst\fR. See `Keyword -substitution\(aq in the CVS manual. Giving an explicit \fB-k\fR option to -\fBcvs update\fR, \fBcvs export\fR, or \fBcvs -checkout\fR overrides this default. -.SP -.IP "" 0 -\fB-l[\fIrev\fB]\fR -.IP "" 2 -Lock the revision with number \fIrev\fR. If a branch -is given, lock the latest revision on that branch. If -\fIrev\fR is omitted, lock the latest revision on the -default branch. There can be no space between -\fB-l\fR and its argument. -.SP -This can be used in conjunction with the -\fBrcslock.pl\fR script in the \fBcontrib\fR -directory of the \fBcvs\fR source distribution to -provide reserved checkouts (where only one user can be -editing a given file at a time). See the comments in -that file for details (and see the \fBREADME\fR file -in that directory for disclaimers about the unsupported -nature of contrib). According to comments in that -file, locking must set to strict (which is the default). -.SP -.IP "" 0 -\fB-L\fR -.IP "" 2 -Set locking to strict. Strict locking means that the -owner of an RCS file is not exempt from locking for -checkin. For use with \fBcvs\fR, strict locking must be -set; see the discussion under the \fB-l\fR option above. -.SP -.IX "Changing a log message" -.IX "Replacing a log message" -.IX "Correcting a log message" -.IX "Fixing a log message" -.IX "Log message, correcting" -.IP "" 0 -\fB-m\fIrev\fB:\fImsg\fB\fR -.IP "" 2 -Replace the log message of revision \fIrev\fR with -\fImsg\fR. -.SP -.IP "" 0 -\fB-N\fIname\fB[:[\fIrev\fB]]\fR -.IP "" 2 -Act like \fB-n\fR, except override any previous -assignment of \fIname\fR. For use with magic branches, -see `Magic branch numbers\(aq in the CVS manual. -.SP -.IP "" 0 -\fB-n\fIname\fB[:[\fIrev\fB]]\fR -.IP "" 2 -Associate the symbolic name \fIname\fR with the branch -or revision \fIrev\fR. It is normally better to use -\fBcvs tag\fR or \fBcvs rtag\fR instead. Delete the -symbolic name if both \fB:\fR and \fIrev\fR are -omitted; otherwise, print an error message if -\fIname\fR is already associated with another number. -If \fIrev\fR is symbolic, it is expanded before -association. A \fIrev\fR consisting of a branch number -followed by a \fB.\fR stands for the current latest -revision in the branch. A \fB:\fR with an empty -\fIrev\fR stands for the current latest revision on the -default branch, normally the trunk. For example, -\fBcvs admin -n\fIname\fB:\fR associates \fIname\fR with the -current latest revision of all the RCS files; -this contrasts with \fBcvs admin -n\fIname\fB:$\fR which -associates \fIname\fR with the revision numbers -extracted from keyword strings in the corresponding -working files. -.SP -.IX "Deleting revisions" -.IX "Outdating revisions" -.IX "Saving space" -.IP "" 0 -\fB-o\fIrange\fB\fR -.IP "" 2 -Deletes (\fIoutdates\fR) the revisions given by -\fIrange\fR. -.SP -Note that this command can be quite dangerous unless -you know \fIexactly\fR what you are doing (for example -see the warnings below about how the -\fIrev1\fR:\fIrev2\fR syntax is confusing). -.SP -If you are short on disc this option might help you. -But think twice before using it\(emthere is no way short -of restoring the latest backup to undo this command! -If you delete different revisions than you planned, -either due to carelessness or (heaven forbid) a \fBcvs\fR -bug, there is no opportunity to correct the error -before the revisions are deleted. It probably would be -a good idea to experiment on a copy of the repository -first. -.SP -Specify \fIrange\fR in one of the following ways: -.SP -.IP "" 2 -\fB\fIrev1\fB::\fIrev2\fB\fR -.IP "" 4 -Collapse all revisions between rev1 and rev2, so that -\fBcvs\fR only stores the differences associated with going -from rev1 to rev2, not intermediate steps. For -example, after \fB-o 1.3::1.5\fR one can retrieve -revision 1.3, revision 1.5, or the differences to get -from 1.3 to 1.5, but not the revision 1.4, or the -differences between 1.3 and 1.4. Other examples: -\fB-o 1.3::1.4\fR and \fB-o 1.3::1.3\fR have no -effect, because there are no intermediate revisions to -remove. -.SP -.IP "" 2 -\fB::\fIrev\fB\fR -.IP "" 4 -Collapse revisions between the beginning of the branch -containing \fIrev\fR and \fIrev\fR itself. The -branchpoint and \fIrev\fR are left intact. For -example, \fB-o ::1.3.2.6\fR deletes revision 1.3.2.1, -revision 1.3.2.5, and everything in between, but leaves -1.3 and 1.3.2.6 intact. -.SP -.IP "" 2 -\fB\fIrev\fB::\fR -.IP "" 4 -Collapse revisions between \fIrev\fR and the end of the -branch containing \fIrev\fR. Revision \fIrev\fR is -left intact but the head revision is deleted. -.SP -.IP "" 2 -\fB\fIrev\fB\fR -.IP "" 4 -Delete the revision \fIrev\fR. For example, \fB-o -1.3\fR is equivalent to \fB-o 1.2::1.4\fR. -.SP -.IP "" 2 -\fB\fIrev1\fB:\fIrev2\fB\fR -.IP "" 4 -Delete the revisions from \fIrev1\fR to \fIrev2\fR, -inclusive, on the same branch. One will not be able to -retrieve \fIrev1\fR or \fIrev2\fR or any of the -revisions in between. For example, the command -\fBcvs admin -oR_1_01:R_1_02 \&.\fR is rarely useful. -It means to delete revisions up to, and including, the -tag R_1_02. But beware! If there are files that have not -changed between R_1_02 and R_1_03 the file will have -\fIthe same\fR numerical revision number assigned to -the tags R_1_02 and R_1_03. So not only will it be -impossible to retrieve R_1_02; R_1_03 will also have to -be restored from the tapes! In most cases you want to -specify \fIrev1\fR::\fIrev2\fR instead. -.SP -.IP "" 2 -\fB:\fIrev\fB\fR -.IP "" 4 -Delete revisions from the beginning of the -branch containing \fIrev\fR up to and including -\fIrev\fR. -.SP -.IP "" 2 -\fB\fIrev\fB:\fR -.IP "" 4 -Delete revisions from revision \fIrev\fR, including -\fIrev\fR itself, to the end of the branch containing -\fIrev\fR. -.SP -None of the revisions to be deleted may have -branches or locks. -.SP -If any of the revisions to be deleted have symbolic -names, and one specifies one of the \fB::\fR syntaxes, -then \fBcvs\fR will give an error and not delete any -revisions. If you really want to delete both the -symbolic names and the revisions, first delete the -symbolic names with \fBcvs tag -d\fR, then run -\fBcvs admin -o\fR. If one specifies the -non-\fB::\fR syntaxes, then \fBcvs\fR will delete the -revisions but leave the symbolic names pointing to -nonexistent revisions. This behavior is preserved for -compatibility with previous versions of \fBcvs\fR, but -because it isn\(aqt very useful, in the future it may -change to be like the \fB::\fR case. -.SP -Due to the way \fBcvs\fR handles branches \fIrev\fR -cannot be specified symbolically if it is a branch. -See `Magic branch numbers\(aq in the CVS manual for an explanation. -.SP -Make sure that no-one has checked out a copy of the -revision you outdate. Strange things will happen if he -starts to edit it and tries to check it back in. For -this reason, this option is not a good way to take back -a bogus commit; commit a new revision undoing the bogus -change instead (see node `Merging two revisions\(aq in the CVS manual). -.SP -.IP "" 0 -\fB-q\fR -.IP "" 2 -Run quietly; do not print diagnostics. -.SP -.IP "" 0 -\fB-s\fIstate\fB[:\fIrev\fB]\fR -.IP "" 2 -Useful with \fBcvs\fR. Set the state attribute of the -revision \fIrev\fR to \fIstate\fR. If \fIrev\fR is a -branch number, assume the latest revision on that -branch. If \fIrev\fR is omitted, assume the latest -revision on the default branch. Any identifier is -acceptable for \fIstate\fR. A useful set of states is -\fBExp\fR (for experimental), \fBStab\fR (for -stable), and \fBRel\fR (for released). By default, -the state of a new revision is set to \fBExp\fR when -it is created. The state is visible in the output from -\fIcvs log\fR (see node `log\(aq in the CVS manual), and in the -\fB$\fP\fPLog$\fR and \fB$\fP\fPState$\fR keywords -(see node `Keyword substitution\(aq in the CVS manual). Note that \fBcvs\fR -uses the \fBdead\fR state for its own purposes (see node `Attic\(aq in the CVS manual); to -take a file to or from the \fBdead\fR state use -commands like \fBcvs remove\fR and \fBcvs add\fR -(see node `Adding and removing\(aq in the CVS manual), not \fBcvs admin -s\fR. -.SP -.IP "" 0 -\fB-t[\fIfile\fB]\fR -.IP "" 2 -Useful with \fBcvs\fR. Write descriptive text from the -contents of the named \fIfile\fR into the RCS file, -deleting the existing text. The \fIfile\fR pathname -may not begin with \fB-\fR. The descriptive text can be seen in the -output from \fBcvs log\fR (see node `log\(aq in the CVS manual). -There can be no space between \fB-t\fR and its argument. -.SP -If \fIfile\fR is omitted, -obtain the text from standard input, terminated by -end-of-file or by a line containing \fB.\fR by itself. -Prompt for the text if interaction is possible; see -\fB-I\fR. -.SP -.IP "" 0 -\fB-t-\fIstring\fB\fR -.IP "" 2 -Similar to \fB-t\fIfile\fB\fR. Write descriptive text -from the \fIstring\fR into the \fBrcs\fR file, deleting -the existing text. -There can be no space between \fB-t\fR and its argument. -.SP -.IP "" 0 -\fB-U\fR -.IP "" 2 -Set locking to non-strict. Non-strict locking means -that the owner of a file need not lock a revision for -checkin. For use with \fBcvs\fR, strict locking must be -set; see the discussion under the \fB-l\fR option -above. -.SP -.IP "" 0 -\fB-u[\fIrev\fB]\fR -.IP "" 2 -See the option \fB-l\fR above, for a discussion of -using this option with \fBcvs\fR. Unlock the revision -with number \fIrev\fR. If a branch is given, unlock -the latest revision on that branch. If \fIrev\fR is -omitted, remove the latest lock held by the caller. -Normally, only the locker of a revision may unlock it; -somebody else unlocking a revision breaks the lock. -This causes the original locker to be sent a \fBcommit\fR -notification (see node `Getting Notified\(aq in the CVS manual). -There can be no space between \fB-u\fR and its argument. -.SP -.IP "" 0 -\fB-V\fIn\fB\fR -.IP "" 2 -In previous versions of \fBcvs\fR, this option meant to -write an \fBrcs\fR file which would be acceptable to -\fBrcs\fR version \fIn\fR, but it is now obsolete and -specifying it will produce an error. -.SP -.IP "" 0 -\fB-x\fIsuffixes\fB\fR -.IP "" 2 -In previous versions of \fBcvs\fR, this was documented -as a way of specifying the names of the \fBrcs\fR -files. However, \fBcvs\fR has always required that the -\fBrcs\fR files used by \fBcvs\fR end in \fB,v\fR, so -this option has never done anything useful. -.SP -.SP -.SH "annotate" -.SS "What revision modified each line of a file?" -.IX "annotate (subcommand)" -.SP -.IP "\(bu" 2 -Synopsis: annotate [options] files\&... -.IP "\(bu" 2 -Requires: repository. -.IP "\(bu" 2 -Synonym: blame -.IP "\(bu" 2 -Changes: nothing. -.SP -For each file in \fIfiles\fR, print the head revision -of the trunk, together with information on the last -modification for each line. -.SP -.SH "annotate options" -.SP -These standard options are supported by \fBannotate\fR -(see node `Common options\(aq in the CVS manual for a complete description of -them): -.SP -.IP "" 0 -\fB-l\fR -.IP "" 2 -Local directory only, no recursion. -.SP -.IP "" 0 -\fB-R\fR -.IP "" 2 -Process directories recursively. -.SP -.IP "" 0 -\fB-f\fR -.IP "" 2 -Use head revision if tag/date not found. -.SP -.IP "" 0 -\fB-F\fR -.IP "" 2 -Annotate binary files. -.SP -.IP "" 0 -\fB-r \fIrevision\fB\fR -.IP "" 2 -Annotate file as of specified revision/tag. -.SP -.IP "" 0 -\fB-D \fIdate\fB\fR -.IP "" 2 -Annotate file as of specified date. -.SP -.SH "annotate example" -.SP -For example: -.SP -.PD 0 -.SP -.IP "" 2 -$ cvs annotate ssfile -.IP "" 2 -Annotations for ssfile -.IP "" 2 -*************** -.IP "" 2 -1.1 (mary 27-Mar-96): ssfile line 1 -.IP "" 2 -1.2 (joe 28-Mar-96): ssfile line 2 - -.PD -.IP "" 0 -.SP -The file \fBssfile\fR currently contains two lines. -The \fBssfile line 1\fR line was checked in by -\fBmary\fR on March 27. Then, on March 28, \fBjoe\fR -added a line \fBssfile line 2\fR, without modifying -the \fBssfile line 1\fR line. This report doesn\(aqt -tell you anything about lines which have been deleted -or replaced; you need to use \fBcvs diff\fR for that -(see node `diff\(aq in the CVS manual). -.SP -The options to \fBcvs annotate\fR are listed in -`Invoking CVS\(aq in the CVS manual, and can be used to select the files -and revisions to annotate. The options are described -in more detail there and in `Common options\(aq in the CVS manual. -.SP -.SH "checkout" -.SS "Check out sources for editing" -.IX "checkout (subcommand)" -.IX "co (subcommand)" -.SP -.IP "\(bu" 2 -Synopsis: checkout [options] modules\&... -.IP "\(bu" 2 -Requires: repository. -.IP "\(bu" 2 -Changes: working directory. -.IP "\(bu" 2 -Synonyms: co, get -.SP -Create or update a working directory containing copies of the -source files specified by \fImodules\fR. You must execute -\fBcheckout\fR before using most of the other \fBcvs\fR -commands, since most of them operate on your working -directory. -.SP -The \fImodules\fR are either -symbolic names for some -collection of source directories and files, or paths to -directories or files in the repository. The symbolic -names are defined in the \fBmodules\fR file. -See `modules\(aq in the CVS manual. -.SP -Depending on the modules you specify, \fBcheckout\fR may -recursively create directories and populate them with -the appropriate source files. You can then edit these -source files at any time (regardless of whether other -software developers are editing their own copies of the -sources); update them to include new changes applied by -others to the source repository; or commit your work as -a permanent change to the source repository. -.SP -Note that \fBcheckout\fR is used to create -directories. The top-level directory created is always -added to the directory where \fBcheckout\fR is -invoked, and usually has the same name as the specified -module. In the case of a module alias, the created -sub-directory may have a different name, but you can be -sure that it will be a sub-directory, and that -\fBcheckout\fR will show the relative path leading to -each file as it is extracted into your private work -area (unless you specify the \fB-Q\fR global option). -.SP -The files created by \fBcheckout\fR are created -read-write, unless the \fB-r\fR option to \fBcvs\fR -(see node `Global options\(aq in the CVS manual) is specified, the -\fBCVSREAD\fR environment variable is specified -(see node `Environment variables\(aq in the CVS manual), or a watch is in -effect for that file (see node `Watches\(aq in the CVS manual). -.SP -Note that running \fBcheckout\fR on a directory that was already -built by a prior \fBcheckout\fR is also permitted. -This is similar to specifying the \fB-d\fR option -to the \fBupdate\fR command in the sense that new -directories that have been created in the repository -will appear in your work area. -However, \fBcheckout\fR takes a module name whereas -\fBupdate\fR takes a directory name. Also -to use \fBcheckout\fR this way it must be run from the -top level directory (where you originally ran -\fBcheckout\fR from), so before you run -\fBcheckout\fR to update an existing directory, don\(aqt -forget to change your directory to the top level -directory. -.SP -For the output produced by the \fBcheckout\fR command, -see node `update output\(aq in the CVS manual. -.SP -.SH "checkout options" -.SP -These standard options are supported by \fBcheckout\fR -(see node `Common options\(aq in the CVS manual for a complete description of -them): -.SP -.IP "" 0 -\fB-D \fIdate\fB\fR -.IP "" 2 -Use the most recent revision no later than \fIdate\fR. -This option is sticky, and implies \fB-P\fR. See -`Sticky tags\(aq in the CVS manual for more information on sticky tags/dates. -.SP -.IP "" 0 -\fB-f\fR -.IP "" 2 -Only useful with the \fB-D \fIdate\fB\fR or \fB-r -\fItag\fB\fR flags. If no matching revision is found, -retrieve the most recent revision (instead of ignoring -the file). -.SP -.IP "" 0 -\fB-k \fIkflag\fB\fR -.IP "" 2 -Process keywords according to \fIkflag\fR. See -`Keyword substitution\(aq in the CVS manual. -This option is sticky; future updates of -this file in this working directory will use the same -\fIkflag\fR. The \fBstatus\fR command can be viewed -to see the sticky options. See `Invoking CVS\(aq in the CVS manual for -more information on the \fBstatus\fR command. -.SP -.IP "" 0 -\fB-l\fR -.IP "" 2 -Local; run only in current working directory. -.SP -.IP "" 0 -\fB-n\fR -.IP "" 2 -Do not run any checkout program (as specified -with the \fB-o\fR option in the modules file; -see node `modules\(aq in the CVS manual). -.SP -.IP "" 0 -\fB-P\fR -.IP "" 2 -Prune empty directories. See `Moving directories\(aq in the CVS manual. -.SP -.IP "" 0 -\fB-p\fR -.IP "" 2 -Pipe files to the standard output. -.SP -.IP "" 0 -\fB-R\fR -.IP "" 2 -Checkout directories recursively. This option is on by default. -.SP -.IP "" 0 -\fB-r \fItag\fB\fR -.IP "" 2 -Use revision \fItag\fR. This option is sticky, and implies \fB-P\fR. -See `Sticky tags\(aq in the CVS manual, for more information on sticky tags/dates. -.SP -In addition to those, you can use these special command -options with \fBcheckout\fR: -.SP -.IP "" 0 -\fB-A\fR -.IP "" 2 -Reset any sticky tags, dates, or \fB-k\fR options. -Does not reset sticky \fB-k\fR options on modified files. -See `Sticky tags\(aq in the CVS manual for more information on sticky tags/dates. -.SP -.IP "" 0 -\fB-c\fR -.IP "" 2 -Copy the module file, sorted, to the standard output, -instead of creating or modifying any files or -directories in your working directory. -.SP -.IP "" 0 -\fB-d \fIdir\fB\fR -.IP "" 2 -Create a directory called \fIdir\fR for the working -files, instead of using the module name. In general, -using this flag is equivalent to using \fBmkdir -\fIdir\fB; cd \fIdir\fB\fR followed by the checkout -command without the \fB-d\fR flag. -.SP -There is an important exception, however. It is very -convenient when checking out a single item to have the -output appear in a directory that doesn\(aqt contain empty -intermediate directories. In this case \fIonly\fR, -\fBcvs\fR tries to \`\`shorten\(aq\(aq pathnames to avoid those empty -directories. -.SP -For example, given a module \fBfoo\fR that contains -the file \fBbar.c\fR, the command \fBcvs co -d dir -foo\fR will create directory \fBdir\fR and place -\fBbar.c\fR inside. Similarly, given a module -\fBbar\fR which has subdirectory \fBbaz\fR wherein -there is a file \fBquux.c\fR, the command \fBcvs co --d dir bar/baz\fR will create directory \fBdir\fR and -place \fBquux.c\fR inside. -.SP -Using the \fB-N\fR flag will defeat this behavior. -Given the same module definitions above, \fBcvs co --N -d dir foo\fR will create directories \fBdir/foo\fR -and place \fBbar.c\fR inside, while \fBcvs co -N -d -dir bar/baz\fR will create directories \fBdir/bar/baz\fR -and place \fBquux.c\fR inside. -.SP -.IP "" 0 -\fB-j \fItag\fB\fR -.IP "" 2 -With two \fB-j\fR options, merge changes from the -revision specified with the first \fB-j\fR option to -the revision specified with the second \fBj\fR option, -into the working directory. -.SP -With one \fB-j\fR option, merge changes from the -ancestor revision to the revision specified with the -\fB-j\fR option, into the working directory. The -ancestor revision is the common ancestor of the -revision which the working directory is based on, and -the revision specified in the \fB-j\fR option. -.SP -In addition, each -j option can contain an optional -date specification which, when used with branches, can -limit the chosen revision to one within a specific -date. An optional date is specified by adding a colon -(:) to the tag: -\fB-j\fISymbolic_Tag\fB:\fIDate_Specifier\fB\fR. -.SP -See `Branching and merging\(aq in the CVS manual. -.SP -.IP "" 0 -\fB-N\fR -.IP "" 2 -Only useful together with \fB-d \fIdir\fB\fR. With -this option, \fBcvs\fR will not \`\`shorten\(aq\(aq module paths -in your working directory when you check out a single -module. See the \fB-d\fR flag for examples and a -discussion. -.SP -.IP "" 0 -\fB-s\fR -.IP "" 2 -Like \fB-c\fR, but include the status of all modules, -and sort it by the status string. See `modules\(aq in the CVS manual, for -info about the \fB-s\fR option that is used inside the -modules file to set the module status. -.SP -.SH "checkout examples" -.SP -Get a copy of the module \fBtc\fR: -.SP -.PD 0 -.SP -.IP "" 2 -$ cvs checkout tc - -.PD -.IP "" 0 -.SP -Get a copy of the module \fBtc\fR as it looked one day -ago: -.SP -.PD 0 -.SP -.IP "" 2 -$ cvs checkout -D yesterday tc - -.PD -.IP "" 0 -.SP -.SH "commit" -.SS "Check files into the repository" -.IX "commit (subcommand)" -.SP -.IP "\(bu" 2 -Synopsis: commit [-lRf] [-m \(aqlog_message\(aq | --F file] [-r revision] [files\&...] -.IP "\(bu" 2 -Requires: working directory, repository. -.IP "\(bu" 2 -Changes: repository. -.IP "\(bu" 2 -Synonym: ci -.SP -Use \fBcommit\fR when you want to incorporate changes -from your working source files into the source -repository. -.SP -If you don\(aqt specify particular files to commit, all of -the files in your working current directory are -examined. \fBcommit\fR is careful to change in the -repository only those files that you have really -changed. By default (or if you explicitly specify the -\fB-R\fR option), files in subdirectories are also -examined and committed if they have changed; you can -use the \fB-l\fR option to limit \fBcommit\fR to the -current directory only. -.SP -\fBcommit\fR verifies that the selected files are up -to date with the current revisions in the source -repository; it will notify you, and exit without -committing, if any of the specified files must be made -current first with \fBupdate\fR (see node `update\(aq in the CVS manual). -\fBcommit\fR does not call the \fBupdate\fR command -for you, but rather leaves that for you to do when the -time is right. -.SP -When all is well, an editor is invoked to allow you to -enter a log message that will be written to one or more -logging programs (see node `modules\(aq in the CVS manual, and see node `loginfo\(aq in the CVS manual) -and placed in the \fBrcs\fR file inside the -repository. This log message can be retrieved with the -\fBlog\fR command; see node `log\(aq in the CVS manual. You can specify the -log message on the command line with the \fB-m -\fImessage\fB\fR option, and thus avoid the editor invocation, -or use the \fB-F \fIfile\fB\fR option to specify -that the argument file contains the log message. -.SP -.SH "commit options" -.SP -These standard options are supported by \fBcommit\fR -(see node `Common options\(aq in the CVS manual for a complete description of -them): -.SP -.IP "" 0 -\fB-l\fR -.IP "" 2 -Local; run only in current working directory. -.SP -.IP "" 0 -\fB-R\fR -.IP "" 2 -Commit directories recursively. This is on by default. -.SP -.IP "" 0 -\fB-r \fIrevision\fB\fR -.IP "" 2 -Commit to \fIrevision\fR. \fIrevision\fR must be -either a branch, or a revision on the main trunk that -is higher than any existing revision number -(see node `Assigning revisions\(aq in the CVS manual). You -cannot commit to a specific revision on a branch. -.SP -\fBcommit\fR also supports these options: -.SP -.IP "" 0 -\fB-F \fIfile\fB\fR -.IP "" 2 -Read the log message from \fIfile\fR, instead -of invoking an editor. -.SP -.IP "" 0 -\fB-f\fR -.IP "" 2 -Note that this is not the standard behavior of -the \fB-f\fR option as defined in `Common options\(aq in the CVS manual. -.SP -Force \fBcvs\fR to commit a new revision even if you haven\(aqt -made any changes to the file. If the current revision -of \fIfile\fR is 1.7, then the following two commands -are equivalent: -.SP -.PD 0 -.SP -.IP "" 4 -$ cvs commit -f \fIfile\fR -.IP "" 4 -$ cvs commit -r 1.8 \fIfile\fR - -.PD -.IP "" 2 -.SP -The \fB-f\fR option disables recursion (i.e., it -implies \fB-l\fR). To force \fBcvs\fR to commit a new -revision for all files in all subdirectories, you must -use \fB-f -R\fR. -.SP -.IP "" 0 -\fB-m \fImessage\fB\fR -.IP "" 2 -Use \fImessage\fR as the log message, instead of -invoking an editor. -.SP -.SH "commit examples" -.SP -.SS "Committing to a branch" -.SP -You can commit to a branch revision (one that has an -even number of dots) with the \fB-r\fR option. To -create a branch revision, use the \fB-b\fR option -of the \fBrtag\fR or \fBtag\fR commands -(see node `Branching and merging\(aq in the CVS manual). Then, either \fBcheckout\fR or -\fBupdate\fR can be used to base your sources on the -newly created branch. From that point on, all -\fBcommit\fR changes made within these working sources -will be automatically added to a branch revision, -thereby not disturbing main-line development in any -way. For example, if you had to create a patch to the -1.2 version of the product, even though the 2.0 version -is already under development, you might do: -.SP -.PD 0 -.SP -.IP "" 2 -$ cvs rtag -b -r FCS1_2 FCS1_2_Patch product_module -.IP "" 2 -$ cvs checkout -r FCS1_2_Patch product_module -.IP "" 2 -$ cd product_module -.IP "" 2 -[[ hack away ]] -.IP "" 2 -$ cvs commit - -.PD -.IP "" 0 -.SP -This works automatically since the \fB-r\fR option is -sticky. -.SP -.SS "Creating the branch after editing" -.SP -Say you have been working on some extremely -experimental software, based on whatever revision you -happened to checkout last week. If others in your -group would like to work on this software with you, but -without disturbing main-line development, you could -commit your change to a new branch. Others can then -checkout your experimental stuff and utilize the full -benefit of \fBcvs\fR conflict resolution. The scenario might -look like: -.SP -.PD 0 -.SP -.IP "" 2 -[[ hacked sources are present ]] -.IP "" 2 -$ cvs tag -b EXPR1 -.IP "" 2 -$ cvs update -r EXPR1 -.IP "" 2 -$ cvs commit - -.PD -.IP "" 0 -.SP -The \fBupdate\fR command will make the \fB-r -EXPR1\fR option sticky on all files. Note that your -changes to the files will never be removed by the -\fBupdate\fR command. The \fBcommit\fR will -automatically commit to the correct branch, because the -\fB-r\fR is sticky. You could also do like this: -.SP -.PD 0 -.SP -.IP "" 2 -[[ hacked sources are present ]] -.IP "" 2 -$ cvs tag -b EXPR1 -.IP "" 2 -$ cvs commit -r EXPR1 - -.PD -.IP "" 0 -.SP -but then, only those files that were changed by you -will have the \fB-r EXPR1\fR sticky flag. If you hack -away, and commit without specifying the \fB-r EXPR1\fR -flag, some files may accidentally end up on the main -trunk. -.SP -To work with you on the experimental change, others -would simply do -.SP -.PD 0 -.SP -.IP "" 2 -$ cvs checkout -r EXPR1 whatever_module - -.PD -.IP "" 0 -.SP -.SH "diff" -.SS "Show differences between revisions" -.IX "diff (subcommand)" -.SP -.IP "\(bu" 2 -Synopsis: diff [-lR] [-k kflag] [format_options] [[-r rev1 | -D date1] [-r rev2 | -D date2]] [files\&...] -.IP "\(bu" 2 -Requires: working directory, repository. -.IP "\(bu" 2 -Changes: nothing. -.SP -The \fBdiff\fR command is used to compare different -revisions of files. The default action is to compare -your working files with the revisions they were based -on, and report any differences that are found. -.SP -If any file names are given, only those files are -compared. If any directories are given, all files -under them will be compared. -.SP -The exit status for diff is different than for other -\fBcvs\fR commands; for details see node `Exit status\(aq in the CVS manual. -.SP -.SH "diff options" -.SP -These standard options are supported by \fBdiff\fR -(see node `Common options\(aq in the CVS manual for a complete description of -them): -.SP -.IP "" 0 -\fB-D \fIdate\fB\fR -.IP "" 2 -Use the most recent revision no later than \fIdate\fR. -See \fB-r\fR for how this affects the comparison. -.SP -.IP "" 0 -\fB-k \fIkflag\fB\fR -.IP "" 2 -Process keywords according to \fIkflag\fR. See -`Keyword substitution\(aq in the CVS manual. -.SP -.IP "" 0 -\fB-l\fR -.IP "" 2 -Local; run only in current working directory. -.SP -.IP "" 0 -\fB-R\fR -.IP "" 2 -Examine directories recursively. This option is on by -default. -.SP -.IP "" 0 -\fB-r \fItag\fB\fR -.IP "" 2 -Compare with revision \fItag\fR. Zero, one or two -\fB-r\fR options can be present. With no \fB-r\fR -option, the working file will be compared with the -revision it was based on. With one \fB-r\fR, that -revision will be compared to your current working file. -With two \fB-r\fR options those two revisions will be -compared (and your working file will not affect the -outcome in any way). -.SP -One or both \fB-r\fR options can be replaced by a -\fB-D \fIdate\fB\fR option, described above. -.SP -The following options specify the format of the -output. They have the same meaning as in GNU diff. -Most options have two equivalent names, one of which is a single letter -preceded by \fB-\fR, and the other of which is a long name preceded by -\fB--\fR. -.SP -.IP "" 0 -\fB-\fIlines\fB\fR -.IP "" 2 -Show \fIlines\fR (an integer) lines of context. This option does not -specify an output format by itself; it has no effect unless it is -combined with \fB-c\fR or \fB-u\fR. This option is obsolete. For proper -operation, \fBpatch\fR typically needs at least two lines of context. -.SP -.IP "" 0 -\fB-a\fR -.IP "" 2 -Treat all files as text and compare them line-by-line, even if they -do not seem to be text. -.SP -.IP "" 0 -\fB-b\fR -.IP "" 2 -Ignore trailing white space and consider all other sequences of one or -more white space characters to be equivalent. -.SP -.IP "" 0 -\fB-B\fR -.IP "" 2 -Ignore changes that just insert or delete blank lines. -.SP -.IP "" 0 -\fB--binary\fR -.IP "" 2 -Read and write data in binary mode. -.SP -.IP "" 0 -\fB--brief\fR -.IP "" 2 -Report only whether the files differ, not the details of the -differences. -.SP -.IP "" 0 -\fB-c\fR -.IP "" 2 -Use the context output format. -.SP -.IP "" 0 -\fB-C \fIlines\fB\fR -.IP "" 2 -.IP "" 0 -\fB--context\fR[\fB=\fIlines\fB\fR]\fB\fR -.IP "" 2 -Use the context output format, showing \fIlines\fR (an integer) lines of -context, or three if \fIlines\fR is not given. -For proper operation, \fBpatch\fR typically needs at least two lines of -context. -.SP -.IP "" 0 -\fB--changed-group-format=\fIformat\fB\fR -.IP "" 2 -Use \fIformat\fR to output a line group containing differing lines from -both files in if-then-else format. See `Line group formats\(aq in the CVS manual. -.SP -.IP "" 0 -\fB-d\fR -.IP "" 2 -Change the algorithm to perhaps find a smaller set of changes. This makes -\fBdiff\fR slower (sometimes much slower). -.SP -.IP "" 0 -\fB-e\fR -.IP "" 2 -.IP "" 0 -\fB--ed\fR -.IP "" 2 -Make output that is a valid \fBed\fR script. -.SP -.IP "" 0 -\fB--expand-tabs\fR -.IP "" 2 -Expand tabs to spaces in the output, to preserve the alignment of tabs -in the input files. -.SP -.IP "" 0 -\fB-f\fR -.IP "" 2 -Make output that looks vaguely like an \fBed\fR script but has changes -in the order they appear in the file. -.SP -.IP "" 0 -\fB-F \fIregexp\fB\fR -.IP "" 2 -In context and unified format, for each hunk of differences, show some -of the last preceding line that matches \fIregexp\fR. -.SP -.IP "" 0 -\fB--forward-ed\fR -.IP "" 2 -Make output that looks vaguely like an \fBed\fR script but has changes -in the order they appear in the file. -.SP -.IP "" 0 -\fB-H\fR -.IP "" 2 -Use heuristics to speed handling of large files that have numerous -scattered small changes. -.SP -.IP "" 0 -\fB--horizon-lines=\fIlines\fB\fR -.IP "" 2 -Do not discard the last \fIlines\fR lines of the common prefix -and the first \fIlines\fR lines of the common suffix. -.SP -.IP "" 0 -\fB-i\fR -.IP "" 2 -Ignore changes in case; consider upper- and lower-case letters -equivalent. -.SP -.IP "" 0 -\fB-I \fIregexp\fB\fR -.IP "" 2 -Ignore changes that just insert or delete lines that match \fIregexp\fR. -.SP -.IP "" 0 -\fB--ifdef=\fIname\fB\fR -.IP "" 2 -Make merged if-then-else output using \fIname\fR. -.SP -.IP "" 0 -\fB--ignore-all-space\fR -.IP "" 2 -Ignore white space when comparing lines. -.SP -.IP "" 0 -\fB--ignore-blank-lines\fR -.IP "" 2 -Ignore changes that just insert or delete blank lines. -.SP -.IP "" 0 -\fB--ignore-case\fR -.IP "" 2 -Ignore changes in case; consider upper- and lower-case to be the same. -.SP -.IP "" 0 -\fB--ignore-matching-lines=\fIregexp\fB\fR -.IP "" 2 -Ignore changes that just insert or delete lines that match \fIregexp\fR. -.SP -.IP "" 0 -\fB--ignore-space-change\fR -.IP "" 2 -Ignore trailing white space and consider all other sequences of one or -more white space characters to be equivalent. -.SP -.IP "" 0 -\fB--initial-tab\fR -.IP "" 2 -Output a tab rather than a space before the text of a line in normal or -context format. This causes the alignment of tabs in the line to look -normal. -.SP -.IP "" 0 -\fB-L \fIlabel\fB\fR -.IP "" 2 -Use \fIlabel\fR instead of the file name in the context format -and unified format headers. -.SP -.IP "" 0 -\fB--label=\fIlabel\fB\fR -.IP "" 2 -Use \fIlabel\fR instead of the file name in the context format -and unified format headers. -.SP -.IP "" 0 -\fB--left-column\fR -.IP "" 2 -Print only the left column of two common lines in side by side format. -.SP -.IP "" 0 -\fB--line-format=\fIformat\fB\fR -.IP "" 2 -Use \fIformat\fR to output all input lines in if-then-else format. -See `Line formats\(aq in the CVS manual. -.SP -.IP "" 0 -\fB--minimal\fR -.IP "" 2 -Change the algorithm to perhaps find a smaller set of changes. This -makes \fBdiff\fR slower (sometimes much slower). -.SP -.IP "" 0 -\fB-n\fR -.IP "" 2 -Output RCS-format diffs; like \fB-f\fR except that each command -specifies the number of lines affected. -.SP -.IP "" 0 -\fB-N\fR -.IP "" 2 -.IP "" 0 -\fB--new-file\fR -.IP "" 2 -In directory comparison, if a file is found in only one directory, -treat it as present but empty in the other directory. -.SP -.IP "" 0 -\fB--new-group-format=\fIformat\fB\fR -.IP "" 2 -Use \fIformat\fR to output a group of lines taken from just the second -file in if-then-else format. See `Line group formats\(aq in the CVS manual. -.SP -.IP "" 0 -\fB--new-line-format=\fIformat\fB\fR -.IP "" 2 -Use \fIformat\fR to output a line taken from just the second file in -if-then-else format. See `Line formats\(aq in the CVS manual. -.SP -.IP "" 0 -\fB--old-group-format=\fIformat\fB\fR -.IP "" 2 -Use \fIformat\fR to output a group of lines taken from just the first -file in if-then-else format. See `Line group formats\(aq in the CVS manual. -.SP -.IP "" 0 -\fB--old-line-format=\fIformat\fB\fR -.IP "" 2 -Use \fIformat\fR to output a line taken from just the first file in -if-then-else format. See `Line formats\(aq in the CVS manual. -.SP -.IP "" 0 -\fB-p\fR -.IP "" 2 -Show which C function each change is in. -.SP -.IP "" 0 -\fB--rcs\fR -.IP "" 2 -Output RCS-format diffs; like \fB-f\fR except that each command -specifies the number of lines affected. -.SP -.IP "" 0 -\fB--report-identical-files\fR -.IP "" 2 -.IP "" 0 -\fB-s\fR -.IP "" 2 -Report when two files are the same. -.SP -.IP "" 0 -\fB--show-c-function\fR -.IP "" 2 -Show which C function each change is in. -.SP -.IP "" 0 -\fB--show-function-line=\fIregexp\fB\fR -.IP "" 2 -In context and unified format, for each hunk of differences, show some -of the last preceding line that matches \fIregexp\fR. -.SP -.IP "" 0 -\fB--side-by-side\fR -.IP "" 2 -Use the side by side output format. -.SP -.IP "" 0 -\fB--speed-large-files\fR -.IP "" 2 -Use heuristics to speed handling of large files that have numerous -scattered small changes. -.SP -.IP "" 0 -\fB--suppress-common-lines\fR -.IP "" 2 -Do not print common lines in side by side format. -.SP -.IP "" 0 -\fB-t\fR -.IP "" 2 -Expand tabs to spaces in the output, to preserve the alignment of tabs -in the input files. -.SP -.IP "" 0 -\fB-T\fR -.IP "" 2 -Output a tab rather than a space before the text of a line in normal or -context format. This causes the alignment of tabs in the line to look -normal. -.SP -.IP "" 0 -\fB--text\fR -.IP "" 2 -Treat all files as text and compare them line-by-line, even if they -do not appear to be text. -.SP -.IP "" 0 -\fB-u\fR -.IP "" 2 -Use the unified output format. -.SP -.IP "" 0 -\fB--unchanged-group-format=\fIformat\fB\fR -.IP "" 2 -Use \fIformat\fR to output a group of common lines taken from both files -in if-then-else format. see node `Line group formats\(aq in the CVS manual. -.SP -.IP "" 0 -\fB--unchanged-line-format=\fIformat\fB\fR -.IP "" 2 -Use \fIformat\fR to output a line common to both files in if-then-else -format. see node `Line formats\(aq in the CVS manual. -.SP -.IP "" 0 -\fB-U \fIlines\fB\fR -.IP "" 2 -.IP "" 0 -\fB--unified\fR[\fB=\fIlines\fB\fR]\fB\fR -.IP "" 2 -Use the unified output format, showing \fIlines\fR (an integer) lines of -context, or three if \fIlines\fR is not given. -For proper operation, \fBpatch\fR typically needs at least two lines of -context. -.SP -.IP "" 0 -\fB-w\fR -.IP "" 2 -Ignore white space when comparing lines. -.SP -.IP "" 0 -\fB-W \fIcolumns\fB\fR -.IP "" 2 -.IP "" 0 -\fB--width=\fIcolumns\fB\fR -.IP "" 2 -Use an output width of \fIcolumns\fR in side by side format. -.SP -.IP "" 0 -\fB-y\fR -.IP "" 2 -Use the side by side output format. -.SP -.SH "Line group formats" -.SP -Line group formats let you specify formats suitable for many -applications that allow if-then-else input, including programming -languages and text formatting languages. A line group format specifies -the output format for a contiguous group of similar lines. -.SP -For example, the following command compares the TeX file \fBmyfile\fR -with the original version from the repository, -and outputs a merged file in which old regions are -surrounded by \fB\\begin{em}\fR-\fB\\end{em}\fR lines, and new -regions are surrounded by \fB\\begin{bf}\fR-\fB\\end{bf}\fR lines. -.SP -.PD 0 -.SP -.IP "" 2 -cvs diff \\ -.IP "" 2 - --old-group-format=\(aq\\begin{em} -.IP "" 2 -%<\\end{em} -.IP "" 2 -\(aq \\ -.IP "" 2 - --new-group-format=\(aq\\begin{bf} -.IP "" 2 -%>\\end{bf} -.IP "" 2 -\(aq \\ -.IP "" 2 - myfile - -.PD -.IP "" 0 -.SP -The following command is equivalent to the above example, but it is a -little more verbose, because it spells out the default line group formats. -.SP -.PD 0 -.SP -.IP "" 2 -cvs diff \\ -.IP "" 2 - --old-group-format=\(aq\\begin{em} -.IP "" 2 -%<\\end{em} -.IP "" 2 -\(aq \\ -.IP "" 2 - --new-group-format=\(aq\\begin{bf} -.IP "" 2 -%>\\end{bf} -.IP "" 2 -\(aq \\ -.IP "" 2 - --unchanged-group-format=\(aq%=\(aq \\ -.IP "" 2 - --changed-group-format=\(aq\\begin{em} -.IP "" 2 -%<\\end{em} -.IP "" 2 -\\begin{bf} -.IP "" 2 -%>\\end{bf} -.IP "" 2 -\(aq \\ -.IP "" 2 - myfile - -.PD -.IP "" 0 -.SP -Here is a more advanced example, which outputs a diff listing with -headers containing line numbers in a \`\`plain English\(aq\(aq style. -.SP -.PD 0 -.SP -.IP "" 2 -cvs diff \\ -.IP "" 2 - --unchanged-group-format=\(aq\(aq \\ -.IP "" 2 - --old-group-format=\(aq-------- %dn line%(n=1?:s) deleted at %df: -.IP "" 2 -%<\(aq \\ -.IP "" 2 - --new-group-format=\(aq-------- %dN line%(N=1?:s) added after %de: -.IP "" 2 -%>\(aq \\ -.IP "" 2 - --changed-group-format=\(aq-------- %dn line%(n=1?:s) changed at %df: -.IP "" 2 -%<-------- to: -.IP "" 2 -%>\(aq \\ -.IP "" 2 - myfile - -.PD -.IP "" 0 -.SP -To specify a line group format, use one of the options -listed below. You can specify up to four line group formats, one for -each kind of line group. You should quote \fIformat\fR, because it -typically contains shell metacharacters. -.SP -.IP "" 0 -\fB--old-group-format=\fIformat\fB\fR -.IP "" 2 -These line groups are hunks containing only lines from the first file. -The default old group format is the same as the changed group format if -it is specified; otherwise it is a format that outputs the line group as-is. -.SP -.IP "" 0 -\fB--new-group-format=\fIformat\fB\fR -.IP "" 2 -These line groups are hunks containing only lines from the second -file. The default new group format is same as the changed group -format if it is specified; otherwise it is a format that outputs the -line group as-is. -.SP -.IP "" 0 -\fB--changed-group-format=\fIformat\fB\fR -.IP "" 2 -These line groups are hunks containing lines from both files. The -default changed group format is the concatenation of the old and new -group formats. -.SP -.IP "" 0 -\fB--unchanged-group-format=\fIformat\fB\fR -.IP "" 2 -These line groups contain lines common to both files. The default -unchanged group format is a format that outputs the line group as-is. -.SP -In a line group format, ordinary characters represent themselves; -conversion specifications start with \fB%\fR and have one of the -following forms. -.SP -.IP "" 0 -\fB%<\fR -.IP "" 2 -stands for the lines from the first file, including the trailing newline. -Each line is formatted according to the old line format (see node `Line formats\(aq in the CVS manual). -.SP -.IP "" 0 -\fB%>\fR -.IP "" 2 -stands for the lines from the second file, including the trailing newline. -Each line is formatted according to the new line format. -.SP -.IP "" 0 -\fB%=\fR -.IP "" 2 -stands for the lines common to both files, including the trailing newline. -Each line is formatted according to the unchanged line format. -.SP -.IP "" 0 -\fB%%\fR -.IP "" 2 -stands for \fB%\fR. -.SP -.IP "" 0 -\fB%c\(aq\fIC\fB\(aq\fR -.IP "" 2 -where \fIC\fR is a single character, stands for \fIC\fR. -\fIC\fR may not be a backslash or an apostrophe. -For example, \fB%c\(aq:\(aq\fR stands for a colon, even inside -the then-part of an if-then-else format, which a colon would -normally terminate. -.SP -.IP "" 0 -\fB%c\(aq\\\fIO\fB\(aq\fR -.IP "" 2 -where \fIO\fR is a string of 1, 2, or 3 octal digits, -stands for the character with octal code \fIO\fR. -For example, \fB%c\(aq\\0\(aq\fR stands for a null character. -.SP -.IP "" 0 -\fB\fIF\fB\fIn\fB\fR -.IP "" 2 -where \fIF\fR is a \fBprintf\fR conversion specification and \fIn\fR is one -of the following letters, stands for \fIn\fR\(aqs value formatted with \fIF\fR. -.SP -.IP "" 2 -\fBe\fR -.IP "" 4 -The line number of the line just before the group in the old file. -.SP -.IP "" 2 -\fBf\fR -.IP "" 4 -The line number of the first line in the group in the old file; -equals \fIe\fR + 1. -.SP -.IP "" 2 -\fBl\fR -.IP "" 4 -The line number of the last line in the group in the old file. -.SP -.IP "" 2 -\fBm\fR -.IP "" 4 -The line number of the line just after the group in the old file; -equals \fIl\fR + 1. -.SP -.IP "" 2 -\fBn\fR -.IP "" 4 -The number of lines in the group in the old file; equals \fIl\fR - \fIf\fR + 1. -.SP -.IP "" 2 -\fBE, F, L, M, N\fR -.IP "" 4 -Likewise, for lines in the new file. -.SP -.SP -The \fBprintf\fR conversion specification can be \fB%d\fR, -\fB%o\fR, \fB%x\fR, or \fB%X\fR, specifying decimal, octal, -lower case hexadecimal, or upper case hexadecimal output -respectively. After the \fB%\fR the following options can appear in -sequence: a \fB-\fR specifying left-justification; an integer -specifying the minimum field width; and a period followed by an -optional integer specifying the minimum number of digits. -For example, \fB%5dN\fR prints the number of new lines in the group -in a field of width 5 characters, using the \fBprintf\fR format \fB"%5d"\fR. -.SP -.IP "" 0 -\fB(\fIA\fB=\fIB\fB?\fIT\fB:\fIE\fB)\fR -.IP "" 2 -If \fIA\fR equals \fIB\fR then \fIT\fR else \fIE\fR. -\fIA\fR and \fIB\fR are each either a decimal constant -or a single letter interpreted as above. -This format spec is equivalent to \fIT\fR if -\fIA\fR\(aqs value equals \fIB\fR\(aqs; otherwise it is equivalent to \fIE\fR. -.SP -For example, \fB%(N=0?no:%dN) line%(N=1?:s)\fR is equivalent to -\fBno lines\fR if \fIN\fR (the number of lines in the group in the -new file) is 0, to \fB1 line\fR if \fIN\fR is 1, and to \fB%dN lines\fR -otherwise. -.SP -.SH "Line formats" -.SP -Line formats control how each line taken from an input file is -output as part of a line group in if-then-else format. -.SP -For example, the following command outputs text with a one-column -change indicator to the left of the text. The first column of output -is \fB-\fR for deleted lines, \fB|\fR for added lines, and a space -for unchanged lines. The formats contain newline characters where -newlines are desired on output. -.SP -.PD 0 -.SP -.IP "" 2 -cvs diff \\ -.IP "" 2 - --old-line-format=\(aq-%l -.IP "" 2 -\(aq \\ -.IP "" 2 - --new-line-format=\(aq|%l -.IP "" 2 -\(aq \\ -.IP "" 2 - --unchanged-line-format=\(aq %l -.IP "" 2 -\(aq \\ -.IP "" 2 - myfile - -.PD -.IP "" 0 -.SP -To specify a line format, use one of the following options. You should -quote \fIformat\fR, since it often contains shell metacharacters. -.SP -.IP "" 0 -\fB--old-line-format=\fIformat\fB\fR -.IP "" 2 -formats lines just from the first file. -.SP -.IP "" 0 -\fB--new-line-format=\fIformat\fB\fR -.IP "" 2 -formats lines just from the second file. -.SP -.IP "" 0 -\fB--unchanged-line-format=\fIformat\fB\fR -.IP "" 2 -formats lines common to both files. -.SP -.IP "" 0 -\fB--line-format=\fIformat\fB\fR -.IP "" 2 -formats all lines; in effect, it sets all three above options simultaneously. -.SP -In a line format, ordinary characters represent themselves; -conversion specifications start with \fB%\fR and have one of the -following forms. -.SP -.IP "" 0 -\fB%l\fR -.IP "" 2 -stands for the contents of the line, not counting its trailing -newline (if any). This format ignores whether the line is incomplete. -.SP -.IP "" 0 -\fB%L\fR -.IP "" 2 -stands for the contents of the line, including its trailing newline -(if any). If a line is incomplete, this format preserves its -incompleteness. -.SP -.IP "" 0 -\fB%%\fR -.IP "" 2 -stands for \fB%\fR. -.SP -.IP "" 0 -\fB%c\(aq\fIC\fB\(aq\fR -.IP "" 2 -where \fIC\fR is a single character, stands for \fIC\fR. -\fIC\fR may not be a backslash or an apostrophe. -For example, \fB%c\(aq:\(aq\fR stands for a colon. -.SP -.IP "" 0 -\fB%c\(aq\\\fIO\fB\(aq\fR -.IP "" 2 -where \fIO\fR is a string of 1, 2, or 3 octal digits, -stands for the character with octal code \fIO\fR. -For example, \fB%c\(aq\\0\(aq\fR stands for a null character. -.SP -.IP "" 0 -\fB\fIF\fBn\fR -.IP "" 2 -where \fIF\fR is a \fBprintf\fR conversion specification, -stands for the line number formatted with \fIF\fR. -For example, \fB%.5dn\fR prints the line number using the -\fBprintf\fR format \fB"%.5d"\fR. see node `Line group formats\(aq in the CVS manual, for -more about printf conversion specifications. -.SP -.SP -The default line format is \fB%l\fR followed by a newline character. -.SP -If the input contains tab characters and it is important that they line -up on output, you should ensure that \fB%l\fR or \fB%L\fR in a line -format is just after a tab stop (e.g. by preceding \fB%l\fR or -\fB%L\fR with a tab character), or you should use the \fB-t\fR or -\fB--expand-tabs\fR option. -.SP -Taken together, the line and line group formats let you specify many -different formats. For example, the following command uses a format -similar to \fBdiff\fR\(aqs normal format. You can tailor this command -to get fine control over \fBdiff\fR\(aqs output. -.SP -.PD 0 -.SP -.IP "" 2 -cvs diff \\ -.IP "" 2 - --old-line-format=\(aq< %l -.IP "" 2 -\(aq \\ -.IP "" 2 - --new-line-format=\(aq> %l -.IP "" 2 -\(aq \\ -.IP "" 2 - --old-group-format=\(aq%df%(f=l?:,%dl)d%dE -.IP "" 2 -%<\(aq \\ -.IP "" 2 - --new-group-format=\(aq%dea%dF%(F=L?:,%dL) -.IP "" 2 -%>\(aq \\ -.IP "" 2 - --changed-group-format=\(aq%df%(f=l?:,%dl)c%dF%(F=L?:,%dL) -.IP "" 2 -%<\(em -.IP "" 2 -%>\(aq \\ -.IP "" 2 - --unchanged-group-format=\(aq\(aq \\ -.IP "" 2 - myfile - -.PD -.IP "" 0 -.SP -.SH "diff examples" -.SP -The following line produces a Unidiff (\fB-u\fR flag) -between revision 1.14 and 1.19 of -\fBbackend.c\fR. Due to the \fB-kk\fR flag no -keywords are substituted, so differences that only depend -on keyword substitution are ignored. -.SP -.PD 0 -.SP -.IP "" 2 -$ cvs diff -kk -u -r 1.14 -r 1.19 backend.c - -.PD -.IP "" 0 -.SP -Suppose the experimental branch EXPR1 was based on a -set of files tagged RELEASE_1_0. To see what has -happened on that branch, the following can be used: -.SP -.PD 0 -.SP -.IP "" 2 -$ cvs diff -r RELEASE_1_0 -r EXPR1 - -.PD -.IP "" 0 -.SP -A command like this can be used to produce a context -diff between two releases: -.SP -.PD 0 -.SP -.IP "" 2 -$ cvs diff -c -r RELEASE_1_0 -r RELEASE_1_1 > diffs - -.PD -.IP "" 0 -.SP -If you are maintaining ChangeLogs, a command like the following -just before you commit your changes may help you write -the ChangeLog entry. All local modifications that have -not yet been committed will be printed. -.SP -.PD 0 -.SP -.IP "" 2 -$ cvs diff -u | less - -.PD -.IP "" 0 -.SP -.SH "export" -.SS "Export sources from CVS, similar to checkout" -.IX "export (subcommand)" -.SP -.IP "\(bu" 2 -Synopsis: export [-flNnR] [-r rev|-D date] [-k subst] [-d dir] module\&... -.IP "\(bu" 2 -Requires: repository. -.IP "\(bu" 2 -Changes: current directory. -.SP -This command is a variant of \fBcheckout\fR; use it -when you want a copy of the source for module without -the \fBcvs\fR administrative directories. For example, you -might use \fBexport\fR to prepare source for shipment -off-site. This command requires that you specify a -date or tag (with \fB-D\fR or \fB-r\fR), so that you -can count on reproducing the source you ship to others -(and thus it always prunes empty directories). -.SP -One often would like to use \fB-kv\fR with \fBcvs -export\fR. This causes any keywords to be -expanded such that an import done at some other site -will not lose the keyword revision information. But be -aware that doesn\(aqt handle an export containing binary -files correctly. Also be aware that after having used -\fB-kv\fR, one can no longer use the \fBident\fR -command (which is part of the \fBrcs\fR suite\(emsee -ident(1)) which looks for keyword strings. If -you want to be able to use \fBident\fR you must not -use \fB-kv\fR. -.SP -.SH "export options" -.SP -These standard options are supported by \fBexport\fR -(see node `Common options\(aq in the CVS manual, for a complete description of -them): -.SP -.IP "" 0 -\fB-D \fIdate\fB\fR -.IP "" 2 -Use the most recent revision no later than \fIdate\fR. -.SP -.IP "" 0 -\fB-f\fR -.IP "" 2 -If no matching revision is found, retrieve the most -recent revision (instead of ignoring the file). -.SP -.IP "" 0 -\fB-l\fR -.IP "" 2 -Local; run only in current working directory. -.SP -.IP "" 0 -\fB-n\fR -.IP "" 2 -Do not run any checkout program. -.SP -.IP "" 0 -\fB-R\fR -.IP "" 2 -Export directories recursively. This is on by default. -.SP -.IP "" 0 -\fB-r \fItag\fB\fR -.IP "" 2 -Use revision \fItag\fR. -.SP -In addition, these options (that are common to -\fBcheckout\fR and \fBexport\fR) are also supported: -.SP -.IP "" 0 -\fB-d \fIdir\fB\fR -.IP "" 2 -Create a directory called \fIdir\fR for the working -files, instead of using the module name. -See `checkout options\(aq in the CVS manual for complete details on how -\fBcvs\fR handles this flag. -.SP -.IP "" 0 -\fB-k \fIsubst\fB\fR -.IP "" 2 -Set keyword expansion mode (see node `Substitution modes\(aq in the CVS manual). -.SP -.IP "" 0 -\fB-N\fR -.IP "" 2 -Only useful together with \fB-d \fIdir\fB\fR. -See `checkout options\(aq in the CVS manual for complete details on how -\fBcvs\fR handles this flag. -.SP -.SH "history" -.SS "Show status of files and users" -.IX "history (subcommand)" -.SP -.IP "\(bu" 2 -Synopsis: history [-report] [-flags] [-options args] [files\&...] -.IP "\(bu" 2 -Requires: the file \fB$CVSROOT/CVSROOT/history\fR -.IP "\(bu" 2 -Changes: nothing. -.SP -\fBcvs\fR can keep a history file that tracks each use of the -\fBcheckout\fR, \fBcommit\fR, \fBrtag\fR, -\fBupdate\fR, and \fBrelease\fR commands. You can -use \fBhistory\fR to display this information in -various formats. -.SP -Logging must be enabled by creating the file -\fB$CVSROOT/CVSROOT/history\fR. -.SP -\fB\fBhistory\fB uses \fB-f\fB, \fB-l\fB, -\fB-n\fB, and \fB-p\fB in ways that conflict with the -normal use inside \fBcvs\fB (see node `Common options\(aq in the CVS manual).\fR -.SP -.SH "history options" -.SP -Several options (shown above as \fB-report\fR) control what -kind of report is generated: -.SP -.IP "" 0 -\fB-c\fR -.IP "" 2 -Report on each time commit was used (i.e., each time -the repository was modified). -.SP -.IP "" 0 -\fB-e\fR -.IP "" 2 -Everything (all record types). Equivalent to -specifying \fB-x\fR with all record types. Of course, -\fB-e\fR will also include record types which are -added in a future version of \fBcvs\fR; if you are -writing a script which can only handle certain record -types, you\(aqll want to specify \fB-x\fR. -.SP -.IP "" 0 -\fB-m \fImodule\fB\fR -.IP "" 2 -Report on a particular module. (You can meaningfully -use \fB-m\fR more than once on the command line.) -.SP -.IP "" 0 -\fB-o\fR -.IP "" 2 -Report on checked-out modules. This is the default report type. -.SP -.IP "" 0 -\fB-T\fR -.IP "" 2 -Report on all tags. -.SP -.IP "" 0 -\fB-x \fItype\fB\fR -.IP "" 2 -Extract a particular set of record types \fItype\fR from the \fBcvs\fR -history. The types are indicated by single letters, -which you may specify in combination. -.SP -Certain commands have a single record type: -.SP -.IP "" 2 -\fBF\fR -.IP "" 4 -release -.IP "" 2 -\fBO\fR -.IP "" 4 -checkout -.IP "" 2 -\fBE\fR -.IP "" 4 -export -.IP "" 2 -\fBT\fR -.IP "" 4 -rtag -.SP -One of five record types may result from an update: -.SP -.IP "" 2 -\fBC\fR -.IP "" 4 -A merge was necessary but collisions were -detected (requiring manual merging). -.IP "" 2 -\fBG\fR -.IP "" 4 -A merge was necessary and it succeeded. -.IP "" 2 -\fBU\fR -.IP "" 4 -A working file was copied from the repository. -.IP "" 2 -\fBP\fR -.IP "" 4 -A working file was patched to match the repository. -.IP "" 2 -\fBW\fR -.IP "" 4 -The working copy of a file was deleted during -update (because it was gone from the repository). -.SP -One of three record types results from commit: -.SP -.IP "" 2 -\fBA\fR -.IP "" 4 -A file was added for the first time. -.IP "" 2 -\fBM\fR -.IP "" 4 -A file was modified. -.IP "" 2 -\fBR\fR -.IP "" 4 -A file was removed. -.SP -The options shown as \fB-flags\fR constrain or expand -the report without requiring option arguments: -.SP -.IP "" 0 -\fB-a\fR -.IP "" 2 -Show data for all users (the default is to show data -only for the user executing \fBhistory\fR). -.SP -.IP "" 0 -\fB-l\fR -.IP "" 2 -Show last modification only. -.SP -.IP "" 0 -\fB-w\fR -.IP "" 2 -Show only the records for modifications done from the -same working directory where \fBhistory\fR is -executing. -.SP -The options shown as \fB-options \fIargs\fB\fR constrain the report -based on an argument: -.SP -.IP "" 0 -\fB-b \fIstr\fB\fR -.IP "" 2 -Show data back to a record containing the string -\fIstr\fR in either the module name, the file name, or -the repository path. -.SP -.IP "" 0 -\fB-D \fIdate\fB\fR -.IP "" 2 -Show data since \fIdate\fR. This is slightly different -from the normal use of \fB-D \fIdate\fB\fR, which -selects the newest revision older than \fIdate\fR. -.SP -.IP "" 0 -\fB-f \fIfile\fB\fR -.IP "" 2 -Show data for a particular file -(you can specify several \fB-f\fR options on the same command line). -This is equivalent to specifying the file on the command line. -.SP -.IP "" 0 -\fB-n \fImodule\fB\fR -.IP "" 2 -Show data for a particular module -(you can specify several \fB-n\fR options on the same command line). -.SP -.IP "" 0 -\fB-p \fIrepository\fB\fR -.IP "" 2 -Show data for a particular source repository (you -can specify several \fB-p\fR options on the same command -line). -.SP -.IP "" 0 -\fB-r \fIrev\fB\fR -.IP "" 2 -Show records referring to revisions since the revision -or tag named \fIrev\fR appears in individual \fBrcs\fR -files. Each \fBrcs\fR file is searched for the revision or -tag. -.SP -.IP "" 0 -\fB-t \fItag\fB\fR -.IP "" 2 -Show records since tag \fItag\fR was last added to the -history file. This differs from the \fB-r\fR flag -above in that it reads only the history file, not the -\fBrcs\fR files, and is much faster. -.SP -.IP "" 0 -\fB-u \fIname\fB\fR -.IP "" 2 -Show records for user \fIname\fR. -.SP -.IP "" 0 -\fB-z \fItimezone\fB\fR -.IP "" 2 -Show times in the selected records using the specified -time zone instead of UTC. -.SP -.SH "import" -.SS "Import sources into CVS, using vendor branches" -.IX "import (subcommand)" -.SP -.IP "\(bu" 2 -Synopsis: import [-options] repository vendortag releasetag\&... -.IP "\(bu" 2 -Requires: Repository, source distribution directory. -.IP "\(bu" 2 -Changes: repository. -.SP -Use \fBimport\fR to incorporate an entire source -distribution from an outside source (e.g., a source -vendor) into your source repository directory. You can -use this command both for initial creation of a -repository, and for wholesale updates to the module -from the outside source. See `Tracking sources\(aq in the CVS manual for -a discussion on this subject. -.SP -The \fIrepository\fR argument gives a directory name -(or a path to a directory) under the \fBcvs\fR root directory -for repositories; if the directory did not exist, -import creates it. -.SP -When you use import for updates to source that has been -modified in your source repository (since a prior -import), it will notify you of any files that conflict -in the two branches of development; use \fBcheckout --j\fR to reconcile the differences, as import instructs -you to do. -.SP -If \fBcvs\fR decides a file should be ignored -(see node `cvsignore\(aq in the CVS manual), it does not import it and prints -\fBI \fR followed by the filename (see node `import output\(aq in the CVS manual for a -complete description of the output). -.SP -If the file \fB$CVSROOT/CVSROOT/cvswrappers\fR exists, -any file whose names match the specifications in that -file will be treated as packages and the appropriate -filtering will be performed on the file/directory -before being imported. See `Wrappers\(aq in the CVS manual. -.SP -The outside source is saved in a first-level -branch, by default 1.1.1. Updates are leaves of this -branch; for example, files from the first imported -collection of source will be revision 1.1.1.1, then -files from the first imported update will be revision -1.1.1.2, and so on. -.SP -At least three arguments are required. -\fIrepository\fR is needed to identify the collection -of source. \fIvendortag\fR is a tag for the entire -branch (e.g., for 1.1.1). You must also specify at -least one \fIreleasetag\fR to uniquely identify the files at -the leaves created each time you execute \fBimport\fR. The -\fIreleasetag\fR should be new, not previously existing in the -repository file, and uniquely identify the imported release, -.SP -Note that \fBimport\fR does \fInot\fR change the -directory in which you invoke it. In particular, it -does not set up that directory as a \fBcvs\fR working -directory; if you want to work with the sources import -them first and then check them out into a different -directory (see node `Getting the source\(aq in the CVS manual). -.SP -.SH "import options" -.SP -This standard option is supported by \fBimport\fR -(see node `Common options\(aq in the CVS manual for a complete description): -.SP -.IP "" 0 -\fB-m \fImessage\fB\fR -.IP "" 2 -Use \fImessage\fR as log information, instead of -invoking an editor. -.SP -There are the following additional special options. -.SP -.IP "" 0 -\fB-b \fIbranch\fB\fR -.IP "" 2 -See `Multiple vendor branches\(aq in the CVS manual. -.SP -.IP "" 0 -\fB-k \fIsubst\fB\fR -.IP "" 2 -Indicate the keyword expansion mode desired. This -setting will apply to all files created during the -import, but not to any files that previously existed in -the repository. See `Substitution modes\(aq in the CVS manual for a -list of valid \fB-k\fR settings. -.SP -.IP "" 0 -\fB-I \fIname\fB\fR -.IP "" 2 -Specify file names that should be ignored during -import. You can use this option repeatedly. To avoid -ignoring any files at all (even those ignored by -default), specify \`-I !\(aq. -.SP -\fIname\fR can be a file name pattern of the same type -that you can specify in the \fB.cvsignore\fR file. -See `cvsignore\(aq in the CVS manual. -.SP -.IP "" 0 -\fB-W \fIspec\fB\fR -.IP "" 2 -Specify file names that should be filtered during -import. You can use this option repeatedly. -.SP -\fIspec\fR can be a file name pattern of the same type -that you can specify in the \fB.cvswrappers\fR -file. see node `Wrappers\(aq in the CVS manual. -.SP -.SH "import output" -.SP -\fBimport\fR keeps you informed of its progress by printing a line -for each file, preceded by one character indicating the status of the file: -.SP -.IP "" 0 -\fBU \fIfile\fB\fR -.IP "" 2 -The file already exists in the repository and has not been locally -modified; a new revision has been created (if necessary). -.SP -.IP "" 0 -\fBN \fIfile\fB\fR -.IP "" 2 -The file is a new file which has been added to the repository. -.SP -.IP "" 0 -\fBC \fIfile\fB\fR -.IP "" 2 -The file already exists in the repository but has been locally modified; -you will have to merge the changes. -.SP -.IP "" 0 -\fBI \fIfile\fB\fR -.IP "" 2 -The file is being ignored (see node `cvsignore\(aq in the CVS manual). -.SP -.IX "Symbolic link, importing" -.IX "Link, symbolic, importing" -.IP "" 0 -\fBL \fIfile\fB\fR -.IP "" 2 -The file is a symbolic link; \fBcvs import\fR ignores symbolic links. -People periodically suggest that this behavior should -be changed, but if there is a consensus on what it -should be changed to, it doesn\(aqt seem to be apparent. -(Various options in the \fBmodules\fR file can be used -to recreate symbolic links on checkout, update, etc.; -see node `modules\(aq in the CVS manual.) -.SP -.SH "import examples" -.SP -See `Tracking sources\(aq in the CVS manual, and `From files\(aq in the CVS manual. -.SP -.SH "log" -.SS "Print out log information for files" -.IX "log (subcommand)" -.SP -.IP "\(bu" 2 -Synopsis: log [options] [files\&...] -.IP "\(bu" 2 -Requires: repository, working directory. -.IP "\(bu" 2 -Changes: nothing. -.SP -Display log information for files. \fBlog\fR used to -call the \fBrcs\fR utility \fBrlog\fR. Although this -is no longer true in the current sources, this history -determines the format of the output and the options, -which are not quite in the style of the other \fBcvs\fR -commands. -.SP -.IX "Timezone, in output" -.IX "Zone, time, in output" -The output includes the location of the \fBrcs\fR file, -the \fIhead\fR revision (the latest revision on the -trunk), all symbolic names (tags) and some other -things. For each revision, the revision number, the -author, the number of lines added/deleted and the log -message are printed. All times are displayed in -Coordinated Universal Time (UTC). (Other parts of -\fBcvs\fR print times in the local timezone). -.SP -\fB\fBlog\fB uses \fB-R\fB in a way that conflicts -with the normal use inside \fBcvs\fB (see node `Common options\(aq in the CVS manual).\fR -.SP -.SH "log options" -.SP -By default, \fBlog\fR prints all information that is -available. All other options restrict the output. Note that the revision -selection options (\fB-b\fR, \fB-d\fR, \fB-r\fR, \fB-s\fR, and \fB-w\fR) -have no -effect, other than possibly causing a search for files in Attic directories, -when used in conjunction with the options that restrict the output to only -\fBlog\fR header fields (\fB-h\fR, \fB-R\fR, and \fB-t\fR) -unless the \fB-S\fR option is also specified. -.SP -.IP "" 0 -\fB-b\fR -.IP "" 2 -Print information about the revisions on the default -branch, normally the highest branch on the trunk. -.SP -.IP "" 0 -\fB-d \fIdates\fB\fR -.IP "" 2 -Print information about revisions with a checkin -date/time in the range given by the -semicolon-separated list of dates. The date formats -accepted are those accepted by the \fB-D\fR option to -many other \fBcvs\fR commands (see node `Common options\(aq in the CVS manual). -Dates can be combined into ranges as follows: -.SP -.IP "" 2 -\fB\fId1\fB<\fId2\fB\fR -.IP "" 4 -.IP "" 2 -\fB\fId2\fB>\fId1\fB\fR -.IP "" 4 -Select the revisions that were deposited between -\fId1\fR and \fId2\fR. -.SP -.IP "" 2 -\fB<\fId\fB\fR -.IP "" 4 -.IP "" 2 -\fB\fId\fB>\fR -.IP "" 4 -Select all revisions dated \fId\fR or earlier. -.SP -.IP "" 2 -\fB\fId\fB<\fR -.IP "" 4 -.IP "" 2 -\fB>\fId\fB\fR -.IP "" 4 -Select all revisions dated \fId\fR or later. -.SP -.IP "" 2 -\fB\fId\fB\fR -.IP "" 4 -Select the single, latest revision dated \fId\fR or -earlier. -.SP -The \fB>\fR or \fB<\fR characters may be followed by -\fB=\fR to indicate an inclusive range rather than an -exclusive one. -.SP -Note that the separator is a semicolon (;). -.SP -.IP "" 0 -\fB-h\fR -.IP "" 2 -Print only the name of the \fBrcs\fR file, name -of the file in the working directory, head, -default branch, access list, locks, symbolic names, and -suffix. -.SP -.IP "" 0 -\fB-l\fR -.IP "" 2 -Local; run only in current working directory. (Default -is to run recursively). -.SP -.IP "" 0 -\fB-N\fR -.IP "" 2 -Do not print the list of tags for this file. This -option can be very useful when your site uses a lot of -tags, so rather than "more"\(aqing over 3 pages of tag -information, the log information is presented without -tags at all. -.SP -.IP "" 0 -\fB-n\fR -.IP "" 2 -Print the list of tags for this file. This option can -be very useful when your \fB.cvsrc\fR file has a -\fBlog -N\fR entry as a way to get a full list of all -of the tags. -.SP -.IP "" 0 -\fB-R\fR -.IP "" 2 -Print only the name of the \fBrcs\fR file. -.SP -.IP "" 0 -\fB-r\fIrevisions\fB\fR -.IP "" 2 -Print information about revisions given in the -comma-separated list \fIrevisions\fR of revisions and -ranges. The following table explains the available -range formats: -.SP -.IP "" 2 -\fB\fIrev1\fB:\fIrev2\fB\fR -.IP "" 4 -Revisions \fIrev1\fR to \fIrev2\fR (which must be on -the same branch). -.SP -.IP "" 2 -\fB\fIrev1\fB::\fIrev2\fB\fR -.IP "" 4 -The same, but excluding \fIrev1\fR. -.SP -.IP "" 2 -\fB:\fIrev\fB\fR -.IP "" 4 -.IP "" 2 -\fB::\fIrev\fB\fR -.IP "" 4 -Revisions from the beginning of the branch up to -and including \fIrev\fR. -.SP -.IP "" 2 -\fB\fIrev\fB:\fR -.IP "" 4 -Revisions starting with \fIrev\fR to the end of the -branch containing \fIrev\fR. -.SP -.IP "" 2 -\fB\fIrev\fB::\fR -.IP "" 4 -Revisions starting just after \fIrev\fR to the end of the -branch containing \fIrev\fR. -.SP -.IP "" 2 -\fB\fIbranch\fB\fR -.IP "" 4 -An argument that is a branch means all revisions on -that branch. -.SP -.IP "" 2 -\fB\fIbranch1\fB:\fIbranch2\fB\fR -.IP "" 4 -.IP "" 2 -\fB\fIbranch1\fB::\fIbranch2\fB\fR -.IP "" 4 -A range of branches means all revisions -on the branches in that range. -.SP -.IP "" 2 -\fB\fIbranch\fB.\fR -.IP "" 4 -The latest revision in \fIbranch\fR. -.SP -A bare \fB-r\fR with no revisions means the latest -revision on the default branch, normally the trunk. -There can be no space between the \fB-r\fR option and -its argument. -.SP -.IP "" 0 -\fB-S\fR -.IP "" 2 -Suppress the header if no revisions are selected. -.SP -.IP "" 0 -\fB-s \fIstates\fB\fR -.IP "" 2 -Print information about revisions whose state -attributes match one of the states given in the -comma-separated list \fIstates\fR. Individual states may -be any text string, though \fBcvs\fR commonly only uses two -states, \fBExp\fR and \fBdead\fR. See `admin options\(aq in the CVS manual -for more information. -.SP -.IP "" 0 -\fB-t\fR -.IP "" 2 -Print the same as \fB-h\fR, plus the descriptive text. -.SP -.IP "" 0 -\fB-w\fIlogins\fB\fR -.IP "" 2 -Print information about revisions checked in by users -with login names appearing in the comma-separated list -\fIlogins\fR. If \fIlogins\fR is omitted, the user\(aqs -login is assumed. There can be no space between the -\fB-w\fR option and its argument. -.SP -\fBlog\fR prints the intersection of the revisions -selected with the options \fB-d\fR, \fB-s\fR, and -\fB-w\fR, intersected with the union of the revisions -selected by \fB-b\fR and \fB-r\fR. -.SP -.SH "log examples" -.SP -Contributed examples are gratefully accepted. -.SP -.SH "rdiff" -.SS "\(aqpatch\(aq format diffs between releases" -.IX "rdiff (subcommand)" -.SP -.IP "\(bu" 2 -rdiff [-flags] [-V vn] [-r t|-D d [-r t2|-D d2]] modules\&... -.IP "\(bu" 2 -Requires: repository. -.IP "\(bu" 2 -Changes: nothing. -.IP "\(bu" 2 -Synonym: patch -.SP -Builds a Larry Wall format patch(1) file between two -releases, that can be fed directly into the \fBpatch\fR -program to bring an old release up-to-date with the new -release. (This is one of the few \fBcvs\fR commands that -operates directly from the repository, and doesn\(aqt -require a prior checkout.) The diff output is sent to -the standard output device. -.SP -You can specify (using the standard \fB-r\fR and -\fB-D\fR options) any combination of one or two -revisions or dates. If only one revision or date is -specified, the patch file reflects differences between -that revision or date and the current head revisions in -the \fBrcs\fR file. -.SP -Note that if the software release affected is contained -in more than one directory, then it may be necessary to -specify the \fB-p\fR option to the \fBpatch\fR command when -patching the old sources, so that \fBpatch\fR is able to find -the files that are located in other directories. -.SP -.SH "rdiff options" -.SP -These standard options are supported by \fBrdiff\fR -(see node `Common options\(aq in the CVS manual for a complete description of -them): -.SP -.IP "" 0 -\fB-D \fIdate\fB\fR -.IP "" 2 -Use the most recent revision no later than \fIdate\fR. -.SP -.IP "" 0 -\fB-f\fR -.IP "" 2 -If no matching revision is found, retrieve the most -recent revision (instead of ignoring the file). -.SP -.IP "" 0 -\fB-k \fIkflag\fB\fR -.IP "" 2 -Process keywords according to \fIkflag\fR. See -`Keyword substitution\(aq in the CVS manual. -.SP -.IP "" 0 -\fB-l\fR -.IP "" 2 -Local; don\(aqt descend subdirectories. -.SP -.IP "" 0 -\fB-R\fR -.IP "" 2 -Examine directories recursively. This option is on by default. -.SP -.IP "" 0 -\fB-r \fItag\fB\fR -.IP "" 2 -Use revision \fItag\fR. -.SP -In addition to the above, these options are available: -.SP -.IP "" 0 -\fB-c\fR -.IP "" 2 -Use the context diff format. This is the default format. -.SP -.IP "" 0 -\fB-s\fR -.IP "" 2 -Create a summary change report instead of a patch. The -summary includes information about files that were -changed or added between the releases. It is sent to -the standard output device. This is useful for finding -out, for example, which files have changed between two -dates or revisions. -.SP -.IP "" 0 -\fB-t\fR -.IP "" 2 -A diff of the top two revisions is sent to the standard -output device. This is most useful for seeing what the -last change to a file was. -.SP -.IP "" 0 -\fB-u\fR -.IP "" 2 -Use the unidiff format for the context diffs. -Remember that old versions -of the \fBpatch\fR program can\(aqt handle the unidiff -format, so if you plan to post this patch to the net -you should probably not use \fB-u\fR. -.SP -.IP "" 0 -\fB-V \fIvn\fB\fR -.IP "" 2 -Expand keywords according to the rules current in -\fBrcs\fR version \fIvn\fR (the expansion format changed with -\fBrcs\fR version 5). Note that this option is no -longer accepted. \fBcvs\fR will always expand keywords the -way that \fBrcs\fR version 5 does. -.SP -.SH "rdiff examples" -.SP -Suppose you receive mail from \fRfoo@example.net\fR asking for an -update from release 1.2 to 1.4 of the tc compiler. You -have no such patches on hand, but with \fBcvs\fR that can -easily be fixed with a command such as this: -.SP -.PD 0 -.SP -.IP "" 2 -$ cvs rdiff -c -r FOO1_2 -r FOO1_4 tc | \\ -.IP "" 2 -> Mail -s \(aqThe patches you asked for\(aq foo@example.net - -.PD -.IP "" 0 -.SP -Suppose you have made release 1.3, and forked a branch -called \fBR_1_3fix\fR for bug fixes. \fBR_1_3_1\fR -corresponds to release 1.3.1, which was made some time -ago. Now, you want to see how much development has been -done on the branch. This command can be used: -.SP -.PD 0 -.SP -.IP "" 2 -$ cvs patch -s -r R_1_3_1 -r R_1_3fix module-name -.IP "" 2 -cvs rdiff: Diffing module-name -.IP "" 2 -File ChangeLog,v changed from revision 1.52.2.5 to 1.52.2.6 -.IP "" 2 -File foo.c,v changed from revision 1.52.2.3 to 1.52.2.4 -.IP "" 2 -File bar.h,v changed from revision 1.29.2.1 to 1.2 - -.PD -.IP "" 0 -.SP -.SH "release" -.SS "Indicate that a Module is no longer in use" -.IX "release (subcommand)" -.SP -.IP "\(bu" 2 -release [-d] directories\&... -.IP "\(bu" 2 -Requires: Working directory. -.IP "\(bu" 2 -Changes: Working directory, history log. -.SP -This command is meant to safely cancel the effect of -\fBcvs checkout\fR. Since \fBcvs\fR doesn\(aqt lock files, it -isn\(aqt strictly necessary to use this command. You can -always simply delete your working directory, if you -like; but you risk losing changes you may have -forgotten, and you leave no trace in the \fBcvs\fR history -file (see node `history file\(aq in the CVS manual) that you\(aqve abandoned your -checkout. -.SP -Use \fBcvs release\fR to avoid these problems. This -command checks that no uncommitted changes are -present; that you are executing it from immediately -above a \fBcvs\fR working directory; and that the repository -recorded for your files is the same as the repository -defined in the module database. -.SP -If all these conditions are true, \fBcvs release\fR -leaves a record of its execution (attesting to your -intentionally abandoning your checkout) in the \fBcvs\fR -history log. -.SP -.SH "release options" -.SP -The \fBrelease\fR command supports one command option: -.SP -.IP "" 0 -\fB-d\fR -.IP "" 2 -Delete your working copy of the file if the release -succeeds. If this flag is not given your files will -remain in your working directory. -.SP -\fBWARNING: The \fBrelease\fB command deletes -all directories and files recursively. This -has the very serious side-effect that any directory -created inside checked-out sources, and not added to -the repository (using the \fBadd\fB command; -see node `Adding files\(aq in the CVS manual) will be silently deleted\(emeven -if it is non-empty!\fR -.SP -.SH "release output" -.SP -Before \fBrelease\fR releases your sources it will -print a one-line message for any file that is not -up-to-date. -.SP -.IP "" 0 -\fBU \fIfile\fB\fR -.IP "" 2 -.IP "" 0 -\fBP \fIfile\fB\fR -.IP "" 2 -There exists a newer revision of this file in the -repository, and you have not modified your local copy -of the file (\fBU\fR and \fBP\fR mean the same thing). -.SP -.IP "" 0 -\fBA \fIfile\fB\fR -.IP "" 2 -The file has been added to your private copy of the -sources, but has not yet been committed to the -repository. If you delete your copy of the sources -this file will be lost. -.SP -.IP "" 0 -\fBR \fIfile\fB\fR -.IP "" 2 -The file has been removed from your private copy of the -sources, but has not yet been removed from the -repository, since you have not yet committed the -removal. See `commit\(aq in the CVS manual. -.SP -.IP "" 0 -\fBM \fIfile\fB\fR -.IP "" 2 -The file is modified in your working directory. There -might also be a newer revision inside the repository. -.SP -.IP "" 0 -\fB? \fIfile\fB\fR -.IP "" 2 -\fIfile\fR is in your working directory, but does not -correspond to anything in the source repository, and is -not in the list of files for \fBcvs\fR to ignore (see the -description of the \fB-I\fR option, and -see node `cvsignore\(aq in the CVS manual). If you remove your working -sources, this file will be lost. -.SP -.SH "release examples" -.SP -Release the \fBtc\fR directory, and delete your local working copy -of the files. -.SP -.PD 0 -.SP -.IP "" 2 -$ cd \&.. # \fRYou must stand immediately above the\fR -.IP "" 2 - # \fRsources when you issue \fBcvs release\fR.\fR -.IP "" 2 -$ cvs release -d tc -.IP "" 2 -You have [0] altered files in this repository. -.IP "" 2 -Are you sure you want to release (and delete) directory \`tc\(aq: y -.IP "" 2 -$ - -.PD -.IP "" 0 -.SP -.SH "remove" -.SS "Remove files from active use" -.IX "remove (subcommand)" -.SP -.IP "\(bu" 2 -Synopsis: remove [-flR] [files...] -.IP "\(bu" 2 -Requires: repository, working directory. -.IP "\(bu" 2 -Changes: working directory. -.SP -The \fBremove\fR command is used to remove unwanted -files from active use. The user normally deletes the -files from the working directory prior to invocation -of the \fBremove\fR command. Only the working -directory is updated. Changes to the repository are -not made until the \fBcommit\fR command is run. -.SP -The \fBremove\fR command does not delete files from -from the repository. \fBcvs\fR keeps all historical -data in the repository so that it is possible to -reconstruct previous states of the projects under -revision control. -.SP -To undo \fBcvs\fR \fBremove\fR or to resurrect files -that were previously removed, see node `add\(aq in the CVS manual. -.SP -.SH "remove options" -.SP -These standard options are supported by \fBremove\fR -(see node `Common options\(aq in the CVS manual for a complete description of -them): -.SP -.IP "" 0 -\fB-l\fR -.IP "" 2 -Local; run only in current working directory. See `Recursive behavior\(aq in the CVS manual. -.SP -.IP "" 0 -\fB-R\fR -.IP "" 2 -Process directories recursively. See `Recursive behavior\(aq in the CVS manual. -.SP -.SP -In addition, these options are also supported: -.SP -.IP "" 0 -\fB-f\fR -.IP "" 2 -Note that this is not the standard behavior of -the \fB-f\fR option as defined in `Common options\(aq in the CVS manual. -.SP -Delete files before removing them. -.SP -Entire directory hierarchies are easily removed -using \fB-f\fR, but take note that it is not as -easy to resurrect directory hierarchies as it is -to remove them. -.SP -.SP -.SH "remove examples" -.SP -.SS "Removing a file" -.SP -.PD 0 -.SP -.IP "" 2 -$ cvs remove remove.me -.IP "" 2 -cvs remove: file \`remove.me\(aq still in working directory -.IP "" 2 -cvs remove: 1 file exists; remove it first -.IP "" 2 -$ rm -f remove.me -.IP "" 2 -$ cvs remove remove.me -.IP "" 2 -cvs remove: scheduling \`remove.me\(aq for removal -.IP "" 2 -cvs remove: use \(aqcvs commit\(aq to remove this file permanently -.SP -.IP "" 2 -$ ls remove.it -.IP "" 2 -remove.it -.IP "" 2 -$ cvs remove -f remove.it -.IP "" 2 -cvs remove: scheduling \`remove.it\(aq for removal -.IP "" 2 -cvs remove: use \(aqcvs commit\(aq to remove this file permanently - -.PD -.IP "" 0 -.SP -.SS "Removing entire directories" -.SP -.PD 0 -.IP "" 2 -$ tree -d a -.IP "" 2 -a -.IP "" 2 -|-- CVS -.IP "" 2 -\`-- b -.IP "" 2 - \`-- CVS -.SP -.IP "" 2 -3 directories -.IP "" 2 -$ cvs remove -f a -.IP "" 2 -cvs remove: Removing a -.IP "" 2 -cvs remove: Removing a/b -.IP "" 2 -cvs remove: scheduling \`a/b/c\(aq for removal -.IP "" 2 -cvs remove: use \(aqcvs commit\(aq to remove this file permanently - -.PD -.IP "" 0 -.SP -.SH "update" -.SS "Bring work tree in sync with repository" -.IX "update (subcommand)" -.SP -.IP "\(bu" 2 -update [-ACdflPpR] [-I name] [-j rev [-j rev]] [-k kflag] [-r tag|-D date] [-W spec] files\&... -.IP "\(bu" 2 -Requires: repository, working directory. -.IP "\(bu" 2 -Changes: working directory. -.SP -After you\(aqve run checkout to create your private copy -of source from the common repository, other developers -will continue changing the central source. From time -to time, when it is convenient in your development -process, you can use the \fBupdate\fR command from -within your working directory to reconcile your work -with any revisions applied to the source repository -since your last checkout or update. -.SP -.SH "update options" -.SP -These standard options are available with \fBupdate\fR -(see node `Common options\(aq in the CVS manual for a complete description of -them): -.SP -.IP "" 0 -\fB-D date\fR -.IP "" 2 -Use the most recent revision no later than \fIdate\fR. -This option is sticky, and implies \fB-P\fR. -See `Sticky tags\(aq in the CVS manual for more information on sticky tags/dates. -.SP -.IP "" 0 -\fB-f\fR -.IP "" 2 -Only useful with the \fB-D \fIdate\fB\fR or \fB-r -\fItag\fB\fR flags. If no matching revision is found, -retrieve the most recent revision (instead of ignoring -the file). -.SP -.IP "" 0 -\fB-k \fIkflag\fB\fR -.IP "" 2 -Process keywords according to \fIkflag\fR. See -`Keyword substitution\(aq in the CVS manual. -This option is sticky; future updates of -this file in this working directory will use the same -\fIkflag\fR. The \fBstatus\fR command can be viewed -to see the sticky options. See `Invoking CVS\(aq in the CVS manual for -more information on the \fBstatus\fR command. -.SP -.IP "" 0 -\fB-l\fR -.IP "" 2 -Local; run only in current working directory. See `Recursive behavior\(aq in the CVS manual. -.SP -.IP "" 0 -\fB-P\fR -.IP "" 2 -Prune empty directories. See `Moving directories\(aq in the CVS manual. -.SP -.IP "" 0 -\fB-p\fR -.IP "" 2 -Pipe files to the standard output. -.SP -.IP "" 0 -\fB-R\fR -.IP "" 2 -Update directories recursively (default). See `Recursive -behavior\(aq in the CVS manual. -.SP -.IP "" 0 -\fB-r rev\fR -.IP "" 2 -Retrieve revision/tag \fIrev\fR. This option is sticky, -and implies \fB-P\fR. -See `Sticky tags\(aq in the CVS manual, for more information on sticky tags/dates. -.SP -These special options are also available with -\fBupdate\fR. -.SP -.IP "" 0 -\fB-A\fR -.IP "" 2 -Reset any sticky tags, dates, or \fB-k\fR options. -Does not reset sticky \fB-k\fR options on modified files. -See `Sticky tags\(aq in the CVS manual for more information on sticky tags/dates. -.SP -.IP "" 0 -\fB-C\fR -.IP "" 2 -Overwrite locally modified files with clean copies from -the repository (the modified file is saved in -\fB.#\fIfile\fB.\fIrevision\fB\fR, however). -.SP -.IP "" 0 -\fB-d\fR -.IP "" 2 -Create any directories that exist in the repository if -they\(aqre missing from the working directory. Normally, -\fBupdate\fR acts only on directories and files that -were already enrolled in your working directory. -.SP -This is useful for updating directories that were -created in the repository since the initial checkout; -but it has an unfortunate side effect. If you -deliberately avoided certain directories in the -repository when you created your working directory -(either through use of a module name or by listing -explicitly the files and directories you wanted on the -command line), then updating with \fB-d\fR will create -those directories, which may not be what you want. -.SP -.IP "" 0 -\fB-I \fIname\fB\fR -.IP "" 2 -Ignore files whose names match \fIname\fR (in your -working directory) during the update. You can specify -\fB-I\fR more than once on the command line to specify -several files to ignore. Use \fB-I !\fR to avoid -ignoring any files at all. See `cvsignore\(aq in the CVS manual for other -ways to make \fBcvs\fR ignore some files. -.SP -.IP "" 0 -\fB-W\fIspec\fB\fR -.IP "" 2 -Specify file names that should be filtered during -update. You can use this option repeatedly. -.SP -\fIspec\fR can be a file name pattern of the same type -that you can specify in the \fB.cvswrappers\fR -file. See `Wrappers\(aq in the CVS manual. -.SP -.IP "" 0 -\fB-j\fIrevision\fB\fR -.IP "" 2 -With two \fB-j\fR options, merge changes from the -revision specified with the first \fB-j\fR option to -the revision specified with the second \fBj\fR option, -into the working directory. -.SP -With one \fB-j\fR option, merge changes from the -ancestor revision to the revision specified with the -\fB-j\fR option, into the working directory. The -ancestor revision is the common ancestor of the -revision which the working directory is based on, and -the revision specified in the \fB-j\fR option. -.SP -Note that using a single \fB-j \fItagname\fB\fR option rather than -\fB-j \fIbranchname\fB\fR to merge changes from a branch will -often not remove files which were removed on the branch. -See `Merging adds and removals\(aq in the CVS manual for more information. -.SP -In addition, each \fB-j\fR option can contain an optional -date specification which, when used with branches, can -limit the chosen revision to one within a specific -date. An optional date is specified by adding a colon -(:) to the tag: -\fB-j\fISymbolic_Tag\fB:\fIDate_Specifier\fB\fR. -.SP -See `Branching and merging\(aq in the CVS manual. -.SP -.SP -.SH "update output" -.SP -\fBupdate\fR and \fBcheckout\fR keep you informed of -their progress by printing a line for each file, preceded -by one character indicating the status of the file: -.SP -.IP "" 0 -\fBU \fIfile\fB\fR -.IP "" 2 -The file was brought up to date with respect to the -repository. This is done for any file that exists in -the repository but not in your working directory, and for files -that you haven\(aqt changed but are not the most recent -versions available in the repository. -.SP -.IP "" 0 -\fBP \fIfile\fB\fR -.IP "" 2 -Like \fBU\fR, but the \fBcvs\fR server sends a patch instead of an entire -file. This accomplishes the same thing as \fBU\fR using less bandwidth. -.SP -.IP "" 0 -\fBA \fIfile\fB\fR -.IP "" 2 -The file has been added to your private copy of the -sources, and will be added to the source repository -when you run \fBcommit\fR on the file. This is a -reminder to you that the file needs to be committed. -.SP -.IP "" 0 -\fBR \fIfile\fB\fR -.IP "" 2 -The file has been removed from your private copy of the -sources, and will be removed from the source repository -when you run \fBcommit\fR on the file. This is a -reminder to you that the file needs to be committed. -.SP -.IP "" 0 -\fBM \fIfile\fB\fR -.IP "" 2 -The file is modified in your working directory. -.SP -\fBM\fR can indicate one of two states for a file -you\(aqre working on: either there were no modifications -to the same file in the repository, so that your file -remains as you last saw it; or there were modifications -in the repository as well as in your copy, but they -were merged successfully, without conflict, in your -working directory. -.SP -\fBcvs\fR will print some messages if it merges your work, -and a backup copy of your working file (as it looked -before you ran \fBupdate\fR) will be made. The exact -name of that file is printed while \fBupdate\fR runs. -.SP -.IP "" 0 -\fBC \fIfile\fB\fR -.IP "" 2 -.IX "\&.# files" -.IX "__ files (VMS)" -A conflict was detected while trying to merge your -changes to \fIfile\fR with changes from the source -repository. \fIfile\fR (the copy in your working -directory) is now the result of attempting to merge -the two revisions; an unmodified copy of your file -is also in your working directory, with the name -\fB.#\fIfile\fB.\fIrevision\fB\fR where \fIrevision\fR -is the revision that your modified file started -from. Resolve the conflict as described in -`Conflicts example\(aq in the CVS manual. -(Note that some systems automatically purge -files that begin with \fB.#\fR if they have not been -accessed for a few days. If you intend to keep a copy -of your original file, it is a very good idea to rename -it.) Under \fBvms\fR, the file name starts with -\fB__\fR rather than \fB.#\fR. -.SP -.IP "" 0 -\fB? \fIfile\fB\fR -.IP "" 2 -\fIfile\fR is in your working directory, but does not -correspond to anything in the source repository, and is -not in the list of files for \fBcvs\fR to ignore (see the -description of the \fB-I\fR option, and -see node `cvsignore\(aq in the CVS manual). -.SH "AUTHORS" -.TP -Dick Grune -Original author of the -.B cvs -shell script version posted to -.B comp.sources.unix -in the volume6 release of December, 1986. -Credited with much of the -.B cvs -conflict resolution algorithms. -.TP -Brian Berliner -Coder and designer of the -.B cvs -program itself in April, 1989, based on the original work done by Dick. -.TP -Jeff Polk -Helped Brian with the design of the -.B cvs -module and vendor branch support and author of the -.BR checkin ( 1 ) -shell script (the ancestor of \fBcvs import\fP). -.TP -Larry Jones, Derek R. Price, and Mark D. Baushke -Have helped maintain -.B cvs -for many years. -.TP -And many others too numerous to mention here. -.SH "SEE ALSO" -The most comprehensive manual for CVS is -Version Management with CVS by Per Cederqvist et al. Depending on -your system, you may be able to get it with the -.B info CVS -command or it may be available as cvs.pdf (Portable Document Format), -cvs.ps (PostScript), cvs.texinfo (Texinfo source), or cvs.html. -.SP -For CVS updates, more information on documentation, software related -to CVS, development of CVS, and more, see: -.in +1i -.SP -.PD 0 -.IP "" 4 -.B http://cvs.nongnu.org -.in -1i -.SP -.BR ci ( 1 ), -.BR co ( 1 ), -.BR cvs ( 5 ), -.BR cvsbug ( 8 ), -.BR diff ( 1 ), -.BR grep ( 1 ), -.BR patch ( 1 ), -.BR rcs ( 1 ), -.BR rcsdiff ( 1 ), -.BR rcsmerge ( 1 ), -.BR rlog ( 1 ). diff --git a/contrib/cvs/doc/cvs.man.footer b/contrib/cvs/doc/cvs.man.footer deleted file mode 100644 index fe3f6b4..0000000 --- a/contrib/cvs/doc/cvs.man.footer +++ /dev/null @@ -1,58 +0,0 @@ -.SH "AUTHORS" -.TP -Dick Grune -Original author of the -.B cvs -shell script version posted to -.B comp.sources.unix -in the volume6 release of December, 1986. -Credited with much of the -.B cvs -conflict resolution algorithms. -.TP -Brian Berliner -Coder and designer of the -.B cvs -program itself in April, 1989, based on the original work done by Dick. -.TP -Jeff Polk -Helped Brian with the design of the -.B cvs -module and vendor branch support and author of the -.BR checkin ( 1 ) -shell script (the ancestor of \fBcvs import\fP). -.TP -Larry Jones, Derek R. Price, and Mark D. Baushke -Have helped maintain -.B cvs -for many years. -.TP -And many others too numerous to mention here. -.SH "SEE ALSO" -The most comprehensive manual for CVS is -Version Management with CVS by Per Cederqvist et al. Depending on -your system, you may be able to get it with the -.B info CVS -command or it may be available as cvs.pdf (Portable Document Format), -cvs.ps (PostScript), cvs.texinfo (Texinfo source), or cvs.html. -.SP -For CVS updates, more information on documentation, software related -to CVS, development of CVS, and more, see: -.in +1i -.SP -.PD 0 -.IP "" 4 -.B http://cvs.nongnu.org -.in -1i -.SP -.BR ci ( 1 ), -.BR co ( 1 ), -.BR cvs ( 5 ), -.BR cvsbug ( 8 ), -.BR diff ( 1 ), -.BR grep ( 1 ), -.BR patch ( 1 ), -.BR rcs ( 1 ), -.BR rcsdiff ( 1 ), -.BR rcsmerge ( 1 ), -.BR rlog ( 1 ). diff --git a/contrib/cvs/doc/cvs.man.header b/contrib/cvs/doc/cvs.man.header deleted file mode 100644 index cbc4f7d..0000000 --- a/contrib/cvs/doc/cvs.man.header +++ /dev/null @@ -1,61 +0,0 @@ -.\" This is the man page for CVS. It is auto-generated from the -.\" cvs.man.header, cvs.texinfo, & cvs.man.footer files. Please make changes -.\" there. A full copyright & license notice may also be found in cvs.texinfo. -.\" -.\" Man page autogeneration, including this header file, is -.\" Copyright 2004-2005 The Free Software Foundation, Inc., -.\" Derek R. Price, & Ximbiot . -.\" -.\" This documentation is free software; you can redistribute it and/or modify -.\" it under the terms of the GNU General Public License as published by -.\" the Free Software Foundation; either version 2, or (at your option) -.\" any later version. -.\" -.\" This documentation is distributed in the hope that it will be useful, -.\" but WITHOUT ANY WARRANTY; without even the implied warranty of -.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -.\" GNU General Public License for more details. -.\" -.\" You should have received a copy of the GNU General Public License -.\" along with this documentation; if not, write to the Free Software -.\" Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -.de Id -.ds Rv \\$3 -.ds Dt \\$4 -.. -.TH CVS 1 "\*(Dt" -.\" Full space in nroff; half space in troff -.de SP -.if n .sp -.if t .sp .5 -.. -.\" quoted command -.de ` -.RB ` "\|\\$1\|" '\\$2 -.. -.SH "NAME" -cvs \- Concurrent Versions System -.SH "SYNOPSIS" -.TP -\fBcvs\fP [ \fIcvs_options\fP ] -.I cvs_command -[ -.I command_options -] [ -.I command_args -] -.SH "NOTE" -.IX "revision control system" "\fLcvs\fR" -.IX cvs "" "\fLcvs\fP \- concurrent versions system" -.IX "concurrent versions system \- \fLcvs\fP" -.IX "release control system" "cvs command" "" "\fLcvs\fP \- concurrent versions system" -.IX "source control system" "cvs command" "" "\fLcvs\fP \- concurrent versions system" -.IX revisions "cvs command" "" "\fLcvs\fP \- source control" -This manpage is a summary of some of the features of -\fBcvs\fP. It is auto-generated from an appendix of the CVS manual. -For more in-depth documentation, please consult the -Cederqvist manual (via the -.B info CVS -command or otherwise, -as described in the SEE ALSO section of this manpage). Cross-references -in this man page refer to nodes in the same. diff --git a/contrib/cvs/doc/cvs.texinfo b/contrib/cvs/doc/cvs.texinfo deleted file mode 100644 index 6b1840a..0000000 --- a/contrib/cvs/doc/cvs.texinfo +++ /dev/null @@ -1,14892 +0,0 @@ -\input texinfo @c -*-texinfo-*- -@comment Documentation for CVS. -@setfilename cvs.info -@macro copyleftnotice -@noindent -Copyright @copyright{} 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, - 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 - Free Software Foundation, Inc. - -@multitable @columnfractions .12 .88 -@item Portions -@item @tab Copyright @copyright{} 1999, 2000, 2001, 2002, 2003, 2004, 2005, - 2006, 2007 Derek R. Price, -@item @tab Copyright @copyright{} 2002, 2003, 2004, 2005, 2006, 2007 - Ximbiot @url{http://ximbiot.com}, -@item @tab Copyright @copyright{} 1992, 1993, 1999 Signum Support AB, -@item @tab and Copyright @copyright{} others. -@end multitable - -@ignore -Permission is granted to process this file through Tex and print the -results, provided the printed document carries copying permission -notice identical to this one except for the removal of this paragraph -(this paragraph not being relevant to the printed manual). - -@end ignore -Permission is granted to make and distribute verbatim copies of -this manual provided the copyright notice and this permission notice -are preserved on all copies. - -Permission is granted to copy and distribute modified versions of this -manual under the conditions for verbatim copying, provided also that the -entire resulting derived work is distributed under the terms of a -permission notice identical to this one. - -Permission is granted to copy and distribute translations of this manual -into another language, under the above conditions for modified versions, -except that this permission notice may be stated in a translation -approved by the Free Software Foundation. -@end macro - -@comment This file is part of the CVS distribution. - -@comment CVS is free software; you can redistribute it and/or modify -@comment it under the terms of the GNU General Public License as published by -@comment the Free Software Foundation; either version 2, or (at your option) -@comment any later version. - -@comment CVS is distributed in the hope that it will be useful, -@comment but WITHOUT ANY WARRANTY; without even the implied warranty of -@comment MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -@comment GNU General Public License for more details. - -@c See ../README for A4 vs. US letter size. -@c When we provided A4 postscript, and people tried to -@c print it on US letter, the usual complaint was that the -@c page numbers would get cut off. -@c If one prints US letter on A4, reportedly there is -@c some extra space at the top and/or bottom, and the side -@c margins are a bit narrow, but no text is lost. -@c -@c See -@c http://www.ft.uni-erlangen.de/~mskuhn/iso-paper.html -@c for more on paper sizes. Insuring that margins are -@c big enough to print on either A4 or US letter does -@c indeed seem to be the usual approach (RFC2346). - -@c This document seems to get overfull hboxes with some -@c frequency (probably because the tendency is to -@c sanity-check it with "make info" and run TeX less -@c often). The big ugly boxes just seem to add insult -@c to injury, and I'm not aware of them helping to fix -@c the overfull hboxes at all. -@finalout - -@include version.texi -@settitle CVS---Concurrent Versions System v@value{VERSION} -@setchapternewpage odd - -@c -- TODO list: -@c -- Fix all lines that match "^@c -- " -@c -- Also places marked with FIXME should be manual -@c problems (as opposed to FIXCVS for CVS problems). - -@c @splitrcskeyword{} is used to avoid keyword expansion. It is replaced by -@c @asis when generating info and dvi, and by in the generated html, -@c such that keywords are not expanded in the generated html. -@ifnothtml -@macro splitrcskeyword {arg} -@asis{}\arg\ -@end macro -@end ifnothtml - -@ifhtml -@macro splitrcskeyword {arg} -@i{}\arg\ -@end macro -@end ifhtml - -@dircategory GNU Packages -@direntry -* CVS: (cvs). Concurrent Versions System -@end direntry -@dircategory Individual utilities -@direntry -* cvs: (cvs)CVS commands. Concurrent Versions System -@end direntry - -@comment The titlepage section does not appear in the Info file. -@titlepage -@sp 4 -@comment The title is printed in a large font. -@center @titlefont{Version Management} -@sp -@center @titlefont{with} -@sp -@center @titlefont{CVS} -@sp 2 -@center for @sc{cvs} @value{VERSION} -@comment -release- -@sp 3 -@center Per Cederqvist et al - -@comment The following two commands start the copyright page -@comment for the printed manual. This will not appear in the Info file. -@page -@vskip 0pt plus 1filll -@copyleftnotice -@end titlepage - -@summarycontents - -@contents - -@comment ================================================================ -@comment The real text starts here -@comment ================================================================ - -@ifnottex -@c --------------------------------------------------------------------- -@node Top -@top - -This info manual describes how to use and administer -@sc{cvs} version @value{VERSION}. -@end ifnottex - -@ifinfo -@copyleftnotice -@end ifinfo - -@c This menu is pretty long. Not sure how easily that -@c can be fixed (no brilliant ideas right away)... -@menu -* Overview:: An introduction to CVS -* Repository:: Where all your sources are stored -* Starting a new project:: Starting a project with CVS -* Revisions:: Numeric and symbolic names for revisions -* Branching and merging:: Diverging/rejoining branches of development -* Recursive behavior:: CVS descends directories -* Adding and removing:: Adding/removing/renaming files/directories -* History browsing:: Viewing the history of files in various ways - -CVS and the Real World. ------------------------ -* Binary files:: CVS can handle binary files -* Multiple developers:: How CVS helps a group of developers -* Revision management:: Policy questions for revision management -* Keyword substitution:: CVS can include the revision inside the file -* Tracking sources:: Tracking third-party sources -* Builds:: Issues related to CVS and builds -* Special Files:: Devices, links and other non-regular files - -References. ------------ -* CVS commands:: CVS commands share some things -* Invoking CVS:: Quick reference to CVS commands -* Administrative files:: Reference manual for the Administrative files -* Environment variables:: All environment variables which affect CVS -* Compatibility:: Upgrading CVS versions -* Troubleshooting:: Some tips when nothing works -* Credits:: Some of the contributors to this manual -* BUGS:: Dealing with bugs in CVS or this manual -* Index:: Index -@end menu - -@c --------------------------------------------------------------------- -@node Overview -@chapter Overview -@cindex Overview - -This chapter is for people who have never used -@sc{cvs}, and perhaps have never used version control -software before. - -If you are already familiar with @sc{cvs} and are just -trying to learn a particular feature or remember a -certain command, you can probably skip everything here. - -@menu -* What is CVS?:: What you can do with @sc{cvs} -* What is CVS not?:: Problems @sc{cvs} doesn't try to solve -* A sample session:: A tour of basic @sc{cvs} usage -@end menu - -@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@node What is CVS? -@section What is CVS? -@cindex What is CVS? -@cindex Introduction to CVS -@cindex CVS, introduction to - -@sc{cvs} is a version control system. Using it, you can -record the history of your source files. - -@c -- /// -@c -- ///Those who cannot remember the past are condemned to repeat it. -@c -- /// -- George Santayana -@c -- ////// - -@c -- Insert history quote here! -For example, bugs sometimes creep in when -software is modified, and you might not detect the bug -until a long time after you make the modification. -With @sc{cvs}, you can easily retrieve old versions to see -exactly which change caused the bug. This can -sometimes be a big help. - -You could of course save every version of every file -you have ever created. This would -however waste an enormous amount of disk space. @sc{cvs} -stores all the versions of a file in a single file in a -clever way that only stores the differences between -versions. - -@sc{cvs} also helps you if you are part of a group of people working -on the same project. It is all too easy to overwrite -each others' changes unless you are extremely careful. -Some editors, like @sc{gnu} Emacs, try to make sure that -two people never modify the same file at the -same time. Unfortunately, if someone is using another -editor, that safeguard will not work. @sc{cvs} solves this problem -by insulating the different developers from each other. Every -developer works in his own directory, and @sc{cvs} merges -the work when each developer is done. - -@cindex History of CVS -@cindex CVS, history of -@cindex Credits (CVS program) -@cindex Contributors (CVS program) -@sc{cvs} started out as a bunch of shell scripts written by -Dick Grune, posted to the newsgroup -@code{comp.sources.unix} in the volume 6 -release of July, 1986. While no actual code from -these shell scripts is present in the current version -of @sc{cvs} much of the @sc{cvs} conflict resolution algorithms -come from them. - -In April, 1989, Brian Berliner designed and coded @sc{cvs}. -Jeff Polk later helped Brian with the design of the @sc{cvs} -module and vendor branch support. - -@cindex Source, getting CVS source -You can get @sc{cvs} in a variety of ways, including -free download from the Internet. For more information -on downloading @sc{cvs} and other @sc{cvs} topics, see: - -@example -@url{http://cvs.nongnu.org/} -@end example - -@cindex Mailing list -@cindex List, mailing list -@cindex Newsgroups -There is a mailing list, known as @email{info-cvs@@nongnu.org}, -devoted to @sc{cvs}. To subscribe or -unsubscribe -write to -@email{info-cvs-request@@nongnu.org}. -If you prefer a Usenet group, there is a one-way mirror (posts to the email -list are usually sent to the news group, but not vice versa) of -@email{info-cvs@@nongnu.org} at @url{news:gnu.cvs.help}. The right -Usenet group for posts is @url{news:comp.software.config-mgmt} which is for -@sc{cvs} discussions (along with other configuration -management systems). In the future, it might be -possible to create a -@code{comp.software.config-mgmt.cvs}, but probably only -if there is sufficient @sc{cvs} traffic on -@url{news:comp.software.config-mgmt}. -@c Other random data is that the tale was very -@c skeptical of comp.software.config-mgmt.cvs when the -@c subject came up around 1995 or so (for one -@c thing, because creating it would be a "reorg" which -@c would need to take a more comprehensive look at the -@c whole comp.software.config-mgmt.* hierarchy). - -You can also subscribe to the @email{bug-cvs@@nongnu.org} mailing list, -described in more detail in @ref{BUGS}. To subscribe -send mail to @email{bug-cvs-request@@nongnu.org}. There is a two-way -Usenet mirror (posts to the Usenet group are usually sent to the email list and -vice versa) of @email{bug-cvs@@nongnu.org} named @url{news:gnu.cvs.bug}. - -@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@node What is CVS not? -@section What is CVS not? -@cindex What is CVS not? - -@sc{cvs} can do a lot of things for you, but it does -not try to be everything for everyone. - -@table @asis -@item @sc{cvs} is not a build system. - -Though the structure of your repository and modules -file interact with your build system -(e.g. @file{Makefile}s), they are essentially -independent. - -@sc{cvs} does not dictate how you build anything. It -merely stores files for retrieval in a tree structure -you devise. - -@sc{cvs} does not dictate how to use disk space in the -checked out working directories. If you write your -@file{Makefile}s or scripts in every directory so they -have to know the relative positions of everything else, -you wind up requiring the entire repository to be -checked out. - -If you modularize your work, and construct a build -system that will share files (via links, mounts, -@code{VPATH} in @file{Makefile}s, etc.), you can -arrange your disk usage however you like. - -But you have to remember that @emph{any} such system is -a lot of work to construct and maintain. @sc{cvs} does -not address the issues involved. - -Of course, you should place the tools created to -support such a build system (scripts, @file{Makefile}s, -etc.) under @sc{cvs}. - -Figuring out what files need to be rebuilt when -something changes is, again, something to be handled -outside the scope of @sc{cvs}. One traditional -approach is to use @code{make} for building, and use -some automated tool for generating the dependencies which -@code{make} uses. - -See @ref{Builds}, for more information on doing builds -in conjunction with @sc{cvs}. - -@item @sc{cvs} is not a substitute for management. - -Your managers and project leaders are expected to talk -to you frequently enough to make certain you are aware -of schedules, merge points, branch names and release -dates. If they don't, @sc{cvs} can't help. - -@sc{cvs} is an instrument for making sources dance to -your tune. But you are the piper and the composer. No -instrument plays itself or writes its own music. - -@item @sc{cvs} is not a substitute for developer communication. - -When faced with conflicts within a single file, most -developers manage to resolve them without too much -effort. But a more general definition of ``conflict'' -includes problems too difficult to solve without -communication between developers. - -@sc{cvs} cannot determine when simultaneous changes -within a single file, or across a whole collection of -files, will logically conflict with one another. Its -concept of a @dfn{conflict} is purely textual, arising -when two changes to the same base file are near enough -to spook the merge (i.e., @code{diff3}) command. - -@sc{cvs} does not claim to help at all in figuring out -non-textual or distributed conflicts in program logic. - -For example: Say you change the arguments to function -@code{X} defined in file @file{A}. At the same time, -someone edits file @file{B}, adding new calls to -function @code{X} using the old arguments. You are -outside the realm of @sc{cvs}'s competence. - -Acquire the habit of reading specs and talking to your -peers. - - -@item @sc{cvs} does not have change control - -Change control refers to a number of things. First of -all it can mean @dfn{bug-tracking}, that is being able -to keep a database of reported bugs and the status of -each one (Is it fixed? In what release? Has the bug -submitter agreed that it is fixed?). For interfacing -@sc{cvs} to an external bug-tracking system, see the -@file{rcsinfo} and @file{verifymsg} files -(@pxref{Administrative files}). - -Another aspect of change control is keeping track of -the fact that changes to several files were in fact -changed together as one logical change. If you check -in several files in a single @code{cvs commit} -operation, @sc{cvs} then forgets that those files were -checked in together, and the fact that they have the -same log message is the only thing tying them -together. Keeping a @sc{gnu} style @file{ChangeLog} -can help somewhat. -@c FIXME: should have an xref to a section which talks -@c more about keeping ChangeLog's with CVS, but that -@c section hasn't been written yet. - -Another aspect of change control, in some systems, is -the ability to keep track of the status of each -change. Some changes have been written by a developer, -others have been reviewed by a second developer, and so -on. Generally, the way to do this with @sc{cvs} is to -generate a diff (using @code{cvs diff} or @code{diff}) -and email it to someone who can then apply it using the -@code{patch} utility. This is very flexible, but -depends on mechanisms outside @sc{cvs} to make sure -nothing falls through the cracks. - -@item @sc{cvs} is not an automated testing program - -It should be possible to enforce mandatory use of a -test suite using the @code{commitinfo} file. I haven't -heard a lot about projects trying to do that or whether -there are subtle gotchas, however. - -@item @sc{cvs} does not have a built-in process model - -Some systems provide ways to ensure that changes or -releases go through various steps, with various -approvals as needed. Generally, one can accomplish -this with @sc{cvs} but it might be a little more work. -In some cases you'll want to use the @file{commitinfo}, -@file{loginfo}, @file{rcsinfo}, or @file{verifymsg} -files, to require that certain steps be performed -before cvs will allow a checkin. Also consider whether -features such as branches and tags can be used to -perform tasks such as doing work in a development tree -and then merging certain changes over to a stable tree -only once they have been proven. -@end table - -@c --------------------------------------------------------------------- -@node A sample session -@section A sample session -@cindex Example of a work-session -@cindex Getting started -@cindex Work-session, example of -@cindex tc, Trivial Compiler (example) -@cindex Trivial Compiler (example) - -@c I think an example is a pretty good way to start. But -@c somewhere in here, maybe after the sample session, -@c we need something which is kind of -@c a "roadmap" which is more directed at sketching out -@c the functionality of CVS and pointing people to -@c various other parts of the manual. As it stands now -@c people who read in order get dumped right into all -@c manner of hair regarding remote repositories, -@c creating a repository, etc. -@c -@c The following was in the old Basic concepts node. I don't -@c know how good a job it does at introducing modules, -@c or whether they need to be introduced so soon, but -@c something of this sort might go into some -@c introductory material somewhere. -@ignore -@cindex Modules (intro) -The repository contains directories and files, in an -arbitrary tree. The @dfn{modules} feature can be used -to group together a set of directories or files into a -single entity (@pxref{modules}). A typical usage is to -define one module per project. -@end ignore - -As a way of introducing @sc{cvs}, we'll go through a -typical work-session using @sc{cvs}. The first thing -to understand is that @sc{cvs} stores all files in a -centralized @dfn{repository} (@pxref{Repository}); this -section assumes that a repository is set up. -@c I'm not sure that the sentence concerning the -@c repository quite tells the user what they need to -@c know at this point. Might need to expand on "centralized" -@c slightly (maybe not here, maybe further down in the example?) - -Suppose you are working on a simple compiler. The source -consists of a handful of C files and a @file{Makefile}. -The compiler is called @samp{tc} (Trivial Compiler), -and the repository is set up so that there is a module -called @samp{tc}. - -@menu -* Getting the source:: Creating a workspace -* Committing your changes:: Making your work available to others -* Cleaning up:: Cleaning up -* Viewing differences:: Viewing differences -@end menu - -@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@node Getting the source -@subsection Getting the source -@cindex Getting the source -@cindex Checking out source -@cindex Fetching source -@cindex Source, getting from CVS -@cindex Checkout, example - -The first thing you must do is to get your own working copy of the -source for @samp{tc}. For this, you use the @code{checkout} command: - -@example -$ cvs checkout tc -@end example - -@noindent -This will create a new directory called @file{tc} and populate it with -the source files. - -@example -$ cd tc -$ ls -CVS Makefile backend.c driver.c frontend.c parser.c -@end example - -The @file{CVS} directory is used internally by -@sc{cvs}. Normally, you should not modify or remove -any of the files in it. - -You start your favorite editor, hack away at @file{backend.c}, and a couple -of hours later you have added an optimization pass to the compiler. -A note to @sc{rcs} and @sc{sccs} users: There is no need to lock the files that -you want to edit. @xref{Multiple developers}, for an explanation. - -@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@node Committing your changes -@subsection Committing your changes -@cindex Committing changes to files -@cindex Log message entry - -When you have checked that the compiler is still compilable you decide -to make a new version of @file{backend.c}. This will -store your new @file{backend.c} in the repository and -make it available to anyone else who is using that same -repository. - -@example -$ cvs commit backend.c -@end example - -@noindent -@sc{cvs} starts an editor, to allow you to enter a log -message. You type in ``Added an optimization pass.'', -save the temporary file, and exit the editor. - -@cindex CVSEDITOR, environment variable -@cindex EDITOR, environment variable -The environment variable @code{$CVSEDITOR} determines -which editor is started. If @code{$CVSEDITOR} is not -set, then if the environment variable @code{$EDITOR} is -set, it will be used. If both @code{$CVSEDITOR} and -@code{$EDITOR} are not set then there is a default -which will vary with your operating system, for example -@code{vi} for unix or @code{notepad} for Windows -NT/95. - -@cindex VISUAL, environment variable -In addition, @sc{cvs} checks the @code{$VISUAL} environment -variable. Opinions vary on whether this behavior is desirable and -whether future releases of @sc{cvs} should check @code{$VISUAL} or -ignore it. You will be OK either way if you make sure that -@code{$VISUAL} is either unset or set to the same thing as -@code{$EDITOR}. - -@c This probably should go into some new node -@c containing detailed info on the editor, rather than -@c the intro. In fact, perhaps some of the stuff with -@c CVSEDITOR and -m and so on should too. -When @sc{cvs} starts the editor, it includes a list of -files which are modified. For the @sc{cvs} client, -this list is based on comparing the modification time -of the file against the modification time that the file -had when it was last gotten or updated. Therefore, if -a file's modification time has changed but its contents -have not, it will show up as modified. The simplest -way to handle this is simply not to worry about it---if -you proceed with the commit @sc{cvs} will detect that -the contents are not modified and treat it as an -unmodified file. The next @code{update} will clue -@sc{cvs} in to the fact that the file is unmodified, -and it will reset its stored timestamp so that the file -will not show up in future editor sessions. -@c FIXCVS: Might be nice if "commit" and other commands -@c would reset that timestamp too, but currently commit -@c doesn't. -@c FIXME: Need to talk more about the process of -@c prompting for the log message. Like show an example -@c of what it pops up in the editor, for example. Also -@c a discussion of how to get the "a)bort, c)ontinue, -@c e)dit" prompt and what to do with it. Might also -@c work in the suggestion that if you want a diff, you -@c should make it before running commit (someone -@c suggested that the diff pop up in the editor. I'm -@c not sure that is better than telling people to run -@c "cvs diff" first if that is what they want, but if -@c we want to tell people that, the manual possibly -@c should say it). - -If you want to avoid -starting an editor you can specify the log message on -the command line using the @samp{-m} flag instead, like -this: - -@example -$ cvs commit -m "Added an optimization pass" backend.c -@end example - -@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@node Cleaning up -@subsection Cleaning up -@cindex Cleaning up -@cindex Working copy, removing -@cindex Removing your working copy -@cindex Releasing your working copy - -Before you turn to other tasks you decide to remove your working copy of -tc. One acceptable way to do that is of course - -@example -$ cd .. -$ rm -r tc -@end example - -@noindent -but a better way is to use the @code{release} command (@pxref{release}): - -@example -$ cd .. -$ cvs release -d tc -M driver.c -? tc -You have [1] altered files in this repository. -Are you sure you want to release (and delete) directory `tc': n -** `release' aborted by user choice. -@end example - -The @code{release} command checks that all your modifications have been -committed. If history logging is enabled it also makes a note in the -history file. @xref{history file}. - -When you use the @samp{-d} flag with @code{release}, it -also removes your working copy. - -In the example above, the @code{release} command wrote a couple of lines -of output. @samp{? tc} means that the file @file{tc} is unknown to @sc{cvs}. -That is nothing to worry about: @file{tc} is the executable compiler, -and it should not be stored in the repository. @xref{cvsignore}, -for information about how to make that warning go away. -@xref{release output}, for a complete explanation of -all possible output from @code{release}. - -@samp{M driver.c} is more serious. It means that the -file @file{driver.c} has been modified since it was -checked out. - -The @code{release} command always finishes by telling -you how many modified files you have in your working -copy of the sources, and then asks you for confirmation -before deleting any files or making any note in the -history file. - -You decide to play it safe and answer @kbd{n @key{RET}} -when @code{release} asks for confirmation. - -@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@node Viewing differences -@subsection Viewing differences -@cindex Viewing differences -@cindex Diff - -You do not remember modifying @file{driver.c}, so you want to see what -has happened to that file. - -@example -$ cd tc -$ cvs diff driver.c -@end example - -This command runs @code{diff} to compare the version of @file{driver.c} -that you checked out with your working copy. When you see the output -you remember that you added a command line option that enabled the -optimization pass. You check it in, and release the module. -@c FIXME: we haven't yet defined the term "check in". - -@example -$ cvs commit -m "Added an optimization pass" driver.c -Checking in driver.c; -/usr/local/cvsroot/tc/driver.c,v <-- driver.c -new revision: 1.2; previous revision: 1.1 -done -$ cd .. -$ cvs release -d tc -? tc -You have [0] altered files in this repository. -Are you sure you want to release (and delete) directory `tc': y -@end example - -@c --------------------------------------------------------------------- -@node Repository -@chapter The Repository -@cindex Repository (intro) -@cindex Repository, example -@cindex Layout of repository -@cindex Typical repository -@cindex /usr/local/cvsroot, as example repository -@cindex cvsroot - -The @sc{cvs} @dfn{repository} stores a complete copy of -all the files and directories which are under version -control. - -Normally, you never access any of the files in the -repository directly. Instead, you use @sc{cvs} -commands to get your own copy of the files into a -@dfn{working directory}, and then -work on that copy. When you've finished a set of -changes, you check (or @dfn{commit}) them back into the -repository. The repository then contains the changes -which you have made, as well as recording exactly what -you changed, when you changed it, and other such -information. Note that the repository is not a -subdirectory of the working directory, or vice versa; -they should be in separate locations. -@c Need some example, e.g. repository -@c /usr/local/cvsroot; working directory -@c /home/joe/sources. But this node is too long -@c as it is; need a little reorganization... - -@cindex :local:, setting up -@sc{cvs} can access a repository by a variety of -means. It might be on the local computer, or it might -be on a computer across the room or across the world. -To distinguish various ways to access a repository, the -repository name can start with an @dfn{access method}. -For example, the access method @code{:local:} means to -access a repository directory, so the repository -@code{:local:/usr/local/cvsroot} means that the -repository is in @file{/usr/local/cvsroot} on the -computer running @sc{cvs}. For information on other -access methods, see @ref{Remote repositories}. - -@c Can se say this more concisely? Like by passing -@c more of the buck to the Remote repositories node? -If the access method is omitted, then if the repository -starts with @samp{/}, then @code{:local:} is -assumed. If it does not start with @samp{/} then either -@code{:ext:} or @code{:server:} is assumed. For -example, if you have a local repository in -@file{/usr/local/cvsroot}, you can use -@code{/usr/local/cvsroot} instead of -@code{:local:/usr/local/cvsroot}. But if (under -Windows NT, for example) your local repository is -@file{c:\src\cvsroot}, then you must specify the access -method, as in @code{:local:c:/src/cvsroot}. - -@c This might appear to go in Repository storage, but -@c actually it is describing something which is quite -@c user-visible, when you do a "cvs co CVSROOT". This -@c isn't necessary the perfect place for that, though. -The repository is split in two parts. @file{$CVSROOT/CVSROOT} contains -administrative files for @sc{cvs}. The other directories contain the actual -user-defined modules. - -@menu -* Specifying a repository:: Telling CVS where your repository is -* Repository storage:: The structure of the repository -* Working directory storage:: The structure of working directories -* Intro administrative files:: Defining modules -* Multiple repositories:: Multiple repositories -* Creating a repository:: Creating a repository -* Backing up:: Backing up a repository -* Moving a repository:: Moving a repository -* Remote repositories:: Accessing repositories on remote machines -* Read-only access:: Granting read-only access to the repository -* Server temporary directory:: The server creates temporary directories -@end menu - -@node Specifying a repository -@section Telling CVS where your repository is - -There are several ways to tell @sc{cvs} -where to find the repository. You can name the -repository on the command line explicitly, with the -@code{-d} (for "directory") option: - -@example -cvs -d /usr/local/cvsroot checkout yoyodyne/tc -@end example - -@cindex .profile, setting CVSROOT in -@cindex .cshrc, setting CVSROOT in -@cindex .tcshrc, setting CVSROOT in -@cindex .bashrc, setting CVSROOT in -@cindex CVSROOT, environment variable - Or you can set the @code{$CVSROOT} environment -variable to an absolute path to the root of the -repository, @file{/usr/local/cvsroot} in this example. -To set @code{$CVSROOT}, @code{csh} and @code{tcsh} -users should have this line in their @file{.cshrc} or -@file{.tcshrc} files: - -@example -setenv CVSROOT /usr/local/cvsroot -@end example - -@noindent -@code{sh} and @code{bash} users should instead have these lines in their -@file{.profile} or @file{.bashrc}: - -@example -CVSROOT=/usr/local/cvsroot -export CVSROOT -@end example - -@cindex Root file, in CVS directory -@cindex CVS/Root file - A repository specified with @code{-d} will -override the @code{$CVSROOT} environment variable. -Once you've checked a working copy out from the -repository, it will remember where its repository is -(the information is recorded in the -@file{CVS/Root} file in the working copy). - -The @code{-d} option and the @file{CVS/Root} file both -override the @code{$CVSROOT} environment variable. If -@code{-d} option differs from @file{CVS/Root}, the -former is used. Of course, for proper operation they -should be two ways of referring to the same repository. - -@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@node Repository storage -@section How data is stored in the repository -@cindex Repository, how data is stored - -For most purposes it isn't important @emph{how} -@sc{cvs} stores information in the repository. In -fact, the format has changed in the past, and is likely -to change in the future. Since in almost all cases one -accesses the repository via @sc{cvs} commands, such -changes need not be disruptive. - -However, in some cases it may be necessary to -understand how @sc{cvs} stores data in the repository, -for example you might need to track down @sc{cvs} locks -(@pxref{Concurrency}) or you might need to deal with -the file permissions appropriate for the repository. - -@menu -* Repository files:: What files are stored in the repository -* File permissions:: File permissions -* Windows permissions:: Issues specific to Windows -* Attic:: Some files are stored in the Attic -* CVS in repository:: Additional information in CVS directory -* Locks:: CVS locks control concurrent accesses -* CVSROOT storage:: A few things about CVSROOT are different -@end menu - -@node Repository files -@subsection Where files are stored within the repository - -@c @cindex Filenames, legal -@c @cindex Legal filenames -@c Somewhere we need to say something about legitimate -@c characters in filenames in working directory and -@c repository. Not "/" (not even on non-unix). And -@c here is a specific set of issues: -@c Files starting with a - are handled inconsistently. They can not -@c be added to a repository with an add command, because it they are -@c interpreted as a switch. They can appear in a repository if they are -@c part of a tree that is imported. They can not be removed from the tree -@c once they are there. -@c Note that "--" *is* supported (as a -@c consequence of using GNU getopt). Should document -@c this somewhere ("Common options"?). The other usual technique, -@c "./-foo", isn't as effective, at least for "cvs add" -@c which doesn't support pathnames containing "/". - -The overall structure of the repository is a directory -tree corresponding to the directories in the working -directory. For example, supposing the repository is in - -@example -/usr/local/cvsroot -@end example - -@noindent -here is a possible directory tree (showing only the -directories): - -@example -@t{/usr} - | - +--@t{local} - | | - | +--@t{cvsroot} - | | | - | | +--@t{CVSROOT} - | (administrative files) - | - +--@t{gnu} - | | - | +--@t{diff} - | | (source code to @sc{gnu} diff) - | | - | +--@t{rcs} - | | (source code to @sc{rcs}) - | | - | +--@t{cvs} - | (source code to @sc{cvs}) - | - +--@t{yoyodyne} - | - +--@t{tc} - | | - | +--@t{man} - | | - | +--@t{testing} - | - +--(other Yoyodyne software) -@end example - -With the directories are @dfn{history files} for each file -under version control. The name of the history file is -the name of the corresponding file with @samp{,v} -appended to the end. Here is what the repository for -the @file{yoyodyne/tc} directory might look like: -@c FIXME: Should also mention CVS (CVSREP) -@c FIXME? Should we introduce Attic with an xref to -@c Attic? Not sure whether that is a good idea or not. -@example - @code{$CVSROOT} - | - +--@t{yoyodyne} - | | - | +--@t{tc} - | | | - +--@t{Makefile,v} - +--@t{backend.c,v} - +--@t{driver.c,v} - +--@t{frontend.c,v} - +--@t{parser.c,v} - +--@t{man} - | | - | +--@t{tc.1,v} - | - +--@t{testing} - | - +--@t{testpgm.t,v} - +--@t{test2.t,v} -@end example - -@cindex History files -@cindex RCS history files -@c The first sentence, about what history files -@c contain, is kind of redundant with our intro to what the -@c repository does in node Repository.... -The history files contain, among other things, enough -information to recreate any revision of the file, a log -of all commit messages and the user-name of the person -who committed the revision. The history files are -known as @dfn{RCS files}, because the first program to -store files in that format was a version control system -known as @sc{rcs}. For a full -description of the file format, see the @code{man} page -@cite{rcsfile(5)}, distributed with @sc{rcs}, or the -file @file{doc/RCSFILES} in the @sc{cvs} source -distribution. This -file format has become very common---many systems other -than @sc{cvs} or @sc{rcs} can at least import history -files in this format. -@c FIXME: Think about including documentation for this -@c rather than citing it? In the long run, getting -@c this to be a standard (not sure if we can cope with -@c a standards process as formal as IEEE/ANSI/ISO/etc, -@c though...) is the way to go, so maybe citing is -@c better. - -The @sc{rcs} files used in @sc{cvs} differ in a few -ways from the standard format. The biggest difference -is magic branches; for more information see @ref{Magic -branch numbers}. Also in @sc{cvs} the valid tag names -are a subset of what @sc{rcs} accepts; for @sc{cvs}'s -rules see @ref{Tags}. - -@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -@node File permissions -@subsection File permissions -@c -- Move this to @node Creating a repository or similar -@cindex Security, file permissions in repository -@cindex File permissions, general -@cindex Permissions, general -@c FIXME: we need to somehow reflect "permissions in -@c repository" versus "permissions in working -@c directory" in the index entries. -@cindex Group, UNIX file permissions, in repository -@cindex Read-only files, in repository -All @samp{,v} files are created read-only, and you -should not change the permission of those files. The -directories inside the repository should be writable by -the persons that have permission to modify the files in -each directory. This normally means that you must -create a UNIX group (see group(5)) consisting of the -persons that are to edit the files in a project, and -set up the repository so that it is that group that -owns the directory. -(On some systems, you also need to set the set-group-ID-on-execution bit -on the repository directories (see chmod(1)) so that newly-created files -and directories get the group-ID of the parent directory rather than -that of the current process.) - -@c See also comment in commitinfo node regarding cases -@c which are really awkward with unix groups. - -This means that you can only control access to files on -a per-directory basis. - -Note that users must also have write access to check -out files, because @sc{cvs} needs to create lock files -(@pxref{Concurrency}). You can use LockDir in CVSROOT/config -to put the lock files somewhere other than in the repository -if you want to allow read-only access to some directories -(@pxref{config}). - -@c CVS seems to use CVSUMASK in picking permissions for -@c val-tags, but maybe we should say more about this. -@c Like val-tags gets created by someone who doesn't -@c have CVSUMASK set right? -@cindex CVSROOT/val-tags file, and read-only access to projects -@cindex val-tags file, and read-only access to projects -Also note that users must have write access to the -@file{CVSROOT/val-tags} file. @sc{cvs} uses it to keep -track of what tags are valid tag names (it is sometimes -updated when tags are used, as well as when they are -created). - -Each @sc{rcs} file will be owned by the user who last -checked it in. This has little significance; what -really matters is who owns the directories. - -@cindex CVSUMASK, environment variable -@cindex Umask, for repository files -@sc{cvs} tries to set up reasonable file permissions -for new directories that are added inside the tree, but -you must fix the permissions manually when a new -directory should have different permissions than its -parent directory. If you set the @code{CVSUMASK} -environment variable, that will control the file -permissions which @sc{cvs} uses in creating directories -and/or files in the repository. @code{CVSUMASK} does -not affect the file permissions in the working -directory; such files have the permissions which are -typical for newly created files, except that sometimes -@sc{cvs} creates them read-only (see the sections on -watches, @ref{Setting a watch}; -r, @ref{Global -options}; or @code{CVSREAD}, @ref{Environment variables}). -@c FIXME: Need more discussion of which -@c group should own the file in the repository. -@c Include a somewhat detailed example of the usual -@c case where CVSUMASK is 007, the developers are all -@c in a group, and that group owns stuff in the -@c repository. Need to talk about group ownership of -@c newly-created directories/files (on some unices, -@c such as SunOS4, setting the setgid bit on the -@c directories will make files inherit the directory's -@c group. On other unices, your mileage may vary. I -@c can't remember what POSIX says about this, if -@c anything). - -Note that using the client/server @sc{cvs} -(@pxref{Remote repositories}), there is no good way to -set @code{CVSUMASK}; the setting on the client machine -has no effect. If you are connecting with @code{rsh}, you -can set @code{CVSUMASK} in @file{.bashrc} or @file{.cshrc}, as -described in the documentation for your operating -system. This behavior might change in future versions -of @sc{cvs}; do not rely on the setting of -@code{CVSUMASK} on the client having no effect. -@c FIXME: need to explain what a umask is or cite -@c someplace which does. -@c -@c There is also a larger (largely separate) issue -@c about the meaning of CVSUMASK in a non-unix context. -@c For example, whether there is -@c an equivalent which fits better into other -@c protection schemes like POSIX.6, VMS, &c. -@c -@c FIXME: Need one place which discusses this -@c read-only files thing. Why would one use -r or -@c CVSREAD? Why would one use watches? How do they -@c interact? -@c -@c FIXME: We need to state -@c whether using CVSUMASK removes the need for manually -@c fixing permissions (in fact, if we are going to mention -@c manually fixing permission, we better document a lot -@c better just what we mean by "fix"). - -Using pserver, you will generally need stricter -permissions on the @sc{cvsroot} directory and -directories above it in the tree; see @ref{Password -authentication security}. - -@cindex Setuid -@cindex Setgid -@cindex Security, setuid -@cindex Installed images (VMS) -Some operating systems have features which allow a -particular program to run with the ability to perform -operations which the caller of the program could not. -For example, the set user ID (setuid) or set group ID -(setgid) features of unix or the installed image -feature of VMS. @sc{cvs} was not written to use such -features and therefore attempting to install @sc{cvs} in -this fashion will provide protection against only -accidental lapses; anyone who is trying to circumvent -the measure will be able to do so, and depending on how -you have set it up may gain access to more than just -@sc{cvs}. You may wish to instead consider pserver. It -shares some of the same attributes, in terms of -possibly providing a false sense of security or opening -security holes wider than the ones you are trying to -fix, so read the documentation on pserver security -carefully if you are considering this option -(@ref{Password authentication security}). - -@node Windows permissions -@subsection File Permission issues specific to Windows -@cindex Windows, and permissions -@cindex File permissions, Windows-specific -@cindex Permissions, Windows-specific - -Some file permission issues are specific to Windows -operating systems (Windows 95, Windows NT, and -presumably future operating systems in this family. -Some of the following might apply to OS/2 but I'm not -sure). - -If you are using local @sc{cvs} and the repository is on a -networked file system which is served by the Samba SMB -server, some people have reported problems with -permissions. Enabling WRITE=YES in the samba -configuration is said to fix/workaround it. -Disclaimer: I haven't investigated enough to know the -implications of enabling that option, nor do I know -whether there is something which @sc{cvs} could be doing -differently in order to avoid the problem. If you find -something out, please let us know as described in -@ref{BUGS}. - -@node Attic -@subsection The attic -@cindex Attic - -You will notice that sometimes @sc{cvs} stores an -@sc{rcs} file in the @code{Attic}. For example, if the -@sc{cvsroot} is @file{/usr/local/cvsroot} and we are -talking about the file @file{backend.c} in the -directory @file{yoyodyne/tc}, then the file normally -would be in - -@example -/usr/local/cvsroot/yoyodyne/tc/backend.c,v -@end example - -@noindent -but if it goes in the attic, it would be in - -@example -/usr/local/cvsroot/yoyodyne/tc/Attic/backend.c,v -@end example - -@noindent -@cindex Dead state -instead. It should not matter from a user point of -view whether a file is in the attic; @sc{cvs} keeps -track of this and looks in the attic when it needs to. -But in case you want to know, the rule is that the RCS -file is stored in the attic if and only if the head -revision on the trunk has state @code{dead}. A -@code{dead} state means that file has been removed, or -never added, for that revision. For example, if you -add a file on a branch, it will have a trunk revision -in @code{dead} state, and a branch revision in a -non-@code{dead} state. -@c Probably should have some more concrete examples -@c here, or somewhere (not sure exactly how we should -@c arrange the discussion of the dead state, versus -@c discussion of the attic). - -@node CVS in repository -@subsection The CVS directory in the repository -@cindex CVS directory, in repository - -The @file{CVS} directory in each repository directory -contains information such as file attributes (in a file -called @file{CVS/fileattr}. In the -future additional files may be added to this directory, -so implementations should silently ignore additional -files. - -This behavior is implemented only by @sc{cvs} 1.7 and -later; for details see @ref{Watches Compatibility}. - -The format of the @file{fileattr} file is a series of entries -of the following form (where @samp{@{} and @samp{@}} -means the text between the braces can be repeated zero -or more times): - -@var{ent-type} @var{filename} @var{attrname} = @var{attrval} - @{; @var{attrname} = @var{attrval}@} - -@var{ent-type} is @samp{F} for a file, in which case the entry specifies the -attributes for that file. - -@var{ent-type} is @samp{D}, -and @var{filename} empty, to specify default attributes -to be used for newly added files. - -Other @var{ent-type} are reserved for future expansion. @sc{cvs} 1.9 and older -will delete them any time it writes file attributes. -@sc{cvs} 1.10 and later will preserve them. - -Note that the order of the lines is not significant; -a program writing the fileattr file may -rearrange them at its convenience. - -There is currently no way of quoting tabs or line feeds in the -filename, @samp{=} in @var{attrname}, -@samp{;} in @var{attrval}, etc. Note: some implementations also -don't handle a NUL character in any of the fields, but -implementations are encouraged to allow it. - -By convention, @var{attrname} starting with @samp{_} is for an attribute given -special meaning by @sc{cvs}; other @var{attrname}s are for user-defined attributes -(or will be, once implementations start supporting user-defined attributes). - -Built-in attributes: - -@table @code -@item _watched -Present means the file is watched and should be checked out -read-only. - -@item _watchers -Users with watches for this file. Value is -@var{watcher} > @var{type} @{ , @var{watcher} > @var{type} @} -where @var{watcher} is a username, and @var{type} -is zero or more of edit,unedit,commit separated by -@samp{+} (that is, nothing if none; there is no "none" or "all" keyword). - -@item _editors -Users editing this file. Value is -@var{editor} > @var{val} @{ , @var{editor} > @var{val} @} -where @var{editor} is a username, and @var{val} is -@var{time}+@var{hostname}+@var{pathname}, where -@var{time} is when the @code{cvs edit} command (or -equivalent) happened, -and @var{hostname} and @var{pathname} are for the working directory. -@end table - -Example: - -@c FIXME: sanity.sh should contain a similar test case -@c so we can compare this example from something from -@c Real Life(TM). See cvsclient.texi (under Notify) for more -@c discussion of the date format of _editors. -@example -Ffile1 _watched=;_watchers=joe>edit,mary>commit -Ffile2 _watched=;_editors=sue>8 Jan 1975+workstn1+/home/sue/cvs -D _watched= -@end example - -@noindent -means that the file @file{file1} should be checked out -read-only. Furthermore, joe is watching for edits and -mary is watching for commits. The file @file{file2} -should be checked out read-only; sue started editing it -on 8 Jan 1975 in the directory @file{/home/sue/cvs} on -the machine @code{workstn1}. Future files which are -added should be checked out read-only. To represent -this example here, we have shown a space after -@samp{D}, @samp{Ffile1}, and @samp{Ffile2}, but in fact -there must be a single tab character there and no spaces. - -@node Locks -@subsection CVS locks in the repository - -@cindex #cvs.rfl, technical details -@cindex #cvs.wfl, technical details -@cindex #cvs.lock, technical details -@cindex Locks, cvs, technical details -For an introduction to @sc{cvs} locks focusing on -user-visible behavior, see @ref{Concurrency}. The -following section is aimed at people who are writing -tools which want to access a @sc{cvs} repository without -interfering with other tools accessing the same -repository. If you find yourself confused by concepts -described here, like @dfn{read lock}, @dfn{write lock}, -and @dfn{deadlock}, you might consult the literature on -operating systems or databases. - -@cindex #cvs.tfl -Any file in the repository with a name starting -with @file{#cvs.rfl.} is a read lock. Any file in -the repository with a name starting with -@file{#cvs.wfl} is a write lock. Old versions of @sc{cvs} -(before @sc{cvs} 1.5) also created files with names starting -with @file{#cvs.tfl}, but they are not discussed here. -The directory @file{#cvs.lock} serves as a master -lock. That is, one must obtain this lock first before -creating any of the other locks. - -To obtain a read lock, first create the @file{#cvs.lock} -directory. This operation must be atomic (which should -be true for creating a directory under most operating -systems). If it fails because the directory already -existed, wait for a while and try again. After -obtaining the @file{#cvs.lock} lock, create a file -whose name is @file{#cvs.rfl.} followed by information -of your choice (for example, hostname and process -identification number). Then remove the -@file{#cvs.lock} directory to release the master lock. -Then proceed with reading the repository. When you are -done, remove the @file{#cvs.rfl} file to release the -read lock. - -To obtain a write lock, first create the -@file{#cvs.lock} directory, as with read locks. Then -check that there are no files whose names start with -@file{#cvs.rfl.}. If there are, remove -@file{#cvs.lock}, wait for a while, and try again. If -there are no readers, then create a file whose name is -@file{#cvs.wfl} followed by information of your choice -(for example, hostname and process identification -number). Hang on to the @file{#cvs.lock} lock. Proceed -with writing the repository. When you are done, first -remove the @file{#cvs.wfl} file and then the -@file{#cvs.lock} directory. Note that unlike the -@file{#cvs.rfl} file, the @file{#cvs.wfl} file is just -informational; it has no effect on the locking operation -beyond what is provided by holding on to the -@file{#cvs.lock} lock itself. - -Note that each lock (write lock or read lock) only locks -a single directory in the repository, including -@file{Attic} and @file{CVS} but not including -subdirectories which represent other directories under -version control. To lock an entire tree, you need to -lock each directory (note that if you fail to obtain -any lock you need, you must release the whole tree -before waiting and trying again, to avoid deadlocks). - -Note also that @sc{cvs} expects write locks to control -access to individual @file{foo,v} files. @sc{rcs} has -a scheme where the @file{,foo,} file serves as a lock, -but @sc{cvs} does not implement it and so taking out a -@sc{cvs} write lock is recommended. See the comments at -rcs_internal_lockfile in the @sc{cvs} source code for -further discussion/rationale. - -@node CVSROOT storage -@subsection How files are stored in the CVSROOT directory -@cindex CVSROOT, storage of files - -The @file{$CVSROOT/CVSROOT} directory contains the -various administrative files. In some ways this -directory is just like any other directory in the -repository; it contains @sc{rcs} files whose names end -in @samp{,v}, and many of the @sc{cvs} commands operate -on it the same way. However, there are a few -differences. - -For each administrative file, in addition to the -@sc{rcs} file, there is also a checked out copy of the -file. For example, there is an @sc{rcs} file -@file{loginfo,v} and a file @file{loginfo} which -contains the latest revision contained in -@file{loginfo,v}. When you check in an administrative -file, @sc{cvs} should print - -@example -cvs commit: Rebuilding administrative file database -@end example - -@noindent -and update the checked out copy in -@file{$CVSROOT/CVSROOT}. If it does not, there is -something wrong (@pxref{BUGS}). To add your own files -to the files to be updated in this fashion, you can add -them to the @file{checkoutlist} administrative file -(@pxref{checkoutlist}). - -@cindex modules.db -@cindex modules.pag -@cindex modules.dir -By default, the @file{modules} file behaves as -described above. If the modules file is very large, -storing it as a flat text file may make looking up -modules slow (I'm not sure whether this is as much of a -concern now as when @sc{cvs} first evolved this -feature; I haven't seen benchmarks). Therefore, by -making appropriate edits to the @sc{cvs} source code -one can store the modules file in a database which -implements the @code{ndbm} interface, such as Berkeley -db or GDBM. If this option is in use, then the modules -database will be stored in the files @file{modules.db}, -@file{modules.pag}, and/or @file{modules.dir}. -@c I think fileattr also will use the database stuff. -@c Anything else? - -For information on the meaning of the various -administrative files, see @ref{Administrative files}. - -@node Working directory storage -@section How data is stored in the working directory - -@c FIXME: Somewhere we should discuss timestamps (test -@c case "stamps" in sanity.sh). But not here. Maybe -@c in some kind of "working directory" chapter which -@c would encompass the "Builds" one? But I'm not sure -@c whether that is a good organization (is it based on -@c what the user wants to do?). - -@cindex CVS directory, in working directory -While we are discussing @sc{cvs} internals which may -become visible from time to time, we might as well talk -about what @sc{cvs} puts in the @file{CVS} directories -in the working directories. As with the repository, -@sc{cvs} handles this information and one can usually -access it via @sc{cvs} commands. But in some cases it -may be useful to look at it, and other programs, such -as the @code{jCVS} graphical user interface or the -@code{VC} package for emacs, may need to look at it. -Such programs should follow the recommendations in this -section if they hope to be able to work with other -programs which use those files, including future -versions of the programs just mentioned and the -command-line @sc{cvs} client. - -The @file{CVS} directory contains several files. -Programs which are reading this directory should -silently ignore files which are in the directory but -which are not documented here, to allow for future -expansion. - -The files are stored according to the text file -convention for the system in question. This means that -working directories are not portable between systems -with differing conventions for storing text files. -This is intentional, on the theory that the files being -managed by @sc{cvs} probably will not be portable between -such systems either. - -@table @file -@item Root -This file contains the current @sc{cvs} root, as -described in @ref{Specifying a repository}. - -@cindex Repository file, in CVS directory -@cindex CVS/Repository file -@item Repository -This file contains the directory within the repository -which the current directory corresponds with. It can -be either an absolute pathname or a relative pathname; -@sc{cvs} has had the ability to read either format -since at least version 1.3 or so. The relative -pathname is relative to the root, and is the more -sensible approach, but the absolute pathname is quite -common and implementations should accept either. For -example, after the command - -@example -cvs -d :local:/usr/local/cvsroot checkout yoyodyne/tc -@end example - -@noindent -@file{Root} will contain - -@example -:local:/usr/local/cvsroot -@end example - -@noindent -and @file{Repository} will contain either - -@example -/usr/local/cvsroot/yoyodyne/tc -@end example - -@noindent -or - -@example -yoyodyne/tc -@end example - -If the particular working directory does not correspond -to a directory in the repository, then @file{Repository} -should contain @file{CVSROOT/Emptydir}. -@cindex Emptydir, in CVSROOT directory -@cindex CVSROOT/Emptydir directory - -@cindex Entries file, in CVS directory -@cindex CVS/Entries file -@item Entries -This file lists the files and directories in the -working directory. -The first character of each line indicates what sort of -line it is. If the character is unrecognized, programs -reading the file should silently skip that line, to -allow for future expansion. - -If the first character is @samp{/}, then the format is: - -@example -/@var{name}/@var{revision}/@var{timestamp}[+@var{conflict}]/@var{options}/@var{tagdate} -@end example - -@noindent -where @samp{[} and @samp{]} are not part of the entry, -but instead indicate that the @samp{+} and conflict -marker are optional. @var{name} is the name of the -file within the directory. @var{revision} is the -revision that the file in the working derives from, or -@samp{0} for an added file, or @samp{-} followed by a -revision for a removed file. @var{timestamp} is the -timestamp of the file at the time that @sc{cvs} created -it; if the timestamp differs with the actual -modification time of the file it means the file has -been modified. It is stored in -the format used by the ISO C asctime() function (for -example, @samp{Sun Apr 7 01:29:26 1996}). One may -write a string which is not in that format, for -example, @samp{Result of merge}, to indicate that the -file should always be considered to be modified. This -is not a special case; to see whether a file is -modified a program should take the timestamp of the file -and simply do a string compare with @var{timestamp}. -If there was a conflict, @var{conflict} can be set to -the modification time of the file after the file has been -written with conflict markers (@pxref{Conflicts example}). -Thus if @var{conflict} is subsequently the same as the actual -modification time of the file it means that the user -has obviously not resolved the conflict. @var{options} -contains sticky options (for example @samp{-kb} for a -binary file). @var{tagdate} contains @samp{T} followed -by a tag name, or @samp{D} for a date, followed by a -sticky tag or date. Note that if @var{timestamp} -contains a pair of timestamps separated by a space, -rather than a single timestamp, you are dealing with a -version of @sc{cvs} earlier than @sc{cvs} 1.5 (not -documented here). - -The timezone on the timestamp in CVS/Entries (local or -universal) should be the same as the operating system -stores for the timestamp of the file itself. For -example, on Unix the file's timestamp is in universal -time (UT), so the timestamp in CVS/Entries should be -too. On @sc{vms}, the file's timestamp is in local -time, so @sc{cvs} on @sc{vms} should use local time. -This rule is so that files do not appear to be modified -merely because the timezone changed (for example, to or -from summer time). -@c See comments and calls to gmtime() and friends in -@c src/vers_ts.c (function time_stamp). - -If the first character of a line in @file{Entries} is -@samp{D}, then it indicates a subdirectory. @samp{D} -on a line all by itself indicates that the program -which wrote the @file{Entries} file does record -subdirectories (therefore, if there is such a line and -no other lines beginning with @samp{D}, one knows there -are no subdirectories). Otherwise, the line looks -like: - -@example -D/@var{name}/@var{filler1}/@var{filler2}/@var{filler3}/@var{filler4} -@end example - -@noindent -where @var{name} is the name of the subdirectory, and -all the @var{filler} fields should be silently ignored, -for future expansion. Programs which modify -@code{Entries} files should preserve these fields. - -The lines in the @file{Entries} file can be in any order. - -@cindex Entries.Log file, in CVS directory -@cindex CVS/Entries.Log file -@item Entries.Log -This file does not record any information beyond that -in @file{Entries}, but it does provide a way to update -the information without having to rewrite the entire -@file{Entries} file, including the ability to preserve -the information even if the program writing -@file{Entries} and @file{Entries.Log} abruptly aborts. -Programs which are reading the @file{Entries} file -should also check for @file{Entries.Log}. If the latter -exists, they should read @file{Entries} and then apply -the changes mentioned in @file{Entries.Log}. After -applying the changes, the recommended practice is to -rewrite @file{Entries} and then delete @file{Entries.Log}. -The format of a line in @file{Entries.Log} is a single -character command followed by a space followed by a -line in the format specified for a line in -@file{Entries}. The single character command is -@samp{A} to indicate that the entry is being added, -@samp{R} to indicate that the entry is being removed, -or any other character to indicate that the entire line -in @file{Entries.Log} should be silently ignored (for -future expansion). If the second character of the line -in @file{Entries.Log} is not a space, then it was -written by an older version of @sc{cvs} (not documented -here). - -Programs which are writing rather than reading can -safely ignore @file{Entries.Log} if they so choose. - -@cindex Entries.Backup file, in CVS directory -@cindex CVS/Entries.Backup file -@item Entries.Backup -This is a temporary file. Recommended usage is to -write a new entries file to @file{Entries.Backup}, and -then to rename it (atomically, where possible) to @file{Entries}. - -@cindex Entries.Static file, in CVS directory -@cindex CVS/Entries.Static file -@item Entries.Static -The only relevant thing about this file is whether it -exists or not. If it exists, then it means that only -part of a directory was gotten and @sc{cvs} will -not create additional files in that directory. To -clear it, use the @code{update} command with the -@samp{-d} option, which will get the additional files -and remove @file{Entries.Static}. -@c FIXME: This needs to be better documented, in places -@c other than Working Directory Storage. -@c FIXCVS: The fact that this setting exists needs to -@c be more visible to the user. For example "cvs -@c status foo", in the case where the file would be -@c gotten except for Entries.Static, might say -@c something to distinguish this from other cases. -@c One thing that periodically gets suggested is to -@c have "cvs update" print something when it skips -@c files due to Entries.Static, but IMHO that kind of -@c noise pretty much makes the Entries.Static feature -@c useless. - -@cindex Tag file, in CVS directory -@cindex CVS/Tag file -@cindex Sticky tags/dates, per-directory -@cindex Per-directory sticky tags/dates -@item Tag -This file contains per-directory sticky tags or dates. -The first character is @samp{T} for a branch tag, -@samp{N} for a non-branch tag, or @samp{D} for a date, -or another character to mean the file should be -silently ignored, for future expansion. This character -is followed by the tag or date. Note that -per-directory sticky tags or dates are used for things -like applying to files which are newly added; they -might not be the same as the sticky tags or dates on -individual files. For general information on sticky -tags and dates, see @ref{Sticky tags}. -@c FIXME: This needs to be much better documented, -@c preferably not in the context of "working directory -@c storage". -@c FIXME: The Sticky tags node needs to discuss, or xref to -@c someplace which discusses, per-directory sticky -@c tags and the distinction with per-file sticky tags. - -@cindex Notify file, in CVS directory -@cindex CVS/Notify file -@item Notify -This file stores notifications (for example, for -@code{edit} or @code{unedit}) which have not yet been -sent to the server. Its format is not yet documented -here. - -@cindex Notify.tmp file, in CVS directory -@cindex CVS/Notify.tmp file -@item Notify.tmp -This file is to @file{Notify} as @file{Entries.Backup} -is to @file{Entries}. That is, to write @file{Notify}, -first write the new contents to @file{Notify.tmp} and -then (atomically where possible), rename it to -@file{Notify}. - -@cindex Base directory, in CVS directory -@cindex CVS/Base directory -@item Base -If watches are in use, then an @code{edit} command -stores the original copy of the file in the @file{Base} -directory. This allows the @code{unedit} command to -operate even if it is unable to communicate with the -server. - -@cindex Baserev file, in CVS directory -@cindex CVS/Baserev file -@item Baserev -The file lists the revision for each of the files in -the @file{Base} directory. The format is: - -@example -B@var{name}/@var{rev}/@var{expansion} -@end example - -@noindent -where @var{expansion} should be ignored, to allow for -future expansion. - -@cindex Baserev.tmp file, in CVS directory -@cindex CVS/Baserev.tmp file -@item Baserev.tmp -This file is to @file{Baserev} as @file{Entries.Backup} -is to @file{Entries}. That is, to write @file{Baserev}, -first write the new contents to @file{Baserev.tmp} and -then (atomically where possible), rename it to -@file{Baserev}. - -@cindex Template file, in CVS directory -@cindex CVS/Template file -@item Template -This file contains the template specified by the -@file{rcsinfo} file (@pxref{rcsinfo}). It is only used -by the client; the non-client/server @sc{cvs} consults -@file{rcsinfo} directly. -@end table - -@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@node Intro administrative files -@section The administrative files -@cindex Administrative files (intro) -@cindex Modules file -@cindex CVSROOT, module name -@cindex Defining modules (intro) - -@c FIXME: this node should be reorganized into "general -@c information about admin files" and put the "editing -@c admin files" stuff up front rather than jumping into -@c the details of modules right away. Then the -@c Administrative files node can go away, the information -@c on each admin file distributed to a place appropriate -@c to its function, and this node can contain a table -@c listing each file and a @ref to its detailed description. - -The directory @file{$CVSROOT/CVSROOT} contains some @dfn{administrative -files}. @xref{Administrative files}, for a complete description. -You can use @sc{cvs} without any of these files, but -some commands work better when at least the -@file{modules} file is properly set up. - -The most important of these files is the @file{modules} -file. It defines all modules in the repository. This -is a sample @file{modules} file. - -@c FIXME: The CVSROOT line is a goofy example now that -@c mkmodules doesn't exist. -@example -CVSROOT CVSROOT -modules CVSROOT modules -cvs gnu/cvs -rcs gnu/rcs -diff gnu/diff -tc yoyodyne/tc -@end example - -The @file{modules} file is line oriented. In its -simplest form each line contains the name of the -module, whitespace, and the directory where the module -resides. The directory is a path relative to -@code{$CVSROOT}. The last four lines in the example -above are examples of such lines. - -@c FIXME: might want to introduce the concept of options in modules file -@c (the old example which was here, -i mkmodules, is obsolete). - -The line that defines the module called @samp{modules} -uses features that are not explained here. -@xref{modules}, for a full explanation of all the -available features. - -@c FIXME: subsection without node is bogus -@subsection Editing administrative files -@cindex Editing administrative files -@cindex Administrative files, editing them - -You edit the administrative files in the same way that you would edit -any other module. Use @samp{cvs checkout CVSROOT} to get a working -copy, edit it, and commit your changes in the normal way. - -It is possible to commit an erroneous administrative -file. You can often fix the error and check in a new -revision, but sometimes a particularly bad error in the -administrative file makes it impossible to commit new -revisions. If and when this happens, you can correct -the problem by temporarily copying a corrected administrative file -directly into the @code{$CVSROOT/CVSROOT} repository directory, -then committing the same correction via a checkout of the @file{CVSROOT} -module. It is important that the correction also be made via the -checked out copy, or the next checkout and commit to the -CVSROOT module will overwrite the correction that was -copied directly into the repository, possibly breaking things in such -a way as to prevent commits again. -@c @xref{Bad administrative files} for a hint -@c about how to solve such situations. -@c -- administrative file checking-- - -@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@node Multiple repositories -@section Multiple repositories -@cindex Multiple repositories -@cindex Repositories, multiple -@cindex Many repositories -@cindex Parallel repositories -@cindex Disjoint repositories -@cindex CVSROOT, multiple repositories - -In some situations it is a good idea to have more than -one repository, for instance if you have two -development groups that work on separate projects -without sharing any code. All you have to do to have -several repositories is to specify the appropriate -repository, using the @code{CVSROOT} environment -variable, the @samp{-d} option to @sc{cvs}, or (once -you have checked out a working directory) by simply -allowing @sc{cvs} to use the repository that was used -to check out the working directory -(@pxref{Specifying a repository}). - -The big advantage of having multiple repositories is -that they can reside on different servers. With @sc{cvs} -version 1.10, a single command cannot recurse into -directories from different repositories. With development -versions of @sc{cvs}, you can check out code from multiple -servers into your working directory. @sc{cvs} will -recurse and handle all the details of making -connections to as many server machines as necessary to -perform the requested command. Here is an example of -how to set up a working directory: - -@example -cvs -d server1:/cvs co dir1 -cd dir1 -cvs -d server2:/root co sdir -cvs update -@end example - -The @code{cvs co} commands set up the working -directory, and then the @code{cvs update} command will -contact server2, to update the dir1/sdir subdirectory, -and server1, to update everything else. - -@c FIXME: Does the FAQ have more about this? I have a -@c dim recollection, but I'm too lazy to check right now. - -@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@node Creating a repository -@section Creating a repository - -@cindex Repository, setting up -@cindex Creating a repository -@cindex Setting up a repository - -This section describes how to set up a @sc{cvs} repository for any -sort of access method. After completing the setup described in this -section, you should be able to access your @sc{cvs} repository immediately -via the local access method and several remote access methods. For -more information on setting up remote access to the repository you create -in this section, please read the section on @xref{Remote repositories}. - -To set up a @sc{cvs} repository, first choose the -machine and disk on which you want to store the -revision history of the source files. CPU and memory -requirements are modest, so most machines should be -adequate. For details see @ref{Server requirements}. -@c Possible that we should be providing a quick rule of -@c thumb, like the 32M memory for the server. That -@c might increase the number of people who are happy -@c with the answer, without following the xref. - -To estimate disk space -requirements, if you are importing RCS files from -another system, the size of those files is the -approximate initial size of your repository, or if you -are starting without any version history, a rule of -thumb is to allow for the server approximately three -times the size of the code to be under @sc{cvs} for the -repository (you will eventually outgrow this, but not -for a while). On the machines on which the developers -will be working, you'll want disk space for -approximately one working directory for each developer -(either the entire tree or a portion of it, depending -on what each developer uses). - -The repository should be accessible -(directly or via a networked file system) from all -machines which want to use @sc{cvs} in server or local -mode; the client machines need not have any access to -it other than via the @sc{cvs} protocol. It is not -possible to use @sc{cvs} to read from a repository -which one only has read access to; @sc{cvs} needs to be -able to create lock files (@pxref{Concurrency}). - -@cindex init (subcommand) -To create a repository, run the @code{cvs init} -command. It will set up an empty repository in the -@sc{cvs} root specified in the usual way -(@pxref{Repository}). For example, - -@example -cvs -d /usr/local/cvsroot init -@end example - -@code{cvs init} is careful to never overwrite any -existing files in the repository, so no harm is done if -you run @code{cvs init} on an already set-up -repository. - -@code{cvs init} will enable history logging; if you -don't want that, remove the history file after running -@code{cvs init}. @xref{history file}. - -@node Backing up -@section Backing up a repository -@cindex Repository, backing up -@cindex Backing up, repository - -There is nothing particularly magical about the files -in the repository; for the most part it is possible to -back them up just like any other files. However, there -are a few issues to consider. - -@cindex Locks, cvs, and backups -@cindex #cvs.rfl, and backups -The first is that to be paranoid, one should either not -use @sc{cvs} during the backup, or have the backup -program lock @sc{cvs} while doing the backup. To not -use @sc{cvs}, you might forbid logins to machines which -can access the repository, turn off your @sc{cvs} -server, or similar mechanisms. The details would -depend on your operating system and how you have -@sc{cvs} set up. To lock @sc{cvs}, you would create -@file{#cvs.rfl} locks in each repository directory. -See @ref{Concurrency}, for more on @sc{cvs} locks. -Having said all this, if you just back up without any -of these precautions, the results are unlikely to be -particularly dire. Restoring from backup, the -repository might be in an inconsistent state, but this -would not be particularly hard to fix manually. - -When you restore a repository from backup, assuming -that changes in the repository were made after the time -of the backup, working directories which were not -affected by the failure may refer to revisions which no -longer exist in the repository. Trying to run @sc{cvs} -in such directories will typically produce an error -message. One way to get those changes back into the -repository is as follows: - -@itemize @bullet -@item -Get a new working directory. - -@item -Copy the files from the working directory from before -the failure over to the new working directory (do not -copy the contents of the @file{CVS} directories, of -course). - -@item -Working in the new working directory, use commands such -as @code{cvs update} and @code{cvs diff} to figure out -what has changed, and then when you are ready, commit -the changes into the repository. -@end itemize - -@node Moving a repository -@section Moving a repository -@cindex Repository, moving -@cindex Moving a repository -@cindex Copying a repository - -Just as backing up the files in the repository is -pretty much like backing up any other files, if you -need to move a repository from one place to another it -is also pretty much like just moving any other -collection of files. - -The main thing to consider is that working directories -point to the repository. The simplest way to deal with -a moved repository is to just get a fresh working -directory after the move. Of course, you'll want to -make sure that the old working directory had been -checked in before the move, or you figured out some -other way to make sure that you don't lose any -changes. If you really do want to reuse the existing -working directory, it should be possible with manual -surgery on the @file{CVS/Repository} files. You can -see @ref{Working directory storage}, for information on -the @file{CVS/Repository} and @file{CVS/Root} files, but -unless you are sure you want to bother, it probably -isn't worth it. -@c FIXME: Surgery on CVS/Repository should be avoided -@c by making RELATIVE_REPOS the default. -@c FIXME-maybe: might want some documented way to -@c change the CVS/Root files in some particular tree. -@c But then again, I don't know, maybe just having -@c people do this in perl/shell/&c isn't so bad... - -@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@node Remote repositories -@section Remote repositories -@cindex Repositories, remote -@cindex Remote repositories -@cindex Client/Server Operation -@cindex Server, CVS -@cindex Remote repositories, port specification -@cindex Repositories, remote, port specification -@cindex Client/Server Operation, port specification -@cindex pserver (client/server connection method), port specification -@cindex kserver (client/server connection method), port specification -@cindex gserver (client/server connection method), port specification -@cindex port, specifying for remote repositories - - Your working copy of the sources can be on a -different machine than the repository. Using @sc{cvs} -in this manner is known as @dfn{client/server} -operation. You run @sc{cvs} on a machine which can -mount your working directory, known as the -@dfn{client}, and tell it to communicate to a machine -which can mount the repository, known as the -@dfn{server}. Generally, using a remote -repository is just like using a local one, except that -the format of the repository name is: - -@example -[:@var{method}:][[@var{user}][:@var{password}]@@]@var{hostname}[:[@var{port}]]/path/to/repository -@end example - -Specifying a password in the repository name is not recommended during -checkout, since this will cause @sc{cvs} to store a cleartext copy of the -password in each created directory. @code{cvs login} first instead -(@pxref{Password authentication client}). - -The details of exactly what needs to be set up depend -on how you are connecting to the server. - -If @var{method} is not specified, and the repository -name contains @samp{:}, then the default is @code{ext} -or @code{server}, depending on your platform; both are -described in @ref{Connecting via rsh}. -@c Should we try to explain which platforms are which? -@c Platforms like unix and VMS, which only allow -@c privileged programs to bind to sockets <1024 lose on -@c :server: -@c Platforms like Mac and VMS, whose rsh program is -@c unusable or nonexistent, lose on :ext: -@c Platforms like OS/2 and NT probably could plausibly -@c default either way (modulo -b troubles). - -@c FIXME: We need to have a better way of explaining -@c what method to use. This presentation totally -@c obscures the fact that :ext: and CVS_RSH is the way to -@c use SSH, for example. Plus it incorrectly implies -@c that you need an @code{rsh} binary on the client to use -@c :server:. -@c Also note that rsh not pserver is the right choice if you want -@c users to be able to create their own repositories -@c (because of the --allow-root related issues). -@menu -* Server requirements:: Memory and other resources for servers -* Connecting via rsh:: Using the @code{rsh} program to connect -* Password authenticated:: Direct connections using passwords -* GSSAPI authenticated:: Direct connections using GSSAPI -* Kerberos authenticated:: Direct connections with Kerberos -* Connecting via fork:: Using a forked @code{cvs server} to connect -@end menu - -@node Server requirements -@subsection Server requirements - -The quick answer to what sort of machine is suitable as -a server is that requirements are modest---a server -with 32M of memory or even less can handle a fairly -large source tree with a fair amount of activity. -@c Say something about CPU speed too? I'm even less sure -@c what to say on that subject... - -The real answer, of course, is more complicated. -Estimating the known areas of large memory consumption -should be sufficient to estimate memory requirements. -There are two such areas documented here; other memory -consumption should be small by comparison (if you find -that is not the case, let us know, as described in -@ref{BUGS}, so we can update this documentation). - -The first area of big memory consumption is large -checkouts, when using the @sc{cvs} server. The server -consists of two processes for each client that it is -serving. Memory consumption on the child process -should remain fairly small. Memory consumption on the -parent process, particularly if the network connection -to the client is slow, can be expected to grow to -slightly more than the size of the sources in a single -directory, or two megabytes, whichever is larger. -@c "two megabytes" of course is SERVER_HI_WATER. But -@c we don't mention that here because we are -@c documenting the default configuration of CVS. If it -@c is a "standard" thing to change that value, it -@c should be some kind of run-time configuration. -@c -@c See cvsclient.texi for more on the design decision -@c to not have locks in place while waiting for the -@c client, which is what results in memory consumption -@c as high as this. - -Multiplying the size of each @sc{cvs} server by the -number of servers which you expect to have active at -one time should give an idea of memory requirements for -the server. For the most part, the memory consumed by -the parent process probably can be swap space rather -than physical memory. -@c Has anyone verified that notion about swap space? -@c I say it based pretty much on guessing that the -@c ->text of the struct buffer_data only gets accessed -@c in a first in, first out fashion, but I haven't -@c looked very closely. - -@c What about disk usage in /tmp on the server? I think that -@c it can be substantial, but I haven't looked at this -@c again and tried to figure it out ("cvs import" is -@c probably the worst case...). - -The second area of large memory consumption is -@code{diff}, when checking in large files. This is -required even for binary files. The rule of thumb is -to allow about ten times the size of the largest file -you will want to check in, although five times may be -adequate. For example, if you want to check in a file -which is 10 megabytes, you should have 100 megabytes of -memory on the machine doing the checkin (the server -machine for client/server, or the machine running -@sc{cvs} for non-client/server). This can be swap -space rather than physical memory. Because the memory -is only required briefly, there is no particular need -to allow memory for more than one such checkin at a -time. -@c The 5-10 times rule of thumb is from Paul Eggert for -@c GNU diff. I don't think it is in the GNU diff -@c manual or anyplace like that. -@c -@c Probably we could be saying more about -@c non-client/server CVS. -@c I would guess for non-client/server CVS in an NFS -@c environment the biggest issues are the network and -@c the NFS server. - -Resource consumption for the client is even more -modest---any machine with enough capacity to run the -operating system in question should have little -trouble. -@c Is that true? I think the client still wants to -@c (bogusly) store entire files in memory at times. - -For information on disk space requirements, see -@ref{Creating a repository}. - -@node Connecting via rsh -@subsection Connecting with rsh or ssh - -@cindex ssh -@sc{cvs} may use the @samp{ssh} protocol to perform -these operations, so the remote user host needs to have -a either an agent like @code{ssh-agent} to hold -credentials or a @file{.shosts} file which grants -access to the local user. Note that the program that -@sc{cvs} uses for this purpose may be specified using -the @file{--with-ssh} flag to configure. - -@cindex rsh -@sc{cvs} uses the @samp{rsh} protocol to perform these -operations, so the remote user host needs to have a -@file{.rhosts} file which grants access to the local -user. Note that the program that @sc{cvs} uses for this -purpose may be specified using the @file{--with-rsh} -flag to configure. - -For example, suppose you are the user @samp{mozart} on -the local machine @samp{toe.example.com}, and the -server machine is @samp{faun.example.org}. On -faun, put the following line into the file -@file{.rhosts} in @samp{bach}'s home directory: - -@example -toe.example.com mozart -@end example - -@noindent -Then test that @samp{rsh} is working with - -@example -rsh -l bach faun.example.org 'echo $PATH' -@end example - -@noindent -To test that @samp{ssh} is working use - -@example -ssh -l bach faun.example.org 'echo $PATH' -@end example - -@cindex CVS_SERVER, environment variable -Next you have to make sure that @code{rsh} will be able -to find the server. Make sure that the path which -@code{rsh} printed in the above example includes the -directory containing a program named @code{cvs} which -is the server. You need to set the path in -@file{.bashrc}, @file{.cshrc}, etc., not @file{.login} -or @file{.profile}. Alternately, you can set the -environment variable @code{CVS_SERVER} on the client -machine to the filename of the server you want to use, -for example @file{/usr/local/bin/cvs-1.6}. -@c FIXME: there should be a way to specify the -@c program in CVSROOT, not CVS_SERVER, so that one can use -@c different ones for different roots. e.g. ":server;cvs=cvs-1.6:" -@c instead of ":server:". - -There is no need to edit @file{inetd.conf} or start a -@sc{cvs} server daemon. - -@cindex :server:, setting up -@cindex :ext:, setting up -@cindex :extssh:, setting up -@cindex Kerberos, using kerberized rsh -@cindex SSH (rsh replacement) -@cindex rsh replacements (Kerberized, SSH, &c) -There are three access methods that you use in @code{CVSROOT} -for rsh or ssh. @code{:server:} specifies an internal rsh -client, which is supported only by some @sc{cvs} ports. -@code{:extssh:} specifies an external ssh program. By -default this is @code{ssh} (unless otherwise specified -by the @file{--with-ssh} flag to configure) but you may set the -@code{CVS_SSH} environment variable to invoke another -program or wrapper script. -@code{:ext:} specifies an external rsh program. By -default this is @code{rsh} (unless otherwise specified -by the @file{--with-rsh} flag to configure) but you may set the -@code{CVS_RSH} environment variable to invoke another -program which can access the remote server (for -example, @code{remsh} on HP-UX 9 because @code{rsh} is -something different). It must be a program which can -transmit data to and from the server without modifying -it; for example the Windows NT @code{rsh} is not -suitable since it by default translates between CRLF -and LF. The OS/2 @sc{cvs} port has a hack to pass @samp{-b} -to @code{rsh} to get around this, but since this could -potentially cause problems for programs other than the -standard @code{rsh}, it may change in the future. If -you set @code{CVS_RSH} to @code{SSH} or some other rsh -replacement, the instructions in the rest of this -section concerning @file{.rhosts} and so on are likely -to be inapplicable; consult the documentation for your rsh -replacement. -@c FIXME: there should be a way to specify the -@c program in CVSROOT, not CVS_RSH, so that one can use -@c different ones for different roots. e.g. -@c ":ext;CVS_RSH=remsh:" instead of ":ext:". -@c See also the comment in src/client.c for rationale -@c concerning "rsh" being the default and never -@c "remsh". - -Continuing our example, supposing you want to access -the module @file{foo} in the repository -@file{/usr/local/cvsroot/}, on machine -@file{faun.example.org}, you are ready to go: - -@example -cvs -d :ext:bach@@faun.example.org:/usr/local/cvsroot checkout foo -@end example - -@noindent -(The @file{bach@@} can be omitted if the username is -the same on both the local and remote hosts.) - -@c Should we mention "rsh host echo hi" and "rsh host -@c cat" (the latter followed by typing text and ^D) -@c as troubleshooting techniques? Probably yes -@c (people tend to have trouble setting this up), -@c but this kind of thing can be hard to spell out. - -@node Password authenticated -@subsection Direct connection with password authentication - -The @sc{cvs} client can also connect to the server -using a password protocol. This is particularly useful -if using @code{rsh} is not feasible (for example, -the server is behind a firewall), and Kerberos also is -not available. - - To use this method, it is necessary to make -some adjustments on both the server and client sides. - -@menu -* Password authentication server:: Setting up the server -* Password authentication client:: Using the client -* Password authentication security:: What this method does and does not do -@end menu - -@node Password authentication server -@subsubsection Setting up the server for password authentication - -First of all, you probably want to tighten the -permissions on the @file{$CVSROOT} and -@file{$CVSROOT/CVSROOT} directories. See @ref{Password -authentication security}, for more details. - -@cindex pserver (subcommand) -@cindex Remote repositories, port specification -@cindex Repositories, remote, port specification -@cindex Client/Server Operation, port specification -@cindex pserver (client/server connection method), port specification -@cindex kserver (client/server connection method), port specification -@cindex gserver (client/server connection method), port specification -@cindex port, specifying for remote repositories -@cindex Password server, setting up -@cindex Authenticating server, setting up -@cindex inetd, configuring for pserver -@cindex xinetd, configuring for pserver -@c FIXME: this isn't quite right regarding port -@c numbers; CVS looks up "cvspserver" in -@c /etc/services (on unix, but what about non-unix?). -On the server side, the file @file{/etc/inetd.conf} -needs to be edited so @code{inetd} knows to run the -command @code{cvs pserver} when it receives a -connection on the right port. By default, the port -number is 2401; it would be different if your client -were compiled with @code{CVS_AUTH_PORT} defined to -something else, though. This can also be specified in the CVSROOT variable -(@pxref{Remote repositories}) or overridden with the CVS_CLIENT_PORT -environment variable (@pxref{Environment variables}). - - If your @code{inetd} allows raw port numbers in -@file{/etc/inetd.conf}, then the following (all on a -single line in @file{inetd.conf}) should be sufficient: - -@example -2401 stream tcp nowait root /usr/local/bin/cvs -cvs -f --allow-root=/usr/cvsroot pserver -@end example - -@noindent -(You could also use the -@samp{-T} option to specify a temporary directory.) - -The @samp{--allow-root} option specifies the allowable -@sc{cvsroot} directory. Clients which attempt to use a -different @sc{cvsroot} directory will not be allowed to -connect. If there is more than one @sc{cvsroot} -directory which you want to allow, repeat the option. -(Unfortunately, many versions of @code{inetd} have very small -limits on the number of arguments and/or the total length -of the command. The usual solution to this problem is -to have @code{inetd} run a shell script which then invokes -@sc{cvs} with the necessary arguments.) - - If your @code{inetd} wants a symbolic service -name instead of a raw port number, then put this in -@file{/etc/services}: - -@example -cvspserver 2401/tcp -@end example - -@noindent -and put @code{cvspserver} instead of @code{2401} in @file{inetd.conf}. - -If your system uses @code{xinetd} instead of @code{inetd}, -the procedure is slightly different. -Create a file called @file{/etc/xinetd.d/cvspserver} containing the following: - -@example -service cvspserver -@{ - port = 2401 - socket_type = stream - protocol = tcp - wait = no - user = root - passenv = PATH - server = /usr/local/bin/cvs - server_args = -f --allow-root=/usr/cvsroot pserver -@} -@end example - -@noindent -(If @code{cvspserver} is defined in @file{/etc/services}, you can omit -the @code{port} line.) - - Once the above is taken care of, restart your -@code{inetd}, or do whatever is necessary to force it -to reread its initialization files. - -If you are having trouble setting this up, see -@ref{Connection}. - -@cindex CVS passwd file -@cindex passwd (admin file) -Because the client stores and transmits passwords in -cleartext (almost---see @ref{Password authentication -security}, for details), a separate @sc{cvs} password -file is generally used, so people don't compromise -their regular passwords when they access the -repository. This file is -@file{$CVSROOT/CVSROOT/passwd} (@pxref{Intro -administrative files}). It uses a colon-separated -format, similar to @file{/etc/passwd} on Unix systems, -except that it has fewer fields: @sc{cvs} username, -optional password, and an optional system username for -@sc{cvs} to run as if authentication succeeds. Here is -an example @file{passwd} file with five entries: - -@example -anonymous: -bach:ULtgRLXo7NRxs -spwang:1sOp854gDF3DY -melissa:tGX1fS8sun6rY:pubcvs -qproj:XR4EZcEs0szik:pubcvs -@end example - -@noindent -(The passwords are encrypted according to the standard -Unix @code{crypt()} function, so it is possible to -paste in passwords directly from regular Unix -@file{/etc/passwd} files.) - -The first line in the example will grant access to any -@sc{cvs} client attempting to authenticate as user -@code{anonymous}, no matter what password they use, -including an empty password. (This is typical for -sites granting anonymous read-only access; for -information on how to do the "read-only" part, see -@ref{Read-only access}.) - -The second and third lines will grant access to -@code{bach} and @code{spwang} if they supply their -respective plaintext passwords. - -@cindex User aliases -The fourth line will grant access to @code{melissa}, if -she supplies the correct password, but her @sc{cvs} -operations will actually run on the server side under -the system user @code{pubcvs}. Thus, there need not be -any system user named @code{melissa}, but there -@emph{must} be one named @code{pubcvs}. - -The fifth line shows that system user identities can be -shared: any client who successfully authenticates as -@code{qproj} will actually run as @code{pubcvs}, just -as @code{melissa} does. That way you could create a -single, shared system user for each project in your -repository, and give each developer their own line in -the @file{$CVSROOT/CVSROOT/passwd} file. The @sc{cvs} -username on each line would be different, but the -system username would be the same. The reason to have -different @sc{cvs} usernames is that @sc{cvs} will log their -actions under those names: when @code{melissa} commits -a change to a project, the checkin is recorded in the -project's history under the name @code{melissa}, not -@code{pubcvs}. And the reason to have them share a -system username is so that you can arrange permissions -in the relevant area of the repository such that only -that account has write-permission there. - -If the system-user field is present, all -password-authenticated @sc{cvs} commands run as that -user; if no system user is specified, @sc{cvs} simply -takes the @sc{cvs} username as the system username and -runs commands as that user. In either case, if there -is no such user on the system, then the @sc{cvs} -operation will fail (regardless of whether the client -supplied a valid password). - -The password and system-user fields can both be omitted -(and if the system-user field is omitted, then also -omit the colon that would have separated it from the -encrypted password). For example, this would be a -valid @file{$CVSROOT/CVSROOT/passwd} file: - -@example -anonymous::pubcvs -fish:rKa5jzULzmhOo:kfogel -sussman:1sOp854gDF3DY -@end example - -@noindent -When the password field is omitted or empty, then the -client's authentication attempt will succeed with any -password, including the empty string. However, the -colon after the @sc{cvs} username is always necessary, -even if the password is empty. - -@sc{cvs} can also fall back to use system authentication. -When authenticating a password, the server first checks -for the user in the @file{$CVSROOT/CVSROOT/passwd} -file. If it finds the user, it will use that entry for -authentication as described above. But if it does not -find the user, or if the @sc{cvs} @file{passwd} file -does not exist, then the server can try to authenticate -the username and password using the operating system's -user-lookup routines (this "fallback" behavior can be -disabled by setting @code{SystemAuth=no} in the -@sc{cvs} @file{config} file, @pxref{config}). Be -aware, however, that falling back to system -authentication might be a security risk: @sc{cvs} -operations would then be authenticated with that user's -regular login password, and the password flies across -the network in plaintext. See @ref{Password -authentication security} for more on this. - -Right now, the only way to put a password in the -@sc{cvs} @file{passwd} file is to paste it there from -somewhere else. Someday, there may be a @code{cvs -passwd} command. - -Unlike many of the files in @file{$CVSROOT/CVSROOT}, it -is normal to edit the @file{passwd} file in-place, -rather than via @sc{cvs}. This is because of the -possible security risks of having the @file{passwd} -file checked out to people's working copies. If you do -want to include the @file{passwd} file in checkouts of -@file{$CVSROOT/CVSROOT}, see @ref{checkoutlist}. - -@c We might also suggest using the @code{htpasswd} command -@c from freely available web servers as well, but that -@c would open up a can of worms in that the users next -@c questions are likely to be "where do I get it?" and -@c "how do I use it?" -@c Also note that htpasswd, at least the version I had, -@c likes to clobber the third field. - -@node Password authentication client -@subsubsection Using the client with password authentication -@cindex Login (subcommand) -@cindex Password client, using -@cindex Authenticated client, using -@cindex :pserver:, setting up -To run a @sc{cvs} command on a remote repository via -the password-authenticating server, one specifies the -@code{pserver} protocol, optional username, repository host, an -optional port number, and path to the repository. For example: - -@example -cvs -d :pserver:faun.example.org:/usr/local/cvsroot checkout someproj -@end example - -@noindent -or - -@example -CVSROOT=:pserver:bach@@faun.example.org:2401/usr/local/cvsroot -cvs checkout someproj -@end example - -However, unless you're connecting to a public-access -repository (i.e., one where that username doesn't -require a password), you'll need to supply a password or @dfn{log in} first. -Logging in verifies your password with the repository and stores it in a file. -It's done with the @code{login} command, which will -prompt you interactively for the password if you didn't supply one as part of -@var{$CVSROOT}: - -@example -cvs -d :pserver:bach@@faun.example.org:/usr/local/cvsroot login -CVS password: -@end example - -@noindent -or - -@example -cvs -d :pserver:bach:p4ss30rd@@faun.example.org:/usr/local/cvsroot login -@end example - -After you enter the password, @sc{cvs} verifies it with -the server. If the verification succeeds, then that -combination of username, host, repository, and password -is permanently recorded, so future transactions with -that repository won't require you to run @code{cvs -login}. (If verification fails, @sc{cvs} will exit -complaining that the password was incorrect, and -nothing will be recorded.) - -The records are stored, by default, in the file -@file{$HOME/.cvspass}. That file's format is -human-readable, and to a degree human-editable, but -note that the passwords are not stored in -cleartext---they are trivially encoded to protect them -from "innocent" compromise (i.e., inadvertent viewing -by a system administrator or other non-malicious -person). - -@cindex CVS_PASSFILE, environment variable -You can change the default location of this file by -setting the @code{CVS_PASSFILE} environment variable. -If you use this variable, make sure you set it -@emph{before} @code{cvs login} is run. If you were to -set it after running @code{cvs login}, then later -@sc{cvs} commands would be unable to look up the -password for transmission to the server. - -Once you have logged in, all @sc{cvs} commands using -that remote repository and username will authenticate -with the stored password. So, for example - -@example -cvs -d :pserver:bach@@faun.example.org:/usr/local/cvsroot checkout foo -@end example - -@noindent -should just work (unless the password changes on the -server side, in which case you'll have to re-run -@code{cvs login}). - -Note that if the @samp{:pserver:} were not present in -the repository specification, @sc{cvs} would assume it -should use @code{rsh} to connect with the server -instead (@pxref{Connecting via rsh}). - -Of course, once you have a working copy checked out and -are running @sc{cvs} commands from within it, there is -no longer any need to specify the repository -explicitly, because @sc{cvs} can deduce the repository -from the working copy's @file{CVS} subdirectory. - -@c FIXME: seems to me this needs somewhat more -@c explanation. -@cindex Logout (subcommand) -The password for a given remote repository can be -removed from the @code{CVS_PASSFILE} by using the -@code{cvs logout} command. - -@node Password authentication security -@subsubsection Security considerations with password authentication - -@cindex Security, of pserver -The passwords are stored on the client side in a -trivial encoding of the cleartext, and transmitted in -the same encoding. The encoding is done only to -prevent inadvertent password compromises (i.e., a -system administrator accidentally looking at the file), -and will not prevent even a naive attacker from gaining -the password. - -@c FIXME: The bit about "access to the repository -@c implies general access to the system is *not* specific -@c to pserver; it applies to kerberos and SSH and -@c everything else too. Should reorganize the -@c documentation to make this clear. -The separate @sc{cvs} password file (@pxref{Password -authentication server}) allows people -to use a different password for repository access than -for login access. On the other hand, once a user has -non-read-only -access to the repository, she can execute programs on -the server system through a variety of means. Thus, repository -access implies fairly broad system access as well. It -might be possible to modify @sc{cvs} to prevent that, -but no one has done so as of this writing. -@c OpenBSD uses chroot() and copies the repository to -@c provide anonymous read-only access (for details see -@c http://www.openbsd.org/anoncvs.shar). While this -@c closes the most obvious holes, I'm not sure it -@c closes enough holes to recommend it (plus it is -@c *very* easy to accidentally screw up a setup of this -@c type). - -Note that because the @file{$CVSROOT/CVSROOT} directory -contains @file{passwd} and other files which are used -to check security, you must control the permissions on -this directory as tightly as the permissions on -@file{/etc}. The same applies to the @file{$CVSROOT} -directory itself and any directory -above it in the tree. Anyone who has write access to -such a directory will have the ability to become any -user on the system. Note that these permissions are -typically tighter than you would use if you are not -using pserver. -@c TODO: Would be really nice to document/implement a -@c scheme where the CVS server can run as some non-root -@c user, e.g. "cvs". CVSROOT/passwd would contain a -@c bunch of entries of the form foo:xxx:cvs (or the "cvs" -@c would be implicit). This would greatly reduce -@c security risks such as those hinted at in the -@c previous paragraph. I think minor changes to CVS -@c might be required but mostly this would just need -@c someone who wants to play with it, document it, &c. - -In summary, anyone who gets the password gets -repository access (which may imply some measure of general system -access as well). The password is available to anyone -who can sniff network packets or read a protected -(i.e., user read-only) file. If you want real -security, get Kerberos. - -@node GSSAPI authenticated -@subsection Direct connection with GSSAPI - -@cindex GSSAPI -@cindex Security, GSSAPI -@cindex :gserver:, setting up -@cindex Kerberos, using :gserver: -GSSAPI is a generic interface to network security -systems such as Kerberos 5. -If you have a working GSSAPI library, you can have -@sc{cvs} connect via a direct @sc{tcp} connection, -authenticating with GSSAPI. - -To do this, @sc{cvs} needs to be compiled with GSSAPI -support; when configuring @sc{cvs} it tries to detect -whether GSSAPI libraries using Kerberos version 5 are -present. You can also use the @file{--with-gssapi} -flag to configure. - -The connection is authenticated using GSSAPI, but the -message stream is @emph{not} authenticated by default. -You must use the @code{-a} global option to request -stream authentication. - -The data transmitted is @emph{not} encrypted by -default. Encryption support must be compiled into both -the client and the server; use the -@file{--enable-encrypt} configure option to turn it on. -You must then use the @code{-x} global option to -request encryption. - -GSSAPI connections are handled on the server side by -the same server which handles the password -authentication server; see @ref{Password authentication -server}. If you are using a GSSAPI mechanism such as -Kerberos which provides for strong authentication, you -will probably want to disable the ability to -authenticate via cleartext passwords. To do so, create -an empty @file{CVSROOT/passwd} password file, and set -@code{SystemAuth=no} in the config file -(@pxref{config}). - -The GSSAPI server uses a principal name of -cvs/@var{hostname}, where @var{hostname} is the -canonical name of the server host. You will have to -set this up as required by your GSSAPI mechanism. - -To connect using GSSAPI, use the @samp{:gserver:} method. For -example, - -@example -cvs -d :gserver:faun.example.org:/usr/local/cvsroot checkout foo -@end example - -@node Kerberos authenticated -@subsection Direct connection with Kerberos - -@cindex Kerberos, using :kserver: -@cindex Security, Kerberos -@cindex :kserver:, setting up -The easiest way to use Kerberos is to use the Kerberos -@code{rsh}, as described in @ref{Connecting via rsh}. -The main disadvantage of using rsh is that all the data -needs to pass through additional programs, so it may be -slower. So if you have Kerberos installed you can -connect via a direct @sc{tcp} connection, -authenticating with Kerberos. - -This section concerns the Kerberos network security -system, version 4. Kerberos version 5 is supported via -the GSSAPI generic network security interface, as -described in the previous section. - -To do this, @sc{cvs} needs to be compiled with Kerberos -support; when configuring @sc{cvs} it tries to detect -whether Kerberos is present or you can use the -@file{--with-krb4} flag to configure. - -The data transmitted is @emph{not} encrypted by -default. Encryption support must be compiled into both -the client and server; use the -@file{--enable-encryption} configure option to turn it -on. You must then use the @code{-x} global option to -request encryption. - -@cindex CVS_CLIENT_PORT -You need to edit @file{inetd.conf} on the server -machine to run @code{cvs kserver}. The client uses -port 1999 by default; if you want to use another port -specify it in the @code{CVSROOT} (@pxref{Remote repositories}) -or the @code{CVS_CLIENT_PORT} environment variable -(@pxref{Environment variables}) on the client. - -@cindex kinit -When you want to use @sc{cvs}, get a ticket in the -usual way (generally @code{kinit}); it must be a ticket -which allows you to log into the server machine. Then -you are ready to go: - -@example -cvs -d :kserver:faun.example.org:/usr/local/cvsroot checkout foo -@end example - -Previous versions of @sc{cvs} would fall back to a -connection via rsh; this version will not do so. - -@node Connecting via fork -@subsection Connecting with fork - -@cindex fork, access method -@cindex :fork:, setting up -This access method allows you to connect to a -repository on your local disk via the remote protocol. -In other words it does pretty much the same thing as -@code{:local:}, but various quirks, bugs and the like are -those of the remote @sc{cvs} rather than the local -@sc{cvs}. - -For day-to-day operations you might prefer either -@code{:local:} or @code{:fork:}, depending on your -preferences. Of course @code{:fork:} comes in -particularly handy in testing or -debugging @code{cvs} and the remote protocol. -Specifically, we avoid all of the network-related -setup/configuration, timeouts, and authentication -inherent in the other remote access methods but still -create a connection which uses the remote protocol. - -To connect using the @code{fork} method, use -@samp{:fork:} and the pathname to your local -repository. For example: - -@example -cvs -d :fork:/usr/local/cvsroot checkout foo -@end example - -@cindex CVS_SERVER, and :fork: -As with @code{:ext:}, the server is called @samp{cvs} -by default, or the value of the @code{CVS_SERVER} -environment variable. - -@c --------------------------------------------------------------------- -@node Read-only access -@section Read-only repository access -@cindex Read-only repository access -@cindex readers (admin file) -@cindex writers (admin file) - - It is possible to grant read-only repository -access to people using the password-authenticated -server (@pxref{Password authenticated}). (The -other access methods do not have explicit support for -read-only users because those methods all assume login -access to the repository machine anyway, and therefore -the user can do whatever local file permissions allow -her to do.) - - A user who has read-only access can do only -those @sc{cvs} operations which do not modify the -repository, except for certain ``administrative'' files -(such as lock files and the history file). It may be -desirable to use this feature in conjunction with -user-aliasing (@pxref{Password authentication server}). - -Unlike with previous versions of @sc{cvs}, read-only -users should be able merely to read the repository, and -not to execute programs on the server or otherwise gain -unexpected levels of access. Or to be more accurate, -the @emph{known} holes have been plugged. Because this -feature is new and has not received a comprehensive -security audit, you should use whatever level of -caution seems warranted given your attitude concerning -security. - - There are two ways to specify read-only access -for a user: by inclusion, and by exclusion. - - "Inclusion" means listing that user -specifically in the @file{$CVSROOT/CVSROOT/readers} -file, which is simply a newline-separated list of -users. Here is a sample @file{readers} file: - -@example -melissa -splotnik -jrandom -@end example - -@noindent - (Don't forget the newline after the last user.) - - "Exclusion" means explicitly listing everyone -who has @emph{write} access---if the file - -@example -$CVSROOT/CVSROOT/writers -@end example - -@noindent -exists, then only -those users listed in it have write access, and -everyone else has read-only access (of course, even the -read-only users still need to be listed in the -@sc{cvs} @file{passwd} file). The -@file{writers} file has the same format as the -@file{readers} file. - - Note: if your @sc{cvs} @file{passwd} -file maps cvs users onto system users (@pxref{Password -authentication server}), make sure you deny or grant -read-only access using the @emph{cvs} usernames, not -the system usernames. That is, the @file{readers} and -@file{writers} files contain cvs usernames, which may -or may not be the same as system usernames. - - Here is a complete description of the server's -behavior in deciding whether to grant read-only or -read-write access: - - If @file{readers} exists, and this user is -listed in it, then she gets read-only access. Or if -@file{writers} exists, and this user is NOT listed in -it, then she also gets read-only access (this is true -even if @file{readers} exists but she is not listed -there). Otherwise, she gets full read-write access. - - Of course there is a conflict if the user is -listed in both files. This is resolved in the more -conservative way, it being better to protect the -repository too much than too little: such a user gets -read-only access. - -@node Server temporary directory -@section Temporary directories for the server -@cindex Temporary directories, and server -@cindex Server, temporary directories - -While running, the @sc{cvs} server creates temporary -directories. They are named - -@example -cvs-serv@var{pid} -@end example - -@noindent -where @var{pid} is the process identification number of -the server. -They are located in the directory specified by -the @samp{-T} global option (@pxref{Global options}), -the @code{TMPDIR} environment variable (@pxref{Environment variables}), -or, failing that, @file{/tmp}. - -In most cases the server will remove the temporary -directory when it is done, whether it finishes normally -or abnormally. However, there are a few cases in which -the server does not or cannot remove the temporary -directory, for example: - -@itemize @bullet -@item -If the server aborts due to an internal server error, -it may preserve the directory to aid in debugging - -@item -If the server is killed in a way that it has no way of -cleaning up (most notably, @samp{kill -KILL} on unix). - -@item -If the system shuts down without an orderly shutdown, -which tells the server to clean up. -@end itemize - -In cases such as this, you will need to manually remove -the @file{cvs-serv@var{pid}} directories. As long as -there is no server running with process identification -number @var{pid}, it is safe to do so. - -@c --------------------------------------------------------------------- -@node Starting a new project -@chapter Starting a project with CVS -@cindex Starting a project with CVS -@cindex Creating a project - -@comment --moduledb-- -Because renaming files and moving them between -directories is somewhat inconvenient, the first thing -you do when you start a new project should be to think -through your file organization. It is not impossible -to rename or move files, but it does increase the -potential for confusion and @sc{cvs} does have some -quirks particularly in the area of renaming -directories. @xref{Moving files}. - -What to do next depends on the situation at hand. - -@menu -* Setting up the files:: Getting the files into the repository -* Defining the module:: How to make a module of the files -@end menu -@c -- File permissions! - -@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@node Setting up the files -@section Setting up the files - -The first step is to create the files inside the repository. This can -be done in a couple of different ways. - -@c -- The contributed scripts -@menu -* From files:: This method is useful with old projects - where files already exists. -* From other version control systems:: Old projects where you want to - preserve history from another system. -* From scratch:: Creating a directory tree from scratch. -@end menu - -@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -@node From files -@subsection Creating a directory tree from a number of files -@cindex Importing files - -When you begin using @sc{cvs}, you will probably already have several -projects that can be -put under @sc{cvs} control. In these cases the easiest way is to use the -@code{import} command. An example is probably the easiest way to -explain how to use it. If the files you want to install in -@sc{cvs} reside in @file{@var{wdir}}, and you want them to appear in the -repository as @file{$CVSROOT/yoyodyne/@var{rdir}}, you can do this: - -@example -$ cd @var{wdir} -$ cvs import -m "Imported sources" yoyodyne/@var{rdir} yoyo start -@end example - -Unless you supply a log message with the @samp{-m} -flag, @sc{cvs} starts an editor and prompts for a -message. The string @samp{yoyo} is a @dfn{vendor tag}, -and @samp{start} is a @dfn{release tag}. They may fill -no purpose in this context, but since @sc{cvs} requires -them they must be present. @xref{Tracking sources}, for -more information about them. - -You can now verify that it worked, and remove your -original source directory. -@c FIXME: Need to say more about "verify that it -@c worked". What should the user look for in the output -@c from "diff -r"? - -@example -$ cd .. -$ cvs checkout yoyodyne/@var{rdir} # @r{Explanation below} -$ diff -r @var{wdir} yoyodyne/@var{rdir} -$ rm -r @var{wdir} -@end example - -@noindent -Erasing the original sources is a good idea, to make sure that you do -not accidentally edit them in @var{wdir}, bypassing @sc{cvs}. -Of course, it would be wise to make sure that you have -a backup of the sources before you remove them. - -The @code{checkout} command can either take a module -name as argument (as it has done in all previous -examples) or a path name relative to @code{$CVSROOT}, -as it did in the example above. - -It is a good idea to check that the permissions -@sc{cvs} sets on the directories inside @code{$CVSROOT} -are reasonable, and that they belong to the proper -groups. @xref{File permissions}. - -If some of the files you want to import are binary, you -may want to use the wrappers features to specify which -files are binary and which are not. @xref{Wrappers}. - -@c The node name is too long, but I am having trouble -@c thinking of something more concise. -@node From other version control systems -@subsection Creating Files From Other Version Control Systems -@cindex Importing files, from other version control systems - -If you have a project which you are maintaining with -another version control system, such as @sc{rcs}, you -may wish to put the files from that project into -@sc{cvs}, and preserve the revision history of the -files. - -@table @asis -@cindex RCS, importing files from -@item From RCS -If you have been using @sc{rcs}, find the @sc{rcs} -files---usually a file named @file{foo.c} will have its -@sc{rcs} file in @file{RCS/foo.c,v} (but it could be -other places; consult the @sc{rcs} documentation for -details). Then create the appropriate directories in -@sc{cvs} if they do not already exist. Then copy the -files into the appropriate directories in the @sc{cvs} -repository (the name in the repository must be the name -of the source file with @samp{,v} added; the files go -directly in the appropriate directory of the repository, -not in an @file{RCS} subdirectory). This is one of the -few times when it is a good idea to access the @sc{cvs} -repository directly, rather than using @sc{cvs} -commands. Then you are ready to check out a new -working directory. -@c Someday there probably should be a "cvs import -t -@c rcs" or some such. It could even create magic -@c branches. It could also do something about the case -@c where the RCS file had a (non-magic) "0" branch. - -The @sc{rcs} file should not be locked when you move it -into @sc{cvs}; if it is, @sc{cvs} will have trouble -letting you operate on it. -@c What is the easiest way to unlock your files if you -@c have them locked? Especially if you have a lot of them? -@c This is a CVS bug/misfeature; importing RCS files -@c should ignore whether they are locked and leave them in -@c an unlocked state. Yet another reason for a separate -@c "import RCS file" command. - -@c How many is "many"? Or do they just import RCS files? -@item From another version control system -Many version control systems have the ability to export -@sc{rcs} files in the standard format. If yours does, -export the @sc{rcs} files and then follow the above -instructions. - -Failing that, probably your best bet is to write a -script that will check out the files one revision at a -time using the command line interface to the other -system, and then check the revisions into @sc{cvs}. -The @file{sccs2rcs} script mentioned below may be a -useful example to follow. - -@cindex SCCS, importing files from -@item From SCCS -There is a script in the @file{contrib} directory of -the @sc{cvs} source distribution called @file{sccs2rcs} -which converts @sc{sccs} files to @sc{rcs} files. -Note: you must run it on a machine which has both -@sc{sccs} and @sc{rcs} installed, and like everything -else in contrib it is unsupported (your mileage may -vary). - -@cindex PVCS, importing files from -@item From PVCS -There is a script in the @file{contrib} directory of -the @sc{cvs} source distribution called @file{pvcs_to_rcs} -which converts @sc{pvcs} archives to @sc{rcs} files. -You must run it on a machine which has both -@sc{pvcs} and @sc{rcs} installed, and like everything -else in contrib it is unsupported (your mileage may -vary). See the comments in the script for details. -@end table -@c CMZ and/or PATCHY were systems that were used in the -@c high energy physics community (especially for -@c CERNLIB). CERN has replaced them with CVS, but the -@c CAR format seems to live on as a way to submit -@c changes. There is a program car2cvs which converts -@c but I'm not sure where one gets a copy. -@c Not sure it is worth mentioning here, since it would -@c appear to affect only one particular community. -@c Best page for more information is: -@c http://wwwcn1.cern.ch/asd/cvs/index.html -@c See also: -@c http://ecponion.cern.ch/ecpsa/cernlib.html - -@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -@node From scratch -@subsection Creating a directory tree from scratch - -@c Also/instead should be documenting -@c $ cvs co -l . -@c $ mkdir tc -@c $ cvs add tc -@c $ cd tc -@c $ mkdir man -@c $ cvs add man -@c etc. -@c Using import to create the directories only is -@c probably a somewhat confusing concept. -For a new project, the easiest thing to do is probably -to create an empty directory structure, like this: - -@example -$ mkdir tc -$ mkdir tc/man -$ mkdir tc/testing -@end example - -After that, you use the @code{import} command to create -the corresponding (empty) directory structure inside -the repository: - -@example -$ cd tc -$ cvs import -m "Created directory structure" yoyodyne/@var{dir} yoyo start -@end example - -This will add yoyodyne/@var{dir} as a directory under -@code{$CVSROOT}. - -Use @code{checkout} to get the new project. Then, use @code{add} -to add files (and new directories) as needed. - -@example -$ cd .. -$ cvs co yoyodyne/@var{dir} -@end example - -Check that the permissions @sc{cvs} sets on the -directories inside @code{$CVSROOT} are reasonable. - -@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@node Defining the module -@section Defining the module -@cindex Defining a module -@cindex Editing the modules file -@cindex Module, defining -@cindex Modules file, changing - -The next step is to define the module in the -@file{modules} file. This is not strictly necessary, -but modules can be convenient in grouping together -related files and directories. - -In simple cases these steps are sufficient to define a module. - -@enumerate -@item -Get a working copy of the modules file. - -@example -$ cvs checkout CVSROOT/modules -$ cd CVSROOT -@end example - -@item -Edit the file and insert a line that defines the module. @xref{Intro -administrative files}, for an introduction. @xref{modules}, for a full -description of the modules file. You can use the -following line to define the module @samp{tc}: - -@example -tc yoyodyne/tc -@end example - -@item -Commit your changes to the modules file. - -@example -$ cvs commit -m "Added the tc module." modules -@end example - -@item -Release the modules module. - -@example -$ cd .. -$ cvs release -d CVSROOT -@end example -@end enumerate - -@c --------------------------------------------------------------------- -@node Revisions -@chapter Revisions - -For many uses of @sc{cvs}, one doesn't need to worry -too much about revision numbers; @sc{cvs} assigns -numbers such as @code{1.1}, @code{1.2}, and so on, and -that is all one needs to know. However, some people -prefer to have more knowledge and control concerning -how @sc{cvs} assigns revision numbers. - -If one wants to keep track of a set of revisions -involving more than one file, such as which revisions -went into a particular release, one uses a @dfn{tag}, -which is a symbolic revision which can be assigned to a -numeric revision in each file. - -@menu -* Revision numbers:: The meaning of a revision number -* Versions revisions releases:: Terminology used in this manual -* Assigning revisions:: Assigning revisions -* Tags:: Tags--Symbolic revisions -* Tagging the working directory:: The cvs tag command -* Tagging by date/tag:: The cvs rtag command -* Modifying tags:: Adding, renaming, and deleting tags -* Tagging add/remove:: Tags with adding and removing files -* Sticky tags:: Certain tags are persistent -@end menu - -@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@node Revision numbers -@section Revision numbers -@cindex Revision numbers -@cindex Revision tree -@cindex Linear development -@cindex Number, revision- -@cindex Decimal revision number -@cindex Branch number -@cindex Number, branch - -Each version of a file has a unique @dfn{revision -number}. Revision numbers look like @samp{1.1}, -@samp{1.2}, @samp{1.3.2.2} or even @samp{1.3.2.2.4.5}. -A revision number always has an even number of -period-separated decimal integers. By default revision -1.1 is the first revision of a file. Each successive -revision is given a new number by increasing the -rightmost number by one. The following figure displays -a few revisions, with newer revisions to the right. - -@example - +-----+ +-----+ +-----+ +-----+ +-----+ - ! 1.1 !----! 1.2 !----! 1.3 !----! 1.4 !----! 1.5 ! - +-----+ +-----+ +-----+ +-----+ +-----+ -@end example - -It is also possible to end up with numbers containing -more than one period, for example @samp{1.3.2.2}. Such -revisions represent revisions on branches -(@pxref{Branching and merging}); such revision numbers -are explained in detail in @ref{Branches and -revisions}. - -@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@node Versions revisions releases -@section Versions, revisions and releases -@cindex Revisions, versions and releases -@cindex Versions, revisions and releases -@cindex Releases, revisions and versions - -A file can have several versions, as described above. -Likewise, a software product can have several versions. -A software product is often given a version number such -as @samp{4.1.1}. - -Versions in the first sense are called @dfn{revisions} -in this document, and versions in the second sense are -called @dfn{releases}. To avoid confusion, the word -@dfn{version} is almost never used in this document. - -@node Assigning revisions -@section Assigning revisions - -@c We avoid the "major revision" terminology. It seems -@c like jargon. Hopefully "first number" is clear enough. -By default, @sc{cvs} will assign numeric revisions by -leaving the first number the same and incrementing the -second number. For example, @code{1.1}, @code{1.2}, -@code{1.3}, etc. - -When adding a new file, the second number will always -be one and the first number will equal the highest -first number of any file in that directory. For -example, the current directory contains files whose -highest numbered revisions are @code{1.7}, @code{3.1}, -and @code{4.12}, then an added file will be given the -numeric revision @code{4.1}. -(When using client/server @sc{cvs}, -only files that are actually sent to the server are considered.) - -@c This is sort of redundant with something we said a -@c while ago. Somewhere we need a better way of -@c introducing how the first number can be anything -@c except "1", perhaps. Also I don't think this -@c presentation is clear on why we are discussing releases -@c and first numbers of numeric revisions in the same -@c breath. -Normally there is no reason to care -about the revision numbers---it is easier to treat them -as internal numbers that @sc{cvs} maintains, and tags -provide a better way to distinguish between things like -release 1 versus release 2 of your product -(@pxref{Tags}). However, if you want to set the -numeric revisions, the @samp{-r} option to @code{cvs -commit} can do that. The @samp{-r} option implies the -@samp{-f} option, in the sense that it causes the -files to be committed even if they are not modified. - -For example, to bring all your files up to -revision 3.0 (including those that haven't changed), -you might invoke: - -@example -$ cvs commit -r 3.0 -@end example - -Note that the number you specify with @samp{-r} must be -larger than any existing revision number. That is, if -revision 3.0 exists, you cannot @samp{cvs commit --r 1.3}. If you want to maintain several releases in -parallel, you need to use a branch (@pxref{Branching and merging}). - -@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@node Tags -@section Tags--Symbolic revisions -@cindex Tags - -The revision numbers live a life of their own. They -need not have anything at all to do with the release -numbers of your software product. Depending -on how you use @sc{cvs} the revision numbers might change several times -between two releases. As an example, some of the -source files that make up @sc{rcs} 5.6 have the following -revision numbers: -@cindex RCS revision numbers - -@example -ci.c 5.21 -co.c 5.9 -ident.c 5.3 -rcs.c 5.12 -rcsbase.h 5.11 -rcsdiff.c 5.10 -rcsedit.c 5.11 -rcsfcmp.c 5.9 -rcsgen.c 5.10 -rcslex.c 5.11 -rcsmap.c 5.2 -rcsutil.c 5.10 -@end example - -@cindex tag, command, introduction -@cindex Tag, symbolic name -@cindex Symbolic name (tag) -@cindex Name, symbolic (tag) -@cindex HEAD, as reserved tag name -@cindex BASE, as reserved tag name -You can use the @code{tag} command to give a symbolic name to a -certain revision of a file. You can use the @samp{-v} flag to the -@code{status} command to see all tags that a file has, and -which revision numbers they represent. Tag names must -start with an uppercase or lowercase letter and can -contain uppercase and lowercase letters, digits, -@samp{-}, and @samp{_}. The two tag names @code{BASE} -and @code{HEAD} are reserved for use by @sc{cvs}. It -is expected that future names which are special to -@sc{cvs} will be specially named, for example by -starting with @samp{.}, rather than being named analogously to -@code{BASE} and @code{HEAD}, to avoid conflicts with -actual tag names. -@c Including a character such as % or = has also been -@c suggested as the naming convention for future -@c special tag names. Starting with . is nice because -@c that is not a legal tag name as far as RCS is concerned. -@c FIXME: CVS actually accepts quite a few characters -@c in tag names, not just the ones documented above -@c (see RCS_check_tag). RCS -@c defines legitimate tag names by listing illegal -@c characters rather than legal ones. CVS is said to lose its -@c mind if you try to use "/" (try making such a tag sticky -@c and using "cvs status" client/server--see remote -@c protocol format for entries line for probable cause). -@c TODO: The testsuite -@c should test for whatever are documented above as -@c officially-OK tag names, and CVS should at least reject -@c characters that won't work, like "/". - -You'll want to choose some convention for naming tags, -based on information such as the name of the program -and the version number of the release. For example, -one might take the name of the program, immediately -followed by the version number with @samp{.} changed to -@samp{-}, so that @sc{cvs} 1.9 would be tagged with the name -@code{cvs1-9}. If you choose a consistent convention, -then you won't constantly be guessing whether a tag is -@code{cvs-1-9} or @code{cvs1_9} or what. You might -even want to consider enforcing your convention in the -@file{taginfo} file (@pxref{taginfo}). -@c Might be nice to say more about using taginfo this -@c way, like giving an example, or pointing out any particular -@c issues which arise. - -@cindex Adding a tag -@cindex Tag, example -The following example shows how you can add a tag to a -file. The commands must be issued inside your working -directory. That is, you should issue the -command in the directory where @file{backend.c} -resides. - -@example -$ cvs tag rel-0-4 backend.c -T backend.c -$ cvs status -v backend.c -=================================================================== -File: backend.c Status: Up-to-date - - Version: 1.4 Tue Dec 1 14:39:01 1992 - RCS Version: 1.4 /u/cvsroot/yoyodyne/tc/backend.c,v - Sticky Tag: (none) - Sticky Date: (none) - Sticky Options: (none) - - Existing Tags: - rel-0-4 (revision: 1.4) - -@end example - -For a complete summary of the syntax of @code{cvs tag}, -including the various options, see @ref{Invoking CVS}. - -There is seldom reason to tag a file in isolation. A more common use is -to tag all the files that constitute a module with the same tag at -strategic points in the development life-cycle, such as when a release -is made. - -@example -$ cvs tag rel-1-0 . -cvs tag: Tagging . -T Makefile -T backend.c -T driver.c -T frontend.c -T parser.c -@end example - -@noindent -(When you give @sc{cvs} a directory as argument, it generally applies the -operation to all the files in that directory, and (recursively), to any -subdirectories that it may contain. @xref{Recursive behavior}.) - -@cindex Retrieving an old revision using tags -@cindex Tag, retrieving old revisions -The @code{checkout} command has a flag, @samp{-r}, that lets you check out -a certain revision of a module. This flag makes it easy to -retrieve the sources that make up release 1.0 of the module @samp{tc} at -any time in the future: - -@example -$ cvs checkout -r rel-1-0 tc -@end example - -@noindent -This is useful, for instance, if someone claims that there is a bug in -that release, but you cannot find the bug in the current working copy. - -You can also check out a module as it was at any given date. -@xref{checkout options}. When specifying @samp{-r} to -any of these commands, you will need beware of sticky -tags; see @ref{Sticky tags}. - -When you tag more than one file with the same tag you -can think about the tag as "a curve drawn through a -matrix of filename vs.@: revision number." Say we have 5 -files with the following revisions: - -@example -@group - file1 file2 file3 file4 file5 - - 1.1 1.1 1.1 1.1 /--1.1* <-*- TAG - 1.2*- 1.2 1.2 -1.2*- - 1.3 \- 1.3*- 1.3 / 1.3 - 1.4 \ 1.4 / 1.4 - \-1.5*- 1.5 - 1.6 -@end group -@end example - -At some time in the past, the @code{*} versions were tagged. -You can think of the tag as a handle attached to the curve -drawn through the tagged revisions. When you pull on -the handle, you get all the tagged revisions. Another -way to look at it is that you "sight" through a set of -revisions that is "flat" along the tagged revisions, -like this: - -@example -@group - file1 file2 file3 file4 file5 - - 1.1 - 1.2 - 1.1 1.3 _ - 1.1 1.2 1.4 1.1 / - 1.2*----1.3*----1.5*----1.2*----1.1 (--- <--- Look here - 1.3 1.6 1.3 \_ - 1.4 1.4 - 1.5 -@end group -@end example - -@node Tagging the working directory -@section Specifying what to tag from the working directory - -@cindex tag (subcommand) -The example in the previous section demonstrates one of -the most common ways to choose which revisions to tag. -Namely, running the @code{cvs tag} command without -arguments causes @sc{cvs} to select the revisions which -are checked out in the current working directory. For -example, if the copy of @file{backend.c} in working -directory was checked out from revision 1.4, then -@sc{cvs} will tag revision 1.4. Note that the tag is -applied immediately to revision 1.4 in the repository; -tagging is not like modifying a file, or other -operations in which one first modifies the working -directory and then runs @code{cvs commit} to transfer -that modification to the repository. - -One potentially surprising aspect of the fact that -@code{cvs tag} operates on the repository is that you -are tagging the checked-in revisions, which may differ -from locally modified files in your working directory. -If you want to avoid doing this by mistake, specify the -@samp{-c} option to @code{cvs tag}. If there are any -locally modified files, @sc{cvs} will abort with an -error before it tags any files: - -@example -$ cvs tag -c rel-0-4 -cvs tag: backend.c is locally modified -cvs [tag aborted]: correct the above errors first! -@end example - -@node Tagging by date/tag -@section Specifying what to tag by date or revision -@cindex rtag (subcommand) - -The @code{cvs rtag} command tags the repository as of a -certain date or time (or can be used to tag the latest -revision). @code{rtag} works directly on the -repository contents (it requires no prior checkout and -does not look for a working directory). - -The following options specify which date or revision to -tag. See @ref{Common options}, for a complete -description of them. - -@table @code -@item -D @var{date} -Tag the most recent revision no later than @var{date}. - -@item -f -Only useful with the @samp{-D @var{date}} or @samp{-r @var{tag}} -flags. If no matching revision is found, use the most -recent revision (instead of ignoring the file). - -@item -r @var{tag} -Only tag those files that contain existing tag @var{tag}. -@end table - -The @code{cvs tag} command also allows one to specify -files by revision or date, using the same @samp{-r}, -@samp{-D}, and @samp{-f} options. However, this -feature is probably not what you want. The reason is -that @code{cvs tag} chooses which files to tag based on -the files that exist in the working directory, rather -than the files which existed as of the given tag/date. -Therefore, you are generally better off using @code{cvs -rtag}. The exceptions might be cases like: - -@example -cvs tag -r 1.4 backend.c -@end example - -@node Modifying tags -@section Deleting, moving, and renaming tags - -@c Also see: -@c "How do I move or rename a magic branch tag?" -@c in the FAQ (I think the issues it talks about still -@c apply, but this could use some sanity.sh work). - -Normally one does not modify tags. They exist in order -to record the history of the repository and so deleting -them or changing their meaning would, generally, not be -what you want. - -However, there might be cases in which one uses a tag -temporarily or accidentally puts one in the wrong -place. Therefore, one might delete, move, or rename a -tag. - -@noindent -@strong{WARNING: The commands in this section are -dangerous; they permanently discard historical -information and it can be difficult or impossible to -recover from errors. If you are a @sc{cvs} -administrator, you may consider restricting these -commands with the @file{taginfo} file (@pxref{taginfo}).} - -@cindex Deleting tags -@cindex Deleting branch tags -@cindex Removing tags -@cindex Removing branch tags -@cindex Tags, deleting -@cindex Branch tags, deleting -To delete a tag, specify the @samp{-d} option to either -@code{cvs tag} or @code{cvs rtag}. For example: - -@example -cvs rtag -d rel-0-4 tc -@end example - -@noindent -deletes the non-branch tag @code{rel-0-4} from the module @code{tc}. -In the event that branch tags are encountered within the repository -with the given name, a warning message will be issued and the branch -tag will not be deleted. If you are absolutely certain you know what -you are doing, the @code{-B} option may be specified to allow deletion -of branch tags. In that case, any non-branch tags encountered will -trigger warnings and will not be deleted. - -@noindent -@strong{WARNING: Moving branch tags is very dangerous! If you think -you need the @code{-B} option, think again and ask your @sc{cvs} -administrator about it (if that isn't you). There is almost certainly -another way to accomplish what you want to accomplish.} - -@cindex Moving tags -@cindex Moving branch tags -@cindex Tags, moving -@cindex Branch tags, moving -When we say @dfn{move} a tag, we mean to make the same -name point to different revisions. For example, the -@code{stable} tag may currently point to revision 1.4 -of @file{backend.c} and perhaps we want to make it -point to revision 1.6. To move a non-branch tag, specify the -@samp{-F} option to either @code{cvs tag} or @code{cvs -rtag}. For example, the task just mentioned might be -accomplished as: - -@example -cvs tag -r 1.6 -F stable backend.c -@end example - -@noindent -If any branch tags are encountered in the repository -with the given name, a warning is issued and the branch -tag is not disturbed. If you are absolutely certain you -wish to move the branch tag, the @code{-B} option may be specified. -In that case, non-branch tags encountered with the given -name are ignored with a warning message. - -@noindent -@strong{WARNING: Moving branch tags is very dangerous! If you think you -need the @code{-B} option, think again and ask your @sc{cvs} -administrator about it (if that isn't you). There is almost certainly -another way to accomplish what you want to accomplish.} - -@cindex Renaming tags -@cindex Tags, renaming -When we say @dfn{rename} a tag, we mean to make a -different name point to the same revisions as the old -tag. For example, one may have misspelled the tag name -and want to correct it (hopefully before others are -relying on the old spelling). To rename a tag, first -create a new tag using the @samp{-r} option to -@code{cvs rtag}, and then delete the old name. (Caution: -this method will not work with branch tags.) -This leaves the new tag on exactly the -same files as the old tag. For example: - -@example -cvs rtag -r old-name-0-4 rel-0-4 tc -cvs rtag -d old-name-0-4 tc -@end example - -@node Tagging add/remove -@section Tagging and adding and removing files - -The subject of exactly how tagging interacts with -adding and removing files is somewhat obscure; for the -most part @sc{cvs} will keep track of whether files -exist or not without too much fussing. By default, -tags are applied to only files which have a revision -corresponding to what is being tagged. Files which did -not exist yet, or which were already removed, simply -omit the tag, and @sc{cvs} knows to treat the absence -of a tag as meaning that the file didn't exist as of -that tag. - -However, this can lose a small amount of information. -For example, suppose a file was added and then removed. -Then, if the tag is missing for that file, there is no -way to know whether the tag refers to the time before -the file was added, or the time after it was removed. -If you specify the @samp{-r} option to @code{cvs rtag}, -then @sc{cvs} tags the files which have been removed, -and thereby avoids this problem. For example, one -might specify @code{-r HEAD} to tag the head. - -On the subject of adding and removing files, the -@code{cvs rtag} command has a @samp{-a} option which -means to clear the tag from removed files that would -not otherwise be tagged. For example, one might -specify this option in conjunction with @samp{-F} when -moving a tag. If one moved a tag without @samp{-a}, -then the tag in the removed files might still refer to -the old revision, rather than reflecting the fact that -the file had been removed. I don't think this is -necessary if @samp{-r} is specified, as noted above. - -@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@node Sticky tags -@section Sticky tags -@cindex Sticky tags -@cindex Tags, sticky - -@c A somewhat related issue is per-directory sticky -@c tags (see comment at CVS/Tag in node Working -@c directory storage); we probably want to say -@c something like "you can set a sticky tag for only -@c some files, but you don't want to" or some such. - -Sometimes a working copy's revision has extra data -associated with it, for example it might be on a branch -(@pxref{Branching and merging}), or restricted to -versions prior to a certain date by @samp{checkout -D} -or @samp{update -D}. Because this data persists -- -that is, it applies to subsequent commands in the -working copy -- we refer to it as @dfn{sticky}. - -Most of the time, stickiness is an obscure aspect of -@sc{cvs} that you don't need to think about. However, -even if you don't want to use the feature, you may need -to know @emph{something} about sticky tags (for -example, how to avoid them!). - -You can use the @code{status} command to see if any -sticky tags or dates are set: - -@example -$ cvs status driver.c -=================================================================== -File: driver.c Status: Up-to-date - - Version: 1.7.2.1 Sat Dec 5 19:35:03 1992 - RCS Version: 1.7.2.1 /u/cvsroot/yoyodyne/tc/driver.c,v - Sticky Tag: rel-1-0-patches (branch: 1.7.2) - Sticky Date: (none) - Sticky Options: (none) - -@end example - -@cindex Resetting sticky tags -@cindex Sticky tags, resetting -@cindex Deleting sticky tags -The sticky tags will remain on your working files until -you delete them with @samp{cvs update -A}. The -@samp{-A} option merges local changes into the version of the -file from the head of the trunk, removing any sticky tags, -dates, or options (other than sticky @samp{-k} options on locally -modified files). See @ref{update} for more on the operation -of @code{cvs update}. - -@cindex Sticky date -The most common use of sticky tags is to identify which -branch one is working on, as described in -@ref{Accessing branches}. However, non-branch -sticky tags have uses as well. For example, -suppose that you want to avoid updating your working -directory, to isolate yourself from possibly -destabilizing changes other people are making. You -can, of course, just refrain from running @code{cvs -update}. But if you want to avoid updating only a -portion of a larger tree, then sticky tags can help. -If you check out a certain revision (such as 1.4) it -will become sticky. Subsequent @code{cvs update} -commands will -not retrieve the latest revision until you reset the -tag with @code{cvs update -A}. Likewise, use of the -@samp{-D} option to @code{update} or @code{checkout} -sets a @dfn{sticky date}, which, similarly, causes that -date to be used for future retrievals. - -People often want to retrieve an old version of -a file without setting a sticky tag. This can -be done with the @samp{-p} option to @code{checkout} or -@code{update}, which sends the contents of the file to -standard output. For example: -@example -$ cvs update -p -r 1.1 file1 >file1 -=================================================================== -Checking out file1 -RCS: /tmp/cvs-sanity/cvsroot/first-dir/Attic/file1,v -VERS: 1.1 -*************** -$ -@end example - -However, this isn't the easiest way, if you are asking -how to undo a previous checkin (in this example, put -@file{file1} back to the way it was as of revision -1.1). In that case you are better off using the -@samp{-j} option to @code{update}; for further -discussion see @ref{Merging two revisions}. - -@c --------------------------------------------------------------------- -@node Branching and merging -@chapter Branching and merging -@cindex Branching -@cindex Merging -@cindex Copying changes -@cindex Main trunk and branches -@cindex Revision tree, making branches -@cindex Branches, copying changes between -@cindex Changes, copying between branches -@cindex Modifications, copying between branches - -@sc{cvs} allows you to isolate changes onto a separate -line of development, known as a @dfn{branch}. When you -change files on a branch, those changes do not appear -on the main trunk or other branches. - -Later you can move changes from one branch to another -branch (or the main trunk) by @dfn{merging}. Merging -involves first running @code{cvs update -j}, to merge -the changes into the working directory. -You can then commit that revision, and thus effectively -copy the changes onto another branch. - -@menu -* Branches motivation:: What branches are good for -* Creating a branch:: Creating a branch -* Accessing branches:: Checking out and updating branches -* Branches and revisions:: Branches are reflected in revision numbers -* Magic branch numbers:: Magic branch numbers -* Merging a branch:: Merging an entire branch -* Merging more than once:: Merging from a branch several times -* Merging two revisions:: Merging differences between two revisions -* Merging adds and removals:: What if files are added or removed? -* Merging and keywords:: Avoiding conflicts due to keyword substitution -@end menu - -@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@node Branches motivation -@section What branches are good for -@cindex Branches motivation -@cindex What branches are good for -@cindex Motivation for branches - -@c FIXME: this node mentions one way to use branches, -@c but it is by no means the only way. For example, -@c the technique of committing a new feature on a branch, -@c until it is ready for the main trunk. The whole -@c thing is generally speaking more akin to the -@c "Revision management" node although it isn't clear to -@c me whether policy matters should be centralized or -@c distributed throughout the relevant sections. -Suppose that release 1.0 of tc has been made. You are continuing to -develop tc, planning to create release 1.1 in a couple of months. After a -while your customers start to complain about a fatal bug. You check -out release 1.0 (@pxref{Tags}) and find the bug -(which turns out to have a trivial fix). However, the current revision -of the sources are in a state of flux and are not expected to be stable -for at least another month. There is no way to make a -bug fix release based on the newest sources. - -The thing to do in a situation like this is to create a @dfn{branch} on -the revision trees for all the files that make up -release 1.0 of tc. You can then make -modifications to the branch without disturbing the main trunk. When the -modifications are finished you can elect to either incorporate them on -the main trunk, or leave them on the branch. - -@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@node Creating a branch -@section Creating a branch -@cindex Creating a branch -@cindex Branch, creating a -@cindex tag, creating a branch using -@cindex rtag, creating a branch using - -You can create a branch with @code{tag -b}; for -example, assuming you're in a working copy: - -@example -$ cvs tag -b rel-1-0-patches -@end example - -@c FIXME: we should be more explicit about the value of -@c having a tag on the branchpoint. For example -@c "cvs tag rel-1-0-patches-branchpoint" before -@c the "cvs tag -b". This points out that -@c rel-1-0-patches is a pretty awkward name for -@c this example (more so than for the rtag example -@c below). - -This splits off a branch based on the current revisions -in the working copy, assigning that branch the name -@samp{rel-1-0-patches}. - -It is important to understand that branches get created -in the repository, not in the working copy. Creating a -branch based on current revisions, as the above example -does, will @emph{not} automatically switch the working -copy to be on the new branch. For information on how -to do that, see @ref{Accessing branches}. - -You can also create a branch without reference to any -working copy, by using @code{rtag}: - -@example -$ cvs rtag -b -r rel-1-0 rel-1-0-patches tc -@end example - -@samp{-r rel-1-0} says that this branch should be -rooted at the revision that -corresponds to the tag @samp{rel-1-0}. It need not -be the most recent revision -- it's often useful to -split a branch off an old revision (for example, when -fixing a bug in a past release otherwise known to be -stable). - -As with @samp{tag}, the @samp{-b} flag tells -@code{rtag} to create a branch (rather than just a -symbolic revision name). Note that the numeric -revision number that matches @samp{rel-1-0} will -probably be different from file to file. - -So, the full effect of the command is to create a new -branch -- named @samp{rel-1-0-patches} -- in module -@samp{tc}, rooted in the revision tree at the point tagged -by @samp{rel-1-0}. - -@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@node Accessing branches -@section Accessing branches -@cindex Check out a branch -@cindex Retrieve a branch -@cindex Access a branch -@cindex Identifying a branch -@cindex Branch, check out -@cindex Branch, retrieving -@cindex Branch, accessing -@cindex Branch, identifying - -You can retrieve a branch in one of two ways: by -checking it out fresh from the repository, or by -switching an existing working copy over to the branch. - -To check out a branch from the repository, invoke -@samp{checkout} with the @samp{-r} flag, followed by -the tag name of the branch (@pxref{Creating a branch}): - -@example -$ cvs checkout -r rel-1-0-patches tc -@end example - -Or, if you already have a working copy, you can switch -it to a given branch with @samp{update -r}: - -@example -$ cvs update -r rel-1-0-patches tc -@end example - -@noindent -or equivalently: - -@example -$ cd tc -$ cvs update -r rel-1-0-patches -@end example - -It does not matter if the working copy was originally -on the main trunk or on some other branch -- the above -command will switch it to the named branch. And -similarly to a regular @samp{update} command, -@samp{update -r} merges any changes you have made, -notifying you of conflicts where they occur. - -Once you have a working copy tied to a particular -branch, it remains there until you tell it otherwise. -This means that changes checked in from the working -copy will add new revisions on that branch, while -leaving the main trunk and other branches unaffected. - -@cindex Branches, sticky -To find out what branch a working copy is on, you can -use the @samp{status} command. In its output, look for -the field named @samp{Sticky tag} (@pxref{Sticky tags}) --- that's @sc{cvs}'s way of telling you the branch, if -any, of the current working files: - -@example -$ cvs status -v driver.c backend.c -=================================================================== -File: driver.c Status: Up-to-date - - Version: 1.7 Sat Dec 5 18:25:54 1992 - RCS Version: 1.7 /u/cvsroot/yoyodyne/tc/driver.c,v - Sticky Tag: rel-1-0-patches (branch: 1.7.2) - Sticky Date: (none) - Sticky Options: (none) - - Existing Tags: - rel-1-0-patches (branch: 1.7.2) - rel-1-0 (revision: 1.7) - -=================================================================== -File: backend.c Status: Up-to-date - - Version: 1.4 Tue Dec 1 14:39:01 1992 - RCS Version: 1.4 /u/cvsroot/yoyodyne/tc/backend.c,v - Sticky Tag: rel-1-0-patches (branch: 1.4.2) - Sticky Date: (none) - Sticky Options: (none) - - Existing Tags: - rel-1-0-patches (branch: 1.4.2) - rel-1-0 (revision: 1.4) - rel-0-4 (revision: 1.4) - -@end example - -Don't be confused by the fact that the branch numbers -for each file are different (@samp{1.7.2} and -@samp{1.4.2} respectively). The branch tag is the -same, @samp{rel-1-0-patches}, and the files are -indeed on the same branch. The numbers simply reflect -the point in each file's revision history at which the -branch was made. In the above example, one can deduce -that @samp{driver.c} had been through more changes than -@samp{backend.c} before this branch was created. - -See @ref{Branches and revisions} for details about how -branch numbers are constructed. - -@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@node Branches and revisions -@section Branches and revisions -@cindex Branch number -@cindex Number, branch -@cindex Revision numbers (branches) - -Ordinarily, a file's revision history is a linear -series of increments (@pxref{Revision numbers}): - -@example - +-----+ +-----+ +-----+ +-----+ +-----+ - ! 1.1 !----! 1.2 !----! 1.3 !----! 1.4 !----! 1.5 ! - +-----+ +-----+ +-----+ +-----+ +-----+ -@end example - -However, @sc{cvs} is not limited to linear development. The -@dfn{revision tree} can be split into @dfn{branches}, -where each branch is a self-maintained line of -development. Changes made on one branch can easily be -moved back to the main trunk. - -Each branch has a @dfn{branch number}, consisting of an -odd number of period-separated decimal integers. The -branch number is created by appending an integer to the -revision number where the corresponding branch forked -off. Having branch numbers allows more than one branch -to be forked off from a certain revision. - -@need 3500 -All revisions on a branch have revision numbers formed -by appending an ordinal number to the branch number. -The following figure illustrates branching with an -example. - -@example -@c This example used to have a 1.2.2.4 revision, which -@c might help clarify that development can continue on -@c 1.2.2. Might be worth reinstating if it can be done -@c without overfull hboxes. -@group - +-------------+ - Branch 1.2.2.3.2 -> ! 1.2.2.3.2.1 ! - / +-------------+ - / - / - +---------+ +---------+ +---------+ -Branch 1.2.2 -> _! 1.2.2.1 !----! 1.2.2.2 !----! 1.2.2.3 ! - / +---------+ +---------+ +---------+ - / - / -+-----+ +-----+ +-----+ +-----+ +-----+ -! 1.1 !----! 1.2 !----! 1.3 !----! 1.4 !----! 1.5 ! <- The main trunk -+-----+ +-----+ +-----+ +-----+ +-----+ - ! - ! - ! +---------+ +---------+ +---------+ -Branch 1.2.4 -> +---! 1.2.4.1 !----! 1.2.4.2 !----! 1.2.4.3 ! - +---------+ +---------+ +---------+ - -@end group -@end example - -@c -- However, at least for me the figure is not enough. I suggest more -@c -- text to accompany it. "A picture is worth a thousand words", so you -@c -- have to make sure the reader notices the couple of hundred words -@c -- *you* had in mind more than the others! - -@c -- Why an even number of segments? This section implies that this is -@c -- how the main trunk is distinguished from branch roots, but you never -@c -- explicitly say that this is the purpose of the [by itself rather -@c -- surprising] restriction to an even number of segments. - -The exact details of how the branch number is -constructed is not something you normally need to be -concerned about, but here is how it works: When -@sc{cvs} creates a branch number it picks the first -unused even integer, starting with 2. So when you want -to create a branch from revision 6.4 it will be -numbered 6.4.2. All branch numbers ending in a zero -(such as 6.4.0) are used internally by @sc{cvs} -(@pxref{Magic branch numbers}). The branch 1.1.1 has a -special meaning. @xref{Tracking sources}. - -@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@node Magic branch numbers -@section Magic branch numbers - -@c Want xref to here from "log"? - -This section describes a @sc{cvs} feature called -@dfn{magic branches}. For most purposes, you need not -worry about magic branches; @sc{cvs} handles them for -you. However, they are visible to you in certain -circumstances, so it may be useful to have some idea of -how it works. - -Externally, branch numbers consist of an odd number of -dot-separated decimal integers. @xref{Revision -numbers}. That is not the whole truth, however. For -efficiency reasons @sc{cvs} sometimes inserts an extra 0 -in the second rightmost position (1.2.4 becomes -1.2.0.4, 8.9.10.11.12 becomes 8.9.10.11.0.12 and so -on). - -@sc{cvs} does a pretty good job at hiding these so -called magic branches, but in a few places the hiding -is incomplete: - -@itemize @bullet -@ignore -@c This is in ignore as I'm taking their word for it, -@c that this was fixed -@c a long time ago. But before deleting this -@c entirely, I'd rather verify it (and add a test -@c case to the testsuite). -@item -The magic branch can appear in the output from -@code{cvs status} in vanilla @sc{cvs} 1.3. This is -fixed in @sc{cvs} 1.3-s2. - -@end ignore -@item -The magic branch number appears in the output from -@code{cvs log}. -@c What output should appear instead? - -@item -You cannot specify a symbolic branch name to @code{cvs -admin}. - -@end itemize - -@c Can CVS do this automatically the first time -@c you check something in to that branch? Should -@c it? -You can use the @code{admin} command to reassign a -symbolic name to a branch the way @sc{rcs} expects it -to be. If @code{R4patches} is assigned to the branch -1.4.2 (magic branch number 1.4.0.2) in file -@file{numbers.c} you can do this: - -@example -$ cvs admin -NR4patches:1.4.2 numbers.c -@end example - -It only works if at least one revision is already -committed on the branch. Be very careful so that you -do not assign the tag to the wrong number. (There is -no way to see how the tag was assigned yesterday). - -@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@node Merging a branch -@section Merging an entire branch -@cindex Merging a branch -@cindex -j (merging branches) - -You can merge changes made on a branch into your working copy by giving -the @samp{-j @var{branchname}} flag to the @code{update} subcommand. With one -@samp{-j @var{branchname}} option it merges the changes made between the -greatest common ancestor (GCA) of the branch and the destination revision (in -the simple case below the GCA is the point where the branch forked) and the -newest revision on that branch into your working copy. - -@cindex Join -The @samp{-j} stands for ``join''. - -@cindex Branch merge example -@cindex Example, branch merge -@cindex Merge, branch example -Consider this revision tree: - -@example -+-----+ +-----+ +-----+ +-----+ -! 1.1 !----! 1.2 !----! 1.3 !----! 1.4 ! <- The main trunk -+-----+ +-----+ +-----+ +-----+ - ! - ! - ! +---------+ +---------+ -Branch R1fix -> +---! 1.2.2.1 !----! 1.2.2.2 ! - +---------+ +---------+ -@end example - -@noindent -The branch 1.2.2 has been given the tag (symbolic name) @samp{R1fix}. The -following example assumes that the module @samp{mod} contains only one -file, @file{m.c}. - -@example -$ cvs checkout mod # @r{Retrieve the latest revision, 1.4} - -$ cvs update -j R1fix m.c # @r{Merge all changes made on the branch,} - # @r{i.e. the changes between revision 1.2} - # @r{and 1.2.2.2, into your working copy} - # @r{of the file.} - -$ cvs commit -m "Included R1fix" # @r{Create revision 1.5.} -@end example - -A conflict can result from a merge operation. If that -happens, you should resolve it before committing the -new revision. @xref{Conflicts example}. - -If your source files contain keywords (@pxref{Keyword substitution}), -you might be getting more conflicts than strictly necessary. See -@ref{Merging and keywords}, for information on how to avoid this. - -The @code{checkout} command also supports the @samp{-j @var{branchname}} flag. The -same effect as above could be achieved with this: - -@example -$ cvs checkout -j R1fix mod -$ cvs commit -m "Included R1fix" -@end example - -It should be noted that @code{update -j @var{tagname}} will also work but may -not produce the desired result. @xref{Merging adds and removals}, for more. - -@node Merging more than once -@section Merging from a branch several times - -Continuing our example, the revision tree now looks -like this: - -@example -+-----+ +-----+ +-----+ +-----+ +-----+ -! 1.1 !----! 1.2 !----! 1.3 !----! 1.4 !----! 1.5 ! <- The main trunk -+-----+ +-----+ +-----+ +-----+ +-----+ - ! * - ! * - ! +---------+ +---------+ -Branch R1fix -> +---! 1.2.2.1 !----! 1.2.2.2 ! - +---------+ +---------+ -@end example - -@noindent -where the starred line represents the merge from the -@samp{R1fix} branch to the main trunk, as just -discussed. - -Now suppose that development continues on the -@samp{R1fix} branch: - -@example -+-----+ +-----+ +-----+ +-----+ +-----+ -! 1.1 !----! 1.2 !----! 1.3 !----! 1.4 !----! 1.5 ! <- The main trunk -+-----+ +-----+ +-----+ +-----+ +-----+ - ! * - ! * - ! +---------+ +---------+ +---------+ -Branch R1fix -> +---! 1.2.2.1 !----! 1.2.2.2 !----! 1.2.2.3 ! - +---------+ +---------+ +---------+ -@end example - -@noindent -and then you want to merge those new changes onto the -main trunk. If you just use the @code{cvs update -j -R1fix m.c} command again, @sc{cvs} will attempt to -merge again the changes which you have already merged, -which can have undesirable side effects. - -So instead you need to specify that you only want to -merge the changes on the branch which have not yet been -merged into the trunk. To do that you specify two -@samp{-j} options, and @sc{cvs} merges the changes from -the first revision to the second revision. For -example, in this case the simplest way would be - -@example -cvs update -j 1.2.2.2 -j R1fix m.c # @r{Merge changes from 1.2.2.2 to the} - # @r{head of the R1fix branch} -@end example - -The problem with this is that you need to specify the -1.2.2.2 revision manually. A slightly better approach -might be to use the date the last merge was done: - -@example -cvs update -j R1fix:yesterday -j R1fix m.c -@end example - -Better yet, tag the R1fix branch after every merge into -the trunk, and then use that tag for subsequent merges: - -@example -cvs update -j merged_from_R1fix_to_trunk -j R1fix m.c -@end example - -@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@node Merging two revisions -@section Merging differences between any two revisions -@cindex Merging two revisions -@cindex Revisions, merging differences between -@cindex Differences, merging - -With two @samp{-j @var{revision}} flags, the @code{update} -(and @code{checkout}) command can merge the differences -between any two revisions into your working file. - -@cindex Undoing a change -@cindex Removing a change -@example -$ cvs update -j 1.5 -j 1.3 backend.c -@end example - -@noindent -will undo all changes made between revision -1.3 and 1.5. Note the order of the revisions! - -If you try to use this option when operating on -multiple files, remember that the numeric revisions will -probably be very different between the various files. -You almost always use symbolic -tags rather than revision numbers when operating on -multiple files. - -@cindex Restoring old version of removed file -@cindex Resurrecting old version of dead file -Specifying two @samp{-j} options can also undo file -removals or additions. For example, suppose you have -a file -named @file{file1} which existed as revision 1.1, and -you then removed it (thus adding a dead revision 1.2). -Now suppose you want to add it again, with the same -contents it had previously. Here is how to do it: - -@example -$ cvs update -j 1.2 -j 1.1 file1 -U file1 -$ cvs commit -m test -Checking in file1; -/tmp/cvs-sanity/cvsroot/first-dir/file1,v <-- file1 -new revision: 1.3; previous revision: 1.2 -done -$ -@end example - -@node Merging adds and removals -@section Merging can add or remove files - -If the changes which you are merging involve removing -or adding some files, @code{update -j} will reflect -such additions or removals. - -@c FIXME: This example needs a lot more explanation. -@c We also need other examples for some of the other -@c cases (not all--there are too many--as long as we present a -@c coherent general principle). -For example: -@example -cvs update -A -touch a b c -cvs add a b c ; cvs ci -m "added" a b c -cvs tag -b branchtag -cvs update -r branchtag -touch d ; cvs add d -rm a ; cvs rm a -cvs ci -m "added d, removed a" -cvs update -A -cvs update -jbranchtag -@end example - -After these commands are executed and a @samp{cvs commit} is done, -file @file{a} will be removed and file @file{d} added in the main branch. -@c (which was determined by trying it) - -Note that using a single static tag (@samp{-j @var{tagname}}) -rather than a dynamic tag (@samp{-j @var{branchname}}) to merge -changes from a branch will usually not remove files which were removed on the -branch since @sc{cvs} does not automatically add static tags to dead revisions. -The exception to this rule occurs when -a static tag has been attached to a dead revision manually. Use the branch tag -to merge all changes from the branch or use two static tags as merge endpoints -to be sure that all intended changes are propagated in the merge. - -@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@node Merging and keywords -@section Merging and keywords -@cindex Merging, and keyword substitution -@cindex Keyword substitution, and merging -@cindex -j (merging branches), and keyword substitution -@cindex -kk, to avoid conflicts during a merge - -If you merge files containing keywords (@pxref{Keyword -substitution}), you will normally get numerous -conflicts during the merge, because the keywords are -expanded differently in the revisions which you are -merging. - -Therefore, you will often want to specify the -@samp{-kk} (@pxref{Substitution modes}) switch to the -merge command line. By substituting just the name of -the keyword, not the expanded value of that keyword, -this option ensures that the revisions which you are -merging will be the same as each other, and avoid -spurious conflicts. - -For example, suppose you have a file like this: - -@example - +---------+ - _! 1.1.2.1 ! <- br1 - / +---------+ - / - / -+-----+ +-----+ -! 1.1 !----! 1.2 ! -+-----+ +-----+ -@end example - -@noindent -and your working directory is currently on the trunk -(revision 1.2). Then you might get the following -results from a merge: - -@example -$ cat file1 -key $@splitrcskeyword{Revision}: 1.2 $ -. . . -$ cvs update -j br1 -U file1 -RCS file: /cvsroot/first-dir/file1,v -retrieving revision 1.1 -retrieving revision 1.1.2.1 -Merging differences between 1.1 and 1.1.2.1 into file1 -rcsmerge: warning: conflicts during merge -$ cat file1 -@asis{}<<<<<<< file1 -key $@splitrcskeyword{Revision}: 1.2 $ -@asis{}======= -key $@splitrcskeyword{Revision}: 1.1.2.1 $ -@asis{}>>>>>>> 1.1.2.1 -. . . -@end example - -What happened was that the merge tried to merge the -differences between 1.1 and 1.1.2.1 into your working -directory. So, since the keyword changed from -@code{Revision: 1.1} to @code{Revision: 1.1.2.1}, -@sc{cvs} tried to merge that change into your working -directory, which conflicted with the fact that your -working directory had contained @code{Revision: 1.2}. - -Here is what happens if you had used @samp{-kk}: - -@example -$ cat file1 -key $@splitrcskeyword{Revision}: 1.2 $ -. . . -$ cvs update -kk -j br1 -U file1 -RCS file: /cvsroot/first-dir/file1,v -retrieving revision 1.1 -retrieving revision 1.1.2.1 -Merging differences between 1.1 and 1.1.2.1 into file1 -$ cat file1 -key $@splitrcskeyword{Revision}$ -. . . -@end example - -What is going on here is that revision 1.1 and 1.1.2.1 -both expand as plain @code{Revision}, and therefore -merging the changes between them into the working -directory need not change anything. Therefore, there -is no conflict. - -There is, however, one major caveat with using -@samp{-kk} on merges. Namely, it overrides whatever -keyword expansion mode @sc{cvs} would normally have -used. In particular, this is a problem if the mode had -been @samp{-kb} for a binary file. Therefore, if your -repository contains binary files, you will need to deal -with the conflicts rather than using @samp{-kk}. - -@ignore -The following seems rather confusing, possibly buggy, -and in general, in need of much more thought before it -is a recommended technique. For one thing, does it -apply on Windows as well as on Unix? - -Unchanged binary files will undergo the same keyword substitution -but will not be checked in on a subsequent -@code{cvs commit}. Be aware that binary files containing keyword -strings which are present in or below the working directory -will most likely remain corrupt until repaired, however. A simple -@code{cvs update -A} is sufficient to fix these otherwise unaltered binary files -if the merge is being done to the main branch but -this must be done after the merge has been committed or the merge itself -will be lost. - -For Example: -@example -cvs update -Akk -jbranchtag -cvs commit -cvs update -A -@end example - -@noindent -will update the current directory from the main trunk of the -repository, substituting the base keyword strings for keywords, -and merge changes made on the branch @samp{branchtag} into the new -work files, performing the same keyword substitution on that file set before -comparing the two sets. The final @code{cvs update -A} will restore any -corrupted binary files as well as resetting the sticky @samp{-kk} tags which -were present on the files in and below the working directory. -Unfortunately, this doesn't work as well with an arbitrary branch tag, as the -@samp{-r @var{branchtag}} switch does not reset the sticky @samp{-kk} -switches attached to the working files as @samp{-A} does. The workaround -for this is to release the working directory after the merge has been -committed and check it out again. -@end ignore - -As a result of using @samp{-kk} during the merge, each file examined by the -update will have @samp{-kk} set as sticky options. Running @code{update -A} -will clear the sticky options on unmodified files, but it will not clear -the sticky options on modified files. To get back to the default keyword -substitution for modified files, you must commit the results of the merge -and then run @code{update -A}. - -@c --------------------------------------------------------------------- -@node Recursive behavior -@chapter Recursive behavior -@cindex Recursive (directory descending) -@cindex Directory, descending -@cindex Descending directories -@cindex Subdirectories - -Almost all of the subcommands of @sc{cvs} work -recursively when you specify a directory as an -argument. For instance, consider this directory -structure: - -@example - @code{$HOME} - | - +--@t{tc} - | | - +--@t{CVS} - | (internal @sc{cvs} files) - +--@t{Makefile} - +--@t{backend.c} - +--@t{driver.c} - +--@t{frontend.c} - +--@t{parser.c} - +--@t{man} - | | - | +--@t{CVS} - | | (internal @sc{cvs} files) - | +--@t{tc.1} - | - +--@t{testing} - | - +--@t{CVS} - | (internal @sc{cvs} files) - +--@t{testpgm.t} - +--@t{test2.t} -@end example - -@noindent -If @file{tc} is the current working directory, the -following is true: - -@itemize @bullet -@item -@samp{cvs update testing} is equivalent to - -@example -cvs update testing/testpgm.t testing/test2.t -@end example - -@item -@samp{cvs update testing man} updates all files in the -subdirectories - -@item -@samp{cvs update .} or just @samp{cvs update} updates -all files in the @code{tc} directory -@end itemize - -If no arguments are given to @code{update} it will -update all files in the current working directory and -all its subdirectories. In other words, @file{.} is a -default argument to @code{update}. This is also true -for most of the @sc{cvs} subcommands, not only the -@code{update} command. - -The recursive behavior of the @sc{cvs} subcommands can be -turned off with the @samp{-l} option. -Conversely, the @samp{-R} option can be used to force recursion if -@samp{-l} is specified in @file{~/.cvsrc} (@pxref{~/.cvsrc}). - -@example -$ cvs update -l # @r{Don't update files in subdirectories} -@end example - -@c --------------------------------------------------------------------- -@node Adding and removing -@chapter Adding, removing, and renaming files and directories - -In the course of a project, one will often add new -files. Likewise with removing or renaming, or with -directories. The general concept to keep in mind in -all these cases is that instead of making an -irreversible change you want @sc{cvs} to record the -fact that a change has taken place, just as with -modifying an existing file. The exact mechanisms to do -this in @sc{cvs} vary depending on the situation. - -@menu -* Adding files:: Adding files -* Removing files:: Removing files -* Removing directories:: Removing directories -* Moving files:: Moving and renaming files -* Moving directories:: Moving and renaming directories -@end menu - -@node Adding files -@section Adding files to a directory -@cindex Adding files - -To add a new file to a directory, follow these steps. - -@itemize @bullet -@item -You must have a working copy of the directory. -@xref{Getting the source}. - -@item -Create the new file inside your working copy of the directory. - -@item -Use @samp{cvs add @var{filename}} to tell @sc{cvs} that you -want to version control the file. If the file contains -binary data, specify @samp{-kb} (@pxref{Binary files}). - -@item -Use @samp{cvs commit @var{filename}} to actually check -in the file into the repository. Other developers -cannot see the file until you perform this step. -@end itemize - -You can also use the @code{add} command to add a new -directory. -@c FIXCVS and/or FIXME: Adding a directory doesn't -@c require the commit step. This probably can be -@c considered a CVS bug, but it is possible we should -@c warn people since this behavior probably won't be -@c changing right away. - -Unlike most other commands, the @code{add} command is -not recursive. You have to explicitly name files and -directories that you wish to add to the repository. -However, each directory will need to be added -separately before you will be able to add new files -to those directories. - -@example -$ mkdir -p foo/bar -$ cp ~/myfile foo/bar/myfile -$ cvs add foo foo/bar -$ cvs add foo/bar/myfile -@end example - -@cindex add (subcommand) -@deffn Command {cvs add} [@code{-k} kflag] [@code{-m} message] files @dots{} - -Schedule @var{files} to be added to the repository. -The files or directories specified with @code{add} must -already exist in the current directory. To add a whole -new directory hierarchy to the source repository (for -example, files received from a third-party vendor), use -the @code{import} command instead. @xref{import}. - -The added files are not placed in the source repository -until you use @code{commit} to make the change -permanent. Doing an @code{add} on a file that was -removed with the @code{remove} command will undo the -effect of the @code{remove}, unless a @code{commit} -command intervened. @xref{Removing files}, for an -example. - -The @samp{-k} option specifies the default way that -this file will be checked out; for more information see -@ref{Substitution modes}. - -@c As noted in BUGS, -m is broken client/server (Nov -@c 96). Also see testsuite log2-* tests. -The @samp{-m} option specifies a description for the -file. This description appears in the history log (if -it is enabled, @pxref{history file}). It will also be -saved in the version history inside the repository when -the file is committed. The @code{log} command displays -this description. The description can be changed using -@samp{admin -t}. @xref{admin}. If you omit the -@samp{-m @var{description}} flag, an empty string will -be used. You will not be prompted for a description. -@end deffn - -For example, the following commands add the file -@file{backend.c} to the repository: - -@c This example used to specify -@c -m "Optimizer and code generation passes." -@c to the cvs add command, but that doesn't work -@c client/server (see log2 in sanity.sh). Should fix CVS, -@c but also seems strange to document things which -@c don't work... -@example -$ cvs add backend.c -$ cvs commit -m "Early version. Not yet compilable." backend.c -@end example - -When you add a file it is added only on the branch -which you are working on (@pxref{Branching and merging}). You can -later merge the additions to another branch if you want -(@pxref{Merging adds and removals}). -@c Should we mention that earlier versions of CVS -@c lacked this feature (1.3) or implemented it in a buggy -@c way (well, 1.8 had many bugs in cvs update -j)? -@c Should we mention the bug/limitation regarding a -@c file being a regular file on one branch and a directory -@c on another? -@c FIXME: This needs an example, or several, here or -@c elsewhere, for it to make much sense. -@c Somewhere we need to discuss the aspects of death -@c support which don't involve branching, I guess. -@c Like the ability to re-create a release from a tag. - -@c --------------------------------------------------------------------- -@node Removing files -@section Removing files -@cindex Removing files -@cindex Deleting files - -@c FIXME: this node wants to be split into several -@c smaller nodes. Could make these children of -@c "Adding and removing", probably (death support could -@c be its own section, for example, as could the -@c various bits about undoing mistakes in adding and -@c removing). -Directories change. New files are added, and old files -disappear. Still, you want to be able to retrieve an -exact copy of old releases. - -Here is what you can do to remove a file, -but remain able to retrieve old revisions: - -@itemize @bullet -@c FIXME: should probably be saying something about -@c having a working directory in the first place. -@item -Make sure that you have not made any uncommitted -modifications to the file. @xref{Viewing differences}, -for one way to do that. You can also use the -@code{status} or @code{update} command. If you remove -the file without committing your changes, you will of -course not be able to retrieve the file as it was -immediately before you deleted it. - -@item -Remove the file from your working copy of the directory. -You can for instance use @code{rm}. - -@item -Use @samp{cvs remove @var{filename}} to tell @sc{cvs} that -you really want to delete the file. - -@item -Use @samp{cvs commit @var{filename}} to actually -perform the removal of the file from the repository. -@end itemize - -@c FIXME: Somehow this should be linked in with a more -@c general discussion of death support. I don't know -@c whether we want to use the term "death support" or -@c not (we can perhaps get by without it), but we do -@c need to discuss the "dead" state in "cvs log" and -@c related subjects. The current discussion is -@c scattered around, and not xref'd to each other. -@c FIXME: I think this paragraph wants to be moved -@c later down, at least after the first example. -When you commit the removal of the file, @sc{cvs} -records the fact that the file no longer exists. It is -possible for a file to exist on only some branches and -not on others, or to re-add another file with the same -name later. @sc{cvs} will correctly create or not create -the file, based on the @samp{-r} and @samp{-D} options -specified to @code{checkout} or @code{update}. - -@c FIXME: This style seems to clash with how we -@c document things in general. -@cindex Remove (subcommand) -@deffn Command {cvs remove} [options] files @dots{} - -Schedule file(s) to be removed from the repository -(files which have not already been removed from the -working directory are not processed). This command -does not actually remove the file from the repository -until you commit the removal. For a full list of -options, see @ref{Invoking CVS}. -@end deffn - -Here is an example of removing several files: - -@example -$ cd test -$ rm *.c -$ cvs remove -cvs remove: Removing . -cvs remove: scheduling a.c for removal -cvs remove: scheduling b.c for removal -cvs remove: use 'cvs commit' to remove these files permanently -$ cvs ci -m "Removed unneeded files" -cvs commit: Examining . -cvs commit: Committing . -@end example - -As a convenience you can remove the file and @code{cvs -remove} it in one step, by specifying the @samp{-f} -option. For example, the above example could also be -done like this: - -@example -$ cd test -$ cvs remove -f *.c -cvs remove: scheduling a.c for removal -cvs remove: scheduling b.c for removal -cvs remove: use 'cvs commit' to remove these files permanently -$ cvs ci -m "Removed unneeded files" -cvs commit: Examining . -cvs commit: Committing . -@end example - -If you execute @code{remove} for a file, and then -change your mind before you commit, you can undo the -@code{remove} with an @code{add} command. -@ignore -@c is this worth saying or not? Somehow it seems -@c confusing to me. -Of course, -since you have removed your copy of file in the working -directory, @sc{cvs} does not necessarily bring back the -contents of the file from right before you executed -@code{remove}; instead it gets the file from the -repository again. -@end ignore - -@c FIXME: what if you change your mind after you commit -@c it? (answer is also "cvs add" but we don't say that...). -@c We need some index entries for thinks like "undoing -@c removal" too. - -@example -$ ls -CVS ja.h oj.c -$ rm oj.c -$ cvs remove oj.c -cvs remove: scheduling oj.c for removal -cvs remove: use 'cvs commit' to remove this file permanently -$ cvs add oj.c -U oj.c -cvs add: oj.c, version 1.1.1.1, resurrected -@end example - -If you realize your mistake before you run the -@code{remove} command you can use @code{update} to -resurrect the file: - -@example -$ rm oj.c -$ cvs update oj.c -cvs update: warning: oj.c was lost -U oj.c -@end example - -When you remove a file it is removed only on the branch -which you are working on (@pxref{Branching and merging}). You can -later merge the removals to another branch if you want -(@pxref{Merging adds and removals}). - -@node Removing directories -@section Removing directories -@cindex Removing directories -@cindex Directories, removing - -In concept, removing directories is somewhat similar to -removing files---you want the directory to not exist in -your current working directories, but you also want to -be able to retrieve old releases in which the directory -existed. - -The way that you remove a directory is to remove all -the files in it. You don't remove the directory -itself; there is no way to do that. -Instead you specify the @samp{-P} option to -@code{cvs update} or @code{cvs checkout}, -which will cause @sc{cvs} to remove empty -directories from working directories. -(Note that @code{cvs export} always removes empty directories.) -Probably the -best way to do this is to always specify @samp{-P}; if -you want an empty directory then put a dummy file (for -example @file{.keepme}) in it to prevent @samp{-P} from -removing it. - -@c I'd try to give a rationale for this, but I'm not -@c sure there is a particularly convincing one. What -@c we would _like_ is for CVS to do a better job of version -@c controlling whether directories exist, to eliminate the -@c need for -P and so that a file can be a directory in -@c one revision and a regular file in another. -Note that @samp{-P} is implied by the @samp{-r} or @samp{-D} -options of @code{checkout}. This way, -@sc{cvs} will be able to correctly create the directory -or not depending on whether the particular version you -are checking out contains any files in that directory. - -@c --------------------------------------------------------------------- -@node Moving files -@section Moving and renaming files -@cindex Moving files -@cindex Renaming files -@cindex Files, moving - -Moving files to a different directory or renaming them -is not difficult, but some of the ways in which this -works may be non-obvious. (Moving or renaming a -directory is even harder. @xref{Moving directories}.). - -The examples below assume that the file @var{old} is renamed to -@var{new}. - -@menu -* Outside:: The normal way to Rename -* Inside:: A tricky, alternative way -* Rename by copying:: Another tricky, alternative way -@end menu - -@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@node Outside -@subsection The Normal way to Rename - -@c More rename issues. Not sure whether these are -@c worth documenting; I'm putting them here because -@c it seems to be as good a place as any to try to -@c set down the issues. -@c * "cvs annotate" will annotate either the new -@c file or the old file; it cannot annotate _each -@c line_ based on whether it was last changed in the -@c new or old file. Unlike "cvs log", where the -@c consequences of having to select either the new -@c or old name seem fairly benign, this may be a -@c real advantage to having CVS know about renames -@c other than as a deletion and an addition. - -The normal way to move a file is to copy @var{old} to -@var{new}, and then issue the normal @sc{cvs} commands -to remove @var{old} from the repository, and add -@var{new} to it. -@c The following sentence is not true: one must cd into -@c the directory to run "cvs add". -@c (Both @var{old} and @var{new} could -@c contain relative paths, for example @file{foo/bar.c}). - -@example -$ mv @var{old} @var{new} -$ cvs remove @var{old} -$ cvs add @var{new} -$ cvs commit -m "Renamed @var{old} to @var{new}" @var{old} @var{new} -@end example - -This is the simplest way to move a file, it is not -error-prone, and it preserves the history of what was -done. Note that to access the history of the file you -must specify the old or the new name, depending on what -portion of the history you are accessing. For example, -@code{cvs log @var{old}} will give the log up until the -time of the rename. - -When @var{new} is committed its revision numbers will -start again, usually at 1.1, so if that bothers you, -use the @samp{-r rev} option to commit. For more -information see @ref{Assigning revisions}. - -@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@node Inside -@subsection Moving the history file - -This method is more dangerous, since it involves moving -files inside the repository. Read this entire section -before trying it out! - -@example -$ cd $CVSROOT/@var{dir} -$ mv @var{old},v @var{new},v -@end example - -@noindent -Advantages: - -@itemize @bullet -@item -The log of changes is maintained intact. - -@item -The revision numbers are not affected. -@end itemize - -@noindent -Disadvantages: - -@itemize @bullet -@item -Old releases cannot easily be fetched from the -repository. (The file will show up as @var{new} even -in revisions from the time before it was renamed). - -@item -There is no log information of when the file was renamed. - -@item -Nasty things might happen if someone accesses the history file -while you are moving it. Make sure no one else runs any of the @sc{cvs} -commands while you move it. -@end itemize - -@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@node Rename by copying -@subsection Copying the history file - -This way also involves direct modifications to the -repository. It is safe, but not without drawbacks. - -@example -# @r{Copy the @sc{rcs} file inside the repository} -$ cd $CVSROOT/@var{dir} -$ cp @var{old},v @var{new},v -# @r{Remove the old file} -$ cd ~/@var{dir} -$ rm @var{old} -$ cvs remove @var{old} -$ cvs commit @var{old} -# @r{Remove all tags from @var{new}} -$ cvs update @var{new} -$ cvs log @var{new} # @r{Remember the non-branch tag names} -$ cvs tag -d @var{tag1} @var{new} -$ cvs tag -d @var{tag2} @var{new} -@dots{} -@end example - -By removing the tags you will be able to check out old -revisions. - -@noindent -Advantages: - -@itemize @bullet -@item -@c FIXME: Is this true about -D now that we have death -@c support? See 5B.3 in the FAQ. -Checking out old revisions works correctly, as long as -you use @samp{-r@var{tag}} and not @samp{-D@var{date}} -to retrieve the revisions. - -@item -The log of changes is maintained intact. - -@item -The revision numbers are not affected. -@end itemize - -@noindent -Disadvantages: - -@itemize @bullet -@item -You cannot easily see the history of the file across the rename. - -@ignore -@c Is this true? I don't see how the revision numbers -@c _could_ start over, when new,v is just old,v with -@c the tags deleted. -@c If there is some need to reinstate this text, -@c it is "usually 1.1", not "1.0" and it needs an -@c xref to Assigning revisions -@item -Unless you use the @samp{-r rev} (@pxref{commit -options}) flag when @var{new} is committed its revision -numbers will start at 1.0 again. -@end ignore -@end itemize - -@c --------------------------------------------------------------------- -@node Moving directories -@section Moving and renaming directories -@cindex Moving directories -@cindex Renaming directories -@cindex Directories, moving - -The normal way to rename or move a directory is to -rename or move each file within it as described in -@ref{Outside}. Then check out with the @samp{-P} -option, as described in @ref{Removing directories}. - -If you really want to hack the repository to rename or -delete a directory in the repository, you can do it -like this: - -@enumerate -@item -Inform everyone who has a checked out copy of the directory that the -directory will be renamed. They should commit all their changes in all their -copies of the project containing the directory to be removed, and remove -all their working copies of said project, before you take the steps below. - -@item -Rename the directory inside the repository. - -@example -$ cd $CVSROOT/@var{parent-dir} -$ mv @var{old-dir} @var{new-dir} -@end example - -@item -Fix the @sc{cvs} administrative files, if necessary (for -instance if you renamed an entire module). - -@item -Tell everyone that they can check out again and continue -working. - -@end enumerate - -If someone had a working copy the @sc{cvs} commands will -cease to work for him, until he removes the directory -that disappeared inside the repository. - -It is almost always better to move the files in the -directory instead of moving the directory. If you move the -directory you are unlikely to be able to retrieve old -releases correctly, since they probably depend on the -name of the directories. - -@c --------------------------------------------------------------------- -@node History browsing -@chapter History browsing -@cindex History browsing -@cindex Traceability -@cindex Isolation - -@ignore -@c This is too long for an introduction (goal is -@c one 20x80 character screen), and also mixes up a -@c variety of issues (parallel development, history, -@c maybe even touches on process control). - -@c -- @quote{To lose ones history is to lose ones soul.} -@c -- /// -@c -- ///Those who cannot remember the past are condemned to repeat it. -@c -- /// -- George Santayana -@c -- /// - -@sc{cvs} tries to make it easy for a group of people to work -together. This is done in two ways: - -@itemize @bullet -@item -Isolation---You have your own working copy of the -source. You are not affected by modifications made by -others until you decide to incorporate those changes -(via the @code{update} command---@pxref{update}). - -@item -Traceability---When something has changed, you can -always see @emph{exactly} what changed. -@end itemize - -There are several features of @sc{cvs} that together lead -to traceability: - -@itemize @bullet -@item -Each revision of a file has an accompanying log -message. - -@item -All commits are optionally logged to a central history -database. - -@item -Logging information can be sent to a user-defined -program (@pxref{loginfo}). -@end itemize - -@c -- More text here. - -This chapter should talk about the history file, the -@code{log} command, the usefulness of ChangeLogs -even when you run @sc{cvs}, and things like that. - -@end ignore - -@c kind of lame, in a lot of ways the above text inside -@c the @ignore motivates this chapter better -Once you have used @sc{cvs} to store a version control -history---what files have changed when, how, and by -whom, there are a variety of mechanisms for looking -through the history. - -@c FIXME: should also be talking about how you look at -@c old revisions (e.g. "cvs update -p -r 1.2 foo.c"). -@menu -* log messages:: Log messages -* history database:: The history database -* user-defined logging:: User-defined logging -@end menu - -@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@node log messages -@section Log messages - -@c FIXME: @xref to place where we talk about how to -@c specify message to commit. -Whenever you commit a file you specify a log message. - -@c FIXME: bring the information here, and get rid of or -@c greatly shrink the "log" node. -To look through the log messages which have been -specified for every revision which has been committed, -use the @code{cvs log} command (@pxref{log}). - -@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@node history database -@section The history database - -@c FIXME: bring the information from the history file -@c and history nodes here. Rewrite it to be motivated -@c better (start out by clearly explaining what gets -@c logged in history, for example). -You can use the history file (@pxref{history file}) to -log various @sc{cvs} actions. To retrieve the -information from the history file, use the @code{cvs -history} command (@pxref{history}). - -Note: you can control what is logged to this file by using the -@samp{LogHistory} keyword in the @file{CVSROOT/config} file -(@pxref{config}). - -@c -@c The history database has many problems: -@c * It is very unclear what field means what. This -@c could be improved greatly by better documentation, -@c but there are still non-orthogonalities (for -@c example, tag does not record the "repository" -@c field but most records do). -@c * Confusion about files, directories, and modules. -@c Some commands record one, some record others. -@c * File removal is not logged. There is an 'R' -@c record type documented, but CVS never uses it. -@c * Tags are only logged for the "cvs rtag" command, -@c not "cvs tag". The fix for this is not completely -@c clear (see above about modules vs. files). -@c * Are there other cases of operations that are not -@c logged? One would hope for all changes to the -@c repository to be logged somehow (particularly -@c operations like tagging, "cvs admin -k", and other -@c operations which do not record a history that one -@c can get with "cvs log"). Operations on the working -@c directory, like export, get, and release, are a -@c second category also covered by the current "cvs -@c history". -@c * The history file does not record the options given -@c to a command. The most serious manifestation of -@c this is perhaps that it doesn't record whether a command -@c was recursive. It is not clear to me whether one -@c wants to log at a level very close to the command -@c line, as a sort of way of logging each command -@c (more or less), or whether one wants -@c to log more at the level of what was changed (or -@c something in between), but either way the current -@c information has pretty big gaps. -@c * Further details about a tag--like whether it is a -@c branch tag or, if a non-branch tag, which branch it -@c is on. One can find out this information about the -@c tag as it exists _now_, but if the tag has been -@c moved, one doesn't know what it was like at the time -@c the history record was written. -@c * Whether operating on a particular tag, date, or -@c options was implicit (sticky) or explicit. -@c -@c Another item, only somewhat related to the above, is a -@c way to control what is logged in the history file. -@c This is probably the only good way to handle -@c different people having different ideas about -@c information/space tradeoffs. -@c -@c It isn't really clear that it makes sense to try to -@c patch up the history file format as it exists now to -@c include all that stuff. It might be better to -@c design a whole new CVSROOT/nhistory file and "cvs -@c nhistory" command, or some such, or in some other -@c way trying to come up with a clean break from the -@c past, which can address the above concerns. Another -@c open question is how/whether this relates to -@c taginfo/loginfo/etc. - -@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@node user-defined logging -@section User-defined logging - -@c FIXME: probably should centralize this information -@c here, at least to some extent. Maybe by moving the -@c loginfo, etc., nodes here and replacing -@c the "user-defined logging" node with one node for -@c each method. -You can customize @sc{cvs} to log various kinds of -actions, in whatever manner you choose. These -mechanisms operate by executing a script at various -times. The script might append a message to a file -listing the information and the programmer who created -it, or send mail to a group of developers, or, perhaps, -post a message to a particular newsgroup. To log -commits, use the @file{loginfo} file (@pxref{loginfo}). -To log tags, use the @file{taginfo} file (@pxref{taginfo}). -@c FIXME: What is difference between doing it in the -@c modules file and using loginfo/taginfo? Why should -@c user use one or the other? -To log checkouts, exports, and tags, -respectively, you can also use the -@samp{-o}, @samp{-e}, and @samp{-t} options in the -modules file. For a more flexible way of giving -notifications to various users, which requires less in -the way of keeping centralized scripts up to date, use -the @code{cvs watch add} command (@pxref{Getting -Notified}); this command is useful even if you are not -using @code{cvs watch on}. - -@c --------------------------------------------------------------------- -@node Binary files -@chapter Handling binary files -@cindex Binary files - -The most common use for @sc{cvs} is to store text -files. With text files, @sc{cvs} can merge revisions, -display the differences between revisions in a -human-visible fashion, and other such operations. -However, if you are willing to give up a few of these -abilities, @sc{cvs} can store binary files. For -example, one might store a web site in @sc{cvs} -including both text files and binary images. - -@menu -* Binary why:: More details on issues with binary files -* Binary howto:: How to store them -@end menu - -@node Binary why -@section The issues with binary files - -While the need to manage binary files may seem obvious -if the files that you customarily work with are binary, -putting them into version control does present some -additional issues. - -One basic function of version control is to show the -differences between two revisions. For example, if -someone else checked in a new version of a file, you -may wish to look at what they changed and determine -whether their changes are good. For text files, -@sc{cvs} provides this functionality via the @code{cvs -diff} command. For binary files, it may be possible to -extract the two revisions and then compare them with a -tool external to @sc{cvs} (for example, word processing -software often has such a feature). If there is no -such tool, one must track changes via other mechanisms, -such as urging people to write good log messages, and -hoping that the changes they actually made were the -changes that they intended to make. - -Another ability of a version control system is the -ability to merge two revisions. For @sc{cvs} this -happens in two contexts. The first is when users make -changes in separate working directories -(@pxref{Multiple developers}). The second is when one -merges explicitly with the @samp{update -j} command -(@pxref{Branching and merging}). - -In the case of text -files, @sc{cvs} can merge changes made independently, -and signal a conflict if the changes conflict. With -binary files, the best that @sc{cvs} can do is present -the two different copies of the file, and leave it to -the user to resolve the conflict. The user may choose -one copy or the other, or may run an external merge -tool which knows about that particular file format, if -one exists. -Note that having the user merge relies primarily on the -user to not accidentally omit some changes, and thus is -potentially error prone. - -If this process is thought to be undesirable, the best -choice may be to avoid merging. To avoid the merges -that result from separate working directories, see the -discussion of reserved checkouts (file locking) in -@ref{Multiple developers}. To avoid the merges -resulting from branches, restrict use of branches. - -@node Binary howto -@section How to store binary files - -There are two issues with using @sc{cvs} to store -binary files. The first is that @sc{cvs} by default -converts line endings between the canonical form in -which they are stored in the repository (linefeed -only), and the form appropriate to the operating system -in use on the client (for example, carriage return -followed by line feed for Windows NT). - -The second is that a binary file might happen to -contain data which looks like a keyword (@pxref{Keyword -substitution}), so keyword expansion must be turned -off. - -@c FIXME: the third is that one can't do merges with -@c binary files. xref to Multiple Developers and the -@c reserved checkout issues. - -The @samp{-kb} option available with some @sc{cvs} -commands insures that neither line ending conversion -nor keyword expansion will be done. - -Here is an example of how you can create a new file -using the @samp{-kb} flag: - -@example -$ echo '$@splitrcskeyword{Id}$' > kotest -$ cvs add -kb -m"A test file" kotest -$ cvs ci -m"First checkin; contains a keyword" kotest -@end example - -If a file accidentally gets added without @samp{-kb}, -one can use the @code{cvs admin} command to recover. -For example: - -@example -$ echo '$@splitrcskeyword{Id}$' > kotest -$ cvs add -m"A test file" kotest -$ cvs ci -m"First checkin; contains a keyword" kotest -$ cvs admin -kb kotest -$ cvs update -A kotest -# @r{For non-unix systems:} -# @r{Copy in a good copy of the file from outside CVS} -$ cvs commit -m "make it binary" kotest -@end example - -@c Trying to describe this for both unix and non-unix -@c in the same description is very confusing. Might -@c want to split the two, or just ditch the unix "shortcut" -@c (unixheads don't do much with binary files, anyway). -@c This used to say "(Try the above example, and do a -@c @code{cat kotest} after every command)". But that -@c only really makes sense for the unix case. -When you check in the file @file{kotest} the file is -not preserved as a binary file, because you did not -check it in as a binary file. The @code{cvs -admin -kb} command sets the default keyword -substitution method for this file, but it does not -alter the working copy of the file that you have. If you need to -cope with line endings (that is, you are using -@sc{cvs} on a non-unix system), then you need to -check in a new copy of the file, as shown by the -@code{cvs commit} command above. -On unix, the @code{cvs update -A} command suffices. -@c FIXME: should also describe what the *other users* -@c need to do, if they have checked out copies which -@c have been corrupted by lack of -kb. I think maybe -@c "cvs update -kb" or "cvs -@c update -A" would suffice, although the user who -@c reported this suggested removing the file, manually -@c removing it from CVS/Entries, and then "cvs update" -(Note that you can use @code{cvs log} to determine the default keyword -substitution method for a file and @code{cvs status} to determine -the keyword substitution method for a working copy.) - -However, in using @code{cvs admin -k} to change the -keyword expansion, be aware that the keyword expansion -mode is not version controlled. This means that, for -example, that if you have a text file in old releases, -and a binary file with the same name in new releases, -@sc{cvs} provides no way to check out the file in text -or binary mode depending on what version you are -checking out. There is no good workaround for this -problem. - -You can also set a default for whether @code{cvs add} -and @code{cvs import} treat a file as binary based on -its name; for example you could say that files who -names end in @samp{.exe} are binary. @xref{Wrappers}. -There is currently no way to have @sc{cvs} detect -whether a file is binary based on its contents. The -main difficulty with designing such a feature is that -it is not clear how to distinguish between binary and -non-binary files, and the rules to apply would vary -considerably with the operating system. -@c For example, it would be good on MS-DOS-family OSes -@c for anything containing ^Z to be binary. Having -@c characters with the 8th bit set imply binary is almost -@c surely a bad idea in the context of ISO-8859-* and -@c other such character sets. On VMS or the Mac, we -@c could use the OS's file typing. This is a -@c commonly-desired feature, and something of this sort -@c may make sense. But there are a lot of pitfalls here. -@c -@c Another, probably better, way to tell is to read the -@c file in text mode, write it to a temp file in text -@c mode, and then do a binary mode compare of the two -@c files. If they differ, it is a binary file. This -@c might have problems on VMS (or some other system -@c with several different text modes), but in general -@c should be relatively portable. The only other -@c downside I can think of is that it would be fairly -@c slow, but that is perhaps a small price to pay for -@c not having your files corrupted. Another issue is -@c what happens if you import a text file with bare -@c linefeeds on Windows. Such files will show up on -@c Windows sometimes (I think some native windows -@c programs even write them, on occasion). Perhaps it -@c is reasonable to treat such files as binary; after -@c all it is something of a presumption to assume that -@c the user would want the linefeeds converted to CRLF. - -@c --------------------------------------------------------------------- -@node Multiple developers -@chapter Multiple developers -@cindex Multiple developers -@cindex Team of developers -@cindex File locking -@cindex Locking files -@cindex Working copy -@cindex Reserved checkouts -@cindex Unreserved checkouts -@cindex RCS-style locking - -When more than one person works on a software project -things often get complicated. Often, two people try to -edit the same file simultaneously. One solution, known -as @dfn{file locking} or @dfn{reserved checkouts}, is -to allow only one person to edit each file at a time. -This is the only solution with some version control -systems, including @sc{rcs} and @sc{sccs}. Currently -the usual way to get reserved checkouts with @sc{cvs} -is the @code{cvs admin -l} command (@pxref{admin -options}). This is not as nicely integrated into -@sc{cvs} as the watch features, described below, but it -seems that most people with a need for reserved -checkouts find it adequate. -@c Or "find it better than worrying about implementing -@c nicely integrated reserved checkouts" or ...? -It also may be possible to use the watches -features described below, together with suitable -procedures (not enforced by software), to avoid having -two people edit at the same time. - -@c Our unreserved checkout model might not -@c be quite the same as others. For example, I -@c think that some systems will tend to create a branch -@c in the case where CVS prints "up-to-date check failed". -@c It isn't clear to me whether we should try to -@c explore these subtleties; it could easily just -@c confuse people. -The default model with @sc{cvs} is known as -@dfn{unreserved checkouts}. In this model, developers -can edit their own @dfn{working copy} of a file -simultaneously. The first person that commits his -changes has no automatic way of knowing that another -has started to edit it. Others will get an error -message when they try to commit the file. They must -then use @sc{cvs} commands to bring their working copy -up to date with the repository revision. This process -is almost automatic. - -@c FIXME? should probably use the word "watch" here, to -@c tie this into the text below and above. -@sc{cvs} also supports mechanisms which facilitate -various kinds of communication, without actually -enforcing rules like reserved checkouts do. - -The rest of this chapter describes how these various -models work, and some of the issues involved in -choosing between them. - -@ignore -Here is a draft reserved checkout design or discussion -of the issues. This seems like as good a place as any -for this. - -Might want a cvs lock/cvs unlock--in which the names -differ from edit/unedit because the network must be up -for these to work. unedit gives an error if there is a -reserved checkout in place (so that people don't -accidentally leave locks around); unlock gives an error -if one is not in place (this is more arguable; perhaps -it should act like unedit in that case). - -On the other hand, might want it so that emacs, -scripts, etc., can get ready to edit a file without -having to know which model is in use. In that case we -would have a "cvs watch lock" (or .cvsrc?) (that is, -three settings, "on", "off", and "lock"). Having cvs -watch lock set would cause a get to record in the CVS -directory which model is in use, and cause "cvs edit" -to change behaviors. We'd want a way to query which -setting is in effect (this would be handy even if it is -only "on" or "off" as presently). If lock is in -effect, then commit would require a lock before -allowing a checkin; chmod wouldn't suffice (might be -debatable--see chmod comment below, in watches--but it -is the way people expect RCS to work and I can't think -of any significant downside. On the other hand, maybe -it isn't worth bothering, because people who are used -to RCS wouldn't think to use chmod anyway). - -Implementation: use file attributes or use RCS -locking. The former avoids more dependence on RCS -behaviors we will need to re-implement as we librarify -RCS, and makes it easier to import/export RCS files (in -that context, want to ignore the locker field). But -note that RCS locks are per-branch, which is the -correct behavior (this is also an issue for the "watch -on" features; they should be per-branch too). - -Here are a few more random notes about implementation -details, assuming "cvs watch lock" and - -CVS/Watched file? Or try to fit this into CVS/Entries somehow? -Cases: (1) file is checked out (unreserved or with watch on) by old -version of @sc{cvs}, now we do something with new one, (2) file is checked -out by new version, now we do something with old one. - -Remote protocol would have a "Watched" analogous to "Mode". Of course -it would apply to all Updated-like requests. How do we keep this -setting up to date? I guess that there wants to be a Watched request, -and the server would send a new one if it isn't up to date? (Ugh--hard -to implement and slows down "cvs -q update"--is there an easier way?) - -"cvs edit"--checks CVS/Watched, and if watch lock, then sends -"edit-lock" request. Which comes back with a Checked-in with -appropriate Watched (off, on, lock, locked, or some such?), or error -message if already locked. - -"cvs commit"--only will commit if off/on/locked. lock is not OK. - -Doc: -note that "cvs edit" must be connected to network if watch lock is in -effect. - -Talk about what to do if someone has locked a file and you want to -edit that file. (breaking locks, or lack thereof). - - -One other idea (which could work along with the -existing "cvs admin -l" reserved checkouts, as well as -the above): - -"cvs editors" could show who has the file locked, if -someone does. - -@end ignore - -@menu -* File status:: A file can be in several states -* Updating a file:: Bringing a file up-to-date -* Conflicts example:: An informative example -* Informing others:: To cooperate you must inform -* Concurrency:: Simultaneous repository access -* Watches:: Mechanisms to track who is editing files -* Choosing a model:: Reserved or unreserved checkouts? -@end menu - -@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@node File status -@section File status -@cindex File status -@cindex Status of a file - -@c Shouldn't this start with an example or something, -@c introducing the unreserved checkout model? Before we -@c dive into listing states? -Based on what operations you have performed on a -checked out file, and what operations others have -performed to that file in the repository, one can -classify a file in a number of states. The states, as -reported by the @code{status} command, are: - -@c The order of items is chosen to group logically -@c similar outputs together. -@c People who want alphabetical can use the index... -@table @asis -@cindex Up-to-date -@item Up-to-date -The file is identical with the latest revision in the -repository for the branch in use. -@c FIXME: should we clarify "in use"? The answer is -@c sticky tags, and trying to distinguish branch sticky -@c tags from non-branch sticky tags seems rather awkward -@c here. -@c FIXME: What happens with non-branch sticky tags? Is -@c a stuck file "Up-to-date" or "Needs checkout" or what? - -@item Locally Modified -@cindex Locally Modified -You have edited the file, and not yet committed your changes. - -@item Locally Added -@cindex Locally Added -You have added the file with @code{add}, and not yet -committed your changes. -@c There are many cases involving the file being -@c added/removed/modified in the working directory, and -@c added/removed/modified in the repository, which we -@c don't try to describe here. I'm not sure that "cvs -@c status" produces a non-confusing output in most of -@c those cases. - -@item Locally Removed -@cindex Locally Removed -You have removed the file with @code{remove}, and not yet -committed your changes. - -@item Needs Checkout -@cindex Needs Checkout -Someone else has committed a newer revision to the -repository. The name is slightly misleading; you will -ordinarily use @code{update} rather than -@code{checkout} to get that newer revision. - -@item Needs Patch -@cindex Needs Patch -@c See also newb-123j0 in sanity.sh (although that case -@c should probably be changed rather than documented). -Like Needs Checkout, but the @sc{cvs} server will send -a patch rather than the entire file. Sending a patch or -sending an entire file accomplishes the same thing. - -@item Needs Merge -@cindex Needs Merge -Someone else has committed a newer revision to the repository, and you -have also made modifications to the file. - -@item Unresolved Conflict -@cindex Unresolved Conflict -@c FIXCVS - This file status needs to be changed to some more informative -@c text that distinguishes it more clearly from each of the Locally Added, -@c File had conflicts on merge, and Unknown status types, but an exact and -@c succinct wording escapes me at the moment. -A file with the same name as this new file has been added to the repository -from a second workspace. This file will need to be moved out of the way -to allow an @code{update} to complete. - -@item File had conflicts on merge -@cindex File had conflicts on merge -@c is it worth saying that this message was "Unresolved -@c Conflict" in CVS 1.9 and earlier? I'm inclined to -@c think that is unnecessarily confusing to new users. -This is like Locally Modified, except that a previous -@code{update} command gave a conflict. If you have not -already done so, you need to -resolve the conflict as described in @ref{Conflicts example}. - -@item Unknown -@cindex Unknown -@sc{cvs} doesn't know anything about this file. For -example, you have created a new file and have not run -@code{add}. -@c -@c "Entry Invalid" and "Classify Error" are also in the -@c status.c. The latter definitely indicates a CVS bug -@c (should it be worded more like "internal error" so -@c people submit bug reports if they see it?). The former -@c I'm not as sure; I haven't tracked down whether/when it -@c appears in "cvs status" output. - -@end table - -To help clarify the file status, @code{status} also -reports the @code{Working revision} which is the -revision that the file in the working directory derives -from, and the @code{Repository revision} which is the -latest revision in the repository for the branch in -use. -@c FIXME: should we clarify "in use"? The answer is -@c sticky tags, and trying to distinguish branch sticky -@c tags from non-branch sticky tags seems rather awkward -@c here. -@c FIXME: What happens with non-branch sticky tags? -@c What is the Repository Revision there? See the -@c comment at vn_rcs in cvs.h, which is kind of -@c confused--we really need to document better what this -@c field contains. -@c Q: Should we document "New file!" and other such -@c outputs or are they self-explanatory? -@c FIXME: what about the date to the right of "Working -@c revision"? It doesn't appear with client/server and -@c seems unnecessary (redundant with "ls -l") so -@c perhaps it should be removed for non-client/server too? -@c FIXME: Need some examples. -@c FIXME: Working revision can also be something like -@c "-1.3" for a locally removed file. Not at all -@c self-explanatory (and it is possible that CVS should -@c be changed rather than documenting this). - -@c Would be nice to have an @example showing output -@c from cvs status, with comments showing the xref -@c where each part of the output is described. This -@c might fit in nicely if it is desirable to split this -@c node in two; one to introduce "cvs status" and one -@c to list each of the states. -The options to @code{status} are listed in -@ref{Invoking CVS}. For information on its @code{Sticky tag} -and @code{Sticky date} output, see @ref{Sticky tags}. -For information on its @code{Sticky options} output, -see the @samp{-k} option in @ref{update options}. - -You can think of the @code{status} and @code{update} -commands as somewhat complementary. You use -@code{update} to bring your files up to date, and you -can use @code{status} to give you some idea of what an -@code{update} would do (of course, the state of the -repository might change before you actually run -@code{update}). In fact, if you want a command to -display file status in a more brief format than is -displayed by the @code{status} command, you can invoke - -@cindex update, to display file status -@example -$ cvs -n -q update -@end example - -The @samp{-n} option means to not actually do the -update, but merely to display statuses; the @samp{-q} -option avoids printing the name of each directory. For -more information on the @code{update} command, and -these options, see @ref{Invoking CVS}. - -@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@node Updating a file -@section Bringing a file up to date -@cindex Bringing a file up to date -@cindex Updating a file -@cindex Merging a file -@cindex Update, introduction - -When you want to update or merge a file, use the @code{cvs update -d} -command. For files that are not up to date this is roughly equivalent -to a @code{checkout} command: the newest revision of the file is -extracted from the repository and put in your working directory. The -@code{-d} option, not necessary with @code{checkout}, tells @sc{cvs} -that you wish it to create directories added by other developers. - -Your modifications to a file are never lost when you -use @code{update}. If no newer revision exists, -running @code{update} has no effect. If you have -edited the file, and a newer revision is available, -@sc{cvs} will merge all changes into your working copy. - -For instance, imagine that you checked out revision 1.4 and started -editing it. In the meantime someone else committed revision 1.5, and -shortly after that revision 1.6. If you run @code{update} on the file -now, @sc{cvs} will incorporate all changes between revision 1.4 and 1.6 into -your file. - -@cindex Overlap -If any of the changes between 1.4 and 1.6 were made too -close to any of the changes you have made, an -@dfn{overlap} occurs. In such cases a warning is -printed, and the resulting file includes both -versions of the lines that overlap, delimited by -special markers. -@xref{update}, for a complete description of the -@code{update} command. - -@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@node Conflicts example -@section Conflicts example -@cindex Merge, an example -@cindex Example of merge -@cindex driver.c (merge example) - -Suppose revision 1.4 of @file{driver.c} contains this: - -@example -#include - -void main() -@{ - parse(); - if (nerr == 0) - gencode(); - else - fprintf(stderr, "No code generated.\n"); - exit(nerr == 0 ? 0 : 1); -@} -@end example - -@noindent -Revision 1.6 of @file{driver.c} contains this: - -@example -#include - -int main(int argc, - char **argv) -@{ - parse(); - if (argc != 1) - @{ - fprintf(stderr, "tc: No args expected.\n"); - exit(1); - @} - if (nerr == 0) - gencode(); - else - fprintf(stderr, "No code generated.\n"); - exit(!!nerr); -@} -@end example - -@noindent -Your working copy of @file{driver.c}, based on revision -1.4, contains this before you run @samp{cvs update}: -@c -- Really include "cvs"? - -@example -#include -#include - -void main() -@{ - init_scanner(); - parse(); - if (nerr == 0) - gencode(); - else - fprintf(stderr, "No code generated.\n"); - exit(nerr == 0 ? EXIT_SUCCESS : EXIT_FAILURE); -@} -@end example - -@noindent -You run @samp{cvs update}: -@c -- Really include "cvs"? - -@example -$ cvs update driver.c -RCS file: /usr/local/cvsroot/yoyodyne/tc/driver.c,v -retrieving revision 1.4 -retrieving revision 1.6 -Merging differences between 1.4 and 1.6 into driver.c -rcsmerge warning: overlaps during merge -cvs update: conflicts found in driver.c -C driver.c -@end example - -@noindent -@cindex Conflicts (merge example) -@sc{cvs} tells you that there were some conflicts. -Your original working file is saved unmodified in -@file{.#driver.c.1.4}. The new version of -@file{driver.c} contains this: - -@example -#include -#include - -int main(int argc, - char **argv) -@{ - init_scanner(); - parse(); - if (argc != 1) - @{ - fprintf(stderr, "tc: No args expected.\n"); - exit(1); - @} - if (nerr == 0) - gencode(); - else - fprintf(stderr, "No code generated.\n"); -@asis{}<<<<<<< driver.c - exit(nerr == 0 ? EXIT_SUCCESS : EXIT_FAILURE); -@asis{}======= - exit(!!nerr); -@asis{}>>>>>>> 1.6 -@} -@end example - -@noindent -@cindex Markers, conflict -@cindex Conflict markers -@cindex <<<<<<< -@cindex >>>>>>> -@cindex ======= - -Note how all non-overlapping modifications are incorporated in your working -copy, and that the overlapping section is clearly marked with -@samp{<<<<<<<}, @samp{=======} and @samp{>>>>>>>}. - -@cindex Resolving a conflict -@cindex Conflict resolution -You resolve the conflict by editing the file, removing the markers and -the erroneous line. Suppose you end up with this file: -@c -- Add xref to the pcl-cvs manual when it talks -@c -- about this. -@example -#include -#include - -int main(int argc, - char **argv) -@{ - init_scanner(); - parse(); - if (argc != 1) - @{ - fprintf(stderr, "tc: No args expected.\n"); - exit(1); - @} - if (nerr == 0) - gencode(); - else - fprintf(stderr, "No code generated.\n"); - exit(nerr == 0 ? EXIT_SUCCESS : EXIT_FAILURE); -@} -@end example - -@noindent -You can now go ahead and commit this as revision 1.7. - -@example -$ cvs commit -m "Initialize scanner. Use symbolic exit values." driver.c -Checking in driver.c; -/usr/local/cvsroot/yoyodyne/tc/driver.c,v <-- driver.c -new revision: 1.7; previous revision: 1.6 -done -@end example - -For your protection, @sc{cvs} will refuse to check in a -file if a conflict occurred and you have not resolved -the conflict. Currently to resolve a conflict, you -must change the timestamp on the file. In previous -versions of @sc{cvs}, you also needed to -insure that the file contains no conflict markers. -Because -your file may legitimately contain conflict markers (that -is, occurrences of @samp{>>>>>>> } at the start of a -line that don't mark a conflict), the current -version of @sc{cvs} will print a warning and proceed to -check in the file. -@c The old behavior was really icky; the only way out -@c was to start hacking on -@c the @code{CVS/Entries} file or other such workarounds. -@c -@c If the timestamp thing isn't considered nice enough, -@c maybe there should be a "cvs resolved" command -@c which clears the conflict indication. For a nice user -@c interface, this should be invoked by an interactive -@c merge tool like emerge rather than by the user -@c directly--such a tool can verify that the user has -@c really dealt with each conflict. - -@cindex emerge -If you use release 1.04 or later of pcl-cvs (a @sc{gnu} -Emacs front-end for @sc{cvs}) you can use an Emacs -package called emerge to help you resolve conflicts. -See the documentation for pcl-cvs. - -@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@node Informing others -@section Informing others about commits -@cindex Informing others -@cindex Spreading information -@cindex Mail, automatic mail on commit - -It is often useful to inform others when you commit a -new revision of a file. The @file{loginfo} file can be -used to automate this process. -@xref{loginfo}. You can use these features of @sc{cvs} -to, for instance, instruct @sc{cvs} to mail a -message to all developers, or post a message to a local -newsgroup. -@c -- More text would be nice here. - -@node Concurrency -@section Several developers simultaneously attempting to run CVS - -@cindex Locks, cvs, introduction -@c For a discussion of *why* CVS creates locks, see -@c the comment at the start of src/lock.c -If several developers try to run @sc{cvs} at the same -time, one may get the following message: - -@example -[11:43:23] waiting for bach's lock in /usr/local/cvsroot/foo -@end example - -@cindex #cvs.rfl, removing -@cindex #cvs.wfl, removing -@cindex #cvs.lock, removing -@sc{cvs} will try again every 30 seconds, and either -continue with the operation or print the message again, -if it still needs to wait. If a lock seems to stick -around for an undue amount of time, find the person -holding the lock and ask them about the cvs command -they are running. If they aren't running a cvs -command, look in the repository directory mentioned in -the message and remove files which they own whose names -start with @file{#cvs.rfl}, -@file{#cvs.wfl}, or @file{#cvs.lock}. - -Note that these locks are to protect @sc{cvs}'s -internal data structures and have no relationship to -the word @dfn{lock} in the sense used by -@sc{rcs}---which refers to reserved checkouts -(@pxref{Multiple developers}). - -Any number of people can be reading from a given -repository at a time; only when someone is writing do -the locks prevent other people from reading or writing. - -@cindex Atomic transactions, lack of -@cindex Transactions, atomic, lack of -@c the following talks about what one might call commit/update -@c atomicity. -@c Probably also should say something about -@c commit/commit atomicity, that is, "An update will -@c not get partial versions of more than one commit". -@c CVS currently has this property and I guess we can -@c make it a documented feature. -@c For example one person commits -@c a/one.c and b/four.c and another commits a/two.c and -@c b/three.c. Then an update cannot get the new a/one.c -@c and a/two.c and the old b/four.c and b/three.c. -One might hope for the following property: - -@quotation -If someone commits some changes in one cvs command, -then an update by someone else will either get all the -changes, or none of them. -@end quotation - -@noindent -but @sc{cvs} does @emph{not} have this property. For -example, given the files - -@example -a/one.c -a/two.c -b/three.c -b/four.c -@end example - -@noindent -if someone runs - -@example -cvs ci a/two.c b/three.c -@end example - -@noindent -and someone else runs @code{cvs update} at the same -time, the person running @code{update} might get only -the change to @file{b/three.c} and not the change to -@file{a/two.c}. - -@node Watches -@section Mechanisms to track who is editing files -@cindex Watches - -For many groups, use of @sc{cvs} in its default mode is -perfectly satisfactory. Users may sometimes go to -check in a modification only to find that another -modification has intervened, but they deal with it and -proceed with their check in. Other groups prefer to be -able to know who is editing what files, so that if two -people try to edit the same file they can choose to -talk about who is doing what when rather than be -surprised at check in time. The features in this -section allow such coordination, while retaining the -ability of two developers to edit the same file at the -same time. - -@c Some people might ask why CVS does not enforce the -@c rule on chmod, by requiring a cvs edit before a cvs -@c commit. The main reason is that it could always be -@c circumvented--one could edit the file, and -@c then when ready to check it in, do the cvs edit and put -@c in the new contents and do the cvs commit. One -@c implementation note: if we _do_ want to have cvs commit -@c require a cvs edit, we should store the state on -@c whether the cvs edit has occurred in the working -@c directory, rather than having the server try to keep -@c track of what working directories exist. -@c FIXME: should the above discussion be part of the -@c manual proper, somewhere, not just in a comment? -For maximum benefit developers should use @code{cvs -edit} (not @code{chmod}) to make files read-write to -edit them, and @code{cvs release} (not @code{rm}) to -discard a working directory which is no longer in use, -but @sc{cvs} is not able to enforce this behavior. - -@c I'm a little dissatisfied with this presentation, -@c because "watch on"/"edit"/"editors" are one set of -@c functionality, and "watch add"/"watchers" is another -@c which is somewhat orthogonal even though they interact in -@c various ways. But I think it might be -@c confusing to describe them separately (e.g. "watch -@c add" with loginfo). I don't know. - -@menu -* Setting a watch:: Telling CVS to watch certain files -* Getting Notified:: Telling CVS to notify you -* Editing files:: How to edit a file which is being watched -* Watch information:: Information about who is watching and editing -* Watches Compatibility:: Watches interact poorly with CVS 1.6 or earlier -@end menu - -@node Setting a watch -@subsection Telling CVS to watch certain files - -To enable the watch features, you first specify that -certain files are to be watched. - -@cindex watch on (subcommand) -@deffn Command {cvs watch on} [@code{-lR}] [@var{files}]@dots{} - -@cindex Read-only files, and watches -Specify that developers should run @code{cvs edit} -before editing @var{files}. @sc{cvs} will create working -copies of @var{files} read-only, to remind developers -to run the @code{cvs edit} command before working on -them. - -If @var{files} includes the name of a directory, @sc{cvs} -arranges to watch all files added to the corresponding -repository directory, and sets a default for files -added in the future; this allows the user to set -notification policies on a per-directory basis. The -contents of the directory are processed recursively, -unless the @code{-l} option is given. -The @code{-R} option can be used to force recursion if the @code{-l} -option is set in @file{~/.cvsrc} (@pxref{~/.cvsrc}). - -If @var{files} is omitted, it defaults to the current directory. - -@cindex watch off (subcommand) -@end deffn - -@deffn Command {cvs watch off} [@code{-lR}] [@var{files}]@dots{} - -Do not create @var{files} read-only on checkout; thus, -developers will not be reminded to use @code{cvs edit} -and @code{cvs unedit}. -@ignore -@sc{cvs} will check out @var{files} -read-write as usual, unless other permissions override -due to the @code{PreservePermissions} option being -enabled in the @file{config} administrative file -(@pxref{Special Files}, @pxref{config}) -@end ignore - -The @var{files} and options are processed as for @code{cvs -watch on}. - -@end deffn - -@node Getting Notified -@subsection Telling CVS to notify you - -You can tell @sc{cvs} that you want to receive -notifications about various actions taken on a file. -You can do this without using @code{cvs watch on} for -the file, but generally you will want to use @code{cvs -watch on}, to remind developers to use the @code{cvs edit} -command. - -@cindex watch add (subcommand) -@deffn Command {cvs watch add} [@code{-lR}] [@code{-a} @var{action}]@dots{} [@var{files}]@dots{} - -Add the current user to the list of people to receive notification of -work done on @var{files}. - -The @code{-a} option specifies what kinds of events @sc{cvs} should notify -the user about. @var{action} is one of the following: - -@table @code - -@item edit -Another user has applied the @code{cvs edit} command (described -below) to a watched file. - -@item commit -Another user has committed changes to one of the named @var{files}. - -@item unedit -Another user has abandoned editing a file (other than by committing changes). -They can do this in several ways, by: - -@itemize @bullet - -@item -applying the @code{cvs unedit} command (described below) to the file - -@item -applying the @code{cvs release} command (@pxref{release}) to the file's parent directory -(or recursively to a directory more than one level up) - -@item -deleting the file and allowing @code{cvs update} to recreate it - -@end itemize - -@item all -All of the above. - -@item none -None of the above. (This is useful with @code{cvs edit}, -described below.) - -@end table - -The @code{-a} option may appear more than once, or not at all. If -omitted, the action defaults to @code{all}. - -The @var{files} and options are processed as for -@code{cvs watch on}. - -@end deffn - - -@cindex watch remove (subcommand) -@deffn Command {cvs watch remove} [@code{-lR}] [@code{-a} @var{action}]@dots{} [@var{files}]@dots{} - -Remove a notification request established using @code{cvs watch add}; -the arguments are the same. If the @code{-a} option is present, only -watches for the specified actions are removed. - -@end deffn - -@cindex notify (admin file) -When the conditions exist for notification, @sc{cvs} -calls the @file{notify} administrative file. Edit -@file{notify} as one edits the other administrative -files (@pxref{Intro administrative files}). This -file follows the usual conventions for administrative -files (@pxref{syntax}), where each line is a regular -expression followed by a command to execute. The -command should contain a single occurrence of @samp{%s} -which will be replaced by the user to notify; the rest -of the information regarding the notification will be -supplied to the command on standard input. The -standard thing to put in the @code{notify} file is the -single line: - -@example -ALL mail %s -s "CVS notification" -@end example - -@noindent -This causes users to be notified by electronic mail. -@c FIXME: should it be this hard to set up this -@c behavior (and the result when one fails to do so, -@c silent failure to notify, so non-obvious)? Should -@c CVS give a warning if no line in notify matches (and -@c document the use of "DEFAULT :" for the case where -@c skipping the notification is indeed desired)? - -@cindex users (admin file) -Note that if you set this up in the straightforward -way, users receive notifications on the server machine. -One could of course write a @file{notify} script which -directed notifications elsewhere, but to make this -easy, @sc{cvs} allows you to associate a notification -address for each user. To do so create a file -@file{users} in @file{CVSROOT} with a line for each -user in the format @var{user}:@var{value}. Then -instead of passing the name of the user to be notified -to @file{notify}, @sc{cvs} will pass the @var{value} -(normally an email address on some other machine). - -@sc{cvs} does not notify you for your own changes. -Currently this check is done based on whether the user -name of the person taking the action which triggers -notification matches the user name of the person -getting notification. In fact, in general, the watches -features only track one edit by each user. It probably -would be more useful if watches tracked each working -directory separately, so this behavior might be worth -changing. -@c "behavior might be worth changing" is an effort to -@c point to future directions while also not promising -@c that "they" (as in "why don't they fix CVS to....") -@c will do this. -@c one implementation issue is identifying whether a -@c working directory is same or different. Comparing -@c pathnames/hostnames is hopeless, but having the server -@c supply a serial number which the client stores in the -@c CVS directory as a magic cookie should work. - -@node Editing files -@subsection How to edit a file which is being watched - -@cindex Checkout, as term for getting ready to edit -Since a file which is being watched is checked out -read-only, you cannot simply edit it. To make it -read-write, and inform others that you are planning to -edit it, use the @code{cvs edit} command. Some systems -call this a @dfn{checkout}, but @sc{cvs} uses that term -for obtaining a copy of the sources (@pxref{Getting the -source}), an operation which those systems call a -@dfn{get} or a @dfn{fetch}. -@c Issue to think about: should we transition CVS -@c towards the "get" terminology? "cvs get" is already a -@c synonym for "cvs checkout" and that section of the -@c manual refers to "Getting the source". If this is -@c done, needs to be done gingerly (for example, we should -@c still accept "checkout" in .cvsrc files indefinitely -@c even if the CVS's messages are changed from "cvs checkout: " -@c to "cvs get: "). -@c There is a concern about whether "get" is not as -@c good for novices because it is a more general term -@c than "checkout" (and thus arguably harder to assign -@c a technical meaning for). - -@cindex edit (subcommand) -@deffn Command {cvs edit} [@code{-lR}] [@code{-a} @var{action}]@dots{} [@var{files}]@dots{} - -Prepare to edit the working files @var{files}. @sc{cvs} makes the -@var{files} read-write, and notifies users who have requested -@code{edit} notification for any of @var{files}. - -The @code{cvs edit} command accepts the same options as the -@code{cvs watch add} command, and establishes a temporary watch for the -user on @var{files}; @sc{cvs} will remove the watch when @var{files} are -@code{unedit}ed or @code{commit}ted. If the user does not wish to -receive notifications, she should specify @code{-a none}. - -The @var{files} and the options are processed as for the @code{cvs -watch} commands. - -@ignore -@strong{Caution: If the @code{PreservePermissions} -option is enabled in the repository (@pxref{config}), -@sc{cvs} will not change the permissions on any of the -@var{files}. The reason for this change is to ensure -that using @samp{cvs edit} does not interfere with the -ability to store file permissions in the @sc{cvs} -repository.} -@end ignore - -@end deffn - -Normally when you are done with a set of changes, you -use the @code{cvs commit} command, which checks in your -changes and returns the watched files to their usual -read-only state. But if you instead decide to abandon -your changes, or not to make any changes, you can use -the @code{cvs unedit} command. - -@cindex unedit (subcommand) -@cindex Abandoning work -@cindex Reverting to repository version -@deffn Command {cvs unedit} [@code{-lR}] [@var{files}]@dots{} - -Abandon work on the working files @var{files}, and revert them to the -repository versions on which they are based. @sc{cvs} makes those -@var{files} read-only for which users have requested notification using -@code{cvs watch on}. @sc{cvs} notifies users who have requested @code{unedit} -notification for any of @var{files}. - -The @var{files} and options are processed as for the -@code{cvs watch} commands. - -If watches are not in use, the @code{unedit} command -probably does not work, and the way to revert to the -repository version is with the command @code{cvs update -C file} -(@pxref{update}). -The meaning is -not precisely the same; the latter may also -bring in some changes which have been made in the -repository since the last time you updated. -@c It would be a useful enhancement to CVS to make -@c unedit work in the non-watch case as well. -@end deffn - -When using client/server @sc{cvs}, you can use the -@code{cvs edit} and @code{cvs unedit} commands even if -@sc{cvs} is unable to successfully communicate with the -server; the notifications will be sent upon the next -successful @sc{cvs} command. - -@node Watch information -@subsection Information about who is watching and editing - -@cindex watchers (subcommand) -@deffn Command {cvs watchers} [@code{-lR}] [@var{files}]@dots{} - -List the users currently watching changes to @var{files}. The report -includes the files being watched, and the mail address of each watcher. - -The @var{files} and options are processed as for the -@code{cvs watch} commands. - -@end deffn - - -@cindex editors (subcommand) -@deffn Command {cvs editors} [@code{-lR}] [@var{files}]@dots{} - -List the users currently working on @var{files}. The report -includes the mail address of each user, the time when the user began -working with the file, and the host and path of the working directory -containing the file. - -The @var{files} and options are processed as for the -@code{cvs watch} commands. - -@end deffn - -@node Watches Compatibility -@subsection Using watches with old versions of CVS - -@cindex CVS 1.6, and watches -If you use the watch features on a repository, it -creates @file{CVS} directories in the repository and -stores the information about watches in that directory. -If you attempt to use @sc{cvs} 1.6 or earlier with the -repository, you get an error message such as the -following (all on one line): - -@example -cvs update: cannot open CVS/Entries for reading: -No such file or directory -@end example - -@noindent -and your operation will likely be aborted. To use the -watch features, you must upgrade all copies of @sc{cvs} -which use that repository in local or server mode. If -you cannot upgrade, use the @code{watch off} and -@code{watch remove} commands to remove all watches, and -that will restore the repository to a state which -@sc{cvs} 1.6 can cope with. - -@node Choosing a model -@section Choosing between reserved or unreserved checkouts -@cindex Choosing, reserved or unreserved checkouts - -Reserved and unreserved checkouts each have pros and -cons. Let it be said that a lot of this is a matter of -opinion or what works given different groups' working -styles, but here is a brief description of some of the -issues. There are many ways to organize a team of -developers. @sc{cvs} does not try to enforce a certain -organization. It is a tool that can be used in several -ways. - -Reserved checkouts can be very counter-productive. If -two persons want to edit different parts of a file, -there may be no reason to prevent either of them from -doing so. Also, it is common for someone to take out a -lock on a file, because they are planning to edit it, -but then forget to release the lock. - -@c "many groups"? specifics? cites to papers on this? -@c some way to weasel-word it a bit more so we don't -@c need facts :-)? -People, especially people who are familiar with -reserved checkouts, often wonder how often conflicts -occur if unreserved checkouts are used, and how -difficult they are to resolve. The experience with -many groups is that they occur rarely and usually are -relatively straightforward to resolve. - -The rarity of serious conflicts may be surprising, until one realizes -that they occur only when two developers disagree on the proper design -for a given section of code; such a disagreement suggests that the -team has not been communicating properly in the first place. In order -to collaborate under @emph{any} source management regimen, developers -must agree on the general design of the system; given this agreement, -overlapping changes are usually straightforward to merge. - -In some cases unreserved checkouts are clearly -inappropriate. If no merge tool exists for the kind of -file you are managing (for example word processor files -or files edited by Computer Aided Design programs), and -it is not desirable to change to a program which uses a -mergeable data format, then resolving conflicts is -going to be unpleasant enough that you generally will -be better off to simply avoid the conflicts instead, by -using reserved checkouts. - -The watches features described above in @ref{Watches} -can be considered to be an intermediate model between -reserved checkouts and unreserved checkouts. When you -go to edit a file, it is possible to find out who else -is editing it. And rather than having the system -simply forbid both people editing the file, it can tell -you what the situation is and let you figure out -whether it is a problem in that particular case or not. -Therefore, for some groups it can be considered the -best of both the reserved checkout and unreserved -checkout worlds. - -@c --------------------------------------------------------------------- -@node Revision management -@chapter Revision management -@cindex Revision management - -@c -- This chapter could be expanded a lot. -@c -- Experiences are very welcome! - -If you have read this far, you probably have a pretty -good grasp on what @sc{cvs} can do for you. This -chapter talks a little about things that you still have -to decide. - -If you are doing development on your own using @sc{cvs} -you could probably skip this chapter. The questions -this chapter takes up become more important when more -than one person is working in a repository. - -@menu -* When to commit:: Some discussion on the subject -@end menu - -@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@node When to commit -@section When to commit? -@cindex When to commit -@cindex Committing, when to -@cindex Policy - -Your group should decide which policy to use regarding -commits. Several policies are possible, and as your -experience with @sc{cvs} grows you will probably find -out what works for you. - -If you commit files too quickly you might commit files -that do not even compile. If your partner updates his -working sources to include your buggy file, he will be -unable to compile the code. On the other hand, other -persons will not be able to benefit from the -improvements you make to the code if you commit very -seldom, and conflicts will probably be more common. - -It is common to only commit files after making sure -that they can be compiled. Some sites require that the -files pass a test suite. Policies like this can be -enforced using the commitinfo file -(@pxref{commitinfo}), but you should think twice before -you enforce such a convention. By making the -development environment too controlled it might become -too regimented and thus counter-productive to the real -goal, which is to get software written. - -@c --------------------------------------------------------------------- -@node Keyword substitution -@chapter Keyword substitution -@cindex Keyword substitution -@cindex Keyword expansion -@cindex Identifying files - -@comment Be careful when editing this chapter. -@comment Remember that this file is kept under -@comment version control, so we must not accidentally -@comment include a valid keyword in the running text. - -As long as you edit source files inside a working -directory you can always find out the state of -your files via @samp{cvs status} and @samp{cvs log}. -But as soon as you export the files from your -development environment it becomes harder to identify -which revisions they are. - -@sc{cvs} can use a mechanism known as @dfn{keyword -substitution} (or @dfn{keyword expansion}) to help -identifying the files. Embedded strings of the form -@code{$@var{keyword}$} and -@code{$@var{keyword}:@dots{}$} in a file are replaced -with strings of the form -@code{$@var{keyword}:@var{value}$} whenever you obtain -a new revision of the file. - -@menu -* Keyword list:: Keywords -* Using keywords:: Using keywords -* Avoiding substitution:: Avoiding substitution -* Substitution modes:: Substitution modes -* Log keyword:: Problems with the $@splitrcskeyword{Log}$ keyword. -@end menu - -@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@node Keyword list -@section Keyword List -@cindex Keyword List - -@c FIXME: need some kind of example here I think, -@c perhaps in a -@c "Keyword intro" node. The intro in the "Keyword -@c substitution" node itself seems OK, but to launch -@c into a list of the keywords somehow seems too abrupt. - -This is a list of the keywords: - -@table @code -@cindex Author keyword -@item $@splitrcskeyword{Author}$ -The login name of the user who checked in the revision. - -@cindex Date keyword -@item $@splitrcskeyword{Date}$ -The date and time (UTC) the revision was checked in. - -@cindex Header keyword -@item $@splitrcskeyword{Header}$ -A standard header containing the full pathname of the -@sc{rcs} file, the revision number, the date (UTC), the -author, the state, and the locker (if locked). Files -will normally never be locked when you use @sc{cvs}. - -@cindex Id keyword -@item $@splitrcskeyword{Id}$ -Same as @code{$@splitrcskeyword{Header}$}, except that the @sc{rcs} -filename is without a path. - -@cindex Name keyword -@item $@splitrcskeyword{Name}$ -Tag name used to check out this file. The keyword is -expanded only if one checks out with an explicit tag -name. For example, when running the command @code{cvs -co -r first}, the keyword expands to @samp{Name: first}. - -@cindex Locker keyword -@item $@splitrcskeyword{Locker}$ -The login name of the user who locked the revision -(empty if not locked, which is the normal case unless -@code{cvs admin -l} is in use). - -@cindex Log keyword -@item $@splitrcskeyword{Log}$ -The log message supplied during commit, preceded by a -header containing the @sc{rcs} filename, the revision -number, the author, and the date (UTC). Existing log -messages are @emph{not} replaced. Instead, the new log -message is inserted after @code{$@splitrcskeyword{Log}:@dots{}$}. -Each new line is prefixed with the same string which -precedes the @code{$Log} keyword. For example, if the -file contains: - -@example - /* Here is what people have been up to: - * - * $@splitrcskeyword{Log}: frob.c,v $ - * Revision 1.1 1997/01/03 14:23:51 joe - * Add the superfrobnicate option - * - */ -@end example - -@noindent -then additional lines which are added when expanding -the @code{$Log} keyword will be preceded by @samp{ * }. -Unlike previous versions of @sc{cvs} and @sc{rcs}, the -@dfn{comment leader} from the @sc{rcs} file is not used. -The @code{$Log} keyword is useful for -accumulating a complete change log in a source file, -but for several reasons it can be problematic. -@xref{Log keyword}. - -@cindex RCSfile keyword -@item $@splitrcskeyword{RCSfile}$ -The name of the RCS file without a path. - -@cindex Revision keyword -@item $@splitrcskeyword{Revision}$ -The revision number assigned to the revision. - -@cindex Source keyword -@item $@splitrcskeyword{Source}$ -The full pathname of the RCS file. - -@cindex State keyword -@item $@splitrcskeyword{State}$ -The state assigned to the revision. States can be -assigned with @code{cvs admin -s}---see @ref{admin options}. - -@end table - -@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@node Using keywords -@section Using keywords - -To include a keyword string you simply include the -relevant text string, such as @code{$@splitrcskeyword{Id}$}, inside the -file, and commit the file. @sc{cvs} will automatically (Or, -more accurately, as part of the update run that -automatically happens after a commit.) -expand the string as part of the commit operation. - -It is common to embed the @code{$@splitrcskeyword{Id}$} string in -the source files so that it gets passed through to -generated files. For example, if you are managing -computer program source code, you might include a -variable which is initialized to contain that string. -Or some C compilers may provide a @code{#pragma ident} -directive. Or a document management system might -provide a way to pass a string through to generated -files. - -@c Would be nice to give an example, but doing this in -@c portable C is not possible and the problem with -@c picking any one language (VMS HELP files, Ada, -@c troff, whatever) is that people use CVS for all -@c kinds of files. - -@cindex Ident (shell command) -The @code{ident} command (which is part of the @sc{rcs} -package) can be used to extract keywords and their -values from a file. This can be handy for text files, -but it is even more useful for extracting keywords from -binary files. - -@example -$ ident samp.c -samp.c: - $@splitrcskeyword{Id}: samp.c,v 1.5 1993/10/19 14:57:32 ceder Exp $ -$ gcc samp.c -$ ident a.out -a.out: - $@splitrcskeyword{Id}: samp.c,v 1.5 1993/10/19 14:57:32 ceder Exp $ -@end example - -@cindex What (shell command) -S@sc{ccs} is another popular revision control system. -It has a command, @code{what}, which is very similar to -@code{ident} and used for the same purpose. Many sites -without @sc{rcs} have @sc{sccs}. Since @code{what} -looks for the character sequence @code{@@(#)} it is -easy to include keywords that are detected by either -command. Simply prefix the keyword with the -magic @sc{sccs} phrase, like this: - -@example -static char *id="@@(#) $@splitrcskeyword{Id}: ab.c,v 1.5 1993/10/19 14:57:32 ceder Exp $"; -@end example - -@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@node Avoiding substitution -@section Avoiding substitution - -Keyword substitution has its disadvantages. Sometimes -you might want the literal text string -@samp{$@splitrcskeyword{Author}$} to appear inside a file without -@sc{cvs} interpreting it as a keyword and expanding it -into something like @samp{$@splitrcskeyword{Author}: ceder $}. - -There is unfortunately no way to selectively turn off -keyword substitution. You can use @samp{-ko} -(@pxref{Substitution modes}) to turn off keyword -substitution entirely. - -In many cases you can avoid using keywords in -the source, even though they appear in the final -product. For example, the source for this manual -contains @samp{$@@asis@{@}Author$} whenever the text -@samp{$@splitrcskeyword{Author}$} should appear. In @code{nroff} -and @code{troff} you can embed the null-character -@code{\&} inside the keyword for a similar effect. - -@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@node Substitution modes -@section Substitution modes -@cindex Keyword substitution, changing modes -@cindex -k (keyword substitution) -@cindex Kflag - -@c FIXME: This could be made more coherent, by expanding it -@c with more examples or something. -Each file has a stored default substitution mode, and -each working directory copy of a file also has a -substitution mode. The former is set by the @samp{-k} -option to @code{cvs add} and @code{cvs admin}; the -latter is set by the @samp{-k} or @samp{-A} options to @code{cvs -checkout} or @code{cvs update}. -@code{cvs diff} and @code{cvs rdiff} also -have @samp{-k} options. -For some examples, -see @ref{Binary files}, and @ref{Merging and keywords}. -@c The fact that -A is overloaded to mean both reset -@c sticky options and reset sticky tags/dates is -@c somewhat questionable. Perhaps there should be -@c separate options to reset sticky options (e.g. -k -@c A") and tags/dates (someone suggested -r HEAD could -@c do this instead of setting a sticky tag of "HEAD" -@c as in the status quo but I haven't thought much -@c about that idea. Of course -r .reset or something -@c could be coined if this needs to be a new option). -@c On the other hand, having -A mean "get things back -@c into the state after a fresh checkout" has a certain -@c appeal, and maybe there is no sufficient reason for -@c creeping featurism in this area. - -The modes available are: - -@table @samp -@item -kkv -Generate keyword strings using the default form, e.g. -@code{$@splitrcskeyword{Revision}: 5.7 $} for the @code{Revision} -keyword. - -@item -kkvl -Like @samp{-kkv}, except that a locker's name is always -inserted if the given revision is currently locked. -The locker's name is only relevant if @code{cvs admin --l} is in use. - -@item -kk -Generate only keyword names in keyword strings; omit -their values. For example, for the @code{Revision} -keyword, generate the string @code{$@splitrcskeyword{Revision}$} -instead of @code{$@splitrcskeyword{Revision}: 5.7 $}. This option -is useful to ignore differences due to keyword -substitution when comparing different revisions of a -file (@pxref{Merging and keywords}). - -@item -ko -Generate the old keyword string, present in the working -file just before it was checked in. For example, for -the @code{Revision} keyword, generate the string -@code{$@splitrcskeyword{Revision}: 1.1 $} instead of -@code{$@splitrcskeyword{Revision}: 5.7 $} if that is how the -string appeared when the file was checked in. - -@item -kb -Like @samp{-ko}, but also inhibit conversion of line -endings between the canonical form in which they are -stored in the repository (linefeed only), and the form -appropriate to the operating system in use on the -client. For systems, like unix, which use linefeed -only to terminate lines, this is the same as -@samp{-ko}. For more information on binary files, see -@ref{Binary files}. - -@item -kv -Generate only keyword values for keyword strings. For -example, for the @code{Revision} keyword, generate the string -@code{5.7} instead of @code{$@splitrcskeyword{Revision}: 5.7 $}. -This can help generate files in programming languages -where it is hard to strip keyword delimiters like -@code{$@splitrcskeyword{Revision}: $} from a string. However, -further keyword substitution cannot be performed once -the keyword names are removed, so this option should be -used with care. - -One often would like to use @samp{-kv} with @code{cvs -export}---@pxref{export}. But be aware that doesn't -handle an export containing binary files correctly. - -@end table - -@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@node Log keyword -@section Problems with the $@splitrcskeyword{Log}$ keyword. - -The @code{$@splitrcskeyword{Log}$} keyword is somewhat -controversial. As long as you are working on your -development system the information is easily accessible -even if you do not use the @code{$@splitrcskeyword{Log}$} -keyword---just do a @code{cvs log}. Once you export -the file the history information might be useless -anyhow. - -A more serious concern is that @sc{cvs} is not good at -handling @code{$@splitrcskeyword{Log}$} entries when a branch is -merged onto the main trunk. Conflicts often result -from the merging operation. -@c Might want to check whether the CVS implementation -@c of RCS_merge has this problem the same way rcsmerge -@c does. I would assume so.... - -People also tend to "fix" the log entries in the file -(correcting spelling mistakes and maybe even factual -errors). If that is done the information from -@code{cvs log} will not be consistent with the -information inside the file. This may or may not be a -problem in real life. - -It has been suggested that the @code{$@splitrcskeyword{Log}$} -keyword should be inserted @emph{last} in the file, and -not in the files header, if it is to be used at all. -That way the long list of change messages will not -interfere with everyday source file browsing. - -@c --------------------------------------------------------------------- -@node Tracking sources -@chapter Tracking third-party sources -@cindex Third-party sources -@cindex Tracking sources - -@c FIXME: Need discussion of added and removed files. -@c FIXME: This doesn't really adequately introduce the -@c concepts of "vendor" and "you". They don't *have* -@c to be separate organizations or separate people. -@c We want a description which is somewhat more based on -@c the technical issues of which sources go where, but -@c also with enough examples of how this relates to -@c relationships like customer-supplier, developer-QA, -@c maintainer-contributor, or whatever, to make it -@c seem concrete. -If you modify a program to better fit your site, you -probably want to include your modifications when the next -release of the program arrives. @sc{cvs} can help you with -this task. - -@cindex Vendor -@cindex Vendor branch -@cindex Branch, vendor- -In the terminology used in @sc{cvs}, the supplier of the -program is called a @dfn{vendor}. The unmodified -distribution from the vendor is checked in on its own -branch, the @dfn{vendor branch}. @sc{cvs} reserves branch -1.1.1 for this use. - -When you modify the source and commit it, your revision -will end up on the main trunk. When a new release is -made by the vendor, you commit it on the vendor branch -and copy the modifications onto the main trunk. - -Use the @code{import} command to create and update -the vendor branch. When you import a new file, -the vendor branch is made the `head' revision, so -anyone that checks out a copy of the file gets that -revision. When a local modification is committed it is -placed on the main trunk, and made the `head' -revision. - -@menu -* First import:: Importing for the first time -* Update imports:: Updating with the import command -* Reverting local changes:: Reverting to the latest vendor release -* Binary files in imports:: Binary files require special handling -* Keywords in imports:: Keyword substitution might be undesirable -* Multiple vendor branches:: What if you get sources from several places? -@end menu - -@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@node First import -@section Importing for the first time -@cindex Importing modules - -@c Should mention naming conventions for vendor tags, -@c release tags, and perhaps directory names. -Use the @code{import} command to check in the sources -for the first time. When you use the @code{import} -command to track third-party sources, the @dfn{vendor -tag} and @dfn{release tags} are useful. The -@dfn{vendor tag} is a symbolic name for the branch -(which is always 1.1.1, unless you use the @samp{-b -@var{branch}} flag---see @ref{Multiple vendor branches}.). The -@dfn{release tags} are symbolic names for a particular -release, such as @samp{FSF_0_04}. - -@c I'm not completely sure this belongs here. But -@c we need to say it _somewhere_ reasonably obvious; it -@c is a common misconception among people first learning CVS -Note that @code{import} does @emph{not} change the -directory in which you invoke it. In particular, it -does not set up that directory as a @sc{cvs} working -directory; if you want to work with the sources import -them first and then check them out into a different -directory (@pxref{Getting the source}). - -@cindex wdiff (import example) -Suppose you have the sources to a program called -@code{wdiff} in a directory @file{wdiff-0.04}, -and are going to make private modifications that you -want to be able to use even when new releases are made -in the future. You start by importing the source to -your repository: - -@example -$ cd wdiff-0.04 -$ cvs import -m "Import of FSF v. 0.04" fsf/wdiff FSF_DIST WDIFF_0_04 -@end example - -The vendor tag is named @samp{FSF_DIST} in the above -example, and the only release tag assigned is -@samp{WDIFF_0_04}. -@c FIXME: Need to say where fsf/wdiff comes from. - -@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@node Update imports -@section Updating with the import command - -When a new release of the source arrives, you import it into the -repository with the same @code{import} command that you used to set up -the repository in the first place. The only difference is that you -specify a different release tag this time: - -@example -$ tar xfz wdiff-0.05.tar.gz -$ cd wdiff-0.05 -$ cvs import -m "Import of FSF v. 0.05" fsf/wdiff FSF_DIST WDIFF_0_05 -@end example - -@strong{WARNING: If you use a release tag that already exists in one of the -repository archives, files removed by an import may not be detected.} - -For files that have not been modified locally, the newly created -revision becomes the head revision. If you have made local -changes, @code{import} will warn you that you must merge the changes -into the main trunk, and tell you to use @samp{checkout -j} to do so: - -@c FIXME: why "wdiff" here and "fsf/wdiff" in the -@c "import"? I think the assumption is that one has -@c "wdiff fsf/wdiff" or some such in modules, but it -@c would be better to not use modules in this example. -@example -$ cvs checkout -jFSF_DIST:yesterday -jFSF_DIST wdiff -@end example - -@noindent -The above command will check out the latest revision of -@samp{wdiff}, merging the changes made on the vendor branch @samp{FSF_DIST} -since yesterday into the working copy. If any conflicts arise during -the merge they should be resolved in the normal way (@pxref{Conflicts -example}). Then, the modified files may be committed. - -However, it is much better to use the two release tags rather than using -a date on the branch as suggested above: - -@example -$ cvs checkout -jWDIFF_0_04 -jWDIFF_0_05 wdiff -@end example - -@noindent -The reason this is better is that -using a date, as suggested above, assumes that you do -not import more than one release of a product per day. -More importantly, using the release tags allows @sc{cvs} to detect files -that were removed between the two vendor releases and mark them for -removal. Since @code{import} has no way to detect removed files, you -should do a merge like this even if @code{import} doesn't tell you to. - -@node Reverting local changes -@section Reverting to the latest vendor release - -You can also revert local changes completely and return -to the latest vendor release by changing the `head' -revision back to the vendor branch on all files. For -example, if you have a checked-out copy of the sources -in @file{~/work.d/wdiff}, and you want to revert to the -vendor's version for all the files in that directory, -you would type: - -@example -$ cd ~/work.d/wdiff -$ cvs admin -bFSF_DIST . -@end example - -@noindent -You must specify the @samp{-bFSF_DIST} without any space -after the @samp{-b}. @xref{admin options}. - -@node Binary files in imports -@section How to handle binary files with cvs import - -Use the @samp{-k} wrapper option to tell import which -files are binary. @xref{Wrappers}. - -@node Keywords in imports -@section How to handle keyword substitution with cvs import - -The sources which you are importing may contain -keywords (@pxref{Keyword substitution}). For example, -the vendor may use @sc{cvs} or some other system -which uses similar keyword expansion syntax. If you -just import the files in the default fashion, then -the keyword expansions supplied by the vendor will -be replaced by keyword expansions supplied by your -own copy of @sc{cvs}. It may be more convenient to -maintain the expansions supplied by the vendor, so -that this information can supply information about -the sources that you imported from the vendor. - -To maintain the keyword expansions supplied by the -vendor, supply the @samp{-ko} option to @code{cvs -import} the first time you import the file. -This will turn off keyword expansion -for that file entirely, so if you want to be more -selective you'll have to think about what you want -and use the @samp{-k} option to @code{cvs update} or -@code{cvs admin} as appropriate. -@c Supplying -ko to import if the file already existed -@c has no effect. Not clear to me whether it should -@c or not. - -@node Multiple vendor branches -@section Multiple vendor branches - -All the examples so far assume that there is only one -vendor from which you are getting sources. In some -situations you might get sources from a variety of -places. For example, suppose that you are dealing with -a project where many different people and teams are -modifying the software. There are a variety of ways to -handle this, but in some cases you have a bunch of -source trees lying around and what you want to do more -than anything else is just to all put them in @sc{cvs} so -that you at least have them in one place. - -For handling situations in which there may be more than -one vendor, you may specify the @samp{-b} option to -@code{cvs import}. It takes as an argument the vendor -branch to import to. The default is @samp{-b 1.1.1}. - -For example, suppose that there are two teams, the red -team and the blue team, that are sending you sources. -You want to import the red team's efforts to branch -1.1.1 and use the vendor tag RED. You want to import -the blue team's efforts to branch 1.1.3 and use the -vendor tag BLUE. So the commands you might use are: - -@example -$ cvs import dir RED RED_1-0 -$ cvs import -b 1.1.3 dir BLUE BLUE_1-5 -@end example - -Note that if your vendor tag does not match your -@samp{-b} option, @sc{cvs} will not detect this case! For -example, - -@example -$ cvs import -b 1.1.3 dir RED RED_1-0 -@end example - -@noindent -Be careful; this kind of mismatch is sure to sow -confusion or worse. I can't think of a useful purpose -for the ability to specify a mismatch here, but if you -discover such a use, don't. @sc{cvs} is likely to make this -an error in some future release. - -@c Probably should say more about the semantics of -@c multiple branches. What about the default branch? -@c What about joining (perhaps not as useful with -@c multiple branches, or perhaps it is. Either way -@c should be mentioned). - -@c I'm not sure about the best location for this. In -@c one sense, it might belong right after we've introduced -@c CVS's basic version control model, because people need -@c to figure out builds right away. The current location -@c is based on the theory that it kind of akin to the -@c "Revision management" section. -@node Builds -@chapter How your build system interacts with CVS -@cindex Builds -@cindex make - -As mentioned in the introduction, @sc{cvs} does not -contain software for building your software from source -code. This section describes how various aspects of -your build system might interact with @sc{cvs}. - -@c Is there a way to discuss this without reference to -@c tools other than CVS? I'm not sure there is; I -@c wouldn't think that people who learn CVS first would -@c even have this concern. -One common question, especially from people who are -accustomed to @sc{rcs}, is how to make their build get -an up to date copy of the sources. The answer to this -with @sc{cvs} is two-fold. First of all, since -@sc{cvs} itself can recurse through directories, there -is no need to modify your @file{Makefile} (or whatever -configuration file your build tool uses) to make sure -each file is up to date. Instead, just use two -commands, first @code{cvs -q update} and then -@code{make} or whatever the command is to invoke your -build tool. Secondly, you do not necessarily -@emph{want} to get a copy of a change someone else made -until you have finished your own work. One suggested -approach is to first update your sources, then -implement, build and -test the change you were thinking of, and then commit -your sources (updating first if necessary). By -periodically (in between changes, using the approach -just described) updating your entire tree, you ensure -that your sources are sufficiently up to date. - -@cindex Bill of materials -One common need is to record which versions of which -source files went into a particular build. This kind -of functionality is sometimes called @dfn{bill of -materials} or something similar. The best way to do -this with @sc{cvs} is to use the @code{tag} command to -record which versions went into a given build -(@pxref{Tags}). - -Using @sc{cvs} in the most straightforward manner -possible, each developer will have a copy of the entire -source tree which is used in a particular build. If -the source tree is small, or if developers are -geographically dispersed, this is the preferred -solution. In fact one approach for larger projects is -to break a project down into smaller -@c I say subsystem instead of module because they may or -@c may not use the modules file. -separately-compiled subsystems, and arrange a way of -releasing them internally so that each developer need -check out only those subsystems which they are -actively working on. - -Another approach is to set up a structure which allows -developers to have their own copies of some files, and -for other files to access source files from a central -location. Many people have come up with some such a -@c two such people are paul@sander.cupertino.ca.us (for -@c a previous employer) -@c and gunnar.tornblom@se.abb.com (spicm and related tools), -@c but as far as I know -@c no one has nicely packaged or released such a system (or -@c instructions for constructing one). -system using features such as the symbolic link feature -found in many operating systems, or the @code{VPATH} -feature found in many versions of @code{make}. One build -tool which is designed to help with this kind of thing -is Odin (see -@code{ftp://ftp.cs.colorado.edu/pub/distribs/odin}). -@c Should we be saying more about Odin? Or how you use -@c it with CVS? Also, the Prime Time Freeware for Unix -@c disk (see http://www.ptf.com/) has Odin (with a nice -@c paragraph summarizing it on the web), so that might be a -@c semi-"official" place to point people. -@c -@c Of course, many non-CVS systems have this kind of -@c functionality, for example OSF's ODE -@c (http://www.osf.org/ode/) or mk -@c (http://www.grin.net/~pzi/mk-3.18.4.docs/mk_toc.html -@c He has changed providers in the past; a search engine search -@c for "Peter Ziobrzynski" probably won't get too many -@c spurious hits :-). A more stable URL might be -@c ftp://ftp.uu.net/pub/cmvc/mk). But I'm not sure -@c there is any point in mentioning them here unless they -@c can work with CVS. - -@c --------------------------------------------------------------------- -@node Special Files -@chapter Special Files - -@cindex Special files -@cindex Device nodes -@cindex Ownership, saving in CVS -@cindex Permissions, saving in CVS -@cindex Hard links -@cindex Symbolic links - -In normal circumstances, @sc{cvs} works only with regular -files. Every file in a project is assumed to be -persistent; it must be possible to open, read and close -them; and so on. @sc{cvs} also ignores file permissions and -ownerships, leaving such issues to be resolved by the -developer at installation time. In other words, it is -not possible to "check in" a device into a repository; -if the device file cannot be opened, @sc{cvs} will refuse to -handle it. Files also lose their ownerships and -permissions during repository transactions. - -@ignore -If the configuration variable @code{PreservePermissions} -(@pxref{config}) is set in the repository, @sc{cvs} will -save the following file characteristics in the -repository: - -@itemize @bullet -@item user and group ownership -@item permissions -@item major and minor device numbers -@item symbolic links -@item hard link structure -@end itemize - -Using the @code{PreservePermissions} option affects the -behavior of @sc{cvs} in several ways. First, some of the -new operations supported by @sc{cvs} are not accessible to -all users. In particular, file ownership and special -file characteristics may only be changed by the -superuser. When the @code{PreservePermissions} -configuration variable is set, therefore, users will -have to be `root' in order to perform @sc{cvs} operations. - -When @code{PreservePermissions} is in use, some @sc{cvs} -operations (such as @samp{cvs status}) will not -recognize a file's hard link structure, and so will -emit spurious warnings about mismatching hard links. -The reason is that @sc{cvs}'s internal structure does not -make it easy for these operations to collect all the -necessary data about hard links, so they check for file -conflicts with inaccurate data. - -A more subtle difference is that @sc{cvs} considers a file -to have changed only if its contents have changed -(specifically, if the modification time of the working -file does not match that of the repository's file). -Therefore, if only the permissions, ownership or hard -linkage have changed, or if a device's major or minor -numbers have changed, @sc{cvs} will not notice. In order to -commit such a change to the repository, you must force -the commit with @samp{cvs commit -f}. This also means -that if a file's permissions have changed and the -repository file is newer than the working copy, -performing @samp{cvs update} will silently change the -permissions on the working copy. - -Changing hard links in a @sc{cvs} repository is particularly -delicate. Suppose that file @file{foo} is linked to -file @file{old}, but is later relinked to file -@file{new}. You can wind up in the unusual situation -where, although @file{foo}, @file{old} and @file{new} -have all had their underlying link patterns changed, -only @file{foo} and @file{new} have been modified, so -@file{old} is not considered a candidate for checking -in. It can be very easy to produce inconsistent -results this way. Therefore, we recommend that when it -is important to save hard links in a repository, the -prudent course of action is to @code{touch} any file -whose linkage or status has changed since the last -checkin. Indeed, it may be wise to @code{touch *} -before each commit in a directory with complex hard -link structures. - -It is worth noting that only regular files may -be merged, for reasons that hopefully are obvious. If -@samp{cvs update} or @samp{cvs checkout -j} attempts to -merge a symbolic link with a regular file, or two -device files for different kinds of devices, @sc{cvs} will -report a conflict and refuse to perform the merge. At -the same time, @samp{cvs diff} will not report any -differences between these files, since no meaningful -textual comparisons can be made on files which contain -no text. - -The @code{PreservePermissions} features do not work -with client/server @sc{cvs}. Another limitation is -that hard links must be to other files within the same -directory; hard links across directories are not -supported. -@end ignore - -@c --------------------------------------------------------------------- -@c ----- START MAN 1 ----- -@node CVS commands -@appendix Guide to CVS commands - -This appendix describes the overall structure of -@sc{cvs} commands, and describes some commands in -detail (others are described elsewhere; for a quick -reference to @sc{cvs} commands, @pxref{Invoking CVS}). -@c The idea is that we want to move the commands which -@c are described here into the main body of the manual, -@c in the process reorganizing the manual to be -@c organized around what the user wants to do, not -@c organized around CVS commands. -@c -@c Note that many users do expect a manual which is -@c organized by command. At least some users do. -@c One good addition to the "organized by command" -@c section (if any) would be "see also" links. -@c The awk manual might be a good example; it has a -@c reference manual which is more verbose than Invoking -@c CVS but probably somewhat less verbose than CVS -@c Commands. - -@menu -* Structure:: Overall structure of CVS commands -* Exit status:: Indicating CVS's success or failure -* ~/.cvsrc:: Default options with the ~/.cvsrc file -* Global options:: Options you give to the left of cvs_command -* Common options:: Options you give to the right of cvs_command -* add:: Add files and directories to the repository -* admin:: Administration -* annotate:: What revision modified each line of a file? -* checkout:: Checkout sources for editing -* commit:: Check files into the repository -* diff:: Show differences between revisions -* export:: Export sources from CVS, similar to checkout -* history:: Show status of files and users -* import:: Import sources into CVS, using vendor branches -* log:: Show log messages for files -* rdiff:: 'patch' format diffs between releases -* release:: Indicate that a directory is no longer in use -* remove:: Remove files from active development -* update:: Bring work tree in sync with repository -@end menu - -@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@node Structure -@appendixsec Overall structure of CVS commands -@cindex Structure -@cindex CVS command structure -@cindex Command structure -@cindex Format of CVS commands - -The overall format of all @sc{cvs} commands is: - -@example -cvs [ cvs_options ] cvs_command [ command_options ] [ command_args ] -@end example - -@table @code -@item cvs -The name of the @sc{cvs} program. - -@item cvs_options -Some options that affect all sub-commands of @sc{cvs}. These are -described below. - -@item cvs_command -One of several different sub-commands. Some of the commands have -aliases that can be used instead; those aliases are noted in the -reference manual for that command. There are only two situations -where you may omit @samp{cvs_command}: @samp{cvs -H} elicits a -list of available commands, and @samp{cvs -v} displays version -information on @sc{cvs} itself. - -@item command_options -Options that are specific for the command. - -@item command_args -Arguments to the commands. -@end table - -There is unfortunately some confusion between -@code{cvs_options} and @code{command_options}. -When given as a @code{cvs_option}, some options only -affect some of the commands. When given as a -@code{command_option} it may have a different meaning, and -be accepted by more commands. In other words, do not -take the above categorization too seriously. Look at -the documentation instead. - -@node Exit status -@appendixsec CVS's exit status -@cindex Exit status, of CVS - -@sc{cvs} can indicate to the calling environment whether it -succeeded or failed by setting its @dfn{exit status}. -The exact way of testing the exit status will vary from -one operating system to another. For example in a unix -shell script the @samp{$?} variable will be 0 if the -last command returned a successful exit status, or -greater than 0 if the exit status indicated failure. - -If @sc{cvs} is successful, it returns a successful status; -if there is an error, it prints an error message and -returns a failure status. The one exception to this is -the @code{cvs diff} command. It will return a -successful status if it found no differences, or a -failure status if there were differences or if there -was an error. Because this behavior provides no good -way to detect errors, in the future it is possible that -@code{cvs diff} will be changed to behave like the -other @sc{cvs} commands. -@c It might seem like checking whether cvs -q diff -@c produces empty or non-empty output can tell whether -@c there were differences or not. But it seems like -@c there are cases with output but no differences -@c (testsuite basica-8b). It is not clear to me how -@c useful it is for a script to be able to check -@c whether there were differences. -@c FIXCVS? In previous versions of CVS, cvs diff -@c returned 0 for no differences, 1 for differences, or -@c 2 for errors. Is this behavior worth trying to -@c bring back (but what does it mean for VMS?)? - -@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@node ~/.cvsrc -@appendixsec Default options and the ~/.cvsrc file -@cindex .cvsrc file -@cindex Option defaults - -There are some @code{command_options} that are used so -often that you might have set up an alias or some other -means to make sure you always specify that option. One -example (the one that drove the implementation of the -@file{.cvsrc} support, actually) is that many people find the -default output of the @samp{diff} command to be very -hard to read, and that either context diffs or unidiffs -are much easier to understand. - -The @file{~/.cvsrc} file is a way that you can add -default options to @code{cvs_commands} within cvs, -instead of relying on aliases or other shell scripts. - -The format of the @file{~/.cvsrc} file is simple. The -file is searched for a line that begins with the same -name as the @code{cvs_command} being executed. If a -match is found, then the remainder of the line is split -up (at whitespace characters) into separate options and -added to the command arguments @emph{before} any -options from the command line. - -If a command has two names (e.g., @code{checkout} and -@code{co}), the official name, not necessarily the one -used on the command line, will be used to match against -the file. So if this is the contents of the user's -@file{~/.cvsrc} file: - -@example -log -N -diff -uN -rdiff -u -update -Pd -checkout -P -release -d -@end example - -@noindent -the command @samp{cvs checkout foo} would have the -@samp{-P} option added to the arguments, as well as -@samp{cvs co foo}. - -With the example file above, the output from @samp{cvs -diff foobar} will be in unidiff format. @samp{cvs diff --c foobar} will provide context diffs, as usual. -Getting "old" format diffs would be slightly more -complicated, because @code{diff} doesn't have an option -to specify use of the "old" format, so you would need -@samp{cvs -f diff foobar}. - -In place of the command name you can use @code{cvs} to -specify global options (@pxref{Global options}). For -example the following line in @file{.cvsrc} - -@example -cvs -z6 -@end example - -@noindent -causes @sc{cvs} to use compression level 6. - -@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@node Global options -@appendixsec Global options -@cindex Options, global -@cindex Global options -@cindex Left-hand options - -The available @samp{cvs_options} (that are given to the -left of @samp{cvs_command}) are: - -@table @code -@item --allow-root=@var{rootdir} -Specify legal @sc{cvsroot} directory. See -@ref{Password authentication server}. - -@cindex Authentication, stream -@cindex Stream authentication -@item -a -Authenticate all communication between the client and -the server. Only has an effect on the @sc{cvs} client. -As of this writing, this is only implemented when using -a GSSAPI connection (@pxref{GSSAPI authenticated}). -Authentication prevents certain sorts of attacks -involving hijacking the active @sc{tcp} connection. -Enabling authentication does not enable encryption. - -@cindex RCSBIN, overriding -@cindex Overriding RCSBIN -@item -b @var{bindir} -In @sc{cvs} 1.9.18 and older, this specified that -@sc{rcs} programs are in the @var{bindir} directory. -Current versions of @sc{cvs} do not run @sc{rcs} -programs; for compatibility this option is accepted, -but it does nothing. - -@cindex TMPDIR, overriding -@cindex Overriding TMPDIR -@item -T @var{tempdir} -Use @var{tempdir} as the directory where temporary files are -located. Overrides the setting of the @code{$TMPDIR} environment -variable and any precompiled directory. This parameter should be -specified as an absolute pathname. -(When running client/server, @samp{-T} affects only the local process; -specifying @samp{-T} for the client has no effect on the server and -vice versa.) - -@cindex CVSROOT, overriding -@cindex Overriding CVSROOT -@item -d @var{cvs_root_directory} -Use @var{cvs_root_directory} as the root directory -pathname of the repository. Overrides the setting of -the @code{$CVSROOT} environment variable. See @ref{Repository}. - -@cindex EDITOR, overriding -@cindex Overriding EDITOR -@item -e @var{editor} -Use @var{editor} to enter revision log information. Overrides the -setting of the @code{$CVSEDITOR} and @code{$EDITOR} -environment variables. For more information, see -@ref{Committing your changes}. - -@item -f -Do not read the @file{~/.cvsrc} file. This -option is most often used because of the -non-orthogonality of the @sc{cvs} option set. For -example, the @samp{cvs log} option @samp{-N} (turn off -display of tag names) does not have a corresponding -option to turn the display on. So if you have -@samp{-N} in the @file{~/.cvsrc} entry for @samp{log}, -you may need to use @samp{-f} to show the tag names. - -@item -H -@itemx --help -Display usage information about the specified @samp{cvs_command} -(but do not actually execute the command). If you don't specify -a command name, @samp{cvs -H} displays overall help for -@sc{cvs}, including a list of other help options. -@c It seems to me it is better to document it this way -@c rather than trying to update this documentation -@c every time that we add a --help-foo option. But -@c perhaps that is confusing... - -@cindex Read-only mode -@item -n -Do not change any files. Attempt to execute the -@samp{cvs_command}, but only to issue reports; do not remove, -update, or merge any existing files, or create any new files. - -Note that @sc{cvs} will not necessarily produce exactly -the same output as without @samp{-n}. In some cases -the output will be the same, but in other cases -@sc{cvs} will skip some of the processing that would -have been required to produce the exact same output. - -@item -Q -Cause the command to be really quiet; the command will only -generate output for serious problems. - -@item -q -Cause the command to be somewhat quiet; informational messages, -such as reports of recursion through subdirectories, are -suppressed. - -@cindex Read-only files, and -r -@item -r -Make new working files read-only. Same effect -as if the @code{$CVSREAD} environment variable is set -(@pxref{Environment variables}). The default is to -make working files writable, unless watches are on -(@pxref{Watches}). - -@item -s @var{variable}=@var{value} -Set a user variable (@pxref{Variables}). - -@cindex Trace -@item -t -Trace program execution; display messages showing the steps of -@sc{cvs} activity. Particularly useful with @samp{-n} to explore the -potential impact of an unfamiliar command. - -@item -v -@item --version -Display version and copyright information for @sc{cvs}. - -@cindex CVSREAD, overriding -@cindex Overriding CVSREAD -@item -w -Make new working files read-write. Overrides the -setting of the @code{$CVSREAD} environment variable. -Files are created read-write by default, unless @code{$CVSREAD} is -set or @samp{-r} is given. -@c Note that -w only overrides -r and CVSREAD; it has -@c no effect on files which are readonly because of -@c "cvs watch on". My guess is that is the way it -@c should be (or should "cvs -w get" on a watched file -@c be the same as a get and a cvs edit?), but I'm not -@c completely sure whether to document it this way. - -@item -x -@cindex Encryption -Encrypt all communication between the client and the -server. Only has an effect on the @sc{cvs} client. As -of this writing, this is only implemented when using a -GSSAPI connection (@pxref{GSSAPI authenticated}) or a -Kerberos connection (@pxref{Kerberos authenticated}). -Enabling encryption implies that message traffic is -also authenticated. Encryption support is not -available by default; it must be enabled using a -special configure option, @file{--enable-encryption}, -when you build @sc{cvs}. - -@item -z @var{gzip-level} -@cindex Compression -@cindex Gzip -Set the compression level. -Valid levels are 1 (high speed, low compression) to -9 (low speed, high compression), or 0 to disable -compression (the default). -Only has an effect on the @sc{cvs} client. - -@end table - -@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@node Common options -@appendixsec Common command options -@cindex Common options -@cindex Right-hand options - -This section describes the @samp{command_options} that -are available across several @sc{cvs} commands. These -options are always given to the right of -@samp{cvs_command}. Not all -commands support all of these options; each option is -only supported for commands where it makes sense. -However, when a command has one of these options you -can almost always count on the same behavior of the -option as in other commands. (Other command options, -which are listed with the individual commands, may have -different behavior from one @sc{cvs} command to the other). - -@strong{The @samp{history} command is an exception; it supports -many options that conflict even with these standard options.} - -@table @code -@cindex Dates -@cindex Time -@cindex Specifying dates -@item -D @var{date_spec} -Use the most recent revision no later than @var{date_spec}. -@var{date_spec} is a single argument, a date description -specifying a date in the past. - -The specification is @dfn{sticky} when you use it to make a -private copy of a source file; that is, when you get a working -file using @samp{-D}, @sc{cvs} records the date you specified, so that -further updates in the same directory will use the same date -(for more information on sticky tags/dates, @pxref{Sticky tags}). - -@samp{-D} is available with the @code{annotate}, @code{checkout}, -@code{diff}, @code{export}, @code{history}, -@code{rdiff}, @code{rtag}, and @code{update} commands. -(The @code{history} command uses this option in a -slightly different way; @pxref{history options}). - -@c What other formats should we accept? I don't want -@c to start accepting a whole mess of non-standard -@c new formats (there are a lot which are in wide use in -@c one context or another), but practicality does -@c dictate some level of flexibility. -@c * POSIX.2 (e.g. touch, ls output, date) and other -@c POSIX and/or de facto unix standards (e.g. at). The -@c practice here is too inconsistent to be of any use. -@c * VMS dates. This is not a formal standard, but -@c there is a published specification (see SYS$ASCTIM -@c and SYS$BINTIM in the _VMS System Services Reference -@c Manual_), it is implemented consistently in VMS -@c utilities, and VMS users will expect CVS running on -@c VMS to support this format (and if we're going to do -@c that, better to make CVS support it on all -@c platforms. Maybe). -@c -@c NOTE: The tar manual has some documentation for -@c getdate.y (just for our info; we don't want to -@c attempt to document all the formats accepted by -@c getdate.y). -@c -@c One more note: In output, CVS should consistently -@c use one date format, and that format should be one that -@c it accepts in input as well. The former isn't -@c really true (see survey below), and I'm not -@c sure that either of those formats is accepted in -@c input. -@c -@c cvs log -@c current 1996/01/02 13:45:31 -@c Internet 02 Jan 1996 13:45:31 UT -@c ISO 1996-01-02 13:45:31 -@c cvs ann -@c current 02-Jan-96 -@c Internet-like 02 Jan 96 -@c ISO 96-01-02 -@c cvs status -@c current Tue Jun 11 02:54:53 1996 -@c Internet [Tue,] 11 Jun 1996 02:54:53 -@c ISO 1996-06-11 02:54:53 -@c note: date possibly should be omitted entirely for -@c other reasons. -@c cvs editors -@c current Tue Jun 11 02:54:53 1996 GMT -@c cvs history -@c current 06/11 02:54 +0000 -@c any others? -@c There is a good chance the proper solution has to -@c involve at least some level of letting the user -@c decide which format (with the default being the -@c formats CVS has always used; changing these might be -@c _very_ disruptive since scripts may very well be -@c parsing them). -@c -@c Another random bit of prior art concerning dates is -@c the strptime function which takes templates such as -@c "%m/%d/%y", and apparent a variant of getdate() -@c which also honors them. See -@c X/Open CAE Specification, System Interfaces and -@c Headers Issue 4, Version 2 (September 1994), in the -@c entry for getdate() on page 231 - -@cindex Timezone, in input -@cindex Zone, time, in input -A wide variety of date formats are supported by -@sc{cvs}. The most standard ones are ISO8601 (from the -International Standards Organization) and the Internet -e-mail standard (specified in RFC822 as amended by -RFC1123). - -@c Probably should be doing more to spell out just what -@c the rules are, rather than just giving examples. -@c But I want to keep this simple too. -@c So I don't know.... -@c A few specific issues: (1) Maybe should reassure -@c people that years after 2000 -@c work (they are in the testsuite, so they do indeed -@c work). (2) What do two digit years -@c mean? Where do we accept them? (3) Local times can -@c be ambiguous or nonexistent if they fall during the -@c hour when daylight savings time goes into or out of -@c effect. Pretty obscure, so I'm not at all sure we -@c should be documenting the behavior in that case. -ISO8601 dates have many variants but a few examples -are: - -@example -1972-09-24 -1972-09-24 20:05 -@end example -@c I doubt we really accept all ISO8601 format dates -@c (for example, decimal hours like 1972-09-24 20,2) -@c I'm not sure we should, many of them are pretty -@c bizarre and it has lots of gratuitous multiple ways -@c to specify the same thing. - -There are a lot more ISO8601 date formats, and @sc{cvs} -accepts many of them, but you probably don't want to -hear the @emph{whole} long story :-). - -@c Citing a URL here is kind of problematic given how -@c much they change and people who have old versions of -@c this manual, but in case we want to reinstate an -@c ISO8601 URL, a few are: -@c http://www.saqqara.demon.co.uk/datefmt.htm -@c http://www.cl.cam.ac.uk/~mgk25/iso-time.html -@c Citing some other ISO8601 source is probably even -@c worse :-). - -In addition to the dates allowed in Internet e-mail -itself, @sc{cvs} also allows some of the fields to be -omitted. For example: -@c FIXME: Need to figure out better, and document, -@c what we want to allow the user to omit. -@c NOTE: "omit" does not imply "reorder". -@c FIXME: Need to cite a web page describing how to get -@c RFC's. - -@example -24 Sep 1972 20:05 -24 Sep -@end example - -The date is interpreted as being in the -local timezone, unless a specific timezone is -specified. - -These two date formats are preferred. However, -@sc{cvs} currently accepts a wide variety of other date -formats. They are intentionally not documented here in -any detail, and future versions of @sc{cvs} might not -accept all of them. -@c We should document and testsuite "now" and -@c "yesterday". "now" is mentioned in the FAQ and -@c "yesterday" is mentioned in this document (and the -@c message from "cvs import" suggesting a merge -@c command). What else? Probably some/all of the "3 -@c weeks ago" family. -@c -@c Maybe at -@c some point have CVS start give warnings on "unofficial" -@c formats (many of which might be typos or user -@c misunderstandings, and/or formats people never/rarely -@c use to specify dates)? - -One such format is -@code{@var{month}/@var{day}/@var{year}}. This may -confuse people who are accustomed to having the month -and day in the other order; @samp{1/4/96} is January 4, -not April 1. - -Remember to quote the argument to the @samp{-D} -flag so that your shell doesn't interpret spaces as -argument separators. A command using the @samp{-D} -flag can look like this: - -@example -$ cvs diff -D "1 hour ago" cvs.texinfo -@end example - -@cindex Forcing a tag match -@item -f -When you specify a particular date or tag to @sc{cvs} commands, they -normally ignore files that do not contain the tag (or did not -exist prior to the date) that you specified. Use the @samp{-f} option -if you want files retrieved even when there is no match for the -tag or date. (The most recent revision of the file -will be used). - -Note that even with @samp{-f}, a tag that you specify -must exist (that is, in some file, not necessary in -every file). This is so that @sc{cvs} will continue to -give an error if you mistype a tag name. - -@need 800 -@samp{-f} is available with these commands: -@code{annotate}, @code{checkout}, @code{export}, -@code{rdiff}, @code{rtag}, and @code{update}. - -@strong{WARNING: The @code{commit} and @code{remove} -commands also have a -@samp{-f} option, but it has a different behavior for -those commands. See @ref{commit options}, and -@ref{Removing files}.} - -@item -k @var{kflag} -Alter the default processing of keywords. -See @ref{Keyword substitution}, for the meaning of -@var{kflag}. Your @var{kflag} specification is -@dfn{sticky} when you use it to create a private copy -of a source file; that is, when you use this option -with the @code{checkout} or @code{update} commands, -@sc{cvs} associates your selected @var{kflag} with the -file, and continues to use it with future update -commands on the same file until you specify otherwise. - -The @samp{-k} option is available with the @code{add}, -@code{checkout}, @code{diff}, @code{rdiff}, @code{import} and -@code{update} commands. - -@item -l -Local; run only in current working directory, rather than -recursing through subdirectories. - -Available with the following commands: @code{annotate}, @code{checkout}, -@code{commit}, @code{diff}, @code{edit}, @code{editors}, @code{export}, -@code{log}, @code{rdiff}, @code{remove}, @code{rtag}, -@code{status}, @code{tag}, @code{unedit}, @code{update}, @code{watch}, -and @code{watchers}. - -@cindex Editor, avoiding invocation of -@cindex Avoiding editor invocation -@item -m @var{message} -Use @var{message} as log information, instead of -invoking an editor. - -Available with the following commands: @code{add}, -@code{commit} and @code{import}. - -@item -n -Do not run any tag program. (A program can be -specified to run in the modules -database (@pxref{modules}); this option bypasses it). - -@strong{This is not the same as the @samp{cvs -n} -program option, which you can specify to the left of a cvs command!} - -Available with the @code{checkout}, @code{export}, -and @code{rtag} commands. - -@item -P -Prune empty directories. See @ref{Removing directories}. - -@item -p -Pipe the files retrieved from the repository to standard output, -rather than writing them in the current directory. Available -with the @code{checkout} and @code{update} commands. - -@item -R -Process directories recursively. This is on by default. - -Available with the following commands: @code{annotate}, @code{checkout}, -@code{commit}, @code{diff}, @code{edit}, @code{editors}, @code{export}, -@code{rdiff}, @code{remove}, @code{rtag}, -@code{status}, @code{tag}, @code{unedit}, @code{update}, @code{watch}, -and @code{watchers}. - -@item -r @var{tag} -@cindex HEAD, special tag -@cindex BASE, special tag -Use the revision specified by the @var{tag} argument instead of the -default @dfn{head} revision. As well as arbitrary tags defined -with the @code{tag} or @code{rtag} command, two special tags are -always available: @samp{HEAD} refers to the most recent version -available in the repository, and @samp{BASE} refers to the -revision you last checked out into the current working directory. - -@c FIXME: What does HEAD really mean? I believe that -@c the current answer is the head of the default branch -@c for all cvs commands except diff. For diff, it -@c seems to be (a) the head of the trunk (or the default -@c branch?) if there is no sticky tag, (b) the head of the -@c branch for the sticky tag, if there is a sticky tag. -@c (b) is ugly as it differs -@c from what HEAD means for other commands, but people -@c and/or scripts are quite possibly used to it. -@c See "head" tests in sanity.sh. -@c Probably the best fix is to introduce two new -@c special tags, ".thead" for the head of the trunk, -@c and ".bhead" for the head of the current branch. -@c Then deprecate HEAD. This has the advantage of -@c not surprising people with a change to HEAD, and a -@c side benefit of also phasing out the poorly-named -@c HEAD (see discussion of reserved tag names in node -@c "Tags"). Of course, .thead and .bhead should be -@c carefully implemented (with the implementation the -@c same for "diff" as for everyone else), test cases -@c written (similar to the ones in "head"), new tests -@c cases written for things like default branches, &c. - -The tag specification is sticky when you use this -@c option -with @code{checkout} or @code{update} to make your own -copy of a file: @sc{cvs} remembers the tag and continues to use it on -future update commands, until you specify otherwise (for more information -on sticky tags/dates, @pxref{Sticky tags}). - -The tag can be either a symbolic or numeric tag, as -described in @ref{Tags}, or the name of a branch, as -described in @ref{Branching and merging}. -When a command expects a specific revision, -the name of a branch is interpreted as the most recent -revision on that branch. - -Specifying the @samp{-q} global option along with the -@samp{-r} command option is often useful, to suppress -the warning messages when the @sc{rcs} file -does not contain the specified tag. - -@strong{This is not the same as the overall @samp{cvs -r} option, -which you can specify to the left of a @sc{cvs} command!} - -@samp{-r} is available with the @code{annotate}, @code{checkout}, -@code{commit}, @code{diff}, @code{history}, @code{export}, @code{rdiff}, -@code{rtag}, and @code{update} commands. - -@item -W -Specify file names that should be filtered. You can -use this option repeatedly. The spec can be a file -name pattern of the same type that you can specify in -the @file{.cvswrappers} file. -Available with the following commands: @code{import}, -and @code{update}. - -@end table - -@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@node add -@appendixsec add---Add files and directories to the repository -@cindex add (subcommand) - -@itemize @bullet -@item -Synopsis: add [-k rcs-kflag] [-m message] files... -@item -Requires: repository, working directory. -@item -Changes: repository, working directory. -@end itemize - -The @code{add} command is used to present new files -and directories for addition into the @sc{cvs} -repository. When @code{add} is used on a directory, -a new directory is created in the repository -immediately. When used on a file, only the working -directory is updated. Changes to the repository are -not made until the @code{commit} command is used on -the newly added file. - -The @code{add} command also resurrects files that -have been previously removed. This can be done -before or after the @code{commit} command is used -to finalize the removal of files. Resurrected files -are restored into the working directory at the time -the @code{add} command is executed. - -@menu -* add options:: add options -* add examples:: add examples -@end menu - -@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -@node add options -@appendixsubsec add options - -These standard options are supported by @code{add} -(@pxref{Common options}, for a complete description of -them): - -@table @code -@item -k @var{kflag} -Process keywords according to @var{kflag}. See -@ref{Keyword substitution}. -This option is sticky; future updates of -this file in this working directory will use the same -@var{kflag}. The @code{status} command can be viewed -to see the sticky options. For more information on -the @code{status} command, @xref{Invoking CVS}. - -@item -m @var{message} -Use @var{message} as the log message, instead of -invoking an editor. -@end table - -@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -@node add examples -@appendixsubsec add examples - -@appendixsubsubsec Adding a directory - -@example -$ mkdir doc -$ cvs add doc -Directory /path/to/repository/doc added to the repository -@end example - -@appendixsubsubsec Adding a file - -@example - -$ >TODO -$ cvs add TODO -cvs add: scheduling file `TODO' for addition -cvs add: use 'cvs commit' to add this file permanently -@end example - -@appendixsubsubsec Undoing a @code{remove} command - -@example -$ rm -f makefile -$ cvs remove makefile -cvs remove: scheduling `makefile' for removal -cvs remove: use 'cvs commit' to remove this file permanently -$ cvs add makefile -U makefile -cvs add: makefile, version 1.2, resurrected -@end example - -@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@node admin -@appendixsec admin---Administration -@cindex Admin (subcommand) - -@itemize @bullet -@item -Requires: repository, working directory. -@item -Changes: repository. -@item -Synonym: rcs -@end itemize - -This is the @sc{cvs} interface to assorted -administrative facilities. Some of them have -questionable usefulness for @sc{cvs} but exist for -historical purposes. Some of the questionable options -are likely to disappear in the future. This command -@emph{does} work recursively, so extreme care should be -used. - -@cindex cvsadmin -On unix, if there is a group named @code{cvsadmin}, -only members of that group can run @code{cvs admin} -(except for the @code{cvs admin -k} command, which can -be run by anybody). This group should exist on the -server, or any system running the non-client/server -@sc{cvs}. To disallow @code{cvs admin} for all users, -create a group with no users in it. On NT, the -@code{cvsadmin} feature does not exist and all users -can run @code{cvs admin}. - -@menu -* admin options:: admin options -@end menu - -@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -@node admin options -@appendixsubsec admin options - -Some of these options have questionable usefulness for -@sc{cvs} but exist for historical purposes. Some even -make it impossible to use @sc{cvs} until you undo the -effect! - -@table @code -@item -A@var{oldfile} -Might not work together with @sc{cvs}. Append the -access list of @var{oldfile} to the access list of the -@sc{rcs} file. - -@item -a@var{logins} -Might not work together with @sc{cvs}. Append the -login names appearing in the comma-separated list -@var{logins} to the access list of the @sc{rcs} file. - -@item -b[@var{rev}] -Set the default branch to @var{rev}. In @sc{cvs}, you -normally do not manipulate default branches; sticky -tags (@pxref{Sticky tags}) are a better way to decide -which branch you want to work on. There is one reason -to run @code{cvs admin -b}: to revert to the vendor's -version when using vendor branches (@pxref{Reverting -local changes}). -There can be no space between @samp{-b} and its argument. -@c Hmm, we don't document the usage where rev is -@c omitted. Maybe that usage can/should be deprecated -@c (and replaced with -bHEAD or something?) (so we can toss -@c the optional argument). Note that -bHEAD does not -@c work, as of 17 Sep 1997, but probably will once "cvs -@c admin" is internal to CVS. - -@cindex Comment leader -@item -c@var{string} -Sets the comment leader to @var{string}. The comment -leader is not used by current versions of @sc{cvs} or -@sc{rcs} 5.7. Therefore, you can almost surely not -worry about it. See @ref{Keyword substitution}. - -@item -e[@var{logins}] -Might not work together with @sc{cvs}. Erase the login -names appearing in the comma-separated list -@var{logins} from the access list of the RCS file. If -@var{logins} is omitted, erase the entire access list. -There can be no space between @samp{-e} and its argument. - -@item -I -Run interactively, even if the standard input is not a -terminal. This option does not work with the -client/server @sc{cvs} and is likely to disappear in -a future release of @sc{cvs}. - -@item -i -Useless with @sc{cvs}. This creates and initializes a -new @sc{rcs} file, without depositing a revision. With -@sc{cvs}, add files with the @code{cvs add} command -(@pxref{Adding files}). - -@item -k@var{subst} -Set the default keyword -substitution to @var{subst}. See @ref{Keyword -substitution}. Giving an explicit @samp{-k} option to -@code{cvs update}, @code{cvs export}, or @code{cvs -checkout} overrides this default. - -@item -l[@var{rev}] -Lock the revision with number @var{rev}. If a branch -is given, lock the latest revision on that branch. If -@var{rev} is omitted, lock the latest revision on the -default branch. There can be no space between -@samp{-l} and its argument. - -This can be used in conjunction with the -@file{rcslock.pl} script in the @file{contrib} -directory of the @sc{cvs} source distribution to -provide reserved checkouts (where only one user can be -editing a given file at a time). See the comments in -that file for details (and see the @file{README} file -in that directory for disclaimers about the unsupported -nature of contrib). According to comments in that -file, locking must set to strict (which is the default). - -@item -L -Set locking to strict. Strict locking means that the -owner of an RCS file is not exempt from locking for -checkin. For use with @sc{cvs}, strict locking must be -set; see the discussion under the @samp{-l} option above. - -@cindex Changing a log message -@cindex Replacing a log message -@cindex Correcting a log message -@cindex Fixing a log message -@cindex Log message, correcting -@item -m@var{rev}:@var{msg} -Replace the log message of revision @var{rev} with -@var{msg}. - -@c The rcs -M option, to suppress sending mail, has never been -@c documented as a cvs admin option. - -@item -N@var{name}[:[@var{rev}]] -Act like @samp{-n}, except override any previous -assignment of @var{name}. For use with magic branches, -see @ref{Magic branch numbers}. - -@item -n@var{name}[:[@var{rev}]] -Associate the symbolic name @var{name} with the branch -or revision @var{rev}. It is normally better to use -@samp{cvs tag} or @samp{cvs rtag} instead. Delete the -symbolic name if both @samp{:} and @var{rev} are -omitted; otherwise, print an error message if -@var{name} is already associated with another number. -If @var{rev} is symbolic, it is expanded before -association. A @var{rev} consisting of a branch number -followed by a @samp{.} stands for the current latest -revision in the branch. A @samp{:} with an empty -@var{rev} stands for the current latest revision on the -default branch, normally the trunk. For example, -@samp{cvs admin -n@var{name}:} associates @var{name} with the -current latest revision of all the RCS files; -this contrasts with @samp{cvs admin -n@var{name}:$} which -associates @var{name} with the revision numbers -extracted from keyword strings in the corresponding -working files. - -@cindex Deleting revisions -@cindex Outdating revisions -@cindex Saving space -@item -o@var{range} -Deletes (@dfn{outdates}) the revisions given by -@var{range}. - -Note that this command can be quite dangerous unless -you know @emph{exactly} what you are doing (for example -see the warnings below about how the -@var{rev1}:@var{rev2} syntax is confusing). - -If you are short on disc this option might help you. -But think twice before using it---there is no way short -of restoring the latest backup to undo this command! -If you delete different revisions than you planned, -either due to carelessness or (heaven forbid) a @sc{cvs} -bug, there is no opportunity to correct the error -before the revisions are deleted. It probably would be -a good idea to experiment on a copy of the repository -first. - -Specify @var{range} in one of the following ways: - -@table @code -@item @var{rev1}::@var{rev2} -Collapse all revisions between rev1 and rev2, so that -@sc{cvs} only stores the differences associated with going -from rev1 to rev2, not intermediate steps. For -example, after @samp{-o 1.3::1.5} one can retrieve -revision 1.3, revision 1.5, or the differences to get -from 1.3 to 1.5, but not the revision 1.4, or the -differences between 1.3 and 1.4. Other examples: -@samp{-o 1.3::1.4} and @samp{-o 1.3::1.3} have no -effect, because there are no intermediate revisions to -remove. - -@item ::@var{rev} -Collapse revisions between the beginning of the branch -containing @var{rev} and @var{rev} itself. The -branchpoint and @var{rev} are left intact. For -example, @samp{-o ::1.3.2.6} deletes revision 1.3.2.1, -revision 1.3.2.5, and everything in between, but leaves -1.3 and 1.3.2.6 intact. - -@item @var{rev}:: -Collapse revisions between @var{rev} and the end of the -branch containing @var{rev}. Revision @var{rev} is -left intact but the head revision is deleted. - -@item @var{rev} -Delete the revision @var{rev}. For example, @samp{-o -1.3} is equivalent to @samp{-o 1.2::1.4}. - -@item @var{rev1}:@var{rev2} -Delete the revisions from @var{rev1} to @var{rev2}, -inclusive, on the same branch. One will not be able to -retrieve @var{rev1} or @var{rev2} or any of the -revisions in between. For example, the command -@samp{cvs admin -oR_1_01:R_1_02 .} is rarely useful. -It means to delete revisions up to, and including, the -tag R_1_02. But beware! If there are files that have not -changed between R_1_02 and R_1_03 the file will have -@emph{the same} numerical revision number assigned to -the tags R_1_02 and R_1_03. So not only will it be -impossible to retrieve R_1_02; R_1_03 will also have to -be restored from the tapes! In most cases you want to -specify @var{rev1}::@var{rev2} instead. - -@item :@var{rev} -Delete revisions from the beginning of the -branch containing @var{rev} up to and including -@var{rev}. - -@item @var{rev}: -Delete revisions from revision @var{rev}, including -@var{rev} itself, to the end of the branch containing -@var{rev}. -@end table - -None of the revisions to be deleted may have -branches or locks. - -If any of the revisions to be deleted have symbolic -names, and one specifies one of the @samp{::} syntaxes, -then @sc{cvs} will give an error and not delete any -revisions. If you really want to delete both the -symbolic names and the revisions, first delete the -symbolic names with @code{cvs tag -d}, then run -@code{cvs admin -o}. If one specifies the -non-@samp{::} syntaxes, then @sc{cvs} will delete the -revisions but leave the symbolic names pointing to -nonexistent revisions. This behavior is preserved for -compatibility with previous versions of @sc{cvs}, but -because it isn't very useful, in the future it may -change to be like the @samp{::} case. - -Due to the way @sc{cvs} handles branches @var{rev} -cannot be specified symbolically if it is a branch. -See @ref{Magic branch numbers} for an explanation. -@c FIXME: is this still true? I suspect not. - -Make sure that no-one has checked out a copy of the -revision you outdate. Strange things will happen if he -starts to edit it and tries to check it back in. For -this reason, this option is not a good way to take back -a bogus commit; commit a new revision undoing the bogus -change instead (@pxref{Merging two revisions}). - -@item -q -Run quietly; do not print diagnostics. - -@item -s@var{state}[:@var{rev}] -Useful with @sc{cvs}. Set the state attribute of the -revision @var{rev} to @var{state}. If @var{rev} is a -branch number, assume the latest revision on that -branch. If @var{rev} is omitted, assume the latest -revision on the default branch. Any identifier is -acceptable for @var{state}. A useful set of states is -@samp{Exp} (for experimental), @samp{Stab} (for -stable), and @samp{Rel} (for released). By default, -the state of a new revision is set to @samp{Exp} when -it is created. The state is visible in the output from -@var{cvs log} (@pxref{log}), and in the -@samp{$@splitrcskeyword{Log}$} and @samp{$@splitrcskeyword{State}$} keywords -(@pxref{Keyword substitution}). Note that @sc{cvs} -uses the @code{dead} state for its own purposes (@pxref{Attic}); to -take a file to or from the @code{dead} state use -commands like @code{cvs remove} and @code{cvs add} -(@pxref{Adding and removing}), not @code{cvs admin -s}. - -@item -t[@var{file}] -Useful with @sc{cvs}. Write descriptive text from the -contents of the named @var{file} into the RCS file, -deleting the existing text. The @var{file} pathname -may not begin with @samp{-}. The descriptive text can be seen in the -output from @samp{cvs log} (@pxref{log}). -There can be no space between @samp{-t} and its argument. - -If @var{file} is omitted, -obtain the text from standard input, terminated by -end-of-file or by a line containing @samp{.} by itself. -Prompt for the text if interaction is possible; see -@samp{-I}. - -@item -t-@var{string} -Similar to @samp{-t@var{file}}. Write descriptive text -from the @var{string} into the @sc{rcs} file, deleting -the existing text. -There can be no space between @samp{-t} and its argument. - -@c The rcs -T option, do not update last-mod time for -@c minor changes, has never been documented as a -@c cvs admin option. - -@item -U -Set locking to non-strict. Non-strict locking means -that the owner of a file need not lock a revision for -checkin. For use with @sc{cvs}, strict locking must be -set; see the discussion under the @samp{-l} option -above. - -@item -u[@var{rev}] -See the option @samp{-l} above, for a discussion of -using this option with @sc{cvs}. Unlock the revision -with number @var{rev}. If a branch is given, unlock -the latest revision on that branch. If @var{rev} is -omitted, remove the latest lock held by the caller. -Normally, only the locker of a revision may unlock it; -somebody else unlocking a revision breaks the lock. -This causes the original locker to be sent a @code{commit} -notification (@pxref{Getting Notified}). -There can be no space between @samp{-u} and its argument. - -@item -V@var{n} -In previous versions of @sc{cvs}, this option meant to -write an @sc{rcs} file which would be acceptable to -@sc{rcs} version @var{n}, but it is now obsolete and -specifying it will produce an error. -@c Note that -V without an argument has never been -@c documented as a cvs admin option. - -@item -x@var{suffixes} -In previous versions of @sc{cvs}, this was documented -as a way of specifying the names of the @sc{rcs} -files. However, @sc{cvs} has always required that the -@sc{rcs} files used by @sc{cvs} end in @samp{,v}, so -this option has never done anything useful. - -@c The rcs -z option, to specify the timezone, has -@c never been documented as a cvs admin option. -@end table - - -@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@node annotate -@appendixsec annotate---What revision modified each line of a file? -@cindex annotate (subcommand) - -@itemize @bullet -@item -Synopsis: annotate [options] files@dots{} -@item -Requires: repository. -@item -Synonym: blame -@item -Changes: nothing. -@end itemize - -For each file in @var{files}, print the head revision -of the trunk, together with information on the last -modification for each line. - -@menu -* annotate options:: annotate options -* annotate example:: annotate example -@end menu - -@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -@node annotate options -@appendixsubsec annotate options - -These standard options are supported by @code{annotate} -(@pxref{Common options} for a complete description of -them): - -@table @code -@item -l -Local directory only, no recursion. - -@item -R -Process directories recursively. - -@item -f -Use head revision if tag/date not found. - -@item -F -Annotate binary files. - -@item -r @var{revision} -Annotate file as of specified revision/tag. - -@item -D @var{date} -Annotate file as of specified date. -@end table - -@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -@node annotate example -@appendixsubsec annotate example - -For example: - -@example -$ cvs annotate ssfile -Annotations for ssfile -*************** -1.1 (mary 27-Mar-96): ssfile line 1 -1.2 (joe 28-Mar-96): ssfile line 2 -@end example - -The file @file{ssfile} currently contains two lines. -The @code{ssfile line 1} line was checked in by -@code{mary} on March 27. Then, on March 28, @code{joe} -added a line @code{ssfile line 2}, without modifying -the @code{ssfile line 1} line. This report doesn't -tell you anything about lines which have been deleted -or replaced; you need to use @code{cvs diff} for that -(@pxref{diff}). - -The options to @code{cvs annotate} are listed in -@ref{Invoking CVS}, and can be used to select the files -and revisions to annotate. The options are described -in more detail there and in @ref{Common options}. - -@c FIXME: maybe an example using the options? Just -@c what it means to select a revision might be worth a -@c few words of explanation ("you want to see who -@c changed this line *before* 1.4"...). - - -@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@node checkout -@appendixsec checkout---Check out sources for editing -@cindex checkout (subcommand) -@cindex co (subcommand) - -@itemize @bullet -@item -Synopsis: checkout [options] modules@dots{} -@item -Requires: repository. -@item -Changes: working directory. -@item -Synonyms: co, get -@end itemize - -Create or update a working directory containing copies of the -source files specified by @var{modules}. You must execute -@code{checkout} before using most of the other @sc{cvs} -commands, since most of them operate on your working -directory. - -The @var{modules} are either -symbolic names for some -collection of source directories and files, or paths to -directories or files in the repository. The symbolic -names are defined in the @samp{modules} file. -See @ref{modules}. -@c Needs an example, particularly of the non-"modules" -@c case but probably of both. - -@c FIXME: this seems like a very odd place to introduce -@c people to how CVS works. The bit about unreserved -@c checkouts is also misleading as it depends on how -@c things are set up. -Depending on the modules you specify, @code{checkout} may -recursively create directories and populate them with -the appropriate source files. You can then edit these -source files at any time (regardless of whether other -software developers are editing their own copies of the -sources); update them to include new changes applied by -others to the source repository; or commit your work as -a permanent change to the source repository. - -Note that @code{checkout} is used to create -directories. The top-level directory created is always -added to the directory where @code{checkout} is -invoked, and usually has the same name as the specified -module. In the case of a module alias, the created -sub-directory may have a different name, but you can be -sure that it will be a sub-directory, and that -@code{checkout} will show the relative path leading to -each file as it is extracted into your private work -area (unless you specify the @samp{-Q} global option). - -The files created by @code{checkout} are created -read-write, unless the @samp{-r} option to @sc{cvs} -(@pxref{Global options}) is specified, the -@code{CVSREAD} environment variable is specified -(@pxref{Environment variables}), or a watch is in -effect for that file (@pxref{Watches}). - -Note that running @code{checkout} on a directory that was already -built by a prior @code{checkout} is also permitted. -This is similar to specifying the @samp{-d} option -to the @code{update} command in the sense that new -directories that have been created in the repository -will appear in your work area. -However, @code{checkout} takes a module name whereas -@code{update} takes a directory name. Also -to use @code{checkout} this way it must be run from the -top level directory (where you originally ran -@code{checkout} from), so before you run -@code{checkout} to update an existing directory, don't -forget to change your directory to the top level -directory. - -For the output produced by the @code{checkout} command, -@xref{update output}. - -@menu -* checkout options:: checkout options -* checkout examples:: checkout examples -@end menu - -@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -@node checkout options -@appendixsubsec checkout options - -These standard options are supported by @code{checkout} -(@pxref{Common options} for a complete description of -them): - -@table @code -@item -D @var{date} -Use the most recent revision no later than @var{date}. -This option is sticky, and implies @samp{-P}. See -@ref{Sticky tags} for more information on sticky tags/dates. - -@item -f -Only useful with the @samp{-D @var{date}} or @samp{-r -@var{tag}} flags. If no matching revision is found, -retrieve the most recent revision (instead of ignoring -the file). - -@item -k @var{kflag} -Process keywords according to @var{kflag}. See -@ref{Keyword substitution}. -This option is sticky; future updates of -this file in this working directory will use the same -@var{kflag}. The @code{status} command can be viewed -to see the sticky options. See @ref{Invoking CVS} for -more information on the @code{status} command. - -@item -l -Local; run only in current working directory. - -@item -n -Do not run any checkout program (as specified -with the @samp{-o} option in the modules file; -@pxref{modules}). - -@item -P -Prune empty directories. See @ref{Moving directories}. - -@item -p -Pipe files to the standard output. - -@item -R -Checkout directories recursively. This option is on by default. - -@item -r @var{tag} -Use revision @var{tag}. This option is sticky, and implies @samp{-P}. -See @ref{Sticky tags}, for more information on sticky tags/dates. -@end table - -In addition to those, you can use these special command -options with @code{checkout}: - -@table @code -@item -A -Reset any sticky tags, dates, or @samp{-k} options. -Does not reset sticky @samp{-k} options on modified files. -See @ref{Sticky tags} for more information on sticky tags/dates. - -@item -c -Copy the module file, sorted, to the standard output, -instead of creating or modifying any files or -directories in your working directory. - -@item -d @var{dir} -Create a directory called @var{dir} for the working -files, instead of using the module name. In general, -using this flag is equivalent to using @samp{mkdir -@var{dir}; cd @var{dir}} followed by the checkout -command without the @samp{-d} flag. - -There is an important exception, however. It is very -convenient when checking out a single item to have the -output appear in a directory that doesn't contain empty -intermediate directories. In this case @emph{only}, -@sc{cvs} tries to ``shorten'' pathnames to avoid those empty -directories. - -For example, given a module @samp{foo} that contains -the file @samp{bar.c}, the command @samp{cvs co -d dir -foo} will create directory @samp{dir} and place -@samp{bar.c} inside. Similarly, given a module -@samp{bar} which has subdirectory @samp{baz} wherein -there is a file @samp{quux.c}, the command @samp{cvs co --d dir bar/baz} will create directory @samp{dir} and -place @samp{quux.c} inside. - -Using the @samp{-N} flag will defeat this behavior. -Given the same module definitions above, @samp{cvs co --N -d dir foo} will create directories @samp{dir/foo} -and place @samp{bar.c} inside, while @samp{cvs co -N -d -dir bar/baz} will create directories @samp{dir/bar/baz} -and place @samp{quux.c} inside. - -@item -j @var{tag} -With two @samp{-j} options, merge changes from the -revision specified with the first @samp{-j} option to -the revision specified with the second @samp{j} option, -into the working directory. - -With one @samp{-j} option, merge changes from the -ancestor revision to the revision specified with the -@samp{-j} option, into the working directory. The -ancestor revision is the common ancestor of the -revision which the working directory is based on, and -the revision specified in the @samp{-j} option. - -In addition, each -j option can contain an optional -date specification which, when used with branches, can -limit the chosen revision to one within a specific -date. An optional date is specified by adding a colon -(:) to the tag: -@samp{-j@var{Symbolic_Tag}:@var{Date_Specifier}}. - -See @ref{Branching and merging}. - -@item -N -Only useful together with @samp{-d @var{dir}}. With -this option, @sc{cvs} will not ``shorten'' module paths -in your working directory when you check out a single -module. See the @samp{-d} flag for examples and a -discussion. - -@item -s -Like @samp{-c}, but include the status of all modules, -and sort it by the status string. See @ref{modules}, for -info about the @samp{-s} option that is used inside the -modules file to set the module status. -@end table - -@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -@node checkout examples -@appendixsubsec checkout examples - -Get a copy of the module @samp{tc}: - -@example -$ cvs checkout tc -@end example - -Get a copy of the module @samp{tc} as it looked one day -ago: - -@example -$ cvs checkout -D yesterday tc -@end example - -@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@node commit -@appendixsec commit---Check files into the repository -@cindex commit (subcommand) - -@itemize @bullet -@item -Synopsis: commit [-lRf] [-m 'log_message' | --F file] [-r revision] [files@dots{}] -@item -Requires: working directory, repository. -@item -Changes: repository. -@item -Synonym: ci -@end itemize - -Use @code{commit} when you want to incorporate changes -from your working source files into the source -repository. - -If you don't specify particular files to commit, all of -the files in your working current directory are -examined. @code{commit} is careful to change in the -repository only those files that you have really -changed. By default (or if you explicitly specify the -@samp{-R} option), files in subdirectories are also -examined and committed if they have changed; you can -use the @samp{-l} option to limit @code{commit} to the -current directory only. - -@code{commit} verifies that the selected files are up -to date with the current revisions in the source -repository; it will notify you, and exit without -committing, if any of the specified files must be made -current first with @code{update} (@pxref{update}). -@code{commit} does not call the @code{update} command -for you, but rather leaves that for you to do when the -time is right. - -When all is well, an editor is invoked to allow you to -enter a log message that will be written to one or more -logging programs (@pxref{modules}, and @pxref{loginfo}) -and placed in the @sc{rcs} file inside the -repository. This log message can be retrieved with the -@code{log} command; @xref{log}. You can specify the -log message on the command line with the @samp{-m -@var{message}} option, and thus avoid the editor invocation, -or use the @samp{-F @var{file}} option to specify -that the argument file contains the log message. - -@menu -* commit options:: commit options -* commit examples:: commit examples -@end menu - -@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -@node commit options -@appendixsubsec commit options - -These standard options are supported by @code{commit} -(@pxref{Common options} for a complete description of -them): - -@table @code -@item -l -Local; run only in current working directory. - -@item -R -Commit directories recursively. This is on by default. - -@item -r @var{revision} -Commit to @var{revision}. @var{revision} must be -either a branch, or a revision on the main trunk that -is higher than any existing revision number -(@pxref{Assigning revisions}). You -cannot commit to a specific revision on a branch. -@c FIXME: Need xref for branch case. -@end table - -@code{commit} also supports these options: - -@table @code -@item -F @var{file} -Read the log message from @var{file}, instead -of invoking an editor. - -@item -f -Note that this is not the standard behavior of -the @samp{-f} option as defined in @ref{Common options}. - -Force @sc{cvs} to commit a new revision even if you haven't -made any changes to the file. If the current revision -of @var{file} is 1.7, then the following two commands -are equivalent: - -@example -$ cvs commit -f @var{file} -$ cvs commit -r 1.8 @var{file} -@end example - -@c This is odd, but it's how CVS has worked for some -@c time. -The @samp{-f} option disables recursion (i.e., it -implies @samp{-l}). To force @sc{cvs} to commit a new -revision for all files in all subdirectories, you must -use @samp{-f -R}. - -@item -m @var{message} -Use @var{message} as the log message, instead of -invoking an editor. -@end table - -@need 2000 -@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -@node commit examples -@appendixsubsec commit examples - -@c FIXME: this material wants to be somewhere -@c in "Branching and merging". - -@appendixsubsubsec Committing to a branch - -You can commit to a branch revision (one that has an -even number of dots) with the @samp{-r} option. To -create a branch revision, use the @samp{-b} option -of the @code{rtag} or @code{tag} commands -(@pxref{Branching and merging}). Then, either @code{checkout} or -@code{update} can be used to base your sources on the -newly created branch. From that point on, all -@code{commit} changes made within these working sources -will be automatically added to a branch revision, -thereby not disturbing main-line development in any -way. For example, if you had to create a patch to the -1.2 version of the product, even though the 2.0 version -is already under development, you might do: - -@example -$ cvs rtag -b -r FCS1_2 FCS1_2_Patch product_module -$ cvs checkout -r FCS1_2_Patch product_module -$ cd product_module -[[ hack away ]] -$ cvs commit -@end example - -@noindent -This works automatically since the @samp{-r} option is -sticky. - -@appendixsubsubsec Creating the branch after editing - -Say you have been working on some extremely -experimental software, based on whatever revision you -happened to checkout last week. If others in your -group would like to work on this software with you, but -without disturbing main-line development, you could -commit your change to a new branch. Others can then -checkout your experimental stuff and utilize the full -benefit of @sc{cvs} conflict resolution. The scenario might -look like: - -@c FIXME: Should we be recommending tagging the branchpoint? -@example -[[ hacked sources are present ]] -$ cvs tag -b EXPR1 -$ cvs update -r EXPR1 -$ cvs commit -@end example - -The @code{update} command will make the @samp{-r -EXPR1} option sticky on all files. Note that your -changes to the files will never be removed by the -@code{update} command. The @code{commit} will -automatically commit to the correct branch, because the -@samp{-r} is sticky. You could also do like this: - -@c FIXME: Should we be recommending tagging the branchpoint? -@example -[[ hacked sources are present ]] -$ cvs tag -b EXPR1 -$ cvs commit -r EXPR1 -@end example - -@noindent -but then, only those files that were changed by you -will have the @samp{-r EXPR1} sticky flag. If you hack -away, and commit without specifying the @samp{-r EXPR1} -flag, some files may accidentally end up on the main -trunk. - -To work with you on the experimental change, others -would simply do - -@example -$ cvs checkout -r EXPR1 whatever_module -@end example - -@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@node diff -@appendixsec diff---Show differences between revisions -@cindex diff (subcommand) - -@itemize @bullet -@item -Synopsis: diff [-lR] [-k kflag] [format_options] [[-r rev1 | -D date1] [-r rev2 | -D date2]] [files@dots{}] -@item -Requires: working directory, repository. -@item -Changes: nothing. -@end itemize - -The @code{diff} command is used to compare different -revisions of files. The default action is to compare -your working files with the revisions they were based -on, and report any differences that are found. - -If any file names are given, only those files are -compared. If any directories are given, all files -under them will be compared. - -The exit status for diff is different than for other -@sc{cvs} commands; for details @xref{Exit status}. - -@menu -* diff options:: diff options -* diff examples:: diff examples -@end menu - -@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -@node diff options -@appendixsubsec diff options - -These standard options are supported by @code{diff} -(@pxref{Common options} for a complete description of -them): - -@table @code -@item -D @var{date} -Use the most recent revision no later than @var{date}. -See @samp{-r} for how this affects the comparison. - -@item -k @var{kflag} -Process keywords according to @var{kflag}. See -@ref{Keyword substitution}. - -@item -l -Local; run only in current working directory. - -@item -R -Examine directories recursively. This option is on by -default. - -@item -r @var{tag} -Compare with revision @var{tag}. Zero, one or two -@samp{-r} options can be present. With no @samp{-r} -option, the working file will be compared with the -revision it was based on. With one @samp{-r}, that -revision will be compared to your current working file. -With two @samp{-r} options those two revisions will be -compared (and your working file will not affect the -outcome in any way). -@c We should be a lot more explicit, with examples, -@c about the difference between "cvs diff" and "cvs -@c diff -r HEAD". This often confuses new users. - -One or both @samp{-r} options can be replaced by a -@samp{-D @var{date}} option, described above. -@end table - -@c Conceptually, this is a disaster. There are 3 -@c zillion diff formats that we support via the diff -@c library. It is not obvious to me that we should -@c document them all. Maybe just the most common ones -@c like -c and -u, and think about phasing out the -@c obscure ones. -@c FIXCVS: also should be a way to specify an external -@c diff program (which can be different for different -@c file types) and pass through -@c arbitrary options, so that the user can do -@c "--pass=-Z --pass=foo" or something even if CVS -@c doesn't know about the "-Z foo" option to diff. -@c This would fit nicely with deprecating/eliminating -@c the obscure options of the diff library, because it -@c would let people specify an external GNU diff if -@c they are into that sort of thing. -The following options specify the format of the -output. They have the same meaning as in GNU diff. -Most options have two equivalent names, one of which is a single letter -preceded by @samp{-}, and the other of which is a long name preceded by -@samp{--}. - -@table @samp -@item -@var{lines} -Show @var{lines} (an integer) lines of context. This option does not -specify an output format by itself; it has no effect unless it is -combined with @samp{-c} or @samp{-u}. This option is obsolete. For proper -operation, @code{patch} typically needs at least two lines of context. - -@item -a -Treat all files as text and compare them line-by-line, even if they -do not seem to be text. - -@item -b -Ignore trailing white space and consider all other sequences of one or -more white space characters to be equivalent. - -@item -B -Ignore changes that just insert or delete blank lines. - -@item --binary -Read and write data in binary mode. - -@item --brief -Report only whether the files differ, not the details of the -differences. - -@item -c -Use the context output format. - -@item -C @var{lines} -@itemx --context@r{[}=@var{lines}@r{]} -Use the context output format, showing @var{lines} (an integer) lines of -context, or three if @var{lines} is not given. -For proper operation, @code{patch} typically needs at least two lines of -context. - -@item --changed-group-format=@var{format} -Use @var{format} to output a line group containing differing lines from -both files in if-then-else format. See @ref{Line group formats}. - -@item -d -Change the algorithm to perhaps find a smaller set of changes. This makes -@code{diff} slower (sometimes much slower). - -@item -e -@itemx --ed -Make output that is a valid @code{ed} script. - -@item --expand-tabs -Expand tabs to spaces in the output, to preserve the alignment of tabs -in the input files. - -@item -f -Make output that looks vaguely like an @code{ed} script but has changes -in the order they appear in the file. - -@item -F @var{regexp} -In context and unified format, for each hunk of differences, show some -of the last preceding line that matches @var{regexp}. - -@item --forward-ed -Make output that looks vaguely like an @code{ed} script but has changes -in the order they appear in the file. - -@item -H -Use heuristics to speed handling of large files that have numerous -scattered small changes. - -@item --horizon-lines=@var{lines} -Do not discard the last @var{lines} lines of the common prefix -and the first @var{lines} lines of the common suffix. - -@item -i -Ignore changes in case; consider upper- and lower-case letters -equivalent. - -@item -I @var{regexp} -Ignore changes that just insert or delete lines that match @var{regexp}. - -@item --ifdef=@var{name} -Make merged if-then-else output using @var{name}. - -@item --ignore-all-space -Ignore white space when comparing lines. - -@item --ignore-blank-lines -Ignore changes that just insert or delete blank lines. - -@item --ignore-case -Ignore changes in case; consider upper- and lower-case to be the same. - -@item --ignore-matching-lines=@var{regexp} -Ignore changes that just insert or delete lines that match @var{regexp}. - -@item --ignore-space-change -Ignore trailing white space and consider all other sequences of one or -more white space characters to be equivalent. - -@item --initial-tab -Output a tab rather than a space before the text of a line in normal or -context format. This causes the alignment of tabs in the line to look -normal. - -@item -L @var{label} -Use @var{label} instead of the file name in the context format -and unified format headers. - -@item --label=@var{label} -Use @var{label} instead of the file name in the context format -and unified format headers. - -@item --left-column -Print only the left column of two common lines in side by side format. - -@item --line-format=@var{format} -Use @var{format} to output all input lines in if-then-else format. -See @ref{Line formats}. - -@item --minimal -Change the algorithm to perhaps find a smaller set of changes. This -makes @code{diff} slower (sometimes much slower). - -@item -n -Output RCS-format diffs; like @samp{-f} except that each command -specifies the number of lines affected. - -@item -N -@itemx --new-file -In directory comparison, if a file is found in only one directory, -treat it as present but empty in the other directory. - -@item --new-group-format=@var{format} -Use @var{format} to output a group of lines taken from just the second -file in if-then-else format. See @ref{Line group formats}. - -@item --new-line-format=@var{format} -Use @var{format} to output a line taken from just the second file in -if-then-else format. See @ref{Line formats}. - -@item --old-group-format=@var{format} -Use @var{format} to output a group of lines taken from just the first -file in if-then-else format. See @ref{Line group formats}. - -@item --old-line-format=@var{format} -Use @var{format} to output a line taken from just the first file in -if-then-else format. See @ref{Line formats}. - -@item -p -Show which C function each change is in. - -@item --rcs -Output RCS-format diffs; like @samp{-f} except that each command -specifies the number of lines affected. - -@item --report-identical-files -@itemx -s -Report when two files are the same. - -@item --show-c-function -Show which C function each change is in. - -@item --show-function-line=@var{regexp} -In context and unified format, for each hunk of differences, show some -of the last preceding line that matches @var{regexp}. - -@item --side-by-side -Use the side by side output format. - -@item --speed-large-files -Use heuristics to speed handling of large files that have numerous -scattered small changes. - -@item --suppress-common-lines -Do not print common lines in side by side format. - -@item -t -Expand tabs to spaces in the output, to preserve the alignment of tabs -in the input files. - -@item -T -Output a tab rather than a space before the text of a line in normal or -context format. This causes the alignment of tabs in the line to look -normal. - -@item --text -Treat all files as text and compare them line-by-line, even if they -do not appear to be text. - -@item -u -Use the unified output format. - -@item --unchanged-group-format=@var{format} -Use @var{format} to output a group of common lines taken from both files -in if-then-else format. @xref{Line group formats}. - -@item --unchanged-line-format=@var{format} -Use @var{format} to output a line common to both files in if-then-else -format. @xref{Line formats}. - -@item -U @var{lines} -@itemx --unified@r{[}=@var{lines}@r{]} -Use the unified output format, showing @var{lines} (an integer) lines of -context, or three if @var{lines} is not given. -For proper operation, @code{patch} typically needs at least two lines of -context. - -@item -w -Ignore white space when comparing lines. - -@item -W @var{columns} -@itemx --width=@var{columns} -Use an output width of @var{columns} in side by side format. - -@item -y -Use the side by side output format. -@end table - -@menu -* Line group formats:: Line group formats -* Line formats:: Line formats -@end menu - -@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -@node Line group formats -@appendixsubsubsec Line group formats - -Line group formats let you specify formats suitable for many -applications that allow if-then-else input, including programming -languages and text formatting languages. A line group format specifies -the output format for a contiguous group of similar lines. - -For example, the following command compares the TeX file @file{myfile} -with the original version from the repository, -and outputs a merged file in which old regions are -surrounded by @samp{\begin@{em@}}-@samp{\end@{em@}} lines, and new -regions are surrounded by @samp{\begin@{bf@}}-@samp{\end@{bf@}} lines. - -@example -cvs diff \ - --old-group-format='\begin@{em@} -%<\end@{em@} -' \ - --new-group-format='\begin@{bf@} -%>\end@{bf@} -' \ - myfile -@end example - -The following command is equivalent to the above example, but it is a -little more verbose, because it spells out the default line group formats. - -@example -cvs diff \ - --old-group-format='\begin@{em@} -%<\end@{em@} -' \ - --new-group-format='\begin@{bf@} -%>\end@{bf@} -' \ - --unchanged-group-format='%=' \ - --changed-group-format='\begin@{em@} -%<\end@{em@} -\begin@{bf@} -%>\end@{bf@} -' \ - myfile -@end example - -Here is a more advanced example, which outputs a diff listing with -headers containing line numbers in a ``plain English'' style. - -@example -cvs diff \ - --unchanged-group-format='' \ - --old-group-format='-------- %dn line%(n=1?:s) deleted at %df: -%<' \ - --new-group-format='-------- %dN line%(N=1?:s) added after %de: -%>' \ - --changed-group-format='-------- %dn line%(n=1?:s) changed at %df: -%<-------- to: -%>' \ - myfile -@end example - -To specify a line group format, use one of the options -listed below. You can specify up to four line group formats, one for -each kind of line group. You should quote @var{format}, because it -typically contains shell metacharacters. - -@table @samp -@item --old-group-format=@var{format} -These line groups are hunks containing only lines from the first file. -The default old group format is the same as the changed group format if -it is specified; otherwise it is a format that outputs the line group as-is. - -@item --new-group-format=@var{format} -These line groups are hunks containing only lines from the second -file. The default new group format is same as the changed group -format if it is specified; otherwise it is a format that outputs the -line group as-is. - -@item --changed-group-format=@var{format} -These line groups are hunks containing lines from both files. The -default changed group format is the concatenation of the old and new -group formats. - -@item --unchanged-group-format=@var{format} -These line groups contain lines common to both files. The default -unchanged group format is a format that outputs the line group as-is. -@end table - -In a line group format, ordinary characters represent themselves; -conversion specifications start with @samp{%} and have one of the -following forms. - -@table @samp -@item %< -stands for the lines from the first file, including the trailing newline. -Each line is formatted according to the old line format (@pxref{Line formats}). - -@item %> -stands for the lines from the second file, including the trailing newline. -Each line is formatted according to the new line format. - -@item %= -stands for the lines common to both files, including the trailing newline. -Each line is formatted according to the unchanged line format. - -@item %% -stands for @samp{%}. - -@item %c'@var{C}' -where @var{C} is a single character, stands for @var{C}. -@var{C} may not be a backslash or an apostrophe. -For example, @samp{%c':'} stands for a colon, even inside -the then-part of an if-then-else format, which a colon would -normally terminate. - -@item %c'\@var{O}' -where @var{O} is a string of 1, 2, or 3 octal digits, -stands for the character with octal code @var{O}. -For example, @samp{%c'\0'} stands for a null character. - -@item @var{F}@var{n} -where @var{F} is a @code{printf} conversion specification and @var{n} is one -of the following letters, stands for @var{n}'s value formatted with @var{F}. - -@table @samp -@item e -The line number of the line just before the group in the old file. - -@item f -The line number of the first line in the group in the old file; -equals @var{e} + 1. - -@item l -The line number of the last line in the group in the old file. - -@item m -The line number of the line just after the group in the old file; -equals @var{l} + 1. - -@item n -The number of lines in the group in the old file; equals @var{l} - @var{f} + 1. - -@item E, F, L, M, N -Likewise, for lines in the new file. - -@end table - -The @code{printf} conversion specification can be @samp{%d}, -@samp{%o}, @samp{%x}, or @samp{%X}, specifying decimal, octal, -lower case hexadecimal, or upper case hexadecimal output -respectively. After the @samp{%} the following options can appear in -sequence: a @samp{-} specifying left-justification; an integer -specifying the minimum field width; and a period followed by an -optional integer specifying the minimum number of digits. -For example, @samp{%5dN} prints the number of new lines in the group -in a field of width 5 characters, using the @code{printf} format @code{"%5d"}. - -@item (@var{A}=@var{B}?@var{T}:@var{E}) -If @var{A} equals @var{B} then @var{T} else @var{E}. -@var{A} and @var{B} are each either a decimal constant -or a single letter interpreted as above. -This format spec is equivalent to @var{T} if -@var{A}'s value equals @var{B}'s; otherwise it is equivalent to @var{E}. - -For example, @samp{%(N=0?no:%dN) line%(N=1?:s)} is equivalent to -@samp{no lines} if @var{N} (the number of lines in the group in the -new file) is 0, to @samp{1 line} if @var{N} is 1, and to @samp{%dN lines} -otherwise. -@end table - -@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -@node Line formats -@appendixsubsubsec Line formats - -Line formats control how each line taken from an input file is -output as part of a line group in if-then-else format. - -For example, the following command outputs text with a one-column -change indicator to the left of the text. The first column of output -is @samp{-} for deleted lines, @samp{|} for added lines, and a space -for unchanged lines. The formats contain newline characters where -newlines are desired on output. - -@example -cvs diff \ - --old-line-format='-%l -' \ - --new-line-format='|%l -' \ - --unchanged-line-format=' %l -' \ - myfile -@end example - -To specify a line format, use one of the following options. You should -quote @var{format}, since it often contains shell metacharacters. - -@table @samp -@item --old-line-format=@var{format} -formats lines just from the first file. - -@item --new-line-format=@var{format} -formats lines just from the second file. - -@item --unchanged-line-format=@var{format} -formats lines common to both files. - -@item --line-format=@var{format} -formats all lines; in effect, it sets all three above options simultaneously. -@end table - -In a line format, ordinary characters represent themselves; -conversion specifications start with @samp{%} and have one of the -following forms. - -@table @samp -@item %l -stands for the contents of the line, not counting its trailing -newline (if any). This format ignores whether the line is incomplete. - -@item %L -stands for the contents of the line, including its trailing newline -(if any). If a line is incomplete, this format preserves its -incompleteness. - -@item %% -stands for @samp{%}. - -@item %c'@var{C}' -where @var{C} is a single character, stands for @var{C}. -@var{C} may not be a backslash or an apostrophe. -For example, @samp{%c':'} stands for a colon. - -@item %c'\@var{O}' -where @var{O} is a string of 1, 2, or 3 octal digits, -stands for the character with octal code @var{O}. -For example, @samp{%c'\0'} stands for a null character. - -@item @var{F}n -where @var{F} is a @code{printf} conversion specification, -stands for the line number formatted with @var{F}. -For example, @samp{%.5dn} prints the line number using the -@code{printf} format @code{"%.5d"}. @xref{Line group formats}, for -more about printf conversion specifications. - -@end table - -The default line format is @samp{%l} followed by a newline character. - -If the input contains tab characters and it is important that they line -up on output, you should ensure that @samp{%l} or @samp{%L} in a line -format is just after a tab stop (e.g.@: by preceding @samp{%l} or -@samp{%L} with a tab character), or you should use the @samp{-t} or -@samp{--expand-tabs} option. - -Taken together, the line and line group formats let you specify many -different formats. For example, the following command uses a format -similar to @code{diff}'s normal format. You can tailor this command -to get fine control over @code{diff}'s output. - -@example -cvs diff \ - --old-line-format='< %l -' \ - --new-line-format='> %l -' \ - --old-group-format='%df%(f=l?:,%dl)d%dE -%<' \ - --new-group-format='%dea%dF%(F=L?:,%dL) -%>' \ - --changed-group-format='%df%(f=l?:,%dl)c%dF%(F=L?:,%dL) -%<--- -%>' \ - --unchanged-group-format='' \ - myfile -@end example - -@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -@node diff examples -@appendixsubsec diff examples - -The following line produces a Unidiff (@samp{-u} flag) -between revision 1.14 and 1.19 of -@file{backend.c}. Due to the @samp{-kk} flag no -keywords are substituted, so differences that only depend -on keyword substitution are ignored. - -@example -$ cvs diff -kk -u -r 1.14 -r 1.19 backend.c -@end example - -Suppose the experimental branch EXPR1 was based on a -set of files tagged RELEASE_1_0. To see what has -happened on that branch, the following can be used: - -@example -$ cvs diff -r RELEASE_1_0 -r EXPR1 -@end example - -A command like this can be used to produce a context -diff between two releases: - -@example -$ cvs diff -c -r RELEASE_1_0 -r RELEASE_1_1 > diffs -@end example - -If you are maintaining ChangeLogs, a command like the following -just before you commit your changes may help you write -the ChangeLog entry. All local modifications that have -not yet been committed will be printed. - -@example -$ cvs diff -u | less -@end example - -@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@node export -@appendixsec export---Export sources from CVS, similar to checkout -@cindex export (subcommand) - -@itemize @bullet -@item -Synopsis: export [-flNnR] [-r rev|-D date] [-k subst] [-d dir] module@dots{} -@item -Requires: repository. -@item -Changes: current directory. -@end itemize - -This command is a variant of @code{checkout}; use it -when you want a copy of the source for module without -the @sc{cvs} administrative directories. For example, you -might use @code{export} to prepare source for shipment -off-site. This command requires that you specify a -date or tag (with @samp{-D} or @samp{-r}), so that you -can count on reproducing the source you ship to others -(and thus it always prunes empty directories). - -One often would like to use @samp{-kv} with @code{cvs -export}. This causes any keywords to be -expanded such that an import done at some other site -will not lose the keyword revision information. But be -aware that doesn't handle an export containing binary -files correctly. Also be aware that after having used -@samp{-kv}, one can no longer use the @code{ident} -command (which is part of the @sc{rcs} suite---see -ident(1)) which looks for keyword strings. If -you want to be able to use @code{ident} you must not -use @samp{-kv}. - -@menu -* export options:: export options -@end menu - -@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -@node export options -@appendixsubsec export options - -These standard options are supported by @code{export} -(@pxref{Common options}, for a complete description of -them): - -@table @code -@item -D @var{date} -Use the most recent revision no later than @var{date}. - -@item -f -If no matching revision is found, retrieve the most -recent revision (instead of ignoring the file). - -@item -l -Local; run only in current working directory. - -@item -n -Do not run any checkout program. - -@item -R -Export directories recursively. This is on by default. - -@item -r @var{tag} -Use revision @var{tag}. -@end table - -In addition, these options (that are common to -@code{checkout} and @code{export}) are also supported: - -@table @code -@item -d @var{dir} -Create a directory called @var{dir} for the working -files, instead of using the module name. -See @ref{checkout options} for complete details on how -@sc{cvs} handles this flag. - -@item -k @var{subst} -Set keyword expansion mode (@pxref{Substitution modes}). - -@item -N -Only useful together with @samp{-d @var{dir}}. -See @ref{checkout options} for complete details on how -@sc{cvs} handles this flag. -@end table - -@ignore -@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -@c @node export examples -@appendixsubsec export examples - -Contributed examples are gratefully accepted. -@c -- Examples here!! -@end ignore - -@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@node history -@appendixsec history---Show status of files and users -@cindex history (subcommand) - -@itemize @bullet -@item -Synopsis: history [-report] [-flags] [-options args] [files@dots{}] -@item -Requires: the file @file{$CVSROOT/CVSROOT/history} -@item -Changes: nothing. -@end itemize - -@sc{cvs} can keep a history file that tracks each use of the -@code{checkout}, @code{commit}, @code{rtag}, -@code{update}, and @code{release} commands. You can -use @code{history} to display this information in -various formats. - -Logging must be enabled by creating the file -@file{$CVSROOT/CVSROOT/history}. - -@strong{@code{history} uses @samp{-f}, @samp{-l}, -@samp{-n}, and @samp{-p} in ways that conflict with the -normal use inside @sc{cvs} (@pxref{Common options}).} - -@menu -* history options:: history options -@end menu - -@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -@node history options -@appendixsubsec history options - -Several options (shown above as @samp{-report}) control what -kind of report is generated: - -@table @code -@item -c -Report on each time commit was used (i.e., each time -the repository was modified). - -@item -e -Everything (all record types). Equivalent to -specifying @samp{-x} with all record types. Of course, -@samp{-e} will also include record types which are -added in a future version of @sc{cvs}; if you are -writing a script which can only handle certain record -types, you'll want to specify @samp{-x}. - -@item -m @var{module} -Report on a particular module. (You can meaningfully -use @samp{-m} more than once on the command line.) - -@item -o -Report on checked-out modules. This is the default report type. - -@item -T -Report on all tags. - -@item -x @var{type} -Extract a particular set of record types @var{type} from the @sc{cvs} -history. The types are indicated by single letters, -which you may specify in combination. - -Certain commands have a single record type: - -@table @code -@item F -release -@item O -checkout -@item E -export -@item T -rtag -@end table - -@noindent -One of five record types may result from an update: - -@table @code -@item C -A merge was necessary but collisions were -detected (requiring manual merging). -@item G -A merge was necessary and it succeeded. -@item U -A working file was copied from the repository. -@item P -A working file was patched to match the repository. -@item W -The working copy of a file was deleted during -update (because it was gone from the repository). -@end table - -@noindent -One of three record types results from commit: - -@table @code -@item A -A file was added for the first time. -@item M -A file was modified. -@item R -A file was removed. -@end table -@end table - -The options shown as @samp{-flags} constrain or expand -the report without requiring option arguments: - -@table @code -@item -a -Show data for all users (the default is to show data -only for the user executing @code{history}). - -@item -l -Show last modification only. - -@item -w -Show only the records for modifications done from the -same working directory where @code{history} is -executing. -@end table - -The options shown as @samp{-options @var{args}} constrain the report -based on an argument: - -@table @code -@item -b @var{str} -Show data back to a record containing the string -@var{str} in either the module name, the file name, or -the repository path. - -@item -D @var{date} -Show data since @var{date}. This is slightly different -from the normal use of @samp{-D @var{date}}, which -selects the newest revision older than @var{date}. - -@item -f @var{file} -Show data for a particular file -(you can specify several @samp{-f} options on the same command line). -This is equivalent to specifying the file on the command line. - -@item -n @var{module} -Show data for a particular module -(you can specify several @samp{-n} options on the same command line). - -@item -p @var{repository} -Show data for a particular source repository (you -can specify several @samp{-p} options on the same command -line). - -@item -r @var{rev} -Show records referring to revisions since the revision -or tag named @var{rev} appears in individual @sc{rcs} -files. Each @sc{rcs} file is searched for the revision or -tag. - -@item -t @var{tag} -Show records since tag @var{tag} was last added to the -history file. This differs from the @samp{-r} flag -above in that it reads only the history file, not the -@sc{rcs} files, and is much faster. - -@item -u @var{name} -Show records for user @var{name}. - -@item -z @var{timezone} -Show times in the selected records using the specified -time zone instead of UTC. -@end table - -@ignore -@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -@c @node history examples -@appendixsubsec history examples - -Contributed examples will gratefully be accepted. -@c -- Examples here! -@end ignore - -@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@node import -@appendixsec import---Import sources into CVS, using vendor branches -@cindex import (subcommand) - -@c FIXME: This node is way too long for one which has subnodes. - -@itemize @bullet -@item -Synopsis: import [-options] repository vendortag releasetag@dots{} -@item -Requires: Repository, source distribution directory. -@item -Changes: repository. -@end itemize - -Use @code{import} to incorporate an entire source -distribution from an outside source (e.g., a source -vendor) into your source repository directory. You can -use this command both for initial creation of a -repository, and for wholesale updates to the module -from the outside source. See @ref{Tracking sources} for -a discussion on this subject. - -The @var{repository} argument gives a directory name -(or a path to a directory) under the @sc{cvs} root directory -for repositories; if the directory did not exist, -import creates it. - -When you use import for updates to source that has been -modified in your source repository (since a prior -import), it will notify you of any files that conflict -in the two branches of development; use @samp{checkout --j} to reconcile the differences, as import instructs -you to do. - -If @sc{cvs} decides a file should be ignored -(@pxref{cvsignore}), it does not import it and prints -@samp{I } followed by the filename (@pxref{import output} for a -complete description of the output). - -If the file @file{$CVSROOT/CVSROOT/cvswrappers} exists, -any file whose names match the specifications in that -file will be treated as packages and the appropriate -filtering will be performed on the file/directory -before being imported. See @ref{Wrappers}. - -The outside source is saved in a first-level -branch, by default 1.1.1. Updates are leaves of this -branch; for example, files from the first imported -collection of source will be revision 1.1.1.1, then -files from the first imported update will be revision -1.1.1.2, and so on. - -At least three arguments are required. -@var{repository} is needed to identify the collection -of source. @var{vendortag} is a tag for the entire -branch (e.g., for 1.1.1). You must also specify at -least one @var{releasetag} to uniquely identify the files at -the leaves created each time you execute @code{import}. The -@var{releasetag} should be new, not previously existing in the -repository file, and uniquely identify the imported release, - -@c I'm not completely sure this belongs here. But -@c we need to say it _somewhere_ reasonably obvious; it -@c is a common misconception among people first learning CVS -Note that @code{import} does @emph{not} change the -directory in which you invoke it. In particular, it -does not set up that directory as a @sc{cvs} working -directory; if you want to work with the sources import -them first and then check them out into a different -directory (@pxref{Getting the source}). - -@menu -* import options:: import options -* import output:: import output -* import examples:: import examples -@end menu - -@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -@node import options -@appendixsubsec import options - -This standard option is supported by @code{import} -(@pxref{Common options} for a complete description): - -@table @code -@item -m @var{message} -Use @var{message} as log information, instead of -invoking an editor. -@end table - -There are the following additional special options. - -@table @code -@item -b @var{branch} -See @ref{Multiple vendor branches}. - -@item -k @var{subst} -Indicate the keyword expansion mode desired. This -setting will apply to all files created during the -import, but not to any files that previously existed in -the repository. See @ref{Substitution modes} for a -list of valid @samp{-k} settings. - -@item -I @var{name} -Specify file names that should be ignored during -import. You can use this option repeatedly. To avoid -ignoring any files at all (even those ignored by -default), specify `-I !'. - -@var{name} can be a file name pattern of the same type -that you can specify in the @file{.cvsignore} file. -See @ref{cvsignore}. -@c -- Is this really true? - -@item -W @var{spec} -Specify file names that should be filtered during -import. You can use this option repeatedly. - -@var{spec} can be a file name pattern of the same type -that you can specify in the @file{.cvswrappers} -file. @xref{Wrappers}. -@end table - -@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -@node import output -@appendixsubsec import output - -@code{import} keeps you informed of its progress by printing a line -for each file, preceded by one character indicating the status of the file: - -@table @code -@item U @var{file} -The file already exists in the repository and has not been locally -modified; a new revision has been created (if necessary). - -@item N @var{file} -The file is a new file which has been added to the repository. - -@item C @var{file} -The file already exists in the repository but has been locally modified; -you will have to merge the changes. - -@item I @var{file} -The file is being ignored (@pxref{cvsignore}). - -@cindex Symbolic link, importing -@cindex Link, symbolic, importing -@c FIXME: also (somewhere else) probably -@c should be documenting what happens if you "cvs add" -@c a symbolic link. Also maybe what happens if -@c you manually create symbolic links within the -@c repository (? - not sure why we'd want to suggest -@c doing that). -@item L @var{file} -The file is a symbolic link; @code{cvs import} ignores symbolic links. -People periodically suggest that this behavior should -be changed, but if there is a consensus on what it -should be changed to, it doesn't seem to be apparent. -(Various options in the @file{modules} file can be used -to recreate symbolic links on checkout, update, etc.; -@pxref{modules}.) -@end table - -@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -@node import examples -@appendixsubsec import examples - -See @ref{Tracking sources}, and @ref{From files}. - -@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@node log -@appendixsec log---Print out log information for files -@cindex log (subcommand) - -@itemize @bullet -@item -Synopsis: log [options] [files@dots{}] -@item -Requires: repository, working directory. -@item -Changes: nothing. -@end itemize - -Display log information for files. @code{log} used to -call the @sc{rcs} utility @code{rlog}. Although this -is no longer true in the current sources, this history -determines the format of the output and the options, -which are not quite in the style of the other @sc{cvs} -commands. - -@cindex Timezone, in output -@cindex Zone, time, in output -@c Kind of a funny place to document the timezone used -@c in output from commands other than @code{log}. -@c There is also more we need to say about this, -@c including what happens in a client/server environment. -The output includes the location of the @sc{rcs} file, -the @dfn{head} revision (the latest revision on the -trunk), all symbolic names (tags) and some other -things. For each revision, the revision number, the -author, the number of lines added/deleted and the log -message are printed. All times are displayed in -Coordinated Universal Time (UTC). (Other parts of -@sc{cvs} print times in the local timezone). -@c FIXCVS: need a better way to control the timezone -@c used in output. Previous/current versions of CVS did/do -@c sometimes support -z in RCSINIT, and/or an -@c undocumented (except by reference to 'rlog') -z option -@c to cvs log, but this has not been a consistent, -@c documented feature. Perhaps a new global option, -@c where LT means the client's timezone, which the -@c client then communicates to the server, is the -@c right solution. - -@strong{@code{log} uses @samp{-R} in a way that conflicts -with the normal use inside @sc{cvs} (@pxref{Common options}).} - -@menu -* log options:: log options -* log examples:: log examples -@end menu - -@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -@node log options -@appendixsubsec log options - -By default, @code{log} prints all information that is -available. All other options restrict the output. Note that the revision -selection options (@code{-b}, @code{-d}, @code{-r}, @code{-s}, and @code{-w}) -have no -effect, other than possibly causing a search for files in Attic directories, -when used in conjunction with the options that restrict the output to only -@code{log} header fields (@code{-h}, @code{-R}, and @code{-t}) -unless the @code{-S} option is also specified. - -@table @code -@item -b -Print information about the revisions on the default -branch, normally the highest branch on the trunk. - -@item -d @var{dates} -Print information about revisions with a checkin -date/time in the range given by the -semicolon-separated list of dates. The date formats -accepted are those accepted by the @samp{-D} option to -many other @sc{cvs} commands (@pxref{Common options}). -Dates can be combined into ranges as follows: - -@c Should we be thinking about accepting ISO8601 -@c ranges? For example "1972-09-10/1972-09-12". -@table @code -@item @var{d1}<@var{d2} -@itemx @var{d2}>@var{d1} -Select the revisions that were deposited between -@var{d1} and @var{d2}. - -@item <@var{d} -@itemx @var{d}> -Select all revisions dated @var{d} or earlier. - -@item @var{d}< -@itemx >@var{d} -Select all revisions dated @var{d} or later. - -@item @var{d} -Select the single, latest revision dated @var{d} or -earlier. -@end table - -The @samp{>} or @samp{<} characters may be followed by -@samp{=} to indicate an inclusive range rather than an -exclusive one. - -Note that the separator is a semicolon (;). - -@item -h -Print only the name of the @sc{rcs} file, name -of the file in the working directory, head, -default branch, access list, locks, symbolic names, and -suffix. - -@item -l -Local; run only in current working directory. (Default -is to run recursively). - -@item -N -Do not print the list of tags for this file. This -option can be very useful when your site uses a lot of -tags, so rather than "more"'ing over 3 pages of tag -information, the log information is presented without -tags at all. - -@item -n -Print the list of tags for this file. This option can -be very useful when your @file{.cvsrc} file has a -@samp{log -N} entry as a way to get a full list of all -of the tags. - -@item -R -Print only the name of the @sc{rcs} file. - -@c Note that using a bare revision (in addition to not -@c being explicitly documented here) is potentially -@c confusing; it shows the log message to get from the -@c previous revision to that revision. "-r1.3 -r1.6" -@c (equivalent to "-r1.3,1.6") is even worse; it -@c prints the messages to get from 1.2 to 1.3 and 1.5 -@c to 1.6. By analogy with "cvs diff", users might -@c expect that it is more like specifying a range. -@c It is not 100% clear to me how much of this should -@c be documented (for example, multiple -r options -@c perhaps could/should be deprecated given the false -@c analogy with "cvs diff"). -@c In general, this section should be rewritten to talk -@c about messages to get from revision rev1 to rev2, -@c rather than messages for revision rev2 (that is, the -@c messages are associated with a change not a static -@c revision and failing to make this distinction causes -@c much confusion). -@item -r@var{revisions} -Print information about revisions given in the -comma-separated list @var{revisions} of revisions and -ranges. The following table explains the available -range formats: - -@table @code -@item @var{rev1}:@var{rev2} -Revisions @var{rev1} to @var{rev2} (which must be on -the same branch). - -@item @var{rev1}::@var{rev2} -The same, but excluding @var{rev1}. - -@item :@var{rev} -@itemx ::@var{rev} -Revisions from the beginning of the branch up to -and including @var{rev}. - -@item @var{rev}: -Revisions starting with @var{rev} to the end of the -branch containing @var{rev}. - -@item @var{rev}:: -Revisions starting just after @var{rev} to the end of the -branch containing @var{rev}. - -@item @var{branch} -An argument that is a branch means all revisions on -that branch. - -@item @var{branch1}:@var{branch2} -@itemx @var{branch1}::@var{branch2} -A range of branches means all revisions -on the branches in that range. - -@item @var{branch}. -The latest revision in @var{branch}. -@end table - -A bare @samp{-r} with no revisions means the latest -revision on the default branch, normally the trunk. -There can be no space between the @samp{-r} option and -its argument. - -@item -S -Suppress the header if no revisions are selected. - -@item -s @var{states} -Print information about revisions whose state -attributes match one of the states given in the -comma-separated list @var{states}. Individual states may -be any text string, though @sc{cvs} commonly only uses two -states, @samp{Exp} and @samp{dead}. See @ref{admin options} -for more information. - -@item -t -Print the same as @samp{-h}, plus the descriptive text. - -@item -w@var{logins} -Print information about revisions checked in by users -with login names appearing in the comma-separated list -@var{logins}. If @var{logins} is omitted, the user's -login is assumed. There can be no space between the -@samp{-w} option and its argument. -@end table - -@code{log} prints the intersection of the revisions -selected with the options @samp{-d}, @samp{-s}, and -@samp{-w}, intersected with the union of the revisions -selected by @samp{-b} and @samp{-r}. - -@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -@node log examples -@appendixsubsec log examples - -Contributed examples are gratefully accepted. - -@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@node rdiff -@appendixsec rdiff---'patch' format diffs between releases -@cindex rdiff (subcommand) - -@itemize @bullet -@item -rdiff [-flags] [-V vn] [-r t|-D d [-r t2|-D d2]] modules@dots{} -@item -Requires: repository. -@item -Changes: nothing. -@item -Synonym: patch -@end itemize - -Builds a Larry Wall format patch(1) file between two -releases, that can be fed directly into the @code{patch} -program to bring an old release up-to-date with the new -release. (This is one of the few @sc{cvs} commands that -operates directly from the repository, and doesn't -require a prior checkout.) The diff output is sent to -the standard output device. - -You can specify (using the standard @samp{-r} and -@samp{-D} options) any combination of one or two -revisions or dates. If only one revision or date is -specified, the patch file reflects differences between -that revision or date and the current head revisions in -the @sc{rcs} file. - -Note that if the software release affected is contained -in more than one directory, then it may be necessary to -specify the @samp{-p} option to the @code{patch} command when -patching the old sources, so that @code{patch} is able to find -the files that are located in other directories. - -@menu -* rdiff options:: rdiff options -* rdiff examples:: rdiff examples -@end menu - -@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -@node rdiff options -@appendixsubsec rdiff options - -These standard options are supported by @code{rdiff} -(@pxref{Common options} for a complete description of -them): - -@table @code -@item -D @var{date} -Use the most recent revision no later than @var{date}. - -@item -f -If no matching revision is found, retrieve the most -recent revision (instead of ignoring the file). - -@item -k @var{kflag} -Process keywords according to @var{kflag}. See -@ref{Keyword substitution}. - -@item -l -Local; don't descend subdirectories. - -@item -R -Examine directories recursively. This option is on by default. - -@item -r @var{tag} -Use revision @var{tag}. -@end table - -In addition to the above, these options are available: - -@table @code -@item -c -Use the context diff format. This is the default format. - -@item -s -Create a summary change report instead of a patch. The -summary includes information about files that were -changed or added between the releases. It is sent to -the standard output device. This is useful for finding -out, for example, which files have changed between two -dates or revisions. - -@item -t -A diff of the top two revisions is sent to the standard -output device. This is most useful for seeing what the -last change to a file was. - -@item -u -Use the unidiff format for the context diffs. -Remember that old versions -of the @code{patch} program can't handle the unidiff -format, so if you plan to post this patch to the net -you should probably not use @samp{-u}. - -@item -V @var{vn} -Expand keywords according to the rules current in -@sc{rcs} version @var{vn} (the expansion format changed with -@sc{rcs} version 5). Note that this option is no -longer accepted. @sc{cvs} will always expand keywords the -way that @sc{rcs} version 5 does. -@end table - -@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -@node rdiff examples -@appendixsubsec rdiff examples - -Suppose you receive mail from @t{foo@@example.net} asking for an -update from release 1.2 to 1.4 of the tc compiler. You -have no such patches on hand, but with @sc{cvs} that can -easily be fixed with a command such as this: - -@example -$ cvs rdiff -c -r FOO1_2 -r FOO1_4 tc | \ -> Mail -s 'The patches you asked for' foo@@example.net -@end example - -Suppose you have made release 1.3, and forked a branch -called @samp{R_1_3fix} for bug fixes. @samp{R_1_3_1} -corresponds to release 1.3.1, which was made some time -ago. Now, you want to see how much development has been -done on the branch. This command can be used: - -@example -$ cvs patch -s -r R_1_3_1 -r R_1_3fix module-name -cvs rdiff: Diffing module-name -File ChangeLog,v changed from revision 1.52.2.5 to 1.52.2.6 -File foo.c,v changed from revision 1.52.2.3 to 1.52.2.4 -File bar.h,v changed from revision 1.29.2.1 to 1.2 -@end example - -@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@node release -@appendixsec release---Indicate that a Module is no longer in use -@cindex release (subcommand) - -@itemize @bullet -@item -release [-d] directories@dots{} -@item -Requires: Working directory. -@item -Changes: Working directory, history log. -@end itemize - -This command is meant to safely cancel the effect of -@samp{cvs checkout}. Since @sc{cvs} doesn't lock files, it -isn't strictly necessary to use this command. You can -always simply delete your working directory, if you -like; but you risk losing changes you may have -forgotten, and you leave no trace in the @sc{cvs} history -file (@pxref{history file}) that you've abandoned your -checkout. - -Use @samp{cvs release} to avoid these problems. This -command checks that no uncommitted changes are -present; that you are executing it from immediately -above a @sc{cvs} working directory; and that the repository -recorded for your files is the same as the repository -defined in the module database. - -If all these conditions are true, @samp{cvs release} -leaves a record of its execution (attesting to your -intentionally abandoning your checkout) in the @sc{cvs} -history log. - -@menu -* release options:: release options -* release output:: release output -* release examples:: release examples -@end menu - -@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -@node release options -@appendixsubsec release options - -The @code{release} command supports one command option: - -@table @code -@item -d -Delete your working copy of the file if the release -succeeds. If this flag is not given your files will -remain in your working directory. - -@strong{WARNING: The @code{release} command deletes -all directories and files recursively. This -has the very serious side-effect that any directory -created inside checked-out sources, and not added to -the repository (using the @code{add} command; -@pxref{Adding files}) will be silently deleted---even -if it is non-empty!} -@end table - -@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -@node release output -@appendixsubsec release output - -Before @code{release} releases your sources it will -print a one-line message for any file that is not -up-to-date. - -@table @code -@item U @var{file} -@itemx P @var{file} -There exists a newer revision of this file in the -repository, and you have not modified your local copy -of the file (@samp{U} and @samp{P} mean the same thing). - -@item A @var{file} -The file has been added to your private copy of the -sources, but has not yet been committed to the -repository. If you delete your copy of the sources -this file will be lost. - -@item R @var{file} -The file has been removed from your private copy of the -sources, but has not yet been removed from the -repository, since you have not yet committed the -removal. See @ref{commit}. - -@item M @var{file} -The file is modified in your working directory. There -might also be a newer revision inside the repository. - -@item ? @var{file} -@var{file} is in your working directory, but does not -correspond to anything in the source repository, and is -not in the list of files for @sc{cvs} to ignore (see the -description of the @samp{-I} option, and -@pxref{cvsignore}). If you remove your working -sources, this file will be lost. -@end table - -@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -@node release examples -@appendixsubsec release examples - -Release the @file{tc} directory, and delete your local working copy -of the files. - -@example -$ cd .. # @r{You must stand immediately above the} - # @r{sources when you issue @samp{cvs release}.} -$ cvs release -d tc -You have [0] altered files in this repository. -Are you sure you want to release (and delete) directory `tc': y -$ -@end example - -@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@node remove -@appendixsec remove---Remove files from active use -@cindex remove (subcommand) - -@itemize @bullet -@item -Synopsis: remove [-flR] [files...] -@item -Requires: repository, working directory. -@item -Changes: working directory. -@end itemize - -The @code{remove} command is used to remove unwanted -files from active use. The user normally deletes the -files from the working directory prior to invocation -of the @code{remove} command. Only the working -directory is updated. Changes to the repository are -not made until the @code{commit} command is run. - -The @code{remove} command does not delete files from -from the repository. @sc{cvs} keeps all historical -data in the repository so that it is possible to -reconstruct previous states of the projects under -revision control. - -To undo @sc{cvs} @code{remove} or to resurrect files -that were previously removed, @xref{add}. - -@menu -* remove options:: remove options -* remove examples:: remove examples -@end menu - -@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -@node remove options -@appendixsubsec remove options - -These standard options are supported by @code{remove} -(@pxref{Common options} for a complete description of -them): - -@table @code -@item -l -Local; run only in current working directory. See @ref{Recursive behavior}. - -@item -R -Process directories recursively. See @ref{Recursive behavior}. - -@end table - -In addition, these options are also supported: - -@table @code -@item -f -Note that this is not the standard behavior of -the @samp{-f} option as defined in @ref{Common options}. - -Delete files before removing them. - -Entire directory hierarchies are easily removed -using @samp{-f}, but take note that it is not as -easy to resurrect directory hierarchies as it is -to remove them. - -@end table - -@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -@node remove examples -@appendixsubsec remove examples - -@appendixsubsubsec Removing a file - -@example -$ cvs remove remove.me -cvs remove: file `remove.me' still in working directory -cvs remove: 1 file exists; remove it first -$ rm -f remove.me -$ cvs remove remove.me -cvs remove: scheduling `remove.me' for removal -cvs remove: use 'cvs commit' to remove this file permanently - -$ ls remove.it -remove.it -$ cvs remove -f remove.it -cvs remove: scheduling `remove.it' for removal -cvs remove: use 'cvs commit' to remove this file permanently -@end example - -@appendixsubsubsec Removing entire directories -@example -$ tree -d a -a -|-- CVS -`-- b - `-- CVS - -3 directories -$ cvs remove -f a -cvs remove: Removing a -cvs remove: Removing a/b -cvs remove: scheduling `a/b/c' for removal -cvs remove: use 'cvs commit' to remove this file permanently -@end example - -@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@node update -@appendixsec update---Bring work tree in sync with repository -@cindex update (subcommand) - -@itemize @bullet -@item -update [-ACdflPpR] [-I name] [-j rev [-j rev]] [-k kflag] [-r tag|-D date] [-W spec] files@dots{} -@item -Requires: repository, working directory. -@item -Changes: working directory. -@end itemize - -After you've run checkout to create your private copy -of source from the common repository, other developers -will continue changing the central source. From time -to time, when it is convenient in your development -process, you can use the @code{update} command from -within your working directory to reconcile your work -with any revisions applied to the source repository -since your last checkout or update. - -@menu -* update options:: update options -* update output:: update output -@end menu - -@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -@node update options -@appendixsubsec update options - -These standard options are available with @code{update} -(@pxref{Common options} for a complete description of -them): - -@table @code -@item -D date -Use the most recent revision no later than @var{date}. -This option is sticky, and implies @samp{-P}. -See @ref{Sticky tags} for more information on sticky tags/dates. - -@item -f -Only useful with the @samp{-D @var{date}} or @samp{-r -@var{tag}} flags. If no matching revision is found, -retrieve the most recent revision (instead of ignoring -the file). - -@item -k @var{kflag} -Process keywords according to @var{kflag}. See -@ref{Keyword substitution}. -This option is sticky; future updates of -this file in this working directory will use the same -@var{kflag}. The @code{status} command can be viewed -to see the sticky options. See @ref{Invoking CVS} for -more information on the @code{status} command. - -@item -l -Local; run only in current working directory. See @ref{Recursive behavior}. - -@item -P -Prune empty directories. See @ref{Moving directories}. - -@item -p -Pipe files to the standard output. - -@item -R -Update directories recursively (default). See @ref{Recursive -behavior}. - -@item -r rev -Retrieve revision/tag @var{rev}. This option is sticky, -and implies @samp{-P}. -See @ref{Sticky tags}, for more information on sticky tags/dates. -@end table - -@need 800 -These special options are also available with -@code{update}. - -@table @code -@item -A -Reset any sticky tags, dates, or @samp{-k} options. -Does not reset sticky @samp{-k} options on modified files. -See @ref{Sticky tags} for more information on sticky tags/dates. - -@item -C -Overwrite locally modified files with clean copies from -the repository (the modified file is saved in -@file{.#@var{file}.@var{revision}}, however). - -@item -d -Create any directories that exist in the repository if -they're missing from the working directory. Normally, -@code{update} acts only on directories and files that -were already enrolled in your working directory. - -This is useful for updating directories that were -created in the repository since the initial checkout; -but it has an unfortunate side effect. If you -deliberately avoided certain directories in the -repository when you created your working directory -(either through use of a module name or by listing -explicitly the files and directories you wanted on the -command line), then updating with @samp{-d} will create -those directories, which may not be what you want. - -@item -I @var{name} -Ignore files whose names match @var{name} (in your -working directory) during the update. You can specify -@samp{-I} more than once on the command line to specify -several files to ignore. Use @samp{-I !} to avoid -ignoring any files at all. See @ref{cvsignore} for other -ways to make @sc{cvs} ignore some files. - -@item -W@var{spec} -Specify file names that should be filtered during -update. You can use this option repeatedly. - -@var{spec} can be a file name pattern of the same type -that you can specify in the @file{.cvswrappers} -file. See @ref{Wrappers}. - -@item -j@var{revision} -With two @samp{-j} options, merge changes from the -revision specified with the first @samp{-j} option to -the revision specified with the second @samp{j} option, -into the working directory. - -With one @samp{-j} option, merge changes from the -ancestor revision to the revision specified with the -@samp{-j} option, into the working directory. The -ancestor revision is the common ancestor of the -revision which the working directory is based on, and -the revision specified in the @samp{-j} option. - -Note that using a single @samp{-j @var{tagname}} option rather than -@samp{-j @var{branchname}} to merge changes from a branch will -often not remove files which were removed on the branch. -See @ref{Merging adds and removals} for more information. - -In addition, each @samp{-j} option can contain an optional -date specification which, when used with branches, can -limit the chosen revision to one within a specific -date. An optional date is specified by adding a colon -(:) to the tag: -@samp{-j@var{Symbolic_Tag}:@var{Date_Specifier}}. - -See @ref{Branching and merging}. - -@end table - -@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -@node update output -@appendixsubsec update output - -@code{update} and @code{checkout} keep you informed of -their progress by printing a line for each file, preceded -by one character indicating the status of the file: - -@table @code -@item U @var{file} -The file was brought up to date with respect to the -repository. This is done for any file that exists in -the repository but not in your working directory, and for files -that you haven't changed but are not the most recent -versions available in the repository. - -@item P @var{file} -Like @samp{U}, but the @sc{cvs} server sends a patch instead of an entire -file. This accomplishes the same thing as @samp{U} using less bandwidth. - -@item A @var{file} -The file has been added to your private copy of the -sources, and will be added to the source repository -when you run @code{commit} on the file. This is a -reminder to you that the file needs to be committed. - -@item R @var{file} -The file has been removed from your private copy of the -sources, and will be removed from the source repository -when you run @code{commit} on the file. This is a -reminder to you that the file needs to be committed. - -@item M @var{file} -The file is modified in your working directory. - -@samp{M} can indicate one of two states for a file -you're working on: either there were no modifications -to the same file in the repository, so that your file -remains as you last saw it; or there were modifications -in the repository as well as in your copy, but they -were merged successfully, without conflict, in your -working directory. - -@sc{cvs} will print some messages if it merges your work, -and a backup copy of your working file (as it looked -before you ran @code{update}) will be made. The exact -name of that file is printed while @code{update} runs. - -@item C @var{file} -@cindex .# files -@cindex __ files (VMS) -A conflict was detected while trying to merge your -changes to @var{file} with changes from the source -repository. @var{file} (the copy in your working -directory) is now the result of attempting to merge -the two revisions; an unmodified copy of your file -is also in your working directory, with the name -@file{.#@var{file}.@var{revision}} where @var{revision} -is the revision that your modified file started -from. Resolve the conflict as described in -@ref{Conflicts example}. -@c "some systems" as in out-of-the-box OSes? Not as -@c far as I know. We need to advise sysadmins as well -@c as users how to set up this kind of purge, if that is -@c what they want. -@c We also might want to think about cleaner solutions, -@c like having CVS remove the .# file once the conflict -@c has been resolved or something like that. -(Note that some systems automatically purge -files that begin with @file{.#} if they have not been -accessed for a few days. If you intend to keep a copy -of your original file, it is a very good idea to rename -it.) Under @sc{vms}, the file name starts with -@file{__} rather than @file{.#}. - -@item ? @var{file} -@var{file} is in your working directory, but does not -correspond to anything in the source repository, and is -not in the list of files for @sc{cvs} to ignore (see the -description of the @samp{-I} option, and -@pxref{cvsignore}). -@end table - -@c ----- END MAN 1 ----- -@c --------------------------------------------------------------------- -@node Invoking CVS -@appendix Quick reference to CVS commands -@cindex Command reference -@cindex Reference, commands -@cindex Invoking CVS - -This appendix describes how to invoke @sc{cvs}, with -references to where each command or feature is -described in detail. For other references run the -@code{cvs --help} command, or see @ref{Index}. - -A @sc{cvs} command looks like: - -@example -cvs [ @var{global_options} ] @var{command} [ @var{command_options} ] [ @var{command_args} ] -@end example - -Global options: - -@table @code -@item --allow-root=@var{rootdir} -Specify legal @sc{cvsroot} directory (server only) (not -in @sc{cvs} 1.9 and older). See @ref{Password -authentication server}. - -@item -a -Authenticate all communication (client only) (not in @sc{cvs} -1.9 and older). See @ref{Global options}. - -@item -b -Specify RCS location (@sc{cvs} 1.9 and older). See -@ref{Global options}. - -@item -d @var{root} -Specify the @sc{cvsroot}. See @ref{Repository}. - -@item -e @var{editor} -Edit messages with @var{editor}. See @ref{Committing -your changes}. - -@item -f -Do not read the @file{~/.cvsrc} file. See @ref{Global -options}. - -@item -H -@itemx --help -Print a help message. See @ref{Global options}. - -@item -n -Do not change any files. See @ref{Global options}. - -@item -Q -Be really quiet. See @ref{Global options}. - -@item -q -Be somewhat quiet. See @ref{Global options}. - -@item -r -Make new working files read-only. See @ref{Global options}. - -@item -s @var{variable}=@var{value} -Set a user variable. See @ref{Variables}. - -@item -T @var{tempdir} -Put temporary files in @var{tempdir}. See @ref{Global -options}. - -@item -t -Trace @sc{cvs} execution. See @ref{Global options}. - -@item -v -@item --version -Display version and copyright information for @sc{cvs}. - -@item -w -Make new working files read-write. See @ref{Global -options}. - -@item -x -Encrypt all communication (client only). -See @ref{Global options}. - -@item -z @var{gzip-level} -@cindex Compression -@cindex Gzip -Set the compression level (client only). -See @ref{Global options}. -@end table - -Keyword expansion modes (@pxref{Substitution modes}): - -@example --kkv $@splitrcskeyword{Id}: file1,v 1.1 1993/12/09 03:21:13 joe Exp $ --kkvl $@splitrcskeyword{Id}: file1,v 1.1 1993/12/09 03:21:13 joe Exp harry $ --kk $@splitrcskeyword{Id}$ --kv file1,v 1.1 1993/12/09 03:21:13 joe Exp --ko @i{no expansion} --kb @i{no expansion, file is binary} -@end example - -Keywords (@pxref{Keyword list}): - -@example -$@splitrcskeyword{Author}: joe $ -$@splitrcskeyword{Date}: 1993/12/09 03:21:13 $ -$@splitrcskeyword{Header}: /home/files/file1,v 1.1 1993/12/09 03:21:13 joe Exp harry $ -$@splitrcskeyword{Id}: file1,v 1.1 1993/12/09 03:21:13 joe Exp harry $ -$@splitrcskeyword{Locker}: harry $ -$@splitrcskeyword{Name}: snapshot_1_14 $ -$@splitrcskeyword{RCSfile}: file1,v $ -$@splitrcskeyword{Revision}: 1.1 $ -$@splitrcskeyword{Source}: /home/files/file1,v $ -$@splitrcskeyword{State}: Exp $ -$@splitrcskeyword{Log}: file1,v $ -Revision 1.1 1993/12/09 03:30:17 joe -Initial revision - -@end example - -@c The idea behind this table is that we want each item -@c to be a sentence or two at most. Preferably a -@c single line. -@c -@c In some cases refs to "foo options" are just to get -@c this thing written quickly, not because the "foo -@c options" node is really the best place to point. -Commands, command options, and command arguments: - -@table @code -@c ------------------------------------------------------------ -@item add [@var{options}] [@var{files}@dots{}] -Add a new file/directory. See @ref{Adding files}. - -@table @code -@item -k @var{kflag} -Set keyword expansion. - -@item -m @var{msg} -Set file description. -@end table - -@c ------------------------------------------------------------ -@item admin [@var{options}] [@var{files}@dots{}] -Administration of history files in the repository. See -@ref{admin}. -@c This list omits those options which are not -@c documented as being useful with CVS. That might be -@c a mistake... - -@table @code -@item -b[@var{rev}] -Set default branch. See @ref{Reverting local changes}. - -@item -c@var{string} -Set comment leader. - -@item -k@var{subst} -Set keyword substitution. See @ref{Keyword -substitution}. - -@item -l[@var{rev}] -Lock revision @var{rev}, or latest revision. - -@item -m@var{rev}:@var{msg} -Replace the log message of revision @var{rev} with -@var{msg}. - -@item -o@var{range} -Delete revisions from the repository. See -@ref{admin options}. - -@item -q -Run quietly; do not print diagnostics. - -@item -s@var{state}[:@var{rev}] -Set the state. See @ref{admin options} for more information on possible -states. - -@c Does not work for client/server CVS -@item -t -Set file description from standard input. - -@item -t@var{file} -Set file description from @var{file}. - -@item -t-@var{string} -Set file description to @var{string}. - -@item -u[@var{rev}] -Unlock revision @var{rev}, or latest revision. -@end table - -@c ------------------------------------------------------------ -@item annotate [@var{options}] [@var{files}@dots{}] -Show last revision where each line was modified. See -@ref{annotate}. - -@table @code -@item -D @var{date} -Annotate the most recent revision no later than -@var{date}. See @ref{Common options}. - -@item -F -Force annotation of binary files. (Without this option, -binary files are skipped with a message.) - -@item -f -Use head revision if tag/date not found. See -@ref{Common options}. - -@item -l -Local; run only in current working directory. @xref{Recursive behavior}. - -@item -R -Operate recursively (default). @xref{Recursive -behavior}. - -@item -r @var{tag} -Annotate revision @var{tag}. See @ref{Common options}. -@end table - -@c ------------------------------------------------------------ -@item checkout [@var{options}] @var{modules}@dots{} -Get a copy of the sources. See @ref{checkout}. - -@table @code -@item -A -Reset any sticky tags/date/options. See @ref{Sticky -tags} and @ref{Keyword substitution}. - -@item -c -Output the module database. See @ref{checkout options}. - -@item -D @var{date} -Check out revisions as of @var{date} (is sticky). See -@ref{Common options}. - -@item -d @var{dir} -Check out into @var{dir}. See @ref{checkout options}. - -@item -f -Use head revision if tag/date not found. See -@ref{Common options}. - -@c Probably want to use rev1/rev2 style like for diff -@c -r. Here and in on-line help. -@item -j @var{rev} -Merge in changes. See @ref{checkout options}. - -@item -k @var{kflag} -Use @var{kflag} keyword expansion. See -@ref{Substitution modes}. - -@item -l -Local; run only in current working directory. @xref{Recursive behavior}. - -@item -N -Don't ``shorten'' module paths if -d specified. See -@ref{checkout options}. - -@item -n -Do not run module program (if any). See @ref{checkout options}. - -@item -P -Prune empty directories. See @ref{Moving directories}. - -@item -p -Check out files to standard output (avoids -stickiness). See @ref{checkout options}. - -@item -R -Operate recursively (default). @xref{Recursive -behavior}. - -@item -r @var{tag} -Checkout revision @var{tag} (is sticky). See @ref{Common options}. - -@item -s -Like -c, but include module status. See @ref{checkout options}. -@end table - -@c ------------------------------------------------------------ -@item commit [@var{options}] [@var{files}@dots{}] -Check changes into the repository. See @ref{commit}. - -@table @code -@item -F @var{file} -Read log message from @var{file}. See @ref{commit options}. - -@item -f -@c What is this "disables recursion"? It is from the -@c on-line help; is it documented in this manual? -Force the file to be committed; disables recursion. -See @ref{commit options}. - -@item -l -Local; run only in current working directory. See @ref{Recursive behavior}. - -@item -m @var{msg} -Use @var{msg} as log message. See @ref{commit options}. - -@item -n -Do not run module program (if any). See @ref{commit options}. - -@item -R -Operate recursively (default). @xref{Recursive -behavior}. - -@item -r @var{rev} -Commit to @var{rev}. See @ref{commit options}. -@c FIXME: should be dragging over text from -@c commit options, especially if it can be cleaned up -@c and made concise enough. -@end table - -@c ------------------------------------------------------------ -@item diff [@var{options}] [@var{files}@dots{}] -Show differences between revisions. See @ref{diff}. -In addition to the options shown below, accepts a wide -variety of options to control output style, for example -@samp{-c} for context diffs. - -@table @code -@item -D @var{date1} -Diff revision for date against working file. See -@ref{diff options}. - -@item -D @var{date2} -Diff @var{rev1}/@var{date1} against @var{date2}. See -@ref{diff options}. - -@item -l -Local; run only in current working directory. See @ref{Recursive behavior}. - -@item -N -Include diffs for added and removed files. See -@ref{diff options}. - -@item -R -Operate recursively (default). @xref{Recursive -behavior}. - -@item -r @var{rev1} -Diff revision for @var{rev1} against working file. See -@ref{diff options}. - -@item -r @var{rev2} -Diff @var{rev1}/@var{date1} against @var{rev2}. See @ref{diff options}. -@end table - -@c ------------------------------------------------------------ -@item edit [@var{options}] [@var{files}@dots{}] -Get ready to edit a watched file. See @ref{Editing files}. - -@table @code -@item -a @var{actions} -Specify actions for temporary watch, where -@var{actions} is @code{edit}, @code{unedit}, -@code{commit}, @code{all}, or @code{none}. See -@ref{Editing files}. - -@item -l -Local; run only in current working directory. See @ref{Recursive behavior}. - -@item -R -Operate recursively (default). @xref{Recursive -behavior}. -@end table - -@c ------------------------------------------------------------ -@item editors [@var{options}] [@var{files}@dots{}] -See who is editing a watched file. See @ref{Watch information}. - -@table @code -@item -l -Local; run only in current working directory. See @ref{Recursive behavior}. - -@item -R -Operate recursively (default). @xref{Recursive -behavior}. -@end table - -@c ------------------------------------------------------------ -@item export [@var{options}] @var{modules}@dots{} -Export files from @sc{cvs}. See @ref{export}. - -@table @code -@item -D @var{date} -Check out revisions as of @var{date}. See -@ref{Common options}. - -@item -d @var{dir} -Check out into @var{dir}. See @ref{export options}. - -@item -f -Use head revision if tag/date not found. See -@ref{Common options}. - -@item -k @var{kflag} -Use @var{kflag} keyword expansion. See -@ref{Substitution modes}. - -@item -l -Local; run only in current working directory. @xref{Recursive behavior}. - -@item -N -Don't ``shorten'' module paths if -d specified. See -@ref{export options}. - -@item -n -Do not run module program (if any). See @ref{export options}. - -@item -R -Operate recursively (default). @xref{Recursive -behavior}. - -@item -r @var{tag} -Checkout revision @var{tag}. See @ref{Common options}. -@end table - -@c ------------------------------------------------------------ -@item history [@var{options}] [@var{files}@dots{}] -Show repository access history. See @ref{history}. - -@table @code -@item -a -All users (default is self). See @ref{history options}. - -@item -b @var{str} -Back to record with @var{str} in module/file/repos -field. See @ref{history options}. - -@item -c -Report on committed (modified) files. See @ref{history options}. - -@item -D @var{date} -Since @var{date}. See @ref{history options}. - -@item -e -Report on all record types. See @ref{history options}. - -@item -l -Last modified (committed or modified report). See @ref{history options}. - -@item -m @var{module} -Report on @var{module} (repeatable). See @ref{history options}. - -@item -n @var{module} -In @var{module}. See @ref{history options}. - -@item -o -Report on checked out modules. See @ref{history options}. - -@item -p @var{repository} -In @var{repository}. See @ref{history options}. - -@item -r @var{rev} -Since revision @var{rev}. See @ref{history options}. - -@item -T -@c What the @#$@# is a TAG? Same as a tag? This -@c wording is also in the online-line help. -Produce report on all TAGs. See @ref{history options}. - -@item -t @var{tag} -Since tag record placed in history file (by anyone). -See @ref{history options}. - -@item -u @var{user} -For user @var{user} (repeatable). See @ref{history options}. - -@item -w -Working directory must match. See @ref{history options}. - -@item -x @var{types} -Report on @var{types}, one or more of -@code{TOEFWUPCGMAR}. See @ref{history options}. - -@item -z @var{zone} -Output for time zone @var{zone}. See @ref{history options}. -@end table - -@c ------------------------------------------------------------ -@item import [@var{options}] @var{repository} @var{vendor-tag} @var{release-tags}@dots{} -Import files into @sc{cvs}, using vendor branches. See -@ref{import}. - -@table @code -@item -b @var{bra} -Import to vendor branch @var{bra}. See -@ref{Multiple vendor branches}. - -@item -d -Use the file's modification time as the time of -import. See @ref{import options}. - -@item -k @var{kflag} -Set default keyword substitution mode. See -@ref{import options}. - -@item -m @var{msg} -Use @var{msg} for log message. See -@ref{import options}. - -@item -I @var{ign} -More files to ignore (! to reset). See -@ref{import options}. - -@item -W @var{spec} -More wrappers. See @ref{import options}. -@end table - -@c ------------------------------------------------------------ -@item init -Create a @sc{cvs} repository if it doesn't exist. See -@ref{Creating a repository}. - -@c ------------------------------------------------------------ -@item kserver -Kerberos authenticated server. -See @ref{Kerberos authenticated}. - -@c ------------------------------------------------------------ -@item log [@var{options}] [@var{files}@dots{}] -Print out history information for files. See @ref{log}. - -@table @code -@item -b -Only list revisions on the default branch. See @ref{log options}. - -@item -d @var{dates} -Specify dates (@var{d1}<@var{d2} for range, @var{d} for -latest before). See @ref{log options}. - -@item -h -Only print header. See @ref{log options}. - -@item -l -Local; run only in current working directory. See @ref{Recursive behavior}. - -@item -N -Do not list tags. See @ref{log options}. - -@item -R -Only print name of RCS file. See @ref{log options}. - -@item -r@var{revs} -Only list revisions @var{revs}. See @ref{log options}. - -@item -s @var{states} -Only list revisions with specified states. See @ref{log options}. - -@item -t -Only print header and descriptive text. See @ref{log -options}. - -@item -w@var{logins} -Only list revisions checked in by specified logins. See @ref{log options}. -@end table - -@c ------------------------------------------------------------ -@item login -Prompt for password for authenticating server. See -@ref{Password authentication client}. - -@c ------------------------------------------------------------ -@item logout -Remove stored password for authenticating server. See -@ref{Password authentication client}. - -@c ------------------------------------------------------------ -@item pserver -Password authenticated server. -See @ref{Password authentication server}. - -@c ------------------------------------------------------------ -@item rannotate [@var{options}] [@var{modules}@dots{}] -Show last revision where each line was modified. See -@ref{annotate}. - -@table @code -@item -D @var{date} -Annotate the most recent revision no later than -@var{date}. See @ref{Common options}. - -@item -F -Force annotation of binary files. (Without this option, -binary files are skipped with a message.) - -@item -f -Use head revision if tag/date not found. See -@ref{Common options}. - -@item -l -Local; run only in current working directory. @xref{Recursive behavior}. - -@item -R -Operate recursively (default). @xref{Recursive behavior}. - -@item -r @var{tag} -Annotate revision @var{tag}. See @ref{Common options}. -@end table - -@c ------------------------------------------------------------ -@item rdiff [@var{options}] @var{modules}@dots{} -Show differences between releases. See @ref{rdiff}. - -@table @code -@item -c -Context diff output format (default). See @ref{rdiff options}. - -@item -D @var{date} -Select revisions based on @var{date}. See @ref{Common options}. - -@item -f -Use head revision if tag/date not found. See -@ref{Common options}. - -@item -l -Local; run only in current working directory. See @ref{Recursive behavior}. - -@item -R -Operate recursively (default). @xref{Recursive -behavior}. - -@item -r @var{rev} -Select revisions based on @var{rev}. See @ref{Common options}. - -@item -s -Short patch - one liner per file. See @ref{rdiff options}. - -@item -t -Top two diffs - last change made to the file. See -@ref{diff options}. - -@item -u -Unidiff output format. See @ref{rdiff options}. - -@item -V @var{vers} -Use RCS Version @var{vers} for keyword expansion (obsolete). See -@ref{rdiff options}. -@end table - -@c ------------------------------------------------------------ -@item release [@var{options}] @var{directory} -Indicate that a directory is no longer in use. See -@ref{release}. - -@table @code -@item -d -Delete the given directory. See @ref{release options}. -@end table - -@c ------------------------------------------------------------ -@item remove [@var{options}] [@var{files}@dots{}] -Remove an entry from the repository. See @ref{Removing files}. - -@table @code -@item -f -Delete the file before removing it. See @ref{Removing files}. - -@item -l -Local; run only in current working directory. See @ref{Recursive behavior}. - -@item -R -Operate recursively (default). @xref{Recursive -behavior}. -@end table - -@c ------------------------------------------------------------ -@item rlog [@var{options}] [@var{files}@dots{}] -Print out history information for modules. See @ref{log}. - -@table @code -@item -b -Only list revisions on the default branch. See @ref{log options}. - -@item -d @var{dates} -Specify dates (@var{d1}<@var{d2} for range, @var{d} for -latest before). See @ref{log options}. - -@item -h -Only print header. See @ref{log options}. - -@item -l -Local; run only in current working directory. See @ref{Recursive behavior}. - -@item -N -Do not list tags. See @ref{log options}. - -@item -R -Only print name of RCS file. See @ref{log options}. - -@item -r@var{revs} -Only list revisions @var{revs}. See @ref{log options}. - -@item -s @var{states} -Only list revisions with specified states. See @ref{log options}. - -@item -t -Only print header and descriptive text. See @ref{log options}. - -@item -w@var{logins} -Only list revisions checked in by specified logins. See @ref{log options}. -@end table - -@c ------------------------------------------------------------ -@item rtag [@var{options}] @var{tag} @var{modules}@dots{} -Add a symbolic tag to a module. -See @ref{Revisions} and @ref{Branching and merging}. - -@table @code -@item -a -Clear tag from removed files that would not otherwise -be tagged. See @ref{Tagging add/remove}. - -@item -b -Create a branch named @var{tag}. See @ref{Branching and merging}. - -@item -B -Used in conjunction with -F or -d, enables movement and deletion of -branch tags. Use with extreme caution. - -@item -D @var{date} -Tag revisions as of @var{date}. See @ref{Tagging by date/tag}. - -@item -d -Delete @var{tag}. See @ref{Modifying tags}. - -@item -F -Move @var{tag} if it already exists. See @ref{Modifying tags}. - -@item -f -Force a head revision match if tag/date not found. -See @ref{Tagging by date/tag}. - -@item -l -Local; run only in current working directory. See @ref{Recursive behavior}. - -@item -n -No execution of tag program. See @ref{Common options}. - -@item -R -Operate recursively (default). @xref{Recursive -behavior}. - -@item -r @var{rev} -Tag existing tag @var{rev}. See @ref{Tagging by date/tag}. -@end table - -@c ------------------------------------------------------------ -@item server -Rsh server. See @ref{Connecting via rsh}. - -@c ------------------------------------------------------------ -@item status [@var{options}] @var{files}@dots{} -Display status information in a working directory. See -@ref{File status}. - -@table @code -@item -l -Local; run only in current working directory. See @ref{Recursive behavior}. - -@item -R -Operate recursively (default). @xref{Recursive -behavior}. - -@item -v -Include tag information for file. See @ref{Tags}. -@end table - -@c ------------------------------------------------------------ -@item tag [@var{options}] @var{tag} [@var{files}@dots{}] -Add a symbolic tag to checked out version of files. -See @ref{Revisions} and @ref{Branching and merging}. - -@table @code -@item -b -Create a branch named @var{tag}. See @ref{Branching and merging}. - -@item -c -Check that working files are unmodified. See -@ref{Tagging the working directory}. - -@item -D @var{date} -Tag revisions as of @var{date}. See @ref{Tagging by date/tag}. - -@item -d -Delete @var{tag}. See @ref{Modifying tags}. - -@item -F -Move @var{tag} if it already exists. See @ref{Modifying tags}. - -@item -f -Force a head revision match if tag/date not found. -See @ref{Tagging by date/tag}. - -@item -l -Local; run only in current working directory. See @ref{Recursive behavior}. - -@item -R -Operate recursively (default). @xref{Recursive -behavior}. - -@item -r @var{rev} -Tag existing tag @var{rev}. See @ref{Tagging by date/tag}. -@end table - -@c ------------------------------------------------------------ -@item unedit [@var{options}] [@var{files}@dots{}] -Undo an edit command. See @ref{Editing files}. - -@table @code -@item -l -Local; run only in current working directory. See @ref{Recursive behavior}. - -@item -R -Operate recursively (default). @xref{Recursive behavior}. -@end table - -@c ------------------------------------------------------------ -@item update [@var{options}] [@var{files}@dots{}] -Bring work tree in sync with repository. See -@ref{update}. - -@table @code -@item -A -Reset any sticky tags/date/options. See @ref{Sticky -tags} and @ref{Keyword substitution}. - -@item -C -Overwrite locally modified files with clean copies from -the repository (the modified file is saved in -@file{.#@var{file}.@var{revision}}, however). - -@item -D @var{date} -Check out revisions as of @var{date} (is sticky). See -@ref{Common options}. - -@item -d -Create directories. See @ref{update options}. - -@item -f -Use head revision if tag/date not found. See -@ref{Common options}. - -@item -I @var{ign} -More files to ignore (! to reset). See -@ref{import options}. - -@c Probably want to use rev1/rev2 style like for diff -@c -r. Here and in on-line help. -@item -j @var{rev} -Merge in changes. See @ref{update options}. - -@item -k @var{kflag} -Use @var{kflag} keyword expansion. See -@ref{Substitution modes}. - -@item -l -Local; run only in current working directory. @xref{Recursive behavior}. - -@item -P -Prune empty directories. See @ref{Moving directories}. - -@item -p -Check out files to standard output (avoids -stickiness). See @ref{update options}. - -@item -R -Operate recursively (default). @xref{Recursive -behavior}. - -@item -r @var{tag} -Checkout revision @var{tag} (is sticky). See @ref{Common options}. - -@item -W @var{spec} -More wrappers. See @ref{import options}. -@end table - -@c ------------------------------------------------------------ -@item version -@cindex version (subcommand) - -Display the version of @sc{cvs} being used. If the repository -is remote, display both the client and server versions. - -@c ------------------------------------------------------------ -@item watch [on|off|add|remove] [@var{options}] [@var{files}@dots{}] - -on/off: turn on/off read-only checkouts of files. See -@ref{Setting a watch}. - -add/remove: add or remove notification on actions. See -@ref{Getting Notified}. - -@table @code -@item -a @var{actions} -Specify actions for temporary watch, where -@var{actions} is @code{edit}, @code{unedit}, -@code{commit}, @code{all}, or @code{none}. See -@ref{Editing files}. - -@item -l -Local; run only in current working directory. See @ref{Recursive behavior}. - -@item -R -Operate recursively (default). @xref{Recursive -behavior}. -@end table - -@c ------------------------------------------------------------ -@item watchers [@var{options}] [@var{files}@dots{}] -See who is watching a file. See @ref{Watch information}. - -@table @code -@item -l -Local; run only in current working directory. See @ref{Recursive behavior}. - -@item -R -Operate recursively (default). @xref{Recursive -behavior}. -@end table - -@end table - -@c --------------------------------------------------------------------- -@node Administrative files -@appendix Reference manual for Administrative files -@cindex Administrative files (reference) -@cindex Files, reference manual -@cindex Reference manual (files) -@cindex CVSROOT (file) - -@c FIXME? Somewhere there needs to be a more "how-to" -@c guide to writing these. I think the triggers -@c (commitinfo, loginfo, taginfo, &c) are perhaps a -@c different case than files like modules. One -@c particular issue that people sometimes are -@c (unnecessarily?) worried about is performance, and -@c the impact of writing in perl or sh or ____. -Inside the repository, in the directory -@file{$CVSROOT/CVSROOT}, there are a number of -supportive files for @sc{cvs}. You can use @sc{cvs} in a limited -fashion without any of them, but if they are set up -properly they can help make life easier. For a -discussion of how to edit them, see @ref{Intro -administrative files}. - -The most important of these files is the @file{modules} -file, which defines the modules inside the repository. - -@menu -* modules:: Defining modules -* Wrappers:: Specify binary-ness based on file name -* Trigger Scripts:: Some notes on the commit support files and - taginfo, referenced below. -* commit files:: The commit support files (commitinfo, - verifymsg, editinfo, loginfo) -* taginfo:: Verifying/Logging tags -* rcsinfo:: Templates for the log messages -* cvsignore:: Ignoring files via cvsignore -* checkoutlist:: Adding your own administrative files -* history file:: History information -* Variables:: Various variables are expanded -* config:: Miscellaneous CVS configuration -@end menu - -@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@node modules -@appendixsec The modules file -@cindex Modules (admin file) -@cindex Defining modules (reference manual) - -The @file{modules} file records your definitions of -names for collections of source code. @sc{cvs} will -use these definitions if you use @sc{cvs} to update the -modules file (use normal commands like @code{add}, -@code{commit}, etc). - -The @file{modules} file may contain blank lines and -comments (lines beginning with @samp{#}) as well as -module definitions. Long lines can be continued on the -next line by specifying a backslash (@samp{\}) as the -last character on the line. - -There are three basic types of modules: alias modules, -regular modules, and ampersand modules. The difference -between them is the way that they map files in the -repository to files in the working directory. In all -of the following examples, the top-level repository -contains a directory called @file{first-dir}, which -contains two files, @file{file1} and @file{file2}, and a -directory @file{sdir}. @file{first-dir/sdir} contains -a file @file{sfile}. - -@c FIXME: should test all the examples in this section. - -@menu -* Alias modules:: The simplest kind of module -* Regular modules:: -* Ampersand modules:: -* Excluding directories:: Excluding directories from a module -* Module options:: Regular and ampersand modules can take options -* Module program options:: How the modules ``program options'' programs - are run. -@end menu - -@node Alias modules -@appendixsubsec Alias modules -@cindex Alias modules -@cindex -a, in modules file - -Alias modules are the simplest kind of module: - -@table @code -@item @var{mname} -a @var{aliases}@dots{} -This represents the simplest way of defining a module -@var{mname}. The @samp{-a} flags the definition as a -simple alias: @sc{cvs} will treat any use of @var{mname} (as -a command argument) as if the list of names -@var{aliases} had been specified instead. -@var{aliases} may contain either other module names or -paths. When you use paths in aliases, @code{checkout} -creates all intermediate directories in the working -directory, just as if the path had been specified -explicitly in the @sc{cvs} arguments. -@end table - -For example, if the modules file contains: - -@example -amodule -a first-dir -@end example - -@noindent -then the following two commands are equivalent: - -@example -$ cvs co amodule -$ cvs co first-dir -@end example - -@noindent -and they each would provide output such as: - -@example -cvs checkout: Updating first-dir -U first-dir/file1 -U first-dir/file2 -cvs checkout: Updating first-dir/sdir -U first-dir/sdir/sfile -@end example - -@node Regular modules -@appendixsubsec Regular modules -@cindex Regular modules - -@table @code -@item @var{mname} [ options ] @var{dir} [ @var{files}@dots{} ] -In the simplest case, this form of module definition -reduces to @samp{@var{mname} @var{dir}}. This defines -all the files in directory @var{dir} as module mname. -@var{dir} is a relative path (from @code{$CVSROOT}) to a -directory of source in the source repository. In this -case, on checkout, a single directory called -@var{mname} is created as a working directory; no -intermediate directory levels are used by default, even -if @var{dir} was a path involving several directory -levels. -@end table - -For example, if a module is defined by: - -@example -regmodule first-dir -@end example - -@noindent -then regmodule will contain the files from first-dir: - -@example -$ cvs co regmodule -cvs checkout: Updating regmodule -U regmodule/file1 -U regmodule/file2 -cvs checkout: Updating regmodule/sdir -U regmodule/sdir/sfile -$ -@end example - -By explicitly specifying files in the module definition -after @var{dir}, you can select particular files from -directory @var{dir}. Here is -an example: - -@example -regfiles first-dir/sdir sfile -@end example - -@noindent -With this definition, getting the regfiles module -will create a single working directory -@file{regfiles} containing the file listed, which -comes from a directory deeper -in the @sc{cvs} source repository: - -@example -$ cvs co regfiles -U regfiles/sfile -$ -@end example - -@node Ampersand modules -@appendixsubsec Ampersand modules -@cindex Ampersand modules -@cindex &, in modules file - -A module definition can refer to other modules by -including @samp{&@var{module}} in its definition. -@example -@var{mname} [ options ] @var{&module}@dots{} -@end example - -Then getting the module creates a subdirectory for each such -module, in the directory containing the module. For -example, if modules contains - -@example -ampermod &first-dir -@end example - -@noindent -then a checkout will create an @code{ampermod} directory -which contains a directory called @code{first-dir}, -which in turns contains all the directories and files -which live there. For example, the command - -@example -$ cvs co ampermod -@end example - -@noindent -will create the following files: - -@example -ampermod/first-dir/file1 -ampermod/first-dir/file2 -ampermod/first-dir/sdir/sfile -@end example - -There is one quirk/bug: the messages that @sc{cvs} -prints omit the @file{ampermod}, and thus do not -correctly display the location to which it is checking -out the files: - -@example -$ cvs co ampermod -cvs checkout: Updating first-dir -U first-dir/file1 -U first-dir/file2 -cvs checkout: Updating first-dir/sdir -U first-dir/sdir/sfile -$ -@end example - -Do not rely on this buggy behavior; it may get fixed in -a future release of @sc{cvs}. - -@c FIXCVS: What happens if regular and & modules are -@c combined, as in "ampermodule first-dir &second-dir"? -@c When I tried it, it seemed to just ignore the -@c "first-dir". I think perhaps it should be an error -@c (but this needs further investigation). -@c In addition to discussing what each one does, we -@c should put in a few words about why you would use one or -@c the other in various situations. - -@node Excluding directories -@appendixsubsec Excluding directories -@cindex Excluding directories, in modules file -@cindex !, in modules file - -An alias module may exclude particular directories from -other modules by using an exclamation mark (@samp{!}) -before the name of each directory to be excluded. - -For example, if the modules file contains: - -@example -exmodule -a !first-dir/sdir first-dir -@end example - -@noindent -then checking out the module @samp{exmodule} will check -out everything in @samp{first-dir} except any files in -the subdirectory @samp{first-dir/sdir}. -@c Note that the "!first-dir/sdir" sometimes must be listed -@c before "first-dir". That seems like a probable bug, in which -@c case perhaps it should be fixed (to allow either -@c order) rather than documented. See modules4 in testsuite. - -@node Module options -@appendixsubsec Module options -@cindex Options, in modules file - -Either regular modules or ampersand modules can contain -options, which supply additional information concerning -the module. - -@table @code -@cindex -d, in modules file -@item -d @var{name} -Name the working directory something other than the -module name. -@c FIXME: Needs a bunch of examples, analogous to the -@c examples for alias, regular, and ampersand modules -@c which show where the files go without -d. - -@cindex Export program -@cindex -e, in modules file -@item -e @var{prog} -Specify a program @var{prog} to run whenever files in a -module are exported. @var{prog} runs with a single -argument, the module name. -@c FIXME: Is it run on server? client? - -@cindex Checkout program -@cindex -o, in modules file -@item -o @var{prog} -Specify a program @var{prog} to run whenever files in a -module are checked out. @var{prog} runs with a single -argument, the module name. See @ref{Module program options} for -information on how @var{prog} is called. -@c FIXME: Is it run on server? client? - -@cindex Status of a module -@cindex Module status -@cindex -s, in modules file -@item -s @var{status} -Assign a status to the module. When the module file is -printed with @samp{cvs checkout -s} the modules are -sorted according to primarily module status, and -secondarily according to the module name. This option -has no other meaning. You can use this option for -several things besides status: for instance, list the -person that is responsible for this module. - -@cindex Tag program -@cindex -t, in modules file -@item -t @var{prog} -Specify a program @var{prog} to run whenever files in a -module are tagged with @code{rtag}. @var{prog} runs -with two arguments: the module name and the symbolic -tag specified to @code{rtag}. It is not run -when @code{tag} is executed. Generally you will find -that the @file{taginfo} file is a better solution (@pxref{taginfo}). -@c FIXME: Is it run on server? client? -@c Problems with -t include: -@c * It is run after the tag not before -@c * It doesn't get passed all the information that -@c taginfo does ("mov", &c). -@c * It only is run for rtag, not tag. -@end table - -You should also see @pxref{Module program options} about how the -``program options'' programs are run. - -@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@node Module program options -@appendixsubsec How the modules file ``program options'' programs are run -@cindex Modules file program options -@cindex -t, in modules file -@cindex -o, in modules file -@cindex -e, in modules file - -@noindent -For checkout, rtag, and export, the program is server-based, and as such the -following applies:- - -If using remote access methods (pserver, ext, etc.), -@sc{cvs} will execute this program on the server from a temporary -directory. The path is searched for this program. - -If using ``local access'' (on a local or remote NFS file system, i.e., -repository set just to a path), -the program will be executed from the newly checked-out tree, if -found there, or alternatively searched for in the path if not. - -The programs are all run after the operation has effectively -completed. - - -@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@node Wrappers -@appendixsec The cvswrappers file -@cindex cvswrappers (admin file) -@cindex CVSWRAPPERS, environment variable -@cindex Wrappers - -@c FIXME: need some better way of separating this out -@c by functionality. -m is -@c one feature, and -k is a another. And this discussion -@c should be better motivated (e.g. start with the -@c problems, then explain how the feature solves it). - -Wrappers refers to a @sc{cvs} feature which lets you -control certain settings based on the name of the file -which is being operated on. The settings are @samp{-k} -for binary files, and @samp{-m} for nonmergeable text -files. - -The @samp{-m} option -specifies the merge methodology that should be used when -a non-binary file is updated. @code{MERGE} means the usual -@sc{cvs} behavior: try to merge the files. @code{COPY} -means that @code{cvs update} will refuse to merge -files, as it also does for files specified as binary -with @samp{-kb} (but if the file is specified as -binary, there is no need to specify @samp{-m 'COPY'}). -@sc{cvs} will provide the user with the -two versions of the files, and require the user using -mechanisms outside @sc{cvs}, to insert any necessary -changes. - -@strong{WARNING: Do not use @code{COPY} with -@sc{cvs} 1.9 or earlier - such versions of @sc{cvs} will -copy one version of your file over the other, wiping -out the previous contents.} -@c Ordinarily we don't document the behavior of old -@c versions. But this one is so dangerous, I think we -@c must. I almost renamed it to -m 'NOMERGE' so we -@c could say "never use -m 'COPY'". -The @samp{-m} wrapper option only affects behavior when -merging is done on update; it does not affect how files -are stored. See @ref{Binary files}, for more on -binary files. - -The basic format of the file @file{cvswrappers} is: - -@c FIXME: @example is all wrong for this. Use @deffn or -@c something more sensible. -@example -wildcard [option value][option value]... - -where option is one of --m update methodology value: MERGE or COPY --k keyword expansion value: expansion mode - -and value is a single-quote delimited value. -@end example - -@ignore -@example -*.nib -f 'unwrap %s' -t 'wrap %s %s' -m 'COPY' -*.c -t 'indent %s %s' -@end example -@c When does the filter need to be an absolute pathname -@c and when will something like the above work? I -@c suspect it relates to the PATH of the server (which -@c in turn depends on all kinds of stuff, e.g. inetd -@c for pserver). I'm not sure whether/where to discuss -@c this. -@c FIXME: What do the %s's stand for? - -@noindent -The above example of a @file{cvswrappers} file -states that all files/directories that end with a @code{.nib} -should be filtered with the @file{wrap} program before -checking the file into the repository. The file should -be filtered though the @file{unwrap} program when the -file is checked out of the repository. The -@file{cvswrappers} file also states that a @code{COPY} -methodology should be used when updating the files in -the repository (that is, no merging should be performed). - -@c What pitfalls arise when using indent this way? Is -@c it a winning thing to do? Would be nice to at least -@c hint at those issues; we want our examples to tell -@c how to solve problems, not just to say that cvs can -@c do certain things. -The last example line says that all files that end with -@code{.c} should be filtered with @file{indent} -before being checked into the repository. Unlike the previous -example, no filtering of the @code{.c} file is done when -it is checked out of the repository. -@noindent -The @code{-t} filter is called with two arguments, -the first is the name of the file/directory to filter -and the second is the pathname to where the resulting -filtered file should be placed. - -@noindent -The @code{-f} filter is called with one argument, -which is the name of the file to filter from. The end -result of this filter will be a file in the users directory -that they can work on as they normally would. - -Note that the @samp{-t}/@samp{-f} features do not -conveniently handle one portion of @sc{cvs}'s operation: -determining when files are modified. @sc{cvs} will still -want a file (or directory) to exist, and it will use -its modification time to determine whether a file is -modified. If @sc{cvs} erroneously thinks a file is -unmodified (for example, a directory is unchanged but -one of the files within it is changed), you can force -it to check in the file anyway by specifying the -@samp{-f} option to @code{cvs commit} (@pxref{commit -options}). -@c This is, of course, a serious design flaw in -t/-f. -@c Probably the whole functionality needs to be -@c redesigned (starting from requirements) to fix this. -@end ignore - -@c FIXME: We don't document -W or point to where it is -@c documented. Or .cvswrappers. -For example, the following command imports a -directory, treating files whose name ends in -@samp{.exe} as binary: - -@example -cvs import -I ! -W "*.exe -k 'b'" first-dir vendortag reltag -@end example - -@c Another good example, would be storing files -@c (e.g. binary files) compressed in the repository. -@c :::::::::::::::::: -@c cvswrappers -@c :::::::::::::::::: -@c *.t12 -m 'COPY' -@c *.t[0-9][0-9] -f 'gunzipcp %s' -t 'gzipcp %s %s' -m 'COPY' -@c -@c :::::::::::::::::: -@c gunzipcp -@c :::::::::::::::::: -@c : -@c [ -f $1 ] || exit 1 -@c zcat $1 > /tmp/.#$1.$$ -@c mv /tmp/.#$1.$$ $1 -@c -@c :::::::::::::::::: -@c gzipcp -@c :::::::::::::::::: -@c : -@c DIRNAME=`echo $1 | sed -e "s|/.*/||g"` -@c if [ ! -d $DIRNAME ] ; then -@c DIRNAME=`echo $1 | sed -e "s|.*/||g"` -@c fi -@c gzip -c $DIRNAME > $2 -@c One catch--"cvs diff" will not invoke the wrappers -@c (probably a CVS bug, although I haven't thought it out). - -@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -@node Trigger Scripts -@appendixsec The Trigger Scripts -@cindex Info files -@cindex Trigger scripts - -Several of the administrative files support triggers, or the launching external -scripts or programs at specific times before or after particular events. The -individual files are discussed in the later sections, @ref{commit files} and -@ref{taginfo}, but some of the common elements are discussed here. - -All the trigger scripts are launched in a copy of the user sandbox being -committed, on the server, in client-server mode. In local mode, the scripts -are actually launched directly from the user sandbox directory being committed. -For most intents and purposes, the same scripts can be run in both locations -without alteration. - -@menu -* syntax:: The common syntax -* Trigger Script Security:: Trigger script security -@end menu - -@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -@node syntax -@appendixsubsec The common syntax -@cindex Info files (syntax) -@cindex Syntax of info files -@cindex Common syntax of info files - -@c FIXME: having this so totally separate from the -@c Variables node is rather bogus. - -The administrative files such as @file{commitinfo}, -@file{loginfo}, @file{rcsinfo}, @file{verifymsg}, etc., -all have a common format. The purpose of the files are -described later on. The common syntax is described -here. - -@cindex Regular expression syntax -Each line contains the following: -@itemize @bullet -@item -@c Say anything about DEFAULT and ALL? Right now we -@c leave that to the description of each file (and in fact -@c the practice is inconsistent which is really annoying). -A regular expression. This is a basic regular -expression in the syntax used by GNU emacs. -@c FIXME: What we probably should be saying is "POSIX Basic -@c Regular Expression with the following extensions (`\(' -@c `\|' '+' etc)" -@c rather than define it with reference to emacs. -@c The reference to emacs is not strictly speaking -@c true, as we don't support \=, \s, or \S. Also it isn't -@c clear we should document and/or promise to continue to -@c support all the obscure emacs extensions like \<. -@c Also need to better cite (or include) full -@c documentation for the syntax. -@c Also see comment in configure.in about what happens to the -@c syntax if we pick up a system-supplied regexp matcher. - -@item -A whitespace separator---one or more spaces and/or tabs. - -@item -A file name or command-line template. -@end itemize - -@noindent -Blank lines are ignored. Lines that start with the -character @samp{#} are treated as comments. Long lines -unfortunately can @emph{not} be broken in two parts in -any way. - -The first regular expression that matches the current -directory name in the repository is used. The rest of the line -is used as a file name or command-line as appropriate. - -@c FIXME: need an example. In particular, show what -@c the regular expression is matched against (one -@c ordinarily clueful person got confused about whether it -@c includes the filename--"directory name" above should be -@c unambiguous but there is nothing like an example to -@c confirm people's understanding of this sort of thing). - -@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -@node Trigger Script Security -@appendixsubsec Security and the Trigger Scripts -@cindex Info files, security -@cindex Trigger scripts, security - -Security is a huge subject, and implementing a secure system is a non-trivial -task. This section will barely touch on all the issues involved, but it is -well to note that, as with any script you will be allowing an untrusted -user to run on your server, there are measures you can take to help prevent -your trigger scripts from being abused. - -For instance, since the CVS trigger scripts all run in a copy of the user's -sandbox on the server, a naively coded Perl trigger script which attempts to -use a Perl module that is not installed on the system can be hijacked by any -user with commit access who is checking in a file with the correct name. Other -scripting languages may be vulnerable to similar hacks. - -One way to make a script more secure, at least with Perl, is to use scripts -which invoke the @code{-T}, or "taint-check" switch on their @code{#!} line. -In the most basic terms, this causes Perl to avoid running code that may have -come from an external source. Please run the @code{perldoc perlsec} command -for more on Perl security. Again, other languages may implement other security -verification hooks which look more or less like Perl's "taint-check" mechanism. - -@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@node commit files -@appendixsec The commit support files -@cindex Committing, administrative support files - -There are three kinds of trigger scripts (@pxref{Trigger Scripts}) that can be -run at various times during a commit. They are specified in files in the -repository, as described below. The following table summarizes the -file names and the purpose of the corresponding programs. - -@table @file -@item commitinfo -The program is responsible for checking that the commit -is allowed. If it exits with a non-zero exit status -the commit will be aborted. - -@item verifymsg -The specified program is used to evaluate the log message, -and possibly verify that it contains all required -fields. This is most useful in combination with the -@file{rcsinfo} file, which can hold a log message -template (@pxref{rcsinfo}). - -@item editinfo -The specified program is used to edit the log message, -and possibly verify that it contains all required -fields. This is most useful in combination with the -@file{rcsinfo} file, which can hold a log message -template (@pxref{rcsinfo}). (obsolete) - -@item loginfo -The specified program is called when the commit is -complete. It receives the log message and some -additional information and can store the log message in -a file, or mail it to appropriate persons, or maybe -post it to a local newsgroup, or@dots{} Your -imagination is the limit! -@end table - -@menu -* commitinfo:: Pre-commit checking -* verifymsg:: How are log messages evaluated? -* editinfo:: Specifying how log messages are created - (obsolete) -* loginfo:: Where should log messages be sent? -@end menu - -@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@node commitinfo -@appendixsubsec Commitinfo -@cindex @file{commitinfo} -@cindex Commits, precommit verification of -@cindex Precommit checking - -The @file{commitinfo} file defines programs to execute -whenever @samp{cvs commit} is about to execute. These -programs are used for pre-commit checking to verify -that the modified, added and removed files are really -ready to be committed. This could be used, for -instance, to verify that the changed files conform to -to your site's standards for coding practice. - -As mentioned earlier, each line in the -@file{commitinfo} file consists of a regular expression -and a command-line template. The template can include -a program name and any number of arguments you wish to -supply to it. The full path to the current source -repository is appended to the template, followed by the -file names of any files involved in the commit (added, -removed, and modified files). - -@cindex Exit status, of commitinfo -The first line with a regular expression matching the -directory within the repository will be used. If the -command returns a non-zero exit status the commit will -be aborted. -@c FIXME: need example(s) of what "directory within the -@c repository" means. - -@cindex DEFAULT in commitinfo -If the repository name does not match any of the -regular expressions in this file, the @samp{DEFAULT} -line is used, if it is specified. - -@cindex ALL in commitinfo -All occurrences of the name @samp{ALL} appearing as a -regular expression are used in addition to the first -matching regular expression or the name @samp{DEFAULT}. - -@cindex @file{commitinfo}, working directory -@cindex @file{commitinfo}, command environment -The command will be run in the root of the workspace -containing the new versions of any files the user would like -to modify (commit), @emph{or in a copy of the workspace on -the server (@pxref{Remote repositories})}. If a file is -being removed, there will be no copy of the file under the -current directory. If a file is being added, there will be -no corresponding archive file in the repository unless the -file is being resurrected. - -Note that both the repository directory and the corresponding -Attic (@pxref{Attic}) directory may need to be checked to -locate the archive file corresponding to any given file being -committed. Much of the information about the specific commit -request being made, including the destination branch, commit -message, and command line options specified, is not available -to the command. - -@c FIXME: should discuss using commitinfo to control -@c who has checkin access to what (e.g. Joe can check into -@c directories a, b, and c, and Mary can check into -@c directories b, c, and d--note this case cannot be -@c conveniently handled with unix groups). Of course, -@c adding a new set of features to CVS might be a more -@c natural way to fix this problem than telling people to -@c use commitinfo. -@c FIXME: Should make some reference, especially in -@c the context of controlling who has access, to the fact -@c that commitinfo can be circumvented. Perhaps -@c mention SETXID (but has it been carefully examined -@c for holes?). This fits in with the discussion of -@c general CVS security in "Password authentication -@c security" (the bit which is not pserver-specific). - -@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@node verifymsg -@appendixsubsec Verifying log messages -@cindex @file{verifymsg} (admin file) -@cindex Log message, verifying - -Once you have entered a log message, you can evaluate -that message to check for specific content, such as -a bug ID. Use the @file{verifymsg} file to -specify a program that is used to verify the log message. -This program could be a simple script that checks -that the entered message contains the required fields. - -The @file{verifymsg} file is often most useful together -with the @file{rcsinfo} file, which can be used to -specify a log message template. - -Each line in the @file{verifymsg} file consists of a -regular expression and a command-line template. The -template must include a program name, and can include -any number of arguments. The full path to the current -log message template file is appended to the template. - -One thing that should be noted is that the @samp{ALL} -keyword is not supported. If more than one matching -line is found, the first one is used. This can be -useful for specifying a default verification script in a -directory, and then overriding it in a subdirectory. - -@cindex DEFAULT in @file{verifymsg} -If the repository name does not match any of the -regular expressions in this file, the @samp{DEFAULT} -line is used, if it is specified. - -@cindex Exit status, of @file{verifymsg} -If the verification script exits with a non-zero exit status, -the commit is aborted. - -@cindex @file{verifymsg}, changing the log message -In the default configuration, CVS allows the -verification script to change the log message. This is -controlled via the RereadLogAfterVerify CVSROOT/config -option. - -When @samp{RereadLogAfterVerify=always} or -@samp{RereadLogAfterVerify=stat}, the log message will -either always be reread after the verification script -is run or reread only if the log message file status -has changed. - -@xref{config}, for more on CVSROOT/config options. - -It is NOT a good idea for a @file{verifymsg} script to -interact directly with the user in the various -client/server methods. For the @code{pserver} method, -there is no protocol support for communicating between -@file{verifymsg} and the client on the remote end. For the -@code{ext} and @code{server} methods, it is possible -for CVS to become confused by the characters going -along the same channel as the CVS protocol -messages. See @ref{Remote repositories}, for more -information on client/server setups. In addition, at the time -the @file{verifymsg} script runs, the CVS -server has locks in place in the repository. If control is -returned to the user here then other users may be stuck waiting -for access to the repository. - -This option can be useful if you find yourself using an -rcstemplate that needs to be modified to remove empty -elements or to fill in default values. It can also be -useful if the rcstemplate has changed in the repository -and the CVS/Template was not updated, but is able to be -adapted to the new format by the verification script -that is run by @file{verifymsg}. - -An example of an update might be to change all -occurrences of 'BugId:' to be 'DefectId:' (which can be -useful if the rcstemplate has recently been changed and -there are still checked-out user trees with cached -copies in the CVS/Template file of the older version). - -Another example of an update might be to delete a line -that contains 'BugID: none' from the log message after -validation of that value as being allowed is made. - -The following is a little silly example of a -@file{verifymsg} file, together with the corresponding -@file{rcsinfo} file, the log message template and an -verification script. We begin with the log message template. -We want to always record a bug-id number on the first -line of the log message. The rest of log message is -free text. The following template is found in the file -@file{/usr/cvssupport/tc.template}. - -@example -BugId: -@end example - -The script @file{/usr/cvssupport/bugid.verify} is used to -evaluate the log message. - -@example -#!/bin/sh -# -# bugid.verify filename -# -# Verify that the log message contains a valid bugid -# on the first line. -# -if sed 1q < $1 | grep '^BugId:[ ]*[0-9][0-9]*$' > /dev/null; then - exit 0 -elif sed 1q < $1 | grep '^BugId:[ ]*none$' > /dev/null; then - # It is okay to allow commits with 'BugId: none', - # but do not put that text into the real log message. - grep -v '^BugId:[ ]*none$' > $1.rewrite - mv $1.rewrite $1 - exit 0 -else - echo "No BugId found." - exit 1 -fi -@end example - -The @file{verifymsg} file contains this line: - -@example -^tc /usr/cvssupport/bugid.verify -@end example - -The @file{rcsinfo} file contains this line: - -@example -^tc /usr/cvssupport/tc.template -@end example - -The @file{config} file contains this line: - -@example -RereadLogAfterVerify=always -@end example - - - -@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@node editinfo -@appendixsubsec Editinfo -@cindex editinfo (admin file) -@cindex Editor, specifying per module -@cindex Per-module editor -@cindex Log messages, editing - -@strong{The @file{editinfo} feature has been -rendered obsolete. To set a default editor for log -messages use the @code{CVSEDITOR}, @code{EDITOR} environment variables -(@pxref{Environment variables}) or the @samp{-e} global -option (@pxref{Global options}). See @ref{verifymsg}, -for information on the use of the @file{verifymsg} -feature for evaluating log messages.} - -If you want to make sure that all log messages look the -same way, you can use the @file{editinfo} file to -specify a program that is used to edit the log message. -This program could be a custom-made editor that always -enforces a certain style of the log message, or maybe a -simple shell script that calls an editor, and checks -that the entered message contains the required fields. - -If no matching line is found in the @file{editinfo} -file, the editor specified in the environment variable -@code{$CVSEDITOR} is used instead. If that variable is -not set, then the environment variable @code{$EDITOR} -is used instead. If that variable is not -set a default will be used. See @ref{Committing your changes}. - -The @file{editinfo} file is often most useful together -with the @file{rcsinfo} file, which can be used to -specify a log message template. - -Each line in the @file{editinfo} file consists of a -regular expression and a command-line template. The -template must include a program name, and can include -any number of arguments. The full path to the current -log message template file is appended to the template. - -One thing that should be noted is that the @samp{ALL} -keyword is not supported. If more than one matching -line is found, the first one is used. This can be -useful for specifying a default edit script in a -module, and then overriding it in a subdirectory. - -@cindex DEFAULT in editinfo -If the repository name does not match any of the -regular expressions in this file, the @samp{DEFAULT} -line is used, if it is specified. - -If the edit script exits with a non-zero exit status, -the commit is aborted. - -Note: when @sc{cvs} is accessing a remote repository, -or when the @samp{-m} or @samp{-F} options to @code{cvs -commit} are used, @file{editinfo} will not be consulted. -There is no good workaround for this; use -@file{verifymsg} instead. - -@menu -* editinfo example:: Editinfo example -@end menu - -@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -@node editinfo example -@appendixsubsubsec Editinfo example - -The following is a little silly example of a -@file{editinfo} file, together with the corresponding -@file{rcsinfo} file, the log message template and an -editor script. We begin with the log message template. -We want to always record a bug-id number on the first -line of the log message. The rest of log message is -free text. The following template is found in the file -@file{/usr/cvssupport/tc.template}. - -@example -BugId: -@end example - -The script @file{/usr/cvssupport/bugid.edit} is used to -edit the log message. - -@example -#!/bin/sh -# -# bugid.edit filename -# -# Call $EDITOR on FILENAME, and verify that the -# resulting file contains a valid bugid on the first -# line. -if [ "x$EDITOR" = "x" ]; then EDITOR=vi; fi -if [ "x$CVSEDITOR" = "x" ]; then CVSEDITOR=$EDITOR; fi -$CVSEDITOR $1 -until head -1|grep '^BugId:[ ]*[0-9][0-9]*$' < $1 -do echo -n "No BugId found. Edit again? ([y]/n)" - read ans - case $@{ans@} in - n*) exit 1;; - esac - $CVSEDITOR $1 -done -@end example - -The @file{editinfo} file contains this line: - -@example -^tc /usr/cvssupport/bugid.edit -@end example - -The @file{rcsinfo} file contains this line: - -@example -^tc /usr/cvssupport/tc.template -@end example - -@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@node loginfo -@appendixsubsec Loginfo -@cindex loginfo (admin file) -@cindex Storing log messages -@cindex Mailing log messages -@cindex Distributing log messages -@cindex Log messages - -@c "cvs commit" is not quite right. What we -@c mean is "when the repository gets changed" which -@c also includes "cvs import" and "cvs add" on a directory. -The @file{loginfo} file is used to control where -@samp{cvs commit} log information is sent. The first -entry on a line is a regular expression which is tested -against the directory that the change is being made to, -relative to the @code{$CVSROOT}. If a match is found, then -the remainder of the line is a filter program that -should expect log information on its standard input. -Note that the filter program @strong{must} read @strong{all} -of the log information or @sc{cvs} may fail with a broken pipe signal. - -If the repository name does not match any of the -regular expressions in this file, the @samp{DEFAULT} -line is used, if it is specified. - -All occurrences of the name @samp{ALL} appearing as a -regular expression are used in addition to the first -matching regular expression or @samp{DEFAULT}. - -The first matching regular expression is used. - -@xref{commit files}, for a description of the syntax of -the @file{loginfo} file. - -The user may specify a format string as -part of the filter. The string is composed of a -@samp{%} followed by a space, or followed by a single -format character, or followed by a set of format -characters surrounded by @samp{@{} and @samp{@}} as -separators. The format characters are: - -@table @t -@item s -file name -@item V -old version number (pre-checkin) -@item v -new version number (post-checkin) -@end table - -All other characters that appear in a format string -expand to an empty field (commas separating fields are -still provided). - -For example, some valid format strings are @samp{%}, -@samp{%s}, @samp{%@{s@}}, and @samp{%@{sVv@}}. - -The output will be a space separated string of tokens enclosed in -quotation marks (@t{"}). -Any embedded dollar signs (@t{$}), backticks (@t{`}), -backslashes (@t{\}), or quotation marks will be preceded -by a backslash (this allows the shell to correctly parse it -as a single string, reguardless of the characters it contains). -For backwards compatibility, the first -token will be the repository subdirectory. The rest of the -tokens will be comma-delimited lists of the information -requested in the format string. For example, if -@samp{/u/src/master/yoyodyne/tc} is the repository, @samp{%@{sVv@}} -is the format string, and three files (@t{ChangeLog}, -@t{Makefile}, @t{foo.c}) were modified, the output -might be: - -@example -"yoyodyne/tc ChangeLog,1.1,1.2 Makefile,1.3,1.4 foo.c,1.12,1.13" -@end example - -As another example, @samp{%@{@}} means that only the -name of the repository will be generated. - -Note: when @sc{cvs} is accessing a remote repository, -@file{loginfo} will be run on the @emph{remote} -(i.e., server) side, not the client side (@pxref{Remote -repositories}). - -@menu -* loginfo example:: Loginfo example -* Keeping a checked out copy:: Updating a tree on every checkin -@end menu - -@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -@node loginfo example -@appendixsubsubsec Loginfo example - -The following @file{loginfo} file, together with the -tiny shell-script below, appends all log messages -to the file @file{$CVSROOT/CVSROOT/commitlog}, -and any commits to the administrative files (inside -the @file{CVSROOT} directory) are also logged in -@file{/usr/adm/cvsroot-log}. -Commits to the @file{prog1} directory are mailed to @t{ceder}. - -@c FIXME: is it a CVS feature or bug that only the -@c first matching line is used? It is documented -@c above, but is it useful? For example, if we wanted -@c to run both "cvs-log" and "Mail" for the CVSROOT -@c directory, it is kind of awkward if -@c only the first matching line is used. -@example -ALL /usr/local/bin/cvs-log $CVSROOT/CVSROOT/commitlog $USER -^CVSROOT /usr/local/bin/cvs-log /usr/adm/cvsroot-log -^prog1 Mail -s %s ceder -@end example - -The shell-script @file{/usr/local/bin/cvs-log} looks -like this: - -@example -#!/bin/sh -(echo "------------------------------------------------------"; - echo -n $2" "; - date; - echo; - cat) >> $1 -@end example - -@node Keeping a checked out copy -@appendixsubsubsec Keeping a checked out copy - -@c What other index entries? It seems like -@c people might want to use a lot of different -@c words for this functionality. -@cindex Keeping a checked out copy -@cindex Checked out copy, keeping -@cindex Web pages, maintaining with CVS - -It is often useful to maintain a directory tree which -contains files which correspond to the latest version -in the repository. For example, other developers might -want to refer to the latest sources without having to -check them out, or you might be maintaining a web site -with @sc{cvs} and want every checkin to cause the files -used by the web server to be updated. -@c Can we offer more details on the web example? Or -@c point the user at how to figure it out? This text -@c strikes me as sufficient for someone who already has -@c some idea of what we mean but not enough for the naive -@c user/sysadmin to understand it and set it up. - -The way to do this is by having loginfo invoke -@code{cvs update}. Doing so in the naive way will -cause a problem with locks, so the @code{cvs update} -must be run in the background. -@c Should we try to describe the problem with locks? -@c It seems like a digression for someone who just -@c wants to know how to make it work. -@c Another choice which might work for a single file -@c is to use "cvs -n update -p" which doesn't take -@c out locks (I think) but I don't see many advantages -@c of that and we might as well document something which -@c works for multiple files. -Here is an example for unix (this should all be on one line): - -@example -^cyclic-pages (date; cat; (sleep 2; cd /u/www/local-docs; - cvs -q update -d) &) >> $CVSROOT/CVSROOT/updatelog 2>&1 -@end example - -This will cause checkins to repository directories -starting with @code{cyclic-pages} to update the checked -out tree in @file{/u/www/local-docs}. -@c More info on some of the details? The "sleep 2" is -@c so if we are lucky the lock will be gone by the time -@c we start and we can wait 2 seconds instead of 30. - -@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@node rcsinfo -@appendixsec Rcsinfo -@cindex rcsinfo (admin file) -@cindex Form for log message -@cindex Log message template -@cindex Template for log message - -The @file{rcsinfo} file can be used to specify a form to -edit when filling out the commit log. The -@file{rcsinfo} file has a syntax similar to the -@file{verifymsg}, @file{commitinfo} and @file{loginfo} -files. @xref{syntax}. Unlike the other files the second -part is @emph{not} a command-line template. Instead, -the part after the regular expression should be a full pathname to -a file containing the log message template. - -If the repository name does not match any of the -regular expressions in this file, the @samp{DEFAULT} -line is used, if it is specified. - -All occurrences of the name @samp{ALL} appearing as a -regular expression are used in addition to the first -matching regular expression or @samp{DEFAULT}. - -@c FIXME: should be offering advice, somewhere around -@c here, about where to put the template file. The -@c verifymsg example uses /usr/cvssupport but doesn't -@c say anything about what that directory is for or -@c whether it is hardwired into CVS or who creates -@c it or anything. In particular we should say -@c how to version control the template file. A -@c probably better answer than the /usr/cvssupport -@c stuff is to use checkoutlist (with xref to the -@c checkoutlist doc). -@c Also I am starting to see a connection between -@c this and the Keeping a checked out copy node. -@c Probably want to say something about that. -The log message template will be used as a default log -message. If you specify a log message with @samp{cvs -commit -m @var{message}} or @samp{cvs commit -f -@var{file}} that log message will override the -template. - -@xref{verifymsg}, for an example @file{rcsinfo} -file. - -When @sc{cvs} is accessing a remote repository, -the contents of @file{rcsinfo} at the time a directory -is first checked out will specify a template which does -not then change. If you edit @file{rcsinfo} or its -templates, you may need to check out a new working -directory. -@c Would be nice to fix CVS so this isn't needed. For -@c example, a mechanism analogous to CVS/Entries, where -@c the client keeps track of what version of the template -@c it has. - -@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@node taginfo -@appendixsec Taginfo -@cindex taginfo (admin file) -@cindex Tags, logging -@cindex Tags, verifying -The @file{taginfo} file defines programs to execute -when someone executes a @code{tag} or @code{rtag} -command. The @file{taginfo} file has the standard form -for trigger scripts (@pxref{Trigger Scripts}), -where each line is a regular expression -followed by a command to execute (@pxref{syntax}). The arguments passed -to the command are, in order, the @var{tagname}, -@var{operation} (@code{add} for @code{tag}, -@code{mov} for @code{tag -F}, and @code{del} for -@code{tag -d}), @var{repository}, and any remaining are -pairs of @var{filename} @var{revision}. A non-zero -exit of the filter program will cause the tag to be -aborted. - -Here is an example of using the @file{taginfo} file -to log @code{tag} and @code{rtag} -commands. In the @file{taginfo} file put: - -@example -ALL /usr/local/cvsroot/CVSROOT/loggit -@end example - -@noindent -Where @file{/usr/local/cvsroot/CVSROOT/loggit} contains the -following script: - -@example -#!/bin/sh -echo "$@@" >>/home/kingdon/cvsroot/CVSROOT/taglog -@end example - -@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@node cvsignore -@appendixsec Ignoring files via cvsignore -@cindex cvsignore (admin file), global -@cindex Global cvsignore -@cindex Ignoring files -@c -- This chapter should maybe be moved to the -@c tutorial part of the manual? - -There are certain file names that frequently occur -inside your working copy, but that you don't want to -put under @sc{cvs} control. Examples are all the object -files that you get while you compile your sources. -Normally, when you run @samp{cvs update}, it prints a -line for each file it encounters that it doesn't know -about (@pxref{update output}). - -@sc{cvs} has a list of files (or sh(1) file name patterns) -that it should ignore while running @code{update}, -@code{import} and @code{release}. -@c -- Are those the only three commands affected? -This list is constructed in the following way. - -@itemize @bullet -@item -The list is initialized to include certain file name -patterns: names associated with @sc{cvs} -administration, or with other common source control -systems; common names for patch files, object files, -archive files, and editor backup files; and other names -that are usually artifacts of assorted utilities. -Currently, the default list of ignored file name -patterns is: - -@cindex Ignored files -@cindex Automatically ignored files -@example - RCS SCCS CVS CVS.adm - RCSLOG cvslog.* - tags TAGS - .make.state .nse_depinfo - *~ #* .#* ,* _$* *$ - *.old *.bak *.BAK *.orig *.rej .del-* - *.a *.olb *.o *.obj *.so *.exe - *.Z *.elc *.ln - core -@end example - -@item -The per-repository list in -@file{$CVSROOT/CVSROOT/cvsignore} is appended to -the list, if that file exists. - -@item -The per-user list in @file{.cvsignore} in your home -directory is appended to the list, if it exists. - -@item -Any entries in the environment variable -@code{$CVSIGNORE} is appended to the list. - -@item -Any @samp{-I} options given to @sc{cvs} is appended. - -@item -As @sc{cvs} traverses through your directories, the contents -of any @file{.cvsignore} will be appended to the list. -The patterns found in @file{.cvsignore} are only valid -for the directory that contains them, not for -any sub-directories. -@end itemize - -In any of the 5 places listed above, a single -exclamation mark (@samp{!}) clears the ignore list. -This can be used if you want to store any file which -normally is ignored by @sc{cvs}. - -Specifying @samp{-I !} to @code{cvs import} will import -everything, which is generally what you want to do if -you are importing files from a pristine distribution or -any other source which is known to not contain any -extraneous files. However, looking at the rules above -you will see there is a fly in the ointment; if the -distribution contains any @file{.cvsignore} files, then -the patterns from those files will be processed even if -@samp{-I !} is specified. The only workaround is to -remove the @file{.cvsignore} files in order to do the -import. Because this is awkward, in the future -@samp{-I !} might be modified to override -@file{.cvsignore} files in each directory. - -Note that the syntax of the ignore files consists of a -series of lines, each of which contains a space -separated list of filenames. This offers no clean way -to specify filenames which contain spaces, but you can -use a workaround like @file{foo?bar} to match a file -named @file{foo bar} (it also matches @file{fooxbar} -and the like). Also note that there is currently no -way to specify comments. -@c FIXCVS? I don't _like_ this syntax at all, but -@c changing it raises all the usual compatibility -@c issues and I'm also not sure what to change it to. - -@node checkoutlist -@appendixsec The checkoutlist file -@cindex checkoutlist - -It may be helpful to use @sc{cvs} to maintain your own -files in the @file{CVSROOT} directory. For example, -suppose that you have a script @file{logcommit.pl} -which you run by including the following line in the -@file{commitinfo} administrative file: - -@example -ALL $CVSROOT/CVSROOT/logcommit.pl -@end example - -To maintain @file{logcommit.pl} with @sc{cvs} you would -add the following line to the @file{checkoutlist} -administrative file: - -@example -logcommit.pl -@end example - -The format of @file{checkoutlist} is one line for each -file that you want to maintain using @sc{cvs}, giving -the name of the file, followed optionally by more whitespace -and any error message that should print if the file cannot be -checked out into CVSROOT after a commit: - -@example -logcommit.pl Could not update CVSROOT/logcommit.pl. -@end example - -After setting up @file{checkoutlist} in this fashion, -the files listed there will function just like -@sc{cvs}'s built-in administrative files. For example, -when checking in one of the files you should get a -message such as: - -@example -cvs commit: Rebuilding administrative file database -@end example - -@noindent -and the checked out copy in the @file{CVSROOT} -directory should be updated. - -Note that listing @file{passwd} (@pxref{Password -authentication server}) in @file{checkoutlist} is not -recommended for security reasons. - -For information about keeping a checkout out copy in a -more general context than the one provided by -@file{checkoutlist}, see @ref{Keeping a checked out -copy}. - -@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@node history file -@appendixsec The history file -@cindex History file -@cindex Log information, saving - -The file @file{$CVSROOT/CVSROOT/history} is used -to log information for the @code{history} command -(@pxref{history}). This file must be created to turn -on logging. This is done automatically if the -@code{cvs init} command is used to set up the -repository (@pxref{Creating a repository}). - -The file format of the @file{history} file is -documented only in comments in the @sc{cvs} source -code, but generally programs should use the @code{cvs -history} command to access it anyway, in case the -format changes with future releases of @sc{cvs}. - -@node Variables -@appendixsec Expansions in administrative files -@cindex Internal variables -@cindex Variables - -Sometimes in writing an administrative file, you might -want the file to be able to know various things based -on environment @sc{cvs} is running in. There are -several mechanisms to do that. - -To find the home directory of the user running @sc{cvs} -(from the @code{HOME} environment variable), use -@samp{~} followed by @samp{/} or the end of the line. -Likewise for the home directory of @var{user}, use -@samp{~@var{user}}. These variables are expanded on -the server machine, and don't get any reasonable -expansion if pserver (@pxref{Password authenticated}) -is in use; therefore user variables (see below) may be -a better choice to customize behavior based on the user -running @sc{cvs}. -@c Based on these limitations, should we deprecate ~? -@c What is it good for? Are people using it? - -One may want to know about various pieces of -information internal to @sc{cvs}. A @sc{cvs} internal -variable has the syntax @code{$@{@var{variable}@}}, -where @var{variable} starts with a letter and consists -of alphanumeric characters and @samp{_}. If the -character following @var{variable} is a -non-alphanumeric character other than @samp{_}, the -@samp{@{} and @samp{@}} can be omitted. The @sc{cvs} -internal variables are: - -@table @code -@item CVSROOT -@cindex CVSROOT, internal variable -This is the absolute path to the current @sc{cvs} root directory. -@xref{Repository}, for a description of the various -ways to specify this, but note that the internal -variable contains just the directory and not any -of the access method information. - -@item RCSBIN -@cindex RCSBIN, internal variable -In @sc{cvs} 1.9.18 and older, this specified the -directory where @sc{cvs} was looking for @sc{rcs} -programs. Because @sc{cvs} no longer runs @sc{rcs} -programs, specifying this internal variable is now an -error. - -@item CVSEDITOR -@cindex CVSEDITOR, internal variable -@itemx EDITOR -@cindex EDITOR, internal variable -@itemx VISUAL -@cindex VISUAL, internal variable -These all expand to the same value, which is the editor -that @sc{cvs} is using. @xref{Global options}, for how -to specify this. - -@item USER -@cindex USER, internal variable -Username of the user running @sc{cvs} (on the @sc{cvs} -server machine). -When using pserver, this is the user specified in the repository -specification which need not be the same as the username the -server is running as (@pxref{Password authentication server}). -Do not confuse this with the environment variable of the same name. -@end table - -If you want to pass a value to the administrative files -which the user who is running @sc{cvs} can specify, -use a user variable. -@cindex User variables -To expand a user variable, the -administrative file contains -@code{$@{=@var{variable}@}}. To set a user variable, -specify the global option @samp{-s} to @sc{cvs}, with -argument @code{@var{variable}=@var{value}}. It may be -particularly useful to specify this option via -@file{.cvsrc} (@pxref{~/.cvsrc}). - -For example, if you want the administrative file to -refer to a test directory you might create a user -variable @code{TESTDIR}. Then if @sc{cvs} is invoked -as - -@example -cvs -s TESTDIR=/work/local/tests -@end example - -@noindent -and the -administrative file contains @code{sh -$@{=TESTDIR@}/runtests}, then that string is expanded -to @code{sh /work/local/tests/runtests}. - -All other strings containing @samp{$} are reserved; -there is no way to quote a @samp{$} character so that -@samp{$} represents itself. - -Environment variables passed to administrative files are: - -@table @code -@cindex environment variables, passed to administrative files - -@item CVS_USER -@cindex CVS_USER, environment variable -The @sc{cvs}-specific username provided by the user, if it -can be provided (currently just for the pserver access -method), and to the empty string otherwise. (@code{CVS_USER} -and @code{USER} may differ when @file{$CVSROOT/CVSROOT/passwd} -is used to map @sc{cvs} usernames to system usernames.) - -@item LOGNAME -@cindex LOGNAME, environment variable -The username of the system user. - -@item USER -@cindex USER, environment variable -Same as @code{LOGNAME}. -Do not confuse this with the internal variable of the same name. -@end table - -@node config -@appendixsec The CVSROOT/config configuration file - -@cindex config, in CVSROOT -@cindex CVSROOT/config - -The administrative file @file{config} contains various -miscellaneous settings which affect the behavior of -@sc{cvs}. The syntax is slightly different from the -other administrative files. Variables are not -expanded. Lines which start with @samp{#} are -considered comments. -@c FIXME: where do we define comments for the other -@c administrative files. -Other lines consist of a keyword, @samp{=}, and a -value. Note that this syntax is very strict. -Extraneous spaces or tabs are not permitted. -@c See comments in parseinfo.c:parse_config for more -@c discussion of this strictness. - -Currently defined keywords are: - -@table @code -@cindex RCSBIN, in CVSROOT/config -@item RCSBIN=@var{bindir} -For @sc{cvs} 1.9.12 through 1.9.18, this setting told -@sc{cvs} to look for @sc{rcs} programs in the -@var{bindir} directory. Current versions of @sc{cvs} -do not run @sc{rcs} programs; for compatibility this -setting is accepted, but it does nothing. - -@cindex SystemAuth, in CVSROOT/config -@item SystemAuth=@var{value} -If @var{value} is @samp{yes}, then pserver should check -for users in the system's user database if not found in -@file{CVSROOT/passwd}. If it is @samp{no}, then all -pserver users must exist in @file{CVSROOT/passwd}. -The default is @samp{yes}. For more on pserver, see -@ref{Password authenticated}. - -@ignore -@cindex PreservePermissions, in CVSROOT/config -@item PreservePermissions=@var{value} -Enable support for saving special device files, -symbolic links, file permissions and ownerships in the -repository. The default value is @samp{no}. -@xref{Special Files}, for the full implications of using -this keyword. -@end ignore - -@cindex TopLevelAdmin, in CVSROOT/config -@item TopLevelAdmin=@var{value} -Modify the @samp{checkout} command to create a -@samp{CVS} directory at the top level of the new -working directory, in addition to @samp{CVS} -directories created within checked-out directories. -The default value is @samp{no}. - -This option is useful if you find yourself performing -many commands at the top level of your working -directory, rather than in one of the checked out -subdirectories. The @file{CVS} directory created there -will mean you don't have to specify @code{CVSROOT} for -each command. It also provides a place for the -@file{CVS/Template} file (@pxref{Working directory -storage}). - -@cindex LockDir, in CVSROOT/config -@item LockDir=@var{directory} -Put @sc{cvs} lock files in @var{directory} rather than -directly in the repository. This is useful if you want -to let users read from the repository while giving them -write access only to @var{directory}, not to the -repository. -It can also be used to put the locks on a very fast -in-memory file system to speed up locking and unlocking -the repository. -You need to create @var{directory}, but -@sc{cvs} will create subdirectories of @var{directory} as it -needs them. For information on @sc{cvs} locks, see -@ref{Concurrency}. - -@c Mention this in Compatibility section? -Before enabling the LockDir option, make sure that you -have tracked down and removed any copies of @sc{cvs} 1.9 or -older. Such versions neither support LockDir, nor will -give an error indicating that they don't support it. -The result, if this is allowed to happen, is that some -@sc{cvs} users will put the locks one place, and others will -put them another place, and therefore the repository -could become corrupted. @sc{cvs} 1.10 does not support -LockDir but it will print a warning if run on a -repository with LockDir enabled. - -@cindex LogHistory, in CVSROOT/config -@item LogHistory=@var{value} -Control what is logged to the @file{CVSROOT/history} file (@pxref{history}). -Default of @samp{TOEFWUPCGMAR} (or simply @samp{all}) will log -all transactions. Any subset of the default is -legal. (For example, to only log transactions that modify the -@file{*,v} files, use @samp{LogHistory=TMAR}.) - -@cindex RereadLogAfterVerify, in CVSROOT/config -@cindex @file{verifymsg}, changing the log message -@item RereadLogAfterVerify=@var{value} -Modify the @samp{commit} command such that CVS will reread the -log message after running the program specified by @file{verifymsg}. -@var{value} may be one of @samp{yes} or @samp{always}, indicating that -the log message should always be reread; @samp{no} -or @samp{never}, indicating that it should never be -reread; or @var{value} may be @samp{stat}, indicating -that the file should be checked with the file system -@samp{stat()} function to see if it has changed (see warning below) -before rereading. The default value is @samp{always}. - -@strong{The `stat' mode can cause CVS to pause for up to -one extra second per directory committed. This can be less IO and -CPU intensive but is not recommended for use with large repositories} - -@xref{verifymsg}, for more information on how verifymsg -may be used. - -@cindex IgnoreUnknownConfigKeys, in CVSROOT/config -@item IgnoreUnknownConfigKeys=@var{value} -If @var{value} is @samp{yes}, then @sc{cvs} should -ignore any keywords in @file{CVSROOT/config} which it -does not recognize. This option is intended primarily -for transitions between versions of @sc{cvs} which -support more configuration options in an environment -where a read-only mirror of the current @sc{cvs} server -may be maintained by someone else who is not yet ready -to upgrade to the same version. It is recommended that -this option be used only for a short time so that -problems with the @file{CVSROOT/config} file will be -found quickly. The default is @samp{no}. -@end table - -@c --------------------------------------------------------------------- -@node Environment variables -@appendix All environment variables which affect CVS -@cindex Environment variables -@cindex Reference manual for variables - -This is a complete list of all environment variables -that affect @sc{cvs}. - -@table @code -@cindex CVSIGNORE, environment variable -@item $CVSIGNORE -A whitespace-separated list of file name patterns that -@sc{cvs} should ignore. @xref{cvsignore}. - -@cindex CVSWRAPPERS, environment variable -@item $CVSWRAPPERS -A whitespace-separated list of file name patterns that -@sc{cvs} should treat as wrappers. @xref{Wrappers}. - -@cindex CVSREAD, environment variable -@cindex Read-only files, and CVSREAD -@item $CVSREAD -If this is set, @code{checkout} and @code{update} will -try hard to make the files in your working directory -read-only. When this is not set, the default behavior -is to permit modification of your working files. - -@item $CVSUMASK -Controls permissions of files in the repository. See -@ref{File permissions}. - -@item $CVSROOT -Should contain the full pathname to the root of the @sc{cvs} -source repository (where the @sc{rcs} files are -kept). This information must be available to @sc{cvs} for -most commands to execute; if @code{$CVSROOT} is not set, -or if you wish to override it for one invocation, you -can supply it on the command line: @samp{cvs -d cvsroot -cvs_command@dots{}} Once you have checked out a working -directory, @sc{cvs} stores the appropriate root (in -the file @file{CVS/Root}), so normally you only need to -worry about this when initially checking out a working -directory. - -@item $CVSEDITOR -@cindex CVSEDITOR, environment variable -@itemx $EDITOR -@cindex EDITOR, environment variable -@itemx $VISUAL -@cindex VISUAL, environment variable -Specifies the program to use for recording log messages -during commit. @code{$CVSEDITOR} overrides -@code{$EDITOR}, which overrides @code{$VISUAL}. -See @ref{Committing your changes} for more or -@ref{Global options} for alternative ways of specifying a -log editor. - -@cindex PATH, environment variable -@item $PATH -If @code{$RCSBIN} is not set, and no path is compiled -into @sc{cvs}, it will use @code{$PATH} to try to find all -programs it uses. - -@cindex HOME, environment variable -@item $HOME -@cindex HOMEPATH, environment variable -@item $HOMEPATH -@cindex HOMEDRIVE, environment variable -@item $HOMEDRIVE -Used to locate the directory where the @file{.cvsrc} -file, and other such files, are searched. On Unix, @sc{cvs} -just checks for @code{HOME}. On Windows NT, the system will -set @code{HOMEDRIVE}, for example to @samp{d:} and @code{HOMEPATH}, -for example to @file{\joe}. On Windows 95, you'll -probably need to set @code{HOMEDRIVE} and @code{HOMEPATH} yourself. -@c We are being vague about whether HOME works on -@c Windows; see long comment in windows-NT/filesubr.c. - -@cindex CVS_RSH, environment variable -@item $CVS_RSH -Specifies the external program which @sc{cvs} connects with, -when @code{:ext:} access method is specified. -@pxref{Connecting via rsh}. - -@cindex CVS_SSH, environment variable -@item $CVS_SSH -Specifies the external program which @sc{cvs} connects with, -when @code{:extssh:} access method is specified. -@pxref{Connecting via rsh}. - -@item $CVS_SERVER -Used in client-server mode when accessing a remote -repository using @sc{rsh}. It specifies the name of -the program to start on the server side (and any -necessary arguments) when accessing a remote repository -using the @code{:ext:}, @code{:fork:}, or @code{:server:} access methods. -The default value for @code{:ext:} and @code{:server:} is @code{cvs}; -the default value for @code{:fork:} is the name used to run the client. -@pxref{Connecting via rsh} - -@item $CVS_PASSFILE -Used in client-server mode when accessing the @code{cvs -login server}. Default value is @file{$HOME/.cvspass}. -@pxref{Password authentication client} - -@item $CVS_CLIENT_PORT -Used in client-server mode to set the port to use when accessing the server -via Kerberos, GSSAPI, or @sc{cvs}'s password authentication protocol -if the port is not specified in the CVSROOT. -@pxref{Remote repositories} - -@cindex CVS_RCMD_PORT, environment variable -@item $CVS_RCMD_PORT -Used in client-server mode. If set, specifies the port -number to be used when accessing the @sc{rcmd} demon on -the server side. (Currently not used for Unix clients). - -@cindex CVS_CLIENT_LOG, environment variable -@item $CVS_CLIENT_LOG -Used for debugging only in client-server -mode. If set, everything sent to the server is logged -into @file{@code{$CVS_CLIENT_LOG}.in} and everything -sent from the server is logged into -@file{@code{$CVS_CLIENT_LOG}.out}. - -@cindex CVS_SERVER_SLEEP, environment variable -@item $CVS_SERVER_SLEEP -Used only for debugging the server side in -client-server mode. If set, delays the start of the -server child process the specified amount of -seconds so that you can attach to it with a debugger. - -@cindex CVS_IGNORE_REMOTE_ROOT, environment variable -@item $CVS_IGNORE_REMOTE_ROOT -For @sc{cvs} 1.10 and older, setting this variable -prevents @sc{cvs} from overwriting the @file{CVS/Root} -file when the @samp{-d} global option is specified. -Later versions of @sc{cvs} do not rewrite -@file{CVS/Root}, so @code{CVS_IGNORE_REMOTE_ROOT} has no -effect. - -@cindex COMSPEC, environment variable -@item $COMSPEC -Used under OS/2 only. It specifies the name of the -command interpreter and defaults to @sc{cmd.exe}. - -@cindex TMPDIR, environment variable -@item $TMPDIR -@cindex TMP, environment variable -@itemx $TMP -@cindex TEMP, environment variable -@itemx $TEMP -@cindex Temporary files, location of -@c This is quite nuts. We don't talk about tempnam -@c or mkstemp which we sometimes use. The discussion -@c of "Global options" is semi-incoherent. -@c I'm not even sure those are the only inaccuracies. -@c Furthermore, the conventions are -@c pretty crazy and they should be simplified. -Directory in which temporary files are located. -The @sc{cvs} server uses -@code{TMPDIR}. @xref{Global options}, for a -description of how to specify this. -Some parts of @sc{cvs} will always use @file{/tmp} (via -the @code{tmpnam} function provided by the system). - -On Windows NT, @code{TMP} is used (via the @code{_tempnam} -function provided by the system). - -The @code{patch} program which is used by the @sc{cvs} -client uses @code{TMPDIR}, and if it is not set, uses -@file{/tmp} (at least with GNU patch 2.1). Note that -if your server and client are both running @sc{cvs} -1.9.10 or later, @sc{cvs} will not invoke an external -@code{patch} program. -@end table - -@node Compatibility -@appendix Compatibility between CVS Versions - -@cindex CVS, versions of -@cindex Versions, of CVS -@cindex Compatibility, between CVS versions -@c We don't mention versions older than CVS 1.3 -@c on the theory that it would clutter it up for the vast -@c majority of people, who don't have anything that old. -@c -The repository format is compatible going back to -@sc{cvs} 1.3. But see @ref{Watches Compatibility}, if -you have copies of @sc{cvs} 1.6 or older and you want -to use the optional developer communication features. -@c If you "cvs rm" and commit using 1.3, then you'll -@c want to run "rcs -sdead " on each of the -@c files in the Attic if you then want 1.5 and -@c later to recognize those files as dead (I think the -@c symptom if this is not done is that files reappear -@c in joins). (Wait: the above will work but really to -@c be strictly correct we should suggest checking -@c in a new revision rather than just changing the -@c state of the head revision, shouldn't we?). -@c The old convert.sh script was for this, but it never -@c did get updated to reflect use of the RCS "dead" -@c state. -@c Note: this is tricky to document without confusing -@c people--need to carefully say what CVS version we -@c are talking about and keep in mind the distinction -@c between a -@c repository created with 1.3 and on which one now -@c uses 1.5+, and a repository on which one wants to -@c use both versions side by side (e.g. during a -@c transition period). -@c Wait, can't CVS just detect the case in which a file -@c is in the Attic but the head revision is not dead? -@c Not sure whether this should produce a warning or -@c something, and probably needs further thought, but -@c it would appear that the situation can be detected. -@c -@c We might want to separate out the 1.3 compatibility -@c section (for repository & working directory) from the -@c rest--that might help avoid confusing people who -@c are upgrading (for example) from 1.6 to 1.8. -@c -@c A minor incompatibility is if a current version of CVS -@c puts "Nfoo" into CVS/Tag, then CVS 1.9 or older will -@c see this as if there is no tag. Seems to me this is -@c too obscure to mention. - -The working directory format is compatible going back -to @sc{cvs} 1.5. It did change between @sc{cvs} 1.3 -and @sc{cvs} 1.5. If you run @sc{cvs} 1.5 or newer on -a working directory checked out with @sc{cvs} 1.3, -@sc{cvs} will convert it, but to go back to @sc{cvs} -1.3 you need to check out a new working directory with -@sc{cvs} 1.3. - -The remote protocol is interoperable going back to @sc{cvs} 1.5, but no -further (1.5 was the first official release with the remote protocol, -but some older versions might still be floating around). In many -cases you need to upgrade both the client and the server to take -advantage of new features and bug fixes, however. - -@c Perhaps should be saying something here about the -@c "D" lines in Entries (written by CVS 1.9; 1.8 and -@c older don't use them). These are supposed to be -@c compatible in both directions, but I'm not sure -@c they quite are 100%. One common gripe is if you -@c "rm -r" a directory and 1.9 gets confused, as it -@c still sees it in Entries. That one is fixed in -@c (say) 1.9.6. Someone else reported problems with -@c starting with a directory which was checked out with -@c an old version, and then using a new version, and -@c some "D" lines appeared, but not for every -@c directory, causing some directories to be skipped. -@c They weren't sure how to reproduce this, though. - -@c --------------------------------------------------------------------- -@node Troubleshooting -@appendix Troubleshooting - -If you are having trouble with @sc{cvs}, this appendix -may help. If there is a particular error message which -you are seeing, then you can look up the message -alphabetically. If not, you can look through the -section on other problems to see if your problem is -mentioned there. - -@menu -* Error messages:: Partial list of CVS errors -* Connection:: Trouble making a connection to a CVS server -* Other problems:: Problems not readily listed by error message -@end menu - -@ignore -@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@c @node Bad administrative files -@appendixsec Bad administrative files - -@c -- Give hints on how to fix them -@end ignore - -@node Error messages -@appendixsec Partial list of error messages - -Here is a partial list of error messages that you may -see from @sc{cvs}. It is not a complete list---@sc{cvs} -is capable of printing many, many error messages, often -with parts of them supplied by the operating system, -but the intention is to list the common and/or -potentially confusing error messages. - -The messages are alphabetical, but introductory text -such as @samp{cvs update: } is not considered in -ordering them. - -In some cases the list includes messages printed by old -versions of @sc{cvs} (partly because users may not be -sure which version of @sc{cvs} they are using at any -particular moment). -@c If we want to start retiring messages, perhaps we -@c should pick a cutoff version (for example, no more -@c messages which are specific to versions before 1.9) -@c and then move the old messages to an "old messages" -@c node rather than deleting them completely. - -@table @code -@c FIXME: What is the correct way to format a multiline -@c error message here? Maybe @table is the wrong -@c choice? Texinfo gurus? -@item @var{file}:@var{line}: Assertion '@var{text}' failed -The exact format of this message may vary depending on -your system. It indicates a bug in @sc{cvs}, which can -be handled as described in @ref{BUGS}. - -@item cvs @var{command}: authorization failed: server @var{host} rejected access -This is a generic response when trying to connect to a -pserver server which chooses not to provide a -specific reason for denying authorization. Check that -the username and password specified are correct and -that the @code{CVSROOT} specified is allowed by @samp{--allow-root} -in @file{inetd.conf}. See @ref{Password authenticated}. - -@item cvs @var{command}: conflict: removed @var{file} was modified by second party -This message indicates that you removed a file, and -someone else modified it. To resolve the conflict, -first run @samp{cvs add @var{file}}. If desired, look -at the other party's modification to decide whether you -still want to remove it. If you don't want to remove -it, stop here. If you do want to remove it, proceed -with @samp{cvs remove @var{file}} and commit your -removal. -@c Tests conflicts2-142b* in sanity.sh test for this. - -@item cannot change permissions on temporary directory -@example -Operation not permitted -@end example -This message has been happening in a non-reproducible, -occasional way when we run the client/server testsuite, -both on Red Hat Linux 3.0.3 and 4.1. We haven't been -able to figure out what causes it, nor is it known -whether it is specific to Linux (or even to this -particular machine!). If the problem does occur on -other unices, @samp{Operation not permitted} would be -likely to read @samp{Not owner} or whatever the system -in question uses for the unix @code{EPERM} error. If -you have any information to add, please let us know as -described in @ref{BUGS}. If you experience this error -while using @sc{cvs}, retrying the operation which -produced it should work fine. -@c This has been seen in a variety of tests, including -@c multibranch-2, multibranch-5, and basic1-24-rm-rm, -@c so it doesn't seem particularly specific to any one -@c test. - -@item cvs [server aborted]: Cannot check out files into the repository itself -The obvious cause for this message (especially for -non-client/server @sc{cvs}) is that the @sc{cvs} root -is, for example, @file{/usr/local/cvsroot} and you try -to check out files when you are in a subdirectory, such -as @file{/usr/local/cvsroot/test}. However, there is a -more subtle cause, which is that the temporary -directory on the server is set to a subdirectory of the -root (which is also not allowed). If this is the -problem, set the temporary directory to somewhere else, -for example @file{/var/tmp}; see @code{TMPDIR} in -@ref{Environment variables}, for how to set the -temporary directory. - -@item cannot commit files as 'root' -See @samp{'root' is not allowed to commit files}. - -@c For one example see basica-1a10 in the testsuite -@c For another example, "cvs co ." on NT; see comment -@c at windows-NT/filesubr.c (expand_wild). -@c For another example, "cvs co foo/bar" where foo exists. -@item cannot open CVS/Entries for reading: No such file or directory -This generally indicates a @sc{cvs} internal error, and -can be handled as with other @sc{cvs} bugs -(@pxref{BUGS}). Usually there is a workaround---the -exact nature of which would depend on the situation but -which hopefully could be figured out. - -@c This is more obscure than it might sound; it only -@c happens if you run "cvs init" from a directory which -@c contains a CVS/Root file at the start. -@item cvs [init aborted]: cannot open CVS/Root: No such file or directory -This message is harmless. Provided it is not -accompanied by other errors, the operation has -completed successfully. This message should not occur -with current versions of @sc{cvs}, but it is documented -here for the benefit of @sc{cvs} 1.9 and older. - -@item cvs server: cannot open /root/.cvsignore: Permission denied -@itemx cvs [server aborted]: can't chdir(/root): Permission denied -See @ref{Connection}. - -@item cvs [checkout aborted]: cannot rename file @var{file} to CVS/,,@var{file}: Invalid argument -This message has been reported as intermittently -happening with @sc{cvs} 1.9 on Solaris 2.5. The cause is -unknown; if you know more about what causes it, let us -know as described in @ref{BUGS}. - -@item cvs [@var{command} aborted]: cannot start server via rcmd -This, unfortunately, is a rather nonspecific error -message which @sc{cvs} 1.9 will print if you are -running the @sc{cvs} client and it is having trouble -connecting to the server. Current versions of @sc{cvs} -should print a much more specific error message. If -you get this message when you didn't mean to run the -client at all, you probably forgot to specify -@code{:local:}, as described in @ref{Repository}. - -@item ci: @var{file},v: bad diff output line: Binary files - and /tmp/T2a22651 differ -@sc{cvs} 1.9 and older will print this message -when trying to check in a binary file if -@sc{rcs} is not correctly installed. Re-read the -instructions that came with your @sc{rcs} distribution -and the @sc{install} file in the @sc{cvs} -distribution. Alternately, upgrade to a current -version of @sc{cvs}, which checks in files itself -rather than via @sc{rcs}. - -@item cvs checkout: could not check out @var{file} -With @sc{cvs} 1.9, this can mean that the @code{co} program -(part of @sc{rcs}) returned a failure. It should be -preceded by another error message, however it has been -observed without another error message and the cause is -not well-understood. With the current version of @sc{cvs}, -which does not run @code{co}, if this message occurs -without another error message, it is definitely a @sc{cvs} -bug (@pxref{BUGS}). -@c My current suspicion is that the RCS in the rcs (not -@c cvs/winnt/rcs57nt.zip) directory on the _Practical_ -@c CD is bad (remains to be confirmed). -@c There is also a report of something which looks -@c very similar on SGI, Irix 5.2, so I dunno. - -@item cvs [login aborted]: could not find out home directory -This means that you need to set the environment -variables that @sc{cvs} uses to locate your home directory. -See the discussion of @code{HOME}, @code{HOMEDRIVE}, and @code{HOMEPATH} in -@ref{Environment variables}. - -@item cvs update: could not merge revision @var{rev} of @var{file}: No such file or directory -@sc{cvs} 1.9 and older will print this message if there was -a problem finding the @code{rcsmerge} program. Make -sure that it is in your @code{PATH}, or upgrade to a -current version of @sc{cvs}, which does not require -an external @code{rcsmerge} program. - -@item cvs [update aborted]: could not patch @var{file}: No such file or directory -This means that there was a problem finding the -@code{patch} program. Make sure that it is in your -@code{PATH}. Note that despite appearances the message -is @emph{not} referring to whether it can find @var{file}. -If both the client and the server are running a current -version of @sc{cvs}, then there is no need for an -external patch program and you should not see this -message. But if either client or server is running -@sc{cvs} 1.9, then you need @code{patch}. - -@item cvs update: could not patch @var{file}; will refetch -This means that for whatever reason the client was -unable to apply a patch that the server sent. The -message is nothing to be concerned about, because -inability to apply the patch only slows things down and -has no effect on what @sc{cvs} does. -@c xref to update output. Or File status? -@c Or some place else that -@c explains this whole "patch"/P/Needs Patch thing? - -@item dying gasps from @var{server} unexpected -There is a known bug in the server for @sc{cvs} 1.9.18 -and older which can cause this. For me, this was -reproducible if I used the @samp{-t} global option. It -was fixed by Andy Piper's 14 Nov 1997 change to -src/filesubr.c, if anyone is curious. -If you see the message, -you probably can just retry the operation which failed, -or if you have discovered information concerning its -cause, please let us know as described in @ref{BUGS}. - -@item end of file from server (consult above messages if any) -The most common cause for this message is if you are -using an external @code{rsh} or @code{ssh} program and it exited with -an error. In this case the @code{rsh} program should -have printed a message, which will appear before the -above message. For more information on setting up a -@sc{cvs} client and server, see @ref{Remote repositories}. - -@item cvs [update aborted]: EOF in key in RCS file @var{file},v -@itemx cvs [checkout aborted]: EOF while looking for end of string in RCS file @var{file},v -This means that there is a syntax error in the given -@sc{rcs} file. Note that this might be true even if @sc{rcs} can -read the file OK; @sc{cvs} does more error checking of -errors in the RCS file. That is why you may see this -message when upgrading from @sc{cvs} 1.9 to @sc{cvs} -1.10. The likely cause for the original corruption is -hardware, the operating system, or the like. Of -course, if you find a case in which @sc{cvs} seems to -corrupting the file, by all means report it, -(@pxref{BUGS}). -There are quite a few variations of this error message, -depending on exactly where in the @sc{rcs} file @sc{cvs} -finds the syntax error. - -@cindex mkmodules -@item cvs commit: Executing 'mkmodules' -This means that your repository is set up for a version -of @sc{cvs} prior to @sc{cvs} 1.8. When using @sc{cvs} -1.8 or later, the above message will be preceded by - -@example -cvs commit: Rebuilding administrative file database -@end example - -If you see both messages, the database is being rebuilt -twice, which is unnecessary but harmless. If you wish -to avoid the duplication, and you have no versions of -@sc{cvs} 1.7 or earlier in use, remove @code{-i mkmodules} -every place it appears in your @code{modules} -file. For more information on the @code{modules} file, -see @ref{modules}. - -@c This message comes from "co", and I believe is -@c possible only with older versions of CVS which call -@c co. The problem with being able to create the bogus -@c RCS file still exists, though (and I think maybe -@c there is a different symptom(s) now). -@c FIXME: Would be nice to have a more exact wording -@c for this message. -@item missing author -Typically this can happen if you created an RCS file -with your username set to empty. @sc{cvs} will, bogusly, -create an illegal RCS file with no value for the author -field. The solution is to make sure your username is -set to a non-empty value and re-create the RCS file. -@c "make sure your username is set" is complicated in -@c and of itself, as there are the environment -@c variables the system login name, &c, and it depends -@c on the version of CVS. - -@item cvs [checkout aborted]: no such tag @var{tag} -This message means that @sc{cvs} isn't familiar with -the tag @var{tag}. Usually this means that you have -mistyped a tag name; however there are (relatively -obscure) cases in which @sc{cvs} will require you to -@c Search sanity.sh for "no such tag" to see some of -@c the relatively obscure cases. -try a few other @sc{cvs} commands involving that tag, -before you find one which will cause @sc{cvs} to update -@cindex CVSROOT/val-tags file, forcing tags into -@cindex val-tags file, forcing tags into -the @file{val-tags} file; see discussion of val-tags in -@ref{File permissions}. You only need to worry about -this once for a given tag; when a tag is listed in -@file{val-tags}, it stays there. Note that using -@samp{-f} to not require tag matches does not override -this check; see @ref{Common options}. - -@item *PANIC* administration files missing -This typically means that there is a directory named -@sc{cvs} but it does not contain the administrative files -which @sc{cvs} puts in a CVS directory. If the problem is -that you created a CVS directory via some mechanism -other than @sc{cvs}, then the answer is simple, use a name -other than @sc{cvs}. If not, it indicates a @sc{cvs} bug -(@pxref{BUGS}). - -@item rcs error: Unknown option: -x,v/ -This message will be followed by a usage message for -@sc{rcs}. It means that you have an old version of -@sc{rcs} (probably supplied with your operating -system), as well as an old version of @sc{cvs}. -@sc{cvs} 1.9.18 and earlier only work with @sc{rcs} version 5 and -later; current versions of @sc{cvs} do not run @sc{rcs} programs. -@c For more information on installing @sc{cvs}, see -@c (FIXME: where? it depends on whether you are -@c getting binaries or sources or what). -@c The message can also say "ci error" or something -@c instead of "rcs error", I suspect. - -@item cvs [server aborted]: received broken pipe signal -This message can be caused by a loginfo program that fails to -read all of the log information from its standard input. -If you find it happening in any other circumstances, -please let us know as described in @ref{BUGS}. - -@item 'root' is not allowed to commit files -When committing a permanent change, @sc{cvs} makes a log entry of -who committed the change. If you are committing the change logged -in as "root" (not under "su" or other root-priv giving program), -@sc{cvs} cannot determine who is actually making the change. -As such, by default, @sc{cvs} disallows changes to be committed by users -logged in as "root". (You can disable this option by passing the -@code{--enable-rootcommit} option to @file{configure} and recompiling @sc{cvs}. -On some systems this means editing the appropriate @file{config.h} file -before building @sc{cvs}.) - -@item Terminated with fatal signal 11 -This message usually indicates that @sc{cvs} (the server, if you're -using client/server mode) has run out of (virtual) memory. -Although @sc{cvs} tries to catch the error and issue a more meaningful -message, there are many circumstances where that is not possible. -If you appear to have lots of memory available to the system, -the problem is most likely that you're running into a system-wide -limit on the amount of memory a single process can use or a -similar process-specific limit. -The mechanisms for displaying and setting such limits vary from -system to system, so you'll have to consult an expert for your -particular system if you don't know how to do that. - -@item Too many arguments! -This message is typically printed by the @file{log.pl} -script which is in the @file{contrib} directory in the -@sc{cvs} source distribution. In some versions of -@sc{cvs}, @file{log.pl} has been part of the default -@sc{cvs} installation. The @file{log.pl} script gets -called from the @file{loginfo} administrative file. -Check that the arguments passed in @file{loginfo} match -what your version of @file{log.pl} expects. In -particular, the @file{log.pl} from @sc{cvs} 1.3 and -older expects the log file as an argument whereas the -@file{log.pl} from @sc{cvs} 1.5 and newer expects the -log file to be specified with a @samp{-f} option. Of -course, if you don't need @file{log.pl} you can just -comment it out of @file{loginfo}. - -@item cvs [update aborted]: unexpected EOF reading @var{file},v -See @samp{EOF in key in RCS file}. - -@item cvs [login aborted]: unrecognized auth response from @var{server} -This message typically means that the server is not set -up properly. For example, if @file{inetd.conf} points -to a nonexistent cvs executable. To debug it further, -find the log file which inetd writes -(@file{/var/log/messages} or whatever inetd uses on -your system). For details, see @ref{Connection}, and -@ref{Password authentication server}. - -@item cvs commit: Up-to-date check failed for `@var{file}' -This means that someone else has committed a change to -that file since the last time that you did a @code{cvs -update}. So before proceeding with your @code{cvs -commit} you need to @code{cvs update}. @sc{cvs} will merge -the changes that you made and the changes that the -other person made. If it does not detect any conflicts -it will report @samp{M @var{file}} and you are ready -to @code{cvs commit}. If it detects conflicts it will -print a message saying so, will report @samp{C @var{file}}, -and you need to manually resolve the -conflict. For more details on this process see -@ref{Conflicts example}. - -@item Usage: diff3 [-exEX3 [-i | -m] [-L label1 -L label3]] file1 file2 file3 -@example -Only one of [exEX3] allowed -@end example -This indicates a problem with the installation of -@code{diff3} and @code{rcsmerge}. Specifically -@code{rcsmerge} was compiled to look for GNU diff3, but -it is finding unix diff3 instead. The exact text of -the message will vary depending on the system. The -simplest solution is to upgrade to a current version of -@sc{cvs}, which does not rely on external -@code{rcsmerge} or @code{diff3} programs. - -@item warning: unrecognized response `@var{text}' from cvs server -If @var{text} contains a valid response (such as -@samp{ok}) followed by an extra carriage return -character (on many systems this will cause the second -part of the message to overwrite the first part), then -it probably means that you are using the @samp{:ext:} -access method with a version of rsh, such as most -non-unix rsh versions, which does not by default -provide a transparent data stream. In such cases you -probably want to try @samp{:server:} instead of -@samp{:ext:}. If @var{text} is something else, this -may signify a problem with your @sc{cvs} server. -Double-check your installation against the instructions -for setting up the @sc{cvs} server. -@c FIXCVS: should be printing CR as \r or \015 or some -@c such, probably. - -@item cvs commit: [@var{time}] waiting for @var{user}'s lock in @var{directory} -This is a normal message, not an error. See -@ref{Concurrency}, for more details. - -@item cvs commit: warning: editor session failed -@cindex Exit status, of editor -This means that the editor which @sc{cvs} is using exits with a nonzero -exit status. Some versions of vi will do this even when there was not -a problem editing the file. If so, point the -@code{CVSEDITOR} environment variable to a small script -such as: - -@example -#!/bin/sh -vi $* -exit 0 -@end example - -@item cvs update: warning: @var{file} was lost -This means that the working copy of @var{file} has been deleted -but it has not been removed from @sc{cvs}. -This is nothing to be concerned about, -the update will just recreate the local file from the repository. -(This is a convenient way to discard local changes to a file: -just delete it and then run @code{cvs update}.) - -@item cvs update: warning: @var{file} is not (any longer) pertinent -This means that the working copy of @var{file} has been deleted, -it has not been removed from @sc{cvs} in the current working directory, -but it has been removed from @sc{cvs} in some other working directory. -This is nothing to be concerned about, -the update would have removed the local file anyway. - -@end table - -@node Connection -@appendixsec Trouble making a connection to a CVS server - -This section concerns what to do if you are having -trouble making a connection to a @sc{cvs} server. If -you are running the @sc{cvs} command line client -running on Windows, first upgrade the client to -@sc{cvs} 1.9.12 or later. The error reporting in -earlier versions provided much less information about -what the problem was. If the client is non-Windows, -@sc{cvs} 1.9 should be fine. - -If the error messages are not sufficient to track down -the problem, the next steps depend largely on which -access method you are using. - -@table @code -@cindex :ext:, troubleshooting -@item :ext: -Try running the rsh program from the command line. For -example: "rsh servername cvs -v" should print @sc{cvs} -version information. If this doesn't work, you need to -fix it before you can worry about @sc{cvs} problems. - -@cindex :server:, troubleshooting -@item :server: -You don't need a command line rsh program to use this -access method, but if you have an rsh program around, -it may be useful as a debugging tool. Follow the -directions given for :ext:. - -@cindex :pserver:, troubleshooting -@item :pserver: -Errors along the lines of "connection refused" typically indicate -that inetd isn't even listening for connections on port 2401 -whereas errors like "connection reset by peer", -"received broken pipe signal", "recv() from server: EOF", -or "end of file from server" -typically indicate that inetd is listening for -connections but is unable to start @sc{cvs} (this is frequently -caused by having an incorrect path in @file{inetd.conf} -or by firewall software rejecting the connection). -"unrecognized auth response" errors are caused by a bad command -line in @file{inetd.conf}, typically an invalid option or forgetting -to put the @samp{pserver} command at the end of the line. -Another less common problem is invisible control characters that -your editor "helpfully" added without you noticing. - -One good debugging tool is to "telnet servername -2401". After connecting, send any text (for example -"foo" followed by return). If @sc{cvs} is working -correctly, it will respond with - -@example -cvs [pserver aborted]: bad auth protocol start: foo -@end example - -If instead you get: - -@example -Usage: cvs [cvs-options] command [command-options-and-arguments] -... -@end example - -@noindent -then you're missing the @samp{pserver} command at the end of the -line in @file{inetd.conf}; check to make sure that the entire command -is on one line and that it's complete. - -Likewise, if you get something like: - -@example -Unknown command: `pserved' - -CVS commands are: - add Add a new file/directory to the repository -... -@end example - -@noindent -then you've misspelled @samp{pserver} in some way. If it isn't -obvious, check for invisible control characters (particularly -carriage returns) in @file{inetd.conf}. - -If it fails to work at all, then make sure inetd is working -right. Change the invocation in @file{inetd.conf} to run the -echo program instead of cvs. For example: - -@example -2401 stream tcp nowait root /bin/echo echo hello -@end example - -After making that change and instructing inetd to -re-read its configuration file, "telnet servername -2401" should show you the text hello and then the -server should close the connection. If this doesn't -work, you need to fix it before you can worry about -@sc{cvs} problems. - -On AIX systems, the system will often have its own -program trying to use port 2401. This is AIX's problem -in the sense that port 2401 is registered for use with -@sc{cvs}. I hear that there is an AIX patch available -to address this problem. - -Another good debugging tool is the @samp{-d} -(debugging) option to inetd. Consult your system -documentation for more information. - -If you seem to be connecting but get errors like: - -@example -cvs server: cannot open /root/.cvsignore: Permission denied -cvs [server aborted]: can't chdir(/root): Permission denied -@end example - -@noindent -then you probably haven't specified @samp{-f} in @file{inetd.conf}. -(In releases prior to @sc{cvs} 1.11.1, this problem can be caused by -your system setting the @code{$HOME} environment variable -for programs being run by inetd. In this case, you can either -have inetd run a shell script that unsets @code{$HOME} and then runs -@sc{cvs}, or you can use @code{env} to run @sc{cvs} with a pristine -environment.) - -If you can connect successfully for a while but then can't, -you've probably hit inetd's rate limit. -(If inetd receives too many requests for the same service -in a short period of time, it assumes that something is wrong -and temporarily disables the service.) -Check your inetd documentation to find out how to adjust the -rate limit (some versions of inetd have a single rate limit, -others allow you to set the limit for each service separately.) -@end table - -@node Other problems -@appendixsec Other common problems - -Here is a list of problems which do not fit into the -above categories. They are in no particular order. - -@itemize @bullet -@item -On Windows, if there is a 30 second or so delay when -you run a @sc{cvs} command, it may mean that you have -your home directory set to @file{C:/}, for example (see -@code{HOMEDRIVE} and @code{HOMEPATH} in -@ref{Environment variables}). @sc{cvs} expects the home -directory to not end in a slash, for example @file{C:} -or @file{C:\cvs}. -@c FIXCVS: CVS should at least detect this and print an -@c error, presumably. - -@item -If you are running @sc{cvs} 1.9.18 or older, and -@code{cvs update} finds a conflict and tries to -merge, as described in @ref{Conflicts example}, but -doesn't tell you there were conflicts, then you may -have an old version of @sc{rcs}. The easiest solution -probably is to upgrade to a current version of -@sc{cvs}, which does not rely on external @sc{rcs} -programs. -@end itemize - -@c --------------------------------------------------------------------- -@node Credits -@appendix Credits - -@cindex Contributors (manual) -@cindex Credits (manual) -Roland Pesch, then of Cygnus Support <@t{roland@@wrs.com}> -wrote the manual pages which were distributed with -@sc{cvs} 1.3. Much of their text was copied into this -manual. He also read an early draft -of this manual and contributed many ideas and -corrections. - -The mailing-list @code{info-cvs} is sometimes -informative. I have included information from postings -made by the following persons: -David G. Grubbs <@t{dgg@@think.com}>. - -Some text has been extracted from the man pages for -@sc{rcs}. - -The @sc{cvs} @sc{faq} by David G. Grubbs has provided -useful material. The @sc{faq} is no longer maintained, -however, and this manual is about the closest thing there -is to a successor (with respect to documenting how to -use @sc{cvs}, at least). - -In addition, the following persons have helped by -telling me about mistakes I've made: - -@display -Roxanne Brunskill <@t{rbrunski@@datap.ca}>, -Kathy Dyer <@t{dyer@@phoenix.ocf.llnl.gov}>, -Karl Pingle <@t{pingle@@acuson.com}>, -Thomas A Peterson <@t{tap@@src.honeywell.com}>, -Inge Wallin <@t{ingwa@@signum.se}>, -Dirk Koschuetzki <@t{koschuet@@fmi.uni-passau.de}> -and Michael Brown <@t{brown@@wi.extrel.com}>. -@end display - -The list of contributors here is not comprehensive; for a more -complete list of who has contributed to this manual see -the file @file{doc/ChangeLog} in the @sc{cvs} source -distribution. - -@c --------------------------------------------------------------------- -@node BUGS -@appendix Dealing with bugs in CVS or this manual - -@cindex Bugs in this manual or CVS -Neither @sc{cvs} nor this manual is perfect, and they -probably never will be. If you are having trouble -using @sc{cvs}, or think you have found a bug, there -are a number of things you can do about it. Note that -if the manual is unclear, that can be considered a bug -in the manual, so these problems are often worth doing -something about as well as problems with @sc{cvs} itself. - -@cindex Reporting bugs -@cindex Bugs, reporting -@cindex Errors, reporting -@itemize @bullet -@item -If you want someone to help you and fix bugs that you -report, there are companies which will do that for a -fee. One such company is: - -@cindex Ximbiot -@cindex Support, getting CVS support -@example -Ximbiot LLC -Suite 230 -200 Diversion St. -Rochester Hills, MI 48307-6636 -USA -Email: info@@ximbiot.com -Phone: (248) 835-1260 -Fax: (248) 835-1263 -@url{http://ximbiot.com/} - -@end example - -@item -If you got @sc{cvs} through a distributor, such as an -operating system vendor or a vendor of freeware -@sc{cd-rom}s, you may wish to see whether the -distributor provides support. Often, they will provide -no support or minimal support, but this may vary from -distributor to distributor. - -@item -If you have the skills and time to do so, you may wish -to fix the bug yourself. If you wish to submit your -fix for inclusion in future releases of @sc{cvs}, see -the file @sc{hacking} in the @sc{cvs} source -distribution. It contains much more information on the -process of submitting fixes. - -@item -There may be resources on the net which can help. A -good place to start is: - -@example -@url{http://cvs.nongnu.org/} -@end example - -If you are so inspired, increasing the information -available on the net is likely to be appreciated. For -example, before the standard @sc{cvs} distribution -worked on Windows 95, there was a web page with some -explanation and patches for running @sc{cvs} on Windows -95, and various people helped out by mentioning this -page on mailing lists or newsgroups when the subject -came up. - -@item -It is also possible to report bugs to @email{bug-cvs@@nongnu.org}. -Note that someone may or may not want to do anything -with your bug report---if you need a solution consider -one of the options mentioned above. People probably do -want to hear about bugs which are particularly severe -in consequences and/or easy to fix, however. You can -also increase your odds by being as clear as possible -about the exact nature of the bug and any other -relevant information. The way to report bugs is to -send email to @email{bug-cvs@@nongnu.org}. Note -that submissions to @email{bug-cvs@@nongnu.org} may be distributed -under the terms of the @sc{gnu} Public License, so if -you don't like this, don't submit them. There is -usually no justification for sending mail directly to -one of the @sc{cvs} maintainers rather than to -@email{bug-cvs@@nongnu.org}; those maintainers who want to hear -about such bug reports read @email{bug-cvs@@nongnu.org}. Also note -that sending a bug report to other mailing lists or -newsgroups is @emph{not} a substitute for sending it to -@email{bug-cvs@@nongnu.org}. It is fine to discuss @sc{cvs} bugs on -whatever forum you prefer, but there are not -necessarily any maintainers reading bug reports sent -anywhere except @email{bug-cvs@@nongnu.org}. -@end itemize - -@cindex Known bugs in this manual or CVS -People often ask if there is a list of known bugs or -whether a particular bug is a known one. The file -@sc{bugs} in the @sc{cvs} source distribution is one -list of known bugs, but it doesn't necessarily try to -be comprehensive. Perhaps there will never be a -comprehensive, detailed list of known bugs. - -@c --------------------------------------------------------------------- -@node Index -@unnumbered Index -@cindex Index - -@printindex cp - -@bye - -Local Variables: -fill-column: 55 -End: diff --git a/contrib/cvs/doc/cvsclient.texi b/contrib/cvs/doc/cvsclient.texi deleted file mode 100644 index b727a32..0000000 --- a/contrib/cvs/doc/cvsclient.texi +++ /dev/null @@ -1,2080 +0,0 @@ -\input texinfo @c -*- texinfo -*- - -@setfilename cvsclient.info -@include version-client.texi - -@dircategory Programming -@direntry -* cvsclient: (cvsclient). The CVS client/server protocol. -@end direntry - -@node Top -@top CVS Client/Server - -This document describes the client/server protocol used by CVS. It does -not describe how to use or administer client/server CVS; see the regular -CVS manual for that. This is version @value{VERSION} of the protocol -specification---@xref{Introduction}, for more on what this version number -means. - -@menu -* Introduction:: What is CVS and what is the client/server protocol for? -* Goals:: Basic design decisions, requirements, scope, etc. -* Connection and Authentication:: Various ways to connect to the server -* Password scrambling:: Scrambling used by pserver -* Protocol:: Complete description of the protocol -* Protocol Notes:: Possible enhancements, limitations, etc. of the protocol -@end menu - -@node Introduction -@chapter Introduction - -CVS is a version control system (with some additional configuration -management functionality). It maintains a central @dfn{repository} -which stores files (often source code), including past versions, -information about who modified them and when, and so on. People who -wish to look at or modify those files, known as @dfn{developers}, use -CVS to @dfn{check out} a @dfn{working directory} from the repository, to -@dfn{check in} new versions of files to the repository, and other -operations such as viewing the modification history of a file. If -developers are connected to the repository by a network, particularly a -slow or flaky one, the most efficient way to use the network is with the -CVS-specific protocol described in this document. - -Developers, using the machine on which they store their working -directory, run the CVS @dfn{client} program. To perform operations -which cannot be done locally, it connects to the CVS @dfn{server} -program, which maintains the repository. For more information on how -to connect see @ref{Connection and Authentication}. - -This document describes the CVS protocol. Unfortunately, it does not -yet completely document one aspect of the protocol---the detailed -operation of each CVS command and option---and one must look at the CVS -user documentation, @file{cvs.texinfo}, for that information. The -protocol is non-proprietary (anyone who wants to is encouraged to -implement it) and an implementation, known as CVS, is available under -the GNU Public License. The CVS distribution, containing this -implementation, @file{cvs.texinfo}, and a copy (possibly more or less up -to date than what you are reading now) of this document, -@file{cvsclient.texi}, can be found at the usual GNU FTP sites, with a -filename such as @file{cvs-@var{version}.tar.gz}. - -This is version @value{VERSION} of the protocol specification. This -version number is intended only to aid in distinguishing different -versions of this specification. Although the specification is currently -maintained in conjunction with the CVS implementation, and carries the -same version number, it also intends to document what is involved with -interoperating with other implementations (such as other versions of -CVS); see @ref{Requirements}. This version number should not be used -by clients or servers to determine what variant of the protocol to -speak; they should instead use the @code{valid-requests} and -@code{Valid-responses} mechanism (@pxref{Protocol}), which is more -flexible. - -@node Goals -@chapter Goals - -@itemize @bullet -@item -Do not assume any access to the repository other than via this protocol. -It does not depend on NFS, rdist, etc. - -@item -Providing a reliable transport is outside this protocol. The protocol -expects a reliable transport that is transparent (that is, there is no -translation of characters, including characters such as -linefeeds or carriage returns), and can transmit all 256 octets (for -example for proper handling of binary files, compression, and -encryption). The encoding of characters specified by the protocol (the -names of requests and so on) is the invariant ISO 646 character set (a -subset of most popular character sets including ASCII and others). For -more details on running the protocol over the TCP reliable transport, -see @ref{Connection and Authentication}. - -@item -Security and authentication are handled outside this protocol (but see -below about @samp{cvs kserver} and @samp{cvs pserver}). - -@item -The protocol makes it possible for updates to be atomic with respect to -checkins; that is if someone commits changes to several files in one cvs -command, then an update by someone else would either get all the -changes, or none of them. The current @sc{cvs} server can't do this, -but that isn't the protocol's fault. - -@item -The protocol is, with a few exceptions, transaction-based. That is, the -client sends all its requests (without waiting for server responses), -and then waits for the server to send back all responses (without -waiting for further client requests). This has the advantage of -minimizing network turnarounds and the disadvantage of sometimes -transferring more data than would be necessary if there were a richer -interaction. Another, more subtle, advantage is that there is no need -for the protocol to provide locking for features such as making checkins -atomic with respect to updates. Any such locking can be handled -entirely by the server. A good server implementation (such as the -current @sc{cvs} server) will make sure that it does not have any such -locks in place whenever it is waiting for communication with the client; -this prevents one client on a slow or flaky network from interfering -with the work of others. - -@item -It is a general design goal to provide only one way to do a given -operation (where possible). For example, implementations have no choice -about whether to terminate lines with linefeeds or some other -character(s), and request and response names are case-sensitive. This -is to enhance interoperability. If a protocol allows more than one way -to do something, it is all too easy for some implementations to support -only some of them (perhaps accidentally). -@c I vaguely remember reading, probably in an RFC, about the problems -@c that were caused when some people decided that SMTP should accept -@c other line termination (in the message ("DATA")?) than CRLF. However, I -@c can't seem to track down the reference. -@end itemize - -@node Connection and Authentication -@chapter How to Connect to and Authenticate Oneself to the CVS server - -Connection and authentication occurs before the CVS protocol itself is -started. There are several ways to connect. - -@table @asis -@item server -If the client has a way to execute commands on the server, and provide -input to the commands and output from them, then it can connect that -way. This could be the usual rsh (port 514) protocol, Kerberos rsh, -SSH, or any similar mechanism. The client may allow the user to specify -the name of the server program; the default is @code{cvs}. It is -invoked with one argument, @code{server}. Once it invokes the server, -the client proceeds to start the cvs protocol. - -@item kserver -The kerberized server listens on a port (in the current implementation, -by having inetd call "cvs kserver") which defaults to 1999. The client -connects, sends the usual kerberos authentication information, and then -starts the cvs protocol. Note: port 1999 is officially registered for -another use, and in any event one cannot register more than one port for -CVS, so GSS-API (see below) is recommended instead of kserver as a way -to support kerberos. - -@item pserver -The name @dfn{pserver} is somewhat confusing. It refers to both a -generic framework which allows the CVS protocol to support several -authentication mechanisms, and a name for a specific mechanism which -transfers a username and a cleartext password. Servers need not support -all mechanisms, and in fact servers will typically want to support only -those mechanisms which meet the relevant security needs. - -The pserver server listens on a port (in the current -implementation, by having inetd call "cvs pserver") which defaults to -2401 (this port is officially registered). The client -connects, and sends the following: - -@itemize @bullet -@item -the string @samp{BEGIN AUTH REQUEST}, a linefeed, -@item -the cvs root, a linefeed, -@item -the username, a linefeed, -@item -the password trivially encoded (see @ref{Password scrambling}), a -linefeed, -@item -the string @samp{END AUTH REQUEST}, and a linefeed. -@end itemize - -The client must send the -identical string for cvs root both here and later in the -@code{Root} request of the cvs -protocol itself. Servers are encouraged to enforce this restriction. -The possible server responses (each of which is followed by a linefeed) -are the following. Note that although there is a small similarity -between this authentication protocol and the cvs protocol, they are -separate. - -@table @code -@item I LOVE YOU -The authentication is successful. The client proceeds with the cvs -protocol itself. - -@item I HATE YOU -The authentication fails. After sending this response, the server may -close the connection. It is up to the server to decide whether to give -this response, which is generic, or a more specific response using -@samp{E} and/or @samp{error}. - -@item E @var{text} -Provide a message for the user. After this response, the authentication -protocol continues with another response. Typically the server will -provide a series of @samp{E} responses followed by @samp{error}. -Compatibility note: @sc{cvs} 1.9.10 and older clients will print -@code{unrecognized auth response} and @var{text}, and then exit, upon -receiving this response. - -@item error @var{code} @var{text} -The authentication fails. After sending this response, the server may -close the connection. The @var{code} is a code describing why it -failed, intended for computer consumption. The only code currently -defined is @samp{0} which is nonspecific, but clients must silently -treat any unrecognized codes as nonspecific. -The @var{text} should be supplied to the -user. Compatibility note: @sc{cvs} 1.9.10 and older clients will print -@code{unrecognized auth response} and @var{text}, and then exit, upon -receiving this response. -Note that @var{text} for this response, or the @var{text} in an @code{E} -response, is not designed for machine parsing. More vigorous use of -@var{code}, or future extensions, will be needed to prove a cleaner -machine-parseable indication of what the error was. -@end table - -@c If you are thinking of putting samp or code around BEGIN AUTH REQUEST -@c and friends, watch for overfull hboxes. -If the client wishes to merely authenticate without starting the cvs -protocol, the procedure is the same, except BEGIN AUTH REQUEST is -replaced with BEGIN VERIFICATION REQUEST, END AUTH REQUEST -is replaced with END VERIFICATION REQUEST, and upon receipt of -I LOVE YOU the connection is closed rather than continuing. - -Another mechanism is GSSAPI authentication. GSSAPI is a -generic interface to security services such as kerberos. GSSAPI is -specified in RFC2078 (GSSAPI version 2) and RFC1508 (GSSAPI version 1); -we are not aware of differences between the two which affect the -protocol in incompatible ways, so we make no attempt to specify one -version or the other. -The procedure here is to start with @samp{BEGIN -GSSAPI REQUEST}. GSSAPI authentication information is then exchanged -between the client and the server. Each packet of information consists -of a two byte big-endian length, followed by that many bytes of data. -After the GSSAPI authentication is complete, the server continues with -the responses described above (@samp{I LOVE YOU}, etc.). - -@item future possibilities -There are a nearly unlimited number of ways to connect and authenticate. -One might want to allow access based on IP address (similar to the usual -rsh protocol but with different/no restrictions on ports < 1024), to -adopt mechanisms such as Pluggable Authentication Modules (PAM), to -allow users to run their own servers under their own usernames without -root access, or any number of other possibilities. The way to add -future mechanisms, for the most part, should be to continue to use port -2401, but to use different strings in place of @samp{BEGIN AUTH -REQUEST}. -@end table - -@node Password scrambling -@chapter Password scrambling algorithm - -The pserver authentication protocol, as described in @ref{Connection and -Authentication}, trivially encodes the passwords. This is only to -prevent inadvertent compromise; it provides no protection against even a -relatively unsophisticated attacker. For comparison, HTTP Basic -Authentication (as described in RFC2068) uses BASE64 for a similar -purpose. CVS uses its own algorithm, described here. - -The scrambled password starts with @samp{A}, which serves to identify -the scrambling algorithm in use. After that follows a single octet for -each character in the password, according to a fixed encoding. The -values are shown here, with the encoded values in decimal. Control -characters, space, and characters outside the invariant ISO 646 -character set are not shown; such characters are not recommended for use -in passwords. There is a long discussion of character set issues in -@ref{Protocol Notes}. - -@example - 0 111 P 125 p 58 -! 120 1 52 A 57 Q 55 a 121 q 113 -" 53 2 75 B 83 R 54 b 117 r 32 - 3 119 C 43 S 66 c 104 s 90 - 4 49 D 46 T 124 d 101 t 44 -% 109 5 34 E 102 U 126 e 100 u 98 -& 72 6 82 F 40 V 59 f 69 v 60 -' 108 7 81 G 89 W 47 g 73 w 51 -( 70 8 95 H 38 X 92 h 99 x 33 -) 64 9 65 I 103 Y 71 i 63 y 97 -* 76 : 112 J 45 Z 115 j 94 z 62 -+ 67 ; 86 K 50 k 93 -, 116 < 118 L 42 l 39 -- 74 = 110 M 123 m 37 -. 68 > 122 N 91 n 61 -/ 87 ? 105 O 35 _ 56 o 48 -@end example - -@node Protocol -@chapter The CVS client/server protocol - -In the following, @samp{\n} refers to a linefeed and @samp{\t} refers to -a horizontal tab; @dfn{requests} are what the client sends and -@dfn{responses} are what the server sends. In general, the connection is -governed by the client---the server does not send responses without -first receiving requests to do so; see @ref{Response intro} for more -details of this convention. - -It is typical, early in the connection, for the client to transmit a -@code{Valid-responses} request, containing all the responses it -supports, followed by a @code{valid-requests} request, which elicits -from the server a @code{Valid-requests} response containing all the -requests it understands. In this way, the client and server each find -out what the other supports before exchanging large amounts of data -(such as file contents). - -@c Hmm, having 3 sections in this menu makes a certain amount of sense -@c but that structure gets lost in the printed manual (not sure about -@c HTML). Perhaps there is a better way. -@menu - -General protocol conventions: - -* Entries Lines:: Transmitting RCS data -* File Modes:: Read, write, execute, and possibly more... -* Filenames:: Conventions regarding filenames -* File transmissions:: How file contents are transmitted -* Strings:: Strings in various requests and responses -* Dates:: Times and dates - -The protocol itself: - -* Request intro:: General conventions relating to requests -* Requests:: List of requests -* Response intro:: General conventions relating to responses -* Response pathnames:: The "pathname" in responses -* Responses:: List of responses -* Text tags:: More details about the MT response - -An example session, and some further observations: - -* Example:: A conversation between client and server -* Requirements:: Things not to omit from an implementation -* Obsolete:: Former protocol features -@end menu - -@node Entries Lines -@section Entries Lines - -Entries lines are transmitted as: - -@example -/ @var{name} / @var{version} / @var{conflict} / @var{options} / @var{tag_or_date} -@end example - -@var{tag_or_date} is either @samp{T} @var{tag} or @samp{D} @var{date} -or empty. If it is followed by a slash, anything after the slash -shall be silently ignored. - -@var{version} can be empty, or start with @samp{0} or @samp{-}, for no -user file, new user file, or user file to be removed, respectively. - -@c FIXME: should distinguish sender and receiver behavior here; the -@c "anything else" and "does not start with" are intended for future -@c expansion, and we should specify a sender behavior. -@var{conflict}, if it starts with @samp{+}, indicates that the file had -conflicts in it. The rest of @var{conflict} is @samp{=} if the -timestamp matches the file, or anything else if it doesn't. If -@var{conflict} does not start with a @samp{+}, it is silently ignored. - -@var{options} signifies the keyword expansion options (for example -@samp{-ko}). In an @code{Entry} request, this indicates the options -that were specified with the file from the previous file updating -response (@pxref{Response intro}, for a list of file updating -responses); if the client is specifying the @samp{-k} or @samp{-A} -option to @code{update}, then it is the server which figures out what -overrides what. - -@node File Modes -@section File Modes - -A mode is any number of repetitions of - -@example -@var{mode-type} = @var{data} -@end example - -separated by @samp{,}. - -@var{mode-type} is an identifier composed of alphanumeric characters. -Currently specified: @samp{u} for user, @samp{g} for group, @samp{o} -for other (see below for discussion of whether these have their POSIX -meaning or are more loose). Unrecognized values of @var{mode-type} -are silently ignored. - -@var{data} consists of any data not containing @samp{,}, @samp{\0} or -@samp{\n}. For @samp{u}, @samp{g}, and @samp{o} mode types, data -consists of alphanumeric characters, where @samp{r} means read, @samp{w} -means write, @samp{x} means execute, and unrecognized letters are -silently ignored. - -The two most obvious ways in which the mode matters are: (1) is it -writeable? This is used by the developer communication features, and -is implemented even on OS/2 (and could be implemented on DOS), whose -notion of mode is limited to a readonly bit. (2) is it executable? -Unix CVS users need CVS to store this setting (for shell scripts and -the like). The current CVS implementation on unix does a little bit -more than just maintain these two settings, but it doesn't really have -a nice general facility to store or version control the mode, even on -unix, much less across operating systems with diverse protection -features. So all the ins and outs of what the mode means across -operating systems haven't really been worked out (e.g. should the VMS -port use ACLs to get POSIX semantics for groups?). - -@node Filenames -@section Conventions regarding transmission of file names - -In most contexts, @samp{/} is used to separate directory and file -names in filenames, and any use of other conventions (for example, -that the user might type on the command line) is converted to that -form. The only exceptions might be a few cases in which the server -provides a magic cookie which the client then repeats verbatim, but as -the server has not yet been ported beyond unix, the two rules provide -the same answer (and what to do if future server ports are operating -on a repository like e:/foo or CVS_ROOT:[FOO.BAR] has not been -carefully thought out). - -Characters outside the invariant ISO 646 character set should be avoided -in filenames. This restriction may need to be relaxed to allow for -characters such as @samp{[} and @samp{]} (see above about non-unix -servers); this has not been carefully considered (and currently -implementations probably use whatever character sets that the operating -systems they are running on allow, and/or that users specify). Of -course the most portable practice is to restrict oneself further, to the -POSIX portable filename character set as specified in POSIX.1. - -@node File transmissions -@section File transmissions - -File contents (noted below as @var{file transmission}) can be sent in -one of two forms. The simpler form is a number of bytes, followed by a -linefeed, followed by the specified number of bytes of file contents. -These are the entire contents of the specified file. Second, if both -client and server support @samp{gzip-file-contents}, a @samp{z} may -precede the length, and the `file contents' sent are actually compressed -with @samp{gzip} (RFC1952/1951) compression. The length specified is -that of the compressed version of the file. - -In neither case are the file content followed by any additional data. -The transmission of a file will end with a linefeed iff that file (or its -compressed form) ends with a linefeed. - -The encoding of file contents depends on the value for the @samp{-k} -option. If the file is binary (as specified by the @samp{-kb} option in -the appropriate place), then it is just a certain number of octets, and -the protocol contributes nothing towards determining the encoding (using -the file name is one widespread, if not universally popular, mechanism). -If the file is text (not binary), then the file is sent as a series of -lines, separated by linefeeds. If the keyword expansion is set to -something other than @samp{-ko}, then it is expected that the file -conform to the RCS expectations regarding keyword expansion---in -particular, that it is in a character set such as ASCII in which 0x24 is -a dollar sign (@samp{$}). - -@node Strings -@section Strings - -In various contexts, for example the @code{Argument} request and the -@code{M} response, one transmits what is essentially an arbitrary -string. Often this will have been supplied by the user (for example, -the @samp{-m} option to the @code{ci} request). The protocol has no -mechanism to specify the character set of such strings; it would be -fairly safe to stick to the invariant ISO 646 character set but the -existing practice is probably to just transmit whatever the user -specifies, and hope that everyone involved agrees which character set is -in use, or sticks to a common subset. - -@node Dates -@section Dates - -The protocol contains times and dates in various places. - -For the @samp{-D} option to the @code{annotate}, @code{co}, @code{diff}, -@code{export}, @code{history}, @code{rannotate}, @code{rdiff}, -@code{rtag}, @code{tag}, -and @code{update} requests, the server should support two formats: - -@example -26 May 1997 13:01:40 -0000 ; @r{RFC 822 as modified by RFC 1123} -5/26/1997 13:01:40 GMT ; @r{traditional} -@end example - -The former format is preferred; the latter however is sent by the CVS -command line client (versions 1.5 through at least 1.9). - -For the @samp{-d} option to the @code{log} and @code{rlog} requests, -servers should at -least support RFC 822/1123 format. Clients are encouraged to use this -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 -822/1123 format (see the descriptions of that response and request for -details). - -For @code{Notify}, see the description of that request. - -@node Request intro -@section Request intro - -By convention, requests which begin with a capital letter do not elicit -a response from the server, while all others do -- save one. The -exception is @samp{gzip-file-contents}. Unrecognized requests will -always elicit a response from the server, even if that request begins -with a capital letter. - -The term @dfn{command} means a request which expects a response (except -@code{valid-requests}). The general model is that the client transmits -a great number of requests, but nothing happens until the very end when -the client transmits a command. Although the intention is that -transmitting several commands in one connection should be legal, -existing servers probably have some bugs with some combinations of more -than one command, and so clients may find it necessary to make several -connections in some cases. This should be thought of as a workaround -rather than a desired attribute of the protocol. - -@node Requests -@section Requests - -Here are the requests: - -@table @code -@item Root @var{pathname} \n -Response expected: no. Tell the server which @code{CVSROOT} to use. -Note that @var{pathname} is @emph{not} a fully qualified @code{CVSROOT} -variable, but only the local directory part of it. @var{pathname} must -already exist on the server. Again, @var{pathname} @emph{does not} include -the hostname of the server, how to access the server, etc.; by the time -the CVS protocol is 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}, -@code{Global_option}, @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. -Tell the server what directory to use. The @var{repository} should be a -directory name from a previous server response. Note that -this both gives a default for @code{Entry} and @code{Modified} and -also for @code{ci} and the other commands; normal usage is to send -@code{Directory} for each directory in which there will be an -@code{Entry} or @code{Modified}, and then a final @code{Directory} -for the original directory, then the command. -The @var{local-directory} is relative to -the top level at which the command is occurring (i.e., the last -@code{Directory} which is sent before the command); -to indicate that top level, @samp{.} should be sent for -@var{local-directory}. - -Here is an example of where a client gets @var{repository} and -@var{local-directory}. Suppose that there is a module defined by - -@example -moddir 1dir -@end example - -That is, one can check out @code{moddir} and it will take @code{1dir} in -the repository and check it out to @code{moddir} in the working -directory. Then an initial check out could proceed like this: - -@example -C: Root /home/kingdon/zwork/cvsroot -. . . -C: Argument moddir -C: Directory . -C: /home/kingdon/zwork/cvsroot -C: co -S: Clear-sticky moddir/ -S: /home/kingdon/zwork/cvsroot/1dir/ -. . . -S: ok -@end example - -In this example the response shown is @code{Clear-sticky}, but it could -be another response instead. Note that it returns two pathnames. -The first one, @file{moddir/}, indicates the working -directory to check out into. The second one, ending in @file{1dir/}, -indicates the directory to pass back to the server in a subsequent -@code{Directory} request. For example, a subsequent @code{update} -request might look like: - -@example -C: Directory moddir -C: /home/kingdon/zwork/cvsroot/1dir -. . . -C: update -@end example - -For a given @var{local-directory}, the repository will be the same for -each of the responses, so one can use the repository from whichever -response is most convenient. Typically a client will store the -repository along with the sources for each @var{local-directory}, use -that same setting whenever operating on that @var{local-directory}, and -not update the setting as long as the @var{local-directory} exists. - -A client is free to rename a @var{local-directory} at any time (for -example, in response to an explicit user request). While it is true -that the server supplies a @var{local-directory} to the client, as noted -above, this is only the default place to put the directory. Of course, -the various @code{Directory} requests for a single command (for example, -@code{update} or @code{ci} request) should name a particular directory -with the same @var{local-directory}. - -Each @code{Directory} request specifies a brand-new -@var{local-directory} and @var{repository}; that is, -@var{local-directory} and @var{repository} are never relative to paths -specified in any previous @code{Directory} request. - -Here's a more complex example, in which we request an update of a -working directory which has been checked out from multiple places in the -repository. - -@example -C: Argument dir1 -C: Directory dir1 -C: /home/foo/repos/mod1 -. . . -C: Argument dir2 -C: Directory dir2 -C: /home/foo/repos/mod2 -. . . -C: Argument dir3 -C: Directory dir3/subdir3 -C: /home/foo/repos/mod3 -. . . -C: update -@end example - -While directories @code{dir1} and @code{dir2} will be handled in similar -fashion to the other examples given above, @code{dir3} is slightly -different from the server's standpoint. Notice that module @code{mod3} -is actually checked out into @code{dir3/subdir3}, meaning that directory -@code{dir3} is either empty or does not contain data checked out from -this repository. - -The above example will work correctly in @sc{cvs} 1.10.1 and later. The -server will descend the tree starting from all directories mentioned in -@code{Argument} requests and update those directories specifically -mentioned in @code{Directory} requests. - -Previous versions of @sc{cvs} (1.10 and earlier) do not behave the same -way. While the descent of the tree begins at all directories mentioned -in @code{Argument} requests, descent into subdirectories only occurs if -a directory has been mentioned in a @code{Directory} request. -Therefore, the above example would succeed in updating @code{dir1} and -@code{dir2}, but would skip @code{dir3} because that directory was not -specifically mentioned in a @code{Directory} request. A functional -version of the above that would run on a 1.10 or earlier server is as -follows: - -@example -C: Argument dir1 -C: Directory dir1 -C: /home/foo/repos/mod1 -. . . -C: Argument dir2 -C: Directory dir2 -C: /home/foo/repos/mod2 -. . . -C: Argument dir3 -C: Directory dir3 -C: /home/foo/repos/. -. . . -C: Directory dir3/subdir3 -C: /home/foo/repos/mod3 -. . . -C: update -@end example - -Note the extra @code{Directory dir3} request. It might be better to use -@code{Emptydir} as the repository for the @code{dir3} directory, but the -above will certainly work. - -One more peculiarity of the 1.10 and earlier protocol is the ordering of -@code{Directory} arguments. In order for a subdirectory to be -registered correctly for descent by the recursion processor, its parent -must be sent first. For example, the following would not work to update -@code{dir3/subdir3}: - -@example -. . . -C: Argument dir3 -C: Directory dir3/subdir3 -C: /home/foo/repos/mod3 -. . . -C: Directory dir3 -C: /home/foo/repos/. -. . . -C: update -@end example - -The implementation of the server in 1.10 and earlier writes the -administration files for a given directory at the time of the -@code{Directory} request. It also tries to register the directory with -its parent to mark it for recursion. In the above example, at the time -@code{dir3/subdir3} is created, the physical directory for @code{dir3} -will be created on disk, but the administration files will not have been -created. Therefore, when the server tries to register -@code{dir3/subdir3} for recursion, the operation will silently fail -because the administration files do not yet exist for @code{dir3}. - -@item Max-dotdot @var{level} \n -Response expected: no. -Tell the server that @var{level} levels of directories above the -directory which @code{Directory} requests are relative to will be -needed. For example, if the client is planning to use a -@code{Directory} request for @file{../../foo}, it must send a -@code{Max-dotdot} request with a @var{level} of at least 2. -@code{Max-dotdot} must be sent before the first @code{Directory} -request. - -@item Static-directory \n -Response expected: no. Tell the server that the directory most recently -specified with @code{Directory} should not have -additional files checked out unless explicitly requested. The client -sends this if the @code{Entries.Static} flag is set, which is controlled -by the @code{Set-static-directory} and @code{Clear-static-directory} -responses. - -@item Sticky @var{tagspec} \n -Response expected: no. Tell the server that the directory most recently -specified with @code{Directory} has a sticky tag or date @var{tagspec}. -The first character of @var{tagspec} is @samp{T} for a tag, @samp{D} -for a date, or some other character supplied by a Set-sticky response -from a previous request to the server. The remainder of @var{tagspec} -contains the actual tag or date, again as supplied by Set-sticky. - -The server should remember @code{Static-directory} and @code{Sticky} -requests for a particular directory; the client need not resend them -each time it sends a @code{Directory} request for a given directory. -However, the server is not obliged to remember them beyond the context -of a single command. - -@item Entry @var{entry-line} \n -Response expected: no. Tell the server what version of a file is on the -local machine. The name in @var{entry-line} is a name relative to the -directory most recently specified with @code{Directory}. If the user -is operating on only some files in a directory, @code{Entry} requests -for only those files need be included. If an @code{Entry} request is -sent without @code{Modified}, @code{Is-modified}, or @code{Unchanged}, -it means the file is -lost (does not exist in the working directory). If both @code{Entry} -and one of @code{Modified}, @code{Is-modified}, or @code{Unchanged} are -sent for the same file, @code{Entry} must be sent first. For a -given file, one can send @code{Modified}, @code{Is-modified}, or -@code{Unchanged}, but not more than one of these three. - -@item Kopt @var{option} \n -This indicates to the server which keyword expansion options to use for -the file specified by the next @code{Modified} or @code{Is-modified} -request (for example @samp{-kb} for a binary file). This is similar to -@code{Entry}, but is used for a file for which there is no entries line. -Typically this will be a file being added via an @code{add} or -@code{import} request. The client may not send both @code{Kopt} and -@code{Entry} for the same file. - -@item Checkin-time @var{time} \n -For the file specified by the next @code{Modified} request, use -@var{time} as the time of the checkin. The @var{time} is in the format -specified by RFC822 as modified by RFC1123. The client may specify any -timezone it chooses; servers will want to convert that to their own -timezone as appropriate. An example of this format is: - -@example -26 May 1997 13:01:40 -0400 -@end example - -There is no requirement that the client and server clocks be -synchronized. The client just sends its recommendation for a timestamp -(based on file timestamps or whatever), and the server should just believe -it (this means that the time might be in the future, for example). - -Note that this is not a general-purpose way to tell the server about the -timestamp of a file; that would be a separate request (if there are -servers which can maintain timestamp and time of checkin separately). - -This request should affect the @code{import} request, and may optionally -affect the @code{ci} request or other relevant requests if any. - -@item Modified @var{filename} \n -Response expected: no. Additional data: mode, \n, file transmission. -Send the server a copy of one locally modified file. @var{filename} is -a file within the most recent directory sent with @code{Directory}; it -must not contain @samp{/}. If -the user is operating on only some files in a directory, only those -files need to be included. This can also be sent without @code{Entry}, -if there is no entry for the file. - -@item Is-modified @var{filename} \n -Response expected: no. Additional data: none. Like @code{Modified}, -but used if the server only needs -to know whether the file is modified, not the contents. - -The commands which can take @code{Is-modified} instead of -@code{Modified} with no known change in behavior are: @code{admin}, -@code{diff} (if and only if two @samp{-r} or @samp{-D} options are -specified), @code{watch-on}, @code{watch-off}, @code{watch-add}, -@code{watch-remove}, @code{watchers}, @code{editors}, -@code{log}, and @code{annotate}. - -For the @code{status} command, one can send @code{Is-modified} but if -the client is using imperfect mechanisms such as timestamps to determine -whether to consider a file modified, then the behavior will be -different. That is, if one sends @code{Modified}, then the server will -actually compare the contents of the file sent and the one it derives -from to determine whether the file is genuinely modified. But if one -sends @code{Is-modified}, then the server takes the client's word for -it. A similar situation exists for @code{tag}, if the @samp{-c} option -is specified. - -Commands for which @code{Modified} is necessary are @code{co}, -@code{ci}, @code{update}, and @code{import}. - -Commands which do not need to inform the server about a working -directory, and thus should not be sending either @code{Modified} or -@code{Is-modified}: @code{rdiff}, @code{rtag}, @code{history}, -and @code{release}. - -Commands for which further investigation is warranted are: -@code{remove}, @code{add}, and @code{export}. Pending such -investigation, the more conservative course of action is to stick to -@code{Modified}. - -@item Unchanged @var{filename} \n -Response expected: no. Tell the server that @var{filename} has not been -modified in the checked out directory. The @var{filename} is -a file within the most recent directory sent with @code{Directory}; it -must not contain @samp{/}. - -@item UseUnchanged \n -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 Empty-conflicts \n -Response expected: yes. This request is an alias for @code{noop}. Its -presence in the list of @code{valid-requests} is intended to be used as a -placeholder to alert the client that the server does not require the contents -of files with conflicts that have not been modified since the merge, for -operations other than diff. It was a bug in pre 1.11.22 & pre 1.12.14 servers -that the contents of files with conflicts was required for the server to -acknowledge the existence of the conflicts. - -@item Notify @var{filename} \n -Response expected: no. -Tell the server that an @code{edit} or @code{unedit} command has taken -place. The server needs to send a @code{Notified} response, but such -response is deferred until the next time that the server is sending -responses. -The @var{filename} is a file within the most recent directory sent with -@code{Directory}; it must not contain @samp{/}. -Additional data: -@example -@var{notification-type} \t @var{time} \t @var{clienthost} \t -@var{working-dir} \t @var{watches} \n -@end example -where @var{notification-type} is @samp{E} for edit, @samp{U} for -unedit, undefined behavior if @samp{C}, and all other letters should be -silently ignored for future expansion. -@var{time} is the time at which the edit or unedit took place, in a -user-readable format of the client's choice (the server should treat the -time as an opaque string rather than interpreting it). -@c Might be useful to specify a format, but I don't know if we want to -@c specify the status quo (ISO C asctime() format plus timezone) without -@c offering the option of ISO8601 and/or RFC822/1123 (see cvs.texinfo -@c for much much more on date formats). -@var{clienthost} is the name of the host on which the edit or unedit -took place, and @var{working-dir} is the pathname of the working -directory where the edit or unedit took place. @var{watches} are the -temporary watches, zero or more of the following characters in the -following order: @samp{E} for edit, @samp{U} for unedit, @samp{C} for -commit, and all other letters should be silently ignored for future -expansion. If @var{notification-type} is @samp{E} the temporary watches -are set; if it is @samp{U} they are cleared. -If @var{watches} is followed by \t then the -\t and the rest of the line should be ignored, for future expansion. - -The @var{time}, @var{clienthost}, and @var{working-dir} fields may not -contain the characters @samp{+}, @samp{,}, @samp{>}, @samp{;}, or @samp{=}. - -Note that a client may be capable of performing an @code{edit} or -@code{unedit} operation without connecting to the server at that time, -and instead connecting to the server when it is convenient (for example, -when a laptop is on the net again) to send the @code{Notify} requests. -Even if a client is capable of deferring notifications, it should -attempt to send them immediately (one can send @code{Notify} requests -together with a @code{noop} request, for example), unless perhaps if -it can know that a connection would be impossible. - -@item Questionable @var{filename} \n -Response expected: no. Additional data: no. Tell the server to check -whether @var{filename} should be ignored, and if not, next time the -server sends responses, send (in a @code{M} response) @samp{?} followed -by the directory and filename. @var{filename} must not contain -@samp{/}; it needs to be a file in the directory named by the most -recent @code{Directory} request. -@c FIXME: the bit about not containing / is true of most of the -@c requests, but isn't documented and should be. - -@item Case \n -Response expected: no. Tell the server that filenames should be matched -in a case-insensitive fashion. Note that this is not the primary -mechanism for achieving case-insensitivity; for the most part the client -keeps track of the case which the server wants to use and takes care to -always use that case regardless of what the user specifies. For example -the filenames given in @code{Entry} and @code{Modified} requests for the -same file must match in case regardless of whether the @code{Case} -request is sent. The latter mechanism is more general (it could also be -used for 8.3 filenames, VMS filenames with more than one @samp{.}, and -any other situation in which there is a predictable mapping between -filenames in the working directory and filenames in the protocol), but -there are some situations it cannot handle (ignore patterns, or -situations where the user specifies a filename and the client does not -know about that file). - -Though this request will be supported into the foreseeable future, it has been -the source of numerous bug reports in the past due to the complexity of testing -this functionality via the test suite and client developers are encouraged not -to use it. Instead, please consider munging conflicting names and maintaining -a map for communicating with the server. For example, suppose the server sends -files @file{case}, @file{CASE}, and @file{CaSe}. The client could write all -three files to names such as, @file{case}, @file{case_prefix_case}, and -@file{case_prefix_2_case} and maintain a mapping between the file names in, for -instance a new @file{CVS/Map} file. - -@item Argument @var{text} \n -Response expected: no. -Save argument for use in a subsequent command. Arguments -accumulate until an argument-using command is given, at which point -they are forgotten. - -@item Argumentx @var{text} \n -Response expected: no. Append \n followed by text to the current -argument being saved. - -@item Global_option @var{option} \n -Response expected: no. -Transmit one of the global options @samp{-q}, @samp{-Q}, @samp{-l}, -@samp{-t}, @samp{-r}, or @samp{-n}. @var{option} must be one of those -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. -Use zlib (RFC 1950/1951) compression to compress all further communication -between the client and the server. After this request is sent, all -further communication must be compressed. All further data received -from the server will also be compressed. The @var{level} argument -suggests to the server the level of compression that it should apply; it -should be an integer between 1 and 9, inclusive, where a higher number -indicates more compression. - -@item Kerberos-encrypt \n -Response expected: no. -Use Kerberos encryption to encrypt all further communication between the -client and the server. This will only work if the connection was made -over Kerberos in the first place. If both the @code{Gzip-stream} and -the @code{Kerberos-encrypt} requests are used, the -@code{Kerberos-encrypt} request should be used first. This will make -the client and server encrypt the compressed data, as opposed to -compressing the encrypted data. Encrypted data is generally -incompressible. - -Note that this request does not fully prevent an attacker from hijacking -the connection, in the sense that it does not prevent hijacking the -connection between the initial authentication and the -@code{Kerberos-encrypt} request. - -@item Gssapi-encrypt \n -Response expected: no. -Use GSSAPI encryption to encrypt all further communication between the -client and the server. This will only work if the connection was made -over GSSAPI in the first place. See @code{Kerberos-encrypt}, above, for -the relation between @code{Gssapi-encrypt} and @code{Gzip-stream}. - -Note that this request does not fully prevent an attacker from hijacking -the connection, in the sense that it does not prevent hijacking the -connection between the initial authentication and the -@code{Gssapi-encrypt} request. - -@item Gssapi-authenticate \n -Response expected: no. -Use GSSAPI authentication to authenticate all further communication -between the client and the server. This will only work if the -connection was made over GSSAPI in the first place. Encrypted data is -automatically authenticated, so using both @code{Gssapi-authenticate} -and @code{Gssapi-encrypt} has no effect beyond that of -@code{Gssapi-encrypt}. Unlike encrypted data, it is reasonable to -compress authenticated data. - -Note that this request does not fully prevent an attacker from hijacking -the connection, in the sense that it does not prevent hijacking the -connection between the initial authentication and the -@code{Gssapi-authenticate} request. - -@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 -arguments. Returns the data in @code{Module-expansion} responses. Note -that the server can assume that this is checkout or export, not rtag or -rdiff; the latter do not access the working directory and thus have no -need to expand modules on the client side. - -Expand may not be the best word for what this request does. It does not -necessarily tell you all the files contained in a module, for example. -Basically it is a way of telling you which working directories the -server needs to know about in order to handle a checkout of the -specified modules. - -For example, suppose that the server has a module defined by - -@example -aliasmodule -a 1dir -@end example - -That is, one can check out @code{aliasmodule} and it will take -@code{1dir} in the repository and check it out to @code{1dir} in the -working directory. Now suppose the client already has this module -checked out and is planning on using the @code{co} request to update it. -Without using @code{expand-modules}, the client would have two bad -choices: it could either send information about @emph{all} working -directories under the current directory, which could be unnecessarily -slow, or it could be ignorant of the fact that @code{aliasmodule} stands -for @code{1dir}, and neglect to send information for @code{1dir}, which -would lead to incorrect operation. -@c Those don't really seem like the only two options. I mean, what -@c about keeping track of the correspondence from when we first checked -@c out a fresh directory? Not that the CVS client does this, or that -@c I've really thought about whether it would be a good idea... - -With @code{expand-modules}, the client would first ask for the module to -be expanded: - -@example -C: Root /home/kingdon/zwork/cvsroot -. . . -C: Argument aliasmodule -C: Directory . -C: /home/kingdon/zwork/cvsroot -C: expand-modules -S: Module-expansion 1dir -S: ok -@end example - -and then it knows to check the @file{1dir} directory and send -requests such as @code{Entry} and @code{Modified} for the files in that -directory. - -@item ci \n -@itemx diff \n -@itemx tag \n -@itemx status \n -@itemx admin \n -@itemx history \n -@itemx watchers \n -@itemx editors \n -@itemx annotate \n -Response expected: yes. Actually do a cvs command. This uses any -previous @code{Argument}, @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. 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 -@code{Modified} requests, if they have been sent. Arguments to this -command are module names; the client cannot know what directories they -correspond to except by (1) just sending the @code{co} request, and then -seeing what directory names the server sends back in its responses, and -(2) the @code{expand-modules} request. - -@item export \n -Response expected: yes. Get files from the repository. This uses any -previous @code{Argument}, @code{Directory}, @code{Entry}, or -@code{Modified} requests, if they have been sent. Arguments to this -command are module names, as described for the @code{co} request. The -intention behind this command is that a client can get sources from a -server without storing CVS information about those sources. That is, a -client probably should not count on being able to take the entries line -returned in the @code{Created} response from an @code{export} request -and send it in a future @code{Entry} request. Note that the entries -line in the @code{Created} response must indicate whether the file is -binary or text, so the client can create it correctly. - -@item rannotate \n -@itemx rdiff \n -@itemx rlog \n -@itemx rtag \n -Response expected: yes. Actually do a cvs command. This uses any -previous @code{Argument} requests, if they have been sent. The client -should not send @code{Directory}, @code{Entry}, or @code{Modified} -requests for these commands; they are not used. Arguments to these -commands are module names, as described for @code{co}. - -@item update \n -Response expected: yes. Actually do a @code{cvs update} command. This -uses any previous @code{Argument}, @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. The @code{-I} option is not used--files which the -client can decide whether to ignore are not mentioned and the client -sends the @code{Questionable} request for others. - -@item import \n -Response expected: yes. Actually do a @code{cvs import} command. This -uses any previous @code{Argument}, @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 - unlike most commands, the repository field of each -@code{Directory} request is ignored (it merely must point somewhere -within the root). The files to be imported are sent in @code{Modified} -requests (files which the client knows should be ignored are not sent; -the server must still process the CVSROOT/cvsignore file unless -I !@: is -sent). A log message must have been specified with a @code{-m} -argument. - -@item add \n -Response expected: yes. Add a file or directory. This uses any -previous @code{Argument}, @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. - -To add a directory, send the directory to be added using -@code{Directory} and @code{Argument} requests. For example: - -@example -C: Root /u/cvsroot -. . . -C: Argument nsdir -C: Directory nsdir -C: /u/cvsroot/1dir/nsdir -C: Directory . -C: /u/cvsroot/1dir -C: add -S: M Directory /u/cvsroot/1dir/nsdir added to the repository -S: ok -@end example - -You will notice that the server does not signal to the client in any -particular way that the directory has been successfully added. The -client is supposed to just assume that the directory has been added and -update its records accordingly. Note also that adding a directory is -immediate; it does not wait until a @code{ci} request as files do. - -To add a file, send the file to be added using a @code{Modified} -request. For example: - -@example -C: Argument nfile -C: Directory . -C: /u/cvsroot/1dir -C: Modified nfile -C: u=rw,g=r,o=r -C: 6 -C: hello -C: add -S: E cvs server: scheduling file `nfile' for addition -S: Mode u=rw,g=r,o=r -S: Checked-in ./ -S: /u/cvsroot/1dir/nfile -S: /nfile/0/// -S: E cvs server: use 'cvs commit' to add this file permanently -S: ok -@end example - -Note that the file has not been added to the repository; the only effect -of a successful @code{add} request, for a file, is to supply the client -with a new entries line containing @samp{0} to indicate an added file. -In fact, the client probably could perform this operation without -contacting the server, although using @code{add} does cause the server -to perform a few more checks. - -The client sends a subsequent @code{ci} to actually add the file to the -repository. - -Another quirk of the @code{add} request is that with CVS 1.9 and older, -a pathname specified in -an @code{Argument} request cannot contain @samp{/}. There is no good -reason for this restriction, and in fact more recent CVS servers don't -have it. -But the way to interoperate with the older servers is to ensure that -all @code{Directory} requests for @code{add} (except those used to add -directories, as described above), use @samp{.} for -@var{local-directory}. Specifying another string for -@var{local-directory} may not get an error, but it will get you strange -@code{Checked-in} responses from the buggy servers. - -@item remove \n -Response expected: yes. Remove a file. This uses any -previous @code{Argument}, @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. - -Note that this request does not actually do anything to the repository; -the only effect of a successful @code{remove} request is to supply the -client with a new entries line containing @samp{-} to indicate a removed -file. In fact, the client probably could perform this operation without -contacting the server, although using @code{remove} may cause the server -to perform a few more checks. - -The client sends a subsequent @code{ci} request to actually record the -removal in the repository. - -@item watch-on \n -@itemx watch-off \n -@itemx watch-add \n -@itemx watch-remove \n -Response expected: yes. Actually do the @code{cvs watch on}, @code{cvs -watch off}, @code{cvs watch add}, and @code{cvs watch remove} commands, -respectively. This uses any previous @code{Argument}, -@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. - -@item release \n -Response expected: yes. Note that a @code{cvs release} command has -taken place and update the history file accordingly. - -@item noop \n -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. -This request does not actually do anything. It is used as a signal that -the server is able to generate patches when given an @code{update} -request. The client must issue the @code{-u} argument to @code{update} -in order to receive patches. - -@item gzip-file-contents @var{level} \n -Response expected: no. Note that this request does not follow the -response convention stated above. @code{Gzip-stream} is suggested -instead of @code{gzip-file-contents} as it gives better compression; the -only reason to implement the latter is to provide compression with -@sc{cvs} 1.8 and earlier. The @code{gzip-file-contents} request asks -the server to compress files it sends to the client using @code{gzip} -(RFC1952/1951) compression, using the specified level of compression. -If this request is not made, the server must not compress files. - -This is only a hint to the server. It may still decide (for example, in -the case of very small files, or files that already appear to be -compressed) not to do the compression. Compression is indicated by a -@samp{z} preceding the file length. - -Availability of this request in the server indicates to the client that -it may compress files sent to the server, regardless of whether the -client actually uses this request. - -@item wrapper-sendme-rcsOptions \n -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 -contain any additional data. The response will normally be something like -@samp{error unrecognized request}, but it could be a different error if -a previous request which doesn't expect a response produced an error. -@end table - -When the client is done, it drops the connection. - -@node Response intro -@section Introduction to Responses - -After a command which expects a response, the server sends however many -of the following responses are appropriate. The server should not send -data at other times (the current implementation may violate this -principle in a few minor places, where the server is printing an error -message and exiting---this should be investigated further). - -Any set of responses always ends with @samp{error} or @samp{ok}. This -indicates that the response is over. - -@c "file updating response" and "file update modifying response" are -@c lame terms (mostly because they are so awkward). Any better ideas? -The responses @code{Checked-in}, @code{New-entry}, @code{Updated}, -@code{Created}, @code{Update-existing}, @code{Merged}, and -@code{Patched} are referred to as @dfn{file updating} responses, because -they change the status of a file in the working directory in some way. -The responses @code{Mode}, @code{Mod-time}, and @code{Checksum} are -referred to as @dfn{file update modifying} responses because they modify -the next file updating response. In no case shall a file update -modifying response apply to a file updating response other than the next -one. Nor can the same file update modifying response occur twice for -a given file updating response (if servers diagnose this problem, it may -aid in detecting the case where clients send an update modifying -response without following it by a file updating response). - -@node Response pathnames -@section The "pathname" in responses - -Many of the responses contain something called @var{pathname}. -@c FIXME: should better document when the specified repository needs to -@c end in "/.". -The name is somewhat misleading; it actually indicates a pair of -pathnames. First, a local directory name -relative to the directory in which the command was given (i.e., the last -@code{Directory} before the command). Then a linefeed and a repository -name. Then -a slash and the filename (without a @samp{,v} ending). -For example, for a file @file{i386.mh} -which is in the local directory @file{gas.clean/config} and for which -the repository is @file{/rel/cvsfiles/devo/gas/config}: - -@example -gas.clean/config/ -/rel/cvsfiles/devo/gas/config/i386.mh -@end example - -If the server wants to tell the client to create a directory, then it -merely uses the directory in any response, as described above, and the -client should create the directory if it does not exist. Note that this -should only be done one directory at a time, in order to permit the -client to correctly store the repository for each directory. Servers -can use requests such as @code{Clear-sticky}, -@code{Clear-static-directory}, or any other requests, to create -directories. -@c FIXME: Need example here of how "repository" needs to be sent for -@c each directory, and cannot be correctly deduced from, say, the most -@c deeply nested directory. - -Some server -implementations may poorly distinguish between a directory which should -not exist and a directory which contains no files; in order to refrain -from creating empty directories a client should both send the @samp{-P} -option to @code{update} or @code{co}, and should also detect the case in -which the server asks to create a directory but not any files within it -(in that case the client should remove the directory or refrain from -creating it in the first place). Note that servers could clean this up -greatly by only telling the client to create directories if the -directory in question should exist, but until servers do this, clients -will need to offer the @samp{-P} behavior described above. - -@node Responses -@section Responses - -Here are the responses: - -@table @code -@item Valid-requests @var{request-list} \n -Indicate what requests the server will accept. @var{request-list} -is a space separated list of tokens. If the server supports sending -patches, it will include @samp{update-patches} in this list. The -@samp{update-patches} request does not actually do anything. - -@item Checked-in @var{pathname} \n -Additional data: New Entries line, \n. This means a file @var{pathname} -has been successfully operated on (checked in, added, etc.). The name in -the Entries line is the same as the last component of @var{pathname}. - -@item New-entry @var{pathname} \n -Additional data: New Entries line, \n. Like @code{Checked-in}, but the -file is not up to date. - -@item Updated @var{pathname} \n -Additional data: New Entries line, \n, mode, \n, file transmission. A -new copy of the file is enclosed. This is used for a new revision of an -existing file, or for a new file, or for any other case in which the -local (client-side) copy of the file needs to be updated, and after -being updated it will be up to date. If any directory in pathname does -not exist, create it. This response is not used if @code{Created} and -@code{Update-existing} are supported. - -@item Created @var{pathname} \n -This is just like @code{Updated} and takes the same additional data, but -is used only if no @code{Entry}, @code{Modified}, or -@code{Unchanged} request has been sent for the file in question. The -distinction between @code{Created} and @code{Update-existing} is so -that the client can give an error message in several cases: (1) there is -a file in the working directory, but not one for which @code{Entry}, -@code{Modified}, or @code{Unchanged} was sent (for example, a file which -was ignored, or a file for which @code{Questionable} was sent), (2) -there is a file in the working directory whose name differs from the one -mentioned in @code{Created} in ways that the client is unable to use to -distinguish files. For example, the client is case-insensitive and the -names differ only in case. - -@item Update-existing @var{pathname} \n -This is just like @code{Updated} and takes the same additional data, but -is used only if a @code{Entry}, @code{Modified}, or @code{Unchanged} -request has been sent for the file in question. - -This response, or @code{Merged}, indicates that the server has -determined that it is OK to overwrite the previous contents of the file -specified by @var{pathname}. Provided that the client has correctly -sent @code{Modified} or @code{Is-modified} requests for a modified file, -and the file was not modified while CVS was running, the server can -ensure that a user's modifications are not lost. - -@item Merged @var{pathname} \n -This is just like @code{Updated} and takes the same additional data, -with the one difference that after the new copy of the file is enclosed, -it will still not be up to date. Used for the results of a merge, with -or without conflicts. - -It is useful to preserve an copy of what the file looked like before the -merge. This is basically handled by the server; before sending -@code{Merged} it will send a @code{Copy-file} response. For example, if -the file is @file{aa} and it derives from revision 1.3, the -@code{Copy-file} response will tell the client to copy @file{aa} to -@file{.#aa.1.3}. It is up to the client to decide how long to keep this -file around; traditionally clients have left it around forever, thus -letting the user clean it up as desired. But another answer, such as -until the next commit, might be preferable. - -@item Rcs-diff @var{pathname} \n -This is just like @code{Updated} and takes the same additional data, -with the one difference that instead of sending a new copy of the file, -the server sends an RCS change text. This change text is produced by -@samp{diff -n} (the GNU diff @samp{-a} option may also be used). The -client must apply this change text to the existing file. This will only -be used when the client has an exact copy of an earlier revision of a -file. This response is only used if the @code{update} command is given -the @samp{-u} argument. - -@item Patched @var{pathname} \n -This is just like @code{Rcs-diff} and takes the same additional data, -except that it sends a standard patch rather than an RCS change text. -The patch is produced by @samp{diff -c} for @sc{cvs} 1.6 and later (see -POSIX.2 for a description of this format), or @samp{diff -u} for -previous versions of @sc{cvs}; clients are encouraged to accept either -format. Like @code{Rcs-diff}, this response is only used if the -@code{update} command is given the @samp{-u} argument. - -The @code{Patched} response is deprecated in favor of the -@code{Rcs-diff} response. However, older clients (CVS 1.9 and earlier) -only support @code{Patched}. - -@item Mode @var{mode} \n -This @var{mode} applies to the next file mentioned in -@code{Checked-in}. @code{Mode} is a file update modifying response -as described in @ref{Response intro}. - -@item Mod-time @var{time} \n -Set the modification time of the next file sent to @var{time}. -@code{Mod-time} is a file update modifying response -as described in @ref{Response intro}. -The -@var{time} is in the format specified by RFC822 as modified by RFC1123. -The server may specify any timezone it chooses; clients will want to -convert that to their own timezone as appropriate. An example of this -format is: - -@example -26 May 1997 13:01:40 -0400 -@end example - -There is no requirement that the client and server clocks be -synchronized. The server just sends its recommendation for a timestamp -(based on its own clock, presumably), and the client should just believe -it (this means that the time might be in the future, for example). - -If the server does not send @code{Mod-time} for a given file, the client -should pick a modification time in the usual way (usually, just let the -operating system set the modification time to the time that the CVS -command is running). - -@item Checksum @var{checksum}\n -The @var{checksum} applies to the next file sent (that is, -@code{Checksum} is a file update modifying response -as described in @ref{Response intro}). -In the case of -@code{Patched}, the checksum applies to the file after being patched, -not to the patch itself. The client should compute the checksum itself, -after receiving the file or patch, and signal an error if the checksums -do not match. The checksum is the 128 bit MD5 checksum represented as -32 hex digits (MD5 is described in RFC1321). -This response is optional, and is only used if the -client supports it (as judged by the @code{Valid-responses} request). - -@item Copy-file @var{pathname} \n -Additional data: @var{newname} \n. Copy file @var{pathname} to -@var{newname} in the same directory where it already is. This does not -affect @code{CVS/Entries}. - -This can optionally be implemented as a rename instead of a copy. The -only use for it which currently has been identified is prior to a -@code{Merged} response as described under @code{Merged}. Clients can -probably assume that is how it is being used, if they want to worry -about things like how long to keep the @var{newname} file around. - -@item Removed @var{pathname} \n -The file has been removed from the repository (this is the case where -cvs prints @samp{file foobar.c is no longer pertinent}). - -@item Remove-entry @var{pathname} \n -The file needs its entry removed from @code{CVS/Entries}, but the file -itself is already gone (this happens in response to a @code{ci} request -which involves committing the removal of a file). - -@item Set-static-directory @var{pathname} \n -This instructs the client to set the @code{Entries.Static} flag, which -it should then send back to the server in a @code{Static-directory} -request whenever the directory is operated on. @var{pathname} ends in a -slash; its purpose is to specify a directory, not a file within a -directory. - -@item Clear-static-directory @var{pathname} \n -Like @code{Set-static-directory}, but clear, not set, the flag. - -@item Set-sticky @var{pathname} \n -Additional data: @var{tagspec} \n. Tell the client to set a sticky tag -or date, which should be supplied with the @code{Sticky} request for -future operations. @var{pathname} ends in a slash; its purpose is to -specify a directory, not a file within a directory. The client should -store @var{tagspec} and pass it back to the server as-is, to allow for -future expansion. The first character of @var{tagspec} is @samp{T} for -a tag, @samp{D} for a date, or something else for future expansion. The -remainder of @var{tagspec} contains the actual tag or date. - -@item Clear-sticky @var{pathname} \n -Clear any sticky tag or date set by @code{Set-sticky}. - -@item Template @var{pathname} \n -Additional data: file transmission (note: compressed file transmissions -are not supported). @var{pathname} ends in a slash; its purpose is to -specify a directory, not a file within a directory. Tell the client to -store the file transmission as the template log message, and then use -that template in the future when prompting the user for a log message. - -@item Notified @var{pathname} \n -Indicate to the client that the notification for @var{pathname} has been -done. There should be one such response for every @code{Notify} -request; if there are several @code{Notify} requests for a single file, -the requests should be processed in order; the first @code{Notified} -response pertains to the first @code{Notify} request, etc. - -@item Module-expansion @var{pathname} \n -Return a file or directory -which is included in a particular module. @var{pathname} is relative -to cvsroot, unlike most pathnames in responses. @var{pathname} should -be used to look and see whether some or all of the module exists on -the client side; it is not necessarily suitable for passing as an -argument to a @code{co} request (for example, if the modules file -contains the @samp{-d} option, it will be the directory specified with -@samp{-d}, not the name of the module). - -@item Wrapper-rcsOption @var{pattern} -k '@var{option}' \n -Transmit to the client a filename pattern which implies a certain -keyword expansion mode. The @var{pattern} is a wildcard pattern (for -example, @samp{*.exe}. The @var{option} is @samp{b} for binary, and so -on. Note that although the syntax happens to resemble the syntax in -certain CVS configuration files, it is more constrained; there must be -exactly one space between @var{pattern} and @samp{-k} and exactly one -space between @samp{-k} and @samp{'}, and no string is permitted in -place of @samp{-k} (extensions should be done with new responses, not by -extending this one, for graceful handling of @code{Valid-responses}). - -@item M @var{text} \n -A one-line message for the user. -Note that the format of @var{text} is not designed for machine parsing. -Although sometimes scripts and clients will have little choice, the -exact text which is output is subject to vary at the discretion of the -server and the example output given in this document is just that, -example output. Servers are encouraged to use the @samp{MT} response, -and future versions of this document will hopefully standardize more of -the @samp{MT} tags; see @ref{Text tags}. - -@item Mbinary \n -Additional data: file transmission (note: compressed file transmissions -are not supported). This is like @samp{M}, except the contents of the -file transmission are binary and should be copied to standard output -without translation to local text file conventions. To transmit a text -file to standard output, servers should use a series of @samp{M} requests. - -@item E @var{text} \n -Same as @code{M} but send to stderr not stdout. - -@item F \n -@c FIXME: The second sentence, defining "flush", is somewhat off the top -@c of my head. Is there some text we can steal from ANSI C or someplace -@c which is more carefully thought out? -Flush stderr. That is, make it possible for the user to see what has -been written to stderr (it is up to the implementation to decide exactly -how far it should go to ensure this). - -@item MT @var{tagname} @var{data} \n - -This response provides for tagged text. It is similar to -SGML/HTML/XML in that the data is structured and a naive application -can also make some sense of it without understanding the structure. -The syntax is not SGML-like, however, in order to fit into the CVS -protocol better and (more importantly) to make it easier to parse, -especially in a language like perl or awk. - -The @var{tagname} can have several forms. If it starts with @samp{a} -to @samp{z} or @samp{A} to @samp{Z}, then it represents tagged text. -If the implementation recognizes @var{tagname}, then it may interpret -@var{data} in some particular fashion. If the implementation does not -recognize @var{tagname}, then it should simply treat @var{data} as -text to be sent to the user (similar to an @samp{M} response). There -are two tags which are general purpose. The @samp{text} tag is -similar to an unrecognized tag in that it provides text which will -ordinarily be sent to the user. The @samp{newline} tag is used -without @var{data} and indicates that a newline will ordinarily be -sent to the user (there is no provision for embedding newlines in the -@var{data} of other tagged text responses). - -If @var{tagname} starts with @samp{+} it indicates a start tag and if -it starts with @samp{-} it indicates an end tag. The remainder of -@var{tagname} should be the same for matching start and end tags, and -tags should be nested (for example one could have tags in the -following order @code{+bold} @code{+italic} @code{text} @code{-italic} -@code{-bold} but not @code{+bold} @code{+italic} @code{text} -@code{-bold} @code{-italic}). A particular start and end tag may be -documented to constrain the tagged text responses which are valid -between them. - -Note that if @var{data} is present there will always be exactly one -space between @var{tagname} and @var{data}; if there is more than one -space, then the spaces beyond the first are part of @var{data}. - -Here is an example of some tagged text responses. Note that there is -a trailing space after @samp{Checking in} and @samp{initial revision:} -and there are two trailing spaces after @samp{<--}. Such trailing -spaces are, of course, part of @var{data}. - -@example -MT +checking-in -MT text Checking in -MT fname gz.tst -MT text ; -MT newline -MT rcsfile /home/kingdon/zwork/cvsroot/foo/gz.tst,v -MT text <-- -MT fname gz.tst -MT newline -MT text initial revision: -MT init-rev 1.1 -MT newline -MT text done -MT newline -MT -checking-in -@end example - -If the client does not support the @samp{MT} response, the same -responses might be sent as: - -@example -M Checking in gz.tst; -M /home/kingdon/zwork/cvsroot/foo/gz.tst,v <-- gz.tst -M initial revision: 1.1 -M done -@end example - -For a list of specific tags, see @ref{Text tags}. - -@item error @var{errno-code} @samp{ } @var{text} \n -The command completed with an error. @var{errno-code} is a symbolic -error code (e.g. @code{ENOENT}); if the server doesn't support this -feature, or if it's not appropriate for this particular message, it just -omits the errno-code (in that case there are two spaces after -@samp{error}). Text is an error message such as that provided by -strerror(), or any other message the server wants to use. -The @var{text} is like the @code{M} response, in the sense that it is -not particularly intended to be machine-parsed; servers may wish to -print an error message with @code{MT} responses, and then issue a -@code{error} response without @var{text} (although it should be noted -that @code{MT} currently has no way of flagging the output as intended -for standard error, the way that the @code{E} response does). - -@item ok \n -The command completed successfully. -@end table - -@node Text tags -@section Tags for the MT tagged text response - -The @code{MT} response, as described in @ref{Responses}, offers a -way for the server to send tagged text to the client. This section -describes specific tags. The intention is to update this section as -servers add new tags. - -In the following descriptions, @code{text} and @code{newline} tags are -omitted. Such tags contain information which is intended for users (or -to be discarded), and are subject to change at the whim of the server. -To avoid being vulnerable to such whim, clients should look for the tags -listed here, not @code{text}, @code{newline}, or other tags. - -The following tag means to indicate to the user that a file has been -updated. It is more or less redundant with the @code{Created} and -@code{Update-existing} responses, but we don't try to specify here -whether it occurs in exactly the same circumstances as @code{Created} -and @code{Update-existing}. The @var{name} is the pathname of the file -being updated relative to the directory in which the command is -occurring (that is, the last @code{Directory} request which is sent -before the command). - -@example -MT +updated -MT fname @var{name} -MT -updated -@end example - -The @code{importmergecmd} tag is used when doing an import which has -conflicts. The client can use it to report how to merge in the newly -imported changes. The @var{count} is the number of conflicts. The -newly imported changes can be merged by running the following command: -@smallexample -cvs checkout -j @var{tag1} -j @var{tag2} @var{repository} -@end smallexample - -@example -MT +importmergecmd -MT conflicts @var{count} -MT mergetag1 @var{tag1} -MT mergetag2 @var{tag2} -MT repository @var{repository} -MT -importmergecmd -@end example - -@node Example -@section Example - -@c The C:/S: convention is in imitation of RFC1869 (and presumably -@c other RFC's). In other formatting concerns, we might want to think -@c about whether there is an easy way to provide RFC1543 formatting -@c (without negating the advantages of texinfo), and whether we should -@c use RFC2234 BNF (I fear that would be less clear than -@c what we do now, however). Plus what about RFC2119 terminology (MUST, -@c SHOULD, &c) or ISO terminology (shall, should, or whatever they are)? -Here is an example; lines are prefixed by @samp{C: } to indicate the -client sends them or @samp{S: } to indicate the server sends them. - -The client starts by connecting, sending the root, and completing the -protocol negotiation. In actual practice the lists of valid responses -and requests would be longer. -@c The reason that we artificially shorten the lists is to avoid phony -@c line breaks. Any better solutions? -@c Other than that, this exchange is taken verbatim from the data -@c exchanged by CVS (as of Nov 1996). That is why some of the requests and -@c responses are not quite what you would pick for pedagogical purposes. - -@example -C: Root /u/cvsroot -C: Valid-responses ok error Checked-in M E -C: valid-requests -S: Valid-requests Root Directory Entry Modified Argument Argumentx ci co -S: ok -C: UseUnchanged -@end example - -The client wants to check out the @code{supermunger} module into a fresh -working directory. Therefore it first expands the @code{supermunger} -module; this step would be omitted if the client was operating on a -directory rather than a module. -@c Why does it send Directory here? The description of expand-modules -@c doesn't really say much of anything about what use, if any, it makes of -@c Directory and similar requests sent previously. - -@example -C: Argument supermunger -C: Directory . -C: /u/cvsroot -C: expand-modules -@end example - -The server replies that the @code{supermunger} module expands to the -directory @code{supermunger} (the simplest case): - -@example -S: Module-expansion supermunger -S: ok -@end example - -The client then proceeds to check out the directory. The fact that it -sends only a single @code{Directory} request which specifies @samp{.} -for the working directory means that there is not already a -@code{supermunger} directory on the client. -@c What is -N doing here? - -@example -C: Argument -N -C: Argument supermunger -C: Directory . -C: /u/cvsroot -C: co -@end example - -The server replies with the requested files. In this example, there is -only one file, @file{mungeall.c}. The @code{Clear-sticky} and -@code{Clear-static-directory} requests are sent by the current -implementation but they have no effect because the default is for those -settings to be clear when a directory is newly created. - -@example -S: Clear-sticky supermunger/ -S: /u/cvsroot/supermunger/ -S: Clear-static-directory supermunger/ -S: /u/cvsroot/supermunger/ -S: E cvs server: Updating supermunger -S: M U supermunger/mungeall.c -S: Created supermunger/ -S: /u/cvsroot/supermunger/mungeall.c -S: /mungeall.c/1.1/// -S: u=rw,g=r,o=r -S: 26 -S: int mein () @{ abort (); @} -S: ok -@end example - -The current client implementation would break the connection here and make a -new connection for the next command. However, the protocol allows it -to keep the connection open and continue, which is what we show here. - -After the user modifies the file and instructs the client to check it -back in. The client sends arguments to specify the log message and file -to check in: - -@example -C: Argument -m -C: Argument Well, you see, it took me hours and hours to find -C: Argumentx this typo and I searched and searched and eventually -C: Argumentx had to ask John for help. -C: Argument mungeall.c -@end example - -It also sends information about the contents of the working directory, -including the new contents of the modified file. Note that the user has -changed into the @file{supermunger} directory before executing this -command; the top level directory is a user-visible concept because the -server should print filenames in @code{M} and @code{E} responses -relative to that directory. -@c We are waving our hands about the order of the requests. "Directory" -@c and "Argument" can be in any order, but this probably isn't specified -@c very well. - -@example -C: Directory . -C: /u/cvsroot/supermunger -C: Entry /mungeall.c/1.1/// -C: Modified mungeall.c -C: u=rw,g=r,o=r -C: 26 -C: int main () @{ abort (); @} -@end example - -And finally, the client issues the checkin command (which makes use of -the data just sent): - -@example -C: ci -@end example - -And the server tells the client that the checkin succeeded: - -@example -S: M Checking in mungeall.c; -S: E /u/cvsroot/supermunger/mungeall.c,v <-- mungeall.c -S: E new revision: 1.2; previous revision: 1.1 -S: E done -S: Mode u=rw,g=r,o=r -S: Checked-in ./ -S: /u/cvsroot/supermunger/mungeall.c -S: /mungeall.c/1.2/// -S: ok -@end example - -@node Requirements -@section Required versus optional parts of the protocol - -The following are part of every known implementation of the CVS protocol -(except obsolete, pre-1.5, versions of CVS) and it is considered -reasonable behavior to completely fail to work if you are connected with -an implementation which attempts to not support them. Requests: -@code{Root}, @code{Valid-responses}, @code{valid-requests}, -@code{Directory}, @code{Entry}, @code{Modified}, @code{Unchanged}, -@code{Argument}, @code{Argumentx}, @code{ci}, @code{co}, @code{update}. -Responses: @code{ok}, @code{error}, @code{Valid-requests}, -@code{Checked-in}, @code{Updated}, @code{Merged}, @code{Removed}, -@code{M}, @code{E}. - -A server need not implement @code{Repository}, but in order to interoperate -with CVS 1.5 through 1.9 it must claim to implement it (in -@code{Valid-requests}). The client will not actually send the request. - -@node Obsolete -@section Obsolete protocol elements - -This section briefly describes protocol elements which are obsolete. -There is no attempt to document them in full detail. - -There was a @code{Repository} request which was like @code{Directory} -except it only provided @var{repository}, and the local directory was -assumed to be similarly named. - -If the @code{UseUnchanged} request was not sent, there was a @code{Lost} -request which was sent to indicate that a file did not exist in the -working directory, and the meaning of sending @code{Entries} without -@code{Lost} or @code{Modified} was different. All current clients (CVS -1.5 and later) will send @code{UseUnchanged} if it is supported. - -@node Protocol Notes -@chapter Notes on the Protocol - -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://cvs.nongnu.org} site, in particular the -@cite{Development} pages. - -@itemize @bullet -@item -The @code{Modified} request could be sped up by sending diffs rather -than entire files. The client would need some way to keep the version -of the file which was originally checked out; probably requiring the use -of "cvs edit" in this case is the most sensible course (the "cvs edit" -could be handled by a package like VC for emacs). This would also allow -local operation of @code{cvs diff} without arguments. - -@item -The fact that @code{pserver} requires an extra network turnaround in -order to perform authentication would be nice to avoid. This relates to -the issue of reporting errors; probably the clean solution is to defer -the error until the client has issued a request which expects a -response. To some extent this might relate to the next item (in terms -of how easy it is to skip a whole bunch of requests until we get to one -that expects a response). I know that the kerberos code doesn't wait in -this fashion, but that probably can cause network deadlocks and perhaps -future problems running over a transport which is more transaction -oriented than TCP. On the other hand I'm not sure it is wise to make -the client conduct a lengthy upload only to find there is an -authentication failure. - -@item -The protocol uses an extra network turnaround for protocol negotiation -(@code{valid-requests}). It might be nice to avoid this by having the -client be able to send requests and tell the server to ignore them if -they are unrecognized (different requests could produce a fatal error if -unrecognized). To do this there should be a standard syntax for -requests. For example, perhaps all future requests should be a single -line, with mechanisms analogous to @code{Argumentx}, or several requests -working together, to provide greater amounts of information. Or there -might be a standard mechanism for counted data (analogous to that used -by @code{Modified}) or continuation lines (like a generalized -@code{Argumentx}). It would be useful to compare what HTTP is planning -in this area; last I looked they were contemplating something called -Protocol Extension Protocol but I haven't looked at the relevant IETF -documents in any detail. Obviously, we want something as simple as -possible (but no simpler). - -@item -The scrambling algorithm in the CVS client and server actually support -more characters than those documented in @ref{Password scrambling}. -Someday we are going to either have to document them all (but this is -not as easy as it may look, see below), or (gradually and with adequate -process) phase out the support for other characters in the CVS -implementation. This business of having the feature partly undocumented -isn't a desirable state long-term. - -The problem with documenting other characters is that unless we know -what character set is in use, there is no way to make a password -portable from one system to another. For example, a with a circle on -top might have different encodings in different character sets. - -It @emph{almost} works to say that the client picks an arbitrary, -unknown character set (indeed, having the CVS client know what character -set the user has in mind is a hard problem otherwise), and scrambles -according to a certain octet<->octet mapping. There are two problems -with this. One is that the protocol has no way to transmit character 10 -decimal (linefeed), and the current server and clients have no way to -handle 0 decimal (NUL). This may cause problems with certain multibyte -character sets, in which octets 10 and 0 will appear in the middle of -other characters. The other problem, which is more minor and possibly -not worth worrying about, is that someone can type a password on one -system and then go to another system which uses a different encoding for -the same characters, and have their password not work. - -The restriction to the ISO646 invariant subset is the best approach for -strings which are not particularly significant to users. Passwords are -visible enough that this is somewhat doubtful as applied here. ISO646 -does, however, have the virtue (!?) of offending everyone. It is easy -to say "But the $ is right on people's keyboards! Surely we can't -forbid that". From a human factors point of view, that makes quite a -bit of sense. The contrary argument, of course, is that a with a circle -on top, or some of the characters poorly handled by Unicode, are on -@emph{someone}'s keyboard. - -@end itemize - -@bye diff --git a/contrib/cvs/doc/mdate-sh b/contrib/cvs/doc/mdate-sh deleted file mode 100755 index cd916c0..0000000 --- a/contrib/cvs/doc/mdate-sh +++ /dev/null @@ -1,201 +0,0 @@ -#!/bin/sh -# Get modification time of a file or directory and pretty-print it. - -scriptversion=2005-06-29.22 - -# Copyright (C) 1995, 1996, 1997, 2003, 2004, 2005 Free Software -# Foundation, Inc. -# written by Ulrich Drepper , June 1995 -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - -# This file is maintained in Automake, please report -# bugs to or send patches to -# . - -case $1 in - '') - echo "$0: No file. Try \`$0 --help' for more information." 1>&2 - exit 1; - ;; - -h | --h*) - cat <<\EOF -Usage: mdate-sh [--help] [--version] FILE - -Pretty-print the modification time of FILE. - -Report bugs to . -EOF - exit $? - ;; - -v | --v*) - echo "mdate-sh $scriptversion" - exit $? - ;; -esac - -# Prevent date giving response in another language. -LANG=C -export LANG -LC_ALL=C -export LC_ALL -LC_TIME=C -export LC_TIME - -# GNU ls changes its time format in response to the TIME_STYLE -# variable. Since we cannot assume `unset' works, revert this -# variable to its documented default. -if test "${TIME_STYLE+set}" = set; then - TIME_STYLE=posix-long-iso - export TIME_STYLE -fi - -save_arg1=$1 - -# Find out how to get the extended ls output of a file or directory. -if ls -L /dev/null 1>/dev/null 2>&1; then - ls_command='ls -L -l -d' -else - ls_command='ls -l -d' -fi - -# A `ls -l' line looks as follows on OS/2. -# drwxrwx--- 0 Aug 11 2001 foo -# This differs from Unix, which adds ownership information. -# drwxrwx--- 2 root root 4096 Aug 11 2001 foo -# -# To find the date, we split the line on spaces and iterate on words -# until we find a month. This cannot work with files whose owner is a -# user named `Jan', or `Feb', etc. However, it's unlikely that `/' -# will be owned by a user whose name is a month. So we first look at -# the extended ls output of the root directory to decide how many -# words should be skipped to get the date. - -# On HPUX /bin/sh, "set" interprets "-rw-r--r--" as options, so the "x" below. -set x`ls -l -d /` - -# Find which argument is the month. -month= -command= -until test $month -do - shift - # Add another shift to the command. - command="$command shift;" - case $1 in - Jan) month=January; nummonth=1;; - Feb) month=February; nummonth=2;; - Mar) month=March; nummonth=3;; - Apr) month=April; nummonth=4;; - May) month=May; nummonth=5;; - Jun) month=June; nummonth=6;; - Jul) month=July; nummonth=7;; - Aug) month=August; nummonth=8;; - Sep) month=September; nummonth=9;; - Oct) month=October; nummonth=10;; - Nov) month=November; nummonth=11;; - Dec) month=December; nummonth=12;; - esac -done - -# Get the extended ls output of the file or directory. -set dummy x`eval "$ls_command \"\$save_arg1\""` - -# Remove all preceding arguments -eval $command - -# Because of the dummy argument above, month is in $2. -# -# On a POSIX system, we should have -# -# $# = 5 -# $1 = file size -# $2 = month -# $3 = day -# $4 = year or time -# $5 = filename -# -# On Darwin 7.7.0 and 7.6.0, we have -# -# $# = 4 -# $1 = day -# $2 = month -# $3 = year or time -# $4 = filename - -# Get the month. -case $2 in - Jan) month=January; nummonth=1;; - Feb) month=February; nummonth=2;; - Mar) month=March; nummonth=3;; - Apr) month=April; nummonth=4;; - May) month=May; nummonth=5;; - Jun) month=June; nummonth=6;; - Jul) month=July; nummonth=7;; - Aug) month=August; nummonth=8;; - Sep) month=September; nummonth=9;; - Oct) month=October; nummonth=10;; - Nov) month=November; nummonth=11;; - Dec) month=December; nummonth=12;; -esac - -case $3 in - ???*) day=$1;; - *) day=$3; shift;; -esac - -# Here we have to deal with the problem that the ls output gives either -# the time of day or the year. -case $3 in - *:*) set `date`; eval year=\$$# - case $2 in - Jan) nummonthtod=1;; - Feb) nummonthtod=2;; - Mar) nummonthtod=3;; - Apr) nummonthtod=4;; - May) nummonthtod=5;; - Jun) nummonthtod=6;; - Jul) nummonthtod=7;; - Aug) nummonthtod=8;; - Sep) nummonthtod=9;; - Oct) nummonthtod=10;; - Nov) nummonthtod=11;; - Dec) nummonthtod=12;; - esac - # For the first six month of the year the time notation can also - # be used for files modified in the last year. - if (expr $nummonth \> $nummonthtod) > /dev/null; - then - year=`expr $year - 1` - fi;; - *) year=$3;; -esac - -# The result. -echo $day $month $year - -# Local Variables: -# mode: shell-script -# sh-indentation: 2 -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "scriptversion=" -# time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-end: "$" -# End: diff --git a/contrib/cvs/doc/mkman.pl b/contrib/cvs/doc/mkman.pl deleted file mode 100644 index de0d298..0000000 --- a/contrib/cvs/doc/mkman.pl +++ /dev/null @@ -1,372 +0,0 @@ -#! @PERL@ -# -# Generate a man page from sections of a Texinfo manual. -# -# Copyright 2004, 2006 -# The Free Software Foundation, -# Derek R. Price, -# & Ximbiot -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - - - -# Need Perl 5.005 or greater for re 'eval'. -require 5.005; - -# The usual. -use strict; -use IO::File; - - - -### -### GLOBALS -### -my $texi_num = 0; # Keep track of how many texinfo files have been encountered. -my @parent; # This needs to be global to be used inside of a regex later. -my $nk; # Ditto. -my $ret; # The RE match Type, used in debug prints. -my $debug = 0; # Debug mode? - - - -### -### FUNCTIONS -### -sub debug_print -{ - print @_ if $debug; -} - - - -sub keyword_mode -{ - my ($keyword, $file) = @_; - - return "\\fR" - if $keyword =~ /^(|r|t)$/; - return "\\fB" - if $keyword =~ /^(strong|sc|code|file|samp)$/; - return "\\fI" - if $keyword =~ /^(emph|var|dfn)$/; - die "no handler for keyword \`$keyword', found at line $. of file \`$file'\n"; -} - - - -# Return replacement for \@$keyword{$content}. -sub do_keyword -{ - my ($file, $parent, $keyword, $content) = @_; - - return "`$content\\(aq in the CVS manual" - if $keyword eq "ref"; - return "see node `$content\\(aq in the CVS manual" - if $keyword =~ /^p?xref$/; - return "\\fP\\fP$content" - if $keyword =~ /^splitrcskeyword$/; - - my $endmode = keyword_mode $parent; - my $startmode = keyword_mode $keyword, $file; - - return "$startmode$content$endmode"; -} - - - -### -### MAIN -### -for my $file (@ARGV) -{ - my $fh = new IO::File "< $file" - or die "Failed to open file \`$file': $!"; - - if ($file !~ /\.(texinfo|texi|txi)$/) - { - print stderr "Passing \`$file' through unprocessed.\n"; - # Just cat any file that doesn't look like a Texinfo source. - while (my $line = $fh->getline) - { - print $line; - } - next; - } - - print stderr "Processing \`$file'.\n"; - $texi_num++; - my $gotone = 0; - my $inblank = 0; - my $indent = 0; - my $inexample = 0; - my $inmenu = 0; - my $intable = 0; - my $last_header = ""; - my @table_headers; - my @table_footers; - my $table_header = ""; - my $table_footer = ""; - my $last; - while ($_ = $fh->getline) - { - if (!$gotone && /^\@c ----- START MAN $texi_num -----$/) - { - $gotone = 1; - next; - } - - # Skip ahead until our man section. - next unless $gotone; - - # If we find the end tag we are done. - last if /^\@c ----- END MAN $texi_num -----$/; - - # Need to do this everywhere. i.e., before we print example - # lines, since literal back slashes can appear there too. - s/\\/\\\\/g; - s/^\./\\&./; - s/([\s])\./$1\\&./; - s/'/\\(aq/g; - s/`/\\`/g; - s/(? - [^{}]|(?<=\@)[{}] # Non-braces... - | # ...or... - (??{ $nk }) # ...nested keywords... - )*) # ...without backtracking. - \} - (?{ debug_print "$ret MATCHED $&\nPOPPING ", - pop (@parent), "\n"; }) # Lose track of the current keyword. - /x; - - $ret = "m//"; - if (/\@\w+\{(?:[^{}]|(?<=\@)[{}]|(??{ $nk }))*$/) - { - # If there is an opening keyword on this line without a - # close bracket, we need to find the close bracket - # before processing the line. Set $last to append the - # next line in the next pass. - $last = $_; - next; - } - - # Okay, the following works somewhat counter-intuitively. $nk - # processes the whole line, so @parent gets loaded properly, - # then, since no closing brackets have been found for the - # outermost matches, the innermost matches match and get - # replaced first. - # - # For example: - # - # Processing the line: - # - # yadda yadda @code{yadda @var{foo} yadda @var{bar} yadda} - # - # Happens something like this: - # - # 1. Ignores "yadda yadda " - # 2. Sees "@code{" and pushes "code" onto @parent. - # 3. Ignores "yadda " (backtracks and ignores "yadda yadda - # @code{yadda "?) - # 4. Sees "@var{" and pushes "var" onto @parent. - # 5. Sees "foo}", pops "var", and realizes that "@var{foo}" - # matches the overall pattern ($nk). - # 6. Replaces "@var{foo}" with the result of: - # - # do_keyword $file, $parent[$#parent], $1, $2; - # - # which would be "\Ifoo\B", in this case, because "var" - # signals a request for italics, or "\I", and "code" is - # still on the stack, which means the previous style was - # bold, or "\B". - # - # Then the while loop restarts and a similar series of events - # replaces "@var{bar}" with "\Ibar\B". - # - # Then the while loop restarts and a similar series of events - # replaces "@code{yadda \Ifoo\B yadda \Ibar\B yadda}" with - # "\Byadda \Ifoo\B yadda \Ibar\B yadda\R". - # - $ret = "s///"; - @parent = (""); - while (s/$nk/do_keyword $file, $parent[$#parent], $1, $2/e) - { - # Do nothing except reset our last-replacement - # tracker - the replacement regex above is handling - # everything else. - debug_print "FINAL MATCH $&\n"; - @parent = (""); - } - - # Finally, unprotect texinfo special characters. - s/\@://g; - s/\@([{}])/$1/g; - - # Verify we haven't left commands unprocessed. - die "Unprocessed command at line $. of file \`$file': " - . ($1 ? "$1\n" : "\n") - if /^(?>(?:[^\@]|\@\@)*)\@(\w+|.|$)/; - - # Unprotect @@. - s/\@\@/\@/g; - - # And print whatever's left. - print $_; - } -} diff --git a/contrib/cvs/doc/stamp-1 b/contrib/cvs/doc/stamp-1 deleted file mode 100644 index b17c01c..0000000 --- a/contrib/cvs/doc/stamp-1 +++ /dev/null @@ -1,4 +0,0 @@ -@set UPDATED 7 May 2007 -@set UPDATED-MONTH May 2007 -@set EDITION 1.11.22.1 -@set VERSION 1.11.22.1 diff --git a/contrib/cvs/doc/stamp-vti b/contrib/cvs/doc/stamp-vti deleted file mode 100644 index 05bc349..0000000 --- a/contrib/cvs/doc/stamp-vti +++ /dev/null @@ -1,4 +0,0 @@ -@set UPDATED 27 January 2008 -@set UPDATED-MONTH January 2008 -@set EDITION 1.11.22.1 -@set VERSION 1.11.22.1 diff --git a/contrib/cvs/doc/version-client.texi b/contrib/cvs/doc/version-client.texi deleted file mode 100644 index b17c01c..0000000 --- a/contrib/cvs/doc/version-client.texi +++ /dev/null @@ -1,4 +0,0 @@ -@set UPDATED 7 May 2007 -@set UPDATED-MONTH May 2007 -@set EDITION 1.11.22.1 -@set VERSION 1.11.22.1 diff --git a/contrib/cvs/doc/version.texi b/contrib/cvs/doc/version.texi deleted file mode 100644 index 05bc349..0000000 --- a/contrib/cvs/doc/version.texi +++ /dev/null @@ -1,4 +0,0 @@ -@set UPDATED 27 January 2008 -@set UPDATED-MONTH January 2008 -@set EDITION 1.11.22.1 -@set VERSION 1.11.22.1 diff --git a/contrib/cvs/install-sh b/contrib/cvs/install-sh deleted file mode 100755 index 4fbbae7..0000000 --- a/contrib/cvs/install-sh +++ /dev/null @@ -1,507 +0,0 @@ -#!/bin/sh -# install - install a program, script, or datafile - -scriptversion=2006-10-14.15 - -# This originates from X11R5 (mit/util/scripts/install.sh), which was -# later released in X11R6 (xc/config/util/install.sh) with the -# following copyright and license. -# -# Copyright (C) 1994 X Consortium -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to -# deal in the Software without restriction, including without limitation the -# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -# sell copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN -# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- -# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# -# Except as contained in this notice, the name of the X Consortium shall not -# be used in advertising or otherwise to promote the sale, use or other deal- -# ings in this Software without prior written authorization from the X Consor- -# tium. -# -# -# FSF changes to this file are in the public domain. -# -# Calling this script install-sh is preferred over install.sh, to prevent -# `make' implicit rules from creating a file called install from it -# when there is no Makefile. -# -# This script is compatible with the BSD install script, but was written -# from scratch. - -nl=' -' -IFS=" "" $nl" - -# set DOITPROG to echo to test this script - -# Don't use :- since 4.3BSD and earlier shells don't like it. -doit="${DOITPROG-}" -if test -z "$doit"; then - doit_exec=exec -else - doit_exec=$doit -fi - -# Put in absolute file names if you don't have them in your path; -# or use environment vars. - -mvprog="${MVPROG-mv}" -cpprog="${CPPROG-cp}" -chmodprog="${CHMODPROG-chmod}" -chownprog="${CHOWNPROG-chown}" -chgrpprog="${CHGRPPROG-chgrp}" -stripprog="${STRIPPROG-strip}" -rmprog="${RMPROG-rm}" -mkdirprog="${MKDIRPROG-mkdir}" - -posix_glob= -posix_mkdir= - -# Desired mode of installed file. -mode=0755 - -chmodcmd=$chmodprog -chowncmd= -chgrpcmd= -stripcmd= -rmcmd="$rmprog -f" -mvcmd="$mvprog" -src= -dst= -dir_arg= -dstarg= -no_target_directory= - -usage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE - or: $0 [OPTION]... SRCFILES... DIRECTORY - or: $0 [OPTION]... -t DIRECTORY SRCFILES... - or: $0 [OPTION]... -d DIRECTORIES... - -In the 1st form, copy SRCFILE to DSTFILE. -In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. -In the 4th, create DIRECTORIES. - -Options: --c (ignored) --d create directories instead of installing files. --g GROUP $chgrpprog installed files to GROUP. --m MODE $chmodprog installed files to MODE. --o USER $chownprog installed files to USER. --s $stripprog installed files. --t DIRECTORY install into DIRECTORY. --T report an error if DSTFILE is a directory. ---help display this help and exit. ---version display version info and exit. - -Environment variables override the default commands: - CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG -" - -while test $# -ne 0; do - case $1 in - -c) shift - continue;; - - -d) dir_arg=true - shift - continue;; - - -g) chgrpcmd="$chgrpprog $2" - shift - shift - continue;; - - --help) echo "$usage"; exit $?;; - - -m) mode=$2 - shift - shift - case $mode in - *' '* | *' '* | *' -'* | *'*'* | *'?'* | *'['*) - echo "$0: invalid mode: $mode" >&2 - exit 1;; - esac - continue;; - - -o) chowncmd="$chownprog $2" - shift - shift - continue;; - - -s) stripcmd=$stripprog - shift - continue;; - - -t) dstarg=$2 - shift - shift - continue;; - - -T) no_target_directory=true - shift - continue;; - - --version) echo "$0 $scriptversion"; exit $?;; - - --) shift - break;; - - -*) echo "$0: invalid option: $1" >&2 - exit 1;; - - *) break;; - esac -done - -if test $# -ne 0 && test -z "$dir_arg$dstarg"; then - # When -d is used, all remaining arguments are directories to create. - # When -t is used, the destination is already specified. - # Otherwise, the last argument is the destination. Remove it from $@. - for arg - do - if test -n "$dstarg"; then - # $@ is not empty: it contains at least $arg. - set fnord "$@" "$dstarg" - shift # fnord - fi - shift # arg - dstarg=$arg - done -fi - -if test $# -eq 0; then - if test -z "$dir_arg"; then - echo "$0: no input file specified." >&2 - exit 1 - fi - # It's OK to call `install-sh -d' without argument. - # This can happen when creating conditional directories. - exit 0 -fi - -if test -z "$dir_arg"; then - trap '(exit $?); exit' 1 2 13 15 - - # Set umask so as not to create temps with too-generous modes. - # However, 'strip' requires both read and write access to temps. - case $mode in - # Optimize common cases. - *644) cp_umask=133;; - *755) cp_umask=22;; - - *[0-7]) - if test -z "$stripcmd"; then - u_plus_rw= - else - u_plus_rw='% 200' - fi - cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; - *) - if test -z "$stripcmd"; then - u_plus_rw= - else - u_plus_rw=,u+rw - fi - cp_umask=$mode$u_plus_rw;; - esac -fi - -for src -do - # Protect names starting with `-'. - case $src in - -*) src=./$src ;; - esac - - if test -n "$dir_arg"; then - dst=$src - dstdir=$dst - test -d "$dstdir" - dstdir_status=$? - else - - # Waiting for this to be detected by the "$cpprog $src $dsttmp" command - # might cause directories to be created, which would be especially bad - # if $src (and thus $dsttmp) contains '*'. - if test ! -f "$src" && test ! -d "$src"; then - echo "$0: $src does not exist." >&2 - exit 1 - fi - - if test -z "$dstarg"; then - echo "$0: no destination specified." >&2 - exit 1 - fi - - dst=$dstarg - # Protect names starting with `-'. - case $dst in - -*) dst=./$dst ;; - esac - - # If destination is a directory, append the input filename; won't work - # if double slashes aren't ignored. - if test -d "$dst"; then - if test -n "$no_target_directory"; then - echo "$0: $dstarg: Is a directory" >&2 - exit 1 - fi - dstdir=$dst - dst=$dstdir/`basename "$src"` - dstdir_status=0 - else - # Prefer dirname, but fall back on a substitute if dirname fails. - dstdir=` - (dirname "$dst") 2>/dev/null || - expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$dst" : 'X\(//\)[^/]' \| \ - X"$dst" : 'X\(//\)$' \| \ - X"$dst" : 'X\(/\)' \| . 2>/dev/null || - echo X"$dst" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q' - ` - - test -d "$dstdir" - dstdir_status=$? - fi - fi - - obsolete_mkdir_used=false - - if test $dstdir_status != 0; then - case $posix_mkdir in - '') - # Create intermediate dirs using mode 755 as modified by the umask. - # This is like FreeBSD 'install' as of 1997-10-28. - umask=`umask` - case $stripcmd.$umask in - # Optimize common cases. - *[2367][2367]) mkdir_umask=$umask;; - .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; - - *[0-7]) - mkdir_umask=`expr $umask + 22 \ - - $umask % 100 % 40 + $umask % 20 \ - - $umask % 10 % 4 + $umask % 2 - `;; - *) mkdir_umask=$umask,go-w;; - esac - - # With -d, create the new directory with the user-specified mode. - # Otherwise, rely on $mkdir_umask. - if test -n "$dir_arg"; then - mkdir_mode=-m$mode - else - mkdir_mode= - fi - - posix_mkdir=false - case $umask in - *[123567][0-7][0-7]) - # POSIX mkdir -p sets u+wx bits regardless of umask, which - # is incompatible with FreeBSD 'install' when (umask & 300) != 0. - ;; - *) - tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ - trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 - - if (umask $mkdir_umask && - exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 - then - if test -z "$dir_arg" || { - # Check for POSIX incompatibilities with -m. - # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or - # other-writeable bit of parent directory when it shouldn't. - # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. - ls_ld_tmpdir=`ls -ld "$tmpdir"` - case $ls_ld_tmpdir in - d????-?r-*) different_mode=700;; - d????-?--*) different_mode=755;; - *) false;; - esac && - $mkdirprog -m$different_mode -p -- "$tmpdir" && { - ls_ld_tmpdir_1=`ls -ld "$tmpdir"` - test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" - } - } - then posix_mkdir=: - fi - rmdir "$tmpdir/d" "$tmpdir" - else - # Remove any dirs left behind by ancient mkdir implementations. - rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null - fi - trap '' 0;; - esac;; - esac - - if - $posix_mkdir && ( - umask $mkdir_umask && - $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" - ) - then : - else - - # The umask is ridiculous, or mkdir does not conform to POSIX, - # or it failed possibly due to a race condition. Create the - # directory the slow way, step by step, checking for races as we go. - - case $dstdir in - /*) prefix=/ ;; - -*) prefix=./ ;; - *) prefix= ;; - esac - - case $posix_glob in - '') - if (set -f) 2>/dev/null; then - posix_glob=true - else - posix_glob=false - fi ;; - esac - - oIFS=$IFS - IFS=/ - $posix_glob && set -f - set fnord $dstdir - shift - $posix_glob && set +f - IFS=$oIFS - - prefixes= - - for d - do - test -z "$d" && continue - - prefix=$prefix$d - if test -d "$prefix"; then - prefixes= - else - if $posix_mkdir; then - (umask=$mkdir_umask && - $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break - # Don't fail if two instances are running concurrently. - test -d "$prefix" || exit 1 - else - case $prefix in - *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; - *) qprefix=$prefix;; - esac - prefixes="$prefixes '$qprefix'" - fi - fi - prefix=$prefix/ - done - - if test -n "$prefixes"; then - # Don't fail if two instances are running concurrently. - (umask $mkdir_umask && - eval "\$doit_exec \$mkdirprog $prefixes") || - test -d "$dstdir" || exit 1 - obsolete_mkdir_used=true - fi - fi - fi - - if test -n "$dir_arg"; then - { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && - { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && - { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || - test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 - else - - # Make a couple of temp file names in the proper directory. - dsttmp=$dstdir/_inst.$$_ - rmtmp=$dstdir/_rm.$$_ - - # Trap to clean up those temp files at exit. - trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 - - # Copy the file name to the temp name. - (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && - - # and set any options; do chmod last to preserve setuid bits. - # - # If any of these fail, we abort the whole thing. If we want to - # ignore errors from any of these, just make sure not to ignore - # errors from the above "$doit $cpprog $src $dsttmp" command. - # - { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \ - && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \ - && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \ - && { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && - - # Now rename the file to the real destination. - { $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null \ - || { - # The rename failed, perhaps because mv can't rename something else - # to itself, or perhaps because mv is so ancient that it does not - # support -f. - - # Now remove or move aside any old file at destination location. - # We try this two ways since rm can't unlink itself on some - # systems and the destination file might be busy for other - # reasons. In this case, the final cleanup might fail but the new - # file should still install successfully. - { - if test -f "$dst"; then - $doit $rmcmd -f "$dst" 2>/dev/null \ - || { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null \ - && { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }; }\ - || { - echo "$0: cannot unlink or rename $dst" >&2 - (exit 1); exit 1 - } - else - : - fi - } && - - # Now rename the file to the real destination. - $doit $mvcmd "$dsttmp" "$dst" - } - } || exit 1 - - trap '' 0 - fi -done - -# Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "scriptversion=" -# time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-end: "$" -# End: diff --git a/contrib/cvs/lib/ChangeLog b/contrib/cvs/lib/ChangeLog deleted file mode 100644 index c8e2d46..0000000 --- a/contrib/cvs/lib/ChangeLog +++ /dev/null @@ -1,1161 +0,0 @@ -2006-06-23 Larry Jones - - * xsize.h: Avoid SGI problem with being unusable in C89 - mode. - -2005-11-14 Mark D. Baushke - - * system.h (FOLD_FN_CHAR): Distinguish OSX_ and VMS_ variations - based on USE_VMS_FILENAME macro. - -2005-11-09 Mark D. Baushke - - * system.h (FOLD_FN_CHAR): Create a VMS alternative of this macro - (patch suggested by Piet Schuermans ). - -2005-07-11 Mark D. Baushke - - * getpass.c (getpass): Add a K&R style function definition. - -2005-04-15 Derek Price - - * Makefile.am (EXTRA_DIST): Add test-getdate.sh. - -2005-03-23 Derek Price - - * Makefile.am (TESTS, MOSTLYCLEANFILES, check_PROGRAMS, EXTRA_DIST, - getdate_SOURCES, getdate_CPPFLAGS): Add getdate testing cruft. - * test-getdate.sh: New file. - * .cvsignore: Ignore getdate executable. - -2005-03-23 Larry Jones - - * getdate.c: Remove absolute paths from #line directives. - -2005-03-04 Jim Hyslop - - * xtime.h: added include guards to fix compile errors on IRIX 5.3 - (Patch from Georg Schwarz .) - -2005-02-08 Derek Price - - * fncase.c (OSX_filename_classes): Mac OSX doesn't need \ mapped to /. - * system.h (FOLD_FN_CASE): Clarify comment. - -2005-01-31 Derek Price - - * Makefile.am: Update copyright notices. - -2004-10-05 Derek Price - - * regex.c: Back out my change from 2004-04-07 as possibly suppressing - useful warnings. - -2004-10-05 Mark D. Baushke - - * regex.c (re_comp): Cast gettext return value to char * to - avoid warning in !ENABLE_NLS case. Patch imported from GNULIB. - (Problem report from Martin Neitzel .) - -2004-05-28 Derek Price - - * xsize.h: New file from GNULIB. - * Makefile.am (libcvs_a_SOURCES): Add xsize.h. - -2004-05-15 Derek Price - - * libcvs.dsp: Header file list updated. - * libcvs.dep: Regenerated for "libcvs.dsp" changes. - * libcvs.mak: Regenerated for "libcvs.dsp" changes. - (Patch from Conrad Pino .) - -2004-05-13 Derek Price - - * .cvsignore: Changed for "libcvs.dsp" changes. - * libcvs.dsp: Added for "../cvsnt.dsw" changes. - * libcvs.dep: Added for "libcvs.dsp" addition. - * libcvs.mak: Added for "libcvs.dsp" addition. - (Patch from Conrad Pino .) - -2004-04-20 Derek Price - - * system.h: Correct comments. - -2004-04-19 Derek Price - - * system.h: Gratuitous reformatting. - -2004-04-07 Derek Price - - * regex.c: Revise "FREE_VAR" macro to eliminate C4090/C4022 warnings - in Windows build with Visual C++ 6.0 compiler. - (Original patch from Conrad T. Pino .) - -2004-04-04 Derek Price - - * system.h: Correct comment. - -2004-04-04 Derek Price - - * system.h: Restore complete path folding for Cygwin under Windows. - Add ISABSOLUTE macro for determining whether a path is absolute to - handle X:\ style paths under Windows (& Cygwin). - -2004-03-25 Derek Price - - * system.h: No longer fold back slashes in paths into slashes. - -2004-03-20 Derek Price - - * mkdir.c (mkdir): Declare string args const. - -2004-03-19 Derek Price - - * .cvsignore: Add fnmatch.h for Windows and other platforms which build - it. - -2003-12-09 Derek Price - - * system.h: Correct spelling in comment. - -2003-12-03 Derek Price - - * fncase.c (OSX_filename_classes): New array. - (fncmp): Use FOLD_FN_CASE rather relying on the fact that it will be - #defined to use WNT_filename_classes. - * system.h: Define FOLD_FN_CASE, fncmp, and fnfold for all case - insensitive filesystems. Share some code between the new generic case - insensitive section and the old WOE32 section. - -2003-10-02 Derek Price - - * getpass.c: Back out my last getpass.c update since the new GNULIB - version introduced some dependencies which I do not want to introduce - on stable. - -2003-10-01 Derek Price - - * getpass.c: Update to new version from GNULIB with Larry's fix - incorporated. - -2003-09-30 Larry Jones - - * getpass.c: Fix bug that caused password to be echoed on many - systems (input may not be followed by output on the same stream - without an intervening call to a file positioning function). - (Reported by David Everly .) - -2003-07-29 Derek Price - - * getpass.c: New file, almost identical to GNULIB's currect version. - * Makefile.am (libcvs_a_SOURCES): Add getpass.c. - * Makefile.in: Regenerated. - -2003-06-09 Derek Price - - * system.h: Reference the WIN32 macro only in order to define WOE32, - in accordance with the GNU convention to avoid implying that we - consider the Microsoft Windows Operating Environment any sort of "win". - -2003-05-21 Derek Price - - * Makefile.in: Regenerate with Automake version 1.7.5. - -2003-05-09 Derek Price - - * system.h: Define S_ISSOCK on SCO OpenServer. - -2003-04-10 Larry Jones - - * Makefile.in: Regenerated. - -2003-04-03 Derek Price - - * Makefile.am (distclean-local): New target to remove fnmatch.h when - necessary. This should be handled by Automake, but until then... - (Resolves issue #100 - from - Serguei E. Leontiev .) - - * Makefile.in: Regenerated. - -2003-03-24 Derek Price - - * Makefile.am: Update copyright notice. - - * Makefile.in: Regenerated. - -2003-02-25 Derek Price - - * Makefile.in: Regenerated. - -2003-01-23 Larry Jones - - * getdate.y: Add RCS/CVS timestamp format (Y.mm.dd.hh.mm.ss). - * getdate.c: Regenerated. - - * wait.h (WCOREDUMP): New macro. - -2002-12-27 Derek Price - - * getdate.c: Regenerated with Bison 1.35. - -2002-11-04 Derek Price - - * getdate.y (Convert): Add comment as to the effectiveness of - descriptive error messages. - -2002-09-24 Derek Price - - * Makefile.in: Regenerated using Automake 1.6.3. - -2002-09-24 Derek Price - - * Makefile.in: Regenerated. - -2002-09-15 Larry Jones - - * system.h: Add FOPEN_BINARY_READWRITE. - (Patch submitted by Josh Lehan .) - -2002-08-12 Derek Price - - * Makefile.am: Remove obsolete reference to `ftruncate.c'. - (Symptoms reported by - Andrey Aristarkhov .) - * Makefile.in: Regenerated. - -2002-08-08 Derek Price - - * regex.c: Removed unused `compile_range' declaration. - (Patch from John Tytgat .) - -2002-05-09 Larry Jones - - * getline.c (getstr): Make terminator int instead of char to avoid - promotion problems. - * getline.h (getstr): Change to match. - -2002-05-08 Derek Price - - * Makefile.in: Regenerated. - * fnmatch.h: Move this file... - * fnmatch.h.in: here. - -2002-05-08 Derek Price - - * strerror.c: Use HAVE_CONFIG_H and put config.h in brackets rather - than quotes. - -2002-05-02 Derek Price - - * fnmatch.h: More #defines to avoid Mac OS X namespace conflicts. - -2002-04-30 Derek Price - - * hostname.c: Rename to... - * gethostname.c: this. - * Makefile.am: Change comment to reflect above. - - * Makefile.in: Regenerated with automake 1.6. - -2002-04-28 Derek Price - - * getopt.h: #define new names for functions and variables when they - might conflict with system definitions (namely on Mac OS X 10.1 with - the most recent dev packages - This should be removable after the Mac - dev packages are fixed.). - * regex.h: Ditto. - * Makefile.am (libcvs_a_SOURCES): Remove fnmatch.h. - -2002-04-20 Larry Jones - - * Makefile.am (libcvs_a_SOURCES): Add getpagesize.h. - * Makefile.in: Regenerated. - -2001-09-18 Derek Price - - * fnmatch.c: The header file for a system function we're replacing with - our own should be #included using double quotes. - (Patch from Corey Minyard via - Alexey Mahotkin .) - -2001-09-04 Derek Price - - * Makefile.in: Regenerated with automake 1.5. - -2001-08-09 Derek Price - - * getpagesize.h: Only include sys/param.h when HAVE_SYS_PARAM_H has - been defined by configure. - -2001-08-07 Derek Price - - * build_lib.com: Verify. - * getdate.y: Move the include of xtime.h out from underneath the ifdef - so that it is always included. - (Patch from Mike Marciniszyn .) - - * getdate.c: Regenerated. - -2001-08-06 Derek Price - - * Makefile.in: Regenerated. - -2001-07-05 Larry Jones - - * getpagesize.h: New file to define getpagesize() for systems that - don't already have it. - * valloc.c (valloc): Use it. - -2001-07-04 Derek Price - - * Makefile.in: Regenerated with new Automake release candidate 1.4h. - -2001-06-28 Derek Price - - * Makefile.in: Regenerated with new version of Automake. - -2001-06-15 Derek Price - - * xselect.h: Don't include xtime.h. - (Thanks to Martin Neitzel .) - -2001-04-25 Derek Price - - * Makefile.in: Regenerated using AM 1.4e as of today at 18:10 -0400. - -2001-04-02 Derek Price - for Alon Ziv - - * getdate.y: Add a declaration for yyparse(). - - * getdate.c: Regenerated. - -2001-03-14 Derek Price - - * Makefile.in: Regenerated - -2001-02-20 Derek Price - - * xgssapi.h: New file to perform GSSAPI include magic. - * Makefile.am (EXTRA_DIST): Add xgssapi.h. - - * Makefile.in: Regenerated. - -2001-02-14 Derek Price - - * Makefile.am (libcvs_a_SOURCES): Add xtime.h & xselect.h. - * Makefile.in: Regenerated. - * getdate.y: Include xtime.h. - * getdate.c: Regenerated. - * system.h: Include xtime.h. - * xtime.h: New file to do include magic for time functions. - * xselect.h: New file to do select include magic. - -2001-02-06 Derek Price - Rex Jolliff - Shawn Smith - - * system.h: definitions of CVS_OPENDIR, CVS_READDIR, & CVS_CLOSEDIR - provided here in support of changes to handle VMS DEC C 5.7 - {open,read,close}dir problems. Check today's entry in the vms subdir - for more. - -2001-01-10 Derek Price - Rex Jolliff - - * rename.c: replace calls to unlink() with CVS_UNLINK() for VMS - -2000-12-22 Derek Price - - * Makefile.am (INCLUDES): Fixed typo - * Makefile.in: Regenerated - -2000-12-22 Derek Price - - * Makefile.am (INCLUDES): Added $(top_srcdir)/src - * Makefile.in: Regenerated - -2000-12-21 Derek Price - - * .cvsignore: Added .deps directory and alphabetized - * Makefile.am: New file needed by Automake - * Makefile.in: Regenerated - -2000-11-15 Derek Price - - * system.h: Added CVS_FDOPEN to conform to CVS_FOPEN precedent - -2000-07-10 Larry Jones - - * savecwd.c: #include before . - -2000-07-04 Karl Fogel - - * 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 - - * regex.c, regex.h: Version from emacs 20.7 to plug memory leaks - and avoid potential portability problems. - -2000-03-22 Larry Jones - - * 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 - - * sighandle.c (SIG_inCrSect): New function. - -2000-01-03 Larry Jones - - * 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 - - * 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 - - * getopt.h: Don't declare the arguments to getopt. - -1999-02-09 Jim Kingdon - - * vasprintf.c: Removed; there is apparently no clean, portable - solution to the VA_LIST_IS_ARRAY problem (C9X drafts have va_copy, - but we aren't even assuming C90 yet!). - * Makefile.in (SOURCES): Remove vasprintf.c. - * build_lib.com: Remove vasprintf.c and vasprintf.obj. - -1999-01-26 Jim Kingdon - and Joerg Bullmann - - * fnmatch.c: Use FOLD_FN_CHAR in two cases where it had been - omitted. - -1999-01-22 Jim Kingdon - - * fnmatch.c: Include system.h; FOLD_FN_CHAR has moved there from - config.h (from Alexey Milov). Don't define our own FOLD_FN_CHAR; - that just masks cases in which we got the includes tangled up. - -1999-01-12 Jim Kingdon - - * memmove.c: Remove paragraph which contained the FSF's old - snail mail address; it has changed. - -1999-01-05 Jim Kingdon - - * md5.c, md5.h: Rename all the external interfaces to start with - cvs_* to avoid namespace pollution problems. Include string.h - unconditionally, to avoid gcc -Wall warnings on memset. - -1998-12-29 Jim Kingdon - - * getdate.y (RelativeMonth): Add 1900 to tm_year, so that in 2000, - we pass 2000, not 100, to Convert. - (Convert): Add comment about Year argument. - * getdate.c: Regenerated using byacc. - -Tue Mar 24 16:08:00 1998 Ian Lance Taylor - - * Makefile.in (CFLAGS): Set to @CFLAGS@, not -g. - -1998-02-20 Jim Kingdon - - * regex.c: Partial merge with version from emacs 20.2. Brings - over some trivial changes (whitespace and so on) (most such - changes I didn't bother with, for this time). Don't cast to int - before comparing old_regend[r] to regstart[r] (this is the point - of bothering; the old code was broken for 64 bit machines. - Reported by Paul Vixie). - -Tue Feb 17 18:33:26 1998 Ian Lance Taylor - - * memmove.c: New file, resurrecting the old one. - * Makefile.in (SOURCES): Add memmove.c. - -1998-02-03 Tim Pierce - - * system.h (CVS_LSTAT): New macro. - -Sat Feb 7 17:33:39 1998 Ian Lance Taylor - - * getline.h (getstr): Declare. - -13 Jan 1998 Jim Kingdon - - * fncase.c: Include config.h before system.h. - - * system.h: Just include string.h unconditionally. We already - include it unconditionally elsewhere. - -Tue Jan 13 16:51:59 1998 Ian Lance Taylor - - * fncase.c: New file, taken from windows-NT/filesubr.c. - * system.h: If __CYGWIN32__ or WIN32 are defined, define - FOLD_FN_CHAR, FILENAMES_CASE_INSENSITIVE, and ISDIRSEP, and - declare fncmp and fnfold. Taken from windows-NT/config.h. - * Makefile.in (SOURCES): Add fncase.c. - -Sat Jan 10 10:51:26 1998 Jim Kingdon - - * getline.c (getstr): Make sure to set errno when appropriate. I - didn't test the error case for the new code but inspection shows - the old code was rather broken. - -Sat Nov 29 22:03:39 1997 Jim Kingdon - - getwd and getcwd were a big big mess. Although Jim's fix might - indeed be fixing a typo, the code is so tangled that I would guess - it probably breaks some system. So clean this up: - * xgetwd.c: Always assume we have getcwd (we had been anyway, - before Jim's change). - * getwd.c: Removed. - * Makefile.in: Remove getwd.c - * system.h: Remove declarations of getwd and getcwd. Move getcwd - declaration to the !HAVE_UNISTD_H section. - -1997-11-29 Jim Meyering - - * xgetwd.c: Fix typo s/ifndef/ifdef/ in test of HAVE_GETWD. - -Wed Nov 26 10:12:33 1997 Jim Kingdon - - * system.h: Always use "rb" and "wb". Check for O_BINARY with an - #ifdef, not the error-prone LINES_CRLF_TERMINATED. - -Thu Sep 25 10:57:39 1997 Jim Kingdon - - * getdate.y (get_date): If gmtime returns NULL, try to cope. - * getdate.c: Regenerated using byacc. - - * getdate.y: Remove comment about sending email concerning this file - to Rich Salz. - * getdate.c: Regenerated using byacc. - -Wed Sep 24 10:35:38 1997 Jim Kingdon - - * Makefile.in (OBJECTS): Add regex.o. - -Wed Sep 17 16:37:17 1997 Jim Kingdon - - * getdate.y (ToSeconds): For am or pm, a hour of "12" really means 0. - * getdate.c: Regenerated using byacc (not bison per comment). - -Tue Sep 9 20:51:45 1997 Jim Kingdon - - * build_lib.com: Add vasprintf.c and vasprintf.obj. - - * build_lib.com: Remove strippath.obj from library/create command. - -Sun Sep 7 17:35:27 1997 Jim Kingdon - - * system.h: Replace comment referring to ChangeLog with a - comment based on the ChangeLog entries. - - * strdup.c: Removed, per change to ../configure.in - * Makefile.in (SOURCES): Remove strdup.c. - -Mon Jun 16 18:59:50 1997 Jim Kingdon - - * system.h: Add CVS_FNMATCH. - -Sun Jun 8 23:41:11 1997 Jim Kingdon - - * system.h (mkfifo): Remove; not used anywhere. - -Thu Mar 6 17:14:49 1997 Jim Kingdon - - * regex.c: Partial merge with version from emacs 19.34. I brought - over most trivial changes (whitespace and so on). Most of the - changes to portability cruft I did not bring over, on the theory - of sticking to the devil that we know. I did bring over the - change to undef MAX and MIN (this is a better solution to a - problem we had been handling a different way). There were a - variety of changes I probably could/should have brought over, but - elected not to try to understand them and whether they would cause - trouble (printchar -> putchar, changes to output format in - print_partial_compiled_pattern, internationalization, - FREE_STACK_RETURN and friends which would appear to be fixing - memory leaks in error cases, RE_TRANSLATE_TYPE, and others). I - did merge the changes (union fail_stack_elt, PUSH_FAILURE_POINTER, - etc.) to use a union for the failure stack rather than playing - games with pointers and integers (that was my reason for - bothering; the code had been broken on the Alpha). - -Mon Feb 10 18:52:18 1997 Ullrich von Bassewitz - - * md5.c: Make the parameter to getu32 const since the function will - only read the values and this will avoid compiler warnings in other - places. - -Mon Feb 10 18:29:04 1997 Ullrich von Bassewitz - - * vasprintf.c: Added a #define for systems where a va_list is - defined as an array, not as a pointer. - -Mon Feb 10 09:31:38 1997 Ken Raeburn - - * md5.c (MD5STEP): Truncate to 32 bits before shifting right. - -Thu Jan 30 11:35:26 1997 Jim Kingdon - - * regex.h: Don't prototype re_comp and re_exec. - -Tue Jan 28 17:45:46 1997 Jim Kingdon - - * md5.c, md5.h: Changes so these work without having an integer - type which is exactly 32 bits. Modeled after changes by Tatu Ylonen - as part of SSH but rewritten. - -Wed Jan 8 14:50:47 1997 Jim Kingdon - - * Makefile.in, getopt.h, sighandle.c, system.h: Remove CVSid; we - decided to get rid of these some time ago. - -Thu Jan 2 13:30:56 1997 Jim Kingdon - - * Makefile.in, argmatch.c, fnmatch.c, fnmatch.h, getline.c, - getopt.c, getopt.h, getopt1.c, getwd.c, hostname.c, mkdir.c, - regex.c, regex.h, rename.c, sighandle.c, strdup.c, strerror.c, - stripslash.c, system.h, vasprintf.c, wait.h, xgetwd.c, yesno.c: - Remove "675" paragraph; see ../ChangeLog for rationale. - -Sun Nov 24 13:34:25 1996 Jim Kingdon - - * getdate.y (Convert): Change last acceptable year from 1999 to - 2038. - * getdate.c: Regenerated using byacc 1.9. - -Tue Nov 19 17:11:17 1996 Jim Kingdon - - * Makefile.in (OBJECTS): Remove strippath.o; we don't use - strip_path anymore. - (SOURCES): Remove strippath.c. - * strippath.c: Removed. - * build_lib.com: Remove strippath.c. - -Wed Oct 2 10:43:35 1996 Norbert Kiesel - - * getdate.y: removed CVSid variable - - * getdate.c: regenerated (using byacc 1.9) - -Wed Sep 25 10:25:00 1996 Larry Jones - - * vasprintf.c: Fix type clashes in calls to strtoul. - -Wed Sep 11 15:55:31 1996 Jim Kingdon - - * build_lib.com: Add valloc.c. - -Tue Sep 10 23:04:34 1996 Jim Kingdon - - * Makefile.in (DISTFILES): Add build_lib.com. - -Fri Aug 16 16:01:57 1996 Norbert Kiesel - - * Makefile.in (installdirs): new (empty) target - -Mon Aug 12 11:03:43 1996 Jim Kingdon - - * system.h: Don't use #elif. It is said to cause problems with - one of the HP compilers on HPUX 9.01. - -Sun Jul 7 23:25:46 1996 Jim Kingdon - - * memmove.c: Removed. The memove function was used by a very old - version of the CVS server for nefarious purposes and it has been - long gone. - * Makefile.in (SOURCES): Remove memmove.c. - -Thu Jun 6 15:12:59 1996 Jim Kingdon - - * vasprintf.c: If STDC_HEADERS, include stdlib.h rather than - declaring its functions ourself. - -Wed Jun 05 10:14:29 1996 Mike Ladwig - and Jim Kingdon - - * system.h: If ERRNO_H_MISSING is defined, don't include errno.h. - -Wed Jun 05 10:14:29 1996 Mike Ladwig - - * regex.c: Don't define MAX and MIN if already defined. - -Sun May 12 09:40:08 1996 Jim Kingdon - - * getdate.y: Replace alloca.h include with a comment explaining - why we avoid alloca and the consequences of that. - * getdate.c: Regenerated. - -Wed May 8 09:31:03 1996 Jim Kingdon - - * getdate.c: Regenerate with the version of byacc in Red Hat 3.0.3 - (which I believe is byacc 1.9). byacc, unlike bison, does not - require alloca in the generated parser. - -Thu Apr 25 18:26:34 1996 Jim Kingdon - - * getdate.y (get_date): Set Start from nowtime, not now->time, - which may not be set. - * getdate.c: Regenerated. - -Wed Apr 10 17:55:02 1996 Jim Kingdon - - * getdate.y (get_date): Use a time_t variable rather than a field - in a struct timeb. Works around Solaris compiler bug. Sure, it - is a compiler bug, but the workaround is completely painless. - * getdate.c: Regenerated. - -Fri Mar 22 11:17:05 1996 Jim Kingdon - - * system.h: If EXIT_FAILURE is not defined by stdlib.h, define it - ourself. - -Thu Mar 14 16:27:53 1996 Jim Kingdon - - * system.h: Remove alloca cruft. - -Wed Feb 28 03:16:48 1996 Benjamin J. Lee - - * build_lib.com: Changed definition of symbol CC to search - for include files in [-.VMS] so VMS config.h can be picked - up without copying. - -Tue Feb 27 21:26:34 1996 Benjamin J. Lee - - * build_lib.com: Added. DCL File to build contents of [.lib] - -Tue Feb 27 21:18:38 1996 Benjamin J. Lee - - * system.h: added an existence_error macro check for EVMSERR - necessary for happiness under VMS - -Thu Feb 22 22:30:04 1996 Jim Kingdon - - * Makefile.in (OBJECTS): Remove @ALLOCA@ - (SOURCES): Remove alloca.c - * alloca.c: Removed. - * regex.c (REGEX_MALLOC): Define. - -Thu Feb 15 14:00:00 Jim Kingdon - - * vasprintf.c: Declare abs(). - -Wed Feb 14 14:48:31 1996 Jim Kingdon - - * vasprintf.c (int_vasprintf): Don't cast arguments to memcpy. - * vasprintf.c, strtoul.c: Don't include ansidecl.h. Do include - config.h if HAVE_CONFIG_H (for const). - * strtoul.c: Change CONST to const. - -Tue Feb 13 20:04:39 1996 Jim Kingdon - - * strtoul.c: Added (needed by vasprintf.c, and missing on SunOS4). - * Makefile.in (SOURCES): Add strtoul.c. - -Mon Feb 12 10:04:46 1996 Jim Kingdon - - * vasprintf.c: Added (same contents as before). - * Makefile.in (SOURCES): Add vasprintf.c. - -Thu Feb 1 14:33:17 1996 Karl Fogel - - * Makefile.in (xlint): new rule; does nothing, as I'm not sure - running lint is actually advisable in here, but the top-level - Makefile thinks it can `make xlint' here. - -Thu Feb 1 15:07:42 1996 Jim Kingdon - - * getopt.c: Remove rcsid. - -Tue Jan 30 18:20:27 1996 Jim Kingdon - - * getline.c: Don't define NDEBUG. - (getstr): Rewrite assertions in a way which should stay clear of - signed/unsigned problems and compiler warnings thereof. - -Thu Jan 25 00:14:06 1996 Jim Kingdon - - * yesno.c (yesno): fflush stdout as well as stderr. - -Wed Jan 3 18:16:50 1996 Jim Kingdon - - * sighandle.c (SIG_register): Use memset not bzero. - * system.h: Remove defines for index, rindex, bcmp, and bzero. - All the calls to those functions are gone from CVS. - -Tue Jan 2 13:00:00 1996 Jim Kingdon - - Visual C++ lint: - * sighandle.c: Prototype SIG_handle and SIG_defaults. - Use SIG_ERR where appropriate. - -Mon Dec 18 10:15:05 1995 Jim Kingdon - - * rename.c: Check ENOENT rather than existence_error. The latter - is undefined in this file, and including system.h is said to cause - (unspecified) problems. - -Sun Dec 17 23:58:06 1995 Jim Kingdon - - * vasprintf.c: Removed (it is no longer used). - * Makefile.in (SOURCES): Remove vasprintf.c. - -Sat Dec 16 17:18:33 1995 Jim Kingdon - - * vasprintf.c: Added. - * Makefile.in (SOURCES): Add vasprintf.c - -Mon Dec 4 10:54:04 1995 Jim Kingdon - - * getdate.c: Remove #line directives. I know, this is a kludge, - but Visual C++ 2.1 seems to require it (why, I have no idea. It - has no trouble with the #line directives in getdate in CVS 1.6). - -Sat Nov 18 16:20:37 1995 Karl Fogel - - * rename.c: same. - - * mkdir.c: Use new macro `existence_error', instead of comparing - errno to ENOENT directly. - - * system.h (existence_error): new macro, tries to portably ask if - errno represents a file-not-exist error. - -Fri Nov 17 20:08:58 1995 Karl Fogel - - * system.h (NEED_DECOY_PERMISSIONS): moved this section to where - it belongs, duh. - - * getdate.c: if STDC_HEADERS, then just include instead - of declaring malloc() and realloc() to be char *. - - * system.h: ifdef NEED_DECOY_PERMISSIONS, then define the S_I* - permission masks for USR, GRP, and OTH in terms of the simpler - OS/2 masks. - -Wed Nov 15 15:36:03 1995 Karl Fogel - - * system.h: ifdef USE_OWN_TCPIP_H, then include "tcpip.h". Only - OS/2 does this right now. - -Tue Nov 14 18:44:57 1995 Greg A. Woods - - * getdate.c: OK, this one is from SunOS-4.1 yacc and may be more - portable -- at least it compiles silently here! ;-) - -Mon Nov 13 03:53:45 1995 Karl Fogel - - * fnmatch.c: conform to 80 column standard (yes, I'm a pedant). - -Wed Nov 8 11:10:59 1995 Karl Fogel - - * system.h (STAT_MACROS): ifdef S_IFMT, then use it as before; but - if it's not defined, then just do a single mask and assume - acceptance any of non-zero result. Norbert, I trust you'll let me - know if this is unsatisfactory. :-) - Ifdef HAVE_SYS_UTIME_H, then include . Only OS/2 - defines this right now. - -Wed Nov 8 13:18:51 1995 Norbert Kiesel - - * valloc.c: omit malloc declaration (it's already in system.h - which is included and conflicts with on some - systems). - -Tue Nov 7 19:38:48 1995 Norbert Kiesel - - * system.h (STAT_MACROS_BROKEN): undo previous change, because - else all regular files will be identified as links (the mask for - links is S_IFREG|S_IFCHR). - -Mon Nov 6 19:20:56 1995 Karl Fogel - - * system.h (STAT_MACROS_BROKEN): in defining the S_IF* macros, - don't fold to 1 or 0 by first masking with S_IFMT; not all - systems have that macro, and anyway it's only necessary that we - return non-zero. - -Fri Oct 27 13:43:35 1995 Karl Fogel - - * save-cwd.c: use __PROTO instead of __P (see below). - - * getline.h (__PROTO): same as below. - - * save-cwd.h (__PROTO): replaces __P. New name, so don't ask if - already defined. The conflict was that OS/2 w/ IBM C/C++ uses - `__P' for something else, in of all places. - - * system.h: do nothing about alloca ifdef ALLOCA_IN_STDLIB (see - ../src/ChangeLog). - -Tue Oct 24 13:01:25 1995 Norbert Kiesel - - * wait.h: include sys/resource.h if available. This is needed at - least under AIX-3.2 where doesn't include it. - -Mon Oct 23 17:39:11 1995 Norbert Kiesel - - * valloc.c (valloc): change parameter definition - -Sun Oct 22 14:15:44 1995 Jim Meyering (meyering@comco.com) - - * getline.c, getline.h: New files. - * Makefile.in (SOURCES, OBJECTS, HEADERS): Add getline.c, getline.o, - and getline.h, respectively. - -Tue Oct 10 18:01:50 1995 Karl Fogel - - * Makefile.in (cvs_srcdir): define cvs_srcdir to be ../src, then - include it with -I so save_cwd.c can find error.h (for example). - -Sun Oct 8 12:27:57 1995 Peter Wemm - - * system.h: define POSIX_SIGNALS or BSD_SIGNALS if configure has - located all the necessary functions for each "type". - * sighandle.c: detect/use POSIX/BSD reliable signals (especially - for blocking signals in critical sections). Helps prevent stray - locks on interruption. - -Mon Oct 2 18:11:23 1995 Jim Blandy - - * system.h: Doc fix. - -Mon Oct 2 18:10:35 1995 Larry Jones - - * regex.c: compile 4.2 BSD compatible functions even when - _POSIX_SOURCE is defined since we need them and we wouldn't be - compiling this file unless they don't exist. - -Mon Oct 2 10:32:20 1995 Michael Finken - - * strstr.c (strstr): new file and func. - - * Makefile.in (SOURCES): added strstr.c. - -Sun Oct 1 21:03:40 1995 Karl Fogel - - * regex.c: reverted below change. - -Thu Sep 28 13:37:04 1995 Larry Jones - - * regexp.c: check for ISC. - -Thu Sep 7 19:18:00 1995 Jim Blandy - - * save-cwd.c: #include and , on systems that - have them. - - * getopt.c (_getopt_internal): Cast the return value of strlen, - which is unsigned, before comparing it with the difference between - two pointers, which is unsigned. - -Thu Aug 31 11:31:42 1995 Jim Blandy - - * getdate.y [STDC_HEADERS]: #include , for abort. - [HAVE_ALLOCA_H]: #include , for alloca on Windows NT. - -Wed Aug 30 18:48:44 1995 Jim Blandy - - * system.h [HAVE_IO_H]: #include , for Windows NT. - [HAVE_DIRECT_H]: #include , for Windows NT. - (CVS_MKDIR, FOLD_FN_CHAR, fnfold, fncmp, ISDIRSEP, OPEN_BINARY, - FOPEN_BINARY_READ, FOPEN_BINARY_WRITE): New macros/functions, for - use in system-sensitive code. - - * regex.c (re_set_registers): start and end are pointers, not - integers. Cast the initializing value appropriately. - - * getopt.c [HAVE_STRING_H]: #include , to avoid - warnings. - - * fnmatch.c (FOLD_FN_CHAR): Give this a dummy #definition if - config.h didn't #define it. - (fnmatch): Pass filename characters through FOLD_FN_CHAR before - comparing them. - - * argmatch.c: #include . - (argmatch): Declare arglen to be a size_t, rather than an int, - to avoid signed/unsigned comparison "problems". - - * .cvsignore: Remove getdate.c from this file. We want to - distribute it, for systems that don't have a Yacc-equivalent - installed (like Windows NT). - -Sat Aug 19 22:00:51 1995 Jim Blandy - - * error.c: Don't #define CVS_SUPPORT here. config.h takes care of - that for us. - [CVS_SUPPORT] (error_use_protocol): New variable, with apology. - (error): If error_use_protocol is set, report errors using the - client/server protocol. - * error.h [CVS_SUPPORT]: Extern decl for error_use_protocol. - -Fri Aug 4 00:01:24 1995 Jim Meyering (meyering@comco.com) - - * xgetwd.c: Don't declare free. A K&R style declaration gets - a conflict on some Sun systems when compiling with acc. - - * save-cwd.c: New file. - * save-cwd.h: New file. - * Makefile.in (SOURCES): Add save-cwd.c - (OBJECTS): Add save-cwd.o. - (HEADERS): Add save-cwd.h. - -Thu Aug 3 00:55:54 1995 Jim Meyering (meyering@comco.com) - - * error.h: New file. - * Makefile.in (HEADERS): Add error.h. - -Sat Jul 29 15:53:55 1995 James Kingdon - - * Makefile.in (SOURCES): Add getdate.c. - -Thu Jul 27 09:11:41 1995 Robert Lipe - - * system.h: Check for PATHSIZE before falling back to _POSIX_PATH_MAX. - -Thu Jul 20 12:38:03 1995 James Kingdon - - * error.c: Instead of calling cvs functions to clean up, allow cvs - to register a callback via error_set_cleanup. Avoids hassles with - include files and SERVER_SUPPORT and so on. - -Tue Jul 18 21:18:00 1995 Jim Blandy - - * system.h: Include only if HAVE_SYS_PARAM_H - is #defined. We've added a test to configure.in to #define this - on most systems. - -Thu Jul 13 11:22:21 1995 Jim Meyering (meyering@comco.com) - - * xgetwd.c: New file. - * Makefile.in (SOURCES): Add xgetwd.c - (OBJECTS): Add xgetwd.o. - -Wed Jul 12 09:18:49 1995 Jim Meyering (meyering@comco.com) - - * Makefile.in (OBJECTS): Remove fnmatch.o. Now configure adds it - to LIBOBJS when necessary. - -Fri Jun 30 16:27:18 1995 James Kingdon - - * rename.c (rename): If MVDIR is not defined, just give an error - on attempt to rename a directory. - -Thu Jun 29 00:46:31 1995 James Kingdon - - * system.h: Check HAVE_SYS_TIMEB_H not non-existent HAVE_TIMEB_H. - - * system.h: Don't define alloca if it is already defined. - -Wed Jun 28 15:24:51 1995 James Kingdon - - * system.h: If NeXT, define utimbuf ourself. - -Mon May 29 22:32:40 1995 J.T. Conklin - - * system.h: Handle time and directory headers as recommended in - the autoconf manual. - Undefine the S_FOO() macros if STAT_MACROS_BROKEN is set. - Don't define mode_t, as it is handled by config.h. - -Sat May 27 08:46:00 1995 Jim Meyering (meyering@comco.com) - - * Makefile.in (Makefile): Regenerate only Makefile in current - directory when Makefile.in is out of date. Depend on ../config.status. - -Fri Apr 28 22:49:25 1995 Jim Blandy - - * Makefile.in (SOURCES, OBJECTS): Updated. - (HEADERS): New variable. - (DISTFILES): Updated. - (dist-dir): Renamed from dist; changed to work with DISTDIR - variable passed from parent. - -Wed Feb 8 06:37:53 1995 Roland McGrath - - * system.h (S_IRUSR et al): Define if not already defined. - - * waitpid.c [HAVE_CONFIG_H]: Include "config.h". - (ualloc): Return OLDPTR rather than running off the end. - -Mon Aug 22 22:48:19 1994 Ken Raeburn (raeburn@kr-pc.cygnus.com) - - * error.c (strerror): Replaced conditional static definition - (always used, since the condition variable was never set) with an - extern declaration, since it's provided by libc or strerror.c. - -Wed Aug 10 14:54:25 1994 Ken Raeburn (raeburn@cujo.cygnus.com) - - * Makefile.in (SOURCES): Add waitpid.c. - * waitpid.c: New file. - -Tue Aug 9 16:00:12 1994 Ken Raeburn (raeburn@cujo.cygnus.com) - - * md5.h (uint32): If SIZEOF_LONG isn't 4, don't define this to be - "unsigned long"; try SIZEOF_INT and "unsigned int", otherwise - complain. - - * md5.c: Include config.h. - (const): Don't bother defining here, config.h should take care of - it. - - * valloc.c (malloc): Declare. - -Fri Jul 15 12:57:20 1994 Ian Lance Taylor (ian@sanguine.cygnus.com) - - * getopt.c: Do not include unless __GNU_LIBRARY__ is - defined. On Irix 5.2, includes , which - causes a multiple definition of struct option. - -Fri Jul 8 10:04:59 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * md5.h, md5.c: Remove ANSI-isms. - -Thu Jul 7 20:24:18 1994 Ian Lance Taylor (ian@sanguine.cygnus.com) - - * md5.h, md5.c: New files. - * Makefile.in (SOURCES): Add md5.c. - (OBJECTS): Add md5.o. - (DISTFILES): Add md5.h. - (md5.o): New target; depend upon md5.h. - -Fri May 27 18:15:34 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * valloc.c: New file. - -Tue May 17 08:18:26 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * error.c (error, fperror): If server_active, call server_cleanup - as well as Lock_Cleanup. - -Thu Jan 6 13:45:04 1994 Ken Raeburn (raeburn@cujo.cygnus.com) - - * system.h: Fix Dec 27 change to work correctly. Makes Sep 9 - change unnecessary, so backed that one out. Never define PATH_MAX - in terms of pathconf, because that doesn't produce a constant, and - PATH_MAX is used to set array sizes. - -Mon Dec 27 14:22:07 1993 Mark Eichin (eichin@cygnus.com) - - * system.h: don't touch PATH_MAX or MAXPATHLEN if *both* of them - are already defined, as one may be defined in terms of the other. diff --git a/contrib/cvs/lib/ChangeLog.fsf b/contrib/cvs/lib/ChangeLog.fsf deleted file mode 100644 index 176d791..0000000 --- a/contrib/cvs/lib/ChangeLog.fsf +++ /dev/null @@ -1,90 +0,0 @@ -Thu Sep 15 00:18:26 1994 david d `zoo' zuhn - - * system.h: remove a bunch of "extern int " declarations of system - functions (could conflict with vendor header files, and didn't - do anything *too* useful to begin with). - - * Makefile.in: update getdate.y message (now has 10 s/r conflicts) - -Wed Sep 14 22:12:21 1994 david d `zoo' zuhn - - * strerror.c: more complete, from the Cygnus libiberty package - - * error.c (strerror): removed, functionality is in strerror.c - - * cvs.h: remove duplicate prototype for Reader_Lock - * history.c: printf argument mismatch - (Both fixes thanks to J.T. Conklin (jtc@cygnus.com) - -Sat Jul 30 13:50:11 1994 david d `zoo' zuhn (zoo@monad.armadillo.com) - - * getopt1.c, getopt.c, getopt.h, getdate.y: latest versions from FSF - -Wed Jul 13 22:11:17 1994 david d `zoo' zuhn (zoo@monad.armadillo.com) - - * system.h: don't set PATH_MAX to pathconf(), since PATH_MAX is - used to size arrays. (thanks to kingdon@cygnus.com) - - * getopt1.c: remove #ifdef __STDC__ around const usages (which - isn't correct and weren't complete) - -Wed Apr 20 14:57:16 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * getopt.h: Prevent multiple inclusion. - -Tue Jan 25 17:34:42 1994 david d zuhn (zoo@monad.armadillo.com) - - * Makefile.in: make sure that no blank lines are in the $(OBJECTS) - list (from Brad Figg) - -Mon Jan 24 12:27:13 1994 david d zuhn (zoo@monad.armadillo.com) - - * system.h: remove alloca checks (added to src/cvs.h); revamped - the MAXPATHLEN and PATH_MAX tests (from Brad Figg - ); handle index,rindex,bcmp,bzero better - (don't redefine if already defined); added S_IWRITE, S_IWGRP, - S_IWOTH definitions (header file reorganization) - - * strippath.c: use strchr, not index - - * getopt1.c: match prototypes when __STDC__ compiler (lint fixes) - - * getdate.c: alloca checks for when using bison - - * Makefile.in: added CC and YACC definitions; use YACC not BISON; - better getdate.c tests (also from Brad Figg) - -Sat Dec 18 00:55:43 1993 david d zuhn (zoo@monad.armadillo.com) - - * Makefile.in (VPATH): don't use $(srcdir), but @srcdir@ instead - - * memmove.c: new file, implements memmove in terms of bcopy - - * wait.h: include if HAVE_SYS_WAIT_H, not if POSIX - -Thu Sep 9 18:02:11 1993 david d `zoo' zuhn (zoo@rtl.cygnus.com) - - * system.h: only #undef PATH_MAX if not on an Alpha. The #undef - causes problems with the Alpha C compiler. - -Thu Apr 8 12:39:56 1993 Ian Lance Taylor (ian@cygnus.com) - - * system.h: Removed several incorrect declarations which fail - on Solaris. - -Wed Jan 20 17:57:24 1993 K. Richard Pixley (rich@rtl.cygnus.com) - - * system.h: add externs for sun4 so that gcc -Wall becomes useful - again. - -Wed Feb 26 18:04:40 1992 K. Richard Pixley (rich@cygnus.com) - - * Makefile.in, configure.in: removed traces of namesubdir, - -subdirs, $(subdir), $(unsubdir), some rcs triggers. Forced - copyrights to '92, changed some from Cygnus to FSF. - -Sat Dec 28 02:42:06 1991 K. Richard Pixley (rich at cygnus.com) - - * mkdir.c, rename.c: change fork() to vfork(). - - diff --git a/contrib/cvs/lib/Makefile.am b/contrib/cvs/lib/Makefile.am deleted file mode 100644 index cade9e0..0000000 --- a/contrib/cvs/lib/Makefile.am +++ /dev/null @@ -1,118 +0,0 @@ -## Process this file with automake to produce Makefile.in -# Makefile for library files used by GNU CVS. -# -# Copyright (C) 1986-2005 The Free Software Foundation, Inc. -# -# Portions Copyright (C) 1998-2005 Derek Price, Ximbiot , -# and others. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -# For now we need to include $(top_srcdir)/src because some systems -# (at least 'AIX rioscpu2 3 4 000030498200', -# 'HP-UX hp60 B.10.20 A 9000/770 hp60 two-user license', & -# 'IRIX64 sgiop110 6.5 07151433 IP30') have trouble finding error.h -# when compiling savecwd.c -# -# FIXME - the fact that compiling on my Linux 2.2.16 system finds -# /usr/include/error.h instead of $(top_srcdir)/src/error.h but -# everything compiles and tests anyhow implies that src/error.h may -# be unecessary now. Should look more deeply into this -# -# $(includeopt) is CVS specific and set by configure -INCLUDES = -I$(top_srcdir)/src $(includeopt) - -noinst_LIBRARIES = libcvs.a - -# 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?) -libcvs_a_SOURCES = \ - argmatch.c \ - getdate.y \ - getline.c \ - getopt.c \ - getopt1.c \ - getpass.c \ - md5.c \ - regex.c \ - savecwd.c \ - sighandle.c \ - stripslash.c \ - xgetwd.c \ - yesno.c \ - getline.h \ - getopt.h \ - getpagesize.h \ - md5.h \ - regex.h \ - savecwd.h \ - system.h \ - wait.h \ - xselect.h \ - xtime.h -## because @LIBOBJS@ is included below, automake automatically knows about -## dup2.c -## fncase.c -## fnmatch.c -## fnmatch.h -## ftruncate.c -## gethostname.c -## memmove.c -## mkdir.c -## rename.c -## strstr.c -## strerror.c -## strtoul.c -## valloc.c -## waitpid.c -libcvs_a_LIBADD = @LIBOBJS@ - -EXTRA_DIST = \ - .cvsignore \ - ChangeLog.fsf \ - build_lib.com \ - libcvs.dep libcvs.dsp libcvs.mak \ - xgssapi.h \ - test-getdate.sh - -TESTS = -MOSTLYCLEANFILES = -check_PROGRAMS = - -# Test GNULIB getdate module. -TESTS += test-getdate.sh -MOSTLYCLEANFILES += getdate-expected getdate-got getdate.diff -# Program required by test-getdate.sh for testing getdate.y. -check_PROGRAMS += getdate -EXTRA_DIST += $(check_PROGRAMS) -getdate_SOURCES = getdate.y -getdate_CPPFLAGS = -DTEST -##getdate_LDADD = \ -## $(noinst_LIBRARIES) - -# For the xsize module from GNULIB. -libcvs_a_SOURCES += xsize.h - -# Until Automake gets its act together -distclean-local: - rm -f fnmatch.h - -# for backwards compatibility with the old makefiles -realclean: maintainer-clean -.PHONY: realclean diff --git a/contrib/cvs/lib/Makefile.in b/contrib/cvs/lib/Makefile.in deleted file mode 100644 index 2d0b82e..0000000 --- a/contrib/cvs/lib/Makefile.in +++ /dev/null @@ -1,614 +0,0 @@ -# Makefile.in generated by automake 1.10 from Makefile.am. -# @configure_input@ - -# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006 Free Software Foundation, Inc. -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ - -# Makefile for library files used by GNU CVS. -# -# Copyright (C) 1986-2005 The Free Software Foundation, Inc. -# -# Portions Copyright (C) 1998-2005 Derek Price, Ximbiot , -# and others. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -VPATH = @srcdir@ -pkgdatadir = $(datadir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -check_PROGRAMS = getdate$(EXEEXT) -subdir = lib -DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ - $(srcdir)/fnmatch.h.in ChangeLog dup2.c fncase.c fnmatch.c \ - fnmatch.h.in ftruncate.c getdate.c gethostname.c memmove.c \ - mkdir.c rename.c strerror.c strstr.c strtoul.c valloc.c \ - waitpid.c -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ - $(top_srcdir)/configure.in -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs -CONFIG_HEADER = $(top_builddir)/config.h -CONFIG_CLEAN_FILES = fnmatch.h -LIBRARIES = $(noinst_LIBRARIES) -AR = @AR@ -ARFLAGS = @ARFLAGS@ -libcvs_a_AR = $(AR) $(ARFLAGS) -libcvs_a_DEPENDENCIES = @LIBOBJS@ -am_libcvs_a_OBJECTS = argmatch.$(OBJEXT) getdate.$(OBJEXT) \ - getline.$(OBJEXT) getopt.$(OBJEXT) getopt1.$(OBJEXT) \ - getpass.$(OBJEXT) md5.$(OBJEXT) regex.$(OBJEXT) \ - savecwd.$(OBJEXT) sighandle.$(OBJEXT) stripslash.$(OBJEXT) \ - xgetwd.$(OBJEXT) yesno.$(OBJEXT) -libcvs_a_OBJECTS = $(am_libcvs_a_OBJECTS) -am_getdate_OBJECTS = getdate-getdate.$(OBJEXT) -getdate_OBJECTS = $(am_getdate_OBJECTS) -getdate_LDADD = $(LDADD) -DEFAULT_INCLUDES = -I. -I$(top_builddir)@am__isrc@ -depcomp = $(SHELL) $(top_srcdir)/depcomp -am__depfiles_maybe = depfiles -COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ - $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -CCLD = $(CC) -LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ -@MAINTAINER_MODE_FALSE@am__skipyacc = test -f $@ || -YACCCOMPILE = $(YACC) $(YFLAGS) $(AM_YFLAGS) -YLWRAP = $(top_srcdir)/ylwrap -SOURCES = $(libcvs_a_SOURCES) $(getdate_SOURCES) -DIST_SOURCES = $(libcvs_a_SOURCES) $(getdate_SOURCES) -ETAGS = etags -CTAGS = ctags -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -ACLOCAL = @ACLOCAL@ -AMTAR = @AMTAR@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -CC = @CC@ -CCDEPMODE = @CCDEPMODE@ -CFLAGS = @CFLAGS@ -CPP = @CPP@ -CPPFLAGS = @CPPFLAGS@ -CSH = @CSH@ -CYGPATH_W = @CYGPATH_W@ -DEFS = @DEFS@ -DEPDIR = @DEPDIR@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EDITOR = @EDITOR@ -EGREP = @EGREP@ -EXEEXT = @EXEEXT@ -GREP = @GREP@ -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -KRB4 = @KRB4@ -LDFLAGS = @LDFLAGS@ -LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ -LN_S = @LN_S@ -LTLIBOBJS = @LTLIBOBJS@ -MAINT = @MAINT@ -MAKEINFO = @MAKEINFO@ -MKDIR_P = @MKDIR_P@ -MKTEMP = @MKTEMP@ -OBJEXT = @OBJEXT@ -PACKAGE = @PACKAGE@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ -PACKAGE_NAME = @PACKAGE_NAME@ -PACKAGE_STRING = @PACKAGE_STRING@ -PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -PERL = @PERL@ -PR = @PR@ -PS2PDF = @PS2PDF@ -RANLIB = @RANLIB@ -ROFF = @ROFF@ -SENDMAIL = @SENDMAIL@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -STRIP = @STRIP@ -TEXI2DVI = @TEXI2DVI@ -VERSION = @VERSION@ -YACC = @YACC@ -YFLAGS = @YFLAGS@ -abs_builddir = @abs_builddir@ -abs_srcdir = @abs_srcdir@ -abs_top_builddir = @abs_top_builddir@ -abs_top_srcdir = @abs_top_srcdir@ -ac_ct_CC = @ac_ct_CC@ -ac_prefix_program = @ac_prefix_program@ -am__include = @am__include@ -am__leading_dot = @am__leading_dot@ -am__quote = @am__quote@ -am__tar = @am__tar@ -am__untar = @am__untar@ -bindir = @bindir@ -build_alias = @build_alias@ -builddir = @builddir@ -datadir = @datadir@ -datarootdir = @datarootdir@ -docdir = @docdir@ -dvidir = @dvidir@ -exec_prefix = @exec_prefix@ -host_alias = @host_alias@ -htmldir = @htmldir@ -includedir = @includedir@ -includeopt = @includeopt@ -infodir = @infodir@ -install_sh = @install_sh@ -libdir = @libdir@ -libexecdir = @libexecdir@ -localedir = @localedir@ -localstatedir = @localstatedir@ -mandir = @mandir@ -mkdir_p = @mkdir_p@ -oldincludedir = @oldincludedir@ -pdfdir = @pdfdir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -psdir = @psdir@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -srcdir = @srcdir@ -sysconfdir = @sysconfdir@ -target_alias = @target_alias@ -top_builddir = @top_builddir@ -top_srcdir = @top_srcdir@ -with_default_rsh = @with_default_rsh@ -with_default_ssh = @with_default_ssh@ - -# For now we need to include $(top_srcdir)/src because some systems -# (at least 'AIX rioscpu2 3 4 000030498200', -# 'HP-UX hp60 B.10.20 A 9000/770 hp60 two-user license', & -# 'IRIX64 sgiop110 6.5 07151433 IP30') have trouble finding error.h -# when compiling savecwd.c -# -# FIXME - the fact that compiling on my Linux 2.2.16 system finds -# /usr/include/error.h instead of $(top_srcdir)/src/error.h but -# everything compiles and tests anyhow implies that src/error.h may -# be unecessary now. Should look more deeply into this -# -# $(includeopt) is CVS specific and set by configure -INCLUDES = -I$(top_srcdir)/src $(includeopt) -noinst_LIBRARIES = libcvs.a - -# 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?) - -# For the xsize module from GNULIB. -libcvs_a_SOURCES = argmatch.c getdate.y getline.c getopt.c getopt1.c \ - getpass.c md5.c regex.c savecwd.c sighandle.c stripslash.c \ - xgetwd.c yesno.c getline.h getopt.h getpagesize.h md5.h \ - regex.h savecwd.h system.h wait.h xselect.h xtime.h xsize.h -libcvs_a_LIBADD = @LIBOBJS@ -EXTRA_DIST = .cvsignore ChangeLog.fsf build_lib.com libcvs.dep \ - libcvs.dsp libcvs.mak xgssapi.h test-getdate.sh \ - $(check_PROGRAMS) - -# Test GNULIB getdate module. -TESTS = test-getdate.sh -MOSTLYCLEANFILES = getdate-expected getdate-got getdate.diff -getdate_SOURCES = getdate.y -getdate_CPPFLAGS = -DTEST -all: all-am - -.SUFFIXES: -.SUFFIXES: .c .o .obj .y -$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ - && exit 0; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu lib/Makefile'; \ - cd $(top_srcdir) && \ - $(AUTOMAKE) --gnu lib/Makefile -.PRECIOUS: Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - @case '$?' in \ - *config.status*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ - *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ - esac; - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh - -$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh - -clean-noinstLIBRARIES: - -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) -libcvs.a: $(libcvs_a_OBJECTS) $(libcvs_a_DEPENDENCIES) - -rm -f libcvs.a - $(libcvs_a_AR) libcvs.a $(libcvs_a_OBJECTS) $(libcvs_a_LIBADD) - $(RANLIB) libcvs.a - -clean-checkPROGRAMS: - -test -z "$(check_PROGRAMS)" || rm -f $(check_PROGRAMS) -getdate$(EXEEXT): $(getdate_OBJECTS) $(getdate_DEPENDENCIES) - @rm -f getdate$(EXEEXT) - $(LINK) $(getdate_OBJECTS) $(getdate_LDADD) $(LIBS) - -mostlyclean-compile: - -rm -f *.$(OBJEXT) - -distclean-compile: - -rm -f *.tab.c - -@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/dup2.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/fncase.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/fnmatch.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/fnmatch.h.in@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/ftruncate.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/gethostname.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/memmove.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/mkdir.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/rename.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/strerror.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/strstr.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/strtoul.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/valloc.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/waitpid.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/argmatch.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getdate-getdate.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getdate.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getline.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getopt.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getopt1.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getpass.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/md5.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/regex.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/savecwd.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sighandle.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stripslash.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xgetwd.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/yesno.Po@am__quote@ - -.c.o: -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(COMPILE) -c $< - -.c.obj: -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` -@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` - -getdate-getdate.o: getdate.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(getdate_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT getdate-getdate.o -MD -MP -MF $(DEPDIR)/getdate-getdate.Tpo -c -o getdate-getdate.o `test -f 'getdate.c' || echo '$(srcdir)/'`getdate.c -@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/getdate-getdate.Tpo $(DEPDIR)/getdate-getdate.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='getdate.c' object='getdate-getdate.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(getdate_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o getdate-getdate.o `test -f 'getdate.c' || echo '$(srcdir)/'`getdate.c - -getdate-getdate.obj: getdate.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(getdate_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT getdate-getdate.obj -MD -MP -MF $(DEPDIR)/getdate-getdate.Tpo -c -o getdate-getdate.obj `if test -f 'getdate.c'; then $(CYGPATH_W) 'getdate.c'; else $(CYGPATH_W) '$(srcdir)/getdate.c'; fi` -@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/getdate-getdate.Tpo $(DEPDIR)/getdate-getdate.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='getdate.c' object='getdate-getdate.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(getdate_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o getdate-getdate.obj `if test -f 'getdate.c'; then $(CYGPATH_W) 'getdate.c'; else $(CYGPATH_W) '$(srcdir)/getdate.c'; fi` - -.y.c: - $(am__skipyacc) $(SHELL) $(YLWRAP) $< y.tab.c $@ y.tab.h $*.h y.output $*.output -- $(YACCCOMPILE) - -ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ - mkid -fID $$unique -tags: TAGS - -TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - tags=; \ - here=`pwd`; \ - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ - if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ - test -n "$$unique" || unique=$$empty_fix; \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$tags $$unique; \ - fi -ctags: CTAGS -CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - tags=; \ - here=`pwd`; \ - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ - test -z "$(CTAGS_ARGS)$$tags$$unique" \ - || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ - $$tags $$unique - -GTAGS: - here=`$(am__cd) $(top_builddir) && pwd` \ - && cd $(top_srcdir) \ - && gtags -i $(GTAGS_ARGS) $$here - -distclean-tags: - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags - -check-TESTS: $(TESTS) - @failed=0; all=0; xfail=0; xpass=0; skip=0; ws='[ ]'; \ - srcdir=$(srcdir); export srcdir; \ - list=' $(TESTS) '; \ - if test -n "$$list"; then \ - for tst in $$list; do \ - if test -f ./$$tst; then dir=./; \ - elif test -f $$tst; then dir=; \ - else dir="$(srcdir)/"; fi; \ - if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \ - all=`expr $$all + 1`; \ - case " $(XFAIL_TESTS) " in \ - *$$ws$$tst$$ws*) \ - xpass=`expr $$xpass + 1`; \ - failed=`expr $$failed + 1`; \ - echo "XPASS: $$tst"; \ - ;; \ - *) \ - echo "PASS: $$tst"; \ - ;; \ - esac; \ - elif test $$? -ne 77; then \ - all=`expr $$all + 1`; \ - case " $(XFAIL_TESTS) " in \ - *$$ws$$tst$$ws*) \ - xfail=`expr $$xfail + 1`; \ - echo "XFAIL: $$tst"; \ - ;; \ - *) \ - failed=`expr $$failed + 1`; \ - echo "FAIL: $$tst"; \ - ;; \ - esac; \ - else \ - skip=`expr $$skip + 1`; \ - echo "SKIP: $$tst"; \ - fi; \ - done; \ - if test "$$failed" -eq 0; then \ - if test "$$xfail" -eq 0; then \ - banner="All $$all tests passed"; \ - else \ - banner="All $$all tests behaved as expected ($$xfail expected failures)"; \ - fi; \ - else \ - if test "$$xpass" -eq 0; then \ - banner="$$failed of $$all tests failed"; \ - else \ - banner="$$failed of $$all tests did not behave as expected ($$xpass unexpected passes)"; \ - fi; \ - fi; \ - dashes="$$banner"; \ - skipped=""; \ - if test "$$skip" -ne 0; then \ - skipped="($$skip tests were not run)"; \ - test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \ - dashes="$$skipped"; \ - fi; \ - report=""; \ - if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \ - report="Please report to $(PACKAGE_BUGREPORT)"; \ - test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \ - dashes="$$report"; \ - fi; \ - dashes=`echo "$$dashes" | sed s/./=/g`; \ - echo "$$dashes"; \ - echo "$$banner"; \ - test -z "$$skipped" || echo "$$skipped"; \ - test -z "$$report" || echo "$$report"; \ - echo "$$dashes"; \ - test "$$failed" -eq 0; \ - else :; fi - -distdir: $(DISTFILES) - @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - list='$(DISTFILES)'; \ - dist_files=`for file in $$list; do echo $$file; done | \ - sed -e "s|^$$srcdirstrip/||;t" \ - -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ - case $$dist_files in \ - */*) $(MKDIR_P) `echo "$$dist_files" | \ - sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ - sort -u` ;; \ - esac; \ - for file in $$dist_files; do \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - if test -d $$d/$$file; then \ - dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ - fi; \ - cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ - else \ - test -f $(distdir)/$$file \ - || cp -p $$d/$$file $(distdir)/$$file \ - || exit 1; \ - fi; \ - done -check-am: all-am - $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) - $(MAKE) $(AM_MAKEFLAGS) check-TESTS -check: check-am -all-am: Makefile $(LIBRARIES) -installdirs: -install: install-am -install-exec: install-exec-am -install-data: install-data-am -uninstall: uninstall-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-am -install-strip: - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - `test -z '$(STRIP)' || \ - echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install -mostlyclean-generic: - -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) - -clean-generic: - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." - -rm -f getdate.c -clean: clean-am - -clean-am: clean-checkPROGRAMS clean-generic clean-noinstLIBRARIES \ - mostlyclean-am - -distclean: distclean-am - -rm -rf $(DEPDIR) ./$(DEPDIR) - -rm -f Makefile -distclean-am: clean-am distclean-compile distclean-generic \ - distclean-local distclean-tags - -dvi: dvi-am - -dvi-am: - -html: html-am - -info: info-am - -info-am: - -install-data-am: - -install-dvi: install-dvi-am - -install-exec-am: - -install-html: install-html-am - -install-info: install-info-am - -install-man: - -install-pdf: install-pdf-am - -install-ps: install-ps-am - -installcheck-am: - -maintainer-clean: maintainer-clean-am - -rm -rf $(DEPDIR) ./$(DEPDIR) - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-am - -mostlyclean-am: mostlyclean-compile mostlyclean-generic - -pdf: pdf-am - -pdf-am: - -ps: ps-am - -ps-am: - -uninstall-am: - -.MAKE: install-am install-strip - -.PHONY: CTAGS GTAGS all all-am check check-TESTS check-am clean \ - clean-checkPROGRAMS clean-generic clean-noinstLIBRARIES ctags \ - distclean distclean-compile distclean-generic distclean-local \ - distclean-tags distdir dvi dvi-am html html-am info info-am \ - install install-am install-data install-data-am install-dvi \ - install-dvi-am install-exec install-exec-am install-html \ - install-html-am install-info install-info-am install-man \ - install-pdf install-pdf-am install-ps install-ps-am \ - install-strip installcheck installcheck-am installdirs \ - maintainer-clean maintainer-clean-generic mostlyclean \ - mostlyclean-compile mostlyclean-generic pdf pdf-am ps ps-am \ - tags uninstall uninstall-am - - -# Until Automake gets its act together -distclean-local: - rm -f fnmatch.h - -# for backwards compatibility with the old makefiles -realclean: maintainer-clean -.PHONY: realclean -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/contrib/cvs/lib/argmatch.c b/contrib/cvs/lib/argmatch.c deleted file mode 100644 index 90b44c6..0000000 --- a/contrib/cvs/lib/argmatch.c +++ /dev/null @@ -1,85 +0,0 @@ -/* argmatch.c -- find a match for a string in an array - Copyright (C) 1990 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. */ - -/* Written by David MacKenzie */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include - -#include -#ifdef STDC_HEADERS -#include -#endif - -extern char *program_name; - -/* If ARG is an unambiguous match for an element of the - null-terminated array OPTLIST, return the index in OPTLIST - of the matched element, else -1 if it does not match any element - or -2 if it is ambiguous (is a prefix of more than one element). */ - -int -argmatch (arg, optlist) - char *arg; - char **optlist; -{ - int i; /* Temporary index in OPTLIST. */ - size_t arglen; /* Length of ARG. */ - int matchind = -1; /* Index of first nonexact match. */ - int ambiguous = 0; /* If nonzero, multiple nonexact match(es). */ - - arglen = strlen (arg); - - /* Test all elements for either exact match or abbreviated matches. */ - for (i = 0; optlist[i]; i++) - { - if (!strncmp (optlist[i], arg, arglen)) - { - if (strlen (optlist[i]) == arglen) - /* Exact match found. */ - return i; - else if (matchind == -1) - /* First nonexact match found. */ - matchind = i; - else - /* Second nonexact match found. */ - ambiguous = 1; - } - } - if (ambiguous) - return -2; - else - return matchind; -} - -/* Error reporting for argmatch. - KIND is a description of the type of entity that was being matched. - VALUE is the invalid value that was given. - PROBLEM is the return value from argmatch. */ - -void -invalid_arg (kind, value, problem) - char *kind; - char *value; - int problem; -{ - fprintf (stderr, "%s: ", program_name); - if (problem == -1) - fprintf (stderr, "invalid"); - else /* Assume -2. */ - fprintf (stderr, "ambiguous"); - fprintf (stderr, " %s `%s'\n", kind, value); -} diff --git a/contrib/cvs/lib/dup2.c b/contrib/cvs/lib/dup2.c deleted file mode 100644 index 1974383..0000000 --- a/contrib/cvs/lib/dup2.c +++ /dev/null @@ -1,40 +0,0 @@ -/* - dup2 -- 7th Edition UNIX system call emulation for UNIX System V - - last edit: 11-Feb-1987 D A Gwyn -*/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include - -extern int close(), fcntl(); - -int -dup2( oldfd, newfd ) - int oldfd; /* already-open file descriptor */ - int newfd; /* desired duplicate descriptor */ -{ - register int ret; /* for fcntl() return value */ - register int save; /* for saving entry errno */ - - if ( oldfd == newfd ) - return oldfd; /* be careful not to close() */ - - save = errno; /* save entry errno */ - (void) close( newfd ); /* in case newfd is open */ - /* (may have just clobbered the original errno value) */ - - ret = fcntl( oldfd, F_DUPFD, newfd ); /* dupe it */ - - if ( ret >= 0 ) - errno = save; /* restore entry errno */ - else /* fcntl() returned error */ - if ( errno == EINVAL ) - errno = EBADF; /* we think of everything */ - - return ret; /* return file descriptor */ -} diff --git a/contrib/cvs/lib/fncase.c b/contrib/cvs/lib/fncase.c deleted file mode 100644 index 2842428..0000000 --- a/contrib/cvs/lib/fncase.c +++ /dev/null @@ -1,155 +0,0 @@ -/* fncase.c -- CVS support for case insensitive file systems. - Jim Blandy - - This file is part of GNU CVS. - - GNU CVS is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "system.h" - -/* The equivalence class mapping for filenames. - Windows NT filenames are case-insensitive, but case-preserving. - Both / and \ are path element separators. - Thus, this table maps both upper and lower case to lower case, and - both / and \ to /. */ - -#if 0 -main () -{ - int c; - - for (c = 0; c < 256; c++) - { - int t; - - if (c == '\\') - t = '/'; - else - t = tolower (c); - - if ((c & 0x7) == 0x0) - printf (" "); - printf ("0x%02x,", t); - if ((c & 0x7) == 0x7) - putchar ('\n'); - else if ((c & 0x7) == 0x3) - putchar (' '); - } -} -#endif - -/* Under Windows NT, filenames are case-insensitive but case-preserving, - and both \ and / are path element separators. */ -unsigned char -WNT_filename_classes[] = -{ - 0x00,0x01,0x02,0x03, 0x04,0x05,0x06,0x07, - 0x08,0x09,0x0a,0x0b, 0x0c,0x0d,0x0e,0x0f, - 0x10,0x11,0x12,0x13, 0x14,0x15,0x16,0x17, - 0x18,0x19,0x1a,0x1b, 0x1c,0x1d,0x1e,0x1f, - 0x20,0x21,0x22,0x23, 0x24,0x25,0x26,0x27, - 0x28,0x29,0x2a,0x2b, 0x2c,0x2d,0x2e,0x2f, - 0x30,0x31,0x32,0x33, 0x34,0x35,0x36,0x37, - 0x38,0x39,0x3a,0x3b, 0x3c,0x3d,0x3e,0x3f, - 0x40,0x61,0x62,0x63, 0x64,0x65,0x66,0x67, - 0x68,0x69,0x6a,0x6b, 0x6c,0x6d,0x6e,0x6f, - 0x70,0x71,0x72,0x73, 0x74,0x75,0x76,0x77, - 0x78,0x79,0x7a,0x5b, 0x2f,0x5d,0x5e,0x5f, - 0x60,0x61,0x62,0x63, 0x64,0x65,0x66,0x67, - 0x68,0x69,0x6a,0x6b, 0x6c,0x6d,0x6e,0x6f, - 0x70,0x71,0x72,0x73, 0x74,0x75,0x76,0x77, - 0x78,0x79,0x7a,0x7b, 0x7c,0x7d,0x7e,0x7f, - 0x80,0x81,0x82,0x83, 0x84,0x85,0x86,0x87, - 0x88,0x89,0x8a,0x8b, 0x8c,0x8d,0x8e,0x8f, - 0x90,0x91,0x92,0x93, 0x94,0x95,0x96,0x97, - 0x98,0x99,0x9a,0x9b, 0x9c,0x9d,0x9e,0x9f, - 0xa0,0xa1,0xa2,0xa3, 0xa4,0xa5,0xa6,0xa7, - 0xa8,0xa9,0xaa,0xab, 0xac,0xad,0xae,0xaf, - 0xb0,0xb1,0xb2,0xb3, 0xb4,0xb5,0xb6,0xb7, - 0xb8,0xb9,0xba,0xbb, 0xbc,0xbd,0xbe,0xbf, - 0xc0,0xc1,0xc2,0xc3, 0xc4,0xc5,0xc6,0xc7, - 0xc8,0xc9,0xca,0xcb, 0xcc,0xcd,0xce,0xcf, - 0xd0,0xd1,0xd2,0xd3, 0xd4,0xd5,0xd6,0xd7, - 0xd8,0xd9,0xda,0xdb, 0xdc,0xdd,0xde,0xdf, - 0xe0,0xe1,0xe2,0xe3, 0xe4,0xe5,0xe6,0xe7, - 0xe8,0xe9,0xea,0xeb, 0xec,0xed,0xee,0xef, - 0xf0,0xf1,0xf2,0xf3, 0xf4,0xf5,0xf6,0xf7, - 0xf8,0xf9,0xfa,0xfb, 0xfc,0xfd,0xfe,0xff, -}; - -/* Same as WNT_filename_classes, but do not fold `\' into `/'. */ -unsigned char -OSX_filename_classes[] = -{ - 0x00,0x01,0x02,0x03, 0x04,0x05,0x06,0x07, - 0x08,0x09,0x0a,0x0b, 0x0c,0x0d,0x0e,0x0f, - 0x10,0x11,0x12,0x13, 0x14,0x15,0x16,0x17, - 0x18,0x19,0x1a,0x1b, 0x1c,0x1d,0x1e,0x1f, - 0x20,0x21,0x22,0x23, 0x24,0x25,0x26,0x27, - 0x28,0x29,0x2a,0x2b, 0x2c,0x2d,0x2e,0x2f, - 0x30,0x31,0x32,0x33, 0x34,0x35,0x36,0x37, - 0x38,0x39,0x3a,0x3b, 0x3c,0x3d,0x3e,0x3f, - 0x40,0x61,0x62,0x63, 0x64,0x65,0x66,0x67, - 0x68,0x69,0x6a,0x6b, 0x6c,0x6d,0x6e,0x6f, - 0x70,0x71,0x72,0x73, 0x74,0x75,0x76,0x77, - 0x78,0x79,0x7a,0x5b, 0x5c,0x5d,0x5e,0x5f, - 0x60,0x61,0x62,0x63, 0x64,0x65,0x66,0x67, - 0x68,0x69,0x6a,0x6b, 0x6c,0x6d,0x6e,0x6f, - 0x70,0x71,0x72,0x73, 0x74,0x75,0x76,0x77, - 0x78,0x79,0x7a,0x7b, 0x7c,0x7d,0x7e,0x7f, - 0x80,0x81,0x82,0x83, 0x84,0x85,0x86,0x87, - 0x88,0x89,0x8a,0x8b, 0x8c,0x8d,0x8e,0x8f, - 0x90,0x91,0x92,0x93, 0x94,0x95,0x96,0x97, - 0x98,0x99,0x9a,0x9b, 0x9c,0x9d,0x9e,0x9f, - 0xa0,0xa1,0xa2,0xa3, 0xa4,0xa5,0xa6,0xa7, - 0xa8,0xa9,0xaa,0xab, 0xac,0xad,0xae,0xaf, - 0xb0,0xb1,0xb2,0xb3, 0xb4,0xb5,0xb6,0xb7, - 0xb8,0xb9,0xba,0xbb, 0xbc,0xbd,0xbe,0xbf, - 0xc0,0xc1,0xc2,0xc3, 0xc4,0xc5,0xc6,0xc7, - 0xc8,0xc9,0xca,0xcb, 0xcc,0xcd,0xce,0xcf, - 0xd0,0xd1,0xd2,0xd3, 0xd4,0xd5,0xd6,0xd7, - 0xd8,0xd9,0xda,0xdb, 0xdc,0xdd,0xde,0xdf, - 0xe0,0xe1,0xe2,0xe3, 0xe4,0xe5,0xe6,0xe7, - 0xe8,0xe9,0xea,0xeb, 0xec,0xed,0xee,0xef, - 0xf0,0xf1,0xf2,0xf3, 0xf4,0xf5,0xf6,0xf7, - 0xf8,0xf9,0xfa,0xfb, 0xfc,0xfd,0xfe,0xff, -}; - -/* Like strcmp, but with the appropriate tweaks for file names. - Under Windows NT, filenames are case-insensitive but case-preserving, - and both \ and / are path element separators. Under Mac OS X, filenames - are case-insensitive but case-preserving. */ -int -fncmp (const char *n1, const char *n2) -{ - while (*n1 && *n2 - && (FOLD_FN_CHAR(*n1) - == FOLD_FN_CHAR(*n2))) - n1++, n2++; - return (FOLD_FN_CHAR(*n1) - FOLD_FN_CHAR(*n2)); -} - -/* Fold characters in FILENAME to their canonical forms. - If FOLD_FN_CHAR is not #defined, the system provides a default - definition for this. */ -void -fnfold (char *filename) -{ - while (*filename) - { - *filename = FOLD_FN_CHAR (*filename); - filename++; - } -} diff --git a/contrib/cvs/lib/fnmatch.c b/contrib/cvs/lib/fnmatch.c deleted file mode 100644 index 33b25b8..0000000 --- a/contrib/cvs/lib/fnmatch.c +++ /dev/null @@ -1,181 +0,0 @@ -/* Copyright (C) 1992 Free Software Foundation, Inc. -This file is part of the GNU C Library. - -The GNU C Library is free software; you can redistribute it and/or -modify it under the terms of the GNU Library General Public License as -published by the Free Software Foundation; either version 2 of the -License, or (at your option) any later version. - -The GNU C Library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Library General Public License for more details. */ - -/* Modified slightly by Brian Berliner and - Jim Blandy for CVS use */ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include "system.h" - -/* IGNORE(@ */ -/* #include */ -/* @) */ -#include -#include "fnmatch.h" - -#if !defined(__GNU_LIBRARY__) && !defined(STDC_HEADERS) -extern int errno; -#endif - -/* Match STRING against the filename pattern PATTERN, returning zero if - it matches, nonzero if not. */ -int -#if __STDC__ -fnmatch (const char *pattern, const char *string, int flags) -#else -fnmatch (pattern, string, flags) - char *pattern; - char *string; - int flags; -#endif -{ - register const char *p = pattern, *n = string; - register char c; - - if ((flags & ~__FNM_FLAGS) != 0) - { - errno = EINVAL; - return -1; - } - - while ((c = *p++) != '\0') - { - switch (c) - { - case '?': - if (*n == '\0') - return FNM_NOMATCH; - else if ((flags & FNM_PATHNAME) && *n == '/') - return FNM_NOMATCH; - else if ((flags & FNM_PERIOD) && *n == '.' && - (n == string || ((flags & FNM_PATHNAME) && n[-1] == '/'))) - return FNM_NOMATCH; - break; - - case '\\': - if (!(flags & FNM_NOESCAPE)) - c = *p++; - if (FOLD_FN_CHAR (*n) != FOLD_FN_CHAR (c)) - return FNM_NOMATCH; - break; - - case '*': - if ((flags & FNM_PERIOD) && *n == '.' && - (n == string || ((flags & FNM_PATHNAME) && n[-1] == '/'))) - return FNM_NOMATCH; - - for (c = *p++; c == '?' || c == '*'; c = *p++, ++n) - if (((flags & FNM_PATHNAME) && *n == '/') || - (c == '?' && *n == '\0')) - return FNM_NOMATCH; - - if (c == '\0') - return 0; - - { - char c1 = (!(flags & FNM_NOESCAPE) && c == '\\') ? *p : c; - for (--p; *n != '\0'; ++n) - if ((c == '[' || FOLD_FN_CHAR (*n) == FOLD_FN_CHAR (c1)) && - fnmatch(p, n, flags & ~FNM_PERIOD) == 0) - return 0; - return FNM_NOMATCH; - } - - case '[': - { - /* Nonzero if the sense of the character class is inverted. */ - register int not; - - if (*n == '\0') - return FNM_NOMATCH; - - if ((flags & FNM_PERIOD) && *n == '.' && - (n == string || ((flags & FNM_PATHNAME) && n[-1] == '/'))) - return FNM_NOMATCH; - - not = (*p == '!' || *p == '^'); - if (not) - ++p; - - c = *p++; - for (;;) - { - register char cstart = c, cend = c; - - if (!(flags & FNM_NOESCAPE) && c == '\\') - cstart = cend = *p++; - - if (c == '\0') - /* [ (unterminated) loses. */ - return FNM_NOMATCH; - - c = *p++; - - if ((flags & FNM_PATHNAME) && c == '/') - /* [/] can never match. */ - return FNM_NOMATCH; - - if (c == '-' && *p != ']') - { - cend = *p++; - if (!(flags & FNM_NOESCAPE) && cend == '\\') - cend = *p++; - if (cend == '\0') - return FNM_NOMATCH; - c = *p++; - } - - if (*n >= cstart && *n <= cend) - goto matched; - - if (c == ']') - break; - } - if (!not) - return FNM_NOMATCH; - break; - - matched:; - /* Skip the rest of the [...] that already matched. */ - while (c != ']') - { - if (c == '\0') - /* [... (unterminated) loses. */ - return FNM_NOMATCH; - - c = *p++; - if (!(flags & FNM_NOESCAPE) && c == '\\') - /* 1003.2d11 is unclear if this is right. %%% */ - ++p; - } - if (not) - return FNM_NOMATCH; - } - break; - - default: - if (FOLD_FN_CHAR (c) != FOLD_FN_CHAR (*n)) - return FNM_NOMATCH; - } - - ++n; - } - - if (*n == '\0') - return 0; - - return FNM_NOMATCH; -} diff --git a/contrib/cvs/lib/fnmatch.h.in b/contrib/cvs/lib/fnmatch.h.in deleted file mode 100644 index 3bc04cf..0000000 --- a/contrib/cvs/lib/fnmatch.h.in +++ /dev/null @@ -1,44 +0,0 @@ -/* Copyright (C) 1992 Free Software Foundation, Inc. -This file is part of the GNU C Library. - -The GNU C Library is free software; you can redistribute it and/or -modify it under the terms of the GNU Library General Public License as -published by the Free Software Foundation; either version 2 of the -License, or (at your option) any later version. - -The GNU C Library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Library General Public License for more details. */ - -#ifndef _FNMATCH_H - -#define _FNMATCH_H 1 - -/* Bits set in the FLAGS argument to `fnmatch'. */ -#undef FNM_PATHNAME -#define FNM_PATHNAME (1 << 0)/* No wildcard can ever match `/'. */ -#undef FNM_NOESCAPE -#define FNM_NOESCAPE (1 << 1)/* Backslashes don't quote special chars. */ -#undef FNM_PERIOD -#define FNM_PERIOD (1 << 2)/* Leading `.' is matched only explicitly. */ -#undef __FNM_FLAGS -#define __FNM_FLAGS (FNM_PATHNAME|FNM_NOESCAPE|FNM_PERIOD) - -/* Value returned by `fnmatch' if STRING does not match PATTERN. */ -#undef FNM_NOMATCH -#define FNM_NOMATCH 1 - -/* For Mac OS X namespace conflicts again. Yuck... */ -#ifdef HAVE_FNMATCH_H -# define fnmatch cvs_fnmatch -#endif /* HAVE_FNMATCH_H */ -/* Match STRING against the filename pattern PATTERN, - returning zero if it matches, FNM_NOMATCH if not. */ -#if __STDC__ -extern int fnmatch (const char *pattern, const char *string, int flags); -#else -extern int fnmatch (); -#endif - -#endif /* fnmatch.h */ diff --git a/contrib/cvs/lib/ftruncate.c b/contrib/cvs/lib/ftruncate.c deleted file mode 100644 index 13f20a3..0000000 --- a/contrib/cvs/lib/ftruncate.c +++ /dev/null @@ -1,76 +0,0 @@ -/* ftruncate emulations that work on some System V's. - This file is in the public domain. */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include - -#ifdef F_CHSIZE -int -ftruncate (fd, length) - int fd; - off_t length; -{ - return fcntl (fd, F_CHSIZE, length); -} -#else -#ifdef F_FREESP -/* The following function was written by - kucharsk@Solbourne.com (William Kucharski) */ - -#include -#include -#include - -int -ftruncate (fd, length) - int fd; - off_t length; -{ - struct flock fl; - struct stat filebuf; - - if (fstat (fd, &filebuf) < 0) - return -1; - - if (filebuf.st_size < length) - { - /* Extend file length. */ - if (lseek (fd, (length - 1), SEEK_SET) < 0) - return -1; - - /* Write a "0" byte. */ - if (write (fd, "", 1) != 1) - return -1; - } - else - { - /* Truncate length. */ - fl.l_whence = 0; - fl.l_len = 0; - fl.l_start = length; - fl.l_type = F_WRLCK; /* Write lock on file space. */ - - /* This relies on the UNDOCUMENTED F_FREESP argument to - fcntl, which truncates the file so that it ends at the - position indicated by fl.l_start. - Will minor miracles never cease? */ - if (fcntl (fd, F_FREESP, &fl) < 0) - return -1; - } - - return 0; -} -#else -int -ftruncate (fd, length) - int fd; - off_t length; -{ - return chsize (fd, length); -} -#endif -#endif diff --git a/contrib/cvs/lib/getdate.y b/contrib/cvs/lib/getdate.y deleted file mode 100644 index 0e128d7..0000000 --- a/contrib/cvs/lib/getdate.y +++ /dev/null @@ -1,1030 +0,0 @@ -%{ -/* -** Originally written by Steven M. Bellovin while -** at the University of North Carolina at Chapel Hill. Later tweaked by -** a couple of people on Usenet. Completely overhauled by Rich $alz -** and Jim Berets in August, 1990; -** -** This grammar has 10 shift/reduce conflicts. -** -** This code is in the public domain and has no copyright. -*/ -/* SUPPRESS 287 on yaccpar_sccsid *//* Unused static variable */ -/* SUPPRESS 288 on yyerrlab *//* Label unused */ - -#ifdef HAVE_CONFIG_H -#if defined (emacs) || defined (CONFIG_BROKETS) -#include -#else -#include "config.h" -#endif -#endif - -/* Since the code of getdate.y is not included in the Emacs executable - itself, there is no need to #define static in this file. Even if - the code were included in the Emacs executable, it probably - wouldn't do any harm to #undef it here; this will only cause - problems if we try to write to a static variable, which I don't - think this code needs to do. */ -#ifdef emacs -#undef static -#endif - -#include -#include - -/* The code at the top of get_date which figures out the offset of the - current time zone checks various CPP symbols to see if special - tricks are need, but defaults to using the gettimeofday system call. - Include if that will be used. */ - -#if defined(vms) -# include -#else /* defined(vms) */ -# include -#endif /* !defined(vms) */ -# include "xtime.h" - -#if defined (STDC_HEADERS) || defined (USG) -#include -#endif - -/* Some old versions of bison generate parsers that use bcopy. - That loses on systems that don't provide the function, so we have - to redefine it here. */ -#if !defined (HAVE_BCOPY) && defined (HAVE_MEMCPY) && !defined (bcopy) -#define bcopy(from, to, len) memcpy ((to), (from), (len)) -#endif - -#if defined (STDC_HEADERS) -#include -#endif - -/* NOTES on rebuilding getdate.c (particularly for inclusion in CVS - releases): - - We don't want to mess with all the portability hassles of alloca. - In particular, most (all?) versions of bison will use alloca in - their parser. If bison works on your system (e.g. it should work - with gcc), then go ahead and use it, but the more general solution - is to use byacc instead of bison, which should generate a portable - parser. I played with adding "#define alloca dont_use_alloca", to - give an error if the parser generator uses alloca (and thus detect - unportable getdate.c's), but that seems to cause as many problems - as it solves. */ - -extern struct tm *gmtime(); -extern struct tm *localtime(); - -#define yyparse getdate_yyparse -#define yylex getdate_yylex -#define yyerror getdate_yyerror - -static int yyparse (); -static int yylex (); -static int yyerror (); - -#define EPOCH 1970 -#define HOUR(x) ((time_t)(x) * 60) -#define SECSPERDAY (24L * 60L * 60L) - - -/* -** An entry in the lexical lookup table. -*/ -typedef struct _TABLE { - char *name; - int type; - time_t value; -} TABLE; - - -/* -** Daylight-savings mode: on, off, or not yet known. -*/ -typedef enum _DSTMODE { - DSTon, DSToff, DSTmaybe -} DSTMODE; - -/* -** Meridian: am, pm, or 24-hour style. -*/ -typedef enum _MERIDIAN { - MERam, MERpm, MER24 -} MERIDIAN; - - -/* -** Global variables. We could get rid of most of these by using a good -** union as the yacc stack. (This routine was originally written before -** yacc had the %union construct.) Maybe someday; right now we only use -** the %union very rarely. -*/ -static char *yyInput; -static DSTMODE yyDSTmode; -static time_t yyDayOrdinal; -static time_t yyDayNumber; -static int yyHaveDate; -static int yyHaveDay; -static int yyHaveRel; -static int yyHaveTime; -static int yyHaveZone; -static time_t yyTimezone; -static time_t yyDay; -static time_t yyHour; -static time_t yyMinutes; -static time_t yyMonth; -static time_t yySeconds; -static time_t yyYear; -static MERIDIAN yyMeridian; -static time_t yyRelMonth; -static time_t yyRelSeconds; - -%} - -%union { - time_t Number; - enum _MERIDIAN Meridian; -} - -%token tAGO tDAY tDAYZONE tID tMERIDIAN tMINUTE_UNIT tMONTH tMONTH_UNIT -%token tSEC_UNIT tSNUMBER tUNUMBER tZONE tDST - -%type tDAY tDAYZONE tMINUTE_UNIT tMONTH tMONTH_UNIT -%type tSEC_UNIT tSNUMBER tUNUMBER tZONE -%type tMERIDIAN o_merid - -%% - -spec : /* NULL */ - | spec item - ; - -item : time { - yyHaveTime++; - } - | zone { - yyHaveZone++; - } - | date { - yyHaveDate++; - } - | day { - yyHaveDay++; - } - | rel { - yyHaveRel++; - } - | cvsstamp { - yyHaveTime++; - yyHaveDate++; - yyHaveZone++; - } - | number - ; - -cvsstamp: tUNUMBER '.' tUNUMBER '.' tUNUMBER '.' tUNUMBER '.' tUNUMBER '.' tUNUMBER { - yyYear = $1; - if (yyYear < 100) yyYear += 1900; - yyMonth = $3; - yyDay = $5; - yyHour = $7; - yyMinutes = $9; - yySeconds = $11; - yyDSTmode = DSToff; - yyTimezone = 0; - } - ; - -time : tUNUMBER tMERIDIAN { - yyHour = $1; - yyMinutes = 0; - yySeconds = 0; - yyMeridian = $2; - } - | tUNUMBER ':' tUNUMBER o_merid { - yyHour = $1; - yyMinutes = $3; - yySeconds = 0; - yyMeridian = $4; - } - | tUNUMBER ':' tUNUMBER tSNUMBER { - yyHour = $1; - yyMinutes = $3; - yyMeridian = MER24; - yyDSTmode = DSToff; - yyTimezone = - ($4 % 100 + ($4 / 100) * 60); - } - | tUNUMBER ':' tUNUMBER ':' tUNUMBER o_merid { - yyHour = $1; - yyMinutes = $3; - yySeconds = $5; - yyMeridian = $6; - } - | tUNUMBER ':' tUNUMBER ':' tUNUMBER tSNUMBER { - yyHour = $1; - yyMinutes = $3; - yySeconds = $5; - yyMeridian = MER24; - yyDSTmode = DSToff; - yyTimezone = - ($6 % 100 + ($6 / 100) * 60); - } - ; - -zone : tZONE { - yyTimezone = $1; - yyDSTmode = DSToff; - } - | tDAYZONE { - yyTimezone = $1; - yyDSTmode = DSTon; - } - | - tZONE tDST { - yyTimezone = $1; - yyDSTmode = DSTon; - } - ; - -day : tDAY { - yyDayOrdinal = 1; - yyDayNumber = $1; - } - | tDAY ',' { - yyDayOrdinal = 1; - yyDayNumber = $1; - } - | tUNUMBER tDAY { - yyDayOrdinal = $1; - yyDayNumber = $2; - } - ; - -date : tUNUMBER '/' tUNUMBER { - yyMonth = $1; - yyDay = $3; - } - | tUNUMBER '/' tUNUMBER '/' tUNUMBER { - 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. */ - yyYear = $1; - yyMonth = -$2; - yyDay = -$3; - } - | tUNUMBER tMONTH tSNUMBER { - /* e.g. 17-JUN-1992. */ - yyDay = $1; - yyMonth = $2; - yyYear = -$3; - } - | tMONTH tUNUMBER { - yyMonth = $1; - yyDay = $2; - } - | tMONTH tUNUMBER ',' tUNUMBER { - yyMonth = $1; - yyDay = $2; - yyYear = $4; - } - | tUNUMBER tMONTH { - yyMonth = $2; - yyDay = $1; - } - | tUNUMBER tMONTH tUNUMBER { - yyMonth = $2; - yyDay = $1; - yyYear = $3; - } - ; - -rel : relunit tAGO { - yyRelSeconds = -yyRelSeconds; - yyRelMonth = -yyRelMonth; - } - | relunit - ; - -relunit : tUNUMBER tMINUTE_UNIT { - yyRelSeconds += $1 * $2 * 60L; - } - | tSNUMBER tMINUTE_UNIT { - yyRelSeconds += $1 * $2 * 60L; - } - | tMINUTE_UNIT { - yyRelSeconds += $1 * 60L; - } - | tSNUMBER tSEC_UNIT { - yyRelSeconds += $1; - } - | tUNUMBER tSEC_UNIT { - yyRelSeconds += $1; - } - | tSEC_UNIT { - yyRelSeconds++; - } - | tSNUMBER tMONTH_UNIT { - yyRelMonth += $1 * $2; - } - | tUNUMBER tMONTH_UNIT { - yyRelMonth += $1 * $2; - } - | tMONTH_UNIT { - yyRelMonth += $1; - } - ; - -number : tUNUMBER { - if (yyHaveTime && yyHaveDate && !yyHaveRel) - yyYear = $1; - else { - if($1>10000) { - yyHaveDate++; - yyDay= ($1)%100; - yyMonth= ($1/100)%100; - yyYear = $1/10000; - } - else { - yyHaveTime++; - if ($1 < 100) { - yyHour = $1; - yyMinutes = 0; - } - else { - yyHour = $1 / 100; - yyMinutes = $1 % 100; - } - yySeconds = 0; - yyMeridian = MER24; - } - } - } - ; - -o_merid : /* NULL */ { - $$ = MER24; - } - | tMERIDIAN { - $$ = $1; - } - ; - -%% - -/* Month and day table. */ -static TABLE const MonthDayTable[] = { - { "january", tMONTH, 1 }, - { "february", tMONTH, 2 }, - { "march", tMONTH, 3 }, - { "april", tMONTH, 4 }, - { "may", tMONTH, 5 }, - { "june", tMONTH, 6 }, - { "july", tMONTH, 7 }, - { "august", tMONTH, 8 }, - { "september", tMONTH, 9 }, - { "sept", tMONTH, 9 }, - { "october", tMONTH, 10 }, - { "november", tMONTH, 11 }, - { "december", tMONTH, 12 }, - { "sunday", tDAY, 0 }, - { "monday", tDAY, 1 }, - { "tuesday", tDAY, 2 }, - { "tues", tDAY, 2 }, - { "wednesday", tDAY, 3 }, - { "wednes", tDAY, 3 }, - { "thursday", tDAY, 4 }, - { "thur", tDAY, 4 }, - { "thurs", tDAY, 4 }, - { "friday", tDAY, 5 }, - { "saturday", tDAY, 6 }, - { NULL } -}; - -/* Time units table. */ -static TABLE const UnitsTable[] = { - { "year", tMONTH_UNIT, 12 }, - { "month", tMONTH_UNIT, 1 }, - { "fortnight", tMINUTE_UNIT, 14 * 24 * 60 }, - { "week", tMINUTE_UNIT, 7 * 24 * 60 }, - { "day", tMINUTE_UNIT, 1 * 24 * 60 }, - { "hour", tMINUTE_UNIT, 60 }, - { "minute", tMINUTE_UNIT, 1 }, - { "min", tMINUTE_UNIT, 1 }, - { "second", tSEC_UNIT, 1 }, - { "sec", tSEC_UNIT, 1 }, - { NULL } -}; - -/* Assorted relative-time words. */ -static TABLE const OtherTable[] = { - { "tomorrow", tMINUTE_UNIT, 1 * 24 * 60 }, - { "yesterday", tMINUTE_UNIT, -1 * 24 * 60 }, - { "today", tMINUTE_UNIT, 0 }, - { "now", tMINUTE_UNIT, 0 }, - { "last", tUNUMBER, -1 }, - { "this", tMINUTE_UNIT, 0 }, - { "next", tUNUMBER, 2 }, - { "first", tUNUMBER, 1 }, -/* { "second", tUNUMBER, 2 }, */ - { "third", tUNUMBER, 3 }, - { "fourth", tUNUMBER, 4 }, - { "fifth", tUNUMBER, 5 }, - { "sixth", tUNUMBER, 6 }, - { "seventh", tUNUMBER, 7 }, - { "eighth", tUNUMBER, 8 }, - { "ninth", tUNUMBER, 9 }, - { "tenth", tUNUMBER, 10 }, - { "eleventh", tUNUMBER, 11 }, - { "twelfth", tUNUMBER, 12 }, - { "ago", tAGO, 1 }, - { NULL } -}; - -/* The timezone table. */ -/* Some of these are commented out because a time_t can't store a float. */ -static TABLE const TimezoneTable[] = { - { "gmt", tZONE, HOUR( 0) }, /* Greenwich Mean */ - { "ut", tZONE, HOUR( 0) }, /* Universal (Coordinated) */ - { "utc", tZONE, HOUR( 0) }, - { "wet", tZONE, HOUR( 0) }, /* Western European */ - { "bst", tDAYZONE, HOUR( 0) }, /* British Summer */ - { "wat", tZONE, HOUR( 1) }, /* West Africa */ - { "at", tZONE, HOUR( 2) }, /* Azores */ -#if 0 - /* For completeness. BST is also British Summer, and GST is - * also Guam Standard. */ - { "bst", tZONE, HOUR( 3) }, /* Brazil Standard */ - { "gst", tZONE, HOUR( 3) }, /* Greenland Standard */ -#endif -#if 0 - { "nft", tZONE, HOUR(3.5) }, /* Newfoundland */ - { "nst", tZONE, HOUR(3.5) }, /* Newfoundland Standard */ - { "ndt", tDAYZONE, HOUR(3.5) }, /* Newfoundland Daylight */ -#endif - { "ast", tZONE, HOUR( 4) }, /* Atlantic Standard */ - { "adt", tDAYZONE, HOUR( 4) }, /* Atlantic Daylight */ - { "est", tZONE, HOUR( 5) }, /* Eastern Standard */ - { "edt", tDAYZONE, HOUR( 5) }, /* Eastern Daylight */ - { "cst", tZONE, HOUR( 6) }, /* Central Standard */ - { "cdt", tDAYZONE, HOUR( 6) }, /* Central Daylight */ - { "mst", tZONE, HOUR( 7) }, /* Mountain Standard */ - { "mdt", tDAYZONE, HOUR( 7) }, /* Mountain Daylight */ - { "pst", tZONE, HOUR( 8) }, /* Pacific Standard */ - { "pdt", tDAYZONE, HOUR( 8) }, /* Pacific Daylight */ - { "yst", tZONE, HOUR( 9) }, /* Yukon Standard */ - { "ydt", tDAYZONE, HOUR( 9) }, /* Yukon Daylight */ - { "hst", tZONE, HOUR(10) }, /* Hawaii Standard */ - { "hdt", tDAYZONE, HOUR(10) }, /* Hawaii Daylight */ - { "cat", tZONE, HOUR(10) }, /* Central Alaska */ - { "ahst", tZONE, HOUR(10) }, /* Alaska-Hawaii Standard */ - { "nt", tZONE, HOUR(11) }, /* Nome */ - { "idlw", tZONE, HOUR(12) }, /* International Date Line West */ - { "cet", tZONE, -HOUR(1) }, /* Central European */ - { "met", tZONE, -HOUR(1) }, /* Middle European */ - { "mewt", tZONE, -HOUR(1) }, /* Middle European Winter */ - { "mest", tDAYZONE, -HOUR(1) }, /* Middle European Summer */ - { "swt", tZONE, -HOUR(1) }, /* Swedish Winter */ - { "sst", tDAYZONE, -HOUR(1) }, /* Swedish Summer */ - { "fwt", tZONE, -HOUR(1) }, /* French Winter */ - { "fst", tDAYZONE, -HOUR(1) }, /* French Summer */ - { "eet", tZONE, -HOUR(2) }, /* Eastern Europe, USSR Zone 1 */ - { "bt", tZONE, -HOUR(3) }, /* Baghdad, USSR Zone 2 */ -#if 0 - { "it", tZONE, -HOUR(3.5) },/* Iran */ -#endif - { "zp4", tZONE, -HOUR(4) }, /* USSR Zone 3 */ - { "zp5", tZONE, -HOUR(5) }, /* USSR Zone 4 */ -#if 0 - { "ist", tZONE, -HOUR(5.5) },/* Indian Standard */ -#endif - { "zp6", tZONE, -HOUR(6) }, /* USSR Zone 5 */ -#if 0 - /* For completeness. NST is also Newfoundland Stanard, and SST is - * also Swedish Summer. */ - { "nst", tZONE, -HOUR(6.5) },/* North Sumatra */ - { "sst", tZONE, -HOUR(7) }, /* South Sumatra, USSR Zone 6 */ -#endif /* 0 */ - { "wast", tZONE, -HOUR(7) }, /* West Australian Standard */ - { "wadt", tDAYZONE, -HOUR(7) }, /* West Australian Daylight */ -#if 0 - { "jt", tZONE, -HOUR(7.5) },/* Java (3pm in Cronusland!) */ -#endif - { "cct", tZONE, -HOUR(8) }, /* China Coast, USSR Zone 7 */ - { "jst", tZONE, -HOUR(9) }, /* Japan Standard, USSR Zone 8 */ -#if 0 - { "cast", tZONE, -HOUR(9.5) },/* Central Australian Standard */ - { "cadt", tDAYZONE, -HOUR(9.5) },/* Central Australian Daylight */ -#endif - { "east", tZONE, -HOUR(10) }, /* Eastern Australian Standard */ - { "eadt", tDAYZONE, -HOUR(10) }, /* Eastern Australian Daylight */ - { "gst", tZONE, -HOUR(10) }, /* Guam Standard, USSR Zone 9 */ - { "nzt", tZONE, -HOUR(12) }, /* New Zealand */ - { "nzst", tZONE, -HOUR(12) }, /* New Zealand Standard */ - { "nzdt", tDAYZONE, -HOUR(12) }, /* New Zealand Daylight */ - { "idle", tZONE, -HOUR(12) }, /* International Date Line East */ - { NULL } -}; - -/* Military timezone table. */ -static TABLE const MilitaryTable[] = { - { "a", tZONE, HOUR( 1) }, - { "b", tZONE, HOUR( 2) }, - { "c", tZONE, HOUR( 3) }, - { "d", tZONE, HOUR( 4) }, - { "e", tZONE, HOUR( 5) }, - { "f", tZONE, HOUR( 6) }, - { "g", tZONE, HOUR( 7) }, - { "h", tZONE, HOUR( 8) }, - { "i", tZONE, HOUR( 9) }, - { "k", tZONE, HOUR( 10) }, - { "l", tZONE, HOUR( 11) }, - { "m", tZONE, HOUR( 12) }, - { "n", tZONE, HOUR(- 1) }, - { "o", tZONE, HOUR(- 2) }, - { "p", tZONE, HOUR(- 3) }, - { "q", tZONE, HOUR(- 4) }, - { "r", tZONE, HOUR(- 5) }, - { "s", tZONE, HOUR(- 6) }, - { "t", tZONE, HOUR(- 7) }, - { "u", tZONE, HOUR(- 8) }, - { "v", tZONE, HOUR(- 9) }, - { "w", tZONE, HOUR(-10) }, - { "x", tZONE, HOUR(-11) }, - { "y", tZONE, HOUR(-12) }, - { "z", tZONE, HOUR( 0) }, - { NULL } -}; - - - - -/* ARGSUSED */ -static int -yyerror(s) - char *s; -{ - return 0; -} - - -static time_t -ToSeconds(Hours, Minutes, Seconds, Meridian) - time_t Hours; - time_t Minutes; - time_t Seconds; - MERIDIAN Meridian; -{ - if (Minutes < 0 || Minutes > 59 || Seconds < 0 || Seconds > 59) - return -1; - switch (Meridian) { - case MER24: - if (Hours < 0 || Hours > 23) - return -1; - return (Hours * 60L + Minutes) * 60L + Seconds; - case MERam: - if (Hours < 1 || Hours > 12) - return -1; - if (Hours == 12) - Hours = 0; - return (Hours * 60L + Minutes) * 60L + Seconds; - case MERpm: - if (Hours < 1 || Hours > 12) - return -1; - if (Hours == 12) - Hours = 0; - return ((Hours + 12) * 60L + Minutes) * 60L + Seconds; - default: - abort (); - } - /* NOTREACHED */ -} - - -/* Year is either - * A negative number, which means to use its absolute value (why?) - * A number from 0 to 99, which means a year from 1900 to 1999, or - * The actual year (>=100). */ -static time_t -Convert(Month, Day, Year, Hours, Minutes, Seconds, Meridian, DSTmode) - time_t Month; - time_t Day; - time_t Year; - time_t Hours; - time_t Minutes; - time_t Seconds; - MERIDIAN Meridian; - DSTMODE DSTmode; -{ - static int DaysInMonth[12] = { - 31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 - }; - time_t tod; - time_t Julian; - int i; - - if (Year < 0) - Year = -Year; - if (Year < 69) - Year += 2000; - else if (Year < 100) - Year += 1900; - DaysInMonth[1] = Year % 4 == 0 && (Year % 100 != 0 || Year % 400 == 0) - ? 29 : 28; - /* Checking for 2038 bogusly assumes that time_t is 32 bits. But - I'm too lazy to try to check for time_t overflow in another way. */ - if (Year < EPOCH || Year > 2038 - || Month < 1 || Month > 12 - /* Lint fluff: "conversion from long may lose accuracy" */ - || Day < 1 || Day > DaysInMonth[(int)--Month]) - /* FIXME: - * It would be nice to set a global error string here. - * "February 30 is not a valid date" is much more informative than - * "Can't parse date/time: 100 months" when the user input was - * "100 months" and addition resolved that to February 30, for - * example. See rcs2-7 in src/sanity.sh for more. */ - return -1; - - for (Julian = Day - 1, i = 0; i < Month; i++) - Julian += DaysInMonth[i]; - for (i = EPOCH; i < Year; i++) - Julian += 365 + (i % 4 == 0); - Julian *= SECSPERDAY; - Julian += yyTimezone * 60L; - if ((tod = ToSeconds(Hours, Minutes, Seconds, Meridian)) < 0) - return -1; - Julian += tod; - if (DSTmode == DSTon - || (DSTmode == DSTmaybe && localtime(&Julian)->tm_isdst)) - Julian -= 60 * 60; - return Julian; -} - - -static time_t -DSTcorrect(Start, Future) - time_t Start; - time_t Future; -{ - time_t StartDay; - time_t FutureDay; - - StartDay = (localtime(&Start)->tm_hour + 1) % 24; - FutureDay = (localtime(&Future)->tm_hour + 1) % 24; - return (Future - Start) + (StartDay - FutureDay) * 60L * 60L; -} - - -static time_t -RelativeDate(Start, DayOrdinal, DayNumber) - time_t Start; - time_t DayOrdinal; - time_t DayNumber; -{ - struct tm *tm; - time_t now; - - now = Start; - tm = localtime(&now); - now += SECSPERDAY * ((DayNumber - tm->tm_wday + 7) % 7); - now += 7 * SECSPERDAY * (DayOrdinal <= 0 ? DayOrdinal : DayOrdinal - 1); - return DSTcorrect(Start, now); -} - - -static time_t -RelativeMonth(Start, RelMonth) - time_t Start; - time_t RelMonth; -{ - struct tm *tm; - time_t Month; - time_t Year; - - if (RelMonth == 0) - return 0; - tm = localtime(&Start); - Month = 12 * (tm->tm_year + 1900) + tm->tm_mon + RelMonth; - Year = Month / 12; - Month = Month % 12 + 1; - return DSTcorrect(Start, - Convert(Month, (time_t)tm->tm_mday, Year, - (time_t)tm->tm_hour, (time_t)tm->tm_min, (time_t)tm->tm_sec, - MER24, DSTmaybe)); -} - - -static int -LookupWord(buff) - char *buff; -{ - register char *p; - register char *q; - register const TABLE *tp; - int i; - int abbrev; - - /* Make it lowercase. */ - for (p = buff; *p; p++) - if (isupper(*p)) - *p = tolower(*p); - - if (strcmp(buff, "am") == 0 || strcmp(buff, "a.m.") == 0) { - yylval.Meridian = MERam; - return tMERIDIAN; - } - if (strcmp(buff, "pm") == 0 || strcmp(buff, "p.m.") == 0) { - yylval.Meridian = MERpm; - return tMERIDIAN; - } - - /* See if we have an abbreviation for a month. */ - if (strlen(buff) == 3) - abbrev = 1; - else if (strlen(buff) == 4 && buff[3] == '.') { - abbrev = 1; - buff[3] = '\0'; - } - else - abbrev = 0; - - for (tp = MonthDayTable; tp->name; tp++) { - if (abbrev) { - if (strncmp(buff, tp->name, 3) == 0) { - yylval.Number = tp->value; - return tp->type; - } - } - else if (strcmp(buff, tp->name) == 0) { - yylval.Number = tp->value; - return tp->type; - } - } - - for (tp = TimezoneTable; tp->name; tp++) - if (strcmp(buff, tp->name) == 0) { - yylval.Number = tp->value; - return tp->type; - } - - if (strcmp(buff, "dst") == 0) - return tDST; - - for (tp = UnitsTable; tp->name; tp++) - if (strcmp(buff, tp->name) == 0) { - yylval.Number = tp->value; - return tp->type; - } - - /* Strip off any plural and try the units table again. */ - i = strlen(buff) - 1; - if (buff[i] == 's') { - buff[i] = '\0'; - for (tp = UnitsTable; tp->name; tp++) - if (strcmp(buff, tp->name) == 0) { - yylval.Number = tp->value; - return tp->type; - } - buff[i] = 's'; /* Put back for "this" in OtherTable. */ - } - - for (tp = OtherTable; tp->name; tp++) - if (strcmp(buff, tp->name) == 0) { - yylval.Number = tp->value; - return tp->type; - } - - /* Military timezones. */ - if (buff[1] == '\0' && isalpha(*buff)) { - for (tp = MilitaryTable; tp->name; tp++) - if (strcmp(buff, tp->name) == 0) { - yylval.Number = tp->value; - return tp->type; - } - } - - /* Drop out any periods and try the timezone table again. */ - for (i = 0, p = q = buff; *q; q++) - if (*q != '.') - *p++ = *q; - else - i++; - *p = '\0'; - if (i) - for (tp = TimezoneTable; tp->name; tp++) - if (strcmp(buff, tp->name) == 0) { - yylval.Number = tp->value; - return tp->type; - } - - return tID; -} - - -static int -yylex() -{ - register char c; - register char *p; - char buff[20]; - int Count; - int sign; - - for ( ; ; ) { - while (isspace(*yyInput)) - yyInput++; - - if (isdigit(c = *yyInput) || c == '-' || c == '+') { - if (c == '-' || c == '+') { - sign = c == '-' ? -1 : 1; - if (!isdigit(*++yyInput)) - /* skip the '-' sign */ - continue; - } - else - sign = 0; - for (yylval.Number = 0; isdigit(c = *yyInput++); ) - yylval.Number = 10 * yylval.Number + c - '0'; - yyInput--; - if (sign < 0) - yylval.Number = -yylval.Number; - return sign ? tSNUMBER : tUNUMBER; - } - if (isalpha(c)) { - for (p = buff; isalpha(c = *yyInput++) || c == '.'; ) - if (p < &buff[sizeof buff - 1]) - *p++ = c; - *p = '\0'; - yyInput--; - return LookupWord(buff); - } - if (c != '(') - return *yyInput++; - Count = 0; - do { - c = *yyInput++; - if (c == '\0') - return c; - if (c == '(') - Count++; - else if (c == ')') - Count--; - } while (Count > 0); - } -} - -#define TM_YEAR_ORIGIN 1900 - -/* Yield A - B, measured in seconds. */ -static long -difftm (a, b) - struct tm *a, *b; -{ - int ay = a->tm_year + (TM_YEAR_ORIGIN - 1); - int by = b->tm_year + (TM_YEAR_ORIGIN - 1); - int days = ( - /* difference in day of year */ - a->tm_yday - b->tm_yday - /* + intervening leap days */ - + ((ay >> 2) - (by >> 2)) - - (ay/100 - by/100) - + ((ay/100 >> 2) - (by/100 >> 2)) - /* + difference in years * 365 */ - + (long)(ay-by) * 365 - ); - return (60*(60*(24*days + (a->tm_hour - b->tm_hour)) - + (a->tm_min - b->tm_min)) - + (a->tm_sec - b->tm_sec)); -} - -time_t -get_date(p, now) - char *p; - struct timeb *now; -{ - struct tm *tm, gmt; - struct timeb ftz; - time_t Start; - time_t tod; - time_t nowtime; - - yyInput = p; - if (now == NULL) { - struct tm *gmt_ptr; - - now = &ftz; - (void)time (&nowtime); - - gmt_ptr = gmtime (&nowtime); - if (gmt_ptr != NULL) - { - /* Make a copy, in case localtime modifies *tm (I think - that comment now applies to *gmt_ptr, but I am too - lazy to dig into how gmtime and locatime allocate the - structures they return pointers to). */ - gmt = *gmt_ptr; - } - - if (! (tm = localtime (&nowtime))) - return -1; - - if (gmt_ptr != NULL) - ftz.timezone = difftm (&gmt, tm) / 60; - else - /* We are on a system like VMS, where the system clock is - in local time and the system has no concept of timezones. - Hopefully we can fake this out (for the case in which the - user specifies no timezone) by just saying the timezone - is zero. */ - ftz.timezone = 0; - - if(tm->tm_isdst) - ftz.timezone += 60; - } - else - { - nowtime = now->time; - } - - tm = localtime(&nowtime); - yyYear = tm->tm_year + 1900; - yyMonth = tm->tm_mon + 1; - yyDay = tm->tm_mday; - yyTimezone = now->timezone; - yyDSTmode = DSTmaybe; - yyHour = 0; - yyMinutes = 0; - yySeconds = 0; - yyMeridian = MER24; - yyRelSeconds = 0; - yyRelMonth = 0; - yyHaveDate = 0; - yyHaveDay = 0; - yyHaveRel = 0; - yyHaveTime = 0; - yyHaveZone = 0; - - if (yyparse() - || yyHaveTime > 1 || yyHaveZone > 1 || yyHaveDate > 1 || yyHaveDay > 1) - return -1; - - if (yyHaveDate || yyHaveTime || yyHaveDay) { - Start = Convert(yyMonth, yyDay, yyYear, yyHour, yyMinutes, yySeconds, - yyMeridian, yyDSTmode); - if (Start < 0) - return -1; - } - else { - Start = nowtime; - if (!yyHaveRel) - Start -= ((tm->tm_hour * 60L + tm->tm_min) * 60L) + tm->tm_sec; - } - - Start += yyRelSeconds; - Start += RelativeMonth(Start, yyRelMonth); - - if (yyHaveDay && !yyHaveDate) { - tod = RelativeDate(Start, yyDayOrdinal, yyDayNumber); - Start += tod; - } - - /* Have to do *something* with a legitimate -1 so it's distinguishable - * from the error return value. (Alternately could set errno on error.) */ - return Start == -1 ? 0 : Start; -} - - -#if defined(TEST) - -/* ARGSUSED */ -int -main(ac, av) - int ac; - char *av[]; -{ - char buff[128]; - time_t d; - - (void)printf("Enter date, or blank line to exit.\n\t> "); - (void)fflush(stdout); - while (gets(buff) && buff[0]) { - d = get_date(buff, (struct timeb *)NULL); - if (d == -1) - (void)printf("Bad format - couldn't convert.\n"); - else - (void)printf("%s", ctime(&d)); - (void)printf("\t> "); - (void)fflush(stdout); - } - exit(0); - /* NOTREACHED */ -} -#endif /* defined(TEST) */ diff --git a/contrib/cvs/lib/gethostname.c b/contrib/cvs/lib/gethostname.c deleted file mode 100644 index 7fde534..0000000 --- a/contrib/cvs/lib/gethostname.c +++ /dev/null @@ -1,45 +0,0 @@ -/* hostname.c -- use uname() to get the name of the host - Copyright (C) 1992 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#if defined(STDC_HEADERS) || defined(USG) -#include -#ifndef index -#define index strchr -#endif -#else -#include -#endif - -#include - -/* Put this host's name into NAME, using at most NAMELEN characters */ - -int -gethostname(name, namelen) - char *name; - int namelen; -{ - struct utsname ugnm; - - if (uname(&ugnm) < 0) - return (-1); - - (void) strncpy(name, ugnm.nodename, namelen-1); - name[namelen-1] = '\0'; - - return (0); -} diff --git a/contrib/cvs/lib/getline.c b/contrib/cvs/lib/getline.c deleted file mode 100644 index 9830b4d..0000000 --- a/contrib/cvs/lib/getline.c +++ /dev/null @@ -1,174 +0,0 @@ -/* getline.c -- Replacement for GNU C library function getline - -Copyright (C) 1993 Free Software Foundation, Inc. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License as -published by the Free Software Foundation; either version 2 of the -License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -General Public License for more details. */ - -/* Written by Jan Brittenson, bson@gnu.ai.mit.edu. */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include -#include -#include -#include "getline.h" - -#if STDC_HEADERS -#include -#else -char *malloc (), *realloc (); -#endif - -/* Always add at least this many bytes when extending the buffer. */ -#define MIN_CHUNK 64 - -/* Read up to (and including) a TERMINATOR from STREAM into *LINEPTR - + 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, limit) - char **lineptr; - size_t *n; - FILE *stream; - int terminator; - int offset; - int limit; -{ - int nchars_avail; /* Allocated but unused chars in *LINEPTR. */ - char *read_pos; /* Where we're reading into *LINEPTR. */ - int ret; - - if (!lineptr || !n || !stream) - { - errno = EINVAL; - return -1; - } - - if (!*lineptr) - { - *n = MIN_CHUNK; - *lineptr = malloc (*n); - if (!*lineptr) - { - errno = ENOMEM; - return -1; - } - *lineptr[0] = '\0'; - } - - nchars_avail = *n - offset; - read_pos = *lineptr + offset; - - for (;;) - { - int save_errno; - 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; - - /* We always want at least one char left in the buffer, since we - always (unless we get an error while reading the first char) - NUL-terminate the line buffer. */ - - assert((*lineptr + *n) == (read_pos + nchars_avail)); - if (nchars_avail < 2) - { - if (*n > MIN_CHUNK) - *n *= 2; - else - *n += MIN_CHUNK; - - nchars_avail = *n + *lineptr - read_pos; - *lineptr = realloc (*lineptr, *n); - if (!*lineptr) - { - errno = ENOMEM; - return -1; - } - read_pos = *n - nchars_avail + *lineptr; - assert((*lineptr + *n) == (read_pos + nchars_avail)); - } - - if (ferror (stream)) - { - /* Might like to return partial line, but there is no - place for us to store errno. And we don't want to just - lose errno. */ - errno = save_errno; - return -1; - } - - if (c == EOF) - { - /* Return partial line, if any. */ - if (read_pos == *lineptr) - return -1; - else - break; - } - - *read_pos++ = c; - nchars_avail--; - - if (c == terminator) - /* Return the line. */ - break; - } - - /* Done - NUL terminate and return the number of chars read. */ - *read_pos = '\0'; - - ret = read_pos - (*lineptr + offset); - return ret; -} - -int -getline (lineptr, n, stream) - char **lineptr; - size_t *n; - FILE *stream; -{ - 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); -} diff --git a/contrib/cvs/lib/getline.h b/contrib/cvs/lib/getline.h deleted file mode 100644 index 3bbad56..0000000 --- a/contrib/cvs/lib/getline.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef _getline_h_ -#define _getline_h_ 1 - -#include - -#if defined (__GNUC__) || (defined (__STDC__) && __STDC__) -#define __PROTO(args) args -#else -#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, - int _terminator, int _offset, int limit)); - -#endif /* _getline_h_ */ diff --git a/contrib/cvs/lib/getopt.c b/contrib/cvs/lib/getopt.c deleted file mode 100644 index b5caccd..0000000 --- a/contrib/cvs/lib/getopt.c +++ /dev/null @@ -1,755 +0,0 @@ -/* Getopt for GNU. - NOTE: getopt is now part of the C library, so if you don't know what - "Keep this file name-space clean" means, talk to roland@gnu.ai.mit.edu - before changing it! - - Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94 - Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. */ - -/* This tells Alpha OSF/1 not to define a getopt prototype in . - Ditto for AIX 3.2 and . */ -#ifndef _NO_PROTO -#define _NO_PROTO -#endif - -#ifdef HAVE_CONFIG_H -#if defined (emacs) || defined (CONFIG_BROKETS) -/* We use instead of "config.h" so that a compilation - using -I. -I$srcdir will use ./config.h rather than $srcdir/config.h - (which it would do because it found this file in $srcdir). */ -#include -#else -#include "config.h" -#endif -#endif - -#ifndef __STDC__ -/* This is a separate conditional since some stdc systems - reject `defined (const)'. */ -#ifndef const -#define const -#endif -#endif - -#include - -#ifdef HAVE_STRING_H -#include -#endif - -/* Comment out all this code if we are using the GNU C Library, and are not - actually compiling the library itself. This code is part of the GNU C - Library, but also included in many other GNU distributions. Compiling - and linking in this code is a waste when using the GNU C library - (especially if it is a shared library). Rather than having every GNU - program understand `configure --with-gnu-libc' and omit the object files, - it is simpler to just do this in the source for each such file. */ - -#if defined (_LIBC) || !defined (__GNU_LIBRARY__) - - -/* This needs to come after some library #include - to get __GNU_LIBRARY__ defined. */ -#ifdef __GNU_LIBRARY__ -/* Don't include stdlib.h for non-GNU C libraries because some of them - contain conflicting prototypes for getopt. */ -#include -#endif /* GNU C library. */ - -/* This version of `getopt' appears to the caller like standard Unix `getopt' - but it behaves differently for the user, since it allows the user - to intersperse the options with the other arguments. - - As `getopt' works, it permutes the elements of ARGV so that, - when it is done, all the options precede everything else. Thus - all application programs are extended to handle flexible argument order. - - Setting the environment variable POSIXLY_CORRECT disables permutation. - Then the behavior is completely standard. - - GNU application programs can use a third alternative mode in which - they can distinguish the relative order of options and other arguments. */ - -#include "getopt.h" - -/* For communication from `getopt' to the caller. - When `getopt' finds an option that takes an argument, - the argument value is returned here. - Also, when `ordering' is RETURN_IN_ORDER, - each non-option ARGV-element is returned here. */ - -char *optarg = NULL; - -/* Index in ARGV of the next element to be scanned. - This is used for communication to and from the caller - and for communication between successive calls to `getopt'. - - On entry to `getopt', zero means this is the first call; initialize. - - When `getopt' returns EOF, this is the index of the first of the - non-option elements that the caller should itself scan. - - Otherwise, `optind' communicates from one call to the next - how much of ARGV has been scanned so far. */ - -/* XXX 1003.2 says this must be 1 before any call. */ -int optind = 0; - -/* The next char to be scanned in the option-element - in which the last option character we returned was found. - This allows us to pick up the scan where we left off. - - If this is zero, or a null string, it means resume the scan - by advancing to the next ARGV-element. */ - -static char *nextchar; - -/* Callers store zero here to inhibit the error message - for unrecognized options. */ - -int opterr = 1; - -/* Set to an option character which was unrecognized. - This must be initialized on some systems to avoid linking in the - system's own getopt implementation. */ - -int optopt = '?'; - -/* Describe how to deal with options that follow non-option ARGV-elements. - - If the caller did not specify anything, - the default is REQUIRE_ORDER if the environment variable - POSIXLY_CORRECT is defined, PERMUTE otherwise. - - REQUIRE_ORDER means don't recognize them as options; - stop option processing when the first non-option is seen. - This is what Unix does. - This mode of operation is selected by either setting the environment - variable POSIXLY_CORRECT, or using `+' as the first character - of the list of option characters. - - PERMUTE is the default. We permute the contents of ARGV as we scan, - so that eventually all the non-options are at the end. This allows options - to be given in any order, even with programs that were not written to - expect this. - - RETURN_IN_ORDER is an option available to programs that were written - to expect options and other ARGV-elements in any order and that care about - the ordering of the two. We describe each non-option ARGV-element - as if it were the argument of an option with character code 1. - Using `-' as the first character of the list of option characters - selects this mode of operation. - - The special argument `--' forces an end of option-scanning regardless - of the value of `ordering'. In the case of RETURN_IN_ORDER, only - `--' can cause `getopt' to return EOF with `optind' != ARGC. */ - -static enum -{ - REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER -} ordering; - -/* Value of POSIXLY_CORRECT environment variable. */ -static char *posixly_correct; - -#ifdef __GNU_LIBRARY__ -/* We want to avoid inclusion of string.h with non-GNU libraries - because there are many ways it can cause trouble. - On some systems, it contains special magic macros that don't work - in GCC. */ -#include -#define my_index strchr -#else - -/* Avoid depending on library functions or files - whose names are inconsistent. */ - -char *getenv (); - -static char * -my_index (str, chr) - const char *str; - int chr; -{ - while (*str) - { - if (*str == chr) - return (char *) str; - str++; - } - return 0; -} - -/* If using GCC, we can safely declare strlen this way. - If not using GCC, it is ok not to declare it. */ -#ifdef __GNUC__ -/* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h. - That was relevant to code that was here before. */ -#ifndef __STDC__ -/* gcc with -traditional declares the built-in strlen to return int, - and has done so at least since version 2.4.5. -- rms. */ -extern int strlen (const char *); -#endif /* not __STDC__ */ -#endif /* __GNUC__ */ - -#endif /* not __GNU_LIBRARY__ */ - -/* Handle permutation of arguments. */ - -/* Describe the part of ARGV that contains non-options that have - been skipped. `first_nonopt' is the index in ARGV of the first of them; - `last_nonopt' is the index after the last of them. */ - -static int first_nonopt; -static int last_nonopt; - -/* Exchange two adjacent subsequences of ARGV. - One subsequence is elements [first_nonopt,last_nonopt) - which contains all the non-options that have been skipped so far. - The other is elements [last_nonopt,optind), which contains all - the options processed since those non-options were skipped. - - `first_nonopt' and `last_nonopt' are relocated so that they describe - the new indices of the non-options in ARGV after they are moved. */ - -static void -exchange (argv) - char **argv; -{ - int bottom = first_nonopt; - int middle = last_nonopt; - int top = optind; - char *tem; - - /* Exchange the shorter segment with the far end of the longer segment. - That puts the shorter segment into the right place. - It leaves the longer segment in the right place overall, - but it consists of two parts that need to be swapped next. */ - - while (top > middle && middle > bottom) - { - if (top - middle > middle - bottom) - { - /* Bottom segment is the short one. */ - int len = middle - bottom; - register int i; - - /* Swap it with the top part of the top segment. */ - for (i = 0; i < len; i++) - { - tem = argv[bottom + i]; - argv[bottom + i] = argv[top - (middle - bottom) + i]; - argv[top - (middle - bottom) + i] = tem; - } - /* Exclude the moved bottom segment from further swapping. */ - top -= len; - } - else - { - /* Top segment is the short one. */ - int len = top - middle; - register int i; - - /* Swap it with the bottom part of the bottom segment. */ - for (i = 0; i < len; i++) - { - tem = argv[bottom + i]; - argv[bottom + i] = argv[middle + i]; - argv[middle + i] = tem; - } - /* Exclude the moved top segment from further swapping. */ - bottom += len; - } - } - - /* Update records for the slots the non-options now occupy. */ - - first_nonopt += (optind - last_nonopt); - last_nonopt = optind; -} - -/* Initialize the internal data when the first call is made. */ - -static const char * -_getopt_initialize (optstring) - const char *optstring; -{ - /* Start processing options with ARGV-element 1 (since ARGV-element 0 - is the program name); the sequence of previously skipped - non-option ARGV-elements is empty. */ - - first_nonopt = last_nonopt = optind = 1; - - nextchar = NULL; - - posixly_correct = getenv ("POSIXLY_CORRECT"); - - /* Determine how to handle the ordering of options and nonoptions. */ - - if (optstring[0] == '-') - { - ordering = RETURN_IN_ORDER; - ++optstring; - } - else if (optstring[0] == '+') - { - ordering = REQUIRE_ORDER; - ++optstring; - } - else if (posixly_correct != NULL) - ordering = REQUIRE_ORDER; - else - ordering = PERMUTE; - - return optstring; -} - -/* Scan elements of ARGV (whose length is ARGC) for option characters - given in OPTSTRING. - - If an element of ARGV starts with '-', and is not exactly "-" or "--", - then it is an option element. The characters of this element - (aside from the initial '-') are option characters. If `getopt' - is called repeatedly, it returns successively each of the option characters - from each of the option elements. - - If `getopt' finds another option character, it returns that character, - updating `optind' and `nextchar' so that the next call to `getopt' can - resume the scan with the following option character or ARGV-element. - - If there are no more option characters, `getopt' returns `EOF'. - Then `optind' is the index in ARGV of the first ARGV-element - that is not an option. (The ARGV-elements have been permuted - so that those that are not options now come last.) - - OPTSTRING is a string containing the legitimate option characters. - If an option character is seen that is not listed in OPTSTRING, - return '?' after printing an error message. If you set `opterr' to - zero, the error message is suppressed but we still return '?'. - - If a char in OPTSTRING is followed by a colon, that means it wants an arg, - so the following text in the same ARGV-element, or the text of the following - ARGV-element, is returned in `optarg'. Two colons mean an option that - wants an optional arg; if there is text in the current ARGV-element, - it is returned in `optarg', otherwise `optarg' is set to zero. - - If OPTSTRING starts with `-' or `+', it requests different methods of - handling the non-option ARGV-elements. - See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above. - - Long-named options begin with `--' instead of `-'. - Their names may be abbreviated as long as the abbreviation is unique - or is an exact match for some defined option. If they have an - argument, it follows the option name in the same ARGV-element, separated - from the option name by a `=', or else the in next ARGV-element. - When `getopt' finds a long-named option, it returns 0 if that option's - `flag' field is nonzero, the value of the option's `val' field - if the `flag' field is zero. - - The elements of ARGV aren't really const, because we permute them. - But we pretend they're const in the prototype to be compatible - with other systems. - - LONGOPTS is a vector of `struct option' terminated by an - element containing a name which is zero. - - LONGIND returns the index in LONGOPT of the long-named option found. - It is only valid when a long-named option has been found by the most - recent call. - - If LONG_ONLY is nonzero, '-' as well as '--' can introduce - long-named options. */ - -int -_getopt_internal (argc, argv, optstring, longopts, longind, long_only) - int argc; - char *const *argv; - const char *optstring; - const struct option *longopts; - int *longind; - int long_only; -{ - optarg = NULL; - - if (optind == 0) - optstring = _getopt_initialize (optstring); - - if (nextchar == NULL || *nextchar == '\0') - { - /* Advance to the next ARGV-element. */ - - if (ordering == PERMUTE) - { - /* If we have just processed some options following some non-options, - exchange them so that the options come first. */ - - if (first_nonopt != last_nonopt && last_nonopt != optind) - exchange ((char **) argv); - else if (last_nonopt != optind) - first_nonopt = optind; - - /* Skip any additional non-options - and extend the range of non-options previously skipped. */ - - while (optind < argc - && (argv[optind][0] != '-' || argv[optind][1] == '\0')) - optind++; - last_nonopt = optind; - } - - /* The special ARGV-element `--' means premature end of options. - Skip it like a null option, - then exchange with previous non-options as if it were an option, - then skip everything else like a non-option. */ - - if (optind != argc && !strcmp (argv[optind], "--")) - { - optind++; - - if (first_nonopt != last_nonopt && last_nonopt != optind) - exchange ((char **) argv); - else if (first_nonopt == last_nonopt) - first_nonopt = optind; - last_nonopt = argc; - - optind = argc; - } - - /* If we have done all the ARGV-elements, stop the scan - and back over any non-options that we skipped and permuted. */ - - if (optind == argc) - { - /* Set the next-arg-index to point at the non-options - that we previously skipped, so the caller will digest them. */ - if (first_nonopt != last_nonopt) - optind = first_nonopt; - return EOF; - } - - /* If we have come to a non-option and did not permute it, - either stop the scan or describe it to the caller and pass it by. */ - - if ((argv[optind][0] != '-' || argv[optind][1] == '\0')) - { - if (ordering == REQUIRE_ORDER) - return EOF; - optarg = argv[optind++]; - return 1; - } - - /* We have found another option-ARGV-element. - Skip the initial punctuation. */ - - nextchar = (argv[optind] + 1 - + (longopts != NULL && argv[optind][1] == '-')); - } - - /* Decode the current option-ARGV-element. */ - - /* Check whether the ARGV-element is a long option. - - If long_only and the ARGV-element has the form "-f", where f is - a valid short option, don't consider it an abbreviated form of - a long option that starts with f. Otherwise there would be no - way to give the -f short option. - - On the other hand, if there's a long option "fubar" and - the ARGV-element is "-fu", do consider that an abbreviation of - the long option, just like "--fu", and not "-f" with arg "u". - - This distinction seems to be the most useful approach. */ - - if (longopts != NULL - && (argv[optind][1] == '-' - || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1]))))) - { - char *nameend; - const struct option *p; - const struct option *pfound = NULL; - int exact = 0; - int ambig = 0; - int indfound; - int option_index; - - for (nameend = nextchar; *nameend && *nameend != '='; nameend++) - /* Do nothing. */ ; - - /* Test all long options for either exact match - or abbreviated matches. */ - for (p = longopts, option_index = 0; p->name; p++, option_index++) - if (!strncmp (p->name, nextchar, nameend - nextchar)) - { - if (nameend - nextchar == (int) strlen (p->name)) - { - /* Exact match found. */ - pfound = p; - indfound = option_index; - exact = 1; - break; - } - else if (pfound == NULL) - { - /* First nonexact match found. */ - pfound = p; - indfound = option_index; - } - else - /* Second or later nonexact match found. */ - ambig = 1; - } - - if (ambig && !exact) - { - if (opterr) - fprintf (stderr, "%s: option `%s' is ambiguous\n", - argv[0], argv[optind]); - nextchar += strlen (nextchar); - optind++; - return '?'; - } - - if (pfound != NULL) - { - option_index = indfound; - optind++; - if (*nameend) - { - /* Don't test has_arg with >, because some C compilers don't - allow it to be used on enums. */ - if (pfound->has_arg) - optarg = nameend + 1; - else - { - if (opterr) - { - if (argv[optind - 1][1] == '-') - /* --option */ - fprintf (stderr, - "%s: option `--%s' doesn't allow an argument\n", - argv[0], pfound->name); - else - /* +option or -option */ - fprintf (stderr, - "%s: option `%c%s' doesn't allow an argument\n", - argv[0], argv[optind - 1][0], pfound->name); - } - nextchar += strlen (nextchar); - return '?'; - } - } - else if (pfound->has_arg == 1) - { - if (optind < argc) - optarg = argv[optind++]; - else - { - if (opterr) - fprintf (stderr, "%s: option `%s' requires an argument\n", - argv[0], argv[optind - 1]); - nextchar += strlen (nextchar); - return optstring[0] == ':' ? ':' : '?'; - } - } - nextchar += strlen (nextchar); - if (longind != NULL) - *longind = option_index; - if (pfound->flag) - { - *(pfound->flag) = pfound->val; - return 0; - } - return pfound->val; - } - - /* Can't find it as a long option. If this is not getopt_long_only, - or the option starts with '--' or is not a valid short - option, then it's an error. - Otherwise interpret it as a short option. */ - if (!long_only || argv[optind][1] == '-' - || my_index (optstring, *nextchar) == NULL) - { - if (opterr) - { - if (argv[optind][1] == '-') - /* --option */ - fprintf (stderr, "%s: unrecognized option `--%s'\n", - argv[0], nextchar); - else - /* +option or -option */ - fprintf (stderr, "%s: unrecognized option `%c%s'\n", - argv[0], argv[optind][0], nextchar); - } - nextchar = (char *) ""; - optind++; - return '?'; - } - } - - /* Look at and handle the next short option-character. */ - - { - char c = *nextchar++; - char *temp = my_index (optstring, c); - - /* Increment `optind' when we start to process its last character. */ - if (*nextchar == '\0') - ++optind; - - if (temp == NULL || c == ':') - { - if (opterr) - { - if (posixly_correct) - /* 1003.2 specifies the format of this message. */ - fprintf (stderr, "%s: illegal option -- %c\n", argv[0], c); - else - fprintf (stderr, "%s: invalid option -- %c\n", argv[0], c); - } - optopt = c; - return '?'; - } - if (temp[1] == ':') - { - if (temp[2] == ':') - { - /* This is an option that accepts an argument optionally. */ - if (*nextchar != '\0') - { - optarg = nextchar; - optind++; - } - else - optarg = NULL; - nextchar = NULL; - } - else - { - /* This is an option that requires an argument. */ - if (*nextchar != '\0') - { - optarg = nextchar; - /* If we end this ARGV-element by taking the rest as an arg, - we must advance to the next element now. */ - optind++; - } - else if (optind == argc) - { - if (opterr) - { - /* 1003.2 specifies the format of this message. */ - fprintf (stderr, "%s: option requires an argument -- %c\n", - argv[0], c); - } - optopt = c; - if (optstring[0] == ':') - c = ':'; - else - c = '?'; - } - else - /* We already incremented `optind' once; - increment it again when taking next ARGV-elt as argument. */ - optarg = argv[optind++]; - nextchar = NULL; - } - } - return c; - } -} - -int -getopt (argc, argv, optstring) - int argc; - char *const *argv; - const char *optstring; -{ - return _getopt_internal (argc, argv, optstring, - (const struct option *) 0, - (int *) 0, - 0); -} - -#endif /* _LIBC or not __GNU_LIBRARY__. */ - -#ifdef TEST - -/* Compile with -DTEST to make an executable for use in testing - the above definition of `getopt'. */ - -int -main (argc, argv) - int argc; - char **argv; -{ - int c; - int digit_optind = 0; - - while (1) - { - int this_option_optind = optind ? optind : 1; - - c = getopt (argc, argv, "abc:d:0123456789"); - if (c == EOF) - break; - - switch (c) - { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - if (digit_optind != 0 && digit_optind != this_option_optind) - printf ("digits occur in two different argv-elements.\n"); - digit_optind = this_option_optind; - printf ("option %c\n", c); - break; - - case 'a': - printf ("option a\n"); - break; - - case 'b': - printf ("option b\n"); - break; - - case 'c': - printf ("option c with value `%s'\n", optarg); - break; - - case '?': - break; - - default: - printf ("?? getopt returned character code 0%o ??\n", c); - } - } - - if (optind < argc) - { - printf ("non-option ARGV-elements: "); - while (optind < argc) - printf ("%s ", argv[optind++]); - printf ("\n"); - } - - exit (0); -} - -#endif /* TEST */ diff --git a/contrib/cvs/lib/getopt.h b/contrib/cvs/lib/getopt.h deleted file mode 100644 index 9ba79f2..0000000 --- a/contrib/cvs/lib/getopt.h +++ /dev/null @@ -1,149 +0,0 @@ -/* Declarations for getopt. - Copyright (C) 1989, 1990, 1991, 1992, 1993 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. */ - -#ifndef _GETOPT_H -#define _GETOPT_H 1 - -/* CVS - DRP - * - * If the OS defines this, just redefine the names to avoid namespace - * clashes. In theory, we should be testing the built in functions to - * see if they do what we want and use them if possible, but this is - * easier... - * - * Namely, this was occurring under Mac OS X. This is a Mac OS X (or - * OS X related) bug. - * - * Oops. We avoid compiling this with ifdefs because pretty much all of - * getopt.c is switched on the same macros... this isn't right, but I think - * this isn't our file. Probably best not to mess with it too much. - */ -#if defined (_LIBC) || !defined (__GNU_LIBRARY__) -# ifdef HAVE_GETOPT -# define getopt cvs_getopt -# define optarg cvs_optarg -# define opterr cvs_opterr -# define optind cvs_optind -# define optopt cvs_optopt -# endif /* HAVE_GETOPT */ -#endif /* _LIBC or not __GNU_LIBRARY__. */ - -#ifdef __cplusplus -extern "C" { -#endif - -/* For communication from `getopt' to the caller. - When `getopt' finds an option that takes an argument, - the argument value is returned here. - Also, when `ordering' is RETURN_IN_ORDER, - each non-option ARGV-element is returned here. */ - -extern char *optarg; - -/* Index in ARGV of the next element to be scanned. - This is used for communication to and from the caller - and for communication between successive calls to `getopt'. - - On entry to `getopt', zero means this is the first call; initialize. - - When `getopt' returns EOF, this is the index of the first of the - non-option elements that the caller should itself scan. - - Otherwise, `optind' communicates from one call to the next - how much of ARGV has been scanned so far. */ - -extern int optind; - -/* Callers store zero here to inhibit the error message `getopt' prints - for unrecognized options. */ - -extern int opterr; - -/* Set to an option character which was unrecognized. */ - -extern int optopt; - -/* Describe the long-named options requested by the application. - The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector - of `struct option' terminated by an element containing a name which is - zero. - - The field `has_arg' is: - no_argument (or 0) if the option does not take an argument, - required_argument (or 1) if the option requires an argument, - optional_argument (or 2) if the option takes an optional argument. - - If the field `flag' is not NULL, it points to a variable that is set - to the value given in the field `val' when the option is found, but - left unchanged if the option is not found. - - To have a long-named option do something other than set an `int' to - a compiled-in constant, such as set a value from `optarg', set the - option's `flag' field to zero and its `val' field to a nonzero - value (the equivalent single-letter option character, if there is - one). For long options that have a zero `flag' field, `getopt' - returns the contents of the `val' field. */ - -struct option -{ -#if __STDC__ - const char *name; -#else - char *name; -#endif - /* has_arg can't be an enum because some compilers complain about - type mismatches in all the code that assumes it is an int. */ - int has_arg; - int *flag; - int val; -}; - -/* Names for the values of the `has_arg' field of `struct option'. */ - -#define no_argument 0 -#define required_argument 1 -#define optional_argument 2 - -#if __STDC__ -/* Many other libraries have conflicting prototypes for getopt, with - differences in the consts, in stdlib.h. We used to try to prototype - it if __GNU_LIBRARY__ but that wasn't problem free either (I'm not sure - exactly why), and there is no particular need to prototype it. - We really shouldn't be trampling on the system's namespace at all by - declaring getopt() but that is a bigger issue. */ -extern int getopt (); - -extern int getopt_long (int argc, char *const *argv, const char *shortopts, - const struct option *longopts, int *longind); -extern int getopt_long_only (int argc, char *const *argv, - const char *shortopts, - const struct option *longopts, int *longind); - -/* Internal only. Users should not call this directly. */ -extern int _getopt_internal (int argc, char *const *argv, - const char *shortopts, - const struct option *longopts, int *longind, - int long_only); -#else /* not __STDC__ */ -extern int getopt (); -extern int getopt_long (); -extern int getopt_long_only (); - -extern int _getopt_internal (); -#endif /* not __STDC__ */ - -#ifdef __cplusplus -} -#endif - -#endif /* _GETOPT_H */ diff --git a/contrib/cvs/lib/getopt1.c b/contrib/cvs/lib/getopt1.c deleted file mode 100644 index a4f1976..0000000 --- a/contrib/cvs/lib/getopt1.c +++ /dev/null @@ -1,183 +0,0 @@ -/* getopt_long and getopt_long_only entry points for GNU getopt. - Copyright (C) 1987, 88, 89, 90, 91, 92, 1993 - Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. */ - -#ifdef HAVE_CONFIG_H -#if defined (emacs) || defined (CONFIG_BROKETS) -/* We use instead of "config.h" so that a compilation - using -I. -I$srcdir will use ./config.h rather than $srcdir/config.h - (which it would do because it found this file in $srcdir). */ -#include -#else -#include "config.h" -#endif -#endif - -#include "getopt.h" - -#ifndef __STDC__ -/* This is a separate conditional since some stdc systems - reject `defined (const)'. */ -#ifndef const -#define const -#endif -#endif - -#include - -/* Comment out all this code if we are using the GNU C Library, and are not - actually compiling the library itself. This code is part of the GNU C - Library, but also included in many other GNU distributions. Compiling - and linking in this code is a waste when using the GNU C library - (especially if it is a shared library). Rather than having every GNU - program understand `configure --with-gnu-libc' and omit the object files, - it is simpler to just do this in the source for each such file. */ - -#if defined (_LIBC) || !defined (__GNU_LIBRARY__) - - -/* This needs to come after some library #include - to get __GNU_LIBRARY__ defined. */ -#ifdef __GNU_LIBRARY__ -#include -#else -char *getenv (); -#endif - -#ifndef NULL -#define NULL 0 -#endif - -int -getopt_long (argc, argv, options, long_options, opt_index) - int argc; - char *const *argv; - const char *options; - const struct option *long_options; - int *opt_index; -{ - return _getopt_internal (argc, argv, options, long_options, opt_index, 0); -} - -/* Like getopt_long, but '-' as well as '--' can indicate a long option. - If an option that starts with '-' (not '--') doesn't match a long option, - but does match a short option, it is parsed as a short option - instead. */ - -int -getopt_long_only (argc, argv, options, long_options, opt_index) - int argc; - char *const *argv; - const char *options; - const struct option *long_options; - int *opt_index; -{ - return _getopt_internal (argc, argv, options, long_options, opt_index, 1); -} - - -#endif /* _LIBC or not __GNU_LIBRARY__. */ - -#ifdef TEST - -#include - -int -main (argc, argv) - int argc; - char **argv; -{ - int c; - int digit_optind = 0; - - while (1) - { - int this_option_optind = optind ? optind : 1; - int option_index = 0; - static struct option long_options[] = - { - {"add", 1, 0, 0}, - {"append", 0, 0, 0}, - {"delete", 1, 0, 0}, - {"verbose", 0, 0, 0}, - {"create", 0, 0, 0}, - {"file", 1, 0, 0}, - {0, 0, 0, 0} - }; - - c = getopt_long (argc, argv, "abc:d:0123456789", - long_options, &option_index); - if (c == EOF) - break; - - switch (c) - { - case 0: - printf ("option %s", long_options[option_index].name); - if (optarg) - printf (" with arg %s", optarg); - printf ("\n"); - break; - - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - if (digit_optind != 0 && digit_optind != this_option_optind) - printf ("digits occur in two different argv-elements.\n"); - digit_optind = this_option_optind; - printf ("option %c\n", c); - break; - - case 'a': - printf ("option a\n"); - break; - - case 'b': - printf ("option b\n"); - break; - - case 'c': - printf ("option c with value `%s'\n", optarg); - break; - - case 'd': - printf ("option d with value `%s'\n", optarg); - break; - - case '?': - break; - - default: - printf ("?? getopt returned character code 0%o ??\n", c); - } - } - - if (optind < argc) - { - printf ("non-option ARGV-elements: "); - while (optind < argc) - printf ("%s ", argv[optind++]); - printf ("\n"); - } - - exit (0); -} - -#endif /* TEST */ diff --git a/contrib/cvs/lib/getpagesize.h b/contrib/cvs/lib/getpagesize.h deleted file mode 100644 index 34d6cf4..0000000 --- a/contrib/cvs/lib/getpagesize.h +++ /dev/null @@ -1,55 +0,0 @@ -/* Emulation of getpagesize() for systems that need it. - Copyright (C) 1991 Free Software Foundation, Inc. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#if defined (HAVE_UNISTD_H) -# include -# if defined (_SC_PAGESIZE) -# define getpagesize() sysconf(_SC_PAGESIZE) -# else -# if defined (_SC_PAGE_SIZE) -# define getpagesize() sysconf(_SC_PAGE_SIZE) -# endif /* _SC_PAGE_SIZE */ -# endif /* _SC_PAGESIZE */ -#endif - -#if !defined (getpagesize) -# ifdef HAVE_SYS_PARAM_H -# include -# endif -# if defined (PAGESIZE) -# define getpagesize() PAGESIZE -# else /* !PAGESIZE */ -# if defined (EXEC_PAGESIZE) -# define getpagesize() EXEC_PAGESIZE -# else /* !EXEC_PAGESIZE */ -# if defined (NBPG) -# if !defined (CLSIZE) -# define CLSIZE 1 -# endif /* !CLSIZE */ -# define getpagesize() (NBPG * CLSIZE) -# else /* !NBPG */ -# if defined (NBPC) -# define getpagesize() NBPC -# endif /* NBPC */ -# endif /* !NBPG */ -# endif /* !EXEC_PAGESIZE */ -# endif /* !PAGESIZE */ -#endif /* !getpagesize */ - -#if !defined (getpagesize) -# define getpagesize() 4096 /* Just punt and use reasonable value */ -#endif diff --git a/contrib/cvs/lib/getpass.c b/contrib/cvs/lib/getpass.c deleted file mode 100644 index 31c7460..0000000 --- a/contrib/cvs/lib/getpass.c +++ /dev/null @@ -1,111 +0,0 @@ -/* Copyright (C) 1992,93,94,95,96,97,98,99,2000, 2001 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, - Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#if HAVE_CONFIG_H -# include -#endif - -#include -#ifndef SEEK_CUR -#define SEEK_CUR 1 -#endif -#include -#include -#include "getline.h" - -/* It is desirable to use this bit on systems that have it. - The only bit of terminal state we want to twiddle is echoing, which is - done in software; there is no need to change the state of the terminal - hardware. */ - -#ifndef TCSASOFT -# define TCSASOFT 0 -#endif - -char * -#if __STDC__ -getpass (const char *prompt) -#else -getpass (prompt) - const char *prompt; -#endif -{ - FILE *in, *out; - struct termios s, t; - int tty_changed; - static char *buf; - static size_t bufsize; - ssize_t nread; - - /* Try to write to and read from the terminal if we can. - If we can't open the terminal, use stderr and stdin. */ - - in = fopen ("/dev/tty", "w+"); - if (in == NULL) - { - in = stdin; - out = stderr; - } - else - out = in; - - /* Turn echoing off if it is on now. */ - - if (tcgetattr (fileno (in), &t) == 0) - { - /* Save the old one. */ - s = t; - /* Tricky, tricky. */ - t.c_lflag &= ~(ECHO|ISIG); - tty_changed = (tcsetattr (fileno (in), TCSAFLUSH|TCSASOFT, &t) == 0); - } - else - tty_changed = 0; - - /* Write the prompt. */ - fputs (prompt, out); - fflush (out); - - /* Read the password. */ - nread = getline (&buf, &bufsize, in); - if (buf != NULL) - { - if (nread < 0) - buf[0] = '\0'; - else if (buf[nread - 1] == '\n') - { - /* Remove the newline. */ - buf[nread - 1] = '\0'; - if (tty_changed) - { - /* Write the newline that was not echoed. */ - if (out == in) fseek (out, 0, SEEK_CUR); - putc ('\n', out); - } - } - } - - /* Restore the original setting. */ - if (tty_changed) - (void) tcsetattr (fileno (in), TCSAFLUSH|TCSASOFT, &s); - - if (in != stdin) - /* We opened the terminal; now close it. */ - fclose (in); - - return buf; -} diff --git a/contrib/cvs/lib/md5.c b/contrib/cvs/lib/md5.c deleted file mode 100644 index f9a3cad..0000000 --- a/contrib/cvs/lib/md5.c +++ /dev/null @@ -1,332 +0,0 @@ -/* - * This code implements the MD5 message-digest algorithm. - * The algorithm is due to Ron Rivest. This code was - * written by Colin Plumb in 1993, no copyright is claimed. - * This code is in the public domain; do with it what you wish. - * - * Equivalent code is available from RSA Data Security, Inc. - * This code has been tested against that, and is equivalent, - * except that you don't need to include two pages of legalese - * with every copy. - * - * To compute the message digest of a chunk of bytes, declare an - * MD5Context structure, pass it to MD5Init, call MD5Update as - * needed on buffers full of bytes, and then call MD5Final, which - * will fill a supplied 16-byte array with the digest. - */ - -/* This code was modified in 1997 by Jim Kingdon of Cyclic Software to - not require an integer type which is exactly 32 bits. This work - draws on the changes for the same purpose by Tatu Ylonen - as part of SSH, but since I didn't actually use - that code, there is no copyright issue. I hereby disclaim - copyright in any changes I have made; this code remains in the - public domain. */ - -/* Note regarding cvs_* namespace: this avoids potential conflicts - with libraries such as some versions of Kerberos. No particular - need to worry about whether the system supplies an MD5 library, as - this file is only about 3k of object code. */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include /* for memcpy() and memset() */ - -/* Add prototype support. */ -#ifndef PROTO -#if defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__) -#define PROTO(ARGS) ARGS -#else -#define PROTO(ARGS) () -#endif -#endif - -#include "md5.h" - -/* Little-endian byte-swapping routines. Note that these do not - depend on the size of datatypes such as cvs_uint32, nor do they require - us to detect the endianness of the machine we are running on. It - is possible they should be macros for speed, but I would be - surprised if they were a performance bottleneck for MD5. */ - -static cvs_uint32 -getu32 (addr) - const unsigned char *addr; -{ - return (((((unsigned long)addr[3] << 8) | addr[2]) << 8) - | addr[1]) << 8 | addr[0]; -} - -static void -putu32 (data, addr) - cvs_uint32 data; - unsigned char *addr; -{ - addr[0] = (unsigned char)data; - addr[1] = (unsigned char)(data >> 8); - addr[2] = (unsigned char)(data >> 16); - addr[3] = (unsigned char)(data >> 24); -} - -/* - * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious - * initialization constants. - */ -void -cvs_MD5Init (ctx) - struct cvs_MD5Context *ctx; -{ - ctx->buf[0] = 0x67452301; - ctx->buf[1] = 0xefcdab89; - ctx->buf[2] = 0x98badcfe; - ctx->buf[3] = 0x10325476; - - ctx->bits[0] = 0; - ctx->bits[1] = 0; -} - -/* - * Update context to reflect the concatenation of another buffer full - * of bytes. - */ -void -cvs_MD5Update (ctx, buf, len) - struct cvs_MD5Context *ctx; - unsigned char const *buf; - unsigned len; -{ - cvs_uint32 t; - - /* Update bitcount */ - - t = ctx->bits[0]; - if ((ctx->bits[0] = (t + ((cvs_uint32)len << 3)) & 0xffffffff) < t) - ctx->bits[1]++; /* Carry from low to high */ - ctx->bits[1] += len >> 29; - - t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */ - - /* Handle any leading odd-sized chunks */ - - if ( t ) { - unsigned char *p = ctx->in + t; - - t = 64-t; - if (len < t) { - memcpy(p, buf, len); - return; - } - memcpy(p, buf, t); - cvs_MD5Transform (ctx->buf, ctx->in); - buf += t; - len -= t; - } - - /* Process data in 64-byte chunks */ - - while (len >= 64) { - memcpy(ctx->in, buf, 64); - cvs_MD5Transform (ctx->buf, ctx->in); - buf += 64; - len -= 64; - } - - /* Handle any remaining bytes of data. */ - - memcpy(ctx->in, buf, len); -} - -/* - * Final wrapup - pad to 64-byte boundary with the bit pattern - * 1 0* (64-bit count of bits processed, MSB-first) - */ -void -cvs_MD5Final (digest, ctx) - unsigned char digest[16]; - struct cvs_MD5Context *ctx; -{ - unsigned count; - unsigned char *p; - - /* Compute number of bytes mod 64 */ - count = (ctx->bits[0] >> 3) & 0x3F; - - /* Set the first char of padding to 0x80. This is safe since there is - always at least one byte free */ - p = ctx->in + count; - *p++ = 0x80; - - /* Bytes of padding needed to make 64 bytes */ - count = 64 - 1 - count; - - /* Pad out to 56 mod 64 */ - if (count < 8) { - /* Two lots of padding: Pad the first block to 64 bytes */ - memset(p, 0, count); - cvs_MD5Transform (ctx->buf, ctx->in); - - /* Now fill the next block with 56 bytes */ - memset(ctx->in, 0, 56); - } else { - /* Pad block to 56 bytes */ - memset(p, 0, count-8); - } - - /* Append length in bits and transform */ - putu32(ctx->bits[0], ctx->in + 56); - putu32(ctx->bits[1], ctx->in + 60); - - cvs_MD5Transform (ctx->buf, ctx->in); - putu32(ctx->buf[0], digest); - putu32(ctx->buf[1], digest + 4); - putu32(ctx->buf[2], digest + 8); - putu32(ctx->buf[3], digest + 12); - memset(ctx, 0, sizeof(ctx)); /* In case it's sensitive */ -} - -#ifndef ASM_MD5 - -/* The four core functions - F1 is optimized somewhat */ - -/* #define F1(x, y, z) (x & y | ~x & z) */ -#define F1(x, y, z) (z ^ (x & (y ^ z))) -#define F2(x, y, z) F1(z, x, y) -#define F3(x, y, z) (x ^ y ^ z) -#define F4(x, y, z) (y ^ (x | ~z)) - -/* This is the central step in the MD5 algorithm. */ -#define MD5STEP(f, w, x, y, z, data, s) \ - ( w += f(x, y, z) + data, w &= 0xffffffff, w = w<>(32-s), w += x ) - -/* - * The core of the MD5 algorithm, this alters an existing MD5 hash to - * reflect the addition of 16 longwords of new data. MD5Update blocks - * the data and converts bytes into longwords for this routine. - */ -void -cvs_MD5Transform (buf, inraw) - cvs_uint32 buf[4]; - const unsigned char inraw[64]; -{ - register cvs_uint32 a, b, c, d; - cvs_uint32 in[16]; - int i; - - for (i = 0; i < 16; ++i) - in[i] = getu32 (inraw + 4 * i); - - a = buf[0]; - b = buf[1]; - c = buf[2]; - d = buf[3]; - - MD5STEP(F1, a, b, c, d, in[ 0]+0xd76aa478, 7); - MD5STEP(F1, d, a, b, c, in[ 1]+0xe8c7b756, 12); - MD5STEP(F1, c, d, a, b, in[ 2]+0x242070db, 17); - MD5STEP(F1, b, c, d, a, in[ 3]+0xc1bdceee, 22); - MD5STEP(F1, a, b, c, d, in[ 4]+0xf57c0faf, 7); - MD5STEP(F1, d, a, b, c, in[ 5]+0x4787c62a, 12); - MD5STEP(F1, c, d, a, b, in[ 6]+0xa8304613, 17); - MD5STEP(F1, b, c, d, a, in[ 7]+0xfd469501, 22); - MD5STEP(F1, a, b, c, d, in[ 8]+0x698098d8, 7); - MD5STEP(F1, d, a, b, c, in[ 9]+0x8b44f7af, 12); - MD5STEP(F1, c, d, a, b, in[10]+0xffff5bb1, 17); - MD5STEP(F1, b, c, d, a, in[11]+0x895cd7be, 22); - MD5STEP(F1, a, b, c, d, in[12]+0x6b901122, 7); - MD5STEP(F1, d, a, b, c, in[13]+0xfd987193, 12); - MD5STEP(F1, c, d, a, b, in[14]+0xa679438e, 17); - MD5STEP(F1, b, c, d, a, in[15]+0x49b40821, 22); - - MD5STEP(F2, a, b, c, d, in[ 1]+0xf61e2562, 5); - MD5STEP(F2, d, a, b, c, in[ 6]+0xc040b340, 9); - MD5STEP(F2, c, d, a, b, in[11]+0x265e5a51, 14); - MD5STEP(F2, b, c, d, a, in[ 0]+0xe9b6c7aa, 20); - MD5STEP(F2, a, b, c, d, in[ 5]+0xd62f105d, 5); - MD5STEP(F2, d, a, b, c, in[10]+0x02441453, 9); - MD5STEP(F2, c, d, a, b, in[15]+0xd8a1e681, 14); - MD5STEP(F2, b, c, d, a, in[ 4]+0xe7d3fbc8, 20); - MD5STEP(F2, a, b, c, d, in[ 9]+0x21e1cde6, 5); - MD5STEP(F2, d, a, b, c, in[14]+0xc33707d6, 9); - MD5STEP(F2, c, d, a, b, in[ 3]+0xf4d50d87, 14); - MD5STEP(F2, b, c, d, a, in[ 8]+0x455a14ed, 20); - MD5STEP(F2, a, b, c, d, in[13]+0xa9e3e905, 5); - MD5STEP(F2, d, a, b, c, in[ 2]+0xfcefa3f8, 9); - MD5STEP(F2, c, d, a, b, in[ 7]+0x676f02d9, 14); - MD5STEP(F2, b, c, d, a, in[12]+0x8d2a4c8a, 20); - - MD5STEP(F3, a, b, c, d, in[ 5]+0xfffa3942, 4); - MD5STEP(F3, d, a, b, c, in[ 8]+0x8771f681, 11); - MD5STEP(F3, c, d, a, b, in[11]+0x6d9d6122, 16); - MD5STEP(F3, b, c, d, a, in[14]+0xfde5380c, 23); - MD5STEP(F3, a, b, c, d, in[ 1]+0xa4beea44, 4); - MD5STEP(F3, d, a, b, c, in[ 4]+0x4bdecfa9, 11); - MD5STEP(F3, c, d, a, b, in[ 7]+0xf6bb4b60, 16); - MD5STEP(F3, b, c, d, a, in[10]+0xbebfbc70, 23); - MD5STEP(F3, a, b, c, d, in[13]+0x289b7ec6, 4); - MD5STEP(F3, d, a, b, c, in[ 0]+0xeaa127fa, 11); - MD5STEP(F3, c, d, a, b, in[ 3]+0xd4ef3085, 16); - MD5STEP(F3, b, c, d, a, in[ 6]+0x04881d05, 23); - MD5STEP(F3, a, b, c, d, in[ 9]+0xd9d4d039, 4); - MD5STEP(F3, d, a, b, c, in[12]+0xe6db99e5, 11); - MD5STEP(F3, c, d, a, b, in[15]+0x1fa27cf8, 16); - MD5STEP(F3, b, c, d, a, in[ 2]+0xc4ac5665, 23); - - MD5STEP(F4, a, b, c, d, in[ 0]+0xf4292244, 6); - MD5STEP(F4, d, a, b, c, in[ 7]+0x432aff97, 10); - MD5STEP(F4, c, d, a, b, in[14]+0xab9423a7, 15); - MD5STEP(F4, b, c, d, a, in[ 5]+0xfc93a039, 21); - MD5STEP(F4, a, b, c, d, in[12]+0x655b59c3, 6); - MD5STEP(F4, d, a, b, c, in[ 3]+0x8f0ccc92, 10); - MD5STEP(F4, c, d, a, b, in[10]+0xffeff47d, 15); - MD5STEP(F4, b, c, d, a, in[ 1]+0x85845dd1, 21); - MD5STEP(F4, a, b, c, d, in[ 8]+0x6fa87e4f, 6); - MD5STEP(F4, d, a, b, c, in[15]+0xfe2ce6e0, 10); - MD5STEP(F4, c, d, a, b, in[ 6]+0xa3014314, 15); - MD5STEP(F4, b, c, d, a, in[13]+0x4e0811a1, 21); - MD5STEP(F4, a, b, c, d, in[ 4]+0xf7537e82, 6); - MD5STEP(F4, d, a, b, c, in[11]+0xbd3af235, 10); - MD5STEP(F4, c, d, a, b, in[ 2]+0x2ad7d2bb, 15); - MD5STEP(F4, b, c, d, a, in[ 9]+0xeb86d391, 21); - - buf[0] += a; - buf[1] += b; - buf[2] += c; - buf[3] += d; -} -#endif - -#ifdef TEST -/* Simple test program. Can use it to manually run the tests from - RFC1321 for example. */ -#include - -int -main (int argc, char **argv) -{ - struct cvs_MD5Context context; - unsigned char checksum[16]; - int i; - int j; - - if (argc < 2) - { - fprintf (stderr, "usage: %s string-to-hash\n", argv[0]); - exit (1); - } - for (j = 1; j < argc; ++j) - { - printf ("MD5 (\"%s\") = ", argv[j]); - cvs_MD5Init (&context); - cvs_MD5Update (&context, argv[j], strlen (argv[j])); - cvs_MD5Final (checksum, &context); - for (i = 0; i < 16; i++) - { - printf ("%02x", (unsigned int) checksum[i]); - } - printf ("\n"); - } - return 0; -} -#endif /* TEST */ diff --git a/contrib/cvs/lib/md5.h b/contrib/cvs/lib/md5.h deleted file mode 100644 index 3b5ba05..0000000 --- a/contrib/cvs/lib/md5.h +++ /dev/null @@ -1,41 +0,0 @@ -/* See md5.c for explanation and copyright information. */ - -/* - * $FreeBSD$ - */ - -#ifndef MD5_H -#define MD5_H - -#ifdef __FreeBSD__ -#define cvs_MD5Context MD5Context -#define cvs_MD5Init MD5Init -#define cvs_MD5Update MD5Update -#define cvs_MD5Final MD5Final -#define cvs_MD5Transform MD5Transform -#include -#else - -/* Unlike previous versions of this code, uint32 need not be exactly - 32 bits, merely 32 bits or more. Choosing a data type which is 32 - bits instead of 64 is not important; speed is considerably more - important. ANSI guarantees that "unsigned long" will be big enough, - and always using it seems to have few disadvantages. */ -typedef unsigned long cvs_uint32; - -struct cvs_MD5Context { - cvs_uint32 buf[4]; - cvs_uint32 bits[2]; - unsigned char in[64]; -}; - -void cvs_MD5Init PROTO ((struct cvs_MD5Context *context)); -void cvs_MD5Update PROTO ((struct cvs_MD5Context *context, - unsigned char const *buf, unsigned len)); -void cvs_MD5Final PROTO ((unsigned char digest[16], - struct cvs_MD5Context *context)); -void cvs_MD5Transform PROTO ((cvs_uint32 buf[4], const unsigned char in[64])); - -#endif - -#endif /* !MD5_H */ diff --git a/contrib/cvs/lib/memmove.c b/contrib/cvs/lib/memmove.c deleted file mode 100644 index 047a5a0..0000000 --- a/contrib/cvs/lib/memmove.c +++ /dev/null @@ -1,54 +0,0 @@ -/* memmove -- copy memory regions of arbitary length - Copyright (C) 1991 Free Software Foundation, Inc. - -This file is part of the libiberty library. -Libiberty is free software; you can redistribute it and/or -modify it under the terms of the GNU Library General Public -License as published by the Free Software Foundation; either -version 2 of the License, or (at your option) any later version. - -Libiberty is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Library General Public License for more details. - -*/ - - -/* - -NAME - - memmove -- copy memory regions of arbitary length - -SYNOPSIS - - void memmove (void *out, const void *in, size_t n); - -DESCRIPTION - - Copy LENGTH bytes from memory region pointed to by IN to memory - region pointed to by OUT. - - Regions can be overlapping. -*/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#ifdef __STDC__ -#include -#else -#define size_t unsigned long -#endif - -void * -memmove (out, in, length) - void *out; - const void* in; - size_t length; -{ - bcopy(in, out, length); - return out; -} diff --git a/contrib/cvs/lib/mkdir.c b/contrib/cvs/lib/mkdir.c deleted file mode 100644 index 47ff4ea..0000000 --- a/contrib/cvs/lib/mkdir.c +++ /dev/null @@ -1,125 +0,0 @@ -/* mkrmdir.c -- BSD compatible directory functions for System V - Copyright (C) 1988, 1990 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include -#ifndef STDC_HEADERS -extern int errno; -#endif - -/* mkdir and rmdir adapted from GNU tar. */ - -/* Make directory DPATH, with permission mode DMODE. - - Written by Robert Rother, Mariah Corporation, August 1985 - (sdcsvax!rmr or rmr@uscd). If you want it, it's yours. - - Severely hacked over by John Gilmore to make a 4.2BSD compatible - subroutine. 11Mar86; hoptoad!gnu - - Modified by rmtodd@uokmax 6-28-87 -- when making an already existing dir, - subroutine didn't return EEXIST. It does now. */ - -int -mkdir (dpath, dmode) - const char *dpath; - int dmode; -{ - int cpid, status; - struct stat statbuf; - - if (stat (dpath, &statbuf) == 0) - { - errno = EEXIST; /* stat worked, so it already exists. */ - return -1; - } - - /* If stat fails for a reason other than non-existence, return error. */ - if (! existence_error (errno)) - return -1; - - cpid = fork (); - switch (cpid) - { - case -1: /* Cannot fork. */ - return -1; /* errno is set already. */ - - case 0: /* Child process. */ - /* Cheap hack to set mode of new directory. Since this child - process is going away anyway, we zap its umask. - This won't suffice to set SUID, SGID, etc. on this - directory, so the parent process calls chmod afterward. */ - status = umask (0); /* Get current umask. */ - umask (status | (0777 & ~dmode)); /* Set for mkdir. */ - execl ("/bin/mkdir", "mkdir", dpath, (char *) 0); - _exit (1); - - default: /* Parent process. */ - while (wait (&status) != cpid) /* Wait for kid to finish. */ - /* Do nothing. */ ; - - if (status & 0xFFFF) - { - errno = EIO; /* /bin/mkdir failed. */ - return -1; - } - return chmod (dpath, dmode); - } -} - -/* Remove directory DPATH. - Return 0 if successful, -1 if not. */ - -int -rmdir (dpath) - char *dpath; -{ - int cpid, status; - struct stat statbuf; - - if (stat (dpath, &statbuf) != 0) - return -1; /* stat set errno. */ - - if ((statbuf.st_mode & S_IFMT) != S_IFDIR) - { - errno = ENOTDIR; - return -1; - } - - cpid = fork (); - switch (cpid) - { - case -1: /* Cannot fork. */ - return -1; /* errno is set already. */ - - case 0: /* Child process. */ - execl ("/bin/rmdir", "rmdir", dpath, (char *) 0); - _exit (1); - - default: /* Parent process. */ - while (wait (&status) != cpid) /* Wait for kid to finish. */ - /* Do nothing. */ ; - - if (status & 0xFFFF) - { - errno = EIO; /* /bin/rmdir failed. */ - return -1; - } - return 0; - } -} diff --git a/contrib/cvs/lib/regex.c b/contrib/cvs/lib/regex.c deleted file mode 100644 index e123284..0000000 --- a/contrib/cvs/lib/regex.c +++ /dev/null @@ -1,6375 +0,0 @@ -/* Extended regular expression matching and search library, version - 0.12. (Implements POSIX draft P10003.2/D11.2, except for - internationalization features.) - - Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - USA. */ - -/* AIX requires this to be the first thing in the file. */ -#if defined (_AIX) && !defined (REGEX_MALLOC) - #pragma alloca -#endif - -#undef _GNU_SOURCE -#define _GNU_SOURCE - -#ifdef emacs -/* Converts the pointer to the char to BEG-based offset from the start. */ -#define PTR_TO_OFFSET(d) \ - POS_AS_IN_BUFFER (MATCHING_IN_FIRST_STRING \ - ? (d) - string1 : (d) - (string2 - size1)) -#define POS_AS_IN_BUFFER(p) ((p) + (NILP (re_match_object) || BUFFERP (re_match_object))) -#else -#define PTR_TO_OFFSET(d) 0 -#endif - -#ifdef HAVE_CONFIG_H -#include -#endif - -/* We need this for `regex.h', and perhaps for the Emacs include files. */ -#include - -/* This is for other GNU distributions with internationalized messages. */ -#if HAVE_LIBINTL_H || defined (_LIBC) -# include -#else -# define gettext(msgid) (msgid) -#endif - -#ifndef gettext_noop -/* This define is so xgettext can find the internationalizable - strings. */ -#define gettext_noop(String) String -#endif - -/* The `emacs' switch turns on certain matching commands - that make sense only in Emacs. */ -#ifdef emacs - -#include "lisp.h" -#include "buffer.h" - -/* Make syntax table lookup grant data in gl_state. */ -#define SYNTAX_ENTRY_VIA_PROPERTY - -#include "syntax.h" -#include "charset.h" -#include "category.h" - -#define malloc xmalloc -#define realloc xrealloc -#define free xfree - -#else /* not emacs */ - -/* If we are not linking with Emacs proper, - we can't use the relocating allocator - even if config.h says that we can. */ -#undef REL_ALLOC - -#if defined (STDC_HEADERS) || defined (_LIBC) -#include -#else -char *malloc (); -char *realloc (); -#endif - -/* When used in Emacs's lib-src, we need to get bzero and bcopy somehow. - If nothing else has been done, use the method below. */ -#ifdef INHIBIT_STRING_HEADER -#if !(defined (HAVE_BZERO) && defined (HAVE_BCOPY)) -#if !defined (bzero) && !defined (bcopy) -#undef INHIBIT_STRING_HEADER -#endif -#endif -#endif - -/* This is the normal way of making sure we have a bcopy and a bzero. - This is used in most programs--a few other programs avoid this - by defining INHIBIT_STRING_HEADER. */ -#ifndef INHIBIT_STRING_HEADER -#if defined (HAVE_STRING_H) || defined (STDC_HEADERS) || defined (_LIBC) -#include -#ifndef bcmp -#define bcmp(s1, s2, n) memcmp ((s1), (s2), (n)) -#endif -#ifndef bcopy -#define bcopy(s, d, n) memcpy ((d), (s), (n)) -#endif -#ifndef bzero -#define bzero(s, n) memset ((s), 0, (n)) -#endif -#else -#include -#endif -#endif - -/* Define the syntax stuff for \<, \>, etc. */ - -/* This must be nonzero for the wordchar and notwordchar pattern - commands in re_match_2. */ -#ifndef Sword -#define Sword 1 -#endif - -#ifdef SWITCH_ENUM_BUG -#define SWITCH_ENUM_CAST(x) ((int)(x)) -#else -#define SWITCH_ENUM_CAST(x) (x) -#endif - -#ifdef SYNTAX_TABLE - -extern char *re_syntax_table; - -#else /* not SYNTAX_TABLE */ - -/* How many characters in the character set. */ -#define CHAR_SET_SIZE 256 - -static char re_syntax_table[CHAR_SET_SIZE]; - -static void -init_syntax_once () -{ - register int c; - static int done = 0; - - if (done) - return; - - bzero (re_syntax_table, sizeof re_syntax_table); - - for (c = 'a'; c <= 'z'; c++) - re_syntax_table[c] = Sword; - - for (c = 'A'; c <= 'Z'; c++) - re_syntax_table[c] = Sword; - - for (c = '0'; c <= '9'; c++) - re_syntax_table[c] = Sword; - - re_syntax_table['_'] = Sword; - - done = 1; -} - -#endif /* not SYNTAX_TABLE */ - -#define SYNTAX(c) re_syntax_table[c] - -/* Dummy macros for non-Emacs environments. */ -#define BASE_LEADING_CODE_P(c) (0) -#define WORD_BOUNDARY_P(c1, c2) (0) -#define CHAR_HEAD_P(p) (1) -#define SINGLE_BYTE_CHAR_P(c) (1) -#define SAME_CHARSET_P(c1, c2) (1) -#define MULTIBYTE_FORM_LENGTH(p, s) (1) -#define STRING_CHAR(p, s) (*(p)) -#define STRING_CHAR_AND_LENGTH(p, s, actual_len) ((actual_len) = 1, *(p)) -#define GET_CHAR_AFTER_2(c, p, str1, end1, str2, end2) \ - (c = ((p) == (end1) ? *(str2) : *(p))) -#define GET_CHAR_BEFORE_2(c, p, str1, end1, str2, end2) \ - (c = ((p) == (str2) ? *((end1) - 1) : *((p) - 1))) -#endif /* not emacs */ - -/* Get the interface, including the syntax bits. */ -#include "regex.h" - -/* isalpha etc. are used for the character classes. */ -#include - -/* Jim Meyering writes: - - "... Some ctype macros are valid only for character codes that - isascii says are ASCII (SGI's IRIX-4.0.5 is one such system --when - using /bin/cc or gcc but without giving an ansi option). So, all - ctype uses should be through macros like ISPRINT... If - STDC_HEADERS is defined, then autoconf has verified that the ctype - macros don't need to be guarded with references to isascii. ... - Defining isascii to 1 should let any compiler worth its salt - eliminate the && through constant folding." */ - -#if defined (STDC_HEADERS) || (!defined (isascii) && !defined (HAVE_ISASCII)) -#define ISASCII(c) 1 -#else -#define ISASCII(c) isascii(c) -#endif - -#ifdef isblank -#define ISBLANK(c) (ISASCII (c) && isblank (c)) -#else -#define ISBLANK(c) ((c) == ' ' || (c) == '\t') -#endif -#ifdef isgraph -#define ISGRAPH(c) (ISASCII (c) && isgraph (c)) -#else -#define ISGRAPH(c) (ISASCII (c) && isprint (c) && !isspace (c)) -#endif - -#define ISPRINT(c) (ISASCII (c) && isprint (c)) -#define ISDIGIT(c) (ISASCII (c) && isdigit (c)) -#define ISALNUM(c) (ISASCII (c) && isalnum (c)) -#define ISALPHA(c) (ISASCII (c) && isalpha (c)) -#define ISCNTRL(c) (ISASCII (c) && iscntrl (c)) -#define ISLOWER(c) (ISASCII (c) && islower (c)) -#define ISPUNCT(c) (ISASCII (c) && ispunct (c)) -#define ISSPACE(c) (ISASCII (c) && isspace (c)) -#define ISUPPER(c) (ISASCII (c) && isupper (c)) -#define ISXDIGIT(c) (ISASCII (c) && isxdigit (c)) - -#ifndef NULL -#define NULL (void *)0 -#endif - -/* We remove any previous definition of `SIGN_EXTEND_CHAR', - since ours (we hope) works properly with all combinations of - machines, compilers, `char' and `unsigned char' argument types. - (Per Bothner suggested the basic approach.) */ -#undef SIGN_EXTEND_CHAR -#if __STDC__ -#define SIGN_EXTEND_CHAR(c) ((signed char) (c)) -#else /* not __STDC__ */ -/* As in Harbison and Steele. */ -#define SIGN_EXTEND_CHAR(c) ((((unsigned char) (c)) ^ 128) - 128) -#endif - -/* Should we use malloc or alloca? If REGEX_MALLOC is not defined, we - use `alloca' instead of `malloc'. This is because using malloc in - re_search* or re_match* could cause memory leaks when C-g is used in - Emacs; also, malloc is slower and causes storage fragmentation. On - the other hand, malloc is more portable, and easier to debug. - - Because we sometimes use alloca, some routines have to be macros, - not functions -- `alloca'-allocated space disappears at the end of the - function it is called in. */ - -#ifdef REGEX_MALLOC - -#define REGEX_ALLOCATE malloc -#define REGEX_REALLOCATE(source, osize, nsize) realloc (source, nsize) -#define REGEX_FREE free - -#else /* not REGEX_MALLOC */ - -/* Emacs already defines alloca, sometimes. */ -#ifndef alloca - -/* Make alloca work the best possible way. */ -#ifdef __GNUC__ -#define alloca __builtin_alloca -#else /* not __GNUC__ */ -#if HAVE_ALLOCA_H -#include -#else /* not __GNUC__ or HAVE_ALLOCA_H */ -#if 0 /* It is a bad idea to declare alloca. We always cast the result. */ -#ifndef _AIX /* Already did AIX, up at the top. */ -char *alloca (); -#endif /* not _AIX */ -#endif -#endif /* not HAVE_ALLOCA_H */ -#endif /* not __GNUC__ */ - -#endif /* not alloca */ - -#define REGEX_ALLOCATE alloca - -/* Assumes a `char *destination' variable. */ -#define REGEX_REALLOCATE(source, osize, nsize) \ - (destination = (char *) alloca (nsize), \ - bcopy (source, destination, osize), \ - destination) - -/* No need to do anything to free, after alloca. */ -#define REGEX_FREE(arg) ((void)0) /* Do nothing! But inhibit gcc warning. */ - -#endif /* not REGEX_MALLOC */ - -/* Define how to allocate the failure stack. */ - -#if defined (REL_ALLOC) && defined (REGEX_MALLOC) - -#define REGEX_ALLOCATE_STACK(size) \ - r_alloc (&failure_stack_ptr, (size)) -#define REGEX_REALLOCATE_STACK(source, osize, nsize) \ - r_re_alloc (&failure_stack_ptr, (nsize)) -#define REGEX_FREE_STACK(ptr) \ - r_alloc_free (&failure_stack_ptr) - -#else /* not using relocating allocator */ - -#ifdef REGEX_MALLOC - -#define REGEX_ALLOCATE_STACK malloc -#define REGEX_REALLOCATE_STACK(source, osize, nsize) realloc (source, nsize) -#define REGEX_FREE_STACK free - -#else /* not REGEX_MALLOC */ - -#define REGEX_ALLOCATE_STACK alloca - -#define REGEX_REALLOCATE_STACK(source, osize, nsize) \ - REGEX_REALLOCATE (source, osize, nsize) -/* No need to explicitly free anything. */ -#define REGEX_FREE_STACK(arg) - -#endif /* not REGEX_MALLOC */ -#endif /* not using relocating allocator */ - - -/* True if `size1' is non-NULL and PTR is pointing anywhere inside - `string1' or just past its end. This works if PTR is NULL, which is - a good thing. */ -#define FIRST_STRING_P(ptr) \ - (size1 && string1 <= (ptr) && (ptr) <= string1 + size1) - -/* (Re)Allocate N items of type T using malloc, or fail. */ -#define TALLOC(n, t) ((t *) malloc ((n) * sizeof (t))) -#define RETALLOC(addr, n, t) ((addr) = (t *) realloc (addr, (n) * sizeof (t))) -#define RETALLOC_IF(addr, n, t) \ - if (addr) RETALLOC((addr), (n), t); else (addr) = TALLOC ((n), t) -#define REGEX_TALLOC(n, t) ((t *) REGEX_ALLOCATE ((n) * sizeof (t))) - -#define BYTEWIDTH 8 /* In bits. */ - -#define STREQ(s1, s2) ((strcmp (s1, s2) == 0)) - -#undef MAX -#undef MIN -#define MAX(a, b) ((a) > (b) ? (a) : (b)) -#define MIN(a, b) ((a) < (b) ? (a) : (b)) - -typedef char boolean; -#define false 0 -#define true 1 - -static int re_match_2_internal (); - -/* These are the command codes that appear in compiled regular - expressions. Some opcodes are followed by argument bytes. A - command code can specify any interpretation whatsoever for its - arguments. Zero bytes may appear in the compiled regular expression. */ - -typedef enum -{ - no_op = 0, - - /* Succeed right away--no more backtracking. */ - succeed, - - /* Followed by one byte giving n, then by n literal bytes. */ - exactn, - - /* Matches any (more or less) character. */ - anychar, - - /* Matches any one char belonging to specified set. First - following byte is number of bitmap bytes. Then come bytes - for a bitmap saying which chars are in. Bits in each byte - are ordered low-bit-first. A character is in the set if its - bit is 1. A character too large to have a bit in the map is - automatically not in the set. */ - charset, - - /* Same parameters as charset, but match any character that is - not one of those specified. */ - charset_not, - - /* Start remembering the text that is matched, for storing in a - register. Followed by one byte with the register number, in - the range 0 to one less than the pattern buffer's re_nsub - field. Then followed by one byte with the number of groups - inner to this one. (This last has to be part of the - start_memory only because we need it in the on_failure_jump - of re_match_2.) */ - start_memory, - - /* Stop remembering the text that is matched and store it in a - memory register. Followed by one byte with the register - number, in the range 0 to one less than `re_nsub' in the - pattern buffer, and one byte with the number of inner groups, - just like `start_memory'. (We need the number of inner - groups here because we don't have any easy way of finding the - corresponding start_memory when we're at a stop_memory.) */ - stop_memory, - - /* Match a duplicate of something remembered. Followed by one - byte containing the register number. */ - duplicate, - - /* Fail unless at beginning of line. */ - begline, - - /* Fail unless at end of line. */ - endline, - - /* Succeeds if at beginning of buffer (if emacs) or at beginning - of string to be matched (if not). */ - begbuf, - - /* Analogously, for end of buffer/string. */ - endbuf, - - /* Followed by two byte relative address to which to jump. */ - jump, - - /* Same as jump, but marks the end of an alternative. */ - jump_past_alt, - - /* Followed by two-byte relative address of place to resume at - in case of failure. */ - on_failure_jump, - - /* Like on_failure_jump, but pushes a placeholder instead of the - current string position when executed. */ - on_failure_keep_string_jump, - - /* Throw away latest failure point and then jump to following - two-byte relative address. */ - pop_failure_jump, - - /* Change to pop_failure_jump if know won't have to backtrack to - match; otherwise change to jump. This is used to jump - back to the beginning of a repeat. If what follows this jump - clearly won't match what the repeat does, such that we can be - sure that there is no use backtracking out of repetitions - already matched, then we change it to a pop_failure_jump. - Followed by two-byte address. */ - maybe_pop_jump, - - /* Jump to following two-byte address, and push a dummy failure - point. This failure point will be thrown away if an attempt - is made to use it for a failure. A `+' construct makes this - before the first repeat. Also used as an intermediary kind - of jump when compiling an alternative. */ - dummy_failure_jump, - - /* Push a dummy failure point and continue. Used at the end of - alternatives. */ - push_dummy_failure, - - /* Followed by two-byte relative address and two-byte number n. - After matching N times, jump to the address upon failure. */ - succeed_n, - - /* Followed by two-byte relative address, and two-byte number n. - Jump to the address N times, then fail. */ - jump_n, - - /* Set the following two-byte relative address to the - subsequent two-byte number. The address *includes* the two - bytes of number. */ - set_number_at, - - wordchar, /* Matches any word-constituent character. */ - notwordchar, /* Matches any char that is not a word-constituent. */ - - wordbeg, /* Succeeds if at word beginning. */ - wordend, /* Succeeds if at word end. */ - - wordbound, /* Succeeds if at a word boundary. */ - notwordbound /* Succeeds if not at a word boundary. */ - -#ifdef emacs - ,before_dot, /* Succeeds if before point. */ - at_dot, /* Succeeds if at point. */ - after_dot, /* Succeeds if after point. */ - - /* Matches any character whose syntax is specified. Followed by - a byte which contains a syntax code, e.g., Sword. */ - syntaxspec, - - /* Matches any character whose syntax is not that specified. */ - notsyntaxspec, - - /* Matches any character whose category-set contains the specified - category. The operator is followed by a byte which contains a - category code (mnemonic ASCII character). */ - categoryspec, - - /* Matches any character whose category-set does not contain the - specified category. The operator is followed by a byte which - contains the category code (mnemonic ASCII character). */ - notcategoryspec -#endif /* emacs */ -} re_opcode_t; - -/* Common operations on the compiled pattern. */ - -/* Store NUMBER in two contiguous bytes starting at DESTINATION. */ - -#define STORE_NUMBER(destination, number) \ - do { \ - (destination)[0] = (number) & 0377; \ - (destination)[1] = (number) >> 8; \ - } while (0) - -/* Same as STORE_NUMBER, except increment DESTINATION to - the byte after where the number is stored. Therefore, DESTINATION - must be an lvalue. */ - -#define STORE_NUMBER_AND_INCR(destination, number) \ - do { \ - STORE_NUMBER (destination, number); \ - (destination) += 2; \ - } while (0) - -/* Put into DESTINATION a number stored in two contiguous bytes starting - at SOURCE. */ - -#define EXTRACT_NUMBER(destination, source) \ - do { \ - (destination) = *(source) & 0377; \ - (destination) += SIGN_EXTEND_CHAR (*((source) + 1)) << 8; \ - } while (0) - -#ifdef DEBUG -static void -extract_number (dest, source) - int *dest; - unsigned char *source; -{ - int temp = SIGN_EXTEND_CHAR (*(source + 1)); - *dest = *source & 0377; - *dest += temp << 8; -} - -#ifndef EXTRACT_MACROS /* To debug the macros. */ -#undef EXTRACT_NUMBER -#define EXTRACT_NUMBER(dest, src) extract_number (&dest, src) -#endif /* not EXTRACT_MACROS */ - -#endif /* DEBUG */ - -/* Same as EXTRACT_NUMBER, except increment SOURCE to after the number. - SOURCE must be an lvalue. */ - -#define EXTRACT_NUMBER_AND_INCR(destination, source) \ - do { \ - EXTRACT_NUMBER (destination, source); \ - (source) += 2; \ - } while (0) - -#ifdef DEBUG -static void -extract_number_and_incr (destination, source) - int *destination; - unsigned char **source; -{ - extract_number (destination, *source); - *source += 2; -} - -#ifndef EXTRACT_MACROS -#undef EXTRACT_NUMBER_AND_INCR -#define EXTRACT_NUMBER_AND_INCR(dest, src) \ - extract_number_and_incr (&dest, &src) -#endif /* not EXTRACT_MACROS */ - -#endif /* DEBUG */ - -/* Store a multibyte character in three contiguous bytes starting - DESTINATION, and increment DESTINATION to the byte after where the - character is stored. Therefore, DESTINATION must be an lvalue. */ - -#define STORE_CHARACTER_AND_INCR(destination, character) \ - do { \ - (destination)[0] = (character) & 0377; \ - (destination)[1] = ((character) >> 8) & 0377; \ - (destination)[2] = (character) >> 16; \ - (destination) += 3; \ - } while (0) - -/* Put into DESTINATION a character stored in three contiguous bytes - starting at SOURCE. */ - -#define EXTRACT_CHARACTER(destination, source) \ - do { \ - (destination) = ((source)[0] \ - | ((source)[1] << 8) \ - | ((source)[2] << 16)); \ - } while (0) - - -/* Macros for charset. */ - -/* Size of bitmap of charset P in bytes. P is a start of charset, - i.e. *P is (re_opcode_t) charset or (re_opcode_t) charset_not. */ -#define CHARSET_BITMAP_SIZE(p) ((p)[1] & 0x7F) - -/* Nonzero if charset P has range table. */ -#define CHARSET_RANGE_TABLE_EXISTS_P(p) ((p)[1] & 0x80) - -/* Return the address of range table of charset P. But not the start - of table itself, but the before where the number of ranges is - stored. `2 +' means to skip re_opcode_t and size of bitmap. */ -#define CHARSET_RANGE_TABLE(p) (&(p)[2 + CHARSET_BITMAP_SIZE (p)]) - -/* Test if C is listed in the bitmap of charset P. */ -#define CHARSET_LOOKUP_BITMAP(p, c) \ - ((c) < CHARSET_BITMAP_SIZE (p) * BYTEWIDTH \ - && (p)[2 + (c) / BYTEWIDTH] & (1 << ((c) % BYTEWIDTH))) - -/* Return the address of end of RANGE_TABLE. COUNT is number of - ranges (which is a pair of (start, end)) in the RANGE_TABLE. `* 2' - is start of range and end of range. `* 3' is size of each start - and end. */ -#define CHARSET_RANGE_TABLE_END(range_table, count) \ - ((range_table) + (count) * 2 * 3) - -/* Test if C is in RANGE_TABLE. A flag NOT is negated if C is in. - COUNT is number of ranges in RANGE_TABLE. */ -#define CHARSET_LOOKUP_RANGE_TABLE_RAW(not, c, range_table, count) \ - do \ - { \ - int range_start, range_end; \ - unsigned char *p; \ - unsigned char *range_table_end \ - = CHARSET_RANGE_TABLE_END ((range_table), (count)); \ - \ - for (p = (range_table); p < range_table_end; p += 2 * 3) \ - { \ - EXTRACT_CHARACTER (range_start, p); \ - EXTRACT_CHARACTER (range_end, p + 3); \ - \ - if (range_start <= (c) && (c) <= range_end) \ - { \ - (not) = !(not); \ - break; \ - } \ - } \ - } \ - while (0) - -/* Test if C is in range table of CHARSET. The flag NOT is negated if - C is listed in it. */ -#define CHARSET_LOOKUP_RANGE_TABLE(not, c, charset) \ - do \ - { \ - /* Number of ranges in range table. */ \ - int count; \ - unsigned char *range_table = CHARSET_RANGE_TABLE (charset); \ - \ - EXTRACT_NUMBER_AND_INCR (count, range_table); \ - CHARSET_LOOKUP_RANGE_TABLE_RAW ((not), (c), range_table, count); \ - } \ - while (0) - -/* If DEBUG is defined, Regex prints many voluminous messages about what - it is doing (if the variable `debug' is nonzero). If linked with the - main program in `iregex.c', you can enter patterns and strings - interactively. And if linked with the main program in `main.c' and - the other test files, you can run the already-written tests. */ - -#ifdef DEBUG - -/* We use standard I/O for debugging. */ -#include - -/* It is useful to test things that ``must'' be true when debugging. */ -#include - -static int debug = 0; - -#define DEBUG_STATEMENT(e) e -#define DEBUG_PRINT1(x) if (debug) printf (x) -#define DEBUG_PRINT2(x1, x2) if (debug) printf (x1, x2) -#define DEBUG_PRINT3(x1, x2, x3) if (debug) printf (x1, x2, x3) -#define DEBUG_PRINT4(x1, x2, x3, x4) if (debug) printf (x1, x2, x3, x4) -#define DEBUG_PRINT_COMPILED_PATTERN(p, s, e) \ - if (debug) print_partial_compiled_pattern (s, e) -#define DEBUG_PRINT_DOUBLE_STRING(w, s1, sz1, s2, sz2) \ - if (debug) print_double_string (w, s1, sz1, s2, sz2) - - -/* Print the fastmap in human-readable form. */ - -void -print_fastmap (fastmap) - char *fastmap; -{ - unsigned was_a_range = 0; - unsigned i = 0; - - while (i < (1 << BYTEWIDTH)) - { - if (fastmap[i++]) - { - was_a_range = 0; - putchar (i - 1); - while (i < (1 << BYTEWIDTH) && fastmap[i]) - { - was_a_range = 1; - i++; - } - if (was_a_range) - { - printf ("-"); - putchar (i - 1); - } - } - } - putchar ('\n'); -} - - -/* Print a compiled pattern string in human-readable form, starting at - the START pointer into it and ending just before the pointer END. */ - -void -print_partial_compiled_pattern (start, end) - unsigned char *start; - unsigned char *end; -{ - int mcnt, mcnt2; - unsigned char *p = start; - unsigned char *pend = end; - - if (start == NULL) - { - printf ("(null)\n"); - return; - } - - /* Loop over pattern commands. */ - while (p < pend) - { - printf ("%d:\t", p - start); - - switch ((re_opcode_t) *p++) - { - case no_op: - printf ("/no_op"); - break; - - case exactn: - mcnt = *p++; - printf ("/exactn/%d", mcnt); - do - { - putchar ('/'); - putchar (*p++); - } - while (--mcnt); - break; - - case start_memory: - mcnt = *p++; - printf ("/start_memory/%d/%d", mcnt, *p++); - break; - - case stop_memory: - mcnt = *p++; - printf ("/stop_memory/%d/%d", mcnt, *p++); - break; - - case duplicate: - printf ("/duplicate/%d", *p++); - break; - - case anychar: - printf ("/anychar"); - break; - - case charset: - case charset_not: - { - register int c, last = -100; - register int in_range = 0; - - printf ("/charset [%s", - (re_opcode_t) *(p - 1) == charset_not ? "^" : ""); - - assert (p + *p < pend); - - for (c = 0; c < 256; c++) - if (c / 8 < *p - && (p[1 + (c/8)] & (1 << (c % 8)))) - { - /* Are we starting a range? */ - if (last + 1 == c && ! in_range) - { - putchar ('-'); - in_range = 1; - } - /* Have we broken a range? */ - else if (last + 1 != c && in_range) - { - putchar (last); - in_range = 0; - } - - if (! in_range) - putchar (c); - - last = c; - } - - if (in_range) - putchar (last); - - putchar (']'); - - p += 1 + *p; - } - break; - - case begline: - printf ("/begline"); - break; - - case endline: - printf ("/endline"); - break; - - case on_failure_jump: - extract_number_and_incr (&mcnt, &p); - printf ("/on_failure_jump to %d", p + mcnt - start); - break; - - case on_failure_keep_string_jump: - extract_number_and_incr (&mcnt, &p); - printf ("/on_failure_keep_string_jump to %d", p + mcnt - start); - break; - - case dummy_failure_jump: - extract_number_and_incr (&mcnt, &p); - printf ("/dummy_failure_jump to %d", p + mcnt - start); - break; - - case push_dummy_failure: - printf ("/push_dummy_failure"); - break; - - case maybe_pop_jump: - extract_number_and_incr (&mcnt, &p); - printf ("/maybe_pop_jump to %d", p + mcnt - start); - break; - - case pop_failure_jump: - extract_number_and_incr (&mcnt, &p); - printf ("/pop_failure_jump to %d", p + mcnt - start); - break; - - case jump_past_alt: - extract_number_and_incr (&mcnt, &p); - printf ("/jump_past_alt to %d", p + mcnt - start); - break; - - case jump: - extract_number_and_incr (&mcnt, &p); - printf ("/jump to %d", p + mcnt - start); - break; - - case succeed_n: - extract_number_and_incr (&mcnt, &p); - extract_number_and_incr (&mcnt2, &p); - printf ("/succeed_n to %d, %d times", p + mcnt - start, mcnt2); - break; - - case jump_n: - extract_number_and_incr (&mcnt, &p); - extract_number_and_incr (&mcnt2, &p); - printf ("/jump_n to %d, %d times", p + mcnt - start, mcnt2); - break; - - case set_number_at: - extract_number_and_incr (&mcnt, &p); - extract_number_and_incr (&mcnt2, &p); - printf ("/set_number_at location %d to %d", p + mcnt - start, mcnt2); - break; - - case wordbound: - printf ("/wordbound"); - break; - - case notwordbound: - printf ("/notwordbound"); - break; - - case wordbeg: - printf ("/wordbeg"); - break; - - case wordend: - printf ("/wordend"); - -#ifdef emacs - case before_dot: - printf ("/before_dot"); - break; - - case at_dot: - printf ("/at_dot"); - break; - - case after_dot: - printf ("/after_dot"); - break; - - case syntaxspec: - printf ("/syntaxspec"); - mcnt = *p++; - printf ("/%d", mcnt); - break; - - case notsyntaxspec: - printf ("/notsyntaxspec"); - mcnt = *p++; - printf ("/%d", mcnt); - break; -#endif /* emacs */ - - case wordchar: - printf ("/wordchar"); - break; - - case notwordchar: - printf ("/notwordchar"); - break; - - case begbuf: - printf ("/begbuf"); - break; - - case endbuf: - printf ("/endbuf"); - break; - - default: - printf ("?%d", *(p-1)); - } - - putchar ('\n'); - } - - printf ("%d:\tend of pattern.\n", p - start); -} - - -void -print_compiled_pattern (bufp) - struct re_pattern_buffer *bufp; -{ - unsigned char *buffer = bufp->buffer; - - print_partial_compiled_pattern (buffer, buffer + bufp->used); - printf ("%d bytes used/%d bytes allocated.\n", bufp->used, bufp->allocated); - - if (bufp->fastmap_accurate && bufp->fastmap) - { - printf ("fastmap: "); - print_fastmap (bufp->fastmap); - } - - printf ("re_nsub: %d\t", bufp->re_nsub); - printf ("regs_alloc: %d\t", bufp->regs_allocated); - printf ("can_be_null: %d\t", bufp->can_be_null); - printf ("newline_anchor: %d\n", bufp->newline_anchor); - printf ("no_sub: %d\t", bufp->no_sub); - printf ("not_bol: %d\t", bufp->not_bol); - printf ("not_eol: %d\t", bufp->not_eol); - printf ("syntax: %d\n", bufp->syntax); - /* Perhaps we should print the translate table? */ -} - - -void -print_double_string (where, string1, size1, string2, size2) - const char *where; - const char *string1; - const char *string2; - int size1; - int size2; -{ - unsigned this_char; - - if (where == NULL) - printf ("(null)"); - else - { - if (FIRST_STRING_P (where)) - { - for (this_char = where - string1; this_char < size1; this_char++) - putchar (string1[this_char]); - - where = string2; - } - - for (this_char = where - string2; this_char < size2; this_char++) - putchar (string2[this_char]); - } -} - -#else /* not DEBUG */ - -#undef assert -#define assert(e) - -#define DEBUG_STATEMENT(e) -#define DEBUG_PRINT1(x) -#define DEBUG_PRINT2(x1, x2) -#define DEBUG_PRINT3(x1, x2, x3) -#define DEBUG_PRINT4(x1, x2, x3, x4) -#define DEBUG_PRINT_COMPILED_PATTERN(p, s, e) -#define DEBUG_PRINT_DOUBLE_STRING(w, s1, sz1, s2, sz2) - -#endif /* not DEBUG */ - -/* Set by `re_set_syntax' to the current regexp syntax to recognize. Can - also be assigned to arbitrarily: each pattern buffer stores its own - syntax, so it can be changed between regex compilations. */ -/* This has no initializer because initialized variables in Emacs - become read-only after dumping. */ -reg_syntax_t re_syntax_options; - - -/* Specify the precise syntax of regexps for compilation. This provides - for compatibility for various utilities which historically have - different, incompatible syntaxes. - - The argument SYNTAX is a bit mask comprised of the various bits - defined in regex.h. We return the old syntax. */ - -reg_syntax_t -re_set_syntax (syntax) - reg_syntax_t syntax; -{ - reg_syntax_t ret = re_syntax_options; - - re_syntax_options = syntax; - return ret; -} - -/* This table gives an error message for each of the error codes listed - in regex.h. Obviously the order here has to be same as there. - POSIX doesn't require that we do anything for REG_NOERROR, - but why not be nice? */ - -static const char *re_error_msgid[] = - { - gettext_noop ("Success"), /* REG_NOERROR */ - gettext_noop ("No match"), /* REG_NOMATCH */ - gettext_noop ("Invalid regular expression"), /* REG_BADPAT */ - gettext_noop ("Invalid collation character"), /* REG_ECOLLATE */ - gettext_noop ("Invalid character class name"), /* REG_ECTYPE */ - gettext_noop ("Trailing backslash"), /* REG_EESCAPE */ - gettext_noop ("Invalid back reference"), /* REG_ESUBREG */ - gettext_noop ("Unmatched [ or [^"), /* REG_EBRACK */ - gettext_noop ("Unmatched ( or \\("), /* REG_EPAREN */ - gettext_noop ("Unmatched \\{"), /* REG_EBRACE */ - gettext_noop ("Invalid content of \\{\\}"), /* REG_BADBR */ - gettext_noop ("Invalid range end"), /* REG_ERANGE */ - gettext_noop ("Memory exhausted"), /* REG_ESPACE */ - gettext_noop ("Invalid preceding regular expression"), /* REG_BADRPT */ - gettext_noop ("Premature end of regular expression"), /* REG_EEND */ - gettext_noop ("Regular expression too big"), /* REG_ESIZE */ - gettext_noop ("Unmatched ) or \\)"), /* REG_ERPAREN */ - }; - -/* Avoiding alloca during matching, to placate r_alloc. */ - -/* Define MATCH_MAY_ALLOCATE unless we need to make sure that the - searching and matching functions should not call alloca. On some - systems, alloca is implemented in terms of malloc, and if we're - using the relocating allocator routines, then malloc could cause a - relocation, which might (if the strings being searched are in the - ralloc heap) shift the data out from underneath the regexp - routines. - - Here's another reason to avoid allocation: Emacs - processes input from X in a signal handler; processing X input may - call malloc; if input arrives while a matching routine is calling - malloc, then we're scrod. But Emacs can't just block input while - calling matching routines; then we don't notice interrupts when - they come in. So, Emacs blocks input around all regexp calls - except the matching calls, which it leaves unprotected, in the - faith that they will not malloc. */ - -/* Normally, this is fine. */ -#define MATCH_MAY_ALLOCATE - -/* When using GNU C, we are not REALLY using the C alloca, no matter - what config.h may say. So don't take precautions for it. */ -#ifdef __GNUC__ -#undef C_ALLOCA -#endif - -/* The match routines may not allocate if (1) they would do it with malloc - and (2) it's not safe for them to use malloc. - Note that if REL_ALLOC is defined, matching would not use malloc for the - failure stack, but we would still use it for the register vectors; - so REL_ALLOC should not affect this. */ -#if (defined (C_ALLOCA) || defined (REGEX_MALLOC)) && defined (emacs) -#undef MATCH_MAY_ALLOCATE -#endif - - -/* Failure stack declarations and macros; both re_compile_fastmap and - re_match_2 use a failure stack. These have to be macros because of - REGEX_ALLOCATE_STACK. */ - - -/* Approximate number of failure points for which to initially allocate space - when matching. If this number is exceeded, we allocate more - space, so it is not a hard limit. */ -#ifndef INIT_FAILURE_ALLOC -#define INIT_FAILURE_ALLOC 20 -#endif - -/* Roughly the maximum number of failure points on the stack. Would be - exactly that if always used TYPICAL_FAILURE_SIZE items each time we failed. - This is a variable only so users of regex can assign to it; we never - change it ourselves. */ -#if defined (MATCH_MAY_ALLOCATE) -/* Note that 4400 is enough to cause a crash on Alpha OSF/1, - whose default stack limit is 2mb. In order for a larger - value to work reliably, you have to try to make it accord - with the process stack limit. */ -int re_max_failures = 40000; -#else -int re_max_failures = 4000; -#endif - -union fail_stack_elt -{ - unsigned char *pointer; - int integer; -}; - -typedef union fail_stack_elt fail_stack_elt_t; - -typedef struct -{ - fail_stack_elt_t *stack; - unsigned size; - unsigned avail; /* Offset of next open position. */ -} fail_stack_type; - -#define FAIL_STACK_EMPTY() (fail_stack.avail == 0) -#define FAIL_STACK_PTR_EMPTY() (fail_stack_ptr->avail == 0) -#define FAIL_STACK_FULL() (fail_stack.avail == fail_stack.size) - - -/* Define macros to initialize and free the failure stack. - Do `return -2' if the alloc fails. */ - -#ifdef MATCH_MAY_ALLOCATE -#define INIT_FAIL_STACK() \ - do { \ - fail_stack.stack = (fail_stack_elt_t *) \ - REGEX_ALLOCATE_STACK (INIT_FAILURE_ALLOC * TYPICAL_FAILURE_SIZE \ - * sizeof (fail_stack_elt_t)); \ - \ - if (fail_stack.stack == NULL) \ - return -2; \ - \ - fail_stack.size = INIT_FAILURE_ALLOC; \ - fail_stack.avail = 0; \ - } while (0) - -#define RESET_FAIL_STACK() REGEX_FREE_STACK (fail_stack.stack) -#else -#define INIT_FAIL_STACK() \ - do { \ - fail_stack.avail = 0; \ - } while (0) - -#define RESET_FAIL_STACK() -#endif - - -/* Double the size of FAIL_STACK, up to a limit - which allows approximately `re_max_failures' items. - - Return 1 if succeeds, and 0 if either ran out of memory - allocating space for it or it was already too large. - - REGEX_REALLOCATE_STACK requires `destination' be declared. */ - -/* Factor to increase the failure stack size by - when we increase it. - This used to be 2, but 2 was too wasteful - because the old discarded stacks added up to as much space - were as ultimate, maximum-size stack. */ -#define FAIL_STACK_GROWTH_FACTOR 4 - -#define GROW_FAIL_STACK(fail_stack) \ - (((fail_stack).size * sizeof (fail_stack_elt_t) \ - >= re_max_failures * TYPICAL_FAILURE_SIZE) \ - ? 0 \ - : ((fail_stack).stack \ - = (fail_stack_elt_t *) \ - REGEX_REALLOCATE_STACK ((fail_stack).stack, \ - (fail_stack).size * sizeof (fail_stack_elt_t), \ - MIN (re_max_failures * TYPICAL_FAILURE_SIZE, \ - ((fail_stack).size * sizeof (fail_stack_elt_t) \ - * FAIL_STACK_GROWTH_FACTOR))), \ - \ - (fail_stack).stack == NULL \ - ? 0 \ - : ((fail_stack).size \ - = (MIN (re_max_failures * TYPICAL_FAILURE_SIZE, \ - ((fail_stack).size * sizeof (fail_stack_elt_t) \ - * FAIL_STACK_GROWTH_FACTOR)) \ - / sizeof (fail_stack_elt_t)), \ - 1))) - - -/* Push pointer POINTER on FAIL_STACK. - Return 1 if was able to do so and 0 if ran out of memory allocating - space to do so. */ -#define PUSH_PATTERN_OP(POINTER, FAIL_STACK) \ - ((FAIL_STACK_FULL () \ - && !GROW_FAIL_STACK (FAIL_STACK)) \ - ? 0 \ - : ((FAIL_STACK).stack[(FAIL_STACK).avail++].pointer = POINTER, \ - 1)) - -/* Push a pointer value onto the failure stack. - Assumes the variable `fail_stack'. Probably should only - be called from within `PUSH_FAILURE_POINT'. */ -#define PUSH_FAILURE_POINTER(item) \ - fail_stack.stack[fail_stack.avail++].pointer = (unsigned char *) (item) - -/* This pushes an integer-valued item onto the failure stack. - Assumes the variable `fail_stack'. Probably should only - be called from within `PUSH_FAILURE_POINT'. */ -#define PUSH_FAILURE_INT(item) \ - fail_stack.stack[fail_stack.avail++].integer = (item) - -/* Push a fail_stack_elt_t value onto the failure stack. - Assumes the variable `fail_stack'. Probably should only - be called from within `PUSH_FAILURE_POINT'. */ -#define PUSH_FAILURE_ELT(item) \ - fail_stack.stack[fail_stack.avail++] = (item) - -/* These three POP... operations complement the three PUSH... operations. - All assume that `fail_stack' is nonempty. */ -#define POP_FAILURE_POINTER() fail_stack.stack[--fail_stack.avail].pointer -#define POP_FAILURE_INT() fail_stack.stack[--fail_stack.avail].integer -#define POP_FAILURE_ELT() fail_stack.stack[--fail_stack.avail] - -/* Used to omit pushing failure point id's when we're not debugging. */ -#ifdef DEBUG -#define DEBUG_PUSH PUSH_FAILURE_INT -#define DEBUG_POP(item_addr) *(item_addr) = POP_FAILURE_INT () -#else -#define DEBUG_PUSH(item) -#define DEBUG_POP(item_addr) -#endif - - -/* Push the information about the state we will need - if we ever fail back to it. - - Requires variables fail_stack, regstart, regend, reg_info, and - num_regs be declared. GROW_FAIL_STACK requires `destination' be - declared. - - Does `return FAILURE_CODE' if runs out of memory. */ - -#define PUSH_FAILURE_POINT(pattern_place, string_place, failure_code) \ - do { \ - char *destination; \ - /* Must be int, so when we don't save any registers, the arithmetic \ - of 0 + -1 isn't done as unsigned. */ \ - int this_reg; \ - \ - DEBUG_STATEMENT (failure_id++); \ - DEBUG_STATEMENT (nfailure_points_pushed++); \ - DEBUG_PRINT2 ("\nPUSH_FAILURE_POINT #%u:\n", failure_id); \ - DEBUG_PRINT2 (" Before push, next avail: %d\n", (fail_stack).avail);\ - DEBUG_PRINT2 (" size: %d\n", (fail_stack).size);\ - \ - DEBUG_PRINT2 (" slots needed: %d\n", NUM_FAILURE_ITEMS); \ - DEBUG_PRINT2 (" available: %d\n", REMAINING_AVAIL_SLOTS); \ - \ - /* Ensure we have enough space allocated for what we will push. */ \ - while (REMAINING_AVAIL_SLOTS < NUM_FAILURE_ITEMS) \ - { \ - if (!GROW_FAIL_STACK (fail_stack)) \ - return failure_code; \ - \ - DEBUG_PRINT2 ("\n Doubled stack; size now: %d\n", \ - (fail_stack).size); \ - DEBUG_PRINT2 (" slots available: %d\n", REMAINING_AVAIL_SLOTS);\ - } \ - \ - /* Push the info, starting with the registers. */ \ - DEBUG_PRINT1 ("\n"); \ - \ - if (1) \ - for (this_reg = lowest_active_reg; this_reg <= highest_active_reg; \ - this_reg++) \ - { \ - DEBUG_PRINT2 (" Pushing reg: %d\n", this_reg); \ - DEBUG_STATEMENT (num_regs_pushed++); \ - \ - DEBUG_PRINT2 (" start: 0x%x\n", regstart[this_reg]); \ - PUSH_FAILURE_POINTER (regstart[this_reg]); \ - \ - DEBUG_PRINT2 (" end: 0x%x\n", regend[this_reg]); \ - PUSH_FAILURE_POINTER (regend[this_reg]); \ - \ - DEBUG_PRINT2 (" info: 0x%x\n ", reg_info[this_reg]); \ - DEBUG_PRINT2 (" match_null=%d", \ - REG_MATCH_NULL_STRING_P (reg_info[this_reg])); \ - DEBUG_PRINT2 (" active=%d", IS_ACTIVE (reg_info[this_reg])); \ - DEBUG_PRINT2 (" matched_something=%d", \ - MATCHED_SOMETHING (reg_info[this_reg])); \ - DEBUG_PRINT2 (" ever_matched=%d", \ - EVER_MATCHED_SOMETHING (reg_info[this_reg])); \ - DEBUG_PRINT1 ("\n"); \ - PUSH_FAILURE_ELT (reg_info[this_reg].word); \ - } \ - \ - DEBUG_PRINT2 (" Pushing low active reg: %d\n", lowest_active_reg);\ - PUSH_FAILURE_INT (lowest_active_reg); \ - \ - DEBUG_PRINT2 (" Pushing high active reg: %d\n", highest_active_reg);\ - PUSH_FAILURE_INT (highest_active_reg); \ - \ - DEBUG_PRINT2 (" Pushing pattern 0x%x: ", pattern_place); \ - DEBUG_PRINT_COMPILED_PATTERN (bufp, pattern_place, pend); \ - PUSH_FAILURE_POINTER (pattern_place); \ - \ - DEBUG_PRINT2 (" Pushing string 0x%x: `", string_place); \ - DEBUG_PRINT_DOUBLE_STRING (string_place, string1, size1, string2, \ - size2); \ - DEBUG_PRINT1 ("'\n"); \ - PUSH_FAILURE_POINTER (string_place); \ - \ - DEBUG_PRINT2 (" Pushing failure id: %u\n", failure_id); \ - DEBUG_PUSH (failure_id); \ - } while (0) - -/* This is the number of items that are pushed and popped on the stack - for each register. */ -#define NUM_REG_ITEMS 3 - -/* Individual items aside from the registers. */ -#ifdef DEBUG -#define NUM_NONREG_ITEMS 5 /* Includes failure point id. */ -#else -#define NUM_NONREG_ITEMS 4 -#endif - -/* Estimate the size of data pushed by a typical failure stack entry. - An estimate is all we need, because all we use this for - is to choose a limit for how big to make the failure stack. */ - -#define TYPICAL_FAILURE_SIZE 20 - -/* This is how many items we actually use for a failure point. - It depends on the regexp. */ -#define NUM_FAILURE_ITEMS \ - (((0 \ - ? 0 : highest_active_reg - lowest_active_reg + 1) \ - * NUM_REG_ITEMS) \ - + NUM_NONREG_ITEMS) - -/* How many items can still be added to the stack without overflowing it. */ -#define REMAINING_AVAIL_SLOTS ((fail_stack).size - (fail_stack).avail) - - -/* Pops what PUSH_FAIL_STACK pushes. - - We restore into the parameters, all of which should be lvalues: - STR -- the saved data position. - PAT -- the saved pattern position. - LOW_REG, HIGH_REG -- the highest and lowest active registers. - REGSTART, REGEND -- arrays of string positions. - REG_INFO -- array of information about each subexpression. - - Also assumes the variables `fail_stack' and (if debugging), `bufp', - `pend', `string1', `size1', `string2', and `size2'. */ - -#define POP_FAILURE_POINT(str, pat, low_reg, high_reg, regstart, regend, reg_info)\ -{ \ - DEBUG_STATEMENT (fail_stack_elt_t failure_id;) \ - int this_reg; \ - const unsigned char *string_temp; \ - \ - assert (!FAIL_STACK_EMPTY ()); \ - \ - /* Remove failure points and point to how many regs pushed. */ \ - DEBUG_PRINT1 ("POP_FAILURE_POINT:\n"); \ - DEBUG_PRINT2 (" Before pop, next avail: %d\n", fail_stack.avail); \ - DEBUG_PRINT2 (" size: %d\n", fail_stack.size); \ - \ - assert (fail_stack.avail >= NUM_NONREG_ITEMS); \ - \ - DEBUG_POP (&failure_id); \ - DEBUG_PRINT2 (" Popping failure id: %u\n", failure_id); \ - \ - /* If the saved string location is NULL, it came from an \ - on_failure_keep_string_jump opcode, and we want to throw away the \ - saved NULL, thus retaining our current position in the string. */ \ - string_temp = POP_FAILURE_POINTER (); \ - if (string_temp != NULL) \ - str = (const char *) string_temp; \ - \ - DEBUG_PRINT2 (" Popping string 0x%x: `", str); \ - DEBUG_PRINT_DOUBLE_STRING (str, string1, size1, string2, size2); \ - DEBUG_PRINT1 ("'\n"); \ - \ - pat = (unsigned char *) POP_FAILURE_POINTER (); \ - DEBUG_PRINT2 (" Popping pattern 0x%x: ", pat); \ - DEBUG_PRINT_COMPILED_PATTERN (bufp, pat, pend); \ - \ - /* Restore register info. */ \ - high_reg = (unsigned) POP_FAILURE_INT (); \ - DEBUG_PRINT2 (" Popping high active reg: %d\n", high_reg); \ - \ - low_reg = (unsigned) POP_FAILURE_INT (); \ - DEBUG_PRINT2 (" Popping low active reg: %d\n", low_reg); \ - \ - if (1) \ - for (this_reg = high_reg; this_reg >= low_reg; this_reg--) \ - { \ - DEBUG_PRINT2 (" Popping reg: %d\n", this_reg); \ - \ - reg_info[this_reg].word = POP_FAILURE_ELT (); \ - DEBUG_PRINT2 (" info: 0x%x\n", reg_info[this_reg]); \ - \ - regend[this_reg] = (const char *) POP_FAILURE_POINTER (); \ - DEBUG_PRINT2 (" end: 0x%x\n", regend[this_reg]); \ - \ - regstart[this_reg] = (const char *) POP_FAILURE_POINTER (); \ - DEBUG_PRINT2 (" start: 0x%x\n", regstart[this_reg]); \ - } \ - else \ - { \ - for (this_reg = highest_active_reg; this_reg > high_reg; this_reg--) \ - { \ - reg_info[this_reg].word.integer = 0; \ - regend[this_reg] = 0; \ - regstart[this_reg] = 0; \ - } \ - highest_active_reg = high_reg; \ - } \ - \ - set_regs_matched_done = 0; \ - DEBUG_STATEMENT (nfailure_points_popped++); \ -} /* POP_FAILURE_POINT */ - - - -/* Structure for per-register (a.k.a. per-group) information. - Other register information, such as the - starting and ending positions (which are addresses), and the list of - inner groups (which is a bits list) are maintained in separate - variables. - - We are making a (strictly speaking) nonportable assumption here: that - the compiler will pack our bit fields into something that fits into - the type of `word', i.e., is something that fits into one item on the - failure stack. */ - -typedef union -{ - fail_stack_elt_t word; - struct - { - /* This field is one if this group can match the empty string, - zero if not. If not yet determined, `MATCH_NULL_UNSET_VALUE'. */ -#define MATCH_NULL_UNSET_VALUE 3 - unsigned match_null_string_p : 2; - unsigned is_active : 1; - unsigned matched_something : 1; - unsigned ever_matched_something : 1; - } bits; -} register_info_type; - -#define REG_MATCH_NULL_STRING_P(R) ((R).bits.match_null_string_p) -#define IS_ACTIVE(R) ((R).bits.is_active) -#define MATCHED_SOMETHING(R) ((R).bits.matched_something) -#define EVER_MATCHED_SOMETHING(R) ((R).bits.ever_matched_something) - - -/* Call this when have matched a real character; it sets `matched' flags - for the subexpressions which we are currently inside. Also records - that those subexprs have matched. */ -#define SET_REGS_MATCHED() \ - do \ - { \ - if (!set_regs_matched_done) \ - { \ - unsigned r; \ - set_regs_matched_done = 1; \ - for (r = lowest_active_reg; r <= highest_active_reg; r++) \ - { \ - MATCHED_SOMETHING (reg_info[r]) \ - = EVER_MATCHED_SOMETHING (reg_info[r]) \ - = 1; \ - } \ - } \ - } \ - while (0) - -/* Registers are set to a sentinel when they haven't yet matched. */ -static char reg_unset_dummy; -#define REG_UNSET_VALUE (®_unset_dummy) -#define REG_UNSET(e) ((e) == REG_UNSET_VALUE) - -/* Subroutine declarations and macros for regex_compile. */ - -static void store_op1 (), store_op2 (); -static void insert_op1 (), insert_op2 (); -static boolean at_begline_loc_p (), at_endline_loc_p (); -static boolean group_in_compile_stack (); - -/* Fetch the next character in the uncompiled pattern---translating it - if necessary. Also cast from a signed character in the constant - string passed to us by the user to an unsigned char that we can use - as an array index (in, e.g., `translate'). */ -#ifndef PATFETCH -#define PATFETCH(c) \ - do {if (p == pend) return REG_EEND; \ - c = (unsigned char) *p++; \ - if (RE_TRANSLATE_P (translate)) c = RE_TRANSLATE (translate, c); \ - } while (0) -#endif - -/* Fetch the next character in the uncompiled pattern, with no - translation. */ -#define PATFETCH_RAW(c) \ - do {if (p == pend) return REG_EEND; \ - c = (unsigned char) *p++; \ - } while (0) - -/* Go backwards one character in the pattern. */ -#define PATUNFETCH p-- - - -/* If `translate' is non-null, return translate[D], else just D. We - cast the subscript to translate because some data is declared as - `char *', to avoid warnings when a string constant is passed. But - when we use a character as a subscript we must make it unsigned. */ -#ifndef TRANSLATE -#define TRANSLATE(d) \ - (RE_TRANSLATE_P (translate) \ - ? (unsigned) RE_TRANSLATE (translate, (unsigned) (d)) : (d)) -#endif - - -/* Macros for outputting the compiled pattern into `buffer'. */ - -/* If the buffer isn't allocated when it comes in, use this. */ -#define INIT_BUF_SIZE 32 - -/* Make sure we have at least N more bytes of space in buffer. */ -#define GET_BUFFER_SPACE(n) \ - while (b - bufp->buffer + (n) > bufp->allocated) \ - EXTEND_BUFFER () - -/* Make sure we have one more byte of buffer space and then add C to it. */ -#define BUF_PUSH(c) \ - do { \ - GET_BUFFER_SPACE (1); \ - *b++ = (unsigned char) (c); \ - } while (0) - - -/* Ensure we have two more bytes of buffer space and then append C1 and C2. */ -#define BUF_PUSH_2(c1, c2) \ - do { \ - GET_BUFFER_SPACE (2); \ - *b++ = (unsigned char) (c1); \ - *b++ = (unsigned char) (c2); \ - } while (0) - - -/* As with BUF_PUSH_2, except for three bytes. */ -#define BUF_PUSH_3(c1, c2, c3) \ - do { \ - GET_BUFFER_SPACE (3); \ - *b++ = (unsigned char) (c1); \ - *b++ = (unsigned char) (c2); \ - *b++ = (unsigned char) (c3); \ - } while (0) - - -/* Store a jump with opcode OP at LOC to location TO. We store a - relative address offset by the three bytes the jump itself occupies. */ -#define STORE_JUMP(op, loc, to) \ - store_op1 (op, loc, (to) - (loc) - 3) - -/* Likewise, for a two-argument jump. */ -#define STORE_JUMP2(op, loc, to, arg) \ - store_op2 (op, loc, (to) - (loc) - 3, arg) - -/* Like `STORE_JUMP', but for inserting. Assume `b' is the buffer end. */ -#define INSERT_JUMP(op, loc, to) \ - insert_op1 (op, loc, (to) - (loc) - 3, b) - -/* Like `STORE_JUMP2', but for inserting. Assume `b' is the buffer end. */ -#define INSERT_JUMP2(op, loc, to, arg) \ - insert_op2 (op, loc, (to) - (loc) - 3, arg, b) - - -/* This is not an arbitrary limit: the arguments which represent offsets - into the pattern are two bytes long. So if 2^16 bytes turns out to - be too small, many things would have to change. */ -#define MAX_BUF_SIZE (1L << 16) - - -/* Extend the buffer by twice its current size via realloc and - reset the pointers that pointed into the old block to point to the - correct places in the new one. If extending the buffer results in it - being larger than MAX_BUF_SIZE, then flag memory exhausted. */ -#define EXTEND_BUFFER() \ - do { \ - unsigned char *old_buffer = bufp->buffer; \ - if (bufp->allocated == MAX_BUF_SIZE) \ - return REG_ESIZE; \ - bufp->allocated <<= 1; \ - if (bufp->allocated > MAX_BUF_SIZE) \ - bufp->allocated = MAX_BUF_SIZE; \ - bufp->buffer = (unsigned char *) realloc (bufp->buffer, bufp->allocated);\ - if (bufp->buffer == NULL) \ - return REG_ESPACE; \ - /* If the buffer moved, move all the pointers into it. */ \ - if (old_buffer != bufp->buffer) \ - { \ - b = (b - old_buffer) + bufp->buffer; \ - begalt = (begalt - old_buffer) + bufp->buffer; \ - if (fixup_alt_jump) \ - fixup_alt_jump = (fixup_alt_jump - old_buffer) + bufp->buffer;\ - if (laststart) \ - laststart = (laststart - old_buffer) + bufp->buffer; \ - if (pending_exact) \ - pending_exact = (pending_exact - old_buffer) + bufp->buffer; \ - } \ - } while (0) - - -/* Since we have one byte reserved for the register number argument to - {start,stop}_memory, the maximum number of groups we can report - things about is what fits in that byte. */ -#define MAX_REGNUM 255 - -/* But patterns can have more than `MAX_REGNUM' registers. We just - ignore the excess. */ -typedef unsigned regnum_t; - - -/* Macros for the compile stack. */ - -/* Since offsets can go either forwards or backwards, this type needs to - be able to hold values from -(MAX_BUF_SIZE - 1) to MAX_BUF_SIZE - 1. */ -typedef int pattern_offset_t; - -typedef struct -{ - pattern_offset_t begalt_offset; - pattern_offset_t fixup_alt_jump; - pattern_offset_t inner_group_offset; - pattern_offset_t laststart_offset; - regnum_t regnum; -} compile_stack_elt_t; - - -typedef struct -{ - compile_stack_elt_t *stack; - unsigned size; - unsigned avail; /* Offset of next open position. */ -} compile_stack_type; - - -#define INIT_COMPILE_STACK_SIZE 32 - -#define COMPILE_STACK_EMPTY (compile_stack.avail == 0) -#define COMPILE_STACK_FULL (compile_stack.avail == compile_stack.size) - -/* The next available element. */ -#define COMPILE_STACK_TOP (compile_stack.stack[compile_stack.avail]) - - -/* Structure to manage work area for range table. */ -struct range_table_work_area -{ - int *table; /* actual work area. */ - int allocated; /* allocated size for work area in bytes. */ - int used; /* actually used size in words. */ -}; - -/* Make sure that WORK_AREA can hold more N multibyte characters. */ -#define EXTEND_RANGE_TABLE_WORK_AREA(work_area, n) \ - do { \ - if (((work_area).used + (n)) * sizeof (int) > (work_area).allocated) \ - { \ - (work_area).allocated += 16 * sizeof (int); \ - if ((work_area).table) \ - (work_area).table \ - = (int *) realloc ((work_area).table, (work_area).allocated); \ - else \ - (work_area).table \ - = (int *) malloc ((work_area).allocated); \ - if ((work_area).table == 0) \ - FREE_STACK_RETURN (REG_ESPACE); \ - } \ - } while (0) - -/* Set a range (RANGE_START, RANGE_END) to WORK_AREA. */ -#define SET_RANGE_TABLE_WORK_AREA(work_area, range_start, range_end) \ - do { \ - EXTEND_RANGE_TABLE_WORK_AREA ((work_area), 2); \ - (work_area).table[(work_area).used++] = (range_start); \ - (work_area).table[(work_area).used++] = (range_end); \ - } while (0) - -/* Free allocated memory for WORK_AREA. */ -#define FREE_RANGE_TABLE_WORK_AREA(work_area) \ - do { \ - if ((work_area).table) \ - free ((work_area).table); \ - } while (0) - -#define CLEAR_RANGE_TABLE_WORK_USED(work_area) ((work_area).used = 0) -#define RANGE_TABLE_WORK_USED(work_area) ((work_area).used) -#define RANGE_TABLE_WORK_ELT(work_area, i) ((work_area).table[i]) - - -/* Set the bit for character C in a list. */ -#define SET_LIST_BIT(c) \ - (b[((unsigned char) (c)) / BYTEWIDTH] \ - |= 1 << (((unsigned char) c) % BYTEWIDTH)) - - -/* Get the next unsigned number in the uncompiled pattern. */ -#define GET_UNSIGNED_NUMBER(num) \ - { if (p != pend) \ - { \ - PATFETCH (c); \ - while (ISDIGIT (c)) \ - { \ - if (num < 0) \ - num = 0; \ - num = num * 10 + c - '0'; \ - if (p == pend) \ - break; \ - PATFETCH (c); \ - } \ - } \ - } - -#define CHAR_CLASS_MAX_LENGTH 6 /* Namely, `xdigit'. */ - -#define IS_CHAR_CLASS(string) \ - (STREQ (string, "alpha") || STREQ (string, "upper") \ - || STREQ (string, "lower") || STREQ (string, "digit") \ - || STREQ (string, "alnum") || STREQ (string, "xdigit") \ - || STREQ (string, "space") || STREQ (string, "print") \ - || STREQ (string, "punct") || STREQ (string, "graph") \ - || STREQ (string, "cntrl") || STREQ (string, "blank")) - -#ifndef MATCH_MAY_ALLOCATE - -/* If we cannot allocate large objects within re_match_2_internal, - we make the fail stack and register vectors global. - The fail stack, we grow to the maximum size when a regexp - is compiled. - The register vectors, we adjust in size each time we - compile a regexp, according to the number of registers it needs. */ - -static fail_stack_type fail_stack; - -/* Size with which the following vectors are currently allocated. - That is so we can make them bigger as needed, - but never make them smaller. */ -static int regs_allocated_size; - -static const char ** regstart, ** regend; -static const char ** old_regstart, ** old_regend; -static const char **best_regstart, **best_regend; -static register_info_type *reg_info; -static const char **reg_dummy; -static register_info_type *reg_info_dummy; - -/* Make the register vectors big enough for NUM_REGS registers, - but don't make them smaller. */ - -static -regex_grow_registers (num_regs) - int num_regs; -{ - if (num_regs > regs_allocated_size) - { - RETALLOC_IF (regstart, num_regs, const char *); - RETALLOC_IF (regend, num_regs, const char *); - RETALLOC_IF (old_regstart, num_regs, const char *); - RETALLOC_IF (old_regend, num_regs, const char *); - RETALLOC_IF (best_regstart, num_regs, const char *); - RETALLOC_IF (best_regend, num_regs, const char *); - RETALLOC_IF (reg_info, num_regs, register_info_type); - RETALLOC_IF (reg_dummy, num_regs, const char *); - RETALLOC_IF (reg_info_dummy, num_regs, register_info_type); - - regs_allocated_size = num_regs; - } -} - -#endif /* not MATCH_MAY_ALLOCATE */ - -/* `regex_compile' compiles PATTERN (of length SIZE) according to SYNTAX. - Returns one of error codes defined in `regex.h', or zero for success. - - Assumes the `allocated' (and perhaps `buffer') and `translate' - fields are set in BUFP on entry. - - If it succeeds, results are put in BUFP (if it returns an error, the - contents of BUFP are undefined): - `buffer' is the compiled pattern; - `syntax' is set to SYNTAX; - `used' is set to the length of the compiled pattern; - `fastmap_accurate' is zero; - `re_nsub' is the number of subexpressions in PATTERN; - `not_bol' and `not_eol' are zero; - - The `fastmap' and `newline_anchor' fields are neither - examined nor set. */ - -/* Return, freeing storage we allocated. */ -#define FREE_STACK_RETURN(value) \ - do { \ - FREE_RANGE_TABLE_WORK_AREA (range_table_work); \ - free (compile_stack.stack); \ - return value; \ - } while (0) - -static reg_errcode_t -regex_compile (pattern, size, syntax, bufp) - const char *pattern; - int size; - reg_syntax_t syntax; - struct re_pattern_buffer *bufp; -{ - /* We fetch characters from PATTERN here. Even though PATTERN is - `char *' (i.e., signed), we declare these variables as unsigned, so - they can be reliably used as array indices. */ - register unsigned int c, c1; - - /* A random temporary spot in PATTERN. */ - const char *p1; - - /* Points to the end of the buffer, where we should append. */ - register unsigned char *b; - - /* Keeps track of unclosed groups. */ - compile_stack_type compile_stack; - - /* Points to the current (ending) position in the pattern. */ -#ifdef AIX - /* `const' makes AIX compiler fail. */ - char *p = pattern; -#else - const char *p = pattern; -#endif - const char *pend = pattern + size; - - /* How to translate the characters in the pattern. */ - RE_TRANSLATE_TYPE translate = bufp->translate; - - /* Address of the count-byte of the most recently inserted `exactn' - command. This makes it possible to tell if a new exact-match - character can be added to that command or if the character requires - a new `exactn' command. */ - unsigned char *pending_exact = 0; - - /* Address of start of the most recently finished expression. - This tells, e.g., postfix * where to find the start of its - operand. Reset at the beginning of groups and alternatives. */ - unsigned char *laststart = 0; - - /* Address of beginning of regexp, or inside of last group. */ - unsigned char *begalt; - - /* Place in the uncompiled pattern (i.e., the {) to - which to go back if the interval is invalid. */ - const char *beg_interval; - - /* Address of the place where a forward jump should go to the end of - the containing expression. Each alternative of an `or' -- except the - last -- ends with a forward jump of this sort. */ - unsigned char *fixup_alt_jump = 0; - - /* Counts open-groups as they are encountered. Remembered for the - matching close-group on the compile stack, so the same register - number is put in the stop_memory as the start_memory. */ - regnum_t regnum = 0; - - /* Work area for range table of charset. */ - struct range_table_work_area range_table_work; - -#ifdef DEBUG - DEBUG_PRINT1 ("\nCompiling pattern: "); - if (debug) - { - unsigned debug_count; - - for (debug_count = 0; debug_count < size; debug_count++) - putchar (pattern[debug_count]); - putchar ('\n'); - } -#endif /* DEBUG */ - - /* Initialize the compile stack. */ - compile_stack.stack = TALLOC (INIT_COMPILE_STACK_SIZE, compile_stack_elt_t); - if (compile_stack.stack == NULL) - return REG_ESPACE; - - compile_stack.size = INIT_COMPILE_STACK_SIZE; - compile_stack.avail = 0; - - range_table_work.table = 0; - range_table_work.allocated = 0; - - /* Initialize the pattern buffer. */ - bufp->syntax = syntax; - bufp->fastmap_accurate = 0; - bufp->not_bol = bufp->not_eol = 0; - - /* Set `used' to zero, so that if we return an error, the pattern - printer (for debugging) will think there's no pattern. We reset it - at the end. */ - bufp->used = 0; - - /* Always count groups, whether or not bufp->no_sub is set. */ - bufp->re_nsub = 0; - -#ifdef emacs - /* bufp->multibyte is set before regex_compile is called, so don't alter - it. */ -#else /* not emacs */ - /* Nothing is recognized as a multibyte character. */ - bufp->multibyte = 0; -#endif - -#if !defined (emacs) && !defined (SYNTAX_TABLE) - /* Initialize the syntax table. */ - init_syntax_once (); -#endif - - if (bufp->allocated == 0) - { - if (bufp->buffer) - { /* If zero allocated, but buffer is non-null, try to realloc - enough space. This loses if buffer's address is bogus, but - that is the user's responsibility. */ - RETALLOC (bufp->buffer, INIT_BUF_SIZE, unsigned char); - } - else - { /* Caller did not allocate a buffer. Do it for them. */ - bufp->buffer = TALLOC (INIT_BUF_SIZE, unsigned char); - } - if (!bufp->buffer) FREE_STACK_RETURN (REG_ESPACE); - - bufp->allocated = INIT_BUF_SIZE; - } - - begalt = b = bufp->buffer; - - /* Loop through the uncompiled pattern until we're at the end. */ - while (p != pend) - { - PATFETCH (c); - - switch (c) - { - case '^': - { - if ( /* If at start of pattern, it's an operator. */ - p == pattern + 1 - /* If context independent, it's an operator. */ - || syntax & RE_CONTEXT_INDEP_ANCHORS - /* Otherwise, depends on what's come before. */ - || at_begline_loc_p (pattern, p, syntax)) - BUF_PUSH (begline); - else - goto normal_char; - } - break; - - - case '$': - { - if ( /* If at end of pattern, it's an operator. */ - p == pend - /* If context independent, it's an operator. */ - || syntax & RE_CONTEXT_INDEP_ANCHORS - /* Otherwise, depends on what's next. */ - || at_endline_loc_p (p, pend, syntax)) - BUF_PUSH (endline); - else - goto normal_char; - } - break; - - - case '+': - case '?': - if ((syntax & RE_BK_PLUS_QM) - || (syntax & RE_LIMITED_OPS)) - goto normal_char; - handle_plus: - case '*': - /* If there is no previous pattern... */ - if (!laststart) - { - if (syntax & RE_CONTEXT_INVALID_OPS) - FREE_STACK_RETURN (REG_BADRPT); - else if (!(syntax & RE_CONTEXT_INDEP_OPS)) - goto normal_char; - } - - { - /* Are we optimizing this jump? */ - boolean keep_string_p = false; - - /* 1 means zero (many) matches is allowed. */ - char zero_times_ok = 0, many_times_ok = 0; - - /* If there is a sequence of repetition chars, collapse it - down to just one (the right one). We can't combine - interval operators with these because of, e.g., `a{2}*', - which should only match an even number of `a's. */ - - for (;;) - { - zero_times_ok |= c != '+'; - many_times_ok |= c != '?'; - - if (p == pend) - break; - - PATFETCH (c); - - if (c == '*' - || (!(syntax & RE_BK_PLUS_QM) && (c == '+' || c == '?'))) - ; - - else if (syntax & RE_BK_PLUS_QM && c == '\\') - { - if (p == pend) FREE_STACK_RETURN (REG_EESCAPE); - - PATFETCH (c1); - if (!(c1 == '+' || c1 == '?')) - { - PATUNFETCH; - PATUNFETCH; - break; - } - - c = c1; - } - else - { - PATUNFETCH; - break; - } - - /* If we get here, we found another repeat character. */ - } - - /* Star, etc. applied to an empty pattern is equivalent - to an empty pattern. */ - if (!laststart) - break; - - /* Now we know whether or not zero matches is allowed - and also whether or not two or more matches is allowed. */ - if (many_times_ok) - { /* More than one repetition is allowed, so put in at the - end a backward relative jump from `b' to before the next - jump we're going to put in below (which jumps from - laststart to after this jump). - - But if we are at the `*' in the exact sequence `.*\n', - insert an unconditional jump backwards to the ., - instead of the beginning of the loop. This way we only - push a failure point once, instead of every time - through the loop. */ - assert (p - 1 > pattern); - - /* Allocate the space for the jump. */ - GET_BUFFER_SPACE (3); - - /* We know we are not at the first character of the pattern, - because laststart was nonzero. And we've already - incremented `p', by the way, to be the character after - the `*'. Do we have to do something analogous here - for null bytes, because of RE_DOT_NOT_NULL? */ - if (TRANSLATE ((unsigned char)*(p - 2)) == TRANSLATE ('.') - && zero_times_ok - && p < pend - && TRANSLATE ((unsigned char)*p) == TRANSLATE ('\n') - && !(syntax & RE_DOT_NEWLINE)) - { /* We have .*\n. */ - STORE_JUMP (jump, b, laststart); - keep_string_p = true; - } - else - /* Anything else. */ - STORE_JUMP (maybe_pop_jump, b, laststart - 3); - - /* We've added more stuff to the buffer. */ - b += 3; - } - - /* On failure, jump from laststart to b + 3, which will be the - end of the buffer after this jump is inserted. */ - GET_BUFFER_SPACE (3); - INSERT_JUMP (keep_string_p ? on_failure_keep_string_jump - : on_failure_jump, - laststart, b + 3); - pending_exact = 0; - b += 3; - - if (!zero_times_ok) - { - /* At least one repetition is required, so insert a - `dummy_failure_jump' before the initial - `on_failure_jump' instruction of the loop. This - effects a skip over that instruction the first time - we hit that loop. */ - GET_BUFFER_SPACE (3); - INSERT_JUMP (dummy_failure_jump, laststart, laststart + 6); - b += 3; - } - } - break; - - - case '.': - laststart = b; - BUF_PUSH (anychar); - break; - - - case '[': - { - CLEAR_RANGE_TABLE_WORK_USED (range_table_work); - - if (p == pend) FREE_STACK_RETURN (REG_EBRACK); - - /* Ensure that we have enough space to push a charset: the - opcode, the length count, and the bitset; 34 bytes in all. */ - GET_BUFFER_SPACE (34); - - laststart = b; - - /* We test `*p == '^' twice, instead of using an if - statement, so we only need one BUF_PUSH. */ - BUF_PUSH (*p == '^' ? charset_not : charset); - if (*p == '^') - p++; - - /* Remember the first position in the bracket expression. */ - p1 = p; - - /* Push the number of bytes in the bitmap. */ - BUF_PUSH ((1 << BYTEWIDTH) / BYTEWIDTH); - - /* Clear the whole map. */ - bzero (b, (1 << BYTEWIDTH) / BYTEWIDTH); - - /* charset_not matches newline according to a syntax bit. */ - if ((re_opcode_t) b[-2] == charset_not - && (syntax & RE_HAT_LISTS_NOT_NEWLINE)) - SET_LIST_BIT ('\n'); - - /* Read in characters and ranges, setting map bits. */ - for (;;) - { - int len; - boolean escaped_char = false; - - if (p == pend) FREE_STACK_RETURN (REG_EBRACK); - - PATFETCH (c); - - /* \ might escape characters inside [...] and [^...]. */ - if ((syntax & RE_BACKSLASH_ESCAPE_IN_LISTS) && c == '\\') - { - if (p == pend) FREE_STACK_RETURN (REG_EESCAPE); - - PATFETCH (c); - escaped_char = true; - } - else - { - /* Could be the end of the bracket expression. If it's - not (i.e., when the bracket expression is `[]' so - far), the ']' character bit gets set way below. */ - if (c == ']' && p != p1 + 1) - break; - } - - /* If C indicates start of multibyte char, get the - actual character code in C, and set the pattern - pointer P to the next character boundary. */ - if (bufp->multibyte && BASE_LEADING_CODE_P (c)) - { - PATUNFETCH; - c = STRING_CHAR_AND_LENGTH (p, pend - p, len); - p += len; - } - /* What should we do for the character which is - greater than 0x7F, but not BASE_LEADING_CODE_P? - XXX */ - - /* See if we're at the beginning of a possible character - class. */ - - else if (!escaped_char && - syntax & RE_CHAR_CLASSES && c == '[' && *p == ':') - { - /* Leave room for the null. */ - char str[CHAR_CLASS_MAX_LENGTH + 1]; - - PATFETCH (c); - c1 = 0; - - /* If pattern is `[[:'. */ - if (p == pend) FREE_STACK_RETURN (REG_EBRACK); - - for (;;) - { - PATFETCH (c); - if (c == ':' || c == ']' || p == pend - || c1 == CHAR_CLASS_MAX_LENGTH) - break; - str[c1++] = c; - } - str[c1] = '\0'; - - /* If isn't a word bracketed by `[:' and `:]': - undo the ending character, the letters, and - leave the leading `:' and `[' (but set bits for - them). */ - if (c == ':' && *p == ']') - { - int ch; - boolean is_alnum = STREQ (str, "alnum"); - boolean is_alpha = STREQ (str, "alpha"); - boolean is_blank = STREQ (str, "blank"); - boolean is_cntrl = STREQ (str, "cntrl"); - boolean is_digit = STREQ (str, "digit"); - boolean is_graph = STREQ (str, "graph"); - boolean is_lower = STREQ (str, "lower"); - boolean is_print = STREQ (str, "print"); - boolean is_punct = STREQ (str, "punct"); - boolean is_space = STREQ (str, "space"); - boolean is_upper = STREQ (str, "upper"); - boolean is_xdigit = STREQ (str, "xdigit"); - - if (!IS_CHAR_CLASS (str)) - FREE_STACK_RETURN (REG_ECTYPE); - - /* Throw away the ] at the end of the character - class. */ - PATFETCH (c); - - if (p == pend) FREE_STACK_RETURN (REG_EBRACK); - - for (ch = 0; ch < 1 << BYTEWIDTH; ch++) - { - int translated = TRANSLATE (ch); - /* This was split into 3 if's to - avoid an arbitrary limit in some compiler. */ - if ( (is_alnum && ISALNUM (ch)) - || (is_alpha && ISALPHA (ch)) - || (is_blank && ISBLANK (ch)) - || (is_cntrl && ISCNTRL (ch))) - SET_LIST_BIT (translated); - if ( (is_digit && ISDIGIT (ch)) - || (is_graph && ISGRAPH (ch)) - || (is_lower && ISLOWER (ch)) - || (is_print && ISPRINT (ch))) - SET_LIST_BIT (translated); - if ( (is_punct && ISPUNCT (ch)) - || (is_space && ISSPACE (ch)) - || (is_upper && ISUPPER (ch)) - || (is_xdigit && ISXDIGIT (ch))) - SET_LIST_BIT (translated); - } - - /* Repeat the loop. */ - continue; - } - else - { - c1++; - while (c1--) - PATUNFETCH; - SET_LIST_BIT ('['); - - /* Because the `:' may starts the range, we - can't simply set bit and repeat the loop. - Instead, just set it to C and handle below. */ - c = ':'; - } - } - - if (p < pend && p[0] == '-' && p[1] != ']') - { - - /* Discard the `-'. */ - PATFETCH (c1); - - /* Fetch the character which ends the range. */ - PATFETCH (c1); - if (bufp->multibyte && BASE_LEADING_CODE_P (c1)) - { - PATUNFETCH; - c1 = STRING_CHAR_AND_LENGTH (p, pend - p, len); - p += len; - } - - if (SINGLE_BYTE_CHAR_P (c) - && ! SINGLE_BYTE_CHAR_P (c1)) - { - /* Handle a range such as \177-\377 in multibyte mode. - Split that into two ranges,, - the low one ending at 0237, and the high one - starting at ...040. */ - int c1_base = (c1 & ~0177) | 040; - SET_RANGE_TABLE_WORK_AREA (range_table_work, c, c1); - c1 = 0237; - } - else if (!SAME_CHARSET_P (c, c1)) - FREE_STACK_RETURN (REG_ERANGE); - } - else - /* Range from C to C. */ - c1 = c; - - /* Set the range ... */ - if (SINGLE_BYTE_CHAR_P (c)) - /* ... into bitmap. */ - { - unsigned this_char; - int range_start = c, range_end = c1; - - /* If the start is after the end, the range is empty. */ - if (range_start > range_end) - { - if (syntax & RE_NO_EMPTY_RANGES) - FREE_STACK_RETURN (REG_ERANGE); - /* Else, repeat the loop. */ - } - else - { - for (this_char = range_start; this_char <= range_end; - this_char++) - SET_LIST_BIT (TRANSLATE (this_char)); - } - } - else - /* ... into range table. */ - SET_RANGE_TABLE_WORK_AREA (range_table_work, c, c1); - } - - /* Discard any (non)matching list bytes that are all 0 at the - end of the map. Decrease the map-length byte too. */ - while ((int) b[-1] > 0 && b[b[-1] - 1] == 0) - b[-1]--; - b += b[-1]; - - /* Build real range table from work area. */ - if (RANGE_TABLE_WORK_USED (range_table_work)) - { - int i; - int used = RANGE_TABLE_WORK_USED (range_table_work); - - /* Allocate space for COUNT + RANGE_TABLE. Needs two - bytes for COUNT and three bytes for each character. */ - GET_BUFFER_SPACE (2 + used * 3); - - /* Indicate the existence of range table. */ - laststart[1] |= 0x80; - - STORE_NUMBER_AND_INCR (b, used / 2); - for (i = 0; i < used; i++) - STORE_CHARACTER_AND_INCR - (b, RANGE_TABLE_WORK_ELT (range_table_work, i)); - } - } - break; - - - case '(': - if (syntax & RE_NO_BK_PARENS) - goto handle_open; - else - goto normal_char; - - - case ')': - if (syntax & RE_NO_BK_PARENS) - goto handle_close; - else - goto normal_char; - - - case '\n': - if (syntax & RE_NEWLINE_ALT) - goto handle_alt; - else - goto normal_char; - - - case '|': - if (syntax & RE_NO_BK_VBAR) - goto handle_alt; - else - goto normal_char; - - - case '{': - if (syntax & RE_INTERVALS && syntax & RE_NO_BK_BRACES) - goto handle_interval; - else - goto normal_char; - - - case '\\': - if (p == pend) FREE_STACK_RETURN (REG_EESCAPE); - - /* Do not translate the character after the \, so that we can - distinguish, e.g., \B from \b, even if we normally would - translate, e.g., B to b. */ - PATFETCH_RAW (c); - - switch (c) - { - case '(': - if (syntax & RE_NO_BK_PARENS) - goto normal_backslash; - - handle_open: - bufp->re_nsub++; - regnum++; - - if (COMPILE_STACK_FULL) - { - RETALLOC (compile_stack.stack, compile_stack.size << 1, - compile_stack_elt_t); - if (compile_stack.stack == NULL) return REG_ESPACE; - - compile_stack.size <<= 1; - } - - /* These are the values to restore when we hit end of this - group. They are all relative offsets, so that if the - whole pattern moves because of realloc, they will still - be valid. */ - COMPILE_STACK_TOP.begalt_offset = begalt - bufp->buffer; - COMPILE_STACK_TOP.fixup_alt_jump - = fixup_alt_jump ? fixup_alt_jump - bufp->buffer + 1 : 0; - COMPILE_STACK_TOP.laststart_offset = b - bufp->buffer; - COMPILE_STACK_TOP.regnum = regnum; - - /* We will eventually replace the 0 with the number of - groups inner to this one. But do not push a - start_memory for groups beyond the last one we can - represent in the compiled pattern. */ - if (regnum <= MAX_REGNUM) - { - COMPILE_STACK_TOP.inner_group_offset = b - bufp->buffer + 2; - BUF_PUSH_3 (start_memory, regnum, 0); - } - - compile_stack.avail++; - - fixup_alt_jump = 0; - laststart = 0; - begalt = b; - /* If we've reached MAX_REGNUM groups, then this open - won't actually generate any code, so we'll have to - clear pending_exact explicitly. */ - pending_exact = 0; - break; - - - case ')': - if (syntax & RE_NO_BK_PARENS) goto normal_backslash; - - if (COMPILE_STACK_EMPTY) - if (syntax & RE_UNMATCHED_RIGHT_PAREN_ORD) - goto normal_backslash; - else - FREE_STACK_RETURN (REG_ERPAREN); - - handle_close: - if (fixup_alt_jump) - { /* Push a dummy failure point at the end of the - alternative for a possible future - `pop_failure_jump' to pop. See comments at - `push_dummy_failure' in `re_match_2'. */ - BUF_PUSH (push_dummy_failure); - - /* We allocated space for this jump when we assigned - to `fixup_alt_jump', in the `handle_alt' case below. */ - STORE_JUMP (jump_past_alt, fixup_alt_jump, b - 1); - } - - /* See similar code for backslashed left paren above. */ - if (COMPILE_STACK_EMPTY) - if (syntax & RE_UNMATCHED_RIGHT_PAREN_ORD) - goto normal_char; - else - FREE_STACK_RETURN (REG_ERPAREN); - - /* Since we just checked for an empty stack above, this - ``can't happen''. */ - assert (compile_stack.avail != 0); - { - /* We don't just want to restore into `regnum', because - later groups should continue to be numbered higher, - as in `(ab)c(de)' -- the second group is #2. */ - regnum_t this_group_regnum; - - compile_stack.avail--; - begalt = bufp->buffer + COMPILE_STACK_TOP.begalt_offset; - fixup_alt_jump - = COMPILE_STACK_TOP.fixup_alt_jump - ? bufp->buffer + COMPILE_STACK_TOP.fixup_alt_jump - 1 - : 0; - laststart = bufp->buffer + COMPILE_STACK_TOP.laststart_offset; - this_group_regnum = COMPILE_STACK_TOP.regnum; - /* If we've reached MAX_REGNUM groups, then this open - won't actually generate any code, so we'll have to - clear pending_exact explicitly. */ - pending_exact = 0; - - /* We're at the end of the group, so now we know how many - groups were inside this one. */ - if (this_group_regnum <= MAX_REGNUM) - { - unsigned char *inner_group_loc - = bufp->buffer + COMPILE_STACK_TOP.inner_group_offset; - - *inner_group_loc = regnum - this_group_regnum; - BUF_PUSH_3 (stop_memory, this_group_regnum, - regnum - this_group_regnum); - } - } - break; - - - case '|': /* `\|'. */ - if (syntax & RE_LIMITED_OPS || syntax & RE_NO_BK_VBAR) - goto normal_backslash; - handle_alt: - if (syntax & RE_LIMITED_OPS) - goto normal_char; - - /* Insert before the previous alternative a jump which - jumps to this alternative if the former fails. */ - GET_BUFFER_SPACE (3); - INSERT_JUMP (on_failure_jump, begalt, b + 6); - pending_exact = 0; - b += 3; - - /* The alternative before this one has a jump after it - which gets executed if it gets matched. Adjust that - jump so it will jump to this alternative's analogous - jump (put in below, which in turn will jump to the next - (if any) alternative's such jump, etc.). The last such - jump jumps to the correct final destination. A picture: - _____ _____ - | | | | - | v | v - a | b | c - - If we are at `b', then fixup_alt_jump right now points to a - three-byte space after `a'. We'll put in the jump, set - fixup_alt_jump to right after `b', and leave behind three - bytes which we'll fill in when we get to after `c'. */ - - if (fixup_alt_jump) - STORE_JUMP (jump_past_alt, fixup_alt_jump, b); - - /* Mark and leave space for a jump after this alternative, - to be filled in later either by next alternative or - when know we're at the end of a series of alternatives. */ - fixup_alt_jump = b; - GET_BUFFER_SPACE (3); - b += 3; - - laststart = 0; - begalt = b; - break; - - - case '{': - /* If \{ is a literal. */ - if (!(syntax & RE_INTERVALS) - /* If we're at `\{' and it's not the open-interval - operator. */ - || ((syntax & RE_INTERVALS) && (syntax & RE_NO_BK_BRACES)) - || (p - 2 == pattern && p == pend)) - goto normal_backslash; - - handle_interval: - { - /* If got here, then the syntax allows intervals. */ - - /* At least (most) this many matches must be made. */ - int lower_bound = -1, upper_bound = -1; - - beg_interval = p - 1; - - if (p == pend) - { - if (syntax & RE_NO_BK_BRACES) - goto unfetch_interval; - else - FREE_STACK_RETURN (REG_EBRACE); - } - - GET_UNSIGNED_NUMBER (lower_bound); - - if (c == ',') - { - GET_UNSIGNED_NUMBER (upper_bound); - if (upper_bound < 0) upper_bound = RE_DUP_MAX; - } - else - /* Interval such as `{1}' => match exactly once. */ - upper_bound = lower_bound; - - if (lower_bound < 0 || upper_bound > RE_DUP_MAX - || lower_bound > upper_bound) - { - if (syntax & RE_NO_BK_BRACES) - goto unfetch_interval; - else - FREE_STACK_RETURN (REG_BADBR); - } - - if (!(syntax & RE_NO_BK_BRACES)) - { - if (c != '\\') FREE_STACK_RETURN (REG_EBRACE); - - PATFETCH (c); - } - - if (c != '}') - { - if (syntax & RE_NO_BK_BRACES) - goto unfetch_interval; - else - FREE_STACK_RETURN (REG_BADBR); - } - - /* We just parsed a valid interval. */ - - /* If it's invalid to have no preceding re. */ - if (!laststart) - { - if (syntax & RE_CONTEXT_INVALID_OPS) - FREE_STACK_RETURN (REG_BADRPT); - else if (syntax & RE_CONTEXT_INDEP_OPS) - laststart = b; - else - goto unfetch_interval; - } - - /* If the upper bound is zero, don't want to succeed at - all; jump from `laststart' to `b + 3', which will be - the end of the buffer after we insert the jump. */ - if (upper_bound == 0) - { - GET_BUFFER_SPACE (3); - INSERT_JUMP (jump, laststart, b + 3); - b += 3; - } - - /* Otherwise, we have a nontrivial interval. When - we're all done, the pattern will look like: - set_number_at - set_number_at - succeed_n - - jump_n - (The upper bound and `jump_n' are omitted if - `upper_bound' is 1, though.) */ - else - { /* If the upper bound is > 1, we need to insert - more at the end of the loop. */ - unsigned nbytes = 10 + (upper_bound > 1) * 10; - - GET_BUFFER_SPACE (nbytes); - - /* Initialize lower bound of the `succeed_n', even - though it will be set during matching by its - attendant `set_number_at' (inserted next), - because `re_compile_fastmap' needs to know. - Jump to the `jump_n' we might insert below. */ - INSERT_JUMP2 (succeed_n, laststart, - b + 5 + (upper_bound > 1) * 5, - lower_bound); - b += 5; - - /* Code to initialize the lower bound. Insert - before the `succeed_n'. The `5' is the last two - bytes of this `set_number_at', plus 3 bytes of - the following `succeed_n'. */ - insert_op2 (set_number_at, laststart, 5, lower_bound, b); - b += 5; - - if (upper_bound > 1) - { /* More than one repetition is allowed, so - append a backward jump to the `succeed_n' - that starts this interval. - - When we've reached this during matching, - we'll have matched the interval once, so - jump back only `upper_bound - 1' times. */ - STORE_JUMP2 (jump_n, b, laststart + 5, - upper_bound - 1); - b += 5; - - /* The location we want to set is the second - parameter of the `jump_n'; that is `b-2' as - an absolute address. `laststart' will be - the `set_number_at' we're about to insert; - `laststart+3' the number to set, the source - for the relative address. But we are - inserting into the middle of the pattern -- - so everything is getting moved up by 5. - Conclusion: (b - 2) - (laststart + 3) + 5, - i.e., b - laststart. - - We insert this at the beginning of the loop - so that if we fail during matching, we'll - reinitialize the bounds. */ - insert_op2 (set_number_at, laststart, b - laststart, - upper_bound - 1, b); - b += 5; - } - } - pending_exact = 0; - beg_interval = NULL; - } - break; - - unfetch_interval: - /* If an invalid interval, match the characters as literals. */ - assert (beg_interval); - p = beg_interval; - beg_interval = NULL; - - /* normal_char and normal_backslash need `c'. */ - PATFETCH (c); - - if (!(syntax & RE_NO_BK_BRACES)) - { - if (p > pattern && p[-1] == '\\') - goto normal_backslash; - } - goto normal_char; - -#ifdef emacs - /* There is no way to specify the before_dot and after_dot - operators. rms says this is ok. --karl */ - case '=': - BUF_PUSH (at_dot); - break; - - case 's': - laststart = b; - PATFETCH (c); - BUF_PUSH_2 (syntaxspec, syntax_spec_code[c]); - break; - - case 'S': - laststart = b; - PATFETCH (c); - BUF_PUSH_2 (notsyntaxspec, syntax_spec_code[c]); - break; - - case 'c': - laststart = b; - PATFETCH_RAW (c); - BUF_PUSH_2 (categoryspec, c); - break; - - case 'C': - laststart = b; - PATFETCH_RAW (c); - BUF_PUSH_2 (notcategoryspec, c); - break; -#endif /* emacs */ - - - case 'w': - laststart = b; - BUF_PUSH (wordchar); - break; - - - case 'W': - laststart = b; - BUF_PUSH (notwordchar); - break; - - - case '<': - BUF_PUSH (wordbeg); - break; - - case '>': - BUF_PUSH (wordend); - break; - - case 'b': - BUF_PUSH (wordbound); - break; - - case 'B': - BUF_PUSH (notwordbound); - break; - - case '`': - BUF_PUSH (begbuf); - break; - - case '\'': - BUF_PUSH (endbuf); - break; - - case '1': case '2': case '3': case '4': case '5': - case '6': case '7': case '8': case '9': - if (syntax & RE_NO_BK_REFS) - goto normal_char; - - c1 = c - '0'; - - if (c1 > regnum) - FREE_STACK_RETURN (REG_ESUBREG); - - /* Can't back reference to a subexpression if inside of it. */ - if (group_in_compile_stack (compile_stack, c1)) - goto normal_char; - - laststart = b; - BUF_PUSH_2 (duplicate, c1); - break; - - - case '+': - case '?': - if (syntax & RE_BK_PLUS_QM) - goto handle_plus; - else - goto normal_backslash; - - default: - normal_backslash: - /* You might think it would be useful for \ to mean - not to translate; but if we don't translate it - it will never match anything. */ - c = TRANSLATE (c); - goto normal_char; - } - break; - - - default: - /* Expects the character in `c'. */ - normal_char: - p1 = p - 1; /* P1 points the head of C. */ -#ifdef emacs - if (bufp->multibyte) - { - c = STRING_CHAR (p1, pend - p1); - c = TRANSLATE (c); - /* Set P to the next character boundary. */ - p += MULTIBYTE_FORM_LENGTH (p1, pend - p1) - 1; - } -#endif - /* If no exactn currently being built. */ - if (!pending_exact - - /* If last exactn not at current position. */ - || pending_exact + *pending_exact + 1 != b - - /* We have only one byte following the exactn for the count. */ - || *pending_exact >= (1 << BYTEWIDTH) - (p - p1) - - /* If followed by a repetition operator. */ - || (p != pend && (*p == '*' || *p == '^')) - || ((syntax & RE_BK_PLUS_QM) - ? p + 1 < pend && *p == '\\' && (p[1] == '+' || p[1] == '?') - : p != pend && (*p == '+' || *p == '?')) - || ((syntax & RE_INTERVALS) - && ((syntax & RE_NO_BK_BRACES) - ? p != pend && *p == '{' - : p + 1 < pend && p[0] == '\\' && p[1] == '{'))) - { - /* Start building a new exactn. */ - - laststart = b; - - BUF_PUSH_2 (exactn, 0); - pending_exact = b - 1; - } - -#ifdef emacs - if (! SINGLE_BYTE_CHAR_P (c)) - { - unsigned char work[4], *str; - int i = CHAR_STRING (c, work, str); - int j; - for (j = 0; j < i; j++) - { - BUF_PUSH (str[j]); - (*pending_exact)++; - } - } - else -#endif - { - BUF_PUSH (c); - (*pending_exact)++; - } - break; - } /* switch (c) */ - } /* while p != pend */ - - - /* Through the pattern now. */ - - if (fixup_alt_jump) - STORE_JUMP (jump_past_alt, fixup_alt_jump, b); - - if (!COMPILE_STACK_EMPTY) - FREE_STACK_RETURN (REG_EPAREN); - - /* If we don't want backtracking, force success - the first time we reach the end of the compiled pattern. */ - if (syntax & RE_NO_POSIX_BACKTRACKING) - BUF_PUSH (succeed); - - free (compile_stack.stack); - - /* We have succeeded; set the length of the buffer. */ - bufp->used = b - bufp->buffer; - -#ifdef DEBUG - if (debug) - { - DEBUG_PRINT1 ("\nCompiled pattern: \n"); - print_compiled_pattern (bufp); - } -#endif /* DEBUG */ - -#ifndef MATCH_MAY_ALLOCATE - /* Initialize the failure stack to the largest possible stack. This - isn't necessary unless we're trying to avoid calling alloca in - the search and match routines. */ - { - int num_regs = bufp->re_nsub + 1; - - if (fail_stack.size < re_max_failures * TYPICAL_FAILURE_SIZE) - { - fail_stack.size = re_max_failures * TYPICAL_FAILURE_SIZE; - -#ifdef emacs - if (! fail_stack.stack) - fail_stack.stack - = (fail_stack_elt_t *) xmalloc (fail_stack.size - * sizeof (fail_stack_elt_t)); - else - fail_stack.stack - = (fail_stack_elt_t *) xrealloc (fail_stack.stack, - (fail_stack.size - * sizeof (fail_stack_elt_t))); -#else /* not emacs */ - if (! fail_stack.stack) - fail_stack.stack - = (fail_stack_elt_t *) malloc (fail_stack.size - * sizeof (fail_stack_elt_t)); - else - fail_stack.stack - = (fail_stack_elt_t *) realloc (fail_stack.stack, - (fail_stack.size - * sizeof (fail_stack_elt_t))); -#endif /* not emacs */ - } - - regex_grow_registers (num_regs); - } -#endif /* not MATCH_MAY_ALLOCATE */ - - return REG_NOERROR; -} /* regex_compile */ - -/* Subroutines for `regex_compile'. */ - -/* Store OP at LOC followed by two-byte integer parameter ARG. */ - -static void -store_op1 (op, loc, arg) - re_opcode_t op; - unsigned char *loc; - int arg; -{ - *loc = (unsigned char) op; - STORE_NUMBER (loc + 1, arg); -} - - -/* Like `store_op1', but for two two-byte parameters ARG1 and ARG2. */ - -static void -store_op2 (op, loc, arg1, arg2) - re_opcode_t op; - unsigned char *loc; - int arg1, arg2; -{ - *loc = (unsigned char) op; - STORE_NUMBER (loc + 1, arg1); - STORE_NUMBER (loc + 3, arg2); -} - - -/* Copy the bytes from LOC to END to open up three bytes of space at LOC - for OP followed by two-byte integer parameter ARG. */ - -static void -insert_op1 (op, loc, arg, end) - re_opcode_t op; - unsigned char *loc; - int arg; - unsigned char *end; -{ - register unsigned char *pfrom = end; - register unsigned char *pto = end + 3; - - while (pfrom != loc) - *--pto = *--pfrom; - - store_op1 (op, loc, arg); -} - - -/* Like `insert_op1', but for two two-byte parameters ARG1 and ARG2. */ - -static void -insert_op2 (op, loc, arg1, arg2, end) - re_opcode_t op; - unsigned char *loc; - int arg1, arg2; - unsigned char *end; -{ - register unsigned char *pfrom = end; - register unsigned char *pto = end + 5; - - while (pfrom != loc) - *--pto = *--pfrom; - - store_op2 (op, loc, arg1, arg2); -} - - -/* P points to just after a ^ in PATTERN. Return true if that ^ comes - after an alternative or a begin-subexpression. We assume there is at - least one character before the ^. */ - -static boolean -at_begline_loc_p (pattern, p, syntax) - const char *pattern, *p; - reg_syntax_t syntax; -{ - const char *prev = p - 2; - boolean prev_prev_backslash = prev > pattern && prev[-1] == '\\'; - - return - /* After a subexpression? */ - (*prev == '(' && (syntax & RE_NO_BK_PARENS || prev_prev_backslash)) - /* After an alternative? */ - || (*prev == '|' && (syntax & RE_NO_BK_VBAR || prev_prev_backslash)); -} - - -/* The dual of at_begline_loc_p. This one is for $. We assume there is - at least one character after the $, i.e., `P < PEND'. */ - -static boolean -at_endline_loc_p (p, pend, syntax) - const char *p, *pend; - int syntax; -{ - const char *next = p; - boolean next_backslash = *next == '\\'; - const char *next_next = p + 1 < pend ? p + 1 : 0; - - return - /* Before a subexpression? */ - (syntax & RE_NO_BK_PARENS ? *next == ')' - : next_backslash && next_next && *next_next == ')') - /* Before an alternative? */ - || (syntax & RE_NO_BK_VBAR ? *next == '|' - : next_backslash && next_next && *next_next == '|'); -} - - -/* Returns true if REGNUM is in one of COMPILE_STACK's elements and - false if it's not. */ - -static boolean -group_in_compile_stack (compile_stack, regnum) - compile_stack_type compile_stack; - regnum_t regnum; -{ - int this_element; - - for (this_element = compile_stack.avail - 1; - this_element >= 0; - this_element--) - if (compile_stack.stack[this_element].regnum == regnum) - return true; - - return false; -} - -/* re_compile_fastmap computes a ``fastmap'' for the compiled pattern in - BUFP. A fastmap records which of the (1 << BYTEWIDTH) possible - characters can start a string that matches the pattern. This fastmap - is used by re_search to skip quickly over impossible starting points. - - The caller must supply the address of a (1 << BYTEWIDTH)-byte data - area as BUFP->fastmap. - - We set the `fastmap', `fastmap_accurate', and `can_be_null' fields in - the pattern buffer. - - Returns 0 if we succeed, -2 if an internal error. */ - -int -re_compile_fastmap (bufp) - struct re_pattern_buffer *bufp; -{ - int i, j, k; -#ifdef MATCH_MAY_ALLOCATE - fail_stack_type fail_stack; -#endif -#ifndef REGEX_MALLOC - char *destination; -#endif - /* We don't push any register information onto the failure stack. */ - unsigned num_regs = 0; - - register char *fastmap = bufp->fastmap; - unsigned char *pattern = bufp->buffer; - unsigned long size = bufp->used; - unsigned char *p = pattern; - register unsigned char *pend = pattern + size; - - /* This holds the pointer to the failure stack, when - it is allocated relocatably. */ - fail_stack_elt_t *failure_stack_ptr; - - /* Assume that each path through the pattern can be null until - proven otherwise. We set this false at the bottom of switch - statement, to which we get only if a particular path doesn't - match the empty string. */ - boolean path_can_be_null = true; - - /* We aren't doing a `succeed_n' to begin with. */ - boolean succeed_n_p = false; - - /* If all elements for base leading-codes in fastmap is set, this - flag is set true. */ - boolean match_any_multibyte_characters = false; - - /* Maximum code of simple (single byte) character. */ - int simple_char_max; - - assert (fastmap != NULL && p != NULL); - - INIT_FAIL_STACK (); - bzero (fastmap, 1 << BYTEWIDTH); /* Assume nothing's valid. */ - bufp->fastmap_accurate = 1; /* It will be when we're done. */ - bufp->can_be_null = 0; - - while (1) - { - if (p == pend || *p == succeed) - { - /* We have reached the (effective) end of pattern. */ - if (!FAIL_STACK_EMPTY ()) - { - bufp->can_be_null |= path_can_be_null; - - /* Reset for next path. */ - path_can_be_null = true; - - p = fail_stack.stack[--fail_stack.avail].pointer; - - continue; - } - else - break; - } - - /* We should never be about to go beyond the end of the pattern. */ - assert (p < pend); - - switch (SWITCH_ENUM_CAST ((re_opcode_t) *p++)) - { - - /* I guess the idea here is to simply not bother with a fastmap - if a backreference is used, since it's too hard to figure out - the fastmap for the corresponding group. Setting - `can_be_null' stops `re_search_2' from using the fastmap, so - that is all we do. */ - case duplicate: - bufp->can_be_null = 1; - goto done; - - - /* Following are the cases which match a character. These end - with `break'. */ - - case exactn: - fastmap[p[1]] = 1; - break; - - -#ifndef emacs - case charset: - for (j = *p++ * BYTEWIDTH - 1; j >= 0; j--) - if (p[j / BYTEWIDTH] & (1 << (j % BYTEWIDTH))) - fastmap[j] = 1; - break; - - - case charset_not: - /* Chars beyond end of map must be allowed. */ - for (j = *p * BYTEWIDTH; j < (1 << BYTEWIDTH); j++) - fastmap[j] = 1; - - for (j = *p++ * BYTEWIDTH - 1; j >= 0; j--) - if (!(p[j / BYTEWIDTH] & (1 << (j % BYTEWIDTH)))) - fastmap[j] = 1; - break; - - - case wordchar: - for (j = 0; j < (1 << BYTEWIDTH); j++) - if (SYNTAX (j) == Sword) - fastmap[j] = 1; - break; - - - case notwordchar: - for (j = 0; j < (1 << BYTEWIDTH); j++) - if (SYNTAX (j) != Sword) - fastmap[j] = 1; - break; -#else /* emacs */ - case charset: - for (j = CHARSET_BITMAP_SIZE (&p[-1]) * BYTEWIDTH - 1, p++; - j >= 0; j--) - if (p[j / BYTEWIDTH] & (1 << (j % BYTEWIDTH))) - fastmap[j] = 1; - - if (CHARSET_RANGE_TABLE_EXISTS_P (&p[-2]) - && match_any_multibyte_characters == false) - { - /* Set fastmap[I] 1 where I is a base leading code of each - multibyte character in the range table. */ - int c, count; - - /* Make P points the range table. */ - p += CHARSET_BITMAP_SIZE (&p[-2]); - - /* Extract the number of ranges in range table into - COUNT. */ - EXTRACT_NUMBER_AND_INCR (count, p); - for (; count > 0; count--, p += 2 * 3) /* XXX */ - { - /* Extract the start of each range. */ - EXTRACT_CHARACTER (c, p); - j = CHAR_CHARSET (c); - fastmap[CHARSET_LEADING_CODE_BASE (j)] = 1; - } - } - break; - - - case charset_not: - /* Chars beyond end of bitmap are possible matches. - All the single-byte codes can occur in multibyte buffers. - So any that are not listed in the charset - are possible matches, even in multibyte buffers. */ - simple_char_max = (1 << BYTEWIDTH); - for (j = CHARSET_BITMAP_SIZE (&p[-1]) * BYTEWIDTH; - j < simple_char_max; j++) - fastmap[j] = 1; - - for (j = CHARSET_BITMAP_SIZE (&p[-1]) * BYTEWIDTH - 1, p++; - j >= 0; j--) - if (!(p[j / BYTEWIDTH] & (1 << (j % BYTEWIDTH)))) - fastmap[j] = 1; - - if (bufp->multibyte) - /* Any character set can possibly contain a character - which doesn't match the specified set of characters. */ - { - set_fastmap_for_multibyte_characters: - if (match_any_multibyte_characters == false) - { - for (j = 0x80; j < 0xA0; j++) /* XXX */ - if (BASE_LEADING_CODE_P (j)) - fastmap[j] = 1; - match_any_multibyte_characters = true; - } - } - break; - - - case wordchar: - /* All the single-byte codes can occur in multibyte buffers, - and they may have word syntax. So do consider them. */ - simple_char_max = (1 << BYTEWIDTH); - for (j = 0; j < simple_char_max; j++) - if (SYNTAX (j) == Sword) - fastmap[j] = 1; - - if (bufp->multibyte) - /* Any character set can possibly contain a character - whose syntax is `Sword'. */ - goto set_fastmap_for_multibyte_characters; - break; - - - case notwordchar: - /* All the single-byte codes can occur in multibyte buffers, - and they may not have word syntax. So do consider them. */ - simple_char_max = (1 << BYTEWIDTH); - for (j = 0; j < simple_char_max; j++) - if (SYNTAX (j) != Sword) - fastmap[j] = 1; - - if (bufp->multibyte) - /* Any character set can possibly contain a character - whose syntax is not `Sword'. */ - goto set_fastmap_for_multibyte_characters; - break; -#endif - - case anychar: - { - int fastmap_newline = fastmap['\n']; - - /* `.' matches anything, except perhaps newline. - Even in a multibyte buffer, it should match any - conceivable byte value for the fastmap. */ - if (bufp->multibyte) - match_any_multibyte_characters = true; - - simple_char_max = (1 << BYTEWIDTH); - for (j = 0; j < simple_char_max; j++) - fastmap[j] = 1; - - /* ... except perhaps newline. */ - if (!(bufp->syntax & RE_DOT_NEWLINE)) - fastmap['\n'] = fastmap_newline; - - /* Return if we have already set `can_be_null'; if we have, - then the fastmap is irrelevant. Something's wrong here. */ - else if (bufp->can_be_null) - goto done; - - /* Otherwise, have to check alternative paths. */ - break; - } - -#ifdef emacs - case wordbound: - case notwordbound: - case wordbeg: - case wordend: - case notsyntaxspec: - case syntaxspec: - /* This match depends on text properties. These end with - aborting optimizations. */ - bufp->can_be_null = 1; - goto done; -#if 0 - k = *p++; - simple_char_max = bufp->multibyte ? 0x80 : (1 << BYTEWIDTH); - for (j = 0; j < simple_char_max; j++) - if (SYNTAX (j) == (enum syntaxcode) k) - fastmap[j] = 1; - - if (bufp->multibyte) - /* Any character set can possibly contain a character - whose syntax is K. */ - goto set_fastmap_for_multibyte_characters; - break; - - case notsyntaxspec: - k = *p++; - simple_char_max = bufp->multibyte ? 0x80 : (1 << BYTEWIDTH); - for (j = 0; j < simple_char_max; j++) - if (SYNTAX (j) != (enum syntaxcode) k) - fastmap[j] = 1; - - if (bufp->multibyte) - /* Any character set can possibly contain a character - whose syntax is not K. */ - goto set_fastmap_for_multibyte_characters; - break; -#endif - - - case categoryspec: - k = *p++; - simple_char_max = (1 << BYTEWIDTH); - for (j = 0; j < simple_char_max; j++) - if (CHAR_HAS_CATEGORY (j, k)) - fastmap[j] = 1; - - if (bufp->multibyte) - /* Any character set can possibly contain a character - whose category is K. */ - goto set_fastmap_for_multibyte_characters; - break; - - - case notcategoryspec: - k = *p++; - simple_char_max = (1 << BYTEWIDTH); - for (j = 0; j < simple_char_max; j++) - if (!CHAR_HAS_CATEGORY (j, k)) - fastmap[j] = 1; - - if (bufp->multibyte) - /* Any character set can possibly contain a character - whose category is not K. */ - goto set_fastmap_for_multibyte_characters; - break; - - /* All cases after this match the empty string. These end with - `continue'. */ - - - case before_dot: - case at_dot: - case after_dot: - continue; -#endif /* emacs */ - - - case no_op: - case begline: - case endline: - case begbuf: - case endbuf: -#ifndef emacs - case wordbound: - case notwordbound: - case wordbeg: - case wordend: -#endif - case push_dummy_failure: - continue; - - - case jump_n: - case pop_failure_jump: - case maybe_pop_jump: - case jump: - case jump_past_alt: - case dummy_failure_jump: - EXTRACT_NUMBER_AND_INCR (j, p); - p += j; - if (j > 0) - continue; - - /* Jump backward implies we just went through the body of a - loop and matched nothing. Opcode jumped to should be - `on_failure_jump' or `succeed_n'. Just treat it like an - ordinary jump. For a * loop, it has pushed its failure - point already; if so, discard that as redundant. */ - if ((re_opcode_t) *p != on_failure_jump - && (re_opcode_t) *p != succeed_n) - continue; - - p++; - EXTRACT_NUMBER_AND_INCR (j, p); - p += j; - - /* If what's on the stack is where we are now, pop it. */ - if (!FAIL_STACK_EMPTY () - && fail_stack.stack[fail_stack.avail - 1].pointer == p) - fail_stack.avail--; - - continue; - - - case on_failure_jump: - case on_failure_keep_string_jump: - handle_on_failure_jump: - EXTRACT_NUMBER_AND_INCR (j, p); - - /* For some patterns, e.g., `(a?)?', `p+j' here points to the - end of the pattern. We don't want to push such a point, - since when we restore it above, entering the switch will - increment `p' past the end of the pattern. We don't need - to push such a point since we obviously won't find any more - fastmap entries beyond `pend'. Such a pattern can match - the null string, though. */ - if (p + j < pend) - { - if (!PUSH_PATTERN_OP (p + j, fail_stack)) - { - RESET_FAIL_STACK (); - return -2; - } - } - else - bufp->can_be_null = 1; - - if (succeed_n_p) - { - EXTRACT_NUMBER_AND_INCR (k, p); /* Skip the n. */ - succeed_n_p = false; - } - - continue; - - - case succeed_n: - /* Get to the number of times to succeed. */ - p += 2; - - /* Increment p past the n for when k != 0. */ - EXTRACT_NUMBER_AND_INCR (k, p); - if (k == 0) - { - p -= 4; - succeed_n_p = true; /* Spaghetti code alert. */ - goto handle_on_failure_jump; - } - continue; - - - case set_number_at: - p += 4; - continue; - - - case start_memory: - case stop_memory: - p += 2; - continue; - - - default: - abort (); /* We have listed all the cases. */ - } /* switch *p++ */ - - /* Getting here means we have found the possible starting - characters for one path of the pattern -- and that the empty - string does not match. We need not follow this path further. - Instead, look at the next alternative (remembered on the - stack), or quit if no more. The test at the top of the loop - does these things. */ - path_can_be_null = false; - p = pend; - } /* while p */ - - /* Set `can_be_null' for the last path (also the first path, if the - pattern is empty). */ - bufp->can_be_null |= path_can_be_null; - - done: - RESET_FAIL_STACK (); - return 0; -} /* re_compile_fastmap */ - -/* Set REGS to hold NUM_REGS registers, storing them in STARTS and - ENDS. Subsequent matches using PATTERN_BUFFER and REGS will use - this memory for recording register information. STARTS and ENDS - must be allocated using the malloc library routine, and must each - be at least NUM_REGS * sizeof (regoff_t) bytes long. - - If NUM_REGS == 0, then subsequent matches should allocate their own - register data. - - Unless this function is called, the first search or match using - PATTERN_BUFFER will allocate its own register data, without - freeing the old data. */ - -void -re_set_registers (bufp, regs, num_regs, starts, ends) - struct re_pattern_buffer *bufp; - struct re_registers *regs; - unsigned num_regs; - regoff_t *starts, *ends; -{ - if (num_regs) - { - bufp->regs_allocated = REGS_REALLOCATE; - regs->num_regs = num_regs; - regs->start = starts; - regs->end = ends; - } - else - { - bufp->regs_allocated = REGS_UNALLOCATED; - regs->num_regs = 0; - regs->start = regs->end = (regoff_t *) 0; - } -} - -/* Searching routines. */ - -/* Like re_search_2, below, but only one string is specified, and - doesn't let you say where to stop matching. */ - -int -re_search (bufp, string, size, startpos, range, regs) - struct re_pattern_buffer *bufp; - const char *string; - int size, startpos, range; - struct re_registers *regs; -{ - return re_search_2 (bufp, NULL, 0, string, size, startpos, range, - regs, size); -} - -/* End address of virtual concatenation of string. */ -#define STOP_ADDR_VSTRING(P) \ - (((P) >= size1 ? string2 + size2 : string1 + size1)) - -/* Address of POS in the concatenation of virtual string. */ -#define POS_ADDR_VSTRING(POS) \ - (((POS) >= size1 ? string2 - size1 : string1) + (POS)) - -/* Using the compiled pattern in BUFP->buffer, first tries to match the - virtual concatenation of STRING1 and STRING2, starting first at index - STARTPOS, then at STARTPOS + 1, and so on. - - STRING1 and STRING2 have length SIZE1 and SIZE2, respectively. - - RANGE is how far to scan while trying to match. RANGE = 0 means try - only at STARTPOS; in general, the last start tried is STARTPOS + - RANGE. - - In REGS, return the indices of the virtual concatenation of STRING1 - and STRING2 that matched the entire BUFP->buffer and its contained - subexpressions. - - Do not consider matching one past the index STOP in the virtual - concatenation of STRING1 and STRING2. - - We return either the position in the strings at which the match was - found, -1 if no match, or -2 if error (such as failure - stack overflow). */ - -int -re_search_2 (bufp, string1, size1, string2, size2, startpos, range, regs, stop) - struct re_pattern_buffer *bufp; - const char *string1, *string2; - int size1, size2; - int startpos; - int range; - struct re_registers *regs; - int stop; -{ - int val; - register char *fastmap = bufp->fastmap; - register RE_TRANSLATE_TYPE translate = bufp->translate; - int total_size = size1 + size2; - int endpos = startpos + range; - int anchored_start = 0; - - /* Nonzero if we have to concern multibyte character. */ - int multibyte = bufp->multibyte; - - /* Check for out-of-range STARTPOS. */ - if (startpos < 0 || startpos > total_size) - return -1; - - /* Fix up RANGE if it might eventually take us outside - the virtual concatenation of STRING1 and STRING2. - Make sure we won't move STARTPOS below 0 or above TOTAL_SIZE. */ - if (endpos < 0) - range = 0 - startpos; - else if (endpos > total_size) - range = total_size - startpos; - - /* If the search isn't to be a backwards one, don't waste time in a - search for a pattern anchored at beginning of buffer. */ - if (bufp->used > 0 && (re_opcode_t) bufp->buffer[0] == begbuf && range > 0) - { - if (startpos > 0) - return -1; - else - range = 0; - } - -#ifdef emacs - /* In a forward search for something that starts with \=. - don't keep searching past point. */ - if (bufp->used > 0 && (re_opcode_t) bufp->buffer[0] == at_dot && range > 0) - { - range = PT_BYTE - BEGV_BYTE - startpos; - if (range < 0) - return -1; - } -#endif /* emacs */ - - /* Update the fastmap now if not correct already. */ - if (fastmap && !bufp->fastmap_accurate) - if (re_compile_fastmap (bufp) == -2) - return -2; - - /* See whether the pattern is anchored. */ - if (bufp->buffer[0] == begline) - anchored_start = 1; - -#ifdef emacs - gl_state.object = re_match_object; - { - int adjpos = NILP (re_match_object) || BUFFERP (re_match_object); - int charpos = SYNTAX_TABLE_BYTE_TO_CHAR (startpos + adjpos); - - SETUP_SYNTAX_TABLE_FOR_OBJECT (re_match_object, charpos, 1); - } -#endif - - /* Loop through the string, looking for a place to start matching. */ - for (;;) - { - /* If the pattern is anchored, - skip quickly past places we cannot match. - We don't bother to treat startpos == 0 specially - because that case doesn't repeat. */ - if (anchored_start && startpos > 0) - { - if (! (bufp->newline_anchor - && ((startpos <= size1 ? string1[startpos - 1] - : string2[startpos - size1 - 1]) - == '\n'))) - goto advance; - } - - /* If a fastmap is supplied, skip quickly over characters that - cannot be the start of a match. If the pattern can match the - null string, however, we don't need to skip characters; we want - the first null string. */ - if (fastmap && startpos < total_size && !bufp->can_be_null) - { - register const char *d; - register unsigned int buf_ch; - - d = POS_ADDR_VSTRING (startpos); - - if (range > 0) /* Searching forwards. */ - { - register int lim = 0; - int irange = range; - - if (startpos < size1 && startpos + range >= size1) - lim = range - (size1 - startpos); - - /* Written out as an if-else to avoid testing `translate' - inside the loop. */ - if (RE_TRANSLATE_P (translate)) - { - if (multibyte) - while (range > lim) - { - int buf_charlen; - - buf_ch = STRING_CHAR_AND_LENGTH (d, range - lim, - buf_charlen); - - buf_ch = RE_TRANSLATE (translate, buf_ch); - if (buf_ch >= 0400 - || fastmap[buf_ch]) - break; - - range -= buf_charlen; - d += buf_charlen; - } - else - while (range > lim - && !fastmap[(unsigned char) - RE_TRANSLATE (translate, (unsigned char) *d)]) - { - d++; - range--; - } - } - else - while (range > lim && !fastmap[(unsigned char) *d]) - { - d++; - range--; - } - - startpos += irange - range; - } - else /* Searching backwards. */ - { - int room = (size1 == 0 || startpos >= size1 - ? size2 + size1 - startpos - : size1 - startpos); - - buf_ch = STRING_CHAR (d, room); - if (RE_TRANSLATE_P (translate)) - buf_ch = RE_TRANSLATE (translate, buf_ch); - - if (! (buf_ch >= 0400 - || fastmap[buf_ch])) - goto advance; - } - } - - /* If can't match the null string, and that's all we have left, fail. */ - if (range >= 0 && startpos == total_size && fastmap - && !bufp->can_be_null) - return -1; - - val = re_match_2_internal (bufp, string1, size1, string2, size2, - startpos, regs, stop); -#ifndef REGEX_MALLOC -#ifdef C_ALLOCA - alloca (0); -#endif -#endif - - if (val >= 0) - return startpos; - - if (val == -2) - return -2; - - advance: - if (!range) - break; - else if (range > 0) - { - /* Update STARTPOS to the next character boundary. */ - if (multibyte) - { - const unsigned char *p - = (const unsigned char *) POS_ADDR_VSTRING (startpos); - const unsigned char *pend - = (const unsigned char *) STOP_ADDR_VSTRING (startpos); - int len = MULTIBYTE_FORM_LENGTH (p, pend - p); - - range -= len; - if (range < 0) - break; - startpos += len; - } - else - { - range--; - startpos++; - } - } - else - { - range++; - startpos--; - - /* Update STARTPOS to the previous character boundary. */ - if (multibyte) - { - const unsigned char *p - = (const unsigned char *) POS_ADDR_VSTRING (startpos); - int len = 0; - - /* Find the head of multibyte form. */ - while (!CHAR_HEAD_P (*p)) - p--, len++; - - /* Adjust it. */ -#if 0 /* XXX */ - if (MULTIBYTE_FORM_LENGTH (p, len + 1) != (len + 1)) - ; - else -#endif - { - range += len; - if (range > 0) - break; - - startpos -= len; - } - } - } - } - return -1; -} /* re_search_2 */ - -/* Declarations and macros for re_match_2. */ - -static int bcmp_translate (); -static boolean alt_match_null_string_p (), - common_op_match_null_string_p (), - group_match_null_string_p (); - -/* This converts PTR, a pointer into one of the search strings `string1' - and `string2' into an offset from the beginning of that string. */ -#define POINTER_TO_OFFSET(ptr) \ - (FIRST_STRING_P (ptr) \ - ? ((regoff_t) ((ptr) - string1)) \ - : ((regoff_t) ((ptr) - string2 + size1))) - -/* Macros for dealing with the split strings in re_match_2. */ - -#define MATCHING_IN_FIRST_STRING (dend == end_match_1) - -/* Call before fetching a character with *d. This switches over to - string2 if necessary. */ -#define PREFETCH() \ - while (d == dend) \ - { \ - /* End of string2 => fail. */ \ - if (dend == end_match_2) \ - goto fail; \ - /* End of string1 => advance to string2. */ \ - d = string2; \ - dend = end_match_2; \ - } - - -/* Test if at very beginning or at very end of the virtual concatenation - of `string1' and `string2'. If only one string, it's `string2'. */ -#define AT_STRINGS_BEG(d) ((d) == (size1 ? string1 : string2) || !size2) -#define AT_STRINGS_END(d) ((d) == end2) - - -/* Test if D points to a character which is word-constituent. We have - two special cases to check for: if past the end of string1, look at - the first character in string2; and if before the beginning of - string2, look at the last character in string1. */ -#define WORDCHAR_P(d) \ - (SYNTAX ((d) == end1 ? *string2 \ - : (d) == string2 - 1 ? *(end1 - 1) : *(d)) \ - == Sword) - -/* Disabled due to a compiler bug -- see comment at case wordbound */ - -/* The comment at case wordbound is following one, but we don't use - AT_WORD_BOUNDARY anymore to support multibyte form. - - The DEC Alpha C compiler 3.x generates incorrect code for the - test WORDCHAR_P (d - 1) != WORDCHAR_P (d) in the expansion of - AT_WORD_BOUNDARY, so this code is disabled. Expanding the - macro and introducing temporary variables works around the bug. */ - -#if 0 -/* Test if the character before D and the one at D differ with respect - to being word-constituent. */ -#define AT_WORD_BOUNDARY(d) \ - (AT_STRINGS_BEG (d) || AT_STRINGS_END (d) \ - || WORDCHAR_P (d - 1) != WORDCHAR_P (d)) -#endif - -/* Free everything we malloc. */ -#ifdef MATCH_MAY_ALLOCATE -#define FREE_VAR(var) if (var) { REGEX_FREE (var); var = NULL; } else -#define FREE_VARIABLES() \ - do { \ - REGEX_FREE_STACK (fail_stack.stack); \ - FREE_VAR (regstart); \ - FREE_VAR (regend); \ - FREE_VAR (old_regstart); \ - FREE_VAR (old_regend); \ - FREE_VAR (best_regstart); \ - FREE_VAR (best_regend); \ - FREE_VAR (reg_info); \ - FREE_VAR (reg_dummy); \ - FREE_VAR (reg_info_dummy); \ - } while (0) -#else -#define FREE_VARIABLES() ((void)0) /* Do nothing! But inhibit gcc warning. */ -#endif /* not MATCH_MAY_ALLOCATE */ - -/* These values must meet several constraints. They must not be valid - register values; since we have a limit of 255 registers (because - we use only one byte in the pattern for the register number), we can - use numbers larger than 255. They must differ by 1, because of - NUM_FAILURE_ITEMS above. And the value for the lowest register must - be larger than the value for the highest register, so we do not try - to actually save any registers when none are active. */ -#define NO_HIGHEST_ACTIVE_REG (1 << BYTEWIDTH) -#define NO_LOWEST_ACTIVE_REG (NO_HIGHEST_ACTIVE_REG + 1) - -/* Matching routines. */ - -#ifndef emacs /* Emacs never uses this. */ -/* re_match is like re_match_2 except it takes only a single string. */ - -int -re_match (bufp, string, size, pos, regs) - struct re_pattern_buffer *bufp; - const char *string; - int size, pos; - struct re_registers *regs; -{ - int result = re_match_2_internal (bufp, NULL, 0, string, size, - pos, regs, size); -#ifndef REGEX_MALLOC /* CVS */ -#ifdef C_ALLOCA /* CVS */ - alloca (0); -#endif /* CVS */ -#endif /* CVS */ - return result; -} -#endif /* not emacs */ - -#ifdef emacs -/* In Emacs, this is the string or buffer in which we - are matching. It is used for looking up syntax properties. */ -Lisp_Object re_match_object; -#endif - -/* re_match_2 matches the compiled pattern in BUFP against the - the (virtual) concatenation of STRING1 and STRING2 (of length SIZE1 - and SIZE2, respectively). We start matching at POS, and stop - matching at STOP. - - If REGS is non-null and the `no_sub' field of BUFP is nonzero, we - store offsets for the substring each group matched in REGS. See the - documentation for exactly how many groups we fill. - - We return -1 if no match, -2 if an internal error (such as the - failure stack overflowing). Otherwise, we return the length of the - matched substring. */ - -int -re_match_2 (bufp, string1, size1, string2, size2, pos, regs, stop) - struct re_pattern_buffer *bufp; - const char *string1, *string2; - int size1, size2; - int pos; - struct re_registers *regs; - int stop; -{ - int result; - -#ifdef emacs - int charpos; - int adjpos = NILP (re_match_object) || BUFFERP (re_match_object); - gl_state.object = re_match_object; - charpos = SYNTAX_TABLE_BYTE_TO_CHAR (pos + adjpos); - SETUP_SYNTAX_TABLE_FOR_OBJECT (re_match_object, charpos, 1); -#endif - - result = re_match_2_internal (bufp, string1, size1, string2, size2, - pos, regs, stop); -#ifndef REGEX_MALLOC /* CVS */ -#ifdef C_ALLOCA /* CVS */ - alloca (0); -#endif /* CVS */ -#endif /* CVS */ - return result; -} - -/* This is a separate function so that we can force an alloca cleanup - afterwards. */ -static int -re_match_2_internal (bufp, string1, size1, string2, size2, pos, regs, stop) - struct re_pattern_buffer *bufp; - const char *string1, *string2; - int size1, size2; - int pos; - struct re_registers *regs; - int stop; -{ - /* General temporaries. */ - int mcnt; - unsigned char *p1; - - /* Just past the end of the corresponding string. */ - const char *end1, *end2; - - /* Pointers into string1 and string2, just past the last characters in - each to consider matching. */ - const char *end_match_1, *end_match_2; - - /* Where we are in the data, and the end of the current string. */ - const char *d, *dend; - - /* Where we are in the pattern, and the end of the pattern. */ - unsigned char *p = bufp->buffer; - register unsigned char *pend = p + bufp->used; - - /* Mark the opcode just after a start_memory, so we can test for an - empty subpattern when we get to the stop_memory. */ - unsigned char *just_past_start_mem = 0; - - /* We use this to map every character in the string. */ - RE_TRANSLATE_TYPE translate = bufp->translate; - - /* Nonzero if we have to concern multibyte character. */ - int multibyte = bufp->multibyte; - - /* Failure point stack. Each place that can handle a failure further - down the line pushes a failure point on this stack. It consists of - restart, regend, and reg_info for all registers corresponding to - the subexpressions we're currently inside, plus the number of such - registers, and, finally, two char *'s. The first char * is where - to resume scanning the pattern; the second one is where to resume - scanning the strings. If the latter is zero, the failure point is - a ``dummy''; if a failure happens and the failure point is a dummy, - it gets discarded and the next next one is tried. */ -#ifdef MATCH_MAY_ALLOCATE /* otherwise, this is global. */ - fail_stack_type fail_stack; -#endif -#ifdef DEBUG - static unsigned failure_id = 0; - unsigned nfailure_points_pushed = 0, nfailure_points_popped = 0; -#endif - - /* This holds the pointer to the failure stack, when - it is allocated relocatably. */ - fail_stack_elt_t *failure_stack_ptr; - - /* We fill all the registers internally, independent of what we - return, for use in backreferences. The number here includes - an element for register zero. */ - unsigned num_regs = bufp->re_nsub + 1; - - /* The currently active registers. */ - unsigned lowest_active_reg = NO_LOWEST_ACTIVE_REG; - unsigned highest_active_reg = NO_HIGHEST_ACTIVE_REG; - - /* Information on the contents of registers. These are pointers into - the input strings; they record just what was matched (on this - attempt) by a subexpression part of the pattern, that is, the - regnum-th regstart pointer points to where in the pattern we began - matching and the regnum-th regend points to right after where we - stopped matching the regnum-th subexpression. (The zeroth register - keeps track of what the whole pattern matches.) */ -#ifdef MATCH_MAY_ALLOCATE /* otherwise, these are global. */ - const char **regstart, **regend; -#endif - - /* If a group that's operated upon by a repetition operator fails to - match anything, then the register for its start will need to be - restored because it will have been set to wherever in the string we - are when we last see its open-group operator. Similarly for a - register's end. */ -#ifdef MATCH_MAY_ALLOCATE /* otherwise, these are global. */ - const char **old_regstart, **old_regend; -#endif - - /* The is_active field of reg_info helps us keep track of which (possibly - nested) subexpressions we are currently in. The matched_something - field of reg_info[reg_num] helps us tell whether or not we have - matched any of the pattern so far this time through the reg_num-th - subexpression. These two fields get reset each time through any - loop their register is in. */ -#ifdef MATCH_MAY_ALLOCATE /* otherwise, this is global. */ - register_info_type *reg_info; -#endif - - /* The following record the register info as found in the above - variables when we find a match better than any we've seen before. - This happens as we backtrack through the failure points, which in - turn happens only if we have not yet matched the entire string. */ - unsigned best_regs_set = false; -#ifdef MATCH_MAY_ALLOCATE /* otherwise, these are global. */ - const char **best_regstart, **best_regend; -#endif - - /* Logically, this is `best_regend[0]'. But we don't want to have to - allocate space for that if we're not allocating space for anything - else (see below). Also, we never need info about register 0 for - any of the other register vectors, and it seems rather a kludge to - treat `best_regend' differently than the rest. So we keep track of - the end of the best match so far in a separate variable. We - initialize this to NULL so that when we backtrack the first time - and need to test it, it's not garbage. */ - const char *match_end = NULL; - - /* This helps SET_REGS_MATCHED avoid doing redundant work. */ - int set_regs_matched_done = 0; - - /* Used when we pop values we don't care about. */ -#ifdef MATCH_MAY_ALLOCATE /* otherwise, these are global. */ - const char **reg_dummy; - register_info_type *reg_info_dummy; -#endif - -#ifdef DEBUG - /* Counts the total number of registers pushed. */ - unsigned num_regs_pushed = 0; -#endif - - DEBUG_PRINT1 ("\n\nEntering re_match_2.\n"); - - INIT_FAIL_STACK (); - -#ifdef MATCH_MAY_ALLOCATE - /* Do not bother to initialize all the register variables if there are - no groups in the pattern, as it takes a fair amount of time. If - there are groups, we include space for register 0 (the whole - pattern), even though we never use it, since it simplifies the - array indexing. We should fix this. */ - if (bufp->re_nsub) - { - regstart = REGEX_TALLOC (num_regs, const char *); - regend = REGEX_TALLOC (num_regs, const char *); - old_regstart = REGEX_TALLOC (num_regs, const char *); - old_regend = REGEX_TALLOC (num_regs, const char *); - best_regstart = REGEX_TALLOC (num_regs, const char *); - best_regend = REGEX_TALLOC (num_regs, const char *); - reg_info = REGEX_TALLOC (num_regs, register_info_type); - reg_dummy = REGEX_TALLOC (num_regs, const char *); - reg_info_dummy = REGEX_TALLOC (num_regs, register_info_type); - - if (!(regstart && regend && old_regstart && old_regend && reg_info - && best_regstart && best_regend && reg_dummy && reg_info_dummy)) - { - FREE_VARIABLES (); - return -2; - } - } - else - { - /* We must initialize all our variables to NULL, so that - `FREE_VARIABLES' doesn't try to free them. */ - regstart = regend = old_regstart = old_regend = best_regstart - = best_regend = reg_dummy = NULL; - reg_info = reg_info_dummy = (register_info_type *) NULL; - } -#endif /* MATCH_MAY_ALLOCATE */ - - /* The starting position is bogus. */ - if (pos < 0 || pos > size1 + size2) - { - FREE_VARIABLES (); - return -1; - } - - /* Initialize subexpression text positions to -1 to mark ones that no - start_memory/stop_memory has been seen for. Also initialize the - register information struct. */ - for (mcnt = 1; mcnt < num_regs; mcnt++) - { - regstart[mcnt] = regend[mcnt] - = old_regstart[mcnt] = old_regend[mcnt] = REG_UNSET_VALUE; - - REG_MATCH_NULL_STRING_P (reg_info[mcnt]) = MATCH_NULL_UNSET_VALUE; - IS_ACTIVE (reg_info[mcnt]) = 0; - MATCHED_SOMETHING (reg_info[mcnt]) = 0; - EVER_MATCHED_SOMETHING (reg_info[mcnt]) = 0; - } - - /* We move `string1' into `string2' if the latter's empty -- but not if - `string1' is null. */ - if (size2 == 0 && string1 != NULL) - { - string2 = string1; - size2 = size1; - string1 = 0; - size1 = 0; - } - end1 = string1 + size1; - end2 = string2 + size2; - - /* Compute where to stop matching, within the two strings. */ - if (stop <= size1) - { - end_match_1 = string1 + stop; - end_match_2 = string2; - } - else - { - end_match_1 = end1; - end_match_2 = string2 + stop - size1; - } - - /* `p' scans through the pattern as `d' scans through the data. - `dend' is the end of the input string that `d' points within. `d' - is advanced into the following input string whenever necessary, but - this happens before fetching; therefore, at the beginning of the - loop, `d' can be pointing at the end of a string, but it cannot - equal `string2'. */ - if (size1 > 0 && pos <= size1) - { - d = string1 + pos; - dend = end_match_1; - } - else - { - d = string2 + pos - size1; - dend = end_match_2; - } - - DEBUG_PRINT1 ("The compiled pattern is: "); - DEBUG_PRINT_COMPILED_PATTERN (bufp, p, pend); - DEBUG_PRINT1 ("The string to match is: `"); - DEBUG_PRINT_DOUBLE_STRING (d, string1, size1, string2, size2); - DEBUG_PRINT1 ("'\n"); - - /* This loops over pattern commands. It exits by returning from the - function if the match is complete, or it drops through if the match - fails at this starting point in the input data. */ - for (;;) - { - DEBUG_PRINT2 ("\n0x%x: ", p); - - if (p == pend) - { /* End of pattern means we might have succeeded. */ - DEBUG_PRINT1 ("end of pattern ... "); - - /* If we haven't matched the entire string, and we want the - longest match, try backtracking. */ - if (d != end_match_2) - { - /* 1 if this match ends in the same string (string1 or string2) - as the best previous match. */ - boolean same_str_p = (FIRST_STRING_P (match_end) - == MATCHING_IN_FIRST_STRING); - /* 1 if this match is the best seen so far. */ - boolean best_match_p; - - /* AIX compiler got confused when this was combined - with the previous declaration. */ - if (same_str_p) - best_match_p = d > match_end; - else - best_match_p = !MATCHING_IN_FIRST_STRING; - - DEBUG_PRINT1 ("backtracking.\n"); - - if (!FAIL_STACK_EMPTY ()) - { /* More failure points to try. */ - - /* If exceeds best match so far, save it. */ - if (!best_regs_set || best_match_p) - { - best_regs_set = true; - match_end = d; - - DEBUG_PRINT1 ("\nSAVING match as best so far.\n"); - - for (mcnt = 1; mcnt < num_regs; mcnt++) - { - best_regstart[mcnt] = regstart[mcnt]; - best_regend[mcnt] = regend[mcnt]; - } - } - goto fail; - } - - /* If no failure points, don't restore garbage. And if - last match is real best match, don't restore second - best one. */ - else if (best_regs_set && !best_match_p) - { - restore_best_regs: - /* Restore best match. It may happen that `dend == - end_match_1' while the restored d is in string2. - For example, the pattern `x.*y.*z' against the - strings `x-' and `y-z-', if the two strings are - not consecutive in memory. */ - DEBUG_PRINT1 ("Restoring best registers.\n"); - - d = match_end; - dend = ((d >= string1 && d <= end1) - ? end_match_1 : end_match_2); - - for (mcnt = 1; mcnt < num_regs; mcnt++) - { - regstart[mcnt] = best_regstart[mcnt]; - regend[mcnt] = best_regend[mcnt]; - } - } - } /* d != end_match_2 */ - - succeed_label: - DEBUG_PRINT1 ("Accepting match.\n"); - - /* If caller wants register contents data back, do it. */ - if (regs && !bufp->no_sub) - { - /* Have the register data arrays been allocated? */ - if (bufp->regs_allocated == REGS_UNALLOCATED) - { /* No. So allocate them with malloc. We need one - extra element beyond `num_regs' for the `-1' marker - GNU code uses. */ - regs->num_regs = MAX (RE_NREGS, num_regs + 1); - regs->start = TALLOC (regs->num_regs, regoff_t); - regs->end = TALLOC (regs->num_regs, regoff_t); - if (regs->start == NULL || regs->end == NULL) - { - FREE_VARIABLES (); - return -2; - } - bufp->regs_allocated = REGS_REALLOCATE; - } - else if (bufp->regs_allocated == REGS_REALLOCATE) - { /* Yes. If we need more elements than were already - allocated, reallocate them. If we need fewer, just - leave it alone. */ - if (regs->num_regs < num_regs + 1) - { - regs->num_regs = num_regs + 1; - RETALLOC (regs->start, regs->num_regs, regoff_t); - RETALLOC (regs->end, regs->num_regs, regoff_t); - if (regs->start == NULL || regs->end == NULL) - { - FREE_VARIABLES (); - return -2; - } - } - } - else - { - /* These braces fend off a "empty body in an else-statement" - warning under GCC when assert expands to nothing. */ - assert (bufp->regs_allocated == REGS_FIXED); - } - - /* Convert the pointer data in `regstart' and `regend' to - indices. Register zero has to be set differently, - since we haven't kept track of any info for it. */ - if (regs->num_regs > 0) - { - regs->start[0] = pos; - regs->end[0] = (MATCHING_IN_FIRST_STRING - ? ((regoff_t) (d - string1)) - : ((regoff_t) (d - string2 + size1))); - } - - /* Go through the first `min (num_regs, regs->num_regs)' - registers, since that is all we initialized. */ - for (mcnt = 1; mcnt < MIN (num_regs, regs->num_regs); mcnt++) - { - if (REG_UNSET (regstart[mcnt]) || REG_UNSET (regend[mcnt])) - regs->start[mcnt] = regs->end[mcnt] = -1; - else - { - regs->start[mcnt] - = (regoff_t) POINTER_TO_OFFSET (regstart[mcnt]); - regs->end[mcnt] - = (regoff_t) POINTER_TO_OFFSET (regend[mcnt]); - } - } - - /* If the regs structure we return has more elements than - were in the pattern, set the extra elements to -1. If - we (re)allocated the registers, this is the case, - because we always allocate enough to have at least one - -1 at the end. */ - for (mcnt = num_regs; mcnt < regs->num_regs; mcnt++) - regs->start[mcnt] = regs->end[mcnt] = -1; - } /* regs && !bufp->no_sub */ - - DEBUG_PRINT4 ("%u failure points pushed, %u popped (%u remain).\n", - nfailure_points_pushed, nfailure_points_popped, - nfailure_points_pushed - nfailure_points_popped); - DEBUG_PRINT2 ("%u registers pushed.\n", num_regs_pushed); - - mcnt = d - pos - (MATCHING_IN_FIRST_STRING - ? string1 - : string2 - size1); - - DEBUG_PRINT2 ("Returning %d from re_match_2.\n", mcnt); - - FREE_VARIABLES (); - return mcnt; - } - - /* Otherwise match next pattern command. */ - switch (SWITCH_ENUM_CAST ((re_opcode_t) *p++)) - { - /* Ignore these. Used to ignore the n of succeed_n's which - currently have n == 0. */ - case no_op: - DEBUG_PRINT1 ("EXECUTING no_op.\n"); - break; - - case succeed: - DEBUG_PRINT1 ("EXECUTING succeed.\n"); - goto succeed_label; - - /* Match the next n pattern characters exactly. The following - byte in the pattern defines n, and the n bytes after that - are the characters to match. */ - case exactn: - mcnt = *p++; - DEBUG_PRINT2 ("EXECUTING exactn %d.\n", mcnt); - - /* This is written out as an if-else so we don't waste time - testing `translate' inside the loop. */ - if (RE_TRANSLATE_P (translate)) - { -#ifdef emacs - if (multibyte) - do - { - int pat_charlen, buf_charlen; - unsigned int pat_ch, buf_ch; - - PREFETCH (); - pat_ch = STRING_CHAR_AND_LENGTH (p, pend - p, pat_charlen); - buf_ch = STRING_CHAR_AND_LENGTH (d, dend - d, buf_charlen); - - if (RE_TRANSLATE (translate, buf_ch) - != pat_ch) - goto fail; - - p += pat_charlen; - d += buf_charlen; - mcnt -= pat_charlen; - } - while (mcnt > 0); - else -#endif /* not emacs */ - do - { - PREFETCH (); - if ((unsigned char) RE_TRANSLATE (translate, (unsigned char) *d) - != (unsigned char) *p++) - goto fail; - d++; - } - while (--mcnt); - } - else - { - do - { - PREFETCH (); - if (*d++ != (char) *p++) goto fail; - } - while (--mcnt); - } - SET_REGS_MATCHED (); - break; - - - /* Match any character except possibly a newline or a null. */ - case anychar: - { - int buf_charlen; - unsigned int buf_ch; - - DEBUG_PRINT1 ("EXECUTING anychar.\n"); - - PREFETCH (); - -#ifdef emacs - if (multibyte) - buf_ch = STRING_CHAR_AND_LENGTH (d, dend - d, buf_charlen); - else -#endif /* not emacs */ - { - buf_ch = (unsigned char) *d; - buf_charlen = 1; - } - - buf_ch = TRANSLATE (buf_ch); - - if ((!(bufp->syntax & RE_DOT_NEWLINE) - && buf_ch == '\n') - || ((bufp->syntax & RE_DOT_NOT_NULL) - && buf_ch == '\000')) - goto fail; - - SET_REGS_MATCHED (); - DEBUG_PRINT2 (" Matched `%d'.\n", *d); - d += buf_charlen; - } - break; - - - case charset: - case charset_not: - { - register unsigned int c; - boolean not = (re_opcode_t) *(p - 1) == charset_not; - int len; - - /* Start of actual range_table, or end of bitmap if there is no - range table. */ - unsigned char *range_table; - - /* Nonzero if there is range table. */ - int range_table_exists; - - /* Number of ranges of range table. Not in bytes. */ - int count; - - DEBUG_PRINT2 ("EXECUTING charset%s.\n", not ? "_not" : ""); - - PREFETCH (); - c = (unsigned char) *d; - - range_table = CHARSET_RANGE_TABLE (&p[-1]); /* Past the bitmap. */ - range_table_exists = CHARSET_RANGE_TABLE_EXISTS_P (&p[-1]); - if (range_table_exists) - EXTRACT_NUMBER_AND_INCR (count, range_table); - else - count = 0; - - if (multibyte && BASE_LEADING_CODE_P (c)) - c = STRING_CHAR_AND_LENGTH (d, dend - d, len); - - if (SINGLE_BYTE_CHAR_P (c)) - { /* Lookup bitmap. */ - c = TRANSLATE (c); /* The character to match. */ - len = 1; - - /* Cast to `unsigned' instead of `unsigned char' in - case the bit list is a full 32 bytes long. */ - if (c < (unsigned) (CHARSET_BITMAP_SIZE (&p[-1]) * BYTEWIDTH) - && p[1 + c / BYTEWIDTH] & (1 << (c % BYTEWIDTH))) - not = !not; - } - else if (range_table_exists) - CHARSET_LOOKUP_RANGE_TABLE_RAW (not, c, range_table, count); - - p = CHARSET_RANGE_TABLE_END (range_table, count); - - if (!not) goto fail; - - SET_REGS_MATCHED (); - d += len; - break; - } - - - /* The beginning of a group is represented by start_memory. - The arguments are the register number in the next byte, and the - number of groups inner to this one in the next. The text - matched within the group is recorded (in the internal - registers data structure) under the register number. */ - case start_memory: - DEBUG_PRINT3 ("EXECUTING start_memory %d (%d):\n", *p, p[1]); - - /* Find out if this group can match the empty string. */ - p1 = p; /* To send to group_match_null_string_p. */ - - if (REG_MATCH_NULL_STRING_P (reg_info[*p]) == MATCH_NULL_UNSET_VALUE) - REG_MATCH_NULL_STRING_P (reg_info[*p]) - = group_match_null_string_p (&p1, pend, reg_info); - - /* Save the position in the string where we were the last time - we were at this open-group operator in case the group is - operated upon by a repetition operator, e.g., with `(a*)*b' - against `ab'; then we want to ignore where we are now in - the string in case this attempt to match fails. */ - old_regstart[*p] = REG_MATCH_NULL_STRING_P (reg_info[*p]) - ? REG_UNSET (regstart[*p]) ? d : regstart[*p] - : regstart[*p]; - DEBUG_PRINT2 (" old_regstart: %d\n", - POINTER_TO_OFFSET (old_regstart[*p])); - - regstart[*p] = d; - DEBUG_PRINT2 (" regstart: %d\n", POINTER_TO_OFFSET (regstart[*p])); - - IS_ACTIVE (reg_info[*p]) = 1; - MATCHED_SOMETHING (reg_info[*p]) = 0; - - /* Clear this whenever we change the register activity status. */ - set_regs_matched_done = 0; - - /* This is the new highest active register. */ - highest_active_reg = *p; - - /* If nothing was active before, this is the new lowest active - register. */ - if (lowest_active_reg == NO_LOWEST_ACTIVE_REG) - lowest_active_reg = *p; - - /* Move past the register number and inner group count. */ - p += 2; - just_past_start_mem = p; - - break; - - - /* The stop_memory opcode represents the end of a group. Its - arguments are the same as start_memory's: the register - number, and the number of inner groups. */ - case stop_memory: - DEBUG_PRINT3 ("EXECUTING stop_memory %d (%d):\n", *p, p[1]); - - /* We need to save the string position the last time we were at - this close-group operator in case the group is operated - upon by a repetition operator, e.g., with `((a*)*(b*)*)*' - against `aba'; then we want to ignore where we are now in - the string in case this attempt to match fails. */ - old_regend[*p] = REG_MATCH_NULL_STRING_P (reg_info[*p]) - ? REG_UNSET (regend[*p]) ? d : regend[*p] - : regend[*p]; - DEBUG_PRINT2 (" old_regend: %d\n", - POINTER_TO_OFFSET (old_regend[*p])); - - regend[*p] = d; - DEBUG_PRINT2 (" regend: %d\n", POINTER_TO_OFFSET (regend[*p])); - - /* This register isn't active anymore. */ - IS_ACTIVE (reg_info[*p]) = 0; - - /* Clear this whenever we change the register activity status. */ - set_regs_matched_done = 0; - - /* If this was the only register active, nothing is active - anymore. */ - if (lowest_active_reg == highest_active_reg) - { - lowest_active_reg = NO_LOWEST_ACTIVE_REG; - highest_active_reg = NO_HIGHEST_ACTIVE_REG; - } - else - { /* We must scan for the new highest active register, since - it isn't necessarily one less than now: consider - (a(b)c(d(e)f)g). When group 3 ends, after the f), the - new highest active register is 1. */ - unsigned char r = *p - 1; - while (r > 0 && !IS_ACTIVE (reg_info[r])) - r--; - - /* If we end up at register zero, that means that we saved - the registers as the result of an `on_failure_jump', not - a `start_memory', and we jumped to past the innermost - `stop_memory'. For example, in ((.)*) we save - registers 1 and 2 as a result of the *, but when we pop - back to the second ), we are at the stop_memory 1. - Thus, nothing is active. */ - if (r == 0) - { - lowest_active_reg = NO_LOWEST_ACTIVE_REG; - highest_active_reg = NO_HIGHEST_ACTIVE_REG; - } - else - highest_active_reg = r; - } - - /* If just failed to match something this time around with a - group that's operated on by a repetition operator, try to - force exit from the ``loop'', and restore the register - information for this group that we had before trying this - last match. */ - if ((!MATCHED_SOMETHING (reg_info[*p]) - || just_past_start_mem == p - 1) - && (p + 2) < pend) - { - boolean is_a_jump_n = false; - - p1 = p + 2; - mcnt = 0; - switch ((re_opcode_t) *p1++) - { - case jump_n: - is_a_jump_n = true; - case pop_failure_jump: - case maybe_pop_jump: - case jump: - case dummy_failure_jump: - EXTRACT_NUMBER_AND_INCR (mcnt, p1); - if (is_a_jump_n) - p1 += 2; - break; - - default: - /* do nothing */ ; - } - p1 += mcnt; - - /* If the next operation is a jump backwards in the pattern - to an on_failure_jump right before the start_memory - corresponding to this stop_memory, exit from the loop - by forcing a failure after pushing on the stack the - on_failure_jump's jump in the pattern, and d. */ - if (mcnt < 0 && (re_opcode_t) *p1 == on_failure_jump - && (re_opcode_t) p1[3] == start_memory && p1[4] == *p) - { - /* If this group ever matched anything, then restore - what its registers were before trying this last - failed match, e.g., with `(a*)*b' against `ab' for - regstart[1], and, e.g., with `((a*)*(b*)*)*' - against `aba' for regend[3]. - - Also restore the registers for inner groups for, - e.g., `((a*)(b*))*' against `aba' (register 3 would - otherwise get trashed). */ - - if (EVER_MATCHED_SOMETHING (reg_info[*p])) - { - unsigned r; - - EVER_MATCHED_SOMETHING (reg_info[*p]) = 0; - - /* Restore this and inner groups' (if any) registers. */ - for (r = *p; r < *p + *(p + 1); r++) - { - regstart[r] = old_regstart[r]; - - /* xx why this test? */ - if (old_regend[r] >= regstart[r]) - regend[r] = old_regend[r]; - } - } - p1++; - EXTRACT_NUMBER_AND_INCR (mcnt, p1); - PUSH_FAILURE_POINT (p1 + mcnt, d, -2); - - goto fail; - } - } - - /* Move past the register number and the inner group count. */ - p += 2; - break; - - - /* \ has been turned into a `duplicate' command which is - followed by the numeric value of as the register number. */ - case duplicate: - { - register const char *d2, *dend2; - int regno = *p++; /* Get which register to match against. */ - DEBUG_PRINT2 ("EXECUTING duplicate %d.\n", regno); - - /* Can't back reference a group which we've never matched. */ - if (REG_UNSET (regstart[regno]) || REG_UNSET (regend[regno])) - goto fail; - - /* Where in input to try to start matching. */ - d2 = regstart[regno]; - - /* Where to stop matching; if both the place to start and - the place to stop matching are in the same string, then - set to the place to stop, otherwise, for now have to use - the end of the first string. */ - - dend2 = ((FIRST_STRING_P (regstart[regno]) - == FIRST_STRING_P (regend[regno])) - ? regend[regno] : end_match_1); - for (;;) - { - /* If necessary, advance to next segment in register - contents. */ - while (d2 == dend2) - { - if (dend2 == end_match_2) break; - if (dend2 == regend[regno]) break; - - /* End of string1 => advance to string2. */ - d2 = string2; - dend2 = regend[regno]; - } - /* At end of register contents => success */ - if (d2 == dend2) break; - - /* If necessary, advance to next segment in data. */ - PREFETCH (); - - /* How many characters left in this segment to match. */ - mcnt = dend - d; - - /* Want how many consecutive characters we can match in - one shot, so, if necessary, adjust the count. */ - if (mcnt > dend2 - d2) - mcnt = dend2 - d2; - - /* Compare that many; failure if mismatch, else move - past them. */ - if (RE_TRANSLATE_P (translate) - ? bcmp_translate (d, d2, mcnt, translate) - : bcmp (d, d2, mcnt)) - goto fail; - d += mcnt, d2 += mcnt; - - /* Do this because we've match some characters. */ - SET_REGS_MATCHED (); - } - } - break; - - - /* begline matches the empty string at the beginning of the string - (unless `not_bol' is set in `bufp'), and, if - `newline_anchor' is set, after newlines. */ - case begline: - DEBUG_PRINT1 ("EXECUTING begline.\n"); - - if (AT_STRINGS_BEG (d)) - { - if (!bufp->not_bol) break; - } - else if (d[-1] == '\n' && bufp->newline_anchor) - { - break; - } - /* In all other cases, we fail. */ - goto fail; - - - /* endline is the dual of begline. */ - case endline: - DEBUG_PRINT1 ("EXECUTING endline.\n"); - - if (AT_STRINGS_END (d)) - { - if (!bufp->not_eol) break; - } - - /* We have to ``prefetch'' the next character. */ - else if ((d == end1 ? *string2 : *d) == '\n' - && bufp->newline_anchor) - { - break; - } - goto fail; - - - /* Match at the very beginning of the data. */ - case begbuf: - DEBUG_PRINT1 ("EXECUTING begbuf.\n"); - if (AT_STRINGS_BEG (d)) - break; - goto fail; - - - /* Match at the very end of the data. */ - case endbuf: - DEBUG_PRINT1 ("EXECUTING endbuf.\n"); - if (AT_STRINGS_END (d)) - break; - goto fail; - - - /* on_failure_keep_string_jump is used to optimize `.*\n'. It - pushes NULL as the value for the string on the stack. Then - `pop_failure_point' will keep the current value for the - string, instead of restoring it. To see why, consider - matching `foo\nbar' against `.*\n'. The .* matches the foo; - then the . fails against the \n. But the next thing we want - to do is match the \n against the \n; if we restored the - string value, we would be back at the foo. - - Because this is used only in specific cases, we don't need to - check all the things that `on_failure_jump' does, to make - sure the right things get saved on the stack. Hence we don't - share its code. The only reason to push anything on the - stack at all is that otherwise we would have to change - `anychar's code to do something besides goto fail in this - case; that seems worse than this. */ - case on_failure_keep_string_jump: - DEBUG_PRINT1 ("EXECUTING on_failure_keep_string_jump"); - - EXTRACT_NUMBER_AND_INCR (mcnt, p); - DEBUG_PRINT3 (" %d (to 0x%x):\n", mcnt, p + mcnt); - - PUSH_FAILURE_POINT (p + mcnt, NULL, -2); - break; - - - /* Uses of on_failure_jump: - - Each alternative starts with an on_failure_jump that points - to the beginning of the next alternative. Each alternative - except the last ends with a jump that in effect jumps past - the rest of the alternatives. (They really jump to the - ending jump of the following alternative, because tensioning - these jumps is a hassle.) - - Repeats start with an on_failure_jump that points past both - the repetition text and either the following jump or - pop_failure_jump back to this on_failure_jump. */ - case on_failure_jump: - on_failure: - DEBUG_PRINT1 ("EXECUTING on_failure_jump"); - -#if defined (WINDOWSNT) && defined (emacs) - QUIT; -#endif - - EXTRACT_NUMBER_AND_INCR (mcnt, p); - DEBUG_PRINT3 (" %d (to 0x%x)", mcnt, p + mcnt); - - /* If this on_failure_jump comes right before a group (i.e., - the original * applied to a group), save the information - for that group and all inner ones, so that if we fail back - to this point, the group's information will be correct. - For example, in \(a*\)*\1, we need the preceding group, - and in \(zz\(a*\)b*\)\2, we need the inner group. */ - - /* We can't use `p' to check ahead because we push - a failure point to `p + mcnt' after we do this. */ - p1 = p; - - /* We need to skip no_op's before we look for the - start_memory in case this on_failure_jump is happening as - the result of a completed succeed_n, as in \(a\)\{1,3\}b\1 - against aba. */ - while (p1 < pend && (re_opcode_t) *p1 == no_op) - p1++; - - if (p1 < pend && (re_opcode_t) *p1 == start_memory) - { - /* We have a new highest active register now. This will - get reset at the start_memory we are about to get to, - but we will have saved all the registers relevant to - this repetition op, as described above. */ - highest_active_reg = *(p1 + 1) + *(p1 + 2); - if (lowest_active_reg == NO_LOWEST_ACTIVE_REG) - lowest_active_reg = *(p1 + 1); - } - - DEBUG_PRINT1 (":\n"); - PUSH_FAILURE_POINT (p + mcnt, d, -2); - break; - - - /* A smart repeat ends with `maybe_pop_jump'. - We change it to either `pop_failure_jump' or `jump'. */ - case maybe_pop_jump: -#if defined (WINDOWSNT) && defined (emacs) - QUIT; -#endif - EXTRACT_NUMBER_AND_INCR (mcnt, p); - DEBUG_PRINT2 ("EXECUTING maybe_pop_jump %d.\n", mcnt); - { - register unsigned char *p2 = p; - - /* Compare the beginning of the repeat with what in the - pattern follows its end. If we can establish that there - is nothing that they would both match, i.e., that we - would have to backtrack because of (as in, e.g., `a*a') - then we can change to pop_failure_jump, because we'll - never have to backtrack. - - This is not true in the case of alternatives: in - `(a|ab)*' we do need to backtrack to the `ab' alternative - (e.g., if the string was `ab'). But instead of trying to - detect that here, the alternative has put on a dummy - failure point which is what we will end up popping. */ - - /* Skip over open/close-group commands. - If what follows this loop is a ...+ construct, - look at what begins its body, since we will have to - match at least one of that. */ - while (1) - { - if (p2 + 2 < pend - && ((re_opcode_t) *p2 == stop_memory - || (re_opcode_t) *p2 == start_memory)) - p2 += 3; - else if (p2 + 6 < pend - && (re_opcode_t) *p2 == dummy_failure_jump) - p2 += 6; - else - break; - } - - p1 = p + mcnt; - /* p1[0] ... p1[2] are the `on_failure_jump' corresponding - to the `maybe_finalize_jump' of this case. Examine what - follows. */ - - /* If we're at the end of the pattern, we can change. */ - if (p2 == pend) - { - /* Consider what happens when matching ":\(.*\)" - against ":/". I don't really understand this code - yet. */ - p[-3] = (unsigned char) pop_failure_jump; - DEBUG_PRINT1 - (" End of pattern: change to `pop_failure_jump'.\n"); - } - - else if ((re_opcode_t) *p2 == exactn - || (bufp->newline_anchor && (re_opcode_t) *p2 == endline)) - { - register unsigned int c - = *p2 == (unsigned char) endline ? '\n' : p2[2]; - - if ((re_opcode_t) p1[3] == exactn) - { - if (!(multibyte /* && (c != '\n') */ - && BASE_LEADING_CODE_P (c)) - ? c != p1[5] - : (STRING_CHAR (&p2[2], pend - &p2[2]) - != STRING_CHAR (&p1[5], pend - &p1[5]))) - { - p[-3] = (unsigned char) pop_failure_jump; - DEBUG_PRINT3 (" %c != %c => pop_failure_jump.\n", - c, p1[5]); - } - } - - else if ((re_opcode_t) p1[3] == charset - || (re_opcode_t) p1[3] == charset_not) - { - int not = (re_opcode_t) p1[3] == charset_not; - - if (multibyte /* && (c != '\n') */ - && BASE_LEADING_CODE_P (c)) - c = STRING_CHAR (&p2[2], pend - &p2[2]); - - /* Test if C is listed in charset (or charset_not) - at `&p1[3]'. */ - if (SINGLE_BYTE_CHAR_P (c)) - { - if (c < CHARSET_BITMAP_SIZE (&p1[3]) * BYTEWIDTH - && p1[5 + c / BYTEWIDTH] & (1 << (c % BYTEWIDTH))) - not = !not; - } - else if (CHARSET_RANGE_TABLE_EXISTS_P (&p1[3])) - CHARSET_LOOKUP_RANGE_TABLE (not, c, &p1[3]); - - /* `not' is equal to 1 if c would match, which means - that we can't change to pop_failure_jump. */ - if (!not) - { - p[-3] = (unsigned char) pop_failure_jump; - DEBUG_PRINT1 (" No match => pop_failure_jump.\n"); - } - } - } - else if ((re_opcode_t) *p2 == charset) - { - if ((re_opcode_t) p1[3] == exactn) - { - register unsigned int c = p1[5]; - int not = 0; - - if (multibyte && BASE_LEADING_CODE_P (c)) - c = STRING_CHAR (&p1[5], pend - &p1[5]); - - /* Test if C is listed in charset at `p2'. */ - if (SINGLE_BYTE_CHAR_P (c)) - { - if (c < CHARSET_BITMAP_SIZE (p2) * BYTEWIDTH - && (p2[2 + c / BYTEWIDTH] - & (1 << (c % BYTEWIDTH)))) - not = !not; - } - else if (CHARSET_RANGE_TABLE_EXISTS_P (p2)) - CHARSET_LOOKUP_RANGE_TABLE (not, c, p2); - - if (!not) - { - p[-3] = (unsigned char) pop_failure_jump; - DEBUG_PRINT1 (" No match => pop_failure_jump.\n"); - } - } - - /* It is hard to list up all the character in charset - P2 if it includes multibyte character. Give up in - such case. */ - else if (!multibyte || !CHARSET_RANGE_TABLE_EXISTS_P (p2)) - { - /* Now, we are sure that P2 has no range table. - So, for the size of bitmap in P2, `p2[1]' is - enough. But P1 may have range table, so the - size of bitmap table of P1 is extracted by - using macro `CHARSET_BITMAP_SIZE'. - - Since we know that all the character listed in - P2 is ASCII, it is enough to test only bitmap - table of P1. */ - - if ((re_opcode_t) p1[3] == charset_not) - { - int idx; - /* We win if the charset_not inside the loop lists - every character listed in the charset after. */ - for (idx = 0; idx < (int) p2[1]; idx++) - if (! (p2[2 + idx] == 0 - || (idx < CHARSET_BITMAP_SIZE (&p1[3]) - && ((p2[2 + idx] & ~ p1[5 + idx]) == 0)))) - break; - - if (idx == p2[1]) - { - p[-3] = (unsigned char) pop_failure_jump; - DEBUG_PRINT1 (" No match => pop_failure_jump.\n"); - } - } - else if ((re_opcode_t) p1[3] == charset) - { - int idx; - /* We win if the charset inside the loop - has no overlap with the one after the loop. */ - for (idx = 0; - (idx < (int) p2[1] - && idx < CHARSET_BITMAP_SIZE (&p1[3])); - idx++) - if ((p2[2 + idx] & p1[5 + idx]) != 0) - break; - - if (idx == p2[1] - || idx == CHARSET_BITMAP_SIZE (&p1[3])) - { - p[-3] = (unsigned char) pop_failure_jump; - DEBUG_PRINT1 (" No match => pop_failure_jump.\n"); - } - } - } - } - } - p -= 2; /* Point at relative address again. */ - if ((re_opcode_t) p[-1] != pop_failure_jump) - { - p[-1] = (unsigned char) jump; - DEBUG_PRINT1 (" Match => jump.\n"); - goto unconditional_jump; - } - /* Note fall through. */ - - - /* The end of a simple repeat has a pop_failure_jump back to - its matching on_failure_jump, where the latter will push a - failure point. The pop_failure_jump takes off failure - points put on by this pop_failure_jump's matching - on_failure_jump; we got through the pattern to here from the - matching on_failure_jump, so didn't fail. */ - case pop_failure_jump: - { - /* We need to pass separate storage for the lowest and - highest registers, even though we don't care about the - actual values. Otherwise, we will restore only one - register from the stack, since lowest will == highest in - `pop_failure_point'. */ - unsigned dummy_low_reg, dummy_high_reg; - unsigned char *pdummy; - const char *sdummy; - - DEBUG_PRINT1 ("EXECUTING pop_failure_jump.\n"); - POP_FAILURE_POINT (sdummy, pdummy, - dummy_low_reg, dummy_high_reg, - reg_dummy, reg_dummy, reg_info_dummy); - } - /* Note fall through. */ - - - /* Unconditionally jump (without popping any failure points). */ - case jump: - unconditional_jump: -#if defined (WINDOWSNT) && defined (emacs) - QUIT; -#endif - EXTRACT_NUMBER_AND_INCR (mcnt, p); /* Get the amount to jump. */ - DEBUG_PRINT2 ("EXECUTING jump %d ", mcnt); - p += mcnt; /* Do the jump. */ - DEBUG_PRINT2 ("(to 0x%x).\n", p); - break; - - - /* We need this opcode so we can detect where alternatives end - in `group_match_null_string_p' et al. */ - case jump_past_alt: - DEBUG_PRINT1 ("EXECUTING jump_past_alt.\n"); - goto unconditional_jump; - - - /* Normally, the on_failure_jump pushes a failure point, which - then gets popped at pop_failure_jump. We will end up at - pop_failure_jump, also, and with a pattern of, say, `a+', we - are skipping over the on_failure_jump, so we have to push - something meaningless for pop_failure_jump to pop. */ - case dummy_failure_jump: - DEBUG_PRINT1 ("EXECUTING dummy_failure_jump.\n"); - /* It doesn't matter what we push for the string here. What - the code at `fail' tests is the value for the pattern. */ - PUSH_FAILURE_POINT (0, 0, -2); - goto unconditional_jump; - - - /* At the end of an alternative, we need to push a dummy failure - point in case we are followed by a `pop_failure_jump', because - we don't want the failure point for the alternative to be - popped. For example, matching `(a|ab)*' against `aab' - requires that we match the `ab' alternative. */ - case push_dummy_failure: - DEBUG_PRINT1 ("EXECUTING push_dummy_failure.\n"); - /* See comments just above at `dummy_failure_jump' about the - two zeroes. */ - PUSH_FAILURE_POINT (0, 0, -2); - break; - - /* Have to succeed matching what follows at least n times. - After that, handle like `on_failure_jump'. */ - case succeed_n: - EXTRACT_NUMBER (mcnt, p + 2); - DEBUG_PRINT2 ("EXECUTING succeed_n %d.\n", mcnt); - - assert (mcnt >= 0); - /* Originally, this is how many times we HAVE to succeed. */ - if (mcnt > 0) - { - mcnt--; - p += 2; - STORE_NUMBER_AND_INCR (p, mcnt); - DEBUG_PRINT3 (" Setting 0x%x to %d.\n", p, mcnt); - } - else if (mcnt == 0) - { - DEBUG_PRINT2 (" Setting two bytes from 0x%x to no_op.\n", p+2); - p[2] = (unsigned char) no_op; - p[3] = (unsigned char) no_op; - goto on_failure; - } - break; - - case jump_n: - EXTRACT_NUMBER (mcnt, p + 2); - DEBUG_PRINT2 ("EXECUTING jump_n %d.\n", mcnt); - - /* Originally, this is how many times we CAN jump. */ - if (mcnt) - { - mcnt--; - STORE_NUMBER (p + 2, mcnt); - goto unconditional_jump; - } - /* If don't have to jump any more, skip over the rest of command. */ - else - p += 4; - break; - - case set_number_at: - { - DEBUG_PRINT1 ("EXECUTING set_number_at.\n"); - - EXTRACT_NUMBER_AND_INCR (mcnt, p); - p1 = p + mcnt; - EXTRACT_NUMBER_AND_INCR (mcnt, p); - DEBUG_PRINT3 (" Setting 0x%x to %d.\n", p1, mcnt); - STORE_NUMBER (p1, mcnt); - break; - } - - case wordbound: - DEBUG_PRINT1 ("EXECUTING wordbound.\n"); - - /* We SUCCEED in one of the following cases: */ - - /* Case 1: D is at the beginning or the end of string. */ - if (AT_STRINGS_BEG (d) || AT_STRINGS_END (d)) - break; - else - { - /* C1 is the character before D, S1 is the syntax of C1, C2 - is the character at D, and S2 is the syntax of C2. */ - int c1, c2, s1, s2; - int pos1 = PTR_TO_OFFSET (d - 1); - int charpos; - - GET_CHAR_BEFORE_2 (c1, d, string1, end1, string2, end2); - GET_CHAR_AFTER_2 (c2, d, string1, end1, string2, end2); -#ifdef emacs - charpos = SYNTAX_TABLE_BYTE_TO_CHAR (pos1); - UPDATE_SYNTAX_TABLE (charpos); -#endif - s1 = SYNTAX (c1); -#ifdef emacs - UPDATE_SYNTAX_TABLE_FORWARD (charpos + 1); -#endif - s2 = SYNTAX (c2); - - if (/* Case 2: Only one of S1 and S2 is Sword. */ - ((s1 == Sword) != (s2 == Sword)) - /* Case 3: Both of S1 and S2 are Sword, and macro - WORD_BOUNDARY_P (C1, C2) returns nonzero. */ - || ((s1 == Sword) && WORD_BOUNDARY_P (c1, c2))) - break; - } - goto fail; - - case notwordbound: - DEBUG_PRINT1 ("EXECUTING notwordbound.\n"); - - /* We FAIL in one of the following cases: */ - - /* Case 1: D is at the beginning or the end of string. */ - if (AT_STRINGS_BEG (d) || AT_STRINGS_END (d)) - goto fail; - else - { - /* C1 is the character before D, S1 is the syntax of C1, C2 - is the character at D, and S2 is the syntax of C2. */ - int c1, c2, s1, s2; - int pos1 = PTR_TO_OFFSET (d - 1); - int charpos; - - GET_CHAR_BEFORE_2 (c1, d, string1, end1, string2, end2); - GET_CHAR_AFTER_2 (c2, d, string1, end1, string2, end2); -#ifdef emacs - charpos = SYNTAX_TABLE_BYTE_TO_CHAR (pos1); - UPDATE_SYNTAX_TABLE (charpos); -#endif - s1 = SYNTAX (c1); -#ifdef emacs - UPDATE_SYNTAX_TABLE_FORWARD (charpos + 1); -#endif - s2 = SYNTAX (c2); - - if (/* Case 2: Only one of S1 and S2 is Sword. */ - ((s1 == Sword) != (s2 == Sword)) - /* Case 3: Both of S1 and S2 are Sword, and macro - WORD_BOUNDARY_P (C1, C2) returns nonzero. */ - || ((s1 == Sword) && WORD_BOUNDARY_P (c1, c2))) - goto fail; - } - break; - - case wordbeg: - DEBUG_PRINT1 ("EXECUTING wordbeg.\n"); - - /* We FAIL in one of the following cases: */ - - /* Case 1: D is at the end of string. */ - if (AT_STRINGS_END (d)) - goto fail; - else - { - /* C1 is the character before D, S1 is the syntax of C1, C2 - is the character at D, and S2 is the syntax of C2. */ - int c1, c2, s1, s2; - int pos1 = PTR_TO_OFFSET (d); - int charpos; - - GET_CHAR_AFTER_2 (c2, d, string1, end1, string2, end2); -#ifdef emacs - charpos = SYNTAX_TABLE_BYTE_TO_CHAR (pos1); - UPDATE_SYNTAX_TABLE (charpos); -#endif - s2 = SYNTAX (c2); - - /* Case 2: S2 is not Sword. */ - if (s2 != Sword) - goto fail; - - /* Case 3: D is not at the beginning of string ... */ - if (!AT_STRINGS_BEG (d)) - { - GET_CHAR_BEFORE_2 (c1, d, string1, end1, string2, end2); -#ifdef emacs - UPDATE_SYNTAX_TABLE_BACKWARD (charpos - 1); -#endif - s1 = SYNTAX (c1); - - /* ... and S1 is Sword, and WORD_BOUNDARY_P (C1, C2) - returns 0. */ - if ((s1 == Sword) && !WORD_BOUNDARY_P (c1, c2)) - goto fail; - } - } - break; - - case wordend: - DEBUG_PRINT1 ("EXECUTING wordend.\n"); - - /* We FAIL in one of the following cases: */ - - /* Case 1: D is at the beginning of string. */ - if (AT_STRINGS_BEG (d)) - goto fail; - else - { - /* C1 is the character before D, S1 is the syntax of C1, C2 - is the character at D, and S2 is the syntax of C2. */ - int c1, c2, s1, s2; - int pos1 = PTR_TO_OFFSET (d); - int charpos; - - GET_CHAR_BEFORE_2 (c1, d, string1, end1, string2, end2); -#ifdef emacs - charpos = SYNTAX_TABLE_BYTE_TO_CHAR (pos1 - 1); - UPDATE_SYNTAX_TABLE (charpos); -#endif - s1 = SYNTAX (c1); - - /* Case 2: S1 is not Sword. */ - if (s1 != Sword) - goto fail; - - /* Case 3: D is not at the end of string ... */ - if (!AT_STRINGS_END (d)) - { - GET_CHAR_AFTER_2 (c2, d, string1, end1, string2, end2); -#ifdef emacs - UPDATE_SYNTAX_TABLE_FORWARD (charpos); -#endif - s2 = SYNTAX (c2); - - /* ... and S2 is Sword, and WORD_BOUNDARY_P (C1, C2) - returns 0. */ - if ((s2 == Sword) && !WORD_BOUNDARY_P (c1, c2)) - goto fail; - } - } - break; - -#ifdef emacs - case before_dot: - DEBUG_PRINT1 ("EXECUTING before_dot.\n"); - if (PTR_BYTE_POS ((unsigned char *) d) >= PT_BYTE) - goto fail; - break; - - case at_dot: - DEBUG_PRINT1 ("EXECUTING at_dot.\n"); - if (PTR_BYTE_POS ((unsigned char *) d) != PT_BYTE) - goto fail; - break; - - case after_dot: - DEBUG_PRINT1 ("EXECUTING after_dot.\n"); - if (PTR_BYTE_POS ((unsigned char *) d) <= PT_BYTE) - goto fail; - break; - - case syntaxspec: - DEBUG_PRINT2 ("EXECUTING syntaxspec %d.\n", mcnt); - mcnt = *p++; - goto matchsyntax; - - case wordchar: - DEBUG_PRINT1 ("EXECUTING Emacs wordchar.\n"); - mcnt = (int) Sword; - matchsyntax: - PREFETCH (); -#ifdef emacs - { - int pos1 = SYNTAX_TABLE_BYTE_TO_CHAR (PTR_TO_OFFSET (d)); - UPDATE_SYNTAX_TABLE (pos1); - } -#endif - { - int c, len; - - if (multibyte) - /* we must concern about multibyte form, ... */ - c = STRING_CHAR_AND_LENGTH (d, dend - d, len); - else - /* everything should be handled as ASCII, even though it - looks like multibyte form. */ - c = *d, len = 1; - - if (SYNTAX (c) != (enum syntaxcode) mcnt) - goto fail; - d += len; - } - SET_REGS_MATCHED (); - break; - - case notsyntaxspec: - DEBUG_PRINT2 ("EXECUTING notsyntaxspec %d.\n", mcnt); - mcnt = *p++; - goto matchnotsyntax; - - case notwordchar: - DEBUG_PRINT1 ("EXECUTING Emacs notwordchar.\n"); - mcnt = (int) Sword; - matchnotsyntax: - PREFETCH (); -#ifdef emacs - { - int pos1 = SYNTAX_TABLE_BYTE_TO_CHAR (PTR_TO_OFFSET (d)); - UPDATE_SYNTAX_TABLE (pos1); - } -#endif - { - int c, len; - - if (multibyte) - c = STRING_CHAR_AND_LENGTH (d, dend - d, len); - else - c = *d, len = 1; - - if (SYNTAX (c) == (enum syntaxcode) mcnt) - goto fail; - d += len; - } - SET_REGS_MATCHED (); - break; - - case categoryspec: - DEBUG_PRINT2 ("EXECUTING categoryspec %d.\n", *p); - mcnt = *p++; - PREFETCH (); - { - int c, len; - - if (multibyte) - c = STRING_CHAR_AND_LENGTH (d, dend - d, len); - else - c = *d, len = 1; - - if (!CHAR_HAS_CATEGORY (c, mcnt)) - goto fail; - d += len; - } - SET_REGS_MATCHED (); - break; - - case notcategoryspec: - DEBUG_PRINT2 ("EXECUTING notcategoryspec %d.\n", *p); - mcnt = *p++; - PREFETCH (); - { - int c, len; - - if (multibyte) - c = STRING_CHAR_AND_LENGTH (d, dend - d, len); - else - c = *d, len = 1; - - if (CHAR_HAS_CATEGORY (c, mcnt)) - goto fail; - d += len; - } - SET_REGS_MATCHED (); - break; - -#else /* not emacs */ - case wordchar: - DEBUG_PRINT1 ("EXECUTING non-Emacs wordchar.\n"); - PREFETCH (); - if (!WORDCHAR_P (d)) - goto fail; - SET_REGS_MATCHED (); - d++; - break; - - case notwordchar: - DEBUG_PRINT1 ("EXECUTING non-Emacs notwordchar.\n"); - PREFETCH (); - if (WORDCHAR_P (d)) - goto fail; - SET_REGS_MATCHED (); - d++; - break; -#endif /* not emacs */ - - default: - abort (); - } - continue; /* Successfully executed one pattern command; keep going. */ - - - /* We goto here if a matching operation fails. */ - fail: -#if defined (WINDOWSNT) && defined (emacs) - QUIT; -#endif - if (!FAIL_STACK_EMPTY ()) - { /* A restart point is known. Restore to that state. */ - DEBUG_PRINT1 ("\nFAIL:\n"); - POP_FAILURE_POINT (d, p, - lowest_active_reg, highest_active_reg, - regstart, regend, reg_info); - - /* If this failure point is a dummy, try the next one. */ - if (!p) - goto fail; - - /* If we failed to the end of the pattern, don't examine *p. */ - assert (p <= pend); - if (p < pend) - { - boolean is_a_jump_n = false; - - /* If failed to a backwards jump that's part of a repetition - loop, need to pop this failure point and use the next one. */ - switch ((re_opcode_t) *p) - { - case jump_n: - is_a_jump_n = true; - case maybe_pop_jump: - case pop_failure_jump: - case jump: - p1 = p + 1; - EXTRACT_NUMBER_AND_INCR (mcnt, p1); - p1 += mcnt; - - if ((is_a_jump_n && (re_opcode_t) *p1 == succeed_n) - || (!is_a_jump_n - && (re_opcode_t) *p1 == on_failure_jump)) - goto fail; - break; - default: - /* do nothing */ ; - } - } - - if (d >= string1 && d <= end1) - dend = end_match_1; - } - else - break; /* Matching at this starting point really fails. */ - } /* for (;;) */ - - if (best_regs_set) - goto restore_best_regs; - - FREE_VARIABLES (); - - return -1; /* Failure to match. */ -} /* re_match_2 */ - -/* Subroutine definitions for re_match_2. */ - - -/* We are passed P pointing to a register number after a start_memory. - - Return true if the pattern up to the corresponding stop_memory can - match the empty string, and false otherwise. - - If we find the matching stop_memory, sets P to point to one past its number. - Otherwise, sets P to an undefined byte less than or equal to END. - - We don't handle duplicates properly (yet). */ - -static boolean -group_match_null_string_p (p, end, reg_info) - unsigned char **p, *end; - register_info_type *reg_info; -{ - int mcnt; - /* Point to after the args to the start_memory. */ - unsigned char *p1 = *p + 2; - - while (p1 < end) - { - /* Skip over opcodes that can match nothing, and return true or - false, as appropriate, when we get to one that can't, or to the - matching stop_memory. */ - - switch ((re_opcode_t) *p1) - { - /* Could be either a loop or a series of alternatives. */ - case on_failure_jump: - p1++; - EXTRACT_NUMBER_AND_INCR (mcnt, p1); - - /* If the next operation is not a jump backwards in the - pattern. */ - - if (mcnt >= 0) - { - /* Go through the on_failure_jumps of the alternatives, - seeing if any of the alternatives cannot match nothing. - The last alternative starts with only a jump, - whereas the rest start with on_failure_jump and end - with a jump, e.g., here is the pattern for `a|b|c': - - /on_failure_jump/0/6/exactn/1/a/jump_past_alt/0/6 - /on_failure_jump/0/6/exactn/1/b/jump_past_alt/0/3 - /exactn/1/c - - So, we have to first go through the first (n-1) - alternatives and then deal with the last one separately. */ - - - /* Deal with the first (n-1) alternatives, which start - with an on_failure_jump (see above) that jumps to right - past a jump_past_alt. */ - - while ((re_opcode_t) p1[mcnt-3] == jump_past_alt) - { - /* `mcnt' holds how many bytes long the alternative - is, including the ending `jump_past_alt' and - its number. */ - - if (!alt_match_null_string_p (p1, p1 + mcnt - 3, - reg_info)) - return false; - - /* Move to right after this alternative, including the - jump_past_alt. */ - p1 += mcnt; - - /* Break if it's the beginning of an n-th alternative - that doesn't begin with an on_failure_jump. */ - if ((re_opcode_t) *p1 != on_failure_jump) - break; - - /* Still have to check that it's not an n-th - alternative that starts with an on_failure_jump. */ - p1++; - EXTRACT_NUMBER_AND_INCR (mcnt, p1); - if ((re_opcode_t) p1[mcnt-3] != jump_past_alt) - { - /* Get to the beginning of the n-th alternative. */ - p1 -= 3; - break; - } - } - - /* Deal with the last alternative: go back and get number - of the `jump_past_alt' just before it. `mcnt' contains - the length of the alternative. */ - EXTRACT_NUMBER (mcnt, p1 - 2); - - if (!alt_match_null_string_p (p1, p1 + mcnt, reg_info)) - return false; - - p1 += mcnt; /* Get past the n-th alternative. */ - } /* if mcnt > 0 */ - break; - - - case stop_memory: - assert (p1[1] == **p); - *p = p1 + 2; - return true; - - - default: - if (!common_op_match_null_string_p (&p1, end, reg_info)) - return false; - } - } /* while p1 < end */ - - return false; -} /* group_match_null_string_p */ - - -/* Similar to group_match_null_string_p, but doesn't deal with alternatives: - It expects P to be the first byte of a single alternative and END one - byte past the last. The alternative can contain groups. */ - -static boolean -alt_match_null_string_p (p, end, reg_info) - unsigned char *p, *end; - register_info_type *reg_info; -{ - int mcnt; - unsigned char *p1 = p; - - while (p1 < end) - { - /* Skip over opcodes that can match nothing, and break when we get - to one that can't. */ - - switch ((re_opcode_t) *p1) - { - /* It's a loop. */ - case on_failure_jump: - p1++; - EXTRACT_NUMBER_AND_INCR (mcnt, p1); - p1 += mcnt; - break; - - default: - if (!common_op_match_null_string_p (&p1, end, reg_info)) - return false; - } - } /* while p1 < end */ - - return true; -} /* alt_match_null_string_p */ - - -/* Deals with the ops common to group_match_null_string_p and - alt_match_null_string_p. - - Sets P to one after the op and its arguments, if any. */ - -static boolean -common_op_match_null_string_p (p, end, reg_info) - unsigned char **p, *end; - register_info_type *reg_info; -{ - int mcnt; - boolean ret; - int reg_no; - unsigned char *p1 = *p; - - switch ((re_opcode_t) *p1++) - { - case no_op: - case begline: - case endline: - case begbuf: - case endbuf: - case wordbeg: - case wordend: - case wordbound: - case notwordbound: -#ifdef emacs - case before_dot: - case at_dot: - case after_dot: -#endif - break; - - case start_memory: - reg_no = *p1; - assert (reg_no > 0 && reg_no <= MAX_REGNUM); - ret = group_match_null_string_p (&p1, end, reg_info); - - /* Have to set this here in case we're checking a group which - contains a group and a back reference to it. */ - - if (REG_MATCH_NULL_STRING_P (reg_info[reg_no]) == MATCH_NULL_UNSET_VALUE) - REG_MATCH_NULL_STRING_P (reg_info[reg_no]) = ret; - - if (!ret) - return false; - break; - - /* If this is an optimized succeed_n for zero times, make the jump. */ - case jump: - EXTRACT_NUMBER_AND_INCR (mcnt, p1); - if (mcnt >= 0) - p1 += mcnt; - else - return false; - break; - - case succeed_n: - /* Get to the number of times to succeed. */ - p1 += 2; - EXTRACT_NUMBER_AND_INCR (mcnt, p1); - - if (mcnt == 0) - { - p1 -= 4; - EXTRACT_NUMBER_AND_INCR (mcnt, p1); - p1 += mcnt; - } - else - return false; - break; - - case duplicate: - if (!REG_MATCH_NULL_STRING_P (reg_info[*p1])) - return false; - break; - - case set_number_at: - p1 += 4; - - default: - /* All other opcodes mean we cannot match the empty string. */ - return false; - } - - *p = p1; - return true; -} /* common_op_match_null_string_p */ - - -/* Return zero if TRANSLATE[S1] and TRANSLATE[S2] are identical for LEN - bytes; nonzero otherwise. */ - -static int -bcmp_translate (s1, s2, len, translate) - unsigned char *s1, *s2; - register int len; - RE_TRANSLATE_TYPE translate; -{ - register unsigned char *p1 = s1, *p2 = s2; - unsigned char *p1_end = s1 + len; - unsigned char *p2_end = s2 + len; - - while (p1 != p1_end && p2 != p2_end) - { - int p1_charlen, p2_charlen; - int p1_ch, p2_ch; - - p1_ch = STRING_CHAR_AND_LENGTH (p1, p1_end - p1, p1_charlen); - p2_ch = STRING_CHAR_AND_LENGTH (p2, p2_end - p2, p2_charlen); - - if (RE_TRANSLATE (translate, p1_ch) - != RE_TRANSLATE (translate, p2_ch)) - return 1; - - p1 += p1_charlen, p2 += p2_charlen; - } - - if (p1 != p1_end || p2 != p2_end) - return 1; - - return 0; -} - -/* Entry points for GNU code. */ - -/* re_compile_pattern is the GNU regular expression compiler: it - compiles PATTERN (of length SIZE) and puts the result in BUFP. - Returns 0 if the pattern was valid, otherwise an error string. - - Assumes the `allocated' (and perhaps `buffer') and `translate' fields - are set in BUFP on entry. - - We call regex_compile to do the actual compilation. */ - -const char * -re_compile_pattern (pattern, length, bufp) - const char *pattern; - int length; - struct re_pattern_buffer *bufp; -{ - reg_errcode_t ret; - - /* GNU code is written to assume at least RE_NREGS registers will be set - (and at least one extra will be -1). */ - bufp->regs_allocated = REGS_UNALLOCATED; - - /* And GNU code determines whether or not to get register information - by passing null for the REGS argument to re_match, etc., not by - setting no_sub. */ - bufp->no_sub = 0; - - /* Match anchors at newline. */ - bufp->newline_anchor = 1; - - ret = regex_compile (pattern, length, re_syntax_options, bufp); - - if (!ret) - return NULL; - return gettext (re_error_msgid[(int) ret]); -} - -/* Entry points compatible with 4.2 BSD regex library. We don't define - them unless specifically requested. */ - -#if defined (_REGEX_RE_COMP) || defined (_LIBC) - -/* BSD has one and only one pattern buffer. */ -static struct re_pattern_buffer re_comp_buf; - -char * -#ifdef _LIBC -/* Make these definitions weak in libc, so POSIX programs can redefine - these names if they don't use our functions, and still use - regcomp/regexec below without link errors. */ -weak_function -#endif -re_comp (s) - const char *s; -{ - reg_errcode_t ret; - - if (!s) - { - if (!re_comp_buf.buffer) - return (char *) gettext ("No previous regular expression"); - return 0; - } - - if (!re_comp_buf.buffer) - { - re_comp_buf.buffer = (unsigned char *) malloc (200); - if (re_comp_buf.buffer == NULL) - /* CVS: Yes, we're discarding `const' here if !HAVE_LIBINTL. */ - return (char *) gettext (re_error_msgid[(int) REG_ESPACE]); - re_comp_buf.allocated = 200; - - re_comp_buf.fastmap = (char *) malloc (1 << BYTEWIDTH); - if (re_comp_buf.fastmap == NULL) - /* CVS: Yes, we're discarding `const' here if !HAVE_LIBINTL. */ - return (char *) gettext (re_error_msgid[(int) REG_ESPACE]); - } - - /* Since `re_exec' always passes NULL for the `regs' argument, we - don't need to initialize the pattern buffer fields which affect it. */ - - /* Match anchors at newlines. */ - re_comp_buf.newline_anchor = 1; - - ret = regex_compile (s, strlen (s), re_syntax_options, &re_comp_buf); - - if (!ret) - return NULL; - - /* Yes, we're discarding `const' here if !HAVE_LIBINTL. */ - return (char *) gettext (re_error_msgid[(int) ret]); -} - - -int -#ifdef _LIBC -weak_function -#endif -re_exec (s) - const char *s; -{ - const int len = strlen (s); - return - 0 <= re_search (&re_comp_buf, s, len, 0, len, (struct re_registers *) 0); -} -#endif /* _REGEX_RE_COMP */ - -/* POSIX.2 functions. Don't define these for Emacs. */ - -#ifndef emacs - -/* regcomp takes a regular expression as a string and compiles it. - - PREG is a regex_t *. We do not expect any fields to be initialized, - since POSIX says we shouldn't. Thus, we set - - `buffer' to the compiled pattern; - `used' to the length of the compiled pattern; - `syntax' to RE_SYNTAX_POSIX_EXTENDED if the - REG_EXTENDED bit in CFLAGS is set; otherwise, to - RE_SYNTAX_POSIX_BASIC; - `newline_anchor' to REG_NEWLINE being set in CFLAGS; - `fastmap' and `fastmap_accurate' to zero; - `re_nsub' to the number of subexpressions in PATTERN. - - PATTERN is the address of the pattern string. - - CFLAGS is a series of bits which affect compilation. - - If REG_EXTENDED is set, we use POSIX extended syntax; otherwise, we - use POSIX basic syntax. - - If REG_NEWLINE is set, then . and [^...] don't match newline. - Also, regexec will try a match beginning after every newline. - - If REG_ICASE is set, then we considers upper- and lowercase - versions of letters to be equivalent when matching. - - If REG_NOSUB is set, then when PREG is passed to regexec, that - routine will report only success or failure, and nothing about the - registers. - - It returns 0 if it succeeds, nonzero if it doesn't. (See regex.h for - the return codes and their meanings.) */ - -int -regcomp (preg, pattern, cflags) - regex_t *preg; - const char *pattern; - int cflags; -{ - reg_errcode_t ret; - unsigned syntax - = (cflags & REG_EXTENDED) ? - RE_SYNTAX_POSIX_EXTENDED : RE_SYNTAX_POSIX_BASIC; - - /* regex_compile will allocate the space for the compiled pattern. */ - preg->buffer = 0; - preg->allocated = 0; - preg->used = 0; - - /* Don't bother to use a fastmap when searching. This simplifies the - REG_NEWLINE case: if we used a fastmap, we'd have to put all the - characters after newlines into the fastmap. This way, we just try - every character. */ - preg->fastmap = 0; - - if (cflags & REG_ICASE) - { - unsigned i; - - preg->translate - = (RE_TRANSLATE_TYPE) malloc (CHAR_SET_SIZE - * sizeof (*(RE_TRANSLATE_TYPE)0)); - if (preg->translate == NULL) - return (int) REG_ESPACE; - - /* Map uppercase characters to corresponding lowercase ones. */ - for (i = 0; i < CHAR_SET_SIZE; i++) - preg->translate[i] = ISUPPER (i) ? tolower (i) : i; - } - else - preg->translate = NULL; - - /* If REG_NEWLINE is set, newlines are treated differently. */ - if (cflags & REG_NEWLINE) - { /* REG_NEWLINE implies neither . nor [^...] match newline. */ - syntax &= ~RE_DOT_NEWLINE; - syntax |= RE_HAT_LISTS_NOT_NEWLINE; - /* It also changes the matching behavior. */ - preg->newline_anchor = 1; - } - else - preg->newline_anchor = 0; - - preg->no_sub = !!(cflags & REG_NOSUB); - - /* POSIX says a null character in the pattern terminates it, so we - can use strlen here in compiling the pattern. */ - ret = regex_compile (pattern, strlen (pattern), syntax, preg); - - /* POSIX doesn't distinguish between an unmatched open-group and an - unmatched close-group: both are REG_EPAREN. */ - if (ret == REG_ERPAREN) ret = REG_EPAREN; - - return (int) ret; -} - - -/* regexec searches for a given pattern, specified by PREG, in the - string STRING. - - If NMATCH is zero or REG_NOSUB was set in the cflags argument to - `regcomp', we ignore PMATCH. Otherwise, we assume PMATCH has at - least NMATCH elements, and we set them to the offsets of the - corresponding matched substrings. - - EFLAGS specifies `execution flags' which affect matching: if - REG_NOTBOL is set, then ^ does not match at the beginning of the - string; if REG_NOTEOL is set, then $ does not match at the end. - - We return 0 if we find a match and REG_NOMATCH if not. */ - -int -regexec (preg, string, nmatch, pmatch, eflags) - const regex_t *preg; - const char *string; - size_t nmatch; - regmatch_t pmatch[]; - int eflags; -{ - int ret; - struct re_registers regs; - regex_t private_preg; - int len = strlen (string); - boolean want_reg_info = !preg->no_sub && nmatch > 0; - - private_preg = *preg; - - private_preg.not_bol = !!(eflags & REG_NOTBOL); - private_preg.not_eol = !!(eflags & REG_NOTEOL); - - /* The user has told us exactly how many registers to return - information about, via `nmatch'. We have to pass that on to the - matching routines. */ - private_preg.regs_allocated = REGS_FIXED; - - if (want_reg_info) - { - regs.num_regs = nmatch; - regs.start = TALLOC (nmatch, regoff_t); - regs.end = TALLOC (nmatch, regoff_t); - if (regs.start == NULL || regs.end == NULL) - return (int) REG_NOMATCH; - } - - /* Perform the searching operation. */ - ret = re_search (&private_preg, string, len, - /* start: */ 0, /* range: */ len, - want_reg_info ? ®s : (struct re_registers *) 0); - - /* Copy the register information to the POSIX structure. */ - if (want_reg_info) - { - if (ret >= 0) - { - unsigned r; - - for (r = 0; r < nmatch; r++) - { - pmatch[r].rm_so = regs.start[r]; - pmatch[r].rm_eo = regs.end[r]; - } - } - - /* If we needed the temporary register info, free the space now. */ - free (regs.start); - free (regs.end); - } - - /* We want zero return to mean success, unlike `re_search'. */ - return ret >= 0 ? (int) REG_NOERROR : (int) REG_NOMATCH; -} - - -/* Returns a message corresponding to an error code, ERRCODE, returned - from either regcomp or regexec. We don't use PREG here. */ - -size_t -regerror (errcode, preg, errbuf, errbuf_size) - int errcode; - const regex_t *preg; - char *errbuf; - size_t errbuf_size; -{ - const char *msg; - size_t msg_size; - - if (errcode < 0 - || errcode >= (sizeof (re_error_msgid) / sizeof (re_error_msgid[0]))) - /* Only error codes returned by the rest of the code should be passed - to this routine. If we are given anything else, or if other regex - code generates an invalid error code, then the program has a bug. - Dump core so we can fix it. */ - abort (); - - msg = gettext (re_error_msgid[errcode]); - - msg_size = strlen (msg) + 1; /* Includes the null. */ - - if (errbuf_size != 0) - { - if (msg_size > errbuf_size) - { - strncpy (errbuf, msg, errbuf_size - 1); - errbuf[errbuf_size - 1] = 0; - } - else - strcpy (errbuf, msg); - } - - return msg_size; -} - - -/* Free dynamically allocated space used by PREG. */ - -void -regfree (preg) - regex_t *preg; -{ - if (preg->buffer != NULL) - free (preg->buffer); - preg->buffer = NULL; - - preg->allocated = 0; - preg->used = 0; - - if (preg->fastmap != NULL) - free (preg->fastmap); - preg->fastmap = NULL; - preg->fastmap_accurate = 0; - - if (preg->translate != NULL) - free (preg->translate); - preg->translate = NULL; -} - -#endif /* not emacs */ diff --git a/contrib/cvs/lib/regex.h b/contrib/cvs/lib/regex.h deleted file mode 100644 index 6c0c850..0000000 --- a/contrib/cvs/lib/regex.h +++ /dev/null @@ -1,533 +0,0 @@ -/* Definitions for data structures and routines for the regular - expression library, version 0.12. - - 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 - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - USA. */ - -#ifndef __REGEXP_LIBRARY_H__ -#define __REGEXP_LIBRARY_H__ - -/* POSIX says that must be included (by the caller) before - . */ - -#if !defined (_POSIX_C_SOURCE) && !defined (_POSIX_SOURCE) && defined (VMS) -/* VMS doesn't have `size_t' in , even though POSIX says it - should be there. */ -#include -#endif - - -/* The following bits are used to determine the regexp syntax we - recognize. The set/not-set meanings are chosen so that Emacs syntax - remains the value 0. The bits are given in alphabetical order, and - the definitions shifted by one from the previous bit; thus, when we - add or remove a bit, only one other definition need change. */ -typedef unsigned reg_syntax_t; - -/* If this bit is not set, then \ inside a bracket expression is literal. - If set, then such a \ quotes the following character. */ -#define RE_BACKSLASH_ESCAPE_IN_LISTS (1) - -/* If this bit is not set, then + and ? are operators, and \+ and \? are - literals. - If set, then \+ and \? are operators and + and ? are literals. */ -#define RE_BK_PLUS_QM (RE_BACKSLASH_ESCAPE_IN_LISTS << 1) - -/* If this bit is set, then character classes are supported. They are: - [:alpha:], [:upper:], [:lower:], [:digit:], [:alnum:], [:xdigit:], - [:space:], [:print:], [:punct:], [:graph:], and [:cntrl:]. - If not set, then character classes are not supported. */ -#define RE_CHAR_CLASSES (RE_BK_PLUS_QM << 1) - -/* If this bit is set, then ^ and $ are always anchors (outside bracket - expressions, of course). - If this bit is not set, then it depends: - ^ is an anchor if it is at the beginning of a regular - expression or after an open-group or an alternation operator; - $ is an anchor if it is at the end of a regular expression, or - before a close-group or an alternation operator. - - This bit could be (re)combined with RE_CONTEXT_INDEP_OPS, because - POSIX draft 11.2 says that * etc. in leading positions is undefined. - We already implemented a previous draft which made those constructs - invalid, though, so we haven't changed the code back. */ -#define RE_CONTEXT_INDEP_ANCHORS (RE_CHAR_CLASSES << 1) - -/* If this bit is set, then special characters are always special - regardless of where they are in the pattern. - If this bit is not set, then special characters are special only in - some contexts; otherwise they are ordinary. Specifically, - * + ? and intervals are only special when not after the beginning, - open-group, or alternation operator. */ -#define RE_CONTEXT_INDEP_OPS (RE_CONTEXT_INDEP_ANCHORS << 1) - -/* If this bit is set, then *, +, ?, and { cannot be first in an re or - immediately after an alternation or begin-group operator. */ -#define RE_CONTEXT_INVALID_OPS (RE_CONTEXT_INDEP_OPS << 1) - -/* If this bit is set, then . matches newline. - If not set, then it doesn't. */ -#define RE_DOT_NEWLINE (RE_CONTEXT_INVALID_OPS << 1) - -/* If this bit is set, then . doesn't match NUL. - If not set, then it does. */ -#define RE_DOT_NOT_NULL (RE_DOT_NEWLINE << 1) - -/* If this bit is set, nonmatching lists [^...] do not match newline. - If not set, they do. */ -#define RE_HAT_LISTS_NOT_NEWLINE (RE_DOT_NOT_NULL << 1) - -/* If this bit is set, either \{...\} or {...} defines an - interval, depending on RE_NO_BK_BRACES. - If not set, \{, \}, {, and } are literals. */ -#define RE_INTERVALS (RE_HAT_LISTS_NOT_NEWLINE << 1) - -/* If this bit is set, +, ? and | aren't recognized as operators. - If not set, they are. */ -#define RE_LIMITED_OPS (RE_INTERVALS << 1) - -/* If this bit is set, newline is an alternation operator. - If not set, newline is literal. */ -#define RE_NEWLINE_ALT (RE_LIMITED_OPS << 1) - -/* If this bit is set, then `{...}' defines an interval, and \{ and \} - are literals. - If not set, then `\{...\}' defines an interval. */ -#define RE_NO_BK_BRACES (RE_NEWLINE_ALT << 1) - -/* If this bit is set, (...) defines a group, and \( and \) are literals. - If not set, \(...\) defines a group, and ( and ) are literals. */ -#define RE_NO_BK_PARENS (RE_NO_BK_BRACES << 1) - -/* If this bit is set, then \ matches . - If not set, then \ is a back-reference. */ -#define RE_NO_BK_REFS (RE_NO_BK_PARENS << 1) - -/* If this bit is set, then | is an alternation operator, and \| is literal. - If not set, then \| is an alternation operator, and | is literal. */ -#define RE_NO_BK_VBAR (RE_NO_BK_REFS << 1) - -/* If this bit is set, then an ending range point collating higher - than the starting range point, as in [z-a], is invalid. - If not set, then when ending range point collates higher than the - starting range point, the range is ignored. */ -#define RE_NO_EMPTY_RANGES (RE_NO_BK_VBAR << 1) - -/* If this bit is set, then an unmatched ) is ordinary. - 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 - don't delete them!) */ -/* [[[begin syntaxes]]] */ -#define RE_SYNTAX_EMACS 0 - -#define RE_SYNTAX_AWK \ - (RE_BACKSLASH_ESCAPE_IN_LISTS | RE_DOT_NOT_NULL \ - | RE_NO_BK_PARENS | RE_NO_BK_REFS \ - | RE_NO_BK_VBAR | RE_NO_EMPTY_RANGES \ - | RE_UNMATCHED_RIGHT_PAREN_ORD) - -#define RE_SYNTAX_POSIX_AWK \ - (RE_SYNTAX_POSIX_EXTENDED | RE_BACKSLASH_ESCAPE_IN_LISTS) - -#define RE_SYNTAX_GREP \ - (RE_BK_PLUS_QM | RE_CHAR_CLASSES \ - | RE_HAT_LISTS_NOT_NEWLINE | RE_INTERVALS \ - | RE_NEWLINE_ALT) - -#define RE_SYNTAX_EGREP \ - (RE_CHAR_CLASSES | RE_CONTEXT_INDEP_ANCHORS \ - | RE_CONTEXT_INDEP_OPS | RE_HAT_LISTS_NOT_NEWLINE \ - | RE_NEWLINE_ALT | RE_NO_BK_PARENS \ - | RE_NO_BK_VBAR) - -#define RE_SYNTAX_POSIX_EGREP \ - (RE_SYNTAX_EGREP | RE_INTERVALS | RE_NO_BK_BRACES) - -/* P1003.2/D11.2, section 4.20.7.1, lines 5078ff. */ -#define RE_SYNTAX_ED RE_SYNTAX_POSIX_BASIC - -#define RE_SYNTAX_SED RE_SYNTAX_POSIX_BASIC - -/* Syntax bits common to both basic and extended POSIX regex syntax. */ -#define _RE_SYNTAX_POSIX_COMMON \ - (RE_CHAR_CLASSES | RE_DOT_NEWLINE | RE_DOT_NOT_NULL \ - | RE_INTERVALS | RE_NO_EMPTY_RANGES) - -#define RE_SYNTAX_POSIX_BASIC \ - (_RE_SYNTAX_POSIX_COMMON | RE_BK_PLUS_QM) - -/* Differs from ..._POSIX_BASIC only in that RE_BK_PLUS_QM becomes - RE_LIMITED_OPS, i.e., \? \+ \| are not recognized. Actually, this - isn't minimal, since other operators, such as \`, aren't disabled. */ -#define RE_SYNTAX_POSIX_MINIMAL_BASIC \ - (_RE_SYNTAX_POSIX_COMMON | RE_LIMITED_OPS) - -#define RE_SYNTAX_POSIX_EXTENDED \ - (_RE_SYNTAX_POSIX_COMMON | RE_CONTEXT_INDEP_ANCHORS \ - | RE_CONTEXT_INDEP_OPS | RE_NO_BK_BRACES \ - | RE_NO_BK_PARENS | RE_NO_BK_VBAR \ - | RE_UNMATCHED_RIGHT_PAREN_ORD) - -/* Differs from ..._POSIX_EXTENDED in that RE_CONTEXT_INVALID_OPS - replaces RE_CONTEXT_INDEP_OPS and RE_NO_BK_REFS is added. */ -#define RE_SYNTAX_POSIX_MINIMAL_EXTENDED \ - (_RE_SYNTAX_POSIX_COMMON | RE_CONTEXT_INDEP_ANCHORS \ - | RE_CONTEXT_INVALID_OPS | RE_NO_BK_BRACES \ - | RE_NO_BK_PARENS | RE_NO_BK_REFS \ - | RE_NO_BK_VBAR | RE_UNMATCHED_RIGHT_PAREN_ORD) -/* [[[end syntaxes]]] */ - -/* Maximum number of duplicates an interval can allow. Some systems - (erroneously) define this in other header files, but we want our - value, so remove any previous define. */ -#ifdef RE_DUP_MAX -#undef RE_DUP_MAX -#endif -#define RE_DUP_MAX ((1 << 15) - 1) - - -/* POSIX `cflags' bits (i.e., information for `regcomp'). */ - -/* If this bit is set, then use extended regular expression syntax. - If not set, then use basic regular expression syntax. */ -#define REG_EXTENDED 1 - -/* If this bit is set, then ignore case when matching. - If not set, then case is significant. */ -#define REG_ICASE (REG_EXTENDED << 1) - -/* If this bit is set, then anchors do not match at newline - characters in the string. - If not set, then anchors do match at newlines. */ -#define REG_NEWLINE (REG_ICASE << 1) - -/* If this bit is set, then report only success or fail in regexec. - If not set, then returns differ between not matching and errors. */ -#define REG_NOSUB (REG_NEWLINE << 1) - - -/* POSIX `eflags' bits (i.e., information for regexec). */ - -/* If this bit is set, then the beginning-of-line operator doesn't match - the beginning of the string (presumably because it's not the - beginning of a line). - If not set, then the beginning-of-line operator does match the - beginning of the string. */ -#define REG_NOTBOL 1 - -/* Like REG_NOTBOL, except for the end-of-line. */ -#define REG_NOTEOL (1 << 1) - - -/* If any error codes are removed, changed, or added, update the - `re_error_msg' table in regex.c. */ -typedef enum -{ - REG_NOERROR = 0, /* Success. */ - REG_NOMATCH, /* Didn't find a match (for regexec). */ - - /* POSIX regcomp return error codes. (In the order listed in the - standard.) */ - REG_BADPAT, /* Invalid pattern. */ - REG_ECOLLATE, /* Not implemented. */ - REG_ECTYPE, /* Invalid character class name. */ - REG_EESCAPE, /* Trailing backslash. */ - REG_ESUBREG, /* Invalid back reference. */ - REG_EBRACK, /* Unmatched left bracket. */ - REG_EPAREN, /* Parenthesis imbalance. */ - REG_EBRACE, /* Unmatched \{. */ - REG_BADBR, /* Invalid contents of \{\}. */ - REG_ERANGE, /* Invalid range end. */ - REG_ESPACE, /* Ran out of memory. */ - REG_BADRPT, /* No preceding re for repetition op. */ - - /* Error codes we've added. */ - REG_EEND, /* Premature end. */ - REG_ESIZE, /* Compiled pattern bigger than 2^16 bytes. */ - REG_ERPAREN /* Unmatched ) or \); not returned from regcomp. */ -} reg_errcode_t; - -/* This data structure represents a compiled pattern. Before calling - the pattern compiler, the fields `buffer', `allocated', `fastmap', - `translate', and `no_sub' can be set. After the pattern has been - 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]]] */ - /* Space that holds the compiled pattern. It is declared as - `unsigned char *' because its elements are - sometimes used as array indexes. */ - unsigned char *buffer; - - /* Number of bytes to which `buffer' points. */ - unsigned long allocated; - - /* Number of bytes actually used in `buffer'. */ - unsigned long used; - - /* Syntax setting with which the pattern was compiled. */ - reg_syntax_t syntax; - - /* Pointer to a fastmap, if any, otherwise zero. re_search uses - the fastmap, if there is one, to skip over impossible - starting points for matches. */ - char *fastmap; - - /* Either a translate table to apply to all characters before - 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. */ - RE_TRANSLATE_TYPE translate; - - /* Number of subexpressions found by the compiler. */ - size_t re_nsub; - - /* Zero if this pattern cannot match the empty string, one else. - Well, in truth it's used only in `re_search_2', to see - whether or not we should use the fastmap, so we don't set - this absolutely perfectly; see `re_compile_fastmap' (the - `duplicate' case). */ - unsigned can_be_null : 1; - - /* If REGS_UNALLOCATED, allocate space in the `regs' structure - for `max (RE_NREGS, re_nsub + 1)' groups. - If REGS_REALLOCATE, reallocate space if necessary. - If REGS_FIXED, use what's there. */ -#define REGS_UNALLOCATED 0 -#define REGS_REALLOCATE 1 -#define REGS_FIXED 2 - unsigned regs_allocated : 2; - - /* Set to zero when `regex_compile' compiles a pattern; set to one - by `re_compile_fastmap' if it updates the fastmap. */ - unsigned fastmap_accurate : 1; - - /* If set, `re_match_2' does not return information about - subexpressions. */ - unsigned no_sub : 1; - - /* If set, a beginning-of-line anchor doesn't match at the - beginning of the string. */ - unsigned not_bol : 1; - - /* Similarly for an end-of-line anchor. */ - unsigned not_eol : 1; - - /* 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; - -/* Type for byte offsets within the string. POSIX mandates this. */ -typedef int regoff_t; - - -/* This is the structure we store register match data in. See - regex.texinfo for a full description of what registers match. */ -struct re_registers -{ - unsigned num_regs; - regoff_t *start; - regoff_t *end; -}; - - -/* If `regs_allocated' is REGS_UNALLOCATED in the pattern buffer, - `re_match_2' returns information about at least this many registers - the first time a `regs' structure is passed. */ -#ifndef RE_NREGS -#define RE_NREGS 30 -#endif - - -/* POSIX specification for registers. Aside from the different names than - `re_registers', POSIX uses an array of structures, instead of a - structure of arrays. */ -typedef struct -{ - regoff_t rm_so; /* Byte offset from string's start to substring's start. */ - regoff_t rm_eo; /* Byte offset from string's start to substring's end. */ -} regmatch_t; - -/* Declarations for routines. */ - -/* To avoid duplicating every routine declaration -- once with a - prototype (if we are ANSI), and once without (if we aren't) -- we - use the following macro to declare argument types. This - unfortunately clutters up the declarations a bit, but I think it's - worth it. */ - -#if __STDC__ - -#define _RE_ARGS(args) args - -#else /* not __STDC__ */ - -#define _RE_ARGS(args) () - -#endif /* not __STDC__ */ - -/* Sets the current default syntax to SYNTAX, and return the old syntax. - You can also simply assign to the `re_syntax_options' variable. */ -extern reg_syntax_t re_set_syntax _RE_ARGS ((reg_syntax_t syntax)); - -/* Compile the regular expression PATTERN, with length LENGTH - and syntax given by the global `re_syntax_options', into the buffer - BUFFER. Return NULL if successful, and an error string if not. */ -extern const char *re_compile_pattern - _RE_ARGS ((const char *pattern, int length, - struct re_pattern_buffer *buffer)); - - -/* Compile a fastmap for the compiled pattern in BUFFER; used to - accelerate searches. Return 0 if successful and -2 if was an - internal error. */ -extern int re_compile_fastmap _RE_ARGS ((struct re_pattern_buffer *buffer)); - - -/* Search in the string STRING (with length LENGTH) for the pattern - compiled into BUFFER. Start searching at position START, for RANGE - characters. Return the starting position of the match, -1 for no - match, or -2 for an internal error. Also return register - information in REGS (if REGS and BUFFER->no_sub are nonzero). */ -extern int re_search - _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string, - int length, int start, int range, struct re_registers *regs)); - - -/* Like `re_search', but search in the concatenation of STRING1 and - STRING2. Also, stop searching at index START + STOP. */ -extern int re_search_2 - _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string1, - int length1, const char *string2, int length2, - int start, int range, struct re_registers *regs, int stop)); - - -/* Like `re_search', but return how many characters in STRING the regexp - in BUFFER matched, starting at position START. */ -extern int re_match - _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string, - int length, int start, struct re_registers *regs)); - - -/* Relates to `re_match' as `re_search_2' relates to `re_search'. */ -extern int re_match_2 - _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string1, - int length1, const char *string2, int length2, - int start, struct re_registers *regs, int stop)); - - -/* Set REGS to hold NUM_REGS registers, storing them in STARTS and - ENDS. Subsequent matches using BUFFER and REGS will use this memory - for recording register information. STARTS and ENDS must be - allocated with malloc, and must each be at least `NUM_REGS * sizeof - (regoff_t)' bytes long. - - If NUM_REGS == 0, then subsequent matches should allocate their own - register data. - - Unless this function is called, the first search or match using - PATTERN_BUFFER will allocate its own register data, without - freeing the old data. */ -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)); - -#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. */ -/* CVS - DRP - * - * If the OS defines this, just redefine the names to avoid namespace - * clashes. In theory, we should be testing the built in functions to - * see if they do what we want and use them if possible, but this is - * easier... - * - * Namely, this was occurring under Mac OS X. This is a Mac OS X (or - * OS X related) bug. - */ -#ifdef HAVE_REGCOMP -# define regcomp cvs_regcomp -#endif /* HAVE_REGCOMP */ -#ifdef HAVE_REGERROR -# define regerror cvs_regerror -#endif /* HAVE_REGERROR */ -#ifdef HAVE_REGEXEC -# define regexec cvs_regexec -#endif /* HAVE_REGEXEC */ -#ifdef HAVE_REGFREE -# define regfree cvs_regfree -#endif /* HAVE_REGFREE */ - -extern int regcomp _RE_ARGS ((regex_t *preg, const char *pattern, int cflags)); -extern int regexec - _RE_ARGS ((const regex_t *preg, const char *string, size_t nmatch, - regmatch_t pmatch[], int eflags)); -extern size_t regerror - _RE_ARGS ((int errcode, const regex_t *preg, char *errbuf, - size_t errbuf_size)); -extern void regfree _RE_ARGS ((regex_t *preg)); - -#endif /* not __REGEXP_LIBRARY_H__ */ - -/* -Local variables: -make-backup-files: t -version-control: t -trim-versions-without-asking: nil -End: -*/ diff --git a/contrib/cvs/lib/rename.c b/contrib/cvs/lib/rename.c deleted file mode 100644 index 8dc0239..0000000 --- a/contrib/cvs/lib/rename.c +++ /dev/null @@ -1,80 +0,0 @@ -/* rename.c -- BSD compatible directory function for System V - Copyright (C) 1988, 1990 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include -#ifndef STDC_HEADERS -extern int errno; -#endif - -/* Rename file FROM to file TO. - Return 0 if successful, -1 if not. */ - -int -rename (from, to) - char *from; - char *to; -{ - struct stat from_stats; - int pid, status; - - if (stat (from, &from_stats) == 0) - { - /* We don't check existence_error because the systems which need it - have rename(). */ - if (CVS_UNLINK (to) && errno != ENOENT) - return -1; - if ((from_stats.st_mode & S_IFMT) == S_IFDIR) - { -#ifdef MVDIR - /* I don't think MVDIR ever gets defined, but I don't think - it matters, because I don't think CVS ever calls rename() - on directories. */ - - /* Need a setuid root process to link and unlink directories. */ - pid = fork (); - switch (pid) - { - case -1: /* Error. */ - error (1, errno, "cannot fork"); - - case 0: /* Child. */ - execl (MVDIR, "mvdir", from, to, (char *) 0); - error (255, errno, "cannot run `%s'", MVDIR); - - default: /* Parent. */ - while (wait (&status) != pid) - /* Do nothing. */ ; - - errno = 0; /* mvdir printed the system error message. */ - return status != 0 ? -1 : 0; - } -#else /* no MVDIR */ - error (1, 0, "internal error: cannot move directories"); -#endif /* no MVDIR */ - } - else - { - /* We don't check existence_error because the systems which need it - have rename(). */ - if (link (from, to) == 0 && (CVS_UNLINK (from) == 0 || errno == ENOENT)) - return 0; - } - } - return -1; -} diff --git a/contrib/cvs/lib/savecwd.c b/contrib/cvs/lib/savecwd.c deleted file mode 100644 index 2d687c3..0000000 --- a/contrib/cvs/lib/savecwd.c +++ /dev/null @@ -1,142 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include - -#ifdef STDC_HEADERS -# include -#endif - -#ifdef HAVE_UNISTD_H -# include -#endif - -#ifdef HAVE_FCNTL_H -# include -# include -#else -# include -#endif - -#ifdef HAVE_DIRECT_H -# include -#endif - -#ifdef HAVE_IO_H -# include -#endif - -#include -# ifndef errno -extern int errno; -#endif - -#include "savecwd.h" -#include "error.h" - -char *xgetwd __PROTO((void)); - -/* Record the location of the current working directory in CWD so that - the program may change to other directories and later use restore_cwd - to return to the recorded location. This function may allocate - space using malloc (via xgetwd) or leave a file descriptor open; - use free_cwd to perform the necessary free or close. Upon failure, - no memory is allocated, any locally opened file descriptors are - closed; return non-zero -- in that case, free_cwd need not be - called, but doing so is ok. Otherwise, return zero. */ - -int -save_cwd (cwd) - struct saved_cwd *cwd; -{ - static int have_working_fchdir = 1; - - cwd->desc = -1; - cwd->name = NULL; - - if (have_working_fchdir) - { -#ifdef HAVE_FCHDIR - cwd->desc = open (".", O_RDONLY); - if (cwd->desc < 0) - { - error (0, errno, "cannot open current directory"); - return 1; - } - -# if __sun__ || sun - /* On SunOS 4, fchdir returns EINVAL if accounting is enabled, - so we have to fall back to chdir. */ - if (fchdir (cwd->desc)) - { - if (errno == EINVAL) - { - close (cwd->desc); - cwd->desc = -1; - have_working_fchdir = 0; - } - else - { - error (0, errno, "current directory"); - close (cwd->desc); - cwd->desc = -1; - return 1; - } - } -# endif /* __sun__ || sun */ -#else -#define fchdir(x) (abort (), 0) - have_working_fchdir = 0; -#endif - } - - if (!have_working_fchdir) - { - cwd->name = xgetwd (); - if (cwd->name == NULL) - { - error (0, errno, "cannot get current directory"); - return 1; - } - } - return 0; -} - -/* Change to recorded location, CWD, in directory hierarchy. - If "saved working directory", NULL)) - */ - -int -restore_cwd (cwd, dest) - const struct saved_cwd *cwd; - const char *dest; -{ - int fail = 0; - if (cwd->desc >= 0) - { - if (fchdir (cwd->desc)) - { - error (0, errno, "cannot return to %s", - (dest ? dest : "saved working directory")); - fail = 1; - } - } - else if (chdir (cwd->name) < 0) - { - error (0, errno, "%s", cwd->name); - fail = 1; - } - return fail; -} - -void -free_cwd (cwd) - struct saved_cwd *cwd; -{ - if (cwd->desc >= 0) - close (cwd->desc); - if (cwd->name) - free (cwd->name); -} - diff --git a/contrib/cvs/lib/savecwd.h b/contrib/cvs/lib/savecwd.h deleted file mode 100644 index f9802f8..0000000 --- a/contrib/cvs/lib/savecwd.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef SAVE_CWD_H -#define SAVE_CWD_H 1 - -struct saved_cwd - { - int desc; - char *name; - }; - -#if defined (__GNUC__) || (defined (__STDC__) && __STDC__) -#define __PROTO(args) args -#else -#define __PROTO(args) () -#endif /* GCC. */ - -int save_cwd __PROTO((struct saved_cwd *cwd)); -int restore_cwd __PROTO((const struct saved_cwd *cwd, const char *dest)); -void free_cwd __PROTO((struct saved_cwd *cwd)); - -#endif /* SAVE_CWD_H */ diff --git a/contrib/cvs/lib/sighandle.c b/contrib/cvs/lib/sighandle.c deleted file mode 100644 index 2d21df8..0000000 --- a/contrib/cvs/lib/sighandle.c +++ /dev/null @@ -1,418 +0,0 @@ -/* sighandle.c -- Library routines for manipulating chains of signal handlers - Copyright (C) 1992 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. */ - -/* Written by Paul Sander, HaL Computer Systems, Inc. - Brian Berliner added POSIX support */ - -/************************************************************************* - * - * signal.c -- This file contains code that manipulates chains of signal - * handlers. - * - * Facilities are provided to register a signal handler for - * any specific signal. When a signal is received, all of the - * registered signal handlers are invoked in the reverse order - * in which they are registered. Note that the signal handlers - * must not themselves make calls to the signal handling - * facilities. - * - *************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif -#include "system.h" - -#include -#include -#include - -/* Add prototype support. */ -#ifndef PROTO -#if defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__) -#define PROTO(ARGS) ARGS -#else -#define PROTO(ARGS) () -#endif -#endif - -#ifdef STDC_HEADERS -#include -#else -#if __STDC__ -char *calloc(unsigned nelem, unsigned size); -char *malloc(unsigned size); -#else -char *calloc(); -char *malloc(); -#endif /* __STDC__ */ -#endif /* STDC_HEADERS */ - -/* Define the highest signal number (usually) */ -#ifndef SIGMAX -#define SIGMAX 64 -#endif - -/* Define linked list of signal handlers structure */ -struct SIG_hlist { - RETSIGTYPE (*handler)(); - struct SIG_hlist *next; -}; - -/* - * Define array of lists of signal handlers. Note that this depends on - * the implementation to initialize each element to a null pointer. - */ - -static struct SIG_hlist **SIG_handlers; - -/* Define array of default signal vectors */ - -#ifdef POSIX_SIGNALS -static struct sigaction *SIG_defaults; -#else -#ifdef BSD_SIGNALS -static struct sigvec *SIG_defaults; -#else -static RETSIGTYPE (**SIG_defaults) PROTO ((int)); -#endif -#endif - -/* Critical section housekeeping */ -static int SIG_crSectNest = 0; /* Nesting level */ -#ifdef POSIX_SIGNALS -static sigset_t SIG_crSectMask; /* Signal mask */ -#else -static int SIG_crSectMask; /* Signal mask */ -#endif - -/* - * Initialize the signal handler arrays - */ - -static int SIG_init() -{ - int i; -#ifdef POSIX_SIGNALS - sigset_t sigset_test; -#endif - - if (SIG_defaults && SIG_handlers) /* already allocated */ - return (0); - -#ifdef POSIX_SIGNALS - (void) sigfillset(&sigset_test); - for (i = 1; i < SIGMAX && sigismember(&sigset_test, i) == 1; i++) - ; - if (i < SIGMAX) - i = SIGMAX; - i++; - if (!SIG_defaults) - SIG_defaults = (struct sigaction *) - calloc(i, sizeof(struct sigaction)); - (void) sigemptyset(&SIG_crSectMask); -#else - i = SIGMAX+1; -#ifdef BSD_SIGNALS - if (!SIG_defaults) - SIG_defaults = (struct sigvec *) - calloc(i, sizeof(struct sigvec)); -#else - if (!SIG_defaults) - SIG_defaults = (RETSIGTYPE (**) PROTO ((int)) ) - calloc(i, sizeof(RETSIGTYPE (**) PROTO ((int)) )); -#endif - SIG_crSectMask = 0; -#endif - if (!SIG_handlers) - SIG_handlers = (struct SIG_hlist **) - calloc(i, sizeof(struct SIG_hlist *)); - return (!SIG_defaults || !SIG_handlers); -} - -/* - * The following invokes each signal handler in the reverse order in which - * they were registered. - */ -static RETSIGTYPE SIG_handle PROTO ((int)); - -static RETSIGTYPE SIG_handle(sig) -int sig; -{ - struct SIG_hlist *this; - - /* Dispatch signal handlers */ - this = SIG_handlers[sig]; - while (this != (struct SIG_hlist *) NULL) - { - (*this->handler)(sig); - this = this->next; - } - - return; -} - -/* - * The following registers a signal handler. If the handler is already - * registered, it is not registered twice, nor is the order in which signal - * handlers are invoked changed. If this is the first signal handler - * registered for a given signal, the old sigvec structure is saved for - * restoration later. - */ - -int SIG_register(sig,fn) -int sig; -RETSIGTYPE (*fn)(); -{ - int val; - struct SIG_hlist *this; -#ifdef POSIX_SIGNALS - struct sigaction act; - sigset_t sigset_mask, sigset_omask; -#else -#ifdef BSD_SIGNALS - struct sigvec vec; - int mask; -#endif -#endif - - /* Initialize */ - if (SIG_init() != 0) - return (-1); - val = 0; - - /* Block this signal while we look at handler chain */ -#ifdef POSIX_SIGNALS - (void) sigemptyset(&sigset_mask); - (void) sigaddset(&sigset_mask, sig); - (void) sigprocmask(SIG_BLOCK, &sigset_mask, &sigset_omask); -#else -#ifdef BSD_SIGNALS - mask = sigblock(sigmask(sig)); -#endif -#endif - - /* See if this handler was already registered */ - this = SIG_handlers[sig]; - while (this != (struct SIG_hlist *) NULL) - { - if (this->handler == fn) break; - this = this->next; - } - - /* Register the new handler only if it is not already registered. */ - if (this == (struct SIG_hlist *) NULL) - { - - /* - * If this is the first handler registered for this signal, - * set up the signal handler dispatcher - */ - - if (SIG_handlers[sig] == (struct SIG_hlist *) NULL) - { -#ifdef POSIX_SIGNALS - act.sa_handler = SIG_handle; - (void) sigemptyset(&act.sa_mask); - act.sa_flags = 0; - val = sigaction(sig, &act, &SIG_defaults[sig]); -#else -#ifdef BSD_SIGNALS - memset (&vec, 0, sizeof (vec)); - vec.sv_handler = SIG_handle; - val = sigvec(sig, &vec, &SIG_defaults[sig]); -#else - if ((SIG_defaults[sig] = signal(sig, SIG_handle)) == SIG_ERR) - val = -1; -#endif -#endif - } - - /* If not, register it */ - if ((val == 0) && (this == (struct SIG_hlist *) NULL)) - { - this = (struct SIG_hlist *) - malloc(sizeof(struct SIG_hlist)); - if (this == NULL) - { - val = -1; - } - else - { - this->handler = fn; - this->next = SIG_handlers[sig]; - SIG_handlers[sig] = this; - } - } - } - - /* Unblock the signal */ -#ifdef POSIX_SIGNALS - (void) sigprocmask(SIG_SETMASK, &sigset_omask, NULL); -#else -#ifdef BSD_SIGNALS - (void) sigsetmask(mask); -#endif -#endif - - return val; -} - -/* - * The following deregisters a signal handler. If the last signal handler for - * a given signal is deregistered, the default sigvec information is restored. - */ - -int SIG_deregister(sig,fn) -int sig; -RETSIGTYPE (*fn)(); -{ - int val; - struct SIG_hlist *this; - struct SIG_hlist *last; -#ifdef POSIX_SIGNALS - sigset_t sigset_mask, sigset_omask; -#else -#ifdef BSD_SIGNALS - int mask; -#endif -#endif - - /* Initialize */ - if (SIG_init() != 0) - return (-1); - val = 0; - last = (struct SIG_hlist *) NULL; - - /* Block this signal while we look at handler chain */ -#ifdef POSIX_SIGNALS - (void) sigemptyset(&sigset_mask); - (void) sigaddset(&sigset_mask, sig); - (void) sigprocmask(SIG_BLOCK, &sigset_mask, &sigset_omask); -#else -#ifdef BSD_SIGNALS - mask = sigblock(sigmask(sig)); -#endif -#endif - - /* Search for the signal handler */ - this = SIG_handlers[sig]; - while ((this != (struct SIG_hlist *) NULL) && (this->handler != fn)) - { - last = this; - this = this->next; - } - - /* If it was registered, remove it */ - if (this != (struct SIG_hlist *) NULL) - { - if (last == (struct SIG_hlist *) NULL) - { - SIG_handlers[sig] = this->next; - } - else - { - last->next = this->next; - } - free((char *) this); - } - - /* Restore default behavior if there are no registered handlers */ - if (SIG_handlers[sig] == (struct SIG_hlist *) NULL) - { -#ifdef POSIX_SIGNALS - val = sigaction(sig, &SIG_defaults[sig], - (struct sigaction *) NULL); -#else -#ifdef BSD_SIGNALS - val = sigvec(sig, &SIG_defaults[sig], (struct sigvec *) NULL); -#else - if (signal(sig, SIG_defaults[sig]) == SIG_ERR) - val = -1; -#endif -#endif - } - - /* Unblock the signal */ -#ifdef POSIX_SIGNALS - (void) sigprocmask(SIG_SETMASK, &sigset_omask, NULL); -#else -#ifdef BSD_SIGNALS - (void) sigsetmask(mask); -#endif -#endif - - return val; -} - -/* - * The following begins a critical section. - */ - -void SIG_beginCrSect() -{ - if (SIG_init() == 0) - { - if (SIG_crSectNest == 0) - { -#ifdef POSIX_SIGNALS - sigset_t sigset_mask; - - (void) sigfillset(&sigset_mask); - (void) sigprocmask(SIG_SETMASK, - &sigset_mask, &SIG_crSectMask); -#else -#ifdef BSD_SIGNALS - SIG_crSectMask = sigblock(~0); -#else - /* TBD */ -#endif -#endif - } - SIG_crSectNest++; - } -} - -/* - * Return nonzero if currently in a critical section. - * Otherwise return zero. - */ - -int SIG_inCrSect() -{ - return SIG_crSectNest > 0; -} - -/* - * The following ends a critical section. - */ - -void SIG_endCrSect() -{ - if (SIG_init() == 0) - { - SIG_crSectNest--; - if (SIG_crSectNest == 0) - { -#ifdef POSIX_SIGNALS - (void) sigprocmask(SIG_SETMASK, &SIG_crSectMask, NULL); -#else -#ifdef BSD_SIGNALS - (void) sigsetmask(SIG_crSectMask); -#else - /* TBD */ -#endif -#endif - } - } -} diff --git a/contrib/cvs/lib/strerror.c b/contrib/cvs/lib/strerror.c deleted file mode 100644 index 2da413f..0000000 --- a/contrib/cvs/lib/strerror.c +++ /dev/null @@ -1,810 +0,0 @@ -/* Extended support for using errno values. - Copyright (C) 1992 Free Software Foundation, Inc. - Written by Fred Fish. fnf@cygnus.com - -This file is part of the libiberty library. -Libiberty is free software; you can redistribute it and/or -modify it under the terms of the GNU Library General Public -License as published by the Free Software Foundation; either -version 2 of the License, or (at your option) any later version. - -Libiberty is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Library General Public License for more details. */ - -#ifdef HAVE_CONFIG_H -# include -#endif /* HAVE_CONFIG_H */ - -#ifndef NEED_sys_errlist -/* Note that errno.h (not sure what OS) or stdio.h (BSD 4.4, at least) - might declare sys_errlist in a way that the compiler might consider - incompatible with our later declaration, perhaps by using const - attributes. So we hide the declaration in errno.h (if any) using a - macro. */ -#define sys_errlist sys_errlist__ -#endif - -#include -#include - -#ifndef NEED_sys_errlist -#undef sys_errlist -#endif - -/* Routines imported from standard C runtime libraries. */ - -#ifdef __STDC__ -#include -extern void *malloc (size_t size); /* 4.10.3.3 */ -extern void *memset (void *s, int c, size_t n); /* 4.11.6.1 */ -#else /* !__STDC__ */ -extern char *malloc (); /* Standard memory allocater */ -extern char *memset (); -#endif /* __STDC__ */ - -#ifndef MAX -# define MAX(a,b) ((a) > (b) ? (a) : (b)) -#endif - -/* Translation table for errno values. See intro(2) in most UNIX systems - Programmers Reference Manuals. - - Note that this table is generally only accessed when it is used at runtime - to initialize errno name and message tables that are indexed by errno - value. - - Not all of these errnos will exist on all systems. This table is the only - thing that should have to be updated as new error numbers are introduced. - It's sort of ugly, but at least its portable. */ - -struct error_info -{ - int value; /* The numeric value from */ - char *name; /* The equivalent symbolic value */ -#ifdef NEED_sys_errlist - char *msg; /* Short message about this value */ -#endif -}; - -#ifdef NEED_sys_errlist -# define ENTRY(value, name, msg) {value, name, msg} -#else -# define ENTRY(value, name, msg) {value, name} -#endif - -static const struct error_info error_table[] = -{ -#if defined (EPERM) - ENTRY(EPERM, "EPERM", "Not owner"), -#endif -#if defined (ENOENT) - ENTRY(ENOENT, "ENOENT", "No such file or directory"), -#endif -#if defined (ESRCH) - ENTRY(ESRCH, "ESRCH", "No such process"), -#endif -#if defined (EINTR) - ENTRY(EINTR, "EINTR", "Interrupted system call"), -#endif -#if defined (EIO) - ENTRY(EIO, "EIO", "I/O error"), -#endif -#if defined (ENXIO) - ENTRY(ENXIO, "ENXIO", "No such device or address"), -#endif -#if defined (E2BIG) - ENTRY(E2BIG, "E2BIG", "Arg list too long"), -#endif -#if defined (ENOEXEC) - ENTRY(ENOEXEC, "ENOEXEC", "Exec format error"), -#endif -#if defined (EBADF) - ENTRY(EBADF, "EBADF", "Bad file number"), -#endif -#if defined (ECHILD) - ENTRY(ECHILD, "ECHILD", "No child processes"), -#endif -#if defined (EWOULDBLOCK) /* Put before EAGAIN, sometimes aliased */ - ENTRY(EWOULDBLOCK, "EWOULDBLOCK", "Operation would block"), -#endif -#if defined (EAGAIN) - ENTRY(EAGAIN, "EAGAIN", "No more processes"), -#endif -#if defined (ENOMEM) - ENTRY(ENOMEM, "ENOMEM", "Not enough space"), -#endif -#if defined (EACCES) - ENTRY(EACCES, "EACCES", "Permission denied"), -#endif -#if defined (EFAULT) - ENTRY(EFAULT, "EFAULT", "Bad address"), -#endif -#if defined (ENOTBLK) - ENTRY(ENOTBLK, "ENOTBLK", "Block device required"), -#endif -#if defined (EBUSY) - ENTRY(EBUSY, "EBUSY", "Device busy"), -#endif -#if defined (EEXIST) - ENTRY(EEXIST, "EEXIST", "File exists"), -#endif -#if defined (EXDEV) - ENTRY(EXDEV, "EXDEV", "Cross-device link"), -#endif -#if defined (ENODEV) - ENTRY(ENODEV, "ENODEV", "No such device"), -#endif -#if defined (ENOTDIR) - ENTRY(ENOTDIR, "ENOTDIR", "Not a directory"), -#endif -#if defined (EISDIR) - ENTRY(EISDIR, "EISDIR", "Is a directory"), -#endif -#if defined (EINVAL) - ENTRY(EINVAL, "EINVAL", "Invalid argument"), -#endif -#if defined (ENFILE) - ENTRY(ENFILE, "ENFILE", "File table overflow"), -#endif -#if defined (EMFILE) - ENTRY(EMFILE, "EMFILE", "Too many open files"), -#endif -#if defined (ENOTTY) - ENTRY(ENOTTY, "ENOTTY", "Not a typewriter"), -#endif -#if defined (ETXTBSY) - ENTRY(ETXTBSY, "ETXTBSY", "Text file busy"), -#endif -#if defined (EFBIG) - ENTRY(EFBIG, "EFBIG", "File too large"), -#endif -#if defined (ENOSPC) - ENTRY(ENOSPC, "ENOSPC", "No space left on device"), -#endif -#if defined (ESPIPE) - ENTRY(ESPIPE, "ESPIPE", "Illegal seek"), -#endif -#if defined (EROFS) - ENTRY(EROFS, "EROFS", "Read-only file system"), -#endif -#if defined (EMLINK) - ENTRY(EMLINK, "EMLINK", "Too many links"), -#endif -#if defined (EPIPE) - ENTRY(EPIPE, "EPIPE", "Broken pipe"), -#endif -#if defined (EDOM) - ENTRY(EDOM, "EDOM", "Math argument out of domain of func"), -#endif -#if defined (ERANGE) - ENTRY(ERANGE, "ERANGE", "Math result not representable"), -#endif -#if defined (ENOMSG) - ENTRY(ENOMSG, "ENOMSG", "No message of desired type"), -#endif -#if defined (EIDRM) - ENTRY(EIDRM, "EIDRM", "Identifier removed"), -#endif -#if defined (ECHRNG) - ENTRY(ECHRNG, "ECHRNG", "Channel number out of range"), -#endif -#if defined (EL2NSYNC) - ENTRY(EL2NSYNC, "EL2NSYNC", "Level 2 not synchronized"), -#endif -#if defined (EL3HLT) - ENTRY(EL3HLT, "EL3HLT", "Level 3 halted"), -#endif -#if defined (EL3RST) - ENTRY(EL3RST, "EL3RST", "Level 3 reset"), -#endif -#if defined (ELNRNG) - ENTRY(ELNRNG, "ELNRNG", "Link number out of range"), -#endif -#if defined (EUNATCH) - ENTRY(EUNATCH, "EUNATCH", "Protocol driver not attached"), -#endif -#if defined (ENOCSI) - ENTRY(ENOCSI, "ENOCSI", "No CSI structure available"), -#endif -#if defined (EL2HLT) - ENTRY(EL2HLT, "EL2HLT", "Level 2 halted"), -#endif -#if defined (EDEADLK) - ENTRY(EDEADLK, "EDEADLK", "Deadlock condition"), -#endif -#if defined (ENOLCK) - ENTRY(ENOLCK, "ENOLCK", "No record locks available"), -#endif -#if defined (EBADE) - ENTRY(EBADE, "EBADE", "Invalid exchange"), -#endif -#if defined (EBADR) - ENTRY(EBADR, "EBADR", "Invalid request descriptor"), -#endif -#if defined (EXFULL) - ENTRY(EXFULL, "EXFULL", "Exchange full"), -#endif -#if defined (ENOANO) - ENTRY(ENOANO, "ENOANO", "No anode"), -#endif -#if defined (EBADRQC) - ENTRY(EBADRQC, "EBADRQC", "Invalid request code"), -#endif -#if defined (EBADSLT) - ENTRY(EBADSLT, "EBADSLT", "Invalid slot"), -#endif -#if defined (EDEADLOCK) - ENTRY(EDEADLOCK, "EDEADLOCK", "File locking deadlock error"), -#endif -#if defined (EBFONT) - ENTRY(EBFONT, "EBFONT", "Bad font file format"), -#endif -#if defined (ENOSTR) - ENTRY(ENOSTR, "ENOSTR", "Device not a stream"), -#endif -#if defined (ENODATA) - ENTRY(ENODATA, "ENODATA", "No data available"), -#endif -#if defined (ETIME) - ENTRY(ETIME, "ETIME", "Timer expired"), -#endif -#if defined (ENOSR) - ENTRY(ENOSR, "ENOSR", "Out of streams resources"), -#endif -#if defined (ENONET) - ENTRY(ENONET, "ENONET", "Machine is not on the network"), -#endif -#if defined (ENOPKG) - ENTRY(ENOPKG, "ENOPKG", "Package not installed"), -#endif -#if defined (EREMOTE) - ENTRY(EREMOTE, "EREMOTE", "Object is remote"), -#endif -#if defined (ENOLINK) - ENTRY(ENOLINK, "ENOLINK", "Link has been severed"), -#endif -#if defined (EADV) - ENTRY(EADV, "EADV", "Advertise error"), -#endif -#if defined (ESRMNT) - ENTRY(ESRMNT, "ESRMNT", "Srmount error"), -#endif -#if defined (ECOMM) - ENTRY(ECOMM, "ECOMM", "Communication error on send"), -#endif -#if defined (EPROTO) - ENTRY(EPROTO, "EPROTO", "Protocol error"), -#endif -#if defined (EMULTIHOP) - ENTRY(EMULTIHOP, "EMULTIHOP", "Multihop attempted"), -#endif -#if defined (EDOTDOT) - ENTRY(EDOTDOT, "EDOTDOT", "RFS specific error"), -#endif -#if defined (EBADMSG) - ENTRY(EBADMSG, "EBADMSG", "Not a data message"), -#endif -#if defined (ENAMETOOLONG) - ENTRY(ENAMETOOLONG, "ENAMETOOLONG", "File name too long"), -#endif -#if defined (EOVERFLOW) - ENTRY(EOVERFLOW, "EOVERFLOW", "Value too large for defined data type"), -#endif -#if defined (ENOTUNIQ) - ENTRY(ENOTUNIQ, "ENOTUNIQ", "Name not unique on network"), -#endif -#if defined (EBADFD) - ENTRY(EBADFD, "EBADFD", "File descriptor in bad state"), -#endif -#if defined (EREMCHG) - ENTRY(EREMCHG, "EREMCHG", "Remote address changed"), -#endif -#if defined (ELIBACC) - ENTRY(ELIBACC, "ELIBACC", "Can not access a needed shared library"), -#endif -#if defined (ELIBBAD) - ENTRY(ELIBBAD, "ELIBBAD", "Accessing a corrupted shared library"), -#endif -#if defined (ELIBSCN) - ENTRY(ELIBSCN, "ELIBSCN", ".lib section in a.out corrupted"), -#endif -#if defined (ELIBMAX) - ENTRY(ELIBMAX, "ELIBMAX", "Attempting to link in too many shared libraries"), -#endif -#if defined (ELIBEXEC) - ENTRY(ELIBEXEC, "ELIBEXEC", "Cannot exec a shared library directly"), -#endif -#if defined (EILSEQ) - ENTRY(EILSEQ, "EILSEQ", "Illegal byte sequence"), -#endif -#if defined (ENOSYS) - ENTRY(ENOSYS, "ENOSYS", "Operation not applicable"), -#endif -#if defined (ELOOP) - ENTRY(ELOOP, "ELOOP", "Too many symbolic links encountered"), -#endif -#if defined (ERESTART) - ENTRY(ERESTART, "ERESTART", "Interrupted system call should be restarted"), -#endif -#if defined (ESTRPIPE) - ENTRY(ESTRPIPE, "ESTRPIPE", "Streams pipe error"), -#endif -#if defined (ENOTEMPTY) - ENTRY(ENOTEMPTY, "ENOTEMPTY", "Directory not empty"), -#endif -#if defined (EUSERS) - ENTRY(EUSERS, "EUSERS", "Too many users"), -#endif -#if defined (ENOTSOCK) - ENTRY(ENOTSOCK, "ENOTSOCK", "Socket operation on non-socket"), -#endif -#if defined (EDESTADDRREQ) - ENTRY(EDESTADDRREQ, "EDESTADDRREQ", "Destination address required"), -#endif -#if defined (EMSGSIZE) - ENTRY(EMSGSIZE, "EMSGSIZE", "Message too long"), -#endif -#if defined (EPROTOTYPE) - ENTRY(EPROTOTYPE, "EPROTOTYPE", "Protocol wrong type for socket"), -#endif -#if defined (ENOPROTOOPT) - ENTRY(ENOPROTOOPT, "ENOPROTOOPT", "Protocol not available"), -#endif -#if defined (EPROTONOSUPPORT) - ENTRY(EPROTONOSUPPORT, "EPROTONOSUPPORT", "Protocol not supported"), -#endif -#if defined (ESOCKTNOSUPPORT) - ENTRY(ESOCKTNOSUPPORT, "ESOCKTNOSUPPORT", "Socket type not supported"), -#endif -#if defined (EOPNOTSUPP) - ENTRY(EOPNOTSUPP, "EOPNOTSUPP", "Operation not supported on transport endpoint"), -#endif -#if defined (EPFNOSUPPORT) - ENTRY(EPFNOSUPPORT, "EPFNOSUPPORT", "Protocol family not supported"), -#endif -#if defined (EAFNOSUPPORT) - ENTRY(EAFNOSUPPORT, "EAFNOSUPPORT", "Address family not supported by protocol"), -#endif -#if defined (EADDRINUSE) - ENTRY(EADDRINUSE, "EADDRINUSE", "Address already in use"), -#endif -#if defined (EADDRNOTAVAIL) - ENTRY(EADDRNOTAVAIL, "EADDRNOTAVAIL","Cannot assign requested address"), -#endif -#if defined (ENETDOWN) - ENTRY(ENETDOWN, "ENETDOWN", "Network is down"), -#endif -#if defined (ENETUNREACH) - ENTRY(ENETUNREACH, "ENETUNREACH", "Network is unreachable"), -#endif -#if defined (ENETRESET) - ENTRY(ENETRESET, "ENETRESET", "Network dropped connection because of reset"), -#endif -#if defined (ECONNABORTED) - ENTRY(ECONNABORTED, "ECONNABORTED", "Software caused connection abort"), -#endif -#if defined (ECONNRESET) - ENTRY(ECONNRESET, "ECONNRESET", "Connection reset by peer"), -#endif -#if defined (ENOBUFS) - ENTRY(ENOBUFS, "ENOBUFS", "No buffer space available"), -#endif -#if defined (EISCONN) - ENTRY(EISCONN, "EISCONN", "Transport endpoint is already connected"), -#endif -#if defined (ENOTCONN) - ENTRY(ENOTCONN, "ENOTCONN", "Transport endpoint is not connected"), -#endif -#if defined (ESHUTDOWN) - ENTRY(ESHUTDOWN, "ESHUTDOWN", "Cannot send after transport endpoint shutdown"), -#endif -#if defined (ETOOMANYREFS) - ENTRY(ETOOMANYREFS, "ETOOMANYREFS", "Too many references: cannot splice"), -#endif -#if defined (ETIMEDOUT) - ENTRY(ETIMEDOUT, "ETIMEDOUT", "Connection timed out"), -#endif -#if defined (ECONNREFUSED) - ENTRY(ECONNREFUSED, "ECONNREFUSED", "Connection refused"), -#endif -#if defined (EHOSTDOWN) - ENTRY(EHOSTDOWN, "EHOSTDOWN", "Host is down"), -#endif -#if defined (EHOSTUNREACH) - ENTRY(EHOSTUNREACH, "EHOSTUNREACH", "No route to host"), -#endif -#if defined (EALREADY) - ENTRY(EALREADY, "EALREADY", "Operation already in progress"), -#endif -#if defined (EINPROGRESS) - ENTRY(EINPROGRESS, "EINPROGRESS", "Operation now in progress"), -#endif -#if defined (ESTALE) - ENTRY(ESTALE, "ESTALE", "Stale NFS file handle"), -#endif -#if defined (EUCLEAN) - ENTRY(EUCLEAN, "EUCLEAN", "Structure needs cleaning"), -#endif -#if defined (ENOTNAM) - ENTRY(ENOTNAM, "ENOTNAM", "Not a XENIX named type file"), -#endif -#if defined (ENAVAIL) - ENTRY(ENAVAIL, "ENAVAIL", "No XENIX semaphores available"), -#endif -#if defined (EISNAM) - ENTRY(EISNAM, "EISNAM", "Is a named type file"), -#endif -#if defined (EREMOTEIO) - ENTRY(EREMOTEIO, "EREMOTEIO", "Remote I/O error"), -#endif - ENTRY(0, NULL, NULL) -}; - -/* Translation table allocated and initialized at runtime. Indexed by the - errno value to find the equivalent symbolic value. */ - -static char **error_names; -static int num_error_names = 0; - -/* Translation table allocated and initialized at runtime, if it does not - already exist in the host environment. Indexed by the errno value to find - the descriptive string. - - We don't export it for use in other modules because even though it has the - same name, it differs from other implementations in that it is dynamically - initialized rather than statically initialized. */ - -#ifdef NEED_sys_errlist - -static int sys_nerr; -static char **sys_errlist; - -#else - -extern int sys_nerr; -extern char *sys_errlist[]; - -#endif - - -/* - -NAME - - init_error_tables -- initialize the name and message tables - -SYNOPSIS - - static void init_error_tables (); - -DESCRIPTION - - Using the error_table, which is initialized at compile time, generate - the error_names and the sys_errlist (if needed) tables, which are - indexed at runtime by a specific errno value. - -BUGS - - The initialization of the tables may fail under low memory conditions, - in which case we don't do anything particularly useful, but we don't - bomb either. Who knows, it might succeed at a later point if we free - some memory in the meantime. In any case, the other routines know - how to deal with lack of a table after trying to initialize it. This - may or may not be considered to be a bug, that we don't specifically - warn about this particular failure mode. - -*/ - -static void -init_error_tables () -{ - const struct error_info *eip; - int nbytes; - - /* If we haven't already scanned the error_table once to find the maximum - errno value, then go find it now. */ - - if (num_error_names == 0) - { - for (eip = error_table; eip -> name != NULL; eip++) - { - if (eip -> value >= num_error_names) - { - num_error_names = eip -> value + 1; - } - } - } - - /* Now attempt to allocate the error_names table, zero it out, and then - initialize it from the statically initialized error_table. */ - - if (error_names == NULL) - { - nbytes = num_error_names * sizeof (char *); - if ((error_names = (char **) malloc (nbytes)) != NULL) - { - memset (error_names, 0, nbytes); - for (eip = error_table; eip -> name != NULL; eip++) - { - error_names[eip -> value] = eip -> name; - } - } - } - -#ifdef NEED_sys_errlist - - /* Now attempt to allocate the sys_errlist table, zero it out, and then - initialize it from the statically initialized error_table. */ - - if (sys_errlist == NULL) - { - nbytes = num_error_names * sizeof (char *); - if ((sys_errlist = (char **) malloc (nbytes)) != NULL) - { - memset (sys_errlist, 0, nbytes); - sys_nerr = num_error_names; - for (eip = error_table; eip -> name != NULL; eip++) - { - sys_errlist[eip -> value] = eip -> msg; - } - } - } - -#endif - -} - -/* - -NAME - - errno_max -- return the max errno value - -SYNOPSIS - - int errno_max (); - -DESCRIPTION - - Returns the maximum errno value for which a corresponding symbolic - name or message is available. Note that in the case where - we use the sys_errlist supplied by the system, it is possible for - there to be more symbolic names than messages, or vice versa. - In fact, the manual page for perror(3C) explicitly warns that one - should check the size of the table (sys_nerr) before indexing it, - since new error codes may be added to the system before they are - added to the table. Thus sys_nerr might be smaller than value - implied by the largest errno value defined in . - - We return the maximum value that can be used to obtain a meaningful - symbolic name or message. - -*/ - -int -errno_max () -{ - int maxsize; - - if (error_names == NULL) - { - init_error_tables (); - } - maxsize = MAX (sys_nerr, num_error_names); - return (maxsize - 1); -} - -/* - -NAME - - strerror -- map an error number to an error message string - -SYNOPSIS - - char *strerror (int errnoval) - -DESCRIPTION - - Maps an errno number to an error message string, the contents of - which are implementation defined. On systems which have the external - variables sys_nerr and sys_errlist, these strings will be the same - as the ones used by perror(). - - If the supplied error number is within the valid range of indices - for the sys_errlist, but no message is available for the particular - error number, then returns the string "Error NUM", where NUM is the - error number. - - If the supplied error number is not a valid index into sys_errlist, - returns NULL. - - The returned string is only guaranteed to be valid only until the - next call to strerror. - -*/ - -char * -strerror (errnoval) - int errnoval; -{ - char *msg; - static char buf[32]; - -#ifdef NEED_sys_errlist - - if (error_names == NULL) - { - init_error_tables (); - } - -#endif - - if ((errnoval < 0) || (errnoval >= sys_nerr)) - { - /* Out of range, just return NULL */ - msg = NULL; - } - else if ((sys_errlist == NULL) || (sys_errlist[errnoval] == NULL)) - { - /* In range, but no sys_errlist or no entry at this index. */ - sprintf (buf, "Error %d", errnoval); - msg = buf; - } - else - { - /* In range, and a valid message. Just return the message. */ - msg = sys_errlist[errnoval]; - } - - return (msg); -} - - - -/* - -NAME - - strerrno -- map an error number to a symbolic name string - -SYNOPSIS - - char *strerrno (int errnoval) - -DESCRIPTION - - Given an error number returned from a system call (typically - returned in errno), returns a pointer to a string containing the - symbolic name of that error number, as found in . - - If the supplied error number is within the valid range of indices - for symbolic names, but no name is available for the particular - error number, then returns the string "Error NUM", where NUM is - the error number. - - If the supplied error number is not within the range of valid - indices, then returns NULL. - -BUGS - - The contents of the location pointed to are only guaranteed to be - valid until the next call to strerrno. - -*/ - -char * -strerrno (errnoval) - int errnoval; -{ - char *name; - static char buf[32]; - - if (error_names == NULL) - { - init_error_tables (); - } - - if ((errnoval < 0) || (errnoval >= num_error_names)) - { - /* Out of range, just return NULL */ - name = NULL; - } - else if ((error_names == NULL) || (error_names[errnoval] == NULL)) - { - /* In range, but no error_names or no entry at this index. */ - sprintf (buf, "Error %d", errnoval); - name = buf; - } - else - { - /* In range, and a valid name. Just return the name. */ - name = error_names[errnoval]; - } - - return (name); -} - -/* - -NAME - - strtoerrno -- map a symbolic errno name to a numeric value - -SYNOPSIS - - int strtoerrno (char *name) - -DESCRIPTION - - Given the symbolic name of a error number, map it to an errno value. - If no translation is found, returns 0. - -*/ - -int -strtoerrno (name) - char *name; -{ - int errnoval = 0; - - if (name != NULL) - { - if (error_names == NULL) - { - init_error_tables (); - } - for (errnoval = 0; errnoval < num_error_names; errnoval++) - { - if ((error_names[errnoval] != NULL) && - (strcmp (name, error_names[errnoval]) == 0)) - { - break; - } - } - if (errnoval == num_error_names) - { - errnoval = 0; - } - } - return (errnoval); -} - - -/* A simple little main that does nothing but print all the errno translations - if MAIN is defined and this file is compiled and linked. */ - -#ifdef MAIN - -main () -{ - int errn; - int errnmax; - char *name; - char *msg; - char *strerrno (); - char *strerror (); - - errnmax = errno_max (); - printf ("%d entries in names table.\n", num_error_names); - printf ("%d entries in messages table.\n", sys_nerr); - printf ("%d is max useful index.\n", errnmax); - - /* Keep printing values until we get to the end of *both* tables, not - *either* table. Note that knowing the maximum useful index does *not* - relieve us of the responsibility of testing the return pointer for - NULL. */ - - for (errn = 0; errn <= errnmax; errn++) - { - name = strerrno (errn); - name = (name == NULL) ? "" : name; - msg = strerror (errn); - msg = (msg == NULL) ? "" : msg; - printf ("%-4d%-18s%s\n", errn, name, msg); - } -} - -#endif diff --git a/contrib/cvs/lib/stripslash.c b/contrib/cvs/lib/stripslash.c deleted file mode 100644 index ece8ec8..0000000 --- a/contrib/cvs/lib/stripslash.c +++ /dev/null @@ -1,40 +0,0 @@ -/* stripslash.c -- remove trailing slashes from a string - Copyright (C) 1990 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#if STDC_HEADERS || HAVE_STRING_H -#include -/* An ANSI string.h and pre-ANSI memory.h might conflict. */ -#if !STDC_HEADERS && HAVE_MEMORY_H -#include -#endif /* not STDC_HEADERS and HAVE_MEMORY_H */ -#else /* not STDC_HJEADERS and not HAVE_STRING_H */ -#include -/* memory.h and strings.h conflict on some systems. */ -#endif /* not STDC_HEADERS and not HAVE_STRING_H */ - -/* Remove trailing slashes from PATH. */ - -void -strip_trailing_slashes (path) - char *path; -{ - int last; - - last = strlen (path) - 1; - while (last > 0 && path[last] == '/') - path[last--] = '\0'; -} diff --git a/contrib/cvs/lib/strstr.c b/contrib/cvs/lib/strstr.c deleted file mode 100644 index e43bca0..0000000 --- a/contrib/cvs/lib/strstr.c +++ /dev/null @@ -1,40 +0,0 @@ -/****************************************************************************** -* * -* s t r s t r * -* * -* Find the first occurrence of a string in another string. * -* * -* Format: * -* return = strstr(Source,What); * -* * -* Parameters: * -* * -* Returns: * -* * -* Scope: PUBLIC * -* * -******************************************************************************/ - -char *strstr(Source, What) -register const char *Source; -register const char *What; -{ -register char WhatChar; -register char SourceChar; -register long Length; - - - if ((WhatChar = *What++) != 0) { - Length = strlen(What); - do { - do { - if ((SourceChar = *Source++) == 0) { - return (0); - } - } while (SourceChar != WhatChar); - } while (strncmp(Source, What, Length) != 0); - Source--; - } - return ((char *)Source); - -}/*strstr*/ diff --git a/contrib/cvs/lib/strtoul.c b/contrib/cvs/lib/strtoul.c deleted file mode 100644 index 7d42c21..0000000 --- a/contrib/cvs/lib/strtoul.c +++ /dev/null @@ -1,100 +0,0 @@ -/* - * strtol : convert a string to long. - * - * Andy Wilson, 2-Oct-89. - */ - -#include -#include -#include - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#ifndef ULONG_MAX -#define ULONG_MAX ((unsigned long)(~0L)) /* 0xFFFFFFFF */ -#endif - -extern int errno; - -unsigned long -strtoul(s, ptr, base) - const char *s; char **ptr; int base; -{ - unsigned long total = 0; - unsigned digit; - const char *start=s; - int did_conversion=0; - int overflow = 0; - int negate = 0; - unsigned long maxdiv, maxrem; - - if (s==NULL) - { - errno = ERANGE; - if (!ptr) - *ptr = (char *)start; - return 0L; - } - - while (isspace(*s)) - s++; - if (*s == '+') - s++; - else if (*s == '-') - s++, negate = 1; - if (base==0 || base==16) /* the 'base==16' is for handling 0x */ - { - int tmp; - - /* - * try to infer base from the string - */ - if (*s != '0') - tmp = 10; /* doesn't start with 0 - assume decimal */ - else if (s[1] == 'X' || s[1] == 'x') - tmp = 16, s += 2; /* starts with 0x or 0X - hence hex */ - else - tmp = 8; /* starts with 0 - hence octal */ - if (base==0) - base = (int)tmp; - } - - maxdiv = ULONG_MAX / base; - maxrem = ULONG_MAX % base; - - while ((digit = *s) != '\0') - { - if (digit >= '0' && digit < ('0'+base)) - digit -= '0'; - else - if (base > 10) - { - if (digit >= 'a' && digit < ('a'+(base-10))) - digit = digit - 'a' + 10; - else if (digit >= 'A' && digit < ('A'+(base-10))) - digit = digit - 'A' + 10; - else - break; - } - else - break; - did_conversion = 1; - if (total > maxdiv - || (total == maxdiv && digit > maxrem)) - overflow = 1; - total = (total * base) + digit; - s++; - } - if (overflow) - { - errno = ERANGE; - if (ptr != NULL) - *ptr = (char *)s; - return (ULONG_MAX); - } - if (ptr != NULL) - *ptr = (char *) ((did_conversion) ? (char *)s : (char *)start); - return negate ? -total : total; -} diff --git a/contrib/cvs/lib/system.h b/contrib/cvs/lib/system.h deleted file mode 100644 index 3956f37..0000000 --- a/contrib/cvs/lib/system.h +++ /dev/null @@ -1,570 +0,0 @@ -/* system-dependent definitions for CVS. - Copyright (C) 1989-1992 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. */ - -#include -#include - -#ifdef STAT_MACROS_BROKEN -#undef S_ISBLK -#undef S_ISCHR -#undef S_ISDIR -#undef S_ISREG -#undef S_ISFIFO -#undef S_ISLNK -#undef S_ISSOCK -#undef S_ISMPB -#undef S_ISMPC -#undef S_ISNWK -#endif - -/* Not all systems have S_IFMT, but we want to use it if we have it. - The S_IFMT code below looks right (it masks and compares). The - non-S_IFMT code looks bogus (are there really systems on which - S_IFBLK, S_IFLNK, &c, each have their own bit? I suspect it was - written for OS/2 using the IBM C/C++ Tools 2.01 compiler). - - Of course POSIX systems will have S_IS*, so maybe the issue is - semi-moot. */ - -#if !defined(S_ISBLK) && defined(S_IFBLK) -# if defined(S_IFMT) -# define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK) -# else -# define S_ISBLK(m) ((m) & S_IFBLK) -# endif -#endif - -#if !defined(S_ISCHR) && defined(S_IFCHR) -# if defined(S_IFMT) -# define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR) -# else -# define S_ISCHR(m) ((m) & S_IFCHR) -# endif -#endif - -#if !defined(S_ISDIR) && defined(S_IFDIR) -# if defined(S_IFMT) -# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) -# else -# define S_ISDIR(m) ((m) & S_IFDIR) -# endif -#endif - -#if !defined(S_ISREG) && defined(S_IFREG) -# if defined(S_IFMT) -# define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) -# else -# define S_ISREG(m) ((m) & S_IFREG) -# endif -#endif - -#if !defined(S_ISFIFO) && defined(S_IFIFO) -# if defined(S_IFMT) -# define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO) -# else -# define S_ISFIFO(m) ((m) & S_IFIFO) -# endif -#endif - -#if !defined(S_ISLNK) && defined(S_IFLNK) -# if defined(S_IFMT) -# define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK) -# else -# define S_ISLNK(m) ((m) & S_IFLNK) -# endif -#endif - -#ifndef S_ISSOCK -# if defined( S_IFSOCK ) -# ifdef S_IFMT -# define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK) -# else -# define S_ISSOCK(m) ((m) & S_IFSOCK) -# endif /* S_IFMT */ -# elif defined( S_ISNAM ) - /* SCO OpenServer 5.0.6a */ -# define S_ISSOCK S_ISNAM -# endif /* !S_IFSOCK && S_ISNAM */ -#endif /* !S_ISSOCK */ - -#if !defined(S_ISMPB) && defined(S_IFMPB) /* V7 */ -# if defined(S_IFMT) -# define S_ISMPB(m) (((m) & S_IFMT) == S_IFMPB) -# define S_ISMPC(m) (((m) & S_IFMT) == S_IFMPC) -# else -# define S_ISMPB(m) ((m) & S_IFMPB) -# define S_ISMPC(m) ((m) & S_IFMPC) -# endif -#endif - -#if !defined(S_ISNWK) && defined(S_IFNWK) /* HP/UX */ -# if defined(S_IFMT) -# define S_ISNWK(m) (((m) & S_IFMT) == S_IFNWK) -# else -# define S_ISNWK(m) ((m) & S_IFNWK) -# endif -#endif - -#ifdef NEED_DECOY_PERMISSIONS /* OS/2, really */ - -#define S_IRUSR S_IREAD -#define S_IWUSR S_IWRITE -#define S_IXUSR S_IEXEC -#define S_IRWXU (S_IRUSR | S_IWUSR | S_IXUSR) -#define S_IRGRP S_IREAD -#define S_IWGRP S_IWRITE -#define S_IXGRP S_IEXEC -#define S_IRWXG (S_IRGRP | S_IWGRP | S_IXGRP) -#define S_IROTH S_IREAD -#define S_IWOTH S_IWRITE -#define S_IXOTH S_IEXEC -#define S_IRWXO (S_IROTH | S_IWOTH | S_IXOTH) - -#else /* ! NEED_DECOY_PERMISSIONS */ - -#ifndef S_IRUSR -#define S_IRUSR 0400 -#define S_IWUSR 0200 -#define S_IXUSR 0100 -/* Read, write, and execute by owner. */ -#define S_IRWXU (S_IRUSR|S_IWUSR|S_IXUSR) - -#define S_IRGRP (S_IRUSR >> 3) /* Read by group. */ -#define S_IWGRP (S_IWUSR >> 3) /* Write by group. */ -#define S_IXGRP (S_IXUSR >> 3) /* Execute by group. */ -/* Read, write, and execute by group. */ -#define S_IRWXG (S_IRWXU >> 3) - -#define S_IROTH (S_IRGRP >> 3) /* Read by others. */ -#define S_IWOTH (S_IWGRP >> 3) /* Write by others. */ -#define S_IXOTH (S_IXGRP >> 3) /* Execute by others. */ -/* Read, write, and execute by others. */ -#define S_IRWXO (S_IRWXG >> 3) -#endif /* !def S_IRUSR */ -#endif /* NEED_DECOY_PERMISSIONS */ - -#if defined(POSIX) || defined(HAVE_UNISTD_H) -#include -#include -#else -off_t lseek (); -char *getcwd (); -#endif - -#include "xtime.h" - -#ifdef HAVE_IO_H -#include -#endif - -#ifdef HAVE_DIRECT_H -#include -#endif - - - -/* -** MAXPATHLEN and PATH_MAX -** -** On most systems MAXPATHLEN is defined in sys/param.h to be 1024. Of -** those that this is not true, again most define PATH_MAX in limits.h -** or sys/limits.h which usually gets included by limits.h. On the few -** remaining systems that neither statement is true, _POSIX_PATH_MAX -** is defined. -** -** So: -** 1. If PATH_MAX is defined just use it. -** 2. If MAXPATHLEN is defined but not PATH_MAX, then define -** PATH_MAX in terms of MAXPATHLEN. -** 3. If neither is defined, include limits.h and check for -** PATH_MAX again. -** 3.1 If we now have PATHSIZE, define PATH_MAX in terms of that. -** and ignore the rest. Since _POSIX_PATH_MAX (checked for -** next) is the *most* restrictive (smallest) value, if we -** trust _POSIX_PATH_MAX, several of our buffers are too small. -** 4. If PATH_MAX is still not defined but _POSIX_PATH_MAX is, -** then define PATH_MAX in terms of _POSIX_PATH_MAX. -** 5. And if even _POSIX_PATH_MAX doesn't exist just put in -** a reasonable value. -** *. All in all, this is an excellent argument for using pathconf() -** when at all possible. Or better yet, dynamically allocate -** our buffers and use getcwd() not getwd(). -** -** This works on: -** Sun Sparc 10 SunOS 4.1.3 & Solaris 1.2 -** HP 9000/700 HP/UX 8.07 & HP/UX 9.01 -** Tektronix XD88/10 UTekV 3.2e -** IBM RS6000 AIX 3.2 -** Dec Alpha OSF 1 ???? -** Intel 386 BSDI BSD/386 -** Intel 386 SCO OpenServer Release 5 -** Apollo Domain 10.4 -** NEC SVR4 -*/ - -/* On MOST systems this will get you MAXPATHLEN. - Windows NT doesn't have this file, tho. */ -#ifdef HAVE_SYS_PARAM_H -#include -#endif - -#ifndef PATH_MAX -# ifdef MAXPATHLEN -# define PATH_MAX MAXPATHLEN -# else -# include -# ifndef PATH_MAX -# ifdef PATHSIZE -# define PATH_MAX PATHSIZE -# else /* no PATHSIZE */ -# ifdef _POSIX_PATH_MAX -# define PATH_MAX _POSIX_PATH_MAX -# else -# define PATH_MAX 1024 -# endif /* no _POSIX_PATH_MAX */ -# endif /* no PATHSIZE */ -# endif /* no PATH_MAX */ -# endif /* MAXPATHLEN */ -#endif /* PATH_MAX */ - - -/* The NeXT (without _POSIX_SOURCE, which we don't want) has a utime.h - which doesn't define anything. It would be cleaner to have configure - check for struct utimbuf, but for now I'm checking NeXT here (so I don't - have to debug the configure check across all the machines). */ -#if defined (HAVE_UTIME_H) && !defined (NeXT) -# include -#else -# if defined (HAVE_SYS_UTIME_H) -# include -# else -# ifndef ALTOS -struct utimbuf -{ - long actime; - long modtime; -}; -# endif -int utime (); -# endif -#endif - -#include - -#ifndef ERRNO_H_MISSING -#include -#endif - -/* Not all systems set the same error code on a non-existent-file - error. This tries to ask the question somewhat portably. - On systems that don't have ENOTEXIST, this should behave just like - x == ENOENT. "x" is probably errno, of course. */ - -#ifdef ENOTEXIST -# ifdef EOS2ERR -# define existence_error(x) \ - (((x) == ENOTEXIST) || ((x) == ENOENT) || ((x) == EOS2ERR)) -# else -# define existence_error(x) \ - (((x) == ENOTEXIST) || ((x) == ENOENT)) -# endif -#else -# ifdef EVMSERR -# define existence_error(x) \ -((x) == ENOENT || (x) == EINVAL || (x) == EVMSERR) -# else -# define existence_error(x) ((x) == ENOENT) -# endif -#endif - - -#ifdef STDC_HEADERS -# include -#else -char *getenv (); -char *malloc (); -char *realloc (); -char *calloc (); -extern int errno; -#endif - -/* SunOS4 apparently does not define this in stdlib.h. */ -#ifndef EXIT_FAILURE -# define EXIT_FAILURE 1 -#endif - -/* check for POSIX signals */ -#if defined(HAVE_SIGACTION) && defined(HAVE_SIGPROCMASK) -# define POSIX_SIGNALS -#endif - -/* MINIX 1.6 doesn't properly support sigaction */ -#if defined(_MINIX) -# undef POSIX_SIGNALS -#endif - -/* If !POSIX, try for BSD.. Reason: 4.4BSD implements these as wrappers */ -#if !defined(POSIX_SIGNALS) -# if defined(HAVE_SIGVEC) && defined(HAVE_SIGSETMASK) && defined(HAVE_SIGBLOCK) -# define BSD_SIGNALS -# endif -#endif - -/* Under OS/2, this must be included _after_ stdio.h; that's why we do - it here. */ -#ifdef USE_OWN_TCPIP_H -# include "tcpip.h" -#endif - -#ifdef HAVE_FCNTL_H -# include -#else -# include -#endif - -#ifndef SEEK_SET -# define SEEK_SET 0 -# define SEEK_CUR 1 -# define SEEK_END 2 -#endif - -#ifndef F_OK -# define F_OK 0 -# define X_OK 1 -# define W_OK 2 -# define R_OK 4 -#endif - -#if HAVE_DIRENT_H -# include -# define NAMLEN(dirent) strlen((dirent)->d_name) -#else -# define dirent direct -# define NAMLEN(dirent) (dirent)->d_namlen -# if HAVE_SYS_NDIR_H -# include -# endif -# if HAVE_SYS_DIR_H -# include -# endif -# if HAVE_NDIR_H -# include -# endif -#endif - -/* Convert B 512-byte blocks to kilobytes if K is nonzero, - otherwise return it unchanged. */ -#define convert_blocks(b, k) ((k) ? ((b) + 1) / 2 : (b)) - -#ifndef S_ISLNK -# define lstat stat -#endif - -/* - * Some UNIX distributions don't include these in their stat.h Defined here - * because "config.h" is always included last. - */ -#ifndef S_IWRITE -# define S_IWRITE 0000200 /* write permission, owner */ -#endif -#ifndef S_IWGRP -# define S_IWGRP 0000020 /* write permission, grougroup */ -#endif -#ifndef S_IWOTH -# define S_IWOTH 0000002 /* write permission, other */ -#endif - -/* Under non-UNIX operating systems (MS-DOS, WinNT, MacOS), many filesystem - calls take only one argument; permission is handled very differently on - those systems than in Unix. So we leave such systems a hook on which they - can hang their own definitions. */ - -#ifndef CVS_ACCESS -# define CVS_ACCESS access -#endif - -#ifndef CVS_CHDIR -# define CVS_CHDIR chdir -#endif - -#ifndef CVS_CREAT -# define CVS_CREAT creat -#endif - -#ifndef CVS_FOPEN -# define CVS_FOPEN fopen -#endif - -#ifndef CVS_FDOPEN -# define CVS_FDOPEN fdopen -#endif - -#ifndef CVS_MKDIR -# define CVS_MKDIR mkdir -#endif - -#ifndef CVS_OPEN -# define CVS_OPEN open -#endif - -#ifndef CVS_READDIR -# define CVS_READDIR readdir -#endif - -#ifndef CVS_CLOSEDIR -# define CVS_CLOSEDIR closedir -#endif - -#ifndef CVS_OPENDIR -# define CVS_OPENDIR opendir -#endif - -#ifndef CVS_RENAME -# define CVS_RENAME rename -#endif - -#ifndef CVS_RMDIR -# define CVS_RMDIR rmdir -#endif - -#ifndef CVS_STAT -# define CVS_STAT stat -#endif - -/* Open question: should CVS_STAT be lstat by default? We need - to use lstat in order to handle symbolic links correctly with - the PreservePermissions option. -twp */ -#ifndef CVS_LSTAT -# define CVS_LSTAT lstat -#endif - -#ifndef CVS_UNLINK -# define CVS_UNLINK unlink -#endif - -/* Wildcard matcher. Should be case-insensitive if the system is. */ -#ifndef CVS_FNMATCH -# define CVS_FNMATCH fnmatch -#endif - -#ifdef WIN32 -/* - * According to GNU conventions, we should avoid referencing any macro - * containing "WIN" as a reference to Microsoft Windows, as we would like to - * avoid any implication that we consider Microsoft Windows any sort of "win". - * - * FIXME: As of 2003-06-09, folks on the GNULIB project were discussing - * defining a configure macro to define WOE32 appropriately. If they ever do - * write such a beast, we should use it, though in most cases it would be - * preferable to avoid referencing any OS or compiler anyhow, per Autoconf - * convention, and reference only tested features of the system. - */ -# define WOE32 1 -#endif /* WIN32 */ - - -#ifdef WOE32 - /* Under Windows NT, filenames are case-insensitive. */ -# define FILENAMES_CASE_INSENSITIVE 1 -#endif /* WOE32 */ - - - -#ifdef FILENAMES_CASE_INSENSITIVE - -# if defined (__CYGWIN32__) || defined (WOE32) - /* Under Windows, filenames are case-insensitive, and both / and \ - are path component separators. */ -# define FOLD_FN_CHAR(c) (WNT_filename_classes[(unsigned char) (c)]) -extern unsigned char WNT_filename_classes[]; - /* Is the character C a path name separator? Under - Windows NT, you can use either / or \. */ -# define ISDIRSEP(c) (FOLD_FN_CHAR(c) == '/') -# define ISABSOLUTE(s) (ISDIRSEP(s[0]) || FOLD_FN_CHAR(s[0]) >= 'a' && FOLD_FN_CHAR(s[0]) <= 'z' && s[1] == ':' && ISDIRSEP(s[2])) -# else /* !__CYGWIN32__ && !WOE32 */ - /* As far as I know, only Macintosh OS X & VMS make it here, but any - * platform defining FILENAMES_CASE_INSENSITIVE which isn't WOE32 or - * piggy-backing the same could, in theory. Since the OS X fold just folds - * A-Z into a-z, I'm just allowing it to be used for any case insensitive - * system which we aren't yet making other specific folds or exceptions for. - * WOE32 needs its own class since \ and C:\ style absolute paths also need - * to be accounted for. - */ -# if defined(USE_VMS_FILENAMES) -# define FOLD_FN_CHAR(c) (VMS_filename_classes[(unsigned char) (c)]) -extern unsigned char VMS_filename_classes[]; -# else -# define FOLD_FN_CHAR(c) (OSX_filename_classes[(unsigned char) (c)]) -extern unsigned char OSX_filename_classes[]; -# endif -# endif /* __CYGWIN32__ || WOE32 */ - -/* The following need to be declared for all case insensitive filesystems. - * When not FOLD_FN_CHAR is not #defined, a default definition for these - * functions is provided later in this header file. */ - -/* Like strcmp, but with the appropriate tweaks for file names. */ -extern int fncmp (const char *n1, const char *n2); - -/* Fold characters in FILENAME to their canonical forms. */ -extern void fnfold (char *FILENAME); - -#endif /* FILENAMES_CASE_INSENSITIVE */ - - - -/* Some file systems are case-insensitive. If FOLD_FN_CHAR is - #defined, it maps the character C onto its "canonical" form. In a - case-insensitive system, it would map all alphanumeric characters - to lower case. Under Windows NT, / and \ are both path component - separators, so FOLD_FN_CHAR would map them both to /. */ -#ifndef FOLD_FN_CHAR -# define FOLD_FN_CHAR(c) (c) -# define fnfold(filename) (filename) -# define fncmp strcmp -#endif - -/* Different file systems have different path component separators. - For the VMS port we might need to abstract further back than this. */ -#ifndef ISDIRSEP -# define ISDIRSEP(c) ((c) == '/') -#endif - -/* Different file systems can have different naming patterns which designate - * a path as absolute - */ -#ifndef ISABSOLUTE -# define ISABSOLUTE(s) ISDIRSEP(s[0]) -#endif - - -/* On some systems, we have to be careful about writing/reading files - in text or binary mode (so in text mode the system can handle CRLF - vs. LF, VMS text file conventions, &c). We decide to just always - be careful. That way we don't have to worry about whether text and - binary differ on this system. We just have to worry about whether - the system has O_BINARY and "rb". The latter is easy; all ANSI C - libraries have it, SunOS4 has it, and CVS has used it unguarded - some places for a while now without complaints (e.g. "rb" in - server.c (server_updated), since CVS 1.8). The former is just an - #ifdef. */ - -#define FOPEN_BINARY_READ ("rb") -#define FOPEN_BINARY_WRITE ("wb") -#define FOPEN_BINARY_READWRITE ("r+b") - -#ifdef O_BINARY -#define OPEN_BINARY (O_BINARY) -#else -#define OPEN_BINARY (0) -#endif diff --git a/contrib/cvs/lib/test-getdate.sh b/contrib/cvs/lib/test-getdate.sh deleted file mode 100755 index 5b1db24..0000000 --- a/contrib/cvs/lib/test-getdate.sh +++ /dev/null @@ -1,127 +0,0 @@ -#! /bin/sh - -# Test that a getdate executable meets its specification. -# -# Copyright (C) 2004 Free Software Foundation, Inc. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -# Why are these dates tested? -# -# February 29, 2003 -# Is not a leap year - should be invalid. -# -# 2004-12-40 -# Make sure get_date does not "roll" date forward to January 9th. Some -# versions have been known to do this. -# -# Dec-5-1972 -# This is my birthday. :) -# -# 3/29/1974 -# 1996/05/12 13:57:45 -# Because. -# -# 12-05-12 -# This will be my 40th birthday. Ouch. :) -# -# 05/12/96 -# Because. -# -# third tuesday in March, 2078 -# Wanted this to work. -# -# 1969-12-32 2:00:00 UTC -# 1970-01-01 2:00:00 UTC -# 1969-12-32 2:00:00 +0400 -# 1970-01-01 2:00:00 +0400 -# 1969-12-32 2:00:00 -0400 -# 1970-01-01 2:00:00 -0400 -# Playing near the UNIX Epoch boundry condition to make sure date rolling -# is also disabled there. -# -# 1996-12-12 1 month -# Test a relative date. -# -# Tue Jan 19 03:14:07 2038 +0000 -# For machines with 31-bit time_t, any date past this date will be an -# invalid date. So, any test date with a value greater than this -# time is not portable. -# -# Feb. 29, 2096 4 years -# 4 years from this date is _not_ a leap year, so Feb. 29th does not exist. -# -# Feb. 29, 2096 8 years -# 8 years from this date is a leap year, so Feb. 29th does exist, -# but on many hosts with 32-bit time_t types time, this test will -# fail. So, this is not a portable test. -# - -TZ=UTC0; export TZ - -cat >getdate-expected < Bad format - couldn't convert. - > Bad format - couldn't convert. - > Bad format - couldn't convert. - > Fri Mar 29 00:00:00 1974 - > Sun May 12 13:57:45 1996 - > Sat May 12 00:00:00 2012 - > Sun May 12 00:00:00 1996 - > Bad format - couldn't convert. - > Bad format - couldn't convert. - > Thu Jan 1 02:00:00 1970 - > Bad format - couldn't convert. - > Bad format - couldn't convert. - > Bad format - couldn't convert. - > Thu Jan 1 06:00:00 1970 - > Sun Jan 12 00:00:00 1997 - > -EOF - -./getdate >getdate-got <>getdate-got - -if cmp getdate-expected getdate-got >getdate.cmp; then :; else - LOGFILE=`pwd`/getdate.log - cat getdate.cmp >${LOGFILE} - echo "** expected: " >>${LOGFILE} - cat getdate-expected >>${LOGFILE} - echo "** got: " >>${LOGFILE} - cat getdate-got >>${LOGFILE} - echo "FAIL: getdate" | tee -a ${LOGFILE} - echo "Failed! See ${LOGFILE} for more!" >&2 - exit 1 -fi - -rm getdate-expected getdate-got getdate.cmp -exit 0 diff --git a/contrib/cvs/lib/valloc.c b/contrib/cvs/lib/valloc.c deleted file mode 100644 index 17fb14b..0000000 --- a/contrib/cvs/lib/valloc.c +++ /dev/null @@ -1,25 +0,0 @@ -/* valloc -- return memory aligned to the page size. */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "system.h" - -#ifndef HAVE_GETPAGESIZE -# include "getpagesize.h" -#endif - -void * -valloc (bytes) - size_t bytes; -{ - long pagesize; - char *ret; - - pagesize = getpagesize (); - ret = (char *) malloc (bytes + pagesize - 1); - if (ret) - ret = (char *) ((long) (ret + pagesize - 1) &~ (pagesize - 1)); - return ret; -} diff --git a/contrib/cvs/lib/wait.h b/contrib/cvs/lib/wait.h deleted file mode 100644 index 81df938..0000000 --- a/contrib/cvs/lib/wait.h +++ /dev/null @@ -1,42 +0,0 @@ -/* wait.h -- POSIX macros for evaluating exit statuses - Copyright (C) 1990 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. */ - -#ifdef HAVE_SYS_WAIT_H -#include /* For pid_t. */ -#ifdef HAVE_SYS_RESOURCE_H -#include /* for rusage */ -#endif -#include -#endif -#ifndef WIFSTOPPED -#define WIFSTOPPED(w) (((w) & 0xff) == 0x7f) -#endif -#ifndef WIFSIGNALED -#define WIFSIGNALED(w) (((w) & 0xff) != 0x7f && ((w) & 0xff) != 0) -#endif -#ifndef WIFEXITED -#define WIFEXITED(w) (((w) & 0xff) == 0) -#endif -#ifndef WCOREDUMP /* not POSIX, but common and useful */ -#define WCOREDUMP(w) (((w) & 0x80) != 0) -#endif - -#ifndef WSTOPSIG -#define WSTOPSIG(w) (((w) >> 8) & 0xff) -#endif -#ifndef WTERMSIG -#define WTERMSIG(w) ((w) & 0x7f) -#endif -#ifndef WEXITSTATUS -#define WEXITSTATUS(w) (((w) >> 8) & 0xff) -#endif diff --git a/contrib/cvs/lib/waitpid.c b/contrib/cvs/lib/waitpid.c deleted file mode 100644 index 02d6acb..0000000 --- a/contrib/cvs/lib/waitpid.c +++ /dev/null @@ -1,80 +0,0 @@ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "system.h" -#include "wait.h" - -#include - -struct unreaped { - pid_t pid; - int status; -}; -static struct unreaped *unreaped; -static int n; - -static struct unreaped *ualloc (oldptr, n) - struct unreaped *oldptr; - int n; -{ - n *= sizeof (struct unreaped); - if (n == 0) - n = 1; - if (oldptr) - oldptr = (struct unreaped *) realloc ((char *) oldptr, n); - else - oldptr = (struct unreaped *) malloc (n); - if (oldptr == 0) - { - fprintf (stderr, "cannot allocate %d bytes\n", n); - exit (1); - } - return oldptr; -} - -pid_t waitpid (pid, status, options) - pid_t pid; - int *status; - int options; -{ - int i; - - /* initialize */ - if (unreaped == 0) - { - unreaped = ualloc (unreaped, 1); - unreaped[0].pid = 0; - n = 1; - } - - for (i = 0; unreaped[i].pid; i++) - if (unreaped[i].pid == pid) - { - *status = unreaped[i].status; - while (unreaped[i].pid) - { - unreaped[i] = unreaped[i+1]; - i++; - } - n--; - return pid; - } - - while (1) - { -#ifdef HAVE_WAIT3 - pid_t p = wait3 (status, options, (struct rusage *) 0); -#else - pid_t p = wait (status); -#endif - - if (p == 0 || p == -1 || p == pid) - return p; - - n++; - unreaped = ualloc (unreaped, n); - unreaped[n-1].pid = p; - unreaped[n-1].status = *status; - } -} diff --git a/contrib/cvs/lib/xgetwd.c b/contrib/cvs/lib/xgetwd.c deleted file mode 100644 index bbae81d..0000000 --- a/contrib/cvs/lib/xgetwd.c +++ /dev/null @@ -1,67 +0,0 @@ -/* xgetwd.c -- return current directory with unlimited length - Copyright (C) 1992, 1997 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. */ - -/* Derived from xgetcwd.c in e.g. the GNU sh-utils. */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include "system.h" - -#include -#include -#ifndef errno -extern int errno; -#endif -#include - -/* Amount by which to increase buffer size when allocating more space. */ -#define PATH_INCR 32 - -char *xmalloc (); -char *xrealloc (); - -/* Return the current directory, newly allocated, arbitrarily long. - Return NULL and set errno on error. */ - -char * -xgetwd () -{ - char *cwd; - char *ret; - unsigned path_max; - - errno = 0; - path_max = (unsigned) PATH_MAX; - path_max += 2; /* The getcwd docs say to do this. */ - - cwd = xmalloc (path_max); - - errno = 0; - while ((ret = getcwd (cwd, path_max)) == NULL && errno == ERANGE) - { - path_max += PATH_INCR; - cwd = xrealloc (cwd, path_max); - errno = 0; - } - - if (ret == NULL) - { - int save_errno = errno; - free (cwd); - errno = save_errno; - return NULL; - } - return cwd; -} diff --git a/contrib/cvs/lib/xgssapi.h b/contrib/cvs/lib/xgssapi.h deleted file mode 100644 index 31b8e39..0000000 --- a/contrib/cvs/lib/xgssapi.h +++ /dev/null @@ -1,30 +0,0 @@ -/* This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. */ - -/* This file performs the generic include magic necessary for using - * cross platform gssapi which configure doesn't perform itself. - */ - -/* Can't include both of these headers at the same time with Solaris 7 & - * Heimdal Kerberos 0.3. If some system ends up requiring both, a configure - * test like TIME_AND_SYS_TIME will probably be necessary. - */ -#ifdef HAVE_GSSAPI_H -# include -#else -/* Assume existance of this header so that the user will get an informative - * message if HAVE_GSSAPI somehow gets defined with both headers missing. - */ -# include -#endif -#ifdef HAVE_GSSAPI_GSSAPI_GENERIC_H -/* MIT Kerberos 5 v1.2.1 */ -# include -#endif diff --git a/contrib/cvs/lib/xselect.h b/contrib/cvs/lib/xselect.h deleted file mode 100644 index 5605cbd..0000000 --- a/contrib/cvs/lib/xselect.h +++ /dev/null @@ -1,21 +0,0 @@ -/* This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. */ - -/* This file simply performs the include magic necessary for using select */ - -/* select also requires , "xtime.h", and */ - -#ifdef HAVE_SYS_BSDTYPES_H -# include -#endif - -#if HAVE_SYS_SELECT_H -# include -#endif diff --git a/contrib/cvs/lib/xsize.h b/contrib/cvs/lib/xsize.h deleted file mode 100644 index 3a17628..0000000 --- a/contrib/cvs/lib/xsize.h +++ /dev/null @@ -1,110 +0,0 @@ -/* xsize.h -- Checked size_t computations. - - Copyright (C) 2003 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#ifndef _XSIZE_H -#define _XSIZE_H - -/* Get size_t. */ -#include - -/* Get SIZE_MAX. */ -#include -#if HAVE_INTTYPES_H -# include -#elif HAVE_STDINT_H -# include -#endif - -/* The size of memory objects is often computed through expressions of - type size_t. Example: - void* p = malloc (header_size + n * element_size). - These computations can lead to overflow. When this happens, malloc() - returns a piece of memory that is way too small, and the program then - crashes while attempting to fill the memory. - To avoid this, the functions and macros in this file check for overflow. - The convention is that SIZE_MAX represents overflow. - malloc (SIZE_MAX) is not guaranteed to fail -- think of a malloc - implementation that uses mmap --, it's recommended to use size_overflow_p() - or size_in_bounds_p() before invoking malloc(). - The example thus becomes: - size_t size = xsum (header_size, xtimes (n, element_size)); - void *p = (size_in_bounds_p (size) ? malloc (size) : NULL); -*/ - -/* Convert an arbitrary value >= 0 to type size_t. */ -#define xcast_size_t(N) \ - ((N) <= SIZE_MAX ? (size_t) (N) : SIZE_MAX) - -/* Sum of two sizes, with overflow check. */ -static inline size_t -#if __GNUC__ >= 3 -__attribute__ ((__pure__)) -#endif -xsum (size_t size1, size_t size2) -{ - size_t sum = size1 + size2; - return (sum >= size1 ? sum : SIZE_MAX); -} - -/* Sum of three sizes, with overflow check. */ -static inline size_t -#if __GNUC__ >= 3 -__attribute__ ((__pure__)) -#endif -xsum3 (size_t size1, size_t size2, size_t size3) -{ - return xsum (xsum (size1, size2), size3); -} - -/* Sum of four sizes, with overflow check. */ -static inline size_t -#if __GNUC__ >= 3 -__attribute__ ((__pure__)) -#endif -xsum4 (size_t size1, size_t size2, size_t size3, size_t size4) -{ - return xsum (xsum (xsum (size1, size2), size3), size4); -} - -/* Maximum of two sizes, with overflow check. */ -static inline size_t -#if __GNUC__ >= 3 -__attribute__ ((__pure__)) -#endif -xmax (size_t size1, size_t size2) -{ - /* No explicit check is needed here, because for any n: - max (SIZE_MAX, n) == SIZE_MAX and max (n, SIZE_MAX) == SIZE_MAX. */ - return (size1 >= size2 ? size1 : size2); -} - -/* Multiplication of a count with an element size, with overflow check. - The count must be >= 0 and the element size must be > 0. - This is a macro, not an inline function, so that it works correctly even - when N is of a wider tupe and N > SIZE_MAX. */ -#define xtimes(N, ELSIZE) \ - ((N) <= SIZE_MAX / (ELSIZE) ? (size_t) (N) * (ELSIZE) : SIZE_MAX) - -/* Check for overflow. */ -#define size_overflow_p(SIZE) \ - ((SIZE) == SIZE_MAX) -/* Check against overflow. */ -#define size_in_bounds_p(SIZE) \ - ((SIZE) != SIZE_MAX) - -#endif /* _XSIZE_H */ diff --git a/contrib/cvs/lib/xtime.h b/contrib/cvs/lib/xtime.h deleted file mode 100644 index 7760de5..0000000 --- a/contrib/cvs/lib/xtime.h +++ /dev/null @@ -1,61 +0,0 @@ -/* This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. */ - -/* This file simply performs the include magic necessary for using time - * functions - */ -#ifndef XTIME_HEADER_INCLUDED -#define XTIME_HEADER_INCLUDED - -#ifdef vms -# include -#else /* vms */ - -# if TIME_WITH_SYS_TIME -# include -# include -# else /* TIME_WITH_SYS_TIME */ -# if HAVE_SYS_TIME_H -# include -# else /* HAVE_SYS_TIME_H */ -# include -# endif /* !HAVE_SYS_TIME_H */ -# endif /* !TIME_WITH_SYS_TIME */ - -# ifdef HAVE_SYS_TIMEB_H -# include -# else /* HAVE_SYS_TIMEB_H */ -/* - * We use the obsolete `struct timeb' as part of our interface! - * Since the system doesn't have it, we define it here; - * our callers must do likewise. - * - * At the least we were using this in lib/getdate.y, but lib/system.h used to - * define it too, so maybe CVS is using it elsewhere. - */ -struct timeb { - time_t time; /* Seconds since the epoch */ - unsigned short millitm; /* Field not used */ - short timezone; /* Minutes west of GMT */ - short dstflag; /* Field not used */ -}; -# endif /* !HAVE_SYS_TIMEB_H */ - -# ifdef timezone -# undef timezone /* needed for sgi */ -# endif /* timezone */ - -# if !defined(HAVE_FTIME) && !defined(HAVE_TIMEZONE) -extern long timezone; -# endif /* !defined(HAVE_FTIME) && !defined(HAVE_TIMEZONE) */ - -#endif /* !vms */ - -#endif /* !XTIME_HEADER_INCLUDED */ diff --git a/contrib/cvs/lib/yesno.c b/contrib/cvs/lib/yesno.c deleted file mode 100644 index 1e87938..0000000 --- a/contrib/cvs/lib/yesno.c +++ /dev/null @@ -1,38 +0,0 @@ -/* yesno.c -- read a yes/no response from stdin - Copyright (C) 1990 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include - -/* Read one line from standard input - and return nonzero if that line begins with y or Y, - otherwise return 0. */ - -int -yesno () -{ - int c; - int rv; - - fflush (stderr); - fflush (stdout); - c = getchar (); - rv = (c == 'y') || (c == 'Y'); - while (c != EOF && c != '\n') - c = getchar (); - - return rv; -} diff --git a/contrib/cvs/man/ChangeLog b/contrib/cvs/man/ChangeLog deleted file mode 100644 index 1d16469..0000000 --- a/contrib/cvs/man/ChangeLog +++ /dev/null @@ -1,382 +0,0 @@ -2005-01-31 Derek Price - - * Makefile.am: Update copyright notices. - -2004-04-30 Derek Price - - First pass at closing issue #3 from cvshome.org. - * Makefile.am (man_MANS): Remove cvs.1. - * cvs.1: Removed. - * Makefile.in: Regenerated. - -2004-02-12 Derek Price - - Close issue #162. - * cvs.1: Remove references to the removed global -l option. - (Original patch from Ville Skyttä .) - -2004-02-12 Derek Price - - Close issue #161. - * cvs.1, cvs.5: A couple of spelling fixes. - (Patch from Ville Skyttä .) - -2004-01-30 Derek Price - - Close issue #146. - * cvs.1: Reference `cvs --help diff' rather than the rcsdiff man page. - Use consistent spelling of `initialization'. - (Patch from Ville Skyttä .) - -2003-05-21 Derek Price - - * Makefile.in: Regenerate with Automake version 1.7.5. - -2003-04-10 Larry Jones - - * Makefile.in: Regenerated. - -2003-03-24 Derek Price - - * Makefile.am: Update copyright notice. - - * Makefile.in: Regenerated. - -2003-03-05 Mark D. Baushke - - * cvs.1 (CVS_LOCAL_BRANCH_NUM): Backout CVS_LOCAL_BRANCH_NUM feature. - - * cvs.1 (CVS_LOCAL_BRANCH_NUM): Document new environment variable. - -2003-02-26 Larry Jones - - * cvs.1: Note using "cvs" in .cvsrc for global options. - (Patch from "Mark D. Baushke" ). - -2003-02-25 Derek Price - - * Makefile.in: Regenerated. - -2002-09-24 Derek Price - - * Makefile.in: Regenerated using Automake 1.6.3. - -2002-09-24 Derek Price - - * Makefile.in: Regenerated. - -2002-04-30 Derek Price - - * Makefile.in: Regenerated with automake 1.6. - -2002-04-17 Derek Price - - * cvs.1(cvs tag): Mention -c option. - (Correction from Michael Richardson .) - -2002-04-17 Derek Price - - * cvs.1(cvs commit): It's '-F' now, not '-f'. - (Correction from Norikatsu Shigemura .) - -2002-04-17 Derek Price - - * cvs.1: Claim to be out of date and direct users to the Cederqvist. - Replace www.cyclic.com with cvshome.org. - * cvs.5: Ditto. - -2001-11-27 Larry Jones - - * cvsbug.8: Fixed typo. - (Correction from Mark D. Baushke .) - -2001-09-04 Derek Price - - * Makefile.in: Regenerated with automake 1.5. - -2001-08-06 Derek Price - - * Makefile.in: Regenerated. - -2001-07-04 Derek Price - - * Makefile.in: Regenerated with new Automake release candidate 1.4h. - -2001-06-28 Derek Price - - * Makefile.in: Regenerated with new version of Automake. - -2001-05-21 Derek Price - - * cvs.1: Correct a quoting error. - (Patch from Alexey Mahotkin ). - -2001-05-18 Derek Price - - * cvs.1: Add note about 'P' file status from update. - (Reported by Jani Averbach ). - -2001-04-25 Derek Price - - * Makefile.in: Regenerated using AM 1.4e as of today at 18:10 -0400. - -2001-03-14 Derek Price - - * Makefile.in: Regenerated - -2000-12-22 Derek Price - - * Makefile.in: Regenerated - -2000-12-21 Derek Price - - * Makefile.am: New file needed by Automake - * Makefile.in: Regenerated - -2000-09-07 Larry Jones - - * Makefile.in: Use @bindir@, @libdir@, @infodir@, and @mandir@ - from autoconf. - -2000-05-03 Larry Jones - - * cvs.1: Correct CVSEDITOR/VISUAL/EDITOR documentation. - Correct KJ's botched patch application. - -2000-01-02 John P Cavanaugh - - * cvs.texinfo: document new -C option to update, now that it works - both remotely and locally. - (Re-applied by Karl Fogel .) - -1999-12-11 Karl Fogel - - * Revert previous change -- it doesn't work remotely yet. - -1999-12-10 John P Cavanaugh - - * cvs.1: document new -C option to update. - (Applied by Karl Fogel .) - -1999-11-29 Larry Jones - - * cvsbug.8: Change .TH from section 1 to section 8. - -1999-11-10 Jim Kingdon - - * cvs.1: Don't document -H as a command option; it has been a - while since that worked. - -1999-01-19 Vitaly V Fedrushkov - - * Makefile.in (INSTALL_DATA): Wrong manpage permissions fixed. - -1998-06-28 Jim Kingdon - - * cvs.1: Update various items which were out of date. Mostly - these related to CVS no longer calling external RCS programs. - -Mon Jan 12 11:10:21 1998 Jim Kingdon - - * cvs.1: Refer to Cederqvist as Cederqvist not as cvs.texinfo. - Describe it in a way which hopefully makes more sense for people - who aren't getting the CVS source distribution itself. In "SEE - ALSO" section, also mention web pages. Use a period not a comma - at the end of the references to other manpages. - - * cvs.1: Remove $Id; we decided to get rid of these some time ago. - -Sun Jan 11 13:46:54 1998 Peter Wemm - - * cvs.1: Fix "the the" typo. From Wolfram Schneider - via FreeBSD sources. - -Wed Feb 12 14:20:43 1997 Jim Kingdon - - * Makefile.in (install): Depend on installdirs. - -Thu Jan 2 13:30:56 1997 Jim Kingdon - - * Makefile.in, cvsbug.8: Remove "675" paragraph; - see ../ChangeLog for rationale. - -Sat Nov 30 14:49:32 1996 Jim Kingdon - - * cvs.1: Add note at beginning about how cvs.texinfo is more - complete than this document. Without some such indication, users - have no way of knowing which document to consult. - -Tue Oct 1 14:01:28 1996 Jim Kingdon - - * cvs.1: Revert all changes by Greg Woods since CVS 1.8.86. They - are for new features which are not appropriate at this stage of - the release process. - -Mon Sep 30 18:21:05 1996 Greg A. Woods - - * cvs.1: document -D, -g, DIFFBIN, and GREPBIN. - -Mon Sep 16 23:22:16 1996 Jim Kingdon - - * cvsbug.8: Remove references to cvsbug.el (or other aspects of - emacs interface) and cvsbug.info (or other aspects of texinfo - documentation). Neither one has ever existed. - -Wed Jul 24 19:01:35 1996 Ian Lance Taylor - - * cvs.1: Document -x. - -Fri Sep 13 11:01:59 1996 Greg A. Woods - - * cvs.1: add description of -k and -K for rdiff. Mention that - import allows '-b 1' to import to the trunk. - -Tue May 14 10:23:59 1996 Jim Kingdon - - * cvs.1: Add cvs.texinfo to the SEE ALSO section. Replace an out - of date list of default ignore patterns with a reference to - cvs.texinfo (if someone wants to undo this change that is OK with - me but I did it this way because it isn't clear people would - actually keep cvs.1 up to date). - -Wed Mar 13 17:06:39 1996 Jim Kingdon - - * cvsinit.8: Removed. - * Makefile.in, cvs.1, cvs.5: Remove references to cvsinit. - -Tue Feb 13 22:30:54 1996 Samuel Tardieu - - * Makefile.in: Remove reference to mkmodules.1 - -Mon Feb 12 16:30:40 1996 Jim Kingdon - - * cvs.1, cvsinit.8: Remove references to mkmodules, rm, sort - * cvs.5: Remove references to mkmodules. - * mkmodules.1: Removed. - -Tue Jan 30 18:32:27 1996 Jim Kingdon - - * Makefile.in: Revise comment regarding install and installdirs. - -Tue Nov 14 15:47:44 1995 Greg A. Woods - - * cvs.5: - - list filenames in alpha sort order - - describe the cvswrappers file - - describe the taginfo file - - fix cvsinit chapter number - (This is by no means complete -- it's just stuff I noticed.) - - * cvs.1: put the filenames in alpha sort order - - * cvsinit.8: remove the .pl extension from filenames - -Wed Oct 18 11:07:07 1995 Vince Demarco - - * cvs.1 (Flag): Updated the CVSROOT/wrappers stuff. Everyone seems - to think this is a NEXT specific thing it isn't. - -Tue Oct 17 17:38:27 1995 Warren Jones - - * cvs.1: Change \. to \&. at start of line. - -Tue Oct 3 13:43:33 1995 Del - - * cvs.1: Updated man page for all the new features of 1.6 - (including some that were missed in 1.5 and 1.4.xx). This includes: - - -f and -z global options. - - tag -F, and -r options. - - rtag -F options - - CVSROOT/taginfo and CVSROOT/wrappers files (the latter could use a touch - up because I don't really understand how wrappers work or why anyone would - use them -- I haven't ever played with a NEXT. - - export -k option - - New environment variables CVS_IGNORE_REMOTE_ROOT, CVS_RSH, CVS_SERVER, and - CVSWRAPPERS. I left CVS_CLIENT_LOG, CVS_CLIENT_PORT, and CVS_SERVER_SLEEP - undocumented because these appear to be for testing / debugging only. - Note that TMPDIR, HOME and PATH are used as well and strictly speaking - should be documented. - - New files ~/.cvsrc and ~/.cvswrappers - -Tue Aug 15 08:13:14 1995 Karl Fogel - - * Makefile.in (MANFILES): include $MAN8FILES too, so they get - tarred up in the distribution just like anything else. - -Mon Jul 24 19:11:15 1995 James Kingdon - - * cvs.1: Remove references to -q and -Q command options. - -Fri Jul 14 23:30:33 1995 Jim Blandy - - * Makefile.in (prefix): Don't forget to give this a value. - -Sun Jul 9 21:22:56 1995 Karl Fogel - - Greg Woods' change: - - * cvsbug.8, cvsinit.8: new files. - -Sun Jul 9 19:03:00 1995 Greg A. Woods - - * cvs.1: document 'cvs status [-qQ]' - - note reference to cvsinit(8) and cvsbug(8) - (from previous local changes) - - * Makefile.in: add support for installing in man8, and new cvsbug - and cvsinit pages (from previous local changes) - -Sat May 27 08:46:00 1995 Jim Meyering (meyering@comco.com) - - * Makefile.in (Makefile): Regenerate only Makefile in current - directory when Makefile.in is out of date. Depend on ../config.status. - -Fri Apr 28 22:51:31 1995 Jim Blandy - - * Makefile.in (DISTFILES): Updated. - (dist-dir): Renamed from dist; changed to work with DISTDIR - variable passed from parent. - -Fri Jul 15 12:58:14 1994 Ian Lance Taylor (ian@sanguine.cygnus.com) - - * Makefile.in (install): Do not depend upon installdirs. - -Sat Dec 18 01:23:13 1993 david d zuhn (zoo@monad.armadillo.com) - - * Makefile.in (VPATH): don't use $(srcdir), but @srcdir@ instead - -Mon Jun 14 12:20:33 1993 david d `zoo' zuhn (zoo at rtl.cygnus.com) - - * Makefile.in (install): remove parentdir support - -Mon Aug 31 01:42:43 1992 david d [zoo] zuhn (zoo at cirdan.cygnus.com) - - * Makefile.in (install): create $(man1dir) and $(man5dir) before - installing the man pages - -Wed Feb 26 18:04:40 1992 K. Richard Pixley (rich@cygnus.com) - - * Makefile.in, configure.in: removed traces of namesubdir, - -subdirs, $(subdir), $(unsubdir), some rcs triggers. Forced - copyrights to '92, changed some from Cygnus to FSF. - -Tue Dec 10 04:07:08 1991 K. Richard Pixley (rich at rtl.cygnus.com) - - * Makefile.in: infodir belongs in datadir. - -Tue Dec 10 03:59:10 1991 K. Richard Pixley (rich at cygnus.com) - - * cvs.man: small correction to an explanation of an example. - -Thu Dec 5 22:45:59 1991 K. Richard Pixley (rich at rtl.cygnus.com) - - * Makefile.in: idestdir and ddestdir go away. Added copyrights - and shift gpl to v2. Added ChangeLog if it didn't exist. docdir - and mandir now keyed off datadir by default. - -Wed Nov 27 02:46:20 1991 K. Richard Pixley (rich at sendai) - - * brought Makefile.in's up to standards.text. - - * fresh changelog. - diff --git a/contrib/cvs/man/Makefile.am b/contrib/cvs/man/Makefile.am deleted file mode 100644 index c2a494d..0000000 --- a/contrib/cvs/man/Makefile.am +++ /dev/null @@ -1,26 +0,0 @@ -## Process this file with automake to produce Makefile.in -# Makefile.am for GNU CVS man pages. -# -# Copyright (C) 1986-2005 The Free Software Foundation, Inc. -# -# Portions Copyright (C) 1998-2005 Derek Price, Ximbiot , -# and others. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -man_MANS = cvs.5 cvsbug.8 -EXTRA_DIST = \ - .cvsignore \ - $(man_MANS) - -# for backwards compatibility with the old makefiles -realclean: maintainer-clean -.PHONY: realclean diff --git a/contrib/cvs/man/Makefile.in b/contrib/cvs/man/Makefile.in deleted file mode 100644 index 855f580..0000000 --- a/contrib/cvs/man/Makefile.in +++ /dev/null @@ -1,437 +0,0 @@ -# Makefile.in generated by automake 1.10 from Makefile.am. -# @configure_input@ - -# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006 Free Software Foundation, Inc. -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ - -# Makefile.am for GNU CVS man pages. -# -# Copyright (C) 1986-2005 The Free Software Foundation, Inc. -# -# Portions Copyright (C) 1998-2005 Derek Price, Ximbiot , -# and others. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -VPATH = @srcdir@ -pkgdatadir = $(datadir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -subdir = man -DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ChangeLog -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ - $(top_srcdir)/configure.in -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs -CONFIG_HEADER = $(top_builddir)/config.h -CONFIG_CLEAN_FILES = -SOURCES = -DIST_SOURCES = -man5dir = $(mandir)/man5 -am__installdirs = "$(DESTDIR)$(man5dir)" "$(DESTDIR)$(man8dir)" -man8dir = $(mandir)/man8 -NROFF = nroff -MANS = $(man_MANS) -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -ACLOCAL = @ACLOCAL@ -AMTAR = @AMTAR@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -CC = @CC@ -CCDEPMODE = @CCDEPMODE@ -CFLAGS = @CFLAGS@ -CPP = @CPP@ -CPPFLAGS = @CPPFLAGS@ -CSH = @CSH@ -CYGPATH_W = @CYGPATH_W@ -DEFS = @DEFS@ -DEPDIR = @DEPDIR@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EDITOR = @EDITOR@ -EGREP = @EGREP@ -EXEEXT = @EXEEXT@ -GREP = @GREP@ -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -KRB4 = @KRB4@ -LDFLAGS = @LDFLAGS@ -LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ -LN_S = @LN_S@ -LTLIBOBJS = @LTLIBOBJS@ -MAINT = @MAINT@ -MAKEINFO = @MAKEINFO@ -MKDIR_P = @MKDIR_P@ -MKTEMP = @MKTEMP@ -OBJEXT = @OBJEXT@ -PACKAGE = @PACKAGE@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ -PACKAGE_NAME = @PACKAGE_NAME@ -PACKAGE_STRING = @PACKAGE_STRING@ -PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -PERL = @PERL@ -PR = @PR@ -PS2PDF = @PS2PDF@ -RANLIB = @RANLIB@ -ROFF = @ROFF@ -SENDMAIL = @SENDMAIL@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -STRIP = @STRIP@ -TEXI2DVI = @TEXI2DVI@ -VERSION = @VERSION@ -YACC = @YACC@ -YFLAGS = @YFLAGS@ -abs_builddir = @abs_builddir@ -abs_srcdir = @abs_srcdir@ -abs_top_builddir = @abs_top_builddir@ -abs_top_srcdir = @abs_top_srcdir@ -ac_ct_CC = @ac_ct_CC@ -ac_prefix_program = @ac_prefix_program@ -am__include = @am__include@ -am__leading_dot = @am__leading_dot@ -am__quote = @am__quote@ -am__tar = @am__tar@ -am__untar = @am__untar@ -bindir = @bindir@ -build_alias = @build_alias@ -builddir = @builddir@ -datadir = @datadir@ -datarootdir = @datarootdir@ -docdir = @docdir@ -dvidir = @dvidir@ -exec_prefix = @exec_prefix@ -host_alias = @host_alias@ -htmldir = @htmldir@ -includedir = @includedir@ -includeopt = @includeopt@ -infodir = @infodir@ -install_sh = @install_sh@ -libdir = @libdir@ -libexecdir = @libexecdir@ -localedir = @localedir@ -localstatedir = @localstatedir@ -mandir = @mandir@ -mkdir_p = @mkdir_p@ -oldincludedir = @oldincludedir@ -pdfdir = @pdfdir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -psdir = @psdir@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -srcdir = @srcdir@ -sysconfdir = @sysconfdir@ -target_alias = @target_alias@ -top_builddir = @top_builddir@ -top_srcdir = @top_srcdir@ -with_default_rsh = @with_default_rsh@ -with_default_ssh = @with_default_ssh@ -man_MANS = cvs.5 cvsbug.8 -EXTRA_DIST = \ - .cvsignore \ - $(man_MANS) - -all: all-am - -.SUFFIXES: -$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ - && exit 0; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu man/Makefile'; \ - cd $(top_srcdir) && \ - $(AUTOMAKE) --gnu man/Makefile -.PRECIOUS: Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - @case '$?' in \ - *config.status*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ - *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ - esac; - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh - -$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -install-man5: $(man5_MANS) $(man_MANS) - @$(NORMAL_INSTALL) - test -z "$(man5dir)" || $(MKDIR_P) "$(DESTDIR)$(man5dir)" - @list='$(man5_MANS) $(dist_man5_MANS) $(nodist_man5_MANS)'; \ - l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \ - for i in $$l2; do \ - case "$$i" in \ - *.5*) list="$$list $$i" ;; \ - esac; \ - done; \ - for i in $$list; do \ - if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \ - else file=$$i; fi; \ - ext=`echo $$i | sed -e 's/^.*\\.//'`; \ - case "$$ext" in \ - 5*) ;; \ - *) ext='5' ;; \ - esac; \ - inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ - inst=`echo $$inst | sed -e 's/^.*\///'`; \ - inst=`echo $$inst | sed '$(transform)'`.$$ext; \ - echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man5dir)/$$inst'"; \ - $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man5dir)/$$inst"; \ - done -uninstall-man5: - @$(NORMAL_UNINSTALL) - @list='$(man5_MANS) $(dist_man5_MANS) $(nodist_man5_MANS)'; \ - l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \ - for i in $$l2; do \ - case "$$i" in \ - *.5*) list="$$list $$i" ;; \ - esac; \ - done; \ - for i in $$list; do \ - ext=`echo $$i | sed -e 's/^.*\\.//'`; \ - case "$$ext" in \ - 5*) ;; \ - *) ext='5' ;; \ - esac; \ - inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ - inst=`echo $$inst | sed -e 's/^.*\///'`; \ - inst=`echo $$inst | sed '$(transform)'`.$$ext; \ - echo " rm -f '$(DESTDIR)$(man5dir)/$$inst'"; \ - rm -f "$(DESTDIR)$(man5dir)/$$inst"; \ - done -install-man8: $(man8_MANS) $(man_MANS) - @$(NORMAL_INSTALL) - test -z "$(man8dir)" || $(MKDIR_P) "$(DESTDIR)$(man8dir)" - @list='$(man8_MANS) $(dist_man8_MANS) $(nodist_man8_MANS)'; \ - l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \ - for i in $$l2; do \ - case "$$i" in \ - *.8*) list="$$list $$i" ;; \ - esac; \ - done; \ - for i in $$list; do \ - if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \ - else file=$$i; fi; \ - ext=`echo $$i | sed -e 's/^.*\\.//'`; \ - case "$$ext" in \ - 8*) ;; \ - *) ext='8' ;; \ - esac; \ - inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ - inst=`echo $$inst | sed -e 's/^.*\///'`; \ - inst=`echo $$inst | sed '$(transform)'`.$$ext; \ - echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \ - $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst"; \ - done -uninstall-man8: - @$(NORMAL_UNINSTALL) - @list='$(man8_MANS) $(dist_man8_MANS) $(nodist_man8_MANS)'; \ - l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \ - for i in $$l2; do \ - case "$$i" in \ - *.8*) list="$$list $$i" ;; \ - esac; \ - done; \ - for i in $$list; do \ - ext=`echo $$i | sed -e 's/^.*\\.//'`; \ - case "$$ext" in \ - 8*) ;; \ - *) ext='8' ;; \ - esac; \ - inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ - inst=`echo $$inst | sed -e 's/^.*\///'`; \ - inst=`echo $$inst | sed '$(transform)'`.$$ext; \ - echo " rm -f '$(DESTDIR)$(man8dir)/$$inst'"; \ - rm -f "$(DESTDIR)$(man8dir)/$$inst"; \ - done -tags: TAGS -TAGS: - -ctags: CTAGS -CTAGS: - - -distdir: $(DISTFILES) - @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - list='$(DISTFILES)'; \ - dist_files=`for file in $$list; do echo $$file; done | \ - sed -e "s|^$$srcdirstrip/||;t" \ - -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ - case $$dist_files in \ - */*) $(MKDIR_P) `echo "$$dist_files" | \ - sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ - sort -u` ;; \ - esac; \ - for file in $$dist_files; do \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - if test -d $$d/$$file; then \ - dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ - fi; \ - cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ - else \ - test -f $(distdir)/$$file \ - || cp -p $$d/$$file $(distdir)/$$file \ - || exit 1; \ - fi; \ - done -check-am: all-am -check: check-am -all-am: Makefile $(MANS) -installdirs: - for dir in "$(DESTDIR)$(man5dir)" "$(DESTDIR)$(man8dir)"; do \ - test -z "$$dir" || $(MKDIR_P) "$$dir"; \ - done -install: install-am -install-exec: install-exec-am -install-data: install-data-am -uninstall: uninstall-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-am -install-strip: - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - `test -z '$(STRIP)' || \ - echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install -mostlyclean-generic: - -clean-generic: - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." -clean: clean-am - -clean-am: clean-generic mostlyclean-am - -distclean: distclean-am - -rm -f Makefile -distclean-am: clean-am distclean-generic - -dvi: dvi-am - -dvi-am: - -html: html-am - -info: info-am - -info-am: - -install-data-am: install-man - -install-dvi: install-dvi-am - -install-exec-am: - -install-html: install-html-am - -install-info: install-info-am - -install-man: install-man5 install-man8 - -install-pdf: install-pdf-am - -install-ps: install-ps-am - -installcheck-am: - -maintainer-clean: maintainer-clean-am - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-am - -mostlyclean-am: mostlyclean-generic - -pdf: pdf-am - -pdf-am: - -ps: ps-am - -ps-am: - -uninstall-am: uninstall-man - -uninstall-man: uninstall-man5 uninstall-man8 - -.MAKE: install-am install-strip - -.PHONY: all all-am check check-am clean clean-generic distclean \ - distclean-generic distdir dvi dvi-am html html-am info info-am \ - install install-am install-data install-data-am install-dvi \ - install-dvi-am install-exec install-exec-am install-html \ - install-html-am install-info install-info-am install-man \ - install-man5 install-man8 install-pdf install-pdf-am \ - install-ps install-ps-am install-strip installcheck \ - installcheck-am installdirs maintainer-clean \ - maintainer-clean-generic mostlyclean mostlyclean-generic pdf \ - pdf-am ps ps-am uninstall uninstall-am uninstall-man \ - uninstall-man5 uninstall-man8 - - -# for backwards compatibility with the old makefiles -realclean: maintainer-clean -.PHONY: realclean -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/contrib/cvs/man/cvs.1 b/contrib/cvs/man/cvs.1 deleted file mode 100644 index 02355c2..0000000 --- a/contrib/cvs/man/cvs.1 +++ /dev/null @@ -1,2212 +0,0 @@ -\fBimport\fR. -.\" $FreeBSD$ -.de Id -.ds Rv \\$3 -.ds Dt \\$4 -.. -.TH CVS 1 "\*(Dt" -.\" Full space in nroff; half space in troff -.de SP -.if n .sp -.if t .sp .5 -.. -.\" quoted command -.de ` -.RB ` "\|\\$1\|" '\\$2 -.. -.SH "NAME" -cvs \- Concurrent Versions System -.SH "SYNOPSIS" -.TP -\fBcvs\fP [ \fIcvs_options\fP ] -.I cvs_command -[ -.I command_options -] [ -.I command_args -] -.SH "NOTE" -This manpage is a summary of some of the features of -.B cvs -but it may no longer be kept up-to-date. -For more current and in-depth documentation, please consult the -Cederqvist manual (via the -.B info cvs -command or otherwise, -as described in the SEE ALSO section of this manpage). -.SH "DESCRIPTION" -.IX "revision control system" "\fLcvs\fR" -.IX cvs "" "\fLcvs\fP \- concurrent versions system" -.IX "concurrent versions system \- \fLcvs\fP" -.IX "release control system" "cvs command" "" "\fLcvs\fP \- concurrent versions system" -.IX "source control system" "cvs command" "" "\fLcvs\fP \- concurrent versions system" -.IX revisions "cvs command" "" "\fLcvs\fP \- source control" -CVS is a version control system, which allows you to keep old versions -of files (usually source code), keep a log of who, when, and why -changes occurred, etc., like RCS or SCCS. Unlike the simpler systems, -CVS does not just operate on one file at a time or one directory at a -time, but operates on hierarchical collections of directories -consisting of version controlled files. CVS helps to manage releases -and to control the concurrent editing of source files among multiple -authors. CVS allows triggers to enable/log/control various -operations and works well over a wide area network. -.SP -.B cvs -keeps a single copy of the master sources. -This copy is called the source ``repository''; it contains all the -information to permit extracting previous software releases at any -time based on either a symbolic revision tag, or a date in the past. -.SH "ESSENTIAL COMMANDS" -.B cvs -provides a rich variety of commands (\fIcvs_command\fP in the -Synopsis), each of which often has a wealth of options, to satisfy the -many needs of source management in distributed environments. However, -you don't have to master every detail to do useful work with -.BR cvs ; -in fact, five commands are sufficient to use (and contribute to) -the source repository. -.TP -\fBcvs checkout\fP \fImodules\fP\|.\|.\|. -A necessary preliminary for most \fBcvs\fP work: creates your private -copy of the source for \fImodules\fP (named collections of source; you -can also use a path relative to the source repository here). You can -work with this copy without interfering with others' work. At least -one subdirectory level is always created. -.TP -.B cvs update -Execute this command from \fIwithin\fP your private source -directory when you wish to update your copies of source files from -changes that other developers have made to the source in the -repository. -.TP -\fBcvs add\fP \fIfile\fP\|.\|.\|. -Use this command to enroll new files in \fBcvs\fP records of your -working directory. The files will be added to the repository the next -time you run -.` "cvs commit". -Note: -You should use the -.` "cvs import" -command to bootstrap new sources into the source repository. -.` "cvs add" -is only used for new files to an already checked-out module. -.TP -\fBcvs remove\fP \fIfile\fP\|.\|.\|. -Use this command (after erasing any files listed) to declare that you -wish to eliminate files from the repository. The removal does not -affect others until you run -.` "cvs commit". -.TP -\fBcvs commit\fP \fIfile\fP\|.\|.\|. -Use this command when you wish to ``publish'' your changes to other -developers, by incorporating them in the source repository. -.SH "OPTIONS" -The -.B cvs -command line can include -.IR cvs_options , -which apply to the overall -.B cvs -program; a -.IR cvs_command , -which specifies a particular action on the source repository; and -.I command_options -and -.I command_arguments -to fully specify what the -.I cvs_command -will do. -.SP -.I Warning: -you must be careful of precisely where you place options relative to the -.IR cvs_command . -The same option can mean different things depending on whether it -is in the -.I cvs_options -position (to the left of a -.B cvs -command) or in the -.I command_options -position (to the right of a -.B cvs -command). -.SP -There are only two situations where you may omit -.IR cvs_command : -.` "cvs \-H" -or -.` "cvs --help" -elicits a list of available commands, and -.` "cvs \-v" -or -.` "cvs --version" -displays version information on \fBcvs\fP itself. -.SP -.SH "CVS OPTIONS" -As of release 1.6, -.B cvs -supports -.SM GNU -style long options as well as short options. Only -a few long options are currently supported, these are listed in -brackets after the short options whose functions they duplicate. -.SP -Use these options to control the overall -.B cvs -program: -.TP -.B \-H [ --help ] -Display usage information about the specified -.I cvs_command -(but do not actually execute the command). If you don't specify a -command name, -.` "cvs \-H" -displays a summary of all the commands available. -.TP -.B \-Q -Causes the command to be -.I really -quiet; the command will generate output only for serious problems. -.TP -.B \-q -Causes the command to be somewhat quiet; informational messages, such -as reports of recursion through subdirectories, are suppressed. -.TP -\fB\-b\fP \fIbindir\fP -Use -.I bindir -as the directory where -.SM RCS -programs are located (CVS 1.9 and older). -Overrides the setting of the -.SM RCSBIN -environment variable. -This value should be specified as an absolute pathname. -.TP -\fB\-d\fP \fICVS_root_directory\fP -Use -.I CVS_root_directory -as the root directory pathname of the master -source repository. -Overrides the setting of the -.SM CVSROOT -environment variable. -This value should be specified as an absolute pathname. -.TP -\fB\-e\fP \fIeditor\fP -Use -.I editor -to enter revision log information. -Overrides the setting of the -.SM CVSEDITOR\c -, -.SM VISUAL\c -, and -.SM EDITOR -environment variables. -.TP -.B \-f -Do not read the -.B cvs -startup file (\fI~/.cvsrc\fP). -.TP -.B \-n -Do not change any files. Attempt to execute the -.IR cvs_command , -but only to issue reports; do not remove, update, or merge any -existing files, or create any new files. -.TP -.B \-t -Trace program execution; display messages showing the steps of -.B cvs -activity. Particularly useful with -.B \-n -to explore the potential impact of an unfamiliar command. -.TP -.B \-r -Makes new working files read-only. -Same effect as if the -.SM CVSREAD -environment variable is set. -.TP -.B \-R -Turns on read-only repository mode. This allows one to check out from a -read-only repository, such as within an anoncvs server, or from a CDROM -repository. -Same effect as if the -.SM CVSREADONLYFS -environment variable is set. Using -.B \-R -can also considerably speed up checkout's over NFS. -.TP -.B \-v [ --version ] -Displays version and copyright information for -.BR cvs . -.TP -.B \-w -Makes new working files read-write (default). -Overrides the setting of the -.SM CVSREAD -environment variable. -.TP -.B \-g -Forces group-write perms on working files. This option is typically -used when you have multiple users sharing a single checked out source -tree, allowing them to operate their shells with a less dangerous umask. -To use this feature, create a directory to hold the checked-out source -tree, set it to a private group, and set up the directory such that -files created under it inherit the group id of the directory. This occurs -automatically with FreeBSD. With SysV you must typically set the SGID bit -on the directory. The users who are to share the checked out tree must -be placed in that group. Note that the sharing of a single checked-out -source tree is very different from giving several users access to a common -CVS repository. Access to a common CVS repository already maintains shared -group-write perms and does not require this option. - -To use the option transparently, simply place the line 'cvs -g' in your -~/.cvsrc file. Doing this is not recommended unless you firewall all your -source checkouts within a private group or within a private mode 0700 -directory. -.TP -.B \-x -Encrypt all communication between the client and the server. As of -this writing, this is only implemented when using a Kerberos -connection. -.TP -\fB\-z\fP \fIcompression\-level\fP -When transferring files across the network use -.B gzip -with compression level \fIcompression\-level\fP to compress and -de-compress data as it is transferred. Requires the presence of -the -.SM GNU -.B gzip -program in the current search path at both ends of the link. -.SH "USAGE" -Except when requesting general help with -.` "cvs \-H", -you must specify a -.I cvs_command -to -.B cvs -to select a specific release control function to perform. -Each -.B cvs -command accepts its own collection of options and arguments. -However, many options are available across several commands. -You can display a usage summary for each command by specifying the -.B \-H -option with the command. -.SH "CVS STARTUP FILE" -Normally, when CVS starts up, it reads the -.I .cvsrc -file from the home directory of the user reading it. This startup -procedure can be turned off with the -.B \-f -flag. -.SP -The -.I .cvsrc -file lists CVS commands with a list of arguments, one command per -line. For example, the following line in \fI.cvsrc\fP: -.SP -diff \-c -.SP -will mean that the -.` "cvs diff" -command will always be passed the \-c option in addition to any -other options that are specified in the command line (in this case -it will have the effect of producing context sensitive diffs for -all executions of -.` "cvs diff" -). -.SP -Global options are specified using the \fBcvs\fP keyword. For example, -the following: -.SP -cvs \-q -.SP -will mean that all -.` "cvs" -commands will behave as thought he \-q global option had been supplied. -.SH "CVS COMMAND SUMMARY" -Here are brief descriptions of all the -.B cvs -commands: -.TP -.B add -Add a new file or directory to the repository, pending a -.` "cvs commit" -on the same file. -Can only be done from within sources created by a previous -.` "cvs checkout" -invocation. -Use -.` "cvs import" -to place whole new hierarchies of sources under -.B cvs -control. -(Does not directly affect repository; changes -working directory.) -.TP -.B admin -Execute -control functions on the source repository. (Changes -repository directly; uses working directory without changing it.) -.TP -.B checkout -Make a working directory of source files for editing. (Creates or changes -working directory.) -.TP -.B commit -Apply to the source repository changes, additions, and deletions from your -working directory. (Changes repository.) -.TP -.B diff -Show differences between files in working directory and source -repository, or between two revisions in source repository. -(Does not change either repository or working directory.) -.TP -.B export -Prepare copies of a set of source files for shipment off site. -Differs from -.` "cvs checkout" -in that no -.B cvs -administrative directories are created (and therefore -.` "cvs commit" -cannot be executed from a directory prepared with -.` "cvs export"), -and a symbolic tag must be specified. -(Does not change repository; creates directory similar to working -directories). -.TP -.B history -Show reports on -.B cvs -commands that you or others have executed on a particular file or -directory in the source repository. (Does not change repository or -working directory.) History logs are kept only if enabled by creation -of the -.` "$CVSROOT/CVSROOT/history" -file; see -.BR cvs ( 5 ). -.TP -.B import -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. -(Does not change repository or working directory.) -.TP -.B rdiff -Prepare a collection of diffs as a patch file between two releases in -the repository. (Does not change repository or working directory.) -.TP -.B release -Cancel a -.` "cvs checkout", -abandoning any changes. -(Can delete working directory; no effect on repository.) -.TP -.B remove -Remove files from the source repository, pending a -.` "cvs commit" -on the same files. (Does not directly affect repository; -changes working directory.) -.TP -.B rtag -Explicitly specify a symbolic tag for particular revisions of files in the -source repository. See also -.` "cvs tag". -(Changes repository directly; does not require or affect -working directory.) -.TP -.B status -Show current status of files: latest version, version in working -directory, whether working version has been edited and, optionally, -symbolic tags in the -.SM RCS -file. (Does not change -repository or working directory.) -.TP -.B tag -Specify a symbolic tag for files in the repository. By default, tags -the revisions -that were last synchronized with your working directory. (Changes -repository directly; uses working directory without changing it.) -.TP -.B update -Bring your working directory up to date with changes from the -repository. Merges are performed automatically when possible; a -warning is issued if manual resolution is required for conflicting -changes. (Changes working directory; does not change repository.) -.SH "COMMON COMMAND OPTIONS" -This section describes the -.I command_options -that are available across several -.B cvs -commands. Not all commands support all of these options; each option -is only supported for commands where it makes sense. However, when -a command has one of these options you can count on the same meaning -for the option as in other commands. (Other command -options, which are listed with the individual commands, may have -different meanings from one -.B cvs -command to another.) -.I "Warning:" -the -.B history -command is an exception; -it supports many options that conflict -even with these standard options. -.TP -\fB\-D\fP \fIdate_spec\fP -Use the most recent revision no later than \fIdate_spec\fP (a single -argument, date description specifying a date in the -past). A wide variety of date formats are supported, in particular -ISO ("1972-09-24 20:05") or Internet ("24 Sep 1972 20:05"). -The \fIdate_spec\fP is interpreted as being in the local timezone, unless a -specific timezone is specified. -The specification is ``sticky'' when you use it to make a -private copy of a source file; that is, when you get a working file -using \fB\-D\fP, \fBcvs\fP records the date you -specified, so that further updates in the same directory will use the -same date (unless you explicitly override it; see the description of -the \fBupdate\fP command). -.B \-D -is available with the -.BR checkout ", " diff ", " history ", " export ", " -.BR rdiff ", " rtag ", and " -.B update -commands. -Examples of valid date specifications include: -.in +1i -.ft B -.nf -1 month ago -2 hours ago -400000 seconds ago -last year -last Monday -yesterday -a fortnight ago -3/31/92 10:00:07 PST -January 23, 1987 10:05pm -22:00 GMT -.fi -.ft P -.in -1i -.TP -.B \-f -When you specify a particular date or tag to \fBcvs\fP commands, they -normally ignore files that do not contain the tag (or did not exist on -the date) that you specified. Use the \fB\-f\fP option if you want -files retrieved even when there is no match for the tag or date. (The -most recent version is used in this situation.) -.B \-f -is available with these commands: -.BR checkout ", " export ", " -.BR rdiff ", " rtag ", and " update . -.TP -\fB\-k\fP \fIkflag\fP -Alter the default -processing of keywords. -The \fB\-k\fP option is available with the -.BR add ", " checkout ", " diff ", " rdiff ", " export ", and " -BR update -commands. Your \fIkflag\fP specification is ``sticky'' when you use -it to create a private copy of a source file; that is, when you use -this option with the \fBcheckout\fP or \fBupdate\fP commands, -\fBcvs\fP associates your selected \fIkflag\fP with the file, and -continues to use it with future \fBupdate\fP commands on the same file -until you specify otherwise. -.SP -Some of the more useful \fIkflag\fPs are \-ko and \-kb (for binary files), -and \-kv which is useful for an -.B export -where you wish to retain keyword information after an -.B import -at some other site. -.TP -.B \-l -Local; run only in current working directory, rather than recurring through -subdirectories. Available with the following commands: -.BR checkout ", " commit ", " diff ", " -.BR export ", " remove ", " rdiff ", " rtag ", " -.BR status ", " tag ", and " update . -.TP -.B \-n -Do -.I not -run any -.BR checkout / commit / tag / update -program. (A program can be specified to run on each of these -activities, in the modules database; this option bypasses it.) -Available with the -.BR checkout ", " export ", and " -.B rtag -commands. -.I Warning: -this is not the same -as the overall -.` "cvs \-n" -option, which you can specify to the -.I left -of a -.B cvs -command! -.TP -.B \-P -Prune (remove) directories that are empty after being updated, on -.BR checkout ", or " update . -Normally, an empty directory (one that is void of revision-controlled -files) is left alone. -Specifying -.B \-P -will cause these directories to be silently removed from your checked-out -sources. -This does not remove the directory from the repository, only from your -checked out copy. -Note that this option is implied by the -.B \-r -or -.B \-D -options of -.BR checkout " and " export . -.TP -.B \-T -Create/Update CVS/Template by copying it from the (local) repository. -This option is useful for developers maintaining a local cvs repository -but committing to a remote repository. By maintaining CVS/Template the -remote commits will still be able to bring up the proper template in the -commit editor session. -Available with the -.BR checkout " and " update -commands. -.TP -.B \-p -Pipe the files retrieved from the repository to standard output, -rather than writing them in the current directory. Available with the -.BR checkout " and " update -commands. -.TP -\fB\-r\fP \fItag\fP -Use the revision specified by the -.I tag -argument instead of the default ``head'' revision. As well as -arbitrary tags defined with the \fBtag\fP or \fBrtag\fP command, two -special tags are always available: -.` "HEAD" -refers to the most -recent version available in the repository, and -.` "BASE" -refers to the revision you last checked out into the current working -directory. -.SP -The \fItag\fP specification is ``sticky'' when you use -this option with -.` "cvs checkout" -or -.` "cvs update" -to -make your own copy of a file: \fBcvs\fP remembers the \fItag\fP and -continues to use it on future \fBupdate\fP commands, until you specify -otherwise. -.I tag -can be either a symbolic or numeric tag. -When a command expects a specific revision, -the name of a branch is interpreted as the most recent -revision on that branch. -Specifying the -.B \-q -global option along with the -.B \-r -command option is often useful, to suppress the warning messages when the -.SM RCS -file does not contain the specified tag. -.B \-r -is available with the -.BR annotate ", " checkout ", " -.BR commit ", " diff ", " history ", " export ", " rdiff ", " -.BR rtag ", and " update -commands. -.I Warning: -this is not the same -as the overall -.` "cvs \-r" -option, which you can specify to the -.I left -of a -.B cvs -command! -.SH "CVS COMMANDS" -Here (finally) are details on all the -.B cvs -commands and the options each accepts. The summary lines at the top -of each command's description highlight three kinds of things: -.TP 1i -\ \ \ \ Command Options and Arguments -Special options are described in detail below; common command options -may appear only in the summary line. -.TP 1i -\ \ \ \ Working Directory, or Repository? -Some \fBcvs\fP commands require a working directory to operate; some -require a repository. Also, some commands \fIchange\fP the -repository, some change the working directory, and some change -nothing. -.TP 1i -\ \ \ \ Synonyms -Many commands have synonyms, which you may find easier to -remember (or type) than the principal name. -.PP -.TP -\fBadd\fP [\fB\-k\fP \fIkflag\fP] [\fB\-m '\fP\fImessage\fP\fB'\fP] \fIfiles.\|.\|.\fP -.I Requires: -repository, working directory. -.br -.I Changes: -working directory. -.br -.I Synonym: -.B new -.br -Use the -.B add -command to create a new file or directory in the -source repository. -The files or directories specified with -.B add -must already exist in the current directory (which must have been created -with the -.B checkout -command). -To add a whole new directory hierarchy to the source repository -(for example, files received from a third-party vendor), use the -.` "cvs import" -command instead. -.SP -If the argument to -.` "cvs add" -refers to an immediate sub-directory, the directory is -created at the correct place in the -source repository, and the necessary -.B cvs -administration files are created in your working directory. -If the directory already exists in the source repository, -.` "cvs add" -still creates the administration files in your version of the directory. -This allows you to use -.` "cvs add" -to add a particular directory to your private sources even if -someone else created that directory after your -.B checkout -of the sources. You can do the following: -.SP -.in +1i -.ft B -.nf -example% mkdir new_directory -example% cvs add new_directory -example% cvs update new_directory -.fi -.ft P -.in -1i -.SP -An alternate approach using -.` "cvs update" -might be: -.SP -.in +1i -.ft B -.nf -example% cvs update -d new_directory -.fi -.ft P -.in -1i -.SP -(To add \fIany available\fP new directories to your working directory, it's -probably simpler to use -.` "cvs checkout" -or -.` "cvs update -d".) -.SP -The added files are not placed in the -source repository until you use -.` "cvs commit" -to make the change permanent. -Doing a -.` "cvs add" -on a file that was removed with the -.` "cvs remove" -command will resurrect the file, if no -.` "cvs commit" -command intervened. -.SP -You will have the opportunity to specify a logging message, as usual, -when you use -.` "cvs commit" -to make the new file permanent. If you'd like to have another -logging message associated with just -.I creation -of the file (for example, to describe the file's purpose), you can -specify it with the -.` "\-m \fImessage\fP" -option to the -.B add -command. -.SP -The -.` "-k kflag" -option specifies the default way that this -file will be checked out. -The -.` "kflag" -argument is stored in the -.SM RCS -file and can be changed with -.` "cvs admin". -Specifying -.` "-ko" -is useful for checking in binaries that -shouldn't have -keywords expanded. -.TP -\fBadmin\fP [\fIrcs-options\fP] \fIfiles.\|.\|.\fP -.I Requires: -repository, working directory. -.br -.I Changes: -repository. -.br -.I Synonym: -.B rcs -.br -This is the -.B cvs -interface to assorted administrative -facilities, similar to -.BR rcs ( 1 ). -This command works recursively, so extreme care should be -used. -.TP -\fBcheckout\fP [\fBoptions\fP] \fImodules\fP.\|.\|. -.I Requires: -repository. -.br -.I Changes: -working directory. -.br -.I Synonyms: -.BR co ", " get -.br -Make a working directory containing copies of the source files specified by -.IR modules . -You must execute -.` "cvs checkout" -before using most of the other -.B cvs -commands, since most of them operate on your working directory. -.SP -\fImodules\fP are either symbolic names (themselves defined as the -module -.` "modules" -in the source repository; see -.BR cvs ( 5 )) -for some collection of source directories and files, or paths to -directories or files in the repository. -.SP -Depending on the -.I modules -you specify, -.B checkout -may recursively create directories and populate them with the appropriate -source files. -You can then edit these source files at any time (regardless of whether -other software developers are editing their own copies of the sources); -update them to include new changes applied by others to the source -repository; or commit your work as a permanent change to the -repository. -.SP -Note that -.B checkout -is used to create directories. -The top-level directory created is always added to the directory -where -.B checkout -is invoked, and usually has the same name as the specified -.IR module . -In the case of a -.I module -alias, the created sub-directory may have a different name, but you can be -sure that it will be a sub-directory, and that -.B checkout -will show the relative path leading to each file as it is extracted into -your private work area (unless you specify the -.B \-Q -global option). -.SP -Running -.` "cvs checkout" -on a directory that was already built by a prior -.B checkout -is also permitted, and -has the same effect as specifying the -.B \-d -option to the -.B update -command described below. -.SP -The -.I options -permitted with -.` "cvs checkout" -include the standard command options -.BR \-P ", " \-f ", " -.BI \-k " kflag" -\&, -.BR \-l ", " \-n ", " \-p ", " -.BR \-r -.IR tag ", and" -.BI \-D " date"\c -\&. -.SP -In addition to those, you can use these special command options -with -.BR checkout : -.SP -Use the -.B \-A -option to reset any sticky tags, dates, or -.B \-k -options. (If you get a working file using one of the -\fB\-r\fP, \fB\-D\fP, or \fB\-k\fP options, \fBcvs\fP remembers the -corresponding tag, date, or \fIkflag\fP and continues using it on -future updates; use the \fB\-A\fP option to make \fBcvs\fP forget these -specifications, and retrieve the ``head'' version of the file). -Does not reset sticky -.B \-k -options on modified files. -.SP -The -.BI \-j " branch" -option merges the changes made between the -resulting revision and the revision that it is based on (e.g., if -the tag refers to a branch, -.B cvs -will merge all changes made in that branch into your working file). -.SP -With two \fB-j\fP options, -.B cvs -will merge in the changes between the two respective revisions. -This can be used to ``remove'' a certain delta from your working file. -.SP -In addition, each \fB-j\fP option can contain on optional date -specification which, when used with branches, can limit the chosen -revision to one within a specific date. -An optional date is specified by adding a colon (:) to the tag. -An example might be what -.` "cvs import" -tells you to do when you have -just imported sources that have conflicts with local changes: -.SP -.in +1i -.ft B -.nf -example% cvs checkout -jTAG:yesterday -jTAG module -.fi -.ft P -.in -1i -.SP -Use the -.B \-N -option with -.` "\-d \fIdir\fP" -to avoid shortening module paths in your working directory. (Normally, \fBcvs\fP shortens paths as much as possible when you specify an explicit target directory.) -.SP -Use the -.B \-c -option to copy the module file, sorted, to the standard output, -instead of creating or modifying any files or directories in your -working directory. -.SP -Use the -.BI \-d " dir" -option to create a directory called -.I dir -for the working files, instead of using the module name. Unless you -also use \fB\-N\fP, the paths created under \fIdir\fP will be as short -as possible. -.SP -Use the -.B \-s -option to display per-module status information stored with -the -.B \-s -option within the modules file. -.TP -\fBcommit\fP [\fB\-lR\fP] [\fB\-m\fP '\fIlog_message\fP' | \fB\-F\fP \fIfile\fP] [\fB\-r\fP \fIrevision\fP] [\fIfiles.\|.\|.\fP] -.I Requires: -working directory, repository. -.br -.I Changes: -repository. -.br -.I Synonym: -.B ci -.br -Use -.` "cvs commit" -when you want to incorporate changes from your working source -files into the general source repository. -.SP -If you don't specify particular \fIfiles\fP to commit, all -of the files in your working current directory are examined. -.B commit -is careful to change in the repository only those files that you have -really changed. By default (or if you explicitly specify the -.B \-R -option), files -in subdirectories are also examined and committed if they have -changed; you can use the -.B \-l -option to limit -.B commit -to the current directory only. -Sometimes you may want to force a file to be committed even though it -is unchanged; this is achieved with the -.B \-f -flag, which also has the effect of disabling recursion (you can turn -it back on with -.B \-R -of course). -.SP -.B commit -verifies that the selected files are up to date with the current revisions -in the source repository; it will notify you, and exit without -committing, if any of the specified files must be made current first -with -.` "cvs update". -.B commit -does not call the -.B update -command for you, but rather leaves that for you to do when -the time is right. -.SP -When all is well, an editor is invoked to allow you to enter a log -message that will be written to one or more logging programs and placed in the -source repository file. -You can instead specify the log message on the command line with the -.B \-m -option, thus suppressing the editor invocation, or use the -.B \-F -option to specify that the argument \fIfile\fP contains the log message. -.SP -The -.B \-r -option can be used to commit to a particular symbolic or numeric revision. -For example, to bring all your files up to the -revision ``3.0'' (including those that haven't changed), you might do: -.SP -.in +1i -.ft B -.nf -example% cvs commit -r3.0 -.fi -.ft P -.in -1i -.SP -.B cvs -will only allow you to commit to a revision that is on the main trunk (a -revision with a single dot). -However, you can also commit to a branch revision (one that has an even -number of dots) with the -.B \-r -option. -To create a branch revision, one typically use the -.B \-b -option of the -.BR rtag " or " tag -commands. -Then, either -.BR checkout " or " update -can be used to base your sources on the newly created branch. -From that point on, all -.B commit -changes made within these working sources will be automatically added -to a branch revision, thereby not perturbing main-line development in any -way. -For example, if you had to create a patch to the 1.2 version of the -product, even though the 2.0 version is already under development, you -might do: -.SP -.in +1i -.ft B -.nf -example% cvs rtag -b -rFCS1_2 FCS1_2_Patch product_module -example% cvs checkout -rFCS1_2_Patch product_module -example% cd product_module -[[ hack away ]] -example% cvs commit -.fi -.ft P -.in -1i -.SP -Say you have been working on some extremely experimental software, based on -whatever revision you happened to checkout last week. -If others in your group would like to work on this software with you, but -without disturbing main-line development, you could commit your change to a -new branch. -Others can then checkout your experimental stuff and utilize the full -benefit of -.B cvs -conflict resolution. -The scenario might look like: -.SP -.in +1i -.ft B -.nf -example% cvs tag -b EXPR1 -example% cvs update -rEXPR1 -[[ hack away ]] -example% cvs commit -.fi -.ft P -.in -1i -.SP -Others would simply do -.` "cvs checkout -rEXPR1 whatever_module" -to work with you on the experimental change. -.TP -\fBdiff\fP [\fB\-kl\fP] [\fIformat_options\fP] [[\fB\-r\fP \fIrev1\fP | \fB\-D\fP \fIdate1\fP | \fB\-j\fP \fIrev1:date1\fP] [\fB\-r\fP \fIrev2\fP | \fB\-D\fP \fIdate2\fP | \fB\-j\fP \fIrev2:date2\fP]] [\fIfiles.\|.\|.\fP] -.I Requires: -working directory, repository. -.br -.I Changes: -nothing. -.br -You can compare your working files with revisions in the source -repository, with the -.` "cvs diff" -command. If you don't specify a particular revision, your files -are compared with the revisions they were based on. You can also use -the standard -.B cvs -command option -.B \-r -to specify a particular revision to compare your files with. Finally, -if you use -.B \-r -twice, you can see differences between two revisions in the -repository. -You can also specify -.B \-D -options to diff against a revision (on the head branch) in the past, and -you can also specify -.B \-j -options to diff against a revision relative to a branch tag in the past. -The -.B \-r -and -.B \-D -and -.B \-j -options can be mixed together with at most two options ever specified. -.SP -See -.` "cvs --help diff" -for a list of supported -.IR format_options . -.SP -If you don't specify any files, -.B diff -will display differences for all those files in the current directory -(and its subdirectories, unless you use the standard option -.BR \-l ) -that -differ from the corresponding revision in the source repository -(i.e. files that -.I you -have changed), or that differ from the revision specified. -.TP -\fBexport\fP [\-\fBf\|lNnQq\fP] \fB\-r\fP \fIrev\fP\||\|\fB\-D\fP \fIdate\fP [\fB\-d\fP \fIdir\fP] [\fB\-k\fP \fIkflag\fP] \fImodule\fP.\|.\|. -.I Requires: -repository. -.br -.I Changes: -current directory. -.br -This command is a variant of -.` "cvs checkout"; -use it when you want a copy of the source for \fImodule\fP -without the \fBcvs\fP administrative directories. For example, you -might use -.` "cvs export" -to prepare source for shipment -off-site. This command \fIrequires\fP that you specify a date or tag -(with \fB\-D\fP or \fB\-r\fP), so that you can count on reproducing -the source you ship to others. -.SP -The only non-standard options are -.` "\-d \fIdir\fP" -(write the -source into directory \fIdir\fP) and -.` "\-N" -(don't shorten -module paths). -These have the same meanings as the same options in -.` "cvs checkout". -.SP -The -.B \-kv -option is useful when -.B export -is used. -This causes any -keywords to be expanded such that an -.B import -done at some other site will not lose the keyword revision information. -Other \fIkflag\fPs may be used with -.` "cvs export" -and are described in -.BR co ( 1 ). -.TP -\fBhistory\fP [\fB\-\fP\fIreport\fP] [\fB\-\fP\fIflags\fP] [\fB\-\fP\fIoptions args\fP] [\fIfiles\fP.\|.\|.] -.I Requires: -the file -.` "$CVSROOT/CVSROOT/history" -.br -.I Changes: -nothing. -.br -\fBcvs\fP keeps a history file that tracks each use of the -\fBcheckout\fP, \fBcommit\fP, \fBrtag\fP, \fBupdate\fP, and \fBrelease\fP -commands. You can use -.` "cvs history" -to display this -information in various formats. -.SP -.I Warning: -.` "cvs history" -uses -.` "\-f", -.` "\-l", -.` "\-n", -and -.` "\-p" -in ways that conflict with the -descriptions in -.SM -COMMON COMMAND OPTIONS\c -\&. -.SP -Several options (shown above as \fB\-\fP\fIreport\fP) control what -kind of report is generated: -.TP 1i -.B \ \ \ \ \ \ \-c -Report on each time \fBcommit\fP was used (i.e., each time the -repository was modified). -.TP 1i -\fB\ \ \ \ \ \ \-m\fP \fImodule\fP -Report on a particular \fImodule\fP. (You can meaningfully use -\fB\-m\fP more than once on the command line.) -.TP 1i -.B \ \ \ \ \ \ \-o -Report on checked-out modules. -.TP 1i -.B \ \ \ \ \ \ \-T -Report on all tags. -.TP 1i -\fB\ \ \ \ \ \ \-x\fP \fItype\fP -Extract a particular set of record types \fIX\fP from the \fBcvs\fP -history. The types are indicated by single letters, which you may -specify in combination. -Certain commands have a single record type: \fBcheckout\fP (type `O'), -\fBrelease\fP (type `F'), and \fBrtag\fP (type `T'). One of four -record types may result from an \fBupdate\fP: `W', when the working copy -of a file is deleted during update (because it was gone from the -repository); `U', when a working file was copied from the -repository; `G', when a merge was necessary and it succeeded; and 'C', -when a merge was necessary but collisions were detected (requiring -manual merging). Finally, one of three record types results from -\fBcommit\fP: `M', when a file was modified; `A', when a file is first -added; and `R', when a file is removed. -.TP 1i -.B \ \ \ \ \ \ \-e -Everything (all record types); equivalent to specifying -.` "\-xMACFROGWUT". -.TP 1i -\fB\ \ \ \ \ \ \-z\fP \fIzone\fP -Use time zone -.I zone -when outputting history records. -The zone name -.B LT -stands for local time; -numeric offsets stand for hours and minutes ahead of UTC. -For example, -.B +0530 -stands for 5 hours and 30 minutes ahead of (i.e. east of) UTC. -.PP -.RS .5i -The options shown as \fB\-\fP\fIflags\fP constrain the report without -requiring option arguments: -.RE -.TP 1i -.B \ \ \ \ \ \ \-a -Show data for all users (the default is to show data only for the user -executing -.` "cvs history"). -.TP 1i -.B \ \ \ \ \ \ \-l -Show last modification only. -.TP 1i -.B \ \ \ \ \ \ \-w -Show only the records for modifications done from the same working -directory where -.` "cvs history" -is executing. -.PP -.RS .5i -The options shown as \fB\-\fP\fIoptions args\fP constrain the report -based on an argument: -.RE -.TP 1i -\fB\ \ \ \ \ \ \-b\fP \fIstr\fP -Show data back to a record containing the string \fIstr\fP in either -the module name, the file name, or the repository path. -.TP 1i -\fB\ \ \ \ \ \ \-D\fP \fIdate\fP -Show data since \fIdate\fP. -.TP 1i -\fB\ \ \ \ \ \ \-p\fP \fIrepository\fP -Show data for a particular source repository (you can specify several -\fB\-p\fP options on the same command line). -.TP 1i -\fB\ \ \ \ \ \ \-r\fP \fIrev\fP -Show records referring to revisions since the revision or tag -named \fIrev\fP appears in individual RCS files. -Each -.SM RCS -file is searched for the revision or tag. -.TP 1i -\fB\ \ \ \ \ \ \-t\fP \fItag\fP -Show records since tag \fItag\fP was last added to the history file. -This differs from the \fB-r\fP flag above in that it reads -only the history file, not the -.SM RCS -files, and is much faster. -.TP 1i -\fB\ \ \ \ \ \ \-u\fP \fIname\fP -Show records for user \fIname\fP. -.PP -.TP -\fBimport\fP [\fB\-\fP\fIoptions\fP] \fIrepository vendortag releasetag\fP.\|.\|. -.I Requires: -Repository, source distribution directory. -.br -.I Changes: -repository. -.br -Use -.` "cvs import" -to incorporate an entire source -distribution from an outside source (e.g., a source vendor) into your -source repository directory. You can use this command both for -initial creation of a repository, and for wholesale updates to the -module form the outside source. -.SP -The \fIrepository\fP argument gives a directory name (or a path to a -directory) under the CVS root directory for repositories; if the -directory did not exist, \fBimport\fP creates it. -.SP -When you use \fBimport\fP for updates to source that has been modified in your -source repository (since a prior \fBimport\fP), it -will notify you of any files that conflict in the two branches of -development; use -.` "cvs checkout -j" -to reconcile the differences, as \fBimport\fP instructs you to do. -.SP -By default, certain file names are ignored during -.` "cvs import": -names associated with -.SM CVS -administration, or with other common source control systems; common -names for patch files, object files, archive files, and editor backup -files; and other names that are usually artifacts of assorted utilities. -For an up to date list of ignored file names, see the Cederqvist manual (as -described in the SEE ALSO section of this manpage). -.SP -The outside source is saved in a first-level -branch, by default -.` "1.1.1". -Updates are leaves of this -branch; for example, files from the first imported collection of -source will be revision -.` "1.1.1.1", -then files from the first -imported update will be revision -.` "1.1.1.2", -and so on. -.SP -At least three arguments are required. \fIrepository\fP is needed to -identify the collection of source. \fIvendortag\fP is a tag for the -entire branch (e.g., for -.` "1.1.1"). -You must also specify at -least one \fIreleasetag\fR to uniquely identify the files at -the leaves created each time you execute -.` "cvs import". -The -\fIreleasetag\fR should be new, not previously existing in the -repository file, and uniquely identify the imported release. -.SP -One of the standard -.B cvs -command options is available: \fB\-m\fP -\fImessage\fP. If you do not specify a logging message with -\fB\-m\fP, your editor is invoked (as with \fBcommit\fP) to allow you -to enter one. -.SP -There are three additional special options. -.SP -Use -.` "\-d" -to specify that each file's time of last modification should be used -for the checkin date and time. -.SP -Use -.` "\-b \fIbranch\fP" -to specify a first-level branch other -than -.` "1.1.1". -.SP -Use -.` "\-I \fIname\fP" -to specify file names that should be -ignored during \fBimport\fP. You can use this option repeatedly. -To avoid ignoring any files at all (even those ignored by default), -specify -.` "\-I !". -.TP -\fBlog\fP [\fB\-l\fP] \fIrlog-options [files\fP\|.\|.\|.] -.I Requires: -repository, working directory. -.br -.I Changes: -nothing. -.br -.I Synonym: -.B rlog -.br -Display log information for \fIfiles\fP. -Among the more useful options are \fB\-h\fP -to display only the header (including tag definitions, but omitting -most of the full log); \fB\-r\fP to select logs on particular -revisions or ranges of revisions; and \fB\-d\fP to select particular -dates or date ranges. See -.BR rlog ( 1 ) -for full explanations. -This command is recursive by default, unless the -.B \-l -option is specified. -.TP -\fBrdiff\fP [\fB\-\fP\fIflags\fP] [\fB\-V\fP \fIvn\fP] [\fB\-r\fP \fIt\fP|\fB\-D\fP \fId\fP [\fB\-r\fP \fIt2\fP|\fB\-D\fP \fId2\fP]] \fImodules\|.\|.\|.\fP -.I Requires: -repository. -.br -.I Changes: -nothing. -.br -.I Synonym: -.B patch -.br -Builds a Larry Wall format -.BR patch ( 1 ) -file between two releases, that can be fed directly into the -.B patch -program to bring an old release up-to-date with the new release. -(This is one of the few \fBcvs\fP commands that operates directly from -the repository, and doesn't require a prior -.BR checkout .) -The diff output is sent to the standard output device. -You can specify (using the standard \fB\-r\fP and \fB\-D\fP options) -any combination of one or two revisions or dates. -If only one revision or date is specified, the -patch file reflects differences between that revision or date and the -current ``head'' revisions in the -.SM RCS -file. -.SP -Note that if the software release affected -is contained in more than one directory, then it may be necessary to -specify the -.B \-p -option to the -.B patch -command when patching the old sources, so that -.B patch -is able to find the files that are located in other directories. -.SP -The standard option \fIflags\fP \fB\-f\fP, and \fB\-l\fP -are available with this command. There are also several -special option flags: -.SP -If you use the -.B \-s -option, no patch output is produced. -Instead, a summary of the changed or added files between the two -releases is sent to the standard output device. -This is useful for finding out, for example, which files have changed -between two dates or revisions. -.SP -If you use the -.B \-t -option, a diff of the top two revisions is sent to the standard output device. -This is most useful for seeing what the last change to a file was. -.SP -If you use the -.B \-u -option, the patch output uses the newer ``unidiff'' format for context -diffs. -.SP -You can use -.B \-c -to explicitly specify the -.` "diff \-c" -form of context diffs -(which is the default), if you like. -.TP -\fBrelease\fP [\fB\-dQq\fP] \fImodules\fP\|.\|.\|. -.I Requires: -Working directory. -.br -.I Changes: -Working directory, history log. -.br -This command is meant to safely cancel the effect of -.` "cvs checkout". -Since -.B cvs -doesn't lock files, it isn't strictly necessary to use this command. -You can always simply delete your working directory, if you -like; but you risk losing changes you may have forgotten, and you -leave no trace in the -.B cvs -history file that you've abandoned your checkout. -.SP -Use -.` "cvs release" -to avoid these problems. This command -checks that no un-committed changes are present; that you are -executing it from immediately above, or inside, a \fBcvs\fP working -directory; and that the repository recorded for your files is the same -as the repository defined in the module database. -.SP -If all these conditions are true, -.` "cvs release" -leaves a -record of its execution (attesting to your intentionally abandoning -your checkout) in the -.B cvs -history log. -.SP -You can use the \fB\-d\fP flag to request that your working copies of -the source files be deleted if the \fBrelease\fP succeeds. -.TP -\fBremove\fP [\fB\-lR\fP] [\fIfiles\|.\|.\|.\fP] -.I Requires: -Working directory. -.br -.I Changes: -Working directory. -.br -.I Synonyms: -.BR rm ", " delete -.br -Use this command to declare that you wish to remove \fIfiles\fP from -the source repository. Like most -.B cvs -commands, -.` "cvs remove" -works on files in your working -directory, not directly on the repository. As a safeguard, it also -requires that you first erase the specified files from your working -directory. -.SP -The files are not actually removed until you apply your changes to the -repository with -.BR commit ; -at that point, the corresponding -.SM RCS -files in the source repository are -.I moved -into the -.` "Attic" -directory (also within the source repository). -.SP -This command is recursive by default, scheduling all physically removed -files that it finds for removal by the next -.BR commit . -Use the -.B \-l -option to avoid this recursion, or just specify that actual files that you -wish remove to consider. -.TP -\fBrtag\fP [\fB\-f\|alnRQq\fP] [\fB\-b\fP] [\fB\-d\fP] [\fB\-r\fP \fItag\fP | \fB\-D\fP \fIdate\fP] \fIsymbolic_tag\fP \fImodules\|.\|.\|.\fP -.I Requires: -repository. -.br -.I Changes: -repository. -.br -.I Synonym: -.B rfreeze -.br -You can use this command to assign symbolic tags to particular, -explicitly specified source versions in the repository. -.` "cvs rtag" -works directly on the repository contents (and requires no -prior -.BR checkout ). -Use -.` "cvs tag" -instead, to base the selection of -versions to tag on the contents of your working directory. -.SP -In general, tags (often the symbolic names of software distributions) -should not be removed, but the -.B \-d -option is available as a means to remove completely obsolete symbolic names -if necessary (as might be the case for an Alpha release, say). -.SP -.` "cvs rtag" -will not move a tag that already exists. With the \fB\-F\fP option, -however, -.` "cvs rtag" -will re-locate any instance of \fIsymbolic_tag\fP that already exists -on that file to the new repository versions. Without the \fB\-F\fP -option, attempting to use -.` "cvs rtag" -to apply a tag that already exists on that file will produce an error -message. -.SP -The \fB-b\fP option makes the tag a ``branch'' tag, allowing -concurrent, isolated development. -This is most useful for creating a patch to a previously released software -distribution. -.SP -You can use the standard \fB\-r\fP and \fB\-D\fP options to tag only those -files that already contain a certain tag. This method would be used -to rename a tag: tag only the files identified by the old tag, then delete the -old tag, leaving the new tag on exactly the same files as the old tag. -.SP -.B rtag -executes recursively by default, tagging all subdirectories of -\fImodules\fP you specify in the argument. You can restrict its -operation to top-level directories with the standard \fB\-l\fP option; -or you can explicitly request recursion with \fB\-R\fP. -.SP -The modules database can specify a program to execute whenever a tag -is specified; a typical use is to send electronic mail to a group of -interested parties. If you want to bypass that program, use the -standard \fB\-n\fP option. -.SP -Use the -.B \-a -option to have -.B rtag -look in the -.` "Attic" -for removed files that contain the specified tag. -The tag is removed from these files, which makes it convenient to re-use a -symbolic tag as development continues (and files get removed from the -up-coming distribution). -.TP -\fBstatus\fP [\fB\-lRqQ\fP] [\fB\-v\fP] [\fIfiles\fP\|.\|.\|.] -.I Requires: -working directory, repository. -.br -.I Changes: -nothing. -.br -Display a brief report on the current status of \fIfiles\fP with -respect to the source repository, including any ``sticky'' tags, -dates, or \fB\-k\fP options. (``Sticky'' options will restrict how -.` "cvs update" -operates until you reset them; see the -description of -.` "cvs update \-A\|.\|.\|.".) -.SP -You can also use this command to anticipate the potential impact of a -.` "cvs update" -on your working source directory. If you do -not specify any \fIfiles\fP explicitly, reports are shown for all -files that \fBcvs\fP has placed in your working directory. You can -limit the scope of this search to the current directory itself (not -its subdirectories) with the standard \fB\-l\fP option flag; or you -can explicitly request recursive status reports with the \fB\-R\fP -option. -.SP -The -.B \-v -option causes the symbolic tags for the -.SM RCS -file to be displayed as well. -.TP -\fBtag\fP [\fB\-lQqR\fP] [\fB\-F\fP] [\fB\-b\fP] [\fB\-d\fP] [\fB\-r\fP \fItag\fP | \fB\-D\fP \fIdate\fP] [\fB\-f\fP] \fIsymbolic_tag\fP [\fIfiles\fP\|.\|.\|.\|] -.I Requires: -working directory, repository. -.br -.I Changes: -repository. -.br -.I Synonym: -.B freeze -.br -Use this command to assign symbolic tags to the nearest repository -versions to your working sources. The tags are applied immediately to -the repository, as with \fBrtag\fP. -.SP -One potentially surprising aspect of the fact that \fBcvs tag\fP -operates on the repository is that you are tagging the checked-in -revisions, which may differ from locally modified files in your working -directory. If you want to avoid doing this by mistake, specify the -\fB-c\fP option to \fBcvs tag\fP. If there are any locally modified files, CVS -will abort with an error before it tags any files. -.SP -One use for tags is to record a ``snapshot'' of the current sources -when the software freeze date of a project arrives. As bugs are fixed -after the freeze date, only those changed sources that are to be part -of the release need be re-tagged. -.SP -The symbolic tags are meant to permanently record which revisions of which -files were used in creating a software distribution. -The -.BR checkout , -.B export -and -.B update -commands allow you to extract an exact copy of a tagged release at any time in -the future, regardless of whether files have been changed, added, or removed -since the release was tagged. -.SP -You can use the standard \fB\-r\fP and \fB\-D\fP options to tag only those -files that already contain a certain tag. This method would be used -to rename a tag: tag only the files identified by the old tag, then delete the -old tag, leaving the new tag on exactly the same files as the old tag. -.SP -Specifying the \fB\-f\fP flag in addition to the \fB\-r\fP or \fB\-D\fP -flags will tag those files named on the command line even if they do not -contain the old tag or did not exist on the specified date. -.SP -By default (without a \fB\-r\fP or \fB\-D\fP flag) -the versions to be tagged are supplied -implicitly by the \fBcvs\fP records of your working files' history -rather than applied explicitly. -.SP -If you use -.` "cvs tag \-d \fIsymbolic_tag\fP\|.\|.\|.", -the -symbolic tag you specify is -.I deleted -instead of being added. \fIWarning\fP: Be very certain of your ground -before you delete a tag; doing this effectively discards some -historical information, which may later turn out to have been valuable. -.SP -.` "cvs tag" -will not move a tag that already exists. With the \fB\-F\fP option, -however, -.` "cvs tag" -will re-locate any instance of \fIsymbolic_tag\fP that already exists -on that file to the new repository versions. Without the \fB\-F\fP -option, attempting to use -.` "cvs tag" -to apply a tag that already exists on that file will produce an error -message. -.SP -The \fB-b\fP option makes the tag a ``branch'' tag, allowing -concurrent, isolated development. -This is most useful for creating a patch to a previously released software -distribution. -.SP -Normally, -.B tag -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\-ACdf\|lPpQqR\fP] [\fB\-d\fP] [\fB\-r\fP \fItag\fP|\fB\-D\fP \fIdate\fP] \fIfiles\|.\|.\|.\fP -.I Requires: -repository, working directory. -.br -.I Changes: -working directory. -.br -After you've run -.B checkout -to create your private copy of source from the common repository, -other developers will continue changing the central source. From time -to time, when it is convenient in your development process, you can -use the -.B update -command -from within your working directory to reconcile your work with any -revisions applied to the source repository since your last -.B checkout -or -.BR update . -.SP -.B update -keeps you informed of its progress by printing a line for each file, -prefaced with one of the characters -.` "U P A R M C ?" -to indicate the status of the file: -.TP 1i -\fBU\fP \fIfile\fP -The file was brought \fIup to date\fP with respect to the repository. -This is done for any file that exists in the repository but not in your -working directory, and for files that you haven't changed but are not the most -recent versions available in the repository. -.TP 1i -\fBP\fP \fIfile\fP -Like \fBU\fP, but the CVS server sends a patch instead of an entire file. -This accomplishes the same thing as \fBU\fP using less bandwidth. -.TP 1i -\fBA\fP \fIfile\fP -The file has been \fIadded\fP to your private copy of the sources, and -will be added to the -source repository when you run -.` "cvs commit" -on the file. -This is a reminder to you that the file needs to be committed. -.TP 1i -\fBR\fP \fIfile\fP -The file has been \fIremoved\fP from your private copy of the sources, and -will be removed from the -source repository when you run -.` "cvs commit" -on the file. -This is a reminder to you that the file needs to be committed. -.TP 1i -\fBM\fP \fIfile\fP -The file is \fImodified\fP in your working directory. -.` "M" -can indicate one of two states for a file you're working on: either -there were no modifications to the same file in the repository, so -that your file remains as you last saw it; or there were modifications -in the repository as well as in your copy, but they were -\fImerged\fP successfully, without conflict, in your working -directory. -.TP 1i -\fBC\fP \fIfile\fP -A \fIconflict\fP was detected while trying to merge your changes to -\fIfile\fP with changes from the source repository. \fIfile\fP (the -copy in your working directory) is now the result of merging -the two versions; an unmodified copy of your file is also -in your working directory, with the name `\fB.#\fP\fIfile\fP\fB.\fP\fIversion\fP', -where -.I version -is the -revision that your modified file started from. -(Note that some systems automatically purge files that begin with -\& -.` ".#" -if they have not been accessed for a few days. -If you intend to keep a copy of your original file, it is a very good -idea to rename it.) -.TP 1i -\fB?\fP \fIfile\fP -\fIfile\fP is in your working directory, but does not correspond to -anything in the source repository, and is not in the list of files -for \fBcvs\fP to ignore (see the description of the \fB\-I\fP option). -.PP -.RS .5i -.SP -Use the -.B \-A -option to reset any sticky tags, dates, or -.B \-k -options. (If you get a working copy of a file by using one of the -\fB\-r\fP, \fB\-D\fP, or \fB\-k\fP options, \fBcvs\fP remembers the -corresponding tag, date, or \fIkflag\fP and continues using it on -future updates; use the \fB\-A\fP option to make \fBcvs\fP forget these -specifications, and retrieve the ``head'' version of the file). -.SP -The \fB\-j\fP\fIbranch\fP option -merges the changes made between the -resulting revision and the revision that it is based on (e.g., if -the tag refers to a branch, -.B cvs -will merge all changes made in -that branch into your working file). -.SP -With two \fB-j\fP options, -.B cvs -will merge in the changes between the two respective revisions. -This can be used to ``remove'' a certain delta from your working file. -E.g., If the file foo.c is based on -revision 1.6 and I want to remove the changes made between 1.3 and -1.5, I might do: -.SP -.in +1i -.ft B -.nf -example% cvs update -j1.5 -j1.3 foo.c # note the order... -.fi -.ft P -.in -1i -.SP -In addition, each \fB-j\fP option can contain on optional date -specification which, when used with branches, can limit the chosen -revision to one within a specific date. -An optional date is specified by adding a colon (:) to the tag. -.SP -.in +1i -.ft B -.nf --jSymbolic_Tag:Date_Specifier -.fi -.ft P -.in -1i -.SP -Use the -.B \-d -option to create any directories that exist in the repository if they're -missing from the working directory. (Normally, update acts only on -directories and files that were already enrolled in your -working directory.) This is useful for updating directories -that were created in the repository since the initial -\fBcheckout\fP; but it has an unfortunate side effect. If you -deliberately avoided certain directories in the repository when you -created your working directory (either through use of a module name or by -listing explicitly the files and directories you wanted on the -command line), then updating with -.B \-d -will create those directories, which may not be what you want. -.SP -Use \fB\-I\fP \fIname\fP to ignore files whose names match \fIname\fP -(in your working directory) during the update. You can specify -\fB\-I\fP more than once on the command line to specify several files -to ignore. By default, -\fBupdate\fP ignores files whose names match certain patterns; for -an up to date list of ignored file names, see the Cederqvist manual (as -described in the SEE ALSO section of this manpage). -.SP -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. -.RE -.SH "FILES" -For more detailed information on -.B cvs -supporting files, see -.BR cvs ( 5 ). -.LP -.I -Files in home directories: -.TP -\&.cvsrc -The -.B cvs -initialization file. Lines in this file can be used to specify default -options for each -.B cvs -command. For example the line -.` "diff \-c" -will ensure that -.` "cvs diff" -is always passed the -.B \-c -option in addition to any other options passed on the command line. -.TP -\&.cvswrappers -Specifies wrappers to be used in addition to those specified in the -CVSROOT/cvswrappers file in the repository. -.LP -.I -Files in working directories: -.TP -CVS -A directory of \fBcvs\fP administrative files. -.I -Do not delete. -.TP -CVS/Entries -List and status of files in your working directory. -.TP -CVS/Entries.Backup -A backup of -.` "CVS/Entries". -.TP -CVS/Entries.Static -Flag: do not add more entries on -.` "cvs update". -.TP -CVS/Root -Pathname to the repository ( -.SM CVSROOT -) location at the time of checkout. This file is used instead -of the -.SM CVSROOT -environment variable if the environment variable is not -set. A warning message will be issued when the contents of this -file and the -.SM CVSROOT -environment variable differ. The file may be over-ridden by the -presence of the -.SM CVS_IGNORE_REMOTE_ROOT -environment variable. -.TP -CVS/Repository -Pathname to the corresponding directory in the source repository. -.TP -CVS/Tag -Contains the per-directory ``sticky'' tag or date information. -This file is created/updated when you specify -.B \-r -or -.B \-D -to the -.B checkout -or -.B update -commands, and no files are specified. -.TP -CVS/Checkin.prog -Name of program to run on -.` "cvs commit". -.TP -CVS/Update.prog -Name of program to run on -.` "cvs update". -.LP -.I -Files in source repositories: -.TP -$CVSROOT/CVSROOT -Directory of global administrative files for repository. -.TP -CVSROOT/commitinfo,v -Records programs for filtering -.` "cvs commit" -requests. -.TP -CVSROOT/cvswrappers,v -Records -.B cvs -wrapper commands to be used when checking files into and out of the -repository. Wrappers allow the file or directory to be processed -on the way in and out of CVS. The intended uses are many, one -possible use would be to reformat a C file before the file is checked -in, so all of the code in the repository looks the same. -.TP -CVSROOT/editinfo,v -Records programs for editing/validating -.` "cvs commit" -log entries. -.TP -CVSROOT/history -Log file of \fBcvs\fP transactions. -.TP -CVSROOT/loginfo,v -Records programs for piping -.` "cvs commit" -log entries. -.TP -CVSROOT/modules,v -Definitions for modules in this repository. -.TP -CVSROOT/rcsinfo,v -Records pathnames to templates used during a -.` "cvs commit" -operation. -.TP -CVSROOT/taginfo,v -Records programs for validating/logging -.` "cvs tag" -and -.` "cvs rtag" -operations. -.TP -MODULE/Attic -Directory for removed source files. -.TP -#cvs.lock -A lock directory created by -.B cvs -when doing sensitive changes to the -source repository. -.TP -#cvs.tfl.\fIpid\fP -Temporary lock file for repository. -.TP -#cvs.rfl.\fIpid\fP -A read lock. -.TP -#cvs.wfl.\fIpid\fP -A write lock. -.SH "ENVIRONMENT" -.TP -.SM CVSROOT -Should contain the full pathname to the root of the -.B cvs -source repository (where the -.SM RCS -files are kept). This information must be available to \fBcvs\fP for -most commands to execute; if -.SM CVSROOT -is not set, or if you wish to override it for one invocation, you can -supply it on the command line: -.` "cvs \-d \fIcvsroot cvs_command\fP\|.\|.\|." -You may not need to set -.SM CVSROOT -if your \fBcvs\fP binary has the right path compiled in. -.TP -.SM CVSREAD -If this is set, -.B checkout -and -.B update -will try hard to make the files in your working directory read-only. -When this is not set, the default behavior is to permit modification -of your working files. -.TP -.SM CVSREADONLYFS -If this is set, the -.B \-R -option is assumed, and -.B cvs -operates in read-only repository mode. -.TP -.SM RCSBIN -Specifies the full pathname where to find -.SM RCS -programs, such as -.BR co ( 1 ) -and -.BR ci ( 1 ) -(CVS 1.9 and older). -.TP -.SM CVSEDITOR -Specifies the program to use for recording log messages during -.BR commit . -If not set, the -.SM VISUAL -and -.SM EDITOR -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_CLIENT_PORT -If this variable is set then -.B cvs -will use this port in -\fIpserver mode\fP -rather than the default port (cvspserver 2401). -.TP -.SM CVS_IGNORE_REMOTE_ROOT -If this variable is set then -.B cvs -will ignore all references to remote repositories in the CVS/Root file. -.TP -.SM CVS_OPTIONS -Specifies a set of default options for -.B cvs. -These options are interpreted before the startup file (\fI~/.cvsrc\fP) is read -and can be overridden by explicit command line parameters. -.TP -.SM CVS_RSH -.B cvs -uses the contents of this variable to determine the name of the -remote shell command to use when starting a -.B cvs -server. If this variable is not set then -.` "ssh" -is used. -.TP -.SM CVS_SERVER -.B cvs -uses the contents of this variable to determine the name of the -.B cvs -server command. If this variable is not set then -.` "cvs" -is used. -.TP -.SM CVSWRAPPERS -This variable is used by the -.` "cvswrappers" -script to determine the name of the wrapper file, in addition to the -wrappers defaults contained in the repository -.SM (CVSROOT/cvswrappers) -and the user's home directory (~/.cvswrappers). -.SH "AUTHORS" -.TP -Dick Grune -Original author of the -.B cvs -shell script version posted to -.B comp.sources.unix -in the volume6 release of December, 1986. -Credited with much of the -.B cvs -conflict resolution algorithms. -.TP -Brian Berliner -Coder and designer of the -.B cvs -program itself in April, 1989, based on the original work done by Dick. -.TP -Jeff Polk -Helped Brian with the design of the -.B cvs -module and vendor branch support and author of the -.BR checkin ( 1 ) -shell script (the ancestor of -.` "cvs import"). -.TP -And many others too numerous to mention here. -.SH "SEE ALSO" -The most comprehensive manual for CVS is -Version Management with CVS by Per Cederqvist et al. Depending on -your system, you may be able to get it with the -.B info cvs -command or it may be available as cvs.ps (postscript), cvs.texinfo -(texinfo source), or cvs.html. -.SP -For CVS updates, more information on documentation, software related -to CVS, development of CVS, and more, see: -.in +1i -.B http://cvs.nongnu.org -.in -1i -.SP -.BR ci ( 1 ), -.BR co ( 1 ), -.BR cvs ( 5 ), -.BR cvsbug ( 8 ), -.BR diff ( 1 ), -.BR grep ( 1 ), -.BR patch ( 1 ), -.BR rcs ( 1 ), -.BR rcsdiff ( 1 ), -.BR rcsmerge ( 1 ), -.BR rlog ( 1 ). diff --git a/contrib/cvs/man/cvs.5 b/contrib/cvs/man/cvs.5 deleted file mode 100644 index 589f067..0000000 --- a/contrib/cvs/man/cvs.5 +++ /dev/null @@ -1,330 +0,0 @@ -.TH cvs 5 "12 February 1992" -.\" Full space in nroff; half space in troff -.de SP -.if n .sp -.if t .sp .5 -.. -.SH NAME -cvs \- Concurrent Versions System support files -.SH NOTE -This documentation may no longer be up to date. Please consult the Cederqvist -(CVS Manual) as specified in -.BR cvs ( 1 ). - -.SH SYNOPSIS -.hy 0 -.na -.TP -.B $CVSROOT/CVSROOT/commitinfo,v -.TP -.B $CVSROOT/CVSROOT/cvsignore,v -.TP -.B $CVSROOT/CVSROOT/cvswrappers,v -.TP -.B $CVSROOT/CVSROOT/editinfo,v -.TP -.B $CVSROOT/CVSROOT/history -.TP -.B $CVSROOT/CVSROOT/loginfo,v -.TP -.B $CVSROOT/CVSROOT/modules,v -.TP -.B $CVSROOT/CVSROOT/rcsinfo,v -.TP -.B $CVSROOT/CVSROOT/taginfo,v -.ad b -.hy 1 -.SH DESCRIPTION -.B cvs -is a system for providing source control to hierarchical collections -of source directories. Commands and procedures for using \fBcvs\fP -are described in -.BR cvs ( 1 ). -.SP -.B cvs -manages \fIsource repositories\fP, the directories containing master -copies of the revision-controlled files, by copying particular -revisions of the files to (and modifications back from) developers' -private \fIworking directories\fP. In terms of file structure, each -individual source repository is an immediate subdirectory of -\fB$CVSROOT\fP. -.SP -The files described here are supporting files; they do not have to -exist for \fBcvs\fP to operate, but they allow you to make \fBcvs\fP -operation more flexible. -.SP -You can use the `\|modules\|' file to define symbolic names for -collections of source maintained with \fBcvs\fP. If there is no -`\|modules\|' file, developers must specify complete path names -(absolute, or relative to \fB$CVSROOT\fP) for the files they wish to -manage with \fBcvs\fP commands. -.SP -You can use the `\|commitinfo\|' file to define programs to execute -whenever `\|\fBcvs commit\fP\|' is about to execute. -These programs are used for ``pre-commit'' checking to verify that the -modified, added, and removed files are really ready to be committed. -Some uses for this check might be to turn off a portion (or all) of the -source repository from a particular person or group. -Or, perhaps, to verify that the changed files conform to the site's -standards for coding practice. -.SP -You can use the `\|cvswrappers\|' file to record -.B cvs -wrapper commands to be used when checking files into and out of the -repository. Wrappers allow the file or directory to be processed -on the way in and out of CVS. The intended uses are many, one -possible use would be to reformat a C file before the file is checked -in, so all of the code in the repository looks the same. -.SP -You can use the `\|loginfo\|' file to define programs to execute after -any -.BR commit , -which writes a log entry for changes in the repository. -These logging programs might be used to append the log message to a file. -Or send the log message through electronic mail to a group of developers. -Or, perhaps, post the log message to a particular newsgroup. -.SP -You can use the `\|taginfo\|' file to define programs to execute after -any -.BR tag or rtag -operation. These programs might be used to append a message to a file -listing the new tag name and the programmer who created it, or send mail -to a group of developers, or, perhaps, post a message to a particular -newsgroup. -.SP -You can use the `\|rcsinfo\|' file to define forms for log messages. -.SP -You can use the `\|editinfo\|' file to define a program to execute for -editing/validating `\|\fBcvs commit\fP\|' log entries. -This is most useful when used with a `\|rcsinfo\|' forms specification, as -it can verify that the proper fields of the form have been filled in by the -user committing the change. -.SP -You can use the `\|cvsignore\|' file to specify the default list of -files to ignore during \fBupdate\fP. -.SP -You can use the `\|history\|' file to record the \fBcvs\fP commands -that affect the repository. -The creation of this file enables history logging. -.SH FILES -.TP -.B modules -The `\|modules\|' file records your definitions of names for -collections of source code. \fBcvs\fP will use these definitions if -you use \fBcvs\fP to check in a file with the right format to -`\|\fB$CVSROOT/CVSROOT/modules,v\fP\|'. -.SP -The `\|modules\|' file may contain blank lines and comments (lines -beginning with `\|\fB#\fP\|') as well as module definitions. -Long lines can be continued on the next line by specifying a backslash -(``\e'') as the last character on the line. -.SP -A \fImodule definition\fP is a single line of the `\|modules\|' file, -in either of two formats. In both cases, \fImname\fP represents the -symbolic module name, and the remainder of the line is its definition. -.SP -\fImname\fP \fB\-a\fP \fIaliases\fP\|.\|.\|. -.br -This represents the simplest way of defining a module \fImname\fP. -The `\|\fB\-a\fP\|' flags the definition as a simple alias: \fBcvs\fP -will treat any use of \fImname\fP (as a command argument) as if the list -of names \fIaliases\fP had been specified instead. \fIaliases\fP may -contain either other module names or paths. When you use paths in -\fIaliases\fP, `\|\fBcvs checkout\fP\|' creates all intermediate -directories in the working directory, just as if the path had been -specified explicitly in the \fBcvs\fP arguments. -.SP -.nf -\fImname\fP [ \fIoptions\fP ] \fIdir\fP [ \fIfiles\fP\|.\|.\|. ] [ \fB&\fP\fImodule\fP\|.\|.\|. ] -.fi -.SP -In the simplest case, this form of module definition reduces to -`\|\fImname dir\fP\|'. This defines all the files in directory -\fIdir\fP as module \fImname\fP. \fIdir\fP is a relative path (from -\fB$CVSROOT\fP) to a directory of source in one of the source -repositories. In this case, on \fBcheckout\fP, a single directory -called \fImname\fP is created as a working directory; no intermediate -directory levels are used by default, even if \fIdir\fP was a path -involving several directory levels. -.SP -By explicitly specifying \fIfiles\fP in the module definition after -\fIdir\fP, you can select particular files from directory -\fIdir\fP. The sample definition for \fBmodules\fP is an example of -a module defined with a single file from a particular directory. Here -is another example: -.SP -.nf -.ft B -m4test unsupported/gnu/m4 foreach.m4 forloop.m4 -.ft P -.fi -.SP -With this definition, executing `\|\fBcvs checkout m4test\fP\|' -will create a single working directory `\|m4test\|' containing the two -files listed, which both come from a common directory several levels -deep in the \fBcvs\fP source repository. -.SP -A module definition can refer to other modules by including -`\|\fB&\fP\fImodule\fP\|' in its definition. \fBcheckout\fP creates -a subdirectory for each such \fImodule\fP, in your working directory. -.br -.I -New in \fBcvs\fP 1.3; -avoid this feature if sharing module definitions with older versions -of \fBcvs\fP. -.SP -Finally, you can use one or more of the following \fIoptions\fP in -module definitions: -.SP -\&`\|\fB\-d\fP \fIname\fP\|', to name the working directory something -other than the module name. -.br -.I -New in \fBcvs\fP 1.3; -avoid this feature if sharing module definitions with older versions -of \fBcvs\fP. -.SP -\&`\|\fB\-i\fP \fIprog\fP\|' allows you to specify a program \fIprog\fP -to run whenever files in a module are committed. \fIprog\fP runs with a -single argument, the full pathname of the affected directory in a -source repository. The `\|commitinfo\|', `\|loginfo\|', and -`\|editinfo\|' files provide other ways to call a program on \fBcommit\fP. -.SP -`\|\fB\-o\fP \fIprog\fP\|' allows you to specify a program \fIprog\fP -to run whenever files in a module are checked out. \fIprog\fP runs -with a single argument, the module name. -.SP -`\|\fB\-e\fP \fIprog\fP\|' allows you to specify a program \fIprog\fP -to run whenever files in a module are exported. \fIprog\fP runs -with a single argument, the module name. -.SP -`\|\fB\-t\fP \fIprog\fP\|' allows you to specify a program \fIprog\fP -to run whenever files in a module are tagged. \fIprog\fP runs with two -arguments: the module name and the symbolic tag specified to \fBrtag\fP. -.SP -`\|\fB\-u\fP \fIprog\fP\|' allows you to specify a program \fIprog\fP -to run whenever `\|\fBcvs update\fP\|' is executed from the top-level -directory of the checked-out module. \fIprog\fP runs with a -single argument, the full path to the source repository for this module. -.TP -\&\fBcommitinfo\fP, \fBloginfo\fP, \fBrcsinfo\fP, \fBeditinfo\fP -These files all specify programs to call at different points in the -`\|\fBcvs commit\fP\|' process. They have a common structure. -Each line is a pair of fields: a regular expression, separated by -whitespace from a filename or command-line template. -Whenever one of the regular expression matches a directory name in the -repository, the rest of the line is used. -If the line begins with a \fB#\fP character, the entire line is considered -a comment and is ignored. -Whitespace between the fields is also ignored. -.SP -For `\|loginfo\|', the rest of the -line is a command-line template to execute. -The templates can include not only -a program name, but whatever list of arguments you wish. If you write -`\|\fB%s\fP\|' somewhere on the argument list, \fBcvs\fP supplies, at -that point, the list of files affected by the \fBcommit\fP. -The first entry in the list is the relative path within the source -repository where the change is being made. -The remaining arguments list the files that are being modified, added, or -removed by this \fBcommit\fP invocation. -.SP -For `\|taginfo\|', the rest of the -line is a command-line template to execute. -The arguments passed to the command are, in order, the -.I tagname , -.I operation -(i.e. -.B add -for `tag', -.B mov -for `tag -F', and -.B del -for `tag -d`), -.I repository , -and any remaining are pairs of -.B "filename revision" . -A non-zero exit of the filter program will cause the tag to be aborted. -.SP -For `\|commitinfo\|', the rest of the line is a command-line template to -execute. -The template can include not only a program name, but whatever -list of arguments you wish. -The full path to the current source repository is appended to the template, -followed by the file names of any files involved in the commit (added, -removed, and modified files). -.SP -For `\|rcsinfo\|', the rest of the line is the full path to a file that -should be loaded into the log message template. -.SP -For `\|editinfo\|', the rest of the line is a command-line template to -execute. -The template can include not only a program name, but whatever -list of arguments you wish. -The full path to the current log message template file is appended to the -template. -.SP -You can use one of two special strings instead of a regular -expression: `\|\fBALL\fP\|' specifies a command line template that -must always be executed, and `\|\fBDEFAULT\fP\|' specifies a command -line template to use if no regular expression is a match. -.SP -The `\|commitinfo\|' file contains commands to execute \fIbefore\fP any -other \fBcommit\fP activity, to allow you to check any conditions that -must be satisfied before \fBcommit\fP can proceed. The rest of the -\fBcommit\fP will execute only if all selected commands from this file -exit with exit status \fB0\fP. -.SP -The `\|rcsinfo\|' file allows you to specify \fIlog templates\fP for -the \fBcommit\fP logging session; you can use this to provide a form -to edit when filling out the \fBcommit\fP log. The field after the -regular expression, in this file, contains filenames (of files -containing the logging forms) rather than command templates. -.SP -The `\|editinfo\|' file allows you to execute a script \fIbefore the -commit starts\fP, but after the log information is recorded. These -"edit" scripts can verify information recorded in the log file. If -the edit script exits with a non-zero exit status, the commit is aborted. -.SP -The `\|loginfo\|' file contains commands to execute \fIat the end\fP -of a commit. The text specified as a commit log message is piped -through the command; typical uses include sending mail, filing an -article in a newsgroup, or appending to a central file. -.TP -\&\fBcvsignore\fP, \fB.cvsignore\fP -The default list of files (or -.BR sh ( 1 ) -file name patterns) to ignore during `\|\fBcvs update\fP\|'. -At startup time, \fBcvs\fP loads the compiled in default list of file name -patterns (see -.BR cvs ( 1 )). -Then the per-repository list included in \fB$CVSROOT/CVSROOT/cvsignore\fP -is loaded, if it exists. -Then the per-user list is loaded from `\|$HOME/.cvsignore\|'. -Finally, as \fBcvs\fP traverses through your directories, it will load any -per-directory `\|.cvsignore\|' files whenever it finds one. -These per-directory files are only valid for exactly the directory that -contains them, not for any sub-directories. -.TP -.B history -Create this file in \fB$CVSROOT/CVSROOT\fP to enable history logging -(see the description of `\|\fBcvs history\fP\|'). -.SH "SEE ALSO" -.BR cvs ( 1 ), -.SH COPYING -Copyright \(co 1992 Cygnus Support, Brian Berliner, and Jeff Polk -.PP -Permission is granted to make and distribute verbatim copies of -this manual provided the copyright notice and this permission notice -are preserved on all copies. -.PP -Permission is granted to copy and distribute modified versions of this -manual under the conditions for verbatim copying, provided that the -entire resulting derived work is distributed under the terms of a -permission notice identical to this one. -.PP -Permission is granted to copy and distribute translations of this -manual into another language, under the above conditions for modified -versions, except that this permission notice may be included in -translations approved by the Free Software Foundation instead of in -the original English. diff --git a/contrib/cvs/man/cvsbug.8 b/contrib/cvs/man/cvsbug.8 deleted file mode 100644 index 460ca46..0000000 --- a/contrib/cvs/man/cvsbug.8 +++ /dev/null @@ -1,244 +0,0 @@ -.\" -*- nroff -*- -.\" --------------------------------------------------------------------------- -.\" man page for send-pr (by Heinz G. Seidl, hgs@cygnus.com) -.\" updated Feb 1993 for GNATS 3.00 by Jeffrey Osier, jeffrey@cygnus.com -.\" -.\" This file is part of the Problem Report Management System (GNATS) -.\" Copyright 1992 Cygnus Support -.\" -.\" This program is free software; you can redistribute it and/or -.\" modify it under the terms of the GNU General Public -.\" License as published by the Free Software Foundation; either -.\" version 2 of the License, or (at your option) any later version. -.\" -.\" This program is distributed in the hope that it will be useful, -.\" but WITHOUT ANY WARRANTY; without even the implied warranty of -.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -.\" General Public License for more details. -.\" -.\" --------------------------------------------------------------------------- -.\" $FreeBSD$ -.nh -.TH CVSBUG 8 xVERSIONx "February 1993" -.SH NAME -cvsbug \- send problem report (PR) about CVS to a central support site -.SH SYNOPSIS -.B cvsbug -[ -.I site -] -[ -.B \-f -.I problem-report -] -[ -.B \-t -.I mail-address -] -.br -.in +0.8i -[ -.B \-P -] -[ -.B \-L -] -[ -.B \-\-request-id -] -[ -.B \-v -] -.SH DESCRIPTION -.B cvsbug -is a tool used to submit -.I problem reports -.\" SITE ADMINISTRATORS - change this if you use a local default -(PRs) to a central support site. In most cases the correct -.I site -will be the default. This argument indicates the support site which -is responsible for the category of problem involved. Some sites may -use a local address as a default. -.I site -values are defined by using the -.BR aliases (5). -.LP -.B cvsbug -invokes an editor on a problem report template (after trying to fill -in some fields with reasonable default values). When you exit the -editor, -.B cvsbug -sends the completed form to the -.I Problem Report Management System -(\fBGNATS\fR) at a central support site. At the support site, the PR -is assigned a unique number and is stored in the \fBGNATS\fR database -according to its category and submitter-id. \fBGNATS\fR automatically -replies with an acknowledgement, citing the category and the PR -number. -.LP -To ensure that a PR is handled promptly, it should contain your (unique) -\fIsubmitter-id\fR and one of the available \fIcategories\fR to identify the -problem area. (Use -.B `cvsbug -L' -to see a list of categories.) -.LP -The -.B cvsbug -template at your site should already be customized with your -submitter-id (running `\|\fBinstall-sid\fP \fIsubmitter-id\fP\|' to -accomplish this is part of the installation procedures for -.BR cvsbug ). -If this hasn't been done, see your system administrator for your -submitter-id, or request one from your support site by invoking -.B `cvsbug \-\-request\-id'. -If your site does not distinguish between different user sites, or if -you are not affiliated with the support site, use -.B `net' -for this field. -.LP -The more precise your problem description and the more complete your -information, the faster your support team can solve your problems. -.SH OPTIONS -.TP -.BI \-f " problem-report" -specify a file (\fIproblem-report\fR) which already contains a -complete problem report. -.B cvsbug -sends the contents of the file without invoking the editor. If -the value for -.I problem-report -is -.BR `\|\-\|' , -then -.B cvsbug -reads from standard input. -.TP -.BI \-t " mail-address" -Change mail address at the support site for problem reports. The -default -.I mail-address -is the address used for the default -.IR site . -Use the -.I site -argument rather than this option in nearly all cases. -.TP -.B \-P -print the form specified by the environment variable -.B PR_FORM -on standard output. If -.B PR_FORM -is not set, print the standard blank PR template. No mail is sent. -.TP -.B -L -print the list of available categories. No mail is sent. -.TP -.B \-\-request\-id -sends mail to the default support site, or -.I site -if specified, with a request for your -.IR submitter-id . -If you are -not affiliated with -.IR site , -use a -.I submitter-id -of -.BR net \|'. -.TP -.B \-v -Display the -.B cvsbug -version number. -.LP -Note: use -.B cvsbug -to submit problem reports rather than mailing them directly. Using -both the template and -.B cvsbug -itself will help ensure all necessary information will reach the -support site. -.SH ENVIRONMENT -The environment variable -.B EDITOR -specifies the editor to invoke on the template. -.br -default: -.B vi -.sp -If the environment variable -.B PR_FORM -is set, then its value is used as the file name of the template for -your problem-report editing session. You can use this to start with a -partially completed form (for example, a form with the identification -fields already completed). -.SH "HOW TO FILL OUT A PROBLEM REPORT" -Problem reports have to be in a particular form so that a program can -easily manage them. Please remember the following guidelines: -.IP \(bu 3m -describe only -.B one problem -with each problem report. -.IP \(bu 3m -For follow-up mail, use the same subject line as the one in the automatic -acknowledgement. It consists of category, PR number and the original synopsis -line. This allows the support site to relate several mail messages to a -particular PR and to record them automatically. -.IP \(bu 3m -Please try to be as accurate as possible in the subject and/or synopsis line. -.IP \(bu 3m -The subject and the synopsis line are not confidential. This is -because open-bugs lists are compiled from them. Avoid confidential -information there. -.LP -See the GNU -.B Info -file -.B cvsbug.info -or the document \fIReporting Problems With cvsbug\fR\ for detailed -information on reporting problems -.SH "HOW TO SUBMIT TEST CASES, CODE, ETC." -Submit small code samples with the PR. Contact the support site for -instructions on submitting larger test cases and problematic source -code. -.SH FILES -.ta \w'/tmp/pbad$$ 'u -/tmp/p$$ copy of PR used in editing session -.br -/tmp/pf$$ copy of empty PR form, for testing purposes -.br -/tmp/pbad$$ file for rejected PRs -.SH INSTALLATION AND CONFIGURATION -See -.B INSTALL -for installation instructions. -.SH SEE ALSO -.BR gnats (l), -.BR query-pr (1), -.BR edit-pr (1), -.BR gnats (8), -.BR queue-pr (8), -.BR at-pr (8), -.BR mkcat (8), -.BR mkdist (8). -.SH AUTHORS -Jeffrey Osier, Brendan Kehoe, Jason Merrill, Heinz G. Seidl (Cygnus -Support) -.SH COPYING -Copyright (c) 1992, 1993 Free Software Foundation, Inc. -.PP -Permission is granted to make and distribute verbatim copies of -this manual provided the copyright notice and this permission notice -are preserved on all copies. -.PP -Permission is granted to copy and distribute modified versions of this -manual under the conditions for verbatim copying, provided that the -entire resulting derived work is distributed under the terms of a -permission notice identical to this one. -.PP -Permission is granted to copy and distribute translations of this -manual into another language, under the above conditions for modified -versions, except that this permission notice may be included in -translations approved by the Free Software Foundation instead of in -the original English. - diff --git a/contrib/cvs/mdate-sh b/contrib/cvs/mdate-sh deleted file mode 100755 index 0c88e75..0000000 --- a/contrib/cvs/mdate-sh +++ /dev/null @@ -1,92 +0,0 @@ -#!/bin/sh -# Get modification time of a file or directory and pretty-print it. -# Copyright 1995, 1996, 1997 Free Software Foundation, Inc. -# written by Ulrich Drepper , June 1995 -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -# Prevent date giving response in another language. -LANG=C -export LANG -LC_ALL=C -export LC_ALL -LC_TIME=C -export LC_TIME - -# Get the extended ls output of the file or directory. -# On HPUX /bin/sh, "set" interprets "-rw-r--r--" as options, so the "x" below. -if ls -L /dev/null 1>/dev/null 2>&1; then - set - x`ls -L -l -d $1` -else - set - x`ls -l -d $1` -fi -# The month is at least the fourth argument -# (3 shifts here, the next inside the loop). -shift -shift -shift - -# Find the month. Next argument is day, followed by the year or time. -month= -until test $month -do - shift - case $1 in - Jan) month=January; nummonth=1;; - Feb) month=February; nummonth=2;; - Mar) month=March; nummonth=3;; - Apr) month=April; nummonth=4;; - May) month=May; nummonth=5;; - Jun) month=June; nummonth=6;; - Jul) month=July; nummonth=7;; - Aug) month=August; nummonth=8;; - Sep) month=September; nummonth=9;; - Oct) month=October; nummonth=10;; - Nov) month=November; nummonth=11;; - Dec) month=December; nummonth=12;; - esac -done - -day=$2 - -# Here we have to deal with the problem that the ls output gives either -# the time of day or the year. -case $3 in - *:*) set `date`; eval year=\$$# - case $2 in - Jan) nummonthtod=1;; - Feb) nummonthtod=2;; - Mar) nummonthtod=3;; - Apr) nummonthtod=4;; - May) nummonthtod=5;; - Jun) nummonthtod=6;; - Jul) nummonthtod=7;; - Aug) nummonthtod=8;; - Sep) nummonthtod=9;; - Oct) nummonthtod=10;; - Nov) nummonthtod=11;; - Dec) nummonthtod=12;; - esac - # For the first six month of the year the time notation can also - # be used for files modified in the last year. - if (expr $nummonth \> $nummonthtod) > /dev/null; - then - year=`expr $year - 1` - fi;; - *) year=$3;; -esac - -# The result. -echo $day $month $year diff --git a/contrib/cvs/missing b/contrib/cvs/missing deleted file mode 100755 index 1c8ff70..0000000 --- a/contrib/cvs/missing +++ /dev/null @@ -1,367 +0,0 @@ -#! /bin/sh -# Common stub for a few missing GNU programs while installing. - -scriptversion=2006-05-10.23 - -# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006 -# Free Software Foundation, Inc. -# Originally by Fran,cois Pinard , 1996. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -# 02110-1301, USA. - -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - -if test $# -eq 0; then - echo 1>&2 "Try \`$0 --help' for more information" - exit 1 -fi - -run=: -sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p' -sed_minuso='s/.* -o \([^ ]*\).*/\1/p' - -# In the cases where this matters, `missing' is being run in the -# srcdir already. -if test -f configure.ac; then - configure_ac=configure.ac -else - configure_ac=configure.in -fi - -msg="missing on your system" - -case $1 in ---run) - # Try to run requested program, and just exit if it succeeds. - run= - shift - "$@" && exit 0 - # Exit code 63 means version mismatch. This often happens - # when the user try to use an ancient version of a tool on - # a file that requires a minimum version. In this case we - # we should proceed has if the program had been absent, or - # if --run hadn't been passed. - if test $? = 63; then - run=: - msg="probably too old" - fi - ;; - - -h|--h|--he|--hel|--help) - echo "\ -$0 [OPTION]... PROGRAM [ARGUMENT]... - -Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an -error status if there is no known handling for PROGRAM. - -Options: - -h, --help display this help and exit - -v, --version output version information and exit - --run try to run the given command, and emulate it if it fails - -Supported PROGRAM values: - aclocal touch file \`aclocal.m4' - autoconf touch file \`configure' - autoheader touch file \`config.h.in' - autom4te touch the output file, or create a stub one - automake touch all \`Makefile.in' files - bison create \`y.tab.[ch]', if possible, from existing .[ch] - flex create \`lex.yy.c', if possible, from existing .c - help2man touch the output file - lex create \`lex.yy.c', if possible, from existing .c - makeinfo touch the output file - tar try tar, gnutar, gtar, then tar without non-portable flags - yacc create \`y.tab.[ch]', if possible, from existing .[ch] - -Send bug reports to ." - exit $? - ;; - - -v|--v|--ve|--ver|--vers|--versi|--versio|--version) - echo "missing $scriptversion (GNU Automake)" - exit $? - ;; - - -*) - echo 1>&2 "$0: Unknown \`$1' option" - echo 1>&2 "Try \`$0 --help' for more information" - exit 1 - ;; - -esac - -# Now exit if we have it, but it failed. Also exit now if we -# don't have it and --version was passed (most likely to detect -# the program). -case $1 in - lex|yacc) - # Not GNU programs, they don't have --version. - ;; - - tar) - if test -n "$run"; then - echo 1>&2 "ERROR: \`tar' requires --run" - exit 1 - elif test "x$2" = "x--version" || test "x$2" = "x--help"; then - exit 1 - fi - ;; - - *) - if test -z "$run" && ($1 --version) > /dev/null 2>&1; then - # We have it, but it failed. - exit 1 - elif test "x$2" = "x--version" || test "x$2" = "x--help"; then - # Could not run --version or --help. This is probably someone - # running `$TOOL --version' or `$TOOL --help' to check whether - # $TOOL exists and not knowing $TOOL uses missing. - exit 1 - fi - ;; -esac - -# If it does not exist, or fails to run (possibly an outdated version), -# try to emulate it. -case $1 in - aclocal*) - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified \`acinclude.m4' or \`${configure_ac}'. You might want - to install the \`Automake' and \`Perl' packages. Grab them from - any GNU archive site." - touch aclocal.m4 - ;; - - autoconf) - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified \`${configure_ac}'. You might want to install the - \`Autoconf' and \`GNU m4' packages. Grab them from any GNU - archive site." - touch configure - ;; - - autoheader) - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified \`acconfig.h' or \`${configure_ac}'. You might want - to install the \`Autoconf' and \`GNU m4' packages. Grab them - from any GNU archive site." - files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` - test -z "$files" && files="config.h" - touch_files= - for f in $files; do - case $f in - *:*) touch_files="$touch_files "`echo "$f" | - sed -e 's/^[^:]*://' -e 's/:.*//'`;; - *) touch_files="$touch_files $f.in";; - esac - done - touch $touch_files - ;; - - automake*) - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. - You might want to install the \`Automake' and \`Perl' packages. - Grab them from any GNU archive site." - find . -type f -name Makefile.am -print | - sed 's/\.am$/.in/' | - while read f; do touch "$f"; done - ;; - - autom4te) - echo 1>&2 "\ -WARNING: \`$1' is needed, but is $msg. - You might have modified some files without having the - proper tools for further handling them. - You can get \`$1' as part of \`Autoconf' from any GNU - archive site." - - file=`echo "$*" | sed -n "$sed_output"` - test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` - if test -f "$file"; then - touch $file - else - test -z "$file" || exec >$file - echo "#! /bin/sh" - echo "# Created by GNU Automake missing as a replacement of" - echo "# $ $@" - echo "exit 0" - chmod +x $file - exit 1 - fi - ;; - - bison|yacc) - echo 1>&2 "\ -WARNING: \`$1' $msg. You should only need it if - you modified a \`.y' file. You may need the \`Bison' package - in order for those modifications to take effect. You can get - \`Bison' from any GNU archive site." - rm -f y.tab.c y.tab.h - if test $# -ne 1; then - eval LASTARG="\${$#}" - case $LASTARG in - *.y) - SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` - if test -f "$SRCFILE"; then - cp "$SRCFILE" y.tab.c - fi - SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` - if test -f "$SRCFILE"; then - cp "$SRCFILE" y.tab.h - fi - ;; - esac - fi - if test ! -f y.tab.h; then - echo >y.tab.h - fi - if test ! -f y.tab.c; then - echo 'main() { return 0; }' >y.tab.c - fi - ;; - - lex|flex) - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified a \`.l' file. You may need the \`Flex' package - in order for those modifications to take effect. You can get - \`Flex' from any GNU archive site." - rm -f lex.yy.c - if test $# -ne 1; then - eval LASTARG="\${$#}" - case $LASTARG in - *.l) - SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` - if test -f "$SRCFILE"; then - cp "$SRCFILE" lex.yy.c - fi - ;; - esac - fi - if test ! -f lex.yy.c; then - echo 'main() { return 0; }' >lex.yy.c - fi - ;; - - help2man) - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified a dependency of a manual page. You may need the - \`Help2man' package in order for those modifications to take - effect. You can get \`Help2man' from any GNU archive site." - - file=`echo "$*" | sed -n "$sed_output"` - test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` - if test -f "$file"; then - touch $file - else - test -z "$file" || exec >$file - echo ".ab help2man is required to generate this page" - exit 1 - fi - ;; - - makeinfo) - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified a \`.texi' or \`.texinfo' file, or any other file - indirectly affecting the aspect of the manual. The spurious - call might also be the consequence of using a buggy \`make' (AIX, - DU, IRIX). You might want to install the \`Texinfo' package or - the \`GNU make' package. Grab either from any GNU archive site." - # The file to touch is that specified with -o ... - file=`echo "$*" | sed -n "$sed_output"` - test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` - if test -z "$file"; then - # ... or it is the one specified with @setfilename ... - infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` - file=`sed -n ' - /^@setfilename/{ - s/.* \([^ ]*\) *$/\1/ - p - q - }' $infile` - # ... or it is derived from the source name (dir/f.texi becomes f.info) - test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info - fi - # If the file does not exist, the user really needs makeinfo; - # let's fail without touching anything. - test -f $file || exit 1 - touch $file - ;; - - tar) - shift - - # We have already tried tar in the generic part. - # Look for gnutar/gtar before invocation to avoid ugly error - # messages. - if (gnutar --version > /dev/null 2>&1); then - gnutar "$@" && exit 0 - fi - if (gtar --version > /dev/null 2>&1); then - gtar "$@" && exit 0 - fi - firstarg="$1" - if shift; then - case $firstarg in - *o*) - firstarg=`echo "$firstarg" | sed s/o//` - tar "$firstarg" "$@" && exit 0 - ;; - esac - case $firstarg in - *h*) - firstarg=`echo "$firstarg" | sed s/h//` - tar "$firstarg" "$@" && exit 0 - ;; - esac - fi - - echo 1>&2 "\ -WARNING: I can't seem to be able to run \`tar' with the given arguments. - You may want to install GNU tar or Free paxutils, or check the - command line arguments." - exit 1 - ;; - - *) - echo 1>&2 "\ -WARNING: \`$1' is needed, and is $msg. - You might have modified some files without having the - proper tools for further handling them. Check the \`README' file, - it often tells you about the needed prerequisites for installing - this package. You may also peek at any GNU archive site, in case - some other package would contain this missing \`$1' program." - exit 1 - ;; -esac - -exit 0 - -# Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "scriptversion=" -# time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-end: "$" -# End: diff --git a/contrib/cvs/mkinstalldirs b/contrib/cvs/mkinstalldirs deleted file mode 100755 index ef7e16f..0000000 --- a/contrib/cvs/mkinstalldirs +++ /dev/null @@ -1,161 +0,0 @@ -#! /bin/sh -# mkinstalldirs --- make directory hierarchy - -scriptversion=2006-05-11.19 - -# Original author: Noah Friedman -# Created: 1993-05-16 -# Public domain. -# -# This file is maintained in Automake, please report -# bugs to or send patches to -# . - -nl=' -' -IFS=" "" $nl" -errstatus=0 -dirmode= - -usage="\ -Usage: mkinstalldirs [-h] [--help] [--version] [-m MODE] DIR ... - -Create each directory DIR (with mode MODE, if specified), including all -leading file name components. - -Report bugs to ." - -# process command line arguments -while test $# -gt 0 ; do - case $1 in - -h | --help | --h*) # -h for help - echo "$usage" - exit $? - ;; - -m) # -m PERM arg - shift - test $# -eq 0 && { echo "$usage" 1>&2; exit 1; } - dirmode=$1 - shift - ;; - --version) - echo "$0 $scriptversion" - exit $? - ;; - --) # stop option processing - shift - break - ;; - -*) # unknown option - echo "$usage" 1>&2 - exit 1 - ;; - *) # first non-opt arg - break - ;; - esac -done - -for file -do - if test -d "$file"; then - shift - else - break - fi -done - -case $# in - 0) exit 0 ;; -esac - -# Solaris 8's mkdir -p isn't thread-safe. If you mkdir -p a/b and -# mkdir -p a/c at the same time, both will detect that a is missing, -# one will create a, then the other will try to create a and die with -# a "File exists" error. This is a problem when calling mkinstalldirs -# from a parallel make. We use --version in the probe to restrict -# ourselves to GNU mkdir, which is thread-safe. -case $dirmode in - '') - if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then - echo "mkdir -p -- $*" - exec mkdir -p -- "$@" - else - # On NextStep and OpenStep, the `mkdir' command does not - # recognize any option. It will interpret all options as - # directories to create, and then abort because `.' already - # exists. - test -d ./-p && rmdir ./-p - test -d ./--version && rmdir ./--version - fi - ;; - *) - if mkdir -m "$dirmode" -p --version . >/dev/null 2>&1 && - test ! -d ./--version; then - echo "mkdir -m $dirmode -p -- $*" - exec mkdir -m "$dirmode" -p -- "$@" - else - # Clean up after NextStep and OpenStep mkdir. - for d in ./-m ./-p ./--version "./$dirmode"; - do - test -d $d && rmdir $d - done - fi - ;; -esac - -for file -do - case $file in - /*) pathcomp=/ ;; - *) pathcomp= ;; - esac - oIFS=$IFS - IFS=/ - set fnord $file - shift - IFS=$oIFS - - for d - do - test "x$d" = x && continue - - pathcomp=$pathcomp$d - case $pathcomp in - -*) pathcomp=./$pathcomp ;; - esac - - if test ! -d "$pathcomp"; then - echo "mkdir $pathcomp" - - mkdir "$pathcomp" || lasterr=$? - - if test ! -d "$pathcomp"; then - errstatus=$lasterr - else - if test ! -z "$dirmode"; then - echo "chmod $dirmode $pathcomp" - lasterr= - chmod "$dirmode" "$pathcomp" || lasterr=$? - - if test ! -z "$lasterr"; then - errstatus=$lasterr - fi - fi - fi - fi - - pathcomp=$pathcomp/ - done -done - -exit $errstatus - -# Local Variables: -# mode: shell-script -# sh-indentation: 2 -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "scriptversion=" -# time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-end: "$" -# End: diff --git a/contrib/cvs/mktemp.sh b/contrib/cvs/mktemp.sh deleted file mode 100644 index 8bef4d5..0000000 --- a/contrib/cvs/mktemp.sh +++ /dev/null @@ -1,39 +0,0 @@ -# mktemp - -# Copyright (c) Derek Price, Ximbiot , and the -# Free Software Foundation, Inc. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA -# 02111-1307, USA. - - - -# This Bourne Shell scriptlet is intended as a simple replacement for -# the BSD mktemp function for systems that do not support mktemp. It -# currently does not check that the files it is creating did not exist -# previously and it does not verify that it successfully creates the -# files it returns the names of. -mktemp() { - if test x"$1" = x-d; then - tmp=`echo $2 |sed "s/XXXXXX/$$/"` - (umask 077 && exec mkdir $tmp) || return 1 - else - tmp=`echo $1 |sed "s/XXXXXX/$$/"` - (umask 077 && touch $tmp) || return 1 - fi - echo $tmp - return 0 -} - diff --git a/contrib/cvs/src/ChangeLog b/contrib/cvs/src/ChangeLog deleted file mode 100644 index 4e7a422..0000000 --- a/contrib/cvs/src/ChangeLog +++ /dev/null @@ -1,9664 +0,0 @@ -2008-03-10 Mark D. Baushke - - * mkmodules.c, parseinfo.c: Update copyright. - - * parseinfo.c (parse_config): Add support for new - "IgnoreUnknownConfigKeys" configuration key. - * mkmodules.c (config_contents): Add text about the - "IgnoreUnknownConfigKeys" option. - * sanity.sh (config): Test that IgnoreUnknownConfigKeys=yes works. - -2008-01-30 Derek R. Price - - * update.c (join_file): Use local copy to detect deletion conflicts, - as opposed to the base revision. Restore freeing of rev2 to its - original location. Use simpler conflict message. - * sanity.sh: Update to compensate. - -2008-01-29 Derek R. Price - - * update.c (join_file): Remove trace that is no longer needed. - -2008-01-29 Derek R. Price - Paul Edwards - - * update.c (join_file): Detect deletion conflicts. - * sanity.sh (join, join4): Adjusted for this fix. - (join8, join9): Add new tests for conflicts. - -2008-01-27 Mark D. Baushke - - * filesubr.c (xreadlink): s/128/BUFSIZ/ avoid magic numbers. - - * client.c (start_rsh_server): Use CVS_SSH for the :extssh: - method or fall back to "ssh" as set using the --with-ssh flag to - configure. - - * client.h, log.c, main.c, recurse.c, root.c: Update copyright for - 2008. - -2008-01-24 Mark D. Baushke - - * log.c (cvslog): New -n option to revert the -N switch. - (log_usage): Add -n to the help string. - * main.c (cmds[]): Add "blame" as a synonym for the - "annotate" command. - * sanity.sh (cvs-log): New tests for 'cvs log -N -n' validation. - (ann-10w1blame): Test the 'cvs blame' synonym for annotate. - (Patch suggested by "David O'Brien" ) - - * edit.c (notify_check): Rename to... - (cvs_notify_check): ...this to avoid Mac OSX symbol conflicts. - * client.h, edit.h, recurse.c: Change all references. - - * client.c (start_rsh_server): Use RSH_DFLT not a hardcoded "rsh" - * root.c (parse_cvsroot): Fix parsing for the :extssh: method. - - * sanity.sh (expr_set_DASHDASH): Fix for non-POSIX expr - implementations. - (CVSROOTDIR): Use 'cvsrootdir' instead of 'cvsroot' to - avoid problems on case preserving and/or case insensitive - filesystems (e.g., HFS+). - (CVSROOT_DIRNAME): Use ${TESTDIR}/${CVSROOTDIR} instead of - ${TESTDIR}/cvsroot to avoid filesystem case sensitivity problems. - (crerepos-extssh): Clone of crerepos tests, but use the :extssh: - method. - -2007-12-19 Larry Jones - - * client.c, import.c, lock.c, login.c, mkmodules.c, modules.c, - rcs.c, server.c: Fix gcc -Wall warnings. - -2007-12-16 Larry Jones - - * rcs.c (HAVE_MMAP): Fall back to stdio if mmap fails. - -2007-12-13 Larry Jones - - * rcs.c (rcsbuf_ftell): Avoid potential overflow. - -2007-12-12 Larry Jones - - * vers_ts.c (time_stamp): Add warnings for [l]stat failures - other than no such file. - -2007-08-26 Derek Price - - * mkmodules.c (in_root): Rename to... - (in_repository): ...this. - -2007-08-26 Larry Jones - - * mkmodules.c (in_root, init): Unmix declarations and code. - -2007-08-22 Derek Price - - * add.c (add): Check last component of argument paths instead of the - entire argument. - * sanity.sh (add-restricted): Test indirect paths to `CVS' dir with - add. - - * server.c (serve_init): Remove unnecessary argument to printf style - function. - - * mkmodules.c (in_root): New function. - (init): Verify that new roots are not created inside others. - * sanity.sh (init-3): New test for same. - -2007-08-16 Derek Price - - * root.c (root_allow_used): New function and... - * root.h (root_allow_used): ...its prototype. - * server.c (serve_root): Backport --allow-root test for `cvs server'. - * sanity.sh (server2-5, server2-6): New tests for the above. - -2007-06-18 Derek Price - - * client.c (send_repository): Don't attempt to send metadata from CVS - subdirectories when importing. - -2007-06-15 Derek Price - - * import.c (import): Check more carefully for files and directories - named "CVS". - * sanity.sh (import-1b): New test for same. - (import-2): Test files named "CVS", in addition to directories. - -2007-05-22 Larry Jones - - * rcs.c (RCS_fully_parse): Include revision in error message. - -2007-05-07 Derek Price - - * mkmodules.c (init): Assert that the server is not active. - * server.c (serve_init): Send error message when the init command is - received from a client. - - * sanity.sh (*): Avoid using remote init. - (skip_always, localonly, restore_adm): New convenience functions. - -2007-03-08 Larry Jones - - * rcs.c (findmagictag): Cast node->data before doing arithmetic - since it's now (void *). - -2007-03-05 Larry Jones - - * rcs.c (RCS_delete_revs): When checking for tagged revisions, - include magic branch tags. - -2007-03-01 Larry Jones - - * import.c (import_descend_dir): Correct error message. - * sanity.sh (pserver-3a): New test. - -2006-09-14 Derek Price - - * sanity.sh (server3, client2): New tests. - -2006-09-07 Derek Price - - [bug #17560] - * rcs.c (apply_rcs_changes): Improve comments. Restore repaired error - handling. - -2006-09-06 Larry Jones - - * rcs.c (apply_rcs_changes): Improve linked list handling. Remove - unused variables and unreachable error handling code. Avoid unneeded - dynamic allocation of temp linevector. Minor stylistic code clean up. - -2006-09-06 Derek Price - - [bug #17560] - * rcs.c (apply_rcs_changes): Improve header block comment. Clean up - unused linevector on non-fatal error. - -2006-09-06 Derek Price - - [bug #17560] - * rcs.c (apply_rcs_changes): Remove an unecessary memcpy. Avoid some - other processing on error. - (linevector_delete): Remove - it's no longer used. - -2006-09-06 Mark D. Baushke - - [bug #17560] - * rcs.c (apply_rcs_changes): Fix the merge algorithm from O(n^2) - to O(n). - (Based on a patch submitted by "Michael J. Smith" - ) - -2006-08-28 Derek Price - - * recurse.c (do_recursion): Remove misguided assertion. - * sanity.sh (dottedroot-3): Add test for the above. - (Thanks to report from Paul Eggert .) - - [bug #17168] - * classify.c (Classify_File): Use T_PATCH for changed keywords instead - of T_CHECKOUT to conserver bandwidth. Don't sticky check when marking - files for update anyhow. - * sanity.sh: Update to compensate (s/^U /[UP] /). - -2006-08-25 Derek Price - - [bug #17168] - * classify.c (Classify_file): Mark files with potential keyword - substitution changes as needing update. - * sanity.sh: Update to compensate. - (keyword, keywordname, serverpatch): Update to compensate, removing - the last few "checksum failed" tests. - - * classify.c (Classify_File): Remove hacks which worked around checksum - failures from bug #17032. - -2006-08-24 Derek Price - - [bug #17032] - * update.c (patch_file): Correctly recreate client working files - containing the RCS `Name' keyword before generating patches. - * sanity.sh (keyword-23r): Merge with local case to compensate. - -2006-08-17 Larry Jones - - * hash.h: Rename structs node and list to hashnode and hashlist - to avoid name clashes. - -2006-07-25 Mark D. Baushke - - * login.c (free_cvs_password): New function to control freeing of - the static get_cvs_passwd() returned storage. - (login): Call it. - * cvs.h (free_cvs_password): Add prototype for it. - * client.c (auth_server): Call it. - [Alter the previous NetBSD coverity cid-3404 patch.] - -2006-07-11 Larry Jones - - * log.c (log_usage): Fix misleading description of -b (it selects - revisions on the default branch *in addition to* revisions selected - with -r). - -2006-06-29 Derek Price - - * client.c (is_arg_a_parent_or_listed_dir): Strip trailing slashes from - dir name defore searching for it. Partially addresses TODO #205. - * sanity.sh (trailingslashes): Update to compensate. - -2006-06-28 Derek Price - - [bug #16961] - * login.c (get_cvs_password): Return copy of global variable. - (Patch from .) - -2006-06-23 Larry Jones - - * server.c (do_cvs_command): Remove unused variable. - -2006-06-22 Larry Jones - - * mkmodules.c (modules_contents): Remove defunct -i option. - -2006-06-10 Derek Price - - * sanity.sh (conflicts4): Don't expect specific file permissions. Use - $PLUS. - -2006-06-08 Derek Price - - * sanity.sh (conflicts4): Test that the client honors Empty-conflicts. - - * server.c (requests): Add "Empty-conflicts" marker. - * client.c (send_fileproc): Send contents of all files with conflicts - unless the server can handle the conflict marker in the Entry. - - * sanity.sh (conflicts4): New tests. - (Original patch from Mark D. Baushke .) - -2006-06-07 Mark D. Baushke - - * modules.c (my_module): Remove unused variable xvalue. - [Fixes NetBSD coverity cid-705.] - -2006-05-31 Mark D. Baushke - - * add.c (add): Fix memory leak. - [Fixes NetBSD coverity cid-3751.] - (add_directory): Fix memory leak. - [Fixes NetBSD coverity cid-3640.] - - * checkin.c (Checkin): Avoid possible NULL dereference. - [Fixes NetBSD coverity cid-2425.] - - * client.c (auth_server): Fix memory leak. - [Fixes NetBSD coverity cid-3404.] - - * commit.c (remove_file): Fix memory leak. - [Fixes NetBSD coverity cid-3752.] - - * rcs.c (RCS_checkin): Add assert (tip). - [Fixes NetBSD coverity cid-2424.] - -2006-05-26 Mark D. Baushke - - * add.c (add): Do not leak memory. - [Fixes NetBSD coverity cid-2199.] - - * edit.c (onoff_fileproc): Do not leak memory. - [Fixes NetBSD coverity cid-2201.] - - * edit.c (onoff_filesdoneproc): Do not leak memory. - [Fixes NetBSD coverity cid-2202.] - - * lock.c (readers_exist): Add assert (lockdir). - [Fixes NetBSD coverity cid-2411.] - - * rcs.c (RCS_findlock_or_tip): Do not leak memory. - [Fixes NetBSD coverity cid-2198.] - - * rcs.c (RCS_getdate): Avoid possible NULL dereference. - [Fixes NetBSD coverity cid-2412.] - - * server.c (serve_sticky): Do not leak file descriptors. - [Fixes NetBSD coverity cid-2197.] - - * server.c (do_cvs_command): Do not leak memory. - [Fixes NetBSD coverity cid-2204.] - - * tag.c (add_to_val_tags): Do not leak memory. - [Fixes NetBSD coverity cid-2071.] - -2006-05-25 Derek Price - - * client.c (start_rsh_server): Default rsh client to RSH_DFLT. Remove - verbose comment attempting to justify the previous default. - -2006-05-24 Larry Jones - - * sanity.sh: Add -v|--verbose option to echo test names. Clean - up help message. - Remove val-tags files for cleanup instead of truncating since the - truncation code doesn't work right on Solaris. Always use -f when - removing val-tags. - -2006-05-22 Derek Price - - * rcs.c (RCS_reparsercsfile, RCS_fully_parse, RCS_checkout, RCS_deltas, - RCS_getdeltatext, RCS_copydeltas): Verify input revision numbers. - (rcs6): Update to compensate. - - * sanity.sh (rcs6): New test. - -2006-05-16 Derek Price - - * main.c: Update copyright for 2006. - -2006-05-12 Mark D. Baushke - - * log.c (log_expand_revlist): Add assert (r->first). It should - only be possible for both r->first == NULL && r->last == NULL - which would have been handled. - [Fixes NetBSD coverity cid-1063.] - - * server.c (do_cvs_command): Protect close (dev_null_fd) against - invalid fd value in error_exit. - [Fixes NetBSD coverity cid-1307.] - - * rcs.c (RCS_isdead): Assert that the first argument is not NULL. - [Fixes NetBSD coverity cid-1058.] - - * commit.c (checkaddfile): Do not dereference NULL on call to - error(). - [Fixes NetBSD coverity cid-1061.] - - * log.c (cvslog): Assert p->start && p->end instead of masking the - problem. - * server.c (server_updated): Assert findnode_fn results instead of - masking the problem. - - * add.c (add_directory): Revert previous change. The xstrdup() - function already deals a NULL argument. - * client.c (handle_mt): Ditto. - * entries.c (Entnode_Create): Ditto. - (Entries_Open): Ditto. - * logmsg.c (fmt_proc): Ditto. - * vers_ts.c (Version_TS): Ditto. - -2006-05-11 Mark D. Baushke - - * add.c (add_directory): Protect tag from NULL dereference. - [Fixes NetBSD cid-1054.] - - * client.c (handle_mt): Deal with missing text argument. - [Fixes NetBSD cid-924.] - - * entries.c (Entnode_Create): Protect date, tag and ts_conflict - from possible NULL dereference. - [Fixes NetBSD coverity cid-994, cid-995, cid-1055, cid-1057.] - - * entries.c (Entries_Open): Protect dirtag and dirdate from - possible NULL dereference. - [Fixes NetBSD coverity cid-996.] - - * log.c (cvslog): Validate start and end args to - date_to_internet(). - [Fixes NetBSD coverity cid-2427 and cid-2428.] - - * logmsg.c (fmt_proc): Protect li->tag from NULL dereference. - [Fixes NetBSD coverity cid-997.] - - * vers_ts.c (Version_TS): Protect tag and vers_ts->tag from NULL - dereference. - [Fixes NetBSD coverity cid-1053.] - -2006-05-04 Mark D. Baushke - - * filesubr.c (cvs_temp_file): Avoid keeping pointers to free()'d - storage laying around. - * commit.c (commit): Handle possible NULL filename values - returned from cvs_temp_file(). - * filesubr.c (cvs_temp_name): Ditto. - * import.c (import): Ditto. - * login.c (password_entry_operation): Ditto. - * logmsg.c (do_verify): Ditto. - * patch.c (patch_fileproc): Ditto. - [Fixes NetBSD coverity cid-2545.] - - * buffer.c (packetizing_buffer_output): Initialize outdata. - [Fixes NetBSD coverity cid-2474.] - - * server.c (server_updated): Check for NULL return from - findnode_fn(). [Fixes NetBSD coverity cid-1352.] - -2006-04-19 Larry Jones - - * history.c (sort_order): Back out previous change - not needed. - -2006-04-15 Larry Jones - - * history.c (sort_order): Add prototype. - * server.c (template_proc): Add prototype and make args const. - * update.c (RegisterMerge): Make static to match prototype. - -2006-04-07 Derek Price - - * client.c (strto_file_size): New function which checks for errors when - parsing protocol input. - (read_counted_file, update_entries, handle_mbinary): Use new function. - Remove FIXME. - (Thanks to a report from Brendan Harrison - .) - - * client.c (send_a_repository): Add assertion. - (Thanks to an incorrect report from Brendan Harrison - .) - -2006-04-06 Derek Price - - * filesubr.c (last_component, expand_wild), rcs.c (RCS_deltas, - RCS_rewrite), server.c (server_checked_in): Add assertions. - (Thanks to an incorrect report from Brendan Harrison - .) - -2006-03-31 Mark D. Baushke - - * cvsrc.c (read_cvsrc): Deal with \r\n (DOS) line endings in - .cvsrc files. - -2006-03-07 Derek Price - - * tag.c (rtag_proc): Search the Attic when -F is used. - * sanity.sh (tests): Run death-rtag. - (death-rtag): Expect success. - - * sanity.sh (death-rtag): Add failing force tag move test. - -2006-03-06 Derek Price - - * tag.c (rtag_proc): Always search in the attic when -r is used. - - * sanity.sh (death-rtag): New test. - (Original report from C. Michael Pilato .) - -2006-03-01 Derek Price - - * sanity.sh: Set MALLOC_CHECK_ in hopes of exposing common memory - errors when CVS is linked with glibc 2.x. - -2006-02-27 Derek Price - - * lock.c (internal_lock): Back out previous change, we don't change - user visible output on stable unless absolutely necessary. - - * lock.c (internal_lock): Improve error message. - -2006-02-26 Derek Price - - * client.c (call_in_directory): Remove unneeded code. - * sanity.sh (toplevel-12): Compensate by failing to expect a redundant - error message. - -2006-02-24 Mark D. Baushke - - * client.c (gzip_level): Move to... - * main.c (gzip_level): ...here. - (main): Revert previous change in '-z' argument processing and - remove CLIENT_SUPPORT ifdef/endif. - * sanity.h (crerepos-6a): Deal with --disable-client output. - - * main.c (main): Validate the gzip compression level for - --disable-client configurations. - -2006-02-13 Derek Price - - * server.c (do_cvs_command): Skip server_cleanup in the child process. - - * sanity.sh (sshstdio-6): Rewrite using more portable sed script. - -2006-02-02 Derek Price - - * sanity.sh (sshstdio): Attempt to ignore spurious SSH output. - - * main.c (main), release.c (release), server.c (do_cvs_command): Always - call the cleanup hooks before exit. - -2006-02-01 Derek Price - - * tag.c (add_to_val_tags): When a tag turns out to exist in the db when - it isn't expected, release the lock. - - * history.c (save_user, save_file, save_mod, read_hrecs): Avoid - overflow. - -2006-01-30 Derek Price - - * server.c (do_cvs_command): Set flow control pipe to blocking mode - before waiting for it to close. - (set_block_fd): New function. - (Original patch from Garrett Rooney .) - -2006-01-13 Larry Jones - - * mkmodules.c (config_contents): Change SystemAuth to yes to match - the default value. Add missing newline in RereadLogAfterVerify. - -2006-01-09 Larry Jones - - * commit.c (remove_file): Record correct revision in history file. - (Reported by Chris Reed .) - -2005-12-07 Derek Price - - * client.c (start_server), root.c (method_names), root.h (CVSmethod): - Handle :extssh: as a kindness to Eclipse users. - (Suggestion from Joseph P. Skudlarek .) - -2005-12-06 Mark D. Baushke - - * buffer.c (stdio_buffer_shutdown): No longer assert() the - fstat(). Use error (0, ...) instead of error (1, ...) to avoid - infinite loops. (patch #4678) - Patch adapted from "Allan L. Bazinet" - -2005-11-10 Larry Jones - - * commit.c (commit): Complain about obsolete -n option if not in - server mode. - -2005-11-09 Derek Price - - * sanity.sh (pserver-4.2): Accept a "no such sytem user" message when - a root attempt is made. - -2005-09-30 Larry Jones - - * expand_path.c (expand_path): Fix memory leaks. - -2005-09-29 Paul Eggert - Derek Price - - * client.c (handle_m, handle_e): Remove incomplete workaround for - O_NONBLOCK problem; no longer needed because of the fix below. - (start_rsh_server): We need the O_NONBLOCK fix, so pass 'true' to - piped_child to enable the workaround. - * cvs.h (piped_child): New bool argument saying whether O_NONBLOCK - fix is needed. All uses changed. - * run.c (work_around_openssh_glitch): New function. - (piped_child): Use it if the fix is requested. Avoid call call to - vfork with undefined behavior. - -2005-09-26 Conrad T. Pino - - * rcs.c: Use "#ifdef HAVE_FSYNC" just like every where else. - -2005-09-25 Derek Price - - * rcs.c (rcs_internal_unlockfile): Fsync files before renaming them. - Patch from Rahul Bhargava . - -2005-09-24 Derek Price - - * update.c (merge_file): Check for RCS_checkout errors. - -2005-09-23 Larry Jones - - * checkout.c (export_usage): Note that -r requires a tag. - -2005-09-22 Larry Jones - - * patch.c (patch_usage): Document -k option. - -2005-09-22 Derek Price - - * classify.c (Classify_File): If a file had a conflict and the - timestamp hasn't changed, it still has a conflict. Add comment about - how T_MODIFIED could later turn out to have conflict markers and why - it should not be checked in this function. - * client.c (send_fileproc): Don't send contents for files known to have - conflicts unless this is for `cvs diff'. - * commit.c (check_fileproc): T_CONFLICT should be handled like - T_MODIFIED, since force could be requested. Simplify logic since - T_CONFLICT can now be trusted. - * cvs.h (file_has_conflict): Remove proto. - * rcs.c (RCS_Checkout): Comment noexec behavior in header block. - * server.c (serve_unchanged, serve_is_modified): Handle conflicts. - * status.c (status_fileproc): Trust T_CONFLICT to simplify. - * subr.c (file_has_conflict): Removed. - * update.c (update_fileproc): Trust T_CONFLICT. - (RegisterMerge): New function factored from... - (merge_file, join_file): ...these two functions. - * vers_ts.c (time_stamp_server): Handle = conflict timestamps in server - entdata. - * sanity.sh (files-12): Account for slight behavior improvement. - (status, conflicts, mwrap): Account for corrected behavior. - (join-readonly-conflict-10): Correct comment. - (binfiles-con1b): New test for correct behavior. - -2005-09-19 Derek Price - - * sanity.sh (modules5-8): Rename... - (modules5-8r): ...to this and comment Mac OS X failure. - Comment Solaris 9 failure below with a `FIXME?' tag. - - * sanity.sh: Remove previous hack in favor of setting TESTDIR on - Solaris (and Mac OS X) until problem is solved correctly. - -2005-09-15 Derek Price - - * sanity.sh: Use /bin/pwd to verify current dir since Solaris 9 is - sometimes resolving symlinked paths. - -2005-09-14 Derek Price - - * edit.c (edit_usage, unedit_usage, editors_usage), watch.c - (watch_usage, watchers_usage): Add quotes and reword for clarity and - consistency. - - * edit.c (edit_usage): Add missing syntax. Reword description for - clarity. Mention default behavior. - -2005-09-13 Derek Price - - * sanity.sh: Split $username into $username & $username8. Rename - $author as $anyusername. - -2005-09-12 Derek Price - - * sanity.sh (binfiles-con1b): Back out accidental addition. - - * sanity.sh (username): Cut $username down to 8 characters when longer, - since that is all that appears in output. - -2005-09-07 Derek Price - - Close . - * rcs.c (RCS_parse): Free variable *after* using it for the last time. - -2005-09-06 Derek Price - - * rcs.c (RCS_putdtree): Remove unused variable. - -2005-09-06 Mark D. Baushke - - Close . - * rcs.c (RCS_putdtree): Avoid stack overflow which may be - possible with excessive recursive calls to RCS_putdtree(). - (Patch from Serg Masyutin.) - -2005-09-03 Derek Price - - * add.c (add_usage): Standardize usage message somewhat. - -2005-09-02 Larry Jones - - * commit.c (checkaddfile): Improve error messages for lock_RCS failure. - * release.c (release): Improve error message for pclose failure. - - * root.h (struct cvsroot_s): Always declare isremote to simplify - other code. Simplify referencing code. - * root.c (new_cvsroot_t): Always initialize isremote. - * server.h: Always declare server_active to simplify other code. - Simplify referencing code. - * server.c: Always define server_active. - -2005-09-01 Derek Price - - * main.c, wrapper.c: Update links. - -2005-09-01 Derek Price - - * recurse.c: Update bug report email address. - -2005-08-30 Larry Jones - - * import.c (import_descend): Lock repository directory during import. - -2005-07-12 Derek Price - - * buffer.c, buffer.h, client.h, expand_path.c, history.c, myndbm.h, - release.c: Add copyright notices. - -2005-07-11 Derek Price - - * buffer.c, buffer.h, client.h, expand_path.c, history.c, myndbm.h, - release.c: Update license notices. - -2005-06-22 Larry Jones - - * vers_ts (Version_TS): Don't allow command line keyword expansion - modes to override binary mode. - * sanity.sh (): Tests for the above. - (Merged from trunk.) - -2005-06-06 Conrad T. Pino - - * cvs.h: Reverse patch committed 2005-05-27 by Conrad T. Pino. - * run.c: Reverse patch committed 2005-05-27 by Conrad T. Pino. - -2005-06-02 Derek Price - - * zlib.c (compress_buffer_shutdown_input): Don't attempt to read EOF - from the client during shutdown. It might never be sent. - * sanity.sh (abspath2): Test for this. - -2005-05-31 Derek Price - for Alexander Taler - - * rcscmds.c: Change type of call_diff_argc_allocated from int to - size_t, to match the prototype of run_add_arg_p(). This fixes a - bus error in OpenBSD 3.6 sparc64. - -2005-05-27 Conrad T. Pino - - * cvs.h: Replace "run_arg" function with "#define run_arg run_add_arg", - add "run_add_arg" prototype, change "piped_child" prototype to be same - as feature branch to reflect "(os2,src,windows-NT)/run.c" changes. - * run.c: Remove "run_arg" to synchronize with "../windows-NT/run.c". - Function "run_add_arg" scope was "static" and is now "extern" scope. - Synchronize "piped_child" function arguments with feature branch. - -2005-05-27 Derek Price - - * client.c (send_arg): Make arg const. - (send_option_string): Rename to... - (send_options): ...this and accept argc/argv in place of string. - * client.h: Update protos to match the changes to client.c. - * cvs.h (RCS_exec_rcsdiff, diff_exec): Update protos. - (run_add_arg_p, run_arg_free_p): New protos. - * diff.c (opts, opts_allocated): Replace with... - (diff_argv, diff_argc, diff_arg_allocated): ...these. - (add_diff_args): New convenience function. - (diff): Use new constructs and APIs. - * patch.c (patch_fileproc, RCS_checkin, RCS_delete_revs), rcscmds.c - (call_diff_add_arg, call_diff_setup, RCS_merge, RCS_exec_rcsdiff, - diff_exec, RCS_output_diff_options), update.c (patch_file): Use new - APIs. - * run.c (run_add_arg_p, run_arg_free_p): New functions. - (run_argc_allocated): Make size_t. - (run_setup, run_add_arg): Use new functions. - * sanity.sh: Accomodate above changes. - (rcslib-diffrgx-3): Slip in test for space splitting. - -2005-05-02 Derek Price - - Remove unnecessary level of indirection. - * lock.c (L_HISTORY_LOCK, L_VAL_TAGS_LOCK): Remove macros. - (internal_lock, internal_clear_lock): Accept lock as argument. - (history_lock, clear_history_lock, val_tags_lock, clear_val_tags_lock): - Replace old macro arg with an actual lock pointer. - -2005-05-02 Derek Price - - * lock.c (internal_lock, internal_clear_lock): Add protos. - (history_lock, val_tags_lock): Return the chartered true/false status. - -2005-05-02 Derek Price - - * cvs.h (CVSHISTLCK): Rename macro to... - (CVSHISTORYLCK): ...this. - (CVSVALTAGSLCK): New macro. - (val_tags_lock, clear_val_tags_lock): New functions. - * lock.c (global_val_tags_lock): New global. - (Lock_Cleanup): Clean up after val-tags lock if necessary. - (L_HISTORY_LOCK, L_VAL_TAGS_LOCK): New local macros. - (internal_lock, internal_clear_lock, val_tags_lock, - clear_val_tags_lock): New functions. - (history_lock, clear_history_lock): Use new internal functions. - * tag.c (is_in_val_tags, add_to_val_tags): New functions using the - write-lock for val-tags and factored from... - (tag_check_valid): ...this function. - * sanity.sh (lockfiles-22): Add val-tags lock test. - -2005-04-28 Derek Price - - * cvs.h (history_lock, clear_history_lock): New protos. - * lock.c (struct lock): Add lockdirname. - (global_history_lock): New global. - (global_read_lock): Initialize. - (lock_name): Handle const args. - (lock_simple_remove): Factor out code in favor of clear_lock call. - (set_lock): Handle variable lockdirname. - (lock_filesdoneproc): Set new lockdirname. - (history_lock, clear_history_lock): New functions. - (clear_lock): Avoid segfault on missing lock. - (Lock_Cleanup): Clean up history locks when necessary. - * history.c (history_write): Use new lock. - * sanity.sh (lockfiles-20): Test new lock. - -2005-04-28 Derek Price - - * sanity.sh (lockfiles): Port some locking tests over from 1.12.x. - -2005-04-28 Derek Price - - * lock.c (clear_lock): Improve comment. - -2005-04-28 Derek Price - - * lock.c (struct lock): Store lockdir name. - (masterlock): Remove global. - (remove_lock_files, clear_lock, set_lock): Update to compensate. - -2005-04-20 Derek Price - - * sanity.sh (rcs5): Minor cosmetic change. - -2005-04-20 Derek Price - - * sanity.sh (tests): Add rcs4. - (rcs5): Add comments. - -2005-04-20 Derek Price - - * rcs.c (expand_keywords): Avoid buffer overflow. - (Original patch from Stewart Brodie .) - - * sanity.sh (rcs5): New tests for the above. - -2005-03-17 Derek Price - - * login.c (password_entry_parseline): Avoid using uninitialized - variable. - * rcs.c (RCS_deltas): Avoid buffer overflow. - (RCS_checkout): Avoid using uninitialized loglen. - * patch.c (patch_fileproc): Free original pointer, not one that may - have been incremented. - (Thanks to report from Alen Zukich .) - -2005-03-17 Derek Price - - * commit.c (checkaddfile): Avoid dereferencing a NULL pointer in - response to a rare error. - * admin.c (admin_fileproc), log.c (log_expand_revlist), mkmodules.c - (checkout_file), rcs.c (RCS_getdate, RCS_deltas, RCS_findlock_or_tip, - RCS_tag2rev): Avoid dereferencing NULL pointer. - (Thanks to report from Alen Zukich .) - -2005-03-17 Derek Price - - * rcs.c (RCS_reparsercsfile): Avoid memory leak. - (Thanks to report from Alen Zukich .) - -2005-03-17 Derek Price - - * log.c (log_expand_revlist): Suppress message and not error handling - when really_quiet. - -2005-03-17 Derek Price - - * client.c (call_in_directory): Put function call after var decls. - -2005-03-16 Derek Price - - * client.c (call_in_directory), commit.c (commit_filesdoneproc), log.c - (log_expand_revlist, log_version), logmsg.c (logfile_write), modules - (my_module), no_diff.c (No_Difference), parseinfo.c (Parse_Info), rcs.c - (RCS_deltas, RCS_checkin, RCS_addbranch, do_locks, do_symbols), - rcscmds.c (RCS_merge), root.c (parse_cvsroot, normalize_cvsroot), - update.c (merge_file): Verify assumptions via assertions. - (Thanks to (probably) incorrect reports from Alen Zukich - .) - -2005-03-16 Derek Price - - * server.c (create_adm_p, serve_entry), tag.c (rtag_proc): Avoid memory - leaks. - (Thanks to report from Alen Zukich .) - -2005-03-15 Mark D. Baushke - - * history.c (select_hrec): Avoid possible memory leak. - -2005-03-15 Derek Price - - * patch.c (patch_proc): Avoid memory leak. - (Thanks to report from Alen Zukich .) - -2005-03-11 Mark D. Baushke - - * modules.c (my_module): Protect against free (NULL) code path. - -2005-03-11 Derek Price - - * annotate.c (rannotate_proc), fileattr.c (fileattr_write), rcs.c - (RCS_deltas), server.c (check_repository_password), update.c (update): - Avoid memory leaks. - (Thanks to report from Alen Zukich .) - -2005-03-09 Derek Price - - * add.c (add, add_directory), buffer.c (allocate_buffer_datas), - client.c (update_entries), commit.c (checkaddfile), entries.c - (Entries_Open), fileattr.c (fileattr_read), ignore.c (ign_add), - import.c (import), main.c (main), parseinfo.c (parse_config), rcs.c - (RCS_reparsercsfile, RCS_getbranchpoint, RCS_checkout, - RCS_delete_revs, apply_rcs_changes): Avoid memory leaks. - (Thanks to report from Alen Zukich .) - - * hardlink.c, hardlink.h: Avoid compiling entire contents of these - files w/o preserve permissions support. - -2005-03-09 Mark D. Baushke - - * history.c (history, save_file): Cleanup the API to match the - comments. - -2005-02-27 Jim Meyering - - * login.c (password_entry_operation): Exit nonzero when - failing to close a just-appended-to .cvspass file. - -2005-02-26 Larry Jones - - * release.c (release): Remove unneeded code. - -2005-02-22 Derek Price - - * edit.c: Load watch settings before setting new ones with - `cvs watch on/off'. - (Original patch from Jim Hyslop .) - - * sanity.sh (watch6): New tests for same. - (Outline from Jim Hyslop .) - -2005-02-21 Mark D. Baushke - - * import.c (import): Avoid using assert with side effects it may - be configured away using NDEBUG. - (Patch from Frank Hemer .) - -2005-02-08 Derek Price - - * build_src.com: Build stack.c on VMS. - (Suggestion from Piet Schuermans .) - -2005-02-01 Larry Jones - - * log.c (log_fileproc, log_expand_revlist): Add support for BASE tag. - * sanity.sh (log): New tests for above. - -2005-01-31 Derek Price - - * main.c: Update year in copyright notice to match GNU standards. - * sanity.sh (version-1): Update to match. - -2005-01-31 Derek Price - - * main.c: Rephrase --version message. - * sanity.sh (version-1): Update to match. - -2005-01-31 Derek Price - - * Makefile.am, add.c, admin.c, annotate.c, checkin.c, checkout.c, - classify.c, commit.c, create_adm.c, cvs.h, cvsrc.c, diff.c, entries.c, - find_names.c, hash.c, hash.h, history.h, import.c, lock.c, log.c, - login.c, logmsg.c, main.c, mkmodules.c, modules.c, myndbm.c, no_diff.c, - parseinfo.c, patch.c, rcs.c, rcs.h, rcscmds.c, recurse.c, remove.c, - repos.c, root.c, root.h, server.h, stack.c, stack.h, status.c, subr.c, - tag.c, update.c, vers_ts.c, version.c: Update copyright notices. - -2005-01-29 Derek Price - - * log.c (log_usage): Add note about using -S with revision info - supression and selection. - (Suggestion from Dan Peterson .) - -2004-12-19 Larry Jones - - * expand_path.c (expand_path): Rewrite using offsets instead of - pointers to simplify and avoid reallocation bugs. - (Inspired by Jeremy Bopp .) - -2004-12-09 Derek Price - - * sanity.sh (tests): Add modules7. - -2004-12-09 Derek Price - - * sanity.sh (modules7): New test group. - (Based on a patch from Mark D. Baushke , based on a - report from Richard Verhoeven .) - -2004-11-18 Mark D. Baushke - - * checkout.c (checkout_proc): Passing the repository to - tag_check_valid seems to stop the assertion failure in recurse.c - do_recursion. - * sanity.sh (basic2-21a): Removed. - (basic2-21b): Fixed. - -2004-11-17 Mark D. Baushke - - * sanity.sh (basic2-21a): The val-tags file should have - at least 'rtagged-by-head y' in it. - (basic2-21b): New test showing a cvs bug when val-tags - is not properly updated. - (Report from "John Elgin" .) - -2004-11-17 Mark D. Baushke - - * client.c (handle_m, handle_e): Winsock is returning - SOCK_ERRNO == WSAENOTSOCK for select() problems and not - setting errno. Do not bother with printing an error from a - select() that is not returning an non-zero errno. - (Report from Conrad T. Pino .) - -2004-11-10 Derek Price - - * sanity.sh: Maintain pass/skip/warn status and output at end. - (usage): Note new functionality of -e. - (warn): New function. - (verify_tmp_empty): Warn instead of failing. Delete turds if warn() - doesn't exit. - -2004-11-10 Derek Price - - * sanity.sh (verify_tmp_empty): New function. - (dotest_internal_*): Call verify_tmp_empty as needed. - -2004-11-09 Mark D. Baushke - - * sanity.sh: Backport find_tool changes from 1.12.9.1. - (SEARCHPATH): New list of PATH directories to search. - (Which): Use $SEARCHPATH. Support -a switch. - (badtools,set_bad_tool,is_bad_tool): Keep track of tools that do - not work for us. - (version_test): Obtain the version of tools under test if - possible. - (tool_find): Rewrite. API changed to allow a list of - tests to be used against a list of possible command names found on - the SEARCHPATH. - (id_tool_test): Check that 'id -u' and 'id -un' work. - (expr_tooltest1): Check for NextStep 3.3 expr bug. - (expr_tooltest2): Check for SunOS expr multi-line pattern bug. - (expr_create_bar): Create a test file for expr testing. - (expr_tooltest3): Use it and test for big multi-line identity - matches. - (expr_set_ENDANCHOR): Find and set the right value for ENDANCHOR. - (expr_set_DOTSTAR): Find and set the right value for DOTSTAR. - (expr_tooltest_DOTSTAR): Ensure that DOTSTAR works with big - matches. - (tr_tooltest1): Verify that tr handles NUL bytes. - (awk_tooltest1): Verify that awk the BEGIN clause works properly. - (awk_tooltest2): Verify that print %c format item works properly. - -2004-11-02 Mark D. Baushke - - * filesubr.c (MAXSIZE): New macro. - (xreadlink): Ensure initial buffer size does not exceed MAXSIZE. - Avoid cast. If readlink fails with buffer size just under MAXSIZE, - try again with MAXSIZE. - -2004-11-02 Mark D. Baushke - - * filesubr.c (xreadlink): AIX and HP-UX readlink() returns ERANGE - when there is not enough room in the buffer. - -2004-11-01 Derek Price - - * sanity.sh (rcslib): Fix typo in path. - -2004-11-01 Derek Price - - * sanity.sh (rcslib): Test a link to a path longer than 128 - characters. - -2004-10-29 Derek Price - - * filesubr.c (xreadlink): Make sure allocation is tried once at the - maximum buffer size. Protect against overflow. - -2004-10-29 Mark D. Baushke - - * filesubr.c (SIZE_MAX, SSIZE_MAX): Use #include "xsize.h" instead. - (xreadlink): Use xrealloc instead of xmalloc/free. - -2004-10-29 Mark D. Baushke - - * filesubr.c (SIZE_MAX, SSIZE_MAX): New constants. - (xreadlink): Deal with symlinks longer than 127 bytes. - (Problem reported as issue 190 by Gottfried Ganssauge - .) - -2004-10-28 Mark D. Baushke - - * release.c (release): Allow builds of cvs with --disable-server - --disable-client both used for local installation configuration. - * root.c (Name_Root): Ditto. - * update.c (checkout_file): Ditto. - (Problem reported by Jean Olivier Caron .) - -2004-10-27 Mark D. Baushke - - * cvs.h (RCS_FLAGS_USETIME): New flag. - * rcs.c (RCS_checkin): Add citime argument. - * rcs.h (RCS_checkin): Ditto. - * checkin.c (Checkin): Pass new RCS_checkin argument. - * commit.c (remove_file, checkaddfile): Ditto. - * import.c (add_rev): Ditto. - - * sanity.sh (tagdate): Delete tagdate-19b as an incorrect test. - -2004-10-27 Mark D. Baushke - - * sanity.sh (tagdate): Provide more output. - -2004-10-26 Mark D. Baushke - - * commit.c (checkaddfile): Create a dead version for a new file - added to a branch. Fixes FIXCVS for tagdate tests. - * sanity.sh (tagdate): Update to expect correct results. - (death2, branch-after-import, join, ignore-on-branch): Ditto. - -2004-10-26 Derek Price - - * client.c (connect_to_gserver): Avoid truncating error messages from - the GSSAPI server. - (Report from Dan Peterson .) - -2004-10-26 Derek Price - - * sanity.sh (import-quirks): Test an even branch number. - -2004-10-25 Derek Price - - * import.c (import): Repair regex for regressions introduced in last - commit. - * sanity.sh (import-quirks): Test a few branch numbers import shouldn't - have a problem with. - -2004-10-25 Derek Price - - * import.c (import): Anchor and simplify branch verification regex. - * sanity.sh (import-quirks): Test another pattern that should fail. - -2004-10-25 Mark D. Baushke - - * sanity.sh (tagdate): Added some additional tests and FIXCVS - comments for dealing properly with a 'cvs add' of a file to - a branch that already exists on the mainline. - (Problem reported by Renny Barrett .) - - * sanity.sh (getrlogdate): New shell function. - (tagdate-{13,14,16}): Use it to avoid 'sleep 60' by using - the exact 1.1.4.1 timestamp for tagdate-14 and tagdate-16. - -2004-10-22 Mark D. Baushke - - * sanity.sh (tagdate): Fix typo. - -2004-10-19 Derek Price - - * add.c (add): Avoid attempting to resurrect a dead rev 1.1. - * sanity.sh (resurrection): Add test for the above. - (Report from Dan Peterson .) - -2004-10-14 Derek Price - - * import.c (import): Verify branch specifications more thoroughly. - * sanity.sh (importb): Adapt to new error message. - (import-quirks): New test. - -2004-10-04 Derek Price - - * cvs.h (CVSROOT_DFLT): Undef rather than defining to NULL. - * main.c (main): Untangle parsing of CVSROOT, eliminating several - variables in the process. Simplify xmalloc/sprintf with asnprintf. - -2004-10-01 Mark D. Baushke - - * main.c (main): Initialize CVSroot before it is used. - (Report and patch by Martin Neitzel .) - * sanity.sh (status): Test it. - -2004-09-25 Mark D. Baushke - - * sanity.sh (parseroot2): Correct two test names. Restore CVSROOT. - - * sanity.sh (parseroot2): Expand dokeep inline. - -2004-09-24 Derek Price - - * sanity.sh (tests): Add parseroot2. - -2004-09-24 Derek Price - - * sanity.sh (parseroot2): New test for root parsing consistency. - (Original patch from Alexander Taler .) - - * cvs.h (Name_Root, free_cvsroot_t, parse_cvsroot, local_cvsroot, - Create_Root, root_allow_add, root_allow_free, root_allow_ok): Move - these protos to... - * root.h: ...here. - * client.c (arg_should_not_be_sent_to_server), recurse.c - (start_recusrion, do_recursion): Use new Name_Root API. - * main.c (current_root): Remove global. - (set_root_directory): Set current_parsed_root directly. - (main): Use new Name_Root API. Restore deletion of root directories - list. - * root.c (Name_Root): Return a parsed cvsroot_t rather than a string. - -2004-09-23 Derek Price - - * sanity.sh (depends_on_ssh, sshstdio): Don't use skip() to skip - remote-only tests. - -2004-09-23 Mark D. Baushke - - * server.c (cvs_output, cvs_output_binary): fflush (stderr) - here to avoid problems with 'cvs status 2>&1'. - (Report by Frank Hemer .) - -2004-09-23 Derek Price - - * sanity.sh (crerepos, sshstdio): Minor modifications to make use of - the new depends_on_?sh API. - -2004-09-23 Derek Price - - * sanity.sh: Accept new -e option to interpret non-fatal calls to skip - as errors. - (skip, depends_on_rsh, depends_on_ssh): New functions. - -2004-09-12 Mark D. Baushke - - * rcs.c (RCS_checkout): Allow noexec to do checkouts when - server_active is true. - * sanity.sh (join7): Test above change (fixes a FIXCVS). - -2004-09-08 Mark D. Baushke - - * sanity.sh (join7): Fix if-then-else conditional. - - * server.c (server_updated): Deal with cvs -n update -jt1 -jt2 - "protocol error: uncounted data discarded" problem. - * sanity.sh (join7): New test for this case. - -2004-08-24 Derek Price - - * recurse.c (start_recursion): Don't shorten //. to / (use //). - -2004-08-24 Derek Price - - * recurse.c (start_recursion): Strip trailing CWD indirections on - repository. - * sanity.sh (rstar-toplevel): Update to account for new behavior. - (Report from Dan Peterson .) - -2004-08-24 Mark D. Baushke - - * recurse.c (do_recursion): Correct test for calling - server_pause_check to occur when locktype != CVS_LOCK_WRITE. - (Patch suggested by Ian Lance Taylor - in bug#198). - -2004-08-24 Derek Price - - * rcs.c (translate_symtag): Prevent infinite loop. - * tag.c (tag_check_valid): Check tag syntax before searching for tags. - * sanity.sh (tag-space): Some tests for the above. - (Report from Dan Peterson .) - -2004-08-24 Mark D. Baushke - - * ignore.c (ignore_directory): Include the terminating NUL - character in the directory name comparison to avoid matching - substrings of directories by accident. - (Report and suggested fix from James E Wilson - .) - * sanity.sh (modules4): Add some more tests testing the above - change. - -2004-08-17 Mark D. Baushke - - * sanity.sh (sshstdio): Fix comment typo plus gratuitous - reformatting. - - * client.c (handle_m): Workaround to deal with stdio getting put - into non-blocking via redirection of stderr and interaction with - ssh on some platforms. On those boxes, stdio can put stdout - unexpectedly into non-blocking mode which may lead to fwrite() or - fflush() failing with EAGAIN, but cvs not checking for the error. - (Patch suggested by Frank Hemer .) - - * client.c (handle_e): Similar fix for stderr. - * sanity.sh (sshstdio): New test for non-blocking stdio via ssh. - -2004-08-11 Derek Price - - * sanity.sh (basicc): Work around a problem in Linux 2.2 & Bash 2.05b - which prevents a `cd ..' from a deleted directory from working. - (Original patch from Matthew Ogilvie .) - -2004-06-22 Derek Price - - * wrapper.c: Add explicit "void" return type to "wrap_clean_fmt_str" - definition. - (Patch from Conrad T. Pino .) - -2004-06-09 Derek Price - - * commit.c, filesubr.c, history.c, server.c, wrapper.c: Various - security fixes. - (Original patch from Stefan Essler & Sebastian - Krahmer .) - - * cvs.h: Include xsize.h. - -2004-06-09 Derek Price - - * server.c (serve_entry, serve_is_modified, serve_unchanged): Protect - against malformed entries. - * sanity.sh (server): Tests for same. - -2004-06-07 Larry Jones - - * sanity.sh (basica): More tests for string-based revision inc. - -2004-06-04 Larry Jones - - * subr.c (increment_revnum): Rewrite ala RCS to work directly on - the string rather than converting to int to avoid overflow. - * sanity.sh (basica): New tests for above, update others to match. - -2004-05-19 Derek Price - - * server.c (serve_unchanged, serve_is_modified): Overwrite existing - data in timefields. Fixes CAN-2004-0396. - -2004-05-14 Derek Price - - * subr.c (file_has_conflict), vers_ts.c (time_stamp_server): Don't - require '=' to be the only character here, as this is potentially - destabilizing. - -2004-05-14 Mark D. Baushke - - * sanity.sh (trailingslashes): During cleanup remove topfile,v to - avoid problems in later tests (editor-1). - -2004-05-13 Derek Price - - * sanity.sh (trailingslashes): Note TODO item #205 in the comment. - -2004-05-13 Derek Price - - * sanity.sh (trailingslashes): New tests to expose a bug in CVS when - paths are specified with trailing slashes. This relates to TODO #205. - -2004-05-12 Derek Price - - * subr.c (file_has_conflict), vers_ts.c (time_stamp_server): Only - special case "=" when it is the only character in a timestamp field. - Gratuitous reformatting. - * vers_ts.c (time_stamp_server): Check for NULL in a consistent manner. - Gratuitous reformatting. - -2004-05-10 Derek Price - - * sanity.sh (top-level): Rename to... - (rstar-toplevel): ...this for clarity. - -2004-05-10 Derek Price - - * sanity.sh (dirs2-10ar): Remove unnecessary empty argument. - -2004-05-02 Larry Jones - - * log.c (log_expand_revlist): Suppress warnings if really_quiet. - -2004-05-07 Derek Price - - * sanity.sh (basica): Remove unnecessary empty arguments. - -2004-05-07 Derek Price - - * cvs.h (fopen_case): Remove obsolescent prototype. - -2004-05-05 Derek Price - - * sanity.sh: Wait a second and retry if cvs-serv* directories are - discovered to avoid race conditions on some systems. - (Patch from Pavel Roskin .) - -2004-05-05 Derek Price - - * commit.c: Some gratuitous reformatting. - -2004-05-04 Derek Price - - * update.c: Some gratuitous reformatting. - -2004-05-04 Derek Price - - * add.c (add): Remove obsolete FIXME comment. - (*): Some gratuitous reformatting. - -2004-04-26 Derek Price - - * client.c (start_rsh_server): Don't rely on GNU argument processing - capabilities in the RSH command. - (Report from Mark Andrews .) - -2004-04-19 Derek Price - - * ignore.c: Gratuitous reformatting. - -2004-04-11 Derek Price - - * client.c (call_in_directory): Check paths the server sends us to make - sure they are within a sandbox the user requested be updated. - (is_valid_client_path, path_list_prefixed): New functions. - -2004-04-11 Derek Price - - * modules.c (do_module): Don't allow up-level references in paths to - step out of the repository. - * sanity.sh (multiroot3): Update tests and add a few more. - -2004-04-07 Derek Price - - * sanity.sh (parseroot): Replace hard path with $HOME. - -2004-04-07 Derek Price - - * sanity.sh (parseroot): s/oberon/$username/. - -2004-04-07 Derek Price - - * client.c (start_tcp_server): Use xstrdup rather than - xmalloc(strlen)/strcpy. - -2004-04-07 Derek Price - - * root.c (parse_cvsroot): Ignore method options. - * sanity.sh (parseroot): Verify that method options are ignored. - -2004-04-06 Derek Price - - * root.h (cvsroot_t): Move username, password, hostname, port inside - CLIENT_SUPPORT ifdefs. - * buffer.c, root.c, server.c: Add #ifdefs as necessary so that this - will compile without client support and the root.h change. Some - gratuitous restyling. - -2004-04-06 Derek Price - - * log.c, tag.c: Gratuitous restyling. - -2004-04-04 Derek Price - - * filesubr.c (isabsolute): Move... - * subr.c: ...here and use new ISABSOLUTE macro. - -2004-04-04 Derek Price - - * client.c (send_file_names): Cast out an unneeded const to avoid a - warning. - -2004-04-03 Larry Jones - - * client.c (send_file_names): Remove unused variables. - -2004-04-02 Derek Price - - * sanity.sh (client): Honor $keep. - -2004-04-02 Derek Price - - * log.c, patch.c, rcs.c: Gratuitous restyling. - -2004-04-02 Derek Price - - * import.c (import): Use ISDIRSEP rather than testing paths against `/' - directly. Some gratuitos reformatting. - -2004-04-02 Derek Price - - * sanity.sh: Note the effectiveness of `tail -f check.log' in providing - running status. - -2004-04-02 Derek Price - - * client.c (send_file_names): Move code which calculates and sends - Max-dotdot... - (send_max_dotdot): ...to this new function. - (send_files): Call send_max_dotdot. - * sanity.sh (files-14): Expect .. in paths to work now. - (status): Add a few new tests using `..'. - -2004-04-01 Derek Price - - * lock.c: Gratuitous restyling. - -2004-04-01 Derek Price - - * cvs.h, server.c: Gratuitous restyling. - * run.c (run_exec): Ditto, plus call cvs_flush{out,err}() instead of - flushing stderr & stdout directly. - -2004-03-29 Derek Price - - * server.c: Gratuitous restyling. - -2004-03-29 Derek Price - - * login.c: Gratuitous restyling. - -2004-03-22 Derek Price - - * sanity.sh (toplevel): Remove FIXME type comment and unneeded - Emtptydir removal. - -2004-03-22 Derek Price - - * update.c: Some minor style cleanup. - -2004-03-22 Derek Price - - * sanity.sh (top-level): Don't match most of the assertion since this - string is often system dependent. - (Thanks to Larry Jones .) - -2004-03-22 Derek Price - - * sanity.sh (top-level): Don't match the assertion's line number. - -2004-03-22 Derek Price - - * sanity.sh (top-level): New test to confirm assertion failure. - -2004-03-22 Derek Price - - * sanity.sh: Only verify argument to -f when -f was passed. Check for - $TMPDIR/cvsXXXXXX temp files after each test. - -2004-03-22 Derek Price - - * sanity.sh: Verify that the argument to -f is really a test. - -2004-03-20 Larry Jones - - * cvs.h: Change command_name to cvs_command_name to avoid conflict - on HP-UX (incredibly, it declares a global command_name in prot.h, - which is included from shadow.h, which we include in server.c). - Change all references. - - * subr.c (previous_rev): Fix == vs = typo. - - * buffer.h: Add prototype for buf_empty. - - * add.c (add): Remove unused variable. - -2004-03-20 Derek Price - - * add.c (add, add_directory, build_entry), admin.c (admin_dirproc), - checkin.c (Checkin), checkout.c (safe_location, build_dirs_and_chdir), - client.c (add_prune_candidate, send_repository, send_a_repository, - send_to_server, start_rsh_server, send_arg, send_modified, - send_ignproc, send_filesdone_proc, send_dirent_proc, - send_dirleave_proc, client_notify), commit.c (check_direntproc, - check_filesdoneproc, checkaddfile, commit_direntproc, - commit_dirleaveproc, lock_RCS, precommit_proc, find_data, - find_dirent_proc, find_ignproc, find_filesdoneproc), create_adm.c - (Create_Admin), cvsrc.c (read_cvsrc), diff.c (diff_dirproc, - diff_filesdoneproc, diff_dirleaveproc), edit.c (onoff_filesdoneproc, - mark_up_to_date, editor_set, notify_proc_args, notify_proc, notify_do, - notify_check), entries.c (Scratch_Entry, Register, WriteTag), - expand_path.c (expand_variable, expand_path), fileattr.c - (fileattr_startdir), filesubr.c (mkdir_if_needed, xchmod, - last_component), history.c (history_write), ignore.c (ignore_directory, - ignore_files), import.c (get_comment, add_rcs_file, expand_at_signs),xi - lock.c (lock_filesdoneproc), log.c (log_dirproc), logmsg.c - (logfile_write, rcsinfo_proc, update_logfile_proc, editinfo_proc, - verifymsg_proc, do_editor, do_verify, Update_Logfile), main.c (main - program_name, program_path, command_name), parseinfo.c (Parse_Info), - patch.c (patch_dirproc), rcs.c (RCS_getdatebranch, rcs_lockfilename, - RCS_parse, RCS_setattic, RCS_getversion, RCS_gettag, RCS_getbranch, - RCS_getdate, RCS_datecmp, RCS_getrevtime, RCS_setexpand, - expand_keywords, RCS_checkout, RCS_addbranch, RCS_checkin, RCS_lock, - RCS_cmp_file, RCS_deltas, rcs_lockfilename, make_file_label), - rcscmds.c (RCS_output_diff_options, call_diff, RCS_merge, - RCS_exec_rcsdiff, diff_exec), recurse.c (start_recursion, do_recursion, - do_file_proc), remove.c (remove_dirproc), repos.c (Name_Repository, - Short_Repository), root.c (Name_Root, Create_Root), run.c - (piped_child), server.c (output_dir, server_register, - server_checked_in, server_update_entries, server_copy_file, - server_set_entstat, server_clear_entstat, server_set_sticky, - server_template, cvs_output_tagged), status.c (status_dirproc), subr.c - (make_message_rcslegal), tag.c (pretag_proc, tag_dirproc, - check_fileproc, check_filesdoneproc, tag_fileproc, val_direntproc), - update.c (update_dirent_proc, update_dirleave_proc, update_ignproc, - update_filesdone_proc, isemptydir), vers_ts.c (time_stamp_server, - time_stamp), watch.c (watch_modify_watchers, addremove_filesdoneproc), - zlib.c (read_and_gzip): Make most string args const, mainly in the - interest of preserving repository & updatedir but including some - collateral damage. Update a few functions to comply with new - requirement. Some style fixes. - * client.h, cvs.h, edit.h, fileattr.h, rcs.h, server.h, update.h, - watch.h: Update prototypes to match. - -2004-03-20 Derek Price - - * sanity.sh (conflicts2): s/cvs/$testcvs/. - -2004-03-20 Derek Price - - * add.c (add): Correct longstanding resurrection bugs. Remove FIXME - comment to this effect. Set mode and Entries timestamps of resurrected - files correctly. - * sanity.sh (basica, binfiles, conflicts2, recase, resurrection, - update-p): Update tests to compensate. Remove FIXCVS comments. - -2004-03-19 Mark D. Baushke - - * server.c (gserver_authenticate_connection): Handle large - GSSAPI packets dynamically. - (Bug report from Douglas Engert ) - -2004-03-19 Derek Price - - * cvs.h (pathname_levels, previous_rev): Remove leading underscore from - prototype arguments to avoid potential conflicts with implementations. - -2004-03-18 Derek Price - - * cvs.h (pathname_levels): Make string argument const. - * subr.c (pathname_levels): Simplify function. - -2004-03-17 Derek Price - - * subr.c (pathname_levels): Get it right this time. - -2004-03-17 Derek Price - - * subr.c (pathname_levels): Remove incorrect assertion and just - return 0 when pathname is NULL. - -2004-03-17 Derek Price - - * subr.c (pathname_levels): Use ISDIRSEP() instead of strchr('/') - and remove FIXME comment to that effect. - -2004-03-16 Derek Price - - * main.c (main): Update the --version Copyright (c) string to - include 2004. - -2004-03-15 Mark D. Baushke - - * release.c (release): Add missing xmalloc of update_cmd. - -2004-03-15 Derek Price - - * release.c (release): Enable authentication and encryption for a child - update process when necessary. - (Original patch from Dan Russell via Hal Mahaffey - .) - -2004-03-14 Derek Price - - * add.c (add): Only call server_updated() when we actual have a new - resurrected file for the client. - -2004-03-14 Derek Price - - * cvs.h (previous_rev, write_letter): New prototypes. - (struct file_info): Move to before the write_letter prototype. - * add.c (add): Allow resurrection of files which used to exist on a - branch. - * subr.c (previous_rev): New function. - * update.c: Consolidate like pragmas. - (write_letter): Remove prototype. Remove static declaration. - * sanity.sh (resurrection): New tests. - -2004-03-14 Derek Price - - * commit.c (remove_file): Print the actual previous revision instead of - a branch number. - * sanity.sh: Update to match. - -2004-03-14 Derek Price - - * rcs.c (RCS_cmp_file): Print the actual name of the file we failed to - open in the error message. - -2004-03-14 Derek Price - - * diff.c (diff_fileproc): Allow diffing of new files against arbitrary - revisions instead of assuming that there is no RCS archive file. - -2004-03-03 Derek Price - - * import.c (import): Check that the module name specified by the user - does not contain `CVS' as a directory name. - * ignore.c (ign_add): Never cease ignoring "CVS" - it is a reserved - name. - (Original patch from Dan Peterson .) - - * sanity.sh (import-CVS): New tests for the above. - -2004-02-29 Larry Jones - - * import.c (expand_at_signs): Change type of len to size_t. - * subr.c (resolve_symlink): Move declaration of newname inside - #ifdef, clean up coding style. - * zlib.c (gunzip_and_write): Fix up potential overlow problems. - (read_and_gzip): Add explicit casts to placate paranoid compilers. - -2004-02-28 Larry Jones - - * sanity.sh (join6): New tests for previous fix. - - * update.c (join_file): One more fix to avoid dereferencing NULL. - (Reported by Steve McIntyre .) - * sanity.sh (join6): New tests for above. - -2004-02-25 Larry Jones - - * update.c (join_file): Fix optimization to avoid dereferencing NULL. - (Reported by Steve McIntyre .) - -2004-02-25 Derek Price - - * buffer.c (buf_empty): New function. - * server.c (server): Check for unread data in buffer before closing. - -2004-02-25 Derek Price - - * release.c (release): Restore the initial directory before and after - calling various sections of code that expect it to prevent corruption - of CVS/Entries files on release of a subdir and tell unedit() what to - release. - * sanity.sh: Add test case for release.c fix. - (Original patch from Matthew Ogilvie .) - - * client.c (last_entries): Move global variable... - (call_in_directory): ...here (now a local variable). Remove test that - always evaluates to true. - (last_dir_name): Remove unused global variable. - -2004-02-24 Larry Jones - - * filesubr.c (xresolvepath): Fix crash in error case. - (Reported by Reinhard Zierke .) - -2004-02-24 Derek Price - - * sanity.sh (crerepos): Minor stylistic changes to previous change. - -2004-02-24 Derek Price - - * sanity.sh (crerepos): Fix it so that it ignores the user's - .cvsrc file (.cvsrc "checkout -r" used to cause the "rm -r 1" - command to print warnings and wait for input). - (Original patch from Matthew Ogilvie .) - - * sanity.sh (reposmv, parseroot, devcom3, binwrap3): - s/_SAVED\>/_save/ for consistency. - -2004-02-20 Derek Price - - * subr.c (set_nonblock_fd): Move back to... - * server.c: ...here. - * cvs.h: Remove protos for the above two functions. - * buffer.c (stdio_buffer_shutdown): Remove unexessary and possibly - dangerous check for unread data on a pipe with a nonblock read. - -2004-02-20 Derek Price - - * ChangeLog, commit.c, filesubr.c, rcs.c, root.c, sanity.sh, subr.c, - update.c: Remove VIM editor commands. - -2004-02-20 Larry Jones - - * hash.h (struct node): Change data from char * to void *, change - all callers. - -2004-02-19 Larry Jones - - * login.c (password_entry_operation): Initialize line. - -2004-02-19 Derek Price - - * sanity.sh (crerepos): Correct comment. - -2004-02-19 Derek Price - - * sanity.sh (crerepos): Don't create directories named `tmp' in - $TESTDIR to avoid conflicts with the default value of $TMPDIR. - -2004-02-19 Derek Price - - * sanity.sh (directory_cmp): Use $TESTDIR for temporary files, like the - dotest functions. - -2004-02-19 Derek Price - - * sanity.sh: No longer allow user override of $tmp. Set $TMPDIR to a - directory under $TESTDIR, as for $HOME, but still allowing for user - override. Check for cvs-serv* directories under $TMPDIR rather than - $tmp at the end of the script. - -2004-02-17 Derek Price - - * sanity.sh: Check for $PWD != $TESTDIR after each set of tests rather - than once at the end. Check that there are no cvs-serv* directories in - $tmp after each set of remote tests. - -2004-02-17 Derek Price - - * sanity.sh: Don't check for an empty $TESTDIR - if $TESTDIR was empty - then the preceding call to mkdir would have failed anyhow. - -2004-02-17 Larry Jones - - * log.c (rlog_proc): Fix (harmless) uninitialized variable. - - * sanity.sh (basicc): Add tests pointing out defective handling - of the Entries file. - -2004-02-17 Derek Price - - * checkout.c (build_dir_and_chdir): Expand header comment. - -2004-02-15 Mark D. Baushke - - * annotate.c (rannotate_proc): Plug a memory leak. - * log.c (log_fileproc): Ditto. - * tag.c (tag_fileproc): Ditto. - * update.c (checkout_file): Ditto. - * server.c (server_updated): Do not buf_free (filebuf) here. - -2004-02-13 Larry Jones - - * rcs.c (locate_rcs): Remove unused variables. - -2004-02-12 Mark D. Baushke - - * lock.c (readers_exist): Plug a memory leak. - -2004-02-12 Mark D. Baushke - - * server.c (do_cvs_command): Plug a memory leak. - -2004-02-12 Derek Price - - * modules.c: Reformat comment and line to fit in 80 chars. - -2004-02-12 Larry Jones - - * modules.c (_do_module): Rename to my_module to avoid reserved name. - * stack.c (_push, _pop, _unshift, _shift): Rename to do_*. - -2004-02-11 Larry Jones - - * root.c (parse_cvsroot): Set hostname in fork mode for error messages. - * buffer.c (stdio_buffer_shutdown): Undo previous change. - -2004-02-11 Mark D. Baushke - - * buffer.c (buf_free): Plug a memory leak. - * commit.c (checkaddfile): Ditto. - - * server.c (fd_buffer_shutdown): Avoid a double free(). - - * parseinfo.c (parse_config): Fix comments. - -2004-02-11 Derek Price - - * buffer.c (stdio_buffer_shutdown): Add logic to avoid attempting to - print current_parsed_root->hostname when using the fork method. - -2004-02-11 Derek Price - - * server.c (do_cvs_command): Simplify stream & pipe closing. - (Suggestion from Eric Siegerman .) - - * cvs.h, subr.c (set_block_fd): Remove this unnecessary function. - -2004-02-11 Derek Price - - * checkout.c (checkout_proc): s/is_absolute/isabsolute/. - -2004-02-11 Derek Price - - * checkout.c (checkout_proc): Remove unneeded variable and enclosing - block. - * modules.c (_do_modules): Minor whitespace change. - -2004-02-10 Derek Price - - * server.c (do_cvs_command): s/FIXCVS/FIXME/ in comment. - (set_block_fd, set_nonblock_fd): Move to... - * subr.c: ...here. - * cvs.h: Add protos for the above two functions. - * buffer.c (stdio_buffer_shutdown): Replace fgetc() which checked for - unread data on a pipe with a nonblock read. - -2004-02-10 Derek Price - - * server.c (do_cvs_command): Have the server child close all the pipes - but the flow control pipe and wait on an EOF on the flow control pipe - from the parent when done to avoid a race condition that could - otherwise generate a SIGPIPE for the parent before the SIGCHILD when - the other pipes were so full after a child exited that the parent - attempted to write a stop byte to the flow control pipe. - (Original report from .) - -2004-02-10 Derek Price - - * buffer.c (stdio_buffer_shutdown): Add a helpful comment. - -2004-02-09 Derek Price - - * sanity.sh (co-d): Update comments and tests to reflect the current - state of my side of my discussion with Larry Jones on how these - commands should behave. - -2004-02-09 Derek Price - - * sanity.sh (emptydir): Add two new tests for how modules -d behaves - when a directory already exists in the user's workspace. - (emptydir): Add --keep functionality. - -2004-02-09 Derek Price - - * sanity.sh (co-d): New test to prove `co -d' failure case. - -2004-02-05 Derek Price - - * sanity.sh (recase): Fix typo that creeped in somehow between my last - test run and my commit. - -2004-02-04 Derek Price - - * stack.c (shift, shift_string): Make sure these functions return their - result. - -2004-02-04 Derek Price - - * modules.c (do_modules): Move content to and make this function a - wrapper for... - (_do_modules): ...this new function which can watch for infinite loops - in alias modules. - * stack.c (_push, _pop, _unshift, _shift, push_string, pop_string, - unshift_string, shift_string): New - functions. - * stack.h (push_string, pop_string, unshift_string, shift_string: New - prototypes. - * sanity.sh (modules): Add check for nested alias loops. - -2004-02-04 Derek Price - - * sanity.sh (recase): Update test names and comments for clarity and - consistency. - -2004-02-03 Derek Price - - Preserve the case of checked out directories in a path as well as file - names for client communication with the server. - - * Makefile.am (cvs_SOURCES): Add stack.c & stack.h. - * stack.c, stack.h: New files. - * cvs.h: Include stack.h. - * client.c (send_file_names): Preserve the case of directories in a - path as well as file names for communication with the server. - - * Makefile.in: Regenerated. - -2004-02-02 Derek Price - - * sanity.sh (join-rm): New test for issue #104 & #159. - -2004-02-02 Derek Price - - Continue removal from server of handling of case insensitive clients. - - * cvs.h: Remove extern declaration of ign_case. - * ignore.c (ign_case): Remove declaration. - (ign_name): Remove support for ign_case. - * server.c (serve_case): Ditto. - (requests): No longer support the "Case" request. - * rcs.c (locate_rcs): Remove reference to GLOBAL in function header - comment. - -2004-02-02 Derek Price - - * add.c, client.c, cvs.h, rcs.c, subr.c: Remove server support for case - insensitivity. - -2004-01-25 Derek Price - - * server.c (kserver_authenticate_connection): Fix call to - switch_to_user(). - (Original patch from Alexey Mahotkin .) - -2004-01-22 Derek Price - - * modules.c (do_module): Strip trailing slashes before checking for - infinite alias loops. - * sanity.sh (modules): Tests for response to infinite alias loops. - -2004-01-17 Mark D. Baushke - - * logmsg.c (do_verify): Eliminate double-free bug. - (Original patch from Gerald Combs.) - -2004-01-07 Larry Jones - - * checkout.c (safe_location): Remove unused variable(s). - * lock.c (lock_tree_for_write): Ditto. - * rcs.c (RCS_checkin): Ditto. - * subr.c (compare_revnums): Ditto. - * tag.c (tag_check_valid): Ditto. - * mkmodules.c (init): Initialize err and return it rather than 0. - * server.c (do_cvs_command): Only define and set max_command_fd if - we're actually going to use it. - -2004-01-01 Larry Jones - - * zlib.c (read_and_gzip, gunzip_and_write): Fix potential buffer - overruns, use names for magic numbers. - (Original patch from Jeff Downs .) - -2003-12-18 Derek Price - - * server.c (switch_to_user): SysLog attempts to root from pserver. - -2003-12-18 Derek Price - - * server.c (switch_to_user): Don't allow CVS to run as root in pserver - mode. - (Original patch from Wichert Akkerman via Bradley M Kuhn - .) - * sanity.sh (pserver): Check for bad root error message. - -2003-12-17 Larry Jones - - * run.c (close_on_exec): fcntl is not documented to return 0 for - success (and QNX doesn't), only -1 for error. - (Patch from George Refseth .) - -2003-12-09 Mark D. Baushke - - * server.c (template_proc): Fix broken Template protocol code. - Must call send buf_send_counted() for Template files to avoid - "Protocol error: uncounted data discarded" messages in some - circumstances. - (Problem reported by "Jim.Hyslop" .) - -2003-12-03 Derek Price - - * sanity.sh (recase-8csss): rename to... - (recase-8sscs): ...this to match the convention. - -2003-12-03 Derek Price - - * sanity.sh (recase): Add some clarifying comments. - -2003-12-03 Larry Jones - - * expand_path.c (expand_variable): Expand ${CVSROOT} to just the - directory like it's supposed to be. - (Reported by Michael S. Tsirkin .) - -2003-11-26 Derek Price - - * sanity.sh (modules3-2): Simplify syntax that may have given Cygwin - intermittent conniptions. - -2003-11-25 Mark D. Baushke - - * sanity.sh (recase-17sscs): Use ${CVSROOT_DIRNAME} in pattern. - -2003-11-25 Derek Price - - * sanity.sh (release): Perform forgotten cleanup. - -2003-11-25 Derek Price - - * commit.c (commit_fileproc): Reword comment. - -2003-11-25 Derek Price - - * add.c (add): Disable ign_case for the purposes of adding a file so - that recasing the name of a file is possible from a case insensitive - client. - * sanity.sh (recase): New tests for behavior which varies when the - client and/or the server are case insensitive. - -2003-11-25 Derek Price - - * sanity.sh (devcom3-9ar): Ignore the stderr output since it varies - considerably between platforms. - -2003-11-24 Larry Jones - - * diff.c (diff_file_nodiff): use_rev1 does *not* imply that diff_rev1 - is not null, diff_date1 could be set instead (ditto for use_rev2). - (Reported by .) - -2003-11-24 Derek Price - - * sanity.sh (modes3): Skip modes3-5 entirely under Cygwin since - permisions are broken there. This change removes most of the earlier - Cygwin differentiation in this test ($cygwin_hack & $cygwin_hack2) in - favor of skipping the test entirely. - -2003-11-21 Larry Jones - - * hash.c (printnode, printlist): Cast %p arguments to void * as - required by the C standard. - -2003-11-21 Derek Price - - * sanity.sh: Add `-h ' option to enable testing across a - :ext: connection to another host. Warn when `-h' is specified without - $TESTDIR. Leave $TESTDIR intact when it looks absolute since it may - contain symlinks. Allow $CVS_SERVER to be overridden via the - environment for `-h'. Default $CVS_RSH to `rsh'. - (*): Use $CVS_RSH to perform certain commands on the remote host (esp. - `ln -s' and `chmod') when `-h' is specified to work around - incompatibilities with CygWin & Samba. Add a few other minor - workarounds for Cygwin bugs. - - (newroot): New function. - (*): Use newroot when appropriate. - -2003-11-19 Larry Jones - - * rcs.c (RCS_getrevtime): Add error checking; cleanup. - -2003-11-18 Derek Price - - * modules.c (do_module): Reject absolute paths. - (Report and suggested fix from Tony Hoyle .) - - * sanity.sh (abspath2): Check for the above. - (spacefiles): Remove tests that expect absolute paths to files in the - top level repository directory to work. - (tests): Add abspath2. - -2003-11-13 Derek Price - - * rcs.c (RCS_delete_revs): It's `&&', not `and'. - -2003-11-13 Derek Price - - * sanity.sh: Create the empty log to make it easier to tail immediately - after the script is started. - -2003-11-13 Derek Price - - * sanity.sh (exit_help): Correct help to specify `-H' and not `-h' as - the help option. - -2003-11-13 Derek Price - - * rcs.c (RCS_delete_revs): Don't use the WOE32 kludge which refuses to - delete revisions from bvinary files on Cygwin. I'm not sure what the - kludge was trying to avoid, but commenting it out causes the test suite - to pass. - -2003-11-10 Derek Price - - * commit.c (check_fileproc, find_fileproc): Don't leak memory. - -2003-11-10 Derek Price - - * commit.c (find_fileproc, check_fileproc): Refuse to remove files - when the file exists in the sandbox. This used to cause data loss. - (Report from Andreas Reifschneider .) - - * sanity.sh (rmadd3): Update to match. Expand comments. - -2003-11-10 Derek Price - - * sanity.sh (rmadd3): Test the behavior of commit after the - add/replace. - (Report from Andreas Reifschneider .) - -2003-11-10 Mark D. Baushke - - * Backport symlink bugfix from cvs 1.12.1.1 feature release - as written by Derek Price . (This fixes - the Issue 142 bug.) - - * recurse.c (start_recursion): Accept new repository argument so - that the working directory may be tracked by do_recursion without - using xgetwd(), which returned a value different from the one the - user requested when symlinks were in use. Pass repository_in to - do_recursion() as part of the recursion frame. - - * cvs.h (xreadlink): #ifdef HAVE_READLINK proto. - (xresolvepath): New proto. - (start_recursion): Add repository to proto. - - * checkout.c (safe_location): Add more complete header comment. - Add trace. Use new xresolvepath() function. Always return true - in client mode since checking our destination path against the - CVSROOT path is usually meaningless in client/server mode. - (checkout_proc): Pass repository to do_update() for later use with - start_recursion(). - - * admin.c (admin): Use new definition of start_recursion(). - * annotate.c (rannotate_proc): Ditto. - * client.c (send_files): Ditto. - * commit.c (commit): Ditto. - * diff.c (diff): Ditto. - * edit.c (watch_onoff, send_notifications, edit, unedit, editors): - Ditto. - * lock.c (lock_tree_for_write): Ditto. - * log.c (rlog_proc): Ditto. - * patch.c (patch_proc): Ditto. - * remove.c (cvsremove): Ditto. - * tag.c (rtag_proc): Ditto. - * update.c (do_update): Ditto. - * watch.c (watch_addremove, watchers): Ditto. - - * patch.c (patch_proc): Call tag_check_valid with repository - instead of NULL. - - * filesubr.c (xreadlink): #ifdef HAVE_READLINK this function. Add - more complete header comment. - (xresolvepath): New function. - - * recurse.c (do_recursion): Call Lock_Cleanup() only repository - was set. - - * update.c (do_update): Accept new repository argument so that the - working directory may be tracked. - (update): Pass NULL repository to do_update(). - * update.c (do_update): Add repository to proto. - - * checkout.c (checkout_proc): Use new definition of do_update(). - * update.c (update): Ditto. - - * sanity.sh: Add new -l option to test symlinked roots. - (checkout_repository-1): Add server error messages about absolute - paths since the client now skips destination validity checks. - (check_repository-2): Test renamed to checkout_repository-2. - (checkout_repository-2): Process client error messages about - CVSROOT files being in the way since the client skips destination - validity checks since it should be rare that a client is running - in client/server mode on the server and CVS has no current way to - check if it is running on the server. - (check_repository-3): Test renamed to checkout_repository-3. - (dottedroot): New test to check that a CVSROOT with a "." in the - name will work. - -2003-11-10 Derek Price - - * sanity.sh (rmadd3): Add whitespace after end of test for readability. - -2003-11-10 Derek Price - - * sanity.sh (rmadd3): New tests that confirms that CVS refuses to - delete a file it thinks was already removed. - (Report and test from Andreas Reifschneider - .) - -2003-11-03 Derek Price - - * sanity.sh (server): Test that the global `-l' option is ignored - nonfatally. - -2003-11-01 Larry Jones - - * ignore.c (ignore_files): Use CVS_LSTAT() instead of lstat(). - * filesubr.c (xcmp): Make sure S_ISLNK exists before calling it. - (Reported by Paul Edwards .) - -2003-10-31 Derek Price - - * sanity.sh (checkout_repository): Name tests consistently. - -2003-10-31 Derek Price - - * sanity.sh: s/${TESTDIR}/cvsroot/${CVSROOT_DIRNAME}/. - -2003-10-28 Derek Price - - * sanity.sh (devcom): s/cvs/$PROG/. - -2003-10-28 Derek Price - - * sanity.sh (devcom): Renumber tests and use dotest function. - -2003-10-28 Derek Price - - * sever.h: Add the standard copyright notice. - -2003-10-28 Derek Price - - * lock.c: Remove some suggestions which have already been implemented - or which have become obsolete from the header comment. - -2003-10-26 Derek Price - - * sanity.sh (join6): Fix a few typos in the last test and remove a - misplaced test. - -2003-10-25 Mark D. Baushke - - * sanity.sh (parseroot): Perform this test in a subdirectory. - It should avoid problems on case-insensitive systems where - CVSROOT and cvsroot are the same directory (eg, MacOS X). - -2003-10-24 Derek Price - - * update.c (join_file): Restore the optimization Mark recently removed, - but fix it. Move one other optimization up since it needs to be - checked for first. Add bew status messages like merge_file produces - when the requested diff has already been applied to the destination. - Expand header comment. - * sanity.sh (join6): Add tests for the new error messages. - (import-113, join-admin-2, diffmerge1): Fix collateral damage. - -2003-10-23 Mark D. Baushke - - * update.c (join_file): Do the -jrev1 -jrev2 merge even when - the file is already at rev2. - * sanity.sh (join6): New testcase for above. - (Suggested by Paul Edwards, from somewhere in Australia.) - (import): Fix collateral damage. - -2003-10-23 Derek Price - - * sanity.sh (fail): Refer the user to the `TESTS' and `check.log' files - on failure. - -2003-10-19 Mark D. Baushke - - * sanity.sh (admin-31): Fix more typos. - -2003-10-18 Mark D. Baushke - - * sanity.sh (admin): Fix a typo. - - * admin.c (admin_fileproc): Restore the ':' character in the - -mtag:message admin argument even if the tag does not exist so - that other files with the tag will be found. Also, be more - paranoid that a symbolic tag actually points to a version that - exists. - (Reported by Rodolfo Schulz de Lima .) - * sanity.sh (admin): Test these changes. - -2003-10-17 Mark D. Baushke - - * admin.c (admin_fileproc): Force tag match on admin - -mversion:message rather than altering the wrong log message. - (Patch from "Rodolfo Schulz de Lima" .) - * sanity.sh (admin): Test case for it. - -2003-10-15 Larry Jones - - * commit.c (commit_fileproc, finaladd): Don't call fixaddfile() - if the RCS file didn't get created at all. - (Reported by David Wood .) - -2003-10-14 Derek Price - - Port to pedantic POSIX 1003.1-2001 hosts, such as Debian GNU/Linux - testing with _POSIX2_VERSION=200112 in the environment. - - * sanity.sh: Use 'sed 1q', not 'head -1'. - (Patch from Paul Eggert .) - -2003-10-10 Derek Price - - * lock.c (set_lock): Clarify comment. - -2003-10-08 Derek Price - - * Makefile.am (cvs_SOURCES): Add history.h. - * history.c: Include history.h. Add the `P' record types to more - comments. s/ALL_REC_TYPES/ALL_HISTORY_REC_TYPES/. - (usage): Reference ALL_HISTORY_REC_TYPES rather than using a separate - string literal. - (report_hrecs): Handle `P' record type. - (ALL_REC_TYPES): Rename and move... - * history.h (ALL_HISTORY_REC_TYPES): ...here. - * mkmodules.c: Include history.h. - (config_contents): Update contents of and references to LogHistory - records to use ALL_HISTORY_REC_TYPES. - * sanity.sh (basic2-64): Update to include history records of type `P'. - - * Makefile.in: Regenerated. - -2003-10-08 Derek Price - - * update.c (patch_file): Correct spelling and punctuation in comment. - Update some lines to fit in 80 characters. - -2003-10-08 Larry Jones - - * history.c (history): Don't conflate -e with -x since the client's - idea of what -e means may not match the server's. - (Reported by Frank Hemer .) - -2003-10-07 Larry Jones - - * sanity.sh: Use dotest_fail instead of dotest_status for diff tests - since CVS only returns success/fail rather than 0/1/2 like diff does. - -2003-10-07 Derek Price - - Fix a client/server bug introduced via the data loss fix of 2003-03-17. - Basically, the server was reporting ambiguous filename requests when it - should have been trusting the user to type the intended case or using - the case the client preserved in CVS/Entries before it tried to look - anything up in case insensitive mode. - - * rcs.c (locate_rcs): Use the filename exactly as cased before - investigating a case insensitive lookup, per the client/server protocol - specification. Expand comments. - * subr.c (locate_file_in_dir): This function only needs to locate files - case insensitively. Expand comments. - * cvs.h (locate_file_in_dir): Only prototype when servers which need to - handle case insensitivity are being compiled. - -2003-10-07 Derek Price - - * rcs.c (locate_rcs): Declare static. Move to an earlier location in - file to avoid prototyping. - * rcs.h (locate_rcs): Remove proto. - -2003-10-03 Derek Price - - * server.c (serve_global_option): Warn that -l is being ignored rather - than exiting fatally due to backwards compatibility complaints from - administrators. - -2003-09-29 Derek Price - - * rcs.c (make_file_label): Make a failure to stat a file a fatal error - since it signals that a later read will also fail. - -2003-09-26 Derek Price - - * diff.c (diff): Add a FIXME re spaces in diff arguments. - -2003-09-25 Mark D. Baushke - - * rcs.c (make_file_label): Do not return an uninitialized label. - (Reported by "Todd C. Miller" ) - -2003-09-12 Derek Price - - * sanity.sh (mkmodules): Correct comments. - -2003-09-12 Derek Price - - * mkmodules.c (mkmodules): Do not pass a string which came from the - checkoutlist file directly to error as a format string since we don't - want to trust any user with access to checkoutlist with creating printf - format strings. I already claimed I did this in the NEWS file. - (Thanks to Larry Jones for spotting my mistake.) - * sanity.sh (mkmodules): Test for the above. - -2003-09-12 Derek Price - - * mkmodules.c (checkoutlist_contents): Document the optional portions - of this file format more accurately. - (mkmodules): Ditto, in comments. Fix bug that always failed to ignore - whitespace before error messages. - * sanity.sh (mkmodules-temp-file-removal): Rename to... - (mkmodules): ...this and add a test of the checkoutlist error message. - Add cleanup step to restore checkoutlist. - -2003-08-27 Larry Jones - - * history.c: 'P' is a valid record type and has been for a long time. - Add it to the comments, usage message, and, most important, - ALL_REC_TYPES so it gets recorded by default. - * server.c (do_cvs_command): Set global command_name to the real - command name rather than leaving it set to "server". - * sanity.sh: Update to match. - (Reported by Dmitry Ryzhkov .) - -2003-08-13 Larry Jones - - * server.c (server_cleanup): Don't shutdown buf_from_net if it's - null. - (Reported by Scott Mitchell .) - -2003-08-01 Derek Price - - * sanity.sh (join5): Use $PROG consistently and escape a `.'. - -2003-08-01 Derek Price - - * sanity.sh (join5): Use `[a-z]*' as opposed to `update'. - -2003-07-31 Derek Price - - * add.c (add_directory): Restore a malloc I shouldn't have altered on - the stable branch. - -2003-07-31 Derek Price - - * rcscmds.c (RCS_merge): Pass `--' before the filename arguments to - diff so that filenames starting with `-' can be merged. - * sanity.sh (join5): New test for same. - -2003-07-31 Derek Price - - * add.c (add_directory): Don't print status information in really_quiet - mode. - -2003-07-29 Derek Price - - * commit.c (checkaddfile): Simplify the logic here, using assumptions - already made later in the function to remove calls to locate_rcs and - some conditionals. Use same assumptions to remove some variables. - -2003-07-29 Derek Price - - * login.c: Remove GETPASS & HAVE_GETPASSPHRASE cruft in favor of always - using the GNULIB getpass since the system getpass was removed from the - POSIX.2 specification. - -2003-07-28 Derek Price - - * subr.c (strip_trailiing_newlines): Use size_t rather than int to - count string length. - (Suggestion from Paul Edwards, who provides a broken return email - address in Tonga. I believe he is actually from Australia.) - -2003-07-28 Derek Price - - * checkout.c (checkout): Remove out-of-date comment about Checkin.prog - and Update.prog. - -2003-07-25 Derek Price - - * rcs.c (RCS_parsercsfile): Declare rcsfile argument as const. - * rcs.h (RCS_parsercsfile): Update prototype to match. - * commit.c (fixaddfile): Accept a single path to an rcs file as an - argument rather than trying to look it up again when it is not - necessary. - -2003-07-25 Derek Price - - * commit.c (finaladd): But don't free variables we no longer allocate. - -2003-07-25 Derek Price - - * checkin.c (Checkin): The rcs argument is unecessary since we know - that the parsed RCS data always exists as part of finfo by the time - this function gets called. - * commit.c (commit_fileproc, finaladd): Use new Checkin() API. - * cvs.h (Checkin): Update prototype. - -2003-07-25 Derek Price - - * subr.c (strip_trailing_newlines): Check len b4 str[len] to avoid - exceeding the array bounds when the string length == 0. - (Report from John Tytgat .) - -2003-07-25 Derek Price - - * subr.c (strip_trailing_newlines): Generalize this function to watch - len so that it cannot walk past the beginning of the string passed in. - (Report from John Tytgat .) - -2003-07-25 Derek Price - - * subr.c (strip_trailing_newlines): Leave the K&R function decl on this - branch. - -2003-07-25 Derek Price - - * cvs.h (strip_trailing_newlines): Update prototype. - * subr.c (strip_trailing_newlines): Return true when newlines are - removed. - * server.c (pserver_authenticate_connection): Don't give a DOS attack a - chance to authenticate accidentally because I like to be paranoid. - * sanity.sh (pserver): New test for same. - -2003-07-20 Derek Price - - * wrapper.c: Remove mention of obsolete -f and -t wrapper options from - a comment. - -2003-07-12 Larry Jones - - * sanity.sh (diffnl): New tests for diff on files with no newline - at end. - (Patch from Andrew Moise .) - -2003-07-09 Larry Jones - - * add.c (add): Update "re-adding" message to have quotes around - the file name like all the other similar messages. - * sanity.sh: Update to match. - - * update.c (join_file): Handle locally removed but not yet committed - files. - (Reported by Larry Lords .) - * sanity.sh (join, join4): New tests for above. - -2003-06-28 Larry Jones - - * commit.c (fixaddfile): Bail out if locate_rcs() fails. Make - parameters const. - - * add.c (add): Fix -Wall complaints. - * diff.c (diff_file_nodiff): Ditto. - * filesubr.c (cvs_casecmp): Ditto. - * patch.c (patch_fileproc): Ditto. - * rcs.c (RCS_cmp_file): Ditto. - * root.c (parse_cvsroot): Ditto. - * subr.c (locate_file_in_dir): Ditto. - * cvs.h (cvs_casecmp, locate_file_in_dir): Update prototypes. - -2003-06-27 Larry Jones - - * lock.c (readers_exist): Use LockDir rather than always looking - in the repository. - (Original patch from Robert Ambalu .) - Remove vestigial lock promotion code. - -2003-06-26 Larry Jones - - * hash.c (sortlist): Avoid crash when list is null. - -2003-06-23 Derek Price - - * patch.c (patch_fileproc): Output revision number of the original - revision in the removed case. - (Idea from Paul Edwards .) - - * sanity.sh (rdiff-add-remove-nodiff): Rename to... - (rdiff-short): ...this. Test for the above changes. Add some tests - for when rev2 defaults to the trunk. Expand comments. - -2003-06-23 Derek Price - - * add.c (add): Fix xmalloc's strlen() of wrong variable. - * checkout.c (safe_location): leak: reused where_location without free. - * log.c (rlog_proc): leak: free where before exit. - * logmsg.c (do_verify): leak: free verifymsg_script before exit. - (Original patch from Kenneth Lorber .) - -2003-06-20 Derek Price - - * client.c: Remove silly comment. - (Patch from Alexey Mahotkin .) - -2003-06-13 Derek Price - - * subr.c (file_has_conflict): Fix comment. - (Patch from Paul Edwards .) - -2003-06-13 Derek Price - - * subr.c (xrealloc): Trivial comment fix. - (Patch from Kenneth Lorber .) - -2003-06-13 Derek Price - - * diff.c (diff_fileproc): Fix memory leak. - (Patch from Kenneth Lorber .) - -2003-06-12 Derek Price - - * root.c (parse_cvsroot, local_cvsroot): Parse trailing '/'s off the - end of cvsroots. Make arguments const. - * cvs.h: Update prototypes to match. - (Idea from Miles Zarathustra .) - -2003-06-11 Larry Jones - - * sanity.sh: Change warning messages to note that defective tools - can result in defective results, both pass and fail. Also change - "which" to "that" for errant grammar pedants. - -2003-06-09 Derek Price - - * rcs.c (RCS_delete_revs): Reference WOE32 rather than WIN32 in - accordance with the GNU convention to avoid implying that we consider - the Microsoft Windows Operating Environment any sort of "win". - -2003-06-09 Derek Price - - * filesubr.c (cvs_temp_file): Tidy a comment. - -2003-06-09 Derek Price - - * patch.c (patch_fileproc): Don't assume the content of files is - different just because the revision number is different. - * sanity.sh (rdiff-add-remove-nodiff): New tests for the above. - (Report & original patches from Paul Edwards .) - -2003-06-04 Derek Price - - * cvs.h (locate_file_in_dir): New proto. - (locate_rcs): Move proto... - * rcs.h: ...here. - * filesubr.c (locate_rcs): Move function... - * rcs.c: ...here for Windows. - * filesubr.c (locate_file_in_dir): Move function... - * subr.c: ...here for Windows. - -2003-06-02 Derek Price - - * diff.c (diff_file_nodiff): Don't assume that because two specified - revision numbers are different, the contents are different. - (Original report & patch from Paul Edwards .) - - * diff.c (diff_file_nodiff): Pass through rev1_cache to be filled in - by RCS_cmp_file when it needs to check out revision 1 into a file. Add - some more informative error messages. Cleanup for efficiency & - readability. - (diff_fileproc): Pass the cached revision to RCS_exec_diff(). Clean up - the error exit code. Remove code killed by the changes to - diff_file_nodiff(). - * rcscmds.c (RCS_exec_rcsdiff): Accept and use new cached revision text - if present. - * rcs.c (RCS_cmp_file): Accept a second revision number and cache the - first revision if it needs to be checked out. - - * checkin.c (Checkin): Use new RCS_cmp_file(). - * import.c (update_rcs_file): Ditto. - * no_diff.c (No_Difference): Ditto. - - * cvs.h (RCS_exec_rcsdiff): New proto to match above changes. - * rcs.h (RCS_cmp_file): Ditto. - - * sanity.sh: Minor corrections to handle the above changes. - -2003-05-29 Derek Price - - * client.c (start_server): Don't send -l to server. - * history.c (history_write): Fix comment. - * main.c (main): Don't process -l. - * server.c (serve_global_option): Ditto. - (Suggestion from Rob Lanphier .) - -2003-05-23 Larry Jones - - * sanity.sh (info-cleanup-verifymsg): Avoid race in output. - -2003-05-22 Larry Jones - - * commit.c (commit): Fix leading zero stripping code to not strip - unless there's a following digit. - - * parseinfo.c (Parse_Info): Warn if multiple DEFAULT lines found. - * sanity.sh (info): New test for above. - -2003-05-21 Derek Price - - * Makefile.in: Regenerate with Automake version 1.7.5. - -2003-05-20 Larry Jones - - * parseinfo.c (Parse_Info): Fix stupid memory management error. - - * logmsg.c (do_verify): Treate Parse_Info errors as failure. - * parseinfo.c (Parse_Info): Don't call expand_path until executing - the command so that errors in unexecuted commands aren't reported. - * sanity.sh (info): New tests for above. - -2003-05-18 Mark D. Baushke - - * Makefile.am (localcheck,remotecheck): Use cvs$(EXEEXT) not cvs. - * Makefile.in: Regenerated. - * sanity.sh (status-init-7): Use ${PROG} not cvs in tests. - (branch-after-import-5): Ditto. - (keywordname-update-11): Ditto. - -2003-05-18 Larry Jones - - * server.h (kserver_authenticate_connection, - pserver_authenticate_connection): Add prototypes. - - * client.c (update_entries): Set file's access time to the current - time rather than the same as the modification time. - * vers_ts.c (Version_TS): Ditto. - -2003-05-01 Derek Price - - * main.c (main): Ignore -z when CLIENT_SUPPORT is not defined. - (Report from Jim Salter .) - -2003-05-01 Derek Price - - * repos.c (Sanitize_Repository_Name): Remove some old comments about - the defunct RELATIVE_REPOS macro. - * server.c (outside_root): Ditto. - -2003-04-30 Derek Price - - * add.c (add): Fix a possible, if unlikely, memory out of bounds error. - -2003-04-28 Derek Price - - * client.c (save_prog): Remove unneeded struct. - (checkin_progs, update_progs): Remove these unneeded globals. - (handle_set_checkin_prog, handle_set_update_prog, do_deferred_progs): - Remove these functions. - (send_repository): Remove checkin and update prog support. - (responses): Remove Set-checkin-prog and Set-update-prog. - (get_responses_and_close): Don't call do_deferred_prog(). - * commit.c (commit_usage): Remove reference to -n. - (commit): Don't set and send run_module_prog via -n. Don't run - Checkin.prog or Checkout.prog in local mode. - * modules.c (CVSMODULE_OPTS): Remove -i and -u. - (do_module): Don't process -i and -u options to set checkin and update - progs, respectively. - * server.c (server_prog, serve_checkin_prog, server_update_prog): - Remove unused functions. - (requests): Remove Checkin-prog and Update-prog. - * update.c (update_dirleave_proc): Remove update prog functionality. - - * cvs.h (CVSADM_CIPROG, CVSADM_UPROG): Remove unneeded defines. - * server.h (server_prog): Remove proto. - (progs): Remove enum. - - * sanity.sh (modules5): Remove tests for checkin and update programs. - -2003-04-10 Larry Jones - - * Makefile.in: Regenerated. - -2003-03-27 Mark D. Baushke - - * sanity.sh (rdiff2): Add new test case for SEGV problem reported - against cvs 1.11.5. - (Report from James Cribb) - -2003-03-26 Derek Price - - * client.c: Fix, reorganize, and comment ifdefs for AUTH_CLIENT_SUPPORT - and HAVE_GSSAPI. - * client.h: Ditto. Remove some unecessary server function prototypes. - -2003-03-26 Derek Price - - * client.c: Include the net headers for HAVE_GSSAPI. - (Report from Jim Salter .) - -2003-03-26 Derek Price - - * main.c (main): Verify the argument to -z when running without - CLIENT_SUPPORT since Eric Siegerman complained about being bit - by a run of `cvs -z -n up' which parsed the -n as the argument to - -z. - * sanity.sh (opterrmsg): New tests for -z argument checking. - -2003-03-26 Larry Jones - - * main.c (main): Use strtol() instead of atoi() when parsing -z - to detect errors. - (Reported by Eric Siegerman .) - -2003-03-24 Derek Price - - * Makefile.am: Update copyright notice. - - * Makefile.in: Regenerated. - -2003-03-19 Larry Jones - - * filesubr.c (mkdir_if_needed): Save errno since isdir() can clobber. - (Patch from Brian Poole .) - * sanity.sh (abspath-4): Update to match. - - * filesubr.c (locate_rcs): Fix gcc warning. - -2003-03-17 Derek Price - - * add.c: Correct comment. - * client.c: Ditto. - * checkin.c (Checkin): Pass work file name to RCS_checkin so that this - function works properly in the case insensitive mode. - * commit.c (checkaddfile): Fix and factor add logic so that the - correct files and directories are created in the case insensitive mode. - Reuse code in RCS_parse() below. This avoids a problem that could - cause corrupted RCS files to be created on an add from a case - insensitive system. Corrupted RCS files could cause later assertion - failures for everyone. - (locate_rcs): Move this function... - * filesubr.c (locate_rcs): ...here and rewrite it. - (fopen_case): Remove this function. - (locate_file_in_dir): New function. - * cvs.h (locate_rcs): Prototype new function. - * rcs.c (RCS_parse): Factor out file location into locate_rcs. - -2003-03-17 Larry Jones - - * server.c (switch_to_user): Add syslog calls for setgid/setuid - failure. - -2003-03-07 Derek Price - - * sanity.sh (help): Add explanation of CVS-TO-TEST and edit for - consistency. - -2003-03-07 Derek Price - - * sanity.sh (usage): Show users long --help rather than less - informative -h. - -2003-03-07 Derek Price - - * sanity.sh: Add support for long options. - (exit_usage): Move the actual generation of usage text to... - (usage): ...this new function and improve the usage message. - (exit_help): New function. - -2003-03-07 Larry Jones - - * commit.c (check_fileproc): Remove unused variables. - - * patch.c (patch): Pass local to do_module so that -l actually works. - (Reported by John Coers .) - (patch_fileproc): Fix uninitialized variables. - * sanity.sh: Define a DATE pattern for rdiff and use it. - (basic2-24a): New test for above. - -2003-03-06 Derek Price - - * subr.c (file_has_conflict): New file. - * commit.c (check_fileproc): Factor code into new file_has_conflict() - function. - * update.c (update_fileproc): Ditto. - * status.c (status_fileproc): Use new file_has_conflict() function. - (Report from Bernd Kuemmerlen .) - - * sanity.sh (status): New test for same. - -2003-03-05 Mark D. Baushke - - * rcs.c (RCS_magicrev): Backout CVS_LOCAL_BRANCH_NUM feature. - - * rcs.c (RCS_magicrev): CVS_LOCAL_BRANCH_NUM feature. - Port of the FreeBSD hack for setting the next magic branch number - to be used. The original patch was written by Peter Wemm - and may be found by visiting the URL: - http://www.freebsd.org/cgi/cvsweb.cgi/src/contrib/cvs/src/rcs.c.diff?r1=1.1&r2=1.2 - Implement a horrible (but simple) hack to allow some control over the - branch number that is assigned. This is specifically to support the - local commit feature of cvsup. If one sets $CVS_LOCAL_BRANCH_NUM to - (say) 1000 then branches the local repository, the revision numbers - will look like 1.66.1000.xx. This is almost a dead-set certainty that - there will be no conflicts with version numbers. - (This needs to be something more than an option to 'cvs tag' or 'cvs - rtag' as various parts of cvs "know" how to automatically branch files - (eg: cvs add). Trying to remember state is getting "Too Hard (TM)") - * sanity.sh (branches3): Test the CVS_LOCAL_BRANCH_NUM feature. - -2003-03-04 Derek Price - - * history.c (history_write): Remove unneeded O_CREAT in the call to - open() since we abort a few lines earlier if the file doesn't exist. - Add a comment to the effect that this is not the optimal method of - doing things and needs fixed. - -2003-02-28 Derek Price - - * root.c (parse_cvsroot): s/no_passwd/no_password/ in comments. - -2003-02-28 Derek Price - - * root.c (parse_cvsroot): Set no_password for :gserver: and :kserver: - as tokens should already be obtained via external sources. - * update.c (update_fileproc): Remove redundant code. - -2003-02-28 Larry Jones - - * lock.c (set_lock): If possible, try a short wait with no message - before calling lock_wait() to optimize master lock contention. - -2003-02-26 Larry Jones - - * checkout.c (checkout): Send "--" before file names. - * sanity.sh (spacefiles): Remote now works just like local. - -2003-02-25 Derek Price - - * sanity.sh (rcs4): Use UTC to work across timezones. - -2003-02-25 Derek Price - - * rcs.c (RCS_getdate): Fix a bug that shows up when checking out - files by date with the "-D date" command line option. There is - code in the original to handle a special case. If the date search - finds revision 1.1 it is supposed to check whether revision - 1.1.1.1 has the same date stamp, which would indicate that the - file was originally brought in with "cvs import". In that case it - is supposed to return the vendor branch version 1.1.1.1. - - However, there was a bug in the code. It actually compares the date - of revision 1.1 for equality with the date given on the command - line -- clearly wrong. This commit fixes the coding bug. - - Note: There is an additional bug which is _not_ fixed in this - commit. The date comparison should not be a strict equality test. - It should allow a fudge factor of, say, 2-3 seconds. Old versions - of CVS created the two revisions with two separate invocations of - the RCS "ci" command. We have many old files in the tree in which - the dates of revisions 1.1 and 1.1.1.1 differ by 1 second. - - This bug was discovered and fixed for FreeBSD cvs. See v 1.21 of - - for more information. - - * sanity.sh (rcs4): Tests for same. - (Patch from Mark D. Baushke .) - -2003-02-25 Derek Price - - * logmsg.c (logfile_write): Do not pass a NULL pointer to - fprintf() when we have an empty log message. - * sanity.sh (editor): Add new tests to verify correct behavior of - empty log messages. - (Patch from Mark D. Baushke , original report from - Piotr KUCHARSKI .) - -2003-02-25 Derek Price - - * cvsbug.in: Import use of mktemp function from RedHat 8.0's - CVS 1.11.2 RPM. Use new MKTEMP configure variable. Use new - SENDMAIL from configure. - - * Makefile.in: Regenerated. - -2003-02-25 Derek Price - - * watch.c (watch_usage): Use {} rather than () for literals. - -2003-02-14 Derek Price - - * watch.c (watch_usage): Make the repeatability of -a part of the - usage spec. - -2003-02-14 Derek Price - - * watch.c (watch_usage): Mention default for -a. Mention multiple - invocations of -a. Mention -R as default. Use required () rather than - optional [] around watch subcommand list in invocation spec. Use - `path' instead of `file'. Put variable <> around `action' and `path'. - -2003-02-07 Derek Price - - * commit.c (checkaddfile): Do not lose the vendor branch when - adding files to a new branch. Avoids extranious conflicts for - future vendor imports. This was found and fixed in FreeBSD cvs. - See http://www.freebsd.org/cgi/query-pr.cgi?pr=4033 for details. - * sanity.sh (branch-after-import): New test. - (Thanks to Mark D Baushke for forwarding the - patch and writing the test cases!) - - * sanity.sh (branch-after-import): Misc portablility and standard - changes. - -2003-02-12 Derek Price - - * main.c (main): Update copyright message to 2003. - -2003-02-21 Larry Jones - - * server.c (switch_to_user): Update comment, change error message - so it's not an exact duplicate of the one in check_password. - (check_repository_password): Add syslog call for password mismatches. - (check_password): Add syslog call for password mismatches, rearrange - code to simplify and eliminate redundancy. - (pserver_authenticate_connection): Remove syslog call, now done by - lower-level routines. - -2003-02-19 Larry Jones - - * sanity.sh (admin-10): Add test for repository files not in - working directory. - - * admin.c (admin_fileproc): Fix crash when no rcs file, return - failure status for bogus files. - * sanity.sh (admin-4a): Test for above. - (Original patch submitted by Mark D. Baushke ). - -2003-02-14 Larry Jones - - * log.c (log_expand_revlist): Fix crashes in error cases. - (Reported by Bart Santy .) - * sanity.sh (log): New tests for above. - -2003-02-01 Larry Jones - - * buffer.c (stdio_buffer_shutdown): Handle EINTR from waitpid. - (Patch from Johannes Grødem .) - -2003-02-08 Derek Price - - * rcs.c (RCS_checkout): Supply the full function name in the trace - output. - * update.c (checkout_file, join_file): Supply tag properly to - RCS_checkout more often. - (patch_file): Ditto. Fill out comments. - * sanity.sh (keyword, keywordname): Some changes to accomodate the fact - that the above changes cause patches generated by patch_file to fail - occassionally. - -2003-02-06 Derek Price - - * client.c: Use the complete path to the CVSADM_TEMPLATE file in - error messages. Remove related FIXME. - -2003-01-31 Derek Price - - * sanity.sh (keywordname): Change a "FIXME" comment to "FIXCVS". - -2003-01-30 Derek Price - - * sanity.sh (keywordname): New test. - -2003-01-23 Larry Jones - - * diff.c (diff_fileproc): Restructure code to simplify and eliminate - redundant tests. - - * server.c (do_cvs_command): Use WCOREDUMP macro rather than hard - coding test for core file. - -2003-01-21 Larry Jones - - * root.c (method_name): Redefine as a 2D array. - * root.h (method_name): Ditto. - -2003-01-21 Jim Meyering - - * add.c (add): Rename local-shadowing `i' to `j'. - - * root.c (method_names): Declare to be a const array of const strings. - (Name_Root): Save errno so it doesn't get clobbered - by the intervening error call. - Use getline's return value, mainly to save a call to strrchr. - -2003-01-20 Larry Jones - - * myndbm.c (O_ACCMODE): Parenthesize the replacement string so that - it parses correctly. - (Reported by Andres Bertens .) - -2003-01-15 Karl Fogel - - * server.c (dirswitch): Don't free dir_name until right before - allocating it again. This removes a potential double-free - problem, whereby this function could free dir_name and then - immediately return due to invalid directory syntax (without ever - reassigning dir_name), then reenter and free dir_name again. - - Thanks to Stefan Esser for the fix. - -2003-01-08 Larry Jones - - * client.c (update_entries): Only "0" is a special version number; - other numbers starting with 0 (like 0.1) are normal version numbers. - * commit.c (find_fileproc): Ditto. Also reorganize the code to - simplify the conditions. - (Reported by Michele Zamparelli .) - -2003-01-02 Larry Jones - - * rcs.c (getdelta): Use RCSDEAD rather than literal "dead". - -2002-12-27 Derek Price - - * admin.c: s/LOCK_(NONE|WRITE|READ)/CVS_$&/g; since the definition of - LOCK_WRITE clashes with a definition in objidl.h on Windoze platforms. - * annotate.c: Ditto. - * client.c: Ditto. - * commit.c: Ditto. - * cvs.h: Ditto. - * diff.c: Ditto. - * edit.c: Ditto. - * lock.c: Ditto. - * log.c: Ditto. - * patch.c: Ditto. - * recurse.c: Ditto. - * remove.c: Ditto. - * status.c: Ditto. - * tag.c: Ditto. - * update.c: Ditto. - * watch.c: Ditto. - * myndbm.c: Ditto & define O_ACCMODE when it isn't defined, as under - Windoze. - (Thanks to Stephane Rouleau , - Cristopher Seawood , and - Frederico Costa for all their hints, - tips, and patches for this problem.) - -2002-12-20 Derek Price - - * client.c (send_a_repository): Suppress a warning under Windoze. - -2002-12-19 Derek Price - - * Makefile.am: Remove reference to options.h. - * cvs.h: Ditto. - * options.h: Remove this obsolete file. - * sanity.sh: Remove comment about external diffs causing tests to fail - since CVS hasn't used external diffs in years. - - * Makefile.in: Regenerated. - -2002-12-16 Derek Price - - * admin.c: Disable cvsadmin group checking on the client. - (Reported by Dan Peterson .) - -2002-12-06 Derek Price - - * buffer.c: Replace calls to malloc with calls to xmalloc and calls to - realloc with calls to xrealloc. - * parseinfo.c: Ditto. - * root.c: Ditto. - * server.c: Ditto. - * zlib.c: Ditto. - * scramble.c: Change some comments to refer to xmalloc rather than - malloc. - (Reported by Dan Peterson .) - -2002-12-04 Derek Price - - * options.h: Remove CVS_ADMIN_GROUP. - -2002-12-02 Larry Jones - - * commit.c (commit): Strip leading zeros from numeric revision - in addition to trailing dots. - (Reported by Peter Meszaros .) - -2002-11-22 Larry Jones - - * sanity.sh: Note that the tests run for a long time. - - * checkout.c (safe_location): Use xstrdup, not strdup. - (Reported by Terrence Enger .) - -2002-11-19 Larry Jones - - * log.c (log_expand_revlist): Fix cross-branch correction code. - - * sanity.sh: Set $LANG for systems that ignore $LC_ALL. - (rcs2-7): Change date offset from 100 months to 96 months to reduce - periodic problems with invalid dates. - -2002-11-12 Derek Price - - * sanity.sh (rcslib-symlink): Use rm -f rather than a simple rm when - removing links because under some configurations of RH Linux 8.0 the - script pauses to ask for removal approval. - -2002-11-08 Derek Price - - * sanity.sh (importc): Update the use of the touch command to be - compliant with POSIX 1003.1-2001, SUS2, and SUS3 now that GNU touch - supports this. If this breaks any test platforms we should test - the behavior of touch like we do for other tools. - -2002-11-03 Derek Price - - * sanity.sh (rcs2-7): Notate with a wild untested hypothesis. - -2002-11-03 Derek Price - - * sanity.sh (rcs2-7): Notate with three more failure dates. - -2002-10-25 Derek Price - - * root.c: Change some calls to SYSTEM_CLEANUP() and then exit() to - more appropriate calls to error_exit(). - * server.c: Ditto. - * tag.c: Ditto. - -2002-10-24 Derek Price - - * buffer.c (stdio_buffer_shutdown): Remove the getc() call used to - detect spurious output from clients since getc() would sometimes - block and hang indefinately if the client kept the conection open but - sent no data. Bug reports state that this hapened frequently with - older clients connecting to 1.11.2 servers, especially when - compression is enabled. - (Original report from Mark D. Baushke . - Original patch from Ralf S. Engelschall - via Peter Wemm .) - -2002-10-05 Larry Jones - - * recurse.c (start_recursion, do_recursion): Allow write locking - in addition to read locking. Change all callers. - * cvs.h: Change prototype to match, add lock types. - * tag.c (rtag_proc, rtag_fileproc, tag_fileproc): Have start_recursion - use write locks rather than calling lock_dir_for_write to avoid deadly - embrace. - -2002-10-04 Larry Jones - - * client.c (get_responses_and_close, connect_to_pserver): Set - to_server and from_server to NULL after freeing. - * main.c (main): Clear server_active when finished. Also neaten - up the SERVER_SUPPORT ifdef's. - * server.c (do_cvs_command): Set protocol_inbuf, stderrbuf, and - stdoutbuf to NULL after freeing. - (server_cleanup): Free buf_from_net and buf_to_set and set to NULL. - Also reset error_use_protocol. - (server): Don't SIG_register server_cleanup. main_cleanup (which - is already registered) outputs a fatal error which causes it to - be called; registering it directly results in it being called twice. - (cvs_output): Don't try to use buf_to_net or protocol if they're NULL. - -2002-10-03 Larry Jones - - * lock.c (readers_exist): Ignore our own read lock, if any, to - allow upgrading an existing read lock to a write lock. - * tag.c (rtag_proc, rtag_fileproc, tag_fileproc): Rather than - locking the entire tree, have start_recursion establish read - locks and then upgrade the read lock to a write lock (so only - one directory is locked at a time). - -2002-09-27 Larry Jones - - * add.c (add): Send "--" before file names. - * admin.c (admin): Ditto. - * annotate.c (annotate): Ditto. - * commit.c (commit): Ditto. - * diff.c (diff): Ditto. - * edit.c (watch_onoff, editors): Ditto. - * log.c (cvslog): Ditto. - * remove.c (cvsremove): Ditto. - * status.c (cvsstatus): Ditto. - * tag.c (cvstag): Ditto. - * update.c (update): Ditto. - * watch.c (watch_addremove, watchers): Ditto. - - * sanity.sh (client-9): Update to match. - -2002-09-24 Derek Price - - * options.h: Remove prototype of STDC exit() function. If this breaks - a build, this should be detected in configure.in somehow rather than - restoring the line to this file. - -2002-09-24 Derek Price - - * options.h: Move definition of AUTH_CLIENT_SUPPORT into configure.in. - -2002-09-24 Derek Price - - * options.h: Move definition of FORCE_USE_EDITOR into configure.in. - -2002-09-24 Derek Price - - * options.h: Move definition of UMASK_DFLT into configure.in. - -2002-09-24 Derek Price - - * Makefile.in: Regenerated using Automake 1.6.3. - -2002-09-24 Larry Jones - - * filesubr.c, history.c, import.c, rcs.c, update.c: Use - HAVE_STRUCT_STAT_ST_BLKSIZE and HAVE_STRUCT_STAT_ST_RDEV instead of - the obsolete HAVE_ST_BLKSIZE and HAVE_ST_RDEV. - -2002-09-24 Derek Price - - * options.h: Move definition of TMPDIR_DFLT into configure.in. - -2002-09-24 Derek Price - - * options.h: Move defininition of EDITOR_DFLT into configure.in. - - * Makefile.in: Regenerated. - -2002-09-23 Jim Meyering - - If `cvs -d REPO commit ...' was used to override CVS/Root, - then modified files in the directory from which cvs is invoked - would not be committed. - * client.c (arg_should_not_be_sent_to_server): The above would happen - because this function would throw out a file name when CVS/Root - did not match the current server. Fix by allowing the command-line- - specified repository to take precedence over the value returned - by Name_Root. Patch by Simon Walton . - * sanity.sh (commit-d): New tests for the above. - Patch by Simon Walton . - -2002-09-20 Derek Price - - * options.h: Move definition of SERVER_FLOWCONTROL, SERVER_HI_WATER, - and SERVER_LO_WATER into configure.in. - -2002-09-20 Derek Price - - * options.h: Move definition of PATCH_PROGRAM to configure.in. - -2002-09-18 Larry Jones - - * client.c (call_in_directory): Don't create admin directory when - exporting into an existing directory. - (Reported by Jens Engel .) - * sanity.sh (basic2): New tests for above. - -2002-09-16 Jim Meyering - - * server.c (do_cvs_command): Move declarations of locals, timeout and - timeout_ptr, `up', out of enclosing `#ifdef SERVER_FLOWCONTROL' block. - Otherwise, this file would not compile with SERVER_FLOWCONTROL - turned off. Patch by Ed Santiago . - -2002-09-15 Larry Jones - - * myndbm.c (mydbm_open): Open the file read/write rather than read- - only if that's what the user asked for to ensure that the later open - for write will succeed. - (Patch submitted by Josh Lehan .) - -2002-08-28 Larry Jones - - * logmsg.c (do_editor): Fix bug which prevented reusing log messages. - (Reported by Eric Siegerman .) - -2002-08-16 Derek Price - - * create_adm.c (Create_Admin): Assume RELATIVE_REPOS is set. - * server.c (outside_root): Add comment. - * options.h: Remove RELATIVE_REPOS & CVS_BADROOT. - * sanity.sh: Remove a lot of !RELATIVE_REPOS cruft from tests. - -2002-08-14 Derek Price - - * server.c (server): Dispose of the correct pointer. Tidy comment. - -2002-08-13 Derek Price - - * client.c (get_cvs_port_number): Fix typo in comment. Add comments. - * server.c (server): Fix a FIXME. Remove an errant "const" directive. - Remove some redundant memory allocation and error handling code. - -2002-08-08 Derek Price - - * import.c (import): Surrounded `server_active' with - #ifdef SERVER_SUPPORT/#endif. - * commit.c (commit_fileproc, commit_direntproc): Likewise. - (Patch from John Tytgat .) - -2002-07-31 Derek Price - - * filesubr.c: Add a line so VIM can determine tab stops and shift widths. - * root.c: Ditto. - * (parse_cvsroot): Add comments and tidy slightly. - -2002-07-31 Derek Price - - * sanity.sh: Add another date to the comment about rcs2-7 failing. - -2002-07-26 Jim Meyering - - * commit.c (find_fileproc): When committing in client mode, - arrange to fail if a `cvs add'ed file no longer exists in the - working directory. - * sanity.sh (commit-add-missing): New test for above. - -2002-07-25 Larry Jones - - * sanity.sh: Set $TMPDIR if it's not already set and use it rather - than /tmp for the expected server temp directory path. - -2002-07-09 Larry Jones - - * vers_ts.c (time_stamp_server, time_stamp): Eliminate unneeded - struct_tm copying. - - * lock.c (lock_wait, lock_obtained): Display time in UTC if possible - to reduce confusion in client/server mode. - (Original patch from Eduardo Perez Ureta .) - -2002-06-26 Larry Jones - - * tag.c (check_fileproc): When checking up-to-date, T_REMOVE_ENTRY - is also a valid status. - (Reported by David Everly .) - * sanity.sh (tagc): New tests for above. - -2002-06-18 Larry Jones - - * update.c (patch_file): Don't patch if diff bigger than file. - Don't bother adjusting the permission on the diff output if - we're not going to use it. - - -2002-06-18 Derek Price - - * server.c: Handle HPUX password expiration fields in the passwd - string in case we are set up on a server with NIS passwords served - from HPUX. - (Original patch from John Cavanaugh .) - -2002-06-17 Larry Jones - and Jonathan Kamens - - * commit.c (commit_fileproc, commit_direntproc): Don't try to call - an editor to get the log message if running as a server. Instead, - just use an empty log message. - * import.c (import): Ditto. - - * import.c (import): In client mode, always send a message to the - server, even if it's empty (this parallels a change made by Larry - Jones to commit.c on May 7). - -2002-05-31 Larry Jones - - * rcs.c: Conditionally define MAP_FAILED for old systems that don't - have it in . - (Reported by jeremy brand .) - -2002-05-24 Larry Jones - - * rcscmds.c (diff_exec): Add a -- before the first file name just - in case it looks like an option. - (Reported by Zooko .) - - * rcscmds.c (diff_execv): Remove -- same as diff_exec. Change - only caller. - * cvs.h: Ditto. - -2002-05-23 Larry Jones - - * cvs.h (strcat_filename_onto_homedir): Make arguments const. - * filesubr.c (strcat_filename_onto_homedir): Make arguments const, - move more code here from callers, change all callers. - -2002-05-22 Derek Price - - * cvs.h: Add prototype for this... - * filesubr.c (strcat_filename_onto_homedir): new function. - * login.c (): Use new function. - - * cvsrc.c (read_cvsrc): Use new function due to problems on VMS. - * ignore.c (ign_setup): Ditto. - * wrapper.c (wrap_setup): Ditto. - (Original patch from Karsten Spang .) - -2002-05-21 Larry Jones - - * rcs.c (rcsbuf_getkey): Correct off-by-one error in ptr assertion - and add a similar assertion for ptrend. - (Reported by Rebecca Young .) - (rcsbuf_fill): Remove redundant code. - -2002-05-20 Derek Price - - * buffer.h: New prototype for... - * buffer.c (stdio_buffer_get_file): this new function to abstract - access to a buffer's file descriptor. - * client.c (auth_server): Use the new function. - (Original patch from Jonathan Kamens .) - -2002-05-20 Derek Price - - * main.c (main): Add 2002 to the copyright years output with the - version string. - -2002-05-15 Larry Jones - - * log.c (log_parse_list): Fix off-by-one error which caused - incorrect handling of 'cvs log -wuser1,user2 foo.c' command. - (Patch from Alexey Mahotkin , - reported by Alex Morozov .) - -2002-05-09 Larry Jones - - * login.c (password_entry_operation): Get cvsroot_canonical before - trying to read the user's password file so we have it even if the - file doesn't exist. - (Reported by Sarah Thompson .) - -2002-05-08 Derek Price - - * Makefile.am (cvs_SOURCES): Add options.h explicitly - since we - stopped generating it dynamically, Automake stopped noticing it and - including it in dists. See TODO item #214 for notes. - -2002-05-08 Derek Price - - * cvs.h: Use the HAVE_CONFIG_H define. - -2002-05-07 Larry Jones - - * filesubr.c (isaccessible): Set errno before returning failure - in the SETXID_SUPPORT code. - - * logmsg (do_verify): Avoid even more work if there's no verifymsg - script to run. - - * logmsg: Use fputs/putc rather than fprintf where appropriate. - (do_verify): Run the verifymsg script even if there's no log - message. (Reported by Andy Baker .) - Don't reread the log message unless a verifymsg script was run. - - * commit.c (commit): Always send -m to the server, even if there's - no message. - - * create_adm.c (Create_Admin): Add dotemplate parameter to trace. - Remove unreachable code. - -2002-05-03 Larry Jones - - * server.c (serve_watch_on, serve_watch_off, serve_watch_add, - serve_watch_remove): Just pass "watch" as the command name - to do_cvs_command to avoid unknown command errors. - (Reported by Gary Hennigan .) - - * rcs.c (RCS_checkin): Fix bad call to error () in buggy - PRESERVE_PERMISSIONS code. - (rcs_internal_unlockfile): Include current value of errno in error - message even though it may well be irrelevant (it's still better - than nothing). - -2002-05-02 Derek Price - - * .cvsignore: Remove lines for files obsoleted by new autotools. - -2002-05-02 Derek Price - - * stamp-h2.in: Remove this uneeded file. - -2002-05-01 Derek Price - - * options.h.in: Move to... - * options.h: here. - -2002-04-30 Derek Price - - * version.h.in: Remove this file. - * version.h: Ditto. - - * Makefile.am: Remove references to version.h. - * cvs.h: Use <> rather than "" around the config.h #include. I didn't - quite bother to understand why, but autoconf recommends it. - * cvsbug.in: Use PACKAGE_BUGREPORT defined by configure for the bug - report email address. - * version.c (version): Use PACKAGE_STRING defined in config.h instead - of the version_string that used to be defined in version.h. - - * Makefile.in: Regenerated with automake 1.6. - -2002-04-28 Derek Price - - * cvs.h: Use `"'s around includes when we mean a local file. - -2002-04-28 Derek Price - - * cvs.h: #define new names for functions and variables when they - might conflict with system definitions (namely on Mac OS X 10.1 with - the most recent dev packages - This should be removable after the Mac - dev packages are fixed.). - -2002-04-26 Larry Jones - - * logmsg.c (do_editor): Fix assertion when CLIENT_SUPPORT not defined. - (Reported by Matthias Andree .) - -2002-04-19 Larry Jones - - * log.c (log_expand_revlist): First cut at code to allow logging - between a revision and *any* ancestor, not just one explicitly on - the same branch (e.g., from 1.1 to 4.1.2.3.6.1). - - * subr.c (gca): Simplify and optimize. - -2002-04-19 Jim Meyering - and Ed Santiago - - * classify.c (Classify_File): Fix it so that `cvs update -p -r...' - works, even under some slightly unusual (though perfectly legitimate) - circumstances. - * sanity.sh (update-p): New tests for this. - -2002-04-18 Derek Price - - * sanity.sh: Move test for regex metacharacters in username until - after we're sure we found the version of expr that we're going to use. - -2002-04-18 Larry Jones - - * admin.c (admin_fileproc): Allow admin to be used on RCS files with - no local version (e.g., removed files) like most other subcommands. - - * wrapper.c (wrap_add): Update URL of -t/-f wrapper discussion. - -2002-04-18 Derek Price - - * version.h: Regenerated for 1.11.2.1 version update. - -2002-04-17 Derek Price - - * version.h: Regenerated for 1.11.2. - -2002-04-03 Derek Price - - * stamp-h2.in: Regenerate with recent version of Autoconf. - -2002-04-03 Derek Price - - * sanity.sh (TR): Send the stderr of one of the tool setup (tr) tests - to /dev/null to avoid spurious output on some operating systems - (notably Mac OS X). - -2002-03-22 Larry Jones - - * sanity.sh (rcslib): Correct new tests to use ${testcvs} instead - of cvs. - -2002-03-21 Derek Price - - * vers_ts.c (time_stamp): Return the timestamp for the newer of the - link and the link's source when the file is a link. - (Patch from RedHat cvs-1.11.1p1-7 SRPM.) - - * sanity.sh (rcslib): Test for same. - -2002-03-17 Larry Jones - - * log.c (cvslog, log_fileproc): Add -S option to suppress head or - file name if no revisions selected. - * sanity.sh (log): New tests for above. - -2002-03-13 Derek Price - - * main.c (usg): Correct a spelling mistake in a comment. - (Thanks to Matt Kraai .) - -2002-03-09 Larry Jones - - * import.c (import): Change the suggested merge message to use - rev tags instead of the branch tag with a date. - * sanity.sh (import, importb): Change to match. - - * remove.c (remove_fileproc): Disallow removing files with sticky - dates for the same reason we already disallow sticky numeric tags. - * sanity.sh (sticky): New test for above. - -2002-02-27 Larry Jones - - * diff.c (diff_fileproc): Treat dead revisions as nonexistent. - -2002-02-26 Larry Jones - - * diff.c (diff): Remove -V and --paginate options: they aren't valid. - (diff_usage): Document all the diff options. - -2002-02-13 Larry Jones - - * rcs.c (RCS_gettag): Do not interpret an empty tag as HEAD (nothing - else does and I don't see any documentation that says it should). - (translate_symtag): Break out of loop at end of symbols to prevent - looping forever when tag is "". - (Reported by Alain ENOUT - via Eric Gillespie .) - -2002-02-11 Larry Jones - - * server.c (server_cleanup): Set buf_to_net back to blocking mode - and flush it (in case there are any error messages pending) before - shutting down buf_from_net and again right before shutting it down. - -2002-02-08 Larry Jones - - * main.c (lookup_command_attribute): Throw a fatal error if the - command is not found. - * server.c (server_tag): Use the correct command name. - -2002-01-30 Larry Jones - - * error.h (error_exit): Remove unintended prototype. - - * server.c (serve_root): Remove check for impossible condition. - (serve_init): Save and restore current_parsed_root. - -2002-01-29 Larry Jones - - * error.h (error_exit): Declare __noreturn__ to avoid spurious - warnings. - - * server.c (serve_root): If the specified root doesn't match the - pserver root, return before changing current_parsed_root to prevent - subsequent commands from accessing an unchecked root directory. - (server_init): Check specified root against the pserver root and - complain if they don't match. Also, if there are pending errors, - print them and return before changing current_parsed_root to prevent - subsequent commands from accessing an unchecked root directory. - * sanity.sh (pserver): New tests for above. - -2002-01-10 Larry Jones - - * log.c (log_version_requested): Change :: in revision spec to be - exclusive just on the low end (so -r tag1::tag2 gives revisions - after tag1 but up to and including tag2), which is much more useful - than the previous (exclusive at both ends) behavior. - (log_usage): Update to match. - * sanity.sh (log): Update to match. - -2002-01-02 Larry Jones - - * server.c (LOG_DAEMON): Define if needed. - (Patch from John David Anglin .) - - * server.c (pserver_authenticate_connection): Add a specific error - message for EOF at protocol start and syslog if available. - * sanity.sh (pserver-bufinit): Update to match. - -2001-12-10 Larry Jones - - * log.c (log_usage): Note that -r and -d take lists, not just a - single specification. - (log_expand_revlist): Don't dereference null pointers when one end - of a revision range is a non-existent tag. - -2001-12-03 Larry Jones - - * annotate.c (annotate, annotate_fileproc): Don't annotate binary - files unless new -F option given. - * sanity.sh (basica, ann, ann-id, rcs, keywordlog, tagdate): Update - to match. - -2001-11-30 Larry Jones - - * admin.c (admin): Allow unrestricted usage of -q in addition to -k. - -2001-10-25 Larry Jones - - * log.c (log_expand_revlist): Make erroneous or inconsistent revision - specs select no revisions rather than all revisions. - -2001-10-23 Larry Jones - - * import.c (add_rcs_file): Don't put an expand entry into the file - for the default expansion mode (kv). - * wrapper.c (wrap_send, wrap_unparse_rcs_options): Process entries - with default expansion mode since they may be needed to avoid matching - a more general entry later. - (wrap_add): Set rcsOption to NULL for default (kv). - (wrap_add_entry): Use structure assignment to copy entries rather - that copying members by hand. - * sanity.sh (binwrap3): Revise to test wrapper entries that don't - specify any non-default options but just prevent matching later, - more general entries. - -2001-10-02 Larry Jones - - * rcs.c (RCS_fully_parse): Add revision number to more error messages. - -2001-09-27 Larry Jones - - * rcs.c (RCS_fully_parse, RCS_getdeltatext): Add the missing revision - number to the "mismatch" error message. - - * sanity.sh (multiroot2-9a): Update to match changes to lock.c. - -2001-09-26 Larry Jones - - * lock.c (Lock_Cleanup, Reader_Lock, write_lock): Add trace messages. - -2001-09-24 Derek Price - - * find_names.c (add_entries_proc): Leave closure specified as such in the - function definition for clarity. - - * find_names.c (Find_Names): Use 'closure' feature of walklist() - to eliminate the static variable. - (add_entries_proc): Expect closure to be the file list. - (Patch from Alexey Mahotkin .) - -2001-09-19 Derek Price - - * rcs.c (rcsbuf_valpolish_internal): Restore one of the - "if ( ... ) abort();" sequences since it seems to check the validity of - the RCS file rather than for a programming error. Also added a FIXME - comment to the effect that we should explain the RCS file error to the - user as such if it is such. - (Thanks to Larry Jones .) - -2001-09-19 Derek Price - - * rcs.c (rcsbuf_getkey, rcsbuf_valpolish_internal): Replace some code - of the form "if ( ... ) abort();" with equivalent calls to assert(). - -2001-09-17 Derek Price - - * myndbm.c (mydbm_load_file): Fix buffer overflow error and make error - messages more informative. - * sanity.sh (modules6): New test. - (Original report from Taska and others.) - -2001-09-14 Derek Price - - * logmsg.c (do_verify): Dispose memory when finished with it. - -2001-09-07 Larry Jones - - * mkmodules.c (notify_contents): In the example, move the %s to - the end since many, if not most, versions of mail insist on - options coming before addresses. - -2001-09-06 Derek Price - - * login.c (login): Deal with NULL return value from getpass. - -2001-09-04 Derek Price - - * Makefile.in: Regenerated with automake 1.5. - * stamp-h2.in: Ditto. - -2001-09-04 Derek Price - - * main.c (main): Fix empty CVSROOT message to specify `valid' instead - of `legal'. - -2001-09-04 Derek Price - - * server.c (pserver_authenticate_connection): Back out changes from the - 30th and... - * getline.c (getstr): init the buffer instead. - -2001-08-31 Derek Price - - * Makefile.in: Backed out accidental commit from yesterday. - -2001-08-30 Derek Price - - * server.c (pserver_authenticate_connection): Don't print from the - NULL pointer in the error message string in the case where the client - didn't send any data. - * sanity.sh (pserver): Test for this case. - (Report from Mark Welch ). - -2001-08-24 Derek Price - - * logmsg.c (do_editor): Add comment and assertion. - * import.c (import): Don't call do_editor with a repository argument - in client mode. - (Report and original patch from darkness .) - -2001-08-24 Larry Jones - - * log.c (log_expand_revlist): Arrange for nil revision specs to - select nothing instead of everything. - * sanity.sh (log): New tests for above. - -2001-08-24 Derek Price - - * parseinfo.c (Parse_Info): Change the function name in the trace - and add the client/server string. - -2001-08-24 Derek Price - - * Implement RereadLogAfterVerify CVSROOT/config option to control - FreeBSD read-write of log messages in the verification script. - * logmsg.c: RereadLogAfterVerify defaults to LOGMSG_REREAD_NEVER - to preserve the status quo. - * parseinfo.c (parse_config): Add parsing for RereadLogAfterVerify - option. Possible values are: no | never | yes | always | stat - * cvs.h: Add extern for RereadLogAfterVerify and new value macros - LOGMSG_REREAD_NEVER, LOGMSG_REREAD_ALWAYS, LOGMSG_REREAD_STAT for - its values. - (Patch from Mark D. Baushke .) - - * Apply changes from FreeBSD cvs sources to implement a read-write - user-defined verification script. - * logmsg.c (do_verify): Update do_verify to expect a pointer - to the saved message. The log file passed to the verifymsg_script - should be re-read after the user-defined verification script has - been run. The user-defined verification script is allowed to - modify the message. This allows the script to add extra - information to the log message or to remove template lines that - are not needed. - * cvs.h: Update prototype for do_verify prototype to expect a - pointer to the saved_message. - * commit.c (commit, commit_fileproc, commit_direntproc): Update - calls to do_verify as the saved_message arg is now read-write. - * import.c (import): Update calls to do_verify as the - saved_message arg is now read-write. - * sanity.sh (info-v4-[12]): Rename the old info-v4 test to info-v5 - and add a new info-v4 test case have the verification script - modify the log message to test the above changes. - (Patch from Mark D. Baushke .) - - * logmsg.c: Change RereadLogAfterVerify default to always. - (do_verify): Reformat and make minor fixes to Mark's patch. - * mkmodules.c (config_constants): Add comment about - RereadLogAfterVerify. - * sanity.sh (info-rereadlog): Rename the tests from Mark's patch and - reformat them a bit. - -2001-08-23 Derek Price - - * sanity.sh (info): Demonstrate that the verifymsg scripts can - sometimes, but not always, retreive information on which directory is - being committed to. - -2001-08-22 Derek Price - - * logmsg.c: Back out the last change - the repository which is passed - in is actually the directory and changes with each call to do_verify. - If a verifymsg script is using `pwd`, this could change the operation. - * cvs.h: Ditto. - * commit.c: Ditto. - * import.c: Ditto. - -2001-08-22 Derek Price - - * logmsg.c (do_editor): Return reused_message. - (do_verify): Don't verify the same log message more than once. - * cvs.h: Update prototypes for do_verify and do_editor. - * commit.c (commit_fileproc, commit_direntproc): Use the new functionality. - * import.c (import): Ditto. - -2001-08-22 Derek Price - - * logmsg.c (do_verify): Remove an unecessary "else" clause following an - exit and unindent the former contents. - -2001-08-22 Derek Price - - * commit.c (commit): Don't call do_verify in client mode since we know - do_verify will just return anyhow. - -2001-08-20 Derek Price - - * Makefile.am (cvs_SOURCES): Add version.c and version.h. - (BUILT_SOURCES): Add version.h. - (Maintainer Targets): Remove version.h. - * version.c: Remove @VERSION@ dependant bits. - * version.c.in: Removed. - * version.h.in: New file. - (Original patch from Alexey Mahotkin .) - - * Makefile.am: Various modifications to make Automake, make dist, and - windows targets work like they are supposed to. - * version.h: New (generated) file. - - * Makefile.in: Regenerated. - -2001-08-09 Derek Price - - * client.c (socket_buffer_shutdown): Use recv instead of read and - return 0 on success. - (Patch from "Manfred Klug" .) - -2001-08-09 Derek Price - - * buffer.c (stdio_buffer_shutdown): Assume the buffer is not a socket - when NO_SOCKET_TO_FD is defined. - * client.c (make_bufs_from_fds): Add is_sock argument and remove fstat - call and reference to S_ISSOCK since these functions aren't available - under Windows. - (connect_to_forked_server, connect_to_pserver, start_tcp_server, - start_server, start_rsh_server): Use new argument. - (Patch from "Manfred Klug" .) - - * buffer.c (stdio_buffer_shutdown): Various reformattings, fix bug - where rsh pipes weren't being closed. - -2001-08-09 Derek Price - - * sanity.sh (rmadd, rm-update-message, join-two-branch, - ignore-on-branch): Change a few references to `cvs' to `$PROG'. - -2001-08-07 Derek Price - - * build_src.com: Add annotate.c/annotate.obj,verify, correct zlib name. - * patch.c: VMS time_t appears to be unsigned. Add a cast when testing - for (time_t)-1. - * subr.c: #else,#endif for no symlinks should be moved. - (Patch from Mike Marciniszyn .) - -2001-08-06 Derek Price - - * Makefile.in: Regenerated. - -2001-08-01 Derek Price - - * diff.c (diff): Send long option for side-by-side diffs to the server - rather than '-y', for backwards compatibility with old servers. - (Original patch from Peter Mathiasson .) - -2001-07-19 Larry Jones - - * mkmodules.c (cvswrappers_contents): Remove -t/-f since they're - disabled in wrapper.c. - - * checkout.c (checkout): Don't complain about checking out into the - repository when piping output. - (Reported by der Mouse .) - * sanity.sh (checkout_repository): New tests for above. - -2001-07-10 Larry Jones - - * sanity.sh (importc-7): Now works correctly in local mode. - - * commit.c (commit_dirleaveproc): We're still in the directory when - this is called, so the first argument to Name_Repository needs to - be NULL, not dir. - * sanity.sh (rmadd): New tests for above. - - * commit.c (commit): Reword error messages for committing as root. - -2001-07-08 Larry Jones - - * rcs.c (RCS_checkout): Correct scanf format to allow for trailing - NUL terminator. - * update.c (special_file_mismatch): Ditto. - (Reported by Pekka Savola .) - -2001-07-05 Larry Jones - - * client.c, root.c: Fix -Wall warnings. - - * buffer.c: #include socket header to declare shutdown(). - - * rcs.c (rcsbuf_open): Use getpagesize() instead of sysconf() for - portability. - (RCS_copydeltas, rcsbuf_fill): Fix -Wall warnings. - -2001-07-04 Derek Price - - * Makefile.in: Regenerated with new Automake release candidate 1.4h. - -2001-07-03 Derek Price - - * rcs.c (rcsbuf_open): Reduce memory consumption still further by not - mmapping the entire file when pos is specified. - (rcsbuf_cache_open): Add FIXME comment wrt read-only mmaps and rcsbuf - caching. - -2001-07-03 Derek Price - - * rcs.c (rcsbuf_open): Use mmap when possible to reduce memory - consumption, especially with large (e.g. binary) files. - (rcsbuf_close): Call munmap. - (rcsbuf_getkey): Remove the buffer fill code when using mmap. - (rcsbuf_getrevnum): Ditto. - (rcsbuf_fill): Remove this function when using mmap. - (rcsbuf_cache_open): Mostly don't use this function with mmap. - (RCS_copydeltas): Don't depend on the file pointer with mmap. - - * stamp-h2.in: Regenerated. - -2001-07-03 Derek Price - - * update.c: Indent compiler directives. - -2001-07-02 Larry Jones - - * import.c (update_rcs_file): Use -kb instead of -ko when comparing - binary files. - (Reported by Gyula Faller .) - -2001-06-28 Larry Jones - - * checkout.c (checkout): Explicitly initialize all the static options - so that multiple calls work right. Also fix potential memory leaks. - (Reported by Dr. Dieter Maurer .) - -2001-06-28 Derek Price - - * Makefile.in: Regenerated with new version of Automake. - -2001-06-28 Larry Jones - - * checkout.c (checkout): Set history_name for export as well as - checkout. - (checkout_proc): Use it. - - * checkout.c (safe_location): Add missing argument in error message. - -2001-06-26 Larry Jones - - * recurse.c (start_recursion): Use strip_trailing_slashes instead - of doing it by hand. - - * server.c (pserver_authenticate_connection): Don't clear out - descrambled_password until *after* it's (potentially) logged. - (Reported by Eric Hanchrow .) - -2001-06-25 Larry Jones - - * recurse.c (start_recursion): Deal with at least some of the cases - where trailing slashes cause confusion. - (Reported by Malcolm Fernandes .) - * sanity.sh (basica, basicb): Tweak existing tests to check this. - -2001-06-22 Larry Jones - - * sanity.sh (modules5): New tests with -d on command line. - -2001-06-21 Larry Jones - - * modules.c (do_module): Use run_module_prog and server_active to - determine when to call server_prog instead of using server_expanding - so that we get the right paths in the replies as long as we take - mwhere into account in addition to where. - (Reported by Pascal Bourguignon .) - * server.c (server_prog): Use protocol pipe instead of buf_to_net. - * sanity.sh (modules5): Remove FIXCVS comment and update to match. - * server.c, server.h: Remove server_expanding since now unused. - -2001-06-21 Larry Jones - for Stephen Rasku - - * admin.c: Corrected spelling mistakes in help. - -2001-06-20 Derek Price - - * client.c (socket_buffer_shutdown): Fix untested typos. - (Reported by "Jerzy Kaczorowski" .) - - * buffer.c (stdio_buffer_shutdown): Put the call to SHUTDOWN_SERVER in - the correct place. - -2001-06-20 Derek Price - - * logmsg.c (do_editor): Abort in the case that the file has only - comment lines. - (Original patch from Mark Valentine .) - - * logmsg.c (do_editor): Fix rare memory leak. - * sanity.sh (editor): Add tests for aborted log messages. - -2001-06-20 Larry Jones - - * server.c (switch_to_user): Only set $CVS_USER if - AUTH_SERVER_SUPPORT is defined. - (Reported by Nalin Dahyabhai .) - -2001-06-13 Derek Price - - * client.c: Fix incorrect fixed-size buffer usage in - connect_to_gserver(). - (Minor changes to a patch from Alexey Mahotkin .) - -2001-06-11 Derek Price - - * main.c (main): Always print $CVSROOT when parse_cvsroot fails. - * root.c (parse_cvsroot): Tidy error messages and provide more - consistent behavior. - * sanity.sh (crerepos): Adapt to new error messages. - (Suggested by Alexey Mahotkin .) - -2001-06-08 Derek Price - - * sanity.sh (tagf-28): Use $CVSROOT_DIRNAME. - -2001-06-07 Larry Jones - - * rcs.c (RCS_unlock): Reverse kj's change of 1999-10-18: a bare -u - should never break locks, you have to specify a specific revision - to do that. Also add an informative message for a bare -u when - the user doesn't hold any locks. - * commit.c (unlockrcs): Make RCS_unlock quiet, like RCS_lock. - * sanity.sh (rmadd-24): Update to match. - - * sanity.sh (crerepos-6a): Set CVS_RSH for ${testcvs}, not for - dotest_fail. Allow for "broken pipe" rather than "end of file". - -2001-06-07 Derek Price - - * sanity.sh (tagf): Use $CVSROOT_DIRNAME rather than - /tmp/cvs-sanity/cvsroot. - -2001-06-06 Derek Price - - (Reformatting, bug fixes, tests, and comments to a - patch from Stephen Cameron .) - - * tag.c: (rtag_fileproc, rtag_delete, tag_fileproc) - Changed behavior of "cvs tag -F", "cvs tag -d", "cvs rtag -F" - and "cvs rtag -d" so that they will not disturb existing - branch tags unless a new "-B" option is given. - * sanity.sh (tagf-16 - tagf-33): Added tests for new -B option - to "cvs tag" and "cvs rtag" - -2001-06-06 Derek Price - - * sanity.sh (crerepos-6a): Set CVS_RSH=false and only for the actual - test call at Larry's suggestion. Also, test the error message since - it's fixed now. - -2001-06-05 Larry Jones - - * rcs.c (RCS_unlock): Note when breaking someone else's lock. - (Reported by MURVAI-BUZOGANY Laszlo - .) - * sanity.sh (reserved-14): Update to match. - -2001-06-05 Derek Price - - * sanity.sh (crerepos-6a): Set CVS_RSH=/bin/false... this is a local - mode only test anyhow. - (Thanks to Larry Jones and Morgan Burke .) - -2001-05-31 Derek Price - - * sanity.sh (rcs2-7): Add today to the list of failure dates for rcs2-7 - in the hopes that the data will eventually prove useful to someone - motivated enough to fix the problem. - -2001-05-30 Derek Price - - * stamp-h2.in: Regenerated. - -2001-05-30 Derek Price - - * *: Various bug fixes and comments for the following - patch from Donald Sharp : - - * checkout.c (safe_location): cvs co -d still had - failure modes from the way the -d option works. - * sanity.sh: Misc error message resynching. - -2001-05-29 Derek Price - - * Makefile.am (cvs_SOURCES): Add root.h. - - * Makefile.in: Regenerated. - * stamp-h2.in: Regenerated. - -2001-05-29 Derek Price - - * checkout.c (safe_location): Correct formatting. - -2001-05-29 Derek Price - - * root.c (parse_cvsroot): Fix a comment. - -2001-05-26 Larry Jones - - * checkout.c (safe_location): Use old-style definition to keep - non-ANSI compilers happy. - - * sanity.sh (check_respository): Use ${CVSROOT_DIRNAME} instead - of /tmp/cvs-sanity/cvsroot. - -2001-05-25 Larry Jones - - * sanity.sh (modules5): Add sleep to script to help avoid out of - order messages. - - * filesubr.c (mkdir_if_needed): Return 1 if the directory exists - reguardless of what errno is set to. - (Reported by "Robinson, Greg" .) - -2001-05-25 Derek Price - for Donald Sharp - - * checkout.c: Modified safe_location() to refuse checkout if - the -d option to co specifies inside of the repository. - * import.c: New parameter to safe_location needed to be added. - * cvs.h: New parameter to safe_location needed to be added. - * sanity.sh: Test case to test for failure mode. - -2001-05-23 Larry Jones - - * checkout.c (checkout_proc): Don't build top_level_admin directory - when exporting. - (Reported by Tony Byrne .) - -2001-05-21 Derek Price - - * client.c: Fix a mispelling in a comment. - (Patch from Alexey Mahotkin ). - -2001-05-05 Larry Jones - - * login.c (password_entry_operation): Only warn if unable to open - .cvspass for reading: may be initial login and it doesn't exist yet. - -2001-05-15 Derek Price - - * client.c (start_tcp_server): Use the struct sockaddr_in declared in - the function. - (Reported by Emil Isberg .) - -2001-05-05 Larry Jones - - * annotate.c (annotate): Pass local to do_module and rannotate_proc - so that -l actually works. - * log.c (cvslog): Ditto. - * patch.c (patch): Ditto; make local local instead of global. - (patch_proc): Use local_specified parameter instead of global. - * tag.c (cvstag, rtag_proc): Ditto. - -2001-05-05 Larry Jones - - * client.h: Declare "struct buffer" outside prototype for __STDC__ - compilers. - -2001-05-04 Derek Price - - * client.c: General refactoring. Removed several global variables in - favor of passing locals and/or dynamic evaluation. - (recv_line): Removed this function. - (make_bufs_from_fds): New function with factored code. - (connect_to_forked_server): New prototype. Use new functions. - (connect_to_pserver): New prototype. Use new functions. - (connect_to_gserver): New prototype. Use new API. - (auth_server): Factored this portion of the pserver code so it can be - shared. Rewrote to use buffers rather than depending on a socket. - (start_rsh_server): New prototype. Use new API. - (start_tcp_server): New prototype. Use new API. - (start_server): Factor some code. Use new API. - * client.h: New prototypes. - * cvs.h: Gratuitous reformatting. Use new root.h. - * login.c (login): Use new connect_to_pserver API. - * root.h: New file. Contains some code that used to be in cvs.h. - -2001-05-04 Derek Price - - * client.c: Gratuitous reformatting. - * client.h: Ditto. - -2001-05-04 Derek Price - - * zlib.c (compress_buffer_shutdown_input): Use new buffer shutdown - prototype. - (compress_buffer_shutdown_output): Ditto. - (Thanks to Pavel Roskin .) - -2001-05-03 Derek Price - - * buffer.c (struct stdio_buffer_closure): New structure to hold a - FILE * and the child's PID when necessary. - (stdio_buffer_initialize): Change proto to accept PID. Set up new - closure. Pass new stdio_buffer_shutdown to buf_initialize. - (stdio_buffer_input): Use new closure. - (stdio_buffer_output): Ditto. - (stdio_buffer_flush): Ditto. - (stdio_buffer_shutdown): New function. Teach buffer to close itself. - (packetizing_buffer_shutdown): Use new buffer shutdown proto. - * buffer.h (struct buffer): New buffer shutdown proto. - (stdio_buffer_initialize): New proto. - * client.c (log_buffer_shutdown): Use new proto. - (socket_buffer_initialize): Pass shutdown func. - (socket_buffer_shutdown): New function. - * server.c (get_responses_and_close): Remove most of the guts. Rely - on the buffer shutdown function from now on. - (start_rsh_server): Return child PID. - -2001-05-03 Larry Jones - - * history.c (history_write): Handle the case where the user's home - directory doesn't exist gracefully instead of erroring out. - (Reported by David Hoover .) - -2001-05-03 Derek Price - - * cvs.h: s/allocate_and_strcat/xrealloc_and_strcat/ since that is what - I wrote in the ChangeLog, oh, so long ago. - * diff.c (diff): Ditto. - * subr.c (allocate_and_strcat, xrealloc_and_strcat): Ditto. - -2001-05-02 Larry Jones - - * rcs.c (RCS_getdate): Handle the (unusual!) case where we - can't find any revisions at all. - (Reported by Ryan Grow .) - -2001-04-30 Larry Jones - - * sanity.sh (multiroot2-9a): Rename (from multiroot2-9) to avoid - duplicate names; fix to work without SERVER_SUPPORT defined. - (Reported by Pavel Roskin .) - -2001-04-29 Derek Price - - * Makefile.am (check-local): Make dependent on localcheck and - remotecheck and move old check target... - (localcheck): here. - - * Makefile.in: Regenerated. - -2001-04-27 Larry Jones - - * sanity.sh (pserver): Add tests for readers and writers. - -2001-04-27 Derek Price - - * sanity.sh (version-2r): Update to handle patch releases in version - numbers. - -2001-04-27 Derek Price - - * version.c: Regenerated. - -2001-04-27 Derek Price - - * version.c: Regenerated. - -2001-04-27 Larry Jones - - * main.c (lookup_command_attribute): Lookup specified command, not - whatever's in the global command_name. - -2001-04-25 Derek Price - - * Makefile.in: Regenerated using AM 1.4e as of today at 18:10 -0400. - * version.c: Regenerated. - -2001-04-22 Larry Jones - - * tag.c (tag_check_valid): Make an unwritable val-tags file a - warning instead of a fatal error. - -2001-04-20 Larry Jones - - * annotate.c (annotate_usage): -r and -D are not mutually exclusive. - * main.c (cmd_usage): Add missing version subcommand. - * update.c (update_usage): Add missing -C option. - - * sanity.sh (death2): New tests for previous change. - - * classify.c (Classify_File): Treat a dead revision like the RCS - file doesn't exist. - * sanity.sh: Update to match. - -2001-04-16 Larry Jones - - * checkout.c, update.c: Fix usage messages: -r and -D are not - mutually exclusive. - (Suggested by David L. Martin .) - - * logmsg.c (do_editor): Don't add a blank line to the message. - * sanity.sh (editor-log-file*): Update to match. - - * checkout.c, update.c: Note in usage message that -k is sticky. - - * server.c: (server_cleanup, wait_sig): Remove ancient SunOS kludge. - (Suggested by Rob Saccoccio .) - -2001-04-04 Larry Jones - - * sanity.sh (dotest, dotest_lit, dotest_fail, dotest_status, - dotest_sort): Don't count on $? being set in then or else clauses. - - * ignore.c (ignore_files): Collect unignored files into a list and - sort it before calling PROC to avoid order dependencies. Rewrite - the while loop to allow normal continues instead of goto. - -2001-04-04 Derek Price - - * sanity.sh (ignore-on-branch-3): Fix in the remote case. - -2001-04-03 Larry Jones - - * update.c (update_fileproc): Remove unused variable (resurrecting). - -2001-04-03 Derek Price - Larry Jones - reported by Jakob Bøhm - - * update.c (update_fileproc): Don't store a file with T_UNKNOWN status - in ignlist if present in the sandbox. - * sanity.sh (ignore-on-branch): New test. - (ignore): Tidy this test. - -2001-04-02 Derek Price - - * sanity.sh: Make sure the test for `id' fails when a nonstandard `id' - is used and the user is root. Fix some quoting in error messages. - (fork): Take `cvs' out of the PATH. - (TODO): Add note about the test suite not working with user names over - eight characters in length. - -2001-04-02 Derek Price - - * sanity.sh (fork): New test for CVS_SERVER default. - (TODO): Note about eventually removing most of the references to - CVS_SERVER. - -2001-04-02 Larry Jones - - * client.c (connect_to_forked_server): Use program_path as the default - server instead of "cvs". - -2001-04-02 Derek Price - - * sanity.sh: Use less obfuscated English in my comment about sanity - checking sanity.sh. - -2001-04-02 Derek Price - - * sanity.sh (rm-update-message): Create a test directory again but - change back to the correct directory upon completion this time. - -2001-04-02 Derek Price - - * sanity.sh: Change last two '[.*]'s to 'test's for - consistency and remove... - (TODO): the note from the TODO list. - -2001-04-02 Derek Price - - * sanity.sh: Add test for PWD before successful exit. - -2001-03-30 Larry Jones - - * sanity.sh (rm-update-message): Remove duplicate code. - -2001-03-30 Derek Price - - * sanity.sh (rm-update-message): New test for local/client-server - warning message discrepency. - -2001-03-30 Larry Jones - - * annotate.c: Move annotate() here from rcs.c, support rannotate. - * Makefile.am, Makefile.in: Add annotate.c. - * main.c (cmds[], cmd_usage[]): Add rannotate. - * rcs.c: Move declarations of rcs_delta_op and RCS_deltas to... - * rcs.h: ... here. - * server.c (serve_rannotate): New. - (requests[]): Add rannotate. - * sanity.sh (ann): New tests for rannotate. - - * log.c (rlog_proc): Remove dead code. - -2001-03-30 Derek Price - - * sanity.sh (join-readonly-conflict): Run more of this through dotest. - -2001-03-30 Larry Jones - - * log.c (log_fileproc): Don't output working file for rlog. - * sanity.sh (log): New tests for rlog. - - * cvs.h (mtype): Add MISC type. - * log.c (cvslog): Support rlog as well as log. - (rlog_proc): New. - * main.c (cmds[], cmd_usage[]): Add rlog. - (main): Remove old rlog warning message. - * server.c (serve_rlog): New. - (requests[]): Add rlog. - -2001-03-29 Derek Price - - * sanity.sh: cd to $TESTDIR once after it is normalized. Make TODO - on history and symlinks more specific. Tested properly this time. - -2001-03-29 Larry Jones - - * main.c (cmds[], lookup_command_attribute, main): Include the - command attributes in the global command table instead of inferring - them from the command names. Change the sense of the - CVS_CMD_IGNORE_ADMROOT attribute to match its name. - -2001-03-29 Derek Price - - * sanity.sh (*, basic2-64): Remove references to TMPPWD. Fix FIXME - at end of script now that $TESTDIR can't be relative. - -2001-03-29 Derek Price - - * sanity.sh: Normalize TESTDIR even when the user set it. - -2001-03-29 Larry Jones - - * client.c (connect_to_pserver, start_tcp_server): Add IP address - to connect failed message. - (connect_to_forked_server, connect_to_pserver, start_tcp_server): Add - trace messages ala start_rsh_server. - (start_rsh_server): Include entire command in trace message for - START_RSH_WITH_POPEN_RW like ! START_RSH_WITH_POPEN_RW does. - -2001-03-29 Derek Price - - * sanity.sh: Global search & replace ${TESTDIR}/cvsroot with - ${CVSROOT_DIRNAME} for consistency. - -2001-03-29 Derek Price - - * sanity.sh (conflicts-12[68].5): Remove sanity hack which has allowed - for a CVS bug since May 96/97. Not sure when the bug went bye-bye, but - the tests broke when $TESTDIR != $TMPPWD. - -2001-03-26 Larry Jones - - * classify.c (Classify_File): Don't report a conflict for a removed - file when piping. Also simplify the code structure. - (Reported by Milos Kleint .) - * sanity.sh (rmadd2-14[abc]): New tests for above. - -2001-03-24 Noel Cragg - - * diff.c: mods to allow `-T' and `-y' options to be passed through - to the diff library. This wasn't allowed earlier because of a - similarly named options that got passed through to the old rcs - programs. We've long since stopped sending `-T' to any rcs - utility and have never used `-y'. Any users of moldly CVS - versions which used to support `-T' have (hopefully) upgraded to - one where that option isn't supported. It seems reasonable to - enable them again and pass them through. (sanity.sh still works - anyways...) - (longopts): add short option equivalents for --initial-tab and - --side-by-side. - (diff): add new short options to getopt string and switch - statement. - -2001-03-22 Larry Jones - - * sanity.sh: Add check for ${DOTSTAR} with large matches. - -2001-03-23 Derek Price - - * sanity.sh: Do the same as below for $keep. - -2001-03-23 Derek Price - - * sanity.sh: Replace 'remote=(yes|no)' with 'remote=(:|false)' since - often 'false' and more often ':' are shell builtins. This makes the - succinct, 'if $remote; then' faster than 'if test $remote = yes; then'. - Alter tests in the rest of the script to match the new usage. Added - a suffix of 'r' to remote test names when it was appropriate and I - remembered. Some reformatting. - -2001-03-22 Larry Jones - - * sanity.sh (diffmerge1_yours, diffmerge1_mine): Check for exact - output instead of using wildcards to avoid buffer overflows in some - versions of expr. - -2001-03-21 Derek Price - - * sanity.sh: cd to '/tmp' again rather than $HOME since HOME was set to - a value inside ${TESTDIR} by the script. - -2001-03-20 Derek Price - - * sanity.sh (diffmerge1): Minor formatting and syntax changes. - - for Jacob Burckhardt - - * sanity.sh (diffmerge1): More merging behavior tests. Specifically, - test some cases which broke before in Karl Tomlinson's diff fix was - checked in today. - -2001-03-20 Derek Price - - * sanity.sh: Don't use unescaped parens in sh outside of quotes. - -2001-03-20 Derek Price - - * sanity.sh: Don't remove ${TESTDIR} when -k (keep) set. - -2001-03-20 Derek Price - - * sanity.sh: Change usage to match the new getopts format and comment. - -2001-03-16 Derek Price - - * sanity.sh (modules2-nestedrename): New test. Verifies behavior of - renames nested under an ampersand module. - (modules2-ampertag): New test. Verifies an error condition which - prevents some ampersand modules from being checked out when a tag - is specified. - -2001-03-16 Derek Price - - * sanity.sh (modules2): Additional test for ampersand module behavior - with '-d'. - - for Greg Klanderman - - * checkout.c (build_one_dir): Fix typo where clauses of two - conditionals were reversed in call to Create_Admin. This caused - the CVS/Tag file to be removed in cases where it should have been - set, and vice-versa. It only surfaced in rare cases as this code - is only invoked when using the -d option to build the path to - check out in. Further, the bug would only matter when checking - out a module containing ampersand modules within it, via - client/server CVS. - -2001-03-16 Derek Price - - * sanity.sh (admin-28-5): Confirm that a missing tag during an - 'admin -n' operation is not a fatal error. - -2001-03-16 Derek Price - - * admin.c (admin_data): Remove 'quiet' member. - (admin_fileproc): Use global 'really_quiet' rather than - admin_data->quiet. - -2001-03-16 Derek Price - - * sanity.sh (admin): Replace hardcoded testdir path with the variable. - -2001-03-15 Derek Price - - * sanity.sh (basica, binfiles, head, admin): Adjust for new messages. - * admin.c (admin_fileproc): Only print messages when not in - really_quiet mode. - - for Stephen Rasku - - * rcs.c (RCS_tag2rev): Make a missing tag a survivable error. - -2001-03-15 Larry Jones - - * subr.c (sleep_past): Fix various bugs that would result in a - negative sleep time if it weren't unsigned; since it is, it would - result in a very large sleep time. Ensure that us is always less - than 1000000. Don't try to sleep for more 1 sec with usleep. - Cast NULL select arguments to correct type just in case. - -2001-03-14 Derek Price - - * subr.c (sleep_past): New function. - * client.c (get_responses_and_close): Use new function. - * commit.c (commit): Ditto. - * update.c (do_update): Ditto. - * cvs.h: Prototype new function. - - * stamp-h2.in: Regenerated. - -2001-03-14 Derek Price - - * Makefile.in: Regenerated. - * stamp-h2.in: Ditto. - -2001-03-14 Larry Jones - - * commit.c (check_fileproc): Allow adding on the trunk when there's - an existing non-Attic RCS file as long as the head revision is dead. - This can happen due to an aborted resurrection. - (commit_fileproc): When resurrecting, consider the dead revision - along with the other files' revisions. - (findmaxrev): Avoid unnecessary work. - (checkaddfile): Only warn if file isn't in Attic as expected. - (Reported by Ross Burton .) - * sanity.sh (basica-r*): New tests for above. - (basica-o4): Update to match. - -2001-03-09 Larry Jones - - * edit.c (edit_fileproc, unedit_fileproc): Some implementations of - asctime/ctime apparently use a leading zero on the date instead - of the space required by the C Standard. Correct for this so that - shared working directories work without hassle. - (Reported by David L. Martin .) - * entries.c (fgetentent): Ditto. - * vers_ts.c (time_stamp_server, time_stamp) Ditto. - -2001-03-07 Larry Jones - - * sanity.sh (basica, binfiles2, head, admin): Update to match - change to admin.c. - -2001-03-06 Larry Jones - - * client.c (recv_bytes): Handle EOF as in recv_line(). - (Reported by Pavel Roskin .) - - * admin.c (admin_fileproc): Change final error message to clarify - that CVS refused to modify the RCS file rather than being unable to. - -2001-02-28 Jim Meyering - - * commit.c (commit_usage): Use `-F logfile' (rather than -F file') in - the description of that option, to be consistent with the `-F logfile' - in the Usage: line. Use spaces instead of TAB characters, and realign. - -2001-03-02 Derek Price - - * sanity.sh (crerepos): Make failed ${CVS_RSH-rsh} attempt print the - name of the command it actually used rather than 'rsh'. - -2001-02-27 Derek Price - - * sanity.sh (modules2-ampermod-*): Added these tests to make sure the - top level directory is created in an ampermodule when '-n' is passed to - checkout. - - original bug report from - Wolfgang Haefelinger - -2001-02-27 Derek Price - - * sanity.sh (version-[12]): replace ' (client/server)' with .* in these - two tests so that 'make check' works with whatever client/server - options the executable was compiled with. - -2001-02-23 Derek Price - - * main.c (main): Only check a cvsroot_t's isremote member when client - support is enabled. - * server.c: Include GSSAPI headers with client support as well as - server support. - -2001-02-21 Larry Jones - - * modules.c, cvs.h (do_module): Add build_dirs argument and use it - instead of run_module_prog. Change all callers. - * tag.c (cvstag): For rtag, don't build directories. - * sanity.sh (modules3): Update to match. - -2001-02-20 Derek Price - - * client.c: Use xgssapi.h. - * server.c: Ditto. - -2001-02-15 Derek Price - - * Makefile.am (cvs_SOURCES): Correct error from yesterday. - * Makefile.in: Regenerated. - -2001-02-14 Derek Price - - * server.c: Include xselect.h. - * update.c (do_update): Use best available sleep function. - -2001-02-14 Derek Price - - * Makefile.am (cvs_SOURCES): Alphabetize and split to one/line. - (cvs_LDADD): Alphabetize and split to one/line. - * Makefile.in: Regenerated. - -2001-02-14 Larry Jones - - * build_src.com: Remove references to rtag.c & rtag.obj. - -2001-02-13 Derek Price - - * main.c (date_to_tm): New function to convert an RCS date string to a - struct tm. - (tm_to_internet): New function to convert a struct tm to a date string - as specified by RFC822 and amended by RFC 1123. - (date_to_internet): Use the above two functions and a struct tm - intermediary for conversion. - * patch.c (patch_fileproc): Answer somebody's comment and use the new - diff_exec API. - * rcs.c (RCS_checkin): Use new diff_exec API. - (RCS_delete_revs): Use new diff_exec API. - (make_file_label): If the file name is DEVNULL, date it the Epoch for - compatibility with the POSIX.2 spec and Larry Wall's patch - implementation. - * rcscmds.c (diff_exec): Accept new label arguments. - * sanity.sh (death2): Update some diff tests to accept the new format. - * update.c (patch_file): Use new diff_exec API. - * diff.c (diff_fileproc): Create header labels appropriate for - compatibility with the Larry Wall version of patch. - (diff): Rename calls to strcat_and_allocate. - (strcat_and_allocate): Rename and move... - * subr.c (xrealloc_and_strcat): here. - * cvs.h: Update prototypes to match. - -2001-02-13 Derek Price - - * Makefile.am (cvs_SOURCES): Remove rtag.c. - -2001-02-07 Larry Jones - - * sanity.sh (directory_cmp): Return status rather than setting ISDIFF. - (basic2): Rewrite using dotest. - -2001-02-06 Larry Jones - - * tag.c, rtag.c: Merge with tag.c being the surviving file. - * Makefile.in: Update to match. - * main.c (cmds): rtag() => cvstag(). - * server.c (serve_rtag): Ditto, and set command name. - -2001-02-06 Derek Price - Rex Jolliff - Shawn Smith - - * add.c: Replace opendir, closedir, & readdir calls with CVS_OPENDIR, - CVS_CLOSEDIR, & CVS_READDIR in support of changes to handle VMS DEC C - 5.7 {open,read,close}dir problems. Check today's entry in the vms - subdir for more. - * filesubr.c: ditto - * find_names.c: ditto - * ignore.c: ditto - * import.c: ditto - * lock.c: ditto - * update.c: ditto - -2001-02-02 Larry Jones - - * error.h: Changed include guard macro from _error_h_ to ERROR_H; - names beginning with underscore are reserved. - * login.c (password_entry_parseline, password_entry_operation, - password_entry_operation_e, password_entry_operation_t): Removed - leading underscore(s). - (password_entry_parseline): Corrected error messages. - (password_entry_operation): Fixed uninitialized variable (password). - (login): Removed unused variable (found_password). - - * rtag.c (rtag_proc): Call lock_tree_for_write() before calling - start_recursion. This fixes a serious problem where do_recursion - was reading and caching RCS files without any locks in place and - that information was subsequently being used to rewrite the file - causing any intermediate changes to be lost. - (rtag_filesdoneproc): Defunct. - (Reported by Karl Tomlinson .) - * tag.c (cvstag, tag_filesdoneproc): Ditto. - * lock.c (lock_tree_for_write): Add which argument, change all - callers to pass W_LOCAL. - * rcs.h: Ditto. - -2001-01-29 Derek Price - - * client.c (get_cvs_port_number): change the prototype to accept a - const cvsroot_t * as input and add a FIXME comment - * cvs.h: new prototypes for get_cvs_port_number & normalize_cvsroot - * login.c (_password_entry_operation): consolidate all the ~/.cvspass - access into a single new function which reads ~/.cvspass in a backwards - compatible manner - (logout): use the new _password_entry_operation function - (login): ditto - (get_cvs_password): ditto - * root.c (normalize_cvsroot): move knowledge of default port & username - values inside - -2001-01-29 Larry Jones - - * subr.c (shell_escape): New function. - * cvs.h: Declare it. - * logmsg.c (logfile_write): Use it to avoid problems with filenames - containing "'". - (Reported by Gerhard Ahuis .) - - * server.c (outbuf_memory_error, pserver_authenticate_connection, - kserver_authenticate_connection): If available, use syslog() to - record some errors. - -2001-01-25 Larry Jones - - * server.c (do_cvs_command): If there's a partial output line left - over and the client doesn't support MT, go ahead and send it in an - M response instead of just dropping it. - (Reported by Milos Kleint .) - - * update.c (update_fileproc): Handle toss_local_changes in the - T_NEEDS_MERGE case. - (Inspired by Noel L Yap .) - * sanity.sh (clean): New tests for above. - -2001-01-23 Derek Price - - * run.c (run_exec): flush, if used, stderr and stdout before exit - * server.c (cvs_flusherr): flush stderr & send a stderr flush command - on the protocol pipe - (cvs_flushout): like above, for stdout - (do_cvs_command): handle flushes properly - * sanity.sh (reserved): make the commitinfo script echo errors to - stderr rather than stdin - -2001-01-18 Larry Jones - - * log.c (option_revlist, revlist, log_usage, cvslog, - log_parse_revlist, log_expand_revlist, log_version_requested): Add - support for :: for exclusive ranges. - * admin.c (admin_usage): Reorder -o to be parallel to log -r. - * sanity.sh (log): New tests for above. - -2001-01-18 Derek Price - - * main.c: Add '2001' to the range of copyright years listed by the - --version option - * version.c.in (version): check current_parsed_root before its isremote - member to avoid a core dump - * sanity.sh (version): add a test for the version command - - * version.c: regenerated - -2001-01-12 Larry Jones - - * rcs.c, rcs.h (RCS_lock, RCS_unlock): Use RCS_gettag to find the - correct revision so that symbolic tags work correctly. (This - requires removing the "const" from the rev parameter since it's - passed to RCS_gettag which might modify it.) - (Reported by irina sturm .) - -2001-01-11 Larry Jones - - * run.c (close_on_exec): Remove check for FD_CLOEXEC. As far as I - can see, it's *never* been defined, which defeats the whole point. - If F_SETFD is defined, it's probably safe to use it. - - * server.c (do_cvs_command): Call close_on_exec on the protocol and - flow control pipes in the child process so they don't get inherited - by any subsidiary processes. - (Reported by Tristan Gingold .) - - * cvs.h (free_cvsroot_t): Spell correctly (was free_CVSroot_t). - -2001-01-10 Derek Price - Rex Jolliff - - * build_src.com: VMS changes - * filesubr.c: replace calls to unlink() with CVS_UNLINK() for VMS - * rcs.c: ditto - -2001-01-10 Derek Price - - * main.c (current_root): explicitly list this as a static global - -2001-01-10 Derek Price - - * cvs.h (get_cvs_port_number): change name & prototype from - get_port_number - * client.c (get_cvs_port_number): new function which returns a port - number based on a cvsroot_t rather than requiring all possible sources - passed in - (connect_to_pserver): use new get_cvs_port_number function - (connect_to_server): ditto - * login.c (get_password): use new get_cvs_port_number function - (login): ditto - (logout): ditto - -2001-01-10 Derek Price - - * Makefile.am ($(srcdir)/version.c): specify $(srcdir) for all subparts - of the build since some systems don't allow mv's across partitions - * Makefile.in: regenerated - -2001-01-10 Derek Price - - * Makefile.am (version.c): specify $(srcdir) explicitly in target rule - so version.c gets built properly for all makes. - (version.o): specify $(srcdir)/version.c explicitly so dependency is - found and built properly - * Makefile.in: regenerated - -2001-01-09 Derek Price - - * version.c: updated timestamp - -2001-01-09 Larry Jones - - * server.c (server): Change to server_temp_dir immediately after - creating it so that any stray files that happen to be created go - there instead of in the server's initial directory, wherever that - may be. - * sanity.sh (modules5-15): Update to match. - - * version.c.in: Update to match Derek's change to version.c. - -2001-01-09 Derek Price - - * cvs.h: Remove the various CVSroot_* bits and replace them with a - single structure of type cvsroot_t (current_parsed_root) - - * root.c (parse_cvsroot): return pointer to a new cvsroot_t rather than - altering global variables - (local_cvsroot): return a pointer to a new cvsroot_t rather than - setting globals. changed the name of this function from - set_local_cvsroot to better explain new functionality - (new_cvsroot_t): new initializer function - (free_cvsroot_t): new function - (others): use current_parsed_root rather than the old CVSroot_* globals - - * add.c: use current_parsed_root rather than the old CVSroot_* globals - * admin.c: ditto - * checkout.c: ditto - * client.c: ditto - * commit.c: ditto - * create_adm.c: ditto - * diff.c: ditto - * edit.c: ditto - * expand_path.c: ditto - * find_names.c: ditto - * history.c: ditto - * ignore.c: ditto - * import.c: ditto - * lock.c: ditto - * log.c: ditto - * login.c: ditto - * logmsg.c: ditto - * main.c: ditto - * mkmodules.c: ditto - * modules.c: ditto - * parseinfo.c: ditto - * patch.c: ditto - * rcs.c: ditto - * recurse.c: ditto - * release.c: ditto - * remove.c: ditto - * repos.c: ditto - * rtag.c: ditto - * server.c: ditto - * status.c: ditto - * tag.c: ditto - * update.c: ditto - * version.c: ditto - * watch.c: ditto - * wrapper.c: ditto - -2001-01-05 Derek Price - - * cvs.h (enum CVSmethod): add null_method - * root.c (method_names): correlate null_method & "undefined" - (parse_cvsroot): make two error cases non fatal - * sanity.sh (crerepos-6b): account for new error message, re above - -2001-01-05 Derek Price - - * src/Makefile.am (cvsbug, cvsbug_EXTRA_DIST, EXTRA_DIST): move cvsbug - target to configure.in - see ../ChangeLog for more - * src/cvsbug.in: Rename from cvsbug.sh - * src/cvsbug.sh: Rename to cvsbug.in - -2001-01-04 Larry Jones - - * Makefile.am (cvsbug): Explicitly list input file ($< is only - valid in inference rules). - * Makefile.in: Ditto. - -2001-01-04 Derek Price - - * sanity.sh: use getopts rather than getopt for portability reasons - -2001-01-03 Derek Price - - * Makefile.am (remotecheck): depend on 'all' - * Makefile.in: regenerated - -2000-12-29 Derek Price - - * sanity.sh: remove explicit "$@" from last checkin and move the 'do' - to the line following the 'for'. Apparently this is more portable. - -2000-12-29 Derek Price - - * sanity.sh: make "$@" explicit in 'for' statement since Solaris 5.6's - implementation of Bourne shell doesn't seem to implement this default - behavior. - -2000-12-27 Derek Price - - * sanity.sh: add a -f option for continuing from a particular test - and shorten --keep to -k so we can use the getopt function. - -2000-12-27 Derek Price - - * Makefile.am (remotecheck): Make remotecheck dependant on all - * Makefile.in: regenerated - -2000-12-26 Derek Price - - * Makefile.in: update timestamp - * stamp-h2.in: ditto - * version.c: ditto - -2000-12-26 Derek Price - - * Makefile.am: new target for version.c - (EXTRA_DIST): add version.c.in & version.c so builds work when - configure doesn't - * Makefile.in: Regenerated - * stamp-h2.in: update timestamp - * version.c: ditto - -2000-12-26 Derek Price - - * Makefile.am (INCLUDES): add zlib - * Makefile.in: Regenerated - -2000-12-22 Derek Price - - * Makefile.am (DISTCLEANFILES): added a few files - (INCLUDES): commented - * Makefile.in: Regenerated - -2000-12-21 Derek Price - - * .cvsignore: Added .deps directory and a new stamp file - * Makefile.am: New file needed by Automake - * Makefile.in: Regenerated - * stamp-h2.in: New stamp file created by Automake - * version.c.in: use configure to generate version.c - -2000-12-16 Derek Price - - * server.c (server_update): Keep the vers structure up to date after - sending a Remove or Remove-entry command to the client - * update.c (update): remove call to server_updated() after - scratch_file() - (scratch_file): in server mode, call server_updated(), otherwise keep - the vers structure up to date - (join_file): add a trace, save the revision to Register() on a remove - before calling server_scratch & server_updated - * sanity.sh (join): Add test for a remove/add caused by an update - to a new branch and a join in the same step. - -2000-12-15 Larry Jones - - * error.c (error): Add %ld and %lu. - - * history.c: Change hrec.idx from int to long, reformat NEXT_BAR - for readability, add hrec_idx. - (fill_hrec): Change initialization to be portable and always set - idx so it can be used as a line number in error messages; improve - parsing and error checking. - (read_hrecs): Initialize hrec_idx, handle embedded NULs, warn about - no newline at end of file. - (select_hrec): Add basic validity checking. - -2000-12-07 Larry Jones - - * history.c (history): Allow multiple -m options as documented. - -2000-11-29 Derek Price - - * root.c (parse_cvsroot): back out yesterday's redundant changes - * main.c (main): fix CVSROOT trace message to look like other trace - messages - * sanity.sh (multiroot2-9): expect new trace message - -2000-11-28 Derek Price - - * root.c (parse_cvsroot): add trace on this function - * client.c (get_port_number): make trace print look like others - -2000-11-16 Derek Price - - * filesubr.c (cvs_temp_file): back out the previous change in the - interests of portability, add an assertion, and fix the header comment - -2000-11-16 Derek Price - - * filesubr.c (cvs_temp_file): refine the exit behavior to notice if - the out param was passed in NULL and, if so, avoid setting it and delete - the temp file for later - -2000-11-16 Derek Price - - * filesubr.c (cvs_temp_file): fixed a garble or two, added some - additional error checking, and added a comment - -2000-11-15 Derek Price - - * filesubr.c (cvs_temp_file): added cvs_temp_file - function to use mkstemp rather than one of the other temp file - generators as gcc keeps complaining I should. - (cvs_temp_name): altered this function to simply wrap cvs_temp_file - and deprecated it - * cvs.h: added prototype for cvs_temp_file - * commit.c (commit): use the new function instead of the old and plug - an old (though related) memory leak. - * import.c (import): use the new function - * login.c (login): Ditto - * logmsg.c (do_editor, do_verify): Ditto - * patch.c (patch_fileproc): Ditto - -2000-11-14 Larry Jones - - * update.c, update.h (do_update): Add xdotemplate parameter. - Change all callers. - (update_dirent_proc): Use dotemplate for Create_Admin, not 1. - * checkout.c (checkout_proc): Don't create CVS/Template if - exporting. - (Reported by Andrey Podkolzin .) - -2000-11-08 Larry Jones - - * admin.c (admin): Use getgroups() to check for membership in - CVS_ADMIN_GROUP if it exists. In any event, check the user's - primary group in addition to any additional groups. - (Reported by Thomas Okken .) - -2000-11-06 Jim Meyering - - Compile with gcc's -Wformat and fix the exposed problems. - * root.c (parse_cvsroot) [! HAVE_KERBEROS]: Provide an argument - for the %s error format spec. - [! HAVE_GSSAPI]: Likewise. - (normalize_cvsroot): Put comment delimiters around token after `#endif'. - -2000-11-03 Larry Jones - - * sanity.sh: Some versions of sed require a space between -e and - the value. - -2000-10-27 Larry Jones - - * checkout.c (checkout): Don't check for a safe location if just - cat'ing the module database. - (Reported by Ilya Martynov .) - Have -s set cat as well as status; it simplifies the code. - -2000-10-26 Larry Jones - - * sanity.sh (join-admin-2): Check output from all commands instead - of (mostly) discarding. (Some of the tests used to produce stray - output in remote mode.) - - * sanity.sh (dotest_line_by_line): Handle empty lines in pattern - (expr doesn't distingish between successfully matching nothing - and failing to match anything). - - * sanity.sh (dotest_internal): Rearrange and use elif to simplify. - -2000-10-24 Jim Meyering - - Fix a bug, introduced with my fix of 2000-07-10, whereby -kk would - sometimes be ignored for some of the files involved in an update. - - * update.c (join_file): Restore the original value of `options' - right after calling checkout_file. - * sanity.sh (join-admin-2): New test for this. - -2000-10-23 Derek Price - James Youngman - - * sanity.sh: it's /gnu/bin, not /gun/bin. Thanks go to James Youngman - for the bug report and patch. - -2000-10-20 Jim Kingdon - - * server.c (switch_to_user): Set CVS_USER. Patch from Sudish - Joseph and popularized by dozens (e.g. mozilla.org, also others). - -2000-10-20 Derek Price - KOIE Hidetaka - - * root.c (normalize_cvsroot): plug a memory leak. Thanks to - KOIE Hidetaka - -2000-10-18 Derek Price - - * client.c (connect_to_pserver): added a close brace the lack of which - was preventing compilation when gssapi was enabled. Removed a - redundant check for HAVE_KERBEROS. - -2000-10-18 Derek Price - - * root.c (normalize_cvsroot): removed references to free_port_s and the - now useless call to free now that port_s is on the stack. Thanks to - Jon Miner. - -2000-10-18 Derek Price - - * root.c (normalize_cvsroot): remove calls to snprintf for - compatibility with M$ Windoze. - -2000-10-18 Derek Price - - * sanity.sh (crerepos-6a, crerepos-6a-r): fix a "?" in a regex & pipe - the output of a test to /dev/null since we don't know what error - messages specific rsh implementations will output. - -2000-10-17 Derek Price - - * cvs.h: added CVSroot_password variable. Provided prototypes for - get_port_number & normalize_cvsroot. - * client.c (get_port_number): Fixed an ANSI prototype I had included - for get_port_number. - * login.c (login, logout): Removed two checks for a non-null - CVSroot_username since parse_cvsroot now supplies a default in pserver - mode. allow for a password in CVSROOT - (get_cvs_passsword): return CVSroot_password if it was supplied - in the CVSROOT. - * root.c (parse_cvsroot): Changed CVSROOT spec from - :method:user@host/port:/cvsroot to - :method:[[user][:password]@]host[:[port]]/cvsroot - Removed the xstrdup function since we'd rather have the error checking - from the version in subr.c anyhow. Moved some error messages which - looked like they would print the wrong error message after a failed - connect_to_gserver call. - (normalize_cvsroot): return a normalized CVSROOT for use in the - .cvspass file. - * sanity.sh (crerepos-6): fix a test which was expecting an old error - message. - - * client.c (connect_to_pserver): Moved some error messages which looked like they - would print the wrong error message after a failed connect_to_gserver - call. - - * login.c (login): Paranoiacly zero a password in memory. - -2000-10-12 Derek Price - - * client.c (auth_server_port_number -> get_port_number, start_pserver, - start_tcp_server): use a port specified in CVSROOT instead of the - default port. Failing that, use the CVS_CLIENT_PORT environment - variable. - * cvs.h: Added global CVSroot_port & renamed auth_server_port_number. - * root.c (parse_cvsroot): Parse the new CVSROOT format properly. - Incidentally reformated some error messages for uniformity and - readability. - * sanity.sh (crerepos): fix two tests which were now expecting the - wrong error message. - -2000-10-11 Larry Jones - - * server.c (pserver_authenticate_connection): Fix stupid mistake - in previous change. - -2000-10-11 Derek Price - - * main.c (main): Dispose old CVSroot when parsing a '-d' option if - free_CVSroot is set. - * root.c (parse_cvsroot): remove references to 'cvsroot_parsed', a - static boolean I expect hasn't been used since CVS learned to handle - multiple CVSROOTs. - -2000-10-10 Larry Jones - - * server.c (print_error): Make up a message if strerror fails. - - * server.c (pserver_authenticate_connection): Give a real error - message for an invalid repository. - -2000-10-06 Derek Price - - * add.c (add): Made quiet mode affect some warning messages as seemed - appropriate. Specifically, some of the messages which a user might - want to ignore so they don't have to be quite so specific on the - command line: files added twice, files already in the repository and - check out properly (i.e. but picked up by 'cvs add *'), & files which - are readded in place of a dead revision or onto a branch. '-q' will - not change the non-zero exit code for the cases where at least one - passed in file name was already in the Entries file. There seems to - be a precedent in remove.c. - * remove.c (cvsremove): switched the "use cvs ci to make these changes - permanent message" to only print w/o '-Q' to match the new behavior of - add. This seems appropriate as '-Q' is defined to restrict messages - to critical errors. - * sanity.sh (adderrmsg): Added some tests for the above behavior. - -2000-10-05 Larry Jones - - * client.c (call_in_directory): Create CVSADM directory if it doesn't - exist in the directory. This makes client/server work more like - standalone when checking out into an existing (non-CVS) directory. - * sanity.sh (dirs2, conflicts3, toplevel): Update to match. - -2000-10-03 Larry Jones - - * filesubr.c (get_homedir): Ignore $HOME when running in server mode. - -2000-10-02 Larry Jones - - * cvs.h: Define (and use) T_PATCH as a valid file classification - even when SERVER_SUPPORT isn't defined -- it simplifies the code. - * classify.c (Classify_File): Ditto. - * commit.c (check_fileproc): Ditto. - * status.c (status_fileproc): Ditto. - * update.c (update_fileproc): Ditto. - * tag.c (check_fileproc): Accept T_PATCH in addition to T_CHECKOUT. - * sanity.sh (tagc-10): Update to match. - -2000-09-29 Larry Jones - - * client.c (get_responses_and_close): Reset server_fd to -1 after - shutting down. - (Reported by Joerg Thoennes .) - -2000-09-27 Larry Jones - - * commit.c (commit): Don't sleep before returning in server mode, - just let the client do it. - * update.c (do_update): Ditto. - - * sanity.sh (find_tool): Correct method of checking for GNU tools. - - * checkout.c (checkout_proc): Match up user directories with - repository directories instead of using Emptydir. - * sanity.sh (cvsadm, emptydir): Update to match. - -2000-09-19 Larry Jones - - * version.c: Push version number to 1.11.0.1. - - * version.c: Version 1.11. - -2000-09-07 Larry Jones - - * Makefile.in: Use @bindir@, @libdir@, @infodir@, and @mandir@ - from autoconf. - -2000-08-23 Larry Jones - - * mkmodules.c (init): Create an empty val-tags file if it doesn't - already exist to avoid problems with users not having sufficient - permissions to create it later. - -2000-09-06 Jim Kingdon - - * main.c (lookup_command_attribute): Add "release" to commands - which can be done by a read-only user. - -2000-08-23 Larry Jones - - * repos.c (Name_Repository): Use pathname_levels to detect attempts - to get above the repository instead of checking for leading .. - which isn't reliable. - * sanity.sh (multiroot3-12 to multiroot3-15): New tests for above. - -2000-08-21 Larry Jones - - * rcs.c (expand_keywords): Handle the unusual case of log == NULL. - (Reported by Craig Metz .) - -2000-08-01 Larry Jones - - * subr.c (pathname_levels): Fix bug that miscounts adjacent - slashes. - (Patch submitted by Tanaka Akira .) - - * loginc.c (login): If available, use getpassphrase instead of - getpass to support long passwords on Solaris. - -2000-07-28 Larry Jones - - * server.c (server_noop): Avoid do_cvs_command() overhead. - (requests): Make noop RQ_ROOTLESS. - -2000-07-27 Noel Cragg - - * root.c (parse_cvsroot): change fork method to behave like other - remote methods -- let the server check that the repository - directory is an absolute pathname. - -2000-07-27 Larry Jones - - * lock.c (set_lock): Include actual lock directory in error message. - * sanity.sh (multiroot3-10): Change to match. - - * sanity.sh (client-3): Allow for a potential "broken pipe". - -2000-07-26 Larry Jones - - * commit.c (commit_filesdoneproc): Flush stdout before running script. - * modules.c (do_module): Ditto. - * update.c (update_dirleave_proc): Ditto. - * server.c (do_cvs_command): Give input from the protocol pipe - precedence over input from stdout/stderr. There's no particularly - good justification for this other than helping to avoid out-of-order - messages in sanity.sh. - - * admin.c (admin_usage): Add the supported options. - - * sanity.sh (info): Try to avoid out-of-order messages. - - * sanity.sh (info): Fix problems when running twice in a row. - -2000-07-17 Larry Jones - - * sanity.sh (modules5-7, cvsadm-1e, emptydir-2): Allow for a nil - commit (can happen if the test is run twice in a row). - -2000-07-19 Pavel Roskin - and Larry Jones - - * mkmodules.c (config_contents): Add a commented out example for - LockDir. Don't suggest PreservePermissions unless it's enabled. - -2000-07-17 Larry Jones - - * login.c (get_cvs_password): Handle malformed ~/.cvspass more - gracefully. - -2000-07-12 Larry Jones - - * sanity.sh (modules5): New tests for module programs. - -2000-07-11 Larry Jones - - * filesubr.c (copy_file, xcmp): Handle systems (like Plan 9) that - don't support mknod() and/or st_rdev. - * import.c (add_rcs_file): Ditto. - * rcs.c (RCS_checkout, RCS_checkin): Ditto. - * update.c (special_file_mismatch): Ditto. - -2000-07-10 Larry Jones - - * zlib.c (gunzip_and_write): Fix type clashes. - - * main.c (main): Remove unused variables. - -2000-07-10 Jim Meyering - - When a command like `cvs update -kk -jT1 -jT2' creates a new file - (because it had the T2 tag, but not T1), the subsequent commit of - that just-added file would effectively set the admin `-kk' option - for that file in the repository. - - * update.c (join_file): Rename global-shadowing local `options' - to `t_options'. - Set file-scoped global `options' to NULL just before - check-out. - * sanity.sh (join-admin): New test for this. - -2000-07-08 Larry Jones - - * version.c, cvs.h (version): New function. - * main.c (cmds[]): Add version command to invoke it. - (main): Also use it in -v. - * server.c (serve_version): New function. - (requests[]): Add version command to invoke it. - -2000-07-06 Karl Fogel - - * sanity.sh (pserver-14): remove this test for portability - reasons (it was only recently added for the 2000-07-04 change). - -2000-07-06 Larry Jones - - sanity.sh (modules-148): Don't test for specific revisions. - - * main.c (main): Catch SIGABRT to try to clean up after assertion - failures. Don't bother SIG_register'ing Lock_Cleanup because - main_cleanup calls it indirectly anyway. - * patch.c (patch): Catch SIGABRT. - * rcs.c (rcs_internal_lockfile): Ditto. - * server.c (server): Ditto. - - * fileattr.c (fileattr_write): Don't delete the unrecog_head list - when writing... - (fileattr_free): Delete it when freeing! - -2000-07-05 Larry Jones - - * admin.c (admin): Handle -t in client so reading from files works - correctly in client/server mode. - * sanity.sh (log2): Update to match. - -2000-07-04 Karl Fogel - - * server.c (pserver_authenticate_connection): use new - getline_safe() during authentication phase, to avoid a - denial-of-service attack in which client sends arbitrary - amounts of data with no newlines. - (Reported by .) - - * sanity.sh: new test pserver-14 for above. - - * myndbm.c: #include getline.h. - (mydbm_load_file): pass new GETLINE_NO_LIMIT flag to getstr(). - -2000-07-03 Larry Jones - - * sanity.sh (modules): Rewrite using dotest. Add "modules-" - prefix to test names. - -2000-06-28 Larry Jones - - * error.c (error_exit): Call rcs_cleanup () to release any rcs locks. - * rcs.c, rcs.h (rcs_cleanup): Make public, close file before trying - to remove (some systems won't remove open files). - (RCS_putdtree): Don't worry about cleaning up before call error - since it now does it for us. - (rcs_internal_lockfile, rcs_internal_unlockfile): Keep track of - lock file fd for rcs_cleanup (). - - * client.c (handle_set_checkin_prog, handle_set_update_prog): - Just ignore the request when exporting. - -2000-06-27 Larry Jones - - * create_adm.c, cvs.h (Create_Admin): Add dotemplate argument. - Change all callers. - * checkout.c (checkout_proc): Don't create CVS/Template if - exporting. - -2000-06-26 Pavel Roskin - and Larry Jones - - * server.c (switch_to_user): Only set CVS_Username if - AUTH_SERVER_SUPPORT is defined. - -2000-06-23 Larry Jones - - * client.c (send_dirent_proc): Don't allocate ignlist if you're - going to skip the directory (plugs memory leak). - (send_dirleave_proc): New function. - (send_files): Use it (plugs memory leak). - * root.c (root_allow_free): Plug memory leaks. - * server.c (serve_directory, serve_notify, check_password, - pserver_authenticate_connection): Ditto. - * update.c (update): Ditto. - - This completes the memory leak shoot-out -- the Purify'ed version - of CVS now runs the entire test suite, both local and remote (except - for remote crerepos, which causes Purify to choke) with *no* memory - leaks. - - * server.c (pserver_authenticate_connection): Don't free null pointer. - -2000-06-21 Larry Jones - - * client.c (update_entries, get_responses_and_close): Plug memory leaks. - * commit.c (find_fileproc, commit): Ditto. - * import.c (import): Ditto. - * log.c (cvslog): Ditto. - * recurse.c (start_recursion): Ditto. - * remove.c (cvsremove): Ditto. - * server.c (fd_buffer_initialize, server_notify, do_cvs_command): Ditto. - (fd_buffer_shutdown): New function. - -2000-06-20 Larry Jones - - * root.c (parse_cvsroot): Put the terminating NUL byte into the - string *before* copying it, not after. :-( - -2000-06-19 Larry Jones - - * main.c (main): Plug memory leaks. - * root.c (parse_cvsroot, set_local_cvsroot): Ditto. - * server.c (serve_root): Ditto. - -2000-06-16 Larry Jones - - * fileattr.c (fileattr_read): Plug memory leak. - * rcs.c (RCS_whatbranch): Ditto. - * update.c (update_dirleave_proc): Ditto. - - * ignore.c (ign_dir_add): Duplicate string so caller can free. - - * modules.c (do_module): Don't write into dbm's memory! - -2000-06-15 Larry Jones - - * checkout.c (checkout_proc): Fix non-ANSI code in call to - findslash(), minor cleanups. - -2000-06-14 Larry Jones - - * tag.c (val_direntproc): Return R_PROCESS instead of 0. - - * client.c (update_entries): Fix type clash calling gunzip_and_write(). - * server.c (receive_file): Fix type clash calling gunzip_and_write(). - (server_updated): Fix type clash calling buf_output(). - * error.c (error): Make buf char instead of unsigned char to avoid - type clashes. - - * modules.c (do_module): Change callback_proc to pass argc by - value instead of by reference: callback procs shouldn't be - messing with the callers argc/argv, it makes correct memory - management impossible. Plug memory leaks. - * cvs.h: Change to match. - * checkout.c (checkout_proc): Ditto; use a local argv array instead - of messing with caller's. - * modules.c (callback_proc): Ditto. - * patch.c (patch_proc): Ditto; use a local argv array instead - of messing with caller's. - * rtag.c (rtag_proc): Ditto; use a local argv array instead - of messing with caller's. - * server.c (expand_proc): Ditto. - * subr.c (line2argv): Change initial argv_allocated back to 1. - - * checkout.c (findslash): Fix non-ANSI code. - - * sanity.sh (modes3): Fix test names. - -2000-06-13 Larry Jones - - * add.c (add): Plug memory leaks. - * admin.c (admin_fileproc): Ditto. - * checkout.c (build_dirs_and_chdir): Ditto. - * edit.c (editors_fileproc): Ditto. - * log.c (cvslog, log_parse_revlist, log_parse_date): Ditto. - * rcs.c (RCS_addaccess): Ditto. - * tag.c (check_fileproc): Ditto. - * vers_ts.c (Version_TS): Ditto. - * watch.c (watchers_fileproc): Ditto. - -2000-06-12 Larry Jones - - * rcs.c (rcsbuf_valword): Set rcsbuf->vlen to keep rcsbuf_valcopy() - from allocating more memory than needed for @ strings. Don't declare - unless PRESERVE_PERMISSIONS_SUPPORT (since not defined). - - * rcs.c (RCS_abandon): New function to abandon changes. - * rcs.h: Declare it. - * admin.c (admin_fileproc): Use it instead of RCS_reparsercsfile. - - * commit.c (commit_fileproc): Fix memory leaks. - * patch.c (patch_fileproc): Ditto. - * rcs.c (RCS_nodeisbranch, RCS_copydeltas): Ditto. - * tag.c (tag_fileproc): Ditto. - * update.c (update): Ditto. - -2000-06-09 Larry Jones - - * rcs.c (RCS_reparsercsfile, RCS_fully_parse, getdelta, - RCS_getdeltatext): Handle newphrases with composite values. - (rcsbuf_getkey): Don't remove @s in composite values -- it makes - it impossible to parse the value! Set special flag to indicate - a composite value. - (rcsbuf_valcopy, rcsbuf_valpolish_internal): Handle composite values. - (putrcsfield): Write composite values. - (RCS_checkin): Set node types in other_delta list. - * hash.h: Add RCSCMPFLD. - * hash.c (nodetypestring): Ditto. - - * rcs.c (getdelta): Never allocate space for value, just return - pointer into rcsbuf (fixes memory leaks). Use rcsbuf_getkey to - read a key and value and then parse the value if needed rather - than trying to read it in bits and pieces with rcsbuf_getid, - rcsbuf_getstring, and rcsbuf_getword. - (RCS_reparsercsfile): Change callers to compensate. - (rcsbuf_valcmp, rcsbuf_valword): New functions. - (rcsbuf_getid, rcsbuf_getstring, rcsbuf_getword): Deleted. - * sanity.sh (rcs3-1): Now get slightly different error message. - -2000-06-08 Larry Jones - - * main.c (usg): Update CVS home page URL. - - * main.c (main): Provide an actual error message for an unknown - command in addition to the usage message. - -2000-06-07 Larry Jones - - * server.c (serve_root, dirswitch, serve_repository, - serve_static_directory, serve_sticky, receive_partial_file, - receive_file, serve_modified, server_write_entries, serve_notify, - serve_checkin_prog, serve_update_prog, server): Don't set - pending_error before calling alloc_pending, it makes it fail; - use alloc_pending instead of malloc when reasonable; be sure to - save errno before calling functions that might change it. - (Patch submitted by Dietmar Petras .) - -2000-06-03 Larry Jones - - * commit.c (checkaddfile): Plug memory leak. - * rcs.c (RCS_checkin): Plug memory leaks. - * server.c (do_cvs_command): Plug file descriptor leaks. - * tag.c (check_fileproc): Plug memory leak. - -2000-05-26 Larry Jones - - * recurse.c (unroll_files_proc): Plug memory leak. - - * recurse.c (addfile): Fix nonportable pointer cast. - - * rcs.c (rcsbuf_getstring, rcsbuf_getword, getdelta): Plug memory - leaks. - -2000-05-25 Larry Jones - - * checkout.c (checkout, build_one_dir, checkout_proc): Move m_type - to file scope and use it instead of continually doing strcmp on - command_name. - (build_one_dir, checkout_proc): Don't allow export if CVSADM - directory already exists. - -2000-05-23 Larry Jones - - * rcs.c (RCS_checkin, RCS_cmp_file): Plug memory leaks. (Patch - submitted by Chris G. Demetriou .) - -2000-05-20 Ian Lance Taylor - - * client.c (connect_to_gserver): Handle server error messages - reasonably. - -2000-05-19 Larry Jones - - * server.c (requests): Make Global_option RQ_ROOTLESS so it can be - used with init. - -2000-05-18 Larry Jones - - * client.c (start_server): Don't do encryption, authentication, - compression, or case insensitivity when doing init because init - is ROOTLESS and they're not. - - * client.c (connect_to_pserver): Include repository and username in - authorization failed message -- if a directory tree crosses multiple - repositories, it can be quite difficult for the user to figure out - which one is the problem. - -2000-05-17 Larry Jones - - * main.c (main): Use full set of options when looking for -f to - avoid misparsing options that take values (previously, -sVAR=foo - was incorrectly parsed as though it were -s -V -A -R -= -f -o -o - because it didn't know that -s takes a value). - * sanity.sh (info-6b): New test for above. - - * sanity.sh (conflicts-status): Fix tests so they work remotely, too. - -2000-05-17 Jim Meyering - - * sanity.sh (TESTDIR): Fix braino in last change: - cd to /tmp before invoking pwd. - - * sanity.sh: Set TESTDIR so that `make check' passes even when /tmp - is a symlink. - (join-36): Use $TESTDIR rather than hard-coding `/tmp/cvs-sanity'. - (conflicts-132): Remove unnecessary `rm aa'. - -2000-05-16 Jim Kingdon - - * cvs.h, checkout.c (safe_location): Make extern. - * import.c (import): Call it rather than reimplementing - (incompletely) the same check. - -2000-05-16 Larry Jones - - * rcs.h, subr.c (file_has_markers): Check for any of the three - conflict marker lines, not just one. - * sanity.sh (conflicts-status): New tests for above. - * sanity.sh: Revise to avoid tripping the above check when merging - changes into sanity.sh itself. - -2000-05-15 Larry Jones - - * update.c (join_file): When registering the result of the merge, - make sure that the version number is valid (vers->vn_rcs may be - null if the file doesn't exist on the branch yet). (Patch submitted - by Robert de Vries .) - * update.c (join_file): Correct diagnostics (previous change was not - correct -- the file *does* exist in the specified revision, it just - doesn't exist in the sandbox). - * sanity.sh (import-113, join): New tests and changes for above. - -2000-05-04 Larry Jones - - * sanity.sh: Look for a useful id program. Since we're getting - the real username for some tests anyway, use it for all the - tests instead of a generic regular expression that may or may - not match the actual username. - -2000-05-04 Larry Jones - - * server.c: More error messages. - -2000-05-02 Donald Sharp - and Larry Jones - - * history.c (report_hrecs): Added code to print out year instead of - just month/day. - * sanity.sh (basic2-64, history): Update to match. - -2000-04-19 Larry Jones - - * server.c (dirswitch): Set pending_error_text in addition to - pending_error to aid in problem determination. - -2000-03-23 Larry Jones - - * mkmodules.c (mkmodules): Return without doing anything if noexec - is set to avoid trashing existing files. - -2000-03-23 Larry Jones - - * main.c: Alphabetize cmds[] and cmd_usage[] and add server - commands to cmd_usage[]. - -2000-03-21 Larry Jones - - * sanity.sh (client-1): May get "Broken pipe" message from the - "server" in addition to the expected output. - -2000-03-17 Larry Jones - - * server.c (switch_to_user): Set CVS_Username if it hasn't already - been set elsewhere. (Patch submitted by Gordon Matzigkeit - ). - -2000-03-13 Larry Jones - - * parseinfo.c: Add extern to logHistory declaration. (Reported by - .) - (parse_config): Reformat logHistory code. - -2000-03-10 Larry Jones - - * add.c (add): Don't try to set cvsroot_len until after checking - for help only -- CVSroot_directory isn't set in that case. - -2000-03-03 Larry Jones - - * mkmodules.c (init): Use mkdir_if_needed to create CVSROOT/Emptydir - so we don't fail if run multiple times. (Reported by KOIE Hidetaka - .) - * sanity.sh (1a): New test for above. - -2000-03-02 Larry Jones - - * main.c: Use identical #if's in the command table and the code - for pserver and kserver to prevent "peculiar" configurations from - having really perverse behavior because the command table entries - are present but the related code isn't. - -2000-03-01 Larry Jones - - * import.c (import): Don't allow importing the repository. - * sanity.sh (errmsg2-20, errmsg2-21): New tests for above. - -2000-03-01 Larry Jones - - * main.c (main): Update year in copyright message. - -2000-03-01 Larry Jones - - * logmsg.c (do_editor): Correct previous change. - -2000-02-29 Larry Jones - - * logmsg.c (do_editor): When reading temp file, check that message - buffer is large enough to hold the next line and expand if needed. - -2000-02-28 Larry Jones - - * commit.c (commit): Use get_file() to read log file correctly - and in text mode rather than binary mode. - - * subr.c (get_file): Ignore bufsize if buf is NULL. Include - terminating NUL byte when estimating required buffer size. - -2000-02-28 Larry Jones - - * sanity.sh (find_tool): New function to replace duplicated code. - -2000-02-25 Larry Jones - - * import.c (add_rcs_file): Don't abort just because lstat fails. - -2000-02-16 Jim Meyering - - Avoid race condition whereby a catchable signal could - end up corrupting the repository. - * commit.c (checkaddfile): Put a critical section around the code - that handles the first commit on the trunk of a file that's already - been committed on a branch. - * cvs.h (Sig_inCrSect): Declare new function. - -2000-02-21 Karl Fogel - - * main.c (main): still check for repository, but not history file - (correction to 2000-02-18 change -- that's what I get for - believing the comment rather than the code). - -2000-02-21 K.J. Paradise - - * history.c mkmodules.c parseinfo.c: control which actions - get logged to the cvs history file via CVSROOT/config file - and LogHistory keyword. (John P Cavanaugh ) - -2000-02-18 Karl Fogel - - * history.c (history_write): don't die if history file not - writable, just warn (unless `really_quiet') and skip out. - - * main.c (main): don't bother checking if history file is - writable. - - * server.c (serve_root): same. - -2000-02-17 Larry Jones - - * sanity.sh (perms symlinks symlinks2 hardlinks): Don't run by - default since PreservePermissions code is now disabled. - -2000-02-17 Larry Jones - - * sanity.sh (import-113): Revise to match Jim Meyering's fix. - -2000-02-16 Larry Jones - - * add.c (add): Don't allow adding files or directories to Emptydir. - (Patch submitted by Chris Cameron .) - * sanity.sh (emptydir): Revise (emptydir-7 and emptydir-8) for this. - -2000-02-16 Jim Meyering - - * update.c (join_file): Correct typo in diagnostic: - change `file %s is present...' to `file %s is not present...'. - -2000-02-10 Larry Jones - - * parseinfo.c (Parse_Info): Treat matching lines with bad expansions - as errors rather than just ignoring. - -2000-02-10 Larry Jones - - * edit.c (edit): Check for invalid characters in hostname and CurDir. - (Reported by "Andrew S. Townley" .) - * sanity.sh (devcom2): New tests for above. - -2000-02-10 Larry Jones - - * cvs.h: Always #include "server.h" to prevent compile errors when - neither CLIENT_SUPPORT nor SERVER_SUPPORT is defined. - (Reported by "Crow, Ian" .) - * log.c (send_one, send_arg_list): Only define when CLIENT_SUPPORT - is defined to prevent link errors. - - * server.c (server): Always create a new temporary directory, don't - try to reuse an existing one since we might not have correct - permissions. Also, include directory name in error messages. - -2000-01-29 Jim Kingdon - - * ignore.c (ignore_files): Correctly set errno to 0 when we go - back to the top of the loop. Fixes spurious errors like "cvs - update: error reading current directory: No such file or - directory". - -2000-01-26 Larry Jones - - * run.c (run_exec): Conditionalize K.J.'s change so that it only - applies when SETXID_SUPPORT is defined since some platforms don't - have setegid(). - -2000-01-26 Larry Jones - - * sanity.sh: Make TESTDIR earlier then use it to check for versions - of expr that don't work right with long expressions. - - * sanity.sh (dotest_line_by_line): Have wc read from stdin so it - doesn't output the file name and confuse expr. Make the output a - bit less verbose and easier to read. - -2000-01-24 K.J. Paradise - - * run.c :> prevents a user from creating a privileged shell from the - text editor when the SETXID_SUPPORT option is selected. This came from - Bob Colle , and is his completely. - -2000-01-22 Jim Kingdon - - * sanity.sh (emptydir): Add a case in which one might hope for a - non-Emptydir result, but which result? - -2000-01-18 Larry Jones - - * main.c (main): Allow -z0 to disable gzip compression. - -2000-01-17 Larry Jones for - K.J. Paradise (kj@sourcegear.com) - - * version.c: Push version number to 1.10.8.1. - - * version.c: Version 1.10.8. - -2000-01-17 Larry Jones - - * mkmodules.c (init): Create CVSROOT/Emptydir to avoid problems - with users not having sufficient permissions to create it later. - -2000-01-04 Larry Jones - - * client.c (get_responses_and_close): Simplify time-stamp race - avoidance code. - * commit.c (commit): Ditto. - * update.c (do_update): Ditto. - (Prompted by patch submitted by Pavel Roskin - .) - - * hardlink.c: sizeof (char) is 1, by definition. - * logmsg.c: Ditto. - * rcs.c: Ditto. - -2000-01-03 Karl Fogel - - * filesubr.c, subr.c (backup_file): moved this function from - filesubr.c to subr.c, at JimK's suggestion. - -2000-01-03 Jim Kingdon - - * sanity.sh (clean): Test the contents of the .#cleanme.txt.1.1 - file, not just its existence. - -2000-01-03 Karl Fogel - - * cvs.h, filesubr.c (backup_file): use `const' for suffix too; - correct suffix length calculation and appending behavior; discard - unnecessary `void' cast. Thanks to Jim Meyering for noticing. - -2000-01-03 Larry Jones - - * sanity.sh (clean): Fix up expected output. - -2000-01-02 John P Cavanaugh - and Karl Fogel - - New -C option to update: overwrites local changes with clean - copies from the repository. (This is an unreversion of the - 1999-12-10 change, further modified to work remotely.) - - * client.h (BACKUP_MODIFIED_FILES): new #define. - - * client.c (struct send_data): new element `backup_modified'. - (send_files): set above element if BACKUP_MODIFIED_FILES flag is - present. - - * filesubr.c (backup_file): new function. - - * cvs.h: prototype for new function `backup_file'. - - * update.c (toss_local_changes): new file-scoped global. - (update): set toss_local_changes if -C flag seen. If - client_active, send "-C" to server, and set SEND_NO_CONTENTS and - BACKUP_MODIFIED_FILES flags before calling send_files(). - - (update_fileproc): if file is modified and toss_local_changes is - set, then back the file up and then check out a fresh copy from - the repository. Also, fixed indentation and formatting for a - particularly bad stretch of code near (but unrelated to) these - changes. - - * sanity.sh: new test `clean', for update -C option. - -1999-12-29 Jim Kingdon - - * history.c (read_hrecs): st_blksize is unsigned long, not int. - This isn't just cosmetic - getting it wrong will cause coredumps - and such on 64 bit machines. - - * import.c (import_descend), ignore.c (ignore_files): Placate gcc - -Wall by parenthesizing foo || (bar && baz). - -1999-12-24 Larry Jones - - * release.c (release): Use fputs to echo lines from update instead - of printf to avoid problems with lines containing "%". (Reported - by Jean-Luc Simard .) - - * history.c (read_hrecs): Allocate a single 2-block buffer instead - of allocating and freeing a buffer for each block. - (fill_hrec): Remove redundant code. - (select_hrec): Plug memory leak. - -1999-12-22 Larry Jones - - * history.c (history): For "modified" or "checkout", sort on - file if user specified -l, even if user also specified a date- - oriented flag. - * sanity.sh (history): Update to match; add new tests. - -1999-12-15 Pavel Roskin - and Larry Jones - - * lock.c (lock_name): fixed assertion failure for the - top-level CVS directory when LockDir is used - * sanity.sh (lockfiles-9): new test for this case - -1999-12-11 Karl Fogel - - * Revert previous change -- it doesn't work remotely yet. - -1999-12-10 John P Cavanaugh - and Karl Fogel - - * update.c: new -C option to update, overwrites local changes with - clean copies from the repository. - Also, fixed indentation and formatting for a particularly bad - stretch of code near these changes in update_fileproc(). - - * sanity.sh: test new update -C option. - -1999-12-10 Larry Jones - - * commit.c (remove_file): Call history_write with update_dir NULL - like Checkin() does for add and modify. - * sanity.sh (basic2-64): Update to match, add "R" records to expected - remote output. - -1999-12-09 K.J. Paradise (kj@sourcegear.com) - - * history.c, commit.c, sanity.sh: found (I think) final - cause of seg fault in history command. Also, added the "R" - history functionality. Fixed basic2-64 so it looks correct for - the change. - -1999-11-30 K.J. Paradise (kj@sourcegear.com) - - * history.c: fixed seg fault caused by 11-03 changes. - off by one in block memory allocations. - -1999-11-29 Karl Fogel - - * login.c (logout): free `tmp_name' when done. - Correct a comment. - -1999-11-29 Larry Jones - - * cvs.h, error.c, import.c: Rename fperror to avoid name clash - on LynxOS. (Reported by Markus Braun .) - -1999-11-23 Larry Jones - - * checkout.c (checkout_proc): Split declaration and initialization - of rp to placate neurotic compilers that gripe about jumping past - an initialization, even when the variable is not subsequently used. - -1999-11-19 Larry Jones - - * server.c (switch_to_user): Correct setgid error messages. - -1999-11-19 Karl Fogel - - * edit.c (unedit_usage, unedit): new struct, use it. Now "cvs - unedit" prints an accurate usage message (formerly it printed the - message for "cvs edit", even though the two commands do not have - identical usages). - -1999-11-19 Larry Jones - - * history.c: Move -e documentation from Flags to Reports. - (history): Add -e to list of report types in error message. - - * history.c (history): Process file arguments before client/server - processing so they get sent to the server. - * sanity.sh (history): New tests for above. (Also remove comments - about variable spacing -- history output is in variable-width - columns with exactly one space between.) - -1999-11-19 Larry Jones - - * sanity.sh: Reestablish check for running as root (using ``id -u'' - instead of ``whoami''). - - * sanity.sh(dotest, dotest_lit, dotest_fail, dotest_status, - dotest_sort): Eval the command so quoting and pipes work right. - (spacefiles, dirs, rcslib, modules, unedit-without-baserev, - ignore, rcs, rcs2, history, tagdate, pserver, server, server2) - Simplify various tests based on above. - -1999-11-19 Karl Fogel - - * mkmodules.c (init): make history file world-writeable after - creating it, since it needs to be writeable for virtually any - CVS operation. - -1999-11-10 Jim Kingdon - - * admin.c: Revert change to add -H command option. The help - invocation is "cvs -H admin" not "cvs admin -H" (see cvs.texinfo, - basicb-21 in sanity.sh; fix to cvs.1) - -1999-11-08 Jim Kingdon - - * log.c (cvslog): If client_active, send options to the server - based on our parsed options rather than trying to send the exact - strings specified (using canonical forms, like RFC822/1123 - dates, in the protocol is just cleaner). - (send_one, send_arg_list): New functions, helpers for above. - * sanity.sh (logopt-6a): New test, for this fix. - -1999-11-09 K.J. Paradise - - * admin.c: made the -H option do what it is documented to - do. a - -1999-11-08 Tom Tromey - - * client.c (connect_to_gserver): Print more error text if gssapi - initialization fails. From Assar Westerlund . - -1999-11-06 Larry Jones - - *sanity.sh(rcs3-5): Remote output can be out-of-order, so need a - more general pattern to match the assertion failure. - -1999-11-05 K.J. Paradise (kj@sourcegear.com) - - * history.c: Added a trap to verify that if a - read(file, buffer,blocksize) returns less than blocksize, - that we really are at the end of the file. I can't easily - come up with a test case where this code gets touched, so - it may cause problems. All sanity tests still pass though. - -1999-11-05 Jim Kingdon - - * sanity.sh (logopt): New test, for Larry's fix. - * sanity.sh (log-18a, rcs-15 to rcs-19): New tests, to test -d - and -r more thoroughly. - -1999-11-05 Larry Jones - - * log.c (cvslog): Fix -s and -d with spaces on client side. - (log_usage): Revert Karl's change once again. - sanity.sh(rcs3-5): No longer get different results from local - and client/server. - -1999-11-04 Karl Fogel - - * 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 - - * log.c (log_usage): Revert Karl's change regarding -d and - -s. A space is allowed (see sanity.sh for example). - -1999-11-03 K.J. Paradise (kj@sourcegear.com> - - * history.c: cleaned up my prior change a bit, per Larry Jones' - comments, and John O'Conner's additional comments about bits of - non MS-Visual C++ compliancy of my code. - -1999-11-04 Larry Jones - - * sanity.sh: Check that tr that correctly handles NULs; if not, try - to find a version that does; if none can be found, warn user. - Also fix warnings for defective expr. - -1999-11-04 Karl Fogel - - Changes for empty/random passwords in anon pserver access: - - * server.c (check_repository_password): if password empty, grant - access no matter what password is received; this is so anon CVS no - longer requires a password but remains backwards-compatible with - all those clients out there. - - * client.c (connect_to_pserver): proceed with login even if - password not found in .cvspass file -- just use empty string as - password. And if such a login fails, print a descriptive error. - - * login.c (get_cvs_password): don't complain if file or password - not found. That condition is no longer a showstopper, now that - empty passwords are permissible. - Cleaned up conditional chaining a bit, too. - - * sanity.sh (pserver-9, pserver-10, pserver-11, pserver-12, - pserver-13): new tests, about empty-password pserver access. - -1999-11-03 K.J. Paradise (kj@sourcegear.com> - - * history.c: modify parsing routines to parse the history - file a block at a time, rather than all at once. This allows - people with large history files and small amount of memory - to still get some functionality out of the history file. - -1999-11-03 Karl Fogel - - * log.c (log_usage): correct usage message for -d and -s options. - Because the space between the option letter and its argument has - been eliminated, I capitalized the argument portion to distinguish - it from the option letter. This makes it slightly inconsistent - with other such usage summaries, but at least it is now both - correct and readable. - -1999-10-22 Larry Jones - - * sanity.sh (dotest_sort): Old versions of tr don't understand \t - so use a literal tab instead. - -1999-10-21 Larry Jones - - * sanity.sh (dotest_sort): Convert any tabs in the output into spaces - before sorting to avoid POSIX.2 sort weirdness. - (import-106, importb-2): Change expected output per above. - -1999-10-18 K.J. Paradise - - Bug: users 'stan' and 'cartman' both have full read/write access - to the cvs repository. 'cartman' does a 'cvs admin -l foo.c'. - 'stan' then does a 'cvs admin -u foo.c'. The lock wouldn't be - removed, and no warning/error would be given. This is now fixed. - * rcs.c:(c.6157) remove caller/user check on the multiple lock - detection routines. Sanity.sh runs with no errors after this fix. - -1999-10-14 Larry Jones - - Make "cvs admin -e" (with no list of users) work: - * admin.c (admin): Remove error message. - (admin_fileproc): If no args for -e, call RCS_delaccess with NULL user. - * rcs.c (RCS_delaccess): Interpret NULL user as request to delete - entire access list. - * sanity.sh (admin-19a-*): Test. - -1999-09-29 Larry Jones - - * entries.c (Subdirs_Known): Use entfilename when opening CVSADM_ENTLOG - like everywhere else. Although this isn't strictly necessary (since - we immediately close it again), it keeps the code consistent and fixes - a bug where an open error reported the wrong file name. - -1999-09-16 Larry Jones - - * log.c (log_parse_revlist): Handle peculiar revision specs like - "-r.", "-r:", and "-r," correctly. (Thanks to Pavel Roskin - for submitting a patch, this fix is - somewhat different.) - * sanity.sh (log): New tests for above. - -1999-09-15 Larry Jones - - * sanity.sh (basica-8b1): New test to check fix for bad diff options - causing cvs to crash. - -1999-09-02 Larry Jones - - * modules.c (do_module): Handle case where module definition has - options and special options but no directory; fix potential problems - running off beginning of string while stripping trailing blanks. - * sanity.sh (modules2): New tests for above. - -1999-08-26 Larry Jones - - * lock.c (lock_name): Remove side-effects from assert() expression - since they won't occur if NDEBUG is defined (not that that's a good - thing to do). (Reported by KOIE Hidetaka .) - -1999-08-25 Larry Jones - - * sanity.sh: Use "${AWK}" instead of "awk" to make it easier for - people to use nawk/gawk/etc.; use an explicit "-print" with find - since some older version don't assume it; rename tests to avoid - duplicate importc-8. (Changes along these lines suggested by - Chris Cameron .) - -1999-08-24 Larry Jones - - * commit.c (check_fileproc): Don't crash when a file has no - repository, just treat it as unknown. (Reported by Stefaan - Diericx .) - * sanity.sh (errmsg2): New tests, for this fix. - -1999-08-18 Larry Jones - - * update.c (special_file_mismatch): Initialize *_hardlinks to - avoid trying to free garbage later on. (Reported by Jan - Scheffczyk .) - -1999-08-17 Larry Jones - - * sanity.sh (basicc-11): Older versions of sh don't understand - ``if ! test...''. (Patch submitted by David J N Begley - .) - -1999-08-17 Larry Jones - - * client.c, hardlink.c, hash.c, hash.h, main.c, recurse.c: Change - enum constant UNKNOWN to avoid conflicts on HPUX 11.0. (Reported - by Laurent Duperval .) - -1999-08-16 Larry Jones - - client.c: Eliminate redundant #if. (Patch submitted by Assar - Westerlund .) - -1999-07-30 Larry Jones - - * rcs.c (RCS_checkin): Terminate cleanly if RCS_addbranch fails - rather than blithely continuing on and crashing. - * sanity.sh (basica): New tests, for this fix. - -1999-07-29 Larry Jones - - * import.c (add_rcs_file): change "cannot lstat" message to include - userfile (the actual file causing the problem) instead of user - (which may or may not be the same). - -1999-07-29 Eric Sink - - * version.c: Push version number to 1.10.7.1. - - * version.c: Version 1.10.7. - -1999-07-28 Eric Sink - - * sanity.sh: before running basicc-11, we need to see if - the cwd has been deleted (by basicc-8). If so, we - recreate it to allow basicc-11 to proceed. This may be - something that only happens under the Linux 2.2 kernel. - -1999-07-18 Karl Fogel - - * edit.c (notify_do): chop newline, if any, from the value - obtained from CVSROOT/users. Otherwise it just gets passed along - in the argument to the notification program (usually mail), which - will misinterpret it as signifying the end of the command. - -1999-07-19 Larry Jones - - * rcs.c (RCS_delete_revs): In the WIN32 kludge, be sure that the result - of RCS_getexpand is not NULL before trying to use what it points to. - (Patch submitted by Timothy L. Taylor .) - -1999-07-16 Tom Tromey - - * admin.c (admin): Allow `-k' options to be used unrestricted. - -1999-06-23 Jim Kingdon - - * sanity.sh (symlinks2): New test, for symlinks in working - directory without PreservePermissions. This test (modulo a few - details not relevant to testing whether we are following symlinks) - worked remote as of now, or either remote or local for CVS 1.9. - * subr.c (get_file): Revert 1998-02-15 change to special-case - symlinks. This makes the above test work local too. - * rcs.c (RCS_checkin): Move the logic to handle special-case - symlinks (and other files other than regular files) here, and make - it only happen if PreservePermissions is on. - -1999-06-18 Larry Jones - - * sanity.sh (devcom3-9a): Be less specific about the expected - error message (BSD/OS 4.0 has a bug that can cause exec* to fail - with EACCES instead of ENOENT). - -1999-06-08 Larry Jones - - * sanity.sh (diff-4, dirs2-10, tagf-13, importc-7, conflicts2-142b8): - Use ${PROG} instead of "cvs". - -1999-06-05 Jim Kingdon - - * recurse.c (do_recursion, do_dir_proc): Make the SERVER_ACTIVE - #ifdef be only around the check for server_active. Modulo a few - cosmetic tweaks, same as a patch submitted by Johannes Stezenbach - of propack-data.de. - -1999-06-01 Jim Kingdon - - * sanity.sh: Add comment about rcs2-7 failures on certain days. - - Make "cvs status -v" on a removed file work: - * status.c (cvsstatus): Reindent the client code. - (status_fileproc): Don't need a CVS/Entries listing to show the - tags. - * sanity.sh (rmadd2): New test rmadd2-16 tests the existing - behavior with "cvs log"; new test rmadd2-17 tests the new behavior - with "cvs status". - - * sanity.sh (basicc): To match no output in dotest, put the empty - regexp first. Remove tests which check that first-dir exists, - since that isn't true in the case where the OS let us delete it. - (dotest_internal): Fix so that things work with two regexps, with - an empty one first. - -1999-05-28 Larry Jones - - * sanity.sh (server-4): Replace bogus directory with real one since - the server now checks it. - -1999-05-27 Jim Kingdon - - * sanity.sh (spacefiles): Clean up -c, top, and -b at end. - (spacefiles, files): Fix bad references to CVSROOT_DIRNAME. - - Fix two problems pointed out by Olaf Kirch of swb.de/caldera.de: - * server.c (outside_root): New function, contains expanded version - of code from serve_directory. - (serve_directory): Call outside_root. - (outside_dir): New function - (serve_modified, serve_is_modified, serve_notify, - serve_questionable, serve_unchanged): Call outside_dir. - * sanity.sh (server2): New tests, for these fixes. - -1999-05-26 Jim Kingdon - - * cvs.h, subr.c (xmalloc): Return void* not char*, like xrealloc - has done for some time. - * modules.c (do_module): If we find the module as a directory/file - (rather than in the modules file), skip a bunch of processing - which was unnecessary and also broken in most of the cases - now tested for by the spacefiles sanity.sh test. - * sanity.sh (spacefiles): New test, for specifying filenames - (containing spaces, or starting with '-', or starting with '/') to - "cvs co". - -1999-05-25 Jim Kingdon - - * client.c (update_entries): Make the old DONT_USE_PATCH code the - only code. This means that if people are still on CVS 1.9 - servers, then CVS will fall back to transferring entire files. - This is better than looking for an external "patch" program which - causes no end of troubles (especially on Windows, but someone just - posted to info-cvs about a problem with the Solaris patch). (This - change was run by devel-cvs and feedback was positive). - - * subr.c (xmalloc, xrealloc): The new error.c does not support - %lu; use sprintf instead. - -1999-05-25 Derek Price - - - * sanity.sh (server): Escaped a few more newlines in - another awk script. Solaris awk still don't like 'em. - -1999-05-25 Derek Price - - and Jim Kingdon - - * log.c: Remove comment which said "you can delete [this line]" - and which stuck around for over 3 years. - * sanity.sh (errmsg2 & tagdate): Added tests to prove the - current functionality with respect to combining -r and -D. - -1999-05-20 Larry Jones - - * server.c (pserver_authenticate_connection): Previous changes - broke verify_and_exit (reported by Robert Fitzsimons, thanks). - * sanity.sh (pserver): New tests pserver-7 and pserver-8 for this. - -1999-05-18 Derek Price - - - * sanity.sh (keyword2): Escaped a newline in an awk script. - Apparently Solaris awk don't like 'em. - -1999-05-18 Jim Kingdon - - * sanity.sh (basicc): Allow the behavior whereby unlink(".") - succeeds. Reported by Jeremy Buhler and Pavel Roskin. - -1999-05-17 Steve Cameron of Compaq - - * sanity.sh: Modified to no longer use "test -e" for existence - test as it has turned out to be not portable enough. Instead use - "test -f", "test -d", etc. - [SCO Unixware 7 apparently doesn't always support it -kingdon] - -1999-05-17 Jim Kingdon - - * version.c: Push version number to 1.10.6.1. - - * version.c: Version 1.10.6. - -1999-05-16 Jim Kingdon - - * update.c (patch_file): When we are passing vn_rcs to - RCS_checkout, pass vn_tag as well. - * sanity.sh (keyword): In test keyword-22, test for the fixed - behavior rather than the buggy behavior. Adjust keyword-23. Add - test keyword-24, to see whether keyword-23 really worked. - -1999-05-12 Larry Jones - - * sanity.sh (pserver-4, pserver-5): Bogus error messages from - non-root initgroups on some 4.4BSD derived systems now show up - in different places in the output. - -1999-05-12 Jim Kingdon - - * import.c (import): Don't allow the user to supply a repository - directory which takes us out of the cvsroot. - * sanity.sh (importc): New tests importc-10 to importc-12, for this. - -1999-05-11 Larry Jones - - * server.c (serve_notify): Allocate enough memory to hold the - "misformed Notify request" message in pending_error_text. - -1999-05-11 Jim Kingdon - - * server.c (switch_to_user): Ignore EPERM from initgroups. Fixes - pserver-4 in testsuite. - (pserver_authenticate_connection): Only print "I LOVE YOU" after - switch_to_user has come back successfully. - - * server.c (pserver_authenticate_connection): Call error_exit - rather than reinventing the wheel ourselves. - (switch_to_user): Check for errors from setuid, setgid, and - initgroups. Fix the #ifdef's (the previous code would skip the - setuid call if SETXID_SUPPORT). - -1999-05-10 Jim Kingdon - - * server.c (serve_notify), edit.c (notify_do): Check for - and reject characters which will get confused with delimiters. - * sanity.sh (server): New tests server-7 through server-15 test - for this and for other notify behaviors. - - * rcs.c (RCS_tag2rev): Also look for a physical branch with - RCS_getversion. - * sanity.sh (tagf): Adjust tagf-12 and following tests to test for - the fixed behavior rather than the broken behavior. - -1999-05-07 Jim Kingdon - - * server.c (server_notify): Also set last_node to NULL. - * sanity.sh (server): New tests server-6 and server-7, for this. - -1999-05-05 Jim Kingdon - - * rcs.c (rcs_internal_lockfile): Remove unused variable lockfile. - - * add.c (add): Look for directories with the same name in a - different case where appropriate (analogous to fopen_case). - In client code, add comment about how this doesn't do quite - everything. - -1999-05-03 Jim Meyering - - Remove rcs-style ,file, lock files upon signal. - * rcs.c (rcs_lockfile): New file-scoped global. - (rcs_cleanup): New function (similar to patch_cleanup). - (rcs_internal_lockfile): Register rcs_cleanup the first time this - function is called. Rename uses of local `lockfile' to refer to new - global, `rcs_lockfile'. Don't free the lock file name string, now - that it's global. - (rcs_internal_unlockfile): Rename `lockfile', as above, and carefully - free and NULL-out the global, rcs_lockfile. - -1999-04-30 Jim Kingdon - - * rcs.c (annotate_fileproc): Don't cast NULL in passing it to - RCS_deltas. Because there is a prototype in scope the cast is - unnecessary (per HACKING's ANSI C or SunOS4 rule), and in fact it - was causing failures on UNICOS because it cast to size_t instead - of size_t*. (Thanks to Dean Kopesky for reporting this). - -1999-04-29 Jim Kingdon - - * sanity.sh: If invoked without any arguments, print a usage - message (thanks to Pavel Roskin for a report/patch). - - * run.c (piped_child): Make the error messages more verbose. - (close_on_exec): Reindent. - * sanity.sh (devcom3): Several errors are possible in devcom3-9a. - Adjust for change to piped_child error message. - -1999-04-28 Jim Kingdon - - * sanity.sh (devcom3): Add some tests of the CVS/Notify file and - disconnected "cvs edit". - - * main.c (opt_usage): Remove -b. - -1999-04-20 Derek Price - - - * rcs.c (RCS_delete_revs): RCS_delete_revs uses an - RCS_checkout call to get a new copy of a revision to be - used internally after old revisions were deleted and it was - performing keyword substitutions. This munged all the - the revisions of the file on the branch containing the - deleted revisions and its sub-branches, as the original they - were being patched from was incorrect. Corrected this by - passing in "-ko" as an option to RCS_checkout. - * sanity.sh (keywordlog): modified this test to verify the - correct behavior of 'cvs admin -o'. - [Fixed use of \$ in keywordlog test; added code in RCS_delete_revs - to abort on binary file on Windows -kingdon] - -1999-04-21 Derek Price - - and Jim Kingdon - - * tag.c (tag_check_valid): A bug was causing CVS to spin - indefinately when -j: was specified. CVS now returns - an error. - * sanity.sh: Added a test (tagdate-12) to test this. - -1999-04-19 Jim Kingdon - - * sanity.sh (backuprecover): Clean up the repository at the end. - -1999-04-18 Derek Price - - - * sanity.sh added a test (backuprecover) to test cvs behavior - with a repository that is out of date relative to the - developer's workspaces. - [Fix --keep code; move test to "Repository Storage" section since - it doesn't really exercise the diff/diff3 library. -kingdon] - -1999-04-13 Derek Price - - - * sanity.sh (diff): Tests to verify correct operation of - the --ifdef parameter to cvs diff. - [indentation fixed -kingdon]. - -1999-04-13 Derek Price - - for Noah Friedman - - * diff.c (diff): Put "--ifdef=" in opts string, not "-D"; the - latter is confused by pserver for a date spec. - -1999-04-14 Jim Kingdon - - * fileattr.h: Adjust comments to reflect the official version of - the fileattr format now being in cvs.texinfo. - -1999-04-05 Jim Kingdon - - * sanity.sh (watch5): Remove nonstandard --keep code. Don't pass - -f to rm when cleaning up (that tends to mask bugs). Add watch5 - to list of tests at start. Add comment explaining why we consider - the behavior we test for the right one. Rename a few tests which - had been erroneously named watch6* instead of watch5*. - * client.c (update_entries): Add comment with brief discussion of - whether there is a better way. - -1999-04-05 Derek Price - - - * client.c (update_entries): Only call mark_up_to_date - (which deletes the CVS/Base/ file for watched - and edited files) on commit. - * sanity.sh: Make sure the CVS/Base/ file for - a watched and edited file is not removed on a status or - update of a touched/unmodfied file. - -1999-03-30 Larry Jones - - * client.c (get_responses_and_close), commit.c (commit), - update.c (do_update): If the sleep(1) call returns prematurely - (due to the way wakeup is scheduled or receiving a signal), do - it again. - -1999-03-26 Jim Kingdon - - * server.c (server): Add comment about Gzip-stream vs. RQ_ROOTLESS. - - * sanity.sh (modules3-11b): Adjust exact text of error message to - reflect 1999-03-24 change to dirswitch. - -1999-03-25 Jim Kingdon - - * admin.c (admin): Make argument to -e optional, to match the - documentation. - * sanity.sh (admin-19a-2): Test for this. - - * server.c (serve_root): Update comment about checking for missing - Root request. - -1999-03-24 Jim Kingdon - - * server.c (dirswitch): Also check dir here, similar to - what server_pathname_check does for other cases. - * sanity.sh (files): Adjust files-14 to test for this. - -1999-03-24 Derek Price - - and Jim Kingdon - - * sanity.sh: added a test (files-13) to test .. indirection - in a path and another (files-14) to make sure we still fail - out when the '..' indirection takes us into the $CVSROOT - directory or beyond. - -1999-03-24 Larry Jones - - * rcs.c: Change enum constants ADD and DELETE to something less - likely to run into conflicts. - -1999-03-21 Jim Kingdon - - * sanity.sh (tagf): New test, tests for moving a branch tag to a - non-branch tag and trying to recover. - -1999-03-12 Jim Kingdon - - * sanity.sh (branches): Tweak test branches-5 to test the case in - which one modifies a file and then branches it. - -1999-03-09 John Bley of duke.edu - - * mkmodules.c (filelist): Missed a NULL in this struct (should - have 3 members, only had 2). - -1999-03-07 Jim Kingdon - - * sanity.sh (Index): Rename new test from rm_CVS/Root to rmroot - (we don't have a formal rule about funky punctuation in test names - but both underscore and a slash is too funky for me :-)). - Reindent a few tests which were off. - - * root.c: Remove the sentence which had the improper English; - there isn't really a need for that sentence and it isn't - particularly accurate any more. - -1999-02-27 Derek Price - - - * sanity.sh: Added rm_CVS/Root test to test that CVS uses - $CVSROOT rather than dumping core when running remotely and - the admin file CVS/Root is deleted from the workspace. - - Also, altered a few 'cvs commit' 's in regular expressions to - fit the .${PROG} commit. portability syntax. - - * recurse.c: Stopped CVS from dumping core in the case tested - above. - - * root.c: Fixed somebody's improper english. - -1999-02-25 Larry Jones - - * sanity.sh (keyword2-12): Use ${QUESTION} instead of ? in the - expected result. - -1999-02-24 Jim Kingdon - - * sanity.sh (keyword2): Restore the original \\\$ instead of $. - The latter ends up working due to various kludgy semantics in the - shell and regular expressions, but the former is cleaner. - - * sanity.sh (keyword2): Protect keywords against accidental - expansion in sanity.sh itself (most occurrences had this, but not - all). - -1999-02-23 Derek Price - and Jim Kingdon. - - * sanity.sh (keyword2): New test, tests for merging with -kk. - -1999-02-22 Jim Kingdon - - * version.c: Ease version number to 1.10.5.1. - - * version.c: Version 1.10.5. - -1999-02-18 Jim Kingdon - - * sanity.sh (files): New test, for a relatively obscure spurious - "Up-to-date check failed" in client/server. - - * main.c (lookup_command_attribute): Don't check for "history" - twice. - -1999-02-17 Jim Kingdon - and Hallvard B Furuseth - - * root.c (parse_cvsroot): Rearrange ifdefs to squelch possible - warnings about statement not reached. - -1999-02-16 Jim Kingdon - - * recurse.c (start_recursion): If we are skipping the current - directory (due to it being from the wrong repository), also adjust - the arguments we send to the server accordingly (like we already - do for the case in which there is no CVS directory). - * sanity.sh (multiroot4): New test, for this. All these tests had - passed locally, but remote multiroot4-12 tests for this fix. - (multiroot): Adjust multiroot-diff-1, multiroot-update-2, - multiroot-tag-1, multiroot-status-1, multiroot-update-3, and - multiroot-log-1 to reflect the cosmetic change this produces (one - less "Diffing ." message). - (multiroot2): multiroot2-8 likewise. - -1999-02-10 Jim Kingdon - - * tag.c (cvstag): Don't pass SEND_NO_CONTENTS if -c specified. - * sanity.sh (tagc): New test, for various tag -c behaviors. - Test tagc-6 tests for this fix. - -1999-02-09 Jim Kingdon - - * error.c (error): Rewrite to no longer use vasprintf (see - ../lib/ChangeLog for rationale). Note the slight change in - interface - callers which want %8.8s or similar formats need to - call sprintf. - * lock.c (lock_wait, lock_obtained): Use sprintf. - -1999-02-08 Jim Kingdon - - * rcs.c (RCS_delete_revs): Pass -a to diff_exec. - * sanity.sh (binfiles3): New tests binfiles3-9 through - binfiles3-13 test for this fix. - * sanity.sh (binfiles): New tests binfiles-o4 and binfiles-o5 - (which don't test this bug, just on general principles). - -1999-02-04 Jim Kingdon - - * lock.c (lock_name): Permissions of directories in LockDir - shouldn't depend on the umask. - * sanity.sh (lockfiles): Set umask and CVSUMASK, to test for this. - -1999-02-01 Jim Kingdon - - * sanity.sh (keywordlog): New tests keywordlog-22 and - keywordlog-23 test keyword expansion and $Log. Adjust other tests - so that revisions differ more from each other, so this is a - better test. - -1999-01-29 Jim Kingdon - - * commit.c (checkaddfile): If options is "", treat it the same as - NULL. Centralize this check, and the one for it starting with - "-k", at the start of the function. - - * rcs.c, rcs.h (RCS_setexpand): New function. - * admin.c (admin_fileproc): Access keyword expansion field via - RCS_getexpand and RCS_setexpand, rather than directly. - * commit.c (checkaddfile): When resurrecting, set the keyword - expansion mode. - * sanity.sh (binfiles3): Adjust tests binfiles3-7 and binfiles3-8 - for the new behavior. - -1999-01-27 Jim Kingdon - - * sanity.sh (multiroot3): Add new variant of multiroot3-10 test - for RELATIVE_REPOS. Move multiroot3-11 test out of the - conditionals; it works the same for remote or local, - RELATIVE_REPOS or no. - - * options.h.in: Make RELATIVE_REPOS the default, as has been - announced as a future direction since 1997-10-11. - * sanity.sh (multiroot): Tweak multiroot-update-1a and - multiroot-update-1b tests to work with either RELATIVE_REPOS or - non-RELATIVE_REPOS. - - * sanity.sh (client-9): Don't assume the time zone. - -1999-01-26 Jim Kingdon - - Fix one facet of the "cvs add -kb" re-adding problem (the other - known facet is tested for by binfiles3-8). - * add.c (add): When re-adding a file, set the keyword expansion - as we normally would. - * sanity.sh (binfiles3): New test binfiles3-6a tests for this. - -1999-01-22 Jim Kingdon - - * sanity.sh (rmadd2): New tests, for undoing a commit. - -1999-01-21 Eric Mumpower - - * sanity.sh (reposmv): Actually modify CVSROOT in current - environment when calling functions, rather than trying to achieve - the same effect with "CVSROOT=foo functionname". (Many common - bourne shells, including those in SunOS and Solaris 2.4-2.7, - do not properly handle "ENVVAR=foo command" when "command" is - a user-defined shell function rather than an actual executable.) - -1999-01-15 Jim Kingdon - - * sanity.sh (rcs3): Redirect awk's stdin to /dev/null like all the - other awk invocations. GNU awk seems not to read stdin in this - case, but that behavior is hard to reconcile with the Single Unix - Spec and some awks don't do it. - - * sanity.sh (binfiles, binfiles2, binfiles3, server): Use the same - tr trick as in rcs3. People don't seem to have been complaining, - and this should fix server-4 for HPUX. - -1999-01-14 Jim Kingdon - - * client.c (recv_line): If the line we are reading contains a - character which would sign-extend to EOF, don't treat it as end of - file. recv() doesn't report end of file this way and this might - fix bugs with 0xff characters. - -1999-01-14 Larry Jones - - * client.c (recv_line): Handle EOF from server. - - * sanity.sh (importc-8, importc-9): Accept anything in the seconds - fields of the timestamps since touch doesn't set it reliably. - (This isn't great, but it's better than nothing.) - -1999-01-14 Jim Kingdon - - * run.c (run_exec): Adjust comment about vfork; this isn't the place - to get into a treatise about fork performance vs. vfork - performance but it isn't quite as simple as whether one has - copy-on-write. - -1999-01-13 Larry Jones - - * sanity.sh (dotest_fail): Handle spurrious output from assert better. - - * sanity.sh (rcs3-4, rcs3-5a): Handle even more variants of the - assertion failure message. - -1999-01-12 Larry Jones - - * sanity.sh (mtfr-3): ls behavior varies wildly on nonexistant files, - just use echo instead. - -1999-01-11 Jim Meyering - - * sanity.sh (mkmodules-temp-file-removal): New test, for this. - * mkmodules.c (mkmodules): Remove each `CVSROOT/.#[0-9]*' temporary - file that's used to check out files listed in CVSROOT/checkoutlist. - Remove extra semicolon at end of line. - -1999-01-11 Larry Jones - - * sanity.sh (rcs3-5a): Allow for multiple lines of output before the - assertion failure message. - - * sanity.sh (lockfiles-6, client-8): Work around bug in HP-UX chmod - (doesn't allow anything to follow omitted permissions). - -1999-01-09 Jim Kingdon - - * client.c (set_sticky): Nonfatal error if we can't write it. - * sanity.sh (dirs2-8 through dirs2-14): New tests, for this. - - * sanity.sh (rcs3): Write NUL character with tr not awk, in - accordance with Single Unix Specification. Hopefully will fix - rcs3-7 for HPUX. Will not work on SunOS4, but then again neither - did the old syntax. - -1999-01-05 Jim Kingdon - - * client.c, update.c: Rename MD5* functions to cvs_MD5* per - corresponding change to ../lib/md5.h. - -1999-01-03 Jim Kingdon - - * sanity.sh (client): Give file1 a predictable mode so that the - output in client-9 will not depend on the umask of the user - running the tests. - -1998-12-29 Jim Kingdon - - * client.c (client_senddate): Use date_to_internet rather than - using our own "5/26/1997 13:01:40 GMT" date format. - * main.c (date_to_internet): Check for errors from sscanf. Always - send a four digit year. Send hours, minutes, and seconds as two - digits per RFC822. - * sanity.sh (client): New tests client-8 and client-9 test for this. - - * sanity.sh (rcs2): New tests rcs2-6 through rcs2-8 test for fix - to lib/getdate.y (before the fix, "100 months" or "8 years" would - tend to mean the year 1969, thus the tests would give "cvs update: - file1 is no longer in the repository"). - -1998-12-28 Larry Jones - - * entries.c (Register): Return if unable to open log file to avoid - referencing the invalid file pointer. - * sanity.sh (dirs2-7): With above change, no longer fails. - * sanity.sh (rcs3-5a): Another assertion failure message. - * sanity.sh (pserver-4, pserver-5): Some 4.4BSD derived systems spit - out bogus error messages when initgroups is called as non-root. - -1998-12-23 Larry Jones - - * sanity.sh (rcs3, dotest_fail): The assertion failure message varies - wildly between different systems and the resulting abort call can - even result in spurrious output. Fix the regexp to accept nearly - anything containing some kind of assertion failure and ensure that - any spurrious output ends up in the output file instead of on the - terminal. - -1998-12-23 Jim Kingdon - - * admin.c, checkout.c, commit.c, cvsrc.c, expand_path.c, - history.c, ignore.c, import.c, log.c, mkmodules.c, modules.c, - myndbm.c, parseinfo.c, rcs.c, remove.c, rtag.c, status.c, subr.c, - tag.c, wrapper.c: Cast all char's to unsigned char before passing - them to ctype.h functions (isalpha, isgraph, isalnum, isspace, - isdigit, isprint, isupper). Whether using ctype.h is the right - thing at all is unclear to me (having the server depend on locale - seems wrong, as we don't necessarily have any good way to set the - right locale, if there even is such a concept as 'right' locale in - this context), but as long as we use ctype.h we might as use it - according to the standards (this affects systems where plain char - is signed but users supply characters with the 8th bit set). - Thanks to Paul Eggert for suggesting this. - -1998-12-22 Jim Kingdon - - * sanity.sh (rcs3): Oops, the earlier fix for srcdir only fixed - the non-remote case, not the remote case. Fix the other occurrence. - -1998-12-22 Jim Kingdon - - * sanity.sh (rcs3): The assertion failure message varies slightly - depending on whether CVS was built with srcdir != ".". Fix regexp. - -1998-12-21 Jim Kingdon - - * rcs.c (RCS_getdate): Reindent Jim Meyering's change; remove - unused variable x_vers. - - * rcs.c: When printing an unexpected character we found in the RCS - file, print it in hex rather than as a character (see comment for - rationale). - * sanity.sh (rcs3): Adjust rcs3-2 and rcs3-7 tests accordingly. - - * sanity.sh (rcs3): New test, for some error handling cases - involving parsing RCS files. - -1998-12-16 Jim Meyering - - * rcs.c (RCS_getdate): Handle the case in which a file is first - imported after its initial version has been created. - * sanity.sh (import-after-initial): New test for that. - -1998-12-17 Jim Kingdon - - * server.c (serve_root): Pserver_Repos only exists if - AUTH_SERVER_SUPPORT is defined. - -1998-12-12 Jim Kingdon, and Derek R. Price of Stortek. - - * sanity.sh (multiroot): Change + to ${PLUS}. - -1998-12-12 Jim Kingdon, and Gary Young of Motorola - - * sanity.sh (admin): In tests admin-13, admin-25, and admin-29, - allow 4 digit year in addition to 2 digit year. - -1998-12-12 Jim Kingdon - - * sanity.sh (log): New tests log-14a and log-14b test for -rHEAD - and for HEAD as (nonexistent) file name. - -1998-12-02 Jim Kingdon - - * version.c: Squish version number to 1.10.4.1. - - * version.c: Version 1.10.4. - -1998-11-24 Jim Kingdon - - * recurse.c (do_file_proc): Check for errors from RCS_parse. - * sanity.sh (rcslib-symlink-7 through rcslib-symlink-10): New - tests, test for this. - - * sanity.sh (reposmv-2): Adjust for 22-Nov change to Find_Names. - - * entries.c (Register): If we can't write Entries.Log, make it a - nonfatal error. - * sanity.sh (dirs2): Test for this fix. - - * sanity.sh (dirs2): Clean up working directory at end of test. - -1998-11-23 Jim Kingdon - - * sanity.sh (dirs2): New test, for some more cases involving - deleting directories and such. - - * sanity.sh (dirs): Update for yesterday's change in Find_Names - error handling. The error in dirs-4 is fairly different now; in - dirs-3 and dirs-3a it is the obvious change. - -1998-11-22 Jim Kingdon - - * sanity.sh (release): Move the commments listing "cvs release" - tests from modules2-6 to here. - * release.c (release): Update comment to reflect "? foo" case. - - * find_names.c (Find_Names): If we can't read the repository, make - it a nonfatal error. Tell the caller whether this happened. - (find_rcs): Add comment regarding this behavior. - * recurse.c (do_recursion): If Find_Names gives an error, skip - the directory and print a message saying so. - * sanity.sh (modes3): New test, for this. - -1998-11-18 Jim Kingdon - - * rtag.c (rtag_usage), tag.c (tag_usage): Use "-r rev" - consistently. - - * sanity.sh (conflicts3): Tests conflicts3-24 through - conflicts3-28 test for another case similar to conflicts3-22. - -1998-11-14 Jim Kingdon - - * sanity.sh (diff): New test, for now just tests for the "I know - nothing" message. - - * sanity.sh (conflicts2-142b7 through conflicts2-142b11): New - tests; resurrecting doesn't work from one level up. - - * sanity.sh (mwrap-7): Remote prints the messages in a different - order. - -1998-11-13 Jim Kingdon - - * tag.c (check_fileproc): Log tag deletions. - * rtag.c (check_fileproc): Likewise. - * sanity.sh (taginfo-14 through taginfo-18): New tests, for - these behaviors. - -1998-11-12 Jim Kingdon - - * sanity.sh (mwrap-7): Update for the noexec fix. - - * server.c (server_copy_file): Add comment about noexec. - - * update.c (checkout_file): Handle noexec case involving revbuf - and modes. - (update_fileproc): In case T_NEEDS_MERGE, let merge_file take care - of noexec, so it can tell the user if there would be conflicts. - (merge_file): Print "conflicts found in FILE" message - regardless of noexec. Add comment about checking for whether the - file already contained the changes, and noexec. - * sanity.sh (conflicts-192a): New test, for this. - -1998-10-20 Jim Kingdon - - Use the gzip library on the server. Probably doesn't speed things - up as currently implemented, but does avoid hassles in terms of - finding an external gzip program. - * zlib.c, server.h (gunzip_and_write, read_and_gzip): Now returns - whether a fatal error occurred, rather than expecting error (1, - ...) to work. - * client.c (update_entries, send_modified): Change callers. - * server.c (receive_file): Rewrite gzip code to use - gunzip_and_write rather than filter_through_gunzip. - (server_updated): Likewise, use read_and_gzip rather than - filter_through_gzip. - * client.c, client.h (filter_through_gzip, filter_through_gunzip), - run.c, cvs.h (filter_stream_through_program): Removed; no longer used. - * sanity.sh (server): New tests server-4 and server-5 test - this feature (note that CVS 1.10 also passes these tests; the - behavior is supposed to be unchanged). - -1998-10-19 Jim Kingdon - - * sanity.sh (multiroot3): New test, tests for a few more - multiroot cases. - - * lock.c (lock_name): Set the permissions on each directory we - create to that of the parent directory. - * sanity.sh (lockfiles): New chmod and tests lockfiles-7a and - lockfiles-7b test for this. Adjust lockfiles-5 for new text of - error message. - -1998-10-15 Jim Kingdon - - * server.c (requests): Set RQ_ROOTLESS for "Set". - * sanity.sh (info): Also clean up $HOME/.cvsrc. - (server): Test that we can send Set before Root (had been tested - by crerepos-6b, but only if you ran the info test first). Tests - for this fix. - -1998-10-14 Jim Kingdon - - * subr.c (expand_string): Tweak the algorithm so that the size - that it allocates is generally a power of two. - -1998-10-14 Eivind Eklund and Jim Kingdon - - * commit.c (commit): For the client, don't worry about whether we - are root. - -1998-10-13 Jim Kingdon - - * server.h (struct request): Change status field to flags and add - RQ_ROOTLESS. - * client.c (handle_valid_requests, supported_request): Change - status to flags. - * server.c (requests): Change status to flags. Add RQ_ROOTLESS. - * server.c (server): If not RQ_ROOTLESS, and we haven't gotten a - Root request, give an error. - -1998-10-12 Jim Kingdon - - * version.c: Slide version number to 1.10.3.1. - - * Version 1.10.3. - - * sanity.sh (modules2-17): Update for 9 Oct 1998 change to - update_dirent_proc. - -1998-10-11 Jim Kingdon - - * commit.c (checkaddfile, commit_fileproc): A numeric value for - 'tag' does not mean that we are adding on a branch. - * sanity.sh (keywordlog): Adjust this test, to test for this - (replaces comment saying we should be doing it). - (rmadd): Likewise. - - * sanity.sh (rmadd): New test, tests for various existing - behaviors with "cvs ci -r". - -1998-10-09 Jim Kingdon - - * update.c (update_dirent_proc): For local CVS, if the directory - does not exist in the working directory nor in the repository, - just skip it. - * sanity.sh (dirs): New tests dirs-3a, dirs-7 and dirs-8 test for - this and related behaviors. Note that the new behavior was also - the previous behavior for remote; we are only changing it for local. - - * wrapper.c, cvsrc.c, ignore.c: Add comments about ignoring .cvsrc - and friends if we can't find a home directory. - * expand_path.c (expand_path): If we can't find the home - directory, give an error rather than a coredump (or worse). - * login.c (construct_cvspass_filename): Don't use errno in error - message; get_homedir doesn't set it. Add comment about this - message. - -1998-10-07 Jim Kingdon - - * diff.c (diff): Set variables to NULL at the start, and free - memory at the end. - * sanity.sh (multiroot2): Add tests for this (before the fix, - multiroot2-12 would abort with "no more than two revisions/dates - can be specified"). - -1998-10-06 Jim Kingdon - - * Makefile.in (installcheck check): Remove references to RCSBIN; - they don't do anything now that RCSBIN is ignored. - - * client.c: Clean up horrible confusion about whether stored_mode - or stored_mode_valid (or nothing :-)) indicates whether - stored_mode is allocated. Should fix crashes (for example, on NT - when the server has renamed multiple files from uppercase to - lowercase). - - * sanity.sh (dirs): New tests, tests for some cases involving - admins who do surgery on the repository. - -1998-10-03 Johannes Stezenbach - - * vers_ts.c (Version_TS): If UTIME_EXPECTS_WRITABLE, if - necessary change the file to be writable temporarily to set its - modification time. - -1998-10-03 Jim Kingdon - - * client.c (handle_error): Add comment about indicating which - errors are from the server. - -1998-10-01 Jim Kingdon - - * sanity.sh (devcom-180): Allow one digit day. - -1998-09-30 Jim Kingdon - - * main.c (main): Don't call Name_Root if -d specified. - * recurse.c (do_recursion, do_dir_proc): Don't check CVS/Root - if -d was specified. - * import.c (import): Indentation fix. - * sanity.sh (multiroot): Update for this change. - (reposmv): New test, tests for this. - -1998-09-28 Jim Kingdon - - * sanity.sh (multiroot2): New test, tests some nested directory - cases. - -1998-09-25 Jim Kingdon - - * sanity.sh (multiroot): Change a few comments which said modules - when they meant directories. - -1998-09-25 Jim Meyering - - * sanity.sh (devcom-180): Add 0-9 to the range of characters allowed - in hostname regexp. - -1998-09-25 Jim Kingdon - - * sanity.sh (log2): New test log2-7a tests for one error handling - case. Add a comment about another. - -1998-09-24 Jim Kingdon - - * sanity.sh: Change crerepos test back to :ext: (for several - reasons; see comments). - -1998-09-24 Noel Cragg - - * sanity.sh (rcslib-symlink-5, rcslib-symlink-6): new tests to - check the operation of "tag" when there are symlinks in the - repository. - - * rcs.c (RCS_checkin): remove old code that resolved the symlink - and call resolve_symlink instead. - (RCS_rewrite): call resolve_symlink before doing anything else to - make sure we're operating on the file and not the symlink. - - * subr.c (resolve_symlink): new routine -- resolves a symbolic - link chain to its destination. - * cvs.h: add prototype. - - * sanity.sh (basica-6.2, basica-6.3): changed match expressions to - reflect new diff output. - - * rcs.c (make_file_label): generate labels for files that include - the pathname so that output from "cvs diff" is useable by patch. - Looks like I came up with the mods as Andy Piper - ; his patch was on the Cyclic unofficial - patches page. - - * sanity.sh: change remote access method from ext to fork. This - results in a significant speed improvement when running the - testsuite. The ext method on my machine (i586 120MHz Linux 2.0.35 - with TCP wrappers installed) runs in 450% of the time of the local - method while the fork method runs in only 150% of the time of the - local method! Yow! Am I SWAPPING yet?! - (crerepos-6a, crerepos-6b): change to reflect different error - messages for fork method. - (modes-15): same. - - * client.c (connect_to_forked_server): new routine. - (start_server): call the above when method is fork_method. - - * root.c: add a new method named "fork". This method uses the - remote protocol, but does so by forking a "cvs server" process - directly rather than doing "rsh host cvs server" (for example). - This new method has few advantages for day-to-day use, but has - three important benefits for debugging: - - 1) Most secure installations these days don't allow rsh access. - With this new method, we can still test the remote protocol on - these machines because we don't need to be able to make a local - TCP connection. - - 2) Even if installations allow rsh access, they almost always - have TCP wrappers to check permissions by IP/hostname. This - causes a short delay for every connection. For invocations from - the command line, this doesn't matter much, but it adds up to a - significant amount of time when running the testsuite. - - 3) On machines that can't (or do not usually) provide rshd - access (I'm thinking of WNT/W95 in particular), we can now run - tests of the remote protocol using this method. Indeed, we can - run remote protocol tests on any machine that has an - implementation of piped_child(). - - (parse_cvsroot): handle new method. - (error_exit, xstrdup, isabsolute): new stub functions to use when - compiling root.c with the DEBUG option. - (main): fix a few typos. - * cvs.h (CVSmethod): add fork_method. - - * server.c (create_adm_p): use Emptydir as the placeholder - directory instead of "." to avoid problems with "cvs update -d" et - al. - -1998-09-22 Noel Cragg - - * sanity.sh (devcom-180): fixed typo in regexp. - - * main.c (main): remove need_to_create_root and related code - (including CVS_IGNORE_REMOTE_ROOT environment variable). The - current implementation (just removed) of rewriting the contents of - the CVS/Root file isn't desirable for a number of reasons: - - 1) Only the top-level CVS/Root directory is updated. If we're - really interested in pointing our WD at another CVSROOT, we - should have a separate command. - - 2) With the new multiroot mods, we don't ever want to rewrite - CVS/Root files in the way the removed code did. Consider: - - cvs -d repository1 co a - cd a - cvs -d repository2 co b - cvs -d repository2 update b - - The update command would rewrite the contents of a/CVS/Root to - the incorrect value. Bad. We then wouldn't be talking to the - correct repository for files in a. - - 3) The removed code seems to be a quick hack to support working - directories checked out from multiple repositories. With the - CVS_IGNORE_REMOTE_ROOT variable set, one could perform commands - as in example 2, above, without worring about updating CVS/Root - files. While in pre-1.10.1 recursive commands wouldn't handle - that working directory hierarchy, one could use commands like - "cvs foo -l" instead. While not great, this allows you (with a - lot of manual interaction) to have a multiroot WD. Since we now - have multiroot mods checked in, we don't need this code. - - (lookup_command_attribute): while we don't need the - CVS_CMD_USES_WORK_DIR flag anymore (since it only was supporting - the need_to_create_root code), I'm leaving it in. It may come in - handy at some later date. - -1998-09-18 Jim Kingdon - - * version.c: Advance version number to 1.10.2.1. - - * Version 1.10.2. - -1998-09-13 Jim Kingdon - - * client.c: Refuse to Copy-file to another directory - * sanity.sh (client): New test, tests for this. - - * edit.c (editors_fileproc), watch.c (watchers_fileproc): Use - cvs_output rather than writing to stdout. - * sanity.sh (devcom): Use dotest for tests 178, 180, and 183 - (tests that we preserve existing behavior on "cvs editors"). - - * commit.c (check_fileproc): Don't allow commits in Emptydir. - * sanity.sh (emptydir-8): Test for this change in behavior. - - * sanity.sh: Add some compatibility tests to TODO comments at end. - -1998-09-10 Jim Kingdon - - * wrapper.c (wrap_add): Remove obsolete comment about -m. - - * server.c (server_updated): Check for error from CVS_UNLINK. - -1998-09-09 Jim Kingdon - - * server.c (serve_root): Allocate with malloc, not xmalloc. - - * root.c (set_local_cvsroot): Move memory allocation from here... - * server.c (serve_root): ...to here. Fixes error handling. - - * root.c (parse_cvsroot): Don't call check_root_consistent; - parse_cvsroot is only used for local and client. - * root.c (set_local_cvsroot): Move check_root_consistent - functionality from here... - * server.c (serve_root): ...to here. Fixes error handling. Also - made the error more explicit, while I am at it. - * server.c (Pserver_Repos): Now static. - * cvs.h: Don't declare it. - * root.c (check_root_consistent): Removed; no longer needed. - * sanity.sh (pserver): New test, tests for this behavior and some - other basic pserver stuff. - - * update.c (merge_file): Use cvs_output for "already contains the - differences" message. Found this one when I actually observed the - out-of-order bug in Real Life(TM). - -1998-09-09 Jim Kingdon - - * find_names.c (find_dirs): Make sure to zero errno before - going around the loop again. - * find_names.c (find_rcs): Make sure to set save_errno. - (thanks to Alexandre Parenteau for reporting both problems). - -1998-09-09 Jim Kingdon and Michael Pakovic - - * edit.c (notify_do): Only free line if it is not NULL. - -1998-09-07 Jim Kingdon - - * cvs.h: dirs_sent_to_server should not be inside - AUTH_SERVER_SUPPORT (reported by both Richard Levitte and Murray - Bishop, thanks). - - * lock.c, cvs.h: New variable lock_dir. - * parseinfo.c (parse_config): New option LockDir. - * lock.c (lock_name): New function, abstracts out lock file naming - and also supports LockDir. - * lock.c (lock_simple_remove, Reader_Lock, write_lock, set_lock): - Call it (6 places, to create/remove read/write/master locks). - (Lock_Cleanup): Refuse to reenter this function. - * sanity.sh (lockfiles): New test, tests for this feature. - -1998-09-03 Jim Kingdon - - * sanity.sh (multiroot): Expect ${TESTDIR} in output instead of - assuming it is /tmp/cvs-sanity (thanks to Mark D. Baushke of Cisco). - Clean up working directory when done (fixes apparent thinko). - - * server.c (create_adm_p): Fix one "return" which didn't return a - value. - (dirswitch): Check for errors from create_adm_p. - - * sanity.sh: Set LC_ALL rather than just LC_COLLATE. - -Wed Sep 2 02:30:22 1998 Jim Kingdon - - * version.c: Bump version number to 1.10.1.1. - - * Version 1.10.1. - -1998-09-01 Jim Kingdon - - Administrative note regarding Noel's changes to allow one to - switch from one CVS root to another in a single command: The - ChangeLog entries for the changes which Noel just checked in - appear for 1998-09-01, 1998-08-28, 1998-08-25, 1998-08-19, and - 1998-08-18, rather than being all together. - - * main.c (set_root_directory): Fix whitespace. - (main): Nuke new -m option and just have that message controlled - by -t. - * server.c (server): Revert the CVS_SERVER_SLEEP code back the way - it was in CVS 1.10. Attaching to the parent process is relatively - boring (you can just run "cvs server" under a debugger instead), - but connecting to the child process is what the old code was for. - * recurse.c, server.c: Remove DEBUG_NJC code. - -1998-09-01 Noel Cragg - - * server.c (do_cvs_command): add another environment variable, - CVS_SERVER_SLEEP2, after forking to pause the program so one can - attach a debugger. - - * sanity.sh (crerepos): clean up crerepos-18 now that multiroot - works in this case. - (multiroot): finalize tests for local vs. remote operation. - - * recurse.c (start_recursion): near the beginning, save the list - of directories to spoof as command-line arguments, if necessary. - Use that list near the end and call send_file_names to send those - arguments to the server. - (do_argument_proc): removed, since we call send_file_names now. - - * main.c (main): re-initialize dirs_sent_to_server on each pass - through the loop for each CVSROOT. - - * cvs.h: add proto for global variable which keeps track of which - directories have been sent to the server when in client mode. - - * client.c (is_arg_a_parent_or_listed_dir): new function. - (arg_should_not_be_sent_to_server): new function. Tries to decide - whether the given argument should be sent to the server, based on - the current CVSROOT and the list of directories sent to the - server. - (send_repository): add the directory name to the list of - directories sent to the server. - (send_file_names): call arg_should_not_be_sent_to_server. - - * add.c (add): switch the order of send_files and send_file_names - to make multiple repository support possible. send_files needs to - create a list of directories being requested so that - send_file_names can decide which command-line arguments to send to - the server for the given current CVSROOT. - * admin.c (admin): same. - * commit.c (commit): same. - * diff.c (diff): same. - * edit.c (editors): same. - * log.c (cvslog): same. - * rcs.c (annotate): same. - * remove.c (cvsremove): same. - * status.c (cvsstatus): same. - * tag.c (cvstag): same. - * update.c (update): same. - * watch.c (watch_addremove): same. - (watchers): same. - -1998-08-31 Jim Kingdon - - * sanity.sh: Remove "debug" function; it was apparently checked - in accidentally by Norbert Kiesel's change. - -1998-08-31 Norbert Kiesel - - * release.c (release): modify last patch to release so that - save_cwd is called only once and restore_cwd is always called when - neccessary. Also fixed a tiny memory leak. - - * sanity.sh (release): added some more tests for "cvs release" - including a test with two dirs and a "no" for the first one (which - fails without the above patch). - -1998-08-28 Noel Cragg - - * sanity.sh (crerepos-18): add new comment and change test - slightly to support multiroot. - (multiroot): add more tests. - - * server.c (create_adm_p): new function. - (dirswitch): call create_adm_p. Modify the code to always write a - new CVSADM_REP file, since create_adm_p might have put a - placeholder there and our value is guaranteed to be correct. - (server): move the CVS_SERVER_SLEEP check here so we can debug - things at an earlier stage. - - * recurse.c (start_recursion): add large comment about the ideal - solution to the "Argument xxx" problem. - - * main.c (main): move position of debugging comment for -m flag. - - * diff.c (diff): clear a static variable. - - * client.c (send_file_names): check to see if we should send this - argument to the server based on the contents of the appropriate - CVSADM directory. This avoids "nothing known about foo" messages - and problems with duplicate modules names in multiple - repositories. - (send_a_repository): change method of calculating toplevel_repos - to support multiple CVSROOTs. - (start_server): clear some static variables. - -1998-08-28 Jim Meyering - - * sanity.sh (basicc-8, basicc-11): Use `.*' instead of explicit - `Operation not permitted'. Solaris2.5.1 gets a different error: - `Invalid argument'. - -1998-08-26 Eric M. Hopper - - * sanity.sh: Set LC_COLLATE to "C". - -1998-08-25 Noel Cragg - - * sanity.sh (multiroot): new set of tests to check the behavior of - multiroot. - - * diff.c (diff): set options value to NULL after freeing to reset - the state for the next time around. - -1998-08-25 Jim Kingdon - - Fix problems with trying to rename an open file: - * rcs.c, rcs.h (RCS_setattic): New function. - * commit.c (remove_file, checkaddfile): Call it. - -1998-08-24 Jim Kingdon - - * release.c (release): Use save_cwd and restore_cwd to get back to - where we started, rather than hoping that CVS_CHDIR ("..") will do - something useful. This removes the need for most of - release_delete, so remove that function and inline what is left. - * sanity.sh (basicc): Adjust tests for this fix, also some tests - with multiple arguments to "cvs release" (in the non-"-d"-case, it - would seem like the old code would CVS_CHDIR into directories and not - CVS_CHDIR back, but I'm not going to investigate this and it - should be a moot point with this fix.). - - * sanity.sh (basicc): Add tests for a serious bug in "cvs release - -d .". - - More error handling fixes: - * ignore.c (ignore_files): Check for errors from opendir and - readdir. - * find_names.c (Find_Names): Check for errors from find_rcs. - (find_rcs, find_dirs): Comment error handling better; also return - an error if we got one from readdir. - * filesubr.c (deep_remove_dir): Also check for errors from readdir. - * import.c (import_descend): Print message on error from opendir - or readdir. - * commit.c (remove_file): Check for errors from CVS_MKDIR and - CVS_RENAME. - (remove_file): No need to remove the file in the temporary - directory; server.c now informs time_stamp_server of what is going - on via CVS/Entries rather than a file with a kludged up timestamp. - * client.c, entries.c, login.c, logmsg.c, mkmodules.c, patch.c, - remove.c, update.c: Check for errors from unlink_file. - * mkmodules.c (write_dbmfile, rename_dbfile, rename_rcsfile): - Check for errors from fclose, CVS_RENAME, and CVS_STAT. - * mkmodules.c (checkout_file): Clarify error handling convention. - * mkmodules.c (mkmodules): Call checkout_file accordingly. - * entries.c (Entries_Open): Check for errors from fclose. - -1998-08-21 Ian Lance Taylor - - * import.c (import): Output suggested merge command using - cvs_output_tagged rather than just cvs_output. Don't put - CVSroot_cmdline in the log file. - * client.c (importmergecmd): New static struct. - (handle_mt): Handle +importmergecmd tag. - * sanity.sh (import): Use an explicit -d in importb-2, to test - whether it is reported in the suggested merge command. - -1998-08-20 Ian Lance Taylor - - * sanity.sh (import): Rewrite tests to use dotest. - -1998-08-20 Jim Kingdon - - * sanity.sh: Add comments about binary files and cvs import. - -1998-08-19 Jim Kingdon - - * sanity.sh (importc): Use ${username} in one place where I had - missed it. - - Make import -d work client/server: - * client.c, client.h (client_process_import_file): Take new - argument, for whether -d is specified, and send Checkin-time - request if it is set. - * import.c (import_descend): Pass it. - * main.c, cvs.h (date_to_internet): New function. - * server.c (server_modtime): Call date_to_internet. - * server.c (serve_checkin_time): New function. - (requests): Add "Checkin-time" request. - (serve_modified): If it was sent, set the timestamp in the - temporary directory. - * import.c (import): If the client sends a -d option, complain. - (import): For the server, always use the timestamps from the temp - directory. - (import): Don't send a -d option to the server. - * sanity.sh (importc): Add tests for import -d. - -Wed Aug 19 15:19:13 1998 Larry Jones - - * sanity.sh (unedit-without-baserev-5): use ${DOTSTAR} instead - of .* since we expect to match multiple lines. - -1998-08-19 Ian Lance Taylor - - * cvs.h (CVSroot_cmdline): Declare. - * root.c (CVSroot_cmdline): Define. - * main.c (main): Set CVSroot_cmdline if the -d option is used. - * import.c (import): If CVSroot_cmdline is not NULL, then mention - an explicit -d option in the suggested merge command line. - -Wed Aug 19 00:28:50 1998 Noel Cragg - - * recurse.c (do_dir_proc): don't muck with CVS/Root directories - when running in server mode. - (do_recursion): same. - - * main.c (main): add the command-line option `m' to help debug the - multiroot environment; it prints out the value of CVSROOT for each - iteration through the main loop. Also, changed the main loop so - that it gets executed only once when running in server mode (the - server will only deal with a single CVSROOT). - - * recurse.c (do_recursion): change default for - PROCESS_THIS_DIRECTORY to true; we should always process a - directory's contents unless there's an existing CVS/Root file with - a different root than the current root to tell us otherwise. - (do_dir_proc): same. - -Tue Aug 18 14:30:59 1998 Noel Cragg - - * recurse.c (do_recursion): check the current value of CVS/Root - and add it to our list of CVSROOTs if it doesn't exist. Decide - whether or not to process files in this directory based based on - the value of CURRENT_ROOT. - (do_dir_proc): same. - - * main.c: add two new globals -- root_directories and current_root - -- which keep track of the values of CVSROOT we've seen and which - value of CVSROOT we're currently processing. - (main): put the main loop for stepping through cvsroot values - here, since we might need to send command-specific arguments for - every unique non-local cvsroot. Moved blocks of code around so - that one-time initializations happen first (outside the loop) and - the other stuff happens inside the loop. - (set_root_directory): helper function. - - * cvs.h: add prototypes for root_directories and current_root, two - new globals for keeping track of multiple CVSROOT information. - -1998-08-18 Jim Kingdon - - * sanity.sh: Don't assume that the shell leaves $^ unexpanded in - an unquoted here-document (suggested by Bart Schaefer to help when - zsh is the shell). - -1998-08-17 Ian Lance Taylor - - * commit.c (checkaddfile): Don't call fix_rcs_modes. - (fix_rcs_modes): Remove. - -1998-08-16 Jim Kingdon - - * create_adm.c (Create_Admin): Don't condition traces on - SERVER_SUPPORT; SERVER_SUPPORT shouldn't do (much of) anything - independent of server_active. - - * sanity.sh (binfiles3): New test, for yet another binary file - bug (sigh). Thanks to Jason Aten for reporting this one. - -1998-08-15 Jim Kingdon - - * rcscmds.c (call_diff_write_output): Update to reflect new - calling convention for the write_output callback. - -1998-08-15 Jim Meyering - - * update.c (merge_file): Warn about failed unlink when not due - to ENOENT. - - * server.h (CLIENT_SERVER_STR): New macro - * create_adm.c (Create_Admin): Use it. - * entries.c (Scratch_Entry, Register): Use it. - * filesubr.c (copy_file, xchmod, rename_file, unlink_file): Use it. - * history.c (history_write): Use it. - * modules.c (do_module): Use it. - * no_diff.c (No_Difference): Use it. - * run.c (run_popen): Use it. - * server.c (server_register): Use it. - -1998-08-14 Jim Meyering - - * hardlink.c (lookup_file_by_inode): Use existence_error rather than - comparing errno to ENOENT directly. - - * client.c (copy_a_file): Unlink destination before doing copy. - * sanity.sh (join-readonly-conflict): New test for this -- it would - fail only in client/server mode. - - * sanity.sh (rcsmerge-symlink-4): Don't use `test -L', it's not - portable. Instead, match against the output of `ls -l'. - (dotest tag8k-16): Simplify tag-construction code and at the same - time, avoid using expr's `length' and `substr' operators. Not - all versions of expr support those. - -1998-08-14 Jim Kingdon - - * version.c: Bump version number to 1.10.0.1. - -Thu Aug 13 11:15:24 1998 Noel Cragg - - * version.c: Change version number to 1.10 and name to `Halibut'. - - * sanity.sh (rcslib): new tests to check behavior of symlinks in - the repository. - -Wed Aug 12 15:39:38 1998 Noel Cragg - - * main.c (lookup_command_attribute): the `annotate' command - shouldn't require access to the repository. Add comment about - commands that do not use the working directory. - -Mon Aug 10 10:26:38 1998 Noel Cragg - - * version.c: Change version number to 1.9.30. - -Thu Aug 6 17:44:50 1998 Noel Cragg - - * server.c (serve_rdiff): change the name of the command (for - error reporting, etc.) from "patch" to "rdiff." - (serve_remove): rename from "cvsremove" to "remove." - - * main.c (lookup_command_attribute): the `rdiff' command shouldn't - require write access to the repository. - -1998-08-06 David Masterson of kla-tencor.com - and Jim Kingdon - - * commit.c (commit_filesdoneproc): Don't call strlen ("CVSROOT") - from within the assert statement. Apparently HP's cc compiler on - HPUX 10.20 has trouble with that. - -1998-08-06 Jim Kingdon - - * rcs.c (RCS_checkin): When adding branch, if there is a lock on - the branchpoint owned by someone else, leave it alone. This - restores CVS 1.9 (RCS 5.7) behavior, fixing a core dump. - * sanity.sh (reserved): New tests reserved-16 through reserved-19 - test for this fix. - -1998-08-05 Jim Kingdon - - * sanity.sh (unedit-without-baserev): Use ${QUESTION} not "?". - This makes it work with GNU expr 1.12 as well as 1.16. - -Sun Aug 2 20:27:44 1998 Noel Cragg - - * mkmodules.c: add comment about TopLevelAdmin for the initial - contents of CVSROOT/config. - -1998-07-29 Jim Kingdon - - * rcs.c (RCS_checkin): Only try to call xreadlink if HAVE_READLINK - is defined. - -Tue Jul 28 19:33:08 1998 Noel Cragg - - * version.c: Change version number to 1.9.29. - - * rcs.c (RCS_checkin): add code to follow symbolic links in the - repository. - -Sun Jul 26 05:14:41 1998 Noel Cragg - - * This set of changes reverts the code to pre-1.9.2 behavior and - does not create CVS directories at top-level (except for the - obvious "cvs co ."). Added a new configuration option to switch - between 1.9 and 1.9.2 behavior. - - * recurse.c (do_argument_proc): new function. - (start_recursion): in the case that we've done a command from - top-level but have no CVS directory there, the behavior should be - the same as "cvs dir1 dir2 dir3...". Make sure that the - appropriate "Argument" commands are sent to the server by calling - walklist with do_argument_proc. - - * client.c (call_in_directory): only create the top-level CVS - directory when we're checking out "." explicitly. The server will - force creation of this directory in all other cases. - - * checkout.c (checkout_proc): only generate the top-level - directory when the TopLevelAdmin=yes. Also send a message to the - client to do the same. - - * parseinfo.c (parse_config): handle TopLevelAdmin option. Set - top_level_admin. - - * main.c: add new variable top_level_admin. - * cvs.h: add extern definition for above. - - * sanity.sh: since we're reverting to pre 1.9.2 behavior for - top-level CVS directories, I needed to make changes to a bunch of - tests that made assumptions about said directories. - (preamble): make sure to add read and execute access to everything - in TMPDIR before removing, since some tests make things read-only. - (basicb-1a, basicb-1b, basicb-9a, basicb-9b): use dotest_fail - because these tests check for the non-existant top-level CVS - directory. - (basicc-3, emptydir-6, emptydir-7, crerepos-6): use "rm -rf" so it - won't complain when trying to remove the non-existant top-level - CVS directory. - (106.5): remove imported-f2-orig.tmp. - (modules2-10, emptydir-4, abspath-1ba, abspath-1bb): cd into the - directory where files exist before using the "add" command so cvs - can find CVSROOT in CVS/Root. - (cvsadm-2): look at a different CVS/Repository file, since the - top-level one doesn't exist. - (taginfo-3): create the directory in the repository directly - rather than relying on the fact that the top-level CVS directory - was created in a previous test. - (serverpatch-6): update first-dir explicity, rather than relying - on the non-existant top-level CVS/Entries file. - (crerepos-18): look at CVS/Repository in a subdirectory rather - than in the non-existant top-level CVS directory. - (toplevel): add code to set TopLevelAdmin=yes. - (toplevel2): new tests -- same as toplevel, but TopLevelAdmin=no. - -1998-07-21 Jim Meyering - - * rcs.c (RCS_checkout): Hoist frees of rev and value. - Warn and return 1 in several cases rather than exiting via - `error (1, ...'. The latter could abort a multi-file commit - in mid-stream, leaving stale locks in the repository. - -1998-07-16 Jim Kingdon - - * build_src.com (rcscmds.c): Also look for include files in - [-.diff], just like Ian's 1998-06-18 change to Makefile.in - -1998-07-14 Jim Kingdon - - * tag.c (pretag_proc), rtag.c (pretag_proc): Don't pass RUN_REALLY - to run_exec. This means that taginfo does not get executed if the - global -n option is specified. Which makes it like loginfo, -i, - -e, -o, -t, -u in modules, editinfo, and verifymsg and unlike - commitinfo. The old behavior was pretty bad in the sense that it - doesn't provide any way to log only the tags which actually - happen. - * sanity.sh (taginfo): New tests taginfo-11 to taginfo-13, for this. - -1998-07-12 Jim Kingdon - - * sanity.sh (ann-id): Write the test so that it tests for the - current (buggy) behavior. - - * sanity.sh (taginfo): Also clean up cvsroot/first-dir. - -1998-07-12 Jim Meyering - - * sanity.sh (ann-id): New (currently failing) test for bug in how - rcs keywords are expanded in the output of `cvs annotate'. - -1998-07-12 Jim Kingdon - - * sanity.sh (taginfo): Write the TESTDIR into the script rather - than having the script look at the environment. This means that - it will work if TESTDIR is set by sanity.sh as well as if - sanity.sh finds TESTDIR in the environment. - -1998-07-11 Jim Kingdon - - * tag.c (check_fileproc): Calculate the revision to be tagged the - same way that tag_fileproc does. - * sanity.sh (taginfo): New tests, test for this (before this fix, - brtag had said 1.1 not 1.1.2.1). - -1998-07-10 Jim Kingdon - - * sanity.sh (unedit-without-baserev): Also clean up "2" directory. - -1998-07-08 Jim Kingdon - - * edit.c (unedit_fileproc): If the Baserev file is missing, don't - get the working file from CVS/Base. The previous code could get - you version 1.1 of the working file and put 1.2 in CVS/Entries. - * sanity.sh (unedit-without-baserev): New tests test for this. - -1998-07-02 Jim Kingdon - - * sanity.sh (unedit-without-baserev): Move the test itself to be - in the same order as in the "tests" variable. - -1998-07-02 Ian Lance Taylor - - * rcscmds.c: Don't include or . Don't - declare vasprintf. - (call_diff_printf_output): Remove. - (call_diff_stdout_callbacks): Don't initialize printf_output - field--it has been removed from the interface. - (call_diff_file_callbacks): Likewise. - -1998-07-01 Jim Meyering - - * edit.c (unedit_fileproc): Handle the case in which base_get - returns a NULL baserev. That happens when a file being `unedit'ed - exists in the CVS/Base directory, but isn't listed in the CVS/Baserev - file. The one case I've seen had no Baserev file at all. The symptom - (if you're lucky) is a segmentation fault upon unedit. If you use - SunOS4.1.4 for which printf prints NULL pointers as `(null)', your - unedit command will complete normally, but it will have corrupted - your CVS/Entries file and a subsequent update may result in an - assertion failure, a core dump, and a stale lock in the repository. - * sanity.sh (unedit-without-baserev): New test for this. - -1998-07-01 Andy Mortimer of aeat.co.uk - and Jim Kingdon - - * server.c (server_updated): Use a prototype if we are using them - for declarations. - -1998-06-29 Jim Kingdon - - * sanity.sh (commit-readonly): Protect keyword against expansion - in sanity.sh itself. Keep the keyword in the file which we check - in (or else this fails to test for the RCS_checkout change). - -1998-06-27 Jim Meyering - - * rcs.c (RCS_checkout): If opening the local workfile fails due to - lack of write access, try to chmod the file and retry the open. - Before, a commit could fail part way through merely because the - open to rewrite with newly expanded rcs keywords would fail. It's - easy to make this happen if you use `cvs -r' or CVSREAD and you - apply a patch to one of your read-only source files -- patch - preserves the read-only setting for the file and your next commit - will fail after committing that file, but before rewriting - (checking out) your working copy. - * sanity.sh (commit-readonly): New test for this. - -1998-06-25 Jim Kingdon - - * update.c (patch_file): Update comments regarding context diffs - to reflect diff library. - -1998-06-23 Jim Kingdon - - * sanity.sh (modules4): Add tests for reversing the order of the - "!first-dir/sdir" and "first-dir". - -1998-06-23 Jim Kingdon - and Dave Wolfe@Motorola. - - * sanity.sh (modes2): Touch the file before chmod'ing it. - -1998-06-21 Ian Lance Taylor - - * update.c (merge_files): Revert changes of 1998-06-19. Instead, - register a merged file with a dummy time stamp. Only set - last_register_time if we need to. - (join_file): Likewise. Always register a merged file, not just - when the merge fails. - -1998-06-21 Jim Kingdon - - * call_diff_write_output, call_diff_printf_output, - call_diff_flush_output, call_diff_write_stdout, call_diff_error, - call_diff_stdout_callbacks, call_diff_file_callbacks): Re-indent. - -1998-06-19 Ian Lance Taylor - - * update.c (merge_file): Make sure the time stamp of the file is - different from the time stamp we register in the Entries file. - (join_file): Likewise. - -1998-06-18 Ian Lance Taylor - - * rcscmds.c: Include . Include either or - . Declare vasprintf. - (call_diff_write_output): New static function. - (call_diff_printf_output): New static function. - (call_diff_flush_output): New static function. - (call_diff_write_stdout): New static function. - (call_diff_error): New static function. - (call_diff_stdout_callbacks): New static variable. - (call_diff_file_callbacks): New static variable. - (call_diff): Don't sleep. Use a callback structure when calling - the diff library. - (call_diff3): Likewise. - - * rcscmds.c: Include diffrun.h. - (call_diff, call_diff3): Pass NULL callback parameter. - (diff_run, diff3_run): Don't declare. - * Makefile.in (rcscmds.o): New target, to use -I for diff - directory. - (zlib.o): Depend upon zlib.h. - -1998-06-09 Mike Sutton@SAIC - - Make it compile with Sun's bundled K&R C compiler: - * rcs.c (count_delta_actions): Change to static to match - declaration. - * client.c (handle_wrapper_rcs_option): Rename error label to - handle_error to avoid clash with function name. - -1998-06-09 Jim Kingdon - - * rcs.c (RCS_delete_revs): If we are trying to delete all - revisions, give an error rather than assertion failed. - * sanity.sh (basicb): New tests basicb-o* test for this. - -1998-06-04 Jim Kingdon - - * add.c (add): Only send "Directory" requests if we need to. - -1998-06-02 Assar Westerlund - - * client.c: Check for HAVE_GSS_C_NT_HOSTBASED_SERVICE rather than - assuming that GSS_C_NT_HOSTBASED_SERVICE is a macro. - * server.c: Likewise. - -1998-06-02 Jim Kingdon - - * fileattr.c (fileattr_read): Check for NULL return from strchr. - * sanity.sh (devcom3): New test devcom3-10 checks for this. - -1998-06-01 Assar Westerlund - and Ian Lance Taylor - - * client.c: If HAVE_GSSAPI_H, include . Only include - if HAVE_GSSAPI_GSSAPI_H. Only include - if HAVE_GSSAPI_GSSAPI_GENERIC_H. - (GSS_C_NT_HOSTBASED_SERVICE): Define if not defined. - (connect_to_gserver): Use GSS_C_NT_HOSTBASED_SERVICE instead of - gss_nt_service_name. - * server.c: Same header file changes. - (GSS_C_NT_HOSTBASED_SERVICE): Define if not defined. - (gserver_authenticate_connection): Use GSS_C_NT_HOSTBASED_SERVICE - instead of gss_nt_service_name. - -1998-06-01 Jim Meyering - - * sanity.sh (tag8k): Add a test for the 1998-05-02 rcs.c bug fix. - -1998-05-26 Jim Kingdon - - * rcs.c (annotate): Call tag_check_valid like the other functions - which have a -r option. - * sanity.sh (ann): New test ann-14 tests for this. - -1998-05-24 Jim Kingdon - - * sanity.sh (importc): New tests importc-5 through importc-8 test - for a (fairly obscure) regression from CVS 1.9. - -1998-05-23 Jim Kingdon - - * sanity.sh (modules2): Add comment listing cvs release tests. - (info): New test info-cleanup-0 tests "cvs -n release". - - * rcs.c (rcsbuf_getid): Remove semicolon at end of #undef. I'm - kind of surprised that compilers accepted this at all, but - removing it squelches a warning for some compilers. - - * version.c: Change version number to 1.9.28.1. - - * Version 1.9.28. - -1998-05-22 Jim Kingdon - - * rcs.c (RCS_cmp_file): Check for errors from CVS_FOPEN. This - restores the CVS 1.9 behavior (fatal error if we can't open the - file), and corrects an apparent oversight in Ian's 13 Apr 1997 - change. - * sanity.sh (modes2): New test, tests for this. - -1998-05-22 Ian Lance Taylor - - * server.c (server_updated): Correct test for whether to unlink - the file. - -1998-05-20 Jim Kingdon - - * wrapper.c (wrap_add): Disable -t/-f wrappers at least until the - serious bug can be fixed. - -1998-05-15 Jim Kingdon - - * checkout.c (checkout): Call server_pathname_check on the - argument to "cvs co -d". - * server.c (server_pathname_check): Add comment about how we could - be handling absolute pathnames. - * sanity.sh (abspath): Rewrite the tests which run "cvs co -d /foo" - for remote, to reflect this. - - * sanity.sh (abspath): Also do the "cannot rename" work-around for - abspath-7d. - -1998-05-13 Jim Kingdon - - * commit.c (commit_filesdoneproc): Free admin_dir when done with it. - -1998-05-13 Jim Meyering - - * sanity.sh (editor): Change bogus sed command, `s/^/x&/g', to `s/^/x/'. - The former exercised a bug in GNU sed-3.01-beta3. - (emptydir-8): Add `Rebuilding administrative file database' message, - since now it does that. - * commit.c (commit_filesdoneproc): Pass only the admin directory - pathname to mkmodules. - Remove #if 0, now that it's fixed. - - * status.c (cvsstatus): Rename from `status' to avoid shadowing - lots of locals and parameters by the same name. - * server.c (serve_status): Update caller. - * main.c (cmds[]): Update table entry. - * cvs.h: Update prototype. - - * commit.c (commit_filesdoneproc): Remove trailing blanks. - (commit) [CLIENT_SUPPORT]: Remove unnecessary (and local-shadowing) - declaration of `err'. - Rename global `tag' to `saved_tag' to avoid overshadowing `tag' - parameters of three functions. - Rename global `message' to `saved_message' to avoid overshadowing - `message' parameter of a function. - Rename global `ulist' to `saved_ulist' and move dcl up with others. - -1998-05-12 Jim Kingdon - - * commit.c (commit_filesdoneproc): #if 0 the new code until it can - be fixed. - - * commit.c (commit_filesdoneproc): Add comment explaining last - change. - -1998-05-12 Jim Meyering - - * commit.c (commit_filesdoneproc): Call mkmodules not just when - committing a file directly under CVSROOT, but also when committing - files in subdirectories of CVSROOT. - -1998-05-08 Jim Meyering - - * filesubr.c (xreadlink): NUL-terminate the symbolic link name. - Use a much smaller initial buffer length. - Test errno only if readlink fails. - Use xstrdup then free the original link name so we don't waste space. - -1998-05-02 Jim Meyering - - * rcs.c (rcsbuf_getword): Fix off-by-one error that would result in - an abort (the first one in rcsbuf_getkey) when operating on on some - ,v files with over 8192 bytes of tag and branch info. - -1998-05-04 Jim Kingdon - - * sanity.sh (ann): New tests ann-12 and ann-13 test for specifying - a numeric branch. - -1998-05-02 Jim Kingdon - - * rcs.c: Add comments about getting rid of rcsbuf_getid, - rcsbuf_getword, and rcsbuf_getstring. - - * sanity.sh (abspath): Revise the workarounds to deal with exit - status. - -1998-04-30 Jim Kingdon - - * sanity.sh (abspath): Work around the "cannot rename" bug. - -1998-04-27 Jim Kingdon - - * classify.c (Classify_File): Add comments about checking whether - command name is "update". - -1998-04-22 Jim Kingdon - - * version.c: Change version number to 1.9.27.1. - - * Version 1.9.27. - -1998-04-20 Jim Kingdon - - (This diff was run by devel-cvs and everyone seemed to like it). - * diff.c (diff_file_nodiff): Make HEAD mean the head of the branch - which contains the sticky tag, not the sticky tag itself. - * rcs.c, rcs.h (RCS_branch_head): New function. - * sanity.sh (head): Update for this changed behavior. - -1998-04-19 Jim Kingdon - - * sanity.sh: Move emptydir tests from basicb to new test emptydir. - This is because we now need a module definition to create Emptydir; - "co -d" doesn't cut it anymore. - -1998-04-17 Petri Virkkula - - * server.c (mkdir_p): Ignore EROFS error (like for EACCES). - -1998-04-16 Jim Kingdon - - * checkout.c (checkout_proc): Don't create directories above the - last one specified in "co -d". - (build_dirs_and_chdir): Revert Noel's change of 17 Feb 1998. - (struct dir_to_build): New field just_chdir. - (build_dirs_and_chdir): Test it. - * sanity.sh (abspath): New tests abspath-7* test for a bug which - we fix, in which CVS would create bogus "D/////" entries in - CVS/Entries. - (abspath): Revise abspath-3* tests to test for the fact that we no - longer create directories above the last one specified in "co -d". - I checked that CVS 1.9 gives an error on this, so changing this - behavior back should be OK. - (cvsadm-2d3): Likewise (also checked CVS 1.9 for this case). - (cvsadm-2d3d): Likewise (also checked CVS 1.9 for this case). - (cvsadm-2d{4,5,6,7,8}, cvsadm-N2d{3,4,5,6,7,8}): Adjust for new - behavior (same case as cvsadm-2d3). - (cvsadm-2d{4,5,6,7,8}d, cvsadm-N2d{3,4,5,6,7,8}d): Remove test - (same case as cvsadm-2d3d). - (cvsadm): For remote, skip most these tests. - (abspath): When cleaning up, delete mod1 and mod2 rather than mod1 - twice (longstanding bug, apparently only becomes visible if you - run the tests in a certain order). - -1998-04-14 Wilfredo Sanchez - - * rcs.c: variable "lockfile" was being referenced after being - free'd. Bad. Moved the free() call down. - -1998-04-12 Jim Kingdon - - * sanity.sh (rcs): Add test for annotate and the year 2000. - - * server.c (do_cvs_command): If there are partial lines left when - the child process is done, send them along. - * sanity.sh (rcs, rcs2): Enable all tests for remote; tests for - this fix. - -1998-04-11 Jim Kingdon - - * client.c (client_senddate): Pass SDATEFORM not DATEFORM to - sscanf. This fixes a Y2K bug. - - * history.c (history, select_hrec): Change since_date from time_t - to RCS format. Use the usual machinery (in particular, Make_Date - and client_senddate) so that it will work on VMS too. - * main.c, cvs.h (date_from_time_t): New function. - * sanity.sh (history): New test, to test that this didn't break - anything (also tests client_senddate fix). - -1998-04-11 Norbert Kiesel - - * server.c (cvs_output_binary): Shut up "gcc -Wall" by removing - unnecessary else if test. - * server.c (check_password): Fix uninitialized memory read if - shadow passwords are used. Also added some comments. - * rcs.c (RCS_checkout): Make sure to call chown with -1 for uid or - gid if they should not be changed - -1998-04-10 Jim Kingdon - - * sanity.sh (rcs2): New test, tests for various Y2K cases. - * rcs.c (getdelta): Value for "state" keyword is optional (bug - discovered incidentally in writing rcs2 test). - -1998-04-09 Jim Kingdon - - * filesubr.c, cvs.h (link_file): Remove; no longer used. - -1998-04-08 Jim Kingdon - - * recurse.c (do_dir_proc): Restore update_dir rather than a - computation which appears to, but does not necessarily, restore it - (reported by various people; this fix is from Greg Hudson). - * sanity.sh (importc): New test, tests for this fix. - -1998-03-27 Jim Kingdon - - * rcs.c (RCS_lock): If the revision is already locked, give an - error rather than dumping core. - * sanity.sh (reserved): New test reserved-13c tests for this. - -1998-03-25 Loren J. Rittle - - * import.c (add_rev): Rewrite to use RCS_FLAGS_KEEPFILE option - of RCS_checkin() to avoid damage to imported files instead of - externally undoing damage after the fact. The side effect is - that callers of add_rev() may now incrementally walk the - entries of the current directory without seeing gratuitous - changes to the directory structure (under at least one file - system under at least one OS). - -1998-03-18 Jim Kingdon - - * error.c (error): Save and restore errno. Should fix test case - conflicts3-23 on SCO 5.0.2. Reported by Steve Cameron. - - * sanity.sh (admin): Rename admin-26-o* to admin-26-*; the "o" - stands for "cvs admin -o". Add comment about length of tests. - Use ${PLUS}. - -1998-03-05 Dan Wilder - - * Fix problem with cvs admin in which -ntag:branch - option associated tag with the branch's head revision. - Should have used branch number. Entailed in this fix, - the following. - - * Add new functions "RCS_exist_rev", "RCS_exist_tag", - "RCS_tag2rev", and "RCS_valid_rev" to rcs.c. RCS_tag2rev - is similar to RCS_gettag, but does less interpretation. - - * Plug a small memory leak. - - * Add tests admin-26 through admin-29 to sanity.sh, - to test "cvs admin -n". - -1998-03-17 Samuel Tardieu - - * server.c (server_register): protect dereferencing timestamp in - the trace message when it is null, to avoid a segmentation fault. - -1998-03-16 Jim Kingdon - - * options.h.in (MY_NDBM): Rewrite the comment explaining this - option. It was not clear to everyone who "my" referred to, for - example. - - * hardlink.c (list_linked_files_on_disk): Remove unused variables - err and p. - (list_linked_files_on_disk): Add comment about memory allocation - of return value. - * rcs.c (rcsbuf_getword): Shut up gcc -Wall with a "return 0". - (RCS_checkin): Remove unused variable fullpath. - * sanity.sh (hardlinks): Remove comment about spurious warnings; - the warnings are gone. - -1998-03-12 Tim Pierce - - New functions for parsing and writing hardlink fields. - * rcs.c [PRESERVE_PERMISSIONS_SUPPORT] (puthardlink_proc): New - function. - (putdelta) [PRESERVE_PERMISSIONS_SUPPORT]: Use it. - (rcsbuf_getid, rcsbuf_getstring, rcsbuf_getword): New functions. - (getdelta): Call them, storing `hardlinks' field in vnode->hardlinks. - (RCS_reparsercsfile): When setting rdata->desc, xstrdup value - rather than rcsbuf_valcopying it (due to changes in how getdelta - handles keys and values in newphrases). - - * sanity.sh (hardlinks): Use uglier filenames. Checking out - hardlinked files no longer produces the same spurious diagnostics, - so fix that test. - (hardlinks-2.3): Renamed from hardlinks-2.2 (duplicate test name). - - New infrastructure for managing hardlink lists internally... - * hardlink.c, hardlink.h (list_linked_files_on_disk, - compare_linkage_lists, find_checkedout_proc): New functions. - * rcs.h (struct rcsversnode) [PRESERVE_PERMISSIONS_SUPPORT]: New - member `hardlinks'. - * update.c (special_file_mismatch): Get hardlinks from - vp->hardlinks instead of from vp->other_delta. - * rcs.c (free_rcsvers_contents): Comment about freeing hardlinks - member. - (RCS_checkout) [PRESERVE_PERMISSIONS_SUPPORT]: Get hardlinks from - vers->hardlinks list instead of vers->other_delta. - - ... and removed obsolete code from earlier revs. - * hardlink.c, hardlink.h (list_files_linked_to, - cache_hardlinks_proc, list_files_proc, set_hardlink_field_proc): - Removed. - * hardlink.h: Removed `links' member from hardlink_info struct. - * commit.c (commit): Remove the call to cache_hardlinks_proc. - (check_fileproc) [PRESERVE_PERMISSIONS_SUPPORT]: Removed reference - to hlinfo->links. - * hardlink.c (update_hardlink_info): Same. - * update.c (get_linkinfo_proc): Same. - - * rcs.c (RCS_checkout) [PRESERVE_PERMISSIONS_SUPPORT]: Use - vp->hardlinks and find_checkedout_proc to find recently-updated - files that may be hardlinked. - * update.c (special_file_mismatch): Use List * structures and - compare_linkage_lists for rev1_hardlinks and rev2_hardlinks. - -1998-03-16 Larry Jones - - * server.c (check_password): If shadow passwords are supported but no - entry is found in the shadow file, check the regular password file. - -1998-03-07 Jim Kingdon - - * sanity.sh: Rename permissions test to perms since that is what - each of its individual tests are named. - * sanity.sh (perms symlinks hardlinks): Change CVSROOT to - CVSROOT_DIRNAME where appropriate. - (perms symlinks hardlinks): Disable/adjust the meat of the tests for - remote. - (symlinks): Link to ${TESTDIR}/fumble rather than - /fumble/mumble/grumble. We shouldn't be making assumptions about - what might exist in random directories outside ${TESTDIR}. - * hardlink.c (cache_hardlinks_proc): Add comment about trimming - whitespace. - -1998-03-07 Tim Pierce - - * rcs.c (RCS_checkout): Negation bug when checking out symlinks: - existence_error should be !existence_error. - * sanity.sh (permissions symlinks hardlinks): New tests, for - PreservePermissions. - -1998-03-04 Jim Kingdon - - * version.c: Change version number to 1.9.26.1. - - * Version 1.9.26. - - * entries.c, cvs.h (Entries_Open): New argument update_dir; use it - in error message. - * add.c, checkout.c, client.c, find_names.c, import.c, recurse.c, - update.c: Pass it (as NULL except in call_in_directory). - * entries.c (Subdirs_Known): Just return if there is no CVSADM - directory (as in subdir_record). - * sanity.sh (conflicts3): New tests conflicts3-20a and - conflicts3-23 test for these fixes. - - * commit.c (commit): Only set up hardlist if preserve_perms. - - * commit.c, import.c, no_diff.c, parseinfo.c, rcs.c, rcscmds.c, - update.c: Omit the preserve_perms code if - PRESERVE_PERMISSIONS_SUPPORT is not defined. Much of that code - won't even compile on non-unix systems. - - * hardlink.c, hardlink.h: Use the 'standard' copyright (as found - in server.c). - * commit.c, rcs.c: Minor whitespace changes to Tim's submission. - * commit.c (check_fileproc), update.c (get_linkinfo_proc): Remove - unused variable delta. - * hardlink.c (set_hardlink_field_proc), update.c - (get_linkinfo_proc): Return a value rather than falling off the - end of the function. - -1998-03-02 Tim Pierce - - * update.c (special_file_mismatch): Compare the hard links of the - two revisions. - - * rcs.c (RCS_checkout): - - * hardlink.c, hardlink.h: New files. - (hardlink_info): New struct. - (hardlist, working_dir): New variables. - (list_files_proc, cache_hardlinks_proc, set_hardlink_field_proc, - lookup_file_by_inode, update_hardlink_info, list_files_linked_to): - New functions. - - * Makefile.in (SOURCES): Add hardlink.c. - (OBJECTS): Add hardlink.o. - (HEADERS): Add hardlink.h. - * commit.c: Include hardlink.h. - (commit): Save the working directory before recursing. Walk the - hardlink list, calling set_hardlink_field_proc on each node. - (check_fileproc): Add each file's link information to hardlist. - * rcs.c: Include hardlink.h. - (RCS_checkin): Save list of hardlinks in delta node. - (RCS_checkout): Look up the file's `hardlinks' delta field, and - see if any of the files linked to it have been checked out - already. Link to one of those files if so. - * update.c: Include hardlink.h. - (get_linkinfo_proc): New function. - (do_update): Extra recursion to collect hardlink info. - (special_file_mismatch): Reparse the RCS file if necessary. - - fsortcmp is now used by several files, so let's make it extern. - * hash.c, hash.h (fsortcmp): New function. - * find_names.c (fsortcmp): Removed. - * lock.c (fsortcmp): Removed. - -1998-03-03 Jim Kingdon - - * sanity.sh (conflicts3): New tests conflicts3-14a, - conflicts3-14b, and conflicts3-21, conflicts3-22 test that we can - skip over a working directory with a CVSADM directory missing. - -1998-02-26 Jim Kingdon - - * sanity.sh (conflicts3): Tests conflicts3-16 and conflicts3-20 - test that we include update_dir in messages. Rename test - conflicts3-14 to fix typo. - -Sun Feb 22 23:14:25 1998 Steve Cameron - and Ian Lance Taylor - - * update.c (tag_update_dir): New static variable. - (update_dirent_proc): If no tag or date were specified when - creating a subdirectory, use the tag and/or date of the parent - directory. - (update_dirleave_proc): If we set the tag and/or date in - update_dirent_proc, reset them when we leave the directory. - * sanity.sh (branches2): New set of tests for above patch, and - related behaviour. - -Sun Feb 22 13:31:51 1998 Ian Lance Taylor - - * commit.c (lock_RCS): Don't call RCS_rewrite. - - * update.c (patch_file): If the revision is dead, let - checkout_file handle it. - * sanity.sh (death2): Add test for above patch: add - death2-10a, death2-10b, death2-13a, and adjust - death2-{2,4,5,11,14,diff-11,diff-12,19}. - - * cvs.h (RCS_FLAGS_KEEPFILE): Define. - * rcs.c (RCS_checkin): If RCS_FLAGS_KEEPFILE is set in the flags - parameter, don't unlink the working file. - * checkin.c (Checkin): Don't copy the file. Instead pass - RCS_FLAGS_KEEPFILE to RCS_checkin, and only check the file out - again if it has changed. - -1998-02-21 Jim Kingdon - - * rcs.c (rcs_internal_unlockfile, RCS_rewrite): Don't assume errno - means anything just because ferror is set. - -Sat Feb 21 20:02:24 1998 Ian Lance Taylor - - * Makefile.in (clean): Change "/bin/rm" to "rm". - - * buffer.c (buf_append_buffer): Correct typo in comment. - * rcs.c (RCS_putadmin): Likewise. - -Fri Feb 20 17:53:06 1998 Ian Lance Taylor - - * rcs.c (rcs_internal_unlockfile): Pass errno when calling error - because ferror is true. - -1998-02-20 Jim Kingdon - - * sanity.sh (abspath): Don't assume that we can't write to /; this - is the kind of thing that is sure to break sooner or later - (especially on Windows). - - * sanity.sh: Add summary of which modules tests are which (at - "modules"). Move cvsadm, abspath, and toplevel next to modules. - Add comments to clarify the structure (such as it is). - -Fri Feb 20 12:47:14 1998 Larry Jones - - * admin.c (admin_fileproc): Better fix for -b. - - * rcs.c (RCS_whatbranch): Back out previous change. - (RCS_getversion): Ditto. - (RCS_setbranch): Treat an empty revision string like a null pointer. - -1998-02-18 Jim Kingdon - - * rcs.c (RCS_whatbranch): Fix indentation. - - * patch.c (patch_fileproc): Check for errors from fclose; check - for errors from fopen properly. - -Wed Feb 18 16:03:37 1998 Larry Jones - - * admin.c (admin_fileproc): Convert -b argument from symbolic name - to revision number before storing in the RCS file. - * rcs.c (RCS_whatbranch): Allow numeric as well as symbolic revision. - (RCS_getversion): Take advantage of above. - * sanity.sh (admin): Add/revise/renumber admin-10c, admin-11a, - admin-12, and admin-12a to check above. - - * commmit.c (lock_RCS): Minor clean-up. - - * sanity.sh (abspath-6a): Don't depend on the sepcific contents of - CVSROOT, it depends on which other tests have been run. - -Wed Feb 18 01:56:04 1998 Ian Lance Taylor - - * rcs.c (putsymbol_proc): Use putc and fputs rather than fprintf. - (RCS_putadmin): Don't call RCS_symbols if the symbols have not yet - been converted to a list. - - * rcs.c (rcsbuf_cache, rcsbuf_cache_open, rcsbuf_cache_close): New - static functions to avoid closing and reopening the RCS file. - (cached_rcs, cached_rcsbuf): New static variables. - (RCS_parse): Call rcsbuf_cache_close. Don't call fclose. - (RCS_parsercsfile): Likewise. - (RCS_parsercsfile_i): Call rcsbuf_cache rather than - rcsbuf_close. Call fclose on error. Remove comment about - inefficiency of opening file twice. - (RCS_reparsercsfile): Call rcsbuf_cache_open rather than fopen and - rcsbuf_open. Call rcsbuf_cache rather than rcsbuf_close and - fclose. - (RCS_fully_parse, RCS_checkout, RCS_deltas): Likewise. - (RCS_rewrite): Likewise. - (RCS_checkin): Call rcsbuf_cache_close. - - * rcs.c (RCS_copydeltas): Fix code which checks for an extra - newline in buffered data. - - * rcs.c (rcsbuf_getkey): Save an indirection by using start rather - than *valp when trimming trailing whitespace from value. - - * rcs.c (rcsbuf_get_buffered): New static function. - (RCS_copydeltas): After we have done all the required special - actions, and inserted any new revision, just copy the file bytes - directly, rather than interpreting all the data. - (count_delta_actions): New static function. - * sanity.sh (rcs): Add rcs-6a and rcs-6b to commit a new branch - revision, to force CVS to interpret all the data, rather than just - copying it. Adjust rcs-5 to add a branch tag. Adjust rcs-8a and - rcs-14 for the changes created by rcs-6b. - -Tue Feb 17 18:34:01 1998 Ian Lance Taylor - - * sanity.sh (cvsadm, diffmerge2): Remove directories at the end of - the test. - - * import.c (expand_at_signs): Rewrite to use memchr and fwrite - rather than putc. - - Rewrite RCS file reading routines for speed: - * rcs.c (struct rcsbuffer): Define. - (rcsbuf_open, rcsbuf_close, rcsbuf_getkey, rcsbuf_getrevnum, - rcsbuf_fill, rcsbuf_valcopy, rcsbuf_valpolish, - rcsbuf_valpolish_internal, rcsbuf_ftell): New static functions. - (getrcskey, getrcsrev, getrevnum): Remove. - (many functions): Change to use new rcsbuf functions instead of - old getrcskey/getrcsrev/getrevnum functions. - (RCS_reparsercsfile): Add rcsbufp parameter. Change all callers. - (RCS_deltas): Add rcsbuf parameter. Change all callers. - (getdelta): Change fp parameter to rcsbuf parameter. Change all - callers. - (RCS_getdeltatext): Add rcsbuf parameter. Change all callers. - (RCS_copydeltas): Add rcsbufin parameter. Change all callers. - * rcs.h (RCS_reparsercsfile): Update declaration. - * admin.c (admin_fileproc): Update calls to RCS_reparsercsfile for - new parameters. - -1998-02-17 Jim Kingdon - - * sanity.sh (toplevel): Also clean up second-dir (not a new - bug, but triggered by running tests as "toplevel abspath"). - - * create_adm.c (Create_Admin): Just print update_dir to tell the - user where we are; not the whole xgetwd. Cleaner than - Noel's change (which also had problems in errno handling). - * sanity.sh (toplevel-12): Update accordingly. - -Tue Feb 17 02:32:21 1998 Noel Cragg - - [These mods make "checkout" work with "-d /absolute/pathname" - once again.] - - * checkout.c (checkout_proc): the -d flag on the command line - should override the -d flag in the modules file if the latter is - an absolute path. The loop that assembles the list of directories - to build has been reorganized slightly to prepare for rewriting - with last_component rather than assuming '/' as a path separator. - Also added to that loop was some code to handle absolute - pathnames. - (build_dirs_and_chdir): add a new argument that tells this routine - whether or not to check before it creates and populates - directories or not. - - * filesubr.c (last_component): return the top-level directory when - asked about the top-level directory. - - * sanity.sh (toplevel-12): change test to reflect the new style of - this error message. - - * create_adm.c (Create_Admin): include the directory in the error - message. - -1998-02-16 Jim Kingdon - - * diff.c (diff_fileproc), import.c (import, add_rcs_file), rcs.c - (RCS_cmp_file): Don't ignore errors from CVS_UNLINK and fclose. - - * patch.c (patch_fileproc): Check for errors from fclose; if we - get -1 from getline check for end of file vs. error. - - * rcs.c (RCS_checkout): Comment return value (0/1, not -1). - * commit.c, diff.c, mkmodules.c, patch.c, rcs.c, update.c: Update - to match this convention. Don't suppress errors based on - quiet or really_quiet variables. - - Fix a longstanding bug which also makes stamps-8kw in make - remotecheck work again (it stopped working with Ian's 8 Feb 98 - checkin): - * client.c, client.h (change_mode): If new argument respect_umask - is set, then honor the umask. - * client.c, server.c: Update callers. - - Cleanups to Tim's checkin: - * rcs.c (RCS_checkout): Use existence_error not ENOENT. - * commit.c (checkaddfile): Remove comment about whether we want to - check for errors from fclose; there is no reason not to. - * rcs.c (RCS_checkout), update.c (special_file_mismatch): sscanf - on %ld requires an unsigned long, not a dev_t. - * update.c (special_file_mismatch): Remove unused variable - check_devnums. - * mkmodules.c (config_contents): Between two settings, use a blank - line not a "#" line. - -1998-02-15 Tim Pierce - - [This is the code as submitted. I'll be checking in my cleanups - shortly. This work sponsored by Abbott Labs. -kingdon] - - Support for device special files, symbolic links, user and group - ownerships, and file permissions. - - * parseinfo.c: (parse_config): Handle new config variable - `PreservePermissions'. - * mkmodules.c (config_contents): Add new PreservePermissions var. - - * rcs.c, rcs.h (preserve_perms): New variable. - (RCS_checkout, RCS_checkin): Support for newphrases `owner', - `group', `permissions', `special', `symlink'. - (RCS_checkout): If `workfile' and `sout' are symlinks, remove them - before attempting to open them for writing. - * import.c (add_rcs_file): Support for newphrases. Do not attempt - to read data from special files or symlinks. Error message - `cannot fstat' is now `cannot lstat'. - - New metrics for deciding when two files are different: - - * update.c, cvs.h (special_file_mismatch): New function. - (merge_file, join_file): Call it. - * no_diff.c (No_Difference): Call it. - - * filesubr.c (xcmp): Consider files to be different if they are of - different types; if they are symlinks which link to different - pathnames; or if they are devices with different device numbers. - Error message is now `cannot lstat'. - * rcs.c (RCS_cmp_file): Use `xcmp' to compare files, simplifying - the special handling for nonregular files. - - * rcscmds.c (diff_exec, diff_execv): If asked to obtain diffs for - special files, report no differences. - - Miscellaneous changes to make special file support possible: - - * commit.c (fix_rcs_modes): Don't attempt to `fix' permissions on - a symlink. - - * import.c (add_rcs_file): Don't try to close fpuser if it was - never opened (e.g. when operating on a symlink). - - * filesubr.c, cvs.h (isdevice, xreadlink): New functions. - * filesubr.c (copy_file): Handle special files and symlinks. - (xchmod): Do nothing if `preserve_perms' is set. - - * commit.c (checkaddfile): Replace `copy_file (DEVNULL, ...)' with - fopen/fclose calls. Copy_file no longer attempts to read data - from device files. - - * filesubr.c (islink): Use CVS_LSTAT, not lstat. - * vers_ts.c (time_stamp, time_stamp_server): Use CVS_LSTAT, not stat, - to get symlinks right. - * subr.c (get_file): Same. Don't attempt to read from special - files or symlinks. - - * classify.c (Classify_File): Doc fix. - -Fri Feb 13 17:07:32 1998 Eric Mumpower - and Ian Lance Taylor - - Fix some file system ordering problems found on Irix 6.4: - * sanity.sh (basic2): Use dotest_sort for test 56. - (importb): Use dotest_sort for tests importb-1 and importb-2. - (head): Use dotest_sort for test head-1. - -Thu Feb 12 15:15:33 1998 Jim Kingdon - - * import.c (add_rcs_file): If add_logfp is NULL, don't call fperror. - -11 Feb 1998 Andy Piper - - * server.c (cvs_output_binary): Use OPEN_BINARY not _O_BINARY. - -Mon Feb 9 18:34:39 1998 Jim Kingdon - - Tweaks to Ian's checkin: - * update.c (merge_file): Remove comment about sending file to - client before the message. It doesn't apply to this code any more - (it does apply to checkout_file, but I'm not sure it is important - to have such a comment anyway). - * buffer.c (buf_default_memory_error, buf_length): Reindent. - * server.h: Declare struct buffer before use. - -Mon Feb 9 21:05:28 1998 Ian Lance Taylor - - * rcs.c (RCS_fully_parse): Call getrevnum rather than getrcsrev. - Don't bother with ungetc. - - * rcs.c (getrcsrev): Rewrite to simply call getrevnum. - -Sun Feb 8 15:49:39 1998 Ian Lance Taylor - - Don't have the server check out a revision into a file and then - immediately read the file; just read into a buffer instead. - * update.c: Include buffer.h. - (update_fileproc): Let checkout_file call server_updated. - (checkout_file): Add merging and update_server parameters. Change - all callers. If server_active, don't mess with backup files. If - server_active, copy the revision into a buffer rather than a file - when possible. If update_server, call server_updated. Fix - handling of error status. - (checkout_to_buffer): New static function used by checkout_file. - (merge_file): Let checkout_file call server_updated. - (join_file): Likewise. - * server.c (server_updated): Change file_info parameter to mode - parameter. Add filebuf parameter. Change all callers. If - filebuf is not NULL, don't read the file. - * server.h (server_updated): Update declaration. - * buffer.c (buf_free): New function. - (buf_append_buffer): New function. - (buf_length): New function. - * buffer.h (buf_free, buf_append_buffer, buf_length): Declare. - - * buffer.c: (buf_initialize): If the memory parameter is NULL, use - buf_default_memory_error. - (buf_default_memory_error): New static function. - * buffer.h (BUFMEMERRPROC): Define typedef. - * client.c (buf_memory_error): Remove. - (start_server): Pass NULL rather than buf_memory_error as buffer - memory error function. - -Sat Feb 7 16:27:30 1998 Ian Lance Taylor - - * rcs.c (RCS_parsercsfile_i): Read the expand keyword from the RCS - file. We do this because Version_TS calls RCS_getexpand in many - common cases, and we don't want to reopen the file just for that. - (RCS_reparsercsfile): Skip the expand keyword. - (RCS_getexpand): Don't call RCS_reparsercsfile. - - * rcs.c (STREQ): New macro. In all string equality tests in the - file, replace strcmp with STREQ. - -Fri Feb 6 16:14:49 1998 Ian Lance Taylor - - * update.c (checkout_file): If we've already removed the backup - file once, don't try to remove it again. - - * filesubr.c (unlink_file_dir): Call stat rather than isdir, and - don't call unlink if the file does not exist. - - * myndbm.c (mydbm_load_file): Rename line_len to line_size. Call - getstr rather than getline, to avoid any confusion between \n and - \012. Use the line length returned by getstr rather than calling - strlen. Remove local variable len. - -Fri Feb 6 13:23:46 1998 Jim Kingdon - - * rcs.c (RCS_parsercsfile_i): Don't suppress errors on - really_quiet. - (RCS_parsercsfile_i, RCS_reparsercsfile, RCS_fully_parse, - RCS_deltas, getdelta, getrcskey, RCS_getdeltatext): - Check for errors. Include errno in error messages. Include - filename in error messages. Pass new argument to getrcskey. - (getrcskey): New argument NAME, so we can report errors ourself. - -Fri Feb 6 12:10:18 1998 Ian Lance Taylor - - * rcs.c (RCS_reparsercsfile): Don't use ftell/fseek; just keep - track of whether we've already read a key/value pair. Use sizeof - rather than strlen for a constant string. Pass the current key - and value to getdelta, and get them back as well. - (getdelta): Add keyp and valp parameters. Don't use ftell/fseek; - just return the key/value pair to the caller. Don't allocate - vnode before we know we need it. Check one getrcskey return - value. Use sizeof rather than strlen for a constant string. - - * rcs.c (getrcskey): Correct comment describing return value. - -Thu Feb 5 22:51:13 1998 Ian Lance Taylor - - * subr.c (getcaller): Cache the result, so that we don't keep - searching the password file. - -Wed Feb 4 23:31:08 1998 Jim Kingdon - - * rcs.c (max_rev): Don't prototype. Interesting that noone - complained about this until now. - -4 Feb 1998 Jim Kingdon - - * rcs.c (RCS_checkin): When adding a new file, read it - with "rb" if binary. - -Fri Jan 30 11:32:41 1998 Jim Kingdon - - * sanity.sh: Also test "first-dir" as the regexp in loginfo in - addition to ALL. - - * main.c (main): Update year in copyright notice to 1998. - -Thu Jan 29 00:01:05 1998 Jim Kingdon - - * version.c: Change version number to 1.9.25. - - * Version 1.9.24. - - * sanity.sh (multibranch2): File file2 and tests multibranch2-13 - through multibranch2-15 test a slightly different case than the - rest of multibranch2. - - * mkmodules.c (cvswrappers_contents): Rewrite. The text didn't - describe -k and had various other problems. - -28 Jan 1998 Karl Fogel and Jim Kingdon - - New feature to let server tell client about wrappers. - * client.h (struct response): Add comment about args being - '\0' terminated when passed to handle_* functions. - * client.c (start_server): send "wrapper-sendme-rcsOptions" to - server iff supported. - (responses): new response "Wrapper-rcsOption"; allows the server - to send certain lines from its cvswrappers file. - (handle_wrapper_rcs_option): new func, handles "Wrapper-rcsOption" - response from server. - * server.c (serve_wrapper_sendme_rcs_options): new func, sends - server side CVSROOT/cvswrappers rcs option lines to client. - (requests): new request "wrapper-sendme-rcsOptions"; if received, - we know we can send "Wrapper-rcsOption..." to the client. - * wrapper.c (wrap_unparse_rcs_options): new func; repeated calls - step down the wrapper list returning rcs option entries, but - repackaged as cvswrappers lines. - (wrap_setup): new guard variable `wrap_setup_already_done'; if - this function has run already, just return having done nothing. - Add comment concerning environment variable. - * cvs.h: declare wrap_unparse_rcs_options(). - -Tue Jan 27 18:27:19 1998 Ian Lance Taylor - - * rtag.c (rtag_dirproc): Call ignore_directory, and skip the - directory if it returns true. - * sanity.sh (modules4): New set of tests to test some aspects of - excluding directories in the modules file, including the above - patch. - -Thu Jan 22 10:05:55 1998 Jim Kingdon - - * server.c (serve_kopt): Check for length of arg. Based on - inspection of the code, plugs a buffer overrun security hole which - was introduced Monday. - - * server.c (serve_is_modified): Don't call xmalloc; we aren't - allowed to call error() here. Remove duplicate (and potentially - confusing) variable 'p'. - - * log.c (log_fileproc): Look for first character of version - '0' AND second character '\0', rather than OR. I didn't try to - come up with a test case but this looks like a simple thinko - (albeit one which would show up in obscure cases if at all). - -Tue Jan 20 19:37:53 1998 Jim Kingdon - - * client.c (send_dirent_proc): Don't send nonexistent directories - unless noexec. - * sanity.sh (modules2): New tests modules2-13 through modules2-18 - test for this fix. - -Mon Jan 19 11:17:51 1998 Jim Kingdon - - * server.c (serve_kopt): New function. - (requests): Add "Kopt" request. - (kopt): New variable. - (serve_is_modified): Write kopts from there into entries. - (serve_modified): Call serve_is_modified so we do the same. - Declare serve_modified and serve_is_modified. - * vers_ts.c (Version_TS): Set ->options even for a dummy ("D" - timestamp) entry. - * import.c (process_import_file): Check for -k options. - * client.c (client_process_import_file): Send Kopt request. - (send_fileproc): Likewise, for "cvs add". - * sanity.sh: Enable test binwrap3-sub2-add1 for remote. - Add -I .cvswrappers to binwrap3-2a; adjust binwrap3-2d - accordingly. Tests for this fix. - -Mon Jan 19 08:48:59 1998 Larry Jones - - * sanity.sh (errmsg1): Append test 168 output to log file. - -Sat Jan 17 08:01:51 1998 Jim Kingdon - - * sanity.sh (ann-10, ann-11): Don't make assumptions about the - number of characters in the username. - -Fri Jan 16 15:34:02 1998 Larry Jones - - * diff.c (diff_fileproc): Free label1 and label2 when finished. - - * edit.c (editor_set): Don't free edlist until after we're - done using it. - - * rcscmds.c (RCS_merge): Free xrev1 and xrev2 when finished. - - * subr.c (make_message_rcslegal): Don't access uninitialized or - unallocated memory; only strip trailing blank lines. - * sanity.sh (log-3): Enhance to test this fix. - -Fri Jan 16 12:41:03 1998 Jim Kingdon - - * sanity.sh: Add keywordlog to list of tests run by default. - - * rcs.c (RCS_deltas): Don't call cvs_output if length is zero; - passing zero length to cvs_output does not mean output zero - bytes. The 27 Dec 1997 change to no longer '\0'-terminate the - ->text field turned this from a time bomb to a user-visible bug. - * sanity.sh (ann): New tests, test for this fix and other annotate - behaviors. - -Thu Jan 15 23:52:00 1998 Jim Kingdon - - * root.c (root_allow_ok): If inetd.conf didn't specify an - --allow-root options at all, we know we are in trouble. Give a - specific error message. - -Thu Jan 15 21:24:59 1998 Ian Lance Taylor - - * sanity.sh (dotest_sort): New variant of dotest which sorts the - output, for use when the output depends upon details of the file - system, typically when doing an import. - (rdiff): Use dotest_sort for rdiff-1. - (ignore): Use dotest_sort for 188a, 188b, 189d, 190, and 191. - - * sanity.sh: (TESTSHELL): New variable. - (editor, info, reserved): Use TESTSHELL in temporary script. - - * sanity.sh (ignore): Do all tests in subdirectory, to avoid - conflict between cvsroot and CVSROOT on Windows. - (binwrap3, mwrap, info, config): Likewise. - - * sanity.sh (binfiles2): Correct test name binfile2-7-brmod to - binfiles2-7-brmod. - - * release.c (release_delete): If __CYGWIN32__ is defined, don't - worry about mismatched inodes. This is a hack, but then I think - the test is rather peculiar anyhow. - -Thu Jan 15 16:07:36 1998 Larry Jones - - * sanity.sh (reserved-9): Use ${PROG} instead of "cvs". - -Wed Jan 14 15:43:13 1998 Jim Kingdon - - * Split ChangeLog into ChangeLog-97 and ChangeLog. - * Makefile.in (DISTFILES): Add ChangeLog-97. - -13 Jan 1998 Jim Kingdon - - * client.c: Declare handle_mt. - -Tue Jan 13 22:21:30 1998 Jim Kingdon - - * sanity.sh: Add comment about how pwd and /bin/pwd often differ - in behavior (but are not guaranteed to). - -Tue Jan 13 13:49:53 1998 Ian Lance Taylor - - * sanity.sh: When setting TMPPWD use just pwd, not /bin/pwd. - - * update.c (checkout_file): Don't pass set_time as true to - Version_TS if the file is dead. - * sanity.sh (modules): Add tests modules-155c6 through - modules-155c8 to test for above patch (without the above patch, - modules-155c8 will fail when remote). - -Tue Jan 13 10:37:02 1998 Larry Jones - - * client.c (send_modified): Change bufsize and newsize from int - to size_t to avoid type clashes in call to read_and_gzip. - -Tue Jan 13 10:33:02 1998 Larry Jones - - * zlib.c (read_and_gzip): Set finish to 0; it was uninitialized. - -Tue Jan 13 10:26:43 1998 Larry Jones - - * add.c, rcs.c: Plug memory leaks. - -Mon Jan 12 10:45:27 1998 Larry Jones - - * server.c (mkdir_p): Don't try to create nameless directories - (i.e., given "/foo//bar", don't try to create "/foo/", - just "/foo" and "/foo//bar") since it isn't necessary and - it fails on some systems in unexpected ways. - -1998-01-11 enami tsugutomo - - * rcs.c (linevector_copy): Delete lines before overwriting them. - -Sat Jan 10 11:05:40 1998 Jim Kingdon - - * cvsrc.c, entries.c, login.c, logmsg.c, myndbm.c, patch.c, - release.c, server.c: Check for errors from getline, CVS_FOPEN, - fprintf, CVS_UNLINK and fclose. Note that the new errors are - nonfatal. This is because of conservatism more than because - it is always the best thing. - * login.c (get_cvs_password): Close the file when done with it. - * client.c (notified_a_file): If -1 return from getline, check - feof rather than assuming errno is set. - -Fri Jan 9 14:38:54 1998 Jim Kingdon - - * server.c (expand_proc): Also output server_dir in - "Module-expansion", not just in output_dir ("Created", &c). - * sanity.sh (modules2): New tests modules2-9 through modules2-12 - test for this. - -Thu Jan 8 12:56:55 1998 Yasutoshi Hiroe - - * import.c (import): Don't strcat on uninitialized memory. Fixes - possible SIGSEGV with zero-length message. - -Tue Jan 6 22:56:29 1998 Jim Kingdon - - * sanity.sh (crerepos): Fix mistaken variable name which caused us - not to clean up at the end of the test. - -Mon Dec 22 01:40:57 1997 Jim Kingdon - - * add.c (add): Also look for .cvswrappers files. - * sanity.sh (binwrap3): New tests binwrap3-2*, binwrap3-sub2-add* - test for this. - -Tue Jan 6 11:50:38 1998 Jim Kingdon - - * sanity.sh (crerepos): New tests crerepos-8 through crerepos-18 - test behaviors when mixing repositories. - -Sun Jan 4 17:40:22 1998 Jim Kingdon - - * version.c: Change version number to 1.9.23. - - * Version 1.9.22. - - -For older changes see ChangeLog-97. diff --git a/contrib/cvs/src/ChangeLog-9194 b/contrib/cvs/src/ChangeLog-9194 deleted file mode 100644 index eb79efc..0000000 --- a/contrib/cvs/src/ChangeLog-9194 +++ /dev/null @@ -1,524 +0,0 @@ -Thu Sep 15 08:20:23 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * subr.c (run_setup, run_args): Check USE_PROTOTYPES if defined - instead of __STDC__, just like cvs.h does. - -Thu Sep 15 00:14:58 1994 david d `zoo' zuhn - - * main.c: rename nocvsrc to use_cvsrc, don`t read ~/.cvsrc when -H - has been seen - -Wed Sep 14 21:55:17 1994 david d `zoo' zuhn - - * cvs.h, subr.c: use size_t for xmalloc, xrealloc, and xstrdup - parameters - - * cvsrc.c: optimize away two calls of getenv - - * commit.c, subr.c: use mode_t for file mode values (Thanks to jtc@cygnus.com) - - * main.c: update copyrights in -v message - -Tue Sep 6 10:29:13 1994 J.T. Conklin (jtc@rtl.cygnus.com) - - * hash.c (hashp): Replace hash function with one from p436 of the - Dragon book (via libg++'s hash.cc) which has *much* better - behavior. - -Wed Aug 17 09:37:44 1994 J.T. Conklin (jtc@cygnus.com) - - * find_names.c (find_dirs): Use 4.4BSD filesystem feature (it - contains the file type in the dirent structure) to avoid - stat'ing each file. - -Tue Aug 16 11:15:12 1994 J.T. Conklin (jtc@cygnus.com) - - * rcs.h (struct rcsnode): add symbols_data field. - * rcs.c (RCS_parsercsfile_i): store value of rcs symbols in - symbols_data instead of parsing it. - (RCS_symbols): New function used for lazy symbols parsing. - Build a list out of symbols_data and store it in symbols if it - hasn't been done already, and return the list of symbols. - (RCS_gettag, RCS_magicrev, RCS_nodeisbranch, RCS_whatbranch): - Use RCS_symbols. - * status.c: (status_fileproc): Use RCS_symbols. - -Thu Jul 14 13:02:51 1994 david d `zoo' zuhn (zoo@monad.armadillo.com) - - * src/diff.c (diff_fileproc): add support for "cvs diff -N" which - allows for adding or removing files via patches. (from - K. Richard Pixley ) - -Wed Jul 13 10:52:56 1994 J.T. Conklin (jtc@phishhead.cygnus.com) - - * cvs.h: Add macro CVSRFLPAT, a string containing a shell wildcard - expression that matches read lock files. - * lock.c (readers_exist): Reorganized to use CVSRFLPAT and to not - compute the full pathname unless the file matches. - - * rcs.h: Add macro RCSPAT, a string containing a shell wildcard - expression that matches RCS files. - * find_names.c (find_rcs, find_dirs): Use RCSPAT. - -Fri Jul 8 07:02:08 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * entries.c (Register): Pass two arguments to write_ent_proc, in - accordance with its declaration. - -Thu Jun 30 09:08:57 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * logmsg.c (do_editor): Fix typo ("c)continue" -> "c)ontinue"). - -Thu Jun 23 18:28:12 1994 J.T. Conklin (jtc@phishhead.cygnus.com) - - * find_names.c (find_rcs, find_dirs): use fnmatch instead of - re_comp/re_exec for wildcard matching. - * lock.c (readers_exist): Likewise. - -Fri May 20 08:13:10 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * modules.c (do_module): If something is aliased to itself, print - an error message rather than recursing. - -Fri May 6 19:25:28 1994 david d zuhn (zoo@monad.armadillo.com) - - * cvsrc.c (read_cvsrc): use open_file for error checking - -Sat Feb 26 10:59:37 1994 david d zuhn (zoo@monad.armadillo.com) - - * import.c: use $TMPDIR if available, instead of relying on /tmp - -Mon Jan 24 19:10:03 1994 david d zuhn (zoo@monad.armadillo.com) - - * update.c (joining): compare join_rev1 with NULL instead of - casting pointer to an int - - * options.h: remove S_IWRITE, S_IWGRP, S_IWOTH macros - - * logmsg.c: #if 0 around gethostbyname prototype - - * hash.c (printnode), find_names.c (add_entries_proc), - entries.c (write_ent_proc): correct declaration for function - (added void *closure) - - * cvs.h: header include order reorganization: First include the - program config headers (config.h, options.h). Then include any - system headers (stdio.h, unistd.h). Last, get the program - headers and any cvs supplied library support - - * commit.c: use xstrdup instead of strdup - - * cvs.h: redefined USE(var) macro; comment after an #endif - - * all .c files: remove the semicolon from after the USE(var) - -Sat Dec 18 00:17:27 1993 david d zuhn (zoo@monad.armadillo.com) - - * cvs.h: include errno.h if available, otherwise declare errno if - it's not somehow else defined - - * commit.c (checkaddfile): remove unused file argument from - RCS_nodeisbranch call - - * rcs.c (RCS_nodeisbranch): remove file from arguments (was unused) - - * rcs.h (RCS_nodeisbranch): remove file from prototype - - * main.c: don't use rcsid when printing version number (the CVS - version number is independent of the repository that it comes - from) - - * hash.c (printlist, printnode): use %p to print pointers, not %x - (avoids gcc format warnings) - - * cvs.h: define USE if GCC 2, to avoid unused variable warning - - * all .c files: use USE(rcsid) - - * Makefile.in (VPATH): don't use $(srcdir), but @srcdir@ instead - (COMMON_OBJECTS): define, and use in several places - (OBJECTS): reorder alphabetically - - * hash.c (nodetypestring): handle default return value better - - * modules.c (do_module): remove extra argument to ign_dir_add - - * main.c (main): initialize cvs_update_env to 0 (zero) - - * modules.c (do_module): return error code when ignoring directory - (instead of a bare return). error code should be zero here - - * cvs.h: add prototypes for ignore_directory, ign_dir_add - - * ignore.c: add comments about ignore_directory - - * root.c (Name_Root): remove unused variables has_cvsadm and path - - * checkin.c (Checkin): only use -m when message is non-NULL - - * cvsrc.c (read_cvsrc): make sure homeinit is never used while - uninitialized (could have happened if getenv("HOME") had failed) - - * cvs.h: include unistd.h if available - -Fri Dec 17 23:54:58 1993 david d zuhn (zoo@monad.armadillo.com) - - * all files: now use strchr, strrchr, and memset instead of index, - rindex, and bzero respectively - -Sat Dec 11 09:50:03 1993 david d zuhn (zoo@monad.armadillo.com) - - * version.c (version_string): bump to +104z - - * Makefile.in: set standard directory variables, CC, and other - variables needed to be able to do 'make all' in this directory - - * import.c: implement -k options, for setting the RCS - keyword expansion mode - - * all files: use PROTO() macro for ANSI function prototypes - instead of #ifdef __STDC__/#else/#endif around two sets of - declarations - -Thu Nov 18 19:02:51 1993 K. Richard Pixley (rich@sendai.cygnus.com) - - * add.c (add), import.c (import), commit.c (commit): change - xmalloc & strcpy to xstrdup. - - * commit.c (remove_file): correct another static buffer problem. - -Wed Nov 10 15:01:34 1993 K. Richard Pixley (rich@sendai.cygnus.com) - - * recurse.c (start_recursion): directories in repository but not - in working directory should be added to dirlist. Fixes "update - -d dir" case. - - * version.c (version_string): bump to +103r. - - * commit.c (checkaddfile): mkdir attic only if it does not already - exist. comment changes. changed diagnostic about adding on a - branch. if a file is added on a branch, remove and replace the - internal representation of that rcs file. - -Tue Nov 9 18:02:01 1993 K. Richard Pixley (rich@sendai.cygnus.com) - - * add.c (add): if a file is being added on a branch, then say so; - add quotes around file names in error messages. - -Thu Nov 4 16:58:33 1993 K. Richard Pixley (rich@sendai.cygnus.com) - - * version.c (version_string): bump to +102r. - - * recurse.c (unroll_files_proc, addfile): new files, forward - decls, and prototypes. - (recursion_frame): new struct. - (start_recursion): rewrite to handle the case of "file1 file2 - dir1/file3". - - * rcs.c (RCS_parsercsfile): trap and error out on the case where - getrcskey tells us it hit an error while reading the file. - - * commit.c (lock_filesdoneproc): add comment about untrapped error - condition. - - * hash.c (addnode): comment change. - - * subr.c: add comment about caching. - - * sanity.sh: updated copyright. - -Wed Nov 3 14:49:15 1993 K. Richard Pixley (rich@sendai.cygnus.com) - - * version.c (version_string): bump to +101r. - - * hash.c (walklist): add a closure for called routines. All - callers, callees, and prototypes changed. - - * hash.c (nodetypestring, printnode, printlist): new functions for - dumping lists & nodes. - - * tag.c (tag_fileproc): fatal out on failure to set tag. - -Tue Nov 2 14:26:38 1993 K. Richard Pixley (rich@sendai.cygnus.com) - - * version.c (version_string): bump version to +99. - -Mon Nov 1 15:54:51 1993 K. Richard Pixley (rich@sendai.cygnus.com) - - Change buffer allocation for check in messages from static to - dynamic. - * add.c (add): dynamically allocate message. - (build_entry): check (message != NULL) now that message is a - pointer. - * commit.c (got_message, commit, commit_fileproc, - commit_filesdoneproc, commit_direntproc): removed. Replaced by - (message != NULL). Dynamically allocate message. - * cvs.h: adjust do_editor prototype and forward decl. - (MAXMESGLEN): removed. - * import.c (import): dynamically allocate message. - * logmsg.c (do_editor): change return type to char *. Remove - message parameter. Slight optimization to algorythm for - removing CVSEDITPREFIX lines. Add comment about fgets lossage. - - * subr.c (xmalloc): change error message to print number of bytes - we were attempting to allocate. - -Fri Oct 29 14:22:02 1993 K. Richard Pixley (rich@sendai.cygnus.com) - - * add.c (add): prevent adding a directory if there exists a dead - file of the same name. - - * sanity.sh: update argument to diff from "+ignore-file" to - "--exclude=". - - * Makefile.in (TAGS): extend to work from an objdir. - -Mon Oct 18 18:45:45 1993 david d `zoo' zuhn (zoo@rtl.cygnus.com) - - * tag.c, rtag.c: change the default actions to make writing over - existing tags harder (but not impossible) - -Thu Oct 14 18:00:53 1993 david d `zoo' zuhn (zoo@rtl.cygnus.com) - - CVS/Root changes from Mark Baushke (mdb@cisco.com) - - * Makefile.in: added new file called root.c - - * create_adm.c: will create CVS/Root at the same time that the - other CVS files are being created - - * cvs.h: new CVSADM_ROOT define plus new function externs - - * main.c: default to using CVS/Root contents for CVSROOT - if neither the environment variable or the command line - "-d" switch is given. If either are given, perform a - sanity check that this directory belongs to that repository. - - * update.c: if CVS/Root does not exist, then create it - during an update -- this may be removed if CVS/Root becomes a - standard feature - - * root.c: implement new functions to manipulate CVS/Root - [this may be integrated with other utility functions in - a future revision if CVS/Root becomes a standard feature.] - -Wed Sep 29 17:01:40 1993 david d `zoo' zuhn (zoo@rtl.cygnus.com) - - * patch.c (patch_fileproc): output an Index: line for each file - -Mon Sep 6 18:40:22 1993 david d `zoo' zuhn (zoo@rtl.cygnus.com) - - * cvs.h: wrap definition of PATH_MAX in #ifndef PATH_MAX/#endif - -Tue Aug 9 21:52:10 1994 Mark Eichin (eichin@cygnus.com) - - * commit.c (remove_file): actually allocate space for the - filename, not just the directory. - -Tue Jul 6 19:05:37 1993 david d `zoo' zuhn (zoo@cygnus.com) - - * diff.c: patches to print an Index: line - -Mon Jun 14 12:19:35 1993 david d `zoo' zuhn (zoo at rtl.cygnus.com) - - * Makefile.in: update install target - -Tue Jun 1 17:03:05 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com) - - * Makefile.in: link cvs against libiberty - -Wed May 19 14:10:34 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com) - - * ignore.c: add code for keeping lists of directories to ignore. - - * modules.c: new syntax for modules file, !dirname is added to - the list of directories to ignore - - * update.c: don't process directories on the ignore list - -Tue Apr 6 14:22:48 1993 Ian Lance Taylor (ian@cygnus.com) - - * cvs.h: Removed gethostname prototype, since it is unnecessary - and does not match prototype in on HP/UX. - -Mon Mar 22 23:25:16 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com) - - * Makefile.in: rename installtest to installcheck - -Mon Feb 1 12:53:34 1993 K. Richard Pixley (rich@rtl.cygnus.com) - - * Makefile.in (check, installtest): set RCSBIN so that we - explicitly test the appropriate version of rcs as well. - -Fri Jan 29 13:37:35 1993 K. Richard Pixley (rich@rtl.cygnus.com) - - * version.c: bump version to +2. - -Thu Jan 28 18:11:34 1993 K. Richard Pixley (rich@rtl.cygnus.com) - - * import.c (update_rcs_file): if a file was dead, be sure to check - in the new version. - - * update.c (checkout_file): if file_is_dead and we *did* have an - entry, scratch it. - -Tue Jan 26 16:16:48 1993 K. Richard Pixley (rich@rtl.cygnus.com) - - * sanity.sh: parcel into pieces for easier truncation when - debugging. - - * update.c (checkout_file): print the "no longer pertinent" - message only if there was a user file. - -Wed Jan 20 17:08:09 1993 K. Richard Pixley (rich@rtl.cygnus.com) - - * update.c (checkout_file): remove unused variable s. - (join_file): remove unused variables rev & baserev. Fix a typo. - - * commit.c (commit_fileproc): remove unused variable magicbranch. - - * sanity.sh: bring back test 45 even though it fails. Update - tests against imported files. - - * add.c (add_directory): move declaration of unused variable. - - * Makefile.in (xxx): when building in this directory, pass CC for - the recursion. - -Mon Jan 18 13:48:33 1993 K. Richard Pixley (rich@cygnus.com) - - * commit.c (remove_file): fix for files removed in trunk - immediately after import. - - * commit.c (remove_file): initialize some variables. Otherwise we - end up free'ing some rather inconvenient things. - -Wed Jan 13 15:55:36 1993 K. Richard Pixley (rich@rtl.cygnus.com) - - * Makefile.in (check, install, installtest): use the sanity test. - - * sanity.el: make into real functions and bind to sun keys. - - * sanity.sh: bring back to working order. Add test for death - after import. - -Tue Dec 22 17:45:19 1992 K. Richard Pixley (rich@cygnus.com) - - * commit.c (remove_file): when checking in a dead revision to a - branch as we are creating the branch, do not lock the underlying - revision. Also free some malloc'd memory. - -Wed Dec 2 13:09:48 1992 K. Richard Pixley (rich@cygnus.com) - - * RCS-patches: new file. - -Fri Nov 27 20:12:48 1992 K. Richard Pixley (rich@rtl.cygnus.com) - - Added support for adding previously removed files, as well as - adding and removing files in branches. - - * add.c (build_entry): add new argument, tag, so as to store in - Entries the per directory sticky tag under which a file is - added. Changed prototype and caller. - (build_entry): Do not prevent file additions if the file exists - in the Attic. - (add): if the file being adding was previously dead, say so, and - mark the Entries file with the addition. - * checkin.c (Checkin): adding with a tag no longer means to add, - then tag. Hence, remove the tagging operation. - * classify.c (Classify_File): if the base RCS version is dead, - then the file is being added. If a file being added already - exists in the attic, and the base RCS version is NOT dead, then - we have a conflict. - * commit.c (checkaddfile): add the list of srcfiles to calling - convention. Change prototype and callers. - (remove_file): add message and list of srcfiles to calling - convention. Change prototype and callers. When removing a file - with a tag, remove the tag only when the tag does not represent - a branch. Remove files by committing dead revisions in the - appropriate branch. When removing files from the trunk, also - move the RCS file into the Attic. - (check_fileproc): when adding, and looking for previously - existing RCS files, do not look in the Attic. - (commit_fileproc): adding files with tags now implies adding the - file on a branch with that tag. - (checkaddfile): When adding a file on a branch, in addition to - creating the rcs file in the Attic, also create a dead, initial - revision on the trunk and stub in a magic branch tag. - * cvs.h (joining, gca): added prototypes. - * rcs.c (RCS_getbranch): now global rather than static. - remove prototype and forward decl. - (parse_rcs_proc): use RCS_addnode. - (RCS_addnode): new function. - (RCS_parsercsfile): recognize the new RCS revision - newphrase, "dead". Mark the node for the revision. - (RCS_gettag): requesting the head of a file in the attic now - returns the head of the file in the attic rather than NULL. - (RCS_isbranch): use RCS_nodeisbranch. - (RCS_nodeisbranch): new function. - (RCS_isdead): new function. - * rcs.h (RCSDEAD): new macro for new rcs keyword. - (struct rcsversnode): new field to flag dead revisions. - (RCS_nodeisbranch, RCS_isdead, RCS_addnode): new functions, - new prototypes, new externs. - (RCS_getbranch): now global, so prototype and extern moved - to here. - * subr.c (gca): new function. - * update.c (join_file): add entries list to calling - convention. Caller changed. - (update): also search the Attic when joining. - (checkout_file): when joining, checkout dead revisions too. If - a file has died across an update then say so. - (join_file): support joins of dead files against live ones, live - files against dead ones, and added files. Change the semantic - of a join with only rev specified to mean join specified rev - against checked out files via the greatest common ancestor of - the specified rev and the base rev of the checked out files. - (joining): new function. - * vers_ts.c (Version_TS): ALWAYS get the rcs version number. - - * update.c (update): write the 'C' letter for conflicts. - - * cvs.h (ParseTag): remove duplicate extern. - - * add.c (add_directory): do not prompt for interactive - verification before adding a directory. Doing so prevents - scripted testing. - -Wed Feb 26 18:04:40 1992 K. Richard Pixley (rich@cygnus.com) - - * Makefile.in, configure.in: removed traces of namesubdir, - -subdirs, $(subdir), $(unsubdir), some rcs triggers. Forced - copyrights to '92, changed some from Cygnus to FSF. - -Tue Dec 10 01:24:40 1991 K. Richard Pixley (rich at cygnus.com) - - * diff.c: do not pass an empty -r option to rcsdiff. - - * update.c: fix bug where return code from rcsmerge wasn't being - handled properly. - - * main.c: "rm" and "delete" now synonyms for "remove". - - * commit.c: abort if editor session fails, but remember to clear - locks. - - * Makefile.in: remove conf.h and checkin.configured on clean. - infodir belongs in datadir. - -Thu Dec 5 22:46:03 1991 K. Richard Pixley (rich at rtl.cygnus.com) - - * Makefile.in: idestdir and ddestdir go away. Added copyrights - and shift gpl to v2. Added ChangeLog if it didn't exist. docdir - and mandir now keyed off datadir by default. - -Wed Nov 27 02:47:13 1991 K. Richard Pixley (rich at sendai) - - * brought Makefile.in's up to standards.text. - - * fresh changelog. - - -For older changes, there might be some relevant stuff in the bottom of -the NEWS file, but I'm afraid probably a lot of them are lost in the -mists of time. diff --git a/contrib/cvs/src/ChangeLog-9395 b/contrib/cvs/src/ChangeLog-9395 deleted file mode 100644 index c2d2111..0000000 --- a/contrib/cvs/src/ChangeLog-9395 +++ /dev/null @@ -1,3731 +0,0 @@ -Note: this log overlaps in time with ChangeLog-9194. There was a time -during which changes which had been merged into the official CVS -(which produced releases such as 1.4A1 and 1.4A2) went into what has -become ChangeLog-9194, and changes which existed only at Cygnus went -into this file (ChangeLog-9395). Eventually the Cygnus release became -Cyclic CVS (as it was then called), which became CVS 1.5, so probably -all the changes in both (what are now) ChangeLog-9194 and -ChangeLog-9395 made it into 1.5. - -Sun Dec 31 17:33:47 1995 Jim Kingdon - - * import.c (add_rev): Revert portion of 31 Aug 95 change which - passes -u to ci instead of using a hard link. - * sanity.sh (import): Add test for above-fixed bug. - -Sun Dec 31 16:40:41 1995 Peter Chubb - and Jim Kingdon - - * admin.c (admin_fileproc): Call freevers_ts before returning. - -Mon Dec 25 12:20:06 1995 Peter Wemm - - * logmsg.c (rcsinfo_proc): initialise line and - line_chars_allocated so they dont cause malloc problems within - getline(). This was causing rcsinfo templates to not work. - -Sun Dec 24 01:38:36 1995 Karl Fogel - - * server.c (authenticate_connection): clarify protocol. - - * login.c (login): deprolixify the password prompt. - -Sat Dec 23 10:46:41 1995 Jim Kingdon - - * myndbm.h, myndbm.c (dbm_store): New function. - * myndbm.h (DBM): Add modified and filename fields. - * myndbm.c (dbm_open, dbm_close): Manipulate new fields. dbm_open - no longer fails if the file doesn't exist and O_CREAT is set. - * cvs.h (CVSROOTADM_VALTAGS): Added. - * tag.c, cvs.h (tag_check_valid): New function. - * update.c (update), checkout.c (checkout_proc), commit.c (commit), - diff.c (diff), patch.c (patch_proc), rtag.c (rtag_proc), tag.c (tag): - Call it. - * sanity.sh: Test for rejection of invalid tagname. - -Fri Dec 22 18:21:39 1995 Karl Fogel - - * client.c (start_server): don't use kerberos if authenticating - server was specified. - -Fri Dec 22 16:35:57 1995 Karl Fogel - - * login.c (login): deal with new scramble methods. - (get_cvs_password): same. - - * server.c (check_repository_password): remove arbitrary limit on - line length. - (authenticate_connection): use a separate variable for the - descrambled password, now that we no longer scramble in place. - Set `error_use_protocol' to 1 and just use error() where used to - do its job inline. - - * cvs.h (scramble, descramble): adjust prototype. - - * scramble.c (scramble, descramble): return char *. - -Fri Dec 22 13:00:00 1995 Jim Kingdon - - * release.c (release): If SERVER_SUPPORT is not defined, still - set up arg_start_idx. - - * release.c (release): When calling unedit, set argv[1] to - NULL (since argc is only 1). - - * edit.c: Pass dosrcs 0 to all calls to start_recursion. - None of the fileprocs were using it, so it just slowed things - down and caused potentially harmful checks for rcs files. - - * edit.c (send_notifications): In client case, do not readlock. - -Thu Dec 21 16:00:00 1995 Jim Kingdon - - Clean up Visual C++ lint: - * client.c (read_line): Change input_index and result_size to size_t. - (update_entries): Remove unused variables buf2, size_left, size_read. - (handle_mode): Prototype. - * client.c, client.h (send_to_server, read_from_server): Change - len to size_t. - * client.c (send_to_server): Change wrtn to size_t. - (read_from_server): Change red to size_t. - * client.c, myndbm.c, edit.c, fileattr.c: Include getline.h. - * checkin.c, commit.c, update.c: Include fileattr.h. - * commit.c, update.c: Include edit.h. - * edit.c (onoff_filesdoneproc): Prototype. - (ncheck_fileproc,edit_fileproc): Change "return" to "return 0". - (notify_do): Cast a signed value to unsigned before comparing - with unsigned value. - -Thu Dec 21 15:24:37 1995 Karl Fogel - - * client.c: don't include socket headers twice just because - both HAVE_KERBEROS and AUTH_CLIENT_SUPPORT are set. - (start_kerberos_server): if fail to connect to kerberos, print out - a more specific error message, mainly so pcl-cvs can know what - happened and not panic. - (start_server): don't assume sprintf() returns len - written (only some systems provide this); instead, have - send_to_server() calculate the length itself. - (send_modified): same. - (send_fileproc): same. - (send_file_names): same. - -Wed Dec 20 14:00:28 1995 Jim Kingdon - - * update.c (ignore_files): Move from here... - * ignore.c (ignore_files): ...to here. No longer static. Take - new argument PROC. - * cvs.h (ignore_files): Declare. - * client.c (send_filesdoneproc): Split off from - update_filesdone_proc. Pass new function send_ignproc to - ignore_files (to ask server about ignored file before printing - "?"). - * server.c: Rename outbuf from but_to_net and take it from - do_cvs_command to a global. Move initialization accordingly. - (serve_questionable): New function. - (requests): Add it. - * update.c (update_filesdone_proc): Remove client stuff. Pass new - function update_ignproc to ignore_files. - * cvs.h (joining, do_update): Move declarations from here... - * update.h: ...to here. - * cvs.h: Include update.h. - * update.c, client.c: Don't include update.h - * ignore.c, cvs.h: New variable ign_inhibit_server, set on -I !. - * import.c (import): Pass -I ! to server if specified. - (import_descend): If server, ignore CVS directories even if -I !. - * update.c (update), import.c (import): Only call ign_setup before - argument processing; don't call it again afterwards in client case. - * sanity.sh (ignore): Test above-fixed bugs and other ignore behaviors. - (dotest): New function. - Move modules checkin from modules test to start, so that other - tests can use mkmodules without a warning message. - -Wed Dec 20 13:06:17 1995 Karl Fogel - - * client.c (send_to_server): don't check string's length twice. - -Wed Dec 20 02:05:19 1995 Karl Fogel - - * login.c (login): took out debugging printf's. - (login): Removed unused variable `p'. - -Wed Dec 20 00:27:36 1995 Karl Fogel - - * login.c (login): prefix scrambled password with 'A', so we know - which version of scrambling was used. This may be useful in the - future. - (get_cvs_password): skip past the leading 'A'. - Scramble $CVS_PASSWORD before returning it. - - * scramble.c: made this work. - -Tue Dec 19 17:45:11 1995 Karl Fogel - - * login.c (cvs_password): new static var, init to NULL. - (login): scramble() the password before using it. - Verify the password with the server. - Check CVSroot more carefully to insure that it is - "fully-qualified". - (get_cvs_password): if cvs_password is not NULL, just return it. - Never prompt -- just tell user why failed, then exit. - Try CVS_PASSWORD environment variable first. - (construct_cvspass_filename): try CVS_PASSFILE environment - variable first. - - * client.h (connect_to_pserver): update prototype. - - * client.c (cvsroot_parsed): new static var. - (parse_cvsroot): set `cvsroot_parsed' to 1 when done. - (connect_to_pserver): return int. - Take `verify_only' arg. If it is non-zero, perform password - verification with the server and then shut down the connection and - return. - Call parse_cvsroot() before doing anything. - - * server.c (authenticate_connection): deal with verification - requests as well as authorization requests. - descramble() the password before hashing it. - - * cvs.h: prototype scramble() and descramble(). - - * Makefile.in: build scramble.o. - - * scramble.c: new file, provides trivial encoding but NOT real - encryption. - -Mon Dec 18 20:57:58 1995 Karl Fogel - - * login.c (login): don't insert extra newlines. They were - harmless, but confusing. - -Mon Dec 18 15:32:32 1995 Jim Kingdon - - * hash.c, hash.h (findnode_fn): New function. - * hash.c (hashp): Tweak hash function so that findnode_fn works. - * update.c (ignore_files): Call findnode_fn, not findnode. - -Mon Dec 18 09:34:56 1995 Jim Kingdon - - * myndbm.c: Remove arbitrary limit. - - * client.c: Fix comment--Windows 95 requires NO_SOCKET_TO_FD, not - Windows NT. - -Mon Dec 18 01:06:20 1995 Karl Fogel - - * client.c (server_sock): replaces `server_socket'. - (start_kerberos_server): added FIXME comment about how - NO_SOCKET_TO_FD is not dealt with in the kerberos case. - (connect_to_pserver): deal with NO_SOCKET_TO_FD case. - (read_line): deal with NO_SOCKET_TO_FD case. - (read_from_server): deal with NO_SOCKET_TO_FD case. - (send_to_server): deal with NO_SOCKET_TO_FD case. - (get_responses_and_close): deal with NO_SOCKET_TO_FD case. - - * client.c (send_to_server): error check logging. - (start_server): error check opening of logfiles. - (read_from_server): error check logging. - (read_line): use fwrite() to log, & error_check it. - Don't log if using socket style, because read_from_server() - already logged for us. - -Mon Dec 18 00:52:26 1995 Karl Fogel - - * client.c (use_socket_style): new static var, init to 0. - (server_socket): new static var. - (connect_to_pserver): don't deal with logging here. - Caller changed. - (start_kerberos_server): don't deal with logging here either. - Caller changed. - -Mon Dec 18 00:40:46 1995 Karl Fogel - - * client.c (send_modified): don't error-check `to_server'; - send_to_server() does that now. - -Mon Dec 18 00:19:16 1995 Karl Fogel - - * login.c (get_cvs_password): Init `linebuf' to NULL. - free() `linebuf' and reset it for each new line. - (login): same as above. - - * client.c: Removed all the varargs prototyping gunk. - (to_server, from_server): make these static. - (from_server_logfile, to_server_logfile): new vars. - (start_server): init above two new vars to NULL. - (send_to_server): return void. - Correct bug in which amount to be written would be too high if the - loop ever ran more than once. - Log to `to_server_logfile' if it's non-NULL. - (read_from_server): new func, does raw reading from server. - Logs to `from_server_logfile' if it's non-NULL. - (update_entries): just use read_from_server() instead of looping - to fread() directly from `from_server'. - (read_line): Log to `from_server_logfile' if it's non-NULL. - - * client.h: send_to_server() returns void now. - (read_from_server): prototype. - -Sun Dec 17 19:38:03 1995 Jim Kingdon - - * checkout.c (checkout_proc), client.c, lock.c (readers_exist), - login.c, modules.c (cat_module, do_module): Remove arbitrary limits. - - * client.c (send_to_server): Fix typo (NULL -> '\0'). - (get_responses_and_close): Set server_started to 0 instead of - setting to_server and from_server to NULL. - * client.c: Make to_server and from_server static. - -Sun Dec 17 17:59:04 1995 Karl Fogel - - * client.h (to_server, from_server): don't declare these anymore. - They are now entirely private to client.c (and in fact will go - away soon there too). - -Sun Dec 17 15:40:58 1995 Karl Fogel - - * client.h: update prototype of send_to_server(). - - * client.c, watch.c, update.c, tag.c, status.c, rtag.c, remove.c, - release.c, patch.c, log.c, import.c, history.c, edit.c, diff.c, - commit.c, client.c, checkout.c, admin.c, add.c: - Convert all send_to_server() calls that used formatting to send - pre-formatted strings instead. And don't error check - send_to_server(), because it does its own error checking now. - - * client.c (send_to_server): don't use vasprintf(), just fwrite a - certain number of bytes to the server. And do error checking - here, so our callers don't have to. - (send_arg): use send_to_server() instead of putc()'ing - directly to `to_server'. - -Sun Dec 17 14:37:52 1995 Karl Fogel - - * options.h.in (AUTH_CLIENT_SUPPORT, AUTH_SERVER_SUPPORT): - Define to 1 but leave commented out, instead of #undef'ing them. - This treats them like everything else in this file. - - * client.c: define server_started, init to 0. - (start_server): set server_started to 1. - - * client.h: declare `server_started', extern. - AUTH_CLIENT_SUPPORT moved here from cvs.h. - - * cvs.h: moved AUTH_CLIENT_SUPPORT stuff to client.h. - - * edit.c (notify_check): use new var server_started. - -Sun Dec 17 00:44:17 1995 Jim Kingdon - - * client.c (get_responses_and_close): Really stop ignoring ECHILD - errors. The Nov 30 1995 change claimed to do this, but the code - was not actually changed. - - * update.c (ignore_files): Revert H.J. Lu change; it was wrong for - directories and sometimes looked at sb.st_mode when it wasn't set. - * import.c (import_descend): Revert H.J. Lu change; it was wrong - for directories and the extra lstat call was an unnecessary - performance hit. - * sanity.sh (import): Add test for the second of these two bugs. - -Sat Dec 16 17:26:08 1995 Jim Kingdon - - * client.c (send_to_server): Remove arbitrary limit. Also remove - !HAVE_VPRINTF code; all relevant systems have vprintf these days. - -Sat Dec 16 21:35:31 1995 Karl Fogel - - * checkout.c (checkout): use send_to_server() now. - -Sat Dec 16 21:18:16 1995 H.J. Lu (hjl@gnu.ai.mit.edu) - (applied by kfogel@cyclic.com) - - * import.c (import_descend): We ignore an entry if it is - 1. not a file, nor a link, nor a directory, or - 2. a file and on the ignore list. - - * update.c (ignore_files): We ignore any thing which is - 1. not a file, or - 2. it is a file on the ignore list. - -Sat Dec 16 00:14:19 1995 Karl Fogel - - * client.c (send_to_server): corrected comment. - - * client.h: prototype new func send_to_server(). - - * add.c, admin.c, client.c, commit.c, diff.c, edit.c, history.c, - import.c, log.c, patch.c, release.c, remove.c, rtag.c, status.c, - tag.c, update.c, watch.c: - Use send_to_server() instead of writing directly to to_server. - - * client.c: conditionally include the right stuff for variable arg - lists. - (send_to_server): new func. - -Fri Dec 15 23:10:22 1995 Karl Fogel - - * error.c: expanded comments. - - * client.c (connect_to_pserver): verbosify errors. - (connect_to_pserver): use send() and recv(), not write() and - read(). Sockets are not file descriptors on all systems. - -Fri Dec 15 22:36:05 1995 Karl Fogel - - * client.c (connect_to_pserver): oops, removed old debugging - printf. - -Fri Dec 15 18:21:16 1995 Karl Fogel (kfogel@floss.cyclic.com) - - * client.c (auth_server_port_number): don't call htons(); - init_sockaddr() does that for us. - (init_sockaddr): zero the sockadder_in struct before doing - anything with it. IBM TCP/IP docs recommend this, and it can't - hurt. - -Fri Dec 15 15:21:53 1995 Karl Fogel - - * client.c (connect_to_pserver): new var `port_number', initialize - with new func auth_server_port_number() and pass to - init_sockaddr(). - (auth_server_port_number): new func. Right now it just returns - `htons (CVS_AUTH_PORT)'. We'll probably add the ability to - specify the port at run time soon, anyway, so having this function - will make that easier. - -Wed Dec 6 18:08:40 1995 Jim Kingdon - - * cvs.h: Add CVSREP. - * find_names.c (find_dirs): Skip CVSREP too. - * fileattr.h, fileattr.c: New files, to manipulate file attributes. - * hash.c (nodetypestring), hash.h (enum ntype): Add FILEATTR. - * hash.c, hash.h (list_isempty): New function. - * recurse.c (do_recursion): Call fileattr_startdir before - processing files in a directory and fileattr_write and - fileattr_free (after files, before recursing). - * watch.c, watch.h: New files, to handle notification features. - * edit.c, edit.h: New file, to handle new read-only checkout features. - * client.c, server.c: Add "Mode" request, to change the mode of a file - when it is checked in. - * main.c (cmds): Add "watch", "edit", "unedit", "watchers", "editors". - * main.c: Split command help from usg into new variable cmd_usage, - which. - (main): Add --help-commands option to print out cmd_usage. - * cvs.h: Declare watch, edit, unedit, watchers, editors. - * client.c, client.h: Add client_watch, client_edit, client_unedit, - client_watchers, client_editors. - * client.c, server.c: Add notification stuff. - * update.c (checkout_file, patch_file), checkin.c (Checkin): Check - _watched attribute when deciding read-only or read-write. - * commit.c (checkaddfile): Call fileattr_newfile to set attributes - on newly created files. - * release.c (release): - * cvs.h: Add CVSADM_NOTIFY and CVSADM_NOTIFYBAK. - * recurse.c (do_recursion): Call notify_check. - * commit.c (commit_fileproc): Call notify_do after committing file. - * client.c (get_responses_and_close): Set to_server and from_server - to NULL so that it is possible to tell whether we are speaking to - the server. - * cvs.h: Add CVSROOTADM_NOTIFY. - * mkmodules.c (main): Add CVSROOTADM_NOTIFY to filelist. - * Makefile.in (SOURCES,OBJECTS,HEADERS): Add new files mentioned above. - * lock.c, cvs.h (lock_tree_for_write, lock_tree_cleanup): New - functions, taken from old commit.c writelock code. As part of - this, fsortcmp and lock_filesdoneproc go from commit.c to lock.c. - So does locklist but it gets renamed to lock_tree_list. - * commit.c: Use lock_tree_*. - -Fri Dec 15 10:37:00 1995 J.T. Conklin - - * tag.c (tag_usage): Added -r and -D flags to usage string. - (tag): Detect when user specifies both -r and -D arguments. - Pass -r and -D arguments to server. - -Thu Dec 14 11:56:13 1995 Karl Fogel - - * client.c (start_rsh_server): use RSH_NEEDS_BINARY_FLAG to - conditionalize "-b" option to "rsh". - - * run.c (filter_stream_through_program): document return value and - error behavior. - - * client.c (filter_through_gunzip): pass the supposedly - superfluous "-d" option to gunzip, to avoid stimulating what seems - to be an argument-passing bug in spawn() under OS/2 with IBM - C/C++. Yucko. - -Wed Dec 13 20:08:37 1995 Jim Kingdon - - * options.h.in (RCSBIN_DFLT): Recommend specifying -b in - inetd.conf for pserver. That is a pretty good solution. - -Wed Dec 13 18:29:59 1995 Preston L. Bannister - and Karl Fogel - - * client.c (send_modified): make sure that vers and vers->options - are non-NULL before strcmp()'ing them with "-kb". - Initialize `bin' near where it is used, not at beginning of - function. - (update_entries): make sure `options' is non-NULL before - strcmp()'ing with "-kb". - Initialize `bin' near where it is used, not at beginning of - function. - -Tue Dec 12 18:56:38 1995 Karl Fogel - - * options.h.in (RCSBIN_DFLT): document the probable need for this - to be set in the authenticating server. - -Tue Dec 12 11:56:43 1995 Jim Kingdon - - * server.c (expand_proc): If mfile is non-NULL, return it too as - part of the expansion. - * sanity.sh (modules): Add tests for above-fixed bug. - -Mon Dec 11 21:39:07 1995 Karl Fogel - - * dog.c (flea_bath): Take `suds' arg. - All collars changed. - -Mon Dec 11 15:58:47 1995 Karl Fogel - - * login.c (login): if client password file doesn't exist, create - it, duh. - - * main.c (main): die if CVSroot has access-method but no - username. - - * root.c: added some comments. - - * main.c: removed all code pertaining to the "-a" option. We - specify access-method in CVSroot now. - - * client.c (parse_cvsroot): new var, `access_method'. If CVSroot - is prepended with an access method (i.e., - ":pserver:user@host:/path"), then handle it. - - * login.c (login): use || when checking if CVSroot is "fully - qualified". - Prepend ":pserver:" before writing to ~/.cvspass. - (get_cvs_password): Take no parameters; we'll just use CVSroot to - get the password. - -Mon Dec 11 12:43:35 1995 adamg - - * error.c, client.c, remove.c, main.c: Add explicit casts for some - function pointers to remove warnings under MS VC. - * main.c (main): remove use of NEED_CALL_SOCKINIT in favor of the - more generic INITIALIZE_SOCKET_SUBSYSTEM. Note that the code assumes - that if INITIALIZE_SOCKET_SUBSYSTEM() returns, socket subsystem - initialization has been successful. - -Sat Dec 9 22:01:41 1995 Dan O'Connor - - * commit.c (check_fileproc): pass RUN_REALLY flag to run_exec, - because it's okay to examine the file with noexec set. - -Sat Dec 9 20:28:01 1995 Karl Fogel - - * client.c (update_entries): new var, `bin, init to 0. - Use it in determining whether to convert the file. - (send_modified): same as above. - -Fri Dec 8 17:47:39 1995 Karl Fogel - - * server.c (downcase_string): removed. - (check_repository_password): don't deal with case-insensitivity - anymore. - - * options.h.in (CVS_PASSWORDS_CASE_SENSITIVE): deleted this. No - need for it anymore. - -Thu Dec 7 21:08:39 1995 Karl Fogel - - * server.c (check_repository_password): when checking for false - prefix-matches, look for ':', not '@'. Duh. - -Thu Dec 7 18:44:51 1995 Karl Fogel - - * options.h.in (CVS_PASSWORDS_CASE_SENSITIVE): replaces - CVS_PASSWORDS_CASE_INSENSITIVE; passwords are now insensitive by - default. Expanded explanatory comment. - - * login.c (get_cvs_password): Use memset(), not bzero(). I - botched this change earlier. - - * server.c (check_repository_password): no need to check - xmalloc()'s return value. - (check_repository_password): check for false prefix-matches (for - example, username is "theo" and linebuf contains user - "theocracy"). - -Thu Dec 7 14:49:16 1995 Jim Meyering (meyering@comco.com) - - * filesubr.c (isaccessible): Rename from isaccessable. - Update callers. - * cvs.h: Update prototype. - * main.c (main): Update callers. - * server.c (main): Update callers. - -Thu Dec 7 12:50:20 1995 Adam Glass - - * cvs.h: "isaccessible" is the correct spelling. - Also add "const" to second arg to make prototype match - declaration. - -Thu Dec 7 11:06:51 1995 Karl Fogel - - * client.c, login.c: memset() instead of bzero(). - -Thu Dec 7 00:08:53 1995 Karl Fogel - - * server.c (authenticate_connection): document server's side of - the Authentication Protocol too. - - * client.c (connect_to_pserver): when printing out "unrecognized - response", also print out the offending response. - - * server.c (check_password): take `repository' arg too now. - Call check_repository_password() before checking /etc/passwd. - (check_repository_password): new func. - - * options.h.in (CVS_PASSWORDS_CASE_INSENSITIVE): new define, unset - by default. - -Wed Dec 6 18:51:16 1995 Karl Fogel - - * server.c (check_password): If user has a null password, then - return 1 if arg is also null. - Reverse sense of return value. Caller changed. - -Wed Dec 6 14:42:57 1995 Karl Fogel - - * server.c (check_password): new func. - (authenticate_connection): call above new func. - - * login.c (login): use construct_cvspass_filename(). - If CVSroot is not "fully-qualified", then insist the user qualify - it before going on. - (get_cvs_password): fleshed out. Now reads from ~/.cvspass, or - prompts if no appropriate password found. - (construct_cvspass_filename): new func. - - * server.c (authenticate_connection): send ACK or NACK to client. - - * client.c (connect_to_pserver): check for ACK vs NACK response - from server after sending authorization request. - - * login.c (get_cvs_password): new func. - - * client.c (connect_to_pserver): use new func get_cvs_password(). - Prototype it at top of file. Hmmm. - -Wed Dec 6 13:29:22 1995 Karl Fogel - - * server.c: same as below (AUTH_SERVER_SUPPORT). - - * main.c: same as below (AUTH_SERVER_SUPPORT where appropriate). - - * login.c: same same as below. - - * cvs.h: same as below. - - * client.c: use AUTH_CLIENT_SUPPORT, not CVS_LOGIN. - - * options.h.in (AUTH_CLIENT_SUPPORT, AUTH_SERVER_SUPPORT): these - replace CVS_LOGIN. - -Wed Dec 6 00:04:58 1995 Karl Fogel - - * server.c (authenticate_connection): expanded comment. - -Tue Dec 5 23:37:39 1995 Karl Fogel - - * client.c (connect_to_pserver): read password from prompt for - now. - - * server.c (authenticate_connection): if the password passes - muster, then don't abort. - -Tue Dec 5 22:46:37 1995 Karl Fogel - - * subr.c (strip_trailing_newlines): new func. - - * client.c (connect_to_pserver): took out print statements. - - * server.c (authenticate_connection): removed print statments. - Use new func strip_trailing_newlines() to purify `repository', - `username', and `password'. - Run a primitive password check, just for testing. - - * client.c (connect_to_pserver): use CVS_AUTH_PORT. - Take tofdp, fromfdp, and log args. Caller changed. - (get_responses_and_close): either kerberos and CVS_LOGIN might - have one fd for both directions, so adjust #ifdef accordingly. - - * cvs.h (CVS_AUTH_PORT): new define, default to 2401. - Prototype strip_trailing_newlines(). - -Tue Dec 5 16:53:35 1995 Karl Fogel - - * server.c (authenticate_connection): new func. - - * client.c (init_sockaddr): func moved here from login.c. - (connect_to_pserver): same as above. Take no args, now. - Include , , , if CVS_LOGIN. - - * cvs.h: Declare use_authenticating_server, as extern int. - Declare connect_to_pserver(). - - * main.c (main): call authenticate_connection(). Removed testing - code. - Add 'a' to the short-option string in the getopt() call. - - * login.c (connect_to_pserver): moved to client.c. - -Tue Dec 5 16:01:42 1995 Peter Chubb - (patch applied by Karl Fogel ) - - * update.c (join_file): if vers->vn_user is "0", file has been - removed on the current branch, so print an error and return. - -Mon Dec 4 14:27:42 1995 Jim Kingdon - - * Version 1.6.3. - -Mon Dec 4 16:28:25 1995 Norbert Kiesel - - * release.c (release): add return (0) as last line - - * cvs.h: declare program_path - - * main.c define program_path - (main): set program_path - - * release.c (release): use program_path for update_cmd - -Mon Dec 4 11:22:42 1995 Jim Kingdon - - * Version 1.6.2. - -Sun Dec 3 20:02:29 1995 Jim Kingdon - - * rcs.h (struct rcsnode), rcs.c (freercsnode): Add expand field. - * rcs.h (RCSEXPAND): New #define. - * rcs.c (RCS_reparsercsfile): Record keyword expansion in expand - field of struct rcsnode. - * update.c (checkout_file): Set keyword expansion in Entries file - from rcs file if there is nowhere else to set it from. - * client.c (send_modified, update_entries) [LINES_CRLF_TERMINATED]: - If -kb is in effect, don't convert. - - * update.c (update_file_proc), commit.c (check_fileproc), - rcscmds.c (RCS_merge): Direct stdout to DEVNULL rather than - passing -s option to grep. This avoids trouble with respect to - finding a grep which support -s and whether we should use the (GNU - grep) -q option if it exists. - * options.h.in: Change "@ggrep_path@" to "grep". - -Fri Dec 1 11:53:19 1995 Norbert Kiesel - - * rcs.c (RCS_gettag): new parameter return_both force return both - tags: the symbolic and the numeric one. - (RCS_getversion): new parameter return_both is forwarded to - RCS_gettag. - - * rtag.c, tag.c, commit.c, patch.c, update.c: pass 0 as additional - last parameter to RCS_getversion and RCS_gettag - - * rcs.h (RCS_gettag): new parameter return_both. - (RCS_getversion): new parameter return_both. - - * cvs.h (struct vers_ts): add vn_tag slot for symbolic tag name - - * vers_ts.c (Version_TS): call RCS_getversion with 1 for - return_both and split output into vn_rcs and vn_tag - (freevers_ts): free vn_tag - - * update.c (checkout_file): use vn_tag instead of vn_rcs when - calling 'rcs co' to allow rcs expansion of :$Name : - -Thu Nov 30 20:44:30 1995 Karl Fogel - - * client.c (get_responses_and_close): undo previous change - regarding waitpid(). The problem has been solved by modifying - os2/waitpid.c instead of its callers. - -Thu Nov 30 16:37:10 1995 Karl Fogel - - * client.c: All these changes are for OS/2, which will no longer have - a separate client.c: - (start_kerberos_server): new func, contains code that - used to be in start_server(). - (start_server): moved kerberos code to above function, reorganized - the rest. Added authentication clause. - (call_in_directory): test errno against EACCESS, if EACCESS is - defined (this is for OS/2's oddball mkdir). - (change_mode): don't set execute permission on anything if - EXECUTE_PERMISSION_LOSES is defined. - (get_responses_and_close): if START_RSH_WITH_POPEN_RW, then use - pclose() instead of fclose(). - If waitpid errors with ECHILD, don't die. This is okay. - (start_rsh_server): alternate definition if - START_RSH_WITH_POPEN_RW. - - * main.c: [all these changes conditional on CVS_LOGIN: ] - Don't prototype connect_to_pserver, don't enter it in cmds[] - (actually, it was never in there, I don't know why my previous - change said it was). - (use_authenticating_server): new global var. - (main): if "-a", then set above new var to TRUE. - (usg): document "-a" option. - -Wed Nov 29 12:55:10 1995 Karl Fogel - - * main.c: Prototype connect_to_pserver(), and enter it in cmds[]. - (main): test some extremely primitive authentication. - - * login.c: Include - (connect_to_pserver): new func. - (init_sockaddr): new func. - -Mon Nov 20 14:07:41 1995 Jim Kingdon - - * Makefile.in (TAGFILES): Separate out from DISTFILES, for C code. - (TAGS,tags): Use TAGFILES not DISTFILES. - -Sun Nov 19 11:22:43 1995 Jim Kingdon - - * recurse.c (do_recursion): Don't call server_pause_check if there - are writelocks around. Revise comment to reflect fact we are no - longer relying on a writelock'd operations being "unable" to - generate enough data to pause. - -Sun Nov 19 10:04:50 1995 Peter Wemm - - * server.c, server.h, options.h.in: Implement hooks for doing - simple flow control on the server to prevent VM exhaustion on a - slow network with a fast server. - * recurse.c: Call the flow control check at a convenient location - while no locks are active. This is a convenience tradeoff against - accurate flow control - if you have a large directory it will all - be queued up, bypassing the flow control check until the next - directory is processed. - -Sat Nov 18 16:22:06 1995 Karl Fogel - - * client.c, update.c, vers_ts.c, server.c, rcs.c, lock.c, - ignore.c, entries.c, diff.c, commit.c, checkin.c: - Use new macro `existence_error', instead of comparing errno to - ENOENT directly. - -Fri Nov 17 14:56:12 1995 Karl Fogel - - * client.c (start_server): removed alternate version of this func, - since os2/client.c will now be used under OS/2. - -Thu Nov 16 22:57:12 1995 Karl Fogel - - * client.c (start_server): ifdef HAVE_POPEN_RW, use a different - version of start_server(). This is maybe not the cleanest cut to - make, but it's better than mucking around with yet more #ifdefs in - the middle of the old start_server() function. Once things are - up, I may reposition this code. - -Wed Nov 15 15:33:37 1995 Karl Fogel - - * main.c (main): ifdef NEED_CALL_SOCKINIT, then call SockInit(). - Only OS/2 needs this initialization. - -Tue Nov 14 18:54:01 1995 Greg A. Woods - - * patch.c: - - fix orientation of test for result of getline() call - - use fputs() not printf() when just copying file out - - * cvsbug.sh: - - add space after #! - - new rcs id - - allow version to be edited by Makefile. - - * Makefile.in: - - make Makefile a dependent of all (this might not be perfect, but - it at least gives you a chance to catch up on the second - go-around). - - filter cvsbug.sh in a manner similar to cvsinit.sh to get the - version number set from version.c - -Tue Nov 14 13:28:17 1995 Jim Kingdon - - * sanity.sh: Call old log file check.plog, not check.olog. - - * sanity.sh: Convert remaining tests from old-style ('***' on fail - and nothing on pass), to new-style (FAIL on fail and PASS on pass). - - * sanity.sh: Fix ability to run only some of the tests (always run - tests 1-4.75 to set up repository, document better how it works). - - * sanity.sh: Change "completed successfully" to "completed" in - message--many tests, but not all, exit if they fail. - -Tue Nov 14 15:10:00 1995 Greg A. Woods - - * sanity.sh: test 63 doesn't work and probably can't - -Tue Nov 14 12:22:00 1995 Greg A. Woods - - * sanity.sh: many minor tweaks: - - make the optional arguments almost work - - use a function 'directory_cmp' instead of 'diff -r' - - fix up a few more tests that weren't working.... - -Mon Nov 13 07:33:55 1995 Karl Fogel - - * cvs.h: ifdef USE_OWN_POPEN, #include "popen.h". Only OS/2 has - its own popen()/pclose() right now. - -Mon Nov 13 04:06:10 1995 Karl Fogel - - * cvs.h: conform to 80 column standard (yes, I'm a pedant). - -Sat Nov 11 13:45:13 1995 Karl Fogel - - * client.c (process_prune_candidates): use unlink_file_dir() to - remove the directory, instead of invoking "rm" via run_exec(). - -Fri Nov 10 14:38:56 1995 Karl Fogel - - * main.c (main): removed "#define KF_GETOPT_LONG 1", since that - change is no longer in testing. - -Thu Nov 9 20:32:12 1995 Karl Fogel - - * release.c (release): Use Popen(), not popen(). - -Wed Nov 8 10:20:20 1995 Jim Meyering (meyering@comco.com) - - * entries.c (ParseTag): Remove dcl of unused local. - - * patch.c: Include getline.h. - -Wed Nov 8 11:57:31 1995 Norbert Kiesel - - * options.h.in: add configuration option STEXID_SUPPORT (default - is off i.e. old semantics) - - * filesubr.c (isaccessable): new function. Checks access-rights - for files like access(), but is getxid-safe. Falls back to - access() if SETXID_SUPPORT is not enabled. - (isfile): replace stat() by isaccessable(file, F_OK) - (isreadable): replace access() by isaccessable() - (iswritable): ditto - (make_directory): rename local variable buf to sb - - * cvs.h: add prototype for new function isaccessable. - - * server.c (serve_root): replace access() by isaccessable() - - * cvsrc.c (read_cvsrc): replace access() by isreadable() - - * main.c (main): replace access() by isaccessable() - -Wed Nov 8 10:22:41 1995 Greg A. Woods - - * entries.c (fgetentent): change definition to static to match the - declaration at the top of the file - -Tue Nov 7 16:59:25 1995 J.T. Conklin - - * rcs.c (RCS_getbranch, RCS_getdate, RCS_getrevtime, RCS_gettag, - RCS_getversion, RCS_head): Use assert() instead of attempting to - "do the right thing" with a bogus RCSNode argument. - -Mon Nov 6 14:24:34 1995 Jim Kingdon - - * vers_ts.c: Remove ctime define. It is just asking for trouble. - -Mon Nov 6 11:58:26 1995 Karl Fogel - - * vers_ts.c: ifdef ctime, undef it before redefining it. It is a - macro on some systems. - - * lock.c: don't prototype ctime() here. (See note below about - fgetentent() in entries.c.) - -Sun Nov 5 16:06:01 1995 Karl Fogel - - * entries.c (fgetentent): don't prototype ctime here; we include - cvs.h, which includes system.h, which includes - unconditionally (either as or ). Anyway, IBM - C/C++ chokes on mid-function, or even mid-file, prototypes. Sigh. - -Thu Nov 2 21:51:04 1995 Dan Wilder - - * rtag.c (rtag): Fix typo ("-T" -> "-F"). - -Tue Oct 31 19:09:11 1995 Dan Wilder - - * diff.c (diff_dirproc): just return R_SKIP_ALL if dir not exist. - (diff_file_nodiff): don't complain if file doesn't exist, just - ignore. - -Tue Oct 31 09:25:10 1995 Norbert Kiesel - - * sanity.sh: Use absolute pathname for mkmodules. - -Sat Oct 28 01:01:41 1995 Jim Meyering (meyering@comco.com) - - * entries.c (ParseTag): Use getline instead of fgets. - -Fri Oct 27 13:44:20 1995 Karl Fogel - - * cvs.h: do nothing about alloca ifdef ALLOCA_IN_STDLIB. I am - rather suspicious of this solution, and will not be surprised to - find out that there's a Right Way to handle this situation ("this - situation" being that OS/2 simply declares alloca in ). - Suggestions are welcome; see src/cvs.h and lib/system.h to see why - I was getting a conflict in the first place. - -Wed Oct 25 16:03:20 1995 J.T. Conklin - - * cvs.h (struct entnode): Add user field. - * entries.c (fputentent): New function, write entries line. - (write_ent_proc): Call fputentent to write entries line. - (Entnode_Create): New function, construct new Entnode. - (Entnode_Destroy): New function, destruct old Entnode. - (AddEntryNode): Changed to take an Entnode argument instead of - separate user, version, timestamp, etc. arguments. - (fgetentent): Changed to return Entnode. - (struct entent, free_entent): Removed. - -Wed Oct 25 12:44:32 1995 Jim Kingdon - - * admin.c (admin): Don't rely on ANSI C string concatenation; - SunOS 4.1.3 /bin/cc doesn't support it. - -Tue Oct 24 22:34:22 1995 Anthony J. Lill - - * import.c (expand_at_signs): Check errno as well as return value - from putc. Some systems bogusly return EOF when successfully - writing 0xff. - -Tue Oct 24 14:32:45 1995 Norbert Kiesel - - * admin.c (admin): use getcaller() instead of getpwuid - - * subr.c (getcaller): prefer getlogin() to $USER and $LOGNAME - (especially useful for NT where getuid always returns 0) - -Tue Oct 24 06:22:08 1995 Jim Meyering (meyering@comco.com) - - * cvsrc.c (read_cvsrc): Use getline instead of fgets. - * patch.c (patch_fileproc): Use getline instead of fgets. - - * entries.c (fgetentent): Use getline instead of fgets. - Use xmalloc to allocate space for each returned entry. - Since LINE is no longer static, save it in struct entent. - (struct entent): New member, line. - (free_entent): New function. - (Entries_Open): Call it after each call to fgetentent. - -Tue Oct 24 11:13:15 1995 Norbert Kiesel - - * cvs.h: Declare valloc again, but this time with the right - signature (also changed in libs/valloc.c) - -Mon Oct 23 12:17:03 1995 Jim Kingdon - - * logmsg.c (do_editor): Check for errors from stdio calls. - -Mon Oct 23 12:37:06 1995 Jim Kingdon - - * cvs.h: Don't declare valloc. Some systems (e.g. linux) declare - it in stdlib.h in a conflicting way. - -Mon Oct 23 08:41:25 1995 Jim Meyering (meyering@comco.com) - - * commit.c (commit_filesdoneproc): Use getline instead of fgets. - - * logmsg.c (do_editor): Use getline instead of fgets. - (rcsinfo_proc): Likewise. - - * logmsg.c (do_editor): Lose if fclose of temp file output - stream fails. - -Mon Oct 23 11:59:41 1995 Norbert Kiesel - - * cvs.h: add valloc declaration - - * server.h: add server_cleanup prototype - - * server.c: remove server_cleanup prototype - - * mkmodules.c (server_cleanup): fix parameter type - - * server.c: encapsulate wait_sig in #ifdef sun (it's only used in - code which is also encapsulated in #ifdef sun) - - * rcscmds.c (RCS_deltag, RCS_lock): add definition of noerr - parameter - - * error.c: include cvs.h instead of config.h, add USE(rcsid) - - * error.c (error): fix parameter type - - * update.c (join_file): encapsulate recent changes from garyo - within #ifdef SERVER_SUPPORT - -Sun Oct 22 13:47:53 1995 J.T. Conklin - - * client.c (update_entries): Fix memory leak; free mode_string and - file_timestamp. - (send_fileproc): Fix memory leak; call freevers_ts before exiting. - - * module.c (do_module): Partially fix memory leak; added - variable so that the address of memory allocated by line2argv - is retained, but comment out the call to free_names. Freeing - the vector at that point loses because some of the elements - may be used later in the function. - (cat_module): fix memory leak. - - * recurse.c (start_recursion): Fix memory leak; free return - value of Name_Repository after it has been used. - -Sat Oct 21 23:24:26 1995 Jim Meyering (meyering@comco.com) - - * client.c (send_modified) [LINES_CRLF_TERMINATED]: Comment text - after #endif. - -Fri Oct 20 14:41:49 1995 Jim Kingdon - - * sanity.sh: Add test 87a, to test for bug fixed by garyo in - change below. - -Fri Oct 20 10:59:58 1995 Gary Oberbrunner - - * update.c (join_file): send file back to client even if no - conflicts were detected, by calling Register(). - -Fri Oct 20 10:46:45 1995 Norbert Kiesel - - * lock.c: Add prototype for Check_Owner - -Thu Oct 19 16:38:14 1995 Jim Meyering (meyering@comco.com) - - * lock.c (Check_Owner): Declare function `static int'. - -Thu Oct 19 14:58:40 1995 Jim Kingdon - - * expand_path.c (expand_variable): Fix typo ('*'->'('). - -Thu Oct 19 14:58:40 1995 Jim Kingdon - - * commit.c (commit_filesdoneproc): Check for errors from fopen, - fgets, and fclose. - - * rcscmds.c (RCS_merge): Remove comment about rcsmerge -E. - Hacking CVS was never a very good solution; the situation is fixed - in RCS 5.7, and is documented in ../INSTALL. - -Thu Oct 19 15:06:15 1995 Jim Meyering (meyering@comco.com) - - * filesubr.c (xchmod): Parenthesize arithmetic in operand of | - to placate gcc -Wall. - - * expand_path.c (expand_path): Parenthesize assignments used as - truth values to placate gcc -Wall. - - * commit.c (checkaddfile): Remove dcls of unused variables. - * lock.c (unlock): Remove dcl of unused variable. - -Thu Oct 19 14:58:40 1995 Jim Kingdon - - * root.c (Create_Root): If noexec, don't create CVS/Root. - -Wed Oct 18 11:19:40 1995 J.T. Conklin - - * lock.c (unlock): Change order of comparison so that Check_Owner - is called only if other conditions are true. This performance - enhancement was broken when the AFS support was added. - -Wed Oct 18 12:51:33 1995 Karl Fogel - - * main.c (main): check if argv[0] is "pserver" with else-if, not - if, since we've already asked if it's "kserver". - -Tue Oct 17 18:09:23 1995 Warren Jones - and Jim Kingdon - - * sanity.sh: Deal with supplying a relative cvs filename, or - with a cvs filename which doesn't have basename "cvs". - -Mon Oct 16 15:58:31 1995 Vince Demarco - - * parseinfo.c (Parse_Info): if the Keyword isn't ALL the current - version doesn't use the expanded variable, It should. - -Mon Oct 16 15:58:31 1995 Gary Oberbrunner - and Jim Kingdon - - * server.c (server_register): Don't pass NULL to printf if tag, - date, or conflict is NULL. - -Thu Oct 12 12:13:42 1995 Karl Fogel - - * main.c (main): begin to handle "pserver"; support not complete - yet, however. - -Thu Oct 12 02:52:13 1995 Roland McGrath - - * expand_path.c: Don't #include , since cvs.h already does, - and not all systems' s are protected from multiple inclusion. - * login.c: Likewise. - -Wed Oct 11 15:23:24 1995 Karl Fogel - - * login.c (login): handle everything correctly now. - -Wed Oct 11 12:02:48 1995 Norbert Kiesel - - * rcs.c (RCS_gettag): support RCS keyword Name - -Tue Oct 10 19:11:16 1995 Karl Fogel - - * options.h.in (CVS_LOGIN): discuss, but leave commented out. - The "cvs login" command is still under construction; however, the - repository was changing so fast that instead of creating a branch - and dealing with the attendant hair, I'm just developing on the - trunk, making sure that everything is surrounded by "#ifdef - CVS_LOGIN ... #endif" so I don't get in anyone's way. - - * login.c: include cvs.h before checking CVS_LOGIN, so it has a - chance to get defined before we ask if it's defined. - (login): oops, use semi not comma in `for' loop init. - - * Makefile.in (SOURCES, OBJECTS): include login.c, login.o. - - * main.c: added protoype for login(). - Added "login" entry to cmds[]. - (usg): added line about "login". - - * login.c: new file. - -Tue Oct 10 18:33:47 1995 Karl Fogel - - * Makefile.in (COMMON_OBJECTS): added error.o. - (OBJECTS): took error.o out; it's in COMMON_OBJECTS now. - -Tue Oct 10 12:02:37 1995 Thorsten Lockert - - * cvsbug.sh: Cater to lame versions of sh (4.4BSD ash) by using - ${foo-bar} instead of `if....`. - -Tue Oct 10 12:02:37 1995 Jim Kingdon - - * remove.c (remove_fileproc): If noexec, don't remove file. Check - for error when removing file. - -Sun Oct 8 12:32:15 1995 Peter Wemm - - * run.c: detect/use POSIX/BSD style reliable signals for critical - section masking etc. Helps prevent stray locks on interruption. - -Sat Oct 7 23:26:54 1995 Norbert Kiesel - - * admin.c (admin): If group CVS_ADMIN_GROUP exists, allow only - users in that group to use "cvs admin". - * options.h.in: Default CVS_ADMIN_GROUP to "cvsadmin". - -Sat Oct 7 23:05:24 1995 Norbert Kiesel - - * add.c, checkout.c, commit.c, cvs.h, filesubr.c, import.c, - lock.c, main.c, modules.c, options.h.in: New variable cvsumask - which is used to set mode of files in repository (regardless of - umask in effect when cvs is run). - -Sat Oct 7 22:40:17 1995 Stephen Bailey - - * lock.c: Include AFSCVS ifdefs to deal with AFS's lack of - correspondance between userid's from stat and from geteuid. - -Sat Oct 7 22:28:49 1995 Scott Carson - - * add.c (add): Pass -ko, not -k -ko, to set keyword expansion options. - - * admin.c (admin): Don't skip first argument when sending to server. - -Fri Oct 6 21:45:03 1995 Jim Kingdon - - * version.c: Version 1.6.1. - -Fri Oct 6 21:31:28 1995 Jeff Johnson - - * cvs.h, admin.c, client.c, commit.c, log.c, modules.c, - parseinfo.c, patch.c, recurse.c, rtag.c, status.c, tag.c: - Prototype when dealing in pointers to functions. - -Fri Oct 6 21:07:22 1995 Mark H. Wilkinson - - * cvsrc.c (read_cvsrc): fix look up of command names in cvsrc file - to use full name from command table rather than possible nickname - in argv. Fixes errors with things like `cvs di' when cvsrc has - `diff -u5' in it. - -Thu Aug 3 01:03:52 1995 Vince DeMarco - - * parseinfo.c (Parse_Info): Add code to call expand_path function - instead of using built in code. - - * wrapper.c (wrap_add): Add code to call expand_path function to - expand all built in variables. - - * expand_path.c (New file): expand things that look like - environmental variables (only expand local CVS environmental - variables) and user names like ~/. - * cvs.h: Declare expand_path. - - * Makefile.in (SOURCES, OBJECTS): Added expand_path.c, - expand_path.o. - -Fri Oct 6 14:03:09 1995 Jim Kingdon - - * ignore.c (ign_setup): Don't try to look for a file in CVSroot if - client. (The recent tightening of the error checking detects this). - - * commit.c (checkaddfile): Don't try to pass options if it is "". - -Thu Oct 5 18:04:46 1995 Karl Fogel - - * sanity.sh: unset CVSREAD, since it causes the script to bomb. - -Thu Oct 5 18:29:17 1995 Jim Kingdon - - * remove.c, add.c, commit.c, cvs.h: Remove CVSEXT_OPT stuff; it - has been broken for ages and the options are already stored in the - Entries file. - -Thu Oct 5 18:20:13 1995 Norbert Kiesel - - * commit.c (checkaddfile): New argument options; pass it to RCS. - (commit_fileproc): Pass it. - -Tue Oct 3 09:26:00 1995 Karl Fogel - - * version.c: upped to 1.6. - -Mon Oct 2 18:10:35 1995 Larry Jones - - * server.c: if HAVE_SYS_BSDTYPES_H, include . - -Mon Oct 2 10:34:53 1995 Karl Fogel - - * version.c: Upped version to 1.5.95. - -Mon Oct 2 15:16:47 1995 Norbert Kiesel - - * tag.c, rtag.c: pass "mov" instead of "add" if tag will be moved - (i.e. invoked with -F) - -Sun Oct 1 18:36:34 1995 Karl Fogel - - * version.c: upped to 1.5.94. - - * server.c: reverted earlier ISC change (of Sep. 28). - - * version.c: upped to 1.5.93, for Peter Wemm's new SVR4 patch. - -Sun Oct 1 14:51:59 1995 Harlan Stenn - - * main.c: don't #include ; cvs.h does that already. - -Fri Sep 29 15:21:35 1995 Karl Fogel - - * version.c: upped to 1.5.91 for another pre-1.6 release. - -Fri Sep 29 14:41:14 1995 - - * root.c: start rcsid[] with "CVSid". - -Fri Sep 29 13:22:44 1995 Jim Blandy - - * diff.c (diff): Doc fix. - -Fri Sep 29 14:32:36 1995 Norbert Kiesel - - * repos.c (Short_Repository): chop superfluous "/". - - * tag.c (pretag_proc): correct user-visible string. - - * rtag.c (pretag_proc): correct user-visible string. - -Fri Sep 29 13:45:36 1995 Karl Fogel - - * cvs.h (USE): if __GNUC__ != 2, expand to a dummy var instead of - nothing. - -Thu Sep 28 13:37:05 1995 Larry Jones - - * server.c: ifdef ISC, include . - -Fri Sep 29 07:54:22 1995 Mike Sutton - - * filesubr.c (last_component): Don't use ANSI style declaration. - -Wed Sep 27 15:24:00 1995 Del - - * tag.c, rtag.c: Pass a few extra options to the script - named in taginfo (del/add, and revision number). - - * tag.c: Support a -r option (at long last). Also needs - a -f option to tag the head if there is no matching -r tag. - -Tue Sep 26 11:41:08 1995 Karl Fogel - - * version.c: Upped version to 1.5.89 for test release preceding - 1.6. - -Wed Sep 20 15:32:49 1995 Jim Kingdon - - * ignore.c (ign_add_file): Check for errors from fopen and fclose. - -Tue Sep 19 18:02:16 1995 Jim Blandy - - * Makefile.in (DISTFILES): Remove sanity.el from this list; the - file has been deleted. - -Thu Sep 14 14:17:52 1995 Peter Wemm - - * import.c: Recover from being unable to open the user file. - - * update.c (join_file): Print a message in the case where the file - was added. - - * mkmodules.c: Deal with .db as well as .pag/.dir (for use with - BSD 4.4 and real dbm support). - -Mon Sep 11 15:44:13 1995 Jim Kingdon - - * release.c (release): Revise comment regarding why and how we - skip argv[0]. - -Mon Sep 11 10:03:59 1995 Karl Fogel - - * release.c (release): use return value of pclose to determine - success of update. - -Mon Sep 11 09:56:33 1995 Jim Kingdon - - * release.c (release_delete): Fix comment. - -Sun Sep 10 18:48:35 1995 Karl Fogel - - * release.c (release): made work with client/server. - Don't ask if is mentioned in `modules'. - -Fri Sep 8 13:25:55 1995 Jim Kingdon - - * sanity.sh: When committing a removal, send stdout to LOGFILE; - this is no longer a silent operation. - - * sanity.sh: Remove OUTPUT variable; it is unused. - - * client.c: Add comment regarding deleting temp file. - * main.c: Add comment regarding getopt REQUIRE_ORDER. - -Thu Sep 7 20:24:46 1995 Karl Fogel - - * main.c (main): use getopt_long(), accept "--help" and - "--version". - Don't assume EOF is -1. - -Thu Sep 7 19:18:00 1995 Jim Blandy - - * cvs.h (unlink_file_dir): Add prototype for this. - -Thu Sep 7 14:38:06 1995 Karl Fogel - - * ALL FILES: add semicolon, as indicated below. - - * cvs.h (USE): don't provide semicolon in the expansion of the USE - macro; we'd rather the callers provided it themselves because that - way etags doesn't get fooled. - -Mon Sep 4 23:30:41 1995 Magnus Hyllander - - * checkout.c: cvs export now takes -k option and does not default - to -kv. - * checkout.c, cvs.h, modules.c: Modules file now takes -e option - for cvs export. - -Mon Sep 4 23:30:41 1995 Kirby Koster - - * commit.c: When committing a removal, print a message saying what - we are doing. - -Wed Aug 2 10:06:51 1995 Vince DeMarco - - * server.c: fix compiler warnings (on NeXT) (declare functions as - static inline instead of just static) functions: get_buffer_date, - buf_append_char, and buf_append_data - -Mon Sep 4 22:31:28 1995 Jim Kingdon - - * client.c (update_entries), import.c (expand_at_signs): Check for - errors from fread and putc. - -Fri Sep 1 00:03:17 1995 Jim Kingdon - - * sanity.sh: Fix TODO item pathname. - - * sanity.el: Removed. It was out of date, didn't do much, and I - doubt anyone was using it. - - * no_diff.c (No_Difference): Don't change the modes of the files. - -Thu Aug 31 13:14:34 1995 Jim Kingdon - - * version.c: Change version to 1.5.1. - - * client.c (start_rsh_server): Don't pass -d to "cvs server" - invocation via rsh (restore change which was lost when NT stuff - was merged in). - * sanity.sh: Add TODO item suggesting test for bug which this fixes. - -Wed Aug 30 12:36:37 1995 Jim Blandy - - * sanity.sh (basic1): Make sure first-dir is deleted before - running this set of tests. - - * subr.c: Extract file twiddling functions to a different file, - because we want to use different versions of many of these - routines under Windows NT. - (copy_file, isdir, islink, isfile, isreadable, iswritable, - open_file, make_directory, make_directories, xchmod, - rename_file, link_file, unlink_file, xcmp, tmpnam, - unlink_file_dir, deep_remove_dir): Moved to... - * filesubr.c: ...this file, which is new. - * Makefile.in (SOURCES): Mention filesubr.c. - (COMMON_OBJECTS): Mention filesubr.o. - - * subr.c: Extract process execution guts to a different file, - because we want to replace these routines entirely under - Windows NT. - (VA_START, va_alist, va_dcl): Move this stuff... - (run_add_arg, run_init_prog): and these declarations... - (run_prog, run_argv, run_argc, run_argc_allocated): and these - variables... - (run_setup, run_arg, run_args, run_add_arg, run_init_prog, - run_exec, run_print, Popen): and these functions... - * run.c: To this file, which is new. - * Makefile.in (SOURCES): Mention run.c. - (COMMON_OBJECTS): Mention run.o. - - * status.c (status): Call ign_setup, if client_active. Otherwise, - we don't end up ignoring CVS directories and such. - - * server.c (mkdir_p, dirswitch): Use CVS_MKDIR instead of mkdir. - - * repos.c (Name_Repository): Use the isabsolute function instead of - checking the first character of the path. - * root.c (Name_Root): Same. - - * release.c (release): Use fncmp instead of strcmp to compare - filenames. - - * rcs.c (RCS_parse, RCS_parsercsfile) [LINES_CRLF_TERMINATED]: - Abort, because we have strong reason to believe this code is - wrong. - - * patch.c (patch): Register signal handlers iff the signal name is - #defined. - - * no_diff.c (No_Difference): Don't try to include server_active in - trace message unless SERVER_SUPPORT is #defined. - - * modules.c (do_module): Use CVS_MKDIR instead of mkdir. - - * mkmodules.c (main): Call last_component instead of writing it out. - - * main.c (main): Call last_component instead of writing it out. - Break up the long copyright string into several strings; Microsoft - Visual C++ can't handle a line that long. Feh. - Use fncmp instead of strcmp to compare filenames. - Register signal handlers iff the signal name is #defined. - - * lock.c (readers_exist): Don't check return value of closedir. - Most of the rest of the code doesn't, and some systems don't - provide a return value anyway. - (set_lock): Use CVS_MKDIR instead of mkdir. - - * import.c (import): Use the isabsolute function instead of - checking the first character of the path. - Try to delete the temporary file again after we close it, so it'll - get deleted on systems that don't let you delete files that are - open. - (add_rev): Instead of making a hard link to the working file and - checking in the revision with ci -r, use ci -u and restore the - permission bits. - (comtable): Include lines from SYSTEM_COMMENT_TABLE, if it is - #defined. - (add_rcs_file) [LINES_CRLF_TERMINATED]: Abort, because we have - strong reason to believe this code is wrong. - (import_descend_dir): Use CVS_MKDIR instead of mkdir. - - * history.c (read_hrecs): Open the file with OPEN_BINARY. - - * find_names.c (add_entries_proc, fsortcmp): Add prototypes. - * entries.c (write_ent_proc): Add prototype. - * hash.c (walklist): Add prototype for PROC argument. - (sortlist): Add prototype for COMP argument. - (printnode): Add a prototype, and make it static. - - * cvs.h (wrap_add_file, wrap_add): Add extern decls for these; - they're used in import.c and update.c. - * wrapper.c (wrap_add_file, wrap_add): Remove them from here. - - * cvs.h (RUN_NORMAL, RUN_COMBINED, RUN_REALLY, RUN_STDOUT_APPEND, - RUN_STDERR_APPEND, RUN_SIGNIGNORE, RUN_TTY, run_arg, run_print, - run_setup, run_args, run_exec, Popen, piped_child, close_on_exec, - filter_stream_through_program, waitpid): Move all these - declarations and definitions to the same section. - - * cvs.h (error_set_cleanup): Fix prototype. - - * cvs.h (isabsolute, last_component): New extern decls. - - * cvs.h (link_file): Function is deleted; remove extern decl. - - * cvs.h (DEATH_STATE, DEATH_SUPPORT): Move #definitions of these - above the point where we #include rcs.h, since rcs.h tests them - (or DEATH_SUPPORT, at least). - - * cvs.h (DEVNULL): #define this iff it isn't already #defined. - config.h may want to override it. - - * cvs.h (SERVER_SUPPORT, CLIENT_SUPPORT): Don't #define these - here; let config.h do that. On some systems, we don't have any - server support. - - * cvs.h: Don't #include or ; we take care of - those in lib/system.h. - - * commit.c (commit): Open logfile with the OPEN_BINARY flag. - (precommit_proc): Use the isabsolute function, instead of - comparing the first character with /. - (remove_file, checkaddfile): Use CVS_MKDIR instead of mkdir. - - * client.c (send_repository): Use larger line buffers. - - * client.c [LINES_CRLF_TERMINATED] (update_entries): If we've just - received a gzipped file, copy it over, converting LF to CRLF, - instead of just renaming it into place. - [LINES_CRLF_TERMINATED] (send_modified): Convert file to LF format - before sending with gzip. - (send_modified): Don't be disturbed if we get fewer than - sb.st_size characters when we read. The read function may be - collapsing CRLF to LF for us. - - * client.c: Add forward declarations for all the cvs command - functions we call. - - * client.c: Add forward static declarations for all the - handle_mumble functions. - - On some systems, RSH converts LF to CRLF; this screws us up. - * client.c (rsh_pid): Declare this iff RSH_NOT_TRANSPARENT is not - #defined. - (get_responses_and_close): Use SHUTDOWN_SERVER if it is #defined. - Only wait for rsh process to exit if RSH_NOT_TRANSPARENT is not - #defined. - (start_rsh_server): Declare and define only if - RSH_NOT_TRANSPARENT is not #defined. Use piped_child, instead of - writing all that out. - (start_server): Only try to call start_rsh_server if - RSH_NOT_TRANSPARENT is not #defined. Use START_SERVER if it is - #defined. Convert file descriptors to stdio file pointers using - the FOPEN_BINARY_WRITE and FOPEN_BINARY_READ strings. - - * client.h (rsh_pid): Don't declare this; it's never used elsewhere. - (supported_request): Add external declaration for this; - it's used in checkout.c. - - Move process-running functions to run.c; we need to totally - replace these on other systems, like Windows NT. - * client.c (close_on_exec, filter_stream_through_program): Moved - to run.c. - * run.c (close_on_exec, filter_stream_through_program): Here they - are. - - * add.c (add_directory): Use CVS_MKDIR instead of straight mkdir. - * checkout.c (checkout, build_dirs_and_chdir): Same. - (checkout_proc): Use fncmp instead of strcmp. - * client.c (call_in_directory): Use CVS_MKDIR instead of straight - mkdir. - - * client.c (handle_checksum): Cast return value of strtol. - -Wed Aug 30 10:35:46 1995 Stefan Monnier - - * main.c (main): Allow -d to override CVSROOT_ENV. - -Thu Aug 24 18:57:49 1995 Jim Kingdon - - * cvs.h, rcscmds.c (RCS_unlock, RCS_deltag, RCS_lock): Add extra - parameter for whether to direct stderr to DEVNULL. - * checkin.c, tag.c, rtag.c, import.c, commit.c: Pass extra - argument. 1 if stderr had been directed to DEVNULL before - rcscmds.c was in use, 0 if it was RUN_TTY. - - * cvs.h: Add comment regarding attic. - -Tue Aug 22 10:09:29 1995 Alexander Dupuy - - * rcs.c (whitespace): Cast to unsigned char in case char is signed - and value is negative. - -Tue Aug 22 10:09:29 1995 Kirby Koster - and Jim Kingdon - - * update.c (join_file): If vers->vn_user is NULL, just return. - -Tue Aug 22 10:09:29 1995 Jim Kingdon - - * server.c, client.c: Add comments about modes and umasks. - -Mon Aug 21 12:54:14 1995 Rick Sladkey - - * update.c (update_filesdone_proc): If pipeout, don't try to - create CVS/Root. - -Mon Aug 21 12:54:14 1995 Jim Kingdon - - * client.c (start_rsh_server): Don't pass -d to "cvs server" - invocation via rsh. - - * server.c (serve_root): Report errors via pending_error_text. - (serve_valid_requests): Check for pending errors. - -Sun Aug 20 00:59:46 1995 Jim Kingdon - - * options.h.in: Document usage of DIFF in update.c - * update.c: Use DIFF -c, not DIFF -u. The small improvement in - diff size is not worth the hassle in terms of everyone having to - make sure that DIFF is GNU diff (IMHO). - -Sat Aug 19 22:05:46 1995 Jim Blandy - - * recurse.c (start_recursion): Doc fix. - - * server.c (do_cvs_command): Clear error_use_protocol in the - child. - (server): Set error_use_protocol. - -Sun Aug 13 15:33:37 1995 Jim Kingdon - - * server.c (do_cvs_command): Don't select on exceptions. - -Fri Aug 4 00:13:47 1995 Jim Meyering (meyering@comco.com) - - * Makefile.in (LDFLAGS): Set to @LDFLAGS@. - (options.h): Depend on ../config.status and options.h.in. - Add rule to build it from dependents. - - * add.c: Include save-cwd.h. - (add_directory): Use save_cwd and restore_cwd instead of - explicit getwd then chdir. - * import.c (import_descend_dir): Likewise. - * modules.c (do_module): Likewise. - - * recurse.c (save_cwd, restore_cwd, free_cwd): Remove functions. - New versions have been broken out into save-cwd.c. - (do_dir_proc): Adapt to handle status code returned by new versions - of save_cwd and restore_cwd -- and one fewer argument to restore_cwd. - (unroll_files_proc): Likewise. - - * wrapper.c (wrap_name_has): Add default: abort () to switch - statement to avoid warning from gcc -Wall. - (wrap_matching_entry): Remove dcl of unused TEMP. - (wrap_tocvs_process_file): Remove dcl of unused ERR. - (wrap_fromcvs_process_file): Likewise. - - * cvs.h: Remove prototype for error. Instead, include error.h. - Also, remove trailing white space. - -Thu Aug 3 10:12:20 1995 Jim Meyering (meyering@comco.com) - - * import.c (import_descend_dir): Don't print probably-bogus CWD - in error messages saying `cannot get working directory'. - -Sun Jul 30 20:52:04 1995 James Kingdon - - * parseinfo.c (Parse_Info): Revise comments and indentation. - -Sun Jul 30 15:30:16 1995 Vince DeMarco - - * history.c: put ifdef SERVER_SUPPORT around tracing code incase - the client/server code is not compiled into the program. - -Sat Jul 29 16:59:49 1995 James Kingdon - - * subr.c (deep_remove_dir): Use struct dirent, not struct direct. - -Sat Jul 29 18:32:06 1995 Vince DeMarco - - * add.c: Check wrap_name_has. - - * diff.c, checkin.c, import.c: have code call unlink_file_dir in - the appropriate places instead of just calling unlink_file. - - * checkin.c: Remove one unlink call. - - * import.c (comtable): Add .m .psw .pswm. - - * import.c (add_rcs_file): Remove tocvsPath before returning. - - * subr.c (unlink_file_dir): Add new function. unlinks the file if - it is a file. or will do a recursive delete if the path is - actually a directory. - (deep_remove_dir): New function, helps unlink_file_dir. - - * mkmodules.c: Added CVSROOTADM_WRAPPER (cvswrappers file) to the - checkout file list. - -Fri Jul 28 16:27:56 1995 James Kingdon - - * checkout.c (safe_location): Use PATH_MAX not MAXPATHLEN. - -Fri Jul 28 19:37:03 1995 Paul Eggert - - * log.c (cvslog, log_fileproc): Pass all options (except -l) - to rlog as-is, so that users can put spaces in options, - can specify multiple -d options, etc. - (ac, av): New variables. - (log_option_with_arg, options): Remove. - - (log_fileproc): Don't prepend `/' to file name if update_dir is empty. - -Tue Jul 25 00:52:26 1995 James Kingdon - - * checkout.c (safe_location): Don't use PROTO in function definition. - -Mon Jul 24 18:32:06 1995 Vince DeMarco - - * checkout.c (safe_location): fix a compiler warning. (Declare - safe_location). Changed code in safe_location to call getwd - instead of getcwd. getwd is declared in the ../lib directory and - used exclusively thoughout the code. (this helps portability on - non POSIX systems). - - * wrapper.c: updated Andrew Athan's email address. - - * main.c: fix an ifdef so the code will compile. syntax error in - the ifdef for CVS_NOADMIN. - -Mon Jul 24 13:25:00 1995 Del - - * checkout.c: New procedure safe_location. - Ensures that you don't check out into the repository - itself. - - * tag.c, rtag.c, cvs.h, mkmodules.c: Added a "taginfo" file in - CVSROOT to perform pre-tag checks. - - * main.c, options.h.in: Added a compile time option to - disable the admin command. - -Fri Jul 21 17:07:42 1995 James Kingdon - - * update.c, status.c, patch.c, checkout.c, import.c, release.c, - rtag.c, tag.c: Now -q and -Q options just print an error message - telling you to use global -q and -Q options. The non-global - options were a mess because some commands accepted them and some - did not, and they were redundant with -q and -Q global options. - - * rcs.c, cvs.h, commit.c, log.c, find_names.c: Remove CVS.dea - stuff. It is slower than the alternatives and I don't think - anyone ever actually used it. - -Fri Jul 21 10:35:10 1995 Vince DeMarco - - * Makefile.in (SOURCES, OBJECTS): Add wrapper.c, wrapper.o. - * add.c, admin.c, checkout.c, commit.c, diff.c, import.c, log.c, - remove.c, status.c: Call wrap_setup at start of commands. - * add.c (add): Check for wrapper, as well as directory, in repository. - * checkin.c: Add tocvsPath variable and associated handling. - * cvs.h: Add wrapper declarations. - * diff.c: Add tocvsPath variable and associated handling. - * import.c: Add -W option, CVSDOTWRAPPER handling. - (import_descend): check wrap_name_has. - (update_rcs_file, add_rev, add_rcs_file): add tocvsPath - variable and associated handling. - * no_diff.c: Add tocvsPath variable and associated handling. - * recurse.c (start_recursion): Check wrap_name_has. - * update.c: Copy, don't merge, copy-by-merge files. Attempt to - use -j on a copy-by-merge file generates a warning and no further - action. - * update.c: Add CVSDOTWRAPPER handling. - * wrapper.c: Added. - -Fri Jul 21 00:20:52 1995 James Kingdon - - * client.c: Revert David Lamkin patch, except for the bits about - removing temp_filename and the .rej file. - * sanity.sh (errmsg1): Test for the underlying bug which Lamkin - kludged around. - * client.c (call_in_directory): Set short_pathname to include the - filename, not just the directory. Improve comments regarding what - is passed to FUNC. - -Thu Jul 20 17:51:54 1995 David Lamkin - - * client.c (short_pathname): Fixes the fetching of the whole file - after a patch to bring it up to date has failed: - - failed_patches[] now holds short path to file that failed - - patch temp files are unlinked where the patch is done - -Thu Jul 20 12:37:10 1995 James Kingdon - - * cvs.h: Declare error_set_cleanup - * main.c: Call it. - (error_cleanup): New function. - -Thu Jul 20 12:17:16 1995 Mark H. Wilkinson - - * add.c, admin.c, checkin.c, checkout.c, classify.c, client.c, - client.h, commit.c, create_adm.c, cvs.h, diff.c, entries.c, - history.c, import.c, log.c, main.c, modules.c, no_diff.c, patch.c, - release.c, remove.c, repos.c, rtag.c, server.c, server.h, - status.c, subr.c, tag.c, update.c, vers_ts.c, version.c: Put - client code inside #ifdef CLIENT_SUPPORT, server code inside - #ifdef SERVER_SUPPORT. When reporting version, report whether - client and/or server are compiled in. - -Wed Jul 19 18:00:00 1995 Jim Blandy - - * subr.c (copy_file): Declare local var n to be an int, - not a size_t. size_t is unsigned, and the return values - of read and write are definitely not unsigned. - - * cvs.h [HAVE_IO_H]: #include . - [HAVE_DIRECT_H]: #include . - -Fri Jul 14 22:28:46 1995 Jim Blandy - - * server.c (dirswitch, serve_static_directory, serve_sticky, - serve_lost, server_write_entries, serve_checkin_prog, - serve_update_prog): Include more information in error messages. - (Thanks, DJM.) - - * cvsbug.sh: Use /usr/sbin/sendmail, unless it doesn't - exist, in which case use /usr/lib/sendmail. (Thanks, DJM.) - - * server.c (server, server_cleanup): Use "/tmp" instead of - "/usr/tmp" when the TMPDIR environment variable isn't set. This - is what the rest of the code uses. - -Thu Jul 13 11:03:17 1995 Jim Meyering (meyering@comco.com) - - * recurse.c (free_cwd): New function. - (save_cwd, restore_cwd): Use it instead of simply freeing any - string. The function also closes any open file descriptor. - - * import.c (comtable): Now static. - (comtable): Put braces around each element of initializer. - - * cvs.h: Add prototype for xgetwd. - * recurse.c (save_cwd, restore_cwd): New functions to encapsulate - run-time solution to secure-SunOS vs. fchown problem. - (do_dir_proc, unroll_files_proc): Use new functions instead of - open-coded fchdir/chdir calls with cpp directives. - - * sanity.sh: Change out of TESTDIR before removing it. - Some versions of rm fail when asked to delete the current directory. - -Wed Jul 12 22:35:04 1995 Jim Meyering (meyering@comco.com) - - * client.c (get_short_pathname): Add const qualifier to parameter dcl. - (copy_a_file): Remove set-but-not-used variable, LEN. - (handle_clear_static_directory): Likewise: SHORT_PATHNAME. - (set_sticky): Likewise: LEN. - (handle_set_sticky): Likewise: SHORT_PATHNAME. - (handle_clear_sticky): Likewise: SHORT_PATHNAME. - (start_rsh_server): Convert perl-style `cond || stmt' to more - conventional C-style `if (cond) stmt.' Sheesh. - Remove dcl of unused file-static, SEND_CONTENTS. - - * history.c: Remove dcls of set-but-not-used file-statics, - HISTSIZE, HISTDATA. - (read_hrecs): Don't set them. - - * import.c (add_rev): Remove dcl of set-but-not-used local, RETCODE. - - * repos.c (Name_Repository): Remove dcl of set-but-not-used local, - HAS_CVSADM. - - * cvsrc.c (read_cvsrc): Parenthesize assignment used as truth value. - -Tue Jul 11 16:49:41 1995 J.T. Conklin - - * hash.h (struct entnode, Entnode): moved from here... - * cvs.h: to here. - -Wed Jul 12 19:45:24 1995 Dominik Westner (dominik@gowest.ppp.informatik.uni-muenchen.de) - - * client.c (server_user): new var. - (parse_cvsroot): set above if repo is "user@host:/dir". - (start_rsh_server): if server_user set, then use it. - -Wed Jul 12 10:53:36 1995 Karl Fogel - - * sanity.sh: remove the TESTDIR after done. - - * cvsbug.sh (GNATS_ADDR): now bug-cvs@prep.ai.mit.edu again. - -Tue Jul 11 15:53:08 1995 Greg A. Woods - - * options.h.in: depend on configure for grep and diff, now that - changes to configure.in are applied. - -Tue Jul 11 14:32:14 1995 Michael Shields - - * Makefile.in (LDFLAGS): Pick up from configure. - -Tue Jul 11 14:20:00 1995 Loren James Rittle - - * import.c (add_rev), commit.c (remove_file, ci_new_rev), - checkin.c (Checkin), subr.c (make_message_rcslegal), cvs.h: - Always perform sanity check and fix-up on messages to be passed - directly to RCS via the '-m' switch. RCS 5.7 requires that a - non-total-whitespace, non-null message be provided or it will - abort with an error. CVS is not setup to handle any returned - error from 'ci' gracefully and, thus, the repository entered a - trashed state. - - * sanity.sh: Add regression tests for new code and interactions - with RCS 5.7. - -Sun Jul 9 19:03:00 1995 Greg A. Woods - - * .cvsignore: added new backup file - - * options.h.in: our new configure.in finds the right diff and - grep paths now.... - - * subr.c: quote the string in run_print() for visibility - - indent a comment - - Jun Hamano's xchmod() patch to prevent writable files - (from previous local changes) - - * logmsg.c: fix a NULL pointer de-reference - - clean up some string handling code... - (from previous local changes) - - * parseinfo.c: add hack to expand $CVSROOT in an *info file. - - document "ALL" and "DEFAULT" in opening comment for Parse_Info() - - fix the code to match the comments w.r.t. callbacks for "ALL" - - add a line of trace output... - (from previous local changes) - - * mkmodules.c: add support for comments in CVSROOT/checkoutlist - - add CVSroot used by something other .o, ala main.c - (from previous local changes) - - * main.c, cvs.h: add support for $VISUAL as log msg editor - (from previous local changes) - - * status.c: add support for -q and -Q (from previous local changes) - - -Sun Jul 9 18:44:32 1995 Karl Fogel - - * log.c: trivial change to test ChangeLog stuff. - -Sat Jul 8 20:33:57 1995 Paul Eggert - - * history.c: (history_write): Don't assume that fopen(..., "a") - lets one interleave writes to the history file from different processes - without interlocking. Use open's O_APPEND option instead. - Throw in an lseek to lessen the race bugs on non-Posix hosts. - * cvs.h, subr.c (Fopen): Remove. - - * log.c (log_fileproc): Pass working file name to rlog, so that - the name is reported correctly. - -Fri Jul 7 18:29:37 1995 Michael Hohmuth - - * client.c, client.h (client_import_setup): New function. - (client_import_done, client_process_import_file): Add comments - regarding now-redundant code. - * import.c (import): Call client_import_setup. - -Tue Jul 4 09:21:26 1995 Bernd Leibing - - * rcs.c (RCS_parsercsfile_i): Rename error to l_error; SunOS4 /bin/cc - doesn't like a label and function with the same name. - -Sun Jul 2 12:51:33 1995 Fred Appelman - - * logmsg.c: Rename strlist to str_list to avoid conflict with - Unixware 2.01. - -Thu Jun 29 17:37:22 1995 Paul Eggert - - * rcs.c (RCS_check_kflag): Allow RCS 5.7's new -kb option. - -Wed Jun 28 09:53:14 1995 James Kingdon - - * Makefile.in (HEADERS): Remove options.h.in. - (DISTFILES): Add options.h.in. - Depend on options.h in addition to HEADERS. - -Tue Jun 27 22:37:28 1995 Vince Demarco - - * subr.c: Don't try to do fancy waitstatus stuff for NeXT, - lib/wait.h is sufficient. - -Mon Jun 26 15:17:45 1995 James Kingdon - - * Makefile.in (DISTFILES): Remove RCS-patches and convert.sh. - -Fri Jun 23 13:38:28 1995 J.T. Conklin (jtc@rtl.cygnus.com) - - * server.c (dirswitch, serve_co): Use CVSADM macro instead of - literal "CVS". - -Fri Jun 23 00:00:51 1995 James Kingdon - - * README-rm-add: Do not talk about patching RCS, that only - confuses people. - * RCS-patches, convert.sh: Removed (likewise). - -Thu Jun 22 10:41:41 1995 James Kingdon - - * subr.c: Change -1 to (size_t)-1 when comparing against a size_t. - -Wed Jun 21 16:51:54 1995 nk@ipgate.col.sw-ley.de (Norbert Kiesel) - - * create_adm.c, entries.c, modules.c: Avoid coredumps if - timestamps, tags, etc., are NULL. - -Tue Jun 20 15:52:53 1995 Jim Meyering (meyering@comco.com) - - * checkout.c (checkout): Remove dcl of unused variable. - * client.c (call_in_directory, handle_clear_static_directory, - handle_set_sticky, handle_clear_sticky, send_a_repository, - send_modified, send_dirent_proc): Remove dcls of unused variables. - * server.c (receive_file, serve_modified, server_cleanup): - Remove dcls of unused variables. - * subr.c (copy_file): Remove dcl of unused variable. - * vers_ts.c (time_stamp_server): Remove dcl of unused variable. - -Mon Jun 19 13:49:35 1995 Jim Blandy - - * sanity.sh: Fix commencement message --- the test suite says - "Ok." when it's done. - -Fri Jun 16 11:23:44 1995 Jim Meyering (meyering@comco.com) - - * entries.c (fgetentent): Parenthesize assignment in if-conditional. - -Thu Jun 15 17:33:28 1995 J.T. Conklin - - * server.c (get_buffer_data, buf_append_char, buf_append_data): - Don't conditionalize use of "inline". Autoconf takes care of - defining it away on systems that don't grok it. - -Thu Jun 15 13:43:38 1995 Jim Kingdon (kingdon@cyclic.com) - - * options.h.in (DIFF): Default to "diff" not "diff -a" since diff - might not support the -a option. - -Wed Jun 14 11:29:42 1995 J.T. Conklin - - * import.c (import_descend): Initialize dirlist to NULL. - - * subr.c (copy_file): Fix infinite loop. - - * server.c (serve_directory): fix a memory leak. - - * checkout.c, commit.c, diff.c, history.c, import.c, log.c, - patch.c, release.c, remove.c, rtag.c, status.c, tag.c, update.c: - Use send_arg() to send command line arguments to server. - - * commit.c (fsortcmp), find_names (fsortcmp), hash.c (hashp, - findnode), hash.h (findnode), rcs.c (RCS_addnode, - RCS_check_kflag, RCS_check_tag, RCS_isdead, RCS_parse, - RCS_parsercsfile_i), rcs.h (RCS_addnode, RCS_check_kflag, - RCS_check_tag, RCS_parse): Added const qualifiers as - appropriate. - * rcs.h (RCS_isdead): Added prototype. - - * hash.h (walklist, sortlist): correct function prototypes. - - * ignore.c (ign_setup): don't bother checking to see if file - exists before calling ign_add_file. - -Fri Jun 9 11:24:06 1995 J.T. Conklin - - * all source files (rcsid): Added const qualifer. - * ignore.c (ign_default): Added const qualifier. - * subr.c (numdots): Added const qualifier to function argument. - * cvs.h (numdots): Added const qualifier to prototype argument. - - * client.c (change_mode): Tied consecutive if statements testing - the same variable together with else if. - - * import.c (import_descend): Build list of subdirectories when - reading directory, and then process the subdirectories in that - list. This change avoids I/O overhead of rereading directory - and reloading ignore list (.cvsignore) for each subdirectory. - -Thu Jun 8 11:54:24 1995 J.T. Conklin - - * import.c (import_descend): Use 4.4BSD d_type field if it is - present. - - * lock.c (set_lockers_name): Use %lu in format and cast st_uid - field to unsigned long. - - * import.c (import): Use RCS_check_kflag() to check -k options. - (keyword_usage, str2expmode, strn2expmode, expand_names): - Removed. - * rcs.c (RCS_check_kflag): Added keyword_usage array from import.c - for more descriptive error messages. - - * subr.c (run_setup, run_args): Changed variable argument - processing to work on machines that use . - - * subr.c (copy_file, xcmp): Changed to read the file(s) by blocks - rather than by reading the whole file into a huge buffer. The - claim that this was reasonable because source files tend to be - small does not hold up in real world situations. CVS is used - to manage non-source files, and mallocs of 400K+ buffers (x2 - for xcmp) can easily fail due to lack of available memory or - even memory pool fragmentation. - (block_read): New function, taken from GNU cmp and slightly - modified. - - * subr.c (xcmp): Added const qualifier to function arguments. - * cvs.h (xcmp): Added const qualifer to prototype arguments. - -Wed Jun 7 11:28:31 1995 J.T. Conklin - - * cvs.h (Popen): Added prototype. - (Fopen, open_file, isreadable, iswritable, isdir, isfile, - islink, make_directory, make_directories, rename_file, - link_file, unlink_file, copy_file): Added const qualifer to - prototype arguments. - * subr.c (Fopen, Popen, open_file, isreadable, iswritable, isdir, - isfile, islink, make_directory, make_directories, rename_file, - link_file, unlink_file, copy_file): Added const qualifier to - function arguments. - - * logmsg.c (logfile_write), recurse.c (do_recursion, addfile): - Don't cast void functions to a void expression. There is at - least one compiler (MPW) that balks at this. - - * rcs.c (keysize, valsize): Change type to size_t. - - * add.c (add_directory): Don't cast umask() argument to int. - - * import.c (add_rcs_file): Changed type of mode to mode_t. - - * rcscmds.c (RCS_merge): New function. - * cvs.h (RCS_merge): Declare. - * update.c (merge_file, join_file): Call RCS_merge instead of - invoking rcsmerge directly. - - * cvs.h: Include if HAVE_STDC_HEADERS, otherwise - declared getenv(). - * cvsrc.c, ignore.c, main.c: Removed getenv() declaration. - - * client.c (mode_to_string): Changed to take mode_t instead of - struct statb argument. Simplified implementation, no longer - overallocates storage for returned mode string. - * client.h (mode_to_string): Updated declaration. - * server.c (server_updated): Updated for new calling conventions, - pass st_mode instead of pointer to struct statb. - - * cvs.h (CONST): Removed definition, use of const qualifier is - determined by autoconf. - * history.c, modules.c, parseinfo.c: Use const instead of CONST. - - * add.c, admin.c, checkout.c, commit.c, diff.c, import.c, log.c, - main.c, mkmodules.c, patch.c, recurse.c, remove.c, rtag.c, - server.c, status.c, subr.c, tag.c, update.c: Changed function - arguments "char *argv[]" to "char **argv" to silence lint - warnings about performing arithmetic on arrays. - -Tue Jun 6 18:57:21 1995 Jim Blandy - - * version.c: Fix up version string, to say that this is Cyclic - CVS. - -Tue Jun 6 15:26:16 1995 J.T. Conklin - - * subr.c (run_setup, run_args, run_add_arg, xstrdup): Add const - qualifier to format argument. - * cvs.h (run_setup, run_args, xstrdup): Likewise. - - * Makefile.in (SOURCES): Added rcscmds.c. - (OBJECTS): Added rcscmds.o. - - * rcscmds.c: New file, with new functions RCS_settag, RCS_deltag, - RCS_setbranch, RCS_lock, RCS_unlock. - * checkin.c, commit.c, import.c, rtag.c, tag.c: Call above - functions instead of exec'ing rcs commands. - * cvs.h: Declare new functions. - -Mon May 29 21:40:54 1995 J.T. Conklin (jtc@rtl.cygnus.com) - - * recurse.c (start_recursion, do_recursion): Set entries to NULL - after calling Entries_Close(). - -Sat May 27 08:08:18 1995 Jim Meyering (meyering@comco.com) - - * Makefile.in (check): Export RCSBIN only if there exists an - `rcs' executable in ../../rcs/src. Before, tests would fail when - the directory existed but contained no executables. - (distclean): Remove options.h, now that it's generated. - (Makefile): Regenerate only *this* file when Makefile.in is - out of date. Depend on ../config.status. - -Fri May 26 14:34:28 1995 J.T. Conklin - - * entries.c (Entries_Open): Added missing fclose(). - (Entries_Close): Don't write Entries unless Entries.Log exists. - - * entries.c (Entries_Open): Renamed from ParseEntries; changed to - process Entries Log files left over from previous crashes or - aborted runs. - (Entries_Close): New function, write out Entries file if - neccessary and erase Log file. - (Register): Append changed records to Log file instead of - re-writing file. - (fgetentent): New function, parse one Entry record from a file. - (AddEntryNode): It's no longer an error for two records with the - same name to be added to the list. New records replace older - ones. - * cvs.h (Entries_Open, Entries_Close): Add prototypes. - (CVSADM_ENTLOG): New constant, name of Entries Log file. - * add.c, checkout.c, client.c, find_names.c, recurse.c: Use - Entries_Open()/Entries_Close() instead of ParseEntries()/dellist(). - - * add.c, admin.c, checkout.c, client.c, commit.c, diff.c, - history.c, import.c, log.c, patch.c, release.c, remove.c, - rtag.c, server.c, status.c, tag.c, update.c: Changed - conditionals so that return value of *printf is tested less than - 0 instead of equal to EOF. - -Thu May 25 08:30:12 1995 Jim Kingdon (kingdon@lioth.cygnus.com) - - * subr.c (xmalloc): Never try to malloc zero bytes; if the user - asks for zero bytes, malloc one instead. - -Wed May 24 12:44:25 1995 Ken Raeburn - - * subr.c (xmalloc): Don't complain about NULL if zero bytes were - requested. - -Tue May 16 21:49:05 1995 Jim Blandy - - * subr.c (xmalloc): Never try to malloc zero bytes; if the user - asks for zero bytes, malloc one instead. - -Mon May 15 14:35:11 1995 J.T. Conklin - - * lock.c (L_LOCK_OWNED): Removed. - - * add.c, checkout.c, client.c, create_adm.c, cvs.h, entries.c, - find_names.c modules.c, recurse.c, release.c, repos.c, update.c: - removed CVS 1.2 compatibility/upgrade code. - -Mon May 8 11:25:07 1995 J.T. Conklin - - * lock.c (write_lock): Missed one instance where rmdir(tmp) should - have been changed to clear_lock(). - -Wed May 3 11:08:32 1995 J.T. Conklin - - * create_adm.c, entries.c, import.c, root.c: Changed conditionals - so that return value of *printf is tested less than 0 instead of - equal to EOF --- That's all Standard C requires. - -Wed May 3 18:03:37 1995 Samuel Tardieu - - * rcs.h: removed #ifdef CVS_PRIVATE and #endif because cvs didn't - compile anymore. - -Mon May 1 13:58:53 1995 J.T. Conklin - - * rcs.c, rcs.h: Implemented lazy parsing of rcs files. - RCS_parsercsfile_i modified to read only the first two records - of rcs files, a new function RCS_reparsercsfile is called only - when additional information (tags, revision numbers, dates, - etc.) is required. - -Mon May 1 12:20:02 1995 Jim Kingdon (kingdon@lioth.cygnus.com) - - * Makefile.in (INCLUDES): Include -I. for options.h. - -Fri Apr 28 16:16:33 1995 Jim Blandy - - * Makefile.in (SOURCES, HEADERS, DISTFILES): Updated. - (dist-dir): Renamed from dist; changed to work with DISTDIR - variable passed from parent. - - We don't want to include a file the user has to edit in the - distribution. - * options.h: No longer distributed. - * options.h.in: Distribute this instead. - * ../INSTALL, ../README: Installation instructions updated. - - * client.c (start_rsh_server): Send the remote command to rsh as a - single string. - -Fri Apr 28 00:29:49 1995 Noel Cragg - - * commit.c: Added initializer for FORCE_CI - - * sanity.sh: Fix tests added 25 Apr -- they were expecting the - server to make noise, but the CVS_SERVER variable had been - accidentally set with the `-Q' flag. Ran all tests -- both - locally and remotely -- to verify that the change didn't break - anything. - -Thu Apr 27 12:41:52 1995 Jim Kingdon (kingdon@lioth.cygnus.com) - - * Makefile.in: Revise comment regarding check vs. remotecheck. - -Thu Apr 27 12:52:28 1995 Bryan O'Sullivan - - * client.c (start_rsh_server): If the CVS_RSH environment variable - is set, use its contents as the name of the program to invoke - instead of `rsh'. - -Thu Apr 27 12:18:38 1995 Noel Cragg - - * checkout.c (checkout): To fix new bug created by Apr 23 change, - re-enabled "expand-module" functionality, because it has the side - effect of setting the checkin/update programs for a directory. To - solve the local/remote checkout problem that prompted this change - in the first place, I performed the next change. - * server.c (expand_proc): Now returns expansions for aliases only. - -Wed Apr 26 12:07:42 1995 J.T. Conklin - - * rcs.c (getrcskey): Rewritten to process runs of whitespace chars - and rcs @ strings instead of using state variables "white" and - "funky". - -Fri Apr 7 15:49:25 1995 J.T. Conklin - - * lock.c (unlock): Only call stat if we need to. - -Wed Apr 26 10:48:44 1995 Jim Kingdon (kingdon@lioth.cygnus.com) - - * server.c (new_entries_line): Don't prototype. - -Tue Apr 25 22:19:16 1995 Jim Blandy - - * sanity.sh: Add new tests to catch bugs in Apr 23 change. - -Tue Apr 25 17:10:55 1995 Roland McGrath - - * create_adm.c (Create_Admin): Use getwd instead of getcwd. - -Sun Apr 23 20:58:32 1995 Noel Cragg - - * checkout.c (checkout): Disabled "expand-module" functionality on - remote checkout, since it makes modules behave like aliases (see - longer note there). This change necessitated the change below. - Also merged the like parts of a conditional. - - * client.c (call_in_directory): Changed the algorithm that created - nested and directories and the "CVS" administration directories - therein. The algoithm wrongly assumed that the name of the - directory that that was to be created and the repository name were - the same, which breaks modules. - - * create_adm.c (Create_Admin), module.c (do_module), server.c - (server_register), subr.c, entries.c: Added fprintfs for trace-mode - debugging. - - * client.c (client_send_expansions): Argument to function didn't - have a type -- added one. - - * server.c (new_entries_line): Arguments to this function are - never used -- reoved them and fixed callers. - -Sat Apr 22 11:17:20 1995 Jim Kingdon (kingdon@lioth.cygnus.com) - - * rcs.c (RCS_parse): If we can't open the file, give an error - message (except for ENOENT in case callers rely on that). - -Wed Apr 19 08:52:37 1995 Jim Kingdon (kingdon@lioth.cygnus.com) - - * client.c (send_repository): Check for CVSADM_ENTSTAT in `dir', not - in `.'. - - * sanity.sh: Add TODO list. Revise some comments. Add tests of - one working directory adding a file and other updating it. - -Sat Apr 8 14:52:55 1995 Jim Blandy - - * Makefile.in (CFLAGS): Let configure set the default for CFLAGS. - Under GCC, we want -g -O. - -Fri Apr 7 15:49:25 1995 J.T. Conklin - - * root.c (Name_Root): merge identical adjacent conditionals. - - * create_admin.c (Create_Admin): Rearranged check for CVSADM and - OCVSADM directories so that CVSADM pathname is only built once. - - * update.c (update_dirleave_proc): Removed code to remove CVS - administration directory if command_name == "export" and to - create CVS/Root file if it is not present. Identical code - in update_filesdone_proc() will perform these same actions. - Also removed code that read and verfied CVS/Root. This is - expensive, and if it is necessary should happen in the - general recursion processor rather than in the update - callbacks. - - * lock.c (masterlock): New variable, pathname of master lockdir. - (set_lock): removed lockdir argument, now constructs it itself - and stores it in masterlock. - (clear_lock): new function, removes master lockdir. - (Reader_Lock, write_lock): call clear_lock instead of removing - master lockdir. - (Reader_Lock, write_lock): #ifdef'd out CVSTFL code. - - * main.c (main): register Lock_Cleanup signal handler. - * lock.c (Reader_Lock, write_lock): no longer register - Lock_Cleanup. - - * main.c (main): initialize new array hostname. - * lock.c (Reader_Lock, write_lock): Use global hostname array. - * logmsg.c (logfile_write): Likewise. - - * recurse.c (do_dir_proc, unroll_files_proc): Use open()/fchdir() - instead of getwd()/chdir() on systems that support the fchdir() - system call. - -Fri Apr 7 06:57:20 1995 Jim Kingdon (kingdon@lioth.cygnus.com) - - * server.c: Include the word "server" in error message for memory - exhausted, so the user knows which machine ran out of memory. - - * sanity.sh: For remote, set CVS_SERVER to test the right server, - rather than a random one from the PATH. - - * commit.c [DEATH_STATE]: Pass -f to `ci'. - -Thu Apr 6 13:05:15 1995 Jim Blandy - - * commit.c (checkaddfile): If we didn't manage to fopen the file, - don't try to fclose it. - - * client.c (handle_m, handle_e): Use fwrite, rather than a loop of - putc's. Sometimes these streams are unbuffered. - -Tue Apr 4 11:33:56 1995 Jim Blandy - - * (DISTFILES): Include cvsbug.sh, ChangeLog, NOTES, RCS-patches, - README-rm-add, ChangeLog.fsf, sanity.sh, sanity.el, and - .cvsignore. - -Mon Mar 27 08:58:42 1995 Jim Kingdon (kingdon@lioth.cygnus.com) - - * rcs.c (RCS_parsercsfile_i): Accept `dead' state regardless of - DEATH_STATE define. Revise comments regarding DEATH_STATE versus - CVSDEA versus the scheme which uses a patched RCS. - * README-rm-add, RCS-patches: Explain what versions of CVS need - RCS patches. - -Sat Mar 25 18:51:39 1995 Roland McGrath - - * server.c (server_cleanup): Only do the abysmal kludge of waiting - for command and draining the pipe #ifdef sun. The code makes - assumptions not valid on all systems, and is only there to - workaround a SunOS bug. - -Wed Mar 22 21:55:56 1995 Jim Kingdon (kingdon@lioth.cygnus.com) - - * server.c (mkdir_p): Call stat only if we get the EACCES. Faster - and more elegant. - -Tue Jan 31 20:59:19 1995 Ken Raeburn - - * server.c: Try to avoid starting the "rm -rf" at cleanup time - until after subprocesses have finished. - (command_fds_to_drain, max_command_fd): New variables. - (do_cvs_command): Set them. - (command_pid_is_dead): New variable. - (wait_sig): New function. - (server_cleanup): If command_pid is nonzero, wait for it to die, - draining output from it in the meantime. If nonzero SIG was - passed, send a signal to the subprocess, to encourage it to die - soon. - - * main.c (usage): Argument is now `const char *const *'. - * cvs.h (usage): Changed prototype. - (USE): Make new variable `const'. - * add.c (add_usage), admin.c (admin_usage), checkout.c - (checkout_usage, export_usage, checkout), commit.c (commit_usage), - diff.c (diff_usage), history.c (history_usg), import.c - (import_usage, keyword_usage), log.c (log_usage), main.c (usg), - patch.c (patch_usage), release.c (release_usage), remove.c - (remove_usage), rtag.c (rtag_usage), server.c (server), status.c - (status_usage), tag.c (tag_usage), update.c (update_usage): Usage - messages are now const arrays of pointers to const char. - - * import.c (comtable): Now const. - * main.c (rcsid): Now static. - (cmd): Now const. - (main): Local variable CM now points to const. - * server.c (outbuf_memory_error): Local var MSG now const. - - * client.c (client_commit_usage): Deleted. - -Sat Dec 31 15:51:55 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * logmsg.c (do_editor): Allocate enough space for trailing '\0'. - -Fri Mar 3 11:59:49 1995 Jim Blandy - - * cvsbug.sh: Call it "Cyclic CVS" now, not "Remote CVS". Call it - version C1.4A, not 1.4A2-remote. Send bugs to cyclic-cvs, not - remote-cvs. - - * classify.c (Classify_File): Put check for dead file inside - "#ifdef DEATH_SUPPORT". - -Thu Feb 23 23:03:43 1995 Jim Blandy - - * update.c (join_file): Don't pass the -E option to rcsmerge here, - either (see Jan 22 change). - -Mon Feb 13 13:28:46 1995 Jim Blandy - - * cvsbug.sh: Send bug reports to remote-cvs@cyclic.com, rather - than to the ordinary CVS bug address. This does mean we'll have - to wade through GNATS-style bug reports, sigh. - -Wed Feb 8 06:42:27 1995 Roland McGrath - - * server.c: Don't include ; system.h already does, and - 4.3BSD can't take it twice. - - * subr.c [! HAVE_VPRINTF] (run_setup, run_args): Don't use va_dcl - in declaration. Declare the a1..a8 args which are used in the - sprintf call. - * cvs.h [! HAVE_VPRINTF] (run_setup, run_args): Don't prototype - args, to avoid conflicting with the function definitions - themselves. - -Tue Feb 7 20:10:00 1995 Jim Blandy - - * client.c (update_entries): Pass the patch subprocess the switch - "-b ~", not "-b~"; the latter form seems not to work with patch - version 2.0 and earlier --- it takes the next argv element as the - backup suffix, and thus doesn't notice that the patch file's name - has been specified, thus doesn't find the patch, thus... *aargh* - -Fri Feb 3 20:28:21 1995 Jim Blandy - - * log.c (log_option_with_arg): New function. - (cvslog): Use it and send_arg to handle the rlog options that take - arguments. The code used to use send_option_string for - everything, which assumes that "-d1995/01/02" is equivalent to - "-d -1 -9 -9 -5 ...". - -Tue Jan 31 15:02:01 1995 Jim Blandy - - * server.c: #include for the new stat call in mkdir_p. - (mkdir_p): Don't try to create the intermediate directory if it - exists already. Some systems return EEXIST, but others return - EACCES, which we can't otherwise distinguish from a real access - problem. - -Sun Jan 22 15:25:45 1995 Jim Blandy - - * update.c (merge_file): My rcsmerge doesn't accept a -E option, - and it doesn't look too important, so don't pass it. - -Fri Jan 20 14:24:58 1995 Ian Lance Taylor - - * client.c (do_deferred_progs): Don't try to chdir to toplevel_wd - if it has not been set. - (process_prune_candidates): Likewise. - -Mon Nov 28 09:59:14 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * client.c (client_commit): Move guts of function from here... - * commit.c (commit): ...to here. - -Mon Nov 28 15:14:36 1994 Ken Raeburn - - * server.c (buf_input_data, buf_send_output): Start cpp directives - in column 1, otherwise Sun 4 pcc complains. - -Mon Nov 28 09:59:14 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * client.c (add_prune_candidate): Don't try to prune ".". - -Tue Nov 22 05:27:10 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * server.c, client.c: More formatting cleanups. - - * client.h, client.c: New variable client_prune_dirs. - * update.c (update), checkout.c (checkout): Set it. - * client.c (add_prune_candidate, process_prune_candidates): New - functions. - (send_repository, call_in_directory, get_responses_and_close): - Call them. - -Wed Nov 23 01:17:32 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * server.c (do_cvs_command): Don't select on STDOUT_FILENO unless - we have something to write. - -Tue Nov 22 05:27:10 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * remove.c (remove_fileproc): Only call server_checked_in if we - actually are changing the entries file. - - * server.c (server_write_entries): New function. - (dirswitch, do_cvs_command): Call it. - (serve_entry, serve_updated): Just update in-memory data - structures, don't mess with CVS/Entries file. - -Mon Nov 21 10:15:11 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * server.c (server_checked_in): Set scratched_file to NULL after - using it. - - * checkin.c (Checkin): If the file was changed by the checkin, - call server_updated not server_checked_in. - -Sun Nov 20 08:01:51 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * client.c (send_repository): Move check for update_dir NULL to - before where we check last_update_dir. Check for "" here too. - - * client.c (send_repository): Use new argument dir. - - * client.c: Pass new argument dir to send_repository and - send_a_repository. - - * server.c, server.h (server_prog): New function. - * modules.c (do_modules): Call it if server_expanding. - * client.c: Support Set-checkin-prog and Set-update-prog responses. - * server.c, client.c: Add Checkin-prog and Update-prog requests. - -Fri Nov 18 14:04:38 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * client.c (get_short_pathname, is_cvsroot_level, - call_in_directory): Base whether this is new-style or - old-style based on whether we actually used the Directory request, - not based on whether the pathname is absolute. Rename - directory_supported to use_directory. - * server.c: Rename use_relative_pathnames to use_dir_and_repos. - * client.c (send_a_repository): If update_dir is absolute, don't - use it to try to reconstruct how far we have recursed. - - * server.c, server.h, client.c, client.h, vers_ts.c, update.h: - More cosmetic changes (identation, PARAMS vs. PROTO, eliminate - alloca, etc.) to remote CVS to make it more like the rest of CVS. - - * server.c: Make server_temp_dir just the dir name, not the name - with "%s" at the end. - * server.c, client.c: Add "Max-dotdot" request, and use it to make - extra directories in server_temp_dir if needed. - -Thu Nov 17 09:03:28 1994 Jim Kingdon - - * client.c: Fix two cases where NULL was used and 0 was meant. - -Mon Nov 14 08:48:41 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * server.c (serve_unchanged): Set noexec to 0 when calling Register. - - * update.c (merge_file): Don't call xcmp if noexec. - -Fri Nov 11 13:58:22 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * client.c (call_in_directory): Deal with it if reposdirname is - not a subdirectory of toplevel_repos. - -Mon Nov 7 09:12:01 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * patch.c: If file is removed and we don't have a tag or date, - just print "current release". - - * classify.c (Classify_File): Treat dead files appropriately. - -Fri Nov 4 07:33:03 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * main.c (main) [SERVER_SUPPORT]: Move call to getwd past where we - know whether we are the server or not. Set CurDir to "" - if we are the server. - - * client.c: Remove #if 0'd function option_with_arg. - Remove #if 0'd code pertaining to the old way of logging the - session. - - * client.c (start_rsh_server): Don't invoke the server with the - -d option. - * server.c (serve_root): Test root for validity, just like main.c - does for non-remote CVS. - * main.c (main): If `cvs server' happens with a colon in the - CVSroot, just handle it normally; don't make it an error. - -Wed Nov 2 11:09:38 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * client.c (send_dirent_proc): If dir does not exist, just return - R_SKIP_ALL. - - * server.c, client.c: Add Directory request and support for - local relative pathnames (along with the repository absolute - pathnames). - * update.c, add.c, checkout.c, checkin.c, cvs.h, create_adm.c, - commit.c, modules.c, server.c, server.h, remove.c, client.h: - Pass update_dir to server_* functions. Include update_dir in - more error messages. - -Fri Oct 28 08:54:00 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * client.c: Reformat to bring closer to cvs standards for brace - position, comment formatting, etc. - - * sanity.sh: Remove wrong "last mod" line. Convert more tests to - put PASS or FAIL in log file. Change it so arguments to the - script specify which tests to run. - - * client.c, client.h, server.c, checkout.c: Expand modules in - separate step from the checkout itself. - -Sat Oct 22 20:33:35 1994 Ken Raeburn (raeburn@kr-pc.cygnus.com) - - * update.c (join_file): When checking for null return from - RCS_getversion, still do return even if quiet flag is set. - -Thu Oct 13 07:36:11 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * client.c (send_files): Call send_repository even if - toplevel_repos was NULL. - - * server.c (server_updated): If joining, don't remove file. - - * update.c (join_file): If server and file is unmodified, check it - out before joining. After joining, call server_updated. New - argument repository. - - * server.c, server.h (server_copy_file): New function. - * update.c (update_file_proc, join_file): Call it. - * client.c (copy_file, handle_copy_file): New functions. - * client.c (responses): Add "Copy-file". - - * client.c, client.h: Make toplevel_wd, failed_patches and - failed_patches_count extern. - * client.c (client_update): Move guts of function from here... - * update.c (update): ...to here. - - * client.c, checkout.c: Likewise for checkout. - - * client.c (is_cvsroot_level): New function. - (handle_set_sticky, handle_clear_sticky, - handle_clear_static_directory): Call it, instead of checking - short_pathname for a slash. - - * client.c, client.h (client_process_import_file, - client_import_done): New functions. - * import.c (import, import_descend): Use them. - * import.c (import_descend): If server, don't mention ignored CVS - directories. - * import.c (import_descend_dir): If client, don't print warm - fuzzies, or make directories in repository. If server, print warm - fuzzies to stdout not stderr. - * client.c (send_modified): New function, broken out from - send_fileproc. - (send_fileproc): Call it. - - * client.c (handle_clear_sticky, handle_set_sticky, - handle_clear_static_directory, handle_set_static_directory): If - command is export, just return. - (call_in_directory, update_entries): If command is export, don't - create CVS directories, CVS/Entries files, etc. - * update.c (update_filesdone_proc): Don't remove CVS directories if - client_active. - - * client.c (send_a_repository): Instead of insisting that - repository end with update_dir, just strip as many pathname - components from the end as there are in update_dir. - - * Makefile.in (remotecheck): New target, pass -r to sanity.sh. - * sanity.sh: Accept -r argument which means to test remote cvs. - - * tag.c (tag), rtag.c (rtag), patch.c (patch), import.c (import), - admin.c (admin), release.c (release): If client_active, connect to - the server and send the right requests. - * main.c (cmds): Add these commands. - (main): Remove code which would strip hostname off cvsroot and try - the command locally. There are no longer any commands which are - not supported. - * client.c, client.h (client_rdiff, client_tag, client_rtag, - client_import, client_admin, client_export, client_history, - client_release): New functions. - * server.c (serve_rdiff, serve_tag, serve_rtag, serve_import, - serve_admin, serve_export, serve_history, serve_release): New - functions. - (requests): List them. - * server.c: Declare cvs commands (add, admin, etc.). - * cvs.h, server.h: Don't declare any of them here. - * main.c: Restore declarations of cvs commands which were - previously removed. - - * cvs.h: New define DEATH_STATE, commented out for now. - * rcs.c (RCS_parsercsfile_i), commit.c (remove_file, checkaddfile) - [DEATH_STATE]: Use RCS state to record a dead file. - -Mon Oct 3 09:44:54 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * status.c (status_fileproc): Now that ts_rcs is just one time, - don't try to print the second time from it. (Same as raeburn 20 - Aug change, it accidentally got lost in 1.4 Alpha-1 merge). - - * cvs.h (CVSDEA): Added (but commented out for now). - * rcs.c (RCS_parsercsfile_i) [CVSDEA]: Also look in CVSDEA to see if - something is dead. - * commit.c (ci_new_rev, mark_file) [CVSDEA]: New functions. - (remove_file, checkaddfile) [CVSDEA]: Use them instead of ci -K. - * find_names.c (find_dirs) [CVSDEA]: Don't match CVSDEA directories. - * update.c (checkout_file): Check RCS_isdead rather than relying - on co to not create the file. - - * sanity.sh: Direct output to logfile, not /dev/null. - - * subr.c (run_exec): Print error message if we are unable to exec. - - * commit.c (remove_file): Call Scratch_Entry when removing tag - from file. The DEATH_SUPPORT ifdef was erroneous. - -Sun Oct 2 20:33:27 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * commit.c (checkaddfile): Instead of calling isdir before - attempting to create the directory, just ignore EEXIST errors from - mkdir. (This removes some DEATH_SUPPORT ifdefs which actually had - nothing to do with death support). - -Thu Sep 29 09:23:57 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * diff.c (diff): Search attic too if we have a second tag/date. - (diff_fileproc): If we have a second tag/date, don't do all the - checking regarding the user file. - -Mon Sep 26 12:02:15 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * checkin.c (Checkin): Check for error from unlink_file. - -Mon Sep 26 08:51:10 1994 Anthony J. Lill (ajlill@ajlc.waterloo.on.ca) - - * rcs.c (getrcskey): Allocate space for terminating '\0' if - necessary. - -Sat Sep 24 09:07:37 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * commit.c (commit_fileproc): Set got_message = 1 when calling - do_editor (accidentally omitted from last change). - -Fri Sep 23 11:59:25 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - Revert buggy parts of Rich's change of 1 Nov 1993 (keeping the - dynamic buffer allocation, which was the point of that change). - * logmsg.c (do_editor): Reinstate message arg, but make it char - **messagep instead of char *message. Change occurances of message - to *messagep. Char return type from char * back to void. - * cvs.h: Change do_editor declaration. - * commit.c: Reinstate got_message variable - (commit_filesdoneproc, commit_fileproc, commit_direntproc): Use it. - * import.c (import), commit.c (commit_fileproc, - commit_direntproc): Pass &message to do_editor; don't expect it to - return a value. - * client.c (client_commit): Likewise. - * import.c (import): Deal with it if message is NULL. - -Wed Sep 21 09:43:25 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * server.c (server_updated): If the file doesn't exist, skip it. - - * diff.c, client.h, client.c: Rename diff_client_senddate to - client_senddate and move from diff.c to client.c. - * client.c (client_update, client_checkout): Use it. - -Sat Sep 17 08:36:58 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * checkout.c (checkout_proc): Don't pass NULL to Register for - version. (should fix "cvs co -r " - coredump on Solaris). - -Fri Sep 16 08:38:02 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * diff.c (diff_fileproc): Set top_rev from vn_user, not vn_rcs. - Rename it to user_file_rev because it need not be the head of any - branch. - (diff_file_nodiff): After checking user_file_rev, if we have both - use_rev1 and use_rev2, compare them instead of going on to code - which assumes use_rev2 == NULL. - -Thu Sep 15 08:20:23 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * status.c (status): Return a value in client_active case. - -Thu Sep 15 15:02:12 1994 Ian Lance Taylor (ian@sanguine.cygnus.com) - - * server.c (serve_modified): Create the file even if the size is - zero. - -Thu Sep 15 08:20:23 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * lock.c (readers_exist): Clear errno each time around the loop, - not just the first time. - - * client.c (start_server): Don't send Global_option -q twice. - - * no_diff.c (No_Difference): Check for error from unlink. - - * no_diff.c, cvs.h (No_Difference): New args repository, - update_dir. Call server_update_entries if needed. Use update_dir - in error message. - * classify.c (Classify_File): Pass new args to No_Difference. - - * server.c (server_update_entries, server_checked_in, - server_updated): Don't do anything if noexec. - - * client.c (send_fileproc): Rather than guessing how big the gzip - output may be, just realloc the buffer as needed. - -Tue Sep 13 13:22:03 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * lock.c: Check for errors from unlink, readdir, and closedir. - - * classify.c (Classify_File): Pass repository and update_dir to - sticky_ck. - (sticky_ck): New args repository and update_dir. - * server.c, server.h (server_update_entries): New function. - * classify.c (sticky_ck): Call it. - * client.c: New response "New-entry". - * client.c (send_fileproc): Send tag/date from vers->entdata, not - from vers itself. - -Mon Sep 12 07:07:05 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * server.c: Clean up formatting ("= (errno)" -> "= errno"). - - * cvs.h: Declare strerror. - - * client.c: Add code to deal with Set-sticky and Clear-sticky - responses, and Sticky request. - * server.c: Add code to deal with Sticky request. - * server.c, server.h (server_set_sticky): New function. - * create_adm.c (Create_Admin), update.c (update, update_dirent_proc), - commit.c (commit_dirleaveproc): Call it. - * client.c, client.h (send_files): Add parameter aflag. - * add.c (add), diff.c (diff), log.c (cvslog), remove.c (cvsremove), - status.c (status), - client.c (client_commit, client_update, client_checkout): Pass it. - * client.c (client_update): Add -A flag. - -Fri Sep 9 07:05:35 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * entries.c (WriteTag): Check for error from unlink_file. - - * server.c (server_updated): Initialize size to 0. Previously if - the file was zero length, the variable size got used without being - set. - -Thu Sep 8 14:23:05 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * server.c (serve_repository): Check for error from fopen on - CVSADM_ENT. - - * update.c (update, update_dirent_proc): Check for errors when - removing Entries.Static. - - * client.c: Add code to deal with Set-static-directory and - Clear-static-directory responses, and Static-directory request. - * server.c, server.h (server_clear_entstat, server_set_entstat): - New functions. - * update.c, checkout.c, modules.c: Call them. - * server.c: Add code to deal with Static-directory request. - - * server.c, client.c: Use strchr and strrchr instead of index and - rindex. - - * server.c (serve_unchanged, serve_lost): Change comments which - referred to changing timestamp; we don't always change the - timestamp in those cases anymore. - -Wed Sep 7 10:58:12 1994 J.T. Conklin (jtc@rtl.cygnus.com) - - * cvsrc.c (read_cvsrc): Don't call getenv() three times when one - time will do. - - * subr.c (xmalloc, xrealloc): Change type of bytes argument from - int to size_t and remove the test that checks if it is less than - zero. - * cvs.h (xmalloc, xrealloc): Update prototype. - -Thu Sep 1 12:22:20 1994 Jim Kingdon (kingdon@cygnus.com) - - * update.c (merge_file, join_file): Pass -E to rcsmerge. - (merge_file): If rcsmerge doesn't change the file, say so. - - * recurse.c, cvs.h (start_recursion): New argument wd_is_repos. - * recurse.c (start_recursion): Use it instead of checking whether - command_name is rtag to find out if we are cd'd to the repository. - * client.c, update.c, commit.c, status.c, diff.c, log.c, admin.c, - remove.c, tag.c: Pass 0 for wd_is_repos. - * rtag.c, patch.c: Pass 1 for wd_is_repos. - - * classify.c, cvs.h (Classify_File): New argument pipeout. - * classify.c (Classify_File): If pipeout, don't complain if the - file is already there. - * update.c, commit.c, status.c: Change callers. - - * mkmodules.c (main): Don't print "reminders" if commitinfo, - loginfo, rcsinfo, or editinfo files are missing. - -Mon Aug 22 23:22:59 1994 Ken Raeburn (raeburn@kr-pc.cygnus.com) - - * server.c (strerror): Static definition replaced by extern - declaration. - -Sun Aug 21 07:16:27 1994 Ken Raeburn (raeburn@kr-pc.cygnus.com) - - * client.c (update_entries): Run "patch" with input from - /dev/null, so if it's the wrong version, it fails quickly rather - than waiting for EOF from terminal before failing. - -Sat Aug 20 04:16:33 1994 Ken Raeburn (raeburn@cujo.cygnus.com) - - * server.c (serve_unchanged): Instead of creating a file with a - zero timestamp, rewrite the entries file to have "=" in the - timestamp field. - * vers_ts.c (mark_lost, mark_unchanged): New macros. - (time_stamp_server): Use them, for clarity. Interpret "=" - timestamp as an unchanged file. A zero-timestamp file should - never be encountered now in use_unchanged mode. - - * client.c (start_server): If CVS_CLIENT_PORT indicates a - non-positive port number, skip straight to rsh connection. - - * status.c (status_fileproc): Fix ts_rcs reference when printing - version info, to correspond to new Entries file format. Don't - print it at all if server_active, because it won't have any useful - data. - -Thu Aug 18 14:38:21 1994 Ken Raeburn (raeburn@cujo.cygnus.com) - - * cvs.h (status): Declare. - * client.c (client_status): New function. - - * client.h (client_status): Declare. - * main.c (cmds): Include it. - * server.c (serve_status): New function. - (requests): Add it. - * status.c (status): Do the remote thing if client_active. - - * client.c (supported_request): New function. - (start_server): Use it. - - * server.c (receive_partial_file): New function, broken out from - serve_modified. Operate with fixed-size local buffer, instead of - growing stack frame by entire file size. - (receive_file): New function, broken out from serve_modified. - (serve_modified): Call it. - (server): Print out name of unrecognized request. - - More generic stream-filtering support: - * client.c (close_on_exec, filter_stream_through_program): New - functions. - (server_fd): New variable. - (get_responses_and_close): Direct non-rsh connection is now - indicated by server_fd being non-negative. File descriptors for - to_server and from_server may now be different in case "tee" - filtering is being done. Wait for rsh_pid specifically. - (start_server): Use filter_stream_through_program for "tee" - filter, and enable it for direct Kerberos-authenticated - connections. Use dup to create new file descriptors for server - connection if logging is enabled. - (start_rsh_server): Disable code that deals with logging. - - Per-file compression support: - * cvs.h (gzip_level): Declare. - * main.c (usg): Describe new -z argument. - (main): Recognize it and set gzip_level. - * client.c (filter_through_gzip, filter_through_gunzip): New - functions to handle compression. - (update_entries): If size starts with "z", uncompress - (start_server): If gzip_level is non-zero and server supports it, - issue gzip-file-contents request. - (send_fileproc): Optionally compress file contents. Use a - slightly larger buffer, anticipating the worst case. - * server.c (gzip_level): Define here. - (receive_file): Uncompress file contents if needed. - (serve_modified): Recognize "z" in file size and pass receive_file - appropriate flag. - (buf_read_file_to_eof, buf_chain_length): New functions. - (server_updated): Call them when sending a compressed file. - (serve_gzip_contents): New function; set gzip_level. - (requests): Added gzip-file-contents request. - -Wed Aug 17 09:37:44 1994 J.T. Conklin (jtc@cygnus.com) - - * find_names.c (find_dirs): Use 4.4BSD filesystem feature (it - contains the file type in the dirent structure) to avoid - stat'ing each file. - - * commit.c (remove_file,checkaddfile): Change type of umask - variables from int to mode_t. - * subr.c (): Likewise. - -Tue Aug 16 19:56:34 1994 Mark Eichin (eichin@cygnus.com) - - * diff.c (diff_fileproc): Don't use diff_rev* because they're - invariant across calls -- add new variable top_rev. - (diff_file_nodiff): After checking possible use_rev* values, if - top_rev is set drop it in as well (if we don't already have two - versions) and then clear it for next time around. - -Wed Aug 10 20:50:47 1994 Mark Eichin (eichin@cygnus.com) - - * diff.c (diff_fileproc): if ts_user and ts_rcs match, then the - file is at the top of the tree -- so we might not even have a - copy. Put the revision into diff_rev1 or diff_rev2. - -Wed Aug 10 14:55:38 1994 Ken Raeburn (raeburn@cujo.cygnus.com) - - * server.c (do_cvs_command): Use waitpid. - - * subr.c (run_exec): Always use waitpid. - - * Makefile.in (CC, LIBS): Define here, in case "make" is run in - this directory instead of top level. - -Wed Aug 10 13:57:06 1994 Mark Eichin (eichin@cygnus.com) - - * client.c (krb_get_err_text): use HAVE_KRB_GET_ERR_TEXT to - determine if we need to use the array or the function. - * main.c: ditto. - -Tue Aug 9 16:43:30 1994 Ken Raeburn (raeburn@cujo.cygnus.com) - - * entries.c (ParseEntries): If timestamp is in old format, rebuild - it in the new format. Fudge an unmatchable entry that won't - trigger this code next time around, if the file is modified. - - * vers_ts.c (time_stamp): Only put st_mtime field into timestamp, - and use GMT time for it. With st_ctime or in local time, copying - trees between machines in different time zones makes all the files - look modified. - (time_stamp_server): Likewise. - -Tue Aug 9 19:40:51 1994 Mark Eichin (eichin@cygnus.com) - - * main.c (main): use krb_get_err_text function instead of - krb_err_txt array. - -Thu Aug 4 15:37:50 1994 Ian Lance Taylor (ian@sanguine.cygnus.com) - - * main.c (main): When invoked as kserver, set LOGNAME and USER - environment variables to the remote user name. - -Thu Aug 4 07:44:37 1994 Mark Eichin (eichin@cygnus.com) - - * client.c: (handle_valid_requests): if we get an option that has - rq_enableme set, then send that option. If it is UseUnchanged, set - use_unchanged so that the rest of the client knows about - it. (Could become a more general method for dealing with protocol - upgrades.) - (send_fileproc): if use_unchanged didn't get set, send an - old-style "Lost" request, otherwise send an "Unchanged" request. - * server.c (serve_unchanged): new function, same as serve_lost, - but used in the opposite case. - (requests): add new UseUnchanged and Unchanged requests, and make - "Lost" optional (there isn't a good way to interlock these.) - * server.h (request.status): rq_enableme, new value for detecting - compatibility changes. - * vers_ts.c (time_stamp_server): swap meaning of zero timestamp if - use_unchanged is set. - -Tue Jul 26 10:19:30 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * sanity.sh: Separate CVSROOT_FILENAME, which must be the filename - of the root, from CVSROOT, which can include a hostname for - testing remote CVS. (but the tests aren't yet prepared to deal - with the bugs in remote CVS). - - * import.c (update_rcs_file): Change temporary file name in TMPDIR - from FILE_HOLDER to cvs-imp. - - * sanity.sh: Add ">/dev/null" and "2>/dev/null" many places to - suppress spurious output. Comment out tests which don't work (cvs - add on top-level directory, cvs diff when non-committed adds or - removes have been made, cvs release, test 53 (already commented as - broken), retagging without deleting old tag, test 63). Now 'make - check' runs without any failures. - -Fri Jul 15 12:58:29 1994 Ian Lance Taylor (ian@sanguine.cygnus.com) - - * Makefile.in (install): Do not depend upon installdirs. - -Thu Jul 14 15:49:42 1994 Ian Lance Taylor (ian@sanguine.cygnus.com) - - * client.c, server.c: Don't try to handle alloca here; it's - handled by cvs.h. - -Tue Jul 12 13:32:40 1994 Ian Lance Taylor (ian@sanguine.cygnus.com) - - * client.c (update_entries): Reset stored_checksum_valid if we - quit early because of a patch failure. - -Fri Jul 8 11:13:05 1994 Ian Lance Taylor (ian@sanguine.cygnus.com) - - * client.c (responses): Mark "Remove-entry" as optional. - -Thu Jul 7 14:07:58 1994 Ian Lance Taylor (ian@sanguine.cygnus.com) - - * server.c (server_updated): Add new checksum argument. If it is - not NULL, and the client supports the "Checksum" response, send - it. - * server.h (server_updated): Update prototype. - * update.c: Include md5.h. - (update_file_proc): Pass new arguments to patch_file and - server_updated. - (patch_file): Add new checksum argument. Set it to the MD5 - checksum of the version of the file being checked out. - (merge_file): Pass new argument to server_updated. - * client.c: Include md5.h. - (stored_checksum_valid, stored_checksum): New static variables. - (handle_checksum): New static function. - (update_entries): If a checksum was received, check it against the - MD5 checksum of the final file. - (responses): Add "Checksum". - (start_server): Clear stored_checksum_valid. - * commit.c (commit_fileproc): Pass new argument to server_updated. - - * client.h (struct response): Move definition in from client.c, - add status field. - (responses): Declare. - * client.c (struct response): Remove definition; moved to - client.h. - (responses): Make non-static. Initialize status field. - * server.c (serve_valid_responses): Check and record valid - responses, just as in handle_valid_requests in client.c. - - * diff.c (diff_client_senddate): New function. - (diff): Use it to send -D arguments to server. - -Wed Jul 6 12:52:37 1994 J.T. Conklin (jtc@phishhead.cygnus.com) - - * rcs.c (RCS_parsercsfile_i): New function, parse RCS file - referenced by file ptr argument. - (RCS_parsercsfile): Open file and pass its file ptr to above function. - (RCS_parse): Likewise. - -Wed Jul 6 01:25:38 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * client.c (update_entries): Print message indicating that an - unpatchable file will be refetched. - (client_update): Print message when refetching unpatchable files. - -Fri Jul 1 07:16:29 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * client.c (send_dirent_proc): Don't call send_a_repository if - repository is "". - -Fri Jul 1 13:58:11 1994 Ian Lance Taylor (ian@sanguine.cygnus.com) - - * client.c (last_dirname, last_repos): Move out of function. - (failed_patches, failed_patches_count): New static variables. - (update_entries): If patch program fails, save short_pathname in - failed_patches array, only exit program if retcode is -1, and - return out of the function rather than update the Entries line. - (start_server): Clear toplevel_repos, last_dirname, last_repos. - (client_update): If failed_patches is not NULL after doing first - update, do another update, but remove all the failed files first. - -Thu Jun 30 09:08:57 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * server.c (requests): Add request "Global_option". - (serve_global_option): New function, to handle it. - * client.c (start_server): Deal with global options. Check for - errors from fprintf. - - * client.c (send_fileproc): Split out code which sends repository - into new function send_a_repository. Also, deal with update_dir - being ".". - (send_dirent_proc): Call send_a_repository. - * add.c (add): If client_active, do special processing for - directories. - (add_directory): If server_active, don't try to create CVSADM - directory. - -Thu Jun 30 11:58:52 1994 Ian Lance Taylor (ian@sanguine.cygnus.com) - - * client.c (update_entries): If patch succeeds, remove the backup - file. - * server.c (server_updated): Add new argument file_info. If it is - not NULL, use it rather than sb to get the file mode. - * server.h (server_updated): Update prototype for new argument. - * update.c (update_file_proc): Pass new arguments to patch_file - and server_updated. - (patch_file): Add new argument file_info. Don't use -p to check - out new version, check it out into file and rename that to file2. - If result is not readable, assume file is dead and set docheckout. - Call xchmod on file2. Close the patch file after checking for a - binary diff. Set file_info to the results of stat on file2. - (merge_file): Pass new argument to server_updated. - * commit.c (commit_fileproc): Pass new argument to server_updated. - -Wed Jun 29 13:00:41 1994 Ian Lance Taylor (ian@sanguine.cygnus.com) - - * client.c (krb_realmofhost): Declare, since it's not the current - . - (start_server): Save the name returned by gethostbyname. Call - krb_realmofhost to get the realm. Pass the resulting realm to - krb_sendauth. Pass the saved real name to krb_sendauth, rather - than server_host. - - * update.c (update_file_proc): Pass &docheckout to patch_file. If - it is set to 1, fall through to T_CHECKOUT case. - (patch_file): Add docheckout argument. Set it to 1 if we can't - make a patch. Check out the files and run diff rather than - rcsdiff. If either file does not end in a newline, we can't make - a patch. If the patch starts with the string "Binary", assume - one or the other is a binary file, and that we can't make a patch. - -Tue Jun 28 11:57:29 1994 Ian Lance Taylor (ian@sanguine.cygnus.com) - - * client.c (update_entries): If the patch file is empty, don't run - patch program; avoids error message. - - * classify.c (Classify_File): Return T_CHECKOUT, not T_PATCH, if - the file is in the Attic. - - * cvs.h (enum classify_type): Add T_PATCH. - * config.h (PATCH_PROGRAM): Define. - * classify.c (Classify_File): If user file exists and is not - modified, and using the same -k options, return T_PATCH instead of - T_CHECKOUT. - * update.c (patches): New static variable. - (update): Add u to gnu_getopt argument. Handle it. - (update_file_proc): Handle T_PATCH. - (patch_file): New static function. - * server.h (enum server_updated_arg4): Add SERVER_PATCHED. - * server.c (server_updated): Handle SERVER_PATCHED by sending - "Patched" command. - (serve_ignore): New static function. - (requests): Add "update-patches". - (client_update): If the server supports "update-patches", send -u. - * client.c (struct update_entries_data): Change contents field - from int to an unnamed enum. - (update_entries): Correponding change. If contents is - UPDATE_ENTRIES_PATCH, pass the input to the patch program. - (handle_checked_in): Initialize contents to enum value, not int. - (handle_updated, handle_merged): Likewise. - (handle_patched): New static function. - (responses): Add "Patched". - * commit.c (check_fileproc): Handle T_PATCH. - * status.c (status_fileproc): Likewise. - - * client.c (start_server): If CVS_CLIENT_PORT is set in the - environment, connect to that port, rather than looking up "cvs" in - /etc/services. For debugging. - -Tue Jun 21 12:48:16 1994 Ken Raeburn (raeburn@cujo.cygnus.com) - - * update.c (joining): Return result of comparing pointer with - NULL, not result of casting (truncating, on Alpha) pointer to int. - - * main.c (main) [HAVE_KERBEROS]: Impose a umask if starting as - Kerberos server, so temp directories won't be world-writeable. - - * update.c (update_filesdone_proc) [CVSADM_ROOT]: If environment - variable CVS_IGNORE_REMOTE_ROOT is set and repository is remote, - don't create CVS/Root file. - * main.c (main): If env var CVS_IGNORE_REMOTE_ROOT is set, don't - check CVS/Root. - -Fri Jun 10 18:48:32 1994 Mark Eichin (eichin@cygnus.com) - - * server.c (O_NDELAY): use POSIX O_NONBLOCK by default, unless it - isn't available (in which case substitute O_NDELAY.) - -Thu Jun 9 19:17:44 1994 Mark Eichin (eichin@cygnus.com) - - * server.c (server_cleanup): chdir out of server_temp_dir before - deleting it (so that it works on non-BSD systems.) Code for choice - of directory cloned from server(). - -Fri May 27 18:16:01 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * client.c (update_entries): Add return type of void. - (get_responses_and_close): If using Kerberos and from_server and - to_server are using the same file descriptor, use shutdown, not - fclose. Close from_server. - (start_server): New function; most of old version renamed to - start_rsh_server. - (start_rsh_server): Mostly renamed from old start_server. - (send_fileproc): Use %lu and cast sb.st_size in fprintf call. - (send_files): Remove unused variables repos and i. - (option_no_arg): Comment out; unused. - * main.c (main): Initialize cvs_update_env to 0. If command is - "kserver", authenticate and change command to "server". If - command is "server", don't call Name_Root, don't check access to - history file, and don't assume that CVSroot is not NULL. - * server.c (my_memmove): Removed. - (strerror): Change check from STRERROR_MISSING to HAVE_STRERROR. - (serve_root): Likewise for putenv. - (serve_modified): Initialize buf to NULL. - (struct output_buffer, buf_try_send): Remove old buffering code. - (struct buffer, struct buffer_data, BUFFER_DATA_SIZE, - allocate_buffer_datas, get_buffer_data, buf_empty_p, - buf_append_char, buf_append_data, buf_read_file, buf_input_data, - buf_copy_lines): New buffering code. - (buf_output, buf_output0, buf_send_output, set_nonblock, - set_block, buf_send_counted, buf_copy_counted): Rewrite for new - buffering code. - (protocol, protocol_memory_error, outbuf_memory_error, - do_cvs_command, server_updated): Rewrite for new buffering code. - (input_memory_error): New function. - (server): Put Rcsbin at start of PATH in environment. - * Makefile.in: Add @includeopt@ to DEFS. - -Fri May 20 08:13:10 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * cvs.h, classify.c (Classify_File): New argument update_dir. - Include it in user messages. - * commit.c (check_fileproc), status.c (status_fileproc), update.c - (update_file_proc): Pass update_dir to Classify_File. - * commit.c (check_fileproc), update.c (checkout_file): - Include update_dir in user messages. - * commit.c (check_fileproc) update.c (update_file_proc): Re-word - "unknown status" message. - - * server.c (server_checked_in): Deal with the case where - scratched_file is set rather than entries_line. - - * entries.c (Register): Write file even if server_active. - * add.c (add): Add comment about how we depend on above behavior. - -Tue May 17 08:16:42 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - * mkmodules.c: Add dummy server_active and server_cleanup, to go - with the dummy Lock_Cleanup already there. - - * server.c (server_cleanup): No longer static. - -Sat May 7 10:17:17 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - Deal with add and remove: - * commit.c (checkaddfile): If CVSEXT_OPT or CVSEXT_LOG file does - not exist, just silently keep going. - (remove_file): If server_active, remove file before creating - temporary file with that name. - * server.c (serve_remove, serve_add): New functions. - (requests): Add them. - * server.c (server_register): If options is NULL, it means there - are no options. - * server.c, server.h (server_scratch_entry_only): New function. - New variable kill_scratched_file. - (server_scratch, server_updated): Deal with kill_scratched_file. - * commit.c (commit_fileproc): If server_active, call - server_scratch_entry_only and server_updated. - * add.c (add): Add client_active code. - (add): If server_active, call server_checked_in for each file added. - * remove.c (remove): Add client_active code. - (remove_fileproc): If server_active, call server_checked_in. - * main.c (cmds), client.c, client.h: New functions client_add and - client_remove. - * Move declarations of add, cvsremove, diff, and cvslog from - main.c to cvs.h. - * client.c (call_in_directory): Update comment regarding Root and - Repository files. - (send_fileproc): Only send Entries line if Version_TS really finds - an entry. If it doesn't find one, send Modified. - (update_entries): If version is empty or starts with 0 or -, - create a dummy timestamp. - -Thu May 5 19:02:51 1994 Per Bothner (bothner@kalessin.cygnus.com) - - * recurse/c (start_recursion): If we're doing rtag, and thus - have cd'd to the reporsitory, add ,v to a file name before stat'ing. - -Wed Apr 20 15:01:45 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * client.c (client_commit): Call ign_setup. - (client_update, client_checkout): Likewise. - * diff.c (diff): If client, call ign_setup. - * log.c (cvslog): Likewise. - * update.h (ignlist): Change definition to declaration to avoid - depending upon common semantics (not required by ANSI C, and not - the default on Irix 5). - * update.c (ignlist): Define. - -Tue Apr 19 00:02:54 1994 John Gilmore (gnu@cygnus.com) - - Add support for remote `cvs log'; clean up `cvs diff' a bit. - - * client.c (send_arg): Make external. - (send_option_string): New function. - (client_diff_usage): Remove, unused. - (client_diff): Just call diff, not do_diff. - (client_log): Add. - * client.h (client_log, send_arg, send_option_string): Declare. - * cvs.h (cvslog): Declare. - * diff.c (do_diff): Fold back into diff(), distinguish by checking - client_active. - (diff): Remove `-*' arg parsing crud; use send_option_string. - * log.c (cvslog): If a client, start the server, pass options - and files, and handle server responses. - * main.c (cmds): Add client_log. - (main): Remove obnoxious message every time CVS/Root is used. - Now CVS will be quiet about it -- unless there is a conflict - between $CVSROOT or -d value versus CVS/Root. - * server.c (serve_log): Add. - (requests): Add "log". - -Mon Apr 18 22:07:53 1994 John Gilmore (gnu@cygnus.com) - - Add support for remote `cvs diff'. - - * diff.c (diff): Break guts out into new fn do_diff. - Add code to handle starting server, writing args, - sending files, and retrieving responses. - (includes): Use PARAMS for static function declarations. - * client.c (to_server, from_server, rsh_pid, - get_responses_and_close, start_server, send_files, - option_with_arg): Make external. - (send_file_names): New function. - (client_diff): New function. - * client.h (client_diff, to_server, from_server, - rsh_pid, option_with_arg, get_responses_and_close, start_server, - send_file_names, send_files): Declare. - * cvs.h (diff): Declare. - * main.c (cmds): Add client_diff to command table. - * server.c (serve_diff): New function. - (requests): Add serve_diff. - (server): Bug fix: avoid free()ing incremented cmd pointer. - * update.h (update_filesdone_proc): Declare with PARAMS. - -Sat Apr 16 04:20:09 1994 John Gilmore (gnu@cygnus.com) - - * root.c (Name_root): Fix tyop (CVSroot when root meant). - -Sat Apr 16 03:49:36 1994 John Gilmore (gnu@cygnus.com) - - Clean up remote `cvs update' to properly handle ignored - files (and files that CVS can't identify), and to create - CVS/Root entries on the client side, not the server side. - - * client.c (send_fileproc): Handle the ignore list. - (send_dirent_proc): New function for handling ignores. - (send_files): Use update_filesdone_proc and send_dirent_proc - while recursing through the local filesystem. - * update.h: New file. - * update.c: Move a few things into update.h so that client.c - can use them. - -Fri Mar 11 13:13:20 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) - - * server.c: If O_NDELAY is not defined, but O_NONBLOCK is, define - O_NDELAY to O_NONBLOCK. - -Wed Mar 9 21:08:30 1994 Jim Kingdon (kingdon@lioth.cygnus.com) - - Fix some spurious remote CVS errors caused by the CVS/Root patches: - * update.c (update_filesdone_proc): If server_active, don't try to - create CVS/Root. - * root.c (Name_Root): Make error messages which happen if root is - not an absolute pathname or if it doesn't exist a bit clearer. - Skip them if root contains a colon. - -Mon Nov 1 15:54:51 1993 K. Richard Pixley (rich@sendai.cygnus.com) - - * client.c (client_commit): dynamically allocate message. - -Tue Jun 1 17:03:05 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com) - - * server.h: remove alloca cruft - - * server.c: replace with better alloca cruft - -Mon May 24 11:25:11 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * entries.c (Scratch_Entry): Update our local Entries file even if - server_active. - - * server.c (server_scratch, server_register): If both Register - and Scratch_Entry happen, use whichever one happened later. - If neither happen, silently continue. - - * client.c (client_checkout): Initialize tag and date (eichin and - I independently discovered this bug at the same time). - -Wed May 19 10:11:51 1993 Mark Eichin (eichin@cygnus.com) - - * client.c (update_entries): handle short reads over the net - (SVR4 fread is known to be broken, specifically for short - reads off of streams.) - -Tue May 18 15:53:44 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - * server.c (do_cvs_command): Fix fencepost error in setting - num_to_check. - - * server.c (do_cvs_command): If terminated with a core dump, print - message and set dont_delete_temp. - (server_cleanup): If dont_delete_temp, don't delete it. - - * client.c (get_server_responses): Don't change cmd since we - are going to "free (cmd)". - - * server.c: Rename memmove to my_memmove pending a real fix. - - * server.c (do_cvs_command): Set num_to_check to largest descriptor - we try to use, rather than using (non-portable) getdtablesize. - -Wed May 12 15:31:40 1993 Jim Kingdon (kingdon@lioth.cygnus.com) - - Add CVS client feature: - * client.{c,h}: New files. - * cvs.h: Include client.h. - * main.c: If CVSROOT has a colon, use client commands instead. - * vers_ts.c (Version_TS): If repository arg is NULL, don't worry - about the repository. - * logmsg.c (do_editor): If repository or changes is NULL, just don't - use those features. - * create_adm.c (Create_Admin), callers: Move the test for whether - the repository exists from here to callers. - * repos.c (Name_Repository): Don't test whether the repository exists - if client_active set (might be better to move test to callers). - - Add CVS server feature: - * server.{c,h}: New files. - * cvs.h: Include server.h. - * checkin.c (Checkin): Call server_checked_in. - * update.c (update_file_proc, merge_files): Call server_updated. - * entries.c (Register): Call server_register. - (Scratch_Entry): Call server_scratch. - * main.c: Add server to cmds. - * vers_ts.c (Version_TS): If server_active, call new function - time_stamp_server to set ts_user. - - -For older changes, there might be some relevant stuff in the bottom of -the NEWS file, but I'm afraid probably a lot of them are lost in the -mists of time. diff --git a/contrib/cvs/src/ChangeLog-96 b/contrib/cvs/src/ChangeLog-96 deleted file mode 100644 index 6c3a2a1..0000000 --- a/contrib/cvs/src/ChangeLog-96 +++ /dev/null @@ -1,4434 +0,0 @@ -Mon Dec 30 15:43:48 1996 Abe Feldman - - * checkout.c (build_dirs_and_chdir): Reproduced block containing - Create_Admin, placing it before Subdir_Register. - * sanity.sh (basicb): Added tests 1a and 9a to test above changes - to the checkout command. - -Mon Dec 30 13:29:14 1996 uz@wuschel.ibb.schwaben.com (Ullrich von Bassewitz) - and Jim Kingdon - - * cvs.h (CVSEDITPREFIXLEN): New define. - * logmsg.c (do_editor): Use CVSEDITPREFIXLEN when deciding whether - to strip off CVSEDITPREFIX and when telling the user what we will - strip off. - -Sun Dec 22 22:06:49 1996 Jim Kingdon - - * logmsg.c (do_verify): If noexec, skip the verification *without* - printing a message. Use cvs_output not printf. Skip verification - for client_active. - -Wed Dec 18 12:27:35 1996 Jim Kingdon - - * repos.c (Name_Repository): Add comment regarding wording of - "*PANIC*" error message. - -1996-12-18 Jim Kingdon - - * client.c (call_in_directory): If the directory we are about - to create is the same as CVSADM as seen by fncmp (for example, - it is "cvs" and filenames are case-insensitive), then give a - fatal error. - -Tue Dec 17 13:14:22 1996 Jim Kingdon - - * options.h.in: Add comments about SETXID security holes. - - * logmsg.c (do_verify): Reindent comments. Check errno if return - code from run_exec is -1, not if it is 1. - * sanity.sh (info): Move tests info-4 and info-8 to end and rename - them. Add verifymsg tests. Instead of forcibly removing loginfo, - remove it nicely (test info-11). - -Tue Dec 17 12:45:32 1996 Abe Feldman - - * commit.c, import.c: Call do_verify as well as do_editor. - * cvs.h (CVSROOTADM_VERIFYMSG): Define. - * logmsg.c, cvs.h (do_verify, verifymsg_proc): New functions. - (verifymsg_script): New variable. - * mkmodules.c (filelist): Add CVSROOTADM_VERIFYMSG. - -Mon Dec 16 13:24:47 1996 Ian Lance Taylor - - * lock.c (remove_locks): New static function, copied from part of - Lock_Cleanup. - (Lock_Cleanup): Call remove_locks. - (Writer_Lock): Call remove_locks rather than Lock_Cleanup when - waiting for a lock. - -Thu Dec 12 10:36:37 1996 Jim Kingdon - - * login.c (get_cvs_password): If CVS_PASSWORD is set, print a - warning (and then proceed to ignore it). It was a documented - feature, so we should point people who were using it to the - replacement. - -Mon Dec 9 12:35:43 1996 Ian Lance Taylor - - * server.c (server_updated): Change comment to only worry about - umask in the rsh case. - (server): Create the temporary directory, and change the mode to - S_IRWXU. - (switch_to_user): Set the umask to 0, not 077. - -Mon Dec 9 10:58:28 1996 Jim Blandy - - * login.c (get_cvs_password): Remove code to check for value of - CVS_PASSWORD. Keeping cleartext passwords in environment - variables is a really bad idea on Unix, since anyone can print - out a processes' environment using 'ps' (on BSD variants - anyway). Update help message. - -Fri Dec 6 15:59:40 1996 Jim Kingdon - - * sanity.sh: When matching "use .cvs commit. to remove this file - permanently" messages, change "cvs" to "${PROG}". - (rdiff, binfiles): Likewise. - This fixes testing a program named something other than "cvs", e.g. - $ cp cvs cvs-test - $ /bin/sh /sanity.sh `pwd`/cvs-test - -1996-12-02 Jim Kingdon - - * client.c: In comment saying that socket buffers don't - implement the blocking routine, say they are blocking. - * buffer.h (struct buffer): In description of input function, - describe blocking, non-blocking, and NEED more fully. Say - what happens if we read a nonzero amount less than NEED and - then get end of file. - * client.c (socket_buffer_input): If NEED == 0, still call - recv (once). Handle the case where recv returns 0. - -Sat Nov 30 15:10:07 1996 Jim Kingdon - - * subr.c, cvs.h (file_has_markers): New function. - * rcs.h (RCS_MERGE_PAT): Now a fixed string not a regexp. - * options.h.in (GREP): Removed; no longer used. - * update.c (update_fileproc), commit.c (check_fileproc): Call - file_has_markers rather than GREP. - * rcscmds.c (RCS_merge): Just give a fatal error in the case where - we had been calling GREP. I suspect noone is using this code - any more. - * sanity.sh (conflicts): Rewrite tests 131, 132, and 133 to use - dotest; tests that the above changes didn't break anything. - -Fri Nov 29 09:06:41 1996 fnf@ninemoons.com (Fred Fish) - and Jim Kingdon - - * checkout.c (safe_location): Only call readlink if HAVE_READLINK. - - * run.c (piped_child, filter_stream_through_program): If - HAVE_VFORK, call vfork not fork. - * run.c (run_exec): Add comment about why we use vfork. - -Mon Nov 25 12:48:31 1996 Jim Kingdon - - * release.c (release): Don't return after processing the first - argument; that kind of defeats the purpose of having a loop, eh? - For client, close the connection after we've processed them all. - * sanity.sh: Remove workaround for modules2-8 test; tests for - above fix. Adjust modules2-6 test to answer both questions. - - * login.c: Reindent (all of get_cvs_password, a handful of lines - elsewhere). - - Cleanups to release, mostly cosmetic: - * release.c (release_server): New function; breaks out server code - from the release function. - * release.c: Move delete_flag inside the release function. - * release.c (release): Reindent. Rewrite comments about how the - implementation could be improved. Don't declare variables as - "register". Include errno in error message. Don't cast result of - printf to void. Remove unused variable srepos. - * release.c: Remove comments at top of file about what it does. - They were not particularly coherent and they were also out of date - (I think). Likewise for comment in release function about "if we - are in a repository". - * release.c: Change "module" to "directory" in a few messages - since that is what is meant. - * sanity.sh: In tests ignore-195 and ignore-193, change expected - message accordingly. - -Sun Nov 24 11:30:55 1996 Jim Kingdon - - * sanity.sh: Clarify a few items in the todo list. - - * log.c (log_parse_date): Use the "end" of the epoch not "next - week" as the time which means "no end time". - * sanity.sh (rcs): New test, tests dates and importing RCS files. - -1996-11-19 Jim Kingdon - - Visual C++ lint: - * hash.c: Declare qsort_comp. - * update.c: Declare isremoved. - -1996-11-19 Jim Kingdon - - * root.c, repos.c, modules.c, create_adm.c: Change all calls to - strip_path to strip_trailing_slashes. Basically strip_path is - just an unneeded complication (we should keep the pathname the way - the user specifies it, and the system can worry about things like - consecutive /'s if it wants to). Stripping trailing slashes is - potentially dubious for the same reason, but it is a somewhat - different case which I won't try to tackle now. - * cvs.h (strip_path): Remove declaration. - -Tue Nov 19 15:18:13 1996 Jim Kingdon - - There are a lot of details to this change, but the concept is - relatively simple: make it so that for every CVSLCK lock that we - might take out, there is a flag which is set iff we have created - the CVSLCK directory. - * lock.c (struct lock): New structure. - * lock.c: Remove static variables repository and cleanup_lckdir. - They are replaced by global_readlock.repository and - global_readlock.have_lckdir, respectively (except insofar as the - rest of these changes change the concept of cleanup_lckdir). - New static variable global_readlock. - (Reader_Lock, Lock_Cleanup): Use global_readlock in place of - repository. - (lock_simple_remove, set_lock, clear_lock, write_lock): Take a - struct lock * instead of just a repository. Set/clear - lock->have_lckdir instead of cleanup_lckdir. - (set_writelock_proc, unlock_proc): Pass ->data, not ->key, to - write_lock or lock_simple_remove. - (lock_filesdoneproc,lock_dir_for_write): Allocate a struct lock, - put it in the ->data field, and fill in its fields. - (lock_simple_remove): Use lock->have_lckdir as the sole test for - whether the CVSLCK directory needs to be removed. Add - comments about why readlock and writelock variables don't tell us - for sure whether locks exist. - (lock_simple_remove, clear_lock): Use SIG_beginCrSect and - SIG_endCrSect to ensure that ->have_lckdir is set to 0 iff the - CVSLCK directory was really removed. - (lock_simple_remove): Check for errors removing CVSLCK directory. - (lock_simple_remove, Check_Owner, set_lock): Remove all code which - checks userids (including all of Check_Owner and all the AFCVS - code). It was bogus if several CVS processes with the same userid - were running (common if several users share a userid; a common - practice with remote CVS), and with the rest of the changes here - should not be needed. - -1996-11-16 Paul Eggert - - * rcs.c (RCS_deltas): Fix unintended trigraphs. - -Fri Nov 15 13:06:03 1996 Tom Hageman - - * diff.c (diff_fileproc): In printing error messages, use the - correct filename for which the error occurred. - -Sun Nov 10 21:13:38 1996 Paul Sanders - and Jim Kingdon - - * server.c: Use all the right cruft which goes along with - including sys/time.h. - - * server.c: Include a "copyright" notice. - - * server.c: If HAVE_WINSOCK_H, include winsock.h. - - * server.c (server): Only set a handler for SIGHUP if it is - defined. Likewise for all the other signals. - - * server.c (do_cvs_command): Use DEVNULL not /dev/null. - -Fri Nov 08 12:14:20 1996 Jim Kingdon - - IBM ICC (OS/2) lint: - * add.c (add): Only declare begin_added_files if - SERVER_SUPPORT. - * client.c (init_sockaddr): Change port argument from - unsigned short to unsigned int. Change hostname - argument from const char * to char *. - -Sun Nov 3 18:24:28 1996 Noel Cragg - - * sanity.sh (info): add new tests that check behavior of format - string substitution in loginfo file. - -Sat Nov 2 09:39:09 1996 Jim Kingdon - - * client.c (do_deferred_progs): Don't access memory once it is - freed (we already did it right for checkin_progs; do the same - thing for update_progs). - - * update.c, client.c, classify.c, client.h, diff.c, commit.c, - create_adm.c: Nuke more PATH_MAX. - -Fri Nov 1 18:22:32 1996 Jim Kingdon - - * error.h: Define PROTO if it is not defined. - -Wed Oct 30 08:53:20 1996 jalving@ibm.net - - * patch.c (patch_fileproc): Set line1 and line2 to NULL up-front - (before the first "goto out") so we don't try to free them. - -Wed Oct 30 08:53:20 1996 Jim Kingdon - - * commit.c (remove_file, commit_filesdoneproc), run.c (run_print, - run_exec), modules.c (open_module, cat_module, do_module), update.c - (update_dirleave_proc), tag.c (tag_fileproc): Call cvs_out* rather - than stdio. - * server.c (serve_expand_modules): Remove comment about do_module - writing to stdout/stderr; above changes should fix this. - -Tue Oct 29 17:23:59 1996 Ian Lance Taylor - - * status.c (tag_list_proc): When printing the tag name, don't - truncate it to 25 characters. - -Tue Oct 29 12:49:07 1996 Jim Kingdon - - * add.c, checkin.c, checkout.c, filesubr.c: Nuke arbitrary limit - of PATH_MAX. Many more such limits surely remain. - - * fileattr.c (fileattr_set): Set attrs_modified *after* we might - call fileattr_read, because fileattr_read clears it. - * sanity.sh (devcom2): New tests, test for above fix and other - behaviors I discovered in the process of looking into it. - -Mon Oct 28 08:55:57 1996 Jim Kingdon - - The following changes are to ensure that SYSTEM_CLEANUP is always - called. - * error.c, cvs.h, main.c: Remove error_set_cleanup and related - machinery. It was for a time when error.c was intended to be - shared with other programs, but that is no longer true. - * error.c, error.h (error_exit): New function; like error_cleanup - from main.c but also calls SYSTEM_CLEANUP and exit (EXIT_FAILURE). - * error.c (error, fperror): Call error_exit instead of doing it - ourself. - * server.c (server, serve_valid_responses, switch_to_user, - check_password, pserver_authenticate_connection, - kserver_authenticate_connection): Call SYSTEM_CLEANUP before exit. - * add.c, client.c, import.c, main.c, mkmodules.c, modules.c, - recurse.c, server.c, tag.c, update.c: Call error_exit () - instead of exit (EXIT_FAILURE). - -Sun Oct 27 08:34:16 1996 Jim Kingdon - - * sanity.sh (conflicts): New test 128.5 tests "cvs co -p" in an empty - directory (like 126.5), but when the file has nonempty contents. - * rcs.c (RCS_checkout): If writing to stdout, use cvs_output - rather than fwrite. - * update.c (checkout_file): Call cvs_stderr not fprintf. - These changes should fix some out-of-order bugs which show up in - situations like conflicts-126.5 and conflicts-128.5. - - * mkmodules.c (checkout_file): Call RCS_checkout rather than - run_exec on RCS_CO. - -Sat Oct 26 18:29:46 1996 Jim Kingdon - - * sanity.sh (rdiff): cd out of testimport directory and remove it - when done. - - * sanity.sh (info): Adjust tests to reflect fact that loginfo was - created by cvs init. - - * sanity.sh (ignore): Change test 187a1 to allow any number of - files in CVSROOT, not just modules. - - * sanity.sh (modules): In tests 148a0 and 148a1, don't expect a - module which defines CVSROOT to itself, since we don't define one - any more. Also change test to rewrite modules rather than append - to it (in case any previous tests are changed to do something with - modules). Change test 155b to allow any number of files in - CVSROOT, not just modules. - - * add.c (add_directory): Set rev_old and rev_new fields of struct - logfile_info to NULL (prevents us from trying to free them later). - * commit.c (find_fileproc), import.c (import): Likewise. - - * sanity.sh (crerepos): New tests, to test alternate ways of - creating a repository and related matters. - * sanity.sh: Remove tests 1 through 3 and related cruft; replace - them with a new test 1 which merely tests "cvs init". By doing - the obscure stuff in crerepos we avoid having to do all this stuff - any time we run any single test. - -Sat Oct 26 16:19:48 1996 Jim Blandy - - * main.c (main): If HAVE_TZSET is #defined, call tzset. This is - harmless on all systems I know of, and required on some. - -Fri Oct 25 13:20:44 1996 Ian Lance Taylor - - * diff.c (diff_file_nodiff): When setting use_rev1, only return - DIFF_SAME if empty_file is DIFF_DIFFERENT and ts_user is not - NULL. Don't get confused by a vn_user field of "0" or one - starting with '-'. - * sanity.sh (death2): Add new death2-diff-{1,2,7,8} tests for - above patch. Renumber existing death2-diff tests to make room. - -Fri Oct 25 12:38:29 1996 Jim Wilson - - * sanity.sh (death2): In tests death2-diff-{2,4,6,8,10}, allow "_" - in temp file names. The system (tmpnam or whatever) generates - these names so they vary from system to system. - -Fri Oct 25 07:52:44 1996 Jim Kingdon - - * logmsg.c (logfile_write): Give an error for several cases which - should not be legal. Adjust comments accordingly. - * mkmodules.c (loginfo_contents): Make description of loginfo much - more concise. This should be a reminder, not full documentation. - -Tue Oct 22 10:37:37 1996 Noel Cragg - - * commit.c (update_delproc): free structure members rev_old and - rev_new if they have been allocated. - - * mkmodules.c: change loginfo_contents to include a description of - the new format string. - - * logmsg.c (logfile_write): change syntax of format string. - -Sat Oct 19 16:09:55 1996 Jim Kingdon - - For reference, this takes CVS's text segment from 348348 bytes to - 347420 bytes. - * server.c (requests): Change Directory to rq_essential - per change in doc/cvsclient.texi. - * client.c: Remove use_directory and all code which executed if - it wasn't set. This includes the get_short_pathname function. - * server.c: Likewise, for use_dir_and_repos. - (serve_repository): Give a fatal error. - * server.c (requests): Remove Lost. Change Unchanged to rq_essential. - (serve_lost): Removed. - * server.c, server.h, client.c, vers_ts.c: Remove use_unchanged, - code to set it, and all code which executed if it wasn't set. - -Sat Oct 19 12:44:08 1996 J. Richard Sladkey - and Jim Kingdon - - * hash.c (sortlist, new function qsort_comp): Rewrite to use qsort - instead of insert sort. Changes algorithm from n^2 to n log n - (assuming qsort is implemented with quicksort or similar). - -Sat Oct 19 12:44:08 1996 Jim Kingdon - - * sanity.sh (basic2): In test basic2-64, use -x and specify types - which exclude E; the test is not built to deal with E (or any - other new types). - -Sat Oct 19 12:00:00 1996 Mark Mitchell - and Jim Kingdon - - * update.c (isemptydir, new function isremoved): Avoid pruning - directories that contain files marked for removal but not - comitted. - * update.c, update.h (isemptydir): Now extern, not static. - * update.c (isemptydir): New parameter might_not_exist handles - difference in functionality from old client_isemptydir. Bring - over the improved error checking from client_isemptydir. - * client.c (client_isemptydir): Removed; isemptydir now suffices. - * update.c (update_dirleave_proc), client.c - (process_prune_candidates): Update callers. - * sanity.sh (deep): Add tests deep-rm* for above fix. - -Fri Oct 18 15:53:41 1996 Jim Kingdon - - * sanity.sh (devcom): Add tests devcom-some* to test watching just - a single file. - - * root.c (Name_Root): Use isabsolute to test whether a pathname is - absolute instead of checking for the first character being '/'. - (Reported by Antoine P. Brusseau ). - - * commit.c (checkaddfile): Free rev only if it is non-NULL (thanks - to cwong@world.std.com (Christopher Wong) for diagnosing this; the - death2-15 test in sanity.sh hits it). - -Thu Oct 17 15:21:56 1996 Jim Kingdon - - * sanity.sh: Reenable rdiff tests. Delete rdiff-9 test to reflect - the fact that the change to add a -K option has not been - incorporated. Adjust rdiff-8 test to reflect the fact that the - change to change the default keyword expansion for the first - revision has not been incorporated. - * patch.c (patch_fileproc): Pass the symbolic revision to - RCS_checkout so that Name can be expanded correctly. Reinstates - one of the 30 Sep 96 changes and fixes a bug which the sanity.sh - rdiff test tests for. - - Reinstate change from 30 Sep 96: - * patch.c (patch): CLIENT_SUPPORT: send '-f' if NOT force_tag_match - - * client.c (process_prune_candidates): Do not ignore errors from - unlink_file_dir. - - * filesubr.c (deep_remove_dir): If rmdir returns an error other - than ENOTEMPTY or EEXIST, return -1 not 0. Add workaround for AIX - header bug. - -Tue Apr 30 08:21:27 1996 Mike Sutton - - * checkout.c, history.c: added logging/reporting of cvs export - command - -Wed Oct 16 10:16:57 1996 Jim Kingdon - - * sanity.sh: Remove tests 4, 4.5, and 4.75; this functionality is - already tested by 45, 45.5 and other tests. - (ignore): New tests ignore-192, ignore-193, ignore-194, and - ignore-195 test output from "cvs release". - (modules2): New tests modules2-6, modules2-7, and modules2-8 test - ability of cvs release to handle multiple arguments. Since it - currently doesn't, the tests are kludged. - - * server.c, cvs.h (cvs_flushout): New function. - * recurse.c (do_file_proc): Call it. - * server.c (cvs_outerr): Call fflush (stdout) in non-server case. - * main.c (main): Don't call setvbuf. The code was incorrectly - checking for "patch" (it really is "rdiff"); the concern about - slowing down large amounts of output is not specific to rdiff - (it applies to "log" for example); and the above changes should - meet the need. - -Tue Oct 15 10:22:10 1996 Jim Kingdon - - This is intended to facilitate some future cleanups to the - locking, but by itself it is a simple, conversative rearrangement: - * tag.c (locked_dir, locked_list): Move from here... - * lock.c: ...to here. - * lock.c (Lock_Cleanup): If locked_dir is set clean it up too. - * tag.c (tag_unlockdir): Removed; with the above change - Lock_Cleanup suffices. - * tag.c (tag_lockdir): Move from here... - * lock.c (lock_dir_for_write): ...to here. - * tag.c (tag_fileproc), rtag.c (rtag_fileproc): Update callers. - Move comments concerning why we are locking what we are from - tag_lockdir to here. - * tag.c (tag_filesdoneproc), rtag.c (rtag_filesdoneproc): - Update callers. - * lock.c (Writer_Lock): Made static. - * cvs.h: Update declarations. - * server.c (server_notify): Call lock_dir_for_write rather than - calling Writer_Lock ourselves. - - This is intended to facilitate some future cleanups to the - locking, but by itself it is a simple, conversative rearrangement: - * lock.c (Lock_Cleanup): Also dellist (lock_tree_list). - * lock.c, cvs.h (lock_tree_cleanup): Removed; with the above change - Lock_Cleanup suffices. - * commit.c, edit.c, watch.c: Change callers. - -Sat Oct 12 21:41:46 1996 Jim Kingdon - - * sanity.sh (deep): Add comment about whether the deep-4b behavior - is considered desirable. - -Sat Oct 12 20:36:36 1996 Ian Lance Taylor - - * client.c (client_send_expansions): Add build_dirs parameter. - Change all callers. - (send_dirent_proc): Get build_dirs from callerdat; if it is - zero, don't send a nonexistent directory to the server. - (send_files): Add build_dirs parameter. Change all callers. - * client.h (send_files): Update prototype. - (send_files_contents): Remove prototype for nonexistent function. - (client_send_expansions): Update prototype. - * sanity.sh (deep): Add deep-4b test for above patch. - -Fri Oct 11 14:07:12 1996 Jim Kingdon - - gcc -Wall lint: - * logmsg.c (title_proc): Remove unused variables title and comma. - - * sanity.sh (modules2): Don't be picky about whether we are - checking in 1.3 or 1.2 of modules; it depends on whether we are - running all the tests or just some. - -Thu Oct 10 14:52:06 1996 Jim Kingdon - - * server.c, server.h (server_dir): New variable. - (output_dir): If it is set, send it before the directory name. - * modules.c (do_module): Set it, in the case of & modules, and - restore it when done. - * sanity.sh (modules): Don't clean up first-dir before starting; - tests now clean up for themselves at the end. - (modules2): New tests, for above fix. - -Wed Oct 9 15:52:34 1996 Jim Blandy - - * sanity.sh: Barf immediately if run as root. - - * rcs.c (RCS_getrevtime): When giving a date to get_date, use the full - year, not the year - 1900, so that dates after 1999 are parsed - correctly. (Change thanks to Paul Eggert.) - -Wed Oct 9 10:59:11 1996 Jim Kingdon - - Clean up gcc -Wmissing-prototypes lint: - * cvs.h (admin, add, checkout, commit, diff, history, import, - cvslog, login, patch, release, cvsremove, rtag, status, tag): - Declare. - * server.c, main.c: Don't declare them here. Don't declare update - either (which is already declared in cvs.h). - * tag.c, cvs.h, main.c, server.c: Rename tag to cvstag to avoid - name conflicts. - * client.c (init_sockaddr, auth_server_port_number), entries.c - (Entnode_Create, Entnode_Destroy), hash.c (nodetypestring), - login.c (construct_cvspass_filename), server.c - (supported_response), wrapper.c (wrap_matching_entry): Make static; - prototype. - * hash.c (printlist): Prototype. - * myndbm.c (mydbm_load_file): Change declaration to prototype. - -Tue Oct 8 22:35:34 1996 Jim Kingdon - - * sanity.sh (log2): Re-add these tests; they were deleted for 1.9 - (because they were thought to be destabilizing and/or due to - confusion/accident), but they can be put back now. - - * sanity.sh (death2): In tests death2-diff-{2,4,6,8,10}, allow "-" - or "%" in temp file names. The system (tmpnam or whatever) - generates these names so they vary from system to system. - -Tue Oct 8 12:37:09 1996 Ian Lance Taylor - - * options.h.in (HAD_RCS4): Remove; no longer used. - -Sun Oct 6 15:58:11 1996 Noel Cragg - - * The following changes address problem #56 in the GNATS database - on harvey.cyclic.com: - - * logmsg.c (str_list_format): new global -- contains the format - for items to be placed in str_list. - (Update_Logfile): move code that creates the "title" string... - (logfile_write): ...to here. Pull apart the filter program and - look for a format string, extracting it if there is one. - (title_proc): write a given filename/value based on the format - string. - - * commit.c (classify_file_internal): new routine, old code (needed - to use the code in more than one place). Determines the status - and version information about a file. - (check_fileproc): use classify_file_internal. Fill in the rev_old - field for the struct logfile_info. - (commit_fileproc): Fill in the rev_new field. - - * cvs.h (struct logfile_info): add two new fields -- rev_old and - rev_new -- that keep track of revision numbers across commits. - -Fri Sep 27 15:21:47 1996 Peter Wemm - - * logmsg.c (do_editor): Do not use editinfo if running on the client. - -Fri Oct 4 15:11:46 1996 Jim Kingdon - - * server.c (server_cleanup): Temporarily clear noexec when calling - unlink_file_dir. This is so we clean up the temp directory even - when the -n global option is specified. - -Wed Oct 2 10:47:33 1996 Norbert Kiesel - - * client.c (send_repository): initialize some variables before - first usage - -Tue Oct 1 13:01:24 1996 Jim Blandy - - Revert some of Greg's changes; they're welcome later, but we're - trying to keep CVS stable for pre-release testing at the moment. - * checkin.c, commit.c, cvs.h, diff.c, import.c, main.c, no_diff.c, - options.h.in, patch.c, rcs.c, rcs.h, rcscmds.c, sanity.sh, update.c: - Revert changes of Sep 29 and 30. - -Tue Oct 1 13:17:31 1996 Ian Lance Taylor - - Make sure the server temporary directory is removed even if - Max-dotdot is used. - * server.c (orig_server_temp_dir): New static variable. - (serve_max_dotdot): Don't free server_temp_dir if it is the same - as orig_server_temp_dir. - (do_cvs_command): Use orig_server_temp_dir in error message. - (server_cleanup): Remove orig_server_temp_dir. - (server): Set orig_server_temp_dir. Remove incorrect indentation - of error message. - - * import.c (update_rcs_file): Restore new argument to - RCS_checkout, removed in last patch. - -Tue Oct 1 00:32:55 1996 Jim Blandy - - * import.c: Revert Greg Woods' changes of Sep 30. We may want - them later, but not before 1.9. - -Mon Sep 30 23:31:01 1996 Jim Blandy - - * log.c (log_fileproc): Now that we might actually find a "desc" - node in rcsfile->other, thanks to Ian's change below, we had - better deal correctly if we find a null pointer in it. - -Mon Sep 30 13:55:03 1996 Greg A. Woods - - * main.c (main): don't set need_to_create_root for "cvs init" - either, just in case it's run from within a valid working - directory. - - * sanity.sh (testcvs): oops, forgot to comment out test version I - was using... - - * diff.c (diff_fileproc): use Diffbin instead of DIFF (3). - * patch.c (patch_fileproc): use Diffbin instead of DIFF. - * commit.c (check_fileproc): use Grepbin instead of GREP. - * rcscmds.c (RCS_merge): use Grepbin instead of GREP. - * update.c (patch_file): use Diffbin instead of DIFF. - (update_fileproc): use Grepbin instead of GREP. - * cvs.h (Diffbin): new declaration. - (Grepbin): new declaration. - (DIFFBIN_ENV): new manifest to name DIFFBIN environ var. - (GREPBIN_ENV): new manifest to name GREPBIN environ var. - * option.h.in (DIFFBIN_DFLT): renamed from DIFF. - (GREPBIN_DFLT): renamed from GREP. - * main.c (main): new variables diffbin_update_env and - grepbin_update_inv, ala rcsbin_update_env. - (main): new options -D diffbin and -g grepbin - (usg): describe new options -D diffbin and -g grepbin. - (Diffbin): new global variable for DIFF path. - (Grepfbin): new global variable for GREP path. - - * options.h.in (RCSBIN_DFLT): mention this needs to be set if - your PATH isn't set properly by rshd. - - * sanity.sh (rdiff): re-do Jim's change, but with the original - keywords I had intended (should be a bit more like real life), and - Jim's better RCS date and user matching form. - [I guess that's what I get for checking things in at 3am! ;-)] - -Mon Sep 30 17:00:20 1996 Ian Lance Taylor - - * rcs.c (RCS_reparsercsfile): Store desc field value in main RCS - node data, not in version specific data. - * sanity.sh: Enable log2 test (for local CVS only). - -Mon Sep 30 13:01:45 1996 Jim Kingdon - - * sanity.sh (log2): New test, tests cvs add -m. Not yet enabled - in "tests" because CVS currently flunks this test. - - * sanity.sh (rdiff, basic2): Allow "cvs server" as well as "cvs - checkout" and friends in messages. In testing output of cvs - status, don't require a tab which isn't there for remote. Skip - test rdiff-9 for remote. In test basic2-64, add missing slash in - the pattern which gets used for remote. - - * sanity.sh (rdiff): Fix strings we were matching against which - got keyword-expanded in checking in sanity.sh. - -Mon Sep 30 03:21:37 1996 Greg A. Woods - - * sanity.sh: change all regexpr literal '.' to '\.' - (basic2): why are tests 34 & 42 commented out (because - of 'diff -u'?)? - add tests 56[abc], 57a, and 58a to test import to the main - branch (i.e. branch '1'). - (rdiff): new test section for rdiff -K, etc. - (dotest): remove dotest.ex? before running a new test. - (dotest_fail): remove dotest.ex? before running a new test. - (dotest_internal): write expected output to dotest.exp, or if $4 - also used, to dotest.ex1 and dotest.ex2. - (patch): renamed this test to 'serverpatch'. - (dotest_lit): rename dotest.res to dotest.exp ala dotest(). - remove dotest.ex? before running a new test. - (DOTSTAR): mention the bug exists up to 1.12 - (ENDANCHOR): mention the bug exists up to 1.12 - (dotest_all_in_one): new function for debugging. - (dotest_line_by_line): new function for debugging. - (dotest_internal_debug): new function for debugging. - (dotest_internal): stop emulating the ancient tests and don't spew - the dotest.tmp contents onto $LOGFILE -- it's just too much - meaningless noise. Only do this if the test fails. Many tests - don't use dotest() yet, so this isn't quite so helpful as it might - otherwise be. - (TODO): mention CVS/* files, especially CVS/Root. - - * main.c (main): add a commented out piece of code to suggest that - there should be a function lookup_command_attribute() that could - tell us various things about internal commands, such as whether - they use CVS/Root, or if they're repository-only, or if they need - a working directory, etc.... - (main): don't set need_to_create_root if command doesn't use a - local working directory. - - * patch.c (patch): CLIENT_SUPPORT: send '-f' if NOT force_tag_match - - * error.c (fperror): protect declaration for un-defined __STDC__ - - * import.c (import): permit imports to a branch with zero dots, - i.e. the trunk. - (update_rcs_file): don't detect conflicts if importing to the - trunk. - (import): add hint that we should allow a module name, instead of - just a pathname relative to $CVSROOT. - (add_rcs_file): if importing to trunk, do it with ci(1). - - * import.c: XXX the following are all #if 0'ed out until a full - implementation can be designed.... - (cbranch): new variable to support conflict detection on another - branch set by -c. - (import): truncate -b and -c optarg if to fit in static storage. - (import_usage): describe -c - - * rcscmds.c (RCS_checkout): add new argument 'rcsver'. If rcsver - is set, turn on 'keywords' to force call to RCS_exec_checkout. - * rcs.c (RCS_exec_checkout): add new argument 'rcsver'. Pass - 'rcsver' to "co" with run_arg(). - * cvs.h: (RCS_checkout): add new argument 'rcsver' to prototype. - (RCS_exec_checkout): add new argument 'rcsver' to prototype. - * commit.c (remove_file): supply new argument to RCS_checkout. - * checkin.c (Checkin): supply new argument to RCS_checkout. - * diff.c (diff_fileproc): supply new argument to RCS_checkout. - (diff_file_nodiff): supply new argument to RCS_checkout. - * no_diff.c (No_Difference): supply new argument to RCS_checkout. - * update.c (checkout_file): supply new argument to RCS_checkout. - (patch_file): supply new argument to RCS_checkout. - (join_file): supply new argument to RCS_checkout. - - * patch.c: (o_options): new variable for -K - (rcsver): new variable for -V. - (patch): add -K flag which sets o_options, change -V to set - rcsver, send o_options and rcsver if in client mode. - (patch_fileproc): use RCS_checkout instead of RCS_fast_checkout in - order to ensure $Name is expanded, use o_options if set, or - options if set, or by default "-ko" when getting "old" file. - -Sun Sep 29 16:43:28 1996 Jim Kingdon - - * rcscmds.c: Replace comment at top of file concerning RCS library - with a reworded version based on discussion between me, Ian, Paul - Eggert, and JimB. - -Sun Sep 29 13:09:45 1996 Noel Cragg - - * main.c (main): don't create/update CVS/Root when doing the "cvs - login" command. Consider: if the user executes "cvs login" with - the working directory inside an already checked out module, we'd - incorrectly change the CVS/Root file to reflect the CVSROOT of the - "cvs login" command. - - * login.c (login): if we're re-logging into a server for which a - .cvspass entry already exists, copy the temporary file to its home - location rather than renaming. Renaming doesn't work between - filesystems. After copying, unlink the temporary file. - -Fri Sep 27 05:24:56 1996 Jim Kingdon - - * diff.c: Add comment about --brief option. - - * README-rm-add: Removed; the information which was here is now in - cvs.texinfo. - * Makefile.in (DISTFILES): Remove README-rm-add. - -Wed Sep 25 10:00:00 1996 Larry Jones - - * Makefile.in (cvsbug): Add dependency on version.c. - -Wed Sep 25 09:01:48 1996 Jim Kingdon - - * filesubr.c (get_homedir), update.c (update): Reindent. - -Wed Sep 25 04:44:54 1996 Jim Blandy - - * version.c (version_string): Bump to 1.8.86. - -Wed Sep 25 05:17:50 1996 Jim Blandy - - * update.c (update): Don't neglect to pass the -kmumble options - to the server. - * sanity.sh (binfiles-sticky): New tests for above. - - * cvsrc.c (read_cvsrc): Deal correctly with lines that specify a - command, but no options; don't corrupt argv. - - * sanity.sh: When testing rsh, use the program specified by - the CVS_RSH environment variable, if it's set. Move test to top - of file, so it runs before all other tests (it's really a - meta-test). - - * filesubr.c (get_homedir): Use getpwuid to find the home - directory, if the HOME environment variable isn't set. - * ignore.c (ign_add_file): Call get_homedir to find the user's - home directory; this is more portable than calling getpwuid. - -Tue Sep 24 09:08:17 1996 Jim Kingdon - - * log.c (log_tree): When walking through branches, follow the - ->prev field rather than following ->next which insures that the - loop only executes once and we only see the last branch. - * sanity.sh (multibranch): Test "cvs log" too; tests for above fix. - -Mon Sep 23 09:55:22 1996 Norbert Kiesel - - * options.h.in: Fixed some typos in the comments and reindented - them. - -Sat Sep 21 02:33:26 1996 Jim Blandy - - * sanity.sh: If we're testing remote CVS, make sure rsh itself is - working before running any tests. It's confusing when basica-1 - fails just because you don't have the local host in your .rhosts - file. - - * version.c (version_string): Bump to 1.8.85. - -Thu Sep 19 09:15:41 1996 Jim Kingdon - - * options.h.in: Define SERVER_FLOWCONTROL, SERVER_HI_WATER, - SERVER_LO_WATER. Several large sites (FreeBSD, Cygnus) have been - pounding on this code without problems, and it doesn't seem to - have any significant downsides. - -Tue Sep 17 01:13:41 1996 Jim Kingdon - - * status.c (status_fileproc): Instead of a default case, set sstat - before the switch. This way gcc -Wall can detect a missed case. - Add explicit T_TITLE case. - -Tue Sep 17 00:09:44 1996 Assar Westerlund - - * login.c (login): Print usage if argc < 0. - -Tue Sep 17 00:09:44 1996 Jim Kingdon - - * lock.c: In comment, mention one more function of readlocks - (fileattr not updated atomically). Note similarity between - solutions #2 and #5. - - * checkout.c (safe_location): Do not reject a location merely - because it textually starts with hardpath; insist that it be - hardpath or a subdirectory thereof. - -Mon Sep 16 11:46:36 1996 Jim Kingdon - - * server.c (server_cleanup): Add comment about ignoring errors - from unlink_file_dir. - -Mon Sep 16 10:31:48 1996 Norbert Kiesel - - * main.c: Add support for -T command line option. This - is needed for servers started via inetd. - (usg): Added line for -T. Improved -z documentation. - (main): Read default for tmpdir from the environment. Test for 'T' - in getopt loop. Use '/tmp' as ultimative fallback. Update - environment if possible. - - * cvs.h (TMPDIR_ENV): Added for -T command line option. - - * options.h.in: Add TMPDIR_DFLT - - * import.c (update_rcs_file): Use global variable Tmpdir instead - of reading the environment. - - * server.c (server_cleanup): Use global variable Tmpdir instead of - reading the environment. Also, replace system("rm -rf") with - unlink_file_dir. - (server): Use global variable Tmpdir instead of reading the - environment. - -Thu Sep 12 1996 Jim Kingdon - - * main.c (main): If ARGV0_NOT_PROGRAM_NAME, then just set - program_name to "cvs" rather than argv[0]. - -Thu Sep 12 12:06:56 1996 Jim Kingdon - - * client.c (update_entries): If we can't write the file, don't - make it a fatal error. - -Wed Sep 11 12:46:23 1996 Jim Kingdon - - * client.c (start_server): Move START_SERVER_RETURNS_SOCKET code - so that it is only run for server_method. It is wrong for - pserver_method (in which connect_to_pserver sets server_sock). - - * login.c (construct_cvspass_filename): If NO_SLASH_AFTER_HOME, - don't put a '/' between $HOME and .cvspass. Reindent function. - * build_src.com: Add zlib.c, login.c, and scramble.c. - - * rcs.c (RCS_deltas): When looking for our branch in ->branches, - check the branch number. - * sanity.sh (multibranch): New tests test for above fix. - - * commit.c (precommit_list_proc): Fix typo in last change - (->status to ->type). - -Tue Sep 10 23:05:41 1996 Jim Kingdon - - * Makefile.in (DISTFILES): Add build_src.com. - * build_src.com: Add buffer.c, buffer.obj, and zlib.olb. - -Tue Sep 10 20:35:23 1996 Juergen Renz - and Jim Kingdon - - * commit.c (precommit_list_proc): Update to reflect Jul 22 change - in which p->data was changed from a Ctype to a struct - logfile_info *. This means that commitinfo scripts again get - passed the file list like they should. - -Tue Sep 10 20:35:23 1996 Jim Kingdon - - * client.c (auth_server_port_number): Change name of service from - "cvs" to "cvspserver". The latter is what the manual has always - recommended, and it is also officially registered with IANA. - -Tue Sep 10 11:12:42 1996 Mark A. Solinski - and Jim Kingdon - - * client.c (socket_buffer_output): Change ifdef VMS to ifdef - SEND_NEVER_PARTIAL. - (start_server): Change ifdef VMS to ifdef START_SERVER_RETURNS_SOCKET. - -Tue Sep 10 17:15:21 1996 Jim Blandy - - * client.c (auth_server_port_number): Look up "cvs" in the - services database, and use the value it returns; fall back to - CVS_AUTH_PORT if no entry is present. - (connect_to_pserver): Use the correct port number in any error - messages. - -Tue Sep 10 11:12:42 1996 Jim Kingdon - - * sanity.sh (newb): New test newb-123j0 tests for another "cvs - status" case. - -Sun Sep 8 15:20:37 1996 Ian Lance Taylor - - * rcs.c (RCS_checkout): Clarify handling of options parameter. - - * rcs.c (RCS_checkout): Free buffer allocated by RCS_deltas. - -Sat Sep 7 21:28:27 1996 Jim Kingdon - - * main.c (struct cmd): Add comment concerning recognizing unique - abbreviations. - -Fri Sep 6 22:31:52 1996 Jim Kingdon - - * rcs.c (RCS_checkout): Fix indentation. - -Fri Sep 6 11:48:08 1996 Ian Lance Taylor - - * rcs.c (RCS_checkout): Replace tag parameter with rev and nametag - parameters. Change all callers. - * rcs.h (RCS_checkout): Update declaration. - - * rcs.c (RCS_getversion): Replace return_both parameter with - simple_tag. Change all callers. - (RCS_gettag): Likewise. - * rcs.h (RCS_getversion, RCS_gettag): Update declarations. - * vers_ts.c (Version_TS): Simplify vn_tag initialization using new - simple_tag rather than old return_both. - * cvs.h (struct vers_ts): Clarify vn_tag comment a bit. - - * main.c (usg): Only mention -x if ENCRYPTION is defined. - (main): Mention ENCRYPTION define in comment for -x. - * client.h (krb_encrypt_buffer_initialize): Only declare if - ENCRYPTION is defined. - * client.c (start_server): Only encrypt if ENCRYPTION is defined. - * server.c (serve_kerberos_encrypt): Only define if ENCRYPTION is - defined. - (requests): Only include Kerberos-encrypt is ENCRYPTION is - defined. - (krb_encrypt_*): Only define if ENCRYPTION is defined. - -Thu Sep 5 17:32:39 1996 Ian Lance Taylor - - * sanity.sh: When testing remote, use :ext: instead of :server: to - match change made earlier today. - -Thu Sep 5 13:57:47 1996 Jim Kingdon - - * client.c (start_tcp_server): Don't allow :kserver: to mean - "direct tcp" (root.c already takes care of this, but I want to - make it clear what is intended, and not intended, here). - (start_server): Handle ext_method (external rsh program) and - server_method (internal rsh client) separately. - * client.c: Take rsh_pid and start_rsh_server out of - RSH_NOT_TRANSPARENT ifdefs. It is useful for things like SSH on NT. - * cvs.h (CVSmethod), root.c (method_names): Add ext_method. - * root.c (parse_cvsroot): Recognize "ext" access method. - If access method is not specified and CVSROOT contains a colon, - use either ext_method or server_method depending on - RSH_NOT_TRANSPARENT. - -Thu Sep 5 00:09:49 1996 Ian Lance Taylor - - * rcs.c (RCS_checkout): Remove flags parameter, which was not - serving any useful purpose. Change all callers. - * rcscmds.c (RCS_exec_checkout): Likewise. - - * rcscmds.c (RCS_exec_checkout): Rename from RCS_checkout. Change - all callers. - * rcs.c (RCS_checkout): Rename from RCS_fast_checkout. Change all - callers. - -Wed Sep 4 14:42:28 1996 Ian Lance Taylor - - * rcs.c (RCS_fast_checkout): If tracing, output a message. If - noexec, and workfile is not NULL, just return immediately. Assert - that sout is RUN_TTY or workfile is NULL, rather than using it as - a conditional. Replace found variable with two variables--gothead - and keywords--reflecting what it actually means. - - * rcs.c (RCS_fast_checkout): Don't handle the case of workfile set - to "". - * rcscmds.c (RCS_checkout): Likewise. - * checkin.c (Checkin): Pass explicit file name, not "", to - RCS_fast_checkout. - * update.c (join_file): Likewise. - * commit.c (remove_file): Pass explicit file name to - RCS_fast_checkout and RCS_checkin. - - * rcs.c (RCS_reparsercsfile): Always continue after seeing - RCSSYMBOLS, even if the value is NULL. Clear the NODELTA flag - after setting delta_pos. - (free_rcsnode_contents): New static function. - (freercsnode): Call free_rcsnode_contents. - (RCS_fast_checkout): If NODELTA is set, reparse the RCS file. - (RCS_settag): New function. Change all callers to old function. - (RCS_deltag, RCS_setbranch): Likewise. - (RCS_lock, RCS_unlock): Likewise. - (RCS_deltas): If NODELTA is set, reparse the RCS file. - * rcs.h (NODELTA): Define. - (RCS_settag, RCS_deltag, RCS_setbranch): Declare. - (RCS_lock, RCS_unlock): Declare. - * rcscmds.c (RCS_exec_settag): Rename from RCS_settag. Don't - check tag against BASE or HEAD (now done in new RCS_settag). - (RCS_exec_deltag): Rename from RCS_deltag. - (RCS_exec_setbranch): Rename from RCS_setbranch. - (RCS_exec_lock): Rename from RCS_lock. - (RCS_exec_unlock): Rename from RCS_unlock. - * cvs.h: Update declarations of renamed functions. - * checkin.c (Checkin): Remove rcscopy variable (no longer needed - because of change in RCS_unlock call). - * commit.c: Include . - (remove_file): Update RCSNode path if the file is renamed. - (unblockrcs): Change rcs parameter to RCSNode. Change all - callers. - (fixbranch): Likewise. - (lock_RCS): Likewise. Don't call RCS_parsercsfile. - (checkaddfile): Update RCSNode path if the file is renamed. After - creating a new file, call RCS_parse. When stubbing a branch, use - the passed in RCSNode if there is one, rather than calling - RCS_Parse. Don't call RCS_Parse again after calling RCS_settag. - Free head and magicrev even if RCS_settag fails. - * import.c (add_rev): Change rcs parameter to RCSNode. Change all - callers. - (add_tag): Likewise. - - * rcs.c (RCS_fast_checkout): Amend last patch: if workfile is - NULL, but sout is not NULL, use sout in error message. - -Wed Sep 4 13:35:09 1996 Jim Kingdon - - * version.c: Increment version number to 1.8.8. - - * Version 1.8.7. - -Wed Sep 4 1996 Jim Kingdon - - * client.c (send_file_names): Look for the name to send in - Entries even if the file doesn't exist; we should send the - name as it appears in Entries in the "rm foo; cvs update FOO" - case. - -Tue Sep 3 20:50:11 1996 William A. Hoffman - - * rcs.c (RCS_fast_checkout): If workfile is NULL, don't try to - include it in error message. - -Mon Aug 26 12:27:38 1996 Jim Kingdon - - * mkmodules.c (mkdir_if_needed): Move from here ... - * filesubr.c, cvs.h (mkdir_if_needed): ... to here. Have it - return a value saying whether the directory was created. - * client.c (call_in_directory), edit.c (edit_fileproc): Call it. - -Fri Aug 23 19:19:44 1996 Ian Lance Taylor - - * checkin.c (Checkin): Copy rcs parameter in case it is freed when - finfo->rcs is freed. - -Fri Aug 23 14:55:41 1996 Jim Kingdon - - * remove.c (remove_fileproc): Revert change of 23 Aug to print - getwd and finfo->file in message. The latter is redundant with - fullname and the former is redundant with fullname and the working - directory when CVS was invoked. The implementation was also - lacking as the getwd call could overflow the buffer. - -Fri Aug 23 18:40:35 1996 Norbert Kiesel - - * remove.c (cvsremove): fix remove -f for client/server - -Fri Aug 23 11:28:27 1996 Jim Kingdon - - * wrapper.c, cvs.h: Remove conflictHook field of WrapperEntry, - WRAP_CONFLICT in WrapMergeHas, and 'c' option in wrap_add; they - are never used. - -Fri Aug 23 11:41:46 1996 Norbert Kiesel - - * server.c (switch_to_user): use #ifdef SETXID_SUPPORT instead of - #if SETXID_SUPPORT - -Thu Aug 22 14:18:43 1996 Ian Lance Taylor - - * checkin.c (Checkin): Remove local variable xfinfo. Reparse the - RCS file after the checkin. Call RCS_fast_checkout rather than - RCS_checkout. - - * cvs.h (RCS_FLAGS_LOCK): Don't define. - (RCS_FLAGS_*): Adjust values to fill in hole left by removal of - RCS_FLAGS_LOCK. - * rcs.c (RCS_fast_checkout): Don't check for RCS_FLAGS_LOCK. - * rcscmds.c (RCS_checkout): Likewise. - * commit.c (commit_fileproc): Remove rcs local variable. If - status is T_MODIFIED, require that finfo->rcs be set, call - Lock_RCS directly, and don't call locate_rcs. If adding to a tag, - require that finfo->rcs be set, and don't call locate_rcs. - (remove_file): Remove rcs local variable. Require that finfo->rcs - be set. Don't call locate_rcs. Don't pass RCS_FLAGS_LOCK to - RCS_checkout; use RCS_lock instead. Call RCS_fast_checkout rather - than RCS_checkout. - (unlockrcs): Use a single rcs parameter rather than two parameters - for file and repository. Change all callers. Don't call - locate_rcs. - (fixbranch): Likewise. - (lockrcsfile): Remove; no more callers. - -Tue Aug 20 10:13:59 1996 Jim Kingdon - - * buffer.c, rcs.c: Don't use inline. It wasn't being used in a - loop or any such place where it would matter for performance, and - it was a (minor) portability hassle. - - * server.c (server): Change "Dummy argument 0" to "cvs server" and - add comment explaining why. - - * rcs.c (linevector_add): Add comment regarding changing \n to \0. - -Tue Aug 20 09:19:19 1996 Norbert Kiesel - - * checkout.c (checkout_proc): Call RCS_parse to get the default - options from the RCS file. - - * sanity.sh (binfiles): Add tests 5.5b0 and 5.5b1 for the above fix - -Mon Aug 19 18:13:32 1996 Ian Lance Taylor - - * rcs.c (linevector_init): Make inline. Set lines_alloced to 0, - not 10. Set vector to NULL. - (linevector_add): Remove assertion that lines_alloced is greater - than zero. Initialize lines_alloced if necessary. - (linevector_copy): Initialize lines_alloced if necessary. - (linevector_free): Only free vector if it is not NULL. - (RCS_deltas): Always call linevector_init and linevector_free on - curlines, headlines, and trunklines. - (RCS_fast_checkout): Remove #if 0 around code that calls - RCS_deltas. - -Fri Aug 16 17:52:54 1996 Ian Lance Taylor - - * rcs.c (linevector_add): Handle zero length correctly. - (RCS_deltas): In RCS_FETCH case, the data is in headlines, not - curlines. - (RCS_fast_checkout): Update comment about RCS_deltas: the - testsuite now passes. - - * rcs.c (RCS_fully_parse): Use the length of the value, rather - than assuming that there are no embedded zero bytes. - (struct line): Add len field. - (linevector_add): Add len parameter. Change all callers. Use - len, rather than assuming that there are no embedded zero bytes. - Set the len field in new lines. - (RCS_deltas): Use the length of the value, rather than assuming - that there are no embedded zero bytes. Use the line length when - outputting it and when copying it. - (RCS_fast_checkout): Update comment about RCS_deltas to remove - note about supporting zero bytes correctly. - -Thu Aug 15 23:38:48 1996 Jim Kingdon - - * commit.c, import.c: Revise comments regarding the fact that we - call start_server before do_editor. - -Thu Aug 15 11:30:55 1996 Ian Lance Taylor - - * server.c: Include if AUTH_SERVER_SUPPORT. - (pserver_authenticate_connection): Set SO_KEEPALIVE on - STDIN_FILENO. - (kserver_authenticate_connection): Likewise. - -Thu Aug 15 10:26:41 1996 Norbert Kiesel - - * server.c (switch_to_user): Fix previous patch to compile it for - both HAVE_KERBEROS and AUTH_SERVER_SUPPORT - -Wed Aug 14 14:02:00 1996 Norbert Kiesel - - * server.c (check_password): if available use getspnam instead of - getpwnam when reading system passwords. This allows cvs pserver - to run on systems with shadow passwords. - (switch_to_user): new static function. Contains the extracted - common tail of kserver_authenticate_connection and - pserver_authenticate_connection. If compiled with SETXID_SUPPORT, - honor the setgid bit if it is set. - (check_repository_password): turn into a static function - (check_password): ditto - (pserver_authenticate_connection): little code cleanup - -Wed Aug 14 01:07:10 1996 Greg A. Woods - - * history.c (history): apply fix posted by Steven Meyer - to info-cvs to correct handling of '-D' - argument. Message-Id: <9608122335.AA01385@nijel.blacksmith.com> - -Tue Aug 13 13:42:36 1996 Ian Lance Taylor - - * log.c (cvslog): Remove comment about calling rlog. - * rcs.c (translate_symtag): Correct typo in comment (l ist -> - list). - * server.c (server_write_entries): Add omitted word (lists) in - comment. - -Tue Aug 13 14:01:49 1996 Norbert Kiesel - - * wrapper.c (wrap_rcsoption): fix memory access error - - * rcs.c (RCS_fast_checkout): fix memory access error (triggered - by an empty option string) - -Mon Aug 12 17:45:15 1996 Jim Kingdon (unknown@beezley) - - * buffer.c, zlib.c: If EIO is not defined, try to define it. - -Mon Aug 12 10:33:27 1996 Jim Kingdon - - * import.c (comtable): Add comment concerning applicability with - RCS 5.7. - - * server.c (server): If TMPDIR is not an absolute pathname, give - an error. - -Mon Aug 12 10:34:43 1996 Norbert Kiesel - - * main.c: add synonym "ann" for "annotate" again - -Sun Aug 11 17:54:11 1996 Jim Kingdon - - * rcs.h (RCS_RLOG): Removed; no longer used. - -Fri Aug 9 20:16:20 1996 Ian Lance Taylor - - * server.c (dirswitch): Open the Entries file with mode "a" rather - than "w+". - (server_write_entries): Open the Entries file with mode "a" rather - than "w". - * sanity.sh (modules): Add topfiles module and 155cN tests for - above patch. - -Fri Aug 9 12:11:25 1996 Jim Kingdon - - * main.c (cmd): Add comment regarding synonyms. - -Thu Aug 8 14:40:10 1996 Jim Kingdon - - * main.c: Remove synonyms for "cvs annotate". Synonyms create - user confusion. - -Thu Aug 8 10:24:04 1996 Norbert Kiesel - - * main.c: Revert (undocumented) change to rename the cvs history - alias "his" to "hist" - -Wed Aug 7 18:26:25 1996 Ian Lance Taylor - - * server.c (cvs_output): Change str parameter to const char *. - Correct loop to print from p, not str. - (cvs_outerr): Likewise. - * cvs.h (cvs_output, cvs_outerr): Update declarations. - - * server.c (receive_partial_file): Read and discard remaining file - data on a write error. - (serve_modified): Discard data while size > 0, not >=. - -Wed Aug 7 15:11:40 1996 Norbert Kiesel - - * main.c (cmds): Add some aliases for "annotate". - (usg): Improve usage message text - (cmd_synonyms): New function to print the command synonym list - (main): Add new option --help-synonyms - -Wed Aug 7 00:07:31 1996 Ian Lance Taylor - - Keep track of subdirectories in the Entries file. - * cvs.h (enum ent_type): Define. - (struct entnode): Add type field. - (struct stickydirtag): Add subdirs field. - (Subdirs_Known, Subdir_Register, Subdir_Deregister): Declare. - (ignore_files): Update declaration for new parameter. - (FILESDONEPROC): Add entries parameter. - (DIRENTPROC, DIRLEAVEPROC): Likewise. - * entries.c (Entnode_Create): Add type parameter. Change all - callers. - (write_ent_proc): If closure is not NULL, treat it as a pointer to - an int, and set it to 1 if a node is seen which is not ENT_FILE. - (write_entries): If subdirectory information is known, but no - subdirectories were written, write an unadorned D to the file. - (Scratch_Entry): Write an R command to Entries.Log. Don't rewrite - the Entries file. - (Register): Set entfilename. Write an A command rather than an - unadorned entries line. - (fgetentent): Add cmd and sawdir parameters. Change all callers. - If CMD is not NULL, expect and return a single character command. - Handle an initial D by setting the type to ENT_SUBDIR. - (fputentent): Output an initial D for an ENT_SUBDIR entry. - (Entries_Open): Handle removal commands in Entries.Log. Record - whether subdirectory information is known in the list private - data. - (Subdirs_Known): New function. - (subdir_record): New static function. - (Subdir_Register, Subdir_Deregister): New functions. - * find_names.c (add_entries_proc): Skip entries that are not - ENT_FILE. - (add_subdir_proc): New static function. - (register_subdir_proc): New static function. - (Find_Directories): If the Entries file has subdirectory - information, get the directories out of it. Otherwise, call - find_dirs, and add the information to the Entries file. - * recurse.c (struct frame_and_entries): Define. - (do_recursion): Don't call Entries_Close until after processing - dirlist. Pass entries to filesdoneproc. Pass a frame_and_entries - structure to do_dir_proc via walklist. - (do_dir_proc): Expect a frame_and_entries structure in closure, - not a recursion_frame. Pass entries to direntproc and - dirleaveproc. - * ignore.c (ignore_files): Add entries parameter. Change all - callers. If we have subdirectory information, check for - directories in entries. - * add.c (add): If client_active, call Subdir_Register on each new - directory. - (add_directory): Add entries parameter. Change caller. Call - Subdir_Register. - * checkout.c (build_dirs_and_chdir): Call Subdir_Register. - * client.c (call_in_directory): Call Subdir_Register for newly - created directories. Call Subdirs_Known or Find_Directories after - calling Entries_Open. - (process_prune_candidates): Call Subdir_Deregister. - * commit.c (findmaxrev): Skip entries that are not ENT_FILE. - * server.c (dirswitch): Call Subdir_Register. - * update.c (update_dirent_proc): Call Subdir_Register. - (update_dirleave_proc): Call Subdir_Deregister. - * Several files: Change direntproc, dirleaveproc, and - filesdoneproc routines to expect an entries argument. - - * rcs.c (translate_symtag): New static function. - (RCS_gettag): Use translate_symtag rather than RCS_symbols. - (RCS_nodeisbranch, RCS_whatbranch): Likewise. - -Tue Aug 6 15:36:09 1996 Ian Lance Taylor - - Finish the conversion of cvs log so that it never invokes rlog. - * log.c (struct log_data): Remove dorlog field. Add nameonly, - header, long_header, statelist, and authorlist fields. - (log_usage): Remove rlog-options. Add -R, -h, -t, -b, -s, -w. - (cvslog): Don't clear opterr. Handle -h, -R, -s, -t, -w. If an - unrecognized option is seen, call usage. - (log_parse_list): New static function. - (log_fileproc): Remove code that called rlog. Check nameonly, - header, and long_header fields in log_data. - (log_version_requested): Check statelist and authorlist. - - * log.c (struct datelist): Define. - (struct log_data): Add datelist and singledatelist fields. - (log_usage): Add -d. - (cvslog): Handle -d. - (log_parse_date): New static function. - (log_fileproc): Do special single date handling. - (log_version_requested): Check datelist and singledatelist. - (log_fix_singledate): New static function. - -Mon Aug 5 23:48:16 1996 Ian Lance Taylor - - * log.c (struct option_revlist): Define. - (struct revlist): Define. - (struct log_data): Add default_branch and revlist fields. - (struct log_data_and_rcs): Define. - (log_usage): Add -N and -r. - (cvslog): Handle -N and -r. - (log_parse_revlist): New static function. - (log_fileproc): Call log_expand_revlist and log_free_revlist. - Pass log_data_and_rcs structure to log_count_print via walklist. - (log_expand_revlist, log_free_revlist): New static functions. - (log_version_requested): New static function. - (log_count_print): New static function. - (log_tree): Add log_data and revlist parameter. Change all - callers. - (log_abranch): Likewise. - (log_version): Likewise. Call log_version_requested. - (version_compare): New static function. - * sanity.sh (log): New tests for -r, -b, and -N options to log. - -Sun Aug 4 11:19:30 1996 Ian Lance Taylor - - Handle simple cases of cvs log without invoking rlog. - * log.c (struct log_data): Define. - (cvslog): Use getopt to parse options. Set up a log_data - structure, and pass it to start_recursion. - (log_fileproc): Get arguments form callerdat rather than static - variables. In simple cases, print the log information directly, - rather than invoking rlog. - (log_symbol, log_count, log_tree): New static functions. - (log_abranch, log_version, log_branch): New static functions. - * rcs.h (struct rcsnode): Add other field. - (struct rcsversnode): Add other field. - (RCS_fully_parse): Declare. - * rcs.c (getrcsrev): Move declaration to start of file. - (RCS_reparsercsfile): Add all parameter. Change all callers. - (RCS_fully_parse): New function. - (freercsnode): Free other list. - (rcsvers_delproc): Free other list. - * hash.h (enum ntype): Add RCSFIELD. - * hash.c (nodetypestring): Handle RCSFIELD. - -Sat Aug 3 19:39:54 1996 Ian Lance Taylor - - * log.c (cvslog): Correct position of CLIENT_SUPPORT #endif. - -Thu Jul 25 12:06:45 1996 Ian Lance Taylor - - * update.c (join_file): If merging a branch, and the branch - revision does not exist, just return without doing anything. - * sanity.sh (join): Add cases file7 and file8 to test above - patch. - - * server.c (cvsencrypt): Rename from encrypt, to avoid conflict - with NetBSD unistd.h. Rename all uses. - - * server.c (krb_encrypt_buffer_output): Fix typo in comment (reply - -> replay). - -Thu Jul 25 10:37:32 1996 Jim Kingdon - - * server.c (krb_encrypt_buffer_output): Fix typo in comment - (krb_recv_auth -> krb_recvauth). - -Wed Jul 24 09:28:33 1996 Jim Kingdon - - * lock.c (set_lock): Adjust comment regarding why we call stat. - -Wed Jul 24 15:06:08 1996 Ian Lance Taylor - - Add encryption support over a Kerberos connection. - * main.c (usg): Mention -x if CLIENT_SUPPORT. - (main): Handle -x. - * client.h (encrypt): Declare. - (krb_encrypt_buffer_initialize): Declare. - * client.c (kblock, sched): New static variables if - HAVE_KERBEROS. - (start_tcp_server): Remove sched local variable. Copy - cred.session into kblock. - (start_server): Turn on encryption if requested. - * server.c (kblock, sched): New static variables if - HAVE_KERBEROS. - (serve_kerberos_encrypt): New static function. - (requests): Add "Kerberos-encrypt" if HAVE_KERBEROS. - (kserver_authenticate_connection): Remove sched local variable. - Copy auth.session into kblock. - (encrypt): New global variable. - (struct krb_encrypt_buffer): Define. - (krb_encrypt_buffer_initialize): New function. - (krb_encrypt_buffer_input): New static function. - (krb_encrypt_buffer_output): New static function. - (krb_encrypt_buffer_flush): New static function. - (krb_encrypt_buffer_block): New static function. - (krb_encrypt_buffer_shutdown): New static function. - -Wed Jul 24 09:28:33 1996 Jim Kingdon - - * recurse.c (do_recursion): Add comment about calling - Name_Repository in !(which & W_LOCAL) case. - - * expand_path.c (expand_variable): Fix typo (varaible -> variable). - -Tue Jul 23 15:05:01 1996 Ian Lance Taylor - - * update.c (update_fileproc): In T_REMOVE_ENTRY case, only call - server_scratch_entry_only if ts_user is NULL. - * sanity.sh (death2): Add death2-20 test for above patch. - - * diff.c (diff_fileproc): If a file is not in the working - directory, check that the tag is present before warning that no - comparison is possible. - * sanity.sh (death2): Add death2-diff-9 and death2-diff-10 tests - for above patch. - -Tue Jul 23 12:05:42 1996 Jim Kingdon - - * tag.c (tag_check_valid): Fix indentation. - - * client.c (handle_e): Flush stdout before writing to stderr. - (handle_m): Flush stderr before writing to stdout. - -Fri Jul 19 16:02:11 1996 Mike Ladwig - - * client.c: Added NO_CLIENT_GZIP_PROCESS to deal with the MacOS - client where Gzip-stream is supported, but "gzip-file-contents" is - not. - -Fri Jul 19 16:02:11 1996 Mike Ladwig - - * repos.c: Fixed recent patch which added plain fopen rather than - CVS_FOPEN - -Mon Jul 22 22:25:53 1996 Ian Lance Taylor - - * logmsg.c (tag): New static variable. - (setup_tmpfile): Don't print the prefix before calling fmt_proc. - Free tag if it is set. - (find_type): Get type from logfile_info struct. - (fmt_proc): Likewise. Print tag information. Handle all prefix - printing. - (revision): Remove static variable. - (Update_Logfile): Remove xrevision parameter. Change all - callers. - (title_proc): Get type from logfile_info struct. - (logfile_write): Remove revision parameter. Change all callers. - * cvs.h (struct logfile_info): Define. - (Update_Logfile): Update prototype. - * commit.c (find_fileproc): Set logfile_info information. - (check_fileproc): Likewise. - (commit_filesdoneproc): Don't call ParseTag. - (update_delproc): Free logfile_info information. - * add.c (add_directory): Set logfile_info information. - * import.c (import): Likewise. - - * tag.c (tag_check_valid): The special BASE and HEAD tags are - always valid. - * sanity.sh (basica): Add basica-6.3 test for above patch. - -Mon Jul 22 14:41:20 1996 Jim Kingdon - - * update.c (merge_file): Pass 0 not NULL to checkout_file (20 Jul - 96 change changed other calls to checkout_file but missed this one). - -Sat Jul 20 00:21:54 1996 Ian Lance Taylor - - * update.c (join_file): Check whether the target of the merge is - the same as the working file revision before checking whether the - file was added during the merge. - - * update.c (scratch_file): Remove existing parameters, and add a - single parameter of type struct file_info. Change all callers. - Warn if unlink_file fails. - (checkout_file): Remove resurrecting_out parameter. Add adding - parameter. Change all callers. Remove joining code. - (join_file): Remove resurrecting parameter. Rewrite to handle - joining dead or added revisions. - * classify.c (Classify_File): If there is no user file, and the - RCS file is dead, return T_UPTODATE rather than T_CHECKOUT. - * checkout.c (checkout_proc): Set W_ATTIC if there is a join tag. - * sanity.sh (join): New set of tests for above patches. - (death): Adjust tests 86, 89, 89a, 92.1c, 95 for above patches. - (import): Adjust test 113 for above patches. - -Thu Jul 18 19:24:08 1996 Jim Kingdon - - * lock.c: Add comment explaining what locks are for. Also discuss - various changes to locking which get proposed from time to time. - - * sanity.sh (death2): Change a number of test names from death-* - to death2-*. - - * wrapper.c (wrap_setup): Don't look in repository if client_active. - * wrapper.c, cvs.h (wrap_send): New function. - * update.c (update), import.c (import): Call it. - * sanity.sh (binwrap): Do binwrap tests for remote as well as - local; tests for above fixes. - - * wrapper.c: Add a few FIXME comments. - -Thu Jul 18 18:43:50 1996 Ian Lance Taylor - - * sanity.sh (patch): Fix names of a couple of tests to say patch - rather than death2. - -Thu Jul 18 16:19:21 1996 Bill Bumgarner - and Jim Kingdon - - * add.c (add), import.c (add_rcs_file): Check for options from - wrappers and use them if specified. - * cvs.h (WrapMergeHas): Add WRAP_RCSOPTION. - * wrapper.c (WrapperEntry): Add rcsOption field. - (wrap_add): Allow a single character argument to an option. - (wrap_add): Handle -k option. - (wrap_add_entry): Handle rcsOption field. - (wrap_name_has): Handle WRAP_RCSOPTION. - * wrapper.c, cvs.h (wrap_rcsoption): New function. - * add.c, import.c, wrapper.c: Minor beautification (mostly - removing trailing spaces). - * sanity.sh (binwrap): New tests test for this feature. - -Wed Jul 17 10:14:20 1996 Ian Lance Taylor - - * checkout.c (checkout): Remove extraneous else accidentally - inserted in last checkin. - -Tue Jul 16 11:37:41 1996 Ian Lance Taylor - - * sanity.sh (import): Use quoting to avoid expansion of RCS ID - strings. - - * sanity.sh (import): Use dotest to examine the output of test - 113, and the actual contents of the file in test 116. - - * update.c (join_file): Always skip rcsmerge if the two revisions - are the same (the old code always did the rcsmerge when two -j - options were specified). - - * checkout.c (history_name): New static variable. - (checkout): Permit both tag and date to be specified. Set - history_name. - (checkout_proc): Use history_name when calling history_write. - * rcs.c (RCS_getversion): If both tag and date are set, use - RCS_whatbranch to get the branch revision number of a symbolic - tag. - (RCS_getdatebranch): If the branch revision itself is early - enough, then use it if the first branch is not early enough. Add - comment for invalid RCS file. Don't bother to check for NULL - before calling xstrdup, since xstrdup checks anyhow. - - * client.h (file_gzip_level): Declare. - * client.c (file_gzip_level): Define. - (start_server): Don't set gzip_level to zero after sending - Gzip-stream command. Set file_gzip_level after sending - gzip-file-contents command. - (send_modified): Use file_gzip_level rather than gzip_level. - * server.c (server_updated): Likewise. - (serve_gzip_contents): Likewise. - - * sanity.sh (patch): New tests. Test remote CVS handling of - unpatchable files. - - * sanity.sh (death2): Accept a '.' in the temporary file name - printed by diff. - - * rcscmds.c (RCS_checkin): Remove noerr parameter. Change all - callers. - * cvs.h (RCS_checkin): Update declaration. - * commit.c (remove_file): Pass RCS_FLAGS_QUIET to RCS_checkin. - - * history.c (history): Cast sizeof to int to use correct type in - error printf string. - (report_hrecs): Cast strlen result to int to use correct type in - printf string. - - * server.c (cvs_flusherr): Correct typo in comment. - - * rcs.c (getrcskey): Hoist three constant strcmp calls out of the - value reading loop. - - * fileattr.c (fileattr_get): Change parameter types from char * to - const char *. - (fileattr_get0, fileattr_modify, fileattr_set): Likewise. - (fileattr_newfile): Likewise. - * fileattr.h (fileattr_get): Update declaration. - (fileattr_get0, fileattr_modify, fileattr_set): Likewise. - (fileattr_newfile): Likewise. - -Thu May 16 11:12:18 1996 Mark P. Immel - and Jim Kingdon - - * client.h, client.c, checkout.c (client_send_expansions): - Pass an additional parameter indicating where the checkout is - to occur, to avoid passing the wrong information to send_files(). - * sanity.sh (basicb): New test basicb-cod-1 tests for above fix. - -Mon Jul 15 18:26:56 1996 Ian Lance Taylor - - * recurse.c (do_recursion): Require a repository before calling - Find_Names. - * repos.c (Name_Repository): Remove sanity checks which spend time - examining the filesystem. - -Mon Jul 15 1996 Jim Kingdon - - * client.c (send_file_names): Send file names as they appear - in CVS/Entries, rather than as specified (in cases where they - might differ in case). - (send_fileproc): Use file name from CVS/Entries (vers->entdata->user) - rather than file name as specified (finfo->file) when available. - -Sun Jul 14 15:39:44 1996 Mark Eichin - and Ian Lance Taylor - - Improve diff -N handling of nonexistent tags and removed files. - * diff.c (enum diff_file): New definition for whole file, moving - unnamed enum out of diff_fileproc, renaming DIFF_NEITHER to - DIFF_DIFFERENT, and adding DIFF_SAME. - (diff): Look through the repository even if only one revision is - given. - (diff_fileproc): Change empty_file to be enum diff_file. If there - is no user revision, but there is a repository file, treat it as a - removed file. Pass empty_file to diff_file_nodiff, and set it - from the return value. - (diff_file_nodiff): Change return type to enum diff_file. Replace - just_set_rev parameter with enum diff_file empty_file parameter. - Change handling of a missing tag to return an enum diff_file value - if empty_files is set, rather than reporting an error. Free tmp - if xcmp returns 0. - * sanity.sh (death2): Add tests for above patches. - -Sat Jul 13 19:11:32 1996 Jim Kingdon - - * rcs.c (annotate): In sending options to server, reverse sense of - test so that we send -f iff -f was specified, rather than iff -f was - not specified. - -Fri Jul 12 20:23:54 1996 Greg A. Woods - - * zlib.c (compress_buffer_input): add a couple of casts for - uses of z_stream's next_in and next_out - -Fri Jul 12 18:55:26 1996 Ian Lance Taylor - - * zlib.c: New file. - * client.c (log_buffer_block): Call set_block and set_nonblock, - rather than lb->buf->block. - (log_buffer_shutdown): New static function. - (get_responses_and_close): Call buf_shutdown on to_server and - from_server. - (start_server): If "Gzip-stream" is supported, use it rather than - "gzip-file-contents". - * server.c (print_error): Call buf_flush rather than - buf_send_output. - (print_pending_error, serve_valid_responses): Likewise. - (serve_expand_modules, serve_valid_requests): Likewise. - (do_cvs_command): Call buf_flush rather than buf_send_output - before the fork, and in the parent after the child has completed. - In the child, set buf_to_net and buf_from_net to NULL. - (serve_gzip_stream): New static function. - (requests): Add "Gzip-stream". - (server_cleanup): Don't do anything with buf_to_net if it is - NULL. Call buf_flush rather than buf_send_output. Call - buf_shutdown on buf_to_net and buf_from_net. Call error for an - malloc failure rather than buf_output to buf_to_net. - * buffer.h (struct buffer): Add shutdown field. - (buf_initialize): Update declaration for new shutdown parameter. - (compress_buffer_initialize): Declare. - (buf_shutdown): Declare. - * buffer.c (buf_initialize): Add shutdown parameter. Change all - callers. - (buf_shutdown): New function. - * Makefile.in (SOURCES): Add zlib.c - (OBJECTS): Add zlib.o. - ($(PROGS)): Depend upon ../zlib/libz.a. - (cvs): Link against ../zlib/libz.a. - (zlib.o): New target. - -Fri Jul 12 1996 Jim Kingdon - - * client.c (log_buffer_input, log_buffer_output): Use size_t - to avoid Visual C++ signed/unsigned warnings. - -Thu Jul 11 22:01:37 1996 Jim Kingdon - - * client.c (handle_f): Reindent. - - * client.c (mode_to_string, handle_m, handle_e, - auth_server_port_number, get_responses_and_close), server.c - (pserver_authenticate_connection, serve_modified, - serve_enable_unchanged, wait_sig, server_cleanup): Reindent. - * server.c: Remove #if 0'd block of code above - check_repository_password; it was yanked out of some unknown - context and didn't seem to be very useful. - -Thu Jul 11 20:10:21 1996 Ian Lance Taylor - - * server.c (do_cvs_command): Pass new special parameter to - buf_copy_counted. If it gets set to -1, send an 'F' response if - the client supports it, and call cvs_flusherr. - (cvs_flusherr): New function. - * cvs.h (cvs_flusherr): Declare. - * client.c (handle_f): New static function. - (responses): Add "F". - * buffer.c (buf_send_special_count): New function. - (buf_copy_counted): Add special parameter. Handle negative counts - specially. - * buffer.h (buf_send_sepcial_count): Declare. - (buf_copy_counted): Update declaration. - * lock.c (lock_wait, lock_obtained): Call cvs_flusherr. - - Change the client to use the buffer data structure. - * client.c: Include "buffer.h". - (to_server): Change to be struct buffer *. - (to_server_fp): New static variable. - (from_server): Change to be struct buffer *. - (from_server_fp): New static variable. - (from_server_logfile, to_server_logfile): Remove. - (buf_memory_error): New static function. - (struct log_buffer): Define. - (log_buffer_initialize, log_buffer_input): New static functions. - (log_buffer_output, log_buffer_flush): New static functions. - (log_buffer_block): New static function. - (struct socket_buffer): Define if NO_SOCKET_TO_FD. - (socket_buffer_initialize): New static function if - NO_SOCKET_TO_FD. - (socket_buffer_input, socket_buffer_output): Likewise. - (socket_buffer_flush): Likewise. - (read_line): Rewrite to use buf_read_line. Remove eof_ok - parameter (it was always passed as 0); change all callers. - (send_to_server): Rewrite to use buf_output. - (try_read_from_server): Rewrite to use buf_read_data. - (get_responses_and_close): Use from_server_fp and to_server_fp for - the streams. Check buf_empty_p when checking for dying gasps. - (start_server): Don't set from_server_logfile and - to_server_logfile; instead, call log_buffer_initialize. If - NO_SOCKET_TO_FD and use_socket_style, call - socket_buffer_initialize; otherwise, call - stdio_buffer_initialize. - * buffer.c: Compile if CLIENT_SUPPORT is defined. - (buf_flush): Fix comment to describe return value. - (buf_read_line): Add lenp parameter. Change all callers. Look - for a line terminated by \012 rather than \n. - * buffer.h: Compile if CLIENT_SUPPORT is defined. - (buf_read_line): Update declaration. - - * server.c (server): Initialize buf_to_net, buf_from_net, - saved_output, and saved_outerr before setting error_use_protocol. - (pserver_authenticate_connection): Don't set error_use_protocol. - Errors before the authentication is complete aren't handled - cleanly anyhow. Change error call after authentication to use - printf. - -Thu Jul 11 1996 Jim Kingdon - - * client.c (start_server): Open logfiles in binary, not text, mode. - -Wed Jul 10 19:24:22 1996 Jim Kingdon - - * server.c (print_pending_error, print_error): Remove comments - about deadlocks; they don't apply here. Add comments saying - that these functions must only be called when it is OK to - send output (which is why the deadlock concern doesn't apply). The - comments remain for server_cleanup and serve_valid_responses, - where they are an example of the "print a message and exit" - behavior which is noted in cvsclient.texi and which also exists - places like kserver_authenticate_connection. - -Wed Jul 10 18:24:46 1996 Ian Lance Taylor - - * server.c (print_error): Add comment warning about potential - deadlock. - (print_pending_error, serve_valid_responses): Likewise. - (server_cleanup): Likewise. - (serve_directory): Don't call buf_send_output. - (serve_modified, serve_notify, server, cvs_outerr): Likewise. - (serve_expand_modules): Call buf_send_output. - (serve_valid_requests): Likewise. - -Wed Jul 10 15:51:29 1996 Jim Kingdon - - * main.c (main): Print a warning for rlog command. - -Wed Jul 10 15:00:55 1996 Ian Lance Taylor - - Abstract the buffer data structure away from the underlying - communication medium. - * buffer.h (struct buffer): Remove fd and output fields. Add - input, output, flush, block, and closure fields. - (buf_initialize, buf_nonio_initialize): Declare. - (stdio_buffer_initialize, buf_flush): Declare. - (buf_read_line, buf_read_data): Declare. - * buffer.c: Include . Don't include . - (O_NONBLOCK, blocking_error): Don't define. - (buf_initialize, buf_nonio_initialize): New functions. - (buf_send_output): Use output function, rather than write. - (buf_flush): New function. - (set_nonblock, set_block): Use block function, rather than calling - fcntl. - (buf_send_counted): Don't check output. - (buf_input_data): Call input function, rather than read. - (buf_read_line, buf_read_data): New functions. - (buf_copy_lines, buf_copy_counted): Don't check output. - (stdio_buffer_initialize): New function. - (stdio_buffer_input, stdio_buffer_output): New static functions. - (stdio_bufer_flush): New static function. - * server.c: Include "getline.h". - (buf_to_net): Change to be a pointer. Change all uses. - (protocol, saved_output, saved_outerr): Likewise. - (buf_from_net): New static variable. - (no_mem_error, NO_MEM_ERROR, read_line): Remove. - (struct fd_buffer): Define. - (fd_buffer_initialize, fd_buffer_input): New static functions. - (fd_buffer_output, fd_buffer_flush): New static functions. - (fd_buffer_block): New static function. - (serve_directory): Call buf_read_line rather than read_line. - (serve_notify, server): Likewise. - (receive_partial_file): Call buf_read_data rather than fread. - (serve_modified): Call buf_read_line rather than read_line. Call - buf_read_data rather than fread. - (do_cvs_command): Initialize buffers with fd_buffer_initialize. - Change stdoutbuf, stderrbuf, and protocol_inbuf to be pointers. - (server): Initialize buffers using fd_buffer_initialize, - stdio_buffer_initialize, and buf_nonio_initialize. - (check_repository_password): Call getline rather than read_line. - -Wed Jul 10 15:51:29 1996 Jim Kingdon - - * commit.c (find_fileproc): Add comments describing a few cases - that we aren't handling. - -Tue Jul 9 04:33:03 1996 Jim Kingdon - - * rcs.c (RCS_deltas): New function, created from guts of old - annotate_fileproc. - (annotate_fileproc): Call RCS_deltas. - (RCS_fast_checkout): Call it (commented out for now; see comment - for reasons). - - * cvs.h, recurse.c (start_recursion): Add callerdat argument. - * cvs.h: Add callerdat argument to recursion processor callbacks. - * recurse.c: add it to struct recursion_frame and pass it to all - the callbacks. - * admin.c, client.c, commit.c, diff.c, edit.c, lock.c, log.c, - patch.c, rcs.c, remove.c, rtag.c, status.c, tag.c, update.c, - watch.c: Update all the functions used as callbacks. Update calls - to start_recursion. - * commit.c (find_filesdoneproc, find_fileproc, find_dirent_proc, - commit), tag.c (val_fileproc, tag_check_valid): Use callerdat - instead of a static variable. - - * recurse.c (do_recursion): Make static and move declaration to here... - * cvs.h: ...from here. - * recurse.c (do_recursion): Replace plethora of arguments with - single struct recursion_frame *. Change callers. - * recurse.c: New structure frame_and_file. Use it and existing - struct recursion_frame structures to pass info to do_file_proc and - do_dir_proc. Remove globals fileproc, filesdoneproc, direntproc, - dirleaveproc, which, flags, aflag, readlock, and dosrcs. - -Tue Jul 9 11:13:29 1996 Ian Lance Taylor - - * modules.c (do_module): Call cvs_outerr rather than fprintf. - -Mon Jul 8 1996 Jim Kingdon - - * rcs.c (RCS_fast_checkout): If -kb is not in use, open the - working file in text, not binary, mode. - -Sun Jul 7 10:36:16 1996 Jim Kingdon - - * rcscmds.c (RCS_settag): Add comment regarding moving check for - reserved tag names to RCS_check_tag. - - * rcscmds.c: Add comment regarding librarifying RCS and related - issues. This is a lightly edited version of a message I sent to - the CVS developers and didn't get flamed for, so it would appear - to be relatively uncontroversial. - - * rcs.c (annotate): Remove comment suggesting -r option and - related functionality; it is done. - -Fri Jul 5 17:19:57 1996 Ian Lance Taylor - - * client.c (last_entries): Make file static, rather than function - static within call_in_directory. - (get_responses_and_close): If last_entries is not NULL, pass it to - Entries_Close. - - * server.c (server_pause_check): Check for errors when reading - from flowcontrol_pipe. - - * client.c (call_in_directory): If dir_name is ".", call - Create_Admin if there is no CVS directory. - (send_dirent_proc): If there is no CVS subdirectory, pretend that - the directory does not exist (i.e., don't try to send any files in - the directory). - * server.c (dirswitch): If dir is "." in the top level repository, - add "/." after the Repository entry. - * sanity.sh (modules): Add test 155b for above patches. - -Thu Jul 4 15:57:34 1996 Ian Lance Taylor - - * server.c (buf_to_net): Move definition near top of file. - (read_line): Call buf_send_output rather than fflush. - (print_error): Output information to buf_to_net buffer rather than - stdout. - (print_pending_error, serve_valid_responses): Likewise. - (server_notify, do_cvs_command, server_co): Likewise. - (expand_proc, serve_expand_modules, server_prog): Likewise. - (serve_valid_requests, server_cleanup, server): Likewise. - (server_notify): Don't call fflush on stdout. - (do_cvs_command): Flush saved_output and saved_outerr to - buf_to_net before fork. Flush buf_to_net before fork. In child, - just initialize memory_error field of saved_output and - saved_outerr. - (server_cleanup): Flush buf_to_net. - (server): Initialize saved_output and saved_outerr. - (cvs_output): Add support for error_use_protocol case. - (cvs_outerr): Likewise. - * error.c (error): In HAVE_VPRINTF case, just call cvs_outerr. - - * buffer.c: New file; buffer support functions taken from - server.c. - * buffer.h: New file; declarations for buffer.c. - * server.c: Move buffer support functions into buffer.c and - buffer.h. Include "buffer.h". - * Makefile.in (SOURCES): Add buffer.c. - (OBJECTS): Add buffer.o. - (HEADERS): Add buffer.h. - -Thu Jul 4 00:12:45 1996 Jim Kingdon - - * version.c: Increment version number to 1.8.6. - -Wed Jul 3 22:31:16 1996 Jim Kingdon - - * version.c: Version 1.8.5. - -Wed Jul 3 21:51:23 1996 Ian Lance Taylor - - * server.c (blocking_error): Define macro. - (buf_send_output, buf_input_data): Use blocking_error rather than - #ifdef EWOULDBLOCK. - -Tue Jul 2 20:38:41 1996 Jim Kingdon - - * add.c (add): Change message which said "version 1.2 of foo.c - will be resurrected"; the message was confusing because it made - people think that the old contents of the file would come back - instead of the contents in the working directory. - -Mon Jul 1 01:38:57 1996 Jim Kingdon - - * find_names.c (find_dirs): Add comment explaining why we bother - with the entries stuff. - -Sat Jun 29 20:23:50 1996 Ian Lance Taylor - - * find_names.c (Find_Directories): Add entries parameter, and pass - it to find_dirs. - (find_dirs): Add entries parameter, and skip all files it names. - * cvs.h (Find_Directories): Update declaration. - * recurse.c (start_recursion): Pass NULL to Find_Directories. - (do_recursion): Pass entries to Find_Directories. - - * client.c (send_modified): Add trace output. - - * diff.c (diff_fileproc): Always call diff_file_nodiff. Handle - dead versions correctly. Handle diffs between a specified - revision to a dead file correctly. - (diff_file_nodiff): Add just_set_rev parameter. Change caller. - * patch.c (patch_fileproc): Check for dead versions. - * sanity.sh (death2): Add tests for above patches. - -Fri Jun 28 20:30:48 1996 Jim Kingdon - - For reference, this takes CVS's text segment from 271136 bytes to - 270352 bytes, a saving of 784. Not as good as I had hoped (oh well, - the source *seems* simpler at least). - * checkin.c (Checkin), commit.c (finaladd, remove_file), update.c - (join_file, checkout_file, patch_file), no_diff.c - (No_Differences), server.c (server_updated), classify.c - (Classify_File), vers_ts.c (Version_TS), diff.c (diff_file_nodiff): - Use a single struct file_info * argument instead of a bunch of - separate arguments for each of its fields. Remove local fullname - emulations. Use fullname in error messages where file had - erroneously been used. - * cvs.h: Update declarations of above functions and move them to - after the struct file_info declaration. - * server.h: Update declarations. - * add.c, admin.c, checkin.c, checkout.c, classify.c, client.c, - commit.c, diff.c, history.c, import.c, update.c, status.c, - remove.c, rtag.c, tag.c: Change callers. - - * diff.c (diff): Remove -q and -Q command options. This somehow - slipped through the cracks of the general removal of -q and -Q - command options on Jul 21 1995. Note that there is no need to - accept and ignore these options in server mode, like there is for - some of the commands, because the client has never sent -q and -Q - command options for "cvs diff". - -Fri Jun 28 16:50:18 1996 Ian Lance Taylor - - * add.c (add): Pass force_tag_match as 1 when calling Version_TS. - * sanity.sh (death2): Add test for above patch. Also add - commented out test for adding a file on a nonbranch tag, which CVS - currently, mistakenly, permits. - -Thu Jun 27 23:20:49 1996 Ian Lance Taylor - and Jim Kingdon - - * diff.c (longopts): New static array. - (diff): Handle long options and new short options in diff 2.7. - Fix arbitrary limit associated with the tmp variable. - * client.c (send_option_string): Parse options as space separated, - rather than requiring all options to be single characters. - * diff.c, options.h.in: Remove CVS_DIFFDATE; the need for it is gone - now that we have --ifdef (the new behavior is the behavior which - was the default, which is that -D specifies a date). - -Wed Jun 26 22:36:29 1996 Ian Lance Taylor - - * commit.c (check_fileproc): If there is a tag, permit adding a - file even if the RCS file already exists. - (checkaddfile): If there is a tag, use the file in the regular - repository, rather than the Attic, if it exists. - * sanity.sh (death2): New set of tests for above patch. - -Tue Jun 25 23:34:13 1996 Jim Kingdon - - * update.c (checkout_file): Add comments about two cases which - seem fishy. - - * sanity.sh (basic2, death): Add comments encouraging people to - stop making these sections bigger and more complex. I'm not (yet - at least) trying to figure out the ideal size for a section (my - current best estimate is 10-20 tests), but surely these - two sections are pushing the limit, whatever it is. - -Tue Jun 25 19:52:02 1996 Ian Lance Taylor - - * update.c (checkout_file): Rewrite handling of dead files when - joining. Avoid space leaks. Avoid unnecessary file - resurrections. - (join_file): Add checks to skip merging a dead revision onto a - dead revision, and to skip merging a common ancestor onto a dead - revision. Move check for non-existent working file after new - checks. - * sanity.sh (death): Use dotest for tests 86 and 95, and add test - death-file2-1, to test above changes. - -Mon Jun 24 11:27:37 1996 Jim Kingdon - - * update.c (merge_file): Replace file, repository, entries, and - update_dir arguments with finfo argument. Use fullname field - instead of locally emulating it. - (update_fileproc): Update caller. - (merge_file): If -kb is in effect, call it a conflict, leave - the two versions in the file and the backup file, and tell the - user to deal with it. The previous behavior was that the merge - would fail and then there was no way to do a checkin even once you - resolved the conflict (short of kludges like moving the file - aside, updating, and then moving it back). - * sanity.sh (binfiles): New tests binfiles-con* test for above - behavior. Adjust remaining tests to reflect changes in revision - numbers. - -Mon Jun 17 15:11:09 1996 Ian Lance Taylor - - * sanity.sh (import): Remove sleep. Requiring it was a bug, and - it is fixed in the current sources. - -Mon Jun 17 1996 Ian Lance Taylor - and Jim Kingdon - - * sanity.sh (TMPPWD): Set to real name of /tmp directory. - (basic2-64, conflicts-126.5): Use ${TMPPWD}. - -Mon Jun 17 1996 Ian Lance Taylor - - * rcscmds.c (RCS_checkout): Remove noerr parameter. Change all - callers. - * rcs.c (RCS_fast_checkout): Likewise. - -Mon Jun 17 1996 Ian Lance Taylor - - Cleaner implementation of tag locking code added Jun 13 1996: - * cvs.h (tag_lockdir, tag_unlockdir): Declare. - * rtag.c (locked_dir, locked_list): Remove. - (rtag_fileproc): Don't lock here; just call tag_lockdir. - (rtag_filesdoneproc): Don't unlock here; just call tag_unlockdir. - * tag.c (locked_dir, locked_list): Move farther down in file. - (tag_fileproc): Don't lock here; just call tag_lockdir. - (tag_filesdoneproc): Don't unlock here; just call tag_unlockdir. - (tag_lockdir, tag_unlockdir): New functions. - -Wed Jun 15 07:52:22 1996 Mike Ladwig - - * client.c (send_modified, update_entries): Fixed bug which didn't - handle binary file transfers in BROKEN_READWRITE_CONVERSION. - -Thu Jun 13 1996 Ian Lance Taylor - and Jim Kingdon - - * update.c (checkout_file): Call server_scratch_entry_only when a - non-pertinent file is found that does not exist. - * sanity.sh (newb): Add test case for above patch. - -Thu Jun 13 1996 Ian Lance Taylor - - * update.c (update_fileproc): Call server_scratch_entry_only when - handling T_REMOVE_ENTRY on the server. - * sanity.sh (conflicts2): Remove special case for remote server - bug fixed by above patch. - -Thu Jun 13 21:16:26 1996 Jim Kingdon - - * sanity.sh (basica-9): Update to reflect change to "sufficient - access" message. - -Thu Jun 13 20:13:55 1996 Ian Lance Taylor - and Jim Kingdon - - * recurse.c, cvs.h (start_recursion): Remove wd_is_repos argument; - add comment about meaning of which argument. Use !(which & - W_LOCAL) instead of wd_is_repos. - * admin.c, client.c, commit.c, diff.c, edit.c, lock.c, log.c, - patch.c, rcs.c, remove.c, rtag.c, status.c, tag.c, update.c, - watch.c: Change callers. This is a semantic change in only two - cases: (1) tag_check_valid, where repository was not "", and (2) - the pipeout case in checkout_proc. In both of those cases the - previous setting of wd_is_repos did not reflect whether we - actually were cd'd into the repository. - * recurse.c (start_recursion): Only check for the CVS subdirectory - if which & W_LOCAL. - * sanity.sh (devcom): Add test case fixed by above patch. - -Thu Jun 13 1996 Ian Lance Taylor - - * ignore.c (ignore_files): Skip based on the file name before - calling lstat. - - * client.c (last_register_time): New static variable. - (update_entries): Set last_register_time when calling Register. - (get_responses_and_close): If the current time is the same as - last_register_time, sleep for a section to avoid timestamp races. - -Thu Jun 13 17:24:38 1996 Jim Kingdon - - * client.c (supported_request): Reindent. - -Thu Jun 13 1996 Mark H. Wilkinson - - * options.h.in, mkmodules.c: Corrections to allow compilation of - non-client-server version. - -Thu Jun 13 1996 Ian Lance Taylor - - * tag.c (tag_check_valid_join): New function. - * cvs.h (tag_check_valid_join): Declare. - * checkout.c (join_tags_validated): New static variable. - (checkout_proc): Check validity of join tags. - * update.c (update): Likewise. - - * tag.c (tag_check_valid): Correct sizeof CVSROOTADM_HISTORY to - use CVSROOTADM_VALTAGS. - - * lock.c (Writer_Lock): If we called lock_wait to wait for a lock, - then call lock_obtained when we get it. - (set_lock): Likewise. - (lock_obtained): New static function. - -Thu Jun 13 13:55:38 1996 Ian Lance Taylor - and Jim Kingdon - - * main.c (main): If we can't read cvs root, don't say "you don't - have sufficient access"; just print the message from errno. It - might be "No such file or directory" or something else for which - "you don't have sufficient access" doesn't make any sense. - -Thu Jun 13 1996 Ian Lance Taylor - - * commit.c (remove_file): Pass noerr as 0 to RCS_checkout. - -Thu Jun 13 12:55:56 1996 Ian Lance Taylor - - * patch.c: Initialize rev1_validated and rev2_validated to 0, not 1. - -Thu Jun 13 12:55:56 1996 Jim Kingdon - - * rtag.c (locked_dir): Revise comments regarding locking; the rtag - and tag situations are different (changing from readlocking one - directory at a time to writelocking one directory at a time does - not do everything we might want, but it does fix simultaneous tags - and it doesn't make anything worse). - -Thu Jun 13 1996 Ian Lance Taylor - - Prevent simultaneous tag operations from interfering with each - other. - * rtag.c (rtag_proc): Pass rtag_filesdoneproc to start_recursion, - and pass readlock as 0. - (locked_dir, locked_list): New static variables. - (rtag_fileproc): Write lock the repository if it is not already - locked. - (rtag_filesdoneproc): New static function to unlock the - repository. - * tag.c (tag): Pass tag_filesdoneproc to start_recursion, and pass - readlock as 0. - (locked_dir, locked_list): New static variables. - (tag_fileproc): Write lock the repository if it is not already - locked. - (tag_filesdoneproc): New static function. - -Thu Jun 13 11:42:25 1996 Mike Sutton - - * sanity.sh: Allow digits in usernames. - -Wed Jun 12 16:23:03 1996 Jim Kingdon - - * client.c (send_modified, update_entries): Reindent and add - comments to BROKEN_READWRITE_CONVERSION code. - -Wed Jun 12 16:23:03 1996 Mike Ladwig - - * client.c (send_modified, update_entries): Add - BROKEN_READWRITE_CONVERSION code. - -Mon Jun 10 20:03:16 1996 J.T. Conklin - - * rcs.c (RCS_gettag): No longer set p to NULL if rcs is also NULL. - rcs will never be null, thanks to the assertion at top of function. - -Mon Jun 10 16:28:14 1996 Ian Lance Taylor - and Jim Kingdon - - * main.c (main): Ignore CVS/Root file when doing an import. - -Fri Jun 7 18:20:01 1996 Jim Kingdon - - * status.c (status_fileproc, tag_list_proc): Use cvs_output rather - than writing to stdout directly. - -Wed Jun 5 13:54:57 1996 Ian Lance Taylor - - * rcs.c (force_tag_match, tag, date): New static variables. - (annotate_fileproc): Redo the loop to look for the version - specified by tag/date/force_tag_match, and handle branches - correctly. - (annotate_usage): Mention -f, -r, and -D. - (annotate): Handle -f, -r, and -D. - -Tue Jun 4 13:38:17 1996 Ian Lance Taylor - - * rcs.c (annotate_fileproc): Skip unrelated branch deltas. - -Fri Jun 7 13:04:01 1996 Jim Kingdon - - * main.c (main): Change INITIALIZE_SOCKET_SUBSYSTEM to - SYSTEM_INITIALIZE and pass it pointers to argc and argv. Rename - CLEANUP_SOCKET_SUBSYSTEM to SYSTEM_CLEANUP. - -Wed Jun 05 10:07:29 1996 Mike Ladwig - - * import.c (add_rcs_file): make buf char[] not unsigned char[] - -Wed Jun 05 10:07:29 1996 Mike Ladwig - and Jim Kingdon - - * main.c (main): Add CLEANUP_SOCKET_SUBSYSTEM hook at end. Revise - comments regarding INITIALIZE_SOCKET_SUBSYSTEM. - -Wed Jun 05 10:07:29 1996 Mike Ladwig - and Jim Kingdon - - * main.c (main): Don't mess with signals if DONT_USE_SIGNALS is - defined. - -Thu Jun 6 15:32:41 1996 Jim Kingdon - - * modules.c (cat_module): Always format for 80 columns rather than - trying to determine how wide the screen is. The code we had for - the latter didn't cover all cases, was a portability headache, and - didn't work client/server. - -Wed Jun 05 10:07:29 1996 Mike Ladwig - - * error.c: Don't declare strerror if it is #defined. - -Wed Jun 05 10:07:29 1996 Mike Ladwig - and Jim Kingdon - - * cvs.h: If ENUMS_CAN_BE_TROUBLE, typedef Dtype to int not an enum. - -Wed Jun 05 10:07:29 1996 Mike Ladwig - and Jim Kingdon - - * update.c (update): If DONT_USE_PATCH, don't request patches. - Also call supported_request rather than reimplementing it. - -Wed Jun 05 10:07:29 1996 Mike Ladwig - - * client.c (read_line): Changed an occurence of '\n' to '\012'. - -Wed Jun 5 17:18:46 1996 Jim Kingdon - - * add.c (add_directory): Don't create the directory if noexec. - * sanity.sh (basica): New tests basica-1a10, basica-1a11 test for - above fix. - * sanity.sh (basicb): New tests basicb-2a10, basicb-2a11, - basicb-3a1 test for analogous situation with files rather than - directories. - -Tue Jun 4 13:38:17 1996 Ian Lance Taylor - - * sanity.sh: When doing a remote check, use :server: in CVSROOT. - -Wed Jun 5 13:32:40 1996 Larry Jones - and Jim Kingdon - - * ignore.c: Set ign_hold to -1 when not holding instead of 0 so - that holding an empty list works correctly. - * sanity.sh (ignore): New tests 190 & 191 for above fix. - -Wed Jun 5 1996 Jim Kingdon - - Visual C++ lint: - * client.c (update_entries): Copy the size to an unsigned variable - before comparing it with unsigned variables. - (handle_created, handle_update_existing): Prototype. - -Tue Jun 4 10:02:44 1996 Jim Kingdon - - * client.c (responses): Add Created and Update-existing responses. - * server.c (server_updated): If they are supported, use them - instead of Updated. - * client.c (struct update_entries_data): Add existp field. - (handle_checked_in, handle_updated, handle_new_entry, - handle_merged, handle_patched): Set it. - (handle_update_existing, handle_created): New functions, - for new responses. - (update_entries): Based on existp, check for - existence/nonexistence of file. - (try_read_from_server): Expand comment. - * server.c, server.h (server_updated): New argument vers. - * checkin.c (Checkin), commit.c (commit_fileproc), update.c - (update_fileproc, merge_file, join_file): Pass it. - * cvs.h: Move include of server.h after Vers_TS declaration. - * sanity.sh (conflicts2): New tests conflicts2-142d* test for - above fix. - - * sanity.sh (ignore): Fix typo in comment. - - * tag.c (tag_check_valid): Add comment clarifying when val-tags - entries are created. - -Mon Jun 3 07:26:35 1996 Jim Kingdon - - * version.c: Increment version number to 1.8.4. - -Mon Jun 3 02:20:30 1996 Noel Cragg - - * version.c: version 1.8.3. - -Thu May 30 10:07:24 1996 Jim Kingdon - - * main.c (cmds): Fix typo ("bdif" -> "dif") which was accidentally - introduced 24 May 96. - - * main.c (main_cleanup): Add comment stating default case will - never be reached. - -Wed May 29 21:43:43 1996 noel - - * main.c (main_cleanup): check to see if SIGHUP, SIGINT, SIGQUIT, - SIGPIPE, and SIGTERM are defined before using them. Also add a - default case to print out those errors numerically which are not - found. - -Wed May 29 18:43:45 1996 Jim Kingdon - - * expand_path.c (expand_path): Document LINE == 0 and allocation - of return value. - * modules.c (do_module): Pass 0, not -1, to indicate line number - not known. Free value returned from expand_path. Deal with NULL - return from expand_path. - -Wed May 29 15:56:47 1996 Greg A. Woods - - * modules.c (do_module): call expand_path() on the program name - specfied by one of '-o', '-t', or '-e' in the modules file before - passing it to run_setup(). This makes it possible to use $CVSROOT - (or indeed ~user or any other user-specified variable) to specify - pathnames for programs not installed in the normal execution path. - -Sun May 26 21:57:09 1996 Jim Kingdon - - * client.c (start_server): Don't include %s in error message; - there is no argument to go with it. Do include "internal error" - in error message since that might not be clear to the user otherwise. - -Sun May 26 11:58:13 1996 Greg A. Woods - - * root.c (set_local_cvsroot): enforce a wee bit of portability - (parse_cvsroot): same.... - (DEBUG main): same, plus style guidelines - (DEBUG error): deleted -- not necessary here (use fprintf instead) - - * mkmodules.c (modules_contents): updated notes about what must be - done if you change any of the options for a module. - (loginfo_contents): fixed grammar, re-pargraphed, and added 'echo - %s;' to the example. - (editinfo_contents): minor grammar fix. - -Sun May 26 17:51:18 1996 Jim Kingdon - - * vers_ts.c (Version_TS): Remove case where we get options from - sdtp->options. Whatever case that was intended to handle is - probably lost in the mists of time, but sdtp->options isn't set - anywhere, and I think that has been true for a long time. - * cvs.h (struct stickydirtag): remove options field. - * entries.c (freesdt): Don't free ->options. - * sanity.sh (binfiles): New tests binfiles-13a* test for above fix. - - * tag.c (check_fileproc): Use fullname not file in error message. - Say "locally modified" not "up-to-date"; the file need not match - the head revision it only need match some revision. - -Sun May 26 16:57:02 1996 Norbert Kiesel - - * tag.c: added support for new option -c to make sure all tagged - files are up-to-date - (tag): check for option and set check_uptodate - (check_fileproc): check status of file if check_uptodate is set - -Sat May 25 15:22:26 1996 Jim Kingdon - - * main.c (main): Revert change to look for a -H command option; - command option parsing should be up to each subcommand and the -H - global option works fine. - -Mon May 23 1996 Ian Lance Taylor - - * client.c (process_prune_candidates): Set prune_candidates to - NULL at the end of the function. - -Mon May 23 1996 Ian Lance Taylor - - * checkout.c (checkout): In code to handle multiple arguments, - pass preload_update_dir, not where, to Create_Admin. - (checkout_proc): Pass preload_update_dir, not where, to - Create_Admin. - -Thu May 23 19:14:35 1996 Jim Kingdon - - * server.c (server_set_sticky): Assert that update_dir != NULL. - * sanity.sh (basicb): New test; tests for Ian's fix to checkout.c - above. - -Thu May 23 1996 Ian Lance Taylor - - * patch.c (patch_fileproc): Don't ignore a file just because it is - in the Attic directory. - -Thu May 23 10:40:24 1996 Jim Kingdon - - * sanity.sh (death): New tests death-{72a,76a0,76a1} test for bug - fixed by Ian's patch_fileproc change above. - - * sanity.sh (death): Remove "temporary hack" in test 89. - - * rcs.c (RCS_fast_checkout): If error closing file, and workfile - is NULL, use sout in error message instead of workfile. - -Thu May 23 1996 Ian Lance Taylor - - * rcs.c (RCS_fast_checkout): Do a fast checkout in the case where - workfile is NULL and sout is a file name. - -Wed May 22 19:06:23 1996 Mark Immel - - * update.c (checkout_file): New arg resurrecting_out, to provide - resurrecting flag to caller. - (join_file): New arg resurrecting. Register with "0" if we are - the server and are resurrecting. - (update_fileproc): Pass the flag from checkout_file to join_file. - -Wed May 22 19:06:23 1996 Jim Kingdon - - * sanity.sh (death): Test for above fix, in test 89 and new test 89a. - -Tue May 21 09:49:04 1996 Greg A. Woods - - * update.c (update_usage): oops -- fix my spelling typo. - -Mon May 20 10:53:14 1996 Jim Kingdon - - * commit.c (find_fileproc): Call freevers_ts. - - * commit.c (find_*): Keep an ignlist, like update.c and client.c do. - * commit.c (commit): Process the files from the ignlists, once we - are connected to the server. - * sanity.sh (ignore): New tests 189e and 189f test for new - commit.c behavior (and client.c behavior, which is unchanged). - * sanity.sh (conflicts): Remove dir1 and sdir in parts of the test - where we aren't prepared for "? dir1" and similar output. - -Mon May 20 13:23:36 1996 Greg A. Woods - - * main.c (cmd_usage): minor corrections to descriptions of status, - rtag, tag, and rdiff. Sort alphabetically by command name. - -Mon May 20 10:36:07 1996 Ian Lance Taylor - - * client.c (call_in_directory): Move the call to Entries_Close - before the call to chdir, since Entries_Close examines files in - the current directory. - -Fri May 17 12:13:09 1996 Jim Kingdon - - * client.c (start_tcp_server, start_server, start_rsh_server, - read_line, filter_through_gzip, filter_through_gunzip, - call_in_directory): Reindent as needed. - - * main.c (main): Add missing #endif. Use indentation to indicate - nesting. - -Thu May 16 17:15:01 1996 Jim Kingdon - - * main.c (cmd_usage): Add "init" command. - -Thu May 16 16:45:51 1996 Noel Cragg - - * client.c (start_tcp_server): Error message modified to tell the - user to use ":server:" instead of setting CVS_CLIENT_PORT to a - negative number. - - * main.c (main): Add #ifdefs for turning off buffering of - stdio/stderr, so we don't get it by default. - -Thu May 16 01:29:47 1996 noel - - * commit.c (commit_filesdoneproc): Print the repository and root - directories as part of the error message. - - * main.c (main): Don't buffer stdout or stderr. It's inefficient, - but it then produces the right output for sanity.sh. - -Thu May 16 09:44:47 1996 Jim Kingdon - - * fileattr.c (fileattr_set): In the case where we are about to - call delproc, don't free ->data; delproc does that. - * sanity.sh (devcom): New tests devcom-b* test for this fix. - - * sanity.sh (conflicts): Remove redundant clean up from previous - tests at the beginning of the test. Use dotest a few more places. - (conflicts2): New test, tests for Ian's fix to Classify_File. - - * client.c (remove_entry_and_file): Add comment about - existence_error's. - -Sat May 16 1996 Ian Lance Taylor - - * update.c (update_dirleave_proc): Don't try to chdir .. and check - for an empty directory if there is a slash in the directory name. - -Thu May 16 09:02:59 1996 Jim Kingdon - - * sanity.sh (deep): New tests deep-4a* test for Ian's fix to - update_dirleave_proc. - -Sat May 16 1996 Ian Lance Taylor - - * main.c (main_cleanup): Report signal name before dying. - -Wed May 15 23:47:59 1996 Noel Cragg - - * main.c (usg): revert usage strings for `-H' flag change. - -Sat May 15 1996 Ian Lance Taylor - - * server.c (serve_static_directory): Return immediately if there - is a pending error. - (serve_sticky): Likewise. - (serve_modified): Read the file data even if there is a pending - error. - -Wed May 15 14:26:32 1996 Jim Kingdon - - * main.c (main): If -d and CVS/Root both specified, after writing - the value from -d into CVS/Root, use the value from -d, not the - old value from CVS/Root. Don't write CVS/Root with value from -d - until we have verified that it works. - * sanity.sh: Reenable test basica-9 and adjust for new behavior. - -Tue May 14 1996 Jim Kingdon - - * logmsg.c (do_editor): If user aborts the commit, still remove the - temporary file. - -Tue May 14 11:45:41 1996 Jim Kingdon - - * filesubr.c, cvs.h (cvs_temp_name): New function. Move L_tmpnam - define from cvs.h to filesubr.c. - * client.c, diff.c, import.c, login.c, logmsg.c, no_diff.c, - patch.c, wrapper.c: Call cvs_temp_name not tmpnam. - * login.c (login): Reindent function. - -Tue May 14 10:56:56 1996 Ian Lance Taylor - - * rcs.c (RCS_fast_checkout): If workfile is NULL, don't call chmod. - -Mon May 13 10:52:10 1996 Greg A. Woods - - * checkout.c (export_usage): note which options cause a sticky - version to be set, and which option avoids this. - * update.c (update_usage): likewise - -Sat May 11 18:57:07 1996 Jim Kingdon - - * sanity.sh: Comment out test basica-9 until I get around to - actually fixing it (the -d vs. CVS/Root change broke it). - -Fri May 10 09:39:49 1996 Jim Kingdon - - * main.c (main): -d now overrides CVS/Root. - -Thu May 9 19:45:24 1996 Jim Kingdon - - * main.c: Remove comment listing commands at beginning. It was - out of date and redundant with the help. - -Thu May 9 09:33:55 1996 Greg A. Woods - - * main.c: add 'init' to opening comment listing commands - - * mkmodules.c (init): fix to recognize argc==-1 as hint to call - usage() [should make "cvs init -H" work as expected] - -Wed May 8 15:02:49 1996 Jim Kingdon - - * sanity.sh: Set EXPR in the case that the expr in the path is the - one that we want. - -Wed May 8 14:06:24 1996 Greg A. Woods - - * sanity.sh (test): - convert all '[' to test ala GCD - -Wed May 8 13:46:56 1996 Greg A. Woods - - * sanity.sh (expr): - make a valiant attempt to find GNU expr - - Patch from Larry Jones: - sanity test deep-4 failed with "expr: arg list too long" - sanity test 56 failed because the stderr and stdout output was not - interleaved as expected. - sanity test modules-155a4 failed with "ls: illegal option -- 1" - - * main.c (main): - Patch from Larry Jones for SysV setvbuf - -Tue May 7 16:41:16 1996 Jim Kingdon - - * version.c: Increment version number to 1.8.2 to work around fact - that CVS 1.8 (confusingly) calls itself 1.8.1 not 1.8. - -Tue May 7 10:44:20 MET DST 1996 Norbert Kiesel - - * rcs.c (rcsvers_delproc): fix memory leak by freeing author - field. - -Mon May 6 10:40:05 1996 Jim Kingdon - - * sanity.sh (conflicts): New test conflicts-126.5 tests for bug - which Ian fixed May 5 in update.c - -Mon May 6 06:00:10 1996 Benjamin J. Lee - - * Version 1.8.1 - -Sun May 5 21:39:02 1996 Jim Kingdon - - * vers_ts.c (Version_TS): If sdtp is NULL, go ahead and check - RCS_getexpand for options. Fixes binaries and non-unix clients. - * sanity.sh: Fix binfiles-5.5 to test for the correct behavior - rather than the buggy behavior which existed when the binfiles-5.5 - test was written. - (binfiles-14c,binfiles-14f): Likewise. - -Sun May 5 17:38:21 1996 Benjamin J. Lee - - Integrated changes submitted by Ian Taylor - - * update.c (update_dirent_proc): cvs co -p doesn't print - anything when run from an empty directory. - - * import.c (import_descend_dir): Check for a file in the - repository which will be checked out to the same name as the - directory. - -Sat May 4 12:33:02 1996 Ian Lance Taylor - - Extract the head revision directly from the RCS file when - possible, rather than execing co. - * rcs.c (RCS_reparsercsfile): Set delta_pos field. - (getrcskey): Add lenp parameter. Change all callers. - (RCS_fast_checkout): New function. - (annotate_fileproc): If PARTIAL is not set, just fseek to - delta_pos. - * rcs.h (struct rcsnode): Add delta_pos field. - (RCS_fast_checkout): Declare. - * diff.c (diff_file_nodiff): Call RCS_fast_checkout rather than - RCS_checkout. - * import.c (update_rcs_file): Likewise. - * no_diff.c (No_Difference): Likewise. - * patch.c (patch_fileproc): Likewise. - * update.c (checkout_file): Likewise. - (patch_file): Likewise. - (join_file): Likewise. - -Sat May 4 12:33:02 1996 Ian Lance Taylor - - * classify.c (Classify_File): Don't report a conflict for a - pending remove if somebody else has already removed the file. - -Thu May 2 13:34:37 1996 Benjamin J. Lee - - * Version 1.7.88 - -Thu May 2 01:40:55 1996 Benjamin J. Lee - - * server.c (HAVE_INITGROUPS): Use initgroups() only if - located by configure, in the event a system has crypt(), but - no initgroups() - -Wed May 01 21:08:21 1996 noel - - * client.c (filter_through_gunzip): use "gzip -d" instead of - "gunzip," since there's no good reason (on NT at least) to have an - extra copy of gzip.exe copied to gunzip.exe (Arrrrgh! No symbolic - links!). - - * mkmodules.c (init): check to see that we have the correct number - of arguments or print out the usage message (used to be argc > 1, - should be argc != 1, because help forces argc == -1 as a special - case). - -Wed May 1 18:05:02 1996 Jim Kingdon - - * sanity.sh (basica): When testing rejection of reserved tag name, - use BASE instead of RESERVED. - -Wed May 1 15:15:11 1996 Tom Jarmolowski - - * rcs.c (linevector_delete): Only copy up to vec->nlines - nlines, - not to vec->nlines. - -Wed May 1 15:43:21 1996 Jim Kingdon - - * rcscmds.c (RCS_settag): Instead of reserving all tag names - containing only uppercase letters, reserve only BASE and HEAD. - * sanity.sh (mflag): Revert 26 Mar change; use all-uppercase tag - name again. - -Wed May 1 15:15:11 1996 Tom Jarmolowski - - * rcs.c (linevector_add): Move increment of i out of larger - statement, to avoid assumptions about evaluation order. - -Tue Apr 30 15:46:03 1996 Jim Kingdon - - * Version 1.7.87. - - * server.c (check_password): Don't use ANSI string concatenation. - Reindent function. - -Mon Apr 29 10:48:38 1996 Noel Cragg - - * root.c (parse_cvsroot): removed "rsh" as an alias to "server" in - the method section. - - * main.c (main): new variable help so we can support the `cvs -H - cmd' convention. Reverts change of 26 Apr 96 which removed this - feature. - -Sun Apr 28 14:57:38 1996 Noel Cragg - - * main.c (main): update error message if parse_cvsroot fails. - * server.c (serve_root): same. - (serve_init): same. - - * client.c (start_tcp_server): get rid of the "fall through" - stuff, now that we have access methods. - (start_server): switch off the access method to choose routine - that starts the server. - (start_tcp_server): tofd wasn't getting set to -1 early enough, - because a call to error for bind or gethostbyname might fail and - the subsequent error check to see if the connection had been made - would fail. - - * root.c: new variable method_names for error reporting purposes. - -Sun Apr 28 17:22:15 1996 Noel Cragg - - * server.c: moved kerberos #includes from main.c for the - kserver_authenticate_connection routine. - -Fri Apr 26 07:59:44 1996 Noel Cragg - - * server.c (serve_init): use the new return value from - parse_cvsroot. - (serve_root): same. - * main.c (main): same. - - * root.c (parse_cvsroot): fix indentation, add a return value - which tells whether the command succeeded or failed. - - * main.c (main): move the setting of the UMASK environment - variable inside the stuff that gets done if the user is NOT asking - for help, so we don't signal any errors prematurely (don't want to - give an error because we can't parse an environment variable - correctly if the user asks for help). Similar mods for the code - that tries to get the working directory. - - Also make CVSADM_Root a local variable instead of a global, since - its scope is only about 20 lines here! - - * server.c (kserver_authenticate_connection): moved code from - main.c to clean up MAIN. Makes sense, since we already have a - pserver_authenticate_connection. - (pserver_authenticate_connection): rename from - authenticate_connection. - - * main.c (main): reorganized the routine to eliminate variables - help, help_commands, and version_flag. Now the routine is much - clearer, since we don't have to be checking to see if these - variables are set. One behavior that was a bug/feature which is - now gone is an invocation like "cvs -H rtag" -- previously this - would give usage for rtag, but now gives usage for cvs itself. - The first behavior didn't make sense, especially since we say in - the docs that command-line flags are position-specific. *Reverted - Above* - -Thu Apr 25 20:05:10 1996 Noel Cragg - - * main.c (main): make sure we have a valid command name before we - do anything else (moved the thing that looks for a command in CMDS - to right after the GETOPT loop). Added `kserver' and `pserver' to - the table so they will be recognized; set their functions to - SERVER so that help will be given when asked for. - - * expand_path.c (expand_variable): return CVSroot_original rather - than CVSroot_directory. - - * main.c (main): save CVSroot in the env rather than - CVSroot_original, since we might not have called PARSE_CVSROOT - (this can happen if we use the -H option to a command). - - * root.c (parse_cvsroot): the parsing method was bogus for - guessing when we had hostnames vs. directories specified. Any - ambiguity should be removed by having the user specify the access - method. If the access method isn't specified, choose - server_method if the string contains a colon or local_method - otherwise. - - * Changed CVSroot_remote back to client_active since the code - reads better. - -Wed Apr 24 17:27:53 1996 Norbert Kiesel - - * vers_ts.c (Version_TS): xmalloc enough space (1 more - byte). Thanks to purify! - -Mon Apr 22 00:38:08 1996 Noel Cragg - - * create_adm.c (Create_Admin): pass CVSroot_original instead of - CVSroot_directory (oops!). - * update.c (update_filesdone_proc): same. - - * server.c (serve_root): modify to use parse_cvsroot rather than - goofing around with other variables. Will need to fix - parse_cvsroot to have a return value so we can return an error and - quit gracefully if in server mode. - (serve_init): same. - - * main.c: modify command table to remove client_* routines, since - they no longer exist. - (main): don't try to switch off non-existent field in command - table! ;-) - - * client.h (client_*): removed prototypes for now non-existent - functions. - - * client.c: remove proto for get_cvs_password, since it is now in - cvs.h. Modify routines to use new globals that describe CVSROOT - rather than client_active, server_host, server_user, and - server_cvsroot. - (parse_cvsroot): removed function, since a more generic version - now lives in root.c. - (connect_to_pserver): remove call to parse_cvsroot, since main.c - has already done it for us. - (client_*): removed all of these routines, since they only call - parse_cvsroot and then their respective operation functions. - Since main.c has already called parse_cvsroot, we shouldn't bother - with the extra function call, since client-server diffs are - already handled in the core routines themselves. - - * main.c: remove CVSroot as a global variable. Remove - use_authenticating_server variable since we have a new - `CVSroot_method' variable instead. - (main): add `CVSroot' as a local variable. Call parse_cvsroot - after we're sure we have the right setting for `CVSroot.' - - * login.c (login): update to use new global variables. Instead of - old behavior which let the user type in user@host when prompted, - it makes them do it in CVSROOT proper. The routine still lets the - user type the password, however. - (get_cvs_password): make sure that CVSROOT is fully qualified - before trying to find the entry in the .cvspass file. - * cvs.h: add prototype for get_cvs_password. - - * add.c: use new globals that describe CVSROOT. - * admin.c: same. - * checkout.c: same. - * commit.c: same. - * create_adm.c: same. - * diff.c: same. - * edit.c: same. - * expand_path.c: same. - * history.c: same. - * ignore.c: same. - * import.c: same. - * log.c: same. - * mkmodules.c: same. - * modules.c: same. - * parseinfo.c: same. - * patch.c: same. - * rcs.c: same. - * recurse.c: same. - * release.c: same. - * remove.c: same. - * repos.c: same. - * rtag.c: same. - * status.c: same. - * tag.c: same. - * update.c: same. - * watch.c: same. - * wrapper.c: same. - - * root.c (Name_Root): remove error message that reports missing - CVSROOT, since new code in main.c will catch it and also print out - an error. - (parse_cvsroot): new function -- takes a CVSROOT string and breaks - it up into its component parts -- method, hostname, username, and - repository directory. Sets new global variables that describe the - repository location more precisely: CVSroot_original, - CVSroot_remote, CVSroot_method, CVSroot_username, - CVSroot_hostname, CVSroot_directory for use by all other - functions. Checks for obvious errors in format of string. - (main): a short routine to test parse_cvsroot from the command - line. - * cvs.h: add prototype for parse_cvsroot and extern definitions - for new globals. - - * cvs.h: removed CVSroot variable, since we don't want other - routines using the raw CVSROOT (also helped to find all of the - refs to the variable!). - -Fri Apr 19 11:22:35 1996 Benjamin J. Lee - - * Version 1.7.86 - -Thu Apr 18 1996 Jim Kingdon - - * client.c (try_read_from_server): Compare return value from fwrite - with a size_t not an int (Visual C++ lint). - -Wed Apr 17 11:56:32 1996 Jim Kingdon - - * client.c (try_read_from_server): New function. - (read_from_server): Use it. - (read_counted_file): New function. - * client.c, server.c: Add Template response. - * cvs.h (CVSADM_TEMPLATE): Added. - * logmsg.c (do_editor): If repository is NULL, use CVSADM_TEMPLATE - file in place of rcsinfo. - * server.c, server.h (server_template): New function. - * create_adm.c (Create_Admin): Call it. - -Tue Apr 16 13:56:06 1996 Jim Kingdon - - * repos.c (Name_Repository): Fix comments. - * create_adm.c (Create_Admin): Fix indentation. - -Wed Apr 10 16:46:54 1996 Jim Kingdon - - * options.h.in: Include relevant information here rather than - citing (former) FAQ. - - * ChangeLog-9395: Fix typo in introductory paragraph. - -Wed Apr 10 14:55:10 1996 code by Mike Spengler mks@msc.edu - comments by Jim Kingdon - - * filesubr.c (unlink_file_dir,deep_remove_dir): Don't call unlink - on something which might be a directory; check using isdir instead. - -Wed Apr 10 14:55:10 1996 Jim Kingdon - - * checkout.c (build_dirs_and_chdir): Pass path, not cp, to - Create_Admin. The former is the correct update dir. - * sanity.sh (modules): New tests modules-155* test, for above fix. - -Mon Apr 8 13:53:27 1996 Samuel Tardieu - - * rcs.c (annotate_fileproc): If the file is not under CVS control, - return instead of dumping a core. Don't bug on files with an empty - first revision. - -Fri Mar 29 16:08:28 1996 Jim Kingdon - - * rcs.c (annotate_fileproc): If last line of add-chunk is not - newline terminated, end the loop when we find that out. - -Fri Mar 29 16:59:34 1996 Norbert Kiesel - - * rcs.c (annotate_fileproc): allow last line of add-chunk not to - be newline terminated - -Thu Mar 28 10:56:36 1996 Jim Kingdon - - Add more diff tests: - * sanity.sh (basic2): Use dotest for test 61. - (basica): Add test basica-6.2. - (branches): Add tests branches-14.4 and branches-14.5. - (basic1): Remove tests 19, 20, 25, and 26. The only thing this - might miss out on is diff's interaction with added and removed - files, but those tests didn't test that very well anyway. - - * rcs.c (RCS_getrevtime): Add comment regarding years after 1999. - - * rcs.c: Add "cvs annotate" command and related code. - (getrcskey): Move special handling of RCSDESC from here to - callers. Handle those keys (desc, log, text) which do not - end in a semicolon. - * rcs.h (RCSVers): Add author field. - * rcs.c (RCS_reparsercsfile): Set it. - * cvs.h (annotate), main.c (cmd_usage, cmds), client.h client.c - (client_annotate), server.c (serve_annotate, requests): Usual - machinery to add a new command. - * sanity.sh (basica): Test cvs annotate. - - * sanity.sh (branches): More tests, of things like adding files on - the trunk after a branch has been made. - -Tue Mar 26 09:48:49 1996 Jim Kingdon - - * expand_path.c: Don't declare free and xmalloc; cvs.h already - takes care of that. - - * sanity.sh (mflag): Don't use tag name reserved to CVS. - - NT local changes plus miscellaneous things noticed in the process: - * import.c (add_rcs_file): Use binary mode to write RCS file. Use - \012 where linefeed is intended. Copy data a small block at a - time, until we hit EOF, rather than trying to read the whole file - into memory at once. - * client.c (send_modified): Add comments regarding st_size. - * commit.c (commit): Add comments regarding binary mode and read(). - * logmsg.c (do_editor): Add comments regarding st_size. - * server.c (server_updated): Use binary mode to read file we are - sending. - - * rcscmds.c (RCS_settag): Complain if user tries to add a tag name - reserved to CVS. - * sanity.sh (basica): Test for this behavior. - - * sanity.sh (binfiles): New tests test ability to change keyword - expansion. - -Mon Mar 25 1996 Jim Kingdon - - * cvs.h, filesubr.c (expand_wild): New function. - * recurse.c (start_recursion): Call expand_wild at beginning and - free its results at the end. - * cvs.h, subr.c (xrealloc): Make argument and return value void *. - * client.h, client.c (send_file_names): Add flags argument. If - SEND_EXPAND_WILD flag is passed, call expand_wild at beginning and - free its results at the end. - * admin.c, add.c, log.c, tag.c, status.c, edit.c, watch.c, - update.c, commit.c, remove.c, client.c, diff.c: Update callers. - -Fri Mar 22 10:09:55 1996 Jim Kingdon - - * error.c (error, fperror): Exit with status EXIT_FAILURE rather - than STATUS. We had been neglecting to check for 256, and the - value of providing a count of errors is probably minimal anyway. - * add.c, modules.c, mkmodules.c, tag.c, server.c, main.c, - import.c, client.c, scramble.c, recurse.c: Exit with status - EXIT_FAILURE rather than 1. On VMS, 1 is success, not failure. - * main.c (main): Return EXIT_FAILURE or 0. The value of providing - a count of errors is minimal. - - * client.c (init_sockaddr): Exit with status 1 rather than - EXIT_FAILURE. The latter apparently doesn't exist on SunOS4. - Reindent function. - -Mon Mar 18 14:28:00 1996 Jim Kingdon - - * cvs.h, ignore.c: New variable ign_case. - * ignore.c (ign_name): If it is set, match in a case-insensitive - fashion. - * server.c (serve_case): New function. - (requests): Add Case request. - * client.c (start_server): If FILENAMES_CASE_INSENSITIVE is - defined, send Case request. - -Sat Mar 16 08:20:01 1996 Jim Kingdon - - For reference, this change takes cvs's text segment from 315392 - bytes to 311296 bytes (one 4096 byte page). - * cvs.h (struct file_info): Add fullname field. - * recurse.c (do_file_proc): Set it. - * commit.c (find_fileproc), client.c (send_fileproc), commit.c - (check_fileproc), diff.c (diff_fileproc), edit.c - (unedit_fileproc), patch.c (patch_fileproc), remove.c - (remove_fileproc), rtag.c (rtag_fileproc), tag.c (tag_fileproc), - update.c (update_fileproc), watch.c (watchers_fileproc): Use it - instead of computing it each time. - * diff.c (diff_fileproc), remove.c (remove_fileproc): Use fullname - where we had been (bogusly) omitting the directory from user - messages. - * edit.c (unedit_fileproc, edit_fileproc): If we cannot close - CVSADM_NOTIFY, mention CVSADM_NOTIFY rather than finfo->file in - error message. - * rtag.c (rtag_fileproc), tag.c (tag_fileproc): Reindent. - -Fri Mar 15 15:12:11 1996 Norbert Kiesel - - * server.h: fix prototype of server_pause_check (was - server_check_pause) - -Thu Mar 14 1996 Jim Kingdon - - * vers_ts.c (Version_TS), entries.c (Scratch_Entry, AddEntryNode): - Change findnode to findnode_fn. - - * main.c: Depending on HAVE_WINSOCK_H, include winsock.h or - declare gethostname. - * cvs.h: Don't declare it here. - -Thu Mar 14 07:06:59 1996 Jim Kingdon - - * commit.c (find_fileproc): If vn_user is NULL and ts_user is not, - print an error rather than silently succeeding. - * sanity.sh (basica-notadded): New test, for above fix. - (dotest_internal): New function. - (dotest,dotest_fail): Call it instead of duplicating code between - these two functions. - - * sanity.sh: Skip tests binfiles-9 through binfiles-13 for remote. - - * options.h.in: Adjust comment to reflect kfogel change. - -Thu Mar 14 01:38:30 1996 Karl Fogel - - * options.h.in (AUTH_CLIENT_SUPPORT): turn on by default. - -Wed Mar 13 09:25:56 1996 Jim Kingdon - - * vers_ts.c (Version_TS): Don't try to override options from rcs - file if there isn't an rcs file (e.g. called from send_fileproc). - This fixes a bug detected by test 59 in "make remotecheck". - - * rcs.c (RCS_reparsercsfile, RCS_getexpand): Assert that argument - is not NULL. - - Fix a gcc -Wall warning: - * rcs.c, rcs.h (RCS_getexpand): New function. - * vers_ts.c (Version_TS): Call it. - * rcs.c (RCS_reparsercsfile): Make static. - - Add a "cvs init" command. This is needed because cvsinit.sh - invoked mkmodules which doesn't exist any more. - * mkmodules.c: Break filelist out of mkmodules function, rename - struct _checkout_file to struct admin_file (for namespace - correctness), and add contents field. - (init,mkdir_if_needed): New functions. - * cvs.h (init): Declare. - * main.c (cmds): Add init. - (main): If command is init, don't require cvsroot to exist. - * client.c, client.h (client_init, send_init_command): New functions. - * client.c (start_server): Don't send Root request if command is init. - * server.c (serve_init): New function. - (requests): Add "init". - -Wed Mar 13 09:51:03 MET 1996 Norbert Kiesel - - * vers_ts.c (Version_TS): set options to default option if the - file if no -k option but -A was given. This avoids the (wrong) - update message for binary files which are up-to-date when - running 'cvs -A'. - - * update.c (checkout_file): remove test of -k option stored in the - file itself because it was moved to vers_ts.c - - * sanity.sh: added tests for the above fix. - -Tue Mar 12 13:47:09 1996 Jim Kingdon - - * hash.c (findnode): Adjust comment regarding errors. - - * hash.c (findnode, findnode_fn): Assert that key != NULL. This - way the check still happens even if the function is later - rewritten to not start out by calling hashp. - -Mon Mar 11 10:21:05 1996 Jim Kingdon - - * sanity.sh: If expr accepts multi-line patterns but is too - liberal in matching them, print a warning but keep going. - - * sanity.sh: Add QUESTION variable, analogous to PLUS. Use it - instead of \? to match a question mark. - - * cvs.h (CVSMODULE_OPTS, CVSMODULE_SPEC): Move from here... - * modules.c: ...to here. They are only used here and the code to - handle the syntax of modules files should not be scattered all over. - * modules.c (CVSMODULE_OPTS): Add "+" as first character. - * sanity.sh (modules): New tests 148a0 and 148a1 test for - above-fixed bug. - -Mon Mar 11 13:11:04 1996 Samuel Tardieu - - * modules.c (cat_module): set optind to 0 to force getopt() to - reinitialize its internal nextchar - -Mon Mar 11 00:09:14 1996 Jim Kingdon - - * hash.c (findnode, findnode_fn): Revert changes of 7-8 Mar 1996. - The correct style is to assert() that key != NULL (see HACKING), - which is already done in the hashp function. - * fileattr.c (fileattr_delproc): Likewise, assert() that - node->data != NULL rather than trying to deal with it being NULL. - -Fri Mar 8 01:31:04 1996 Greg A. Woods - - * hash.c (findnode_fn): one more place to avoid calling hashp() - with a NULL key - -Thu Mar 7 17:30:01 1996 Greg A. Woods - - * hash.c (findnode): also return NULL if key is not set - [[ reported by Chris_Eich@optilink.optilink.dsccc.com, and - supposedly in a PR that should be marked "fixed"..... ]] - - * fileattr.c (fileattr_set): set node->data to NULL after freeing - it to prevent subsequent accesses - (fileattr_delproc): don't free node->data if it's NULL, and set it - to NULL after freeing - [[ reported by Chris_Eich@optilink.optilink.dsccc.com, and - supposedly in a PR that should be marked "fixed"..... ]] - -Fri Mar 1 14:56:08 1996 Jim Kingdon - - * sanity.sh (basica): New test basica-4a tests for bug fixed by - sam@inf.enst.fr on 1 Mar 96. - -Fri Mar 1 18:10:49 1996 Samuel Tardieu - - * tag.c (check_fileproc): Check for file existence before trying - to tag it. - -Fri Mar 1 07:51:29 1996 Jim Kingdon - - * client.c (update_entries): If command is export, set options to - NULL. - -Thu Feb 29 16:54:14 1996 Jim Kingdon - - * lock.c (write_lock, Reader_Lock): Remove - BOGUS_UNLESS_PROVEN_OTHERWISE code. It was pretty bogus, and has - been ifdeffed out for a long time. - * cvs.h (CVSTFL): Removed; no longer used. - - * cvsrc.c, cvs.h (read_cvsrc): Pass in command name rather than - using global variable command_name. - * main.c (command_name): Initialize to "", not "cvs" so that error - messages don't say "cvs cvs". Update calls to read_cvsrc to pass - in command_name or "cvs" as appropriate. - * sanity.sh (basica): New test basica-9 tests for above-fixed bug. - - * lock.c: Rename unlock to lock_simple_remove to avoid conflict - with builtin function on QNX. - -Thu Feb 29 17:02:22 1996 Samuel Tardieu - - * fileattr.c (fileattr_get): Removed NULL pointer dereference - which occurred in the absence of default attribute. - -Thu Feb 29 07:36:57 1996 J.T. Conklin - - * rcs.c (RCS_isbranch, RCS_whatbranch): Remove no longer used file - argument, swap order of remaining two arguments to be like other - RCS_* functions. - (RCS_nodeisbranch): swap order of arguments to be like other RCS_* - functions. - * rcs.h (RCS_isbranch, RCS_whatbranch, RCS_nodeisbranch): Update - prototypes for above changes. - * commit.c, rtag.c, status.c, tag.c: Update for above calling - convention changes. - -Thu Feb 29 08:39:03 1996 Jim Kingdon - - * client.c (start_server): Revert changes which claimed to fall - back to a different way of connecting. Add comments explaining - why. (I don't think the changes did what they claimed, anyway). - Use indentation rather than comments to line up #if, #else, and - #endif. - - * patch.c (patch, patch_fileproc): Revert change to add optional - arguments to -c and -u. Optional arguments are evil and in - violation of the POSIX argument syntax guidelines. The correct - way to do this is -C and -U. Also change DIFF back to "diff" in - output (see comments). - - gcc -Wall lint: - * client.c (copy_a_file): Declare p inside the #ifdef in which is - it used. - * commit.c (remove_file): Remove unused variable p. - * commit.c (checkaddfile): Remove unused variables p. - * rcs.c (RCS_isbranch): Remove unused variable p. - * rcs.c: Remove unused declarations and definitions of - parse_rcs_proc, rcsnode_delproc, rcslist, and repository. - * rtag.c (rtag_fileproc): Remove unused variable p. - * patch.c (patch_fileproc): Remove unused variable p. - * tag.c (val_fileproc): Remove unused variable node. - * client.c, import.c, lock.c, server.c: Cast pid_t to long before - passing it to %ld. - - * cvs.h: Don't prototype gethostname; merely declare it (on linux, - second argument is size_t not int). - -Thu Feb 29 10:29:25 MET 1996 Norbert Kiesel (nk) - - * sanity.sh: added "cat > /dev/null" to loginfo entry to avoid the - SIGPIPE signal - -Thu Feb 29 10:28:25 MET 1996 Norbert Kiesel (nk) - - * patch.c: added new variable diff_opt - (patch): allow optional parameter to -c and -u option, send it to - server - (patch_fileproc): cleaned up the code which prints the current - filename. For "-s" option, print the pathname relative to CVSROOT - instead of just the filename. - - * filesubr.c (xchmod): added cast to shut up gcc - - * cvs.h: added prototype for gethostname - -Thu Feb 29 10:27:25 MET 1996 Norbert Kiesel (nk) - - * lock.c (write_lock), (Reader_Lock), import.c (update_rcs_file), - client.c (update_entries), (send_modified), server.c (server), - (receive_file), (server_updated): use %ld for printing pid_t - variables - -Thu Feb 29 02:22:12 1996 Benjamin J. Lee - - * run.c (run_exec): Added VMS return status support. - -Thu Feb 29 01:07:43 1996 Benjamin J. Lee - - * client.c (send_to_server): wrtn wasn't being declared under - VMS for some reason. - -Wed Feb 28 23:27:04 1996 Benjamin J. Lee - - * client.c: Changed #ifdef VMS && NO_SOCKET_TO_FD to - #if defined(VMS) && defined(NO_SOCKET_TO_FD) - -Wed Feb 28 22:28:43 1996 Benjamin J. Lee - - * build_src.com: Added DCL command procedure to build - and link CVS client for VMS. - -Wed Feb 28 22:07:20 1996 Benjamin J. Lee - - * client.c: VMS CVS client specific changes. - - Added USE_DIRECT_TCP to allow CVS_PORT to be used to specify - a TCP connection port (no Kerberos). Changed - start_kerberos_server() to start_tcp_server(). - - In copy_a_file(): transform a backup file to have a - VMS-friendly name. - - Added HAVE_CONFIG_H to include "config.h". - - start_server() will starts the first successful of any - mutually exclusive methods of starting the CVS server - which might be enabled. - - Initialized use_socket_style and server_sock for VMS in - start_server(). - -Wed Feb 28 21:49:48 1996 Benjamin J. Lee - - * find_names.c, recurse.c, cvs.h: Changed Find_Dirs() to - Find_Directories(). - * cvs.h: Added VMS filenames enabled through USE_VMS_FILENAMES - VMS POSIX will require to use the regular CVS filenames - while VMS is #define'd. - -Wed Feb 28 21:26:22 1996 Benjamin J. Lee - - * ignore.c: Added the patterns *.olb *.exe _$* *$ to default - ignore list for VMS. - -Wed Feb 28 13:32:28 1996 Jim Kingdon - - * logmsg.c (do_editor): Fix indentation. - -Wed Feb 28 12:56:49 1996 Benjamin J. Lee - - * logmsg.c (do_editor): If no editor is defined, exit and print - a message. - -Wed Feb 28 10:40:25 1996 Jim Kingdon - - * vers_ts.c (time_stamp, time_stamp_server): Reindent and revise - comments. - -Tue Feb 27 23:57:55 1996 Benjamin J. Lee - - * vers_ts.c: gmtime() returns NULL on some systems (VMS) - revert to local time via ctime() if GMT is not avaiable. - -Tue Feb 27 13:07:45 1996 J.T. Conklin - - The changes listed below cause cvs to parse each rcs file (and - free the associated rcsnode after the file has been processed) - sequentially. cvs used to parse all files in a directory, an - approach that does not scale to huge repositories with lots - of revisions/branches/tags/etc. - - * cvs.h (struct file_info): Removed srcfiles field. Added rcs - (node) field. - * recurse.c (do_recursion): Removed code that pre-parsed all - rcs files in the directory. - (do_file_proc): Parse current rcs file. - * rcs.c (RCS_parsefiles, parse_rcs_proc, RCS_addnode): Removed. - (RCS_isbranch, RCS_whatbranch): Changed srcfiles argument to - rcs (node). - * rcs.h (RCS_parsefiles, RCS_addnode): Removed prototypes. - (RCS_isbranch, RCS_whatbranch): Updated prototypes. - * add.c, admin.c, checkin.c, checkout.c, classify.c, client.c, - commit.c, diff.c, history.c, import.c, log.c, patch.c, remove.c, - rtag.c, status.c, tag.c, update.c, vers_ts: Updated for above - calling convention / data structure changes. - -Mon Feb 26 16:07:56 1996 Jim Kingdon - - * Version 1.7.3. - - * Version 1.7.2. - -Mon Feb 26 1996 Jim Kingdon - - * recurse.c (start_recursion): Use last_component rather than - checking for '/' directly. - (do_dir_proc): Likewise. - - Visual C++ lint: - * client.c (send_to_server): Change wrtn to size_t. - (connect_to_pserver): Put tofd and fromfd declarations inside - #ifndef NO_SOCKET_TO_FD. - * scramble.c (shifts): Change from array of char to array of - unsigned char. - -Mon Feb 26 13:31:25 1996 Jim Kingdon - - * server.c (check_repository_password): Remove unused variables - linelen, ch. - - * client.c (send_file_names): Translate ISDIRSEP characters to '/'. - -Sat Feb 24 21:25:46 1996 Jim Kingdon - - * checkout.c (safe_location): Re-indent one line. - -Sat Feb 24 10:50:42 1996 Karl Fogel - - * checkout.c (safe_location): put assignment to hardpath[x] in an - `else'-clause, so we don't do it when x == -1. - -Sat Feb 24 01:40:28 1996 Marcus Daniels - via Karl Fogel - - * server.c (check_repository_password): Return by reference an - optional username, the `host_user', from the passwd file. The - host_user will be the user-id under which the cvs repository is - run. - (check_repository_password): Use `read_line' instead of fgets to - allow for passwords larger than 32 characters, as well as the - optional host user argument. - (check_password): Modify to use host_user. - (authenticate_connection): Modify to use host_user. - -Sat Feb 24 01:05:21 1996 Karl Fogel - - * scramble.c (descramble): just shift descrambled string to get - rid of tag char, instead of allocating a whole new copy. - (scramble): cast return value of xmalloc to avoid unsightly - compiler warnings. - - * options.h.in (RCSBIN_DFLT): don't refer to AUTH_SERVER_SUPPORT - in comment anymore, now that it's not defined in this file. - -Fri Feb 23 1996 Jim Kingdon - - * client.c: Ifdef HAVE_WINSOCK_H, include winsock.h - instead of sys/socket.h and friends. - * login.c: Don't include sys/socket.h and friends. - * login.c (login): Only fclose fp in the case where it was - successfully fopen'd. - * login.c: Declare getpass. - * filesubr.c, cvs.h (get_homedir): New function. - * cvsrc.c, expand_path.c, history.c, login.c: Call it instead - of getenv ("HOME"). - -Fri Feb 23 09:23:20 1996 Jim Kingdon - - * client.c (connect_to_pserver): Remove unused variable host. - * login.c: Include getline.h. - (login): Remove unused variables i and username. - (get_cvs_password): Move free of linebuf to where it actually will - be called. Add a "return NULL" at the end of the function to shut - up gcc -Wall. - - * options.h.in: Remove AUTH_SERVER_SUPPORT. - * client.h (authenticate_connection): Declare. - * scramble.c (scramble): Cast char to unsigned char before using - it to look up in table (char might be signed). - * server.c [AUTH_SERVER_SUPPORT]: Include grp.h - (authenticate_connection): Remove unused variables len and - server_user. - - * sanity.sh (basica): Add comments regarding creating a top-level - directory. - (basic1): Don't try to remove first-dir and - ${CVSROOT_DIRNAME}/first-dir at start of test; tests are now - responsible for cleaning up at the end. - (PLUS,DOTSTAR,ENDANCHOR): Add comments regarding fixed GNU expr. - -Thu Feb 22 22:34:11 1996 Jim Kingdon - - * cvs.h: Remove alloca cruft. - -Wed Feb 21 07:30:16 1996 J.T. Conklin - - * modules.c (do_module): call free_cwd before exiting. - - * recurse.c: Removed entries global variable. - (do_recursion): Declare entries. Moved call to Entries_Close so - entries list is closed on all code paths. - (start_recursion): Removed call to Entries_Close, entries list has - been moved to do_recursion only. - -Tue Feb 20 22:10:05 1996 Jim Kingdon - - * update.c (update_dirent_proc): If dir lacks a CVS subdirectory, - don't recurse into it. - * sanity.sh (conflicts): Test for above-fixed bug. - - * update.c (merge_file): Use write_letter not printf. - -Tue Feb 20 12:34:07 EST 1996: Gary Oberbrunner - and Jim Kingdon - - * history.c (history_write): Change username to char * and call - getcaller() to set it. Setting username accidentally got deleted - 8 Feb 96. - * sanity.sh: Revise test 64 to test for above-fixed bug. - * sanity.sh (PLUS): New variable, work around yet another GNU expr - bug. - -Tue Feb 20 14:07:50 1996 Jim Kingdon - - * sanity.sh: Merge test rtags into test basic2. They never were - capable of running separately of each other. - - * sanity.sh (deep): New test, to test ability to operate in deeply - nested directories (more quickly than basic2 test did). - (basic2,rtags): Remove directories dir3 and dir4. Remove file8, - file10, file12, file9, file11, file13, file15, file16, file17. - These additional files slowed down the tests considerably without - significantly increasing coverage. - - * sanity.sh (PROG): New variable. Use it instead of "cvs" - to match the name cvs prints out for itself. - -Mon Feb 19 09:00:29 1996 Jim Kingdon - - This fixes a bug whereby old default attributes would get - clobbered instead of added to on "cvs watch add". - * hash.c (findnode): Don't check for key == NULL; let the - assertion in hashp take care of it. - * fileattr.h, fileattr.c (fileattr_get): If filename is NULL, - return default attributes. - - * client.c (send_repository): Fix indentation. - -Mon Feb 19 01:10:01 1996 Karl Fogel - - * login.c (login): print out full repos so user knows which server - she's logging into. - - * client.c (send_repository): die if `repos' is NULL. This is a - lame solution; see comments in code. - -Thu Feb 15 15:04:01 1996 Jim Kingdon - - * error.c (error): Free entire and mess when done with them. - - * sanity.sh (info): Correct syntax of .cvsrc file. - - * cvs.h, expand_path.c, edit.c, parseinfo.c, wrapper.c: - expand_path now takes arguments containing file and line for error - message, and it prints the error message itself. - * sanity.sh (info-6a): Test printing of error message. - - * expand_path.c (expand_variable): Add USER internal variable. - * sanity.sh (info): Test USER and CVSROOT internal variables too. - -Wed Feb 14 19:11:08 1996 Jim Kingdon - - * main.c (usg): Add -s option. - -Tue Feb 13 20:26:06 1996 Jim Kingdon - - gcc -Wall lint: - * mkmodules.c (mkmodules_usage): Remove declaration of - non-existent function. - * cvs.h (mkmodules): Declare. - -Mon Feb 12 12:20:04 1996 Jim Kingdon - - * mkmodules.c: Rename main to mkmodules and remove various pieces - of scaffolding which it used to emulate non-existent parts of CVS. - Change calling convention to just take a char * not argc,argv. - Save and restore working directory. - * commit.c (commit_filesdoneproc): Call it if checking files into - CVSROOT. - * Makefile.in (SOURCES): Add mkmodules.c. - (OBJECTS): Add mkmodules.o. - (MSOURCES,MOBJECTS): Removed. - (COMMON_OBJECTS): Removed; move former contents into OBJECTS. - Update other rules accordingly. - * sanity.sh: Adjust to reflect nonexistence of mkmodules. - - These changes introduce functions cvs_output and cvs_outerr; - eventually all server output will go through them rather than - stdio directly. - * server.c (saved_output, saved_outerr): New variables. - (do_cvs_command): Initialize them. - (buf_output): Don't require that buf->output be set; saved_* use - this to shove some data in a buffer which buf_copy_lines will - later want to get data from. - * server.c, cvs.h (cvs_output, cvs_outerr): New functions. - * mkmodules.c (cvs_outerr): New function, so error() works. - * error.c: Reindent. Don't declare program_name and command_name; - cvs.h declares them. - (error): Use vasprintf and cvs_outerr (or fputs in the - error_use_protocol case) rather than stdio directly. - * import.c (import_descend_dir): Remove kludge which had prevented - messages from error() from being out of order with respect to - messages from printf; cvs_output and cvs_outerr are a cleaner - solution to the problem. - (add_log, import): Use cvs_output not printf. - * update.c (write_letter): Use cvs_output not printf. - (checkout_file): Use write_letter not printf. - * sanity.sh: Use dotest for test 56 (test that output is actually - correct). In theory should test that the import.c bug is fixed, - but I was unable to reproduce the bug (it is timing dependent). - -Mon Feb 12 16:07:45 1996 Norbert Kiesel - - * commit.c: define last_register_time - (commit): make sure cvs doesn't exit in the same second it wrote - the last timestamp - (commit_fileproc): set last_register_time - (finaladd): set last_register_time - - * run.c, cvs.h: Changed more Popen() to run_popen() - -Mon Feb 12 03:06:50 1996 Benjamin J. Lee - - * release.c, rtag.c, tag.c: changed 'delete' to 'delete_flag' - to avoid symbol collision with DEC C RTL function delete() - -Mon Feb 12 03:01:48 1996 Benjamin J. Lee - - * mkmodules.c: changed 'void Lock_Cleanup()' to 'void static - Lock_Cleanup() to avoid conflict with more substantial - Lock_Cleanup() in lock.c - -Mon Feb 12 02:50:19 1996 Benjamin J. Lee - - * edit.c, logmsg.c, release.c, run.c: Changed Popen() to - run_popen(). VMS' linker is not case sensitive and considered - popen() and Popen() to be identical symbols. - -Sun Feb 11 10:51:14 1996 Jim Kingdon - - * main.c (main) [!CLIENT_SUPPORT]: Silently ignore gzip level - rather than printing usage message. - - * cvs.h, expand_path.c (variable_list): New variable. - (variable_set): New function. - * hash.h (enum ntype), hash.c (nodetypestring): Add VARIABLE. - * expand_path.c (expand_path, expand_variable): Reindent. - (expand_variable): Use user variables not environment variables - for ${=VAR} syntax. The environment variables didn't work - client/server. - * main.c (main): Process new -s global option. - * client.c (send_variable_proc): New function. - (start_server): Call it, to send user variables. - * server.c (serve_set): New function. - (requests): Add Set request. - * sanity.sh: Revise info test to use user variables rather than - environment variables. - -Sat Feb 10 16:55:37 1996 Jim Kingdon - - By itself this is only a small cleanup, but in the long run it - will be way cool (for reference, it takes CVS's text segment from - 290816 bytes to 294912, which I expect will be made up by future - changes which this enables): - * cvs.h (struct file_info): Added. - (FILEPROC): Replace 5 args with single struct file_info *. - * recurse.c (do_file_proc): Adjust args to fileproc; passed in - instead of from globals. - (do_recursion): Call do_file_proc accordingly. Remove srcfiles - global variable. - * update.c (update_fileproc): Renamed from update_file_proc. - * admin.c, client.c, commit.c, diff.c, edit.c, log.c, patch.c, - remove.c, rtag.c, status.c, tag.c, update.c, watch.c: Update - fileprocs to new calling convention. - -Fri Feb 9 15:30:32 1996 Jim Kingdon - - * expand_path.c (expand_variable): Accept a variable name starting - with '=' as a way to specify an environment variable. - * sanity.sh (info): New tests, for above behavior. - - * Makefile.in (clean): Also remove check.log check.plog. - - * import.c (comtable): Remove SYSTEM_COMMENT_TABLE; the table - should *not* depend on what kind of machine the server happens to - be. Add "mak", "rc", "dlg", "frm", and "bas" types which were - formerly included via SYSTEM_COMMENT_TABLE. - - * cvs.h, rcs.h, add.c, checkin.c, classify.c, commit.c, diff.c, - import.c, patch.c, rcs.c, update.c, vers_ts.c: Remove - DEATH_SUPPORT ifdefs. They were introduced to facilitate merging - between Cygnus and Berliner variants of CVS, not because it was - intended to subset CVS this way. And they clutter up the code - quite a bit. - * cvs.h, create_adm.c, main.c, update.c: Likewise, remove - CVSADM_ROOT ifdefs (it is still a #define, of course). I believe - they had a more-or-less similar motivation. - - * sanity.sh: Move setting of HOME from ignore test to the start of - the tests so it applies to all tests. - (CVS): Remove -f; the above change takes care of it. - - * rcs.h (RCS_MERGE): Removed; unused. - - * commit.c (checkaddfile): Fix memory leak. - - * admin.c, commit.c, diff.c, log.c, mkmodules.c: Pass -x,v/ to RCS - commands. - - * rcscmds.c, cvs.h (RCS_checkin): New function. - * checkin.c, commit.c, import.c: Call it, rather than run_*. - * cvs.h, commit.c: Remove DEATH_STATE define; the behavior - which used to be the default (DEATH_STATE) is now the only one. - Failing to define DEATH_STATE has been commented as obsolete at - least since CVS 1.5. We still can read repositories created with - such a CVS, however. - * rcs.h, rcs.c: Adjust comments regarding DEATH_STATE. - * subr.c (make_message_rcslegal): Add comment, describing - allocation of returned value. - -Fri Feb 9 09:53:44 MET 1996 Norbert Kiesel - - * sanity.sh: use "${testcvs}" instead of "cvs" in devcom tests - - * hash.c: fix "dereferencing a NULL pointer" bug triggered with - "cvs watch add" - (findnode): return NULL if key == NULL - (hashp): assert (key != NULL) - -Fri Feb 9 00:46:47 1996 Jim Kingdon - - * rcs.c (RCS_reparsercsfile): Remove unused variable date. - - * myndbm.c (mydbm_load_file): Fix typo ('015' -> '\015'). - -Thu Feb 8 13:00:00 1996 Jim Kingdon - - * rcs.c (RCS_parse, RCS_parsercsfile, RCS_reparsercsfile), - fileattr.c (fileattr_read), myndbm.c (myndbm_open): - Use FOPEN_BINARY_READ. - * fileattr.c (fileattr_write), myndbm.c (myndbm_close): - Use FOPEN_BINARY_WRITE. - * history.c (history_write, read_hrecs): Specify OPEN_BINARY. - * rcs.c: Remove calls to abort. - * myndbm.c (myndbm_load_file): Ignore CRs from ends of lines - if present. - * myndbm.c, fileattr.c: While I am at it, change \n to \012 - a few places where LF is intended. - * history.c (history_write): Use getenv ("HOME"), not getpwnam, - to find home directory. If it isn't set, just keep going; don't - print a message. - * rcscmds.c, cvs.h (RCS_checkout): New function. - * update.c, checkin.c, commit.c, diff.c, import.c, no_diff.c, - patch.c: Call it instead of run_*. - * patch.c (patch_fileproc): Clean up inconsistent handling of - noexec flag. - * rcscmds.c (RCS_*): Pass -x,v/ to RCS commands; elsewhere in - CVS it is assumed that ,v is a suffix. - -Fri Feb 2 14:07:32 1996 J.T. Conklin - - * rcs.h (struct rcsnode): Remove dates field (list of rcsversnodes - indexed by date). CVS maintained this list for each RCS file even - though it was never used. This resulted in higher then necessary - memory requirements (and run time too). Even if revision info was - needed, CVS' List data structure is inappropriate because can't - handle duplicate keys. The above was discovered by tracking down - a memory leak. - * rcs.c (RCS_reparsercsfile): Don't build dates list. - (freercsnode): Don't delete dates list. - (rcsvers_delproc): Free date field. - (null_delproc): Removed. - -Thu Feb 1 12:28:33 1996 Jim Kingdon - - * remove.c (cvsremove): Don't tell user the name of the program - which they use to remove files; we don't have any way of knowing - that, and besides which they might use a GUI or emacs 'dired' anyway. - * update.c (update_filesdone_proc, update_dirleave_proc): Call - unlink_file_dir instead of rm -rf. - * options.h.in: Remove RM; no longer used. - - * sanity.sh: New tests devcom-a* test "cvs watch add", - "cvs watch remove", and "cvs watchers". - - * sanity.sh: New test 171a0 tests for watch.c bug just fixed by kfogel. - - * Most .c files: Remove rcsids. - * cvs.h: Remove USE macro. - -Thu Feb 1 13:07:15 1996 J.T. Conklin - - * tag.c, rtag.c: Update various comments to reflect function name - changes. - -Thu Feb 1 14:14:31 1996 Karl Fogel - - * recurse.c (do_recursion): comment #endif. - - * edit.c (notify_check): surround with #ifdef CLIENT_SUPPORT; else - CVS won't compile if CLIENT_SUPPORT is undefined. - - * edit.h (notify_check): surround declaration with #ifdef - CLIENT_SUPPORT. - - * watch.c (watch): if argc <= 1, then just give usage (previously - was "argc == -1"). - -Thu Feb 1 12:28:33 1996 Jim Kingdon - - * README-rm-add: Remove information which is now in cvs.texinfo. - - * sanity.sh: Remove basic0 tests. Move a few to new tests - basica-1a* (but there is no need to test that *every* command - gracefully does nothing on an empty directory; exhaustive testing - is impractical and the generic recursion processor handles this - anyway). - - * sanity.sh: New tests 69a* test use of update -p to restore old - version of dead file. - -Wed Jan 31 18:32:34 1996 Jim Kingdon - - * ChangeLog-9395: Remove duplicate entries from 1996 which - accidentally got into this file. - - * client.c (read_line, read_from_server): Change "premature end of - file from server" message to "end of file from server (consult - above messages if any)" because 99% of the time it means rsh has - printed an error message and exited. - -Wed Jan 31 15:09:51 1996 J.T. Conklin - - * edit.c (ncheck_fileproc): Fix memory leak; free line before - returning. - -Tue Jan 30 18:06:12 1996 Jim Kingdon - - * recurse.c (do_recursion): Add comment about the fact that we - don't have locks in place at certain points. - -Tue Jan 30 09:43:34 1996 Vince Demarco - - * edit.c (notify_proc): have notify_proc call expand_path with - the name of the filter program. The user may have used a - cvs environmental variable. (Popen will expand it, but it may not - use the correct value) - -Tue Jan 30 09:43:34 1996 Jim Kingdon - - * ChangeLog: take the pre-1996 changes and put them in a new file - ChangeLog-9395. - * ChangeLog-9194: Renamed from ChangeLog.fsf. - * ChangeLog-9194, ChangeLog-9395, ChangeLog: Add additional text - explaining the difference between all these logs and pointing to - older logs. - * Makefile.in (DISTFILES): Add ChangeLog-9194 and ChangeLog-9395; - remove ChangeLog.fsf. - - * modules.c (do_module): Don't fall through from 'l' to 'o' case - of option processing switch statement. - -Tue Jan 30 06:50:19 1996 J.T. Conklin - - * client.c (send_repository): Fix memory leak; free adm_name - before returning. - * diff.c (diff_file_nodiff): Fix memory leak; free xvers before - returning. - * rtag.c (rtag_fileproc): Fix memory leak; if branch_mode is set, - free rev before returning. - * status.c (status_fileproc, tag_list_proc): Fix memory leak; free - return value of RCS_whatbranch. - * tag.c (tag_fileproc): Fix memory leak; free vers before - returning. - (val_fileproc): Fix memory leak; free return value of RCS_gettag. - * watch.c (watch_modify_watchers): Fix memory leak; free mynewattr - before returning. - -Tue Jan 30 09:43:34 1996 Jim Kingdon - - * lock.c (readers_exist): If stat gave an error, print an error - message saying it was from stat, rather than from "reading - directory". Skip the message completely if it was an - existence_error. - - * sanity.sh (branches): New tests (branches off of branches, etc.). - -Tue Jan 30 11:55:34 MET 1996 Norbert Kiesel - - * main.c (main): Add change to run getopt_long twice again. - -Mon Jan 29 15:59:31 1996 Jim Kingdon - - gcc -Wall lint: - * client.c: Include edit.h - -Sun Jan 28 09:45:53 1996 Jim Kingdon - - * edit.c, edit.h (mark_up_to_date): New function, to remove file - in CVS/Base. - * client.c (update_entries): Call it if file is up to date. - * checkin.c (Checkin): Call it in non-server (local) case. - * sanity.sh: New test 182.5, tests for above-fixed bug. - -Sun Jan 28 01:07:22 1996 Jim Kingdon (kingdon@beezley) - - * client.c (change_mode): Separate out CHMOD_BROKEN code to parse - mode_string, rather than going through a mode_t. Cleaner than - the previous CHMOD_BROKEN code (which also had a typo of && not &). - -Sat Jan 27 23:29:46 1996 Jim Kingdon (kingdon@beezley) - - * edit.c (edit_fileproc): Check for EACCESS as well as EEXIST. - -Sat Jan 27 16:26:30 1996 Karl Fogel (kfogel@floss.cyclic.com) - - * client.c (notified_a_file): use rename_file() instead of - rename() (but temporarily set `noexec' to 0 so it runs - unconditionally). - (change_mode): deal with CHMOD_BROKEN. - -Fri Jan 26 00:14:00 1996 Karl Fogel - - * server.c: renamed `dirname' to `dir_name', to avoid conflicts - with system headers. - - * client.c: renamed `dirname' and `last_dirname' to `dir_name' and - last_dir_name' (see above). Not strictly necessary, but - consistency is nice -- as long as you do it all the time. - -Thu Jan 25 00:41:59 1996 Karl Fogel - - * options.h.in (AUTH_SERVER_SUPPORT, AUTH_CLIENT_SUPPORT): change - comment now that no longer under construction. - -Wed Jan 24 15:25:22 1996 Jim Kingdon - - * Version 1.7.1. - - * Version 1.7. - -Sat Jan 20 00:05:08 1996 Jim Kingdon - - * Version 1.6.87. - -Mon Jan 15 18:14:55 1996 Gary Oberbrunner - and Jim Kingdon - - * tag.c (val_direntproc): New function to ignore - nonexistent dirs when recursing to check tag validity. - (tag_check_valid): Pass it to start_recursion. - * sanity.sh (death): New tests 65a0-65a6 cause test 74 to test for - above-fixed bug. - -Mon Jan 15 12:55:37 1996 Jim Kingdon - - * main.c: Revert change to run getopt_long twice. This can go in - after 1.7. - -Mon Jan 15 13:03:28 1996 Norbert Kiesel - - * filesubr.c (deep_remove_dir): added test of EEXIST for nonempty - directory (Posix states that both ENOTEMPTY (BSD) and EEXIST - (SYSV) are valid) - - * main.c (main): run getopt_long twice to allow command-line - suppression of reading the cvsrc file - -Fri Jan 12 10:02:43 1996 Jim Kingdon - - * Version 1.6.86. - -Thu Jan 11 23:28:05 1996 J.T. Conklin - and Jim Kingdon - - * fileattr.h (fileattr_startdir): Add comment about REPOS == NULL. - * fileattr.c (fileattr_read, fileattr_write): Assert that - fileattr_stored_repos != NULL. - (fileattr_free): If fileattr_stored_repos is NULL, don't free it. - -Thu Jan 11 18:03:21 1996 Karl Fogel - - * scramble.c (descramble): deal with DIAGNOSTIC better. - -Thu Jan 11 12:04:42 1996 Norbert Kiesel - - * main.c: remove CVS_NOADMIN. - - * options.h.in: remove CVS_NOADMIN - -Thu Jan 11 10:28:44 1996 Karl Fogel - - * scramble.c (descramble): make sure the string returned is safe - to free(). - -Wed Jan 10 01:11:23 1996 Jim Kingdon - - * server.c (serve_notify): Cast return value from malloc. - - * edit.c (notify_do): Use struct assignment, not struct - initialization (which SunOS4 /bin/cc doesn't have). - -Tue Jan 9 09:41:29 1996 Jim Kingdon - - * Version 1.6.85. - - We use version numbers instead of patchlevels. But there was some - confusing patchlevel stuff lying around. Nuke it: - * Makefile.in (HEADERS): Remove patchlevel.h - * patchlevel.h: Removed. - * main.c: Don't include patchlevel.h. - (main): Don't print patch level. - - * server.c (check_repository_password): Check for errors from - system calls; reindent function. - -Tue Jan 9 23:15:30 1996 Karl Fogel - - * expand_path.c: fix comments (explain expand_path()'s behavior - correctly). - -Tue Jan 9 09:41:29 1996 Jim Kingdon - - * edit.c (notify_proc): After copying in string following %s, - don't clobber it. Instead set up q to end of string. - - * watch.c (watch_modify_watchers), edit.c (editor_set): Fix sense - of test in trying to decide whether attributes are changed. - - * cvs.h (CVSROOTADM_USERS): New macro. - * edit.c (notify_do): Look up notifyee in CVSROOTADM_USERS if it - exists. - -Tue Jan 9 21:39:45 1996 Karl Fogel - - * expand_path.c: don't redundantly #include things that cvs.h - already #includes (i.e., stdio.h, ctype.h, string[s].h). - -Tue Jan 9 09:41:29 1996 Jim Kingdon - - * ignore.c (ign_default): Add *.obj. - - * server.c: Put /* */ around #endif comment. - -Mon Jan 8 20:37:17 1996 Karl Fogel - - * client.c (connect_to_pserver): check return value of recv(). - -Mon Jan 8 11:37:57 1996 Jim Kingdon - - * client.c (connect_to_pserver): Check for error from connect; - reindent function. - - * sanity.sh (4.75): Use dotest, so we get a PASS if test passes. - - * sanity.sh (dotest): New argument OUTPUT2. - (188a): Use it instead of \|. - - * sanity.sh (import): Avoid using string $ followed by Id followed - by $ in sanity.sh source, in case sanity.sh itself is under CVS. - I hate keyword expansion. - - * sanity.sh: If expr cannot handle multiline expressions, fail and - tell the user to get one which can. - - * release.c (release_delete): Remove unused variable retcode. - -Fri Jan 5 13:30:00 1996 Jim Kingdon - - * release.c (release_delete): Call unlink_file_dir rather - than "rm -rf". - -Thu Jan 4 09:58:30 1996 Jim Kingdon - - * commit.c (find_fileproc): Print "nothing known about foo" and - return 1 if the file doesn't exist and isn't in CVS/Entries. - (commit): If the recursion over find_fileproc returns an error, - print "correct above errors first!" just like local CVS. - * sanity.sh (basica): Test for above-fixed bug. - - * release.c (release): If we are the client, only unedit if the - server supports it. - - * sanity.sh: Remove STARTANCHOR stuff; expr patterns are - automatically anchored to the start. ENDANCHOR remains. - - * commit.c (commit): Don't start the server until we have - determined that there is something to commit. - -Thu Jan 4 09:48:33 1996 Ben Laurie - and Jim Kingdon - - * client.c (start_server): dup the file descriptor before - fdopening it. - -Wed Jan 3 18:25:25 1996 Jim Kingdon - - * sanity.sh: Remove tests 5, 5.5, and 5.75. All that stuff is - tested elsewhere. - - * ignore.c (ign_default): Change CVS* to CVS CVS.adm. CVS* is too - broad, especially in a case-insensitive filesystem. - - * Makefile.in (cvsbug): version.c is in srcdir. - -Wed Jan 3 17:30:45 1996 Phi-Long Tran - - * modules.c (do_module): Honor error_use_protocol in printing trace. - * server.c (server_register): Move check for options NULL to above - printing of the trace. - -Wed Jan 3 01:19:53 1996 Mark Immel - and Jim Kingdon - - * update.c (checkout_file): Do not resurrect file on join if it - doesn't contain the revisions we are joining. Probably not a - perfect test, but should be an improvement. - * sanity.sh (death): New death-file4-* tests, for bug fixed above. - -Wed Jan 3 01:19:53 1996 Jim Kingdon - - * add.c, admin.c, checkout.c, client.c, commit.c, diff.c, edit.c, - history.c, import.c, log.c, patch.c, release.c, remove.c, rtag.c, - status.c, tag.c, update.c, watch.c: In calling send_to_server, - pass \012 not \n. On the Mac \n is CR, not LF, and we want to - send LF. I didn't try to deal with whether files in CVSADM should - contain CR or LF--in fact there is some code in client.c which - reads \n from CVSADM files and passes it to send_to_server; it - needs to be cleaned up one way or the other. - - * entries.c (Entries_Open): Don't try to close fpin twice. - - * client.c (update_entries): Fix typo ("strlen (filename + 10)" - -> "strlen (filename) + 10"). - - * commit.c (checkaddfile): Remove arbitrary limit. - -Tue Jan 2 11:25:22 1996 Jim Kingdon - - * commit.c (commit): Only pass files which were modified, added, - or removed to send_file_names. This has as a side effect a - semantic change--the up-to-date check is now skipped for other - files--but probably a good one, or at least not a bad one. - * sanity.sh (basica): New test; tests for bug fixed above. - * sanity.sh (187a3): Adjust for new 'cvs commit' output. Set up - DOTSTAR to match arbitrary text (another GNU expr bug/misfeature, - sigh). - - * sanity.sh: Test that the commit in test 43 actually worked. - Merge tests basic2 and basic3 and make them independent of basic1. - (pass,fail): Don't insert spurious space. - (45.5): Fix typo in directory name. - -Tue Jan 2 13:00:00 1996 Jim Kingdon - - Visual C++ lint: - * myndbm.c: Prototype write_item. - -Tue Jan 2 11:25:22 1996 Jim Kingdon - - gcc -Wall lint: - * client.c (client_expand_modules): Pass error message not "" to error. - * client.c (supported_request), server.c (supported_response): - Return a value (gcc -Wall can't know that error doesn't return). - * commit.c (copy_ulist): Return a value. - * history.c (fill_hrec): Don't make assumptions about whether - time_t is "int" or "long" or what. - * cvs.h: Declare link_file. - * server.c: Include fileattr.h. - * server.c (server_notify): Remove unused variable val. - * tag.c (val_fileproc): Remove unused variable foundtag. - -Mon Jan 1 09:49:16 1996 Jim Kingdon - - * Version 1.6.5. - - * Version 1.6.4. - - * filesubr.c (link_file): Add comment about link vs. copy semantics. - - * cvs.h (struct vers_ts): Fix comments. - * commit.c (commit): Before we ask for a log message, figure out - what is modified and what is not and pass the information to - do_editor. - (copy_ulist,find_fileproc): New helper functions for above code. - - * client.c (read_line): When writing to from_server_logfile, write - the \n too. - - * client.c (send_files): No longer call send_file_names. - * client.h: Update comment. - * add.c, admin.c, commit.c, diff.c, edit.c, log.c, remove.c, - status.c, tag.c, update.c, watch.c: Call send_file_names before - send_files. - * client.c: New variables module_argc, module_argv. - (client_expand_modules): Set them, to arguments. - (client_send_expansions): Use them instead of modules_vector to - send arguments. - * sanity.sh (modules): Add test of modules -d flag. - - -For older changes see ChangeLog-9395. diff --git a/contrib/cvs/src/ChangeLog-97 b/contrib/cvs/src/ChangeLog-97 deleted file mode 100644 index ce7180b..0000000 --- a/contrib/cvs/src/ChangeLog-97 +++ /dev/null @@ -1,3249 +0,0 @@ -1997-12-30 enami tsugutomo - - * rcs.c (RCS_checkin): Use gmtime() instead of localtime() - (restores behavior from RCS 5.x which was broken with RCS library - -kingdon). - -Mon Dec 29 12:53:00 1997 Ian Lance Taylor - - * modules.c (do_module): Check for a request for a file within a - module which is not a directory. - * sanity.sh (modules): Add test 149b1 for above patch. - - * client.c (start_tcp_server): Remove useless assignment, left - behind by Dec 15 patch. - -Sat Dec 27 17:41:11 1997 Jim Kingdon - - * client.c, options.h.in, history.c, import.c, main.c, rcs.c, - update.c: Remove !HAVE_RCS5 code. It had bit-rotted a while ago, - and more to the point is obsolete with the RCS library. - -27 Dec 1997 Jim Kingdon - - * zlib.c, server.h (gunzip_and_write): New function. - * client.c (update_entries): Call it instead of a gunzip subprocess. - * zlib.c, server.h (read_and_gzip): New function. - * client.c (send_modified): Call it instead of a gzip subprocess. - -Sat Dec 27 13:07:38 1997 Jim Kingdon - - Decrease RCS_deltas memory usage to what we need (approximately - the size of the file we are patching plus the size of the largest - patch). Previously memory usage had been approximately the size - of the RCS file because we never freed lines until the end. - * rcs.c (linevector_free, linevector_copy, linevector_add, - linevector_delete): - Instead of having all the lines and struct line's in the alloc_* - space, have each line and its struct line in its own malloc'd - space. Use a refcount to deal with curlines vs. headlines - vs. trunklines in RCS_deltas. - (struct allocblock, blocks, block_alloc, block_free): Remove; no - longer used. - (apply_rcs_changes, RCS_deltas): Don't copy lines into allocated - space; linevector_add now does that for us. - (rcs_change_text, RCS_deltas): Don't call block_free. - -Tue Dec 23 08:28:44 1997 Jim Kingdon - - * cvsbug.sh: Change bug-cvs address from prep.ai.mit.edu to gnu.org - per email from Martin Hamilton. - -Sun Dec 21 21:49:50 1997 Jim Kingdon - - * rcs.c (RCS_checkin): Disable keyword expansion when generating - the change text. - * sanity.sh: Move tests keyword-24 through keyword-27 into - new section keywordlog and expand greatly. Note that CVS 1.9.18 - passes the new tests both local and remote but the current - version failed them both local and remote before this fix. - -Sat Dec 20 19:56:00 1997 Jim Kingdon - - * rcs.c (RCS_delete_revs): Clean up temporary files even if noexec. - Without this fix, basica-o5a in sanity.sh would leave files around. - -Thu Dec 18 13:05:00 1997 Jim Kingdon - - * run.c: Fix typo in declaration (evecvp -> execvp) (credit to - Erik Walthinsen for reporting this). Only declare it if not - HAVE_UNISTD_H. Move declaration to before the first use. - -Tue Dec 16 12:59:00 1997 Jim Kingdon - - * update.c: Collapse two identical declarations for join_file. - -Mon Dec 15 16:01:49 1997 Ian Lance Taylor - - * client.c (start_tcp_server): Remove calls to htons and add one - call to ntohs (init_sockaddr calls htons on the port argument). - -Mon Dec 15 00:07:02 1997 Jim Kingdon - - * client.c (failure_exit): New variable. - (get_server_responses): If it is set, then return - failure. - (updated_seen, updated_fname): New variables. - (update_entries): Use updated_fname if set. In the "move away - foo.c; it is in the way" case print "C" not "U", and set - failure_exit. - (handle_mt): If we get +updated tagged text, stash it away in - updated_fname rather than printing it immediately. - (handle_mt, get_server_responses): If we stashed a filename and - didn't get around to printing it, go ahead and print it. - * sanity.sh (conflicts2-142d2): Adjust to test for fix. Remote is - now like local was in terms of exit status and "C aa.c" message. - -Sun Dec 14 00:27:26 1997 Jim Kingdon - - Implement tagged text feature: - * update.c (write_letter): Take a single finfo argument rather - than file and update_dir. While we are at it change it to return - void (since the returned value always had been 0). - * update.c: Update callers. - * server.c, cvs.h (cvs_output_tagged): New function. - * client.c (responses): Add "MT" response. - (handle_mt): New function. - * update.c (write_letter): Output via cvs_output_tagged. - -Sun Dec 14 14:13:05 1997 Ian Lance Taylor - - * recurse.c (do_dir_proc): Only check for CVS/Repository if - W_LOCAL. - * sanity.sh (devcom-t2, devcom-t3): New tests for above patch. - -Sun Dec 14 00:27:26 1997 Jim Kingdon - - * root.c (parse_cvsroot): Initialize check_hostname (fixes thinko - in GSSAPI changes). - -Sat Dec 13 13:15:35 1997 Jim Kingdon - - * server.c: Use indentation to indicate nesting of #ifdef's. - - * client.c (connect_to_gserver): Reindent (in one place). - -Fri Dec 12 17:38:15 1997 Chris Provenzano - and Ian Lance Taylor - - * cvs.h (CVSmethod): Add gserver_method. - * root.c (method_names): Add gserver. - (parse_cvsroot): Handle :gserver:. - * client.h (cvsauthenticate): Declare. - (cvs_gssapi_encrypt): Declare if HAVE_GSSAPI and ENCRYPTION. - (cvs_gssapi_wrap_buffer_initialize): Declare if HAVE_GSSAPI. - (connect_to_pserver): Update declaration. - (pserver_authenticate_connection): Declare when HAVE_GSSAPI and - SERVER_SUPPORT is defined in addition to other case. - * client.c: If HAVE_GSSAPI, include GSSAPI header files. - (gcontext): New static variable if HAVE_GSSAPI. - (connect_to_pserver): Add do_gssapi parameter. Change all - callers. Move rejection handling to bottom of function. - (recv_bytes): New static function if HAVE_GSSAPI. - (connect_to_gserver): Likewise. - (start_server): Handle gserver_method. Handle GSSAPI encryption - and authentication. - * server.c: Include if HAVE_GSSAPI, in addition to - existing cases. If HAVE_GSSAPI, include GSSAPI header files. - Include even if AUTH_SERVER_SUPPORT is not defined. - (gcontext, cvs_gssapi_wrapping): New static variables if - HAVE_GSSAPI. - (cvs_gssapi_encrypt): New global variable if HAVE_GSSAPI and - ENCRYPTION. - (serve_gssapi_encrypt): New static function if HAVE_GSSAPI and - ENCRYPTION. - (serve_gssapi_authenticate): New static function if HAVE_GSSAPI. - (requests): Add Gssapi-encrypt if HAVE_GSSAPI and ENCRYPTION. Add - Gssapi-authenticate if HAVE_GSSAPI. - (switch_to_user): Compile if HAVE_GSSAPI, in addition to existing - cases. - (pserver_authenticate_connection): Likewise. Ifdef out part of - the code for AUTH_SERVER_SUPPORT. Handle a GSSAPI request. - (gserver_authenticate_connection): New static function if - HAVE_GSSAPI. - (cvsauthenticate): New global variable. - (struct cvs_gssapi_wrap_data): Define if HAVE_GSSAPI. - (cvs_gssapi_wrap_buffer_initialize): New function if HAVE_GSSAPI. - (cvs_gssapi_wrap_input): New static function if HAVE_GSSAPI. - (cvs_gssapi_wrap_output): Likewise. - * main.c (opt_usage): Mention -a. - (main): Handle -a. Handle pserver if HAVE_GSSAPI, in addition to - existing cases. - * login.c (login): Pass new argument to connect_to_pserver. - -Fri Dec 12 15:33:19 1997 Ian Lance Taylor - - * buffer.c (PACKET_SLOP): Define. - (packetizing_buffer_initialize): Use PACKET_SLOP when allocating - holdbuf. - (packetizing_buffer_input): Allow up to PACKET_SLOP bytes in - stackoutbuf. - (packetizing_buffer_output): Use just BUFFER_DATA_SIZE + 2 for - inbuf. Allow PACKET_SLOP + 4 extra bytes in stack_outbuf. - Correct >= to > in test of incoming number of bytes. Use - PACKET_SLOP in other tests. - -Fri Dec 12 10:27:08 1997 Jim Kingdon - - * client.c (start_tcp_server): Revise comment to reflect - SOCK_STRERROR and SOCK_ERRNO now being in use. - -Thu Dec 11 15:32:31 1997 Ian Lance Taylor - - * client.c (init_sockaddr): Compile if HAVE_KERBEROS, as well as - if AUTH_CLIENT_SUPPORT. Return a pointer to a struct hostent. - (start_tcp_server): Clean up. Use init_sockaddr. Use - SOCK_STRERROR and SOCK_ERRNO. Don't bind the socket. - - Generalize buffering code used by Kerberos encryption routines - into a generic packetizing buffer. The new code in buffer.c is a - modified version of the code removed from server.c. - * buffer.c (struct packetizing_buffer): Define. - (packetizing_buffer_initialize): New function. - (packetizing_buffer_input): New static function. - (packetizing_buffer_output): New static function. - (packetizing_buffer_flush): New static function. - (packetizing_buffer_block): New static function. - (packetizing_buffer_shutdown): New static function. - * buffer.h (packetizing_buffer_initialize): Declare. - * server.c (struct krb_encrypt_data): Rename from - krb_encrypt_buffer, and remove all fields not related to - encryption. - (krb_encrypt_buffer_initialize): Just call - packetizing_buffer_initialize. - (krb_encrypt_input): New static function. - (krb_encrypt_output): New static function. - (krb_encrypt_buffer_input): Remove. - (krb_encrypt_buffer_output): Remove. - (krb_encrypt_buffer_flush): Remove. - (krb_encrypt_buffer_block): Remove. - (krb_encrypt_buffer_shutdown): Remove. - -Wed Dec 10 15:39:44 1997 Ian Lance Taylor - - * buffer.c (stdio_buffer_initialize): Correct formatting. - -Sun Dec 7 09:37:19 1997 Jim Kingdon - - * sanity.sh (basicb-0d0): New test, for checkout on existing - directory. - -Sat Dec 6 00:25:11 1997 Jim Kingdon - - * sanity.sh (binwrap3): Clean up repository too. Clean up working - directory with "rm -r" not "rm -rf". - -Thu Dec 4 17:11:18 1997 Larry Jones - - * subr.c (check_numeric): Don't reference argv[1] when argc is 1 - (should be argv[0]). - - * sanity.sh: Fix lines that look like conflict markers but aren't - to prevent problems checking in. - (binwrap3): Remove local CVSROOT when done so that later - tests that expect to create it don't fail. - -Thu Dec 4 18:19:21 1997 Jim Kingdon - - * cvs.h: Remove mempcpy definition. I think the polite way to - describe my feelings about mempcpy is something like "we don't - have agreement that it is a good idea". - * rcs.c (truncate_revnum): Don't call it. - * sanity.sh: Run multibranch2 test by default. - (multibranch2): Use ${TESTDIR} a few places. - (multibranch2-9): Accept "P file1" as well as "U file1". - - * sanity.sh: Don't add 1997 to the copyright notice. Add GPL - terms. Add discussion of copyright issues. - * rcs.c (truncate_revnum, truncate_revnum_in_place, - compare_truncated_revnums): Reindent. - -1997-12-04 Jim Meyering - - * subr.c (xstrdup): Use memcpy rather than strcpy. - (compare_revnums): Declare parameters to be `const'. - Remove unnecessary uses of xstrdup and corresponding frees. - (increment_revnum): Declare parameter to be `const'. - Use memcpy rather than strcpy. - (gca): Declare parameters to be `const'. - (check_numeric): Declare REV parameter to be `const'. - (file_has_markers): Declare parameter to be `const'. - (get_file): Declare `char*' parameters to be `const'. - * run.c (run_exec): Declare `char*' parameters to be `const'. - * cvs.h (mempcpy) [! HAVE_MEMPCPY]: Define it. - Add `const' to types in several prototypes. - - * rcs.c (truncate_revnum): New function. - (truncate_revnum_in_place): New function. - (compare_truncated_revnums): New function. - (max_rev): New function. - (RCS_addbranch): Make BRANCH parameter `const'. - Use the above functions rather than open-coding them. - When BRANCH is a revision number, insert it *in order* - in the sorted list of branch numbers, not at the end. - Add assertion that insertion succeeds. - * sanity.sh (multibranch2): Test for this. - (Copyright): Add 1997. - -Dec 1997 Karl Fogel - - * wrapper.c (wrap_name_has): loop as far as wrap_count + - wrap_temp_count, not wrap_count + wrap_saved_count, otherwise - some wrappers get skipped. - (wrap_matching_entry): same. - * sanity.sh (binwrap3): new test, for import with - CVSROOT/cvswrappers and .cvswrappers specifying -k 'b' options. - -1997-11-30 Jim Meyering - - * client.c (send_a_repository): Strip trailing slashes from the name - of the update directory. Otherwise, running `cvs update dir/' provokes - this failure `protocol error: illegal directory syntax in dir/' when - running in client/server mode. - - * hash.c (insert_before): New function derived from addnode. - (addnode): Simply return insert_before. - (addnode_at_front): Simply return insert_before. - * hash.h (insert_before): Add prototype. - - * server.c (dirswitch): Compute `strlen(dir)' once and save it, - rather than computing it four times. Also do s/illegal/invalid/ to - this diagnostic: "E protocol error: illegal directory syntax in %s". - -Sun Nov 30 18:03:02 1997 Jim Kingdon - - * admin.c: Fix comment (no longer a front-end to "rcs"). - - * error.c, error.h (rcserror): Remove. - * admin.c, rcs.c: Call error instead of rcserror. This changes - the format of these messages from "rcs: : error" to "cvs - : : error". The former format wasn't quite what - RCS printed anyway (because RCS would sometimes print "ci", "co", - &c, not "rcs"), and preserving RCS's exact output probably is not - a good idea anyway (because it will make people think that the - error was caused by an external program). In two cases, I tidied - up the message in a more drastic fashion ("cannot stat" in - RCS_checkin and "could not diff" in RCS_delete_revs). - - * sanity.sh (basica-o2b, binfiles2-o1, admin-18, admin-22-o10, - admin-22-o17): Look for "cvs " not "rcs". - - * run.c, cvs.h (run_setup): Replace varargs nonsense with a single - argument which gets parsed as the result of the vasprintf - used to. - * client.c, commit.c, logmsg.c, modules.c, rtag.c, tag.c, update.c, - wrapper.c: Update callers, either to do the sprintf themself or to - just call run_arg if it will do the job. - * rcscmds.c: Likewise for call_diff_setup and callers. - - * run.c, cvs.h (run_args): Remove; nowhere used. - -Sat Nov 29 22:15:06 1997 Jim Kingdon - - * options.h.in: Remove declaration of getwd; see lib/ChangeLog for - rationale. - -1997-11-29 Jim Meyering - - * update.c (checkout_file): Initialize `backup'. - - * diff.c (diff_fileproc): Initialize `tmp' and `fname'. - - * modules.c (do_module): Initialize `server_dir_to_restore'. - (do_module): Initialize `value' in an else clause. - - * rcs.c (RCS_checkin): Initialize `commitpt'. - (RCS_delete_revs): Initialize `revp'. - (RCS_copydeltas): Always initialize `insertbefore'. - - * run.c (run_print): Define `outfn' even in error case. - -Mon Nov 24 17:28:50 1997 Jim Kingdon - - * rcs.c (RCS_findlock_or_tip): Prototype. - (RCS_checkin): Fix call to pass correct number of arguments. - -Sun Nov 23 10:34:03 1997 Jim Kingdon - - * recurse.c (do_dir_proc): Move check for CVS/Repository and - CVS/Entries to before where we call the direntproc. - * client.c (send_dirent_proc): Remove code to check for - CVS/Repository, now that recurse.c does it. - * sanity.sh (conflicts3-18 through conflicts3-19): New tests, for this. - -Sat Nov 22 10:54:16 1997 Jim Kingdon - - * recurse.c (do_dir_proc): Check that CVS/Repository and - CVS/Entries exist. - * sanity.sh (conflicts3-14 through conflicts3-17): New tests, for this. - - * client.c (send_fileproc): Send options field from - vers->entdata->options not vers->options. - * cvs.h (struct entnode): Add comment (options and timestamp must - not be NULL). - * sanity.sh (binfiles-9 through binfiles-13, binfiles-sticky5, - keyword-17): Remove kludges for remote; tests for fix. - - * update.c (update_fileproc): Fix comment; direct checkout is - still faster than patches for local but not for quite the - same reasons. - - * add.c (add): Pass SEND_NO_CONTENTS to send_files. - -Wed Nov 19 18:25:03 1997 Mike Glendinning - - * update.c (patch_file_write): Missing cast provided. - -Wed Nov 19 15:57:59 1997 Jim Kingdon - - * rcs.c (RCS_deltas): Solve trigraph problem (once and for all, I - hope) with 3 calls to cvs_output. - -Wed Nov 19 01:52:57 1997 Andy Piper - and Jim Kingdon - - * classify.c (Classify_File), cvs.h (struct vers_ts), vers_ts.c - (Version_TS): Clarify NULL versus "" for options in comments. - * vers_ts.c (Version_TS): Treat "" the same way as NULL in options - and vers_ts->options. - * sanity.sh: New tests binfiles-sticky5 through binfiles-17 test - for this. - -1997-11-16 Karl Fogel - - * client.c (update_entries): parse server-sent entries line even - in the case of "cvs export", because we need to know if -kb option - is set. - Init `options' to NULL like anything else. - -Tue Nov 18 09:20:29 1997 Jim Kingdon - - * version.c: Change version number to 1.9.21. - - * Version 1.9.20. - -Mon Nov 17 14:35:31 1997 Jim Kingdon - - * server.c (server_updated): If scratched_file and noexec are set, - clean up so we don't get a "duplicate Scratch_Entry" warning - later. - * sanity.sh: New tests conflicts3-10 to conflicts3-13, for this. - - * sanity.sh (conflicts3): Don't allow "file1 was lost" messages - here; I don't think CVS actually produced them, and they don't - belong. - -Sun Nov 16 23:19:41 1997 Jim Kingdon - - * sanity.sh: Accept either "U file1" or "P file1". - -Fri Nov 14 12:32:05 1997 Jim Kingdon - - * rcs.c: Add comment about cleaning up ,foo, file on ^C. - -Fri Nov 14 11:56:29 1997 Andy Piper - and Jim Kingdon - - * filesubr.c (unlink_file_dir): Don't print trace message in the - server. - -Fri Nov 14 11:28:55 1997 Jim Meyering and Jim Kingdon - - * rcs.c (RCS_getdatebranch): If the branch we are looking for - doesn't exist, return a revision which matches the date, not - just NULL. - * sanity.sh (tagdate): New test, for this. - -Thu Nov 13 10:11:48 1997 Jim Kingdon - - * sanity.sh (basicb-21): Fix comment which described a behavior - which no longer exists. - -Wed Nov 12 16:24:45 1997 Jim Kingdon - - Clean up infrastructure made unnecessary by RCS library: - * rcscmds.c (diff_exec, diff_execv): Use literal "diff" not DIFF. - * options.h.in (DIFF), rcs.h (RCS, RCS_CI, RCS_DIFF, - RCS_RCSMERGE): Removed; no longer used. - * commit.c (commit), patch.c (patch_fileproc), - rcscmds.c (RCS_exec_rcsdiff), start of rcscmds.c: Update comments - to reflect librarification of RCS. - * options.h.in (RCSBIN_DFLT): Removed. - * main.c, cvs.h (Rcsbin, free_Rcsbin): Removed. - * main.c (main): Don't check RCSBIN environment variable. -b - global option is now a noop. - * cvs.h (RCSBIN_ENV): Removed. - * expand_path.c (expand_variable): $RCSBIN is now an error. - * mkmodules.c (config_contents): Remove RCSBIN. - * parseinfo.c (parse_config): RCSBIN now a noop. - * server.c (server): Don't put Rcsbin in PATH. - -Mon, 10 Nov 1997 Jim Kingdon - - * rcs.c (RCS_checkin): Actually, when we get a change text - for a text file using get_file, we want text mode, although - the reasons are kind of subtle (see comment). - - * rcs.c (RCS_checkin): Pass correct mode to get_file for - binary files. - - * rcscmds.c: Declare vasprintf. - -Mon Nov 10 11:11:17 1997 Jim Kingdon - - This fixes problems with windows-NT/run.c improperly quoting, and - is cleaner anyway. - * rcscmds.c (call_diff_setup, call_diff_arg, call_diff_add_arg, - call_diff_argv, call_diff_argc, call_diff_argc_allocated): New - functions/variables, lightly adapted from src/run.c. - * cvs.h, run.c (call_diff, call_diff3): Move from here... - * rcscmds.c: ...to here. - -Sun, 9 Nov 1997 Jim Kingdon - - * rcs.c (rcs_internal_unlockfile): Call rename_file not rename. - This makes it work on NT again. - -Sun Nov 9 16:54:28 1997 Jim Kingdon - - * sanity.sh (diffmerge2): Protect keywords against unwanted - expansion. They got clobbered and the testcase stopped working - when I checked it in. - -Fri Nov 7 13:23:38 1997 Karl Fogel - and Jim Kingdon - - * sanity.sh (diffmerge1, diffmerge2): new tests, for bugs, or - potential bugs, in ../diff/analyze.c which were fixed by Paul - Eggert's patch. - -Sun Nov 9 10:28:43 1997 Jim Kingdon - - * rcs.c (RCS_settag): Reindent. - - * rcs.c (rcs_internal_lockfile): Fix typo (thow -> throw). - -Sat Nov 8 15:58:53 1997 Jim Kingdon - - * sanity.sh (cvsadm): Remove most of the tests which tested - CVS/Root. This takes the run time for the cvsadm tests from - about 5 minutes 15 seconds to about 4 minutes 10 seconds with no - significant loss in coverage. - - * rcs.c (rcs_internal_lockfile): Check for errors from system - calls. If open() gives an error, don't muck with stat and errno - (I don't know what the RCS code that this comes from was trying to - do, but it clearly isn't accomplishing anything here). - (RCS_rewrite, RCS_delete_revs): Check for errors from system calls. - -Sat Nov 1 14:21:29 1997 Michael L.H. Brouwer - - * rcs.c (RCS_checkin): Change type of bufsize from int to size_t. - (RCS_delete_revs): Change type of bufsize and len from int to size_t. - (RCS_getdeltatext): Change type of textlen from int to size_t. - * rcs.h (struct deltatext): Change len from int to size_t to keep - the compiler happy on systems where size_t is unsigned int. - [This goes well beyond keeping the compiler happy; if sizeof - (size_t) != sizeof (int), the old code was quite broken -kingdon] - -Sat Nov 1 14:21:29 1997 Michael L.H. Brouwer - and Jim Kingdon - - * rcs.c (RCS_checkin): When checking if we were holding the lock - use delta->author instead of user since the latter might have been - clobbered by a call to getcaller. This resulted in the failure of - test basica-7. - [I don't completely follow the scenario where it gets clobbered, - it but sounds vaguely plausible and the replacement seems - cleaner, precisely because it avoids allocation issues -kingdon] - -Wed Nov 5 20:16:12 1997 Jim Kingdon - - * checkin.c, checkout.c, commit.c, cvs.h, import.c, login.c, - main.c, update.c: Change FALSE to 0 and TRUE to 1 and replace - monstrosities like "cvswrite == TRUE" with just "cvswrite". FALSE - and TRUE sometimes conflicted with system headers (NextStep3.3?), - but more to the point, good old 1 and 0 are fine and were used by - most of CVS already. - -Tue Nov 4 12:19:28 1997 Jim Kingdon - - * rcs.c (RCS_checkin, RCS_lock, RCS_unlock): Rename local variable - quiet to checkin_quiet or some such, to avoid confusion with - global variable quiet. - - * lock.c: Update comment to refer to add_rcs_file rather than "rcs - -i". - - * rcs.h (struct rcsnode): Add comments for all fields. - * rcs.c (RCS_delete_revs): Refuse to delete revisions which have - symbolic names. Fix fencepost bug which caused us to sometimes - check one more revision than we should for locks, branches, and - this. - (findtag): New function, to help above code. - - * admin.c (admin): Take out writelocks not readlocks. This has - been a bug "forever", but may become more noticeable with - rcs_internal_lockfile relying on the writelocks. - -Mon Nov 3 10:17:19 1997 Jim Kingdon - - * rcs.c (RCS_rewrite): Don't write the file if noexec. - * sanity.sh (basica, branches): Test for this. - -Sat Nov 1 10:01:56 1997 Jim Kingdon - - * rcs.h (struct deltatext): Comment text and log fields. - - * admin.c (admin_fileproc): Call RCS_reparsercsfile not - RCS_fully_parse. Don't muck with ->other field in RCSVers (it - doesn't need to be set). - * rcs.h, rcs.c (RCS_reparsercsfile): No longer static. No point - in having this static when RCS_rewrite and RCS_fully_parse are not. - * rcs.c (getdelta): Remove obsolete comment about not storing the - newphrases from the deltas, since we now do. - -Sat Nov 1 10:01:56 1997 Jim Kingdon - and Paul Eggert - - * rcs.c (rcs_internal_lockfile): Clarify the comments about O_EXCL - and such matters. - -Sat Nov 1 10:01:56 1997 Jim Kingdon - - * rcs.c (RCS_delete_revs): Pass force_tag_match to RCS_settag. - * sanity.sh (basica-o2a, basica-o2b): Test for this. - -1997-11-01 Peter Brandstrom - - * sanity.sh: Use ${username} more places. - -Sat Nov 1 00:14:00 1997 Jim Kingdon - - * rcs.c (rcs_internal_lockfile): Add comments about what we are - trying to accomplish here (versus what RCS tries to accomplish). - - * rcs.c (RCS_parsercsfile_i): Clarify/expand comment about - the purpose of having both this and RCS_reparsercsfile. - (RCS_rewrite): Add comment about how this works. - - * admin.c (admin_fileproc): Add comment about call to - RCS_fully_parse not RCS_reparsercsfile. - * rcs.h: Comment on what delta_pos field of struct rcsnode is. - -Fri Oct 31 16:38:39 1997 Jim Kingdon - and Abe Feldman - - * client.c (update_entries): If UTIME_EXPECTS_WRITABLE, if - necessary change the file to be writable temporarily to set its - modification time. - -Thu Oct 30 17:42:59 1997 Jim Kingdon - - * admin.c (admin): Deal with new :: syntax for ranges. - * rcs.c, rcs.h (RCS_delete_revs): New arg inclusive (set for the old - behavior, clear to enable new code). - * admin.c (admin_fileproc): Set it if :, clear it if ::. - * sanity.sh (basica, head, branches, log): Add tests for this feature. - - * admin.c (admin_fileproc): Clean up the error message which - happens if one of the RCS_* functions returns an error status; it - is confusing to say that "rcs" failed now that this is implemented - internally. - * sanity.sh (admin): Update accordingly. - -Wed Oct 29 07:07:36 1997 Jim Kingdon - - * sanity.sh (admin-22-o24): New test, tests that admin -o - correctly munged the deltatexts on a branch too. - - * rcs.c (RCS_delete_revs): If we are deleting an entire branch, - delete the node in ->branches rather than setting the ->key to the - bogus value NULL. - * rcs.c (RCS_delete_revs): If "rev1" equals "branchpoint", then set - "before" to the revision on the trunk that we branch from. - * rcs.c (RCS_delete_revs): Don't set rev2 to revp->version (the - code is missing an xstrdup, but it doesn't matter because rev2 - isn't used after this point). - * sanity.sh (binfiles2-o2 to binfiles2-o4): New tests, for this. - -Tue Oct 28 19:30:05 1997 Jim Kingdon - - * rcs.c (RCS_delete_revs): Restore code which passes rev2 to - RCS_getbranchpoint if rev1 is NULL; it still makes sense for the - non-trunk case. Fixes admin-22-o22 in testsuite. - - * sanity.sh (admin-18): Adjust to reflect "rcs failed" no longer - being suppressed by global -q option. - - * rcs.c (RCS_delete_revs): If rev1 == NULL and rev2 is on the - trunk, handle it the same way we do everything else--by swapping - the two. This replaces the code which tried to kludge what we - passed to RCS_getbranchpoint (which didn't work). - * sanity.sh (binfiles2-o1 to binfiles2-o4): New tests, for this fix. - * admin.c (admin_fileproc): Don't have -q global option suppress - "rcs failed" message. - -1997-10-28 Jim Kingdon - - * log.c (printlock_proc), rcs.c (putlock_proc): Prototype. - * rcs.c (rcs_internal_lockfile): Only try to call fchmod if - HAVE_FCHMOD is defined. - -Tue Oct 28 10:27:03 1997 Ian Lance Taylor - - * rcs.c (RCS_deltas): Don't use \? in string if __STDC__ is not - defined. - - * rcs.c (make_file_label): Remove extraneous `+'. - -Mon Oct 27 14:40:15 1997 Jim Kingdon - - * status.c (status): Don't pass SEND_NO_CONTENTS to send_files. - -Sat Oct 25 00:33:57 1997 Jim Kingdon - - * rcs.c (RCS_delete_revs): Use : not - for range in error message. - - * rcs.h: Add comment about '\0' in RCS fields. - - * rcs.c (getdelta): Add comment about branches and next field - being mandatory. - - * rcs.c (RCS_reparsercsfile, RCS_deltas), sanity.sh (reserved): - Reindent sections which were misindented as a result of recent - changes. - -Fri Oct 24 10:22:15 1997 Jim Kingdon - - * rcs.c (RCS_findlock_or_tip): Don't worry about file ownership - and nonstrict locking when returning the default branch or head. - The most conspicuous problem with the old code is that in the - error case it would examine rstat.st_uid when it had not been - set. For a discussion of more fundamental reasons, see comment. - - * admin.c (admin_fileproc): In handling -A, don't handle relative - pathnames differently from absolute pathnames. See comment for - rationale. If problem opening the file, give a nice error not a - coredump. - * sanity.sh (admin-19a-admin, admin-19a-log, admin-19a-fix): - New tests, test for traditional "cvs admin -A" behavior with - relative pathnames. - * sanity.sh (admin-19a-nonexist): Test for the core dump fix. - * sanity.sh (admin-22-o1): Look for ${PROG} not cvs. - - * sanity.sh (reserved-16): Remove commitinfo change with "cvs - commit" not "cvs admin -o". In addition to commit being The Right - Thing on general principles, cvs admin -o doesn't work because it - doesn't rebuild the administrative file database. - - * update.c (patch_file): If the first revision does not exist in - the RCS file, fall back to sending entire file. Fixes - admin-22-o15 in make remotecheck. - -1997-10-23 enami tsugutomo - - * rcs.c (RCS_checkin): Unlink temporary files stored in variable - `tmpfile' and `changefile'. - -Wed Oct 22 12:16:10 1997 Jim Kingdon - - * rcs.c (rcs_lockfilename): Allocate enough memory for terminating - '\0'. - - * admin.c (admin_fileproc): Don't support '-' for ranges in "cvs - admin -o". - (admin): Adjust comment. - - * rcs.h (RCSVers): New field other_delta. - * rcs.c (free_rcsvers_contents): Also free other_delta. - (getdelta): Read newphrases from deltas into other_delta field. - (putdelta): Write those newphrases. - * sanity.sh (rcs-8a): New test, for this fix. - * admin.c (admin_fileproc): If "-b" without argument, then set - branch to NULL, not "" (uncovered by rcs-8a test). - * rcs.c (putrcsfield_proc): Add comment about how we (mis)handle - values in newphrases. - - * sanity.sh (reserved): Instead of looking for rcslock.pl in CVS - distribution, just use our own equivalent. - - * rcs.c (RCS_rewrite): Call ferror before fclose to avoid "Invalid - argument" warnings. - -Mon Oct 20 00:30:16 1997 Tim Pierce - - [I removed a ChangeLog entry for a change to sanity.sh (editor), - because the actual change was not made. With this change, CVS no - longer runs RCS. I'll be checking in my cleanups shortly. -kingdon] - - Librarify `ci'. - * rcscmds.c, cvs.h (RCS_checkin): Removed. - * rcs.c, rcs.h (RCS_checkin, RCS_getbranchpoint, RCS_addbranch, - RCS_findlock_or_tip): New functions. RCS_checkin completely - rewritten to eliminate RCS 5.7; change `rcs' parameter from string - to RCSNode, so we can update RCSNode without re-reading from - disk. - * checkin.c (Checkin): Updated RCS_checkin caller, moved RCS_parse - call to before RCS_checkin. - * import.c (add_rev): Updated caller. - * commit.c (remove_file): Updated caller. - (checkaddfile): Updated caller. Parse `rcsfile' after - calling add_rcs_file. Free `rcsfile' instead of asserting it to - be NULL. - - Librarify `rcs'. - * rcscmds.c, cvs.h (RCS_exec_settag, RCS_exec_deltag, - RCS_exec_setbranch, RCS_exec_lock, RCS_exec_unlock): Removed. - - * rcs.c (RCS_settag): Rewritten to eliminate RCS 5.7. - * commit.c (checkaddfile): Call RCS_rewrite after calling RCS_settag. - * import.c (add_tags): Same. - * rtag.c (rtag_fileproc): Same. - * tag.c (tag_fileproc): Same. - - * rcs.c (RCS_deltag): Rewritten to eliminate RCS 5.7. Remove - `quiet' parameter, since this function no longer prints any output. - * commit.c (remove_file): Update caller. Also call RCS_rewrite - after RCS_deltag. - * rtag.c (rtag_delete): Same. - * tag.c (tag_fileproc): Same. - - * rcs.c (RCS_setbranch): Rewritten to eliminate RCS 5.7. - * commit.c (remove_file): Call RCS_rewrite after calling RCS_setbranch. - (fixbranch): Same. - (lock_RCS): Same. - - * rcs.c (RCS_lock): Rewritten to eliminate RCS 5.7. Change third - arg to mean `quiet' and not `noerr', permitting admin_fileproc to - run RCS_lock verbosely. - * commit.c (lock_RCS): Update callers; call - RCS_rewrite after RCS_lock. - (remove_file): Same. Call RCS_lock quietly. - * import.c (add_rev): Same. Do not print `fork failed' error - message, since we're no longer forking. - - * rcs.c (RCS_unlock): Rewritten to eliminate RCS 5.7. Change - `noerr' arg to mean `quiet', permitting admin_fileproc to run - RCS_unlock verbosely. Use notify_do when breaking another user's - lock. Include "edit.h" for notify_do prototype. - * checkin.c (Checkin): Update caller; use RCS_rewrite after RCS_unlock. - * commit.c (unlockrcs): Same. - * import.c (add_rev): Same. - - * rcs.c, rcs.h (RCS_getlocks, RCS_addaccess, RCS_delaccess, - RCS_getaccess, RCS_delete_revs): New functions. - (expand_keywords, RCS_lock, RCS_unlock): Use RCS_getlocks. - * log.c (log_fileproc, log_version): Call RCS_getlocks. Don't add - bogus ";locker" nodes to RCSVers nodes -- walk lock list with - printlock_proc. - (printlock_proc): New function. - - * admin.c (admin_fileproc): Largely rewritten: call internal RCS - library functions instead of forking RCS processes. - (admin, admin_fileproc): Obsolete -V option. - (struct admin_data): Remove `version' member. - * sanity.sh (admin-24): Remove -V test case. - - New functions for reading and writing RCS files. - * rcs.h (struct deltatext, Deltatext): New types. - (struct rcsversnode): New members `text' and `outdated'. - (struct rcsnode): New members `access', `locks', `strict_locks', - `comment', and `desc'. - * rcs.c (RCS_reparsercsfile, expand_keywords): Use new RCSNode members. - (free_rcsnode_contents): Free them. - * log.c (log_fileproc): Use new RCSNode members instead of ->other. - - * rcs.c (getdelta, RCS_getdeltatext, freedeltatext, do_locks, - RCS_putadmin, RCS_putdtree, RCS_putdesc, putdelta, - putrcsfield_proc, putsymbol_proc, RCS_copydeltas, putdeltatext, - RCS_rewrite, getrevnum, rcs_internal_lockfile, - rcs_internal_unlockfile, rcs_lockfilename): New functions. - - (RCS_reparsercsfile): Use getdelta, making sure fp is positioned - correctly before calling it. Skip `head' and `branch' nodes: we - have already parsed them, and they were being added incorrectly to - rcs->other. Do not signal error if the RCS file has an empty - delta tree; this made it impossible for RCS_checkin to perform an - initial checkin. Remove `all' parameter; always store all RCS - fields. - (RCS_fully_parse, RCS_gettag, RCS_getbranch, RCS_getdate, - RCS_getdatebranch, RCS_getrevtime, RCS_symbols, translate_symtag, - RCS_isdead, RCS_getexpand, RCS_checkout, annotate_fileproc): - Update all callers to remove `all' parameter. - - (getrcskey): Do not append trailing whitespace to a value. This - corrupted some log fields and wrecked some sanity.sh test cases. - - (free_rcsvers_contents): New function. - (rcsvers_delproc): Call it. - - * rcs.h (NODELTA): Removed symbol; now obsolete (since RCSNodes - do not go stale). - * import.c (add_rev): Removed NODELTA reference. - * rcs.c (RCS_reparsercsfile, RCS_checkout, RCS_settag, RCS_deltag, - RCS_setbranch, RCS_lock, RCS_unlock, RCS_deltas): Removed NODELTA - references. - - Miscellaneous changes to support RCS librarification and fix some bugs. - * subr.c, cvs.h (line2argv): Add `sepchars' argument. - * modules.c (cat_module, admin_fileproc): Update all callers. - - * subr.c, cvs.h (compare_revnums, increment_revnum): New functions. - (make_message_rcslegal): Strip whitespace from end of - lines and end of string, a la `cleanlogmsg' in RCS 5.7. - (get_file): Terminate buf with \0, extending it if - necessary. Read from stdin if `name' arg is NULL. - * admin.c (admin_fileproc): Call get_file to read -t arg from stdin. - - * error.c, error.h (rcserror): New function, used everywhere. - - * hash.c, hash.h (addnode_at_front): New function. - * rcs.c (RCS_settag, RCS_lock): Call it. - - * import.c, cvs.h (expand_at_signs): Make extern. - * rcs.c (putrcsfield_proc, RCS_putadmin, RCS_putdesc, - putdeltatext): Call it. - - * rcs.c (make_file_label): Use last_component to get file's basename. - - * sanity.sh (srcdir): New variable. - (rcs-7): Remove newphrase warning, no longer produced by CVS. - (rcs-8): Permit random whitespace around newphrase fields. - (admin-22): New test cases for -o options: admin-22-o{1..23}. - (reserved): New test cases for rcslock.pl: reserved-{8..16}. - -Tue Oct 21 16:48:32 1997 Jim Kingdon - - * tag.c (tag_check_valid): Add comment about locking or lack - thereof. - -1997-10-20 Jim Kingdon - - * version.c: Change version number to 1.9.19. - -1997-10-19 Jim Kingdon - - * Version 1.9.18. - -Wed Oct 15 15:21:43 1997 Jim Kingdon - - * sanity.sh (username): Add '-' to characters allowed in user name. - - * rcscmds.c (diff_exec): Remove item about external diff - programs. It doesn't really belong here now that diff is - librarified and TODO #191 now mentions this. - - * checkout.c (checkout_proc): Add comment about assuming '/' is - the only path separator. - * options.h.in: Fix thinko (CVS/Repository -> CVS/Root). - -Mon Oct 13 22:46:03 1997 Jim Kingdon - - * commit.c (commit): Add comment about CVS_BADROOT and command - other than "commit". - -1997-10-11 Noel Cragg - - * options.h.in: RELATIVE_REPOS has been checked for bitrot -- it - now works again. Change the comment before the #define to say - that we'll be switching to it soon. - - * sanity.sh (basicb-1, basicb-1a): update dotest strings to match - no matter if we're running with RELATIVE_REPOS defined or not. - (basicb-9b, basicb-9c): same. - - * sanity.sh (basicb-9b, basicb-9c): modified tests, since the - checkout.c fix changes the way this test module is checked out. - (basicb-9d, basicb-9e, basicb-9f): new tests, same. - (basicb-18): modify test, same. - (cvsadm): new set of exhaustive tests to check the contents of - CVS/Root and CVS/Repository files under various conditions. As a - side effect, it tests the behavior of the "-d" flags (command line - and modules file). - (modules3-7e through modules3-7h): removed, since these tests were - a small subset of what is tested in the new cvsadm section. - (modules-1b, modules-1c): same. - (modules-2b, modules-2c): same. - (modules-3b, modules-3c, modules-3e, modules-3f): same. - - * create_adm.c (Create_Admin): be a bit more verbose when using - trace mode. - - * checkout.c (checkout_proc): rewrote the code that sets the where - variable and the code that matches directory names with repository - directories. This fixes a long-standing bug in CVS. (It used to - be the case that "cvs co -d foo " would not properly, - where and where defined in the modules file. While - the first module would be checked out correctly, the second would - be checked out under the name of the directory to which the module - referred rather than the module name!). This fix also allows us - to check out things into directories that are more than one deep - (e.g. "cvs -d foo/bar/baz co blah" will now work). - (checkout): remove code that performed a CHDIR if the - number of arguments specified was greater than one, since it's no - longer necessary. Also remove the code that prevented us from - doing "cvs co -d /" without existing, since - checkout_proc handles things correctly now. - - * cvs.h: fix typo. - - * rtag.c (rtag): reformat so that we don't run over 80 characters - per line. - (rtag_dirproc): same. - - * sanity.sh: change all old test cases to use pass and fail - functions rather than doing some combination of echo and exit - themselves. - - * commit.c (commit_direntproc): remove the "warm fuzzy" -- this - code never gets called when running in client/server mode, and we - should have CVS' output match as much as possible between the two - modes. Moreover, there is no analogous place to put this same - message when we're running in c/s mode. - (find_direntproc): print the same "fuzzy" as in check_direntproc - so that local and c/s mode have the same messages. - * sanity.sh (187a3): update test case to reflect the above. - -Thu Oct 9 10:57:02 1997 Jim Kingdon - - * parseinfo.c (parse_config): Add comment about compatibility - issues with adding keywords. - -Wed Oct 8 16:40:37 1997 Jim Kingdon - - * recurse.c (do_dir_proc), commit.c (check_direntproc, - commit_direntproc, find_dirent_proc): If this - directory doesn't exist, skip it. - * diff.c (diff_dirproc): Reindent. - * sanity.sh (deep-4b0a, deep-4b0b): Check for this fix. - -Thu Sep 26 16:30:00 1997 Larry Jones - and Jim Kingdon - - * update.c (checkout_file): Don't set timestamp in noexec mode. - * vers_ts.c (Version_TS): Add comment about ignoring errors from - utime. - * sanity.sh (conflicts3): New tests, for this fix. - -Fri Oct 3 09:47:04 1997 Noel Cragg - - * sanity.sh (168): use PROG instead of CVSBASE, since they are - equal. - (importb-2): refer to PROG instead of "cvs" in error message. - - * add.c (add): use PROGRAM_NAME in the error message rather than - "cvs". - * classify.c (Classify_File): same. - * commit.c (find_fileproc): same. - * sanity.sh: change all add notification messages to refer to PROG - rather than "cvs". Fixed nasty quoting in several places at the - same time, replacing older "'command'" forms with newer - ".command." for simplicity. - -Sat Sep 27 01:37:10 1997 Jim Kingdon - - * sanity.sh (rcslib-merge-8): Accept "P file1" as well as "U file1". - -Fri Sep 26 22:24:10 1997 Noel Cragg - - * create_adm.c (Create_Admin): assign our duplicate pointer `cp' - after the xrealloc of `reposcopy' because the latter might have - changed addresses. - -Fri Sep 26 14:25:59 1997 Tim Pierce - - * run.c (call_diff): Don't reset optind; this is done by diff_run now. - - Librarify rcsmerge/diff3. - * rcscmds.c, cvs.h (RCS_merge): Rewritten from scratch: check out - selected files and diff3 them. Take new `rcs' and `workfile' - arguments, so we can resolve symbolic tags and manipulate the - working file. - * update.c (merge_file, join_file): Update RCS_merge calls. - * run.c, cvs.h (call_diff3): New function. - - * sanity.sh (rcslib): New tests, rcslib-merge-{1..13}. - -Fri Sep 26 22:59:56 1997 Jim Kingdon - - * create_adm.c (Create_Admin): Fix thinko in Noel's change: keep - track of the originally allocated "cp" and free it, rather than - calling free on a pointer which may point halfway into the allocation. - * repos.c (Sanitize_Repository_Name): Per HACKING, assert that - repository != NULL, rather than just silently returning if NULL. - Reindent a line. - -Fri Sep 26 15:40:00 1997 Noel Cragg - - * sanity.sh (modules): add tests modules-[123]* that make sure the - administrative files get rebuilt in various cases. - - * add.c (combine_dir): removed function, since we no longer need - to worry about stripping the "." path element out. Changed the - two callers to simply concatenate their two arguments. - - * recurse.c (do_dir_proc): don't bother trying to strip off "." in - the repository name since the below changes fix that behavior -- - simply concatenate the repository and directory names together. - - * checkout.c (checkout_proc): sanitize the repository name after - constructing it (we may create "/path/to/repos/.", but we don't - want that to be passed around). Remove the code that tacks on - "/." when constructing top_repository, since the below changes fix - that behavior. Added comments to the part of this function that - builds administrative files. - - * sanity.sh (basicb): now that the below weirdness is fixed, the - extra "." path element in test basicb-0c doesn't appear when a - top-level file is checked out. Remove it from the expect string. - - * create_adm.c (Create_Admin): now that the repository name isn't - floating around with "." as the last path element, make creation - of the top-level administrative files a special case -- save the - repository name as "/path/to/repos/." Why? I considered not - including the "." but didn't know how it would affect the remote - protocol when RELATIVE_REPOS was defined (do we have a way of - sending "" via the protocol?). After I make sure that the - RELATIVE_REPOS patches still work, I'll check the "" possibility - so we don't have to have a this special case. - - * repos.c (Sanitize_Repository_Name): new function that removes - (if present) the trailing slash and "." component from the - repository name. Many routines break if we don't guarantee this. - See the comment before the function for complete information. - (Name_Repository): call Sanitize_Repository_Name before returning - the value. - * cvs.h: add prototype for Sanitize_Repository_Name. - -Fri Sep 26 14:19:25 1997 Jim Kingdon - - * cvs.h (CVS_CMD_USES_WORK_DIR): Fix comment (the sense of the - flag is not reversed from what it would seem; when I thought so it - was because I was misreading the lookup_command_attribute code). - -Thu Sep 25 23:14:47 1997 Noel Cragg - - * parseinfo.c (Parse_Info): fix typo in the trace message. - -Thu Sep 25 14:22:54 1997 Jim Kingdon - - * build_src.com: Also link with diff.olb. - - * main.c (Make_Date): If gmtime returns NULL, try localtime. - -Wed Sep 24 19:18:40 1997 Noel Cragg - - * checkout.c (checkout): fix typo in comment. - -Wed Sep 24 08:31:46 1997 Jim Kingdon - - * update.c (patch_file): Revise comments about diff -a now that - diff is librarified. - -Sun Sep 21 21:28:26 1997 Jim Kingdon - - * run.c (call_diff): Sleep for a second, in hopes of helping with - out of order bugs. - -Sat Sep 20 07:19:18 1997 Tim Pierce - - Integrate diff library into CVS. - * run.c, cvs.h (call_diff): New function. - * rcscmds.c (diff_exec, diff_execv): Get diffs from call_diff - instead of running diff as a subprocess. - * Makefile.in (cvs): Add ../diff/libdiff.a. - - * diff.c (longopts, diff): Use 131 for --ifdef, fixing Jim's thinko - (using 147 for both --side-by-side and --ifdef). - - * sanity.sh (rcslib): Added tests rcslib-diffrgx-*, to test - handling of regex diff options. - -1997-09-21 Jim Kingdon - - (Note that this requires that DIFF support -L. I'll be checking - in a fix to that in a moment, but I wanted separate checkins in - case that helps with clarity). - Tweaks to rcsdiff librarification: - * sanity.sh (rcslib): Change "cvs" to "${PROG}" and subcommand - names (e.g. "add") to "[a-z]*". Former should deal with ${testcvs} - being "cvs.old" or something; latter fixes make remotecheck. - * rcs.c (make_file_label): Take into account strlen (rev) when - allocating space. Removes a FIXME and probably fixes a buffer - overrun security hole. - * rcscmds.c (RCS_exec_rcsdiff): Remove #if 0'd code to call - rcsdiff. Tim says he has compared the new code with rcsdiff code - and is confident that the behavior is preserved, so we need to - nuke the comment which says this has not been done. #if 0 isn't - really a very good way to document the way it used to work anyway; - the old code is still in CVS. - * diff.c: Add comment about rcsdiff options that we don't support, - which Tim had sent in email. Remove -T and -y, as the - previous meaning had been very confused. - -1997-09-21 Tim Pierce - - Librarify rcsdiff. - - * diff.c (have_rev1_label, have_rev2_label): New variables. - (diff): Generate file labels with make_file_label if necessary; - pass labels, revisions and working file name to RCS_exec_rcsdiff. - * rcscmds.c, cvs.h (RCS_exec_rcsdiff): Completely revised function - to eliminate rcsdiff dependency, based on patch from JimK. - (diff_execv): New function, to exec diff with explicit -L args. - * rcs.c, rcs.h (make_file_label): New function. - (RCS_output_diff_options): New function. - * sanity.sh (rcslib): New test. - -Fri Sep 19 15:08:08 1997 Jim Kingdon - - * rcs.c (RCS_nodeisbranch): Assert that RCS is non-NULL. - * commit.c (remove_file), rcs.c (RCS_getversion), rtag.c - (rtag_fileproc), status.c (status_fileproc, tag_list_proc), tag.c - (tag_fileproc): Call RCS_nodeisbranch not RCS_isbranch - in contexts where we know the RCS argument is non-NULL. - - * commit.c (find_fileproc): Pass tag not NULL to Version_TS for - the tag. - * vers_ts.c (Version_TS): Improve (somewhat) the introductory - comment. - * sanity.sh (editor): New test editor-9 tests for above fix. - Renumber/tweak surrounding tests to fit. - - * log.c (log_version): If p->data is NULL, it is an empty log - message. - * sanity.sh (rcs-14): New test, tests for above fix (previously - this was a coredump). - -Thu Sep 18 08:45:05 1997 Jim Kingdon - - * sanity.sh (rcs-7): Fix stupid ${TESTDIR} omission. - -Wed Sep 17 16:27:41 1997 Jim Kingdon - - * sanity.sh (rcs): New tests rcs-5 through rcs-13 test for - getdate.y fix (rcs-12 and rcs-13 both failed with the buggy - getdate.y). - -Tue Sep 16 00:07:17 1997 Jim Kingdon - - * sanity.sh (editor): Clean up first-dir at end of test. - - * sanity.sh (editor): New tests test do_editor. - - * commit.c (commit): For the client, if we got the log message - from do_editor and there was an error, don't toss the message. - -Mon Sep 15 14:27:54 1997 martin.sjoelin@ubs.com - and Jim Kingdon - - * rcs.c (RCS_checkout): fwrite in bite-size pieces, not the whole - file in one fwrite. - -Sun Sep 14 12:23:15 1997 Jim Kingdon - - * commit.c (check_fileproc): If the file has "conflict - indicators", spit a warning and proceed with the checkin. - * sanity.sh (conflicts): Adjust tests conflicts-132, - conflicts-status-3, conflicts-133, and conflicts-status-4 - for new behavior. - -Fri Sep 12 11:12:34 1997 Jim Kingdon - - * add.c, admin.c, checkin.c, checkout.c, classify.c, commit.c, - create_adm.c, cvsrc.c, diff.c, entries.c, find_names.c, hash.c, - import.c, lock.c, log.c, logmsg.c, main.c, modules.c, myndbm.c, - no_diff.c, parseinfo.c, patch.c, rcs.c, rcscmds.c, recurse.c, - remove.c, repos.c, root.c, rtag.c, status.c, subr.c, tag.c, - update.c, vers_ts.c, hash.h, rcs.h, options.h.in: Change "CVS 1.4 - kit" to "CVS source distribution". - - * sanity.sh: Comment out call to "whoami". - -Thu Sep 11 10:09:04 1997 Jim Kingdon - - * commit.c (classify_file_internal): Add comment about saving - quiet vs. saving really_quiet. - - * sanity.sh (newb-123j0): Use two regexps instead of assuming that - expr has "\(", "\|", and "\)". If we want to require the latter, - we should check for it up front, rather than let people get - halfway through and wonder why the test failed. - -Tue Sep 9 19:22:44 1997 Jim Kingdon - - * expand_path.c (expand_path): If GETPWNAM_MISSING is defined, - just give an error instead of calling getpwnam. - - * subr.c (getcaller): If SYSTEM_GETCALLER is defined, call it - instead of all the getlogin/getpwuid/etc. - * wrapper.c (wrap_setup): Call get_homedir not getpwuid. - -Mon Sep 8 17:54:14 1997 Jim Kingdon - - * sanity.sh (basicc): Change ls -1 to echo *; according to - larry.jones@sdrc.com, ls -1 isn't portable. - -Sun Sep 7 07:45:35 1997 Jim Kingdon - - * sanity.sh (basic2): In test basic2-64, match usernames with - ${username}. - - * root.c: Reindent a few things. - * root.c, cvs.h (same_directories): Remove. Never used, - portability hassle. - - * add.c (add_directory): When checking for CVSADM, call fncmp not - strcmp. I actually suspect this code doesn't do much these days, - but fncmp clearly will make more sense than strcmp. - - * rtag.c (rtag_usage), tag.c (tag_usage): Reword to hopefully be - clearer that -r takes either numeric or symbolic revision. - - * ignore.c (ign_dir_add, ignore_directory): Reindent. Tweaks to - comments. - - * update.c (checkout_file): Only ignore existence_error from - unlink_file_dir, not all errors. - - * checkout.c (safe_location): Check for errors from xgetwd. - * create_adm.c (Create_Admin): Remove call to xgetwd; it is just - debugging code anyway and it wasn't checking for errors. - - * sanity.sh: Add comment about default value for TESTDIR. - - * server.c (serve_log): Change "cvslog" to "log". This - (accidental, I presume) error had made it impossible for anonymous - users to run "cvs log". - - * classify.c (sticky_ck): Change to take an finfo argument rather - than several arguments taken from there. Cleans up the way the - calling convention had depended on SERVER_SUPPORT. - (Classify_File): Change callers. - - * version.c: Change version number to 1.9.17. - - * Version 1.9.16. - - * recurse.c (do_dir_proc): In combining repository and dir, omit - trailing "/." from repository. - * sanity.sh (modules3): Adjust test modules3-4 so we test for - this fix (this is not just cosmetic; the bug prevented the - "Rebuilding administrative file database" from happening). - modules2 already tests the "co CVSROOT/modules" usage. - - * checkout.c (checkout_proc): When building top-level CVSADM - directory, continue the process of walking up the repository one - more level, rather than putting in the same repository as for the - first-level directory. - * sanity.sh: Adjust tests basicb-1b, basicb-9b, modules3-7f, - toplevel-9, and toplevel-11 to test for this fix. - - (For reference, this takes CVS's text segment from 344460 to - 344140 bytes. I know, this may seem unimportant, but it is so - unusual for programs to shrink and I think it is so cool when they - do without losing functionality/clarity/etc). - * checkout.c, cvs.h (emptydir_name): New function. - * checkout.c (checkout, checkout_proc), modules.c (do_module): - Call it instead of duplicating the code to do that. - - * sanity.sh (basicc): Clean up first-dir at end of test. - -Sat Sep 6 09:48:39 1997 Jim Kingdon - - * sanity.sh (join): Fix cut and paste error in join-28 - (/home/kingdon/... -> ${TESTDIR}). - - * recurse.c (start_recursion): If there is no CVSADM and no - subdirectories, give an error. - * sanity.sh (basicc): New tests, test for this fix. - - * sanity.sh (join): New tests join-25 through join-29 test merging - from one branch to a different branch. - - * release.c: In comment about CVSROOTADM_IGNORE, also mention - comment just added to entries.c. - * entries.c: Expand this comment, especially the part about - CVS/Template. - - Keep track of what revisions CVS/Base correspond to: - * cvs.h (CVSADM_BASEREV, CVSADM_BASEREVTMP): Added. - * entries.c, cvs.h (base_register, base_deregister, base_get, - base_walk): New functions. - * edit.c (edit_fileproc): Call base_register when setting up CVS/Base. - (unedit_fileproc): When taking a file out of CVS/Base, put its - revision back into entries, and base_deregister it. - * sanity.sh (watch4): New tests watch4-10 through watch4-18 test - for above fix. - -Fri Sep 5 09:14:10 1997 Jim Kingdon - - * client.c: Only declare start_rsh_server if we are going to - define it (!NO_EXT_METHOD). - - * subr.c, cvs.h (check_numeric): New function. - * admin.c (admin): Call it. - * sanity.sh (admin): New tests admin-10a and admin-10b test for fix. - -Thu Sep 4 15:55:39 1997 Jim Kingdon - - * sanity.sh (binwrap2): New tests, test for the ability to specify - all files are binary except certain patterns. - - * sanity.sh (modules3): New tests modules3-16 and modules3-17 test - for another behavior involving '/' in a module name. - -Sun Aug 31 12:03:15 1997 Jim Kingdon - - * add.c (add): Remove checks for '/' in pathnames. - (add): Move code which handles entries and repository inside loop, - since these now might be different for each argument. Add code to - set finfo.update_dir, finfo.file, and finfo.fullname appropriately - even if pathname contains '/'. Replace user variable with - finfo.file or finfo.fullname, depending on which is meant. chdir - into update_dir for each argument. Likewise for the client code - which creates directories. - (add_directory): Replace arguments with a single finfo argument. - Replace dir with finfo->fullname as needed. - (add): Update call to add_directory. - * client.c, client.h (send_a_repository): No longer static. - * sanity.sh (errmsg2): Adjust tests to test for '/' in pathname. - - * sanity.sh (errmsg2): New tests errmsg2-13 through errmsg2-16 - test the status quo with respect to '/' in cvs add argument. - -Sat Aug 30 17:37:29 1997 Jim Kingdon - - * run.c (run_popen): Add comment on return value. - * release.c (release): Check for NULL return from popen. - -Fri Aug 29 17:49:20 1997 Jim Kingdon - - * client.c (get_server_responses): Add comment about "ok^M". - -Thu Aug 28 13:35:12 1997 Jim Kingdon - - * edit.c (edit_fileproc): If file doesn't exist, give an error. - * sanity.sh (devcom2): Tests devcom2-12 through devcom2-17 test - for above fix. - -Tue Aug 26 16:42:28 1997 Jim Kingdon - - * subr.c (xmalloc): Reword error message to clarify that memory, - not disk space or some other resource, is in question. - -Tue Aug 26 01:04:48 1997 Steve Ralston - and Jim Kingdon - - * add.c (add_directory): In allocating message, also allocate - enough for tag and date related text. - -Tue Aug 26 01:04:48 1997 Jim Kingdon - - * update.c (update_dirent_proc): Use update_dir not dir in "new - directory" message. - * find_names.c (find_dirs): Skip CVSNULLREPOS. - (Find_Directories): Add comment about find_dirs skipping CVSATTIC - and CVSLCK in working directories. - * sanity.sh (basicb): New tests basicb-edir-* test for find_dirs - fix. Change other tests to test that Emptydir is not special in - non-CVSNULLREPOS contexts. - -Sun Aug 17 14:44:57 1997 Jim Kingdon - - * import.c (add_rcs_file): Add comment about -k overriding wrappers. - -Sat Aug 16 18:09:05 1997 Martin Sjoelin - and Jim Kingdon - - * import.c (add_rcs_file): Before opening the input file - when importing, if options is binary, open the file in - binary mode. - -1997-08-16 enami tsugutomo - - * sanity.sh (mcopy): Unset CVSWRAPPERS last of all. - -Fri Aug 15 11:11:44 1997 Jim Kingdon - - * add.c (add_directory): Copy default file attributes from the - parent directory to the directory we are creating. - * fileattr.h, fileattr.c (fileattr_getall, fileattr_setall): - New functions, in support of above. - * fileattr.c (fileattr_free): Add comment about fileattr_write - maybe not clearing attrs_modified. - * sanity.sh (watch4): New test, tests for above fix. - -Thu Aug 14 11:08:40 1997 Jim Kingdon - - * update.c (merge_file, join_file): If wrap_merge_is_copy, treat - files as nonmergeable (as we had been treating binary files). - (join_file, update_fileproc): Remove previous wrap_merge_is_copy - cruft. - * sanity.sh (mcopy): New tests, test for above fix. - (binfiles2): New tests binfiles2-9a-* correct an oversight. - (binfiles, binfiles2): Adjust to reflect wording change from - "binary file" to "nonmergeable file". - (mwrap): Adjust tests mwrap-8 through mwrap-10 for new behavior. - - * main.c (main): Reword copyright notices to include the latest - year, to refer to "other authors" in addition to the ones listed, - and to be more concisely formatted. - -Wed Aug 13 13:50:00 1997 Larry Jones - - * sanity.sh: Replace hard-coded directory with ${TESTDIR}, add - join3 to default tests - -Wed Aug 13 11:42:24 1997 Jim Kingdon - - * rcscmds.c: Adjust comment to reflect progress on removing RCS - execs outside this file. - -Mon Aug 11 10:14:47 1997 Jim Kingdon - - * vers_ts.c (Version_TS): If vers_ts->vn_rcs == NULL, skip setting - modification time in server case as well as local case. - * server.c (server_modtime): Add assertion to clarify that caller - must assure that vers_ts->vn_rcs != NULL. - * sanity.sh (join3): Add file "file2" to test for above fix. - - * modules.c (save_d): When parsing -s option, don't assume that - we will hit a space before we hit the '\0'. - (struct sortrec): Document allocation policies (status quo except - status field is now malloc'd). - (cat_module): No longer need to set the '\0' at the end of the - status field back to ' ', as it no longer shares storage with the - rest field. - * sanity.sh (modules): Add "statusmod" to test for above fix. - -Sun Aug 10 12:18:31 1997 Jim Kingdon - - * sanity.sh: Remove TODO item about more keyword expansion tests. - The keyword test and others cover it pretty well, and such an item - isn't useful unless it is specific. - - * sanity.sh (importb): New tests test "cvs import -b". - - * mkmodules.c: Update comment with more reasons why having - CVSROOT/passwd be a regular administrative file would be a Bad - Idea. - - * server.c (switch_to_user): Add comment about checking for errors - from setuid and friends. - -Wed Aug 6 13:48:29 1997 Jim Kingdon - - * main.c (main): Add comment about errors writing CVS/Root in - need_to_create_root code. - -Tue Aug 5 22:05:20 1997 Jim Kingdon - - * entries.c (write_entries): If trouble writing Entries.Backup, - make it a warning not an error. - -Wed Jul 30 08:42:04 1997 Jim Kingdon - - * parseinfo.c (parse_config): If AUTH_SERVER_SUPPORT is not - defined, don't set system_auth. - - * version.c: Change version number to 1.9.15. - - * Version 1.9.14. - - * create_adm.c, cvs.h (Create_Admin): If new argument WARN is set, - then make creating the CVS directory itself a warning not a fatal - error. New return value indicates whether we did this. - * checkout.c (build_one_dir), client.c (call_in_directory): - Pass WARN as one. - * add.c, client.c, checkout.c, modules.c, update.c: Pass WARN as - zero for all other Create_Admin callers. - * sanity.sh (toplevel): New test toplevel-12 tests for this fix. - * filesubr.c (mkdir_if_needed): Also check EACCES/isdir. Needed - to make toplevel-12 test work. - - * sanity.sh (toplevel): New test toplevel-11 and friends test for - another variation of the toplevel-9 bug. - -Tue Jul 29 12:11:16 1997 Jim Kingdon - - * login.c (construct_cvspass_filename): Revert this change. The - main reason is procedural; Karl is not a current CVS developer. - The other thing is that the new text doesn't say anything about - HOMEDRIVE and HOMEPATH. - -Tue Jul 29 11:36:22 1997 Karl Fogel - - * login.c (construct_cvspass_filename): error message informs user - she may need to set HOME environment variable by hand. - -Sun Jul 27 15:36:44 1997 Jim Kingdon - - * admin.c (admin): Remove comment "XXX send -ko too with i = 0". - It turns out to be a description of a bugfix which was applied on - 8 Oct 1995, and never should have been in a comment in the first - place. - - * admin.c (admin, admin_fileproc): Parse options ourself rather - than blindly passing them to RCS. - Accordingly, add struct admin_data and function arg_add, and delete - global variables ac and av. - * sanity.sh (admin): Change admin-3 test to reflect cvs admin -i - now being an error. - (basicb): Change basicb-21 test to relect the improved error - message here. - -Sat Jul 26 11:34:51 1997 Jim Kingdon - - * sanity.sh (join3): New tests, test a new branch topology and - greatest common ancestor. - -Fri Jul 25 09:51:49 1997 Jim Kingdon - - * server.c (serve_directory): Repository must start with - CVSroot_directory rather than some random pathname. - - * remove.c (remove_fileproc): If there is a numeric sticky tag, - don't allow the remove. - * commit.c (check_fileproc): Add comment about this case. - * sanity.sh (sticky): New tests sticky-15 through sticky-23 - test for this behavior and the analogous behavior with - non-branch sticky tags (which is unchanged). - - * client.c (update_entries): Clear the stored mode, modtime, and - checksum even on an error. - * sanity.sh (contents2-142d*): Also test cvs status. Also test - the case in which the contents of the file are unchanged. Also - test running diff to see the conflict, and resolving the conflict. - Without the fix above, the new contents2-142d2 test would get a - "duplicate Mod-time" warning. - -Thu Jul 24 13:29:15 1997 Jim Kingdon - - * server.c (pserver_authenticate_connection): Call parse_config - here too. - * parseinfo.c (parse_config): If we are called several times, the - times beyond the first do nothing. - * cvs.h, parseinfo.c (parse_config): New argument cvsroot. - * server.c, main.c: Update callers. - * server.c, server.h (system_auth): New variable. - * parseinfo.c (parse_config): Parse new keyword SystemAuth. - * mkmodules.c (config_contents): Add comments for SystemAuth. - * server.c (check_password): If !system_auth, then skip the check - for a system username/password. - - * main.c (main): No fatal error if parse_config returned an error. - * server.c (serve_root): Likewise. - * error.c (error): Add comment about calling from the server. - * parseinfo.c, cvs.h (parse_config): Remove NOERR crock. - Closer reading of server.c makes it seem like calling error - here is OK after all. - * sanity.sh (config): New test, tests for above fix. - - * server.c (serve_root): Fix typo ("doign" -> "doing"). - -Wed Jul 23 13:55:09 1997 Jim Kingdon - - * vers_ts.c (Version_TS): If entdata is for a directory, don't set - vn_user and friends. - * server.c (dirswitch): Add comment about why Subdir_Register is - sometimes a noop here. - * cvs.h (struct vers_ts): Fix comments about NULL vs. "" in vn_user. - * sanity.sh (errmsg2): New tests errmsg2-10 through errmsg2-12 test - for above fix. - * add.c (add_directory): Call cvs_output not printf. This fixes - an out-of-order bug which was showing up in the testcase. - -21 Jul 1997 Jim Kingdon - - * subr.c (get_file): Put st_size into an unsigned variable to - avoid signed/unsigned warnings. - -Mon Jul 21 00:19:30 1997 Jim Kingdon - - * version.c: Change version number to 1.9.13. - - * Version 1.9.12. - - * sanity.sh (toplevel, head): Delete our files from the repository - when done with them. - -Sun Jul 20 15:53:08 1997 Jim Kingdon - - * sanity.sh (admin, reserved): New tests, test most cvs admin - behaviors. - (log2): New tests log2-5 through log2-10 test setting the - description via cvs admin. - -Thu Jul 17 12:39:27 1997 Jim Kingdon - - * client.c (socket_buffer_input, socket_buffer_output): Add - comment regarding size of of buffer we pass to send and recv. - -Sat Jul 12 15:21:24 1997 Jim Kingdon - - * import.c, rcs.h (add_rcs_file): New argument key_opt replaces - access to global variable keyword_opt. New arguments desctext and - desclen allow one to set the description. If add_vhead is NULL, - then omit a revision, like rcs -i. - * import.c (process_import_file), mkmodules.c (init): Change - callers. - * subr.c, cvs.h (get_file): New function, adapted from code in - update_entries. - * client.c (update_entries): Call it. - * commit.c (checkaddfile): Create new RCS files with add_rcs_file - rather than rcs -i. - -Fri Jul 11 12:14:54 1997 Jim Kingdon - - * update.c (join_file): Handle binary files ourself rather than - passing them to RCS_merge (which sort of tries to handle binary - files, but does so badly). - * sanity.sh (binfile2): New "brmod", "brmod-trmod", and - "brmod-wdmod" tests test for this fix. - - * add.c (add): Exit status is now nonzero if any of the arguments - failed (already was mostly true, make it true for the new sanity - check). Move check for '/' (now ISDIRSEP) up to sanity check, so - the client does it too. - * sanity.sh (errmsg2): Test for this fix. - -Thu Jul 10 00:02:54 1997 Jim Kingdon - - * add.c (add): Check for CVSADM, ".", and "..", and skip any - attempt to add them. - * sanity.sh (errmsg2): New tests, tests for above fix. - - * main.c (main): In text printed upon --version, also refer - people to --help. - - * rcscmds.c (RCS_exec_rcsdiff): Add comment about timezones. - - * server.c, cvs.h (cvs_output_binary): New function. - * rcs.c (RCS_checkout): For a binary file, call cvs_output_binary - rather than cvs_output. - * client.c (handle_mbinary): New function. - (responses): Add "Mbinary". - -Tue Jul 8 12:18:16 1997 Jim Kingdon - - * filesubr.c (get_homedir): Add comment about root vs. user - directory in pserver server. - -Mon Jul 7 14:39:33 1997 Jim Kingdon - - * sanity.sh (big): Also test Rcs-diff case. - - * client.c (update_entries): Reindent a line. - - * sanity.sh (death2): Add comment about Sun diff. Thanks to - Warren Jones for reporting this. - - * client.c (update_entries): If DONT_USE_PATCH, then just treat a - Patched response as an indication to try again with complete files. - * update.c (update): Remove DONT_USE_PATCH ifdefs, since a CVS - with DONT_USE_PATCH defined can still handle Rcs-diff. - * sanity.sh (serverpatch): Add comment about this coming up in - real life if the user modifies the file while CVS is running. - - * client.c (start_server): Add comment about logfiles if there are - several connections to the server. - (log_buffer_shutdown): Close the logfile after shutting down the - underlying buffer. This way at least we get the last set of - logfiles rather than a bizarre mishmash. - -1997-07-06 enami tsugutomo - - * logmsg.c (do_verify): Unlink temporary file before call error(). - Remove unneeded `return' statement. Fix comment. - -Sun Jul 6 13:36:32 1997 Jim Kingdon - - * diff.c (diff_fileproc): Change message from "during rcsdiff of" - to "while diffing". For a while now, that message might be - printed after a call to DIFF instead of rcsdiff. - - * diff.c (diff_fileproc): Call cvs_output not printf. Remove - calls to fflush (should be handled now by call to cvs_outflush in - recurse.c). - * patch.c (patch_fileproc): Likewise. - - * rcscmds.c, cvs.h (diff_exec): New function. - * diff.c (diff_fileproc), patch.c (patch_fileproc), - update.c (patch_file): Call it. - - * rcscmds.c: Adjust comments concerning diff library to point to - new, expanded comments at diff_exec. Remove comments concerning - patch library; Rcs-diff should be adequate. - - * client.c (update_entries): Add comment about GNU patch usage (-b - option and so on). - -Sat Jul 5 04:13:28 1997 Jim Kingdon - - * rcscmds.c, cvs.h (RCS_exec_rcsdiff): New function. - * diff.c (diff_fileproc): Call it. - -Thu Jul 3 09:50:07 1997 Jim Kingdon - - * main.c (main): Add comment about how long we should keep the - deprecated "cvs rlog" alias. - - * server.c (cvs_output): Add comment about whether to fflush. - -Wed Jul 2 18:57:29 1997 Jim Kingdon - - * sanity.sh (join2): New tests join2-19 and friends test for a - case that we can't readily get right (see comments). - -Tue Jul 1 09:52:09 1997 Jim Kingdon - - * main.c (cmd_usage): Say "specify" --help rather than the vague - "use". - (opt_usage, cmd_synonyms): Mention --help here too. - * add.c, admin.c, checkout.c, commit.c, diff.c, edit.c, import.c, - log.c, login.c, mkmodules.c, patch.c, rcs.c, release.c, remove.c, - rtag.c, status.c, tag.c, update.c, watch.c: Likewise, for all the - other help messages. - - * sanity.sh (join2): New tests. - - * repos.c (Name_Repository): Check for errors from fclose. - -Fri Jun 27 10:27:48 1997 Jim Kingdon - - * scramble.c, login.c: Reindent. - - * client.c (connect_to_pserver): Check for errors from send(). - If socket() fails, include SOCK_STRERROR (SOCK_ERRNO) in message. - -Wed Jun 25 11:21:52 1997 Jim Kingdon - - * main.c: New option --help-options, with much of the text - from --help. Fix a few capitalization and punctuation problems. - Rewrite text for --help to be an intro to all the --help-* - options. - - * sanity.sh (head): New tests, concerning meaning of HEAD. - -Tue Jun 24 10:14:18 1997 Jim Kingdon - - * client.c (recv_line): New function. - (connect_to_pserver): Call it, and rewrite accordingly. Also - accept new "E" and "error" responses. Change \n to \012. - * server.c (pserver_authenticate_connection): Adjust comment - accordingly, concerning sending I HATE YOU not "error". - -Sun, 22 Jun 1997 Jim Kingdon - - * main.c (main): Move setting of server_active inside #ifdef - SERVER_SUPPORT; otherwise the variable doesn't exist. - * main.c (main): Call return after exit to shut up warning. - -Fri Jun 20 22:56:34 1997 Jim Kingdon - - * client.c (connect_to_pserver): On "I HATE YOU", give - "authorization failed" fatal error regardless of verify_only. - * login.c (login): Don't print that "incorrect password" message; - it now is possible with an --allow-root failure as well as an - incorrect password. cvsclient.texi doesn't really specify what I - HATE YOU means in any detail, and it seems a little silly for - login to give different messages than the other commands. - * client.c, client.h (connect_to_pserver): Return type now void. - -Thu Jun 19 12:16:10 1997 Jim Kingdon - - * server.c (serve_root): Give error on duplicate Root request. - Call parse_config. - * parseinfo.c, cvs.h (parse_config): New function. - * cvs.h (CVSROOTADM_CONFIG): Added. - * main.c (main): Set server_active here... - * server.c (server): ...not here. That seems cleaner than - strcmp's between command_name and "server" in main.c. - * main.c (main): Call parse_config. - * main.c, cvs.h (free_Rcsbin): Make global. - * mkmodules.c (filelist): Add CVSROOTADM_CONFIG. - -Wed Jun 18 11:24:31 1997 Jim Kingdon - - * version.c: Change version number to 1.9.11. - - * Version 1.9.10. - -Tue Jun 17 22:48:00 1997 Jim Kingdon - - * main.c (main): Add --allow-root=ROOT argument; call - root_allow_add for each time it is specified. Call - root_allow_free before exiting. - * root.c, cvs.h (root_allow_add, root_allow_free, root_allow_ok): - New function. - * server.c (pserver_authenticate_connection): If root_allow_ok - doesn't like the CVSROOT directory, don't allow access. - -Tue Jun 17 14:30:14 1997 Jim Kingdon (unknown@beezley) - - * client.c: Add "copyright" notice. If NO_EXT_METHOD, omit - start_rsh_method. - * client.c (update_entries): Cast argument to MD5Update from - char * to unsigned char *. - -Mon Jun 16 16:46:28 1997 Jim Kingdon - - * run.c (piped_child, filter_stream_through_program): - If USE_SETMODE_BINARY, then put the pipes into binary mode. - * find_names.c, ignore.c, lock.c, wrapper.c: Change fnmatch to - CVS_FNMATCH. - * client.c (start_server): If NO_EXT_METHOD, then give a fatal - error on any use of :ext:. - -Sun Jun 15 22:30:27 1997 Jim Kingdon - - * sanity.sh (toplevel): Match U CVSROOT/* lines with DOTSTAR in - test toplevel-9. - -Thu Jun 12 10:27:51 1997 Jim Kingdon - - * sanity.sh (toplevel): Remove Emptydir before starting. - - * sanity.sh: Change "rm -rf" to "rm -r" when deleting working - directories (except a few watches cases). Helps detect cases - where the testsuite has cd'd to somewhere other than where we - think it has. - (basic2): Remove "rm -r first-dir" between tests 49 and 50. The - directory was already deleted in test 45.5. - (rcs): Add "cd .." at end of tests. - (stamps): No longer cd to TESTDIR; shouldn't be necessary with - fix to "rcs" test. - -Wed Jun 11 22:28:38 1997 Jim Kingdon - - * sanity.sh (basicb): Also remove CVSROOT/Emptydir at end of - test. Otherwise it affects the toplevel-9 test for remote. - -Tue Jun 10 14:03:32 1997 Jim Kingdon - - * sanity.sh (toplevel): Change "update" and "checkout" to "[a-z]*" - as these read "server" instead for "make remotecheck". Change - expect strings for toplevel-9 to accept the behavior of remote CVS - (see comments for more discussion). - - * sanity.sh: New tests stamps-9 through stamps-11 test timestamp - behavior on cvs update. - -Mon Jun 9 22:42:50 1997 Jim Kingdon - - * sanity.sh: Remove "#! /bin/zsh" line at end. I assume it was - added accidentally. - -Tue Jun 10 03:08:46 1997 Norbert Kiesel - - * sanity.sh: new tests "toplevel" for the new toplevel CVS - directory creation (including one test which shows an error in - this area). - -Sun Jun 8 20:52:00 1997 Jim Kingdon - - * rcs.c (getrcsrev): Before printing error, check whether it was - feof or ferror. - - * rcs.h, import.c (add_rcs_file): No longer static. New arguments - add_vbranch, add_vhead, and add_logfp replace access to static - variables vbranch, vhead, and logfp. - * mkmodules.c: Call it instead of RCS_CI. - * import.c (process_import_file): Adjust call to add_rcs_file. - -Tue Jun 3 10:18:33 1997 Jim Kingdon - - * sanity.sh (basicb): Match "." with "\." not ".". - -Tue Jun 3 13:02:37 1997 Norbert Kiesel - - * checkout.c (checkout): Removed restriction of not sending -k in - remote export (I think this was introduced while the -k handling - was still broken in remote mode). Give better error texts - regarding -c and -s options. Use error() instead of usage() for - reporting errors in all places. Reindented some lines. Free - xmalloc'd space of options. - -Thu May 29 16:32:47 1997 Jim Kingdon - - * rcscmds.c (RCS_checkin), mkmodules.c (init): Pass -w option to - "ci", specifying getcaller (). - * server.h, server.c (CVS_Username): Now extern. - * subr.c (getcaller): Return CVS_Username if it is set. - -Wed May 28 22:31:38 1997 Jim Kingdon - - * update.c (update_fileproc): If wrap_merge_is_copy and we would - like to do a merge, give a fatal error. See comment for why. - * sanity.sh (mwrap): New tests, tests for above fix. - -Tue May 27 21:59:32 1997 Jim Kingdon - - * sanity.sh (stamps): cd to ${TESTDIR} before starting. - -Mon May 26 15:31:30 1997 Jim Kingdon - - * client.c (handle_mod_time): New function. - (responses): Add "Mod-time". - (stored_modtime_valid, stored_modtime): New variables. - (update_entries): If it is set, change the file's modtime. - * server.c, server.h (server_modtime): New function. - * vers_ts.c (Version_TS): Call it. - * patch.c (patch_fileproc): Add comment about why we don't. - * sanity.sh (stamps): Added, tests for above fix. - -Fri May 16 13:14:30 1997 Jim Kingdon - - * subr.c (free_names): Update documentation to reflect fact that - free_names is now called to free vectors allocated by expand_wild - as well as by line2argv. - - * main.c (main): Use "xstrdup (foo)" not "xstrdup(foo)" as - specified in HACKING. - -Fri May 16 15:10:37 1997 Norbert Kiesel - - * modules.c (do_module): initialize optind to 0. use local copies - of optarg's (because they might me freed within free_names). - -Thu May 15 11:50:15 1997 Norbert Kiesel - - * main.c (main): initialize optind to 0. use local copies of - optarg's (because they might me freed within read_cvsrc). - - * cvsrc.c (read_cvsrc): free old argv after constructing a new - one. This fixes a memory leak. - - * recurse.c (start_recursion): use free_names() instead of - reimplementing it - - * rcs.c (RCS_deltas): free branchversion (memory leak). - - * parseinfo.c (Parse_Info): free some vars (3 memory leaks). - - * logmsg.c (logfile_write): free str_list_format (memory leak). - - * watch.c (watch_addremove), (watchers), update.c (update), tag.c - (cvstag), status.c (status), rtag.c (rtag), remove.c (cvsremove), - release.c (release), patch.c (patch), log.c (cvslog), import.c - (import), history.c (history), edit.c (watch_onoff), (edit), - (unedit), (editors), diff.c (diff), commit.c (commit), checkout.c - (checkout), add.c (add): initialize optind to 0 - - * diff.c (diff_fileproc): cosmetic change (whitespace added). - - * checkout.c (checkout): move local variable definition into the - block where the variable is used. - - * client.c (update_entries): initialize some local variables to shut up - gcc -O -Wall. - - * buffer.c (buf_read_line): initialize a local variable to shut up - gcc -O -Wall. - - -Wed May 14 16:29:50 1997 Jim Kingdon - - * admin.c (admin): When sending options to server, don't try to - send av[ac]. It may contain one of the names that we'll send in - send_file_names (which caused tests like keyword-6 to work, - sort of accidentally), or it may contain NULL (which would tend to - cause a coredump). - * sanity.sh (basicb): New test basicb-21 tests for above fix. - -Mon May 12 16:22:00 1997 Larry Jones - - * add.c (add): Free message and repository in client code. - * checkout.c (checkout): Don't free repository unless allocated. - * client.c (start_rsh_server): Free command. - -Sun May 11 11:43:54 1997 Jim Kingdon - - * client.c: Remove all references to USE_DIRECT_TCP; see - ../ChangeLog for rationale. - -Fri May 9 22:19:36 1997 Jim Kingdon - - * main.c (main): Add comment explaining why we call exit. Pass 0 - not EXIT_SUCCESS, because lib/system.h has portability cruft for - EXIT_FAILURE but not EXIT_SUCCESS. - -Fri May 9 17:25:00 1997 Larry Jones - - Fix miscellaneous memory allocation problems: - * add.c (add): Free repository. - * client.c (notified_a_file): Free getline buffer. - * edit.c (notify_check): Free getline buffer. - * hash.c (dellist): Free header node when not caching. - * login.c (login): Don't continually free & allocate getline - buffer, use xstrdup instead of xmalloc/strcpy, free getline - buffer before returning. - * main.c (main): Call exit instead of returning so tools like - Purify won't consider permanently allocated memory as leaks. - * mkmodules.c (mkmodules): Free getline buffer. - * modules.c (cat_module): Call close_module. - * rcs.c (rcsvers_delproc): Free state. - * recurse.c (start_recursion): Free files_by_dir. - (unroll_files_proc): NULL out p->data after using it to set - filelist to avoid multiple frees. - * server.c (check_command_legal_p): Don't continually free & - allocate getline buffer, free getline buffer before returning. - (check_repository_password): Ditto, use xstrdup instead of - xmalloc/strcpy. - * wrapper.c (wrap_add_file): Free getline buffer. - -Thu May 8 14:21:00 1997 Larry Jones - and Jim Kingdon - - * checkout.c (checkout_proc): Free finfo.rcs (memory leak). - -8 May 1997 Larry Jones - and Jim Kingdon - - * hash.c: Add #ifdef's to disable caching. This makes it easier - to track down memory allocation problems. - -Thu May 8 11:40:39 1997 Larry Jones - - * sanity.sh: In setting "tests" use a number of statements rather - than one very long line. - -Thu May 8 11:40:39 1997 Jim Kingdon - - * cvsbug.sh: Remove $Id; we decided to get rid of these some time - ago. - -Thu May 8 11:34:02 1997 Larry Jones - - * cvsbug.sh: Put separate statements on separate lines, so it - works if awk is AT&T nawk. - -Tue May 6 16:56:00 1997 Larry Jones - and Jim Kingdon - - * cvsrc.c (read_cvsrc): Fix various memory allocation problems: - rearrange code to avoid leaks, use xrealloc instead of xmalloc/ - copy/free, make sure there's room for the remaining args before - appending them. - -Tue May 6 14:20:00 1997 Larry Jones - - * edit.c (watch_onoff, edit, unedit, editors): Add -R like - other things with -l. - * watch.c (watch_addremove, watchers): Ditto. - -Mon May 5 18:10:37 1997 larry.jones@sdrc.com - and Jim Kingdon - - * sanity.sh: Change all /tmp/cvs-sanity to TESTDIR. If TESTDIR - environment variable is set, use it instead of /tmp/cvs-sanity. - * sanity.sh: Make TMPPWD the pwd equivalent of TESTDIR, not of /tmp. - -4 May 1997 Larry jones - and Jim Kingdon - - * checkout.c, diff.c, patch.c, rcs.c: Update usage messages. - * rcs.c (annotate): Add -R like other things with -l. - -Sat May 3 14:57:40 1997 Jim Kingdon - - * sanity.sh (basic1): Rewrite test (use dotest, unroll the loops - which IMHO makes the test a zillion times more understandable, and - only do the variant which tests for 4 files at a time--we test one - file at a time lots of places). - -2 May 1997 Ziv Gigus - and Jim Kingdon - - * client.c, client.h (client_process_import_file): New argument - all_files_binary means treat all files as binary. - * import.c (import_descend): Pass it if -kb is specified. - * client.c (client_process_import_file): In the - non-all_files_binary case, call wrap_rcsoption to determine - whether the file is binary. - -Thu May 1 13:44:51 1997 Jim Kingdon - - * sanity.sh (binfiles2): New tests, for update -j and binary files. - -Wed Apr 30 11:18:36 1997 Jim Kingdon - - * recurse.c (start_recursion): Also free reposfile. - Don't look in repository if client_active (latter bug reported by Paul - Sanders ). - -Mon Apr 28 22:36:39 1997 Jim Kingdon - - * diff.c (diff_file_nodiff): Remove SERVER_SUPPORT ifdefs. They - were not based on server_active, which doesn't really make any - sense (it meant that compiling --disable-server could affect the - behavior of the non-client/server CVS). This affected the output - in tests death2-diff-11 and death2-diff-12 in the testsuite. - * sanity.sh (newb-123j0): Also accept "Needs Checkout", for a - --disable-server CVS. - - * main.c (cmd_usage): Change "run diffs" to "show differences"; - the former is jargon. - * edit.c (edit_usage): Fix typo ("." -> ","). - * edit.c (editors_usage), watch.c (watchers_usage): Mention -l. - * checkout.c (export_usage): Say what -P does. - * history.c (history_usg): Add comment about message wording. - -Mon Apr 28 14:47:45 1997 Norbert Kiesel - - * checkin.c (Checkin): use filename without path when calling - wrapper (bug found by Michal Schmitz ). - -Fri Apr 25 13:28:55 1997 Ian Lance Taylor - - * client.c (update_entries): In UPDATE_ENTRIES_RCS_DIFF case, - write to a temporary file and then rename it. - -Thu Apr 24 11:35:40 1997 Jim Kingdon - - * subr.c, cvs.h (pathname_levels): New function, from a piece of - send_file_names. - * client.c (send_file_names): Call pathname_levels in place of the - code which was moved there. - * server.c, server.h (server_pathname_check): New function. - * recurse.c (start_recursion): Call it. - * sanity.sh (modules3): New test modules3-11b tests for above fix. - - * filesubr.c: Do not define L_tmpnam. It is in ANSI and SunOS4, - so I don't think there will be a problem with it being missing. - Defining it too small can cause memory corruption. - (cvs_temp_name): Do not use L_tmpnam in the mktemp code; this - could cause a buffer overflow if the -T global option was in use. - -Thu Apr 24 13:21:15 1997 Norbert Kiesel - - * filesubr.c (cvs_temp_name): Use tempnam if available, else - mktemp, else tmpnam. See the comment for rationale. - - * sanity.sh: use "tar cf - ." instead of "tar cf - *" for - directory copies. - -Wed Apr 23 23:41:47 1997 Jim Kingdon - - * server.c (serve_update_prog): If in readonly mode, give an error. - -Wed Apr 23 19:07:41 1997 Norbert Kiesel - - * subr.c (line2argv): Allocate at least 4 slots for argv. - - * checkout.c (checkout_proc): Add a comment which says why the - above change was necessary to avoid writing to unallocated memory. - -Wed Apr 23 11:20:40 1997 Jim Kingdon - - * entries.c (ParseTag): Always set *NONBRANCHP. - -21 Apr 1997 Jim Kingdon - - * client.c (update_entries), rcs.c (expand_keywords): Rewrite - test to avoid signed/unsigned warning. - -Mon Apr 21 09:02:22 1997 Jim Kingdon - - * update.c (patch_file): Add comment about whether auto-detecting - features of the DIFF program is a good idea. - -Mon Apr 21 00:03:34 1997 Ian Lance Taylor - - Don't require the patch program: - * client.c (struct update_entries_data): Add - UPDATE_ENTRIES_RCS_DIFF to contents enum. - (update_entries): Handle UPDATE_ENTRIES_RCS_DIFF. - (handle_rcs_diff): New static function. - (responses): Add "Rcs-diff". - * server.c (server_updated): Handle SERVER_RCS_DIFF. - (server_use_rcs_diff): New function. - * server.h (enum server_updated_arg4): Add SERVER_RCS_DIFF. - (server_use_rcs_diff): Declare. - * update.c (rcs_diff_patches): New static variable. - (update): Set rcs_diff_patches. - (update_fileproc): If rcs_diff_patches, pass SERVER_RCS_DIFF - rather than SERVER_PATCHED to server_updated. - (patch_file): Correct initial comment to say diff rather than - rcsdiff. If rcs_diff_options, pass -n to diff rather than -c. - * rcs.c (rcs_change_text): New function. - * rcs.h (rcs_change_text): Declare. - -Mon Apr 21 00:08:59 1997 Jim Kingdon - - * diff.c (diff_fileproc): Add comment concerning updating the - client timestamp. - -Sun Apr 20 23:20:37 1997 Jim Kingdon - - * commit.c (commit): Add comment regarding SEND_FORCE rationale. - -Sat Apr 19 17:10:36 1997 Jim Kingdon - - * server.c (dirswitch): If directory ends in '/', complain. - -Fri Apr 18 18:09:57 1997 Ian Lance Taylor - - * rcs.c (apply_rcs_changes): New static function, broken out of - RCS_deltas. - (RCS_deltas): Call it. - (linevector_add): Change return type to int. Return an indication - of an error for an invalid add, rather than calling error. - -Fri Apr 18 11:24:26 1997 Jim Kingdon - - * version.c: Change version number to 1.9.9. - - * version.c: Version 1.9.8. - - * commit.c (struct find_data): Add field force. - (find_fileproc, commit): Use it instead of force_ci to decide - whether to send files to server. - (commit): Set it if either -f or -r is specified. - * sanity.sh (basica): Add tests basica-8a0, basica-8a1, and - basica-8a2; tests for above fix. - -Wed Apr 16 11:50:59 1997 Jim Kingdon - - * zlib.c: Remove paragraph with Free Software Foundation address. - See 2 Jan 1997 entry in ../ChangeLog for rationale. - -Tue Apr 15 00:36:23 1997 Jim Kingdon - - * update.c (patch_file_write): Always assign to final_nl, so that - it ends up reflecting whether the data from the last call had a - newline, not whether the data from any of the calls ended in a - newline. Doesn't matter with the current RCS_checkout - implementation, but it will if RCS_checkout is changed to pass - less than the entire file. - - * rcs.c (RCS_cmp_file): Change NULL to RUN_TTY in passing sout to - RCS_checkout, for clarity. - - * import.c (update_rcs_file): Remove unused variable ierrno. - - * add.c, checkout.c, commit.c, diff.c, edit.c, import.c, - history.c, log.c, main.c, patch.c, release.c, remove.c, rtag.c, - status.c, tag.c, update.c, watch.c: Pass "+" to all calls to - getopt. This ensures that we maintain existing behavior even with - glibc2. - - * filesubr.c (fopen_case): Don't set *PATHP if we return an - error. Since the 9 Apr 1997 change, the behavior has been to - sometimes set it and sometimes not. - * rcs.c (RCS_parse): Adjust callers to not free it. Without this - change, they could call free() on an uninitialized variable. - - * checkout.c (checkout): Add comment about export -k. - - * root.c (check_root_consistent): Add comment about wording of - message. - -Mon Apr 14 11:51:49 1997 Jim Kingdon - - * client.c (call_in_directory): If rdirp reaches the end of - reposdirname, then just set it to NULL. If server does not create - directories one at a time, give a warning. - * sanity.sh (modules3): Enable tests modules3-8 through - modules3-11 for remote; tests for above fix. - - * client.c (call_in_directory): Don't set short_pathname to - pathname for a while; just use pathname itself (cleans up a relic - of the old "Repository" (not "Directory") code). Add comment - explaining short_pathname. - -Sun Apr 13 18:07:50 1997 Ian Lance Taylor - - * rcs.c (RCS_checkout): Add pfn and callerdat parameters. Change - all callers. Move setting of expand after retrieval of file - data. - (struct cmp_file_data): Define. - (RCS_cmp_file): New function. - (cmp_file_buffer): New static function. - * rcs.h (RCSCHECKOUTPROC): Define type. - (RCS_checkout): Update declaration. - (RCS_cmp_file): Define. - * diff.c (diff_file_nodiff): Call RCS_cmp_file rather than - RCS_checkout and xcmp. - * import.c (update_rcs_file): Likewise. - * no_diff.c (No_Difference): Likewise. - * update.c (struct patch_file_data): Define. - (patch_file): Just return if noexec, or if binary file. Pass - patch_file_write to RCS_checkout. Don't check for newlines or - compute checksums here. Stat RCS file to set modes. - (patch_file_write): New static function. - - * update.c (patch_file): Checkout directly to file2, rather than - to finfo->file followed by rename. Remove check for whether - result of checkout is readable; that was for an old, obsolete, - form of death support. - -Sun Apr 13 13:16:40 1997 Jim Kingdon - - * checkout.c (build_one_dir): New function. - (struct dir_to_build): New structure. - (build_dirs_and_chir): Rewritten to accept a linked list of struct - dir_to_build rather than the silly string processing we had been - doing before. - (checkout_proc): Rewrite code that calls build_dirs_and_chdir - accordingly. - * sanity.sh: Enable tests modules3-10 and modules3-11 for local CVS; - tests for above fix. - - * rcs.h (RCS_CO): Removed; no longer used. - -Sun Apr 13 00:04:34 1997 Ian Lance Taylor - - Expand RCS keywords internally; never call co: - * rcs.h (struct rcsversnode): Add state field. - * rcs.c (kflags): Move out of RCS_check_kflag, and make file - static. - (enum kflag): Define. - (RCS_reparsercsfile): Always save lock information. Save state in - new state field, rather than other field. - (struct rcs_keyword): Define. - (keywords): New static variable. - (enum keyword): Define. - (printable_date, escape_keyword_value): New static functions. - (expand_keywords): New static function. - (RCS_checkout): Call expand_keywords. Don't call - RCS_exec_checkout. - (RCS_deltas): Add log and loglen parameters. Change all callers. - * log.c (log_version_requested): Use new state field. - (log_version): Likewise. - * cvs.h (RCS_exec_checkout): Don't declare. - * rcscmds.c (RCS_exec_checkout): Remove. - -Sat Apr 12 17:32:59 1997 Ian Lance Taylor - - * sanity.sh (modules3): Remove second-dir at end of tests. - (sticky): Correct removal of directories at end of tests. - - * sanity.sh (keyword): New tests for RCS keyword expansion. - -Sat Apr 12 16:47:13 1997 Jim Kingdon - - * sanity.sh (basicb): New tests basicb-1b, basicb-1c, basicb-9b, - basic-9c test current build_dirs_and_chdir behavior. - -Fri Apr 11 23:54:56 1997 Jim Kingdon - - * sanity.sh (modules3): New tests modules3-7* test for ability to - supply a path in -d in modules. Similar to modules3-8 through - modules3-11 except because the nesting is different, these ones - work. - -Thu Apr 10 00:14:47 1997 Jim Kingdon - - * sanity.sh (modules3): New tests modules3-12 through modules3-15 - test use of a module name which contains a slash. - - * sanity.sh (basicb): New tests basicb-14 to basicb-20 test use of - co -d with two or more arguments. - - * rcscmds.c: Refer to doc/RCSFILES in comment. - -Wed Apr 9 09:49:17 1997 Jim Kingdon - - * sanity.sh (basicb): New tests basicb-11 through basicb-13 test - ability to specify several directory levels in co -d (commented - out). - - * filesubr.c (fopen_case): If CVS_OPENDIR gives an - existence_error, return it to the caller instead of giving a fatal - error. - - * client.c (update_entries): Fix typo in call to error (1 -> errno). - -Tue Apr 8 23:02:22 1997 Jim Kingdon - - * error.h, error.c: Test for #ifdef __STDC__, not #if __STDC__. - This is consistent with other parts of CVS; it means that the - declaration for fperror will match the definition even if __STDC__ - is defined to 0 as the SunPro 4.0 compiler does. Reported by - Richard Smith . - -2 Apr 1997 Jim Kingdon - - * entries.c (ParseTag): Add "break;" after "default:" to avoid - error from Visual C++. - -Wed Apr 2 12:06:44 1997 Vince Del Vecchio - and Jim Kingdon - - * client.c: In reporting errors from socket calls, use - SOCK_STRERROR and SOCK_ERRNO since strerror(errno) doesn't work - for Win32. - -Tue Apr 8 10:45:32 1997 Jim Kingdon - - * sanity.sh (modules3): Add tests modules3-8 to modules3-11, to - test for ability to supply a path to -d in modules. Mostly - commented out as CVS is buggy in this area. - -Mon Apr 7 12:41:44 1997 Jim Kingdon - - * add.c (add): Add comment about SEND_NO_CONTENTS. - -Sun Apr 6 21:46:32 1997 Jim Kingdon - - * update.c (update): Add comment about noexec and SEND_NO_CONTENTS. - -Sun Apr 6 17:34:08 1997 Robert Bihlmeyer - - * Pass +f not f to getopt_long to prevent options from being - permuted with glibc 2.0.1. - -Sun Mar 30 00:07:05 1997 Jim Kingdon - - * cvs.h (struct vers_ts): Adjust comment regarding ts_user. - * server.c (serve_is_modified): New function. Set entries to show - that the file is modified but we don't know the contents. - * server.c (requests): Add "Is-modified" request. - * vers_ts.c (time_stamp_server): If the timestamp in entdata is - "M" or "D", just copy that over into ts_user. - * vers_ts.c (Version_TS): If timestamp is "D", use the entries - line for the sole purpose of passing it to time_stamp_server. - * no_diff.c (No_Difference): If ts_user is "M", conclude the files - are different. - * client.h, client.c (send_files): Replace arguments build_dirs - and force with argument flags. Add flag SEND_NO_CONTENTS and add - to struct send_data. - (send_fileproc): If no_contents, then send Is-modified instead of - Modified. - * add.c, admin.c, client.c, commit.c, diff.c, edit.c, log.c, - rcs.c, remove.c, status.c, tag.c, update.c, watch.c: Change all - send_files callers. - -Fri Mar 28 22:32:25 1997 Jim Kingdon - - * server.c (requests): Change "Repository" to rq_optional. I'm - not sure whether I overlooked this when I removed support for - Repository, or whether I was thinking that servers would need to - support it anyway, for CVS 1.5 to 1.9 clients, but making it - optional doesn't prevent the server from supporting it and it - seems silly for the client to complain about absence of a request - that it never will use. - -Fri Mar 28 10:06:59 1997 Steven Miller - - * entries.c (Subdirs_Known): Don't create Entries.Log if noexec. - -Thu Mar 27 18:14:12 1997 Ian Lance Taylor - - * sanity.sh (death2): Remove commented out test death2-21. It - would now pass, but it duplicates the new test sticky-11. - -Thu Mar 27 10:21:19 1997 Jim Kingdon - - * sanity.sh (dotest_internal): Write test output to logfile even - if test succeeds. This was the behavior prior to 30 Sep 1996. - See the comment for rationale. - -Tue Mar 25 13:26:52 1997 Jim Kingdon - - * cvs.h, entries.c (WriteTag): Add arguments nonbranch, - update_dir, and repository. Move the server_set_sticky call from - callers to here. - * cvs.h, create_adm.c (Create_Admin): New argument nonbranch. - * cvs.h, entries.c (ParseTag): Add argument nonbranchp. - * cvs.h (struct stickydirtag): Add field nonbranch. - * entries.c (Entries_Open): Set it. - * cvs.h (Vers_TS): Add field nonbranch. - * vers_ts.c (Version_TS): Copy it from struct stickydirtag. - * server.c, server.h (server_set_sticky): Add argument nonbranch. - * add.c, client.c, checkout.c, modules.c, update.c, create_adm.c, - commit.c: Update callers. - * add.c (add): If nonbranch, don't add the file on that "branch". - * commit.c (write_dirnonbranch): New variable. - (commit_fileproc, commit): Set it. - (commit_dirleaveproc): Pass it to WriteTag. - * update.c (rewrite_tag, nonbranch): New variables. - (update, update_dirent_proc, update_fileproc): Set them. - (update_filesdoneproc): If rewrite_tag, call WriteTag. - * sanity.sh (sticky): New tests, test for above fix. - - * version.c: Change version number to 1.9.7. - - * version.c: Version 1.9.6. - -Mon Mar 24 13:02:04 1997 Jim Kingdon - - * entries.c (ParseTag): Add comment about unrecognized characters - in CVS/Tag file. - - * classify.c (Classify_File): Add comment about how specifying a - tag (bogusly?) suppresses certain messages. - -Fri Mar 21 13:37:46 1997 Jim Kingdon - - * rcs.h (struct rcsnode): Add comment about case of PATH. - * rcs.c (RCS_parse): If ign_case, then try opening the file with - fopen_case. - * ignore.c (ign_case): Adjust comment. - * cvs.h, filesubr.c (cvs_casecmp, fopen_case): New functions. - -20 Mar 1997 Jim Kingdon - - * client.c (send_repository): When sending Directory request, - send any ISDIRSEP character as '/'. Fixes - "cvs log foo\bar\baz.c" on NT & friends. - - * client.c (send_file_names): Don't try to read Entries file if - CVSADM directory does not exist. Fixes fairly serious regression - (warning on all fresh checkouts) introduced by 1997-01-08 change. - -Tue Mar 18 13:03:33 1997 Jim Meyering - - * sanity.sh (RCSINIT): Define to be empty and export, to hide any - existing value that might cause spurious failures. - - * Makefile.in: (install): Depend on installdirs. - Remove `CYGNUS LOCAL' comment saying not to. - -Tue Mar 18 09:36:26 1997 Jim Kingdon - - * recurse.c (struct recursion_frame): Reindent. - (do_dir_proc): Print message if we try to recurse into a CVSADM - directory. - * sanity.sh (basicb): New test basicb-4a tests for above fix. - -Sun Mar 16 10:18:28 1997 Jim Kingdon - - * sanity.sh (death2): Replace regexp matching temporary file name - with new variable ${tempname}. For most of the tests this is a - cosmetic change, but death2-diff-6 had been missing _ which caused - it to fail on Solaris (at least sometimes). - - * sanity.sh (modes): Don't use export -n; it doesn't seem - to be sufficiently portable. - - * version.c: Change version number to 1.9.5. - - * version.c: Version 1.9.4. - - * rcscmds.c (RCS_checkin): Preserve the mode of the rcsfile. - RCS_CI usually, but not always, does this for us. - * commit.c (fix_rcs_modes): Replace algorithm with a more - CVSUMASK-friendly one. - * sanity.sh (modes): Update tests modes-5, modes-7, modes-10, and - modes-15 so they test that CVSUMASK is honored. - -Sun Mar 16 10:18:28 1997 Jim Kingdon - - * sanity.sh (modes): New tests modes-7a and modes-7b test behavior - if one manually changes the modes in the repository. - - * server.c (server): Revise code which checks for errors creating - temporary directory. This won't solve the intermittent - can't create temporary directory - Unknown error -1 - but it will mean (a) the right message based on errno gets - printed, instead of "unknown error -1", and (b) the message says - that it happened in chmod instead of mkdir_p. - -Sat Mar 15 16:47:12 1997 Jim Kingdon - - * sanity.sh (modes): New tests. Note that (for now) these are - just testing how CVS already behaves; I want to record that before - I move on to changing CVS's behavior with modes of RCS files. - -13 Mar 1997 Jim Kingdon - - * subr.c (line2argv): Change argv_allocated from size_t to int. - -Wed Mar 12 22:16:44 1997 Jim Kingdon - - * add.c (add_directory): If repository has an extraneous "." - directory at the end, strip it off. This fixes a bug which was - introduced when strip_path was nuked (this fix is much more - limited in scope than strip_path was; I _think_ that is a good - thing). - (add): Likewise, for client. - (combine_dir): New function, helps with above. - * sanity.sh (modules3): Reenable tests for this behavior. - (basica-0b, basicb-0e): Adjust test to reflect "foo/bar" instead - of "foo/./bar" in message. As with the rest of this, I believe - this is just restoring the behavior prior to the strip_path nuking - (I tried it with CVS 1.9). - -Sun Mar 9 10:06:29 1997 Jim Kingdon - - * root.c (parse_cvsroot), server.c (serve_root, serve_init): - If CVSroot_directory is not an absolute pathname, give a fatal error. - * sanity.sh (crerepos): New tests crerepos-6* test for above fixes. - -Sat Mar 8 22:06:17 1997 Jim Kingdon - - This cleans up the last known code which can overflow its buffers - (except the Mac client). I've skimmed through much of CVS looking - for other such places; but I didn't read everything. If I missed - any please report it to bug-cvs. - * logmsg.c (logfile_write, title_proc): Realloc str_list as - needed; don't assume MAXLISTLEN is enough. - * cvs.h (MAXLISTLEN, MAXFILEPERDIR): Removed; no longer used. - * add.c, myndbm.c, parseinfo.c, update.c: Nuke MAXLINELEN limit. - * parseinfo.c, update.c, mkmodules.c: Check for errors reading file. - * cvs.h (MAXLINELEN): Removed; no longer used. - * logmsg (MAXHOSTNAMELEN): Removed; not used. - * main.c (cmd_synonyms): Allocate based on fullname, nick1, and - nick2, just in case someone makes those big enough so that 100 - bytes is not enough. - (Make_Date): Use MAXDATELEN rather than our own fixed size. - * mkmodules.c (mkmodules): Nuke arbitrary limit on line length. - * rcs.c (ALLOCINCR): Remove; not used. - (RCS_check_kflag): Add comment concerning karg size. - * run.c: Allocate run_prog to the needed size, rather than - allocating a fixed size buffer. - -Fri Mar 7 22:39:08 1997 Jim Kingdon - - * logmsg.c (logfile_write): Allocate prog to needed length rather - than assuming MAXPROGLEN is enough. - * cvs.h (MAXPROGLEN): Removed; no longer used. - * subr.c (MIN_INCR): Update comment to reflect MAXPROGLEN's demise. - - * subr.c (free_names): Fix comment: this function is not used to - free memory allocated by Find_Names (at least it hasn't for a long - time). - * subr.c, cvs.h (line2argv): Change calling convention so that we - allocate argv array rather than the caller. The previous one had - no way of checking whether we overflowed the passed-in buffer. - * subr.c (free_names): Free the argv array too. - * modules.c (do_module, cat_module): Update callers. - -Thu Mar 6 12:44:42 1997 Jim Kingdon - - * import.c: Allocate vhead and vbranch dynamically; removes - arbitrary limit. - * history.c: Likewise (since_rev, since_tag, backto, rec_types). - * ignore.c: Likewise (line). Also check for errors from getline - and add 'copyright' notice to top of file. - * wrapper.c (wrap_add_file): Likewise (line). Also check for - errors from various calls and add 'copyright' notice to top of file. - -Tue Mar 4 17:39:15 1997 Jim Kingdon - - * client.c (update_entries): Add comment about "move away " - message. - -Mon Mar 3 21:51:40 1997 Jim Kingdon - - * sanity.sh (basicb): Clean up topfile,v at end of test. Fixes - failure in modules-155b. - -Sun Mar 2 18:11:09 1997 Dan Wilder - and Jim Kingdon - - * admin.c (admin): Arrange to perform recursion if "cvs admin" - is passed only options. - -Sun Mar 2 18:11:09 1997 Jim Kingdon - - * sanity.sh (basicb): New tests basicb-0* test for files at top - level. - - * error.c (error): Add newline to "out of memory" message. I think - that its omission probably could cause the message to be lost in - the bowels of server.c and never passed to the user. - - * client.c (start_rsh_server): Add comment about "remsh" vs. "rsh". - - * cvs.h: Move copyright notice to top of file. - -Sun Mar 2 13:44:36 1997 Ian Lance Taylor - - * sanity.sh: Use -n when testing whether rsh works. - - * server.c (serve_root): Free path. - -Sun Mar 2 13:12:46 1997 Jim Kingdon - - The following are things that I noticed in the process of trying - to track down: - can't create temporary directory - Unknown error -1 - FAIL: test 28 - from nightly testing. I'm not sure that either item explains that - message however. - * server.c (server): Allocate pending_error_text; - print_pending_error will try to free it so - pending_error_text = "foo" - won't work. - (mkdir_p): Don't assume that isdir will leave errno unmolested. - -Thu Feb 27 15:29:58 1997 Ian Lance Taylor - - * remove.c (cvsremove): When forcing removal in client mode, use - start_recursion rather than calling CVS_UNLINK on each argument. - (remove_force_fileproc): New static function. - * sanity.sh (deep): Add tests deep-rm7 through deep-rm10 for above - patch. - - * sanity.sh (death): Enable death-76a0 and death-76a1 tests for - remote, since they now work. - -Wed Feb 26 16:13:26 1997 Ian Lance Taylor - - * client.c (add_prune_candidate): Skip adding this directory if - it is the same as the first directory already on the list. - -Mon Feb 24 21:36:43 1997 Noel Cragg - - * main.c (lookup_command_attribute): Add the "init" command to the - list of commands that don't use the current working directory. - -Sun Feb 23 09:54:49 1997 Jim Kingdon - - * sanity.sh (devcom3): Clean up at end of test. - - * sanity.sh (basicb): Add commented out test basicb-8a0, for - whether CVS can print an error on bad numeric revision to diff. - Commented out until we get around to fixing CVS. - * diff.c (diff_file_nodiff): Add comment about this case. - - * fileattr.c (fileattr_read): If a filename is duplicated, - continue to ignore subsequent lines but free the node so that we - don't leak memory. - * sanity.sh (devcom3): New tests devcom3-8 and devcom3-9 test for - behavior on duplicated filenames. - - * fileattr.h: Add comment about unrecognized ENT-TYPE and order of - lines in fileattr file. - * fileattr.c (struct unrecog, unrecog_head): New variables, to - record unrecognized lines. - (fileattr_startdir): Assert that unrecog_head == NULL. - (fileattr_read): Record unrecognized lines in unrecog_head linked - list rather than ignoring them. - (fileattr_write): Also write out unrecognized lines, if any. - * sanity.sh (devcom3): New tests, test for above fix. - - * fileattr.h (fileattr_modify): Fix example in comment. - -Sat Feb 22 08:30:27 1997 Jim Kingdon - - * sanity.sh: Add variable username. - (basica rdiff multibranch log log2): Use it instead of our own - (inconsistent) ways of matching an author name. - - * filesubr.c, root.c, rtag.c, server.c, subr.c, update.c, - wrapper.c: Nuke PATH_MAX. - * cvs.h, wrapper.c (wrap_fromcvs_process_file): Now returns void - (return value had been unused). - * cvs.h: Adjust comment to reflect the fact that PATH_MAX is - gone, at least from src/*.c (except safe_location, as noted). - -22 Feb 1997 patch by Tom Hageman (4 Jun 1996) - updated and commented by Jim Kingdon - - * update.c (checkout_file): Call unlink_file_dir on backup, not - unlink_file. - -Fri Feb 21 16:40:03 1997 Jim Kingdon - - * Makefile.in (DISTFILES): Remove NOTES. - - * NOTES: Removed. bcopy->memcpy is done. "static buffers" I - assume refers to what is covered by reentrancy text in HACKING. - Obstack idea moved to comment in hash.c (at nodecache). Checking - system calls for error returns largely done, and isn't a very - helpful suggestion unless you know where the bogus calls are - anyway. Sizing limits--we're in the progress of removing them - (assuming it meant things like PATH_MAX and earlier, already - nuked, limits). Removed various items about changes which were - done a long time ago (I realize that the ChangeLog's probably - aren't reliable that far back, but I'm not convinced anyone cares - anymore). CONFIRM_DIRECTORY_ADDS: I assume this is a - reference to the #if 0'd code in add_directory which asks for - confirmation--a better way of making it harder to accidentally add - directories would be to have to add and commit directories like - for files. I don't know what FORCE_MESSAGE_ON_ADD meant. - - * rcs.c (RCS_getrevtime): Fix documentation (in particular, the - size of the array that DATE must point to, but many other things - too). - * patch.c, recurse.c, release.c, remove.c, repos.c: Nuke PATH_MAX. - (patch_fileproc): Use MAXDATELEN not hardcoded 50. - -Sun Feb 16 12:00:44 1997 Jim Kingdon - - * client.c (client_process_import_file): New variable fullname; - pass it to send_modified. This finishes the job of untangling the - old short_pathname variable into update_dir vs. fullname. - - * client.c (client_process_import_file): Nuke first_time. If - toplevel_repos were ever NULL here, the code would dump core in - strncmp a few lines down. And client_import_setup ensures - toplevel_repos is not NULL. - -Sun Feb 16 08:16:48 1997 Ian Lance Taylor - - * client.c (client_process_import_file): Rename short_pathname to - update_dir (to reflect its function) and make sure that it doesn't - point to uninitialized memory if repository and toplevel_repos - contain the same string. - -Sun Feb 16 08:16:48 1997 Jim Kingdon - - * client.c (start_rsh_server): Nuke comment about weirdnesses with - pre-1.5 versions of CVS and .bashrc/.cshrc. The remote protocol - is interoperable only back to 1.5, and people who need to know are - unlikely to see this comment anyway. - -Sun Dec 15 13:12:30 1996 Michael Douglass - and Jim Kingdon - - * main.c (cmds): Added an entry for new logout command. - (cmd_usage): Added an entry for new logout command. - (lookup_command_attribute): Added 'logout' to list of commands - that set need_to_crate_root to 1. - * login.c, cvs.h (logout): New command for removing entries from - the .cvspass file. - (logout_usage): Usage information on the logout command. - -Wed Feb 12 11:19:42 1997 Jim Kingdon - - * client.c (struct send_data): Fix indentation. - -Wed Feb 12 08:48:04 1997 Greg A. Woods - - * mkmodules.c (loginfo_contents): add missing comma in - initializer statement (caused syntax error on SunOS-4). - -Tue Feb 11 21:14:28 1997 Ian Lance Taylor - - * commit.c (find_fileproc): If force_ci is set, set the status to - T_MODIFIED even if the file hasn't changed. - (commit): Pass force_ci to send_files as new force argument. - * client.c (struct send_data): Define. - (send_fileproc): The callerdat parameter now points to a send_data - struct. If force is set, always call send_modified. - (send_dirent_proc): The callerdat parameter now points to a - send_data struct. - (send_files): Add force parameter. Change all callers. Set up a - send_data struct and pass it to start_recursion as callerdat. - * client.h (send_files): Update declaration. - * sanity.sh (basica): Add a simple test for the above patch. - -Sun Feb 9 12:58:59 1997 Jim Kingdon - - * tag.c (cvstag), rtag.c (rtag): Pass -f to server if specified in - the client. I haven't tried to come up with a test case because - the fix seems obvious. - - * import.c (add_rcs_file): Change size of altdate1 and altdate2 to - MAXDATELEN. - * cvs.h (MAXDATELEN): Fix comments; describe what this is for. - - * diff.c (diff_usage): Document --ifdef and try to briefly say - what "rcsdiff-options" means. - - * update.c (update): If update had a nonzero status and we haven't - yet tried to fetch unpatchable files, go ahead and try it again. - The previous behavior was to quit, which meant that updates would - keep failing until you hacked around the problem. Patch and bug - report by Ian; comment, ChangeLog entry, and willingness to take - the flak if checking it is premature by Jim. - - * server.c (alloc_pending): New function. - * server.c: Call it. Fixes places where we had neglected to - check for NULL return from malloc. - - * sanity.sh (binwrap): Add test binwrap-0, tests for import.c fix - below. - -Sun, 9 Feb 1997 (submitted 19 Jul 1996) John Polstra - - * import.c (import): Give error if the same tag is specified more - than once. The previous behavior was to write an RCS file which - had the same tag listed twice, once pointing to each revision, - which is not legal. - -Sun Feb 9 12:37:09 1997 Jim Kingdon - - * checkin.c (Checkin): Use cvs_output to print message (should - make out of order bugs no worse, as it merely substitues a - protocol_pipe vs. stderr_pipe race instead of a stdout_pipe - vs. stderr_pipe race). Add comment about stdout vs. stderr. - -Fri Feb 7 08:29:52 1997 Josef Nelissen - - * server.c (check_command_legal_p): Don't use ANSI-style definition. - -Thu Feb 6 10:55:37 1997 Jim Kingdon - - * patch.c (patch): Give a fatal error for -V option (see comment - for rationale). - - * diff.c (diff): Also send "options" to server. Pretty much the - patch submitted independently by josef.nelissen@munich.ixos.de and - Ronald Khoo . - -Wed Feb 5 18:57:14 1997 Jim Kingdon - - * modules.c (do_module): Fix typo in 30 Jan 97 PATH_MAX nuking - (free -> free_cwd). Testsuite test 151 gets credit for catching - this one. - -Mon Feb 3 16:14:54 1997 Ian Lance Taylor - - * main.c (lookup_command_attribute): Don't use an ANSI prototype - when defining the function. - -Fri Jan 31 12:49:02 1997 Ian Lance Taylor - - * modules.c (do_module): Actually goto found if is_found is set - (fixes thinko in PATH_MAX nuking of 30 Jan 97). - -Fri Jan 31 12:49:02 1997 Jim Kingdon - - * sanity.sh: Add modules3 and big to list of tests to run - by default; they were omitted by accident. - -Thu Jan 30 11:46:33 1997 Jim Kingdon - - * logmsg.c, main.c, mkmodules.c, modules.c, parseinfo.c, patch.c: - Nuke more PATH_MAX. - - * server.c (server_updated): After we send Created or - Update-existing for a file, mark it as unchanged, in case we - process it again. - * sanity.sh (modules3): New tests, test for above fix. - - * logmsg.c (do_verify): Error return from fopen is NULL, not -1. - Pass errno to error(). - - * login.c [_CRAY]: Don't declare getpass. - -Mon Jan 27 17:25:27 1997 Jim Kingdon - - * import.c (process_import_file): Fix freeing of rcs (Don't free - it before we are done using it, and don't free it twice). - - * modules.c (cat_module): Allocate line right before we use - it. The previous code was wrong because the length of the - s_h->rest changes between the time we allocate line and the time we - sprintf s_h->rest into it. - -Sun Jan 26 21:58:16 1997 Jim Kingdon - - * expand_path.c (expand_path): Revise to call expand_string as - needed. Nuke PATH_MAX. - * find_names.c (find_dirs): Likewise. - * import.c, lock.c: Nuke more PATH_MAX. - - * server.c (mkdir_p): Set retval to 0 at start of function. - Previously it had been uninitialized for some cases. Thanks are - due to nightly testing for catching this one. - -Sat Jan 25 21:34:19 1997 Jim Kingdon - - * subr.c, cvs.h (expand_string): New function. - * rcs.c (getrcskey, getrcsrev): Call it. This greatly reduces the - number of calls to realloc if there is a very large file in the - RCS file. Credit goes to Mike Heath for - pointing out the problem and the basic solution (MIN_INCR, - MAX_INCR); I adapted it into the separate function expand_string. - * sanity.sh (big): New test helps insure this hasn't broken - anything obvious. - -Wed Jan 22 10:06:13 1997 Jim Kingdon - - * status.c (status_fileproc): Change message which is printed for - T_MODIFIED and ts_conflict set, so that it doesn't say "unresolved - confict". This message occurs whether the conflict is resolved or - not. - * sanity.sh (conflicts): Add tests conflicts-status-* to test - output of "cvs status" in the context of conflicts. Tests for - above fix. - - * rtag.c (rtag): Send -n if run_module_prog is NOT true. - -Thu Jan 16 00:06:00 1997 Jim Kingdon - - * version.c: Change version number to 1.9.3. - - * version.c: Version 1.9.2. - -Wed Jan 15 09:14:38 1997 Jim Kingdon - - * client.c (call_in_directory): Take code that creates CVSADM at - top level, move it before the CVS_CHDIR (dir_name) call, and do it - regardless of whether dir_name is ".". Pass "." not dir_name to - Create_Admin (when the code was written they were always the - same). Don't add reposdirname to the repository we pass to - Create_Admin (when the code was written, I think reposdirname - probably would always be "."). Don't create CVSADM if - reposdirname_absolute. - * sanity.sh (basicb): Enable tests basicb-1a and basicb-9a for - remote; tests for above fix. - (basic1): Do entire test within a "1" directory to deal with - creation of CVS directories at top level. Support --keep. - (conflicts): In test conflicts-136, only update first-dir. - (basica): Uncomment the part that tests "cvs co -l .". That tests - the existing functionality which I might have (but hopefully did not) - perturbed with the call_in_directory changes. - -Mon Jan 13 11:04:32 1997 Jim Kingdon - - * server.c (check_command_legal_p): Do not call error (1, ...) - here; that will always cause a protocol violation by shutting down - the connection prematurely. Remove croak_on_illegal arg. - (do_cvs_command): Move call to check_command_legal_p until after - the call to print_pending_error. Print the error message ourself. - - * mkmodules.c (filelist): Add readers and writers. Add comment - about why passwd is not included. Add comment about meaning of - NULL contents field. - -Fri Jan 10 13:23:09 1997 Norbert Kiesel - - * release.c (release): Initialize delete_flag before reading it - (found by running purify) - - * logmsg.c (do_verify): Fix reading unallocated memory (found by - running purify) - -Thu Jan 9 16:32:47 1997 Jim Kingdon - - * checkout.c (build_dirs_and_chdir): Partially revert 3 Jan - change--move call to Subdir_Register back above the CVS_CHDIR call - (we need to register in the old, not the new, directory). Instead - of calling CVS_MKDIR and ignoring errors, call mkdir_if_needed; - this is an effort to catch errors there rather than catching them - in the CVS_CHDIR. This makes test 27-add-add in sanity.sh work - again. - - * find_names.c (Find_Directories): Remove code inside - #ifdef ATTIC_DIR_SUPPORT and replace it with a comment explaining - why we don't look in the attic. ATTIC_DIR_SUPPORT was never defined. - - * find_names.c (find_dirs): Add comment about tmp being unset. - - * commit.c (checkaddfile): Report errors with errno and specific - error messages. - - * rcs.c, commit.c, create_adm.c, entries.c, find_names.c, - ignore.c, history.c: Nuke PATH_MAX arbitrary limits. - -Wed Jan 8 23:07:41 1997 Jim Kingdon - - * add.c (add): Reindent a portion which needed it. - -1997-01-08 Jim Kingdon - - * client.c (send_file_names): When looking name up in Entries, - call Entries_Open and Entries_Close. This has two effects: - (1) we look at Entries.Log, and (2) we don't skip 'D' entries, - both of which are needed to make us get the right (command - line) name for a directory we are adding. - -Wed Jan 8 14:50:47 1997 Jim Kingdon - - * Makefile.in, cvs.h, hash.h, myndbm.h, rcs.h: Remove CVSid; we - decided to get rid of these some time ago. - -Tue Jan 7 12:56:10 1997 Karl Fogel - - * root.c (check_root_consistent): new func, compares below new - global var with CVSroot_directory, assuming both set. - (set_local_cvsroot): use above new func for security check. - (parse_cvsroot): same. - But do all of above only #ifdef AUTH_SERVER_SUPPORT. - - * server.c: (Pserver_Repos): new global var, init to NULL. - (pserver_authenticate_connection): set above new global. - (check_repository_password): be a good scout and use - CVSROOTADM and CVSROOTADM_PASSWD, now that they are the standard. - Make sure all of above is in #ifdef AUTH_SERVER_SUPPORT. - (check_command_legal_p): wrap most of body in #ifdef - AUTH_SERVER_SUPPORT. - Everywhere: wrap all references to CVS_Username in #ifdef - AUTH_SERVER_SUPPORT. - - * cvs.h (Pserver_Repos): new var, used in consistency [security] - check. Defined only #ifdef AUTH_SERVER_SUPPORT. - (CVSROOTADM_PASSWD): new #define, trying to get with the program. - -Fri Jan 3 18:10:39 1997 Ian Lance Taylor - - * checkout.c (build_dirs_and_chdir): Move call to Subdir_Register - until after we know that the directory exists. - -Thu Jan 2 13:30:56 1997 Jim Kingdon - - * Makefile.in, cvsbug.sh, edit.c, edit.h, error.c, error.h, - fileattr.c, fileattr.h, filesubr.c, run.c, update.h, watch.c, - watch.h: Remove "675" paragraph; see ../ChangeLog for rationale. - -Thu Jan 2 12:27:46 1997 Jim Kingdon - - * sanity.sh (info): New test info-cleanup-verifymsg gets rid of - verifymsg when we are done with it. - - * sanity.sh (basicb): Skip tests basicb-1a and basicb-9a for remote. - * sanity.sh (modules-155a4): It is OK if a CVS directory exists. - * sanity.sh (ignore): Do everything inside a "1" directory. The - change to create CVS directories at top-level causes messages such as - "? home" otherwise. In test 191, specify -I CVS so that new CVS - directory is ignored. - * sanity.sh (crerepos): Manually remove CVS directory which had not - existed before. - -Thu Jan 2 09:06:20 1997 Karl Fogel - - * server.c: Changes for pserver read-only repository access: - (check_command_legal_p): new func. Right now, just checks if - repository modification is permitted, and that only if pserver is - active. - (do_cvs_command): take new parameter `cmd_name', a string. All - callers changed. Pass it on to new func check_command_legal_p() - before executing the command. - (CVS_Username): new global, init to NULL. Used by - check_command_legal_p(), set in check_password(). - (check_password): set above new global CVS_Username; reorganized a - bit to facilitate this. - (check_repository_password): give *host_user_ptr permanent - storage iff success. - - * main.c: Changes for pserver read-only repository access: - (lookup_command_attribute): new func. - (main): use new func lookup_command_attribute() to establish if - CVS_CMD_IGNORE_ADMROOT and CVS_CMD_USES_WORK_DIR. - - * cvs.h: Changes for pserver read-only repository access: - (CVSROOTADM_READERS, CVSROOTADM_WRITERS): new #defines. - Prototype lookup_command_attribute(). - (CVS_CMD_IGNORE_ADMROOT, CVS_CMD_USES_WORK_DIR, - CVS_CMD_MODIFIES_REPOSITORY): new #defines for - lookup_command_attribute() and its callers. - -Wed Jan 1 19:50:38 1997 Jim Kingdon - - * options.h.in: Reword comment for TMPDIR_DFLT to make it clear - that this isn't specific to the pserver server. - - * modules.c (do_module): Give an error message if one tries to - specify -a together with another option. - * sanity.sh (modules2): New tests modules2-a* test for above fix. - - * sanity.sh (devcom): Add tests devcom-a-nonexist and - devcom-t-nonexist for "cvs watchers" on nonexistent argument. - -1997-01-01 Fred Fish - - * run.c (piped_child, filter_stream_through_program): Actually - install these HAVE_VFORK patches that got missed. - (There was a log entry for these changes for 29 Nov 1996 but it - seems I accidentally forgot to actually check them in -kingdon). - -Wed Jan 1 18:32:44 1997 Jim Kingdon - - * Makefile.in: Add ChangeLog-96. - * ChangeLog-96: New file, contains former contents of ChangeLog. - * ChangeLog: Now just contains 1997 changes. - - -For older changes see ChangeLog-96. diff --git a/contrib/cvs/src/Makefile.am b/contrib/cvs/src/Makefile.am deleted file mode 100644 index 63e6b18..0000000 --- a/contrib/cvs/src/Makefile.am +++ /dev/null @@ -1,138 +0,0 @@ -## Process this file with automake to produce Makefile.in -# Makefile for GNU CVS program. -# -# Copyright (C) 1986-2005 The Free Software Foundation, Inc. -# -# Portions Copyright (C) 1998-2005 Derek Price, Ximbiot , -# and others. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -SHELL = /bin/sh - -# $(includeopt) is CVS specific and set by configure -# FIXME - This includes line is dependant on its order. This means there is -# some namespace hackery going on that maybe shouldn't be. Long term fix is to -# try and remove naming ocnflicts and fix Automake to allow particular includes -# to be attached only to particular object files. Short term fix is either or. -##INCLUDES = -I. -I.. -I$(srcdir) -I$(top_srcdir)/lib -INCLUDES = -I$(top_srcdir)/lib -I$(top_srcdir)/diff -I$(top_srcdir)/zlib $(includeopt) - -bin_PROGRAMS = cvs -bin_SCRIPTS = cvsbug - -# The cvs executable -cvs_SOURCES = \ - add.c \ - admin.c \ - annotate.c \ - buffer.c \ - checkin.c \ - checkout.c \ - classify.c \ - client.c \ - commit.c \ - create_adm.c \ - cvsrc.c diff.c \ - edit.c \ - entries.c \ - error.c \ - expand_path.c \ - fileattr.c \ - filesubr.c \ - find_names.c \ - hardlink.c \ - hash.c \ - history.c \ - ignore.c \ - import.c \ - lock.c \ - log.c \ - login.c \ - logmsg.c \ - main.c \ - mkmodules.c \ - modules.c \ - myndbm.c \ - no_diff.c \ - parseinfo.c \ - patch.c \ - rcs.c \ - rcscmds.c \ - recurse.c \ - release.c \ - remove.c \ - repos.c \ - root.c \ - run.c \ - scramble.c \ - server.c \ - stack.c \ - status.c \ - subr.c \ - tag.c \ - update.c \ - version.c \ - vers_ts.c \ - watch.c \ - wrapper.c \ - zlib.c \ - buffer.h \ - client.h \ - cvs.h \ - edit.h \ - error.h \ - fileattr.h \ - hardlink.h \ - hash.h \ - history.h \ - myndbm.h \ - rcs.h \ - root.h \ - server.h \ - stack.h \ - update.h \ - watch.h - -cvs_LDADD = \ - ../diff/libdiff.a \ - ../lib/libcvs.a \ - ../zlib/libz.a - -# extra clean targets -# wish this could be distclean-hdr-local but it's not part of automake -DISTCLEANFILES = check.log check.plog - -# General -EXTRA_DIST = \ - .cvsignore \ - ChangeLog-9194 \ - ChangeLog-9395 \ - ChangeLog-96 \ - ChangeLog-97 \ - build_src.com \ - sanity.sh - -check-local: localcheck remotecheck - -.PHONY: localcheck -localcheck: - $(SHELL) $(srcdir)/sanity.sh `pwd`/cvs$(EXEEXT) - -.PHONY: remotecheck -remotecheck: all - $(SHELL) $(srcdir)/sanity.sh -r `pwd`/cvs$(EXEEXT) - -## MAINTAINER Targets - -# for backwards compatibility with the old makefiles -.PHONY: realclean -realclean: maintainer-clean diff --git a/contrib/cvs/src/Makefile.in b/contrib/cvs/src/Makefile.in deleted file mode 100644 index d88773c..0000000 --- a/contrib/cvs/src/Makefile.in +++ /dev/null @@ -1,658 +0,0 @@ -# Makefile.in generated by automake 1.10 from Makefile.am. -# @configure_input@ - -# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006 Free Software Foundation, Inc. -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ - -# Makefile for GNU CVS program. -# -# Copyright (C) 1986-2005 The Free Software Foundation, Inc. -# -# Portions Copyright (C) 1998-2005 Derek Price, Ximbiot , -# and others. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - - -VPATH = @srcdir@ -pkgdatadir = $(datadir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -bin_PROGRAMS = cvs$(EXEEXT) -subdir = src -DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ - $(srcdir)/cvsbug.in ChangeLog -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ - $(top_srcdir)/configure.in -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs -CONFIG_HEADER = $(top_builddir)/config.h -CONFIG_CLEAN_FILES = cvsbug -am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(bindir)" -binPROGRAMS_INSTALL = $(INSTALL_PROGRAM) -PROGRAMS = $(bin_PROGRAMS) -am_cvs_OBJECTS = add.$(OBJEXT) admin.$(OBJEXT) annotate.$(OBJEXT) \ - buffer.$(OBJEXT) checkin.$(OBJEXT) checkout.$(OBJEXT) \ - classify.$(OBJEXT) client.$(OBJEXT) commit.$(OBJEXT) \ - create_adm.$(OBJEXT) cvsrc.$(OBJEXT) diff.$(OBJEXT) \ - edit.$(OBJEXT) entries.$(OBJEXT) error.$(OBJEXT) \ - expand_path.$(OBJEXT) fileattr.$(OBJEXT) filesubr.$(OBJEXT) \ - find_names.$(OBJEXT) hardlink.$(OBJEXT) hash.$(OBJEXT) \ - history.$(OBJEXT) ignore.$(OBJEXT) import.$(OBJEXT) \ - lock.$(OBJEXT) log.$(OBJEXT) login.$(OBJEXT) logmsg.$(OBJEXT) \ - main.$(OBJEXT) mkmodules.$(OBJEXT) modules.$(OBJEXT) \ - myndbm.$(OBJEXT) no_diff.$(OBJEXT) parseinfo.$(OBJEXT) \ - patch.$(OBJEXT) rcs.$(OBJEXT) rcscmds.$(OBJEXT) \ - recurse.$(OBJEXT) release.$(OBJEXT) remove.$(OBJEXT) \ - repos.$(OBJEXT) root.$(OBJEXT) run.$(OBJEXT) \ - scramble.$(OBJEXT) server.$(OBJEXT) stack.$(OBJEXT) \ - status.$(OBJEXT) subr.$(OBJEXT) tag.$(OBJEXT) update.$(OBJEXT) \ - version.$(OBJEXT) vers_ts.$(OBJEXT) watch.$(OBJEXT) \ - wrapper.$(OBJEXT) zlib.$(OBJEXT) -cvs_OBJECTS = $(am_cvs_OBJECTS) -cvs_DEPENDENCIES = ../diff/libdiff.a ../lib/libcvs.a ../zlib/libz.a -binSCRIPT_INSTALL = $(INSTALL_SCRIPT) -SCRIPTS = $(bin_SCRIPTS) -DEFAULT_INCLUDES = -I. -I$(top_builddir)@am__isrc@ -depcomp = $(SHELL) $(top_srcdir)/depcomp -am__depfiles_maybe = depfiles -COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ - $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -CCLD = $(CC) -LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ -SOURCES = $(cvs_SOURCES) -DIST_SOURCES = $(cvs_SOURCES) -ETAGS = etags -CTAGS = ctags -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -ACLOCAL = @ACLOCAL@ -AMTAR = @AMTAR@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -CC = @CC@ -CCDEPMODE = @CCDEPMODE@ -CFLAGS = @CFLAGS@ -CPP = @CPP@ -CPPFLAGS = @CPPFLAGS@ -CSH = @CSH@ -CYGPATH_W = @CYGPATH_W@ -DEFS = @DEFS@ -DEPDIR = @DEPDIR@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EDITOR = @EDITOR@ -EGREP = @EGREP@ -EXEEXT = @EXEEXT@ -GREP = @GREP@ -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -KRB4 = @KRB4@ -LDFLAGS = @LDFLAGS@ -LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ -LN_S = @LN_S@ -LTLIBOBJS = @LTLIBOBJS@ -MAINT = @MAINT@ -MAKEINFO = @MAKEINFO@ -MKDIR_P = @MKDIR_P@ -MKTEMP = @MKTEMP@ -OBJEXT = @OBJEXT@ -PACKAGE = @PACKAGE@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ -PACKAGE_NAME = @PACKAGE_NAME@ -PACKAGE_STRING = @PACKAGE_STRING@ -PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -PERL = @PERL@ -PR = @PR@ -PS2PDF = @PS2PDF@ -RANLIB = @RANLIB@ -ROFF = @ROFF@ -SENDMAIL = @SENDMAIL@ -SET_MAKE = @SET_MAKE@ -SHELL = /bin/sh -STRIP = @STRIP@ -TEXI2DVI = @TEXI2DVI@ -VERSION = @VERSION@ -YACC = @YACC@ -YFLAGS = @YFLAGS@ -abs_builddir = @abs_builddir@ -abs_srcdir = @abs_srcdir@ -abs_top_builddir = @abs_top_builddir@ -abs_top_srcdir = @abs_top_srcdir@ -ac_ct_CC = @ac_ct_CC@ -ac_prefix_program = @ac_prefix_program@ -am__include = @am__include@ -am__leading_dot = @am__leading_dot@ -am__quote = @am__quote@ -am__tar = @am__tar@ -am__untar = @am__untar@ -bindir = @bindir@ -build_alias = @build_alias@ -builddir = @builddir@ -datadir = @datadir@ -datarootdir = @datarootdir@ -docdir = @docdir@ -dvidir = @dvidir@ -exec_prefix = @exec_prefix@ -host_alias = @host_alias@ -htmldir = @htmldir@ -includedir = @includedir@ -includeopt = @includeopt@ -infodir = @infodir@ -install_sh = @install_sh@ -libdir = @libdir@ -libexecdir = @libexecdir@ -localedir = @localedir@ -localstatedir = @localstatedir@ -mandir = @mandir@ -mkdir_p = @mkdir_p@ -oldincludedir = @oldincludedir@ -pdfdir = @pdfdir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -psdir = @psdir@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -srcdir = @srcdir@ -sysconfdir = @sysconfdir@ -target_alias = @target_alias@ -top_builddir = @top_builddir@ -top_srcdir = @top_srcdir@ -with_default_rsh = @with_default_rsh@ -with_default_ssh = @with_default_ssh@ - -# $(includeopt) is CVS specific and set by configure -# FIXME - This includes line is dependant on its order. This means there is -# some namespace hackery going on that maybe shouldn't be. Long term fix is to -# try and remove naming ocnflicts and fix Automake to allow particular includes -# to be attached only to particular object files. Short term fix is either or. -INCLUDES = -I$(top_srcdir)/lib -I$(top_srcdir)/diff -I$(top_srcdir)/zlib $(includeopt) -bin_SCRIPTS = cvsbug - -# The cvs executable -cvs_SOURCES = \ - add.c \ - admin.c \ - annotate.c \ - buffer.c \ - checkin.c \ - checkout.c \ - classify.c \ - client.c \ - commit.c \ - create_adm.c \ - cvsrc.c diff.c \ - edit.c \ - entries.c \ - error.c \ - expand_path.c \ - fileattr.c \ - filesubr.c \ - find_names.c \ - hardlink.c \ - hash.c \ - history.c \ - ignore.c \ - import.c \ - lock.c \ - log.c \ - login.c \ - logmsg.c \ - main.c \ - mkmodules.c \ - modules.c \ - myndbm.c \ - no_diff.c \ - parseinfo.c \ - patch.c \ - rcs.c \ - rcscmds.c \ - recurse.c \ - release.c \ - remove.c \ - repos.c \ - root.c \ - run.c \ - scramble.c \ - server.c \ - stack.c \ - status.c \ - subr.c \ - tag.c \ - update.c \ - version.c \ - vers_ts.c \ - watch.c \ - wrapper.c \ - zlib.c \ - buffer.h \ - client.h \ - cvs.h \ - edit.h \ - error.h \ - fileattr.h \ - hardlink.h \ - hash.h \ - history.h \ - myndbm.h \ - rcs.h \ - root.h \ - server.h \ - stack.h \ - update.h \ - watch.h - -cvs_LDADD = \ - ../diff/libdiff.a \ - ../lib/libcvs.a \ - ../zlib/libz.a - - -# extra clean targets -# wish this could be distclean-hdr-local but it's not part of automake -DISTCLEANFILES = check.log check.plog - -# General -EXTRA_DIST = \ - .cvsignore \ - ChangeLog-9194 \ - ChangeLog-9395 \ - ChangeLog-96 \ - ChangeLog-97 \ - build_src.com \ - sanity.sh - -all: all-am - -.SUFFIXES: -.SUFFIXES: .c .o .obj -$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ - && exit 0; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/Makefile'; \ - cd $(top_srcdir) && \ - $(AUTOMAKE) --gnu src/Makefile -.PRECIOUS: Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - @case '$?' in \ - *config.status*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ - *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ - esac; - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh - -$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -cvsbug: $(top_builddir)/config.status $(srcdir)/cvsbug.in - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ -install-binPROGRAMS: $(bin_PROGRAMS) - @$(NORMAL_INSTALL) - test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)" - @list='$(bin_PROGRAMS)'; for p in $$list; do \ - p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ - if test -f $$p \ - ; then \ - f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \ - echo " $(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(bindir)/$$f'"; \ - $(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(bindir)/$$f" || exit 1; \ - else :; fi; \ - done - -uninstall-binPROGRAMS: - @$(NORMAL_UNINSTALL) - @list='$(bin_PROGRAMS)'; for p in $$list; do \ - f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \ - echo " rm -f '$(DESTDIR)$(bindir)/$$f'"; \ - rm -f "$(DESTDIR)$(bindir)/$$f"; \ - done - -clean-binPROGRAMS: - -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) -cvs$(EXEEXT): $(cvs_OBJECTS) $(cvs_DEPENDENCIES) - @rm -f cvs$(EXEEXT) - $(LINK) $(cvs_OBJECTS) $(cvs_LDADD) $(LIBS) -install-binSCRIPTS: $(bin_SCRIPTS) - @$(NORMAL_INSTALL) - test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)" - @list='$(bin_SCRIPTS)'; for p in $$list; do \ - if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ - if test -f $$d$$p; then \ - f=`echo "$$p" | sed 's|^.*/||;$(transform)'`; \ - echo " $(binSCRIPT_INSTALL) '$$d$$p' '$(DESTDIR)$(bindir)/$$f'"; \ - $(binSCRIPT_INSTALL) "$$d$$p" "$(DESTDIR)$(bindir)/$$f"; \ - else :; fi; \ - done - -uninstall-binSCRIPTS: - @$(NORMAL_UNINSTALL) - @list='$(bin_SCRIPTS)'; for p in $$list; do \ - f=`echo "$$p" | sed 's|^.*/||;$(transform)'`; \ - echo " rm -f '$(DESTDIR)$(bindir)/$$f'"; \ - rm -f "$(DESTDIR)$(bindir)/$$f"; \ - done - -mostlyclean-compile: - -rm -f *.$(OBJEXT) - -distclean-compile: - -rm -f *.tab.c - -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/add.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/admin.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/annotate.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/buffer.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/checkin.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/checkout.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/classify.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/client.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/commit.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/create_adm.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cvsrc.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/diff.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/edit.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/entries.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/error.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/expand_path.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fileattr.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/filesubr.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/find_names.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hardlink.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hash.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/history.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ignore.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/import.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lock.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/log.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/login.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/logmsg.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mkmodules.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/modules.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/myndbm.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/no_diff.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/parseinfo.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/patch.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rcs.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rcscmds.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/recurse.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/release.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/remove.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/repos.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/root.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/run.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/scramble.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/server.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stack.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/status.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/subr.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tag.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/update.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vers_ts.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/version.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/watch.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wrapper.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zlib.Po@am__quote@ - -.c.o: -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(COMPILE) -c $< - -.c.obj: -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` -@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` - -ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ - mkid -fID $$unique -tags: TAGS - -TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - tags=; \ - here=`pwd`; \ - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ - if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ - test -n "$$unique" || unique=$$empty_fix; \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$tags $$unique; \ - fi -ctags: CTAGS -CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - tags=; \ - here=`pwd`; \ - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ - test -z "$(CTAGS_ARGS)$$tags$$unique" \ - || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ - $$tags $$unique - -GTAGS: - here=`$(am__cd) $(top_builddir) && pwd` \ - && cd $(top_srcdir) \ - && gtags -i $(GTAGS_ARGS) $$here - -distclean-tags: - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags - -distdir: $(DISTFILES) - @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - list='$(DISTFILES)'; \ - dist_files=`for file in $$list; do echo $$file; done | \ - sed -e "s|^$$srcdirstrip/||;t" \ - -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ - case $$dist_files in \ - */*) $(MKDIR_P) `echo "$$dist_files" | \ - sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ - sort -u` ;; \ - esac; \ - for file in $$dist_files; do \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - if test -d $$d/$$file; then \ - dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ - fi; \ - cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ - else \ - test -f $(distdir)/$$file \ - || cp -p $$d/$$file $(distdir)/$$file \ - || exit 1; \ - fi; \ - done -check-am: all-am - $(MAKE) $(AM_MAKEFLAGS) check-local -check: check-am -all-am: Makefile $(PROGRAMS) $(SCRIPTS) -installdirs: - for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(bindir)"; do \ - test -z "$$dir" || $(MKDIR_P) "$$dir"; \ - done -install: install-am -install-exec: install-exec-am -install-data: install-data-am -uninstall: uninstall-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-am -install-strip: - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - `test -z '$(STRIP)' || \ - echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install -mostlyclean-generic: - -clean-generic: - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." -clean: clean-am - -clean-am: clean-binPROGRAMS clean-generic mostlyclean-am - -distclean: distclean-am - -rm -rf ./$(DEPDIR) - -rm -f Makefile -distclean-am: clean-am distclean-compile distclean-generic \ - distclean-tags - -dvi: dvi-am - -dvi-am: - -html: html-am - -info: info-am - -info-am: - -install-data-am: - -install-dvi: install-dvi-am - -install-exec-am: install-binPROGRAMS install-binSCRIPTS - -install-html: install-html-am - -install-info: install-info-am - -install-man: - -install-pdf: install-pdf-am - -install-ps: install-ps-am - -installcheck-am: - -maintainer-clean: maintainer-clean-am - -rm -rf ./$(DEPDIR) - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-am - -mostlyclean-am: mostlyclean-compile mostlyclean-generic - -pdf: pdf-am - -pdf-am: - -ps: ps-am - -ps-am: - -uninstall-am: uninstall-binPROGRAMS uninstall-binSCRIPTS - -.MAKE: install-am install-strip - -.PHONY: CTAGS GTAGS all all-am check check-am check-local clean \ - clean-binPROGRAMS clean-generic ctags distclean \ - distclean-compile distclean-generic distclean-tags distdir dvi \ - dvi-am html html-am info info-am install install-am \ - install-binPROGRAMS install-binSCRIPTS install-data \ - install-data-am install-dvi install-dvi-am install-exec \ - install-exec-am install-html install-html-am install-info \ - install-info-am install-man install-pdf install-pdf-am \ - install-ps install-ps-am install-strip installcheck \ - installcheck-am installdirs maintainer-clean \ - maintainer-clean-generic mostlyclean mostlyclean-compile \ - mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \ - uninstall-am uninstall-binPROGRAMS uninstall-binSCRIPTS - - -check-local: localcheck remotecheck - -.PHONY: localcheck -localcheck: - $(SHELL) $(srcdir)/sanity.sh `pwd`/cvs$(EXEEXT) - -.PHONY: remotecheck -remotecheck: all - $(SHELL) $(srcdir)/sanity.sh -r `pwd`/cvs$(EXEEXT) - -# for backwards compatibility with the old makefiles -.PHONY: realclean -realclean: maintainer-clean -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/contrib/cvs/src/add.c b/contrib/cvs/src/add.c deleted file mode 100644 index 228ae69..0000000 --- a/contrib/cvs/src/add.c +++ /dev/null @@ -1,951 +0,0 @@ -/* - * Copyright (C) 1986-2005 The Free Software Foundation, Inc. - * - * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot , - * and others. - * - * Portions Copyright (c) 1992, Brian Berliner and Jeff Polk - * Portions Copyright (c) 1989-1992, Brian Berliner - * - * You may distribute under the terms of the GNU General Public License as - * specified in the README file that comes with the CVS source distribution. - * - * Add - * - * Adds a file or directory to the RCS source repository. For a file, - * the entry is marked as "needing to be added" in the user's own CVS - * directory, and really added to the repository when it is committed. - * For a directory, it is added at the appropriate place in the source - * repository and a CVS directory is generated within the directory. - * - * The -m option is currently the only supported option. Some may wish to - * supply standard "rcs" options here, but I've found that this causes more - * trouble than anything else. - * - * The user files or directories must already exist. For a directory, it must - * not already have a CVS file in it. - * - * An "add" on a file that has been "remove"d but not committed will cause the - * file to be resurrected. - */ - -#include -#include "cvs.h" -#include "savecwd.h" -#include "fileattr.h" - -static int add_directory PROTO ((struct file_info *finfo)); -static int build_entry PROTO((const char *repository, const char *user, - const char *options, const char *message, - List * entries, const char *tag)); - -static const char *const add_usage[] = -{ - "Usage: %s %s [-k rcs-kflag] [-m message] files...\n", - "\t-k rcs-kflag\tUse \"rcs-kflag\" to add the file with the specified\n", - "\t\t\tkflag.\n", - "\t-m message\tUse \"message\" for the creation log.\n", - "(Specify the --help global option for a list of other help options)\n", - NULL -}; - -int -add (argc, argv) - int argc; - char **argv; -{ - char *message = NULL; - int i; - char *repository; - int c; - int err = 0; - int added_files = 0; - char *options = NULL; - List *entries; - Vers_TS *vers; - struct saved_cwd cwd; - /* 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); - - wrap_setup (); - - /* parse args */ - optind = 0; - while ((c = getopt (argc, argv, "+k:m:")) != -1) - { - switch (c) - { - case 'k': - if (options) free (options); - options = RCS_check_kflag (optarg); - break; - - case 'm': - if (message) free (message); - message = xstrdup (optarg); - break; - case '?': - default: - usage (add_usage); - break; - } - } - argc -= optind; - argv += optind; - - if (argc <= 0) - usage (add_usage); - - cvsroot_len = strlen (current_parsed_root->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. */ - for (i = 0; i < argc; i++) - { - int skip_file = 0; - - /* If it were up to me I'd probably make this a fatal error. - But some people are really fond of their "cvs add *", and - don't seem to object to the warnings. - Whatever. */ - strip_trailing_slashes (argv[i]); - if (strcmp (argv[i], ".") == 0 - || strcmp (argv[i], "..") == 0 - || fncmp (last_component(argv[i]), CVSADM) == 0) - { - if (!quiet) - error (0, 0, "cannot add special file `%s'; skipping", argv[i]); - skip_file = 1; - } - else - { - char *p; - p = argv[i]; - while (*p != '\0') - { - if (ISDIRSEP (*p)) - { - found_slash = 1; - break; - } - ++p; - } - } - - if (skip_file) - { - int j; - - /* FIXME: We don't do anything about free'ing argv[i]. But - the problem is that it is only sometimes allocated (see - cvsrc.c). */ - - for (j = i; j < argc - 1; ++j) - argv[j] = argv[j + 1]; - --argc; - /* Check the new argv[i] again. */ - --i; - ++err; - } - } - -#ifdef CLIENT_SUPPORT - if (current_parsed_root->isremote) - { - int j; - - if (argc == 0) - { - /* We snipped out all the arguments in the above sanity - check. We can just forget the whole thing (and we - better, because if we fired up the server and passed it - nothing, it would spit back a usage message). */ - if (options) - free (options); - if (message) - free (message); - return err; - } - - start_server (); - ign_setup (); - if (options) - { - send_arg (options); - free (options); - } - option_with_arg ("-m", message); - send_arg ("--"); - - /* If !found_slash, refrain from sending "Directory", for - CVS 1.9 compatibility. If we only tried to deal with servers - which are at least CVS 1.9.26 or so, we wouldn't have to - special-case this. */ - if (found_slash) - { - repository = Name_Repository (NULL, NULL); - send_a_repository ("", repository, ""); - free (repository); - } - - for (j = 0; j < argc; ++j) - { - /* FIXME: Does this erroneously call Create_Admin in error - conditions which are only detected once the server gets its - hands on things? */ - if (isdir (argv[j])) - { - char *tag; - char *date; - int nonbranch; - char *rcsdir; - char *p; - char *update_dir; - /* This is some mungeable storage into which we can point - with p and/or update_dir. */ - char *filedir; - - if (save_cwd (&cwd)) - error_exit (); - - filedir = xstrdup (argv[j]); - /* Deliberately discard the const below since we know we just - * allocated filedir and can do what we like with it. - */ - p = (char *)last_component (filedir); - if (p == filedir) - { - update_dir = ""; - } - else - { - p[-1] = '\0'; - update_dir = filedir; - if (CVS_CHDIR (update_dir) < 0) - error (1, errno, - "could not chdir to %s", update_dir); - } - - /* find the repository associated with our current dir */ - repository = Name_Repository (NULL, update_dir); - - /* don't add stuff to Emptydir */ - if (strncmp (repository, current_parsed_root->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); - - rcsdir = xmalloc (strlen (repository) + strlen (p) + 5); - sprintf (rcsdir, "%s/%s", repository, p); - - Create_Admin (p, argv[j], rcsdir, tag, date, - nonbranch, 0, 1); - - if (found_slash) - send_a_repository ("", repository, update_dir); - - if (restore_cwd (&cwd, NULL)) - error_exit (); - free_cwd (&cwd); - - if (tag) - free (tag); - if (date) - free (date); - free (rcsdir); - - if (p == filedir) - Subdir_Register ((List *) NULL, (char *) NULL, argv[j]); - else - { - Subdir_Register ((List *) NULL, update_dir, p); - } - free (repository); - free (filedir); - } - } - send_files (argc, argv, 0, 0, SEND_BUILD_DIRS | SEND_NO_CONTENTS); - send_file_names (argc, argv, SEND_EXPAND_WILD); - send_to_server ("add\012", 0); - if (message) - free (message); - return err + get_responses_and_close (); - } -#endif - - /* walk the arg list adding files/dirs */ - for (i = 0; i < argc; i++) - { - int begin_err = err; -#ifdef SERVER_SUPPORT - int begin_added_files = added_files; -#endif - struct file_info finfo; - char *filename, *p; - - memset (&finfo, 0, sizeof finfo); - - if (save_cwd (&cwd)) - error_exit (); - - finfo.fullname = xstrdup (argv[i]); - filename = xstrdup (argv[i]); - /* We know we can discard the const below since we just allocated - * filename and can do as we like with it. - */ - p = (char *)last_component (filename); - if (p == filename) - { - finfo.update_dir = ""; - finfo.file = p; - } - else - { - p[-1] = '\0'; - finfo.update_dir = filename; - finfo.file = p; - if (CVS_CHDIR (finfo.update_dir) < 0) - error (1, errno, "could not chdir to %s", finfo.update_dir); - } - - /* Add wrappers for this directory. They exist only until - the next call to wrap_add_file. */ - wrap_add_file (CVSDOTWRAPPER, 1); - - finfo.rcs = NULL; - - /* Find the repository associated with our current dir. */ - repository = Name_Repository (NULL, finfo.update_dir); - - /* don't add stuff to Emptydir */ - if (strncmp (repository, current_parsed_root->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; - finfo.entries = entries; - - /* We pass force_tag_match as 1. If the directory has a - sticky branch tag, and there is already an RCS file which - does not have that tag, then the head revision is - meaningless to us. */ - vers = Version_TS (&finfo, options, NULL, NULL, 1, 0); - - if (vers->vn_user == NULL) - { - /* No entry available, ts_rcs is invalid */ - if (vers->vn_rcs == NULL) - { - /* There is no RCS file either */ - if (vers->ts_user == NULL) - { - /* There is no user file either */ - error (0, 0, "nothing known about %s", finfo.fullname); - err++; - } - else if (!isdir (finfo.file) - || wrap_name_has (finfo.file, WRAP_TOCVS)) - { - /* - * See if a directory exists in the repository with - * the same name. If so, blow this request off. - */ - char *dname = xmalloc (strlen (repository) - + strlen (finfo.file) - + 10); - (void) sprintf (dname, "%s/%s", repository, finfo.file); - if (isdir (dname)) - { - error (0, 0, - "cannot add file `%s' since the directory", - finfo.fullname); - error (0, 0, "`%s' already exists in the repository", - dname); - error (1, 0, "illegal filename overlap"); - } - free (dname); - - if (vers->options == NULL || *vers->options == '\0') - { - /* No options specified on command line (or in - rcs file if it existed, e.g. the file exists - on another branch). Check for a value from - the wrapper stuff. */ - if (wrap_name_has (finfo.file, WRAP_RCSOPTION)) - { - if (vers->options) - free (vers->options); - vers->options = wrap_rcsoption (finfo.file, 1); - } - } - - if (vers->nonbranch) - { - error (0, 0, - "cannot add file on non-branch tag %s", - vers->tag); - ++err; - } - else - { - /* There is a user file, so build the entry for it */ - if (build_entry (repository, finfo.file, vers->options, - message, entries, vers->tag) != 0) - err++; - else - { - added_files++; - if (!quiet) - { - if (vers->tag) - error (0, 0, "\ -scheduling %s `%s' for addition on branch `%s'", - (wrap_name_has (finfo.file, - WRAP_TOCVS) - ? "wrapper" - : "file"), - finfo.fullname, vers->tag); - else - error (0, 0, - "scheduling %s `%s' for addition", - (wrap_name_has (finfo.file, - WRAP_TOCVS) - ? "wrapper" - : "file"), - finfo.fullname); - } - } - } - } - } - else if (RCS_isdead (vers->srcfile, vers->vn_rcs)) - { - if (isdir (finfo.file) - && !wrap_name_has (finfo.file, WRAP_TOCVS)) - { - error (0, 0, "\ -the directory `%s' cannot be added because a file of the", finfo.fullname); - error (1, 0, "\ -same name already exists in the repository."); - } - else - { - if (vers->nonbranch) - { - error (0, 0, - "cannot add file on non-branch tag %s", - vers->tag); - ++err; - } - else - { - char *timestamp = NULL; - if (vers->ts_user == NULL) - { - /* If this file does not exist locally, assume that - * the last version on the branch is being - * resurrected. - * - * Compute previous revision. We assume that it - * exists and that it is not a revision on the - * trunk of the form X.1 (1.1, 2.1, 3.1, ...). We - * also assume that it is not dead, which seems - * fair since we know vers->vn_rcs is dead - * and we shouldn't see two dead revisions in a - * row. - */ - char *prev = previous_rev (vers->srcfile, - vers->vn_rcs); - int status; - if (prev == NULL) - { - /* There is no previous revision. Either: - * - * * Revision 1.1 was dead, as when a file was - * inititially added on a branch, - * - * or - * - * * All previous revisions have been deleted. - * For instance, via `admin -o'. - */ - if (!really_quiet) - error (0, 0, -"File `%s' has no previous revision to resurrect.", - finfo.fullname); - free (prev); - goto skip_this_file; - } - if (!quiet) - error (0, 0, -"Resurrecting file `%s' from revision %s.", - finfo.fullname, prev); - status = RCS_checkout (vers->srcfile, finfo.file, - prev, vers->tag, - vers->options, RUN_TTY, - NULL, NULL); - xchmod (finfo.file, 1); - if (status != 0) - { - error (0, 0, "Failed to resurrect revision %s", - prev); - err++; - } - else - { - /* I don't actually set vers->ts_user here - * because it would confuse server_update(). - */ - timestamp = time_stamp (finfo.file); - if (!really_quiet) - write_letter (&finfo, 'U'); - } - free (prev); - } - if (!quiet) - { - if (vers->tag) - error (0, 0, -"file `%s' will be added on branch `%s' from version %s", - finfo.fullname, vers->tag, - vers->vn_rcs); - else - /* I'm not sure that mentioning - vers->vn_rcs makes any sense here; I - can't think of a way to word the - message which is not confusing. */ - error (0, 0, -"Re-adding file `%s' (in place of dead revision %s).", - finfo.fullname, vers->vn_rcs); - } - Register (entries, finfo.file, "0", - timestamp ? timestamp : vers->ts_user, - vers->options, vers->tag, vers->date, NULL); - if (timestamp) free (timestamp); -#ifdef SERVER_SUPPORT - if (server_active && vers->ts_user == NULL) - { - /* If we resurrected the file from the archive, we - * need to tell the client about it. - */ - server_updated (&finfo, vers, - SERVER_UPDATED, - (mode_t) -1, NULL, NULL); - /* This is kinda hacky or, at least, it renders the - * name "begin_added_files" obsolete, but we want - * the added_files to be counted without triggering - * the check that causes server_checked_in() to be - * called below since we have already called - * server_updated() to complete the resurrection. - */ - ++begin_added_files; - } -#endif - ++added_files; - } - } - } - else - { - /* - * There is an RCS file already, so somebody else must've - * added it - */ - error (0, 0, "%s added independently by second party", - finfo.fullname); - err++; - } - } - else if (vers->vn_user[0] == '0' && vers->vn_user[1] == '\0') - { - - /* - * An entry for a new-born file, ts_rcs is dummy, but that is - * inappropriate here - */ - if (!quiet) - error (0, 0, "%s has already been entered", finfo.fullname); - err++; - } - else if (vers->vn_user[0] == '-') - { - /* An entry for a removed file, ts_rcs is invalid */ - if (vers->ts_user == NULL) - { - /* There is no user file (as it should be) */ - if (vers->vn_rcs == NULL) - { - - /* - * There is no RCS file, so somebody else must've removed - * it from under us - */ - error (0, 0, "\ -cannot resurrect %s; RCS file removed by second party", finfo.fullname); - err++; - } - else - { - int status; - /* - * There is an RCS file, so remove the "-" from the - * version number and restore the file - */ - char *tmp = xmalloc (strlen (vers->vn_user)); - (void) strcpy (tmp, vers->vn_user + 1); - (void) strcpy (vers->vn_user, tmp); - free(tmp); - status = RCS_checkout (vers->srcfile, finfo.file, - vers->vn_user, vers->tag, - vers->options, RUN_TTY, - NULL, NULL); - xchmod (finfo.file, 1); - if (status != 0) - { - error (0, 0, "Failed to resurrect revision %s", - vers->vn_user); - err++; - tmp = NULL; - } - else - { - /* I don't actually set vers->ts_user here because it - * would confuse server_update(). - */ - tmp = time_stamp (finfo.file); - write_letter (&finfo, 'U'); - if (!quiet) - error (0, 0, "%s, version %s, resurrected", - finfo.fullname, vers->vn_user); - } - Register (entries, finfo.file, vers->vn_user, - tmp, vers->options, - vers->tag, vers->date, NULL); - if (tmp) free (tmp); -#ifdef SERVER_SUPPORT - if (server_active) - { - /* If we resurrected the file from the archive, we - * need to tell the client about it. - */ - server_updated (&finfo, vers, - SERVER_UPDATED, - (mode_t) -1, NULL, NULL); - } - /* We don't increment added_files here because this isn't - * a change that needs to be committed. - */ -#endif - } - } - else - { - /* The user file shouldn't be there */ - error (0, 0, "\ -%s should be removed and is still there (or is back again)", finfo.fullname); - err++; - } - } - else - { - /* A normal entry, ts_rcs is valid, so it must already be there */ - if (!quiet) - error (0, 0, "%s already exists, with version number %s", - finfo.fullname, - vers->vn_user); - err++; - } - freevers_ts (&vers); - - /* passed all the checks. Go ahead and add it if its a directory */ - if (begin_err == err - && isdir (finfo.file) - && !wrap_name_has (finfo.file, WRAP_TOCVS)) - { - err += add_directory (&finfo); - } - else - { -#ifdef SERVER_SUPPORT - if (server_active && begin_added_files != added_files) - server_checked_in (finfo.file, finfo.update_dir, repository); -#endif - } - -skip_this_file: - free (repository); - Entries_Close (entries); - - if (restore_cwd (&cwd, NULL)) - error_exit (); - free_cwd (&cwd); - - /* It's okay to discard the const to free this - we allocated this - * above. The const is for everybody else. - */ - free ((char *) finfo.fullname); - free ((char *) filename); - } - if (added_files && !really_quiet) - error (0, 0, "use '%s commit' to add %s permanently", - program_name, - (added_files == 1) ? "this file" : "these files"); - - if (message) - free (message); - if (options) - free (options); - - return err; -} - - - -/* - * The specified user file is really a directory. So, let's make sure that - * it is created in the RCS source repository, and that the user's directory - * is updated to include a CVS directory. - * - * Returns 1 on failure, 0 on success. - */ -static int -add_directory (finfo) - struct file_info *finfo; -{ - const char *repository = finfo->repository; - List *entries = finfo->entries; - const char *dir = finfo->file; - - char *rcsdir = NULL; - struct saved_cwd cwd; - char *message = NULL; - char *tag, *date; - int nonbranch; - char *attrs; - - if (strchr (dir, '/') != NULL) - { - /* "Can't happen". */ - error (0, 0, - "directory %s not added; must be a direct sub-directory", dir); - return 1; - } - if (fncmp (dir, CVSADM) == 0) - { - error (0, 0, "cannot add a `%s' directory", CVSADM); - return 1; - } - - /* before we do anything else, see if we have any per-directory tags */ - ParseTag (&tag, &date, &nonbranch); - - /* Remember the default attributes from this directory, so we can apply - them to the new directory. */ - fileattr_startdir (repository); - attrs = fileattr_getall (NULL); - fileattr_free (); - - /* now, remember where we were, so we can get back */ - if (save_cwd (&cwd)) - return 1; - if (CVS_CHDIR (dir) < 0) - { - error (0, errno, "cannot chdir to %s", finfo->fullname); - return 1; - } - if (!server_active && isfile (CVSADM)) - { - error (0, 0, "%s/%s already exists", finfo->fullname, CVSADM); - goto out; - } - - rcsdir = xmalloc (strlen (repository) + strlen (dir) + 5); - sprintf (rcsdir, "%s/%s", repository, dir); - if (isfile (rcsdir) && !isdir (rcsdir)) - { - error (0, 0, "%s is not a directory; %s not added", rcsdir, - finfo->fullname); - goto out; - } - - /* setup the log message */ - message = xmalloc (strlen (rcsdir) - + 80 - + (tag == NULL ? 0 : strlen (tag) + 80) - + (date == NULL ? 0 : strlen (date) + 80)); - (void) sprintf (message, "Directory %s added to the repository\n", - rcsdir); - if (tag) - { - (void) strcat (message, "--> Using per-directory sticky tag `"); - (void) strcat (message, tag); - (void) strcat (message, "'\n"); - } - if (date) - { - (void) strcat (message, "--> Using per-directory sticky date `"); - (void) strcat (message, date); - (void) strcat (message, "'\n"); - } - - if (!isdir (rcsdir)) - { - mode_t omask; - Node *p; - List *ulist; - struct logfile_info *li; - - /* There used to be some code here which would prompt for - whether to add the directory. The details of that code had - bitrotted, but more to the point it can't work - client/server, doesn't ask in the right way for GUIs, etc. - A better way of making it harder to accidentally add - directories would be to have to add and commit directories - like for files. The code was #if 0'd at least since CVS 1.5. */ - - if (!noexec) - { - omask = umask (cvsumask); - if (CVS_MKDIR (rcsdir, 0777) < 0) - { - error (0, errno, "cannot mkdir %s", rcsdir); - (void) umask (omask); - goto out; - } - (void) umask (omask); - } - - /* Now set the default file attributes to the ones we inherited - from the parent directory. */ - fileattr_startdir (rcsdir); - fileattr_setall (NULL, attrs); - fileattr_write (); - fileattr_free (); - if (attrs != NULL) - { - free (attrs); - attrs = NULL; - } - - /* - * Set up an update list with a single title node for Update_Logfile - */ - ulist = getlist (); - p = getnode (); - p->type = UPDATE; - p->delproc = update_delproc; - p->key = xstrdup ("- New directory"); - li = (struct logfile_info *) xmalloc (sizeof (struct logfile_info)); - li->type = T_TITLE; - li->tag = xstrdup (tag); - li->rev_old = li->rev_new = NULL; - p->data = li; - (void) addnode (ulist, p); - Update_Logfile (rcsdir, message, (FILE *) NULL, ulist); - dellist (&ulist); - } - - if (!server_active) - Create_Admin (".", finfo->fullname, rcsdir, tag, date, nonbranch, 0, 1); - if (tag) - free (tag); - if (date) - free (date); - - if (restore_cwd (&cwd, NULL)) - error_exit (); - free_cwd (&cwd); - - Subdir_Register (entries, (char *) NULL, dir); - - if (!really_quiet) - cvs_output (message, 0); - - free (rcsdir); - free (message); - if (attrs != NULL) - free (attrs); - - return 0; - -out: - if (restore_cwd (&cwd, NULL)) - error_exit (); - free_cwd (&cwd); - if (message) free (message); - if (rcsdir != NULL) - free (rcsdir); - return 0; -} - - - -/* - * Builds an entry for a new file and sets up "CVS/file",[pt] by - * interrogating the user. Returns non-zero on error. - */ -static int -build_entry (repository, user, options, message, entries, tag) - const char *repository; - const char *user; - const char *options; - const char *message; - List *entries; - const char *tag; -{ - char *fname; - char *line; - FILE *fp; - - if (noexec) - return 0; - - /* - * The requested log is read directly from the user and stored in the - * file user,t. If the "message" argument is set, use it as the - * initial creation log (which typically describes the file). - */ - fname = xmalloc (strlen (user) + 80); - (void) sprintf (fname, "%s/%s%s", CVSADM, user, CVSEXT_LOG); - fp = open_file (fname, "w+"); - if (message && fputs (message, fp) == EOF) - error (1, errno, "cannot write to %s", fname); - if (fclose(fp) == EOF) - error(1, errno, "cannot close %s", fname); - free (fname); - - /* - * Create the entry now, since this allows the user to interrupt us above - * without needing to clean anything up (well, we could clean up the - * ,t file, but who cares). - */ - line = xmalloc (strlen (user) + 20); - (void) sprintf (line, "Initial %s", user); - Register (entries, user, "0", line, options, tag, (char *) 0, (char *) 0); - free (line); - return 0; -} diff --git a/contrib/cvs/src/admin.c b/contrib/cvs/src/admin.c deleted file mode 100644 index 186e27c..0000000 --- a/contrib/cvs/src/admin.c +++ /dev/null @@ -1,950 +0,0 @@ -/* - * Copyright (C) 1986-2005 The Free Software Foundation, Inc. - * - * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot , - * and others. - * - * Portions Copyright (c) 1992, Brian Berliner and Jeff Polk - * Portions Copyright (c) 1989-1992, Brian Berliner - * - * You may distribute under the terms of the GNU General Public License as - * specified in the README file that comes with the CVS source distribution. - * - * Administration ("cvs admin") - * - */ - -#include "cvs.h" -#ifdef CVS_ADMIN_GROUP -#include -#endif -#include - -static Dtype admin_dirproc PROTO ((void *callerdat, const char *dir, - const char *repos, const char *update_dir, - List *entries)); -static int admin_fileproc PROTO ((void *callerdat, struct file_info *finfo)); - -static const char *const admin_usage[] = -{ - "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) Substitute keyword and value.\n", - "\t kvl Substitute keyword, value, and locker (if any).\n", - "\t k Substitute keyword only.\n", - "\t o Preserve original string.\n", - "\t b Like o, but mark file as binary.\n", - "\t v Substitute 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, including rev1 and rev2.\n", - "\t rev1::rev2 Between rev1 and rev2, excluding rev1 and rev2.\n", - "\t rev: rev and following revisions on the same branch.\n", - "\t rev:: After rev on the same branch.\n", - "\t :rev rev and previous revisions on the same branch.\n", - "\t ::rev Before rev on the same branch.\n", - "\t rev Just rev.\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 -}; - -/* This structure is used to pass information through start_recursion. */ -struct admin_data -{ - /* Set default branch (-b). It is "-b" followed by the value - given, or NULL if not specified, or merely "-b" if -b is - specified without a value. */ - char *branch; - - /* Set comment leader (-c). It is "-c" followed by the value - given, or NULL if not specified. The comment leader is - relevant only for old versions of RCS, but we let people set it - anyway. */ - char *comment; - - /* Set strict locking (-L). */ - int set_strict; - - /* Set nonstrict locking (-U). */ - int set_nonstrict; - - /* Delete revisions (-o). It is "-o" followed by the value specified. */ - char *delete_revs; - - /* Keyword substitution mode (-k), e.g. "-kb". */ - char *kflag; - - /* Description (-t). */ - char *desc; - - /* Interactive (-I). Problematic with client/server. */ - int interactive; - - /* This is the cheesy part. It is a vector with the options which - we don't deal with above (e.g. "-afoo" "-abar,baz"). In the future - this presumably will be replaced by other variables which break - out the data in a more convenient fashion. AV as well as each of - the strings it points to is malloc'd. */ - int ac; - char **av; - int av_alloc; -}; - -/* Add an argument. OPT is the option letter, e.g. 'a'. ARG is the - argument to that option, or NULL if omitted (whether NULL can actually - happen depends on whether the option was specified as optional to - getopt). */ -static void -arg_add (dat, opt, arg) - struct admin_data *dat; - int opt; - char *arg; -{ - char *newelt = xmalloc ((arg == NULL ? 0 : strlen (arg)) + 3); - strcpy (newelt, "-"); - newelt[1] = opt; - if (arg == NULL) - newelt[2] = '\0'; - else - strcpy (newelt + 2, arg); - - if (dat->av_alloc == 0) - { - dat->av_alloc = 1; - dat->av = (char **) xmalloc (dat->av_alloc * sizeof (*dat->av)); - } - else if (dat->ac >= dat->av_alloc) - { - dat->av_alloc *= 2; - dat->av = (char **) xrealloc (dat->av, - dat->av_alloc * sizeof (*dat->av)); - } - dat->av[dat->ac++] = newelt; -} - -int -admin (argc, argv) - int argc; - char **argv; -{ - int err; -#ifdef CVS_ADMIN_GROUP - struct group *grp; - struct group *getgrnam(); -#endif - struct admin_data admin_data; - int c; - int i; - int only_k_option; - - if (argc <= 1) - usage (admin_usage); - - wrap_setup (); - - memset (&admin_data, 0, sizeof admin_data); - - /* TODO: get rid of `-' switch notation in admin_data. For - example, admin_data->branch should be not `-bfoo' but simply `foo'. */ - - optind = 0; - only_k_option = 1; - while ((c = getopt (argc, argv, - "+ib::c:a:A:e::l::u::LUn:N:m:o:s:t::IqxV:k:")) != -1) - { - if (c != 'k' && c != 'q') - only_k_option = 0; - - switch (c) - { - case 'i': - /* This has always been documented as useless in cvs.texinfo - and it really is--admin_fileproc silently does nothing - if vers->vn_user is NULL. */ - error (0, 0, "the -i option to admin is not supported"); - error (0, 0, "run add or import to create an RCS file"); - goto usage_error; - - case 'b': - if (admin_data.branch != NULL) - { - error (0, 0, "duplicate 'b' option"); - goto usage_error; - } - if (optarg == NULL) - admin_data.branch = xstrdup ("-b"); - else - { - admin_data.branch = xmalloc (strlen (optarg) + 5); - strcpy (admin_data.branch, "-b"); - strcat (admin_data.branch, optarg); - } - break; - - case 'c': - if (admin_data.comment != NULL) - { - error (0, 0, "duplicate 'c' option"); - goto usage_error; - } - admin_data.comment = xmalloc (strlen (optarg) + 5); - strcpy (admin_data.comment, "-c"); - strcat (admin_data.comment, optarg); - break; - - case 'a': - arg_add (&admin_data, 'a', optarg); - break; - - case 'A': - /* In the client/server case, this is cheesy because - we just pass along the name of the RCS file, which - then will want to exist on the server. This is - accidental; having the client specify a pathname on - the server is not a design feature of the protocol. */ - arg_add (&admin_data, 'A', optarg); - break; - - case 'e': - arg_add (&admin_data, 'e', optarg); - break; - - case 'l': - /* Note that multiple -l options are legal. */ - arg_add (&admin_data, 'l', optarg); - break; - - case 'u': - /* Note that multiple -u options are legal. */ - arg_add (&admin_data, 'u', optarg); - break; - - case 'L': - /* Probably could also complain if -L is specified multiple - times, although RCS doesn't and I suppose it is reasonable - just to have it mean the same as a single -L. */ - if (admin_data.set_nonstrict) - { - error (0, 0, "-U and -L are incompatible"); - goto usage_error; - } - admin_data.set_strict = 1; - break; - - case 'U': - /* Probably could also complain if -U is specified multiple - times, although RCS doesn't and I suppose it is reasonable - just to have it mean the same as a single -U. */ - if (admin_data.set_strict) - { - error (0, 0, "-U and -L are incompatible"); - goto usage_error; - } - admin_data.set_nonstrict = 1; - break; - - case 'n': - /* Mostly similar to cvs tag. Could also be parsing - the syntax of optarg, although for now we just pass - it to rcs as-is. Note that multiple -n options are - legal. */ - arg_add (&admin_data, 'n', optarg); - break; - - case 'N': - /* Mostly similar to cvs tag. Could also be parsing - the syntax of optarg, although for now we just pass - it to rcs as-is. Note that multiple -N options are - legal. */ - arg_add (&admin_data, 'N', optarg); - break; - - case 'm': - /* Change log message. Could also be parsing the syntax - of optarg, although for now we just pass it to rcs - as-is. Note that multiple -m options are legal. */ - arg_add (&admin_data, 'm', optarg); - break; - - case 'o': - /* Delete revisions. Probably should also be parsing the - syntax of optarg, so that the client can give errors - rather than making the server take care of that. - Other than that I'm not sure whether it matters much - whether we parse it here or in admin_fileproc. - - Note that multiple -o options are illegal, in RCS - as well as here. */ - - if (admin_data.delete_revs != NULL) - { - error (0, 0, "duplicate '-o' option"); - goto usage_error; - } - admin_data.delete_revs = xmalloc (strlen (optarg) + 5); - strcpy (admin_data.delete_revs, "-o"); - strcat (admin_data.delete_revs, optarg); - break; - - case 's': - /* Note that multiple -s options are legal. */ - arg_add (&admin_data, 's', optarg); - break; - - case 't': - if (admin_data.desc != NULL) - { - error (0, 0, "duplicate 't' option"); - goto usage_error; - } - if (optarg != NULL && optarg[0] == '-') - admin_data.desc = xstrdup (optarg + 1); - else - { - size_t bufsize = 0; - size_t len; - - get_file (optarg, optarg, "r", &admin_data.desc, - &bufsize, &len); - } - break; - - case 'I': - /* At least in RCS this can be specified several times, - with the same meaning as being specified once. */ - admin_data.interactive = 1; - break; - - case 'q': - /* Silently set the global really_quiet flag. This keeps admin in - * sync with the RCS man page and allows us to silently support - * older servers when necessary. - * - * Some logic says we might want to output a deprecation warning - * here, but I'm opting not to in order to stay quietly in sync - * with the RCS man page. - */ - really_quiet = 1; - break; - - case 'x': - error (0, 0, "the -x option has never done anything useful"); - error (0, 0, "RCS files in CVS always end in ,v"); - goto usage_error; - - case 'V': - /* No longer supported. */ - error (0, 0, "the `-V' option is obsolete"); - break; - - case 'k': - if (admin_data.kflag != NULL) - { - error (0, 0, "duplicate '-k' option"); - goto usage_error; - } - admin_data.kflag = RCS_check_kflag (optarg); - break; - default: - case '?': - /* getopt will have printed an error message. */ - - usage_error: - /* Don't use cvs_cmd_name; it might be "server". */ - error (1, 0, "specify %s -H admin for usage information", - program_name); - } - } - argc -= optind; - argv += optind; - -#ifdef CVS_ADMIN_GROUP - /* The use of `cvs admin -k' is unrestricted. However, any other - option is restricted if the group CVS_ADMIN_GROUP exists on the - server. */ - /* This is only "secure" on the server, since the user could edit the - * RCS file on a local host, but some people like this kind of - * check anyhow. The alternative would be to check only when - * (server_active) rather than when not on the client. - */ - if (!current_parsed_root->isremote && !only_k_option && - (grp = getgrnam(CVS_ADMIN_GROUP)) != NULL) - { -#ifdef HAVE_GETGROUPS - gid_t *grps; - int n; - - /* get number of auxiliary groups */ - n = getgroups (0, NULL); - if (n < 0) - error (1, errno, "unable to get number of auxiliary groups"); - grps = (gid_t *) xmalloc((n + 1) * sizeof *grps); - n = getgroups (n, grps); - if (n < 0) - error (1, errno, "unable to get list of auxiliary groups"); - grps[n] = getgid(); - for (i = 0; i <= n; i++) - if (grps[i] == grp->gr_gid) break; - free (grps); - if (i > n) - error (1, 0, "usage is restricted to members of the group %s", - CVS_ADMIN_GROUP); -#else - char *me = getcaller(); - char **grnam; - - for (grnam = grp->gr_mem; *grnam; grnam++) - if (strcmp (*grnam, me) == 0) break; - if (!*grnam && getgid() != grp->gr_gid) - error (1, 0, "usage is restricted to members of the group %s", - CVS_ADMIN_GROUP); -#endif - } -#endif /* defined CVS_ADMIN_GROUP */ - - for (i = 0; i < admin_data.ac; ++i) - { - assert (admin_data.av[i][0] == '-'); - switch (admin_data.av[i][1]) - { - case 'm': - case 'l': - case 'u': - check_numeric (&admin_data.av[i][2], argc, argv); - break; - default: - break; - } - } - if (admin_data.branch != NULL) - check_numeric (admin_data.branch + 2, argc, argv); - if (admin_data.delete_revs != NULL) - { - char *p; - - check_numeric (admin_data.delete_revs + 2, argc, argv); - p = strchr (admin_data.delete_revs + 2, ':'); - if (p != NULL && isdigit ((unsigned char) p[1])) - check_numeric (p + 1, argc, argv); - else if (p != NULL && p[1] == ':' && isdigit ((unsigned char) p[2])) - check_numeric (p + 2, argc, argv); - } - -#ifdef CLIENT_SUPPORT - if (current_parsed_root->isremote) - { - /* We're the client side. Fire up the remote server. */ - start_server (); - - ign_setup (); - - /* Note that option_with_arg does not work for us, because some - of the options must be sent without a space between the option - and its argument. */ - if (admin_data.interactive) - error (1, 0, "-I option not useful with client/server"); - if (admin_data.branch != NULL) - send_arg (admin_data.branch); - if (admin_data.comment != NULL) - send_arg (admin_data.comment); - if (admin_data.set_strict) - send_arg ("-L"); - if (admin_data.set_nonstrict) - send_arg ("-U"); - if (admin_data.delete_revs != NULL) - send_arg (admin_data.delete_revs); - if (admin_data.desc != NULL) - { - 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); - } - /* Send this for all really_quiets since we know that it will be silently - * ignored when unneeded. This supports old servers. - */ - if (really_quiet) - send_arg ("-q"); - if (admin_data.kflag != NULL) - send_arg (admin_data.kflag); - - for (i = 0; i < admin_data.ac; ++i) - send_arg (admin_data.av[i]); - - send_arg ("--"); - send_files (argc, argv, 0, 0, SEND_NO_CONTENTS); - send_file_names (argc, argv, SEND_EXPAND_WILD); - send_to_server ("admin\012", 0); - err = get_responses_and_close (); - goto return_it; - } -#endif /* CLIENT_SUPPORT */ - - lock_tree_for_write (argc, argv, 0, W_LOCAL, 0); - - err = start_recursion (admin_fileproc, (FILESDONEPROC) NULL, admin_dirproc, - (DIRLEAVEPROC) NULL, (void *)&admin_data, - argc, argv, 0, - W_LOCAL, 0, CVS_LOCK_NONE, (char *) NULL, 1, - (char *) NULL); - Lock_Cleanup (); - - return_it: - if (admin_data.branch != NULL) - free (admin_data.branch); - if (admin_data.comment != NULL) - free (admin_data.comment); - if (admin_data.delete_revs != NULL) - free (admin_data.delete_revs); - if (admin_data.kflag != NULL) - free (admin_data.kflag); - if (admin_data.desc != NULL) - free (admin_data.desc); - for (i = 0; i < admin_data.ac; ++i) - free (admin_data.av[i]); - if (admin_data.av != NULL) - free (admin_data.av); - - return (err); -} - -/* - * Called to run "rcs" on a particular file. - */ -/* ARGSUSED */ -static int -admin_fileproc (callerdat, finfo) - void *callerdat; - struct file_info *finfo; -{ - struct admin_data *admin_data = (struct admin_data *) callerdat; - Vers_TS *vers; - char *version; - int i; - int status = 0; - RCSNode *rcs, *rcs2; - - vers = Version_TS (finfo, NULL, NULL, NULL, 0, 0); - - version = vers->vn_user; - if (version != NULL && strcmp (version, "0") == 0) - { - error (0, 0, "cannot admin newly added file `%s'", finfo->file); - status = 1; - goto exitfunc; - } - - rcs = vers->srcfile; - if (rcs == NULL) - { - if (!really_quiet) - error (0, 0, "nothing known about %s", finfo->file); - status = 1; - goto exitfunc; - } - - if (rcs->flags & PARTIAL) - RCS_reparsercsfile (rcs, (FILE **) NULL, (struct rcsbuffer *) NULL); - - if (!really_quiet) - { - cvs_output ("RCS file: ", 0); - cvs_output (rcs->path, 0); - cvs_output ("\n", 1); - } - - if (admin_data->branch != NULL) - { - char *branch = &admin_data->branch[2]; - if (*branch != '\0' && ! isdigit ((unsigned char) *branch)) - { - branch = RCS_whatbranch (rcs, admin_data->branch + 2); - if (branch == NULL) - { - error (0, 0, "%s: Symbolic name %s is undefined.", - rcs->path, admin_data->branch + 2); - status = 1; - } - } - if (status == 0) - RCS_setbranch (rcs, branch); - if (branch != NULL && branch != &admin_data->branch[2]) - free (branch); - } - if (admin_data->comment != NULL) - { - if (rcs->comment != NULL) - free (rcs->comment); - rcs->comment = xstrdup (admin_data->comment + 2); - } - if (admin_data->set_strict) - rcs->strict_locks = 1; - if (admin_data->set_nonstrict) - rcs->strict_locks = 0; - if (admin_data->delete_revs != NULL) - { - char *s, *t, *rev1, *rev2; - /* Set for :, clear for ::. */ - int inclusive; - char *t2; - - s = admin_data->delete_revs + 2; - inclusive = 1; - t = strchr (s, ':'); - if (t != NULL) - { - if (t[1] == ':') - { - inclusive = 0; - t2 = t + 2; - } - else - t2 = t + 1; - } - - /* Note that we don't support '-' for ranges. RCS considers it - obsolete and it is problematic with tags containing '-'. "cvs log" - has made the same decision. */ - - if (t == NULL) - { - /* -orev */ - rev1 = xstrdup (s); - rev2 = xstrdup (s); - } - else if (t == s) - { - /* -o:rev2 */ - rev1 = NULL; - rev2 = xstrdup (t2); - } - else - { - *t = '\0'; - rev1 = xstrdup (s); - *t = ':'; /* probably unnecessary */ - if (*t2 == '\0') - /* -orev1: */ - rev2 = NULL; - else - /* -orev1:rev2 */ - rev2 = xstrdup (t2); - } - - if (rev1 == NULL && rev2 == NULL) - { - /* RCS segfaults if `-o:' is given */ - error (0, 0, "no valid revisions specified in `%s' option", - admin_data->delete_revs); - status = 1; - } - else - { - status |= RCS_delete_revs (rcs, rev1, rev2, inclusive); - if (rev1) - free (rev1); - if (rev2) - free (rev2); - } - } - if (admin_data->desc != NULL) - { - free (rcs->desc); - rcs->desc = xstrdup (admin_data->desc); - } - if (admin_data->kflag != NULL) - { - char *kflag = admin_data->kflag + 2; - char *oldexpand = RCS_getexpand (rcs); - if (oldexpand == NULL || strcmp (oldexpand, kflag) != 0) - RCS_setexpand (rcs, kflag); - } - - /* Handle miscellaneous options. TODO: decide whether any or all - of these should have their own fields in the admin_data - structure. */ - for (i = 0; i < admin_data->ac; ++i) - { - char *arg; - char *p, *rev, *revnum, *tag, *msg; - char **users; - int argc, u; - Node *n; - RCSVers *delta; - - arg = admin_data->av[i]; - switch (arg[1]) - { - case 'a': /* fall through */ - case 'e': - line2argv (&argc, &users, arg + 2, " ,\t\n"); - 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]); - free_names (&argc, users); - break; - case 'A': - - /* See admin-19a-admin and friends in sanity.sh for - relative pathnames. It makes sense to think in - terms of a syntax which give pathnames relative to - the repository or repository corresponding to the - current directory or some such (and perhaps don't - include ,v), but trying to worry about such things - is a little pointless unless you first worry about - whether "cvs admin -A" as a whole makes any sense - (currently probably not, as access lists don't - affect the behavior of CVS). */ - - rcs2 = RCS_parsercsfile (arg + 2); - if (rcs2 == NULL) - error (1, 0, "cannot continue"); - - p = xstrdup (RCS_getaccess (rcs2)); - line2argv (&argc, &users, p, " \t\n"); - free (p); - freercsnode (&rcs2); - - for (u = 0; u < argc; ++u) - RCS_addaccess (rcs, users[u]); - free_names (&argc, users); - break; - case 'n': /* fall through */ - case 'N': - if (arg[2] == '\0') - { - cvs_outerr ("missing symbolic name after ", 0); - cvs_outerr (arg, 0); - cvs_outerr ("\n", 1); - break; - } - p = strchr (arg, ':'); - if (p == NULL) - { - if (RCS_deltag (rcs, arg + 2) != 0) - { - error (0, 0, "%s: Symbolic name %s is undefined.", - rcs->path, - arg + 2); - status = 1; - continue; - } - break; - } - *p = '\0'; - tag = xstrdup (arg + 2); - *p++ = ':'; - - /* Option `n' signals an error if this tag is already bound. */ - if (arg[1] == 'n') - { - n = findnode (RCS_symbols (rcs), tag); - if (n != NULL) - { - error (0, 0, - "%s: symbolic name %s already bound to %s", - rcs->path, - tag, (char *)n->data); - status = 1; - free (tag); - continue; - } - } - - /* Attempt to perform the requested tagging. */ - - if ((*p == 0 && (rev = RCS_head (rcs))) - || (rev = RCS_tag2rev (rcs, p))) /* tag2rev may exit */ - { - RCS_check_tag (tag); /* exit if not a valid tag */ - RCS_settag (rcs, tag, rev); - free (rev); - } - else - { - if (!really_quiet) - error (0, 0, - "%s: Symbolic name or revision %s is undefined.", - rcs->path, p); - status = 1; - } - free (tag); - break; - case 's': - p = strchr (arg, ':'); - if (p == NULL) - { - tag = xstrdup (arg + 2); - rev = RCS_head (rcs); - if (!rev) - { - error (0, 0, "No head revision in archive file `%s'.", - rcs->path); - status = 1; - continue; - } - } - else - { - *p = '\0'; - tag = xstrdup (arg + 2); - *p++ = ':'; - rev = xstrdup (p); - } - revnum = RCS_gettag (rcs, rev, 0, NULL); - if (revnum != NULL) - { - n = findnode (rcs->versions, revnum); - free (revnum); - } - else - n = NULL; - if (n == NULL) - { - error (0, 0, - "%s: can't set state of nonexisting revision %s", - rcs->path, - rev); - free (rev); - status = 1; - continue; - } - free (rev); - delta = n->data; - free (delta->state); - delta->state = tag; - break; - - case 'm': - p = strchr (arg, ':'); - if (p == NULL) - { - error (0, 0, "%s: -m option lacks revision number", - rcs->path); - status = 1; - continue; - } - *p = '\0'; /* temporarily make arg+2 its own string */ - rev = RCS_gettag (rcs, arg + 2, 1, NULL); /* Force tag match */ - if (rev == NULL) - { - error (0, 0, "%s: no such revision %s", rcs->path, arg+2); - status = 1; - *p = ':'; /* restore the full text of the -m argument */ - continue; - } - msg = p+1; - - n = findnode (rcs->versions, rev); - /* tags may exist against non-existing versions */ - if (n == NULL) - { - error (0, 0, "%s: no such revision %s: %s", - rcs->path, arg+2, rev); - status = 1; - *p = ':'; /* restore the full text of the -m argument */ - free (rev); - continue; - } - *p = ':'; /* restore the full text of the -m argument */ - free (rev); - - delta = n->data; - if (delta->text == NULL) - { - delta->text = (Deltatext *) xmalloc (sizeof (Deltatext)); - memset ((void *) delta->text, 0, sizeof (Deltatext)); - } - delta->text->version = xstrdup (delta->version); - delta->text->log = make_message_rcslegal (msg); - break; - - case 'l': - status |= RCS_lock (rcs, arg[2] ? arg + 2 : NULL, 0); - break; - case 'u': - status |= RCS_unlock (rcs, arg[2] ? arg + 2 : NULL, 0); - break; - default: assert(0); /* can't happen */ - } - } - - if (status == 0) - { - RCS_rewrite (rcs, NULL, NULL); - if (!really_quiet) - cvs_output ("done\n", 5); - } - else - { - /* Note that this message should only occur after another - message has given a more specific error. The point of this - additional message is to make it clear that the previous problems - caused CVS to forget about the idea of modifying the RCS file. */ - if (!really_quiet) - error (0, 0, "RCS file for `%s' not modified.", finfo->file); - RCS_abandon (rcs); - } - - exitfunc: - freevers_ts (&vers); - return status; -} - -/* - * Print a warm fuzzy message - */ -/* ARGSUSED */ -static Dtype -admin_dirproc (callerdat, dir, repos, update_dir, entries) - void *callerdat; - const char *dir; - const char *repos; - const char *update_dir; - List *entries; -{ - if (!quiet) - error (0, 0, "Administrating %s", update_dir); - return (R_PROCESS); -} diff --git a/contrib/cvs/src/annotate.c b/contrib/cvs/src/annotate.c deleted file mode 100644 index d6d0acc..0000000 --- a/contrib/cvs/src/annotate.c +++ /dev/null @@ -1,302 +0,0 @@ -/* - * Copyright (C) 1986-2005 The Free Software Foundation, Inc. - * - * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot , - * and others. - * - * Portions Copyright (c) 1992, Brian Berliner and Jeff Polk - * Portions Copyright (c) 1989-1992, Brian Berliner - * - * You may distribute under the terms of the GNU General Public License as - * specified in the README file that comes with the CVS source distribution. - * - * Show last revision where each line modified - * - * Prints the specified files with each line annotated with the revision - * number where it was last modified. With no argument, annotates all - * all the files in the directory (recursive by default). - */ - -#include "cvs.h" - -/* Options from the command line. */ - -static int force_tag_match = 1; -static int force_binary = 0; -static char *tag = NULL; -static int tag_validated; -static char *date = NULL; - -static int is_rannotate; - -static int annotate_fileproc PROTO ((void *callerdat, struct file_info *)); -static int rannotate_proc PROTO((int argc, char **argv, char *xwhere, - char *mwhere, char *mfile, int shorten, - int local, char *mname, char *msg)); - -static const char *const annotate_usage[] = -{ - "Usage: %s %s [-lRfF] [-r rev] [-D date] [files...]\n", - "\t-l\tLocal directory only, no recursion.\n", - "\t-R\tProcess directories recursively.\n", - "\t-f\tUse head revision if tag/date not found.\n", - "\t-F\tAnnotate binary files.\n", - "\t-r rev\tAnnotate file as of specified revision/tag.\n", - "\t-D date\tAnnotate file as of specified date.\n", - "(Specify the --help global option for a list of other help options)\n", - NULL -}; - -/* Command to show the revision, date, and author where each line of a - file was modified. */ - -int -annotate (argc, argv) - int argc; - char **argv; -{ - int local = 0; - int err = 0; - int c; - - is_rannotate = (strcmp(cvs_cmd_name, "rannotate") == 0); - - if (argc == -1) - usage (annotate_usage); - - optind = 0; - while ((c = getopt (argc, argv, "+lr:D:fFR")) != -1) - { - switch (c) - { - case 'l': - local = 1; - break; - case 'R': - local = 0; - break; - case 'r': - tag = optarg; - break; - case 'D': - date = Make_Date (optarg); - break; - case 'f': - force_tag_match = 0; - break; - case 'F': - force_binary = 1; - break; - case '?': - default: - usage (annotate_usage); - break; - } - } - argc -= optind; - argv += optind; - -#ifdef CLIENT_SUPPORT - if (current_parsed_root->isremote) - { - start_server (); - - if (is_rannotate && !supported_request ("rannotate")) - error (1, 0, "server does not support rannotate"); - - ign_setup (); - - if (local) - send_arg ("-l"); - if (!force_tag_match) - send_arg ("-f"); - if (force_binary) - send_arg ("-F"); - option_with_arg ("-r", tag); - if (date) - client_senddate (date); - send_arg ("--"); - if (is_rannotate) - { - int i; - for (i = 0; i < argc; i++) - send_arg (argv[i]); - send_to_server ("rannotate\012", 0); - } - else - { - send_files (argc, argv, local, 0, SEND_NO_CONTENTS); - send_file_names (argc, argv, SEND_EXPAND_WILD); - send_to_server ("annotate\012", 0); - } - return get_responses_and_close (); - } -#endif /* CLIENT_SUPPORT */ - - if (is_rannotate) - { - DBM *db; - int i; - db = open_module (); - for (i = 0; i < argc; i++) - { - err += do_module (db, argv[i], MISC, "Annotating", rannotate_proc, - (char *) NULL, 0, local, 0, 0, (char *) NULL); - } - close_module (db); - } - else - { - err = rannotate_proc (argc + 1, argv - 1, (char *) NULL, - (char *) NULL, (char *) NULL, 0, local, (char *) NULL, - (char *) NULL); - } - - return err; -} - - -static int -rannotate_proc (argc, argv, xwhere, mwhere, mfile, shorten, local, mname, msg) - int argc; - char **argv; - char *xwhere; - char *mwhere; - char *mfile; - int shorten; - int local; - char *mname; - char *msg; -{ - /* Begin section which is identical to patch_proc--should this - be abstracted out somehow? */ - char *myargv[2]; - int err = 0; - int which; - char *repository; - char *where; - - if (is_rannotate) - { - repository = xmalloc (strlen (current_parsed_root->directory) + strlen (argv[0]) - + (mfile == NULL ? 0 : strlen (mfile) + 1) + 2); - (void) sprintf (repository, "%s/%s", current_parsed_root->directory, argv[0]); - where = xmalloc (strlen (argv[0]) + (mfile == NULL ? 0 : strlen (mfile) + 1) - + 1); - (void) strcpy (where, argv[0]); - - /* if mfile isn't null, we need to set up to do only part of the module */ - if (mfile != NULL) - { - char *cp; - char *path; - - /* if the portion of the module is a path, put the dir part on repos */ - if ((cp = strrchr (mfile, '/')) != NULL) - { - *cp = '\0'; - (void) strcat (repository, "/"); - (void) strcat (repository, mfile); - (void) strcat (where, "/"); - (void) strcat (where, mfile); - mfile = cp + 1; - } - - /* take care of the rest */ - path = xmalloc (strlen (repository) + strlen (mfile) + 5); - (void) sprintf (path, "%s/%s", repository, mfile); - if (isdir (path)) - { - /* directory means repository gets the dir tacked on */ - (void) strcpy (repository, path); - (void) strcat (where, "/"); - (void) strcat (where, mfile); - } - else - { - myargv[0] = argv[0]; - myargv[1] = mfile; - argc = 2; - argv = myargv; - } - free (path); - } - - /* cd to the starting repository */ - if ( CVS_CHDIR (repository) < 0) - { - error (0, errno, "cannot chdir to %s", repository); - free (repository); - free (where); - return (1); - } - /* End section which is identical to patch_proc. */ - - if (force_tag_match && tag != NULL) - which = W_REPOS | W_ATTIC; - else - which = W_REPOS; - } - else - { - where = NULL; - which = W_LOCAL; - repository = ""; - } - - if (tag != NULL && !tag_validated) - { - tag_check_valid (tag, argc - 1, argv + 1, local, 0, repository); - tag_validated = 1; - } - - err = start_recursion (annotate_fileproc, (FILESDONEPROC) NULL, - (DIRENTPROC) NULL, (DIRLEAVEPROC) NULL, NULL, - argc - 1, argv + 1, local, which, 0, CVS_LOCK_READ, - where, 1, repository); - if ( which & W_REPOS ) - free ( repository ); - if ( where != NULL ) - free (where); - return err; -} - - -static int -annotate_fileproc (callerdat, finfo) - void *callerdat; - struct file_info *finfo; -{ - char *expand, *version; - - if (finfo->rcs == NULL) - return (1); - - if (finfo->rcs->flags & PARTIAL) - RCS_reparsercsfile (finfo->rcs, (FILE **) NULL, (struct rcsbuffer *) NULL); - - expand = RCS_getexpand (finfo->rcs); - version = RCS_getversion (finfo->rcs, tag, date, force_tag_match, - (int *) NULL); - - if (version == NULL) - return 0; - - /* Distinguish output for various files if we are processing - several files. */ - cvs_outerr ("\nAnnotations for ", 0); - cvs_outerr (finfo->fullname, 0); - cvs_outerr ("\n***************\n", 0); - - if (!force_binary && expand && expand[0] == 'b') - { - cvs_outerr ("Skipping binary file -- -F not specified.\n", 0); - } - else - { - RCS_deltas (finfo->rcs, (FILE *) NULL, (struct rcsbuffer *) NULL, - version, RCS_ANNOTATE, NULL, NULL, NULL, NULL); - } - free (version); - return 0; -} diff --git a/contrib/cvs/src/buffer.c b/contrib/cvs/src/buffer.c deleted file mode 100644 index db2bea0..0000000 --- a/contrib/cvs/src/buffer.c +++ /dev/null @@ -1,1980 +0,0 @@ -/* - * Copyright (C) 1996-2005 The Free Software Foundation, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -/* Code for the buffer data structure. */ - -/* $FreeBSD$ */ - -#include -#include "cvs.h" -#include "buffer.h" - -#if defined (SERVER_SUPPORT) || defined (CLIENT_SUPPORT) - -#ifdef HAVE_WINSOCK_H -# include -#else -# include -#endif - -/* OS/2 doesn't have EIO. FIXME: this whole notion of turning - a different error into EIO strikes me as pretty dubious. */ -#if !defined (EIO) -#define EIO EBADPOS -#endif - -/* Linked list of available buffer_data structures. */ -static struct buffer_data *free_buffer_data; - -/* Local functions. */ -static void buf_default_memory_error PROTO ((struct buffer *)); -static void allocate_buffer_datas PROTO((void)); -static struct buffer_data *get_buffer_data PROTO((void)); - -/* Initialize a buffer structure. */ - -struct buffer * -buf_initialize (input, output, flush, block, shutdown, memory, closure) - int (*input) PROTO((void *, char *, int, int, int *)); - int (*output) PROTO((void *, const char *, int, int *)); - int (*flush) PROTO((void *)); - int (*block) PROTO((void *, int)); - int (*shutdown) PROTO((struct buffer *)); - void (*memory) PROTO((struct buffer *)); - void *closure; -{ - struct buffer *buf; - - buf = (struct buffer *) xmalloc (sizeof (struct buffer)); - buf->data = NULL; - buf->last = NULL; - buf->nonblocking = 0; - buf->input = input; - buf->output = output; - buf->flush = flush; - buf->block = block; - buf->shutdown = shutdown; - buf->memory_error = memory ? memory : buf_default_memory_error; - buf->closure = closure; - return buf; -} - -/* Free a buffer structure. */ - -void -buf_free (buf) - struct buffer *buf; -{ - if (buf->closure != NULL) - { - free (buf->closure); - buf->closure = NULL; - } - if (buf->data != NULL) - { - buf->last->next = free_buffer_data; - free_buffer_data = buf->data; - } - free (buf); -} - -/* Initialize a buffer structure which is not to be used for I/O. */ - -struct buffer * -buf_nonio_initialize (memory) - void (*memory) PROTO((struct buffer *)); -{ - return (buf_initialize - ((int (*) PROTO((void *, char *, int, int, int *))) NULL, - (int (*) PROTO((void *, const char *, int, int *))) NULL, - (int (*) PROTO((void *))) NULL, - (int (*) PROTO((void *, int))) NULL, - (int (*) PROTO((struct buffer *))) NULL, - memory, - (void *) NULL)); -} - -/* Default memory error handler. */ - -static void -buf_default_memory_error (buf) - struct buffer *buf; -{ - error (1, 0, "out of memory"); -} - -/* Allocate more buffer_data structures. */ - -static void -allocate_buffer_datas () -{ - struct buffer_data *alc; - char *space; - int i; - - /* Allocate buffer_data structures in blocks of 16. */ -#define ALLOC_COUNT (16) - - alc = xmalloc (ALLOC_COUNT * sizeof (struct buffer_data)); - space = (char *) valloc (ALLOC_COUNT * BUFFER_DATA_SIZE); - if (!space) - { - free (alc); - return; - } - for (i = 0; i < ALLOC_COUNT; i++, alc++, space += BUFFER_DATA_SIZE) - { - alc->next = free_buffer_data; - free_buffer_data = alc; - alc->text = space; - } -} - -/* Get a new buffer_data structure. */ - -static struct buffer_data * -get_buffer_data () -{ - struct buffer_data *ret; - - if (free_buffer_data == NULL) - { - allocate_buffer_datas (); - if (free_buffer_data == NULL) - return NULL; - } - - ret = free_buffer_data; - free_buffer_data = ret->next; - return ret; -} - - - -/* See whether a buffer and its file descriptor is empty. */ -int -buf_empty (buf) - struct buffer *buf; -{ - /* Try and read any data on the file descriptor first. - * We already know the descriptor is non-blocking. - */ - buf_input_data (buf, NULL); - return buf_empty_p (buf); -} - - - -/* See whether a buffer is empty. */ -int -buf_empty_p (buf) - struct buffer *buf; -{ - struct buffer_data *data; - - for (data = buf->data; data != NULL; data = data->next) - if (data->size > 0) - return 0; - return 1; -} - - - -#ifdef SERVER_FLOWCONTROL -/* - * Count how much data is stored in the buffer.. - * Note that each buffer is a xmalloc'ed chunk BUFFER_DATA_SIZE. - */ - -int -buf_count_mem (buf) - struct buffer *buf; -{ - struct buffer_data *data; - int mem = 0; - - for (data = buf->data; data != NULL; data = data->next) - mem += BUFFER_DATA_SIZE; - - return mem; -} -#endif /* SERVER_FLOWCONTROL */ - -/* Add data DATA of length LEN to BUF. */ - -void -buf_output (buf, data, len) - struct buffer *buf; - const char *data; - int len; -{ - if (buf->data != NULL - && (((buf->last->text + BUFFER_DATA_SIZE) - - (buf->last->bufp + buf->last->size)) - >= len)) - { - memcpy (buf->last->bufp + buf->last->size, data, len); - buf->last->size += len; - return; - } - - while (1) - { - struct buffer_data *newdata; - - newdata = get_buffer_data (); - if (newdata == NULL) - { - (*buf->memory_error) (buf); - return; - } - - if (buf->data == NULL) - buf->data = newdata; - else - buf->last->next = newdata; - newdata->next = NULL; - buf->last = newdata; - - newdata->bufp = newdata->text; - - if (len <= BUFFER_DATA_SIZE) - { - newdata->size = len; - memcpy (newdata->text, data, len); - return; - } - - newdata->size = BUFFER_DATA_SIZE; - memcpy (newdata->text, data, BUFFER_DATA_SIZE); - - data += BUFFER_DATA_SIZE; - len -= BUFFER_DATA_SIZE; - } - - /*NOTREACHED*/ -} - -/* Add a '\0' terminated string to BUF. */ - -void -buf_output0 (buf, string) - struct buffer *buf; - const char *string; -{ - buf_output (buf, string, strlen (string)); -} - -/* Add a single character to BUF. */ - -void -buf_append_char (buf, ch) - struct buffer *buf; - int ch; -{ - if (buf->data != NULL - && (buf->last->text + BUFFER_DATA_SIZE - != buf->last->bufp + buf->last->size)) - { - *(buf->last->bufp + buf->last->size) = ch; - ++buf->last->size; - } - else - { - char b; - - b = ch; - buf_output (buf, &b, 1); - } -} - -/* - * Send all the output we've been saving up. Returns 0 for success or - * errno code. If the buffer has been set to be nonblocking, this - * will just write until the write would block. - */ - -int -buf_send_output (buf) - struct buffer *buf; -{ - if (buf->output == NULL) - abort (); - - while (buf->data != NULL) - { - struct buffer_data *data; - - data = buf->data; - - if (data->size > 0) - { - int status, nbytes; - - status = (*buf->output) (buf->closure, data->bufp, data->size, - &nbytes); - if (status != 0) - { - /* Some sort of error. Discard the data, and return. */ - - buf->last->next = free_buffer_data; - free_buffer_data = buf->data; - buf->data = NULL; - buf->last = NULL; - - return status; - } - - if (nbytes != data->size) - { - /* Not all the data was written out. This is only - permitted in nonblocking mode. Adjust the buffer, - and return. */ - - assert (buf->nonblocking); - - data->size -= nbytes; - data->bufp += nbytes; - - return 0; - } - } - - buf->data = data->next; - data->next = free_buffer_data; - free_buffer_data = data; - } - - buf->last = NULL; - - return 0; -} - -/* - * Flush any data queued up in the buffer. If BLOCK is nonzero, then - * if the buffer is in nonblocking mode, put it into blocking mode for - * the duration of the flush. This returns 0 on success, or an error - * code. - */ - -int -buf_flush (buf, block) - struct buffer *buf; - int block; -{ - int nonblocking; - int status; - - if (buf->flush == NULL) - abort (); - - nonblocking = buf->nonblocking; - if (nonblocking && block) - { - status = set_block (buf); - if (status != 0) - return status; - } - - status = buf_send_output (buf); - if (status == 0) - status = (*buf->flush) (buf->closure); - - if (nonblocking && block) - { - int blockstat; - - blockstat = set_nonblock (buf); - if (status == 0) - status = blockstat; - } - - return status; -} - -/* - * Set buffer BUF to nonblocking I/O. Returns 0 for success or errno - * code. - */ - -int -set_nonblock (buf) - struct buffer *buf; -{ - int status; - - if (buf->nonblocking) - return 0; - if (buf->block == NULL) - abort (); - status = (*buf->block) (buf->closure, 0); - if (status != 0) - return status; - buf->nonblocking = 1; - return 0; -} - -/* - * Set buffer BUF to blocking I/O. Returns 0 for success or errno - * code. - */ - -int -set_block (buf) - struct buffer *buf; -{ - int status; - - if (! buf->nonblocking) - return 0; - if (buf->block == NULL) - abort (); - status = (*buf->block) (buf->closure, 1); - if (status != 0) - return status; - buf->nonblocking = 0; - return 0; -} - -/* - * Send a character count and some output. Returns errno code or 0 for - * success. - * - * Sending the count in binary is OK since this is only used on a pipe - * within the same system. - */ - -int -buf_send_counted (buf) - struct buffer *buf; -{ - int size; - struct buffer_data *data; - - size = 0; - for (data = buf->data; data != NULL; data = data->next) - size += data->size; - - data = get_buffer_data (); - if (data == NULL) - { - (*buf->memory_error) (buf); - return ENOMEM; - } - - data->next = buf->data; - buf->data = data; - if (buf->last == NULL) - buf->last = data; - - data->bufp = data->text; - data->size = sizeof (int); - - *((int *) data->text) = size; - - return buf_send_output (buf); -} - -/* - * Send a special count. COUNT should be negative. It will be - * handled speciallyi by buf_copy_counted. This function returns 0 or - * an errno code. - * - * Sending the count in binary is OK since this is only used on a pipe - * within the same system. - */ - -int -buf_send_special_count (buf, count) - struct buffer *buf; - int count; -{ - struct buffer_data *data; - - data = get_buffer_data (); - if (data == NULL) - { - (*buf->memory_error) (buf); - return ENOMEM; - } - - data->next = buf->data; - buf->data = data; - if (buf->last == NULL) - buf->last = data; - - data->bufp = data->text; - data->size = sizeof (int); - - *((int *) data->text) = count; - - return buf_send_output (buf); -} - -/* Append a list of buffer_data structures to an buffer. */ - -void -buf_append_data (buf, data, last) - struct buffer *buf; - struct buffer_data *data; - struct buffer_data *last; -{ - if (data != NULL) - { - if (buf->data == NULL) - buf->data = data; - else - buf->last->next = data; - buf->last = last; - } -} - -/* Append the data on one buffer to another. This removes the data - from the source buffer. */ - -void -buf_append_buffer (to, from) - struct buffer *to; - struct buffer *from; -{ - buf_append_data (to, from->data, from->last); - from->data = NULL; - from->last = NULL; -} - -/* - * Copy the contents of file F into buffer_data structures. We can't - * copy directly into an buffer, because we want to handle failure and - * succeess differently. Returns 0 on success, or -2 if out of - * memory, or a status code on error. Since the caller happens to - * know the size of the file, it is passed in as SIZE. On success, - * this function sets *RETP and *LASTP, which may be passed to - * buf_append_data. - */ - -int -buf_read_file (f, size, retp, lastp) - FILE *f; - long size; - struct buffer_data **retp; - struct buffer_data **lastp; -{ - int status; - - *retp = NULL; - *lastp = NULL; - - while (size > 0) - { - struct buffer_data *data; - int get; - - data = get_buffer_data (); - if (data == NULL) - { - status = -2; - goto error_return; - } - - if (*retp == NULL) - *retp = data; - else - (*lastp)->next = data; - data->next = NULL; - *lastp = data; - - data->bufp = data->text; - data->size = 0; - - if (size > BUFFER_DATA_SIZE) - get = BUFFER_DATA_SIZE; - else - get = size; - - errno = EIO; - if (fread (data->text, get, 1, f) != 1) - { - status = errno; - goto error_return; - } - - data->size += get; - size -= get; - } - - return 0; - - error_return: - if (*retp != NULL) - { - (*lastp)->next = free_buffer_data; - free_buffer_data = *retp; - } - return status; -} - -/* - * Copy the contents of file F into buffer_data structures. We can't - * copy directly into an buffer, because we want to handle failure and - * succeess differently. Returns 0 on success, or -2 if out of - * memory, or a status code on error. On success, this function sets - * *RETP and *LASTP, which may be passed to buf_append_data. - */ - -int -buf_read_file_to_eof (f, retp, lastp) - FILE *f; - struct buffer_data **retp; - struct buffer_data **lastp; -{ - int status; - - *retp = NULL; - *lastp = NULL; - - while (!feof (f)) - { - struct buffer_data *data; - int get, nread; - - data = get_buffer_data (); - if (data == NULL) - { - status = -2; - goto error_return; - } - - if (*retp == NULL) - *retp = data; - else - (*lastp)->next = data; - data->next = NULL; - *lastp = data; - - data->bufp = data->text; - data->size = 0; - - get = BUFFER_DATA_SIZE; - - errno = EIO; - nread = fread (data->text, 1, get, f); - if (nread == 0 && !feof (f)) - { - status = errno; - goto error_return; - } - - data->size = nread; - } - - return 0; - - error_return: - if (*retp != NULL) - { - (*lastp)->next = free_buffer_data; - free_buffer_data = *retp; - } - return status; -} - -/* Return the number of bytes in a chain of buffer_data structures. */ - -int -buf_chain_length (buf) - struct buffer_data *buf; -{ - int size = 0; - while (buf) - { - size += buf->size; - buf = buf->next; - } - return size; -} - -/* Return the number of bytes in a buffer. */ - -int -buf_length (buf) - struct buffer *buf; -{ - return buf_chain_length (buf->data); -} - -/* - * Read an arbitrary amount of data into an input buffer. The buffer - * will be in nonblocking mode, and we just grab what we can. Return - * 0 on success, or -1 on end of file, or -2 if out of memory, or an - * error code. If COUNTP is not NULL, *COUNTP is set to the number of - * bytes read. - */ - -int -buf_input_data (buf, countp) - struct buffer *buf; - int *countp; -{ - if (buf->input == NULL) - abort (); - - if (countp != NULL) - *countp = 0; - - while (1) - { - int get; - int status, nbytes; - - if (buf->data == NULL - || (buf->last->bufp + buf->last->size - == buf->last->text + BUFFER_DATA_SIZE)) - { - struct buffer_data *data; - - data = get_buffer_data (); - if (data == NULL) - { - (*buf->memory_error) (buf); - return -2; - } - - if (buf->data == NULL) - buf->data = data; - else - buf->last->next = data; - data->next = NULL; - buf->last = data; - - data->bufp = data->text; - data->size = 0; - } - - get = ((buf->last->text + BUFFER_DATA_SIZE) - - (buf->last->bufp + buf->last->size)); - - status = (*buf->input) (buf->closure, - buf->last->bufp + buf->last->size, - 0, get, &nbytes); - if (status != 0) - return status; - - buf->last->size += nbytes; - if (countp != NULL) - *countp += nbytes; - - if (nbytes < get) - { - /* If we did not fill the buffer, then presumably we read - all the available data. */ - return 0; - } - } - - /*NOTREACHED*/ -} - -/* - * Read a line (characters up to a \012) from an input buffer. (We - * use \012 rather than \n for the benefit of non Unix clients for - * which \n means something else). This returns 0 on success, or -1 - * on end of file, or -2 if out of memory, or an error code. If it - * succeeds, it sets *LINE to an allocated buffer holding the contents - * of the line. The trailing \012 is not included in the buffer. If - * LENP is not NULL, then *LENP is set to the number of bytes read; - * strlen may not work, because there may be embedded null bytes. - */ - -int -buf_read_line (buf, line, lenp) - struct buffer *buf; - char **line; - int *lenp; -{ - if (buf->input == NULL) - abort (); - - *line = NULL; - - while (1) - { - int len, finallen = 0; - struct buffer_data *data; - char *nl; - - /* See if there is a newline in BUF. */ - len = 0; - for (data = buf->data; data != NULL; data = data->next) - { - nl = memchr (data->bufp, '\012', data->size); - if (nl != NULL) - { - finallen = nl - data->bufp; - len += finallen; - break; - } - len += data->size; - } - - /* If we found a newline, copy the line into a memory buffer, - and remove it from BUF. */ - if (data != NULL) - { - char *p; - struct buffer_data *nldata; - - p = xmalloc (len + 1); - if (p == NULL) - return -2; - *line = p; - - nldata = data; - data = buf->data; - while (data != nldata) - { - struct buffer_data *next; - - memcpy (p, data->bufp, data->size); - p += data->size; - next = data->next; - data->next = free_buffer_data; - free_buffer_data = data; - data = next; - } - - memcpy (p, data->bufp, finallen); - p[finallen] = '\0'; - - data->size -= finallen + 1; - data->bufp = nl + 1; - buf->data = data; - - if (lenp != NULL) - *lenp = len; - - return 0; - } - - /* Read more data until we get a newline. */ - while (1) - { - int size, status, nbytes; - char *mem; - - if (buf->data == NULL - || (buf->last->bufp + buf->last->size - == buf->last->text + BUFFER_DATA_SIZE)) - { - data = get_buffer_data (); - if (data == NULL) - { - (*buf->memory_error) (buf); - return -2; - } - - if (buf->data == NULL) - buf->data = data; - else - buf->last->next = data; - data->next = NULL; - buf->last = data; - - data->bufp = data->text; - data->size = 0; - } - - mem = buf->last->bufp + buf->last->size; - size = (buf->last->text + BUFFER_DATA_SIZE) - mem; - - /* We need to read at least 1 byte. We can handle up to - SIZE bytes. This will only be efficient if the - underlying communication stream does its own buffering, - or is clever about getting more than 1 byte at a time. */ - status = (*buf->input) (buf->closure, mem, 1, size, &nbytes); - if (status != 0) - return status; - - buf->last->size += nbytes; - - /* Optimize slightly to avoid an unnecessary call to - memchr. */ - if (nbytes == 1) - { - if (*mem == '\012') - break; - } - else - { - if (memchr (mem, '\012', nbytes) != NULL) - break; - } - } - } -} - -/* - * Extract data from the input buffer BUF. This will read up to WANT - * bytes from the buffer. It will set *RETDATA to point at the bytes, - * and set *GOT to the number of bytes to be found there. Any buffer - * call which uses BUF may change the contents of the buffer at *DATA, - * so the data should be fully processed before any further calls are - * made. This returns 0 on success, or -1 on end of file, or -2 if - * out of memory, or an error code. - */ - -int -buf_read_data (buf, want, retdata, got) - struct buffer *buf; - int want; - char **retdata; - int *got; -{ - if (buf->input == NULL) - abort (); - - while (buf->data != NULL && buf->data->size == 0) - { - struct buffer_data *next; - - next = buf->data->next; - buf->data->next = free_buffer_data; - free_buffer_data = buf->data; - buf->data = next; - if (next == NULL) - buf->last = NULL; - } - - if (buf->data == NULL) - { - struct buffer_data *data; - int get, status, nbytes; - - data = get_buffer_data (); - if (data == NULL) - { - (*buf->memory_error) (buf); - return -2; - } - - buf->data = data; - buf->last = data; - data->next = NULL; - data->bufp = data->text; - data->size = 0; - - if (want < BUFFER_DATA_SIZE) - get = want; - else - get = BUFFER_DATA_SIZE; - status = (*buf->input) (buf->closure, data->bufp, get, - BUFFER_DATA_SIZE, &nbytes); - if (status != 0) - return status; - - data->size = nbytes; - } - - *retdata = buf->data->bufp; - if (want < buf->data->size) - { - *got = want; - buf->data->size -= want; - buf->data->bufp += want; - } - else - { - *got = buf->data->size; - buf->data->size = 0; - } - - return 0; -} - -/* - * Copy lines from an input buffer to an output buffer. This copies - * all complete lines (characters up to a newline) from INBUF to - * OUTBUF. Each line in OUTBUF is preceded by the character COMMAND - * and a space. - */ - -void -buf_copy_lines (outbuf, inbuf, command) - struct buffer *outbuf; - struct buffer *inbuf; - int command; -{ - while (1) - { - struct buffer_data *data; - struct buffer_data *nldata; - char *nl; - int len; - - /* See if there is a newline in INBUF. */ - nldata = NULL; - nl = NULL; - for (data = inbuf->data; data != NULL; data = data->next) - { - nl = memchr (data->bufp, '\n', data->size); - if (nl != NULL) - { - nldata = data; - break; - } - } - - if (nldata == NULL) - { - /* There are no more lines in INBUF. */ - return; - } - - /* Put in the command. */ - buf_append_char (outbuf, command); - buf_append_char (outbuf, ' '); - - if (inbuf->data != nldata) - { - /* - * Simply move over all the buffers up to the one containing - * the newline. - */ - for (data = inbuf->data; data->next != nldata; data = data->next) - ; - data->next = NULL; - buf_append_data (outbuf, inbuf->data, data); - inbuf->data = nldata; - } - - /* - * If the newline is at the very end of the buffer, just move - * the buffer onto OUTBUF. Otherwise we must copy the data. - */ - len = nl + 1 - nldata->bufp; - if (len == nldata->size) - { - inbuf->data = nldata->next; - if (inbuf->data == NULL) - inbuf->last = NULL; - - nldata->next = NULL; - buf_append_data (outbuf, nldata, nldata); - } - else - { - buf_output (outbuf, nldata->bufp, len); - nldata->bufp += len; - nldata->size -= len; - } - } -} - -/* - * Copy counted data from one buffer to another. The count is an - * integer, host size, host byte order (it is only used across a - * pipe). If there is enough data, it should be moved over. If there - * is not enough data, it should remain on the original buffer. A - * negative count is a special case. if one is seen, *SPECIAL is set - * to the (negative) count value and no additional data is gathered - * from the buffer; normally *SPECIAL is set to 0. This function - * returns the number of bytes it needs to see in order to actually - * copy something over. - */ - -int -buf_copy_counted (outbuf, inbuf, special) - struct buffer *outbuf; - struct buffer *inbuf; - int *special; -{ - *special = 0; - - while (1) - { - struct buffer_data *data; - int need; - union - { - char intbuf[sizeof (int)]; - int i; - } u; - char *intp; - int count; - struct buffer_data *start; - int startoff; - struct buffer_data *stop; - int stopwant; - - /* See if we have enough bytes to figure out the count. */ - need = sizeof (int); - intp = u.intbuf; - for (data = inbuf->data; data != NULL; data = data->next) - { - if (data->size >= need) - { - memcpy (intp, data->bufp, need); - break; - } - memcpy (intp, data->bufp, data->size); - intp += data->size; - need -= data->size; - } - if (data == NULL) - { - /* We don't have enough bytes to form an integer. */ - return need; - } - - count = u.i; - start = data; - startoff = need; - - if (count < 0) - { - /* A negative COUNT is a special case meaning that we - don't need any further information. */ - stop = start; - stopwant = 0; - } - else - { - /* - * We have an integer in COUNT. We have gotten all the - * data from INBUF in all buffers before START, and we - * have gotten STARTOFF bytes from START. See if we have - * enough bytes remaining in INBUF. - */ - need = count - (start->size - startoff); - if (need <= 0) - { - stop = start; - stopwant = count; - } - else - { - for (data = start->next; data != NULL; data = data->next) - { - if (need <= data->size) - break; - need -= data->size; - } - if (data == NULL) - { - /* We don't have enough bytes. */ - return need; - } - stop = data; - stopwant = need; - } - } - - /* - * We have enough bytes. Free any buffers in INBUF before - * START, and remove STARTOFF bytes from START, so that we can - * forget about STARTOFF. - */ - start->bufp += startoff; - start->size -= startoff; - - if (start->size == 0) - start = start->next; - - if (stop->size == stopwant) - { - stop = stop->next; - stopwant = 0; - } - - while (inbuf->data != start) - { - data = inbuf->data; - inbuf->data = data->next; - data->next = free_buffer_data; - free_buffer_data = data; - } - - /* If COUNT is negative, set *SPECIAL and get out now. */ - if (count < 0) - { - *special = count; - return 0; - } - - /* - * We want to copy over the bytes from START through STOP. We - * only want STOPWANT bytes from STOP. - */ - - if (start != stop) - { - /* Attach the buffers from START through STOP to OUTBUF. */ - for (data = start; data->next != stop; data = data->next) - ; - inbuf->data = stop; - data->next = NULL; - buf_append_data (outbuf, start, data); - } - - if (stopwant > 0) - { - buf_output (outbuf, stop->bufp, stopwant); - stop->bufp += stopwant; - stop->size -= stopwant; - } - } - - /*NOTREACHED*/ -} - -/* Shut down a buffer. This returns 0 on success, or an errno code. */ - -int -buf_shutdown (buf) - struct buffer *buf; -{ - if (buf->shutdown) - return (*buf->shutdown) (buf); - return 0; -} - - - -/* The simplest type of buffer is one built on top of a stdio FILE. - For simplicity, and because it is all that is required, we do not - implement setting this type of buffer into nonblocking mode. The - closure field is just a FILE *. */ - -static int stdio_buffer_input PROTO((void *, char *, int, int, int *)); -static int stdio_buffer_output PROTO((void *, const char *, int, int *)); -static int stdio_buffer_flush PROTO((void *)); -static int stdio_buffer_shutdown PROTO((struct buffer *buf)); - - - -/* Initialize a buffer built on a stdio FILE. */ -struct stdio_buffer_closure -{ - FILE *fp; - int child_pid; -}; - - - -struct buffer * -stdio_buffer_initialize (fp, child_pid, input, memory) - FILE *fp; - int child_pid; - int input; - void (*memory) PROTO((struct buffer *)); -{ - struct stdio_buffer_closure *bc = xmalloc (sizeof (*bc)); - - bc->fp = fp; - bc->child_pid = child_pid; - - return buf_initialize (input ? stdio_buffer_input : NULL, - input ? NULL : stdio_buffer_output, - input ? NULL : stdio_buffer_flush, - (int (*) PROTO((void *, int))) NULL, - stdio_buffer_shutdown, - memory, - (void *) bc); -} - -/* Return the file associated with a stdio buffer. */ -FILE * -stdio_buffer_get_file (buf) - struct buffer *buf; -{ - struct stdio_buffer_closure *bc; - - assert(buf->shutdown == stdio_buffer_shutdown); - - bc = (struct stdio_buffer_closure *) buf->closure; - - return(bc->fp); -} - -/* The buffer input function for a buffer built on a stdio FILE. */ - -static int -stdio_buffer_input (closure, data, need, size, got) - void *closure; - char *data; - int need; - int size; - int *got; -{ - struct stdio_buffer_closure *bc = (struct stdio_buffer_closure *) closure; - int nbytes; - - /* Since stdio does its own buffering, we don't worry about - getting more bytes than we need. */ - - if (need == 0 || need == 1) - { - int ch; - - ch = getc (bc->fp); - - if (ch == EOF) - { - if (feof (bc->fp)) - return -1; - else if (errno == 0) - return EIO; - else - return errno; - } - - *data = ch; - *got = 1; - return 0; - } - - nbytes = fread (data, 1, need, bc->fp); - - if (nbytes == 0) - { - *got = 0; - if (feof (bc->fp)) - return -1; - else if (errno == 0) - return EIO; - else - return errno; - } - - *got = nbytes; - - return 0; -} - -/* The buffer output function for a buffer built on a stdio FILE. */ - -static int -stdio_buffer_output (closure, data, have, wrote) - void *closure; - const char *data; - int have; - int *wrote; -{ - struct stdio_buffer_closure *bc = (struct stdio_buffer_closure *) closure; - - *wrote = 0; - - while (have > 0) - { - int nbytes; - - nbytes = fwrite (data, 1, have, bc->fp); - - if (nbytes != have) - { - if (errno == 0) - return EIO; - else - return errno; - } - - *wrote += nbytes; - have -= nbytes; - data += nbytes; - } - - return 0; -} - - - -/* The buffer flush function for a buffer built on a stdio FILE. */ -static int -stdio_buffer_flush (closure) - void *closure; -{ - struct stdio_buffer_closure *bc = (struct stdio_buffer_closure *) closure; - - if (fflush (bc->fp) != 0) - { - if (errno == 0) - return EIO; - else - return errno; - } - - return 0; -} - - - -static int -stdio_buffer_shutdown (buf) - struct buffer *buf; -{ - struct stdio_buffer_closure *bc = buf->closure; - struct stat s; - int closefp, statted; - - /* Must be a pipe or a socket. What could go wrong? - * Well, apparently for disconnected clients under AIX, the - * fstat() will return -1 on the server if the client has gone - * away. - */ - if (fstat(fileno(bc->fp), &s) == -1) statted = 0; - else statted = 1; - closefp = statted; - - /* Flush the buffer if we can */ - if (buf->flush) - { - buf_flush (buf, 1); - buf->flush = NULL; - } - - if (buf->input) - { - /* There used to be a check here for unread data in the buffer of on - * the pipe, but it was deemed unnecessary and possibly dangerous. In - * some sense it could be second-guessing the caller who requested it - * closed, as well. - */ - -# ifdef SHUTDOWN_SERVER - if (current_parsed_root->method != server_method) -# endif -# ifndef NO_SOCKET_TO_FD - { - /* shutdown() sockets */ - if (statted && S_ISSOCK (s.st_mode)) - shutdown (fileno (bc->fp), 0); - } -# endif /* NO_SOCKET_TO_FD */ -# ifdef START_RSH_WITH_POPEN_RW - /* Can't be set with SHUTDOWN_SERVER defined */ - else if (pclose (bc->fp) == EOF) - { - error (0, errno, "closing connection to %s", - current_parsed_root->hostname); - closefp = 0; - } -# endif /* START_RSH_WITH_POPEN_RW */ - - buf->input = NULL; - } - else if (buf->output) - { -# ifdef SHUTDOWN_SERVER - /* FIXME: Should have a SHUTDOWN_SERVER_INPUT & - * SHUTDOWN_SERVER_OUTPUT - */ - if (current_parsed_root->method == server_method) - SHUTDOWN_SERVER (fileno (bc->fp)); - else -# endif -# ifndef NO_SOCKET_TO_FD - /* shutdown() sockets */ - if (statted && S_ISSOCK (s.st_mode)) - shutdown (fileno (bc->fp), 1); -# else - { - /* I'm not sure I like this empty block, but the alternative - * is a another nested NO_SOCKET_TO_FD switch above. - */ - } -# endif /* NO_SOCKET_TO_FD */ - - buf->output = NULL; - } - - if (statted && closefp && fclose (bc->fp) == EOF) - { - if (server_active) - { - /* Syslog this? */ - } -# ifdef CLIENT_SUPPORT - /* We are already closing the connection. - * On error, print a warning and try to - * continue to avoid infinte loops. - */ - else - error (0, errno, - "closing down connection to %s", - current_parsed_root->hostname); -# endif /* CLIENT_SUPPORT */ - } - - /* If we were talking to a process, make sure it exited */ - if (bc->child_pid) - { - int w; - - do - w = waitpid (bc->child_pid, (int *) 0, 0); - while (w == -1 && errno == EINTR); - - /* We are already closing the connection. - * On error, print a warning and try to - * continue to avoid infinte loops. - */ - if (w == -1) - error (0, errno, "waiting for process %d", bc->child_pid); - } - return 0; -} - - - -/* Certain types of communication input and output data in packets, - where each packet is translated in some fashion. The packetizing - buffer type supports that, given a buffer which handles lower level - I/O and a routine to translate the data in a packet. - - This code uses two bytes for the size of a packet, so packets are - restricted to 65536 bytes in total. - - The translation functions should just translate; they may not - significantly increase or decrease the amount of data. The actual - size of the initial data is part of the translated data. The - output translation routine may add up to PACKET_SLOP additional - bytes, and the input translation routine should shrink the data - correspondingly. */ - -#define PACKET_SLOP (100) - -/* This structure is the closure field of a packetizing buffer. */ - -struct packetizing_buffer -{ - /* The underlying buffer. */ - struct buffer *buf; - /* The input translation function. Exactly one of inpfn and outfn - will be NULL. The input translation function should - untranslate the data in INPUT, storing the result in OUTPUT. - SIZE is the amount of data in INPUT, and is also the size of - OUTPUT. This should return 0 on success, or an errno code. */ - int (*inpfn) PROTO((void *fnclosure, const char *input, char *output, - int size)); - /* The output translation function. This should translate the - data in INPUT, storing the result in OUTPUT. The first two - bytes in INPUT will be the size of the data, and so will SIZE. - This should set *TRANSLATED to the amount of translated data in - OUTPUT. OUTPUT is large enough to hold SIZE + PACKET_SLOP - bytes. This should return 0 on success, or an errno code. */ - int (*outfn) PROTO((void *fnclosure, const char *input, char *output, - int size, int *translated)); - /* A closure for the translation function. */ - void *fnclosure; - /* For an input buffer, we may have to buffer up data here. */ - /* This is non-zero if the buffered data has been translated. - Otherwise, the buffered data has not been translated, and starts - with the two byte packet size. */ - int translated; - /* The amount of buffered data. */ - int holdsize; - /* The buffer allocated to hold the data. */ - char *holdbuf; - /* The size of holdbuf. */ - int holdbufsize; - /* If translated is set, we need another data pointer to track - where we are in holdbuf. If translated is clear, then this - pointer is not used. */ - char *holddata; -}; - -static int packetizing_buffer_input PROTO((void *, char *, int, int, int *)); -static int packetizing_buffer_output PROTO((void *, const char *, int, int *)); -static int packetizing_buffer_flush PROTO((void *)); -static int packetizing_buffer_block PROTO((void *, int)); -static int packetizing_buffer_shutdown PROTO((struct buffer *)); - -/* Create a packetizing buffer. */ - -struct buffer * -packetizing_buffer_initialize (buf, inpfn, outfn, fnclosure, memory) - struct buffer *buf; - int (*inpfn) PROTO ((void *, const char *, char *, int)); - int (*outfn) PROTO ((void *, const char *, char *, int, int *)); - void *fnclosure; - void (*memory) PROTO((struct buffer *)); -{ - struct packetizing_buffer *pb; - - pb = (struct packetizing_buffer *) xmalloc (sizeof *pb); - memset (pb, 0, sizeof *pb); - - pb->buf = buf; - pb->inpfn = inpfn; - pb->outfn = outfn; - pb->fnclosure = fnclosure; - - if (inpfn != NULL) - { - /* Add PACKET_SLOP to handle larger translated packets, and - add 2 for the count. This buffer is increased if - necessary. */ - pb->holdbufsize = BUFFER_DATA_SIZE + PACKET_SLOP + 2; - pb->holdbuf = xmalloc (pb->holdbufsize); - } - - return buf_initialize (inpfn != NULL ? packetizing_buffer_input : NULL, - inpfn != NULL ? NULL : packetizing_buffer_output, - inpfn != NULL ? NULL : packetizing_buffer_flush, - packetizing_buffer_block, - packetizing_buffer_shutdown, - memory, - pb); -} - -/* Input data from a packetizing buffer. */ - -static int -packetizing_buffer_input (closure, data, need, size, got) - void *closure; - char *data; - int need; - int size; - int *got; -{ - struct packetizing_buffer *pb = (struct packetizing_buffer *) closure; - - *got = 0; - - if (pb->holdsize > 0 && pb->translated) - { - int copy; - - copy = pb->holdsize; - - if (copy > size) - { - memcpy (data, pb->holddata, size); - pb->holdsize -= size; - pb->holddata += size; - *got = size; - return 0; - } - - memcpy (data, pb->holddata, copy); - pb->holdsize = 0; - pb->translated = 0; - - data += copy; - need -= copy; - size -= copy; - *got = copy; - } - - while (need > 0 || *got == 0) - { - int get, status, nread, count, tcount; - char *bytes; - char stackoutbuf[BUFFER_DATA_SIZE + PACKET_SLOP]; - char *inbuf, *outbuf; - - /* If we don't already have the two byte count, get it. */ - if (pb->holdsize < 2) - { - get = 2 - pb->holdsize; - status = buf_read_data (pb->buf, get, &bytes, &nread); - if (status != 0) - { - /* buf_read_data can return -2, but a buffer input - function is only supposed to return -1, 0, or an - error code. */ - if (status == -2) - status = ENOMEM; - return status; - } - - if (nread == 0) - { - /* The buffer is in nonblocking mode, and we didn't - manage to read anything. */ - return 0; - } - - if (get == 1) - pb->holdbuf[1] = bytes[0]; - else - { - pb->holdbuf[0] = bytes[0]; - if (nread < 2) - { - /* We only got one byte, but we needed two. Stash - the byte we got, and try again. */ - pb->holdsize = 1; - continue; - } - pb->holdbuf[1] = bytes[1]; - } - pb->holdsize = 2; - } - - /* Read the packet. */ - - count = (((pb->holdbuf[0] & 0xff) << 8) - + (pb->holdbuf[1] & 0xff)); - - if (count + 2 > pb->holdbufsize) - { - char *n; - - /* We didn't allocate enough space in the initialize - function. */ - - n = xrealloc (pb->holdbuf, count + 2); - if (n == NULL) - { - (*pb->buf->memory_error) (pb->buf); - return ENOMEM; - } - pb->holdbuf = n; - pb->holdbufsize = count + 2; - } - - get = count - (pb->holdsize - 2); - - status = buf_read_data (pb->buf, get, &bytes, &nread); - if (status != 0) - { - /* buf_read_data can return -2, but a buffer input - function is only supposed to return -1, 0, or an error - code. */ - if (status == -2) - status = ENOMEM; - return status; - } - - if (nread == 0) - { - /* We did not get any data. Presumably the buffer is in - nonblocking mode. */ - return 0; - } - - if (nread < get) - { - /* We did not get all the data we need to fill the packet. - buf_read_data does not promise to return all the bytes - requested, so we must try again. */ - memcpy (pb->holdbuf + pb->holdsize, bytes, nread); - pb->holdsize += nread; - continue; - } - - /* We have a complete untranslated packet of COUNT bytes. */ - - if (pb->holdsize == 2) - { - /* We just read the entire packet (the 2 bytes in - PB->HOLDBUF are the size). Save a memcpy by - translating directly from BYTES. */ - inbuf = bytes; - } - else - { - /* We already had a partial packet in PB->HOLDBUF. We - need to copy the new data over to make the input - contiguous. */ - memcpy (pb->holdbuf + pb->holdsize, bytes, nread); - inbuf = pb->holdbuf + 2; - } - - if (count <= sizeof stackoutbuf) - outbuf = stackoutbuf; - else - { - outbuf = xmalloc (count); - if (outbuf == NULL) - { - (*pb->buf->memory_error) (pb->buf); - return ENOMEM; - } - } - - status = (*pb->inpfn) (pb->fnclosure, inbuf, outbuf, count); - if (status != 0) - return status; - - /* The first two bytes in the translated buffer are the real - length of the translated data. */ - tcount = ((outbuf[0] & 0xff) << 8) + (outbuf[1] & 0xff); - - if (tcount > count) - error (1, 0, "Input translation failure"); - - if (tcount > size) - { - /* We have more data than the caller has provided space - for. We need to save some of it for the next call. */ - - memcpy (data, outbuf + 2, size); - *got += size; - - pb->holdsize = tcount - size; - memcpy (pb->holdbuf, outbuf + 2 + size, tcount - size); - pb->holddata = pb->holdbuf; - pb->translated = 1; - - if (outbuf != stackoutbuf) - free (outbuf); - - return 0; - } - - memcpy (data, outbuf + 2, tcount); - - if (outbuf != stackoutbuf) - free (outbuf); - - pb->holdsize = 0; - - data += tcount; - need -= tcount; - size -= tcount; - *got += tcount; - } - - return 0; -} - -/* Output data to a packetizing buffer. */ - -static int -packetizing_buffer_output (closure, data, have, wrote) - void *closure; - const char *data; - int have; - int *wrote; -{ - struct packetizing_buffer *pb = (struct packetizing_buffer *) closure; - char inbuf[BUFFER_DATA_SIZE + 2]; - char stack_outbuf[BUFFER_DATA_SIZE + PACKET_SLOP + 4]; - struct buffer_data *outdata = NULL; - char *outbuf; - int size, status, translated; - - if (have > BUFFER_DATA_SIZE) - { - /* It would be easy to xmalloc a buffer, but I don't think this - case can ever arise. */ - abort (); - } - - inbuf[0] = (have >> 8) & 0xff; - inbuf[1] = have & 0xff; - memcpy (inbuf + 2, data, have); - - size = have + 2; - - /* The output function is permitted to add up to PACKET_SLOP - bytes, and we need 2 bytes for the size of the translated data. - If we can guarantee that the result will fit in a buffer_data, - we translate directly into one to avoid a memcpy in buf_output. */ - if (size + PACKET_SLOP + 2 > BUFFER_DATA_SIZE) - outbuf = stack_outbuf; - else - { - outdata = get_buffer_data (); - if (outdata == NULL) - { - (*pb->buf->memory_error) (pb->buf); - return ENOMEM; - } - - outdata->next = NULL; - outdata->bufp = outdata->text; - - outbuf = outdata->text; - } - - status = (*pb->outfn) (pb->fnclosure, inbuf, outbuf + 2, size, - &translated); - if (status != 0) - return status; - - /* The output function is permitted to add up to PACKET_SLOP - bytes. */ - if (translated > size + PACKET_SLOP) - abort (); - - outbuf[0] = (translated >> 8) & 0xff; - outbuf[1] = translated & 0xff; - - if (outbuf == stack_outbuf) - buf_output (pb->buf, outbuf, translated + 2); - else - { - /* if ((have + PACKET_SLOP + 4) > BUFFER_DATA_SIZE), then - outdata may be NULL. */ - if (outdata == NULL) - abort (); - - outdata->size = translated + 2; - buf_append_data (pb->buf, outdata, outdata); - } - - *wrote = have; - - /* We will only be here because buf_send_output was called on the - packetizing buffer. That means that we should now call - buf_send_output on the underlying buffer. */ - return buf_send_output (pb->buf); -} - - - -/* Flush data to a packetizing buffer. */ -static int -packetizing_buffer_flush (closure) - void *closure; -{ - struct packetizing_buffer *pb = (struct packetizing_buffer *) closure; - - /* Flush the underlying buffer. Note that if the original call to - buf_flush passed 1 for the BLOCK argument, then the buffer will - already have been set into blocking mode, so we should always - pass 0 here. */ - return buf_flush (pb->buf, 0); -} - - - -/* The block routine for a packetizing buffer. */ -static int -packetizing_buffer_block (closure, block) - void *closure; - int block; -{ - struct packetizing_buffer *pb = (struct packetizing_buffer *) closure; - - if (block) - return set_block (pb->buf); - else - return set_nonblock (pb->buf); -} - -/* Shut down a packetizing buffer. */ - -static int -packetizing_buffer_shutdown (buf) - struct buffer *buf; -{ - struct packetizing_buffer *pb = (struct packetizing_buffer *) buf->closure; - - return buf_shutdown (pb->buf); -} - -#endif /* defined (SERVER_SUPPORT) || defined (CLIENT_SUPPORT) */ diff --git a/contrib/cvs/src/buffer.h b/contrib/cvs/src/buffer.h deleted file mode 100644 index 3459058..0000000 --- a/contrib/cvs/src/buffer.h +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright (C) 1996-2005 The Free Software Foundation, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -/* Declarations concerning the buffer data structure. */ - -#if defined (SERVER_SUPPORT) || defined (CLIENT_SUPPORT) - -/* - * We must read data from a child process and send it across the - * network. We do not want to block on writing to the network, so we - * store the data from the child process in memory. A BUFFER - * structure holds the status of one communication, and uses a linked - * list of buffer_data structures to hold data. - */ - -struct buffer -{ - /* Data. */ - struct buffer_data *data; - - /* Last buffer on data chain. */ - struct buffer_data *last; - - /* Nonzero if the buffer is in nonblocking mode. */ - int nonblocking; - - /* Functions must be provided to transfer data in and out of the - buffer. Either the input or output field must be set, but not - both. */ - - /* Read data into the buffer DATA. There is room for up to SIZE - bytes. In blocking mode, wait until some input, at least NEED - bytes, is available (NEED may be 0 but that is the same as NEED - == 1). In non-blocking mode return immediately no matter how - much input is available; NEED is ignored. Return 0 on success, - or -1 on end of file, or an errno code. Set the number of - bytes read in *GOT. - - If there are a nonzero number of bytes available, less than NEED, - followed by end of file, just read those bytes and return 0. */ - int (*input) PROTO((void *closure, char *data, int need, int size, - int *got)); - - /* Write data. This should write up to HAVE bytes from DATA. - This should return 0 on success, or an errno code. It should - set the number of bytes written in *WROTE. */ - int (*output) PROTO((void *closure, const char *data, int have, - int *wrote)); - - /* Flush any data which may be buffered up after previous calls to - OUTPUT. This should return 0 on success, or an errno code. */ - int (*flush) PROTO((void *closure)); - - /* Change the blocking mode of the underlying communication - stream. If BLOCK is non-zero, it should be placed into - blocking mode. Otherwise, it should be placed into - non-blocking mode. This should return 0 on success, or an - errno code. */ - int (*block) PROTO ((void *closure, int block)); - - /* Shut down the communication stream. This does not mean that it - should be closed. It merely means that no more data will be - read or written, and that any final processing that is - appropriate should be done at this point. This may be NULL. - It should return 0 on success, or an errno code. This entry - point exists for the compression code. */ - int (*shutdown) PROTO((struct buffer *)); - - /* This field is passed to the INPUT, OUTPUT, and BLOCK functions. */ - void *closure; - - /* Function to call if we can't allocate memory. */ - void (*memory_error) PROTO((struct buffer *)); -}; - -/* Data is stored in lists of these structures. */ - -struct buffer_data -{ - /* Next buffer in linked list. */ - struct buffer_data *next; - - /* - * A pointer into the data area pointed to by the text field. This - * is where to find data that has not yet been written out. - */ - char *bufp; - - /* The number of data bytes found at BUFP. */ - int size; - - /* - * Actual buffer. This never changes after the structure is - * allocated. The buffer is BUFFER_DATA_SIZE bytes. - */ - char *text; -}; - -/* The size we allocate for each buffer_data structure. */ -#define BUFFER_DATA_SIZE (4096) - -/* The type of a function passed as a memory error handler. */ -typedef void (*BUFMEMERRPROC) PROTO ((struct buffer *)); - -extern struct buffer *buf_initialize PROTO((int (*) (void *, char *, int, - int, int *), - int (*) (void *, const char *, - int, int *), - int (*) (void *), - int (*) (void *, int), - int (*) (struct buffer *), - void (*) (struct buffer *), - void *)); -extern void buf_free PROTO((struct buffer *)); -extern struct buffer *buf_nonio_initialize PROTO((void (*) (struct buffer *))); -extern struct buffer *stdio_buffer_initialize - PROTO((FILE *, int, int, void (*) (struct buffer *))); -extern FILE *stdio_buffer_get_file PROTO((struct buffer *)); -extern struct buffer *compress_buffer_initialize - PROTO((struct buffer *, int, int, void (*) (struct buffer *))); -extern struct buffer *packetizing_buffer_initialize - PROTO((struct buffer *, int (*) (void *, const char *, char *, int), - int (*) (void *, const char *, char *, int, int *), void *, - void (*) (struct buffer *))); -extern int buf_empty PROTO((struct buffer *)); -extern int buf_empty_p PROTO((struct buffer *)); -extern void buf_output PROTO((struct buffer *, const char *, int)); -extern void buf_output0 PROTO((struct buffer *, const char *)); -extern void buf_append_char PROTO((struct buffer *, int)); -extern int buf_send_output PROTO((struct buffer *)); -extern int buf_flush PROTO((struct buffer *, int)); -extern int set_nonblock PROTO((struct buffer *)); -extern int set_block PROTO((struct buffer *)); -extern int buf_send_counted PROTO((struct buffer *)); -extern int buf_send_special_count PROTO((struct buffer *, int)); -extern void buf_append_data PROTO((struct buffer *, - struct buffer_data *, - struct buffer_data *)); -extern void buf_append_buffer PROTO((struct buffer *, struct buffer *)); -extern int buf_read_file PROTO((FILE *, long, struct buffer_data **, - struct buffer_data **)); -extern int buf_read_file_to_eof PROTO((FILE *, struct buffer_data **, - struct buffer_data **)); -extern int buf_input_data PROTO((struct buffer *, int *)); -extern int buf_read_line PROTO((struct buffer *, char **, int *)); -extern int buf_read_data PROTO((struct buffer *, int, char **, int *)); -extern void buf_copy_lines PROTO((struct buffer *, struct buffer *, int)); -extern int buf_copy_counted PROTO((struct buffer *, struct buffer *, int *)); -extern int buf_chain_length PROTO((struct buffer_data *)); -extern int buf_length PROTO((struct buffer *)); -extern int buf_shutdown PROTO((struct buffer *)); - -#ifdef SERVER_FLOWCONTROL -extern int buf_count_mem PROTO((struct buffer *)); -#endif /* SERVER_FLOWCONTROL */ - -#endif /* defined (SERVER_SUPPORT) || defined (CLIENT_SUPPORT) */ diff --git a/contrib/cvs/src/checkin.c b/contrib/cvs/src/checkin.c deleted file mode 100644 index 06d431f..0000000 --- a/contrib/cvs/src/checkin.c +++ /dev/null @@ -1,192 +0,0 @@ -/* - * Copyright (C) 1986-2005 The Free Software Foundation, Inc. - * - * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot , - * and others. - * - * Portions Copyright (C) 1992, Brian Berliner and Jeff Polk - * Portions Copyright (C) 1989-1992, Brian Berliner - * - * You may distribute under the terms of the GNU General Public License as - * specified in the README file that comes with the CVS source distribution. - * - * Check In - * - * Does a very careful checkin of the file "user", and tries not to spoil its - * modification time (to avoid needless recompilations). When RCS ID keywords - * get expanded on checkout, however, the modification time is updated and - * there is no good way to get around this. - * - * Returns non-zero on error. - */ - -#include -#include "cvs.h" -#include "fileattr.h" -#include "edit.h" - -int -Checkin (type, finfo, rev, tag, options, message) - int type; - struct file_info *finfo; - char *rev; - char *tag; - char *options; - char *message; -{ - Vers_TS *vers; - int set_time; - char *tocvsPath = NULL; - - /* Hmm. This message goes to stdout and the "foo,v <-- foo" - message from "ci" goes to stderr. This doesn't make a whole - lot of sense, but making everything go to stdout can only be - gracefully achieved once RCS_checkin is librarified. */ - cvs_output ("Checking in ", 0); - cvs_output (finfo->fullname, 0); - cvs_output (";\n", 0); - - tocvsPath = wrap_tocvs_process_file (finfo->file); - if (!noexec) - { - if (tocvsPath) - { - if (unlink_file_dir (finfo->file) < 0) - if (! existence_error (errno)) - error (1, errno, "cannot remove %s", finfo->fullname); - rename_file (tocvsPath, finfo->file); - } - } - - /* There use to be a check for finfo->rcs == NULL here and then a - * call to RCS_parse when necessary, but Checkin() isn't called - * if the RCS file hasn't already been parsed in one of the - * check functions. - */ - assert (finfo->rcs != NULL); - - switch (RCS_checkin (finfo->rcs, finfo->file, message, rev, 0, - RCS_FLAGS_KEEPFILE)) - { - case 0: /* everything normal */ - - /* The checkin succeeded. If checking the file out again - would not cause any changes, we are done. Otherwise, - we need to check out the file, which will change the - modification time of the file. - - The only way checking out the file could cause any - changes is if the file contains RCS keywords. So we if - we are not expanding RCS keywords, we are done. */ - - if (options != NULL - && strcmp (options, "-V4") == 0) /* upgrade to V5 now */ - options[0] = '\0'; - - /* FIXME: If PreservePermissions is on, RCS_cmp_file is - going to call RCS_checkout into a temporary file - anyhow. In that case, it would be more efficient to - call RCS_checkout here, compare the resulting files - using xcmp, and rename if necessary. I think this - should be fixed in RCS_cmp_file. */ - if( ( ! preserve_perms - && options != NULL - && ( strcmp( options, "-ko" ) == 0 - || strcmp( options, "-kb" ) == 0 ) ) - || RCS_cmp_file( finfo->rcs, rev, (char **)NULL, (char *)NULL, - options, finfo->file ) == 0 ) - { - /* The existing file is correct. We don't have to do - anything. */ - set_time = 0; - } - else - { - /* The existing file is incorrect. We need to check - out the correct file contents. */ - if (RCS_checkout (finfo->rcs, finfo->file, rev, (char *) NULL, - options, RUN_TTY, (RCSCHECKOUTPROC) NULL, - (void *) NULL) != 0) - error (1, 0, "failed when checking out new copy of %s", - finfo->fullname); - xchmod (finfo->file, 1); - set_time = 1; - } - - wrap_fromcvs_process_file (finfo->file); - - /* - * If we want read-only files, muck the permissions here, before - * getting the file time-stamp. - */ - if (!cvswrite || fileattr_get (finfo->file, "_watched")) - xchmod (finfo->file, 0); - - /* Re-register with the new data. */ - vers = Version_TS (finfo, NULL, tag, NULL, 1, set_time); - if (strcmp (vers->options, "-V4") == 0) - vers->options[0] = '\0'; - Register (finfo->entries, finfo->file, vers->vn_rcs, vers->ts_user, - vers->options, vers->tag, vers->date, (char *) 0); - history_write (type, NULL, vers->vn_rcs, - finfo->file, finfo->repository); - - if (tocvsPath) - if (unlink_file_dir (tocvsPath) < 0) - error (0, errno, "cannot remove %s", tocvsPath); - - break; - - case -1: /* fork failed */ - if (tocvsPath) - if (unlink_file_dir (tocvsPath) < 0) - error (0, errno, "cannot remove %s", tocvsPath); - - if (!noexec) - error (1, errno, "could not check in %s -- fork failed", - finfo->fullname); - return (1); - - default: /* ci failed */ - - /* The checkin failed, for some unknown reason, so we - print an error, and return an error. We assume that - the original file has not been touched. */ - if (tocvsPath) - if (unlink_file_dir (tocvsPath) < 0) - error (0, errno, "cannot remove %s", tocvsPath); - - if (!noexec) - error (0, 0, "could not check in %s", finfo->fullname); - return (1); - } - - /* - * When checking in a specific revision, we may have locked the wrong - * branch, so to be sure, we do an extra unlock here before - * returning. - */ - if (rev) - { - (void) RCS_unlock (finfo->rcs, NULL, 1); - RCS_rewrite (finfo->rcs, NULL, NULL); - } - -#ifdef SERVER_SUPPORT - if (server_active) - { - if (set_time) - /* Need to update the checked out file on the client side. */ - server_updated (finfo, vers, SERVER_UPDATED, - (mode_t) -1, (unsigned char *) NULL, - (struct buffer *) NULL); - else - server_checked_in (finfo->file, finfo->update_dir, finfo->repository); - } - else -#endif - mark_up_to_date (finfo->file); - - freevers_ts (&vers); - return 0; -} diff --git a/contrib/cvs/src/checkout.c b/contrib/cvs/src/checkout.c deleted file mode 100644 index a1cd6cc..0000000 --- a/contrib/cvs/src/checkout.c +++ /dev/null @@ -1,1284 +0,0 @@ -/* - * Copyright (C) 1986-2005 The Free Software Foundation, Inc. - * - * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot , - * and others. - * - * Portions Copyright (C) 1992, Brian Berliner and Jeff Polk - * Portions Copyright (C) 1989-1992, Brian Berliner - * - * You may distribute under the terms of the GNU General Public License as - * specified in the README file that comes with the CVS source distribution. - * - * Create Version - * - * "checkout" creates a "version" of an RCS repository. This version is owned - * totally by the user and is actually an independent copy, to be dealt with - * as seen fit. Once "checkout" has been called in a given directory, it - * never needs to be called again. The user can keep up-to-date by calling - * "update" when he feels like it; this will supply him with a merge of his - * own modifications and the changes made in the RCS original. See "update" - * for details. - * - * "checkout" can be given a list of directories or files to be updated and in - * the case of a directory, will recursivley create any sub-directories that - * exist in the repository. - * - * When the user is satisfied with his own modifications, the present version - * can be committed by "commit"; this keeps the present version in tact, - * usually. - * - * The call is cvs checkout [options] ... - * - * "checkout" creates a directory ./CVS, in which it keeps its administration, - * in two files, Repository and Entries. The first contains the name of the - * repository. The second contains one line for each registered file, - * consisting of the version number it derives from, its time stamp at - * derivation time and its name. Both files are normal files and can be - * edited by the user, if necessary (when the repository is moved, e.g.) - */ - -/* - * $FreeBSD$ - */ - -#include -#include "cvs.h" - -static char *findslash PROTO((char *start, char *p)); -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 const char *const checkout_usage[] = -{ - "Usage:\n %s %s [-ANPRcflnps] [-r rev] [-D date] [-d dir]\n", - " [-j rev1] [-j rev2] [-k kopt] modules...\n", - "\t-A\tReset any sticky tags/date/kopts.\n", - "\t-N\tDon't shorten module paths if -d specified.\n", - "\t-P\tPrune empty directories.\n", - "\t-R\tProcess directories recursively.\n", - "\t-T\tCreate Template file from local repository for remote commit.\n", - "\t-c\t\"cat\" the module database.\n", - "\t-f\tForce a head revision match if tag/date not found.\n", - "\t-l\tLocal directory only, not recursive\n", - "\t-n\tDo not run module program (if any).\n", - "\t-p\tCheck out files to standard output (avoids stickiness).\n", - "\t-s\tLike -c, but include module status.\n", - "\t-r rev\tCheck out revision or tag. (implies -P) (is sticky)\n", - "\t-D date\tCheck out revisions as of date. (implies -P) (is sticky)\n", - "\t-d dir\tCheck out into dir instead of module name.\n", - "\t-k kopt\tUse RCS kopt -k option on checkout. (is sticky)\n", - "\t-j rev\tMerge in changes made between current revision and rev.\n", - "(Specify the --help global option for a list of other help options)\n", - NULL -}; - -static const char *const export_usage[] = -{ - "Usage: %s %s [-NRfln] [-r tag] [-D date] [-d dir] [-k kopt] module...\n", - "\t-N\tDon't shorten module paths if -d specified.\n", - "\t-f\tForce a head revision match if tag/date not found.\n", - "\t-l\tLocal directory only, not recursive\n", - "\t-R\tProcess directories recursively (default).\n", - "\t-n\tDo not run module program (if any).\n", - "\t-r tag\tExport tagged revisions.\n", - "\t-D date\tExport revisions as of date.\n", - "\t-d dir\tExport into dir instead of module name.\n", - "\t-k kopt\tUse RCS kopt -k option on checkout.\n", - "(Specify the --help global option for a list of other help options)\n", - NULL -}; - -static int checkout_prune_dirs; -static int force_tag_match; -static int pipeout; -static int aflag; -static char *options; -static char *tag; -static int tag_validated; -static char *date; -static char *join_rev1; -static char *join_rev2; -static int join_tags_validated; -static int pull_template; -static char *preload_update_dir; -static char *history_name; -static enum mtype m_type; - -int -checkout (argc, argv) - int argc; - char **argv; -{ - int i; - int c; - DBM *db; - int cat = 0, err = 0, status = 0; - int run_module_prog = 1; - int local = 0; - int shorten = -1; - char *where = NULL; - char *valid_options; - const char *const *valid_usage; - - /* initialize static options */ - force_tag_match = 1; - if (options) - { - free (options); - options = NULL; - } - tag = date = join_rev1 = join_rev2 = preload_update_dir = NULL; - history_name = NULL; - tag_validated = join_tags_validated = 0; - - - /* - * A smaller subset of options are allowed for the export command, which - * is essentially like checkout, except that it hard-codes certain - * options to be default (like -kv) and takes care to remove the CVS - * directory when it has done its duty - */ - if (strcmp (cvs_cmd_name, "export") == 0) - { - m_type = EXPORT; - valid_options = "+Nnk:d:flRQqr:D:"; - valid_usage = export_usage; - } - else - { - m_type = CHECKOUT; - valid_options = "+ANnk:d:flRpTQqcsr:D:j:P"; - valid_usage = checkout_usage; - } - - if (argc == -1) - usage (valid_usage); - - ign_setup (); - wrap_setup (); - - optind = 0; - while ((c = getopt (argc, argv, valid_options)) != -1) - { - switch (c) - { - case 'A': - aflag = 1; - break; - case 'N': - shorten = 0; - break; - case 'k': - if (options) - free (options); - options = RCS_check_kflag (optarg); - break; - case 'n': - run_module_prog = 0; - break; - case 'T': - pull_template = 1; - break; - case 'Q': - case 'q': - /* The CVS 1.5 client sends these options (in addition to - Global_option requests), so we must ignore them. */ - if (!server_active) - error (1, 0, - "-q or -Q must be specified before \"%s\"", - cvs_cmd_name); - break; - case 'l': - local = 1; - break; - case 'R': - local = 0; - break; - case 'P': - checkout_prune_dirs = 1; - break; - case 'p': - pipeout = 1; - run_module_prog = 0; /* don't run module prog when piping */ - noexec = 1; /* so no locks will be created */ - break; - case 'c': - cat = 1; - break; - case 'd': - where = optarg; - if (shorten == -1) - shorten = 1; - break; - case 's': - cat = status = 1; - break; - case 'f': - force_tag_match = 0; - break; - case 'r': - tag = optarg; - checkout_prune_dirs = 1; - break; - case 'D': - date = Make_Date (optarg); - checkout_prune_dirs = 1; - break; - case 'j': - if (join_rev2) - error (1, 0, "only two -j options can be specified"); - if (join_rev1) - join_rev2 = optarg; - else - join_rev1 = optarg; - break; - case '?': - default: - usage (valid_usage); - break; - } - } - argc -= optind; - argv += optind; - - if (shorten == -1) - shorten = 0; - - if (cat && argc != 0) - error (1, 0, "-c and -s must not get any arguments"); - - if (!cat && argc == 0) - error (1, 0, "must specify at least one module or directory"); - - if (where && pipeout) - error (1, 0, "-d and -p are mutually exclusive"); - - if (m_type == EXPORT) - { - if (!tag && !date) - error (1, 0, "must specify a tag or date"); - - if (tag && isdigit ((unsigned char) tag[0])) - error (1, 0, "tag `%s' must be a symbolic tag", tag); - } - -#ifdef SERVER_SUPPORT - if (server_active && where != NULL) - { - server_pathname_check (where); - } -#endif - - if (!cat && !pipeout && !safe_location( where )) { - error(1, 0, "Cannot check out files into the repository itself"); - } - -#ifdef CLIENT_SUPPORT - if (current_parsed_root->isremote) - { - int expand_modules; - - start_server (); - - ign_setup (); - - expand_modules = (!cat && !pipeout - && supported_request ("expand-modules")); - - if (expand_modules) - { - /* This is done here because we need to read responses - from the server before we send the command checkout or - export files. */ - - client_expand_modules (argc, argv, local); - } - - if (!run_module_prog) - send_arg ("-n"); - if (local) - send_arg ("-l"); - if (pipeout) - send_arg ("-p"); - if (!force_tag_match) - send_arg ("-f"); - if (aflag) - send_arg("-A"); - if (!shorten) - send_arg("-N"); - if (checkout_prune_dirs && m_type == CHECKOUT) - send_arg("-P"); - client_prune_dirs = checkout_prune_dirs; - if (cat && !status) - send_arg("-c"); - if (where != NULL) - option_with_arg ("-d", where); - if (status) - send_arg("-s"); - if (options != NULL && options[0] != '\0') - send_arg (options); - option_with_arg ("-r", tag); - if (date) - client_senddate (date); - if (join_rev1 != NULL) - option_with_arg ("-j", join_rev1); - if (join_rev2 != NULL) - option_with_arg ("-j", join_rev2); - send_arg ("--"); - - if (expand_modules) - { - client_send_expansions (local, where, 1); - } - else - { - int i; - for (i = 0; i < argc; ++i) - send_arg (argv[i]); - client_nonexpanded_setup (); - } - - send_to_server (m_type == EXPORT ? "export\012" : "co\012", 0); - return get_responses_and_close (); - } -#endif /* CLIENT_SUPPORT */ - - if (cat) - { - cat_module (status); - if (options) - { - free (options); - options = NULL; - } - return (0); - } - db = open_module (); - - - /* If we've specified something like "cvs co foo/bar baz/quux" - don't try to shorten names. There are a few cases in which we - could shorten (e.g. "cvs co foo/bar foo/baz"), but we don't - handle those yet. Better to have an extra directory created - than the thing checked out under the wrong directory name. */ - - if (argc > 1) - shorten = 0; - - - /* If we will be calling history_write, work out the name to pass - it. */ - if (!pipeout) - { - if (!date) - history_name = tag; - else if (!tag) - history_name = date; - else - { - history_name = xmalloc (strlen (tag) + strlen (date) + 2); - sprintf (history_name, "%s:%s", tag, date); - } - } - - - for (i = 0; i < argc; i++) - err += do_module (db, argv[i], m_type, "Updating", checkout_proc, - where, shorten, local, run_module_prog, !pipeout, - (char *) NULL); - close_module (db); - if (options) - { - free (options); - options = NULL; - } - if (history_name != tag && history_name != date && history_name != NULL) - free (history_name); - return (err); -} - -/* FIXME: This is and emptydir_name are in checkout.c for historical - reasons, probably want to move them. */ - -/* int - * safe_location ( char *where ) - * - * Return true if where is a safe destination for a checkout. - * - * INPUTS - * where The requested destination directory. - * - * GLOBALS - * current_parsed_root->directory - * current_parsed_root->isremote - * Used to locate our CVSROOT. - * - * RETURNS - * true If we are running in client mode or if where is not located - * within the CVSROOT. - * false Otherwise. - * - * ERRORS - * Exits with a fatal error message when various events occur, such as not - * being able to resolve a path or failing ot chdir to a path. - */ -int -safe_location (where) - char *where; -{ - char *current; - char *where_location; - char *hardpath; - size_t hardpath_len; - int retval; - - if (trace) - (void) fprintf (stderr, "%s-> safe_location( where=%s )\n", - CLIENT_SERVER_STR, - where ? where : "(null)"); - - /* Don't compare remote CVSROOTs to our destination directory. */ - if (current_parsed_root->isremote) return 1; - - /* set current - even if where is set we'll need to cd back... */ - current = xgetwd (); - if (current == NULL) - error (1, errno, "could not get working directory"); - - hardpath = xresolvepath ( current_parsed_root->directory ); - - /* if where is set, set current to where, where - last_component( where ), - * or fail, depending on whether the directories exist or not. - */ - if( where != NULL ) - { - if( chdir( where ) != -1 ) - { - /* where */ - where_location = xgetwd(); - if( where_location == NULL ) - error( 1, errno, "could not get working directory" ); - - if( chdir( current ) == -1 ) - error( 1, errno, "could not change directory to `%s'", current ); - - free( current ); - current = where_location; - } - else if( errno == ENOENT ) - { - if ( last_component( where ) != where ) - { - /* where - last_component( where ) */ - char *parent; - - /* strip the last_component */ - where_location = xstrdup (where); - /* It's okay to cast out the const below since we know we just - * allocated where_location and can do what we like with it. - */ - parent = (char *)last_component (where_location); - parent[-1] = '\0'; - - if( chdir( where_location ) != -1 ) - { - free( where_location ); - where_location = xgetwd(); - if( where_location == NULL ) - error( 1, errno, "could not get working directory (nominally `%s')", where_location ); - - if( chdir( current ) == -1 ) - error( 1, errno, "could not change directory to `%s'", current ); - - free( current ); - current = where_location; - } - else - /* fail */ - error( 1, errno, "could not change directory to requested checkout directory `%s'", where_location ); - } - /* else: ERRNO == ENOENT & last_component(where) == where - * for example, 'cvs co -d newdir module', where newdir hasn't - * been created yet, so leave current set to '.' and check that - */ - } - else - /* fail */ - error( 1, errno, "could not change directory to requested checkout directory `%s'", where ); - } - - hardpath_len = strlen (hardpath); - if (strlen (current) >= hardpath_len - && strncmp (current, hardpath, hardpath_len) == 0) - { - if (/* Current is a subdirectory of hardpath. */ - current[hardpath_len] == '/' - - /* Current is hardpath itself. */ - || current[hardpath_len] == '\0') - retval = 0; - else - /* It isn't a problem. For example, current is - "/foo/cvsroot-bar" and hardpath is "/foo/cvsroot". */ - retval = 1; - } - else - retval = 1; - free (current); - free (hardpath); - return retval; -} - -struct dir_to_build -{ - /* What to put in CVS/Repository. */ - char *repository; - /* The path to the directory. */ - char *dirpath; - - /* If set, don't build the directory, just change to it. - The caller will also want to set REPOSITORY to NULL. */ - int just_chdir; - - struct dir_to_build *next; -}; - -static int build_dirs_and_chdir PROTO ((struct dir_to_build *list, - int sticky)); - -static void build_one_dir PROTO ((char *, char *, int)); - -static void -build_one_dir (repository, dirpath, sticky) - char *repository; - char *dirpath; - int sticky; -{ - FILE *fp; - - 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)) - error (1, 0, "there is no repository %s", repository); - - if (Create_Admin (".", dirpath, repository, - sticky ? tag : (char *) NULL, - sticky ? date : (char *) NULL, - - /* FIXME? This is a guess. If it is important - for nonbranch to be set correctly here I - think we need to write it one way now and - then rewrite it later via WriteTag, once - we've had a chance to call RCS_nodeisbranch - on each file. */ - 0, 1, 1)) - return; - - if (!noexec) - { - 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 (dirpath, repository); -#endif - } - } -} - -/* - * process_module calls us back here so we do the actual checkout stuff - */ -/* ARGSUSED */ -static int -checkout_proc (argc, argv, where_orig, mwhere, mfile, shorten, - local_specified, omodule, msg) - int argc; - char **argv; - char *where_orig; - char *mwhere; - char *mfile; - int shorten; - int local_specified; - char *omodule; - char *msg; -{ - char *myargv[2]; - int err = 0; - int which; - char *cp; - char *repository; - char *oldupdate = NULL; - char *where; - - /* - * OK, so we're doing the checkout! Our args are as follows: - * argc,argv contain either dir or dir followed by a list of files - * where contains where to put it (if supplied by checkout) - * mwhere contains the module name or -d from module file - * mfile says do only that part of the module - * shorten = 1 says shorten as much as possible - * omodule is the original arg to do_module() - */ - - /* Set up the repository (maybe) for the bottom directory. - Allocate more space than we need so we don't need to keep - reallocating this string. */ - repository = xmalloc (strlen (current_parsed_root->directory) - + strlen (argv[0]) - + (mfile == NULL ? 0 : strlen (mfile)) - + 10); - (void) sprintf (repository, "%s/%s", current_parsed_root->directory, argv[0]); - Sanitize_Repository_Name (repository); - - - /* save the original value of preload_update_dir */ - if (preload_update_dir != NULL) - oldupdate = xstrdup (preload_update_dir); - - - /* Allocate space and set up the where variable. We allocate more - space than necessary here so that we don't have to keep - reallocaing it later on. */ - - where = xmalloc (strlen (argv[0]) - + (mfile == NULL ? 0 : strlen (mfile)) - + (mwhere == NULL ? 0 : strlen (mwhere)) - + (where_orig == NULL ? 0 : strlen (where_orig)) - + 10); - - /* Yes, this could be written in a less verbose way, but in this - form it is quite easy to read. - - FIXME? The following code that sets should probably be moved - to do_module in modules.c, since there is similar code in - patch.c and rtag.c. */ - - if (shorten) - { - if (where_orig != NULL) - { - /* If the user has specified a directory with `-d' on the - command line, use it preferentially, even over the `-d' - flag in the modules file. */ - - (void) strcpy (where, where_orig); - } - else if (mwhere != NULL) - { - /* Second preference is the value of mwhere, which is from - the `-d' flag in the modules file. */ - - (void) strcpy (where, mwhere); - } - else - { - /* Third preference is the directory specified in argv[0] - which is this module'e directory in the repository. */ - - (void) strcpy (where, argv[0]); - } - } - else - { - /* Use the same preferences here, bug don't shorten -- that - is, tack on where_orig if it exists. */ - - *where = '\0'; - - if (where_orig != NULL) - { - (void) strcat (where, where_orig); - (void) strcat (where, "/"); - } - - /* If the -d flag in the modules file specified an absolute - directory, let the user override it with the command-line - -d option. */ - - if ((mwhere != NULL) && (! isabsolute (mwhere))) - (void) strcat (where, mwhere); - else - (void) strcat (where, argv[0]); - } - strip_trailing_slashes (where); /* necessary? */ - - - /* At this point, the user may have asked for a single file or - directory from within a module. In that case, we should modify - where, repository, and argv as appropriate. */ - - if (mfile != NULL) - { - /* The mfile variable can have one or more path elements. If - it has multiple elements, we want to tack those onto both - repository and where. The last element may refer to either - a file or directory. Here's what to do: - - it refers to a directory - -> simply tack it on to where and repository - it refers to a file - -> munge argv to contain `basename mfile` */ - - char *cp; - char *path; - - - /* Paranoia check. */ - - if (mfile[strlen (mfile) - 1] == '/') - { - error (0, 0, "checkout_proc: trailing slash on mfile (%s)!", - mfile); - } - - - /* Does mfile have multiple path elements? */ - - cp = strrchr (mfile, '/'); - if (cp != NULL) - { - *cp = '\0'; - (void) strcat (repository, "/"); - (void) strcat (repository, mfile); - (void) strcat (where, "/"); - (void) strcat (where, mfile); - mfile = cp + 1; - } - - - /* Now mfile is a single path element. */ - - path = xmalloc (strlen (repository) + strlen (mfile) + 5); - (void) sprintf (path, "%s/%s", repository, mfile); - if (isdir (path)) - { - /* It's a directory, so tack it on to repository and - where, as we did above. */ - - (void) strcat (repository, "/"); - (void) strcat (repository, mfile); - (void) strcat (where, "/"); - (void) strcat (where, mfile); - } - else - { - /* It's a file, which means we have to screw around with - argv. */ - myargv[0] = argv[0]; - myargv[1] = mfile; - argc = 2; - argv = myargv; - } - free (path); - } - - if (preload_update_dir != NULL) - { - preload_update_dir = - xrealloc (preload_update_dir, - strlen (preload_update_dir) + strlen (where) + 5); - strcat (preload_update_dir, "/"); - strcat (preload_update_dir, where); - } - else - preload_update_dir = xstrdup (where); - - /* - * At this point, where is the directory we want to build, repository is - * the repository for the lowest level of the path. - * - * We need to tell build_dirs not only the path we want it to - * build, but also the repositories we want it to populate the - * path with. To accomplish this, we walk the path backwards, one - * pathname component at a time, constucting a linked list of - * struct dir_to_build. - */ - - /* - * If we are sending everything to stdout, we can skip a whole bunch of - * work from here - */ - if (!pipeout) - { - struct dir_to_build *head; - char *reposcopy; - - if (strncmp (repository, current_parsed_root->directory, - strlen (current_parsed_root->directory)) != 0) - error (1, 0, "\ -internal error: %s doesn't start with %s in checkout_proc", - repository, current_parsed_root->directory); - - /* We always create at least one directory, which corresponds to - the entire strings for WHERE and REPOSITORY. */ - head = (struct dir_to_build *) xmalloc (sizeof (struct dir_to_build)); - /* Special marker to indicate that we don't want build_dirs_and_chdir - to create the CVSADM directory for us. */ - head->repository = NULL; - head->dirpath = xstrdup (where); - head->next = NULL; - head->just_chdir = 0; - - - /* Make a copy of the repository name to play with. */ - reposcopy = xstrdup (repository); - - /* FIXME: this should be written in terms of last_component - instead of hardcoding '/'. This presumably affects OS/2, - NT, &c, if the user specifies '\'. Likewise for the call - to findslash. */ - cp = where + strlen (where); - while (cp > where) - { - struct dir_to_build *new; - - cp = findslash (where, cp - 1); - if (cp == NULL) - break; /* we're done */ - - new = (struct dir_to_build *) - xmalloc (sizeof (struct dir_to_build)); - new->dirpath = xmalloc (strlen (where)); - - /* If the user specified an absolute path for where, the - last path element we create should be the top-level - directory. */ - - if (cp > where) - { - strncpy (new->dirpath, where, cp - where); - new->dirpath[cp - where] = '\0'; - } - else - { - /* where should always be at least one character long. */ - assert (where[0] != '\0'); - strcpy (new->dirpath, "/"); - } - new->next = head; - head = new; - - /* If where consists of multiple pathname components, - then we want to just cd into it, without creating - directories or modifying CVS directories as we go. - In CVS 1.9 and earlier, the code actually does a - CVS_CHDIR up-front; I'm not going to try to go back - to that exact code but this is somewhat similar - in spirit. */ - if (where_orig != NULL - && cp - where < strlen (where_orig)) - { - new->repository = NULL; - new->just_chdir = 1; - continue; - } - - new->just_chdir = 0; - - /* Now figure out what repository directory to generate. - The most complete case would be something like this: - - The modules file contains - foo -d bar/baz quux - - The command issued was: - cvs co -d what/ever -N foo - - The results in the CVS/Repository files should be: - . -> (don't touch CVS/Repository) - (I think this case might be buggy currently) - what -> (don't touch CVS/Repository) - ever -> . (same as "cd what/ever; cvs co -N foo") - bar -> Emptydir (generated dir -- not in repos) - baz -> quux (finally!) */ - - if (strcmp (reposcopy, current_parsed_root->directory) == 0) - { - /* We can't walk up past CVSROOT. Instead, the - repository should be Emptydir. */ - new->repository = emptydir_name (); - } - else - { - /* It's a directory in the repository! */ - - 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", - reposcopy); - - *rp = '\0'; - new->repository = xmalloc (strlen (reposcopy) + 5); - (void) strcpy (new->repository, reposcopy); - - if (strcmp (reposcopy, current_parsed_root->directory) == 0) - { - /* Special case -- the repository name needs - to be "/path/to/repos/." (the trailing dot - is important). We might be able to get rid - of this after the we check out the other - code that handles repository names. */ - (void) strcat (new->repository, "/."); - } - } - } - - /* clean up */ - free (reposcopy); - - /* The top-level CVSADM directory should always be - current_parsed_root->directory. Create it, but only if WHERE is - relative. If WHERE is absolute, our current directory - may not have a thing to do with where the sources are - being checked out. If it does, build_dirs_and_chdir - will take care of creating adm files here. */ - /* FIXME: checking is_absolute (where) is a horrid kludge; - I suspect we probably can just skip the call to - build_one_dir whenever the -d command option was specified - to checkout. */ - - if (!isabsolute (where) && top_level_admin && m_type == CHECKOUT) - { - /* It may be argued that we shouldn't set any sticky - bits for the top-level repository. FIXME? */ - build_one_dir (current_parsed_root->directory, ".", argc <= 1); - -#ifdef SERVER_SUPPORT - /* We _always_ want to have a top-level admin - directory. If we're running in client/server mode, - send a "Clear-static-directory" command to make - sure it is created on the client side. (See 5.10 - in cvsclient.dvi to convince yourself that this is - OK.) If this is a duplicate command being sent, it - will be ignored on the client side. */ - - if (server_active) - server_clear_entstat (".", current_parsed_root->directory); -#endif - } - - - /* Build dirs on the path if necessary and leave us in the - bottom directory (where if where was specified) doesn't - contain a CVS subdir yet, but all the others contain - CVS and Entries.Static files */ - - if (build_dirs_and_chdir (head, argc <= 1) != 0) - { - error (0, 0, "ignoring module %s", omodule); - err = 1; - goto out; - } - - /* set up the repository (or make sure the old one matches) */ - if (!isfile (CVSADM)) - { - FILE *fp; - - 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, - m_type == CHECKOUT); - 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 (where, repository); -#endif - } - else - { - /* 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, tag, date, - - /* FIXME? This is a guess. If it is important - for nonbranch to be set correctly here I - think we need to write it one way now and - then rewrite it later via WriteTag, once - we've had a chance to call RCS_nodeisbranch - on each file. */ - 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) - { - error (0, 0, "existing repository %s does not match %s", - repos, repository); - error (0, 0, "ignoring module %s", omodule); - free (repos); - err = 1; - goto out; - } - free (repos); - } - } - - /* - * If we are going to be updating to stdout, we need to cd to the - * repository directory so the recursion processor can use the current - * directory as the place to find repository information - */ - if (pipeout) - { - if ( CVS_CHDIR (repository) < 0) - { - error (0, errno, "cannot chdir to %s", repository); - err = 1; - goto out; - } - which = W_REPOS; - if (tag != NULL && !tag_validated) - { - tag_check_valid (tag, argc - 1, argv + 1, 0, aflag, - repository); - tag_validated = 1; - } - } - else - { - which = W_LOCAL | W_REPOS; - if (tag != NULL && !tag_validated) - { - tag_check_valid (tag, argc - 1, argv + 1, 0, aflag, - repository); - tag_validated = 1; - } - } - - if (tag != NULL || date != NULL || join_rev1 != NULL) - which |= W_ATTIC; - - if (! join_tags_validated) - { - if (join_rev1 != NULL) - tag_check_valid_join (join_rev1, argc - 1, argv + 1, 0, aflag, - repository); - if (join_rev2 != NULL) - tag_check_valid_join (join_rev2, argc - 1, argv + 1, 0, aflag, - repository); - join_tags_validated = 1; - } - - /* - * if we are going to be recursive (building dirs), go ahead and call the - * update recursion processor. We will be recursive unless either local - * only was specified, or we were passed arguments - */ - if (!(local_specified || argc > 1)) - { - if (!pipeout) - history_write (m_type == CHECKOUT ? 'O' : 'E', preload_update_dir, - history_name, where, repository); - err += do_update (0, (char **) NULL, options, tag, date, - force_tag_match, 0 /* !local */ , - 1 /* update -d */ , aflag, checkout_prune_dirs, - pipeout, which, join_rev1, join_rev2, - preload_update_dir, pull_template, repository); - goto out; - } - - if (!pipeout) - { - int i; - List *entries; - - /* we are only doing files, so register them */ - entries = Entries_Open (0, NULL); - for (i = 1; i < argc; i++) - { - char *line; - Vers_TS *vers; - struct file_info finfo; - - memset (&finfo, 0, sizeof finfo); - finfo.file = argv[i]; - /* Shouldn't be used, so set to arbitrary value. */ - finfo.update_dir = NULL; - finfo.fullname = argv[i]; - finfo.repository = repository; - finfo.entries = entries; - /* The rcs slot is needed to get the options from the RCS - file */ - finfo.rcs = RCS_parse (finfo.file, repository); - - vers = Version_TS (&finfo, options, tag, date, - force_tag_match, 0); - if (vers->ts_user == NULL) - { - line = xmalloc (strlen (finfo.file) + 15); - (void) sprintf (line, "Initial %s", finfo.file); - Register (entries, finfo.file, - vers->vn_rcs ? vers->vn_rcs : "0", - line, vers->options, vers->tag, - vers->date, (char *) 0); - free (line); - } - freevers_ts (&vers); - freercsnode (&finfo.rcs); - } - - Entries_Close (entries); - } - - /* Don't log "export", just regular "checkouts" */ - 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 (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, pull_template, repository); -out: - free (preload_update_dir); - preload_update_dir = oldupdate; - free (where); - free (repository); - return (err); -} - -static char * -findslash (start, p) - char *start; - char *p; -{ - for (;;) - { - if (*p == '/') return p; - if (p == start) break; - --p; - } - return NULL; -} - -/* Return a newly malloc'd string containing a pathname for CVSNULLREPOS, - and make sure that it exists. If there is an error creating the - directory, give a fatal error. Otherwise, the directory is guaranteed - to exist when we return. */ -char * -emptydir_name () -{ - char *repository; - - repository = xmalloc (strlen (current_parsed_root->directory) - + sizeof (CVSROOTADM) - + sizeof (CVSNULLREPOS) - + 3); - (void) sprintf (repository, "%s/%s/%s", current_parsed_root->directory, - CVSROOTADM, CVSNULLREPOS); - if (!isfile (repository)) - { - mode_t omask; - omask = umask (cvsumask); - if (CVS_MKDIR (repository, 0777) < 0) - error (1, errno, "cannot create %s", repository); - (void) umask (omask); - } - return repository; -} - -/* Build all the dirs along the path to DIRS with CVS subdirs with appropriate - * repositories. If DIRS->repository is NULL or the directory already exists, - * do not create a CVSADM directory for that subdirectory; just CVS_CHDIR into - * it. Frees all storage used by DIRS. - * - * ASSUMPTIONS - * 1. Parent directories will be listed in DIRS before their children. - * 2. At most a single directory will need to be changed at one time. In - * other words, if we are in /a/b/c, and our final destination is - * /a/b/c/d/e/f, then we will build d, then d/e, then d/e/f. - * - * INPUTS - * dirs Simple list composed of dir_to_build structures, listing - * information about directories to build. - * sticky Passed to build_one_dir to tell it whether there are any sticky - * tags or dates to be concerned with. - * - * RETURNS - * 1 on error, 0 otherwise. - * - * ERRORS - * The only nonfatal error this function may return is if the CHDIR fails. - */ -static int -build_dirs_and_chdir (dirs, sticky) - struct dir_to_build *dirs; - int sticky; -{ - int retval = 0; - struct dir_to_build *nextdir; - - while (dirs != NULL) - { - const char *dir = last_component (dirs->dirpath); - - if (!dirs->just_chdir) - { - mkdir_if_needed (dir); - Subdir_Register (NULL, NULL, dir); - } - - if (CVS_CHDIR (dir) < 0) - { - error (0, errno, "cannot chdir to %s", dir); - retval = 1; - goto out; - } - if (dirs->repository != NULL) - { - build_one_dir (dirs->repository, dirs->dirpath, sticky); - free (dirs->repository); - } - nextdir = dirs->next; - free (dirs->dirpath); - free (dirs); - dirs = nextdir; - } - - out: - while (dirs != NULL) - { - if (dirs->repository != NULL) - free (dirs->repository); - nextdir = dirs->next; - free (dirs->dirpath); - free (dirs); - dirs = nextdir; - } - return retval; -} diff --git a/contrib/cvs/src/classify.c b/contrib/cvs/src/classify.c deleted file mode 100644 index 28d7263..0000000 --- a/contrib/cvs/src/classify.c +++ /dev/null @@ -1,474 +0,0 @@ -/* - * Copyright (C) 1986-2005 The Free Software Foundation, Inc. - * - * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot , - * and others. - * - * Portions Copyright (C) 1992, Brian Berliner and Jeff Polk - * Portions Copyright (C) 1989-1992, Brian Berliner - * - * You may distribute under the terms of the GNU General Public License as - * specified in the README file that comes with the CVS source distribution. - * - */ - -#include -__FBSDID("$FreeBSD$"); - -#include "cvs.h" - -static void sticky_ck PROTO ((struct file_info *finfo, int aflag, - Vers_TS * vers)); - - - -static inline int keywords_may_change PROTO ((int aflag, Vers_TS * vers)); -static inline int -keywords_may_change (aflag, vers) - int aflag; - Vers_TS * vers; -{ - int retval; - - if (/* Options are different... */ - strcmp (vers->entdata->options, vers->options) - /* ...or... */ - || (/* ...clearing stickies... */ - aflag - /* ...and... */ - && (/* ...there used to be a tag which subs in Name keys... */ - (vers->entdata->tag && !isdigit (vers->entdata->tag[0]) - && vers->tag && !isdigit (vers->tag[0]) - && strcmp (vers->entdata->tag, vers->tag)) - /* ...or there used to be a keyword mode which may be - * changed by -A... - */ - || (strlen (vers->entdata->options) - && strcmp (vers->entdata->options, vers->options) - && strcmp (vers->entdata->options, "-kkv") - && strcmp (vers->entdata->options, "-kb")))) - /* ...or... */ - || (/* ...this is not commit... */ - strcmp (cvs_cmd_name, "commit") - /* ...and... */ - && (/* ...the tag is changing in a way that affects Name keys... */ - (vers->entdata->tag && vers->tag - && strcmp (vers->entdata->tag, vers->tag) - && !(isdigit (vers->entdata->tag[0]) - && isdigit (vers->entdata->tag[0]))) - || (!vers->entdata->tag && vers->tag - && !isdigit (vers->tag[0]))))) - retval = 1; - else - retval = 0; - - return retval; -} - - - -/* - * Classify the state of a file - */ -Ctype -Classify_File (finfo, tag, date, options, force_tag_match, aflag, versp, - pipeout) - struct file_info *finfo; - char *tag; - char *date; - - /* Keyword expansion options. Can be either NULL or "" to - indicate none are specified here. */ - char *options; - - int force_tag_match; - int aflag; - Vers_TS **versp; - int pipeout; -{ - Vers_TS *vers; - Ctype ret; - - /* get all kinds of good data about the file */ - vers = Version_TS (finfo, options, tag, date, - force_tag_match, 0); - - if (vers->vn_user == NULL) - { - /* No entry available, ts_rcs is invalid */ - if (vers->vn_rcs == NULL) - { - /* there is no RCS file either */ - if (vers->ts_user == NULL) - { - /* there is no user file */ - /* FIXME: Why do we skip this message if vers->tag or - vers->date is set? It causes "cvs update -r tag98 foo" - to silently do nothing, which is seriously confusing - behavior. "cvs update foo" gives this message, which - is what I would expect. */ - if (!force_tag_match || !(vers->tag || vers->date)) - if (!really_quiet) - error (0, 0, "nothing known about %s", finfo->fullname); - ret = T_UNKNOWN; - } - else - { - /* there is a user file */ - /* FIXME: Why do we skip this message if vers->tag or - vers->date is set? It causes "cvs update -r tag98 foo" - to silently do nothing, which is seriously confusing - behavior. "cvs update foo" gives this message, which - is what I would expect. */ - if (!force_tag_match || !(vers->tag || vers->date)) - if (!really_quiet) - error (0, 0, "use `%s add' to create an entry for %s", - program_name, finfo->fullname); - ret = T_UNKNOWN; - } - } - else if (RCS_isdead (vers->srcfile, vers->vn_rcs)) - { - /* there is an RCS file, but it's dead */ - if (vers->ts_user == NULL) - ret = T_UPTODATE; - else - { - error (0, 0, "use `%s add' to create an entry for %s", - program_name, finfo->fullname); - ret = T_UNKNOWN; - } - } - else if (!pipeout && vers->ts_user && No_Difference (finfo, vers)) - { - /* the files were different so it is a conflict */ - if (!really_quiet) - error (0, 0, "move away %s; it is in the way", - finfo->fullname); - ret = T_CONFLICT; - } - else - /* no user file or no difference, just checkout */ - ret = T_CHECKOUT; - } - else if (strcmp (vers->vn_user, "0") == 0) - { - /* An entry for a new-born file; ts_rcs is dummy */ - - if (vers->ts_user == NULL) - { - if (pipeout) - { - ret = T_CHECKOUT; - } - else - { - /* - * There is no user file, but there should be one; remove the - * entry - */ - if (!really_quiet) - error (0, 0, "warning: new-born %s has disappeared", - finfo->fullname); - ret = T_REMOVE_ENTRY; - } - } - else if (vers->vn_rcs == NULL || - RCS_isdead (vers->srcfile, vers->vn_rcs)) - /* No RCS file or RCS file revision is dead */ - ret = T_ADDED; - else - { - if (pipeout) - { - ret = T_CHECKOUT; - } - else - { - if (vers->srcfile->flags & INATTIC - && vers->srcfile->flags & VALID) - { - /* This file has been added on some branch other than - the one we are looking at. In the branch we are - looking at, the file was already valid. */ - if (!really_quiet) - error (0, 0, - "conflict: %s has been added, but already exists", - finfo->fullname); - } - else - { - /* - * There is an RCS file, so someone else must have checked - * one in behind our back; conflict - */ - if (!really_quiet) - error (0, 0, - "conflict: %s created independently by second party", - finfo->fullname); - } - ret = T_CONFLICT; - } - } - } - else if (vers->vn_user[0] == '-') - { - /* An entry for a removed file, ts_rcs is invalid */ - - if (vers->ts_user == NULL) - { - /* There is no user file (as it should be) */ - - if (vers->vn_rcs == NULL - || RCS_isdead (vers->srcfile, vers->vn_rcs)) - { - - /* - * There is no RCS file; this is all-right, but it has been - * removed independently by a second party; remove the entry - */ - ret = T_REMOVE_ENTRY; - } - else if (strcmp (vers->vn_rcs, vers->vn_user + 1) == 0) - /* - * The RCS file is the same version as the user file was, and - * that's OK; remove it - */ - ret = T_REMOVED; - else if (pipeout) - /* - * The RCS file doesn't match the user's file, but it doesn't - * matter in this case - */ - ret = T_NEEDS_MERGE; - else - { - - /* - * The RCS file is a newer version than the removed user file - * and this is definitely not OK; make it a conflict. - */ - if (!really_quiet) - error (0, 0, - "conflict: removed %s was modified by second party", - finfo->fullname); - ret = T_CONFLICT; - } - } - else - { - /* The user file shouldn't be there */ - if (!really_quiet) - error (0, 0, "%s should be removed and is still there", - finfo->fullname); - ret = T_REMOVED; - } - } - else - { - /* A normal entry, TS_Rcs is valid */ - if (vers->vn_rcs == NULL || RCS_isdead (vers->srcfile, vers->vn_rcs)) - { - /* There is no RCS file */ - - if (vers->ts_user == NULL) - { - /* There is no user file, so just remove the entry */ - if (!really_quiet) - error (0, 0, "warning: %s is not (any longer) pertinent", - finfo->fullname); - ret = T_REMOVE_ENTRY; - } - else if (strcmp (vers->ts_user, vers->ts_rcs) == 0) - { - - /* - * The user file is still unmodified, so just remove it from - * the entry list - */ - if (!really_quiet) - error (0, 0, "%s is no longer in the repository", - finfo->fullname); - ret = T_REMOVE_ENTRY; - } - else if (No_Difference (finfo, vers)) - { - /* they are different -> conflict */ - if (!really_quiet) - error (0, 0, - "conflict: %s is modified but no longer in the repository", - finfo->fullname); - ret = T_CONFLICT; - } - else - { - /* they weren't really different */ - if (!really_quiet) - error (0, 0, - "warning: %s is not (any longer) pertinent", - finfo->fullname); - ret = T_REMOVE_ENTRY; - } - } - else if (strcmp (vers->vn_rcs, vers->vn_user) == 0) - { - /* The RCS file is the same version as the user file */ - - if (vers->ts_user == NULL) - { - - /* - * There is no user file, so note that it was lost and - * extract a new version - */ - /* Comparing the cvs_cmd_name against "update", in - addition to being an ugly way to operate, means - that this message does not get printed by the - server. That might be considered just a straight - bug, although there is one subtlety: that case also - gets hit when a patch fails and the client fetches - a file. I'm not sure there is currently any way - for the server to distinguish those two cases. */ - if (strcmp (cvs_cmd_name, "update") == 0) - if (!really_quiet) - error (0, 0, "warning: %s was lost", finfo->fullname); - ret = T_CHECKOUT; - } - else if (!strcmp (vers->ts_user, - vers->ts_conflict - ? vers->ts_conflict : vers->ts_rcs)) - { - - /* - * The user file is still unmodified, so nothing special at - * all to do -- no lists updated, unless the sticky -k option - * has changed. If the sticky tag has changed, we just need - * to re-register the entry - */ - /* TODO: decide whether we need to check file permissions - for a mismatch, and return T_CONFLICT if so. */ - if (keywords_may_change (aflag, vers)) - ret = T_PATCH; - else if (vers->ts_conflict) - ret = T_CONFLICT; - else - { - ret = T_UPTODATE; - sticky_ck (finfo, aflag, vers); - } - } - else if (No_Difference (finfo, vers)) - { - - /* - * they really are different; modified if we aren't - * changing any sticky -k options, else needs merge - */ -#ifdef XXX_FIXME_WHEN_RCSMERGE_IS_FIXED - if (strcmp (vers->entdata->options ? - vers->entdata->options : "", vers->options) == 0) - ret = T_MODIFIED; - else - ret = T_NEEDS_MERGE; -#else - /* Files with conflict markers and new timestamps fall through - * here, but they need to. T_CONFLICT is an error in - * commit_fileproc, whereas T_CONFLICT with conflict markers - * is caught but only warned about. Similarly, update_fileproc - * currently reregisters a file that was conflicted but lost - * its markers. - */ - ret = T_MODIFIED; - sticky_ck (finfo, aflag, vers); -#endif - } - else if (strcmp (vers->entdata->options ? - vers->entdata->options : "", vers->options) != 0) - { - /* file has not changed; check out if -k changed */ - ret = T_CHECKOUT; - } - else - { - - /* - * else -> note that No_Difference will Register the - * file already for us, using the new tag/date. This - * is the desired behaviour - */ - ret = T_UPTODATE; - } - } - else - { - /* The RCS file is a newer version than the user file */ - - if (vers->ts_user == NULL) - { - /* There is no user file, so just get it */ - - /* See comment at other "update" compare, for more - thoughts on this comparison. */ - if (strcmp (cvs_cmd_name, "update") == 0) - if (!really_quiet) - error (0, 0, "warning: %s was lost", finfo->fullname); - ret = T_CHECKOUT; - } - else if (strcmp (vers->ts_user, vers->ts_rcs) == 0) - - /* - * The user file is still unmodified, so just get it as well - */ - ret = T_PATCH; - else if (No_Difference (finfo, vers)) - /* really modified, needs to merge */ - ret = T_NEEDS_MERGE; - else - ret = T_PATCH; - } - } - - /* free up the vers struct, or just return it */ - if (versp != (Vers_TS **) NULL) - *versp = vers; - else - freevers_ts (&vers); - - /* return the status of the file */ - return (ret); -} - -static void -sticky_ck (finfo, aflag, vers) - struct file_info *finfo; - int aflag; - Vers_TS *vers; -{ - if (aflag || vers->tag || vers->date) - { - char *enttag = vers->entdata->tag; - char *entdate = vers->entdata->date; - - if ((enttag && vers->tag && strcmp (enttag, vers->tag)) || - ((enttag && !vers->tag) || (!enttag && vers->tag)) || - (entdate && vers->date && strcmp (entdate, vers->date)) || - ((entdate && !vers->date) || (!entdate && vers->date))) - { - Register (finfo->entries, finfo->file, vers->vn_user, vers->ts_rcs, - vers->options, vers->tag, vers->date, vers->ts_conflict); - -#ifdef SERVER_SUPPORT - if (server_active) - { - /* We need to update the entries line on the client side. - It is possible we will later update it again via - server_updated or some such, but that is OK. */ - server_update_entries - (finfo->file, finfo->update_dir, finfo->repository, - strcmp (vers->ts_rcs, vers->ts_user) == 0 ? - SERVER_UPDATED : SERVER_MERGED); - } -#endif - } - } -} diff --git a/contrib/cvs/src/client.c b/contrib/cvs/src/client.c deleted file mode 100644 index 1c8a5d0..0000000 --- a/contrib/cvs/src/client.c +++ /dev/null @@ -1,5948 +0,0 @@ -/* CVS client-related stuff. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. */ - -/* - * $FreeBSD$ - */ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif /* HAVE_CONFIG_H */ - -#include -#include "cvs.h" -#include "getline.h" -#include "edit.h" -#include "buffer.h" -#include "savecwd.h" - -#ifdef CLIENT_SUPPORT - -# include "md5.h" - -# if defined(AUTH_CLIENT_SUPPORT) || defined(HAVE_KERBEROS) || defined(HAVE_GSSAPI) || defined(SOCK_ERRNO) || defined(SOCK_STRERROR) -# ifdef HAVE_WINSOCK_H -# include -# else /* No winsock.h */ -# include -# include -# include -# include -# endif /* No winsock.h */ -# endif - -/* If SOCK_ERRNO is defined, then send()/recv() and other socket calls - do not set errno, but that this macro should be used to obtain an - error code. This probably doesn't make sense unless - NO_SOCKET_TO_FD is also defined. */ -# ifndef SOCK_ERRNO -# define SOCK_ERRNO errno -# endif - -/* If SOCK_STRERROR is defined, then the error codes returned by - socket operations are not known to strerror, and this macro must be - used instead to convert those error codes to strings. */ -# ifndef SOCK_STRERROR -# define SOCK_STRERROR strerror - -# if STDC_HEADERS -# include -# endif - -# ifndef strerror -extern char *strerror (); -# endif -# endif /* ! SOCK_STRERROR */ - -# if HAVE_KERBEROS - -# include - -extern char *krb_realmofhost (); -# ifndef HAVE_KRB_GET_ERR_TEXT -# define krb_get_err_text(status) krb_err_txt[status] -# endif /* HAVE_KRB_GET_ERR_TEXT */ - -/* Information we need if we are going to use Kerberos encryption. */ -static C_Block kblock; -static Key_schedule sched; - -# endif /* HAVE_KERBEROS */ - -# ifdef HAVE_GSSAPI - -# include "xgssapi.h" - -/* This is needed for GSSAPI encryption. */ -static gss_ctx_id_t gcontext; - -static int connect_to_gserver PROTO((cvsroot_t *, int, struct hostent *)); - -# endif /* HAVE_GSSAPI */ - - - -/* Keep track of any paths we are sending for Max-dotdot so that we can verify - * that uplevel paths coming back form the server are valid. - * - * FIXME: The correct way to do this is probably provide some sort of virtual - * path map on the client side. This would be generic enough to be applied to - * absolute paths supplied by the user too. - */ -static List *uppaths = NULL; - - - -static void add_prune_candidate PROTO((const char *)); - -/* All the commands. */ -int add PROTO((int argc, char **argv)); -int admin PROTO((int argc, char **argv)); -int checkout PROTO((int argc, char **argv)); -int commit PROTO((int argc, char **argv)); -int diff PROTO((int argc, char **argv)); -int history PROTO((int argc, char **argv)); -int import PROTO((int argc, char **argv)); -int cvslog PROTO((int argc, char **argv)); -int patch PROTO((int argc, char **argv)); -int release PROTO((int argc, char **argv)); -int cvsremove PROTO((int argc, char **argv)); -int rtag PROTO((int argc, char **argv)); -int status PROTO((int argc, char **argv)); -int tag PROTO((int argc, char **argv)); -int update PROTO((int argc, char **argv)); - -/* All the response handling functions. */ -static void handle_ok PROTO((char *, int)); -static void handle_error PROTO((char *, int)); -static void handle_valid_requests PROTO((char *, int)); -static void handle_checked_in PROTO((char *, int)); -static void handle_new_entry PROTO((char *, int)); -static void handle_checksum PROTO((char *, int)); -static void handle_copy_file PROTO((char *, int)); -static void handle_updated PROTO((char *, int)); -static void handle_merged PROTO((char *, int)); -static void handle_patched PROTO((char *, int)); -static void handle_rcs_diff PROTO((char *, int)); -static void handle_removed PROTO((char *, int)); -static void handle_remove_entry PROTO((char *, int)); -static void handle_set_static_directory PROTO((char *, int)); -static void handle_clear_static_directory PROTO((char *, int)); -static void handle_set_sticky PROTO((char *, int)); -static void handle_clear_sticky PROTO((char *, int)); -static void handle_module_expansion PROTO((char *, int)); -static void handle_wrapper_rcs_option PROTO((char *, int)); -static void handle_m PROTO((char *, int)); -static void handle_e PROTO((char *, int)); -static void handle_f PROTO((char *, int)); -static void handle_notified PROTO((char *, int)); - -static size_t try_read_from_server PROTO ((char *, size_t)); - -static void auth_server PROTO ((cvsroot_t *, struct buffer *, struct buffer *, - int, int, struct hostent *)); - -/* We need to keep track of the list of directories we've sent to the - server. This list, along with the current CVSROOT, will help us - decide which command-line arguments to send. */ -List *dirs_sent_to_server = NULL; - -static int is_arg_a_parent_or_listed_dir PROTO((Node *, void *)); - -static int -is_arg_a_parent_or_listed_dir (n, d) - Node *n; - void *d; -{ - char *directory = n->key; /* name of the dir sent to server */ - char *this_argv_elem = xstrdup (d); /* this argv element */ - int retval; - - /* Say we should send this argument if the argument matches the - beginning of a directory name sent to the server. This way, - the server will know to start at the top of that directory - hierarchy and descend. */ - - strip_trailing_slashes (this_argv_elem); - if (strncmp (directory, this_argv_elem, strlen (this_argv_elem)) == 0) - retval = 1; - else - retval = 0; - - free (this_argv_elem); - return retval; -} - -static int arg_should_not_be_sent_to_server PROTO((char *)); - -/* Return nonzero if this argument should not be sent to the - server. */ - -static int -arg_should_not_be_sent_to_server (arg) - char *arg; -{ - /* Decide if we should send this directory name to the server. We - should always send argv[i] if: - - 1) the list of directories sent to the server is empty (as it - will be for checkout, etc.). - - 2) the argument is "." - - 3) the argument is a file in the cwd and the cwd is checked out - from the current root - - 4) the argument lies within one of the paths in - dirs_sent_to_server. - - */ - - if (list_isempty (dirs_sent_to_server)) - return 0; /* always send it */ - - if (strcmp (arg, ".") == 0) - return 0; /* always send it */ - - /* We should send arg if it is one of the directories sent to the - server or the parent of one; this tells the server to descend - the hierarchy starting at this level. */ - if (isdir (arg)) - { - if (walklist (dirs_sent_to_server, is_arg_a_parent_or_listed_dir, arg)) - return 0; - - /* If arg wasn't a parent, we don't know anything about it (we - would have seen something related to it during the - send_files phase). Don't send it. */ - return 1; - } - - /* Try to decide whether we should send arg to the server by - checking the contents of the corresponding CVSADM directory. */ - { - char *t, *root_string; - cvsroot_t *this_root = NULL; - - /* Calculate "dirname arg" */ - for (t = arg + strlen (arg) - 1; t >= arg; t--) - { - if (ISDIRSEP(*t)) - break; - } - - /* Now we're either poiting to the beginning of the - string, or we found a path separator. */ - if (t >= arg) - { - /* Found a path separator. */ - char c = *t; - *t = '\0'; - - /* First, check to see if we sent this directory to the - server, because it takes less time than actually - opening the stuff in the CVSADM directory. */ - if (walklist (dirs_sent_to_server, is_arg_a_parent_or_listed_dir, - arg)) - { - *t = c; /* make sure to un-truncate the arg */ - return 0; - } - - /* Since we didn't find it in the list, check the CVSADM - files on disk. */ - this_root = Name_Root (arg, (char *) NULL); - root_string = this_root->original; - *t = c; - } - else - { - /* We're at the beginning of the string. Look at the - CVSADM files in cwd. */ - if (CVSroot_cmdline) - root_string = CVSroot_cmdline; - else - { - this_root = Name_Root ((char *) NULL, (char *) NULL); - root_string = this_root->original; - } - } - - /* Now check the value for root. */ - if (CVSroot_cmdline == NULL && - root_string && current_parsed_root - && (strcmp (root_string, current_parsed_root->original) != 0)) - { - /* Don't send this, since the CVSROOTs don't match. */ - if (this_root) free_cvsroot_t (this_root); - return 1; - } - if (this_root) free_cvsroot_t (this_root); - } - - /* OK, let's send it. */ - return 0; -} - - - -#endif /* CLIENT_SUPPORT */ - - - -#if defined(CLIENT_SUPPORT) || defined(SERVER_SUPPORT) - -/* Shared with server. */ - -/* - * Return a malloc'd, '\0'-terminated string - * corresponding to the mode in SB. - */ -char * -#ifdef __STDC__ -mode_to_string (mode_t mode) -#else /* ! __STDC__ */ -mode_to_string (mode) - mode_t mode; -#endif /* __STDC__ */ -{ - char buf[18], u[4], g[4], o[4]; - int i; - - i = 0; - if (mode & S_IRUSR) u[i++] = 'r'; - if (mode & S_IWUSR) u[i++] = 'w'; - if (mode & S_IXUSR) u[i++] = 'x'; - u[i] = '\0'; - - i = 0; - if (mode & S_IRGRP) g[i++] = 'r'; - if (mode & S_IWGRP) g[i++] = 'w'; - if (mode & S_IXGRP) g[i++] = 'x'; - g[i] = '\0'; - - i = 0; - if (mode & S_IROTH) o[i++] = 'r'; - if (mode & S_IWOTH) o[i++] = 'w'; - if (mode & S_IXOTH) o[i++] = 'x'; - o[i] = '\0'; - - sprintf(buf, "u=%s,g=%s,o=%s", u, g, o); - return xstrdup(buf); -} - -/* - * Change mode of FILENAME to MODE_STRING. - * Returns 0 for success or errno code. - * If RESPECT_UMASK is set, then honor the umask. - */ -int -change_mode (filename, mode_string, respect_umask) - char *filename; - char *mode_string; - int respect_umask; -{ -#ifdef CHMOD_BROKEN - char *p; - int writeable = 0; - - /* We can only distinguish between - 1) readable - 2) writeable - 3) Picasso's "Blue Period" - We handle the first two. */ - p = mode_string; - while (*p != '\0') - { - if ((p[0] == 'u' || p[0] == 'g' || p[0] == 'o') && p[1] == '=') - { - char *q = p + 2; - while (*q != ',' && *q != '\0') - { - if (*q == 'w') - writeable = 1; - ++q; - } - } - /* Skip to the next field. */ - while (*p != ',' && *p != '\0') - ++p; - if (*p == ',') - ++p; - } - - /* xchmod honors the umask for us. In the !respect_umask case, we - don't try to cope with it (probably to handle that well, the server - needs to deal with modes in data structures, rather than via the - modes in temporary files). */ - xchmod (filename, writeable); - return 0; - -#else /* ! CHMOD_BROKEN */ - - char *p; - mode_t mode = 0; - mode_t oumask; - - p = mode_string; - while (*p != '\0') - { - if ((p[0] == 'u' || p[0] == 'g' || p[0] == 'o') && p[1] == '=') - { - int can_read = 0, can_write = 0, can_execute = 0; - char *q = p + 2; - while (*q != ',' && *q != '\0') - { - if (*q == 'r') - can_read = 1; - else if (*q == 'w') - can_write = 1; - else if (*q == 'x') - can_execute = 1; - ++q; - } - if (p[0] == 'u') - { - if (can_read) - mode |= S_IRUSR; - if (can_write) - mode |= S_IWUSR; - if (can_execute) - mode |= S_IXUSR; - } - else if (p[0] == 'g') - { - if (can_read) - mode |= S_IRGRP; - if (can_write) - mode |= S_IWGRP; - if (can_execute) - mode |= S_IXGRP; - } - else if (p[0] == 'o') - { - if (can_read) - mode |= S_IROTH; - if (can_write) - mode |= S_IWOTH; - if (can_execute) - mode |= S_IXOTH; - } - } - /* Skip to the next field. */ - while (*p != ',' && *p != '\0') - ++p; - if (*p == ',') - ++p; - } - - if (respect_umask) - { - oumask = umask (0); - (void) umask (oumask); - mode &= ~oumask; - } - - if (chmod (filename, mode) < 0) - return errno; - return 0; -#endif /* ! CHMOD_BROKEN */ -} - -#endif /* CLIENT_SUPPORT or SERVER_SUPPORT */ - -#ifdef CLIENT_SUPPORT - -int client_prune_dirs; - -static List *ignlist = (List *) NULL; - -/* Buffer to write to the server. */ -static struct buffer *to_server; - -/* Buffer used to read from the server. */ -static struct buffer *from_server; - - -/* We want to be able to log data sent between us and the server. We - do it using log buffers. Each log buffer has another buffer which - handles the actual I/O, and a file to log information to. - - This structure is the closure field of a log buffer. */ - -struct log_buffer -{ - /* The underlying buffer. */ - struct buffer *buf; - /* The file to log information to. */ - FILE *log; -}; - -static struct buffer *log_buffer_initialize - PROTO((struct buffer *, FILE *, int, void (*) (struct buffer *))); -static int log_buffer_input PROTO((void *, char *, int, int, int *)); -static int log_buffer_output PROTO((void *, const char *, int, int *)); -static int log_buffer_flush PROTO((void *)); -static int log_buffer_block PROTO((void *, int)); -static int log_buffer_shutdown PROTO((struct buffer *)); - -/* Create a log buffer. */ - -static struct buffer * -log_buffer_initialize (buf, fp, input, memory) - struct buffer *buf; - FILE *fp; - int input; - void (*memory) PROTO((struct buffer *)); -{ - struct log_buffer *n; - - n = (struct log_buffer *) xmalloc (sizeof *n); - n->buf = buf; - n->log = fp; - return buf_initialize (input ? log_buffer_input : NULL, - input ? NULL : log_buffer_output, - input ? NULL : log_buffer_flush, - log_buffer_block, - log_buffer_shutdown, - memory, - n); -} - -/* The input function for a log buffer. */ - -static int -log_buffer_input (closure, data, need, size, got) - void *closure; - char *data; - int need; - int size; - int *got; -{ - struct log_buffer *lb = (struct log_buffer *) closure; - int status; - size_t n_to_write; - - if (lb->buf->input == NULL) - abort (); - - status = (*lb->buf->input) (lb->buf->closure, data, need, size, got); - if (status != 0) - return status; - - if (*got > 0) - { - n_to_write = *got; - if (fwrite (data, 1, n_to_write, lb->log) != n_to_write) - error (0, errno, "writing to log file"); - } - - return 0; -} - -/* The output function for a log buffer. */ - -static int -log_buffer_output (closure, data, have, wrote) - void *closure; - const char *data; - int have; - int *wrote; -{ - struct log_buffer *lb = (struct log_buffer *) closure; - int status; - size_t n_to_write; - - if (lb->buf->output == NULL) - abort (); - - status = (*lb->buf->output) (lb->buf->closure, data, have, wrote); - if (status != 0) - return status; - - if (*wrote > 0) - { - n_to_write = *wrote; - if (fwrite (data, 1, n_to_write, lb->log) != n_to_write) - error (0, errno, "writing to log file"); - } - - return 0; -} - -/* The flush function for a log buffer. */ - -static int -log_buffer_flush (closure) - void *closure; -{ - struct log_buffer *lb = (struct log_buffer *) closure; - - if (lb->buf->flush == NULL) - abort (); - - /* We don't really have to flush the log file here, but doing it - will let tail -f on the log file show what is sent to the - network as it is sent. */ - if (fflush (lb->log) != 0) - error (0, errno, "flushing log file"); - - return (*lb->buf->flush) (lb->buf->closure); -} - -/* The block function for a log buffer. */ - -static int -log_buffer_block (closure, block) - void *closure; - int block; -{ - struct log_buffer *lb = (struct log_buffer *) closure; - - if (block) - return set_block (lb->buf); - else - return set_nonblock (lb->buf); -} - -/* The shutdown function for a log buffer. */ - -static int -log_buffer_shutdown (buf) - struct buffer *buf; -{ - struct log_buffer *lb = (struct log_buffer *) buf->closure; - int retval; - - retval = buf_shutdown (lb->buf); - if (fclose (lb->log) < 0) - error (0, errno, "closing log file"); - return retval; -} - -#ifdef NO_SOCKET_TO_FD - -/* Under certain circumstances, we must communicate with the server - via a socket using send() and recv(). This is because under some - operating systems (OS/2 and Windows 95 come to mind), a socket - cannot be converted to a file descriptor -- it must be treated as a - socket and nothing else. - - We may also need to deal with socket routine error codes differently - in these cases. This is handled through the SOCK_ERRNO and - SOCK_STRERROR macros. */ - -/* These routines implement a buffer structure which uses send and - recv. The buffer is always in blocking mode so we don't implement - the block routine. */ - -/* Note that it is important that these routines always handle errors - internally and never return a positive errno code, since it would in - general be impossible for the caller to know in general whether any - error code came from a socket routine (to decide whether to use - SOCK_STRERROR or simply strerror to print an error message). */ - -/* We use an instance of this structure as the closure field. */ - -struct socket_buffer -{ - /* The socket number. */ - int socket; -}; - -static struct buffer *socket_buffer_initialize - PROTO ((int, int, void (*) (struct buffer *))); -static int socket_buffer_input PROTO((void *, char *, int, int, int *)); -static int socket_buffer_output PROTO((void *, const char *, int, int *)); -static int socket_buffer_flush PROTO((void *)); -static int socket_buffer_shutdown PROTO((struct buffer *)); - - - -/* Create a buffer based on a socket. */ - -static struct buffer * -socket_buffer_initialize (socket, input, memory) - int socket; - int input; - void (*memory) PROTO((struct buffer *)); -{ - struct socket_buffer *n; - - n = (struct socket_buffer *) xmalloc (sizeof *n); - n->socket = socket; - return buf_initialize (input ? socket_buffer_input : NULL, - input ? NULL : socket_buffer_output, - input ? NULL : socket_buffer_flush, - (int (*) PROTO((void *, int))) NULL, - socket_buffer_shutdown, - memory, - n); -} - - - -/* The buffer input function for a buffer built on a socket. */ - -static int -socket_buffer_input (closure, data, need, size, got) - void *closure; - char *data; - int need; - int size; - int *got; -{ - struct socket_buffer *sb = (struct socket_buffer *) closure; - int nbytes; - - /* I believe that the recv function gives us exactly the semantics - we want. If there is a message, it returns immediately with - whatever it could get. If there is no message, it waits until - one comes in. In other words, it is not like read, which in - blocking mode normally waits until all the requested data is - available. */ - - *got = 0; - - do - { - - /* Note that for certain (broken?) networking stacks, like - VMS's UCX (not sure what version, problem reported with - recv() in 1997), and (according to windows-NT/config.h) - Windows NT 3.51, we must call recv or send with a - moderately sized buffer (say, less than 200K or something), - or else there may be network errors (somewhat hard to - produce, e.g. WAN not LAN or some such). buf_read_data - makes sure that we only recv() BUFFER_DATA_SIZE bytes at - a time. */ - - nbytes = recv (sb->socket, data, size, 0); - if (nbytes < 0) - error (1, 0, "reading from server: %s", SOCK_STRERROR (SOCK_ERRNO)); - if (nbytes == 0) - { - /* End of file (for example, the server has closed - the connection). If we've already read something, we - just tell the caller about the data, not about the end of - file. If we've read nothing, we return end of file. */ - if (*got == 0) - return -1; - else - return 0; - } - need -= nbytes; - size -= nbytes; - data += nbytes; - *got += nbytes; - } - while (need > 0); - - return 0; -} - - - -/* The buffer output function for a buffer built on a socket. */ - -static int -socket_buffer_output (closure, data, have, wrote) - void *closure; - const char *data; - int have; - int *wrote; -{ - struct socket_buffer *sb = (struct socket_buffer *) closure; - - *wrote = have; - - /* See comment in socket_buffer_input regarding buffer size we pass - to send and recv. */ - -#ifdef SEND_NEVER_PARTIAL - /* If send() never will produce a partial write, then just do it. This - is needed for systems where its return value is something other than - the number of bytes written. */ - if (send (sb->socket, data, have, 0) < 0) - error (1, 0, "writing to server socket: %s", SOCK_STRERROR (SOCK_ERRNO)); -#else - while (have > 0) - { - int nbytes; - - nbytes = send (sb->socket, data, have, 0); - if (nbytes < 0) - error (1, 0, "writing to server socket: %s", SOCK_STRERROR (SOCK_ERRNO)); - - have -= nbytes; - data += nbytes; - } -#endif - - return 0; -} - - - -/* The buffer flush function for a buffer built on a socket. */ - -/*ARGSUSED*/ -static int -socket_buffer_flush (closure) - void *closure; -{ - /* Nothing to do. Sockets are always flushed. */ - return 0; -} - - - -static int -socket_buffer_shutdown (buf) - struct buffer *buf; -{ - struct socket_buffer *n = (struct socket_buffer *) buf->closure; - char tmp; - - /* no need to flush children of an endpoint buffer here */ - - if (buf->input) - { - int err = 0; - if (! buf_empty_p (buf) - || (err = recv (n->socket, &tmp, 1, 0)) > 0) - error (0, 0, "dying gasps from %s unexpected", current_parsed_root->hostname); - else if (err == -1) - error (0, 0, "reading from %s: %s", current_parsed_root->hostname, SOCK_STRERROR (SOCK_ERRNO)); - - /* shutdown() socket */ -# ifdef SHUTDOWN_SERVER - if (current_parsed_root->method != server_method) -# endif - if (shutdown (n->socket, 0) < 0) - { - error (1, 0, "shutting down server socket: %s", SOCK_STRERROR (SOCK_ERRNO)); - } - - buf->input = NULL; - } - else if (buf->output) - { - /* shutdown() socket */ -# ifdef SHUTDOWN_SERVER - /* FIXME: Should have a SHUTDOWN_SERVER_INPUT & - * SHUTDOWN_SERVER_OUTPUT - */ - if (current_parsed_root->method == server_method) - SHUTDOWN_SERVER (n->socket); - else -# endif - if (shutdown (n->socket, 1) < 0) - { - error (1, 0, "shutting down server socket: %s", SOCK_STRERROR (SOCK_ERRNO)); - } - - buf->output = NULL; - } - - return 0; -} - -#endif /* NO_SOCKET_TO_FD */ - -/* - * Read a line from the server. Result does not include the terminating \n. - * - * Space for the result is malloc'd and should be freed by the caller. - * - * Returns number of bytes read. - */ -static int -read_line (resultp) - char **resultp; -{ - int status; - char *result; - int len; - - status = buf_flush (to_server, 1); - if (status != 0) - error (1, status, "writing to server"); - - status = buf_read_line (from_server, &result, &len); - if (status != 0) - { - if (status == -1) - error (1, 0, "end of file from server (consult above messages if any)"); - else if (status == -2) - error (1, 0, "out of memory"); - else - error (1, status, "reading from server"); - } - - if (resultp != NULL) - *resultp = result; - else - free (result); - - return len; -} - -#endif /* CLIENT_SUPPORT */ - - -#if defined(CLIENT_SUPPORT) || defined(SERVER_SUPPORT) - -/* - * Level of compression to use when running gzip on a single file. - */ -int file_gzip_level; - -#endif /* CLIENT_SUPPORT or SERVER_SUPPORT */ - -#ifdef CLIENT_SUPPORT - -/* - * The Repository for the top level of this command (not necessarily - * the CVSROOT, just the current directory at the time we do it). - */ -static char *toplevel_repos = NULL; - -/* Working directory when we first started. Note: we could speed things - up on some systems by using savecwd.h here instead of just always - storing a name. */ -char *toplevel_wd; - -static void -handle_ok (args, len) - char *args; - int len; -{ - return; -} - -static void -handle_error (args, len) - char *args; - int len; -{ - int something_printed; - - /* - * First there is a symbolic error code followed by a space, which - * we ignore. - */ - char *p = strchr (args, ' '); - if (p == NULL) - { - error (0, 0, "invalid data from cvs server"); - return; - } - ++p; - - /* Next we print the text of the message from the server. We - probably should be prefixing it with "server error" or some - such, because if it is something like "Out of memory", the - current behavior doesn't say which machine is out of - memory. */ - - len -= p - args; - something_printed = 0; - for (; len > 0; --len) - { - something_printed = 1; - putc (*p++, stderr); - } - if (something_printed) - putc ('\n', stderr); -} - -static void -handle_valid_requests (args, len) - char *args; - int len; -{ - char *p = args; - char *q; - struct request *rq; - do - { - q = strchr (p, ' '); - if (q != NULL) - *q++ = '\0'; - for (rq = requests; rq->name != NULL; ++rq) - { - if (strcmp (rq->name, p) == 0) - break; - } - if (rq->name == NULL) - /* - * It is a request we have never heard of (and thus never - * will want to use). So don't worry about it. - */ - ; - else - { - if (rq->flags & RQ_ENABLEME) - { - /* - * Server wants to know if we have this, to enable the - * feature. - */ - send_to_server (rq->name, 0); - send_to_server ("\012", 0); - } - else - rq->flags |= RQ_SUPPORTED; - } - p = q; - } while (q != NULL); - for (rq = requests; rq->name != NULL; ++rq) - { - if ((rq->flags & RQ_SUPPORTED) - || (rq->flags & RQ_ENABLEME)) - continue; - if (rq->flags & RQ_ESSENTIAL) - error (1, 0, "request `%s' not supported by server", rq->name); - } -} - - - -/* - * This is a proc for walklist(). It inverts the error return premise of - * walklist. - * - * RETURNS - * True If this path is prefixed by one of the paths in walklist and - * does not step above the prefix path. - * False Otherwise. - */ -static -int path_list_prefixed (p, closure) - Node *p; - void *closure; -{ - const char *questionable = closure; - const char *prefix = p->key; - if (strncmp (prefix, questionable, strlen (prefix))) return 0; - questionable += strlen (prefix); - while (ISDIRSEP (*questionable)) questionable++; - if (*questionable == '\0') return 1; - return pathname_levels (questionable); -} - - - -/* - * Need to validate the client pathname. Disallowed paths include: - * - * 1. Absolute paths. - * 2. Pathnames that do not reference a specifically requested update - * directory. - * - * In case 2, we actually only check that the directory is under the uppermost - * directories mentioned on the command line. - * - * RETURNS - * True If the path is valid. - * False Otherwise. - */ -static -int is_valid_client_path (pathname) - const char *pathname; -{ - /* 1. Absolute paths. */ - if (isabsolute (pathname)) return 0; - /* 2. No up-references in path. */ - if (pathname_levels (pathname) == 0) return 1; - /* 2. No Max-dotdot paths registered. */ - if (uppaths == NULL) return 0; - - return walklist (uppaths, path_list_prefixed, (void *)pathname); -} - - - -/* - * Do all the processing for PATHNAME, where pathname consists of the - * repository and the filename. The parameters we pass to FUNC are: - * DATA is just the DATA parameter which was passed to - * call_in_directory; ENT_LIST is a pointer to an entries list (which - * we manage the storage for); SHORT_PATHNAME is the pathname of the - * file relative to the (overall) directory in which the command is - * taking place; and FILENAME is the filename portion only of - * SHORT_PATHNAME. When we call FUNC, the curent directory points to - * the directory portion of SHORT_PATHNAME. */ - -static void -call_in_directory (pathname, func, data) - char *pathname; - void (*func) PROTO((char *data, List *ent_list, char *short_pathname, - char *filename)); - char *data; -{ - /* This variable holds the result of Entries_Open. */ - List *last_entries = NULL; - char *dir_name; - char *filename; - /* This is what we get when we hook up the directory (working directory - name) from PATHNAME with the filename from REPOSNAME. For example: - pathname: ccvs/src/ - reposname: /u/src/master/ccvs/foo/ChangeLog - short_pathname: ccvs/src/ChangeLog - */ - char *short_pathname; - char *p; - - /* - * Do the whole descent in parallel for the repositories, so we - * know what to put in CVS/Repository files. I'm not sure the - * full hair is necessary since the server does a similar - * computation; I suspect that we only end up creating one - * directory at a time anyway. - * - * Also note that we must *only* worry about this stuff when we - * are creating directories; `cvs co foo/bar; cd foo/bar; cvs co - * CVSROOT; cvs update' is legitimate, but in this case - * foo/bar/CVSROOT/CVS/Repository is not a subdirectory of - * foo/bar/CVS/Repository. - */ - char *reposname; - char *short_repos; - char *reposdirname; - char *rdirp; - int reposdirname_absolute; - int newdir = 0; - - assert (pathname); - - reposname = NULL; - read_line (&reposname); - assert (reposname != NULL); - - reposdirname_absolute = 0; - if (strncmp (reposname, toplevel_repos, strlen (toplevel_repos)) != 0) - { - reposdirname_absolute = 1; - short_repos = reposname; - } - else - { - short_repos = reposname + strlen (toplevel_repos) + 1; - if (short_repos[-1] != '/') - { - reposdirname_absolute = 1; - short_repos = reposname; - } - } - - /* Now that we have SHORT_REPOS, we can calculate the path to the file we - * are being requested to operate on. - */ - filename = strrchr (short_repos, '/'); - if (filename == NULL) - filename = short_repos; - else - ++filename; - - short_pathname = xmalloc (strlen (pathname) + strlen (filename) + 5); - strcpy (short_pathname, pathname); - strcat (short_pathname, filename); - - /* Now that we know the path to the file we were requested to operate on, - * we can verify that it is valid. - * - * For security reasons, if SHORT_PATHNAME is absolute or attempts to - * ascend outside of the current sanbbox, we abort. The server should not - * send us anything but relative paths which remain inside the sandbox - * here. Anything less means a trojan CVS server could create and edit - * arbitrary files on the client. - */ - if (!is_valid_client_path (short_pathname)) - { - error (0, 0, - "Server attempted to update a file via an invalid pathname:"); - error (1, 0, "`%s'.", short_pathname); - } - - reposdirname = xstrdup (short_repos); - p = strrchr (reposdirname, '/'); - if (p == NULL) - { - reposdirname = xrealloc (reposdirname, 2); - reposdirname[0] = '.'; reposdirname[1] = '\0'; - } - else - *p = '\0'; - - dir_name = xstrdup (pathname); - p = strrchr (dir_name, '/'); - if (p == NULL) - { - dir_name = xrealloc (dir_name, 2); - dir_name[0] = '.'; dir_name[1] = '\0'; - } - else - *p = '\0'; - if (client_prune_dirs) - add_prune_candidate (dir_name); - - if (toplevel_wd == NULL) - { - toplevel_wd = xgetwd (); - if (toplevel_wd == NULL) - error (1, errno, "could not get working directory"); - } - - if (CVS_CHDIR (toplevel_wd) < 0) - error (1, errno, "could not chdir to %s", toplevel_wd); - - if (CVS_CHDIR (dir_name) < 0) - { - char *dir; - char *dirp; - - if (! existence_error (errno)) - error (1, errno, "could not chdir to %s", dir_name); - - /* Directory does not exist, we need to create it. */ - newdir = 1; - - /* Provided we are willing to assume that directories get - created one at a time, we could simplify this a lot. - Do note that one aspect still would need to walk the - dir_name path: the checking for "fncmp (dir, CVSADM)". */ - - dir = xmalloc (strlen (dir_name) + 1); - dirp = dir_name; - rdirp = reposdirname; - - /* This algorithm makes nested directories one at a time - and create CVS administration files in them. For - example, we're checking out foo/bar/baz from the - repository: - - 1) create foo, point CVS/Repository to /foo - 2) .. foo/bar .. /foo/bar - 3) .. foo/bar/baz .. /foo/bar/baz - - As you can see, we're just stepping along DIR_NAME (with - DIRP) and REPOSDIRNAME (with RDIRP) respectively. - - We need to be careful when we are checking out a - module, however, since DIR_NAME and REPOSDIRNAME are not - going to be the same. Since modules will not have any - slashes in their names, we should watch the output of - STRCHR to decide whether or not we should use STRCHR on - the RDIRP. That is, if we're down to a module name, - don't keep picking apart the repository directory name. */ - - do - { - dirp = strchr (dirp, '/'); - if (dirp) - { - strncpy (dir, dir_name, dirp - dir_name); - dir[dirp - dir_name] = '\0'; - /* Skip the slash. */ - ++dirp; - if (rdirp == NULL) - /* This just means that the repository string has - fewer components than the dir_name string. But - that is OK (e.g. see modules3-8 in testsuite). */ - ; - else - rdirp = strchr (rdirp, '/'); - } - else - { - /* If there are no more slashes in the dir name, - we're down to the most nested directory -OR- to - the name of a module. In the first case, we - should be down to a DIRP that has no slashes, - so it won't help/hurt to do another STRCHR call - on DIRP. It will definitely hurt, however, if - we're down to a module name, since a module - name can point to a nested directory (that is, - DIRP will still have slashes in it. Therefore, - we should set it to NULL so the routine below - copies the contents of REMOTEDIRNAME onto the - root repository directory (does this if rdirp - is set to NULL, because we used to do an extra - STRCHR call here). */ - - rdirp = NULL; - strcpy (dir, dir_name); - } - - if (fncmp (dir, CVSADM) == 0) - { - error (0, 0, "cannot create a directory named %s", dir); - error (0, 0, "because CVS uses \"%s\" for its own uses", - CVSADM); - error (1, 0, "rename the directory and try again"); - } - - if (mkdir_if_needed (dir)) - { - /* It already existed, fine. Just keep going. */ - } - else if (strcmp (cvs_cmd_name, "export") == 0) - /* Don't create CVSADM directories if this is export. */ - ; - else - { - /* - * Put repository in CVS/Repository. For historical - * (pre-CVS/Root) reasons, this is an absolute pathname, - * but what really matters is the part of it which is - * relative to cvsroot. - */ - char *repo; - char *r, *b; - - repo = xmalloc (strlen (reposdirname) - + strlen (toplevel_repos) - + 80); - if (reposdirname_absolute) - r = repo; - else - { - strcpy (repo, toplevel_repos); - strcat (repo, "/"); - r = repo + strlen (repo); - } - - if (rdirp) - { - /* See comment near start of function; the only - way that the server can put the right thing - in each CVS/Repository file is to create the - directories one at a time. I think that the - CVS server has been doing this all along. */ - error (0, 0, "\ -warning: server is not creating directories one at a time"); - strncpy (r, reposdirname, rdirp - reposdirname); - r[rdirp - reposdirname] = '\0'; - } - else - strcpy (r, reposdirname); - - Create_Admin (dir, dir, repo, - (char *)NULL, (char *)NULL, 0, 0, 1); - free (repo); - - b = strrchr (dir, '/'); - if (b == NULL) - Subdir_Register ((List *) NULL, (char *) NULL, dir); - else - { - *b = '\0'; - Subdir_Register ((List *) NULL, dir, b + 1); - *b = '/'; - } - } - - if (rdirp != NULL) - { - /* Skip the slash. */ - ++rdirp; - } - - } while (dirp != NULL); - free (dir); - /* Now it better work. */ - if ( CVS_CHDIR (dir_name) < 0) - error (1, errno, "could not chdir to %s", dir_name); - } - else if (strcmp (cvs_cmd_name, "export") == 0) - /* Don't create CVSADM directories if this is export. */ - ; - else if (!isdir (CVSADM)) - { - /* - * Put repository in CVS/Repository. For historical - * (pre-CVS/Root) reasons, this is an absolute pathname, - * but what really matters is the part of it which is - * relative to cvsroot. - */ - char *repo; - - if (reposdirname_absolute) - repo = reposdirname; - else - { - repo = xmalloc (strlen (reposdirname) - + strlen (toplevel_repos) - + 10); - strcpy (repo, toplevel_repos); - strcat (repo, "/"); - strcat (repo, reposdirname); - } - - Create_Admin (".", ".", repo, (char *)NULL, (char *)NULL, 0, 1, 1); - if (repo != reposdirname) - free (repo); - } - - if (strcmp (cvs_cmd_name, "export") != 0) - { - last_entries = Entries_Open (0, dir_name); - - /* If this is a newly created directory, we will record - all subdirectory information, so call Subdirs_Known in - case there are no subdirectories. If this is not a - newly created directory, it may be an old working - directory from before we recorded subdirectory - information in the Entries file. We force a search for - all subdirectories now, to make sure our subdirectory - information is up to date. If the Entries file does - record subdirectory information, then this call only - does list manipulation. */ - if (newdir) - Subdirs_Known (last_entries); - else - { - List *dirlist; - - dirlist = Find_Directories ((char *) NULL, W_LOCAL, - last_entries); - dellist (&dirlist); - } - } - free (reposdirname); - (*func) (data, last_entries, short_pathname, filename); - if (last_entries != NULL) - Entries_Close (last_entries); - free (dir_name); - free (short_pathname); - free (reposname); -} - -static void -copy_a_file (data, ent_list, short_pathname, filename) - char *data; - List *ent_list; - char *short_pathname; - char *filename; -{ - char *newname; -#ifdef USE_VMS_FILENAMES - char *p; -#endif - - read_line (&newname); - -#ifdef USE_VMS_FILENAMES - /* Mogrify the filename so VMS is happy with it. */ - for(p = newname; *p; p++) - if(*p == '.' || *p == '#') *p = '_'; -#endif - /* cvsclient.texi has said for a long time that newname must be in the - same directory. Wouldn't want a malicious or buggy server overwriting - ~/.profile, /etc/passwd, or anything like that. */ - if (last_component (newname) != newname) - error (1, 0, "protocol error: Copy-file tried to specify directory"); - - if (unlink_file (newname) && !existence_error (errno)) - error (0, errno, "unable to remove %s", newname); - copy_file (filename, newname); - free (newname); -} - -static void -handle_copy_file (args, len) - char *args; - int len; -{ - call_in_directory (args, copy_a_file, (char *)NULL); -} - - - -/* Attempt to read a file size from a string. Accepts base 8 (0N), base 16 - * (0xN), or base 10. Exits on error. - * - * RETURNS - * The file size, in a size_t. - * - * FATAL ERRORS - * 1. As strtoul(). - * 2. If the number read exceeds SIZE_MAX. - */ -static size_t -strto_file_size (const char *s) -{ - unsigned long tmp; - char *endptr; - - /* Read it. */ - errno = 0; - tmp = strtoul (s, &endptr, 0); - - /* Check for errors. */ - if (errno || endptr == s) - error (1, errno, "Server sent invalid file size `%s'", s); - if (*endptr != '\0') - error (1, 0, - "Server sent trailing characters in file size `%s'", - endptr); - if (tmp > SIZE_MAX) - error (1, 0, "Server sent file size exceeding client max."); - - /* Return it. */ - return (size_t)tmp; -} - - - -static void read_counted_file PROTO ((char *, char *)); - -/* Read from the server the count for the length of a file, then read - the contents of that file and write them to FILENAME. FULLNAME is - the name of the file for use in error messages. FIXME-someday: - extend this to deal with compressed files and make update_entries - use it. On error, gives a fatal error. */ -static void -read_counted_file (filename, fullname) - char *filename; - char *fullname; -{ - char *size_string; - size_t size; - char *buf; - - /* Pointers in buf to the place to put data which will be read, - and the data which needs to be written, respectively. */ - char *pread; - char *pwrite; - /* Number of bytes left to read and number of bytes in buf waiting to - be written, respectively. */ - size_t nread; - size_t nwrite; - - FILE *fp; - - read_line (&size_string); - if (size_string[0] == 'z') - error (1, 0, "\ -protocol error: compressed files not supported for that operation"); - size = strto_file_size (size_string); - free (size_string); - - /* A more sophisticated implementation would use only a limited amount - of buffer space (8K perhaps), and read that much at a time. We allocate - a buffer for the whole file only to make it easy to keep track what - needs to be read and written. */ - buf = xmalloc (size); - - /* FIXME-someday: caller should pass in a flag saying whether it - is binary or not. I haven't carefully looked into whether - CVS/Template files should use local text file conventions or - not. */ - fp = CVS_FOPEN (filename, "wb"); - if (fp == NULL) - error (1, errno, "cannot write %s", fullname); - nread = size; - nwrite = 0; - pread = buf; - pwrite = buf; - while (nread > 0 || nwrite > 0) - { - size_t n; - - if (nread > 0) - { - n = try_read_from_server (pread, nread); - nread -= n; - pread += n; - nwrite += n; - } - - if (nwrite > 0) - { - n = fwrite (pwrite, 1, nwrite, fp); - if (ferror (fp)) - error (1, errno, "cannot write %s", fullname); - nwrite -= n; - pwrite += n; - } - } - free (buf); - if (fclose (fp) < 0) - error (1, errno, "cannot close %s", fullname); -} - -/* OK, we want to swallow the "U foo.c" response and then output it only - if we can update the file. In the future we probably want some more - systematic approach to parsing tagged text, but for now we keep it - ad hoc. "Why," I hear you cry, "do we not just look at the - Update-existing and Created responses?" That is an excellent question, - and the answer is roughly conservatism/laziness--I haven't read through - update.c enough to figure out the exact correspondence or lack thereof - between those responses and a "U foo.c" line (note that Merged, from - join_file, can be either "C foo" or "U foo" depending on the context). */ -/* Nonzero if we have seen +updated and not -updated. */ -static int updated_seen; -/* Filename from an "fname" tagged response within +updated/-updated. */ -static char *updated_fname; - -/* This struct is used to hold data when reading the +importmergecmd - and -importmergecmd tags. We put the variables in a struct only - for namespace issues. FIXME: As noted above, we need to develop a - more systematic approach. */ -static struct -{ - /* Nonzero if we have seen +importmergecmd and not -importmergecmd. */ - int seen; - /* Number of conflicts, from a "conflicts" tagged response. */ - int conflicts; - /* First merge tag, from a "mergetag1" tagged response. */ - char *mergetag1; - /* Second merge tag, from a "mergetag2" tagged response. */ - char *mergetag2; - /* Repository, from a "repository" tagged response. */ - char *repository; -} importmergecmd; - -/* Nonzero if we should arrange to return with a failure exit status. */ -static int failure_exit; - - -/* - * The time stamp of the last file we registered. - */ -static time_t last_register_time; - -/* - * The Checksum response gives the checksum for the file transferred - * over by the next Updated, Merged or Patch response. We just store - * it here, and then check it in update_entries. - */ - -static int stored_checksum_valid; -static unsigned char stored_checksum[16]; - -static void -handle_checksum (args, len) - char *args; - int len; -{ - char *s; - char buf[3]; - int i; - - if (stored_checksum_valid) - error (1, 0, "Checksum received before last one was used"); - - s = args; - buf[2] = '\0'; - for (i = 0; i < 16; i++) - { - char *bufend; - - buf[0] = *s++; - buf[1] = *s++; - stored_checksum[i] = (char) strtol (buf, &bufend, 16); - if (bufend != buf + 2) - break; - } - - if (i < 16 || *s != '\0') - error (1, 0, "Invalid Checksum response: `%s'", args); - - stored_checksum_valid = 1; -} - -/* Mode that we got in a "Mode" response (malloc'd), or NULL if none. */ -static char *stored_mode; - -static void handle_mode PROTO ((char *, int)); - -static void -handle_mode (args, len) - char *args; - int len; -{ - if (stored_mode != NULL) - error (1, 0, "protocol error: duplicate Mode"); - stored_mode = xstrdup (args); -} - -/* Nonzero if time was specified in Mod-time. */ -static int stored_modtime_valid; -/* Time specified in Mod-time. */ -static time_t stored_modtime; - -static void handle_mod_time PROTO ((char *, int)); - -static void -handle_mod_time (args, len) - char *args; - int len; -{ - if (stored_modtime_valid) - error (0, 0, "protocol error: duplicate Mod-time"); - stored_modtime = get_date (args, NULL); - if (stored_modtime == (time_t) -1) - error (0, 0, "protocol error: cannot parse date %s", args); - else - stored_modtime_valid = 1; -} - -/* - * If we receive a patch, but the patch program fails to apply it, we - * want to request the original file. We keep a list of files whose - * patches have failed. - */ - -char **failed_patches; -int failed_patches_count; - -struct update_entries_data -{ - enum { - /* - * We are just getting an Entries line; the local file is - * correct. - */ - UPDATE_ENTRIES_CHECKIN, - /* We are getting the file contents as well. */ - UPDATE_ENTRIES_UPDATE, - /* - * We are getting a patch against the existing local file, not - * an entire new file. - */ - UPDATE_ENTRIES_PATCH, - /* - * We are getting an RCS change text (diff -n output) against - * the existing local file, not an entire new file. - */ - UPDATE_ENTRIES_RCS_DIFF - } contents; - - enum { - /* We are replacing an existing file. */ - UPDATE_ENTRIES_EXISTING, - /* We are creating a new file. */ - UPDATE_ENTRIES_NEW, - /* We don't know whether it is existing or new. */ - UPDATE_ENTRIES_EXISTING_OR_NEW - } existp; - - /* - * String to put in the timestamp field or NULL to use the timestamp - * of the file. - */ - char *timestamp; -}; - -/* Update the Entries line for this file. */ -static void -update_entries (data_arg, ent_list, short_pathname, filename) - char *data_arg; - List *ent_list; - char *short_pathname; - char *filename; -{ - char *entries_line; - struct update_entries_data *data = (struct update_entries_data *)data_arg; - - char *cp; - char *user; - char *vn; - /* Timestamp field. Always empty according to the protocol. */ - char *ts; - char *options = NULL; - char *tag = NULL; - char *date = NULL; - char *tag_or_date; - char *scratch_entries = NULL; - int bin; - -#ifdef UTIME_EXPECTS_WRITABLE - int change_it_back = 0; -#endif - - read_line (&entries_line); - - /* - * Parse the entries line. - */ - scratch_entries = xstrdup (entries_line); - - if (scratch_entries[0] != '/') - error (1, 0, "bad entries line `%s' from server", entries_line); - user = scratch_entries + 1; - if ((cp = strchr (user, '/')) == NULL) - error (1, 0, "bad entries line `%s' from server", entries_line); - *cp++ = '\0'; - vn = cp; - if ((cp = strchr (vn, '/')) == NULL) - error (1, 0, "bad entries line `%s' from server", entries_line); - *cp++ = '\0'; - - ts = cp; - if ((cp = strchr (ts, '/')) == NULL) - error (1, 0, "bad entries line `%s' from server", entries_line); - *cp++ = '\0'; - options = cp; - if ((cp = strchr (options, '/')) == NULL) - error (1, 0, "bad entries line `%s' from server", entries_line); - *cp++ = '\0'; - tag_or_date = cp; - - /* If a slash ends the tag_or_date, ignore everything after it. */ - cp = strchr (tag_or_date, '/'); - if (cp != NULL) - *cp = '\0'; - if (*tag_or_date == 'T') - tag = tag_or_date + 1; - else if (*tag_or_date == 'D') - date = tag_or_date + 1; - - /* Done parsing the entries line. */ - - if (data->contents == UPDATE_ENTRIES_UPDATE - || data->contents == UPDATE_ENTRIES_PATCH - || data->contents == UPDATE_ENTRIES_RCS_DIFF) - { - char *size_string; - char *mode_string; - size_t size; - char *buf; - char *temp_filename; - int use_gzip; - int patch_failed; - char *s; - - read_line (&mode_string); - - read_line (&size_string); - if (size_string[0] == 'z') - { - use_gzip = 1; - s = size_string + 1; - } - else - { - use_gzip = 0; - s = size_string; - } - size = strto_file_size (s); - free (size_string); - - /* Note that checking this separately from writing the file is - a race condition: if the existence or lack thereof of the - file changes between now and the actual calls which - operate on it, we lose. However (a) there are so many - cases, I'm reluctant to try to fix them all, (b) in some - cases the system might not even have a system call which - does the right thing, and (c) it isn't clear this needs to - work. */ - if (data->existp == UPDATE_ENTRIES_EXISTING - && !isfile (filename)) - /* Emit a warning and update the file anyway. */ - error (0, 0, "warning: %s unexpectedly disappeared", - short_pathname); - - if (data->existp == UPDATE_ENTRIES_NEW - && isfile (filename)) - { - /* Emit a warning and refuse to update the file; we don't want - to clobber a user's file. */ - size_t nread; - size_t toread; - - /* size should be unsigned, but until we get around to fixing - that, work around it. */ - size_t usize; - - char buf[8192]; - - /* This error might be confusing; it isn't really clear to - the user what to do about it. Keep in mind that it has - several causes: (1) something/someone creates the file - during the time that CVS is running, (2) the repository - has two files whose names clash for the client because - of case-insensitivity or similar causes, See 3 for - additional notes. (3) a special case of this is that a - file gets renamed for example from a.c to A.C. A - "cvs update" on a case-insensitive client will get this - error. In this case and in case 2, the filename - (short_pathname) printed in the error message will likely _not_ - have the same case as seen by the user in a directory listing. - (4) the client has a file which the server doesn't know - about (e.g. "? foo" file), and that name clashes with a file - the server does know about, (5) classify.c will print the same - message for other reasons. - - I hope the above paragraph makes it clear that making this - clearer is not a one-line fix. */ - error (0, 0, "move away %s; it is in the way", short_pathname); - if (updated_fname != NULL) - { - cvs_output ("C ", 0); - cvs_output (updated_fname, 0); - cvs_output ("\n", 1); - } - failure_exit = 1; - - discard_file_and_return: - /* Now read and discard the file contents. */ - usize = size; - nread = 0; - while (nread < usize) - { - toread = usize - nread; - if (toread > sizeof buf) - toread = sizeof buf; - - nread += try_read_from_server (buf, toread); - if (nread == usize) - break; - } - - free (mode_string); - free (scratch_entries); - free (entries_line); - - /* The Mode, Mod-time, and Checksum responses should not carry - over to a subsequent Created (or whatever) response, even - in the error case. */ - if (stored_mode != NULL) - { - free (stored_mode); - stored_mode = NULL; - } - stored_modtime_valid = 0; - stored_checksum_valid = 0; - - if (updated_fname != NULL) - { - free (updated_fname); - updated_fname = NULL; - } - return; - } - - temp_filename = xmalloc (strlen (filename) + 80); -#ifdef USE_VMS_FILENAMES - /* A VMS rename of "blah.dat" to "foo" to implies a - destination of "foo.dat" which is unfortinate for CVS */ - sprintf (temp_filename, "%s_new_", filename); -#else -#ifdef _POSIX_NO_TRUNC - sprintf (temp_filename, ".new.%.9s", filename); -#else /* _POSIX_NO_TRUNC */ - sprintf (temp_filename, ".new.%s", filename); -#endif /* _POSIX_NO_TRUNC */ -#endif /* USE_VMS_FILENAMES */ - - buf = xmalloc (size); - - /* Some systems, like OS/2 and Windows NT, end lines with CRLF - instead of just LF. Format translation is done in the C - library I/O funtions. Here we tell them whether or not to - convert -- if this file is marked "binary" with the RCS -kb - flag, then we don't want to convert, else we do (because - CVS assumes text files by default). */ - - if (options) - bin = !(strcmp (options, "-kb")); - else - bin = 0; - - if (data->contents == UPDATE_ENTRIES_RCS_DIFF) - { - /* This is an RCS change text. We just hold the change - text in memory. */ - - if (use_gzip) - error (1, 0, - "server error: gzip invalid with RCS change text"); - - read_from_server (buf, size); - } - else - { - int fd; - - fd = CVS_OPEN (temp_filename, - (O_WRONLY | O_CREAT | O_TRUNC - | (bin ? OPEN_BINARY : 0)), - 0777); - - if (fd < 0) - { - /* I can see a case for making this a fatal error; for - a condition like disk full or network unreachable - (for a file server), carrying on and giving an - error on each file seems unnecessary. But if it is - a permission problem, or some such, then it is - entirely possible that future files will not have - the same problem. */ - error (0, errno, "cannot write %s", short_pathname); - free (temp_filename); - free (buf); - goto discard_file_and_return; - } - - if (size > 0) - { - read_from_server (buf, size); - - if (use_gzip) - { - 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) - error (1, errno, "writing %s", short_pathname); - } - - if (close (fd) < 0) - error (1, errno, "writing %s", short_pathname); - } - - /* This is after we have read the file from the net (a change - from previous versions, where the server would send us - "M U foo.c" before Update-existing or whatever), but before - we finish writing the file (arguably a bug). The timing - affects a user who wants status info about how far we have - gotten, and also affects whether "U foo.c" appears in addition - to various error messages. */ - if (updated_fname != NULL) - { - cvs_output ("U ", 0); - cvs_output (updated_fname, 0); - cvs_output ("\n", 1); - free (updated_fname); - updated_fname = 0; - } - - patch_failed = 0; - - if (data->contents == UPDATE_ENTRIES_UPDATE) - { - rename_file (temp_filename, filename); - } - else if (data->contents == UPDATE_ENTRIES_PATCH) - { - /* You might think we could just leave Patched out of - Valid-responses and not get this response. However, if - memory serves, the CVS 1.9 server bases this on -u - (update-patches), and there is no way for us to send -u - or not based on whether the server supports "Rcs-diff". - - Fall back to transmitting entire files. */ - patch_failed = 1; - } - else - { - char *filebuf; - size_t filebufsize; - size_t nread; - char *patchedbuf; - size_t patchedlen; - - /* Handle UPDATE_ENTRIES_RCS_DIFF. */ - - if (!isfile (filename)) - error (1, 0, "patch original file %s does not exist", - short_pathname); - filebuf = NULL; - filebufsize = 0; - nread = 0; - - get_file (filename, short_pathname, bin ? FOPEN_BINARY_READ : "r", - &filebuf, &filebufsize, &nread); - /* At this point the contents of the existing file are in - FILEBUF, and the length of the contents is in NREAD. - The contents of the patch from the network are in BUF, - and the length of the patch is in SIZE. */ - - if (! rcs_change_text (short_pathname, filebuf, nread, buf, size, - &patchedbuf, &patchedlen)) - patch_failed = 1; - else - { - if (stored_checksum_valid) - { - struct cvs_MD5Context context; - unsigned char checksum[16]; - - /* We have a checksum. Check it before writing - the file out, so that we don't have to read it - back in again. */ - cvs_MD5Init (&context); - cvs_MD5Update (&context, - (unsigned char *) patchedbuf, patchedlen); - cvs_MD5Final (checksum, &context); - if (memcmp (checksum, stored_checksum, 16) != 0) - { - error (0, 0, - "checksum failure after patch to %s; will refetch", - short_pathname); - - patch_failed = 1; - } - - stored_checksum_valid = 0; - } - - if (! patch_failed) - { - FILE *e; - - e = open_file (temp_filename, - bin ? FOPEN_BINARY_WRITE : "w"); - if (fwrite (patchedbuf, 1, patchedlen, e) != patchedlen) - error (1, errno, "cannot write %s", temp_filename); - if (fclose (e) == EOF) - error (1, errno, "cannot close %s", temp_filename); - rename_file (temp_filename, filename); - } - - free (patchedbuf); - } - - free (filebuf); - } - - free (temp_filename); - - if (stored_checksum_valid && ! patch_failed) - { - FILE *e; - struct cvs_MD5Context context; - unsigned char buf[8192]; - unsigned len; - unsigned char checksum[16]; - - /* - * Compute the MD5 checksum. This will normally only be - * used when receiving a patch, so we always compute it - * here on the final file, rather than on the received - * data. - * - * Note that if the file is a text file, we should read it - * here using text mode, so its lines will be terminated the same - * way they were transmitted. - */ - e = CVS_FOPEN (filename, "r"); - if (e == NULL) - error (1, errno, "could not open %s", short_pathname); - - cvs_MD5Init (&context); - while ((len = fread (buf, 1, sizeof buf, e)) != 0) - cvs_MD5Update (&context, buf, len); - if (ferror (e)) - error (1, errno, "could not read %s", short_pathname); - cvs_MD5Final (checksum, &context); - - fclose (e); - - stored_checksum_valid = 0; - - if (memcmp (checksum, stored_checksum, 16) != 0) - { - if (data->contents != UPDATE_ENTRIES_PATCH) - error (1, 0, "checksum failure on %s", - short_pathname); - - error (0, 0, - "checksum failure after patch to %s; will refetch", - short_pathname); - - patch_failed = 1; - } - } - - if (patch_failed) - { - /* Save this file to retrieve later. */ - failed_patches = (char **) xrealloc ((char *) failed_patches, - ((failed_patches_count + 1) - * sizeof (char *))); - failed_patches[failed_patches_count] = xstrdup (short_pathname); - ++failed_patches_count; - - stored_checksum_valid = 0; - - free (mode_string); - free (buf); - free (scratch_entries); - free (entries_line); - - return; - } - - { - int status = change_mode (filename, mode_string, 1); - if (status != 0) - error (0, status, "cannot change mode of %s", short_pathname); - } - - free (mode_string); - free (buf); - } - - if (stored_mode != NULL) - { - change_mode (filename, stored_mode, 1); - free (stored_mode); - stored_mode = NULL; - } - - if (stored_modtime_valid) - { - struct utimbuf t; - - memset (&t, 0, sizeof (t)); - t.modtime = stored_modtime; - (void) time (&t.actime); - -#ifdef UTIME_EXPECTS_WRITABLE - if (!iswritable (filename)) - { - xchmod (filename, 1); - change_it_back = 1; - } -#endif /* UTIME_EXPECTS_WRITABLE */ - - if (utime (filename, &t) < 0) - error (0, errno, "cannot set time on %s", filename); - -#ifdef UTIME_EXPECTS_WRITABLE - if (change_it_back) - { - xchmod (filename, 0); - change_it_back = 0; - } -#endif /* UTIME_EXPECTS_WRITABLE */ - - stored_modtime_valid = 0; - } - - /* - * Process the entries line. Do this after we've written the file, - * since we need the timestamp. - */ - if (strcmp (cvs_cmd_name, "export") != 0) - { - char *local_timestamp; - char *file_timestamp; - - (void) time (&last_register_time); - - local_timestamp = data->timestamp; - if (local_timestamp == NULL || ts[0] == '+') - file_timestamp = time_stamp (filename); - else - file_timestamp = NULL; - - /* - * These special version numbers signify that it is not up to - * date. Create a dummy timestamp which will never compare - * equal to the timestamp of the file. - */ - if (vn[0] == '\0' || strcmp (vn, "0") == 0 || vn[0] == '-') - local_timestamp = "dummy timestamp"; - else if (local_timestamp == NULL) - { - local_timestamp = file_timestamp; - - /* Checking for cvs_cmd_name of "commit" doesn't seem like - the cleanest way to handle this, but it seem to roughly - parallel what the :local: code which calls - mark_up_to_date ends up amounting to. Some day, should - think more about what the Checked-in response means - vis-a-vis both Entries and Base and clarify - cvsclient.texi accordingly. */ - - if (!strcmp (cvs_cmd_name, "commit")) - mark_up_to_date (filename); - } - - Register (ent_list, filename, vn, local_timestamp, - options, tag, date, ts[0] == '+' ? file_timestamp : NULL); - - if (file_timestamp) - free (file_timestamp); - - } - free (scratch_entries); - free (entries_line); -} - -static void -handle_checked_in (args, len) - char *args; - int len; -{ - struct update_entries_data dat; - dat.contents = UPDATE_ENTRIES_CHECKIN; - dat.existp = UPDATE_ENTRIES_EXISTING_OR_NEW; - dat.timestamp = NULL; - call_in_directory (args, update_entries, (char *)&dat); -} - -static void -handle_new_entry (args, len) - char *args; - int len; -{ - struct update_entries_data dat; - dat.contents = UPDATE_ENTRIES_CHECKIN; - dat.existp = UPDATE_ENTRIES_EXISTING_OR_NEW; - dat.timestamp = "dummy timestamp from new-entry"; - call_in_directory (args, update_entries, (char *)&dat); -} - -static void -handle_updated (args, len) - char *args; - int len; -{ - struct update_entries_data dat; - dat.contents = UPDATE_ENTRIES_UPDATE; - dat.existp = UPDATE_ENTRIES_EXISTING_OR_NEW; - dat.timestamp = NULL; - call_in_directory (args, update_entries, (char *)&dat); -} - -static void handle_created PROTO((char *, int)); - -static void -handle_created (args, len) - char *args; - int len; -{ - struct update_entries_data dat; - dat.contents = UPDATE_ENTRIES_UPDATE; - dat.existp = UPDATE_ENTRIES_NEW; - dat.timestamp = NULL; - call_in_directory (args, update_entries, (char *)&dat); -} - -static void handle_update_existing PROTO((char *, int)); - -static void -handle_update_existing (args, len) - char *args; - int len; -{ - struct update_entries_data dat; - dat.contents = UPDATE_ENTRIES_UPDATE; - dat.existp = UPDATE_ENTRIES_EXISTING; - dat.timestamp = NULL; - call_in_directory (args, update_entries, (char *)&dat); -} - -static void -handle_merged (args, len) - char *args; - int len; -{ - struct update_entries_data dat; - dat.contents = UPDATE_ENTRIES_UPDATE; - /* Think this could be UPDATE_ENTRIES_EXISTING, but just in case... */ - dat.existp = UPDATE_ENTRIES_EXISTING_OR_NEW; - dat.timestamp = "Result of merge"; - call_in_directory (args, update_entries, (char *)&dat); -} - -static void -handle_patched (args, len) - char *args; - int len; -{ - struct update_entries_data dat; - dat.contents = UPDATE_ENTRIES_PATCH; - /* Think this could be UPDATE_ENTRIES_EXISTING, but just in case... */ - dat.existp = UPDATE_ENTRIES_EXISTING_OR_NEW; - dat.timestamp = NULL; - call_in_directory (args, update_entries, (char *)&dat); -} - -static void -handle_rcs_diff (args, len) - char *args; - int len; -{ - struct update_entries_data dat; - dat.contents = UPDATE_ENTRIES_RCS_DIFF; - /* Think this could be UPDATE_ENTRIES_EXISTING, but just in case... */ - dat.existp = UPDATE_ENTRIES_EXISTING_OR_NEW; - dat.timestamp = NULL; - call_in_directory (args, update_entries, (char *)&dat); -} - -static void -remove_entry (data, ent_list, short_pathname, filename) - char *data; - List *ent_list; - char *short_pathname; - char *filename; -{ - Scratch_Entry (ent_list, filename); -} - -static void -handle_remove_entry (args, len) - char *args; - int len; -{ - call_in_directory (args, remove_entry, (char *)NULL); -} - -static void -remove_entry_and_file (data, ent_list, short_pathname, filename) - char *data; - List *ent_list; - char *short_pathname; - char *filename; -{ - Scratch_Entry (ent_list, filename); - /* Note that we don't ignore existence_error's here. The server - should be sending Remove-entry rather than Removed in cases - where the file does not exist. And if the user removes the - file halfway through a cvs command, we should be printing an - error. */ - if (unlink_file (filename) < 0) - error (0, errno, "unable to remove %s", short_pathname); -} - -static void -handle_removed (args, len) - char *args; - int len; -{ - call_in_directory (args, remove_entry_and_file, (char *)NULL); -} - -/* Is this the top level (directory containing CVSROOT)? */ -static int -is_cvsroot_level (pathname) - char *pathname; -{ - if (strcmp (toplevel_repos, current_parsed_root->directory) != 0) - return 0; - - return strchr (pathname, '/') == NULL; -} - -static void -set_static (data, ent_list, short_pathname, filename) - char *data; - List *ent_list; - char *short_pathname; - char *filename; -{ - FILE *fp; - fp = open_file (CVSADM_ENTSTAT, "w+"); - if (fclose (fp) == EOF) - error (1, errno, "cannot close %s", CVSADM_ENTSTAT); -} - -static void -handle_set_static_directory (args, len) - char *args; - int len; -{ - if (strcmp (cvs_cmd_name, "export") == 0) - { - /* Swallow the repository. */ - read_line (NULL); - return; - } - call_in_directory (args, set_static, (char *)NULL); -} - -static void -clear_static (data, ent_list, short_pathname, filename) - char *data; - List *ent_list; - char *short_pathname; - char *filename; -{ - if (unlink_file (CVSADM_ENTSTAT) < 0 && ! existence_error (errno)) - error (1, errno, "cannot remove file %s", CVSADM_ENTSTAT); -} - -static void -handle_clear_static_directory (pathname, len) - char *pathname; - int len; -{ - if (strcmp (cvs_cmd_name, "export") == 0) - { - /* Swallow the repository. */ - read_line (NULL); - return; - } - - if (is_cvsroot_level (pathname)) - { - /* - * Top level (directory containing CVSROOT). This seems to normally - * lack a CVS directory, so don't try to create files in it. - */ - return; - } - call_in_directory (pathname, clear_static, (char *)NULL); -} - -static void -set_sticky (data, ent_list, short_pathname, filename) - char *data; - List *ent_list; - char *short_pathname; - char *filename; -{ - char *tagspec; - FILE *f; - - read_line (&tagspec); - - /* FIXME-update-dir: error messages should include the directory. */ - f = CVS_FOPEN (CVSADM_TAG, "w+"); - if (f == NULL) - { - /* Making this non-fatal is a bit of a kludge (see dirs2 - in testsuite). A better solution would be to avoid having - the server tell us about a directory we shouldn't be doing - anything with anyway (e.g. by handling directory - addition/removal better). */ - error (0, errno, "cannot open %s", CVSADM_TAG); - free (tagspec); - return; - } - if (fprintf (f, "%s\n", tagspec) < 0) - error (1, errno, "writing %s", CVSADM_TAG); - if (fclose (f) == EOF) - error (1, errno, "closing %s", CVSADM_TAG); - free (tagspec); -} - -static void -handle_set_sticky (pathname, len) - char *pathname; - int len; -{ - if (strcmp (cvs_cmd_name, "export") == 0) - { - /* Swallow the repository. */ - read_line (NULL); - /* Swallow the tag line. */ - read_line (NULL); - return; - } - if (is_cvsroot_level (pathname)) - { - /* - * Top level (directory containing CVSROOT). This seems to normally - * lack a CVS directory, so don't try to create files in it. - */ - - /* Swallow the repository. */ - read_line (NULL); - /* Swallow the tag line. */ - read_line (NULL); - return; - } - - call_in_directory (pathname, set_sticky, (char *)NULL); -} - -static void -clear_sticky (data, ent_list, short_pathname, filename) - char *data; - List *ent_list; - char *short_pathname; - char *filename; -{ - if (unlink_file (CVSADM_TAG) < 0 && ! existence_error (errno)) - error (1, errno, "cannot remove %s", CVSADM_TAG); -} - -static void -handle_clear_sticky (pathname, len) - char *pathname; - int len; -{ - if (strcmp (cvs_cmd_name, "export") == 0) - { - /* Swallow the repository. */ - read_line (NULL); - return; - } - - if (is_cvsroot_level (pathname)) - { - /* - * Top level (directory containing CVSROOT). This seems to normally - * lack a CVS directory, so don't try to create files in it. - */ - return; - } - - call_in_directory (pathname, clear_sticky, (char *)NULL); -} - - -static void template PROTO ((char *, List *, char *, char *)); - -static void -template (data, ent_list, short_pathname, filename) - char *data; - List *ent_list; - char *short_pathname; - char *filename; -{ - char *buf = xmalloc ( strlen ( short_pathname ) - + strlen ( CVSADM_TEMPLATE ) - + 2 ); - sprintf ( buf, "%s/%s", short_pathname, CVSADM_TEMPLATE ); - read_counted_file ( CVSADM_TEMPLATE, buf ); - free ( buf ); -} - -static void handle_template PROTO ((char *, int)); - -static void -handle_template (pathname, len) - char *pathname; - int len; -{ - call_in_directory (pathname, template, NULL); -} - - - -struct save_dir { - char *dir; - struct save_dir *next; -}; - -struct save_dir *prune_candidates; - -static void -add_prune_candidate (dir) - const char *dir; -{ - struct save_dir *p; - - if ((dir[0] == '.' && dir[1] == '\0') - || (prune_candidates != NULL - && strcmp (dir, prune_candidates->dir) == 0)) - return; - p = (struct save_dir *) xmalloc (sizeof (struct save_dir)); - p->dir = xstrdup (dir); - p->next = prune_candidates; - prune_candidates = p; -} - -static void process_prune_candidates PROTO((void)); - -static void -process_prune_candidates () -{ - struct save_dir *p; - struct save_dir *q; - - if (toplevel_wd != NULL) - { - if (CVS_CHDIR (toplevel_wd) < 0) - error (1, errno, "could not chdir to %s", toplevel_wd); - } - for (p = prune_candidates; p != NULL; ) - { - if (isemptydir (p->dir, 1)) - { - char *b; - - if (unlink_file_dir (p->dir) < 0) - error (0, errno, "cannot remove %s", p->dir); - b = strrchr (p->dir, '/'); - if (b == NULL) - Subdir_Deregister ((List *) NULL, (char *) NULL, p->dir); - else - { - *b = '\0'; - Subdir_Deregister ((List *) NULL, p->dir, b + 1); - } - } - free (p->dir); - q = p->next; - free (p); - p = q; - } - prune_candidates = NULL; -} - -/* Send a Repository line. */ - -static char *last_repos; -static char *last_update_dir; - -static void send_repository PROTO((const char *, const char *, const char *)); - -static void -send_repository (dir, repos, update_dir) - const char *dir; - const char *repos; - const char *update_dir; -{ - char *adm_name; - - /* FIXME: this is probably not the best place to check; I wish I - * knew where in here's callers to really trap this bug. To - * reproduce the bug, just do this: - * - * mkdir junk - * cd junk - * cvs -d some_repos update foo - * - * Poof, CVS seg faults and dies! It's because it's trying to - * send a NULL string to the server but dies in send_to_server. - * That string was supposed to be the repository, but it doesn't - * get set because there's no CVSADM dir, and somehow it's not - * getting set from the -d argument either... ? - */ - if (repos == NULL) - { - /* Lame error. I want a real fix but can't stay up to track - this down right now. */ - error (1, 0, "no repository"); - } - - if (update_dir == NULL || update_dir[0] == '\0') - update_dir = "."; - - if (last_repos != NULL - && strcmp (repos, last_repos) == 0 - && last_update_dir != NULL - && strcmp (update_dir, last_update_dir) == 0) - /* We've already sent it. */ - return; - - if (client_prune_dirs) - add_prune_candidate (update_dir); - - /* Add a directory name to the list of those sent to the - server. */ - if (update_dir && (*update_dir != '\0') - && (strcmp (update_dir, ".") != 0) - && (findnode (dirs_sent_to_server, update_dir) == NULL)) - { - Node *n; - n = getnode (); - n->type = NT_UNKNOWN; - n->key = xstrdup (update_dir); - n->data = NULL; - - if (addnode (dirs_sent_to_server, n)) - error (1, 0, "cannot add directory %s to list", n->key); - } - - /* 80 is large enough for any of CVSADM_*. */ - adm_name = xmalloc (strlen (dir) + 80); - - send_to_server ("Directory ", 0); - { - /* Send the directory name. I know that this - sort of duplicates code elsewhere, but each - case seems slightly different... */ - char buf[1]; - const char *p = update_dir; - while (*p != '\0') - { - assert (*p != '\012'); - if (ISDIRSEP (*p)) - { - buf[0] = '/'; - send_to_server (buf, 1); - } - else - { - buf[0] = *p; - send_to_server (buf, 1); - } - ++p; - } - } - send_to_server ("\012", 1); - send_to_server (repos, 0); - send_to_server ("\012", 1); - - if (strcmp (cvs_cmd_name, "import") - && supported_request ("Static-directory")) - { - adm_name[0] = '\0'; - if (dir[0] != '\0') - { - strcat (adm_name, dir); - strcat (adm_name, "/"); - } - strcat (adm_name, CVSADM_ENTSTAT); - if (isreadable (adm_name)) - { - send_to_server ("Static-directory\012", 0); - } - } - if (strcmp (cvs_cmd_name, "import") - && supported_request ("Sticky")) - { - FILE *f; - if (dir[0] == '\0') - strcpy (adm_name, CVSADM_TAG); - else - sprintf (adm_name, "%s/%s", dir, CVSADM_TAG); - - f = CVS_FOPEN (adm_name, "r"); - if (f == NULL) - { - if (! existence_error (errno)) - error (1, errno, "reading %s", adm_name); - } - else - { - char line[80]; - char *nl = NULL; - send_to_server ("Sticky ", 0); - while (fgets (line, sizeof (line), f) != NULL) - { - send_to_server (line, 0); - nl = strchr (line, '\n'); - if (nl != NULL) - break; - } - if (nl == NULL) - send_to_server ("\012", 1); - if (fclose (f) == EOF) - error (0, errno, "closing %s", adm_name); - } - } - free (adm_name); - if (last_repos != NULL) - free (last_repos); - if (last_update_dir != NULL) - free (last_update_dir); - last_repos = xstrdup (repos); - last_update_dir = xstrdup (update_dir); -} - -/* Send a Repository line and set toplevel_repos. */ - -void -send_a_repository (dir, repository, update_dir_in) - const char *dir; - const char *repository; - const char *update_dir_in; -{ - char *update_dir; - - assert (update_dir_in); - update_dir = xstrdup (update_dir_in); - - if (toplevel_repos == NULL && repository != NULL) - { - if (update_dir[0] == '\0' - || (update_dir[0] == '.' && update_dir[1] == '\0')) - toplevel_repos = xstrdup (repository); - else - { - /* - * Get the repository from a CVS/Repository file if update_dir - * is absolute. This is not correct in general, because - * the CVS/Repository file might not be the top-level one. - * This is for cases like "cvs update /foo/bar" (I'm not - * sure it matters what toplevel_repos we get, but it does - * matter that we don't hit the "internal error" code below). - */ - if (update_dir[0] == '/') - toplevel_repos = Name_Repository (update_dir, update_dir); - else - { - /* - * Guess the repository of that directory by looking at a - * subdirectory and removing as many pathname components - * as are in update_dir. I think that will always (or at - * least almost always) be 1. - * - * So this deals with directories which have been - * renamed, though it doesn't necessarily deal with - * directories which have been put inside other - * directories (and cvs invoked on the containing - * directory). I'm not sure the latter case needs to - * work. - * - * 21 Aug 1998: Well, Mr. Above-Comment-Writer, it - * does need to work after all. When we are using the - * client in a multi-cvsroot environment, it will be - * fairly common that we have the above case (e.g., - * cwd checked out from one repository but - * subdirectory checked out from another). We can't - * assume that by walking up a directory in our wd we - * necessarily walk up a directory in the repository. - */ - /* - * This gets toplevel_repos wrong for "cvs update ../foo" - * but I'm not sure toplevel_repos matters in that case. - */ - - int repository_len, update_dir_len; - - strip_trailing_slashes (update_dir); - - repository_len = strlen (repository); - update_dir_len = strlen (update_dir); - - /* Try to remove the path components in UPDATE_DIR - from REPOSITORY. If the path elements don't exist - in REPOSITORY, or the removal of those path - elements mean that we "step above" - current_parsed_root->directory, set toplevel_repos to - current_parsed_root->directory. */ - if ((repository_len > update_dir_len) - && (strcmp (repository + repository_len - update_dir_len, - update_dir) == 0) - /* TOPLEVEL_REPOS shouldn't be above current_parsed_root->directory */ - && ((size_t)(repository_len - update_dir_len) - > strlen (current_parsed_root->directory))) - { - /* The repository name contains UPDATE_DIR. Set - toplevel_repos to the repository name without - UPDATE_DIR. */ - - toplevel_repos = xmalloc (repository_len - update_dir_len); - /* Note that we don't copy the trailing '/'. */ - strncpy (toplevel_repos, repository, - repository_len - update_dir_len - 1); - toplevel_repos[repository_len - update_dir_len - 1] = '\0'; - } - else - { - toplevel_repos = xstrdup (current_parsed_root->directory); - } - } - } - } - - send_repository (dir, repository, update_dir); - free (update_dir); -} - - - -/* The "expanded" modules. */ -static int modules_count; -static int modules_allocated; -static char **modules_vector; - -static void -handle_module_expansion (args, len) - char *args; - int len; -{ - if (modules_vector == NULL) - { - modules_allocated = 1; /* Small for testing */ - modules_vector = (char **) xmalloc - (modules_allocated * sizeof (modules_vector[0])); - } - else if (modules_count >= modules_allocated) - { - modules_allocated *= 2; - modules_vector = (char **) xrealloc - ((char *) modules_vector, - modules_allocated * sizeof (modules_vector[0])); - } - modules_vector[modules_count] = xmalloc (strlen (args) + 1); - strcpy (modules_vector[modules_count], args); - ++modules_count; -} - -/* Original, not "expanded" modules. */ -static int module_argc; -static char **module_argv; - -void -client_expand_modules (argc, argv, local) - int argc; - char **argv; - int local; -{ - int errs; - int i; - - module_argc = argc; - module_argv = (char **) xmalloc ((argc + 1) * sizeof (module_argv[0])); - for (i = 0; i < argc; ++i) - module_argv[i] = xstrdup (argv[i]); - module_argv[argc] = NULL; - - for (i = 0; i < argc; ++i) - send_arg (argv[i]); - send_a_repository ("", current_parsed_root->directory, ""); - - send_to_server ("expand-modules\012", 0); - - errs = get_server_responses (); - if (last_repos != NULL) - free (last_repos); - last_repos = NULL; - if (last_update_dir != NULL) - free (last_update_dir); - last_update_dir = NULL; - if (errs) - error (errs, 0, "cannot expand modules"); -} - -void -client_send_expansions (local, where, build_dirs) - int local; - char *where; - int build_dirs; -{ - int i; - char *argv[1]; - - /* Send the original module names. The "expanded" module name might - not be suitable as an argument to a co request (e.g. it might be - the result of a -d argument in the modules file). It might be - cleaner if we genuinely expanded module names, all the way to a - local directory and repository, but that isn't the way it works - now. */ - send_file_names (module_argc, module_argv, 0); - - for (i = 0; i < modules_count; ++i) - { - argv[0] = where ? where : modules_vector[i]; - if (isfile (argv[0])) - send_files (1, argv, local, 0, build_dirs ? SEND_BUILD_DIRS : 0); - } - send_a_repository ("", current_parsed_root->directory, ""); -} - -void -client_nonexpanded_setup () -{ - send_a_repository ("", current_parsed_root->directory, ""); -} - -/* Receive a cvswrappers line from the server; it must be a line - containing an RCS option (e.g., "*.exe -k 'b'"). - - Note that this doesn't try to handle -t/-f options (which are a - whole separate issue which noone has thought much about, as far - as I know). - - We need to know the keyword expansion mode so we know whether to - read the file in text or binary mode. */ - -static void -handle_wrapper_rcs_option (args, len) - char *args; - int len; -{ - char *p; - - /* Enforce the notes in cvsclient.texi about how the response is not - as free-form as it looks. */ - p = strchr (args, ' '); - if (p == NULL) - goto handle_error; - if (*++p != '-' - || *++p != 'k' - || *++p != ' ' - || *++p != '\'') - goto handle_error; - if (strchr (p, '\'') == NULL) - goto handle_error; - - /* Add server-side cvswrappers line to our wrapper list. */ - wrap_add (args, 0); - return; - handle_error: - error (0, errno, "protocol error: ignoring invalid wrappers %s", args); -} - - -static void -handle_m (args, len) - char *args; - int len; -{ - /* In the case where stdout and stderr point to the same place, - fflushing stderr will make output happen in the correct order. - Often stderr will be line-buffered and this won't be needed, - but not always (is that true? I think the comment is probably - based on being confused between default buffering between - stdout and stderr. But I'm not sure). */ - fflush (stderr); - fwrite (args, len, sizeof (*args), stdout); - putc ('\n', stdout); -} - -static void handle_mbinary PROTO ((char *, int)); - -static void -handle_mbinary (args, len) - char *args; - int len; -{ - char *size_string; - size_t size; - size_t totalread; - size_t nread; - size_t toread; - char buf[8192]; - - /* See comment at handle_m about (non)flush of stderr. */ - - /* Get the size. */ - read_line (&size_string); - size = strto_file_size (size_string); - free (size_string); - - /* OK, now get all the data. The algorithm here is that we read - as much as the network wants to give us in - try_read_from_server, and then we output it all, and then - repeat, until we get all the data. */ - totalread = 0; - while (totalread < size) - { - toread = size - totalread; - if (toread > sizeof buf) - toread = sizeof buf; - - nread = try_read_from_server (buf, toread); - cvs_output_binary (buf, nread); - totalread += nread; - } -} - -static void -handle_e (args, len) - char *args; - int len; -{ - /* In the case where stdout and stderr point to the same place, - fflushing stdout will make output happen in the correct order. */ - fflush (stdout); - fwrite (args, len, sizeof (*args), stderr); - putc ('\n', stderr); -} - -/*ARGSUSED*/ -static void -handle_f (args, len) - char *args; - int len; -{ - fflush (stderr); -} - -static void handle_mt PROTO ((char *, int)); - -static void -handle_mt (args, len) - char *args; - int len; -{ - char *p; - char *tag = args; - char *text; - - /* See comment at handle_m for more details. */ - fflush (stderr); - - p = strchr (args, ' '); - if (p == NULL) - text = NULL; - else - { - *p++ = '\0'; - text = p; - } - - switch (tag[0]) - { - case '+': - if (strcmp (tag, "+updated") == 0) - updated_seen = 1; - else if (strcmp (tag, "+importmergecmd") == 0) - importmergecmd.seen = 1; - break; - case '-': - if (strcmp (tag, "-updated") == 0) - updated_seen = 0; - else if (strcmp (tag, "-importmergecmd") == 0) - { - char buf[80]; - - /* Now that we have gathered the information, we can - output the suggested merge command. */ - - if (importmergecmd.conflicts == 0 - || importmergecmd.mergetag1 == NULL - || importmergecmd.mergetag2 == NULL - || importmergecmd.repository == NULL) - { - error (0, 0, - "invalid server: incomplete importmergecmd tags"); - break; - } - - sprintf (buf, "\n%d conflicts created by this import.\n", - importmergecmd.conflicts); - cvs_output (buf, 0); - cvs_output ("Use the following command to help the merge:\n\n", - 0); - cvs_output ("\t", 1); - cvs_output (program_name, 0); - if (CVSroot_cmdline != NULL) - { - cvs_output (" -d ", 0); - cvs_output (CVSroot_cmdline, 0); - } - cvs_output (" checkout -j", 0); - cvs_output (importmergecmd.mergetag1, 0); - cvs_output (" -j", 0); - cvs_output (importmergecmd.mergetag2, 0); - cvs_output (" ", 1); - cvs_output (importmergecmd.repository, 0); - cvs_output ("\n\n", 0); - - /* Clear the static variables so that everything is - ready for any subsequent importmergecmd tag. */ - importmergecmd.conflicts = 0; - free (importmergecmd.mergetag1); - importmergecmd.mergetag1 = NULL; - free (importmergecmd.mergetag2); - importmergecmd.mergetag2 = NULL; - free (importmergecmd.repository); - importmergecmd.repository = NULL; - - importmergecmd.seen = 0; - } - break; - default: - if (updated_seen) - { - if (strcmp (tag, "fname") == 0) - { - if (updated_fname != NULL) - { - /* Output the previous message now. This can happen - if there was no Update-existing or other such - response, due to the -n global option. */ - cvs_output ("U ", 0); - cvs_output (updated_fname, 0); - cvs_output ("\n", 1); - free (updated_fname); - } - updated_fname = xstrdup (text); - } - /* Swallow all other tags. Either they are extraneous - or they reflect future extensions that we can - safely ignore. */ - } - else if (importmergecmd.seen) - { - if (strcmp (tag, "conflicts") == 0) - importmergecmd.conflicts = text ? atoi (text) : -1; - else if (strcmp (tag, "mergetag1") == 0) - importmergecmd.mergetag1 = xstrdup (text); - else if (strcmp (tag, "mergetag2") == 0) - importmergecmd.mergetag2 = xstrdup (text); - else if (strcmp (tag, "repository") == 0) - importmergecmd.repository = xstrdup (text); - /* Swallow all other tags. Either they are text for - which we are going to print our own version when we - see -importmergecmd, or they are future extensions - we can safely ignore. */ - } - else if (strcmp (tag, "newline") == 0) - printf ("\n"); - else if (text != NULL) - printf ("%s", text); - } -} - -#endif /* CLIENT_SUPPORT */ -#if defined(CLIENT_SUPPORT) || defined(SERVER_SUPPORT) - -/* This table must be writeable if the server code is included. */ -struct response responses[] = -{ -#ifdef CLIENT_SUPPORT -#define RSP_LINE(n, f, t, s) {n, f, t, s} -#else /* ! CLIENT_SUPPORT */ -#define RSP_LINE(n, f, t, s) {n, s} -#endif /* CLIENT_SUPPORT */ - - RSP_LINE("ok", handle_ok, response_type_ok, rs_essential), - RSP_LINE("error", handle_error, response_type_error, rs_essential), - RSP_LINE("Valid-requests", handle_valid_requests, response_type_normal, - rs_essential), - RSP_LINE("Checked-in", handle_checked_in, response_type_normal, - rs_essential), - RSP_LINE("New-entry", handle_new_entry, response_type_normal, rs_optional), - RSP_LINE("Checksum", handle_checksum, response_type_normal, rs_optional), - RSP_LINE("Copy-file", handle_copy_file, response_type_normal, rs_optional), - RSP_LINE("Updated", handle_updated, response_type_normal, rs_essential), - RSP_LINE("Created", handle_created, response_type_normal, rs_optional), - RSP_LINE("Update-existing", handle_update_existing, response_type_normal, - rs_optional), - RSP_LINE("Merged", handle_merged, response_type_normal, rs_essential), - RSP_LINE("Patched", handle_patched, response_type_normal, rs_optional), - RSP_LINE("Rcs-diff", handle_rcs_diff, response_type_normal, rs_optional), - RSP_LINE("Mode", handle_mode, response_type_normal, rs_optional), - RSP_LINE("Mod-time", handle_mod_time, response_type_normal, rs_optional), - RSP_LINE("Removed", handle_removed, response_type_normal, rs_essential), - RSP_LINE("Remove-entry", handle_remove_entry, response_type_normal, - rs_optional), - RSP_LINE("Set-static-directory", handle_set_static_directory, - response_type_normal, - rs_optional), - RSP_LINE("Clear-static-directory", handle_clear_static_directory, - response_type_normal, - rs_optional), - RSP_LINE("Set-sticky", handle_set_sticky, response_type_normal, - rs_optional), - RSP_LINE("Clear-sticky", handle_clear_sticky, response_type_normal, - rs_optional), - RSP_LINE("Template", handle_template, response_type_normal, - rs_optional), - RSP_LINE("Notified", handle_notified, response_type_normal, rs_optional), - RSP_LINE("Module-expansion", handle_module_expansion, response_type_normal, - rs_optional), - RSP_LINE("Wrapper-rcsOption", handle_wrapper_rcs_option, - response_type_normal, - rs_optional), - RSP_LINE("M", handle_m, response_type_normal, rs_essential), - RSP_LINE("Mbinary", handle_mbinary, response_type_normal, rs_optional), - RSP_LINE("E", handle_e, response_type_normal, rs_essential), - RSP_LINE("F", handle_f, response_type_normal, rs_optional), - RSP_LINE("MT", handle_mt, response_type_normal, rs_optional), - /* Possibly should be response_type_error. */ - RSP_LINE(NULL, NULL, response_type_normal, rs_essential) - -#undef RSP_LINE -}; - -#endif /* CLIENT_SUPPORT or SERVER_SUPPORT */ -#ifdef CLIENT_SUPPORT - -/* - * If LEN is 0, then send_to_server() computes string's length itself. - * - * Therefore, pass the real length when transmitting data that might - * contain 0's. - */ -void -send_to_server (str, len) - const char *str; - size_t len; -{ - static int nbytes; - - if (len == 0) - len = strlen (str); - - buf_output (to_server, str, len); - - /* There is no reason not to send data to the server, so do it - whenever we've accumulated enough information in the buffer to - make it worth sending. */ - nbytes += len; - if (nbytes >= 2 * BUFFER_DATA_SIZE) - { - int status; - - status = buf_send_output (to_server); - if (status != 0) - error (1, status, "error writing to server"); - nbytes = 0; - } -} - -/* Read up to LEN bytes from the server. Returns actual number of - bytes read, which will always be at least one; blocks if there is - no data available at all. Gives a fatal error on EOF or error. */ -static size_t -try_read_from_server (buf, len) - char *buf; - size_t len; -{ - int status, nread; - char *data; - - status = buf_read_data (from_server, len, &data, &nread); - if (status != 0) - { - if (status == -1) - error (1, 0, - "end of file from server (consult above messages if any)"); - else if (status == -2) - error (1, 0, "out of memory"); - else - error (1, status, "reading from server"); - } - - memcpy (buf, data, nread); - - return nread; -} - -/* - * Read LEN bytes from the server or die trying. - */ -void -read_from_server (buf, len) - char *buf; - size_t len; -{ - size_t red = 0; - while (red < len) - { - red += try_read_from_server (buf + red, len - red); - if (red == len) - break; - } -} - -/* - * Get some server responses and process them. Returns nonzero for - * error, 0 for success. */ -int -get_server_responses () -{ - struct response *rs; - do - { - char *cmd; - int len; - - len = read_line (&cmd); - for (rs = responses; rs->name != NULL; ++rs) - if (strncmp (cmd, rs->name, strlen (rs->name)) == 0) - { - int cmdlen = strlen (rs->name); - if (cmd[cmdlen] == '\0') - ; - else if (cmd[cmdlen] == ' ') - ++cmdlen; - else - /* - * The first len characters match, but it's a different - * response. e.g. the response is "oklahoma" but we - * matched "ok". - */ - continue; - (*rs->func) (cmd + cmdlen, len - cmdlen); - break; - } - if (rs->name == NULL) - /* It's OK to print just to the first '\0'. */ - /* We might want to handle control characters and the like - in some other way other than just sending them to stdout. - One common reason for this error is if people use :ext: - with a version of rsh which is doing CRLF translation or - something, and so the client gets "ok^M" instead of "ok". - Right now that will tend to print part of this error - message over the other part of it. It seems like we could - do better (either in general, by quoting or omitting all - control characters, and/or specifically, by detecting the CRLF - case and printing a specific error message). */ - error (0, 0, - "warning: unrecognized response `%s' from cvs server", - cmd); - free (cmd); - } while (rs->type == response_type_normal); - - if (updated_fname != NULL) - { - /* Output the previous message now. This can happen - if there was no Update-existing or other such - response, due to the -n global option. */ - cvs_output ("U ", 0); - cvs_output (updated_fname, 0); - cvs_output ("\n", 1); - free (updated_fname); - updated_fname = NULL; - } - - if (rs->type == response_type_error) - return 1; - if (failure_exit) - return 1; - return 0; -} - - - -/* Get the responses and then close the connection. */ - -/* - * Flag var; we'll set it in start_server() and not one of its - * callees, such as start_rsh_server(). This means that there might - * be a small window between the starting of the server and the - * setting of this var, but all the code in that window shouldn't care - * because it's busy checking return values to see if the server got - * started successfully anyway. - */ -int server_started = 0; - -int -get_responses_and_close () -{ - int errs = get_server_responses (); - int status; - - /* The following is necessary when working with multiple cvsroots, at least - * with commit. It used to be buried nicely in do_deferred_progs() before - * that function was removed. I suspect it wouldn't be necessary if - * call_in_directory() saved its working directory via save_cwd() before - * changing its directory and restored the saved working directory via - * restore_cwd() before exiting. Of course, calling CVS_CHDIR only once, - * here, may be more efficient. - */ - if( toplevel_wd != NULL ) - { - if( CVS_CHDIR( toplevel_wd ) < 0 ) - error( 1, errno, "could not chdir to %s", toplevel_wd ); - } - - if (client_prune_dirs) - process_prune_candidates (); - - /* First we shut down TO_SERVER. That tells the server that its input is - * finished. It then shuts down the buffer it is sending to us, at which - * point our shut down of FROM_SERVER will complete. - */ - - status = buf_shutdown (to_server); - if (status != 0) - error (0, status, "shutting down buffer to server"); - buf_free (to_server); - to_server = NULL; - - status = buf_shutdown (from_server); - if (status != 0) - error (0, status, "shutting down buffer from server"); - buf_free (from_server); - from_server = NULL; - server_started = 0; - - /* see if we need to sleep before returning to avoid time-stamp races */ - if (last_register_time) - { - sleep_past (last_register_time); - } - - return errs; -} - -#ifndef NO_EXT_METHOD -static void start_rsh_server PROTO((cvsroot_t *, struct buffer **, struct buffer **)); -#endif - -int -supported_request (name) - char *name; -{ - struct request *rq; - - for (rq = requests; rq->name; rq++) - if (!strcmp (rq->name, name)) - return (rq->flags & RQ_SUPPORTED) != 0; - error (1, 0, "internal error: testing support for unknown option?"); - /* NOTREACHED */ - return 0; -} - - - -#if defined (AUTH_CLIENT_SUPPORT) || defined (HAVE_KERBEROS) || defined (HAVE_GSSAPI) -static struct hostent *init_sockaddr PROTO ((struct sockaddr_in *, char *, - unsigned int)); - -static struct hostent * -init_sockaddr (name, hostname, port) - struct sockaddr_in *name; - char *hostname; - unsigned int port; -{ - struct hostent *hostinfo; - unsigned short shortport = port; - - memset (name, 0, sizeof (*name)); - name->sin_family = AF_INET; - name->sin_port = htons (shortport); - hostinfo = gethostbyname (hostname); - if (hostinfo == NULL) - { - fprintf (stderr, "Unknown host %s.\n", hostname); - error_exit (); - } - name->sin_addr = *(struct in_addr *) hostinfo->h_addr; - return hostinfo; -} - - - -/* Generic function to do port number lookup tasks. - * - * In order of precedence, will return: - * getenv (envname), if defined - * getservbyname (portname), if defined - * defaultport - */ -static int -get_port_number (envname, portname, defaultport) - const char *envname; - const char *portname; - int defaultport; -{ - struct servent *s; - char *port_s; - - if (envname && (port_s = getenv (envname))) - { - int port = atoi (port_s); - if (port <= 0) - { - error (0, 0, "%s must be a positive integer! If you", envname); - error (0, 0, "are trying to force a connection via rsh, please"); - error (0, 0, "put \":server:\" at the beginning of your CVSROOT"); - error (1, 0, "variable."); - } - return port; - } - else if (portname && (s = getservbyname (portname, "tcp"))) - return ntohs (s->s_port); - else - return defaultport; -} - - - -/* get the port number for a client to connect to based on the port - * and method of a cvsroot_t. - * - * we do this here instead of in parse_cvsroot so that we can keep network - * code confined to a localized area and also to delay the lookup until the - * last possible moment so it remains possible to run cvs client commands that - * skip opening connections to the server (i.e. skip network operations - * entirely) - * - * and yes, I know none of the commands do that now, but here's to planning - * for the future, eh? cheers. - * - * FIXME - We could cache the port lookup safely right now as we never change - * it for a single root on the fly, but we'd have to un'const some other - * functions - REMOVE_FIXME? This may be unecessary. We're talking about, - * what, usually one, sometimes two lookups of the port per invocation. I - * think twice is by far the rarer of the two cases - only the login function - * will need to do it to save the canonical CVSROOT. -DRP - */ -int -get_cvs_port_number (root) - const cvsroot_t *root; -{ - - if (root->port) return root->port; - - switch (root->method) - { -# ifdef HAVE_GSSAPI - case gserver_method: -# endif /* HAVE_GSSAPI */ -# ifdef AUTH_CLIENT_SUPPORT - case pserver_method: -# endif /* AUTH_CLIENT_SUPPORT */ -# if defined (AUTH_CLIENT_SUPPORT) || defined (HAVE_GSSAPI) - return get_port_number ("CVS_CLIENT_PORT", "cvspserver", CVS_AUTH_PORT); -# endif /* defined (AUTH_CLIENT_SUPPORT) || defined (HAVE_GSSAPI) */ -# ifdef HAVE_KERBEROS - case kserver_method: - return get_port_number ("CVS_CLIENT_PORT", "cvs", CVS_PORT); -# endif /* HAVE_KERBEROS */ - default: - error(1, EINVAL, "internal error: get_cvs_port_number called for invalid connection method (%s)", - method_names[root->method]); - break; - } - /* NOTREACHED */ - return -1; -} - - - -void -make_bufs_from_fds (tofd, fromfd, child_pid, to_server, from_server, is_sock) - int tofd; - int fromfd; - int child_pid; - struct buffer **to_server; - struct buffer **from_server; - int is_sock; -{ - FILE *to_server_fp; - FILE *from_server_fp; - -# ifdef NO_SOCKET_TO_FD - if (is_sock) - { - assert (tofd == fromfd); - *to_server = socket_buffer_initialize (tofd, 0, - (BUFMEMERRPROC) NULL); - *from_server = socket_buffer_initialize (tofd, 1, - (BUFMEMERRPROC) NULL); - } - else -# endif /* NO_SOCKET_TO_FD */ - { - /* todo: some OS's don't need these calls... */ - close_on_exec (tofd); - close_on_exec (fromfd); - - /* SCO 3 and AIX have a nasty bug in the I/O libraries which precludes - fdopening the same file descriptor twice, so dup it if it is the - same. */ - if (tofd == fromfd) - { - fromfd = dup (tofd); - if (fromfd < 0) - error (1, errno, "cannot dup net connection"); - } - - /* These will use binary mode on systems which have it. */ - /* - * Also, we know that from_server is shut down second, so we pass - * child_pid in there. In theory, it should be stored in both - * buffers with a ref count... - */ - to_server_fp = fdopen (tofd, FOPEN_BINARY_WRITE); - if (to_server_fp == NULL) - error (1, errno, "cannot fdopen %d for write", tofd); - *to_server = stdio_buffer_initialize (to_server_fp, 0, 0, - (BUFMEMERRPROC) NULL); - - from_server_fp = fdopen (fromfd, FOPEN_BINARY_READ); - if (from_server_fp == NULL) - error (1, errno, "cannot fdopen %d for read", fromfd); - *from_server = stdio_buffer_initialize (from_server_fp, child_pid, 1, - (BUFMEMERRPROC) NULL); - } -} -#endif /* defined (AUTH_CLIENT_SUPPORT) || defined (HAVE_KERBEROS) || defined(HAVE_GSSAPI) */ - - - -#if defined (AUTH_CLIENT_SUPPORT) || defined(HAVE_GSSAPI) -/* Connect to the authenticating server. - - If VERIFY_ONLY is non-zero, then just verify that the password is - correct and then shutdown the connection. - - If VERIFY_ONLY is 0, then really connect to the server. - - If DO_GSSAPI is non-zero, then we use GSSAPI authentication rather - than the pserver password authentication. - - If we fail to connect or if access is denied, then die with fatal - error. */ -void -connect_to_pserver (root, to_server_p, from_server_p, verify_only, do_gssapi) - cvsroot_t *root; - struct buffer **to_server_p; - struct buffer **from_server_p; - int verify_only; - int do_gssapi; -{ - int sock; - int port_number; - struct sockaddr_in client_sai; - struct hostent *hostinfo; - struct buffer *to_server, *from_server; - - sock = socket (AF_INET, SOCK_STREAM, 0); - if (sock == -1) - { - error (1, 0, "cannot create socket: %s", SOCK_STRERROR (SOCK_ERRNO)); - } - port_number = get_cvs_port_number (root); - hostinfo = init_sockaddr (&client_sai, root->hostname, port_number); - if (trace) - { - fprintf (stderr, " -> Connecting to %s(%s):%d\n", - root->hostname, - inet_ntoa (client_sai.sin_addr), port_number); - } - if (connect (sock, (struct sockaddr *) &client_sai, sizeof (client_sai)) - < 0) - error (1, 0, "connect to %s(%s):%d failed: %s", - root->hostname, - inet_ntoa (client_sai.sin_addr), - port_number, SOCK_STRERROR (SOCK_ERRNO)); - - make_bufs_from_fds (sock, sock, 0, &to_server, &from_server, 1); - - auth_server (root, to_server, from_server, verify_only, do_gssapi, hostinfo); - - if (verify_only) - { - int status; - - status = buf_shutdown (to_server); - if (status != 0) - error (0, status, "shutting down buffer to server"); - buf_free (to_server); - to_server = NULL; - - status = buf_shutdown (from_server); - if (status != 0) - error (0, status, "shutting down buffer from server"); - buf_free (from_server); - from_server = NULL; - - /* Don't need to set server_started = 0 since we don't set it to 1 - * until returning from this call. - */ - } - else - { - *to_server_p = to_server; - *from_server_p = from_server; - } - - return; -} - - - -static void -auth_server (root, lto_server, lfrom_server, verify_only, do_gssapi, hostinfo) - cvsroot_t *root; - struct buffer *lto_server; - struct buffer *lfrom_server; - int verify_only; - int do_gssapi; - struct hostent *hostinfo; -{ - char *username = ""; /* the username we use to connect */ - char no_passwd = 0; /* gets set if no password found */ - - /* FIXME!!!!!!!!!!!!!!!!!! - * - * THIS IS REALLY UGLY! - * - * I'm setting the globals here so we can make calls to send_to_server & - * read_line. This happens again _after_ we return if we're not in - * verify_only mode. We should be relying on the values we passed in, but - * sent_to_server and read_line don't require an outside buf yet. - */ - to_server = lto_server; - from_server = lfrom_server; - - /* Run the authorization mini-protocol before anything else. */ - if (do_gssapi) - { -# ifdef HAVE_GSSAPI - FILE *fp = stdio_buffer_get_file(lto_server); - int fd = fp ? fileno(fp) : -1; - struct stat s; - - if ((fd < 0) || (fstat (fd, &s) < 0) || !S_ISSOCK(s.st_mode)) - { - error (1, 0, "gserver currently only enabled for socket connections"); - } - - if (! connect_to_gserver (root, fd, hostinfo)) - { - error (1, 0, - "authorization failed: server %s rejected access to %s", - root->hostname, root->directory); - } -# else /* ! HAVE_GSSAPI */ - error (1, 0, "INTERNAL ERROR: This client does not support GSSAPI authentication"); -# endif /* HAVE_GSSAPI */ - } - else /* ! do_gssapi */ - { -# ifdef AUTH_CLIENT_SUPPORT - char *begin = NULL; - char *password = NULL; - char *end = NULL; - - if (verify_only) - { - begin = "BEGIN VERIFICATION REQUEST"; - end = "END VERIFICATION REQUEST"; - } - else - { - begin = "BEGIN AUTH REQUEST"; - end = "END AUTH REQUEST"; - } - - /* Get the password, probably from ~/.cvspass. */ - password = get_cvs_password (); - username = root->username ? root->username : getcaller(); - - /* 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. */ - send_to_server(begin, 0); - send_to_server("\012", 1); - - /* Send the data the server needs. */ - send_to_server(root->directory, 0); - send_to_server("\012", 1); - send_to_server(username, 0); - send_to_server("\012", 1); - send_to_server(password, 0); - send_to_server("\012", 1); - - /* Announce that we're ending the authorization protocol. */ - send_to_server(end, 0); - send_to_server("\012", 1); - - free_cvs_password (password); - password = NULL; -# else /* ! AUTH_CLIENT_SUPPORT */ - error (1, 0, "INTERNAL ERROR: This client does not support pserver authentication"); -# endif /* AUTH_CLIENT_SUPPORT */ - } /* if (do_gssapi) */ - - { - char *read_buf; - - /* Loop, getting responses from the server. */ - while (1) - { - read_line (&read_buf); - - if (strcmp (read_buf, "I HATE YOU") == 0) - { - /* Authorization not granted. - * - * This is a little confusing since we can reach this while loop in GSSAPI - * mode, but if GSSAPI authentication failed, we already jumped to the - * rejected label (there is no case where the connect_to_gserver function - * can return 1 and we will not receive "I LOVE YOU" from the server, barring - * broken connections and garbled messages, of course). - * - * i.e. This is a pserver specific error message and should be since - * GSSAPI doesn't use username. - */ - error (0, 0, - "authorization failed: server %s rejected access to %s for user %s", - root->hostname, root->directory, 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"); - } - error_exit(); - } - else if (strncmp (read_buf, "E ", 2) == 0) - { - fprintf (stderr, "%s\n", read_buf + 2); - - /* Continue with the authentication protocol. */ - } - else if (strncmp (read_buf, "error ", 6) == 0) - { - char *p; - - /* First skip the code. */ - p = read_buf + 6; - while (*p != ' ' && *p != '\0') - ++p; - - /* Skip the space that follows the code. */ - if (*p == ' ') - ++p; - - /* Now output the text. */ - fprintf (stderr, "%s\n", p); - error_exit(); - } - else if (strcmp (read_buf, "I LOVE YOU") == 0) - { - free (read_buf); - break; - } - else - { - error (1, 0, - "unrecognized auth response from %s: %s", - root->hostname, read_buf); - } - free (read_buf); - } - } -} -#endif /* defined (AUTH_CLIENT_SUPPORT) || defined(HAVE_GSSAPI) */ - - - -#ifdef CLIENT_SUPPORT -/* void - * connect_to_forked_server ( struct buffer **to_server, - * struct buffer **from_server ) - * - * Connect to a forked server process. - */ -void -connect_to_forked_server (to_server, from_server) - struct buffer **to_server; - struct buffer **from_server; -{ - int tofd, fromfd; - int child_pid; - - /* This is pretty simple. All we need to do is choose the correct - cvs binary and call piped_child. */ - - const char *command[3]; - - command[0] = getenv ("CVS_SERVER"); - if (! command[0]) - command[0] = program_path; - - command[1] = "server"; - command[2] = NULL; - - if (trace) - { - fprintf (stderr, " -> Forking server: %s %s\n", command[0], command[1]); - } - - child_pid = piped_child (command, &tofd, &fromfd, 0); - if (child_pid < 0) - error (1, 0, "could not fork server process"); - - make_bufs_from_fds (tofd, fromfd, child_pid, to_server, from_server, 0); -} -#endif /* CLIENT_SUPPORT */ - - - -#ifdef HAVE_KERBEROS -/* This function has not been changed to deal with NO_SOCKET_TO_FD - (i.e., systems on which sockets cannot be converted to file - descriptors). The first person to try building a kerberos client - on such a system (OS/2, Windows 95, and maybe others) will have to - take care of this. */ -void -start_tcp_server (root, to_server, from_server) - cvsroot_t *root; - struct buffer **to_server; - struct buffer **from_server; -{ - int s; - const char *portenv; - int port; - struct hostent *hp; - struct sockaddr_in sin; - char *hname; - - s = socket (AF_INET, SOCK_STREAM, 0); - if (s < 0) - error (1, 0, "cannot create socket: %s", SOCK_STRERROR (SOCK_ERRNO)); - - port = get_cvs_port_number (root); - - hp = init_sockaddr (&sin, root->hostname, port); - - hname = xstrdup (hp->h_name); - - if (trace) - { - fprintf (stderr, " -> Connecting to %s(%s):%d\n", - root->hostname, - inet_ntoa (sin.sin_addr), port); - } - - if (connect (s, (struct sockaddr *) &sin, sizeof sin) < 0) - error (1, 0, "connect to %s(%s):%d failed: %s", - root->hostname, - inet_ntoa (sin.sin_addr), - port, SOCK_STRERROR (SOCK_ERRNO)); - - { - const char *realm; - struct sockaddr_in laddr; - int laddrlen; - KTEXT_ST ticket; - MSG_DAT msg_data; - CREDENTIALS cred; - int status; - - realm = krb_realmofhost (hname); - - laddrlen = sizeof (laddr); - if (getsockname (s, (struct sockaddr *) &laddr, &laddrlen) < 0) - error (1, 0, "getsockname failed: %s", SOCK_STRERROR (SOCK_ERRNO)); - - /* We don't care about the checksum, and pass it as zero. */ - status = krb_sendauth (KOPT_DO_MUTUAL, s, &ticket, "rcmd", - hname, realm, (unsigned long) 0, &msg_data, - &cred, sched, &laddr, &sin, "KCVSV1.0"); - if (status != KSUCCESS) - error (1, 0, "kerberos authentication failed: %s", - krb_get_err_text (status)); - memcpy (kblock, cred.session, sizeof (C_Block)); - } - - close_on_exec (s); - - free (hname); - - /* Give caller the values it wants. */ - make_bufs_from_fds (s, s, 0, to_server, from_server, 1); -} - -#endif /* HAVE_KERBEROS */ - -#ifdef HAVE_GSSAPI - -/* Receive a given number of bytes. */ - -static void -recv_bytes (sock, buf, need) - int sock; - char *buf; - int need; -{ - while (need > 0) - { - int got; - - got = recv (sock, buf, need, 0); - if (got <= 0) - error (1, 0, "recv() from server %s: %s", current_parsed_root->hostname, - got == 0 ? "EOF" : SOCK_STRERROR (SOCK_ERRNO)); - - buf += got; - need -= got; - } -} - -/* Connect to the server using GSSAPI authentication. */ - -/* FIXME - * - * This really needs to be rewritten to use a buffer and not a socket. - * This would enable gserver to work with the SSL code I'm about to commit - * since the SSL connection is going to look like a FIFO and not a socket. - * - * I think, basically, it will need to use buf_output and buf_read directly - * since I don't think there is a read_bytes function - only read_line. - * - * recv_bytes could then be removed too. - * - * Besides, I added some cruft to reenable the socket which shouldn't be - * there. This would also enable its removal. - */ -#define BUFSIZE 1024 -static int -connect_to_gserver (root, sock, hostinfo) - cvsroot_t *root; - int sock; - struct hostent *hostinfo; -{ - char *str; - char buf[BUFSIZE]; - gss_buffer_desc *tok_in_ptr, tok_in, tok_out; - OM_uint32 stat_min, stat_maj; - gss_name_t server_name; - - str = "BEGIN GSSAPI REQUEST\012"; - - if (send (sock, str, strlen (str), 0) < 0) - error (1, 0, "cannot send: %s", SOCK_STRERROR (SOCK_ERRNO)); - - if (strlen (hostinfo->h_name) > BUFSIZE - 5) - error (1, 0, "Internal error: hostname exceeds length of buffer"); - sprintf (buf, "cvs@%s", hostinfo->h_name); - tok_in.length = strlen (buf); - tok_in.value = buf; - gss_import_name (&stat_min, &tok_in, GSS_C_NT_HOSTBASED_SERVICE, - &server_name); - - tok_in_ptr = GSS_C_NO_BUFFER; - gcontext = GSS_C_NO_CONTEXT; - - do - { - stat_maj = gss_init_sec_context (&stat_min, GSS_C_NO_CREDENTIAL, - &gcontext, server_name, - GSS_C_NULL_OID, - (GSS_C_MUTUAL_FLAG - | GSS_C_REPLAY_FLAG), - 0, NULL, tok_in_ptr, NULL, &tok_out, - NULL, NULL); - 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 (&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); - } - - if (tok_out.length == 0) - { - tok_in.length = 0; - } - else - { - char cbuf[2]; - int need; - - cbuf[0] = (tok_out.length >> 8) & 0xff; - cbuf[1] = tok_out.length & 0xff; - if (send (sock, cbuf, 2, 0) < 0) - error (1, 0, "cannot send: %s", SOCK_STRERROR (SOCK_ERRNO)); - if (send (sock, tok_out.value, tok_out.length, 0) < 0) - error (1, 0, "cannot send: %s", SOCK_STRERROR (SOCK_ERRNO)); - - recv_bytes (sock, cbuf, 2); - need = ((cbuf[0] & 0xff) << 8) | (cbuf[1] & 0xff); - - if (need > sizeof buf) - { - ssize_t got; - size_t total; - - /* 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]; - total = 2; - while (got = recv (sock, buf + total, sizeof buf - total, 0)) - { - if (got < 0) - error (1, 0, "recv() from server %s: %s", - root->hostname, SOCK_STRERROR (SOCK_ERRNO)); - total += got; - if (strrchr (buf + total - got, '\n')) - break; - } - buf[total] = '\0'; - if (buf[total - 1] == '\n') - buf[total - 1] = '\0'; - error (1, 0, "error from server %s: %s", root->hostname, - buf); - } - - recv_bytes (sock, buf, need); - tok_in.length = need; - } - - tok_in.value = buf; - tok_in_ptr = &tok_in; - } - while (stat_maj == GSS_S_CONTINUE_NEEDED); - - return 1; -} - -#endif /* HAVE_GSSAPI */ - - - -static int send_variable_proc PROTO ((Node *, void *)); - -static int -send_variable_proc (node, closure) - Node *node; - void *closure; -{ - send_to_server ("Set ", 0); - send_to_server (node->key, 0); - send_to_server ("=", 1); - send_to_server (node->data, 0); - send_to_server ("\012", 1); - return 0; -} - - - -/* Contact the server. */ -void -start_server () -{ - int rootless; - char *log = getenv ("CVS_CLIENT_LOG"); - - /* Clear our static variables for this invocation. */ - if (toplevel_repos != NULL) - free (toplevel_repos); - toplevel_repos = NULL; - - /* Note that generally speaking we do *not* fall back to a different - way of connecting if the first one does not work. This is slow - (*really* slow on a 14.4kbps link); the clean way to have a CVS - which supports several ways of connecting is with access methods. */ - - switch (current_parsed_root->method) - { - -#ifdef AUTH_CLIENT_SUPPORT - case pserver_method: - /* Toss the return value. It will die with an error message if - * anything goes wrong anyway. - */ - connect_to_pserver (current_parsed_root, &to_server, &from_server, 0, 0); - break; -#endif /* AUTH_CLIENT_SUPPORT */ - -#if HAVE_KERBEROS - case kserver_method: - start_tcp_server (current_parsed_root, &to_server, &from_server); - break; -#endif /* HAVE_KERBEROS */ - -#ifdef HAVE_GSSAPI - case gserver_method: - /* GSSAPI authentication is handled by the pserver. */ - connect_to_pserver (current_parsed_root, &to_server, &from_server, 0, 1); - break; -#endif /* HAVE_GSSAPI */ - - case ext_method: - case extssh_method: -#ifdef NO_EXT_METHOD - error (0, 0, ":ext: method not supported by this port of CVS"); - error (1, 0, "try :server: instead"); -#else /* ! NO_EXT_METHOD */ - start_rsh_server (current_parsed_root, &to_server, &from_server); -#endif /* NO_EXT_METHOD */ - break; - - case server_method: -#ifdef START_SERVER - { - int tofd, fromfd; - START_SERVER (&tofd, &fromfd, getcaller (), - current_parsed_root->username, current_parsed_root->hostname, - current_parsed_root->directory); -# ifdef START_SERVER_RETURNS_SOCKET - make_bufs_from_fds (tofd, fromfd, 0, &to_server, &from_server, 1); -# else /* ! START_SERVER_RETURNS_SOCKET */ - make_bufs_from_fds (tofd, fromfd, 0, &to_server, &from_server, 0); -# endif /* START_SERVER_RETURNS_SOCKET */ - } -#else /* ! START_SERVER */ - /* FIXME: It should be possible to implement this portably, - like pserver, which would get rid of the duplicated code - in {vms,windows-NT,...}/startserver.c. */ - error (1, 0, -"the :server: access method is not supported by this port of CVS"); -#endif /* START_SERVER */ - break; - - case fork_method: - connect_to_forked_server (&to_server, &from_server); - break; - - default: - error (1, 0, "\ -(start_server internal error): unknown access method"); - break; - } - - /* "Hi, I'm Darlene and I'll be your server tonight..." */ - server_started = 1; - - /* Set up logfiles, if any. - * - * We do this _after_ authentication on purpose. Wouldn't really like to - * worry about logging passwords... - */ - if (log) - { - int len = strlen (log); - char *buf = xmalloc (len + 5); - char *p; - FILE *fp; - - strcpy (buf, log); - p = buf + len; - - /* Open logfiles in binary mode so that they reflect - exactly what was transmitted and received (that is - more important than that they be maximally - convenient to view). */ - /* Note that if we create several connections in a single CVS client - (currently used by update.c), then the last set of logfiles will - overwrite the others. There is currently no way around this. */ - strcpy (p, ".in"); - fp = open_file (buf, "wb"); - if (fp == NULL) - error (0, errno, "opening to-server logfile %s", buf); - else - to_server = log_buffer_initialize (to_server, fp, 0, - (BUFMEMERRPROC) NULL); - - strcpy (p, ".out"); - fp = open_file (buf, "wb"); - if (fp == NULL) - error (0, errno, "opening from-server logfile %s", buf); - else - from_server = log_buffer_initialize (from_server, fp, 1, - (BUFMEMERRPROC) NULL); - - free (buf); - } - - /* Clear static variables. */ - if (toplevel_repos != NULL) - free (toplevel_repos); - toplevel_repos = NULL; - if (last_repos != NULL) - free (last_repos); - last_repos = NULL; - if (last_update_dir != NULL) - free (last_update_dir); - last_update_dir = NULL; - stored_checksum_valid = 0; - if (stored_mode != NULL) - { - free (stored_mode); - stored_mode = NULL; - } - - rootless = (strcmp (cvs_cmd_name, "init") == 0); - if (!rootless) - { - send_to_server ("Root ", 0); - send_to_server (current_parsed_root->directory, 0); - send_to_server ("\012", 1); - } - - { - struct response *rs; - - send_to_server ("Valid-responses", 0); - - for (rs = responses; rs->name != NULL; ++rs) - { - send_to_server (" ", 0); - send_to_server (rs->name, 0); - } - send_to_server ("\012", 1); - } - send_to_server ("valid-requests\012", 0); - - if (get_server_responses ()) - error_exit (); - - /* - * Now handle global options. - * - * -H, -f, -d, -e should be handled OK locally. - * - * -b we ignore (treating it as a server installation issue). - * FIXME: should be an error message. - * - * -v we print local version info; FIXME: Add a protocol request to get - * the version from the server so we can print that too. - * - * -l -t -r -w -q -n and -Q need to go to the server. - */ - - { - int have_global = supported_request ("Global_option"); - - if (noexec) - { - if (have_global) - { - send_to_server ("Global_option -n\012", 0); - } - else - error (1, 0, - "This server does not support the global -n option."); - } - if (quiet) - { - if (have_global) - { - send_to_server ("Global_option -q\012", 0); - } - else - error (1, 0, - "This server does not support the global -q option."); - } - if (really_quiet) - { - if (have_global) - { - send_to_server ("Global_option -Q\012", 0); - } - else - error (1, 0, - "This server does not support the global -Q option."); - } - if (!cvswrite) - { - if (have_global) - { - send_to_server ("Global_option -r\012", 0); - } - else - error (1, 0, - "This server does not support the global -r option."); - } - if (trace) - { - if (have_global) - { - send_to_server ("Global_option -t\012", 0); - } - else - error (1, 0, - "This server does not support the global -t option."); - } - } - - /* Find out about server-side cvswrappers. An extra network - turnaround for cvs import seems to be unavoidable, unless we - want to add some kind of client-side place to configure which - filenames imply binary. For cvs add, we could avoid the - problem by keeping a copy of the wrappers in CVSADM (the main - reason to bother would be so we could make add work without - contacting the server, I suspect). */ - - if ((strcmp (cvs_cmd_name, "import") == 0) - || (strcmp (cvs_cmd_name, "add") == 0)) - { - if (supported_request ("wrapper-sendme-rcsOptions")) - { - int err; - send_to_server ("wrapper-sendme-rcsOptions\012", 0); - err = get_server_responses (); - if (err != 0) - error (err, 0, "error reading from server"); - } - } - - if (cvsencrypt && !rootless) - { -#ifdef ENCRYPTION - /* Turn on encryption before turning on compression. We do - not want to try to compress the encrypted stream. Instead, - we want to encrypt the compressed stream. If we can't turn - on encryption, bomb out; don't let the user think the data - is being encrypted when it is not. */ -#ifdef HAVE_KERBEROS - if (current_parsed_root->method == kserver_method) - { - if (! supported_request ("Kerberos-encrypt")) - error (1, 0, "This server does not support encryption"); - send_to_server ("Kerberos-encrypt\012", 0); - to_server = krb_encrypt_buffer_initialize (to_server, 0, sched, - kblock, - (BUFMEMERRPROC) NULL); - from_server = krb_encrypt_buffer_initialize (from_server, 1, - sched, kblock, - (BUFMEMERRPROC) NULL); - } - else -#endif /* HAVE_KERBEROS */ -#ifdef HAVE_GSSAPI - if (current_parsed_root->method == gserver_method) - { - if (! supported_request ("Gssapi-encrypt")) - error (1, 0, "This server does not support encryption"); - send_to_server ("Gssapi-encrypt\012", 0); - to_server = cvs_gssapi_wrap_buffer_initialize (to_server, 0, - gcontext, - ((BUFMEMERRPROC) - NULL)); - from_server = cvs_gssapi_wrap_buffer_initialize (from_server, 1, - gcontext, - ((BUFMEMERRPROC) - NULL)); - cvs_gssapi_encrypt = 1; - } - else -#endif /* HAVE_GSSAPI */ - error (1, 0, "Encryption is only supported when using GSSAPI or Kerberos"); -#else /* ! ENCRYPTION */ - error (1, 0, "This client does not support encryption"); -#endif /* ! ENCRYPTION */ - } - - if (gzip_level && !rootless) - { - if (supported_request ("Gzip-stream")) - { - char gzip_level_buf[5]; - send_to_server ("Gzip-stream ", 0); - sprintf (gzip_level_buf, "%d", gzip_level); - send_to_server (gzip_level_buf, 0); - send_to_server ("\012", 1); - - /* All further communication with the server will be - compressed. */ - - to_server = compress_buffer_initialize (to_server, 0, gzip_level, - (BUFMEMERRPROC) NULL); - from_server = compress_buffer_initialize (from_server, 1, - gzip_level, - (BUFMEMERRPROC) NULL); - } -#ifndef NO_CLIENT_GZIP_PROCESS - else if (supported_request ("gzip-file-contents")) - { - char gzip_level_buf[5]; - send_to_server ("gzip-file-contents ", 0); - sprintf (gzip_level_buf, "%d", gzip_level); - send_to_server (gzip_level_buf, 0); - - send_to_server ("\012", 1); - - file_gzip_level = gzip_level; - } -#endif - else - { - fprintf (stderr, "server doesn't support gzip-file-contents\n"); - /* Setting gzip_level to 0 prevents us from giving the - error twice if update has to contact the server again - to fetch unpatchable files. */ - gzip_level = 0; - } - } - - if (cvsauthenticate && ! cvsencrypt && !rootless) - { - /* Turn on authentication after turning on compression, so - that we can compress the authentication information. We - assume that encrypted data is always authenticated--the - ability to decrypt the data stream is itself a form of - authentication. */ -#ifdef HAVE_GSSAPI - if (current_parsed_root->method == gserver_method) - { - if (! supported_request ("Gssapi-authenticate")) - error (1, 0, - "This server does not support stream authentication"); - send_to_server ("Gssapi-authenticate\012", 0); - to_server = cvs_gssapi_wrap_buffer_initialize (to_server, 0, - gcontext, - ((BUFMEMERRPROC) - NULL)); - from_server = cvs_gssapi_wrap_buffer_initialize (from_server, 1, - gcontext, - ((BUFMEMERRPROC) - NULL)); - } - else - error (1, 0, "Stream authentication is only supported when using GSSAPI"); -#else /* ! HAVE_GSSAPI */ - error (1, 0, "This client does not support stream authentication"); -#endif /* ! HAVE_GSSAPI */ - } - - /* If "Set" is not supported, just silently fail to send the variables. - Users with an old server should get a useful error message when it - fails to recognize the ${=foo} syntax. This way if someone uses - several servers, some of which are new and some old, they can still - set user variables in their .cvsrc without trouble. */ - if (supported_request ("Set")) - walklist (variable_list, send_variable_proc, NULL); -} - - - -#ifndef NO_EXT_METHOD - -/* Contact the server by starting it with rsh. */ - -/* Right now, we have two different definitions for this function, - depending on whether we start the rsh server using popenRW or not. - This isn't ideal, and the best thing would probably be to change - the OS/2 port to be more like the regular Unix client (i.e., by - implementing piped_child)... but I'm doing something else at the - moment, and wish to make only one change at a time. -Karl */ - -# ifdef START_RSH_WITH_POPEN_RW - -/* This is actually a crock -- it's OS/2-specific, for no one else - uses it. If I get time, I want to make piped_child and all the - other stuff in os2/run.c work right. In the meantime, this gets us - up and running, and that's most important. */ - -static void -start_rsh_server (root, to_server, from_server) - cvsroot_t *root; - struct buffer **to_server; - struct buffer **from_server; -{ - int pipes[2]; - int child_pid; - - /* If you're working through firewalls, you can set the - CVS_RSH environment variable to a script which uses rsh to - invoke another rsh on a proxy machine. */ - char *env_cvs_rsh = getenv ("CVS_RSH"); - char *env_cvs_ssh = getenv ("CVS_SSH"); - char *cvs_rsh; - char *cvs_server = getenv ("CVS_SERVER"); - int i = 0; - /* This needs to fit "rsh", "-b", "-l", "USER", "host", - "cmd (w/ args)", and NULL. We leave some room to grow. */ - char *rsh_argv[10]; - - if (root->method == extssh_method) - cvs_rsh = env_cvs_ssh ? env_cvs_ssh : SSH_DFLT; - else - cvs_rsh = env_cvs_rsh ? env_cvs_rsh : RSH_DFLT; - - if (!cvs_server) - cvs_server = "cvs"; - - /* The command line starts out with rsh. */ - rsh_argv[i++] = cvs_rsh; - -# ifdef RSH_NEEDS_BINARY_FLAG - /* "-b" for binary, under OS/2. */ - rsh_argv[i++] = "-b"; -# endif /* RSH_NEEDS_BINARY_FLAG */ - - /* Then we strcat more things on the end one by one. */ - if (root->username != NULL) - { - rsh_argv[i++] = "-l"; - rsh_argv[i++] = root->username; - } - - rsh_argv[i++] = root->hostname; - rsh_argv[i++] = cvs_server; - rsh_argv[i++] = "server"; - - /* Mark the end of the arg list. */ - rsh_argv[i] = (char *) NULL; - - if (trace) - { - fprintf (stderr, " -> Starting server: "); - for (i = 0; rsh_argv[i]; i++) - fprintf (stderr, "%s ", rsh_argv[i]); - putc ('\n', stderr); - } - - /* Do the deed. */ - child_pid = popenRW (rsh_argv, pipes); - if (child_pid < 0) - error (1, errno, "cannot start server via rsh"); - - /* Give caller the file descriptors in a form it can deal with. */ - make_bufs_from_fds (pipes[0], pipes[1], child_pid, to_server, from_server, 0); -} - -# else /* ! START_RSH_WITH_POPEN_RW */ - -static void -start_rsh_server (root, to_server, from_server) - cvsroot_t *root; - struct buffer **to_server; - struct buffer **from_server; -{ - /* If you're working through firewalls, you can set the - CVS_RSH environment variable to a script which uses rsh to - invoke another rsh on a proxy machine. */ - char *env_cvs_rsh = getenv ("CVS_RSH"); - char *env_cvs_ssh = getenv ("CVS_SSH"); - char *cvs_rsh; - char *cvs_server = getenv ("CVS_SERVER"); - char *command; - int tofd, fromfd; - int child_pid; - - if (root->method == extssh_method) - cvs_rsh = env_cvs_ssh ? env_cvs_ssh : SSH_DFLT; - else - cvs_rsh = env_cvs_rsh ? env_cvs_rsh : RSH_DFLT; - - if (!cvs_server) - cvs_server = "cvs"; - - /* Pass the command to rsh as a single string. This shouldn't - affect most rsh servers at all, and will pacify some buggy - versions of rsh that grab switches out of the middle of the - command (they're calling the GNU getopt routines incorrectly). */ - command = xmalloc (strlen (cvs_server) + 8); - - /* If you are running a very old (Nov 3, 1994, before 1.5) - * version of the server, you need to make sure that your .bashrc - * on the server machine does not set CVSROOT to something - * containing a colon (or better yet, upgrade the server). */ - sprintf (command, "%s server", cvs_server); - - { - const char *argv[10]; - const char **p = argv; - - *p++ = cvs_rsh; - - /* If the login names differ between client and server - * pass it on to rsh. - */ - if (root->username != NULL) - { - *p++ = "-l"; - *p++ = root->username; - } - - *p++ = root->hostname; - *p++ = command; - *p++ = NULL; - - if (trace) - { - int i; - - fprintf (stderr, " -> Starting server: "); - for (i = 0; argv[i]; i++) - fprintf (stderr, "%s ", argv[i]); - putc ('\n', stderr); - } - child_pid = piped_child (argv, &tofd, &fromfd, 1); - - if (child_pid < 0) - error (1, errno, "cannot start server via rsh"); - } - free (command); - - make_bufs_from_fds (tofd, fromfd, child_pid, to_server, from_server, 0); -} - -# endif /* START_RSH_WITH_POPEN_RW */ - -#endif /* NO_EXT_METHOD */ - - - -/* Send an argument STRING. */ -void -send_arg (string) - const char *string; -{ - char buf[1]; - const char *p = string; - - send_to_server ("Argument ", 0); - - while (*p) - { - if (*p == '\n') - { - send_to_server ("\012Argumentx ", 0); - } - else - { - buf[0] = *p; - send_to_server (buf, 1); - } - ++p; - } - send_to_server ("\012", 1); -} - - - -static void send_modified PROTO ((const char *, const char *, Vers_TS *)); - -/* VERS->OPTIONS specifies whether the file is binary or not. NOTE: BEFORE - using any other fields of the struct vers, we would need to fix - client_process_import_file to set them up. */ - -static void -send_modified (file, short_pathname, vers) - const char *file; - const char *short_pathname; - Vers_TS *vers; -{ - /* File was modified, send it. */ - struct stat sb; - int fd; - char *buf; - char *mode_string; - size_t bufsize; - int bin; - - if (trace) - (void) fprintf (stderr, " -> Sending file `%s' to server\n", file); - - /* Don't think we can assume fstat exists. */ - if ( CVS_STAT (file, &sb) < 0) - error (1, errno, "reading %s", short_pathname); - - mode_string = mode_to_string (sb.st_mode); - - /* Beware: on systems using CRLF line termination conventions, - the read and write functions will convert CRLF to LF, so the - number of characters read is not the same as sb.st_size. Text - files should always be transmitted using the LF convention, so - we don't want to disable this conversion. */ - bufsize = sb.st_size; - buf = xmalloc (bufsize); - - /* Is the file marked as containing binary data by the "-kb" flag? - If so, make sure to open it in binary mode: */ - - if (vers && vers->options) - bin = !(strcmp (vers->options, "-kb")); - else - bin = 0; - -#ifdef BROKEN_READWRITE_CONVERSION - if (!bin) - { - /* If only stdio, not open/write/etc., do text/binary - conversion, use convert_file which can compensate - (FIXME: we could just use stdio instead which would - avoid the whole problem). */ - char tfile[1024]; strcpy(tfile, file); strcat(tfile, ".CVSBFCTMP"); - convert_file (file, O_RDONLY, - tfile, O_WRONLY | O_CREAT | O_TRUNC | OPEN_BINARY); - fd = CVS_OPEN (tfile, O_RDONLY | OPEN_BINARY); - if (fd < 0) - error (1, errno, "reading %s", short_pathname); - } - else - fd = CVS_OPEN (file, O_RDONLY | OPEN_BINARY); -#else - fd = CVS_OPEN (file, O_RDONLY | (bin ? OPEN_BINARY : 0)); -#endif - - if (fd < 0) - error (1, errno, "reading %s", short_pathname); - - if (file_gzip_level && sb.st_size > 100) - { - size_t newsize = 0; - - if (read_and_gzip (fd, short_pathname, (unsigned char **)&buf, - &bufsize, &newsize, - file_gzip_level)) - error (1, 0, "aborting due to compression error"); - - if (close (fd) < 0) - error (0, errno, "warning: can't close %s", short_pathname); - - { - char tmp[80]; - - send_to_server ("Modified ", 0); - send_to_server (file, 0); - send_to_server ("\012", 1); - send_to_server (mode_string, 0); - send_to_server ("\012z", 2); - sprintf (tmp, "%lu\n", (unsigned long) newsize); - send_to_server (tmp, 0); - - send_to_server (buf, newsize); - } - } - else - { - int newsize; - - { - char *bufp = buf; - int len; - - /* FIXME: This is gross. It assumes that we might read - less than st_size bytes (true on NT), but not more. - Instead of this we should just be reading a block of - data (e.g. 8192 bytes), writing it to the network, and - so on until EOF. */ - while ((len = read (fd, bufp, (buf + sb.st_size) - bufp)) > 0) - bufp += len; - - if (len < 0) - error (1, errno, "reading %s", short_pathname); - - newsize = bufp - buf; - } - if (close (fd) < 0) - error (0, errno, "warning: can't close %s", short_pathname); - - { - char tmp[80]; - - send_to_server ("Modified ", 0); - send_to_server (file, 0); - send_to_server ("\012", 1); - send_to_server (mode_string, 0); - send_to_server ("\012", 1); - sprintf (tmp, "%lu\012", (unsigned long) newsize); - send_to_server (tmp, 0); - } -#ifdef BROKEN_READWRITE_CONVERSION - if (!bin) - { - char tfile[1024]; strcpy(tfile, file); strcat(tfile, ".CVSBFCTMP"); - if (CVS_UNLINK (tfile) < 0) - error (0, errno, "warning: can't remove temp file %s", tfile); - } -#endif - - /* - * Note that this only ends with a newline if the file ended with - * one. - */ - if (newsize > 0) - send_to_server (buf, newsize); - } - free (buf); - free (mode_string); -} - -/* The address of an instance of this structure is passed to - send_fileproc, send_filesdoneproc, and send_direntproc, as the - callerdat parameter. */ - -struct send_data -{ - /* Each of the following flags are zero for clear or nonzero for set. */ - int build_dirs; - int force; - int no_contents; - int backup_modified; -}; - -static int send_fileproc PROTO ((void *callerdat, struct file_info *finfo)); - -/* Deal with one file. */ -static int -send_fileproc (callerdat, finfo) - void *callerdat; - struct file_info *finfo; -{ - struct send_data *args = (struct send_data *) callerdat; - Vers_TS *vers; - struct file_info xfinfo; - /* File name to actually use. Might differ in case from - finfo->file. */ - const char *filename; - - send_a_repository ("", finfo->repository, finfo->update_dir); - - xfinfo = *finfo; - xfinfo.repository = NULL; - xfinfo.rcs = NULL; - vers = Version_TS (&xfinfo, NULL, NULL, NULL, 0, 0); - - if (vers->entdata != NULL) - filename = vers->entdata->user; - else - filename = finfo->file; - - if (vers->vn_user != NULL) - { - /* The Entries request. */ - send_to_server ("Entry /", 0); - send_to_server (filename, 0); - send_to_server ("/", 0); - send_to_server (vers->vn_user, 0); - send_to_server ("/", 0); - if (vers->ts_conflict != NULL) - { - if (vers->ts_user != NULL && - strcmp (vers->ts_conflict, vers->ts_user) == 0) - send_to_server ("+=", 0); - else - send_to_server ("+modified", 0); - } - send_to_server ("/", 0); - send_to_server (vers->entdata != NULL - ? vers->entdata->options - : vers->options, - 0); - send_to_server ("/", 0); - if (vers->entdata != NULL && vers->entdata->tag) - { - send_to_server ("T", 0); - send_to_server (vers->entdata->tag, 0); - } - else if (vers->entdata != NULL && vers->entdata->date) - { - send_to_server ("D", 0); - send_to_server (vers->entdata->date, 0); - } - send_to_server ("\012", 1); - } - else - { - /* It seems a little silly to re-read this on each file, but - send_dirent_proc doesn't get called if filenames are specified - explicitly on the command line. */ - wrap_add_file (CVSDOTWRAPPER, 1); - - if (wrap_name_has (filename, WRAP_RCSOPTION)) - { - /* No "Entry", but the wrappers did give us a kopt so we better - send it with "Kopt". As far as I know this only happens - for "cvs add". Question: is there any reason why checking - for options from wrappers isn't done in Version_TS? - - Note: it might have been better to just remember all the - kopts on the client side, rather than send them to the server, - and have it send us back the same kopts. But that seemed like - a bigger change than I had in mind making now. */ - - if (supported_request ("Kopt")) - { - char *opt; - - send_to_server ("Kopt ", 0); - opt = wrap_rcsoption (filename, 1); - send_to_server (opt, 0); - send_to_server ("\012", 1); - free (opt); - } - else - error (0, 0, - "\ -warning: ignoring -k options due to server limitations"); - } - } - - if (vers->ts_user == NULL) - { - /* - * Do we want to print "file was lost" like normal CVS? - * Would it always be appropriate? - */ - /* File no longer exists. Don't do anything, missing files - just happen. */ - } - else if (vers->ts_rcs == NULL - || args->force - || strcmp (vers->ts_conflict - && supported_request ("Empty-conflicts") - ? vers->ts_conflict : vers->ts_rcs, vers->ts_user) - || (vers->ts_conflict && !strcmp (cvs_cmd_name, "diff")) - || (vers->vn_user && *vers->vn_user == '0')) - { - if (args->no_contents - && supported_request ("Is-modified")) - { - send_to_server ("Is-modified ", 0); - send_to_server (filename, 0); - send_to_server ("\012", 1); - } - 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 - { - send_to_server ("Unchanged ", 0); - send_to_server (filename, 0); - send_to_server ("\012", 1); - } - - /* if this directory has an ignore list, add this file to it */ - if (ignlist) - { - Node *p; - - p = getnode (); - p->type = FILES; - p->key = xstrdup (finfo->file); - (void) addnode (ignlist, p); - } - - freevers_ts (&vers); - return 0; -} - - - -static void send_ignproc PROTO ((const char *, const char *)); - -static void -send_ignproc (file, dir) - const char *file; - const char *dir; -{ - if (ign_inhibit_server || !supported_request ("Questionable")) - { - if (dir[0] != '\0') - (void) printf ("? %s/%s\n", dir, file); - else - (void) printf ("? %s\n", file); - } - else - { - send_to_server ("Questionable ", 0); - send_to_server (file, 0); - send_to_server ("\012", 1); - } -} - - - -static int send_filesdoneproc PROTO ((void *, int, const char *, const char *, - List *)); - -static int -send_filesdoneproc (callerdat, err, repository, update_dir, entries) - void *callerdat; - int err; - const char *repository; - const char *update_dir; - List *entries; -{ - /* if this directory has an ignore list, process it then free it */ - if (ignlist) - { - ignore_files (ignlist, entries, update_dir, send_ignproc); - dellist (&ignlist); - } - - return (err); -} - -static Dtype send_dirent_proc PROTO ((void *, const char *, const char *, - const char *, List *)); - -/* - * send_dirent_proc () is called back by the recursion processor before a - * sub-directory is processed for update. - * A return code of 0 indicates the directory should be - * processed by the recursion code. A return of non-zero indicates the - * recursion code should skip this directory. - * - */ -static Dtype -send_dirent_proc (callerdat, dir, repository, update_dir, entries) - void *callerdat; - const char *dir; - const char *repository; - const char *update_dir; - List *entries; -{ - struct send_data *args = (struct send_data *) callerdat; - int dir_exists; - char *cvsadm_name; - - if (ignore_directory (update_dir)) - { - /* print the warm fuzzy message */ - if (!quiet) - error (0, 0, "Ignoring %s", update_dir); - return (R_SKIP_ALL); - } - - /* - * If the directory does not exist yet (e.g. "cvs update -d foo"), - * no need to send any files from it. If the directory does not - * have a CVS directory, then we pretend that it does not exist. - * Otherwise, we will fail when trying to open the Entries file. - * This case will happen when checking out a module defined as - * ``-a .''. - */ - cvsadm_name = xmalloc (strlen (dir) + sizeof (CVSADM) + 10); - sprintf (cvsadm_name, "%s/%s", dir, CVSADM); - dir_exists = isdir (cvsadm_name); - free (cvsadm_name); - - /* - * 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. - */ - - if (dir_exists) - { - /* - * Get the repository from a CVS/Repository file whenever possible. - * The repository variable is wrong if the names in the local - * directory don't match the names in the repository. - */ - 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 - { - /* It doesn't make sense to send a non-existent directory, - because there is no way to get the correct value for - the repository (I suppose maybe via the expand-modules - request). In the case where the "obvious" choice for - repository is correct, the server can figure out whether - to recreate the directory; in the case where it is wrong - (that is, does not match what modules give us), we might as - well just fail to recreate it. - - Checking for noexec is a kludge for "cvs -n add dir". */ - /* Don't send a non-existent directory unless we are building - new directories (build_dirs is true). Otherwise, CVS may - see a D line in an Entries file, and recreate a directory - which the user removed by hand. */ - if (args->build_dirs && noexec) - send_a_repository (dir, repository, update_dir); - } - - return (dir_exists ? R_PROCESS : R_SKIP_ALL); -} - - - -static int send_dirleave_proc PROTO ((void *, const char *, int, const 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; - const char *dir; - int err; - const 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 an array to the server, one by one. - * argv might be "--foo=bar", "-C", "5", "-y". - */ -void -send_options (int argc, char *const *argv) -{ - int i; - for (i = 0; i < argc; i++) - send_arg (argv[i]); -} - - - -/* Send the names of all the argument files to the server. */ -void -send_file_names (argc, argv, flags) - int argc; - char **argv; - unsigned int flags; -{ - int i; - - /* The fact that we do this here as well as start_recursion is a bit - of a performance hit. Perhaps worth cleaning up someday. */ - if (flags & SEND_EXPAND_WILD) - expand_wild (argc, argv, &argc, &argv); - - for (i = 0; i < argc; ++i) - { - char buf[1]; - char *p; -#ifdef FILENAMES_CASE_INSENSITIVE - char *line = xmalloc (1); - *line = '\0'; -#endif /* FILENAMES_CASE_INSENSITIVE */ - - if (arg_should_not_be_sent_to_server (argv[i])) - continue; - -#ifdef FILENAMES_CASE_INSENSITIVE - /* We want to send the path as it appears in the - CVS/Entries files. We put this inside an ifdef - to avoid doing all these system calls in - cases where fncmp is just strcmp anyway. */ - /* The isdir (CVSADM) check could more gracefully be replaced - with a way of having Entries_Open report back the - error to us and letting us ignore existence_error. - Or some such. */ - { - List *stack; - size_t line_len = 0; - char *q, *r; - struct saved_cwd sdir; - - /* Split the argument onto the stack. */ - stack = getlist(); - r = xstrdup (argv[i]); - /* It's okay to discard the const from the last_component return - * below since we know we passed in an arg that was not const. - */ - while ((q = (char *)last_component (r)) != r) - { - push (stack, xstrdup (q)); - *--q = '\0'; - } - push (stack, r); - - /* Normalize the path into outstr. */ - save_cwd (&sdir); - while (q = pop (stack)) - { - Node *node = NULL; - if (isdir (CVSADM)) - { - List *entries; - - /* Note that if we are adding a directory, - the following will read the entry - that we just wrote there, that is, we - will get the case specified on the - command line, not the case of the - directory in the filesystem. This - is correct behavior. */ - entries = Entries_Open (0, NULL); - node = findnode_fn (entries, q); - if (node != NULL) - { - /* Add the slash unless this is our first element. */ - if (line_len) - xrealloc_and_strcat (&line, &line_len, "/"); - xrealloc_and_strcat (&line, &line_len, node->key); - delnode (node); - } - Entries_Close (entries); - } - - /* If node is still NULL then we either didn't find CVSADM or - * we didn't find an entry there. - */ - if (node == NULL) - { - /* Add the slash unless this is our first element. */ - if (line_len) - xrealloc_and_strcat (&line, &line_len, "/"); - xrealloc_and_strcat (&line, &line_len, q); - break; - } - - /* And descend the tree. */ - if (isdir (q)) - CVS_CHDIR (q); - free (q); - } - restore_cwd (&sdir, NULL); - free_cwd (&sdir); - - /* Now put everything we didn't find entries for back on. */ - while (q = pop (stack)) - { - if (line_len) - xrealloc_and_strcat (&line, &line_len, "/"); - xrealloc_and_strcat (&line, &line_len, q); - free (q); - } - - p = line; - - dellist (&stack); - } -#else /* !FILENAMES_CASE_INSENSITIVE */ - p = argv[i]; -#endif /* FILENAMES_CASE_INSENSITIVE */ - - send_to_server ("Argument ", 0); - - while (*p) - { - if (*p == '\n') - { - send_to_server ("\012Argumentx ", 0); - } - else if (ISDIRSEP (*p)) - { - buf[0] = '/'; - send_to_server (buf, 1); - } - else - { - buf[0] = *p; - send_to_server (buf, 1); - } - ++p; - } - send_to_server ("\012", 1); -#ifdef FILENAMES_CASE_INSENSITIVE - free (line); -#endif /* FILENAMES_CASE_INSENSITIVE */ - } - - if (flags & SEND_EXPAND_WILD) - { - int i; - for (i = 0; i < argc; ++i) - free (argv[i]); - free (argv); - } -} - - - -/* Calculate and send max-dotdot to the server */ -static void -send_max_dotdot (argc, argv) - int argc; - char **argv; -{ - int i; - int level = 0; - int max_level = 0; - - /* Send Max-dotdot if needed. */ - for (i = 0; i < argc; ++i) - { - level = pathname_levels (argv[i]); - if (level > 0) - { - if (uppaths == NULL) uppaths = getlist(); - push_string (uppaths, xstrdup (argv[i])); - } - if (level > max_level) - max_level = level; - } - - if (max_level > 0) - { - if (supported_request ("Max-dotdot")) - { - char buf[10]; - sprintf (buf, "%d", max_level); - - send_to_server ("Max-dotdot ", 0); - send_to_server (buf, 0); - send_to_server ("\012", 1); - } - else - { - error (1, 0, -"backreference in path (`..') not supported by old (pre-Max-dotdot) servers"); - } - } -} - - - -/* Send Repository, Modified and Entry. argc and argv contain only - the files to operate on (or empty for everything), not options. - local is nonzero if we should not recurse (-l option). flags & - SEND_BUILD_DIRS is nonzero if nonexistent directories should be - sent. flags & SEND_FORCE is nonzero if we should send unmodified - files to the server as though they were modified. flags & - SEND_NO_CONTENTS means that this command only needs to know - _whether_ a file is modified, not the contents. Also sends Argument - lines for argc and argv, so should be called after options are sent. */ -void -send_files (argc, argv, local, aflag, flags) - int argc; - char **argv; - int local; - int aflag; - unsigned int flags; -{ - struct send_data args; - int err; - - send_max_dotdot (argc, argv); - - /* - * aflag controls whether the tag/date is copied into the vers_ts. - * But we don't actually use it, so I don't think it matters what we pass - * for aflag here. - */ - 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, send_dirleave_proc, (void *) &args, - argc, argv, local, W_LOCAL, aflag, CVS_LOCK_NONE, (char *) NULL, 0, - (char *) NULL); - if (err) - error_exit (); - if (toplevel_repos == NULL) - /* - * This happens if we are not processing any files, - * or for checkouts in directories without any existing stuff - * checked out. The following assignment is correct for the - * latter case; I don't think toplevel_repos matters for the - * former. - */ - toplevel_repos = xstrdup (current_parsed_root->directory); - send_repository ("", toplevel_repos, "."); -} - -void -client_import_setup (repository) - char *repository; -{ - if (toplevel_repos == NULL) /* should always be true */ - send_a_repository ("", repository, ""); -} - -/* - * Process the argument import file. - */ -int -client_process_import_file (message, vfile, vtag, targc, targv, repository, - all_files_binary, modtime) - char *message; - char *vfile; - char *vtag; - int targc; - char *targv[]; - char *repository; - int all_files_binary; - - /* Nonzero for "import -d". */ - int modtime; -{ - char *update_dir; - char *fullname; - Vers_TS vers; - - assert (toplevel_repos != NULL); - - if (strncmp (repository, toplevel_repos, strlen (toplevel_repos)) != 0) - error (1, 0, - "internal error: pathname `%s' doesn't specify file in `%s'", - repository, toplevel_repos); - - if (strcmp (repository, toplevel_repos) == 0) - { - update_dir = ""; - fullname = xstrdup (vfile); - } - else - { - update_dir = repository + strlen (toplevel_repos) + 1; - - fullname = xmalloc (strlen (vfile) + strlen (update_dir) + 10); - strcpy (fullname, update_dir); - strcat (fullname, "/"); - strcat (fullname, vfile); - } - - send_a_repository ("", repository, update_dir); - if (all_files_binary) - { - vers.options = xmalloc (4); /* strlen("-kb") + 1 */ - strcpy (vers.options, "-kb"); - } - else - { - vers.options = wrap_rcsoption (vfile, 1); - } - if (vers.options != NULL) - { - if (supported_request ("Kopt")) - { - send_to_server ("Kopt ", 0); - send_to_server (vers.options, 0); - send_to_server ("\012", 1); - } - else - error (0, 0, - "warning: ignoring -k options due to server limitations"); - } - if (modtime) - { - if (supported_request ("Checkin-time")) - { - struct stat sb; - char *rcsdate; - char netdate[MAXDATELEN]; - - if (CVS_STAT (vfile, &sb) < 0) - error (1, errno, "cannot stat %s", fullname); - rcsdate = date_from_time_t (sb.st_mtime); - date_to_internet (netdate, rcsdate); - free (rcsdate); - - send_to_server ("Checkin-time ", 0); - send_to_server (netdate, 0); - send_to_server ("\012", 1); - } - else - error (0, 0, - "warning: ignoring -d option due to server limitations"); - } - send_modified (vfile, fullname, &vers); - if (vers.options != NULL) - free (vers.options); - free (fullname); - return 0; -} - -void -client_import_done () -{ - if (toplevel_repos == NULL) - /* - * This happens if we are not processing any files, - * or for checkouts in directories without any existing stuff - * checked out. The following assignment is correct for the - * latter case; I don't think toplevel_repos matters for the - * former. - */ - /* FIXME: "can't happen" now that we call client_import_setup - at the beginning. */ - toplevel_repos = xstrdup (current_parsed_root->directory); - send_repository ("", toplevel_repos, "."); -} - - - -static void -notified_a_file (data, ent_list, short_pathname, filename) - char *data; - List *ent_list; - char *short_pathname; - char *filename; -{ - FILE *fp; - FILE *newf; - size_t line_len = 8192; - char *line = xmalloc (line_len); - char *cp; - int nread; - int nwritten; - char *p; - - fp = open_file (CVSADM_NOTIFY, "r"); - if (getline (&line, &line_len, fp) < 0) - { - if (feof (fp)) - error (0, 0, "cannot read %s: end of file", CVSADM_NOTIFY); - else - error (0, errno, "cannot read %s", CVSADM_NOTIFY); - goto error_exit; - } - cp = strchr (line, '\t'); - if (cp == NULL) - { - error (0, 0, "malformed %s file", CVSADM_NOTIFY); - goto error_exit; - } - *cp = '\0'; - if (strcmp (filename, line + 1) != 0) - { - error (0, 0, "protocol error: notified %s, expected %s", filename, - line + 1); - } - - if (getline (&line, &line_len, fp) < 0) - { - if (feof (fp)) - { - free (line); - if (fclose (fp) < 0) - error (0, errno, "cannot close %s", CVSADM_NOTIFY); - if ( CVS_UNLINK (CVSADM_NOTIFY) < 0) - error (0, errno, "cannot remove %s", CVSADM_NOTIFY); - return; - } - else - { - error (0, errno, "cannot read %s", CVSADM_NOTIFY); - goto error_exit; - } - } - newf = open_file (CVSADM_NOTIFYTMP, "w"); - if (fputs (line, newf) < 0) - { - error (0, errno, "cannot write %s", CVSADM_NOTIFYTMP); - goto error2; - } - while ((nread = fread (line, 1, line_len, fp)) > 0) - { - p = line; - while ((nwritten = fwrite (p, 1, nread, newf)) > 0) - { - nread -= nwritten; - p += nwritten; - } - if (ferror (newf)) - { - error (0, errno, "cannot write %s", CVSADM_NOTIFYTMP); - goto error2; - } - } - if (ferror (fp)) - { - error (0, errno, "cannot read %s", CVSADM_NOTIFY); - goto error2; - } - if (fclose (newf) < 0) - { - error (0, errno, "cannot close %s", CVSADM_NOTIFYTMP); - goto error_exit; - } - free (line); - if (fclose (fp) < 0) - { - error (0, errno, "cannot close %s", CVSADM_NOTIFY); - return; - } - - { - /* In this case, we want rename_file() to ignore noexec. */ - int saved_noexec = noexec; - noexec = 0; - rename_file (CVSADM_NOTIFYTMP, CVSADM_NOTIFY); - noexec = saved_noexec; - } - - return; - error2: - (void) fclose (newf); - error_exit: - free (line); - (void) fclose (fp); -} - -static void -handle_notified (args, len) - char *args; - int len; -{ - call_in_directory (args, notified_a_file, NULL); -} - -void -client_notify (repository, update_dir, filename, notif_type, val) - const char *repository; - const char *update_dir; - const char *filename; - int notif_type; - const char *val; -{ - char buf[2]; - - send_a_repository ("", repository, update_dir); - send_to_server ("Notify ", 0); - send_to_server (filename, 0); - send_to_server ("\012", 1); - buf[0] = notif_type; - buf[1] = '\0'; - send_to_server (buf, 1); - send_to_server ("\t", 1); - send_to_server (val, 0); -} - -/* - * Send an option with an argument, dealing correctly with newlines in - * the argument. If ARG is NULL, forget the whole thing. - */ -void -option_with_arg (option, arg) - char *option; - char *arg; -{ - if (arg == NULL) - return; - - send_to_server ("Argument ", 0); - send_to_server (option, 0); - send_to_server ("\012", 1); - - send_arg (arg); -} - -/* Send a date to the server. The input DATE is in RCS format. - The time will be GMT. - - We then convert that to the format required in the protocol - (including the "-D" option) and send it. According to - cvsclient.texi, RFC 822/1123 format is preferred. */ - -void -client_senddate (date) - const char *date; -{ - char buf[MAXDATELEN]; - - date_to_internet (buf, (char *)date); - option_with_arg ("-D", buf); -} - -void -send_init_command () -{ - /* This is here because we need the current_parsed_root->directory variable. */ - send_to_server ("init ", 0); - send_to_server (current_parsed_root->directory, 0); - send_to_server ("\012", 0); -} - -#endif /* CLIENT_SUPPORT */ diff --git a/contrib/cvs/src/client.h b/contrib/cvs/src/client.h deleted file mode 100644 index 9afa4e7..0000000 --- a/contrib/cvs/src/client.h +++ /dev/null @@ -1,222 +0,0 @@ -/* - * Copyright (C) 1994-2008 The Free Software Foundation, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -/* Interface between the client and the rest of CVS. */ - -/* Stuff shared with the server. */ -extern char *mode_to_string PROTO((mode_t)); -extern int change_mode PROTO((char *, char *, int)); - -extern int gzip_level; -extern int file_gzip_level; - -#if defined (CLIENT_SUPPORT) || defined (SERVER_SUPPORT) - -/* Whether the connection should be encrypted. */ -extern int cvsencrypt; - -/* Whether the connection should use per-packet authentication. */ -extern int cvsauthenticate; - -#ifdef __STDC__ -struct buffer; -#endif - -# ifdef ENCRYPTION - -# ifdef HAVE_KERBEROS - -/* We can't declare the arguments without including krb.h, and I don't - want to do that in every file. */ -extern struct buffer *krb_encrypt_buffer_initialize (); - -# endif /* HAVE_KERBEROS */ - -# ifdef HAVE_GSSAPI - -/* Set this to turn on GSSAPI encryption. */ -extern int cvs_gssapi_encrypt; - -# endif /* HAVE_GSSAPI */ - -# endif /* ENCRYPTION */ - -# ifdef HAVE_GSSAPI - -/* We can't declare the arguments without including gssapi.h, and I - don't want to do that in every file. */ -extern struct buffer *cvs_gssapi_wrap_buffer_initialize (); - -# endif /* HAVE_GSSAPI */ - -#endif /* defined (CLIENT_SUPPORT) || defined (SERVER_SUPPORT) */ - -#ifdef CLIENT_SUPPORT -/* - * Flag variable for seeing whether the server has been started yet. - * As of this writing, only edit.c:cvs_notify_check() uses it. - */ -extern int server_started; - -/* Is the -P option to checkout or update specified? */ -extern int client_prune_dirs; - -# ifdef AUTH_CLIENT_SUPPORT -extern int use_authenticating_server; -# endif /* AUTH_CLIENT_SUPPORT */ -# if defined (AUTH_CLIENT_SUPPORT) || defined (HAVE_GSSAPI) -void connect_to_pserver PROTO ((cvsroot_t *, - struct buffer **, - struct buffer **, - int, int )); -# ifndef CVS_AUTH_PORT -# define CVS_AUTH_PORT 2401 -# endif /* CVS_AUTH_PORT */ -# endif /* (AUTH_CLIENT_SUPPORT) || defined (HAVE_GSSAPI) */ - -# if HAVE_KERBEROS -# ifndef CVS_PORT -# define CVS_PORT 1999 -# endif -# endif /* HAVE_KERBEROS */ - -/* Talking to the server. */ -void send_to_server PROTO((const char *str, size_t len)); -void read_from_server PROTO((char *buf, size_t len)); - -/* Internal functions that handle client communication to server, etc. */ -int supported_request PROTO ((char *)); -void option_with_arg PROTO((char *option, char *arg)); - -/* Get the responses and then close the connection. */ -extern int get_responses_and_close PROTO((void)); - -extern int get_server_responses PROTO((void)); - -/* Start up the connection to the server on the other end. */ -void -start_server PROTO((void)); - -/* Send the names of all the argument files to the server. */ -void -send_file_names PROTO((int argc, char **argv, unsigned int flags)); - -/* Flags for send_file_names. */ -/* Expand wild cards? */ -# define SEND_EXPAND_WILD 1 - -/* - * Send Repository, Modified and Entry. argc and argv contain only - * the files to operate on (or empty for everything), not options. - * local is nonzero if we should not recurse (-l option). - */ -void -send_files PROTO((int argc, char **argv, int local, int aflag, - unsigned int flags)); - -/* Flags for send_files. */ -# 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 -send_arg PROTO((const char *string)); - -/* Send a string of single-char options to the remote server, one by one. */ -void send_options PROTO ((int argc, char * const *argv)); - -extern void send_a_repository PROTO ((const char *, const char *, - const char *)); - -#endif /* CLIENT_SUPPORT */ - -/* - * This structure is used to catalog the responses the client is - * prepared to see from the server. - */ - -struct response -{ - /* Name of the response. */ - char *name; - -#ifdef CLIENT_SUPPORT - /* - * Function to carry out the response. ARGS is the text of the - * command after name and, if present, a single space, have been - * stripped off. The function can scribble into ARGS if it wants. - * Note that although LEN is given, ARGS is also guaranteed to be - * '\0' terminated. - */ - void (*func) PROTO((char *args, int len)); - - /* - * ok and error are special; they indicate we are at the end of the - * responses, and error indicates we should exit with nonzero - * exitstatus. - */ - enum {response_type_normal, response_type_ok, response_type_error} type; -#endif - - /* Used by the server to indicate whether response is supported by - the client, as set by the Valid-responses request. */ - enum { - /* - * Failure to implement this response can imply a fatal - * error. This should be set only for responses which were in the - * original version of the protocol; it should not be set for new - * responses. - */ - rs_essential, - - /* Some clients might not understand this response. */ - rs_optional, - - /* - * Set by the server to one of the following based on what this - * client actually supports. - */ - rs_supported, - rs_not_supported - } status; -}; - -/* Table of responses ending in an entry with a NULL name. */ - -extern struct response responses[]; - -#ifdef CLIENT_SUPPORT - -extern void client_senddate PROTO((const char *date)); -extern void client_expand_modules PROTO((int argc, char **argv, int local)); -extern void client_send_expansions PROTO((int local, char *where, - int build_dirs)); -extern void client_nonexpanded_setup PROTO((void)); - -extern void send_init_command PROTO ((void)); - -extern char **failed_patches; -extern int failed_patches_count; -extern char *toplevel_wd; -extern void client_import_setup PROTO((char *repository)); -extern int client_process_import_file - PROTO((char *message, char *vfile, char *vtag, - int targc, char *targv[], char *repository, int all_files_binary, - int modtime)); -extern void client_import_done PROTO((void)); -extern void client_notify PROTO((const char *, const char *, const char *, int, - const char *)); -#endif /* CLIENT_SUPPORT */ diff --git a/contrib/cvs/src/commit.c b/contrib/cvs/src/commit.c deleted file mode 100644 index b3ba47b..0000000 --- a/contrib/cvs/src/commit.c +++ /dev/null @@ -1,2433 +0,0 @@ -/* - * Copyright (C) 1986-2005 The Free Software Foundation, Inc. - * - * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot , - * and others. - * - * Portions Copyright (C) 1992, Brian Berliner and Jeff Polk - * Portions Copyright (C) 1989-1992, Brian Berliner - * - * You may distribute under the terms of the GNU General Public License as - * specified in the README file that comes with the CVS source distribution. - * - * Commit Files - * - * "commit" commits the present version to the RCS repository, AFTER - * having done a test on conflicts. - * - * The call is: cvs commit [options] files... - * - * $FreeBSD$ - */ - -#include -#include "cvs.h" -#include "getline.h" -#include "edit.h" -#include "fileattr.h" -#include "hardlink.h" - -static Dtype check_direntproc PROTO ((void *callerdat, const char *dir, - const char *repos, - const char *update_dir, - List *entries)); -static int check_fileproc PROTO ((void *callerdat, struct file_info *finfo)); -static int check_filesdoneproc PROTO ((void *callerdat, int err, - const char *repos, - const char *update_dir, - List *entries)); -static int checkaddfile PROTO((const char *file, const char *repository, - const char *tag, const char *options, - RCSNode **rcsnode)); -static Dtype commit_direntproc PROTO ((void *callerdat, const char *dir, - const char *repos, - const char *update_dir, - List *entries)); -static int commit_dirleaveproc PROTO ((void *callerdat, const char *dir, - int err, const char *update_dir, - List *entries)); -static int commit_fileproc PROTO ((void *callerdat, struct file_info *finfo)); -static int commit_filesdoneproc PROTO ((void *callerdat, int err, - const char *repository, - const char *update_dir, - List *entries)); -static int finaladd PROTO((struct file_info *finfo, char *revision, char *tag, - char *options)); -static int findmaxrev PROTO((Node * p, void *closure)); -static int lock_RCS PROTO((const char *user, RCSNode *rcs, const char *rev, - const char *repository)); -static int precommit_list_proc PROTO((Node * p, void *closure)); -static int precommit_proc PROTO((const char *repository, const char *filter)); -static int remove_file PROTO ((struct file_info *finfo, char *tag, - char *message)); -static void fixaddfile PROTO((const char *rcs)); -static void fixbranch PROTO((RCSNode *, char *branch)); -static void unlockrcs PROTO((RCSNode *rcs)); -static void ci_delproc PROTO((Node *p)); -static void masterlist_delproc PROTO((Node *p)); - -struct commit_info -{ - Ctype status; /* as returned from Classify_File() */ - char *rev; /* a numeric rev, if we know it */ - char *tag; /* any sticky tag, or -r option */ - char *options; /* Any sticky -k option */ -}; -struct master_lists -{ - List *ulist; /* list for Update_Logfile */ - List *cilist; /* list with commit_info structs */ -}; - -static int force_ci = 0; -static int got_message; -static int aflag; -static char *saved_tag; -static char *write_dirtag; -static int write_dirnonbranch; -static char *logfile; -static List *mulist; -static List *saved_ulist; -static char *saved_message; -static time_t last_register_time; - -static const char *const commit_usage[] = -{ - "Usage: %s %s [-Rlf] [-m msg | -F logfile] [-r rev] files...\n", - " -R Process directories recursively.\n", - " -l Local directory only (not recursive).\n", - " -f Force the file to be committed; disables recursion.\n", - " -F logfile Read the log message from file.\n", - " -m msg Log message.\n", - " -r rev Commit to this branch or trunk revision.\n", - "(Specify the --help global option for a list of other help options)\n", - NULL -}; - -#ifdef CLIENT_SUPPORT -/* Identify a file which needs "? foo" or a Questionable request. */ -struct question { - /* The two fields for the Directory request. */ - char *dir; - char *repos; - - /* The file name. */ - char *file; - - struct question *next; -}; - -struct find_data { - List *ulist; - int argc; - char **argv; - - /* This is used from dirent to filesdone time, for each directory, - to make a list of files we have already seen. */ - List *ignlist; - - /* Linked list of files which need "? foo" or a Questionable request. */ - struct question *questionables; - - /* Only good within functions called from the filesdoneproc. Stores - the repository (pointer into storage managed by the recursion - processor. */ - const char *repository; - - /* Non-zero if we should force the commit. This is enabled by - either -f or -r options, unlike force_ci which is just -f. */ - int force; -}; - - - -static Dtype find_dirent_proc PROTO ((void *callerdat, const char *dir, - const char *repository, - const char *update_dir, - List *entries)); - -static Dtype -find_dirent_proc (callerdat, dir, repository, update_dir, entries) - void *callerdat; - const char *dir; - const char *repository; - const char *update_dir; - List *entries; -{ - struct find_data *find_data = (struct find_data *)callerdat; - - /* This check seems to slowly be creeping throughout CVS (update - and send_dirent_proc by CVS 1.5, diff in 31 Oct 1995. My guess - is that it (or some variant thereof) should go in all the - dirent procs. Unless someone has some better idea... */ - if (!isdir (dir)) - return R_SKIP_ALL; - - /* initialize the ignore list for this directory */ - find_data->ignlist = getlist (); - - /* Print the same warm fuzzy as in check_direntproc, since that - code will never be run during client/server operation and we - want the messages to match. */ - if (!quiet) - error (0, 0, "Examining %s", update_dir); - - return R_PROCESS; -} - - - -/* Here as a static until we get around to fixing ignore_files to pass - it along as an argument. */ -static struct find_data *find_data_static; - - - -static void find_ignproc PROTO ((const char *, const char *)); - -static void -find_ignproc (file, dir) - const char *file; - const char *dir; -{ - struct question *p; - - p = (struct question *) xmalloc (sizeof (struct question)); - p->dir = xstrdup (dir); - p->repos = xstrdup (find_data_static->repository); - p->file = xstrdup (file); - p->next = find_data_static->questionables; - find_data_static->questionables = p; -} - - - -static int find_filesdoneproc PROTO ((void *callerdat, int err, - const char *repository, - const char *update_dir, - List *entries)); - -static int -find_filesdoneproc (callerdat, err, repository, update_dir, entries) - void *callerdat; - int err; - const char *repository; - const char *update_dir; - List *entries; -{ - struct find_data *find_data = (struct find_data *)callerdat; - find_data->repository = repository; - - /* if this directory has an ignore list, process it then free it */ - if (find_data->ignlist) - { - find_data_static = find_data; - ignore_files (find_data->ignlist, entries, update_dir, find_ignproc); - dellist (&find_data->ignlist); - } - - find_data->repository = NULL; - - return err; -} - - - -static int find_fileproc PROTO ((void *callerdat, struct file_info *finfo)); - -/* Machinery to find out what is modified, added, and removed. It is - possible this should be broken out into a new client_classify function; - merging it with classify_file is almost sure to be a mess, though, - because classify_file has all kinds of repository processing. */ -static int -find_fileproc (callerdat, finfo) - void *callerdat; - struct file_info *finfo; -{ - Vers_TS *vers; - enum classify_type status; - Node *node; - struct find_data *args = (struct find_data *)callerdat; - struct logfile_info *data; - struct file_info xfinfo; - - /* if this directory has an ignore list, add this file to it */ - if (args->ignlist) - { - Node *p; - - p = getnode (); - p->type = FILES; - p->key = xstrdup (finfo->file); - if (addnode (args->ignlist, p) != 0) - freenode (p); - } - - xfinfo = *finfo; - xfinfo.repository = NULL; - xfinfo.rcs = NULL; - - vers = Version_TS (&xfinfo, NULL, saved_tag, NULL, 0, 0); - if (vers->vn_user == NULL) - { - if (vers->ts_user == NULL) - error (0, 0, "nothing known about `%s'", finfo->fullname); - else - error (0, 0, "use `%s add' to create an entry for %s", - program_name, finfo->fullname); - freevers_ts (&vers); - return 1; - } - if (vers->vn_user[0] == '-') - { - if (vers->ts_user != NULL) - { - error (0, 0, - "`%s' should be removed and is still there (or is back" - " again)", finfo->fullname); - freevers_ts (&vers); - return 1; - } - /* else */ - status = T_REMOVED; - } - else if (strcmp (vers->vn_user, "0") == 0) - { - if (vers->ts_user == NULL) - { - /* This happens when one has `cvs add'ed a file, but it no - longer exists in the working directory at commit time. - FIXME: What classify_file does in this case is print - "new-born %s has disappeared" and removes the entry. - We probably should do the same. */ - if (!really_quiet) - error (0, 0, "warning: new-born %s has disappeared", - finfo->fullname); - status = T_REMOVE_ENTRY; - } - else - status = T_ADDED; - } - else if (vers->ts_user == NULL) - { - /* FIXME: What classify_file does in this case is print - "%s was lost". We probably should do the same. */ - freevers_ts (&vers); - return 0; - } - else if (vers->ts_rcs != NULL - && (args->force || strcmp (vers->ts_user, vers->ts_rcs) != 0)) - /* If we are forcing commits, pretend that the file is - modified. */ - status = T_MODIFIED; - else - { - /* This covers unmodified files, as well as a variety of other - 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; - } - - node = getnode (); - node->key = xstrdup (finfo->fullname); - - data = (struct logfile_info *) xmalloc (sizeof (struct logfile_info)); - data->type = status; - data->tag = xstrdup (vers->tag); - data->rev_old = data->rev_new = NULL; - - node->type = UPDATE; - node->delproc = update_delproc; - node->data = data; - (void)addnode (args->ulist, node); - - ++args->argc; - - freevers_ts (&vers); - return 0; -} - - - -static int copy_ulist PROTO ((Node *, void *)); - -static int -copy_ulist (node, data) - Node *node; - void *data; -{ - struct find_data *args = (struct find_data *)data; - args->argv[args->argc++] = node->key; - return 0; -} -#endif /* CLIENT_SUPPORT */ - -#ifdef SERVER_SUPPORT -# define COMMIT_OPTIONS "+nlRm:fF:r:" -#else /* !SERVER_SUPPORT */ -# define COMMIT_OPTIONS "+lRm:fF:r:" -#endif /* SERVER_SUPPORT */ -int -commit (argc, argv) - int argc; - char **argv; -{ - int c; - int err = 0; - int local = 0; - - if (argc == -1) - usage (commit_usage); - -#ifdef CVS_BADROOT - /* - * For log purposes, do not allow "root" to commit files. If you look - * like root, but are really logged in as a non-root user, it's OK. - */ - /* FIXME: Shouldn't this check be much more closely related to the - readonly user stuff (CVSROOT/readers, &c). That is, why should - root be able to "cvs init", "cvs import", &c, but not "cvs ci"? */ - /* Who we are on the client side doesn't affect logging. */ - if (geteuid () == (uid_t) 0 && !current_parsed_root->isremote) - { - struct passwd *pw; - - if ((pw = (struct passwd *) getpwnam (getcaller ())) == NULL) - error (1, 0, - "your apparent username (%s) is unknown to this system", - getcaller ()); - if (pw->pw_uid == (uid_t) 0) - error (1, 0, "'root' is not allowed to commit files"); - } -#endif /* CVS_BADROOT */ - - optind = 0; - while ((c = getopt (argc, argv, COMMIT_OPTIONS)) != -1) - { - switch (c) - { -#ifdef SERVER_SUPPORT - case 'n': - /* Silently ignore -n for compatibility with old - * clients. - */ - if (!server_active) error(0, 0, "the `-n' option is obsolete"); - break; -#endif /* SERVER_SUPPORT */ - case 'm': -#ifdef FORCE_USE_EDITOR - use_editor = 1; -#else - use_editor = 0; -#endif - if (saved_message) - { - free (saved_message); - saved_message = NULL; - } - - saved_message = xstrdup(optarg); - break; - case 'r': - if (saved_tag) - free (saved_tag); - saved_tag = xstrdup (optarg); - break; - case 'l': - local = 1; - break; - case 'R': - local = 0; - break; - case 'f': - force_ci = 1; - local = 1; /* also disable recursion */ - break; - case 'F': -#ifdef FORCE_USE_EDITOR - use_editor = 1; -#else - use_editor = 0; -#endif - logfile = optarg; - break; - case '?': - default: - usage (commit_usage); - break; - } - } - argc -= optind; - argv += optind; - - /* numeric specified revision means we ignore sticky tags... */ - if (saved_tag && isdigit ((unsigned char) *saved_tag)) - { - char *p = saved_tag + strlen (saved_tag); - aflag = 1; - /* strip trailing dots and leading zeros */ - while (*--p == '.') ; - p[1] = '\0'; - while (saved_tag[0] == '0' && isdigit ((unsigned char) saved_tag[1])) - ++saved_tag; - } - - /* some checks related to the "-F logfile" option */ - if (logfile) - { - size_t size = 0, len; - - if (saved_message) - error (1, 0, "cannot specify both a message and a log file"); - - get_file (logfile, logfile, "r", &saved_message, &size, &len); - } - -#ifdef CLIENT_SUPPORT - if (current_parsed_root->isremote) - { - struct find_data find_args; - - ign_setup (); - - find_args.ulist = getlist (); - find_args.argc = 0; - find_args.questionables = NULL; - find_args.ignlist = NULL; - find_args.repository = NULL; - - /* It is possible that only a numeric tag should set this. - I haven't really thought about it much. - Anyway, I suspect that setting it unnecessarily only causes - a little unneeded network traffic. */ - find_args.force = force_ci || saved_tag != NULL; - - err = start_recursion (find_fileproc, find_filesdoneproc, - find_dirent_proc, (DIRLEAVEPROC) NULL, - (void *)&find_args, - argc, argv, local, W_LOCAL, 0, CVS_LOCK_NONE, - (char *) NULL, 0, (char *) NULL); - if (err) - error (1, 0, "correct above errors first!"); - - if (find_args.argc == 0) - { - /* Nothing to commit. Exit now without contacting the - server (note that this means that we won't print "? - foo" for files which merit it, because we don't know - what is in the CVSROOT/cvsignore file). */ - 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. - This saves time--we don't want to search the file system - of the working directory twice. */ - if (size_overflow_p (xtimes (find_args.argc, sizeof (char **)))) - { - find_args.argc = 0; - return 0; - } - find_args.argv = xmalloc (xtimes (find_args.argc, sizeof (char **))); - find_args.argc = 0; - walklist (find_args.ulist, copy_ulist, &find_args); - - /* Do this before calling do_editor; don't ask for a log - message if we can't talk to the server. But do it after we - have made the checks that we can locally (to more quickly - catch syntax errors, the case where no files are modified, - added or removed, etc.). - - On the other hand, calling start_server before do_editor - means that we chew up server resources the whole time that - the user has the editor open (hours or days if the user - forgets about it), which seems dubious. */ - start_server (); - - /* - * We do this once, not once for each directory as in normal CVS. - * The protocol is designed this way. This is a feature. - */ - if (use_editor) - do_editor (".", &saved_message, (char *)NULL, find_args.ulist); - - /* We always send some sort of message, even if empty. */ - option_with_arg ("-m", saved_message ? saved_message : ""); - - /* OK, now process all the questionable files we have been saving - up. */ - { - struct question *p; - struct question *q; - - p = find_args.questionables; - while (p != NULL) - { - if (ign_inhibit_server || !supported_request ("Questionable")) - { - cvs_output ("? ", 2); - if (p->dir[0] != '\0') - { - cvs_output (p->dir, 0); - cvs_output ("/", 1); - } - cvs_output (p->file, 0); - cvs_output ("\n", 1); - } - else - { - send_to_server ("Directory ", 0); - send_to_server (p->dir[0] == '\0' ? "." : p->dir, 0); - send_to_server ("\012", 1); - send_to_server (p->repos, 0); - send_to_server ("\012", 1); - - send_to_server ("Questionable ", 0); - send_to_server (p->file, 0); - send_to_server ("\012", 1); - } - free (p->dir); - free (p->repos); - free (p->file); - q = p->next; - free (p); - p = q; - } - } - - if (local) - send_arg("-l"); - if (force_ci) - send_arg("-f"); - option_with_arg ("-r", saved_tag); - send_arg ("--"); - - /* FIXME: This whole find_args.force/SEND_FORCE business is a - kludge. It would seem to be a server bug that we have to - say that files are modified when they are not. This makes - "cvs commit -r 2" across a whole bunch of files a very slow - operation (and it isn't documented in cvsclient.texi). I - haven't looked at the server code carefully enough to be - _sure_ why this is needed, but if it is because the "ci" - program, which we used to call, wanted the file to exist, - then it would be relatively simple to fix in the server. */ - send_files (find_args.argc, find_args.argv, local, 0, - find_args.force ? SEND_FORCE : 0); - - /* Sending only the names of the files which were modified, added, - or removed means that the server will only do an up-to-date - check on those files. This is different from local CVS and - 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 (); - if (err != 0 && use_editor && saved_message != NULL) - { - /* If there was an error, don't nuke the user's carefully - constructed prose. This is something of a kludge; a better - solution is probably more along the lines of #150 in TODO - (doing a second up-to-date check before accepting the - log message has also been suggested, but that seems kind of - iffy because the real up-to-date check could still fail, - another error could occur, &c. Also, a second check would - slow things down). */ - - char *fname; - FILE *fp; - - fp = cvs_temp_file (&fname); - if (fp == NULL) - error (1, 0, "cannot create temporary file %s", - fname ? fname : "(null)"); - if (fwrite (saved_message, 1, strlen (saved_message), fp) - != strlen (saved_message)) - error (1, errno, "cannot write temporary file %s", fname); - if (fclose (fp) < 0) - error (0, errno, "cannot close temporary file %s", fname); - error (0, 0, "saving log message in %s", fname); - free (fname); - } - return err; - } -#endif - - if (saved_tag != NULL) - tag_check_valid (saved_tag, argc, argv, local, aflag, ""); - - /* XXX - this is not the perfect check for this */ - if (argc <= 0) - write_dirtag = saved_tag; - - wrap_setup (); - - lock_tree_for_write (argc, argv, local, W_LOCAL, aflag); - - /* - * Set up the master update list and hard link list - */ - mulist = getlist (); - -#ifdef PRESERVE_PERMISSIONS_SUPPORT - if (preserve_perms) - { - hardlist = getlist (); - - /* - * We need to save the working directory so that - * check_fileproc can construct a full pathname for each file. - */ - working_dir = xgetwd(); - } -#endif - - /* - * Run the recursion processor to verify the files are all up-to-date - */ - err = start_recursion (check_fileproc, check_filesdoneproc, - check_direntproc, (DIRLEAVEPROC) NULL, NULL, argc, - argv, local, W_LOCAL, aflag, CVS_LOCK_NONE, - (char *) NULL, 1, (char *) NULL); - if (err) - { - Lock_Cleanup (); - error (1, 0, "correct above errors first!"); - } - - /* - * Run the recursion processor to commit the files - */ - write_dirnonbranch = 0; - if (noexec == 0) - err = start_recursion (commit_fileproc, commit_filesdoneproc, - commit_direntproc, commit_dirleaveproc, NULL, - argc, argv, local, W_LOCAL, aflag, CVS_LOCK_NONE, - (char *) NULL, 1, (char *) NULL); - - /* - * Unlock all the dirs and clean up - */ - Lock_Cleanup (); - dellist (&mulist); - - if (server_active) - return err; - - /* see if we need to sleep before returning to avoid time-stamp races */ - if (last_register_time) - { - sleep_past (last_register_time); - } - - return err; -} - - - -/* This routine determines the status of a given file and retrieves - the version information that is associated with that file. */ - -static -Ctype -classify_file_internal (finfo, vers) - struct file_info *finfo; - Vers_TS **vers; -{ - int save_noexec, save_quiet, save_really_quiet; - Ctype status; - - /* FIXME: Do we need to save quiet as well as really_quiet? Last - time I glanced at Classify_File I only saw it looking at really_quiet - not quiet. */ - save_noexec = noexec; - save_quiet = quiet; - save_really_quiet = really_quiet; - noexec = quiet = really_quiet = 1; - - /* handle specified numeric revision specially */ - if (saved_tag && isdigit ((unsigned char) *saved_tag)) - { - /* If the tag is for the trunk, make sure we're at the head */ - if (numdots (saved_tag) < 2) - { - status = Classify_File (finfo, (char *) NULL, (char *) NULL, - (char *) NULL, 1, aflag, vers, 0); - if (status == T_UPTODATE || status == T_MODIFIED || - status == T_ADDED) - { - Ctype xstatus; - - freevers_ts (vers); - xstatus = Classify_File (finfo, saved_tag, (char *) NULL, - (char *) NULL, 1, aflag, vers, 0); - if (xstatus == T_REMOVE_ENTRY) - status = T_MODIFIED; - else if (status == T_MODIFIED && xstatus == T_CONFLICT) - status = T_MODIFIED; - else - status = xstatus; - } - } - else - { - char *xtag, *cp; - - /* - * The revision is off the main trunk; make sure we're - * up-to-date with the head of the specified branch. - */ - xtag = xstrdup (saved_tag); - if ((numdots (xtag) & 1) != 0) - { - cp = strrchr (xtag, '.'); - *cp = '\0'; - } - status = Classify_File (finfo, xtag, (char *) NULL, - (char *) NULL, 1, aflag, vers, 0); - if ((status == T_REMOVE_ENTRY || status == T_CONFLICT) - && (cp = strrchr (xtag, '.')) != NULL) - { - /* pluck one more dot off the revision */ - *cp = '\0'; - freevers_ts (vers); - status = Classify_File (finfo, xtag, (char *) NULL, - (char *) NULL, 1, aflag, vers, 0); - if (status == T_UPTODATE || status == T_REMOVE_ENTRY) - status = T_MODIFIED; - } - /* now, muck with vers to make the tag correct */ - free ((*vers)->tag); - (*vers)->tag = xstrdup (saved_tag); - free (xtag); - } - } - else - status = Classify_File (finfo, saved_tag, (char *) NULL, (char *) NULL, - 1, 0, vers, 0); - noexec = save_noexec; - quiet = save_quiet; - really_quiet = save_really_quiet; - - return status; -} - - - -/* - * Check to see if a file is ok to commit and make sure all files are - * up-to-date - */ -/* ARGSUSED */ -static int -check_fileproc (callerdat, finfo) - void *callerdat; - struct file_info *finfo; -{ - Ctype status; - const char *xdir; - Node *p; - List *ulist, *cilist; - Vers_TS *vers; - struct commit_info *ci; - struct logfile_info *li; - - size_t cvsroot_len = strlen (current_parsed_root->directory); - - if (!finfo->repository) - { - error (0, 0, "nothing known about `%s'", finfo->fullname); - return 1; - } - - if (strncmp (finfo->repository, current_parsed_root->directory, - cvsroot_len) == 0 - && ISDIRSEP (finfo->repository[cvsroot_len]) - && strncmp (finfo->repository + cvsroot_len + 1, - CVSROOTADM, - sizeof (CVSROOTADM) - 1) == 0 - && ISDIRSEP (finfo->repository[cvsroot_len + sizeof (CVSROOTADM)]) - && strcmp (finfo->repository + cvsroot_len + sizeof (CVSROOTADM) + 1, - CVSNULLREPOS) == 0 - ) - error (1, 0, "cannot check in to %s", finfo->repository); - - status = classify_file_internal (finfo, &vers); - - /* - * If the force-commit option is enabled, and the file in question - * appears to be up-to-date, just make it look modified so that - * it will be committed. - */ - if (force_ci && status == T_UPTODATE) - status = T_MODIFIED; - - switch (status) - { - case T_CHECKOUT: - case T_PATCH: - case T_NEEDS_MERGE: - case T_REMOVE_ENTRY: - error (0, 0, "Up-to-date check failed for `%s'", finfo->fullname); - freevers_ts (&vers); - return 1; - case T_CONFLICT: - case T_MODIFIED: - case T_ADDED: - case T_REMOVED: - /* - * some quick sanity checks; if no numeric -r option specified: - * - can't have a sticky date - * - can't have a sticky tag that is not a branch - * Also, - * - if status is T_REMOVED, file must not exist and its entry - * can't have a numeric sticky tag. - * - if status is T_ADDED, rcs file must not exist unless on - * a branch or head is dead - * - if status is T_ADDED, can't have a non-trunk numeric rev - * - if status is T_MODIFIED and a Conflict marker exists, don't - * allow the commit if timestamp is identical or if we find - * an RCS_MERGE_PAT in the file. - */ - if (!saved_tag || !isdigit ((unsigned char) *saved_tag)) - { - if (vers->date) - { - error (0, 0, - "cannot commit with sticky date for file `%s'", - finfo->fullname); - freevers_ts (&vers); - return 1; - } - if (status == T_MODIFIED && vers->tag && - !RCS_isbranch (finfo->rcs, vers->tag)) - { - error (0, 0, - "sticky tag `%s' for file `%s' is not a branch", - vers->tag, finfo->fullname); - freevers_ts (&vers); - return 1; - } - } - if (status == T_CONFLICT && !force_ci) - { - error (0, 0, - "file `%s' had a conflict and has not been modified", - finfo->fullname); - freevers_ts (&vers); - return 1; - } - if (status == T_MODIFIED && !force_ci && file_has_markers (finfo)) - { - /* Make this a warning, not an error, because we have - no way of knowing whether the "conflict indicators" - are really from a conflict or whether they are part - of the document itself (cvs.texinfo and sanity.sh in - CVS itself, for example, tend to want to have strings - like ">>>>>>>" at the start of a line). Making people - kludge this the way they need to kludge keyword - expansion seems undesirable. And it is worse than - keyword expansion, because there is no -ko - analogue. */ - error (0, 0, - "\ -warning: file `%s' seems to still contain conflict indicators", - finfo->fullname); - } - - if (status == T_REMOVED) - { - if (vers->ts_user != NULL) - { - error (0, 0, - "`%s' should be removed and is still there (or is" - " back again)", finfo->fullname); - freevers_ts (&vers); - return 1; - } - - if (vers->tag && isdigit ((unsigned char) *vers->tag)) - { - /* Remove also tries to forbid this, but we should check - here. I'm only _sure_ about somewhat obscure cases - (hacking the Entries file, using an old version of - CVS for the remove and a new one for the commit), but - there might be other cases. */ - error (0, 0, - "cannot remove file `%s' which has a numeric sticky" - " tag of `%s'", finfo->fullname, vers->tag); - freevers_ts (&vers); - return 1; - } - } - if (status == T_ADDED) - { - if (vers->tag == NULL) - { - if (finfo->rcs != NULL && - !RCS_isdead (finfo->rcs, finfo->rcs->head)) - { - error (0, 0, - "cannot add file `%s' when RCS file `%s' already exists", - finfo->fullname, finfo->rcs->path); - freevers_ts (&vers); - return 1; - } - } - else if (isdigit ((unsigned char) *vers->tag) && - numdots (vers->tag) > 1) - { - error (0, 0, - "cannot add file `%s' with revision `%s'; must be on trunk", - finfo->fullname, vers->tag); - freevers_ts (&vers); - return 1; - } - } - - /* done with consistency checks; now, to get on with the commit */ - if (finfo->update_dir[0] == '\0') - xdir = "."; - else - xdir = finfo->update_dir; - if ((p = findnode (mulist, xdir)) != NULL) - { - ulist = ((struct master_lists *) p->data)->ulist; - cilist = ((struct master_lists *) p->data)->cilist; - } - else - { - struct master_lists *ml; - - ulist = getlist (); - cilist = getlist (); - p = getnode (); - p->key = xstrdup (xdir); - p->type = UPDATE; - ml = (struct master_lists *) - xmalloc (sizeof (struct master_lists)); - ml->ulist = ulist; - ml->cilist = cilist; - p->data = ml; - p->delproc = masterlist_delproc; - (void) addnode (mulist, p); - } - - /* first do ulist, then cilist */ - p = getnode (); - p->key = xstrdup (finfo->file); - p->type = UPDATE; - p->delproc = update_delproc; - li = ((struct logfile_info *) - xmalloc (sizeof (struct logfile_info))); - li->type = status; - li->tag = xstrdup (vers->tag); - li->rev_old = xstrdup (vers->vn_rcs); - li->rev_new = NULL; - p->data = li; - (void) addnode (ulist, p); - - p = getnode (); - p->key = xstrdup (finfo->file); - p->type = UPDATE; - p->delproc = ci_delproc; - ci = (struct commit_info *) xmalloc (sizeof (struct commit_info)); - ci->status = status; - if (vers->tag) - if (isdigit ((unsigned char) *vers->tag)) - ci->rev = xstrdup (vers->tag); - else - ci->rev = RCS_whatbranch (finfo->rcs, vers->tag); - else - ci->rev = (char *) NULL; - ci->tag = xstrdup (vers->tag); - ci->options = xstrdup(vers->options); - p->data = ci; - (void) addnode (cilist, p); - -#ifdef PRESERVE_PERMISSIONS_SUPPORT - if (preserve_perms) - { - /* Add this file to hardlist, indexed on its inode. When - we are done, we can find out what files are hardlinked - to a given file by looking up its inode in hardlist. */ - char *fullpath; - Node *linkp; - struct hardlink_info *hlinfo; - - /* Get the full pathname of the current file. */ - fullpath = xmalloc (strlen(working_dir) + - strlen(finfo->fullname) + 2); - sprintf (fullpath, "%s/%s", working_dir, finfo->fullname); - - /* To permit following links in subdirectories, files - are keyed on finfo->fullname, not on finfo->name. */ - linkp = lookup_file_by_inode (fullpath); - - /* If linkp is NULL, the file doesn't exist... maybe - we're doing a remove operation? */ - if (linkp != NULL) - { - /* Create a new hardlink_info node, which will record - the current file's status and the links listed in its - `hardlinks' delta field. We will append this - hardlink_info node to the appropriate hardlist entry. */ - hlinfo = (struct hardlink_info *) - xmalloc (sizeof (struct hardlink_info)); - hlinfo->status = status; - linkp->data = hlinfo; - } - } -#endif - - break; - case T_UNKNOWN: - error (0, 0, "nothing known about `%s'", finfo->fullname); - freevers_ts (&vers); - return 1; - case T_UPTODATE: - break; - default: - error (0, 0, "CVS internal error: unknown status %d", status); - break; - } - - freevers_ts (&vers); - return 0; -} - - - -/* - * By default, return the code that tells do_recursion to examine all - * directories - */ -/* ARGSUSED */ -static Dtype -check_direntproc (callerdat, dir, repos, update_dir, entries) - void *callerdat; - const char *dir; - const char *repos; - const char *update_dir; - List *entries; -{ - if (!isdir (dir)) - return R_SKIP_ALL; - - if (!quiet) - error (0, 0, "Examining %s", update_dir); - - return R_PROCESS; -} - - - -/* - * Walklist proc to run pre-commit checks - */ -static int -precommit_list_proc (p, closure) - Node *p; - void *closure; -{ - struct logfile_info *li = p->data; - if (li->type == T_ADDED - || li->type == T_MODIFIED - || li->type == T_REMOVED) - { - run_arg (p->key); - } - return 0; -} - - - -/* - * Callback proc for pre-commit checking - */ -static int -precommit_proc (repository, filter) - const char *repository; - const char *filter; -{ - /* see if the filter is there, only if it's a full path */ - if (isabsolute (filter)) - { - char *s, *cp; - - s = xstrdup (filter); - for (cp = s; *cp; cp++) - if (isspace ((unsigned char) *cp)) - { - *cp = '\0'; - break; - } - if (!isfile (s)) - { - error (0, errno, "cannot find pre-commit filter `%s'", s); - free (s); - return 1; /* so it fails! */ - } - free (s); - } - - run_setup (filter); - run_arg (repository); - (void) walklist (saved_ulist, precommit_list_proc, NULL); - return run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL|RUN_REALLY); -} - - - -/* - * Run the pre-commit checks for the dir - */ -/* ARGSUSED */ -static int -check_filesdoneproc (callerdat, err, repos, update_dir, entries) - void *callerdat; - int err; - const char *repos; - const char *update_dir; - List *entries; -{ - int n; - Node *p; - - /* find the update list for this dir */ - p = findnode (mulist, update_dir); - if (p != NULL) - saved_ulist = ((struct master_lists *) p->data)->ulist; - else - saved_ulist = (List *) NULL; - - /* skip the checks if there's nothing to do */ - if (saved_ulist == NULL || saved_ulist->list->next == saved_ulist->list) - return err; - - /* run any pre-commit checks */ - if ((n = Parse_Info (CVSROOTADM_COMMITINFO, repos, precommit_proc, 1)) > 0) - { - error (0, 0, "Pre-commit check failed"); - err += n; - } - - return err; -} - - - -/* - * Do the work of committing a file - */ -static int maxrev; -static char *sbranch; - -/* ARGSUSED */ -static int -commit_fileproc (callerdat, finfo) - void *callerdat; - struct file_info *finfo; -{ - Node *p; - int err = 0; - List *ulist, *cilist; - struct commit_info *ci; - - /* Keep track of whether write_dirtag is a branch tag. - Note that if it is a branch tag in some files and a nonbranch tag - in others, treat it as a nonbranch tag. It is possible that case - should elicit a warning or an error. */ - if (write_dirtag != NULL - && finfo->rcs != NULL) - { - char *rev = RCS_getversion (finfo->rcs, write_dirtag, NULL, 1, NULL); - if (rev != NULL - && !RCS_nodeisbranch (finfo->rcs, write_dirtag)) - write_dirnonbranch = 1; - if (rev != NULL) - free (rev); - } - - if (finfo->update_dir[0] == '\0') - p = findnode (mulist, "."); - else - p = findnode (mulist, finfo->update_dir); - - /* - * if p is null, there were file type command line args which were - * all up-to-date so nothing really needs to be done - */ - if (p == NULL) - return 0; - ulist = ((struct master_lists *) p->data)->ulist; - cilist = ((struct master_lists *) p->data)->cilist; - - /* - * At this point, we should have the commit message unless we were called - * with files as args from the command line. In that latter case, we - * need to get the commit message ourselves - */ - if (!got_message) - { - got_message = 1; - if (!server_active && use_editor) - do_editor (finfo->update_dir, &saved_message, - finfo->repository, ulist); - do_verify (&saved_message, finfo->repository); - } - - p = findnode (cilist, finfo->file); - if (p == NULL) - return 0; - - ci = p->data; - if (ci->status == T_MODIFIED) - { - if (finfo->rcs == NULL) - error (1, 0, "internal error: no parsed RCS file"); - if (lock_RCS (finfo->file, finfo->rcs, ci->rev, - finfo->repository) != 0) - { - unlockrcs (finfo->rcs); - err = 1; - goto out; - } - } - else if (ci->status == T_ADDED) - { - if (checkaddfile (finfo->file, finfo->repository, ci->tag, ci->options, - &finfo->rcs) != 0) - { - if (finfo->rcs != NULL) - fixaddfile (finfo->rcs->path); - err = 1; - goto out; - } - - /* adding files with a tag, now means adding them on a branch. - Since the branch test was done in check_fileproc for - modified files, we need to stub it in again here. */ - - if (ci->tag - - /* If numeric, it is on the trunk; check_fileproc enforced - this. */ - && !isdigit ((unsigned char) ci->tag[0])) - { - 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, ci->rev, - ci->tag, ci->options, saved_message); - if (err != 0) - { - unlockrcs (finfo->rcs); - fixbranch (finfo->rcs, sbranch); - } - - (void) time (&last_register_time); - - ci->status = T_UPTODATE; - } - } - - /* - * Add the file for real - */ - if (ci->status == T_ADDED) - { - char *xrev = (char *) NULL; - - if (ci->rev == NULL) - { - /* find the max major rev number in this directory */ - maxrev = 0; - (void) walklist (finfo->entries, findmaxrev, NULL); - if (finfo->rcs->head) { - /* resurrecting: include dead revision */ - int thisrev = atoi (finfo->rcs->head); - if (thisrev > maxrev) - maxrev = thisrev; - } - if (maxrev == 0) - maxrev = 1; - xrev = xmalloc (20); - (void) sprintf (xrev, "%d", maxrev); - } - - /* XXX - an added file with symbolic -r should add tag as well */ - err = finaladd (finfo, ci->rev ? ci->rev : xrev, ci->tag, ci->options); - if (xrev) - free (xrev); - } - else if (ci->status == T_MODIFIED) - { - err = Checkin ('M', finfo, ci->rev, ci->tag, - ci->options, saved_message); - - (void) time (&last_register_time); - - if (err != 0) - { - unlockrcs (finfo->rcs); - fixbranch (finfo->rcs, sbranch); - } - } - else if (ci->status == T_REMOVED) - { - err = remove_file (finfo, ci->tag, saved_message); -#ifdef SERVER_SUPPORT - if (server_active) { - server_scratch_entry_only (); - server_updated (finfo, - NULL, - - /* Doesn't matter, it won't get checked. */ - SERVER_UPDATED, - - (mode_t) -1, - (unsigned char *) NULL, - (struct buffer *) NULL); - } -#endif - } - - /* Clearly this is right for T_MODIFIED. I haven't thought so much - about T_ADDED or T_REMOVED. */ - notify_do ('C', finfo->file, getcaller (), NULL, NULL, finfo->repository); - -out: - if (err != 0) - { - /* on failure, remove the file from ulist */ - p = findnode (ulist, finfo->file); - if (p) - delnode (p); - } - else - { - /* On success, retrieve the new version number of the file and - copy it into the log information (see logmsg.c - (logfile_write) for more details). We should only update - the version number for files that have been added or - modified but not removed since classify_file_internal - will return the version number of a file even after it has - been removed from the archive, which is not the behavior we - want for our commitlog messages; we want the old version - number and then "NONE." */ - - if (ci->status != T_REMOVED) - { - p = findnode (ulist, finfo->file); - if (p) - { - Vers_TS *vers; - struct logfile_info *li; - - (void) classify_file_internal (finfo, &vers); - li = p->data; - li->rev_new = xstrdup (vers->vn_rcs); - freevers_ts (&vers); - } - } - } - if (SIG_inCrSect ()) - SIG_endCrSect (); - - return err; -} - - - -/* - * Log the commit and clean up the update list - */ -/* ARGSUSED */ -static int -commit_filesdoneproc (callerdat, err, repository, update_dir, entries) - void *callerdat; - int err; - const char *repository; - const char *update_dir; - List *entries; -{ - Node *p; - List *ulist; - - assert (repository); - - p = findnode (mulist, update_dir); - if (p == NULL) - return err; - - ulist = ((struct master_lists *) p->data)->ulist; - - got_message = 0; - - Update_Logfile (repository, saved_message, (FILE *) 0, ulist); - - /* Build the administrative files if necessary. */ - { - const char *p; - - if (strncmp (current_parsed_root->directory, repository, - strlen (current_parsed_root->directory)) != 0) - error (0, 0, - "internal error: repository (%s) doesn't begin with root (%s)", - repository, current_parsed_root->directory); - p = repository + strlen (current_parsed_root->directory); - if (*p == '/') - ++p; - if (strcmp ("CVSROOT", p) == 0 - /* Check for subdirectories because people may want to create - subdirectories and list files therein in checkoutlist. */ - || strncmp ("CVSROOT/", p, strlen ("CVSROOT/")) == 0 - ) - { - /* "Database" might a little bit grandiose and/or vague, - but "checked-out copies of administrative files, unless - in the case of modules and you are using ndbm in which - case modules.{pag,dir,db}" is verbose and excessively - focused on how the database is implemented. */ - - /* mkmodules requires the absolute name of the CVSROOT directory. - Remove anything after the `CVSROOT' component -- this is - necessary when committing in a subdirectory of CVSROOT. */ - char *admin_dir = xstrdup (repository); - int cvsrootlen = strlen ("CVSROOT"); - assert (admin_dir[p - repository + cvsrootlen] == '\0' - || admin_dir[p - repository + cvsrootlen] == '/'); - admin_dir[p - repository + cvsrootlen] = '\0'; - - cvs_output (program_name, 0); - cvs_output (" ", 1); - cvs_output (cvs_cmd_name, 0); - cvs_output (": Rebuilding administrative file database\n", 0); - mkmodules (admin_dir); - free (admin_dir); - } - } - - return err; -} - - - -/* - * Get the log message for a dir - */ -/* ARGSUSED */ -static Dtype -commit_direntproc (callerdat, dir, repos, update_dir, entries) - void *callerdat; - const char *dir; - const char *repos; - const char *update_dir; - List *entries; -{ - Node *p; - List *ulist; - char *real_repos; - - if (!isdir (dir)) - return R_SKIP_ALL; - - /* find the update list for this dir */ - p = findnode (mulist, update_dir); - if (p != NULL) - ulist = ((struct master_lists *) p->data)->ulist; - else - ulist = (List *) NULL; - - /* skip the files as an optimization */ - if (ulist == NULL || ulist->list->next == ulist->list) - return R_SKIP_FILES; - - /* get commit message */ - real_repos = Name_Repository (dir, update_dir); - got_message = 1; - if (!server_active && use_editor) - do_editor (update_dir, &saved_message, real_repos, ulist); - do_verify (&saved_message, real_repos); - free (real_repos); - return R_PROCESS; -} - - - -/* - * Process the post-commit proc if necessary - */ -/* ARGSUSED */ -static int -commit_dirleaveproc (callerdat, dir, err, update_dir, entries) - void *callerdat; - const char *dir; - int err; - const char *update_dir; - List *entries; -{ - /* update the per-directory tag info */ - /* FIXME? Why? The "commit examples" node of cvs.texinfo briefly - mentions commit -r being sticky, but apparently in the context of - this being a confusing feature! */ - if (err == 0 && write_dirtag != NULL) - { - char *repos = Name_Repository (NULL, update_dir); - WriteTag (NULL, write_dirtag, NULL, write_dirnonbranch, - update_dir, repos); - free (repos); - } - - return err; -} - - - -/* - * find the maximum major rev number in an entries file - */ -static int -findmaxrev (p, closure) - Node *p; - void *closure; -{ - int thisrev; - Entnode *entdata = p->data; - - if (entdata->type != ENT_FILE) - return 0; - thisrev = atoi (entdata->version); - if (thisrev > maxrev) - maxrev = thisrev; - return 0; -} - -/* - * Actually remove a file by moving it to the attic - * XXX - if removing a ,v file that is a relative symbolic link to - * another ,v file, we probably should add a ".." component to the - * link to keep it relative after we move it into the attic. - - Return value is 0 on success, or >0 on error (in which case we have - printed an error message). */ -static int -remove_file (finfo, tag, message) - struct file_info *finfo; - char *tag; - char *message; -{ - int retcode; - - int branch; - int lockflag; - char *corev; - char *rev; - char *prev_rev; - char *old_path; - - corev = NULL; - rev = NULL; - prev_rev = NULL; - - retcode = 0; - - if (finfo->rcs == NULL) - error (1, 0, "internal error: no parsed RCS file"); - - branch = 0; - if (tag && !(branch = RCS_nodeisbranch (finfo->rcs, tag))) - { - /* a symbolic tag is specified; just remove the tag from the file */ - if ((retcode = RCS_deltag (finfo->rcs, tag)) != 0) - { - if (!quiet) - error (0, retcode == -1 ? errno : 0, - "failed to remove tag `%s' from `%s'", tag, - finfo->fullname); - return 1; - } - RCS_rewrite (finfo->rcs, NULL, NULL); - Scratch_Entry (finfo->entries, finfo->file); - return 0; - } - - /* we are removing the file from either the head or a branch */ - /* commit a new, dead revision. */ - - /* Print message indicating that file is going to be removed. */ - cvs_output ("Removing ", 0); - cvs_output (finfo->fullname, 0); - cvs_output (";\n", 0); - - rev = NULL; - lockflag = 1; - if (branch) - { - char *branchname; - - rev = RCS_whatbranch (finfo->rcs, tag); - if (rev == NULL) - { - error (0, 0, "cannot find branch \"%s\".", tag); - return 1; - } - - branchname = RCS_getbranch (finfo->rcs, rev, 1); - if (branchname == NULL) - { - /* no revision exists on this branch. use the previous - revision but do not lock. */ - corev = RCS_gettag (finfo->rcs, tag, 1, (int *) NULL); - prev_rev = xstrdup (corev); - lockflag = 0; - } else - { - corev = xstrdup (rev); - prev_rev = xstrdup (branchname); - free (branchname); - } - - } else /* Not a branch */ - { - /* Get current head revision of file. */ - prev_rev = RCS_head (finfo->rcs); - } - - /* if removing without a tag or a branch, then make sure the default - branch is the trunk. */ - if (!tag && !branch) - { - if (RCS_setbranch (finfo->rcs, NULL) != 0) - { - error (0, 0, "cannot change branch to default for %s", - finfo->fullname); - return 1; - } - RCS_rewrite (finfo->rcs, NULL, NULL); - } - - /* check something out. Generally this is the head. If we have a - particular rev, then name it. */ - retcode = RCS_checkout (finfo->rcs, finfo->file, rev ? corev : NULL, - (char *) NULL, (char *) NULL, RUN_TTY, - (RCSCHECKOUTPROC) NULL, (void *) NULL); - if (retcode != 0) - { - error (0, 0, - "failed to check out `%s'", finfo->fullname); - return 1; - } - - /* Except when we are creating a branch, lock the revision so that - we can check in the new revision. */ - if (lockflag) - { - if (RCS_lock (finfo->rcs, rev ? corev : NULL, 1) == 0) - RCS_rewrite (finfo->rcs, NULL, NULL); - } - - if (corev != NULL) - free (corev); - - retcode = RCS_checkin (finfo->rcs, finfo->file, message, rev, 0, - RCS_FLAGS_DEAD | RCS_FLAGS_QUIET); - if (retcode != 0) - { - if (!quiet) - error (0, retcode == -1 ? errno : 0, - "failed to commit dead revision for `%s'", finfo->fullname); - if (prev_rev != NULL) - free (prev_rev); - return 1; - } - /* At this point, the file has been committed as removed. We should - probably tell the history file about it */ - corev = rev ? RCS_getbranch (finfo->rcs, rev, 1) : RCS_head (finfo->rcs); - history_write ('R', NULL, corev, finfo->file, finfo->repository); - free (corev); - - if (rev != NULL) - free (rev); - - old_path = xstrdup (finfo->rcs->path); - if (!branch) - RCS_setattic (finfo->rcs, 1); - - /* Print message that file was removed. */ - cvs_output (old_path, 0); - cvs_output (" <-- ", 0); - cvs_output (finfo->file, 0); - cvs_output ("\nnew revision: delete; previous revision: ", 0); - cvs_output (prev_rev, 0); - cvs_output ("\ndone\n", 0); - free(prev_rev); - - free (old_path); - - Scratch_Entry (finfo->entries, finfo->file); - return 0; -} - - - -/* - * Do the actual checkin for added files - */ -static int -finaladd (finfo, rev, tag, options) - struct file_info *finfo; - char *rev; - char *tag; - char *options; -{ - int ret; - - ret = Checkin ('A', finfo, rev, tag, options, saved_message); - if (ret == 0) - { - char *tmp = xmalloc (strlen (finfo->file) + sizeof (CVSADM) - + sizeof (CVSEXT_LOG) + 10); - (void) sprintf (tmp, "%s/%s%s", CVSADM, finfo->file, CVSEXT_LOG); - if (unlink_file (tmp) < 0 - && !existence_error (errno)) - error (0, errno, "cannot remove %s", tmp); - free (tmp); - } - else if (finfo->rcs != NULL) - fixaddfile (finfo->rcs->path); - - (void) time (&last_register_time); - - return ret; -} - - - -/* - * Unlock an rcs file - */ -static void -unlockrcs (rcs) - RCSNode *rcs; -{ - int retcode; - - if ((retcode = RCS_unlock (rcs, NULL, 1)) != 0) - error (retcode == -1 ? 1 : 0, retcode == -1 ? errno : 0, - "could not unlock %s", rcs->path); - else - RCS_rewrite (rcs, NULL, NULL); -} - - - -/* - * remove a partially added file. if we can parse it, leave it alone. - * - * FIXME: Every caller that calls this function can access finfo->rcs (the - * parsed RCSNode data), so we should be able to detect that the file needs - * to be removed without reparsing the file as we do below. - */ -static void -fixaddfile (rcs) - const char *rcs; -{ - RCSNode *rcsfile; - int save_really_quiet; - - save_really_quiet = really_quiet; - really_quiet = 1; - if ((rcsfile = RCS_parsercsfile (rcs)) == NULL) - { - if (unlink_file (rcs) < 0) - error (0, errno, "cannot remove %s", rcs); - } - else - freercsnode (&rcsfile); - really_quiet = save_really_quiet; -} - - - -/* - * put the branch back on an rcs file - */ -static void -fixbranch (rcs, branch) - RCSNode *rcs; - char *branch; -{ - int retcode; - - if (branch != NULL) - { - if ((retcode = RCS_setbranch (rcs, branch)) != 0) - error (retcode == -1 ? 1 : 0, retcode == -1 ? errno : 0, - "cannot restore branch to %s for %s", branch, rcs->path); - RCS_rewrite (rcs, NULL, NULL); - } -} - - - -/* - * do the initial part of a file add for the named file. if adding - * with a tag, put the file in the Attic and point the symbolic tag - * at the committed revision. - * - * INPUTS - * file The name of the file in the workspace. - * repository The repository directory to expect to find FILE,v in. - * tag The name or rev num of the branch being added to, if any. - * options Any RCS keyword expansion options specified by the user. - * rcsnode A pointer to the pre-parsed RCSNode for this file, if the file - * exists in the repository. If this is NULL, assume the file - * does not yet exist. - * - * RETURNS - * 0 on success. - * 1 on errors, after printing any appropriate error messages. - * - * ERRORS - * This function will return an error when any of the following functions do: - * add_rcs_file - * RCS_setattic - * lock_RCS - * RCS_checkin - * RCS_parse (called to verify the newly created archive file) - * RCS_settag - */ - -static int -checkaddfile (file, repository, tag, options, rcsnode) - const char *file; - const char *repository; - const char *tag; - const char *options; - RCSNode **rcsnode; -{ - RCSNode *rcs; - char *fname; - int newfile = 0; /* Set to 1 if we created a new RCS archive. */ - int retval = 1; - int adding_on_branch; - - assert (rcsnode != NULL); - - /* Callers expect to be able to use either "" or NULL to mean the - default keyword expansion. */ - if (options != NULL && options[0] == '\0') - options = NULL; - if (options != NULL) - assert (options[0] == '-' && options[1] == 'k'); - - /* If numeric, it is on the trunk; check_fileproc enforced - this. */ - adding_on_branch = tag != NULL && !isdigit ((unsigned char) tag[0]); - - if (*rcsnode == NULL) - { - char *rcsname; - char *desc = NULL; - size_t descalloc = 0; - size_t desclen = 0; - const char *opt; - - if ( adding_on_branch ) - { - mode_t omask; - rcsname = xmalloc (strlen (repository) - + sizeof (CVSATTIC) - + strlen (file) - + sizeof (RCSEXT) - + 3); - (void) sprintf (rcsname, "%s/%s", repository, CVSATTIC); - omask = umask ( cvsumask ); - if (CVS_MKDIR (rcsname, 0777 ) != 0 && errno != EEXIST) - error (1, errno, "cannot make directory `%s'", rcsname); - (void) umask ( omask ); - (void) sprintf (rcsname, - "%s/%s/%s%s", - repository, - CVSATTIC, - file, - RCSEXT); - } - else - { - rcsname = xmalloc (strlen (repository) - + strlen (file) - + sizeof (RCSEXT) - + 2); - (void) sprintf (rcsname, - "%s/%s%s", - repository, - file, - RCSEXT); - } - - /* this is the first time we have ever seen this file; create - an RCS file. */ - fname = xmalloc (strlen (file) + sizeof (CVSADM) - + sizeof (CVSEXT_LOG) + 10); - (void) sprintf (fname, "%s/%s%s", CVSADM, file, CVSEXT_LOG); - /* If the file does not exist, no big deal. In particular, the - server does not (yet at least) create CVSEXT_LOG files. */ - if (isfile (fname)) - /* FIXME: Should be including update_dir in the appropriate - place here. */ - get_file (fname, fname, "r", &desc, &descalloc, &desclen); - free (fname); - - /* From reading the RCS 5.7 source, "rcs -i" adds a newline to the - end of the log message if the message is nonempty. - Do it. RCS also deletes certain whitespace, in cleanlogmsg, - which we don't try to do here. */ - if (desclen > 0) - { - expand_string (&desc, &descalloc, desclen + 1); - desc[desclen++] = '\012'; - } - - /* Set RCS keyword expansion options. */ - if (options != NULL) - opt = options + 2; - else - opt = NULL; - - /* This message is an artifact of the time when this - was implemented via "rcs -i". It should be revised at - some point (does the "initial revision" in the message from - RCS_checkin indicate that this is a new file? Or does the - "RCS file" message serve some function?). */ - cvs_output ("RCS file: ", 0); - cvs_output (rcsname, 0); - cvs_output ("\ndone\n", 0); - - if (add_rcs_file (NULL, rcsname, file, NULL, opt, - NULL, NULL, 0, NULL, - desc, desclen, NULL) != 0) - { - if (rcsname != NULL) - free (rcsname); - goto out; - } - rcs = RCS_parsercsfile (rcsname); - newfile = 1; - if (rcsname != NULL) - free (rcsname); - if (desc != NULL) - free (desc); - *rcsnode = rcs; - } - else - { - /* file has existed in the past. Prepare to resurrect. */ - char *rev; - char *oldexpand; - - rcs = *rcsnode; - - oldexpand = RCS_getexpand (rcs); - if ((oldexpand != NULL - && options != NULL - && strcmp (options + 2, oldexpand) != 0) - || (oldexpand == NULL && options != NULL)) - { - /* We tell the user about this, because it means that the - old revisions will no longer retrieve the way that they - used to. */ - error (0, 0, "changing keyword expansion mode to %s", options); - RCS_setexpand (rcs, options + 2); - } - - if (!adding_on_branch) - { - /* We are adding on the trunk, so move the file out of the - Attic. */ - if (!(rcs->flags & INATTIC)) - { - error (0, 0, "warning: expected %s to be in Attic", - rcs->path); - } - - /* 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 (rcs, 0)) - { - goto out; - } - } - - rev = RCS_getversion (rcs, tag, NULL, 1, (int *) NULL); - /* and lock it */ - if (lock_RCS (file, rcs, rev, repository)) - { - error (0, 0, "cannot lock revision %s in `%s'.", - rev ? rev : tag ? tag : "HEAD", rcs->path); - if (rev != NULL) - free (rev); - goto out; - } - - if (rev != NULL) - free (rev); - } - - /* 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; - int retcode; - - /* 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 (rcs, NULL, tmp, NULL, 0, - 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->path); - free (fname); - 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 (&rcs); - rcs = RCS_parse (file, repository); - if (rcs == NULL) - { - error (0, 0, "could not read %s in %s", file, repository); - goto out; - } - *rcsnode = rcs; - - /* and lock it once again. */ - if (lock_RCS (file, rcs, NULL, repository)) - { - error (0, 0, "cannot lock initial revision in `%s'.", - rcs->path); - goto out; - } - } - - /* when adding with a tag, we need to stub a branch, if it - doesn't already exist. */ - if (!RCS_nodeisbranch (rcs, tag)) - { - /* branch does not exist. Stub it. */ - char *head; - char *magicrev; - int retcode; - time_t headtime = -1; - char *revnum, *tmp; - FILE *fp; - time_t t = -1; - struct tm *ct; - - fixbranch (rcs, sbranch); - - head = RCS_getversion (rcs, NULL, NULL, 0, (int *) NULL); - if (!head) - error (1, 0, "No head revision in archive file `%s'.", - rcs->path); - magicrev = RCS_magicrev (rcs, head); - - /* If this is not a new branch, then we will want a dead - version created before this one. */ - if (!newfile) - headtime = RCS_getrevtime (rcs, head, 0, 0); - - retcode = RCS_settag (rcs, tag, magicrev); - RCS_rewrite (rcs, NULL, NULL); - - free (head); - free (magicrev); - - if (retcode != 0) - { - error (retcode == -1 ? 1 : 0, retcode == -1 ? errno : 0, - "could not stub branch %s for %s", tag, rcs->path); - goto out; - } - /* We need to add a dead version here to avoid -rtag -Dtime - checkout problems between when the head version was - created and now. */ - if (!newfile && headtime != -1) - { - /* 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); - - /* As we will be hacking the delta date, put the time - this was added into the log message. */ - t = time(NULL); - ct = gmtime(&t); - tmp = xmalloc (strlen (file) + strlen (tag) + 80); - - (void) sprintf (tmp, - "file %s was added on branch %s on %d-%02d-%02d %02d:%02d:%02d +0000", - file, tag, - ct->tm_year + (ct->tm_year < 100 ? 0 : 1900), - ct->tm_mon + 1, ct->tm_mday, - ct->tm_hour, ct->tm_min, ct->tm_sec); - - /* commit a dead revision. */ - revnum = RCS_whatbranch (rcs, tag); - retcode = RCS_checkin (rcs, NULL, tmp, revnum, headtime, - RCS_FLAGS_DEAD | - RCS_FLAGS_QUIET | - RCS_FLAGS_USETIME); - free (revnum); - free (tmp); - - if (retcode != 0) - { - error (retcode == -1 ? 1 : 0, retcode == -1 ? errno : 0, - "could not created dead stub %s for %s", tag, - rcs->path); - 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 (&rcs); - rcs = RCS_parse (file, repository); - if (rcs == NULL) - { - error (0, 0, "could not read %s", rcs->path); - goto out; - } - *rcsnode = rcs; - } - } - else - { - /* lock the branch. (stubbed branches need not be locked.) */ - if (lock_RCS (file, rcs, NULL, repository)) - { - error (0, 0, "cannot lock head revision in `%s'.", rcs->path); - goto out; - } - } - - if (*rcsnode != rcs) - { - freercsnode(rcsnode); - *rcsnode = rcs; - } - } - - fileattr_newfile (file); - - /* At this point, we used to set the file mode of the RCS file - based on the mode of the file in the working directory. If we - are creating the RCS file for the first time, add_rcs_file does - this already. If we are re-adding the file, then perhaps it is - consistent to preserve the old file mode, just as we preserve - the old keyword expansion mode. - - If we decide that we should change the modes, then we can't do - it here anyhow. At this point, the RCS file may be owned by - somebody else, so a chmod will fail. We need to instead do the - chmod after rewriting it. - - FIXME: In general, I think the file mode (and the keyword - expansion mode) should be associated with a particular revision - of the file, so that it is possible to have different revisions - of a file have different modes. */ - - retval = 0; - - out: - if (retval != 0 && SIG_inCrSect ()) - SIG_endCrSect (); - return retval; -} - - - -/* - * Attempt to place a lock on the RCS file; returns 0 if it could and 1 if it - * couldn't. If the RCS file currently has a branch as the head, we must - * move the head back to the trunk before locking the file, and be sure to - * put the branch back as the head if there are any errors. - */ -static int -lock_RCS (user, rcs, rev, repository) - const char *user; - RCSNode *rcs; - const char *rev; - const char *repository; -{ - char *branch = NULL; - int err = 0; - - /* - * For a specified, numeric revision of the form "1" or "1.1", (or when - * no revision is specified ""), definitely move the branch to the trunk - * before locking the RCS file. - * - * The assumption is that if there is more than one revision on the trunk, - * the head points to the trunk, not a branch... and as such, it's not - * necessary to move the head in this case. - */ - if (rev == NULL - || (rev && isdigit ((unsigned char) *rev) && numdots (rev) < 2)) - { - branch = xstrdup (rcs->branch); - if (branch != NULL) - { - if (RCS_setbranch (rcs, NULL) != 0) - { - error (0, 0, "cannot change branch to default for %s", - rcs->path); - if (branch) - free (branch); - return 1; - } - } - err = RCS_lock (rcs, NULL, 1); - } - else - { - RCS_lock (rcs, rev, 1); - } - - /* We used to call RCS_rewrite here, and that might seem - appropriate in order to write out the locked revision - information. However, such a call would actually serve no - purpose. CVS locks will prevent any interference from other - CVS processes. The comment above rcs_internal_lockfile - explains that it is already unsafe to use RCS and CVS - simultaneously. It follows that writing out the locked - revision information here would add no additional security. - - If we ever do care about it, the proper fix is to create the - RCS lock file before calling this function, and maintain it - until the checkin is complete. - - The call to RCS_lock is still required at present, since in - some cases RCS_checkin will determine which revision to check - in by looking for a lock. FIXME: This is rather roundabout, - and a more straightforward approach would probably be easier to - understand. */ - - if (err == 0) - { - if (sbranch != NULL) - free (sbranch); - sbranch = branch; - return 0; - } - - /* try to restore the branch if we can on error */ - if (branch != NULL) - fixbranch (rcs, branch); - - if (branch) - free (branch); - return 1; -} - - - -/* - * free an UPDATE node's data - */ -void -update_delproc (p) - Node *p; -{ - struct logfile_info *li = p->data; - - if (li->tag) - free (li->tag); - if (li->rev_old) - free (li->rev_old); - if (li->rev_new) - free (li->rev_new); - free (li); -} - -/* - * Free the commit_info structure in p. - */ -static void -ci_delproc (p) - Node *p; -{ - struct commit_info *ci = p->data; - - if (ci->rev) - free (ci->rev); - if (ci->tag) - free (ci->tag); - if (ci->options) - free (ci->options); - free (ci); -} - -/* - * Free the commit_info structure in p. - */ -static void -masterlist_delproc (p) - Node *p; -{ - struct master_lists *ml = p->data; - - dellist (&ml->ulist); - dellist (&ml->cilist); - free (ml); -} diff --git a/contrib/cvs/src/create_adm.c b/contrib/cvs/src/create_adm.c deleted file mode 100644 index ccf744f..0000000 --- a/contrib/cvs/src/create_adm.c +++ /dev/null @@ -1,187 +0,0 @@ -/* - * Copyright (C) 1986-2005 The Free Software Foundation, Inc. - * - * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot , - * and others. - * - * Portions Copyright (C) 1992, Brian Berliner and Jeff Polk - * Portions Copyright (C) 1989-1992, Brian Berliner - * - * You may distribute under the terms of the GNU General Public License as - * specified in the README file that comes with the CVS source distribution. - * - * Create Administration. - * - * Creates a CVS administration directory based on the argument repository; the - * "Entries" file is prefilled from the "initrecord" argument. - */ - -#include "cvs.h" - -/* update_dir includes dir as its last component. - - Return value is 0 for success, or 1 if we printed a warning message. - Note that many errors are still fatal; particularly for unlikely errors - a fatal error is probably better than a warning which might be missed - or after which CVS might do something non-useful. If WARN is zero, then - don't print warnings; all errors are fatal then. */ - -int -Create_Admin (dir, update_dir, repository, tag, date, nonbranch, warn, - dotemplate) - const char *dir; - const char *update_dir; - const char *repository; - const char *tag; - const char *date; - int nonbranch; - int warn; - int dotemplate; -{ - FILE *fout; - char *cp; - char *reposcopy; - char *tmp; - - if (trace) - { - fprintf (stderr, "%s-> Create_Admin (%s, %s, %s, %s, %s, %d, %d, %d)\n", - CLIENT_SERVER_STR, - dir, update_dir, repository, tag ? tag : "", - date ? date : "", nonbranch, warn, dotemplate); - } - - if (noexec) - return 0; - - tmp = xmalloc (strlen (dir) + 100); - (void) sprintf (tmp, "%s/%s", dir, CVSADM); - if (isfile (tmp)) - error (1, 0, "there is a version in %s already", update_dir); - - if (CVS_MKDIR (tmp, 0777) < 0) - { - /* We want to print out the entire update_dir, since a lot of - our code calls this function with dir == "." or dir == - NULL. I hope that gives enough information in cases like - absolute pathnames; printing out xgetwd or something would - be way too verbose in the common cases. */ - - if (warn) - { - /* The reason that this is a warning, rather than silently - just skipping creating the directory, is that we don't want - CVS's behavior to vary subtly based on factors (like directory - permissions) which are not made clear to the user. With - the warning at least we let them know what is going on. */ - error (0, errno, "warning: cannot make directory %s in %s", - CVSADM, update_dir); - free (tmp); - return 1; - } - else - error (1, errno, "cannot make directory %s in %s", - CVSADM, update_dir); - } - - /* record the current cvs root for later use */ - - Create_Root (dir, current_parsed_root->original); - if (dir != NULL) - (void) sprintf (tmp, "%s/%s", dir, CVSADM_REP); - else - (void) strcpy (tmp, CVSADM_REP); - fout = CVS_FOPEN (tmp, "w+"); - if (fout == NULL) - { - if (update_dir[0] == '\0') - error (1, errno, "cannot open %s", tmp); - else - error (1, errno, "cannot open %s/%s", update_dir, CVSADM_REP); - } - reposcopy = xstrdup (repository); - Sanitize_Repository_Name (reposcopy); - - /* The top level of the repository is a special case -- we need to - write it with an extra dot at the end. This trailing `.' stuff - rubs me the wrong way -- on the other hand, I don't want to - spend the time making sure all of the code can handle it if we - don't do it. */ - - if (strcmp (reposcopy, current_parsed_root->directory) == 0) - { - reposcopy = xrealloc (reposcopy, strlen (reposcopy) + 3); - strcat (reposcopy, "/."); - } - - cp = reposcopy; - - /* - * If the Repository file is to hold a relative path, try to strip off - * the leading CVSroot argument. - */ - { - char *path = xmalloc (strlen (current_parsed_root->directory) + 2); - - (void) sprintf (path, "%s/", current_parsed_root->directory); - if (strncmp (cp, path, strlen (path)) == 0) - cp += strlen (path); - free (path); - } - - if (fprintf (fout, "%s\n", cp) < 0) - { - if (update_dir[0] == '\0') - error (1, errno, "write to %s failed", tmp); - else - error (1, errno, "write to %s/%s failed", update_dir, CVSADM_REP); - } - if (fclose (fout) == EOF) - { - if (update_dir[0] == '\0') - error (1, errno, "cannot close %s", tmp); - else - error (1, errno, "cannot close %s/%s", update_dir, CVSADM_REP); - } - - /* now, do the Entries file */ - if (dir != NULL) - (void) sprintf (tmp, "%s/%s", dir, CVSADM_ENT); - else - (void) strcpy (tmp, CVSADM_ENT); - fout = CVS_FOPEN (tmp, "w+"); - if (fout == NULL) - { - if (update_dir[0] == '\0') - error (1, errno, "cannot open %s", tmp); - else - error (1, errno, "cannot open %s/%s", update_dir, CVSADM_ENT); - } - if (fclose (fout) == EOF) - { - if (update_dir[0] == '\0') - error (1, errno, "cannot close %s", tmp); - else - error (1, errno, "cannot close %s/%s", update_dir, CVSADM_ENT); - } - - /* Create a new CVS/Tag file */ - WriteTag (dir, tag, date, nonbranch, update_dir, repository); - -#ifdef SERVER_SUPPORT - if (server_active && dotemplate) - { - server_template (update_dir, repository); - } - - if (trace) - { - fprintf (stderr, "%c<- Create_Admin\n", - (server_active) ? 'S' : ' '); - } -#endif - - free (reposcopy); - free (tmp); - return 0; -} diff --git a/contrib/cvs/src/cvs.h b/contrib/cvs/src/cvs.h deleted file mode 100644 index 4b7d9f5..0000000 --- a/contrib/cvs/src/cvs.h +++ /dev/null @@ -1,945 +0,0 @@ -/* - * Copyright (C) 1986-2005 The Free Software Foundation, Inc. - * - * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot , - * and others. - * - * Portions Copyright (C) 1992, Brian Berliner and Jeff Polk - * Portions Copyright (C) 1989-1992, Brian Berliner - * - * You may distribute under the terms of the GNU General Public License as - * specified in the README file that comes with the CVS kit. - */ - -/* - * basic information used in all source files - * - * $FreeBSD$ - */ - - -#ifdef HAVE_CONFIG_H -# include /* this is stuff found via autoconf */ -#endif /* CONFIG_H */ - -/* Changed from if __STDC__ to ifdef __STDC__ because of Sun's acc compiler */ - -#ifdef __STDC__ -#define PTR void * -#else -#define PTR char * -#endif - -/* Add prototype support. */ -#ifndef PROTO -#if defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__) -#define PROTO(ARGS) ARGS -#else -#define PROTO(ARGS) () -#endif -#endif - -#include - -/* Under OS/2, doesn't define popen()/pclose(). */ -#ifdef USE_OWN_POPEN -#include "popen.h" -#endif - -/* Begin GNULIB headers. */ -#include "xsize.h" -/* End GNULIB headers. */ - -#ifdef STDC_HEADERS -#include -#else -extern void exit (); -extern char *getenv(); -#endif - -#ifdef HAVE_UNISTD_H -#include -#endif - -#ifdef HAVE_STRING_H -#include -#else -#include -#endif - -#ifdef SERVER_SUPPORT -/* If the system doesn't provide strerror, it won't be declared in - string.h. */ -char *strerror (); -#endif - -#ifdef HAVE_FNMATCH -# include /* This is supposed to be available on Posix systems */ -#else /* HAVE_FNMATCH */ -# include "fnmatch.h" /* Our substitute */ -#endif /* HAVE_FNMATCH */ - -#include -#include -#include - -#ifdef HAVE_ERRNO_H -#include -#else -#ifndef errno -extern int errno; -#endif /* !errno */ -#endif /* HAVE_ERRNO_H */ - -#include "system.h" - -#include "hash.h" -#include "stack.h" - -#include "root.h" - -#if defined(SERVER_SUPPORT) || defined(CLIENT_SUPPORT) -# include "client.h" -#endif - -#ifdef MY_NDBM -#include "myndbm.h" -#else -#include -#endif /* MY_NDBM */ - -#include "regex.h" -#include "getopt.h" -#include "wait.h" - -#include "rcs.h" - - -/* This actually gets set in system.h. Note that the _ONLY_ reason for - this is if various system calls (getwd, getcwd, readlink) require/want - us to use it. All other parts of CVS allocate pathname buffers - dynamically, and we want to keep it that way. */ -#ifndef PATH_MAX -#ifdef MAXPATHLEN -#define PATH_MAX MAXPATHLEN+2 -#else -#define PATH_MAX 1024+2 -#endif -#endif /* PATH_MAX */ - -/* Definitions for the CVS Administrative directory and the files it contains. - Here as #define's to make changing the names a simple task. */ - -#ifdef USE_VMS_FILENAMES -#define CVSADM "CVS" -#define CVSADM_ENT "CVS/Entries." -#define CVSADM_ENTBAK "CVS/Entries.Backup" -#define CVSADM_ENTLOG "CVS/Entries.Log" -#define CVSADM_ENTSTAT "CVS/Entries.Static" -#define CVSADM_REP "CVS/Repository." -#define CVSADM_ROOT "CVS/Root." -#define CVSADM_TAG "CVS/Tag." -#define CVSADM_NOTIFY "CVS/Notify." -#define CVSADM_NOTIFYTMP "CVS/Notify.tmp" -#define CVSADM_BASE "CVS/Base" -#define CVSADM_BASEREV "CVS/Baserev." -#define CVSADM_BASEREVTMP "CVS/Baserev.tmp" -#define CVSADM_TEMPLATE "CVS/Template." -#else /* USE_VMS_FILENAMES */ -#define CVSADM "CVS" -#define CVSADM_ENT "CVS/Entries" -#define CVSADM_ENTBAK "CVS/Entries.Backup" -#define CVSADM_ENTLOG "CVS/Entries.Log" -#define CVSADM_ENTSTAT "CVS/Entries.Static" -#define CVSADM_REP "CVS/Repository" -#define CVSADM_ROOT "CVS/Root" -#define CVSADM_TAG "CVS/Tag" -#define CVSADM_NOTIFY "CVS/Notify" -#define CVSADM_NOTIFYTMP "CVS/Notify.tmp" -/* A directory in which we store base versions of files we currently are - editing with "cvs edit". */ -#define CVSADM_BASE "CVS/Base" -#define CVSADM_BASEREV "CVS/Baserev" -#define CVSADM_BASEREVTMP "CVS/Baserev.tmp" -/* File which contains the template for use in log messages. */ -#define CVSADM_TEMPLATE "CVS/Template" -#endif /* USE_VMS_FILENAMES */ - -/* This is the special directory which we use to store various extra - per-directory information in the repository. It must be the same as - CVSADM to avoid creating a new reserved directory name which users cannot - use, but is a separate #define because if anyone changes it (which I don't - recommend), one needs to deal with old, unconverted, repositories. - - See fileattr.h for details about file attributes, the only thing stored - in CVSREP currently. */ -#define CVSREP "CVS" - -/* - * Definitions for the CVSROOT Administrative directory and the files it - * contains. This directory is created as a sub-directory of the $CVSROOT - * environment variable, and holds global administration information for the - * entire source repository beginning at $CVSROOT. - */ -#define CVSROOTADM "CVSROOT" -#define CVSROOTADM_MODULES "modules" -#define CVSROOTADM_LOGINFO "loginfo" -#define CVSROOTADM_RCSINFO "rcsinfo" -#define CVSROOTADM_COMMITINFO "commitinfo" -#define CVSROOTADM_TAGINFO "taginfo" -#define CVSROOTADM_EDITINFO "editinfo" -#define CVSROOTADM_VERIFYMSG "verifymsg" -#define CVSROOTADM_HISTORY "history" -#define CVSROOTADM_VALTAGS "val-tags" -#define CVSROOTADM_IGNORE "cvsignore" -#define CVSROOTADM_CHECKOUTLIST "checkoutlist" -#define CVSROOTADM_WRAPPER "cvswrappers" -#define CVSROOTADM_NOTIFY "notify" -#define CVSROOTADM_USERS "users" -#define CVSROOTADM_READERS "readers" -#define CVSROOTADM_WRITERS "writers" -#define CVSROOTADM_PASSWD "passwd" -#define CVSROOTADM_CONFIG "config" -#define CVSROOTADM_OPTIONS "options" - -#define CVSNULLREPOS "Emptydir" /* an empty directory */ - -/* Other CVS file names */ - -/* Files go in the attic if the head main branch revision is dead, - otherwise they go in the regular repository directories. The whole - concept of having an attic is sort of a relic from before death - support but on the other hand, it probably does help the speed of - some operations (such as main branch checkouts and updates). */ -#define CVSATTIC "Attic" - -#define CVSLCK "#cvs.lock" -#define CVSHISTORYLCK "#cvs.history.lock" -#define CVSVALTAGSLCK "#cvs.val-tags.lock" -#define CVSRFL "#cvs.rfl" -#define CVSWFL "#cvs.wfl" -#define CVSRFLPAT "#cvs.rfl.*" /* wildcard expr to match read locks */ -#define CVSEXT_LOG ",t" -#define CVSPREFIX ",," -#define CVSDOTIGNORE ".cvsignore" -#define CVSDOTWRAPPER ".cvswrappers" - -/* Command attributes -- see function lookup_command_attribute(). */ -#define CVS_CMD_IGNORE_ADMROOT 1 - -/* Set if CVS needs to create a CVS/Root file upon completion of this - command. The name may be slightly confusing, because the flag - isn't really as general purpose as it seems (it is not set for cvs - release). */ - -#define CVS_CMD_USES_WORK_DIR 2 - -#define CVS_CMD_MODIFIES_REPOSITORY 4 - -/* miscellaneous CVS defines */ - -/* This is the string which is at the start of the non-log-message lines - that we put up for the user when they edit the log message. */ -#define CVSEDITPREFIX "CVS: " -/* Number of characters in CVSEDITPREFIX to compare when deciding to strip - off those lines. We don't check for the space, to accomodate users who - have editors which strip trailing spaces. */ -#define CVSEDITPREFIXLEN 4 - -#define CVSLCKAGE (60*60) /* 1-hour old lock files cleaned up */ -#define CVSLCKSLEEP 30 /* wait 30 seconds before retrying */ -#define CVSBRANCH "1.1.1" /* RCS branch used for vendor srcs */ - -#ifdef USE_VMS_FILENAMES -#define BAKPREFIX "_$" -#define DEVNULL "NLA0:" -#else /* USE_VMS_FILENAMES */ -#define BAKPREFIX ".#" /* when rcsmerge'ing */ -#ifndef DEVNULL -#define DEVNULL "/dev/null" -#endif -#endif /* USE_VMS_FILENAMES */ - -/* - * Special tags. -rHEAD refers to the head of an RCS file, regardless of any - * sticky tags. -rBASE refers to the current revision the user has checked - * out This mimics the behaviour of RCS. - */ -#define TAG_HEAD "HEAD" -#define TAG_BASE "BASE" - -/* Environment variable used by CVS */ -#define CVSREAD_ENV "CVSREAD" /* make files read-only */ -#define CVSREAD_DFLT 0 /* writable files by default */ - -#define CVSREADONLYFS_ENV "CVSREADONLYFS" /* repository is read-only */ - -#define TMPDIR_ENV "TMPDIR" /* Temporary directory */ - -#define EDITOR1_ENV "CVSEDITOR" /* which editor to use */ -#define EDITOR2_ENV "VISUAL" /* which editor to use */ -#define EDITOR3_ENV "EDITOR" /* which editor to use */ - -#define CVSROOT_ENV "CVSROOT" /* source directory root */ -/* Define CVSROOT_DFLT to a fallback value for CVSROOT. - * -#undef CVSROOT_DFL - */ - -#define IGNORE_ENV "CVSIGNORE" /* More files to ignore */ -#define WRAPPER_ENV "CVSWRAPPERS" /* name of the wrapper file */ - -#define CVSUMASK_ENV "CVSUMASK" /* Effective umask for repository */ - -/* - * If the beginning of the Repository matches the following string, strip it - * so that the output to the logfile does not contain a full pathname. - * - * If the CVSROOT environment variable is set, it overrides this define. - */ -#define REPOS_STRIP "/master/" - -/* Large enough to hold DATEFORM. Not an arbitrary limit as long as - it is used for that purpose, and not to hold a string from the - command line, the client, etc. */ -#define MAXDATELEN 50 - -/* The type of an entnode. */ -enum ent_type -{ - ENT_FILE, ENT_SUBDIR -}; - -/* structure of a entry record */ -struct entnode -{ - enum ent_type type; - char *user; - char *version; - - /* Timestamp, or "" if none (never NULL). */ - char *timestamp; - - /* Keyword expansion options, or "" if none (never NULL). */ - char *options; - - char *tag; - char *date; - char *conflict; -}; -typedef struct entnode Entnode; - -/* The type of request that is being done in do_module() */ -enum mtype -{ - CHECKOUT, TAG, PATCH, EXPORT, MISC -}; - -/* - * structure used for list-private storage by Entries_Open() and - * Version_TS() and Find_Directories(). - */ -struct stickydirtag -{ - /* These fields pass sticky tag information from Entries_Open() to - Version_TS(). */ - int aflag; - char *tag; - char *date; - int nonbranch; - - /* This field is set by Entries_Open() if there was subdirectory - information; Find_Directories() uses it to see whether it needs - to scan the directory itself. */ - int subdirs; -}; - -/* Flags for find_{names,dirs} routines */ -#define W_LOCAL 0x01 /* look for files locally */ -#define W_REPOS 0x02 /* look for files in the repository */ -#define W_ATTIC 0x04 /* look for files in the attic */ - -/* Flags for return values of direnter procs for the recursion processor */ -enum direnter_type -{ - R_PROCESS = 1, /* process files and maybe dirs */ - R_SKIP_FILES, /* don't process files in this dir */ - R_SKIP_DIRS, /* don't process sub-dirs */ - R_SKIP_ALL /* don't process files or dirs */ -}; -#ifdef ENUMS_CAN_BE_TROUBLE -typedef int Dtype; -#else -typedef enum direnter_type Dtype; -#endif - -/* Recursion processor lock types */ -#define CVS_LOCK_NONE 0 -#define CVS_LOCK_READ 1 -#define CVS_LOCK_WRITE 2 - -extern const char *program_name, *program_path, *cvs_cmd_name; -extern char *Tmpdir, *Editor; -extern int cvsadmin_root; -extern char *CurDir; -extern int really_quiet, quiet; -extern int use_editor; -extern int cvswrite; -extern mode_t cvsumask; -extern char *RCS_citag; - - - -/* This global variable holds the global -d option. It is NULL if -d - was not used, which means that we must get the CVSroot information - from the CVSROOT environment variable or from a CVS/Root file. */ -extern char *CVSroot_cmdline; - -/* These variables keep track of all of the CVSROOT directories that - have been seen by the client and the current one of those selected. */ -extern List *root_directories; -extern cvsroot_t *current_parsed_root; - -extern char *emptydir_name PROTO ((void)); -extern int safe_location PROTO ((char *)); - -extern int trace; /* Show all commands */ -extern int noexec; /* Don't modify disk anywhere */ -extern int readonlyfs; /* fail on all write locks; succeed all read locks */ -extern int logoff; /* Don't write history entry */ -extern int require_real_user; /* skip CVSROOT/passwd, /etc/passwd users only*/ - -extern int top_level_admin; - - -#define LOGMSG_REREAD_NEVER 0 /* do_verify - never reread message */ -#define LOGMSG_REREAD_ALWAYS 1 /* do_verify - always reread message */ -#define LOGMSG_REREAD_STAT 2 /* do_verify - reread message if changed */ -extern int RereadLogAfterVerify; - -#ifdef CLIENT_SUPPORT -extern List *dirs_sent_to_server; /* used to decide which "Argument - xxx" commands to send to each - server in multiroot mode. */ -#endif - -extern char hostname[]; - -/* Externs that are included directly in the CVS sources */ - -int RCS_merge PROTO((RCSNode *, const char *, const char *, const char *, - const char *, const char *)); -/* Flags used by RCS_* functions. See the description of the individual - functions for which flags mean what for each function. */ -#define RCS_FLAGS_FORCE 1 -#define RCS_FLAGS_DEAD 2 -#define RCS_FLAGS_QUIET 4 -#define RCS_FLAGS_MODTIME 8 -#define RCS_FLAGS_KEEPFILE 16 -#define RCS_FLAGS_USETIME 32 - -extern int RCS_exec_rcsdiff PROTO ((RCSNode *rcsfile, int diff_argc, - char *const *diff_argv, - const char *options, - const char *rev1, const char *rev1_cache, - const char *rev2, const char *label1, - const char *label2, const char *workfile)); -extern int diff_exec PROTO ((const char *file1, const char *file2, - const char *label1, const char *label2, - int diff_argc, char *const *diff_argv, - const char *out)); - - -#include "error.h" - -DBM *open_module PROTO((void)); -FILE *open_file PROTO((const char *, const char *)); -List *Find_Directories PROTO((char *repository, int which, List *entries)); -void Entries_Close PROTO((List *entries)); -List *Entries_Open PROTO ((int aflag, char *update_dir)); -void Subdirs_Known PROTO((List *entries)); -void Subdir_Register PROTO((List *, const char *, const char *)); -void Subdir_Deregister PROTO((List *, const char *, const char *)); - -char *Make_Date PROTO((char *rawdate)); -char *date_from_time_t PROTO ((time_t)); -void date_to_internet PROTO ((char *, const char *)); -void date_to_tm PROTO ((struct tm *, const char *)); -void tm_to_internet PROTO ((char *, const struct tm *)); - -char *Name_Repository PROTO((const char *dir, const char *update_dir)); -const char *Short_Repository PROTO((const char *repository)); -void Sanitize_Repository_Name PROTO((char *repository)); - -char *previous_rev PROTO ((RCSNode *rcs, const char *rev)); -char *gca PROTO ((const char *rev1, const char *rev2)); -extern void check_numeric PROTO ((const char *, int, char **)); -char *getcaller PROTO ((void)); -char *time_stamp PROTO ((const char *file)); - -void *xmalloc PROTO((size_t bytes)); -void *xrealloc PROTO((void *ptr, size_t bytes)); -void expand_string PROTO ((char **, size_t *, size_t)); -void xrealloc_and_strcat PROTO ((char **, size_t *, const char *)); -char *xstrdup PROTO((const char *str)); -int strip_trailing_newlines PROTO((char *str)); -int pathname_levels PROTO ((const char *path)); - -typedef int (*CALLPROC) PROTO((const char *repository, const char *value)); -int Parse_Info PROTO((const char *infofile, const char *repository, - CALLPROC callproc, int all)); -extern int parse_config PROTO ((char *)); - -typedef RETSIGTYPE (*SIGCLEANUPPROC) PROTO(()); -int SIG_register PROTO((int sig, SIGCLEANUPPROC sigcleanup)); -int isdir PROTO((const char *file)); -int isfile PROTO((const char *file)); -int islink PROTO((const char *file)); -int isdevice PROTO ((const char *)); -int isreadable PROTO((const char *file)); -int iswritable PROTO((const char *file)); -int isaccessible PROTO((const char *file, const int mode)); -int isabsolute PROTO((const char *filename)); -#ifdef HAVE_READLINK -char *xreadlink PROTO((const char *link)); -#endif -char *xresolvepath PROTO((const char *path)); -const char *last_component PROTO((const char *path)); -char *get_homedir PROTO ((void)); -char *strcat_filename_onto_homedir PROTO ((const char *, const char *)); -char *cvs_temp_name PROTO ((void)); -FILE *cvs_temp_file PROTO ((char **filename)); -void parseopts PROTO ((const char *root)); - -int numdots PROTO((const char *s)); -char *increment_revnum PROTO ((const char *)); -int compare_revnums PROTO ((const char *, const char *)); -int unlink_file PROTO((const char *f)); -int unlink_file_dir PROTO((const char *f)); - - - -/* This is the structure that the recursion processor passes to the - fileproc to tell it about a particular file. */ -struct file_info -{ - /* Name of the file, without any directory component. */ - const char *file; - - /* Name of the directory we are in, relative to the directory in - which this command was issued. We have cd'd to this directory - (either in the working directory or in the repository, depending - on which sort of recursion we are doing). If we are in the directory - in which the command was issued, this is "". */ - const char *update_dir; - - /* update_dir and file put together, with a slash between them as - necessary. This is the proper way to refer to the file in user - messages. */ - const char *fullname; - - /* Name of the directory corresponding to the repository which contains - this file. */ - const char *repository; - - /* The pre-parsed entries for this directory. */ - List *entries; - - RCSNode *rcs; -}; - - - -int update PROTO((int argc, char *argv[])); -/* The only place this is currently used outside of update.c is add.c. - * Restricting its use to update.c seems to be in the best interest of - * modularity, but I can't think of a good way to get an update of a - * resurrected file done and print the fact otherwise. - */ -void write_letter PROTO ((struct file_info *finfo, int letter)); -int xcmp PROTO((const char *file1, const char *file2)); -int yesno PROTO((void)); -void *valloc PROTO((size_t bytes)); -time_t get_date PROTO((char *date, struct timeb *now)); -extern int Create_Admin PROTO ((const char *dir, const char *update_dir, - const char *repository, const char *tag, - const char *date, - int nonbranch, int warn, int dotemplate)); -extern int expand_at_signs PROTO ((const char *, off_t, FILE *)); - -/* Locking subsystem (implemented in lock.c). */ - -int Reader_Lock PROTO((char *xrepository)); -void Lock_Cleanup PROTO((void)); - -/* Writelock an entire subtree, well the part specified by ARGC, ARGV, LOCAL, - and AFLAG, anyway. */ -void lock_tree_for_write PROTO ((int argc, char **argv, int local, int which, - int aflag)); - -/* See lock.c for description. */ -extern void lock_dir_for_write PROTO ((char *)); - -/* Get a write lock for the history file. */ -int history_lock PROTO ((const char *)); -void clear_history_lock PROTO ((void)); - -/* Get a write lock for the val-tags file. */ -int val_tags_lock PROTO ((const char *)); -void clear_val_tags_lock PROTO ((void)); - -/* LockDir setting from CVSROOT/config. */ -extern char *lock_dir; - -void Scratch_Entry PROTO((List * list, const char *fname)); -void ParseTag PROTO((char **tagp, char **datep, int *nonbranchp)); -void WriteTag PROTO ((const char *dir, const char *tag, const char *date, - int nonbranch, const char *update_dir, - const char *repository)); -void WriteTemplate PROTO ((const char *dir, const char *update_dir)); -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 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)); -void ign_add PROTO((char *ign, int hold)); -void ign_add_file PROTO((char *file, int hold)); -void ign_setup PROTO((void)); -void ign_dir_add PROTO((char *name)); -int ignore_directory PROTO((const char *name)); -typedef void (*Ignore_proc) PROTO ((const char *, const char *)); -extern void ignore_files PROTO ((List *, List *, const char *, Ignore_proc)); -extern int ign_inhibit_server; - -#include "update.h" - -void line2argv PROTO ((int *pargc, char ***argv, char *line, char *sepchars)); -void make_directories PROTO((const char *name)); -void make_directory PROTO((const char *name)); -extern int mkdir_if_needed PROTO ((const char *name)); -void rename_file PROTO((const char *from, const char *to)); -/* Expand wildcards in each element of (ARGC,ARGV). This is according to the - files which exist in the current directory, and accordingly to OS-specific - conventions regarding wildcard syntax. It might be desirable to change the - former in the future (e.g. "cvs status *.h" including files which don't exist - in the working directory). The result is placed in *PARGC and *PARGV; - the *PARGV array itself and all the strings it contains are newly - malloc'd. It is OK to call it with PARGC == &ARGC or PARGV == &ARGV. */ -extern void expand_wild PROTO ((int argc, char **argv, - int *pargc, char ***pargv)); - -#ifdef SERVER_SUPPORT -extern int cvs_casecmp PROTO ((const char *, const char *)); -#endif - -void strip_trailing_slashes PROTO((char *path)); -void update_delproc PROTO((Node * p)); -void usage PROTO((const char *const *cpp)); -void xchmod PROTO((const char *fname, int writable)); -char *xgetwd PROTO((void)); -List *Find_Names PROTO((char *repository, int which, int aflag, - List **optentries)); -void Register PROTO((List * list, const char *fname, const char *vn, - const char *ts, const char *options, const char *tag, - const char *date, const char *ts_conflict)); -void Update_Logfile PROTO((const char *repository, const char *xmessage, - FILE * xlogfp, List * xchanges)); -void do_editor PROTO((const char *dir, char **messagep, - const char *repository, List * changes)); - -void do_verify PROTO((char **messagep, const char *repository)); - -typedef int (*CALLBACKPROC) PROTO((int argc, char *argv[], char *where, - char *mwhere, char *mfile, int shorten, int local_specified, - char *omodule, char *msg)); - -typedef int (*FILEPROC) PROTO ((void *callerdat, struct file_info *finfo)); -typedef int (*FILESDONEPROC) PROTO ((void *callerdat, int err, - const char *repository, - const char *update_dir, - List *entries)); -typedef Dtype (*DIRENTPROC) PROTO ((void *callerdat, const char *dir, - const char *repos, const char *update_dir, - List *entries)); -typedef int (*DIRLEAVEPROC) PROTO ((void *callerdat, const char *dir, int err, - const char *update_dir, List *entries)); - -extern int mkmodules PROTO ((char *dir)); -extern int init PROTO ((int argc, char **argv)); - -int do_module PROTO((DBM * db, char *mname, enum mtype m_type, char *msg, - CALLBACKPROC callback_proc, char *where, int shorten, - int local_specified, int run_module_prog, int build_dirs, - char *extra_arg)); -void history_write PROTO((int type, const char *update_dir, const char *revs, - const char *name, const char *repository)); -int start_recursion PROTO((FILEPROC fileproc, FILESDONEPROC filesdoneproc, - DIRENTPROC direntproc, DIRLEAVEPROC dirleaveproc, - void *callerdat, - int argc, char *argv[], int local, int which, - int aflag, int locktype, char *update_preload, - int dosrcs, char *repository)); -void SIG_beginCrSect PROTO((void)); -void SIG_endCrSect PROTO((void)); -int SIG_inCrSect PROTO((void)); -void read_cvsrc PROTO((int *argc, char ***argv, const char *cmdname)); - -char *make_message_rcslegal PROTO((const char *message)); -extern int file_has_markers PROTO ((const struct file_info *)); -extern void get_file PROTO ((const char *, const char *, const char *, - char **, size_t *, size_t *)); -extern char *shell_escape PROTO((char *buf, const char *str)); -char *backup_file PROTO((const char *file, const char *suffix)); -extern void resolve_symlink PROTO ((char **filename)); -void sleep_past PROTO ((time_t desttime)); - -/* flags for run_exec(), the fast system() for CVS */ -#define RUN_NORMAL 0x0000 /* no special behaviour */ -#define RUN_COMBINED 0x0001 /* stdout is duped to stderr */ -#define RUN_REALLY 0x0002 /* do the exec, even if noexec is on */ -#define RUN_STDOUT_APPEND 0x0004 /* append to stdout, don't truncate */ -#define RUN_STDERR_APPEND 0x0008 /* append to stderr, don't truncate */ -#define RUN_SIGIGNORE 0x0010 /* ignore interrupts for command */ -#define RUN_TTY (char *)0 /* for the benefit of lint */ - -void run_add_arg_p PROTO ((int *, size_t *, char ***, const char *s)); -void run_arg_free_p PROTO ((int, char **)); -void run_arg PROTO((const char *s)); -void run_print PROTO((FILE * fp)); -void run_setup PROTO ((const char *prog)); -int run_exec PROTO((const char *stin, const char *stout, const char *sterr, - int flags)); - -/* other similar-minded stuff from run.c. */ -FILE *run_popen PROTO((const char *, const char *)); -int piped_child PROTO((const char **, int *, int *, int)); -void close_on_exec PROTO((int)); - -pid_t waitpid PROTO((pid_t, int *, int)); - -/* - * a struct vers_ts contains all the information about a file including the - * user and rcs file names, and the version checked out and the head. - * - * this is usually obtained from a call to Version_TS which takes a - * tag argument for the RCS file if desired - */ -struct vers_ts -{ - /* rcs version user file derives from, from CVS/Entries. - It can have the following special values: - - NULL = file is not mentioned in Entries (this is also used for a - directory). - "" = ILLEGAL! The comment used to say that it meant "no user file" - but as far as I know CVS didn't actually use it that way. - Note that according to cvs.texinfo, "" is not legal in the - Entries file. - 0 = user file is new - -vers = user file to be removed. */ - char *vn_user; - - /* Numeric revision number corresponding to ->vn_tag (->vn_tag - will often be symbolic). */ - char *vn_rcs; - /* If ->tag is a simple tag in the RCS file--a tag which really - exists which is not a magic revision--and if ->date is NULL, - then this is a copy of ->tag. Otherwise, it is a copy of - ->vn_rcs. */ - char *vn_tag; - - /* This is the timestamp from stating the file in the working directory. - It is NULL if there is no file in the working directory. It is - "Is-modified" if we know the file is modified but don't have its - contents. */ - char *ts_user; - /* Timestamp from CVS/Entries. For the server, ts_user and ts_rcs - are computed in a slightly different way, but the fact remains that - if they are equal the file in the working directory is unmodified - and if they differ it is modified. */ - char *ts_rcs; - - /* Options from CVS/Entries (keyword expansion), malloc'd. If none, - then it is an empty string (never NULL). */ - char *options; - - /* If non-NULL, there was a conflict (or merely a merge? See merge_file) - and the time stamp in this field is the time stamp of the working - directory file which was created with the conflict markers in it. - This is from CVS/Entries. */ - char *ts_conflict; - - /* Tag specified on the command line, or if none, tag stored in - CVS/Entries. */ - char *tag; - /* Date specified on the command line, or if none, date stored in - CVS/Entries. */ - char *date; - /* If this is 1, then tag is not a branch tag. If this is 0, then - tag may or may not be a branch tag. */ - int nonbranch; - - /* Pointer to entries file node */ - Entnode *entdata; - - /* Pointer to parsed src file info */ - RCSNode *srcfile; -}; -typedef struct vers_ts Vers_TS; - -Vers_TS *Version_TS PROTO ((struct file_info *finfo, char *options, char *tag, - char *date, int force_tag_match, - int set_time)); -void freevers_ts PROTO ((Vers_TS ** versp)); - -/* Miscellaneous CVS infrastructure which layers on top of the recursion - processor (for example, needs struct file_info). */ - -int Checkin PROTO ((int type, struct file_info *finfo, char *rev, - char *tag, char *options, char *message)); -int No_Difference PROTO ((struct file_info *finfo, Vers_TS *vers)); -/* TODO: can the finfo argument to special_file_mismatch be changed? -twp */ -int special_file_mismatch PROTO ((struct file_info *finfo, - char *rev1, char *rev2)); - -/* CVSADM_BASEREV stuff, from entries.c. */ -extern char *base_get PROTO ((struct file_info *)); -extern void base_register PROTO ((struct file_info *, char *)); -extern void base_deregister PROTO ((struct file_info *)); - -/* - * defines for Classify_File() to determine the current state of a file. - * These are also used as types in the data field for the list we make for - * Update_Logfile in commit, import, and add. - */ -enum classify_type -{ - T_UNKNOWN = 1, /* no old-style analog existed */ - T_CONFLICT, /* C (conflict) list */ - T_NEEDS_MERGE, /* G (needs merging) list */ - T_MODIFIED, /* M (needs checked in) list */ - T_CHECKOUT, /* O (needs checkout) list */ - T_ADDED, /* A (added file) list */ - T_REMOVED, /* R (removed file) list */ - T_REMOVE_ENTRY, /* W (removed entry) list */ - T_UPTODATE, /* File is up-to-date */ - T_PATCH, /* P Like C, but can patch */ - T_TITLE /* title for node type */ -}; -typedef enum classify_type Ctype; - -Ctype Classify_File PROTO - ((struct file_info *finfo, char *tag, char *date, char *options, - int force_tag_match, int aflag, Vers_TS **versp, int pipeout)); - -/* - * structure used for list nodes passed to Update_Logfile() and - * do_editor(). - */ -struct logfile_info -{ - enum classify_type type; - char *tag; - char *rev_old; /* rev number before a commit/modify, - NULL for add or import */ - char *rev_new; /* rev number after a commit/modify, - add, or import, NULL for remove */ -}; - -/* Wrappers. */ - -typedef enum { WRAP_MERGE, WRAP_COPY } WrapMergeMethod; -typedef enum { - /* -t and -f wrapper options. Treating directories as single files. */ - WRAP_TOCVS, - WRAP_FROMCVS, - /* -k wrapper option. Default keyword expansion options. */ - WRAP_RCSOPTION -} WrapMergeHas; - -void wrap_setup PROTO((void)); -int wrap_name_has PROTO((const char *name,WrapMergeHas has)); -char *wrap_rcsoption PROTO ((const char *fileName, int asFlag)); -char *wrap_tocvs_process_file PROTO((const char *fileName)); -int wrap_merge_is_copy PROTO((const char *fileName)); -void wrap_fromcvs_process_file PROTO ((const char *fileName)); -void wrap_add_file PROTO((const char *file,int temp)); -void wrap_add PROTO((char *line,int temp)); -void wrap_send PROTO ((void)); -#if defined(SERVER_SUPPORT) || defined(CLIENT_SUPPORT) -void wrap_unparse_rcs_options PROTO ((char **, int)); -#endif /* SERVER_SUPPORT || CLIENT_SUPPORT */ - -/* Pathname expansion */ -char *expand_path PROTO((const char *name, const char *file, int line)); - -/* User variables. */ -extern List *variable_list; - -extern void variable_set PROTO ((char *nameval)); - -int watch PROTO ((int argc, char **argv)); -int edit PROTO ((int argc, char **argv)); -int unedit PROTO ((int argc, char **argv)); -int editors PROTO ((int argc, char **argv)); -int watchers PROTO ((int argc, char **argv)); -extern int annotate PROTO ((int argc, char **argv)); -extern int add PROTO ((int argc, char **argv)); -extern int admin PROTO ((int argc, char **argv)); -extern int checkout PROTO ((int argc, char **argv)); -extern int commit PROTO ((int argc, char **argv)); -extern int diff PROTO ((int argc, char **argv)); -extern int history PROTO ((int argc, char **argv)); -extern int import PROTO ((int argc, char **argv)); -extern int cvslog PROTO ((int argc, char **argv)); -#ifdef AUTH_CLIENT_SUPPORT -/* Some systems (namely Mac OS X) have conflicting definitions for these - * functions. Avoid them. - */ -#ifdef HAVE_LOGIN -# define login cvs_login -#endif /* HAVE_LOGIN */ -#ifdef HAVE_LOGOUT -# define logout cvs_logout -#endif /* HAVE_LOGOUT */ -extern int login PROTO((int argc, char **argv)); -extern int logout PROTO((int argc, char **argv)); -#endif /* AUTH_CLIENT_SUPPORT */ -extern int patch PROTO((int argc, char **argv)); -extern int release PROTO((int argc, char **argv)); -extern int cvsremove PROTO((int argc, char **argv)); -extern int rtag PROTO((int argc, char **argv)); -extern int 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 *)); - -#if defined(AUTH_CLIENT_SUPPORT) || defined(AUTH_SERVER_SUPPORT) -char *scramble PROTO ((char *str)); -char *descramble PROTO ((char *str)); -#endif /* AUTH_CLIENT_SUPPORT || AUTH_SERVER_SUPPORT */ - -#ifdef AUTH_CLIENT_SUPPORT -char *get_cvs_password PROTO((void)); -void free_cvs_password PROTO((char *str)); -int get_cvs_port_number PROTO((const cvsroot_t *root)); -char *normalize_cvsroot PROTO((const cvsroot_t *root)); -#endif /* AUTH_CLIENT_SUPPORT */ - -extern void tag_check_valid PROTO ((char *, int, char **, int, int, char *)); -extern void tag_check_valid_join PROTO ((char *, int, char **, int, int, - char *)); - -#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)); -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 ((const char *, const char *)); diff --git a/contrib/cvs/src/cvsbug.in b/contrib/cvs/src/cvsbug.in deleted file mode 100755 index 07de151..0000000 --- a/contrib/cvs/src/cvsbug.in +++ /dev/null @@ -1,525 +0,0 @@ -#! /bin/sh -# Submit a problem report to a GNATS site. -# Copyright (C) 1993 Free Software Foundation, Inc. -# Contributed by Brendan Kehoe (brendan@cygnus.com), based on a -# version written by Heinz G. Seidl (hgs@ide.com). -# -# This file is part of GNU GNATS. -# Modified by Berliner for CVS. -# -# GNU GNATS is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. -# -# GNU GNATS 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. - -# The version of this send-pr. -VERSION=3.2 - -# The submitter-id for your site. -SUBMITTER=net - -## # Where the GNATS directory lives, if at all. -## [ -z "$GNATS_ROOT" ] && -## GNATS_ROOT=/usr/local/lib/gnats/gnats-db - -# The default mail address for PR submissions. -GNATS_ADDR=@PACKAGE_BUGREPORT@ - -## # Where the gnats category tree lives. -## DATADIR=/usr/local/lib - -## # If we've been moved around, try using GCC_EXEC_PREFIX. -## [ ! -d $DATADIR/gnats -a -d "$GCC_EXEC_PREFIX" ] && DATADIR=${GCC_EXEC_PREFIX}.. - -# The default release for this host. -DEFAULT_RELEASE="@VERSION@" - -# The default organization. -DEFAULT_ORGANIZATION="net" - -## # The default site to look for. -## GNATS_SITE=unknown - -## # Newer config information? -## [ -f ${GNATS_ROOT}/gnats-adm/config ] && . ${GNATS_ROOT}/gnats-adm/config - -# Hack mktemp on systems that don't have it. -@MKTEMP_SH_FUNCTION@ -MKTEMP="@MKTEMP@" - -# What mailer to use. This must come after the config file, since it is -# host-dependent. -SENDMAIL="@SENDMAIL@" -MAIL_AGENT="$SENDMAIL -oi -t" -MAILER=`echo $MAIL_AGENT | sed -e 's, .*,,'` -if [ ! -f "$MAILER" ] ; then - echo "$COMMAND: Cannot find mail program \"$MAILER\"." - echo "$COMMAND: Please fix the MAIL_AGENT entry in the $COMMAND file." - exit 1 -fi - -if test "`echo -n foo`" = foo ; then - ECHON=bsd -elif test "`echo 'foo\c'`" = foo ; then - ECHON=sysv -else - ECHON=none -fi - -if [ $ECHON = bsd ] ; then - ECHON1="echo -n" - ECHON2= -elif [ $ECHON = sysv ] ; then - ECHON1=echo - ECHON2='\c' -else - ECHON1=echo - ECHON2= -fi - -# - -[ -z "$TMPDIR" ] && TMPDIR=/tmp - -TEMP="`$MKTEMP $TMPDIR/p.XXXXXX`" -BAD="`$MKTEMP $TMPDIR/pbad.XXXXXX`" -REF="`$MKTEMP $TMPDIR/pf.XXXXXX`" - -if [ -z "$LOGNAME" -a -n "$USER" ]; then - LOGNAME=$USER -fi - -FROM="$LOGNAME" -REPLY_TO="$LOGNAME" - -# Find out the name of the originator of this PR. -if [ -n "$NAME" ]; then - ORIGINATOR="$NAME" -elif [ -f $HOME/.fullname ]; then - ORIGINATOR="`sed -e '1q' $HOME/.fullname`" -elif [ -f /bin/domainname ]; then - if [ "`/bin/domainname`" != "" -a -f /usr/bin/ypcat ]; then - # Must use temp file due to incompatibilities in quoting behavior - # and to protect shell metacharacters in the expansion of $LOGNAME - /usr/bin/ypcat passwd 2>/dev/null | cat - /etc/passwd | grep "^$LOGNAME:" | - cut -f5 -d':' | sed -e 's/,.*//' > $TEMP - ORIGINATOR="`cat $TEMP`" - fi -fi - -if [ "$ORIGINATOR" = "" ]; then - grep "^$LOGNAME:" /etc/passwd | cut -f5 -d':' | sed -e 's/,.*//' > $TEMP - ORIGINATOR="`cat $TEMP`" -fi - -if [ -n "$ORGANIZATION" ]; then - if [ -f "$ORGANIZATION" ]; then - ORGANIZATION="`cat $ORGANIZATION`" - fi -else - if [ -n "$DEFAULT_ORGANIZATION" ]; then - ORGANIZATION="$DEFAULT_ORGANIZATION" - elif [ -f $HOME/.organization ]; then - ORGANIZATION="`cat $HOME/.organization`" - elif [ -f $HOME/.signature ]; then - ORGANIZATION="`cat $HOME/.signature`" - fi -fi - -# If they don't have a preferred editor set, then use -if [ -z "$VISUAL" ]; then - if [ -z "$EDITOR" ]; then - EDIT=vi - else - EDIT="$EDITOR" - fi -else - EDIT="$VISUAL" -fi - -# Find out some information. -SYSTEM=`( [ -f /bin/uname ] && /bin/uname -a ) || \ - ( [ -f /usr/bin/uname ] && /usr/bin/uname -a ) || echo ""` -ARCH=`[ -f /bin/arch ] && /bin/arch` -MACHINE=`[ -f /bin/machine ] && /bin/machine` - -COMMAND=`echo $0 | sed -e 's,.*/,,'` -## USAGE="Usage: $COMMAND [-PVL] [-t address] [-f filename] [--request-id] -USAGE="Usage: $COMMAND [-PVL] -[--version]" -REMOVE= -BATCH= - -while [ $# -gt 0 ]; do - case "$1" in - -r) ;; # Ignore for backward compat. -## -t | --to) if [ $# -eq 1 ]; then echo "$USAGE"; exit 1; fi -## shift ; GNATS_ADDR="$1" -## EXPLICIT_GNATS_ADDR=true -## ;; -## -f | --file) if [ $# -eq 1 ]; then echo "$USAGE"; exit 1; fi -## shift ; IN_FILE="$1" -## if [ "$IN_FILE" != "-" -a ! -r "$IN_FILE" ]; then -## echo "$COMMAND: cannot read $IN_FILE" -## exit 1 -## fi -## ;; - -b | --batch) BATCH=true ;; - -p | -P | --print) PRINT=true ;; - -L | --list) FORMAT=norm ;; - -l | -CL | --lisp) FORMAT=lisp ;; -## --request-id) REQUEST_ID=true ;; - -h | --help) echo "$USAGE"; exit 0 ;; - -V | --version) echo "$VERSION"; exit 0 ;; - -*) echo "$USAGE" ; exit 1 ;; - *) echo "$USAGE" ; exit 1 -## if [ -z "$USER_GNATS_SITE" ]; then -## if [ ! -r "$DATADIR/gnats/$1" ]; then -## echo "$COMMAND: the GNATS site $1 does not have a categories list." -## exit 1 -## else -## # The site name is the alias they'll have to have created. -## USER_GNATS_SITE=$1 -## fi -## else -## echo "$USAGE" ; exit 1 -## fi - ;; - esac - shift -done - -if [ -n "$USER_GNATS_SITE" ]; then - GNATS_SITE=$USER_GNATS_SITE - GNATS_ADDR=$USER_GNATS_SITE-gnats -fi - -if [ "$SUBMITTER" = "unknown" -a -z "$REQUEST_ID" -a -z "$IN_FILE" ]; then - cat << '__EOF__' -It seems that send-pr is not installed with your unique submitter-id. -You need to run - - install-sid YOUR-SID - -where YOUR-SID is the identification code you received with `send-pr'. -`send-pr' will automatically insert this value into the template field -`>Submitter-Id'. If you've downloaded `send-pr' from the Net, use `net' -for this value. If you do not know your id, run `send-pr --request-id' to -get one from your support site. -__EOF__ - exit 1 -fi - -## if [ -r "$DATADIR/gnats/$GNATS_SITE" ]; then -## CATEGORIES=`grep -v '^#' $DATADIR/gnats/$GNATS_SITE | sort` -## else -## echo "$COMMAND: could not read $DATADIR/gnats/$GNATS_SITE for categories list." -## exit 1 -## fi -CATEGORIES="contrib cvs doc pcl-cvs portability" - -if [ -z "$CATEGORIES" ]; then - echo "$COMMAND: the categories list for $GNATS_SITE was empty!" - exit 1 -fi - -case "$FORMAT" in - lisp) echo "$CATEGORIES" | \ - awk 'BEGIN {printf "( "} - {printf "(\"%s\") ",$0} - END {printf ")\n"}' - exit 0 - ;; - norm) l=`echo "$CATEGORIES" | \ - awk 'BEGIN {max = 0; } - { if (length($0) > max) { max = length($0); } } - END {print max + 1;}'` - c=`expr 70 / $l` - if [ $c -eq 0 ]; then c=1; fi - echo "$CATEGORIES" | \ - awk 'BEGIN {print "Known categories:"; i = 0 } - { printf ("%-'$l'.'$l's", $0); if ((++i % '$c') == 0) { print "" } } - END { print ""; }' - exit 0 - ;; -esac - -ORIGINATOR_C='' -ORGANIZATION_C='' -CONFIDENTIAL_C='<[ yes | no ] (one line)>' -SYNOPSIS_C='' -SEVERITY_C='<[ non-critical | serious | critical ] (one line)>' -PRIORITY_C='<[ low | medium | high ] (one line)>' -CATEGORY_C='' -CLASS_C='<[ sw-bug | doc-bug | change-request | support ] (one line)>' -RELEASE_C='' -ENVIRONMENT_C='' -DESCRIPTION_C='' -HOW_TO_REPEAT_C='' -FIX_C='' - -# Catch some signals. ($xs kludge needed by Sun /bin/sh) -xs=0 -trap 'rm -f $REF $TEMP; exit $xs' 0 -trap 'echo "$COMMAND: Aborting ..."; rm -f $REF $TEMP; xs=1; exit' 1 2 3 13 15 - -# If they told us to use a specific file, then do so. -if [ -n "$IN_FILE" ]; then - if [ "$IN_FILE" = "-" ]; then - # The PR is coming from the standard input. - if [ -n "$EXPLICIT_GNATS_ADDR" ]; then - sed -e "s;^[Tt][Oo]:.*;To: $GNATS_ADDR;" > $TEMP - else - cat > $TEMP - fi - else - # Use the file they named. - if [ -n "$EXPLICIT_GNATS_ADDR" ]; then - sed -e "s;^[Tt][Oo]:.*;To: $GNATS_ADDR;" $IN_FILE > $TEMP - else - cat $IN_FILE > $TEMP - fi - fi -else - - if [ -n "$PR_FORM" -a -z "$PRINT_INTERN" ]; then - # If their PR_FORM points to a bogus entry, then bail. - if [ ! -f "$PR_FORM" -o ! -r "$PR_FORM" -o ! -s "$PR_FORM" ]; then - echo "$COMMAND: can't seem to read your template file (\`$PR_FORM'), ignoring PR_FORM" - sleep 1 - PRINT_INTERN=bad_prform - fi - fi - - if [ -n "$PR_FORM" -a -z "$PRINT_INTERN" ]; then - cp $PR_FORM $TEMP || - ( echo "$COMMAND: could not copy $PR_FORM" ; xs=1; exit ) - else - for file in $TEMP $REF ; do - cat > $file << '__EOF__' -SEND-PR: -*- send-pr -*- -SEND-PR: Lines starting with `SEND-PR' will be removed automatically, as -SEND-PR: will all comments (text enclosed in `<' and `>'). -SEND-PR: -SEND-PR: Choose from the following categories: -SEND-PR: -__EOF__ - - # Format the categories so they fit onto lines. - l=`echo "$CATEGORIES" | \ - awk 'BEGIN {max = 0; } - { if (length($0) > max) { max = length($0); } } - END {print max + 1;}'` - c=`expr 61 / $l` - if [ $c -eq 0 ]; then c=1; fi - echo "$CATEGORIES" | \ - awk 'BEGIN {printf "SEND-PR: "; i = 0 } - { printf ("%-'$l'.'$l's", $0); - if ((++i % '$c') == 0) { printf "\nSEND-PR: " } } - END { printf "\nSEND-PR:\n"; }' >> $file - - cat >> $file << __EOF__ -To: $GNATS_ADDR -Subject: -From: $FROM -Reply-To: $REPLY_TO -X-send-pr-version: $VERSION - - ->Submitter-Id: $SUBMITTER ->Originator: $ORIGINATOR ->Organization: -${ORGANIZATION-$ORGANIZATION_C} ->Confidential: $CONFIDENTIAL_C ->Synopsis: $SYNOPSIS_C ->Severity: $SEVERITY_C ->Priority: $PRIORITY_C ->Category: $CATEGORY_C ->Class: $CLASS_C ->Release: ${DEFAULT_RELEASE-$RELEASE_C} ->Environment: - $ENVIRONMENT_C -`[ -n "$SYSTEM" ] && echo System: $SYSTEM` -`[ -n "$ARCH" ] && echo Architecture: $ARCH` -`[ -n "$MACHINE" ] && echo Machine: $MACHINE` ->Description: - $DESCRIPTION_C ->How-To-Repeat: - $HOW_TO_REPEAT_C ->Fix: - $FIX_C -__EOF__ - done - fi - - if [ "$PRINT" = true -o "$PRINT_INTERN" = true ]; then - cat $TEMP - xs=0; exit - fi - - chmod u+w $TEMP - if [ -z "$REQUEST_ID" ]; then - eval $EDIT $TEMP - else - ed -s $TEMP << '__EOF__' -/^Subject/s/^Subject:.*/Subject: request for a customer id/ -/^>Category/s/^>Category:.*/>Category: send-pr/ -w -q -__EOF__ - fi - - if cmp -s $REF $TEMP ; then - echo "$COMMAND: problem report not filled out, therefore not sent" - xs=1; exit - fi -fi - -# -# Check the enumeration fields - -# This is a "sed-subroutine" with one keyword parameter -# (with workaround for Sun sed bug) -# -SED_CMD=' -/$PATTERN/{ -s||| -s|<.*>|| -s|^[ ]*|| -s|[ ]*$|| -p -q -}' - - -while [ -z "$REQUEST_ID" ]; do - CNT=0 - - # 1) Confidential - # - PATTERN=">Confidential:" - CONFIDENTIAL=`eval sed -n -e "\"$SED_CMD\"" $TEMP` - case "$CONFIDENTIAL" in - ""|yes|no) CNT=`expr $CNT + 1` ;; - *) echo "$COMMAND: \`$CONFIDENTIAL' is not a valid value for \`Confidential'." ;; - esac - # - # 2) Severity - # - PATTERN=">Severity:" - SEVERITY=`eval sed -n -e "\"$SED_CMD\"" $TEMP` - case "$SEVERITY" in - ""|non-critical|serious|critical) CNT=`expr $CNT + 1` ;; - *) echo "$COMMAND: \`$SEVERITY' is not a valid value for \`Severity'." - esac - # - # 3) Priority - # - PATTERN=">Priority:" - PRIORITY=`eval sed -n -e "\"$SED_CMD\"" $TEMP` - case "$PRIORITY" in - ""|low|medium|high) CNT=`expr $CNT + 1` ;; - *) echo "$COMMAND: \`$PRIORITY' is not a valid value for \`Priority'." - esac - # - # 4) Category - # - PATTERN=">Category:" - CATEGORY=`eval sed -n -e "\"$SED_CMD\"" $TEMP` - FOUND= - for C in $CATEGORIES - do - if [ "$C" = "$CATEGORY" ]; then FOUND=true ; break ; fi - done - if [ -n "$FOUND" ]; then - CNT=`expr $CNT + 1` - else - if [ -z "$CATEGORY" ]; then - echo "$COMMAND: you must include a Category: field in your report." - else - echo "$COMMAND: \`$CATEGORY' is not a known category." - fi - fi - # - # 5) Class - # - PATTERN=">Class:" - CLASS=`eval sed -n -e "\"$SED_CMD\"" $TEMP` - case "$CLASS" in - ""|sw-bug|doc-bug|change-request|support) CNT=`expr $CNT + 1` ;; - *) echo "$COMMAND: \`$CLASS' is not a valid value for \`Class'." - esac - - [ $CNT -lt 5 -a -z "$BATCH" ] && - echo "Errors were found with the problem report." - - while true; do - if [ -z "$BATCH" ]; then - $ECHON1 "a)bort, e)dit or s)end? $ECHON2" - read input - else - if [ $CNT -eq 5 ]; then - input=s - else - input=a - fi - fi - case "$input" in - a*) - if [ -z "$BATCH" ]; then - echo "$COMMAND: the problem report remains in $BAD and is not sent." - mv $TEMP $BAD - else - echo "$COMMAND: the problem report is not sent." - fi - xs=1; exit - ;; - e*) - eval $EDIT $TEMP - continue 2 - ;; - s*) - break 2 - ;; - esac - done -done -# -# Remove comments and send the problem report -# (we have to use patterns, where the comment contains regex chars) -# -# /^>Originator:/s;$ORIGINATOR;; -sed -e " -/^SEND-PR:/d -/^>Organization:/,/^>[A-Za-z-]*:/s;$ORGANIZATION_C;; -/^>Confidential:/s;<.*>;; -/^>Synopsis:/s;$SYNOPSIS_C;; -/^>Severity:/s;<.*>;; -/^>Priority:/s;<.*>;; -/^>Category:/s;$CATEGORY_C;; -/^>Class:/s;<.*>;; -/^>Release:/,/^>[A-Za-z-]*:/s;$RELEASE_C;; -/^>Environment:/,/^>[A-Za-z-]*:/s;$ENVIRONMENT_C;; -/^>Description:/,/^>[A-Za-z-]*:/s;$DESCRIPTION_C;; -/^>How-To-Repeat:/,/^>[A-Za-z-]*:/s;$HOW_TO_REPEAT_C;; -/^>Fix:/,/^>[A-Za-z-]*:/s;$FIX_C;; -" $TEMP > $REF - -if $MAIL_AGENT < $REF; then - echo "$COMMAND: problem report sent" - xs=0; exit -else - echo "$COMMAND: mysterious mail failure." - if [ -z "$BATCH" ]; then - echo "$COMMAND: the problem report remains in $BAD and is not sent." - mv $REF $BAD - else - echo "$COMMAND: the problem report is not sent." - fi - xs=1; exit -fi diff --git a/contrib/cvs/src/cvsrc.c b/contrib/cvs/src/cvsrc.c deleted file mode 100644 index 60de909..0000000 --- a/contrib/cvs/src/cvsrc.c +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Copyright (C) 1986-2005 The Free Software Foundation, Inc. - * - * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot , - * and others. - * - * Portions Copyright (C) 1993 david d zuhn - * - * Written by david d `zoo' zuhn while at Cygnus Support - * - * You may distribute under the terms of the GNU General Public License as - * specified in the README file that comes with the CVS source distribution. - * - */ - - -#include "cvs.h" -#include "getline.h" - -/* this file is to be found in the user's home directory */ - -#ifndef CVSRC_FILENAME -#define CVSRC_FILENAME ".cvsrc" -#endif -char cvsrc[] = CVSRC_FILENAME; - -#define GROW 10 - -extern char *strtok (); - -/* Read cvsrc, processing options matching CMDNAME ("cvs" for global - options, and update *ARGC and *ARGV accordingly. */ - -void -read_cvsrc (argc, argv, cmdname) - int *argc; - char ***argv; - const char *cmdname; -{ - char *homedir; - char *homeinit; - FILE *cvsrcfile; - - char *line; - int line_length; - size_t line_chars_allocated; - - char *optstart; - - int command_len; - int found = 0; - - int i; - - int new_argc; - int max_new_argv; - char **new_argv; - - /* old_argc and old_argv hold the values returned from the - previous invocation of read_cvsrc and are used to free the - allocated memory. The first invocation of read_cvsrc gets argv - from the system, this memory must not be free'd. */ - static int old_argc = 0; - static char **old_argv = NULL; - - /* don't do anything if argc is -1, since that implies "help" mode */ - if (*argc == -1) - return; - - /* determine filename for ~/.cvsrc */ - - homedir = get_homedir (); - /* If we can't find a home directory, ignore ~/.cvsrc. This may - make tracking down problems a bit of a pain, but on the other - hand it might be obnoxious to complain when CVS will function - just fine without .cvsrc (and many users won't even know what - .cvsrc is). */ - if (!homedir) - return; - - homeinit = strcat_filename_onto_homedir (homedir, cvsrc); - - /* if it can't be read, there's no point to continuing */ - - if (!isreadable (homeinit)) - { - free (homeinit); - return; - } - - /* now scan the file until we find the line for the command in question */ - - line = NULL; - line_chars_allocated = 0; - command_len = strlen (cmdname); - cvsrcfile = open_file (homeinit, "r"); - while ((line_length = getline (&line, &line_chars_allocated, cvsrcfile)) - >= 0) - { - /* skip over comment lines */ - if (line[0] == '#') - continue; - - /* stop if we match the current command */ - if (!strncmp (line, cmdname, command_len) - && isspace ((unsigned char) *(line + command_len))) - { - found = 1; - break; - } - } - - if (line_length < 0 && !feof (cvsrcfile)) - error (0, errno, "cannot read %s", homeinit); - - fclose (cvsrcfile); - - /* setup the new options list */ - - new_argc = 1; - max_new_argv = (*argc) + GROW; - new_argv = (char **) xmalloc (max_new_argv * sizeof (char*)); - new_argv[0] = xstrdup ((*argv)[0]); - - if (found) - { - /* skip over command in the options line */ - for (optstart = strtok (line + command_len, "\t \n\r"); - optstart; - optstart = strtok (NULL, "\t \n\r")) - { - new_argv [new_argc++] = xstrdup (optstart); - - if (new_argc >= max_new_argv) - { - max_new_argv += GROW; - new_argv = (char **) xrealloc (new_argv, max_new_argv * sizeof (char*)); - } - } - } - - if (line != NULL) - free (line); - - /* now copy the remaining arguments */ - - if (new_argc + *argc > max_new_argv) - { - max_new_argv = new_argc + *argc; - new_argv = (char **) xrealloc (new_argv, max_new_argv * sizeof (char*)); - } - for (i=1; i < *argc; i++) - { - new_argv [new_argc++] = xstrdup ((*argv)[i]); - } - - if (old_argv != NULL) - { - /* Free the memory which was allocated in the previous - read_cvsrc call. */ - free_names (&old_argc, old_argv); - } - - old_argc = *argc = new_argc; - old_argv = *argv = new_argv; - - free (homeinit); - return; -} diff --git a/contrib/cvs/src/diff.c b/contrib/cvs/src/diff.c deleted file mode 100644 index 8a61f9a..0000000 --- a/contrib/cvs/src/diff.c +++ /dev/null @@ -1,1178 +0,0 @@ -/* - * Copyright (C) 1986-2005 The Free Software Foundation, Inc. - * - * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot , - * and others. - * - * Portions Copyright (C) 1992, Brian Berliner and Jeff Polk - * Portions Copyright (C) 1989-1992, Brian Berliner - * - * You may distribute under the terms of the GNU General Public License as - * specified in the README file that comes with the CVS source distribution. - * - * Difference - * - * Run diff against versions in the repository. Options that are specified are - * passed on directly to "rcsdiff". - * - * Without any file arguments, runs diff against all the currently modified - * files. - * - * $FreeBSD$ - */ - -#include -#include "cvs.h" - -enum diff_file -{ - DIFF_ERROR, - DIFF_ADDED, - DIFF_REMOVED, - DIFF_DIFFERENT, - DIFF_SAME -}; - -static Dtype diff_dirproc PROTO ((void *callerdat, const char *dir, - const char *pos_repos, - const char *update_dir, - List *entries)); -static int diff_filesdoneproc PROTO ((void *callerdat, int err, - const char *repos, - const char *update_dir, - List *entries)); -static int diff_dirleaveproc PROTO ((void *callerdat, const char *dir, - int err, const char *update_dir, - List *entries)); -static enum diff_file diff_file_nodiff PROTO(( struct file_info *finfo, - Vers_TS *vers, - enum diff_file, - char **rev1_cache )); -static int diff_fileproc PROTO ((void *callerdat, struct file_info *finfo)); -static void diff_mark_errors PROTO((int err)); - - -/* Global variables. Would be cleaner if we just put this stuff in a - struct like log.c does. */ - -/* Command line tags, from -r option. Points into argv. */ -static char *diff_rev1, *diff_rev2; -/* Command line dates, from -D option. Malloc'd. */ -static char *diff_date1, *diff_date2; -static char *diff_join1, *diff_join2; -static char *use_rev1, *use_rev2; -static int have_rev1_label, have_rev2_label; - -/* Revision of the user file, if it is unchanged from something in the - repository and we want to use that fact. */ -static char *user_file_rev; - -static char *options; -static char **diff_argv; -static int diff_argc; -static size_t diff_arg_allocated; -static int diff_errors; -static int empty_files = 0; - -static const char *const diff_usage[] = -{ - "Usage: %s %s [-lR] [-k kopt] [format_options]\n", - " [[-r rev1 | -D date1] [-r rev2 | -D date2]] [files...] \n", - "\t-l\tLocal directory only, not recursive\n", - "\t-R\tProcess directories recursively.\n", - "\t-k kopt\tSpecify keyword expansion mode.\n", - "\t-D d1\tDiff revision for date against working file.\n", - "\t-D d2\tDiff rev1/date1 against date2.\n", - "\t-r rev1\tDiff revision for rev1 against working file.\n", - "\t-r rev2\tDiff rev1/date1 against rev2.\n", - "\nformat_options:\n", - " -i --ignore-case Consider upper- and lower-case to be the same.\n", - " -w --ignore-all-space Ignore all white space.\n", - " -b --ignore-space-change Ignore changes in the amount of white space.\n", - " -B --ignore-blank-lines Ignore changes whose lines are all blank.\n", - " -I RE --ignore-matching-lines=RE Ignore changes whose lines all match RE.\n", - " --binary Read and write data in binary mode.\n", - " -a --text Treat all files as text.\n\n", - " -c -C NUM --context[=NUM] Output NUM (default 2) lines of copied context.\n", - " -u -U NUM --unified[=NUM] Output NUM (default 2) lines of unified context.\n", - " -NUM Use NUM context lines.\n", - " -L LABEL --label LABEL Use LABEL instead of file name.\n", - " -p --show-c-function Show which C function each change is in.\n", - " -F RE --show-function-line=RE Show the most recent line matching RE.\n", - " --brief Output only whether files differ.\n", - " -e --ed Output an ed script.\n", - " -f --forward-ed Output something like an ed script in forward order.\n", - " -n --rcs Output an RCS format diff.\n", - " -y --side-by-side Output in two columns.\n", - " -W NUM --width=NUM Output at most NUM (default 130) characters per line.\n", - " --left-column Output only the left column of common lines.\n", - " --suppress-common-lines Do not output common lines.\n", - " --ifdef=NAME Output merged file to show `#ifdef NAME' diffs.\n", - " --GTYPE-group-format=GFMT Similar, but format GTYPE input groups with GFMT.\n", - " --line-format=LFMT Similar, but format all input lines with LFMT.\n", - " --LTYPE-line-format=LFMT Similar, but format LTYPE input lines with LFMT.\n", - " LTYPE is `old', `new', or `unchanged'. GTYPE is LTYPE or `changed'.\n", - " GFMT may contain:\n", - " %%< lines from FILE1\n", - " %%> lines from FILE2\n", - " %%= lines common to FILE1 and FILE2\n", - " %%[-][WIDTH][.[PREC]]{doxX}LETTER printf-style spec for LETTER\n", - " LETTERs are as follows for new group, lower case for old group:\n", - " F first line number\n", - " L last line number\n", - " N number of lines = L-F+1\n", - " E F-1\n", - " M L+1\n", - " LFMT may contain:\n", - " %%L contents of line\n", - " %%l contents of line, excluding any trailing newline\n", - " %%[-][WIDTH][.[PREC]]{doxX}n printf-style spec for input line number\n", - " Either GFMT or LFMT may contain:\n", - " %%%% %%\n", - " %%c'C' the single character C\n", - " %%c'\\OOO' the character with octal code OOO\n\n", - " -t --expand-tabs Expand tabs to spaces in output.\n", - " -T --initial-tab Make tabs line up by prepending a tab.\n\n", - " -N --new-file Treat absent files as empty.\n", - " -s --report-identical-files Report when two files are the same.\n", - " --horizon-lines=NUM Keep NUM lines of the common prefix and suffix.\n", - " -d --minimal Try hard to find a smaller set of changes.\n", - " -H --speed-large-files Assume large files and many scattered small changes.\n", - "\n(Specify the --help global option for a list of other help options)\n", - NULL -}; - -/* I copied this array directly out of diff.c in diffutils 2.7, after - removing the following entries, none of which seem relevant to use - with CVS: - --help - --version (-v) - --recursive (-r) - --unidirectional-new-file (-P) - --starting-file (-S) - --exclude (-x) - --exclude-from (-X) - --sdiff-merge-assist - --paginate (-l) (doesn't work with library callbacks) - - I changed the options which take optional arguments (--context and - --unified) to return a number rather than a letter, so that the - optional argument could be handled more easily. I changed the - --brief and --ifdef options to return numbers, since -q and -D mean - something else to cvs diff. - - The numbers 129- that appear in the fourth element of some entries - tell the big switch in `diff' how to process those options. -- Ian - - The following options, which diff lists as "An alias, no longer - recommended" have been removed: --file-label --entire-new-file - --ascii --print. */ - -static struct option const longopts[] = -{ - {"ignore-blank-lines", 0, 0, 'B'}, - {"context", 2, 0, 143}, - {"ifdef", 1, 0, 131}, - {"show-function-line", 1, 0, 'F'}, - {"speed-large-files", 0, 0, 'H'}, - {"ignore-matching-lines", 1, 0, 'I'}, - {"label", 1, 0, 'L'}, - {"new-file", 0, 0, 'N'}, - {"initial-tab", 0, 0, 'T'}, - {"width", 1, 0, 'W'}, - {"text", 0, 0, 'a'}, - {"ignore-space-change", 0, 0, 'b'}, - {"minimal", 0, 0, 'd'}, - {"ed", 0, 0, 'e'}, - {"forward-ed", 0, 0, 'f'}, - {"ignore-case", 0, 0, 'i'}, - {"rcs", 0, 0, 'n'}, - {"show-c-function", 0, 0, 'p'}, - - /* This is a potentially very useful option, except the output is so - silly. It would be much better for it to look like "cvs rdiff -s" - which displays all the same info, minus quite a few lines of - extraneous garbage. */ - {"brief", 0, 0, 145}, - - {"report-identical-files", 0, 0, 's'}, - {"expand-tabs", 0, 0, 't'}, - {"ignore-all-space", 0, 0, 'w'}, - {"side-by-side", 0, 0, 'y'}, - {"unified", 2, 0, 146}, - {"left-column", 0, 0, 129}, - {"suppress-common-lines", 0, 0, 130}, - {"old-line-format", 1, 0, 132}, - {"new-line-format", 1, 0, 133}, - {"unchanged-line-format", 1, 0, 134}, - {"line-format", 1, 0, 135}, - {"old-group-format", 1, 0, 136}, - {"new-group-format", 1, 0, 137}, - {"unchanged-group-format", 1, 0, 138}, - {"changed-group-format", 1, 0, 139}, - {"horizon-lines", 1, 0, 140}, - {"binary", 0, 0, 142}, - {0, 0, 0, 0} -}; - - - -/* Add one of OPT or LONGOPT, and ARGUMENT, when present, to global DIFF_ARGV. - * - * INPUTS - * opt A character option representation. - * longopt A long option name. - * argument Optional option argument. - * - * GLOBALS - * diff_argc The number of arguments in DIFF_ARGV. - * diff_argv Array of argument strings. - * diff_arg_allocated Allocated length of DIFF_ARGV. - * - * NOTES - * Behavior when both OPT & LONGOPT are provided is undefined. - * - * RETURNS - * Nothing. - */ -static void -add_diff_args (char opt, const char *longopt, const char *argument) -{ - char *tmp; - - /* Add opt or longopt to diff_arv. */ - assert (opt || (longopt && *longopt)); - assert (!(opt && (longopt && *longopt))); - if (opt) - { - tmp = xmalloc (3); - sprintf (tmp, "-%c", opt); - } - else - { - tmp = xmalloc (3 + strlen (longopt)); - sprintf (tmp, "--%s", longopt); - } - run_add_arg_p (&diff_argc, &diff_arg_allocated, &diff_argv, tmp); - free (tmp); - - /* When present, add ARGUMENT to DIFF_ARGV. */ - if (argument) - run_add_arg_p (&diff_argc, &diff_arg_allocated, &diff_argv, argument); -} - - - -/* CVS 1.9 and similar versions seemed to have pretty weird handling - of -y and -T. In the cases where it called rcsdiff, - they would have the meanings mentioned below. In the cases where it - called diff, they would have the meanings mentioned in "longopts". - Noone seems to have missed them, so I think the right thing to do is - just to remove the options altogether (which I have done). - - In the case of -z and -q, "cvs diff" did not accept them even back - when we called rcsdiff (at least, it hasn't accepted them - recently). - - In comparing rcsdiff to the new CVS implementation, I noticed that - the following rcsdiff flags are not handled by CVS diff: - - -y: perform diff even when the requested revisions are the - same revision number - -q: run quietly - -T: preserve modification time on the RCS file - -z: specify timezone for use in file labels - - I think these are not really relevant. -y is undocumented even in - RCS 5.7, and seems like a minor change at best. According to RCS - documentation, -T only applies when a RCS file has been modified - because of lock changes; doesn't CVS sidestep RCS's entire lock - structure? -z seems to be unsupported by CVS diff, and has a - different meaning as a global option anyway. (Adding it could be - a feature, but if it is left out for now, it should not break - anything.) For the purposes of producing output, CVS diff appears - mostly to ignore -q. Maybe this should be fixed, but I think it's - a larger issue than the changes included here. */ - -int -diff (argc, argv) - int argc; - char **argv; -{ - int c, err = 0; - int local = 0; - int which; - int option_index; - - if (argc == -1) - usage (diff_usage); - - have_rev1_label = have_rev2_label = 0; - - /* - * Note that we catch all the valid arguments here, so that we can - * intercept the -r arguments for doing revision diffs; and -l/-R for a - * non-recursive/recursive diff. - */ - - /* Clean out our global variables (multiroot can call us multiple - times and the server can too, if the client sends several - diff commands). */ - if (diff_argc) - { - run_arg_free_p (diff_argc, diff_argv); - diff_argc = 0; - } - diff_rev1 = NULL; - diff_rev2 = NULL; - diff_date1 = NULL; - diff_date2 = NULL; - diff_join1 = NULL; - diff_join2 = NULL; - - optind = 0; - /* FIXME: This should really be allocating an argv to be passed to diff - * later rather than strcatting onto the opts variable. We have some - * handling routines that can already handle most of the argc/argv - * maintenance for us and currently, if anyone were to attempt to pass a - * quoted string in here, it would be split on spaces and tabs on its way - * to diff. - */ - while ((c = getopt_long (argc, argv, - "+abcdefhilnpstuwy0123456789BHNRTC:D:F:I:L:U:W:k:r:j:", - longopts, &option_index)) != -1) - { - switch (c) - { - case 'y': - add_diff_args (0, "side-by-side", NULL); - break; - case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': - case 'h': case 'i': case 'n': case 'p': case 's': case 't': - case 'u': case 'w': - case '0': case '1': case '2': case '3': case '4': case '5': - case '6': case '7': case '8': case '9': - case 'B': case 'H': case 'T': - add_diff_args (c, NULL, NULL); - break; - case 'L': - if (have_rev1_label++) - if (have_rev2_label++) - { - error (0, 0, "extra -L arguments ignored"); - break; - } - /* Fall through. */ - case 'C': case 'F': case 'I': case 'U': case 'W': - add_diff_args (c, NULL, optarg); - break; - case 129: case 130: case 131: case 132: case 133: case 134: - case 135: case 136: case 137: case 138: case 139: case 140: - case 141: case 142: case 143: case 145: case 146: - add_diff_args (0, longopts[option_index].name, - longopts[option_index].has_arg ? optarg : NULL); - break; - case 'R': - local = 0; - break; - case 'l': - local = 1; - break; - case 'k': - if (options) - free (options); - options = RCS_check_kflag (optarg); - break; - case 'j': - { - char *ptr; - char *cpy = strdup(optarg); - - if ((ptr = strchr(optarg, ':')) != NULL) - *ptr++ = 0; - if (diff_rev2 != NULL || diff_date2 != NULL) - error (1, 0, - "no more than two revisions/dates can be specified"); - if (diff_rev1 != NULL || diff_date1 != NULL) { - diff_join2 = cpy; - diff_rev2 = optarg; - diff_date2 = ptr ? Make_Date(ptr) : NULL; - } else { - diff_join1 = cpy; - diff_rev1 = optarg; - diff_date1 = ptr ? Make_Date(ptr) : NULL; - } - } - break; - case 'r': - if (diff_rev2 != NULL || diff_date2 != NULL) - error (1, 0, - "no more than two revisions/dates can be specified"); - if (diff_rev1 != NULL || diff_date1 != NULL) - diff_rev2 = optarg; - else - diff_rev1 = optarg; - break; - case 'D': - if (diff_rev2 != NULL || diff_date2 != NULL) - error (1, 0, - "no more than two revisions/dates can be specified"); - if (diff_rev1 != NULL || diff_date1 != NULL) - diff_date2 = Make_Date (optarg); - else - diff_date1 = Make_Date (optarg); - break; - case 'N': - empty_files = 1; - break; - case '?': - default: - usage (diff_usage); - break; - } - } - argc -= optind; - argv += optind; - - /* make sure options is non-null */ - if (!options) - options = xstrdup (""); - -#ifdef CLIENT_SUPPORT - if (current_parsed_root->isremote) { - /* We're the client side. Fire up the remote server. */ - start_server (); - - ign_setup (); - - if (local) - send_arg("-l"); - if (empty_files) - send_arg("-N"); - send_options (diff_argc, diff_argv); - if (options[0] != '\0') - send_arg (options); - if (diff_join1) - option_with_arg ("-j", diff_join1); - else if (diff_rev1) - option_with_arg ("-r", diff_rev1); - else if (diff_date1) - client_senddate (diff_date1); - - if (diff_join2) - option_with_arg ("-j", diff_join2); - else if (diff_rev2) - option_with_arg ("-r", diff_rev2); - else if (diff_date2) - client_senddate (diff_date2); - send_arg ("--"); - - /* Send the current files unless diffing two revs from the archive */ - if (diff_rev2 == NULL && diff_date2 == NULL) - send_files (argc, argv, local, 0, 0); - else - send_files (argc, argv, local, 0, SEND_NO_CONTENTS); - - send_file_names (argc, argv, SEND_EXPAND_WILD); - - send_to_server ("diff\012", 0); - err = get_responses_and_close (); - } else -#endif - { /* FreeBSD addition - warning idention not changed til matching-} */ - if (diff_rev1 != NULL) - tag_check_valid (diff_rev1, argc, argv, local, 0, ""); - if (diff_rev2 != NULL) - tag_check_valid (diff_rev2, argc, argv, local, 0, ""); - - which = W_LOCAL; - if (diff_rev1 != NULL || diff_date1 != NULL) - which |= W_REPOS | W_ATTIC; - - wrap_setup (); - - /* start the recursion processor */ - err = start_recursion (diff_fileproc, diff_filesdoneproc, diff_dirproc, - diff_dirleaveproc, NULL, argc, argv, local, - which, 0, CVS_LOCK_READ, (char *) NULL, 1, - (char *) NULL); - } /* FreeBSD addition */ - - /* clean up */ - free (options); - options = NULL; - - if (diff_date1 != NULL) - free (diff_date1); - if (diff_date2 != NULL) - free (diff_date2); - if (diff_join1 != NULL) - free (diff_join1); - if (diff_join2 != NULL) - free (diff_join2); - - return (err); -} - -/* - * Do a file diff - */ -/* ARGSUSED */ -static int -diff_fileproc (callerdat, finfo) - void *callerdat; - struct file_info *finfo; -{ - int status, err = 2; /* 2 == trouble, like rcsdiff */ - Vers_TS *vers; - enum diff_file empty_file = DIFF_DIFFERENT; - char *tmp = NULL; - char *tocvsPath = NULL; - char *fname = NULL; - char *label1; - char *label2; - char *rev1_cache = NULL; - - user_file_rev = 0; - vers = Version_TS (finfo, NULL, NULL, NULL, 1, 0); - - if (diff_rev2 != NULL || diff_date2 != NULL) - { - /* Skip all the following checks regarding the user file; we're - not using it. */ - } - else if (vers->vn_user == NULL) - { - /* The file does not exist in the working directory. */ - if ((diff_rev1 != NULL || diff_date1 != NULL) - && vers->srcfile != NULL) - { - /* The file does exist in the repository. */ - if (empty_files) - empty_file = DIFF_REMOVED; - else - { - int exists; - - exists = 0; - /* special handling for TAG_HEAD */ - if (diff_rev1 && strcmp (diff_rev1, TAG_HEAD) == 0) - { - char *head = - (vers->vn_rcs == NULL - ? NULL - : RCS_branch_head (vers->srcfile, vers->vn_rcs)); - exists = head != NULL && !RCS_isdead(vers->srcfile, head); - if (head != NULL) - free (head); - } - else - { - Vers_TS *xvers; - - xvers = Version_TS (finfo, NULL, diff_rev1, diff_date1, - 1, 0); - exists = xvers->vn_rcs != NULL && !RCS_isdead(xvers->srcfile, xvers->vn_rcs); - freevers_ts (&xvers); - } - if (exists) - error (0, 0, - "%s no longer exists, no comparison available", - finfo->fullname); - goto out; - } - } - else - { - error (0, 0, "I know nothing about %s", finfo->fullname); - goto out; - } - } - else if (vers->vn_user[0] == '0' && vers->vn_user[1] == '\0') - { - /* The file was added locally. */ - int exists = 0; - - if (vers->srcfile != NULL) - { - /* The file does exist in the repository. */ - - if ((diff_rev1 != NULL || diff_date1 != NULL)) - { - /* special handling for TAG_HEAD */ - if (diff_rev1 && strcmp (diff_rev1, TAG_HEAD) == 0) - { - char *head = - (vers->vn_rcs == NULL - ? NULL - : RCS_branch_head (vers->srcfile, vers->vn_rcs)); - exists = head != NULL && !RCS_isdead(vers->srcfile, head); - if (head != NULL) - free (head); - } - else - { - Vers_TS *xvers; - - xvers = Version_TS (finfo, NULL, diff_rev1, diff_date1, - 1, 0); - exists = xvers->vn_rcs != NULL - && !RCS_isdead (xvers->srcfile, xvers->vn_rcs); - freevers_ts (&xvers); - } - } - else - { - /* The file was added locally, but an RCS archive exists. Our - * base revision must be dead. - */ - /* No need to set, exists = 0, here. That's the default. */ - } - } - if (!exists) - { - /* If we got here, then either the RCS archive does not exist or - * the relevant revision is dead. - */ - if (empty_files) - empty_file = DIFF_ADDED; - else - { - error (0, 0, "%s is a new entry, no comparison available", - finfo->fullname); - goto out; - } - } - } - else if (vers->vn_user[0] == '-') - { - if (empty_files) - empty_file = DIFF_REMOVED; - else - { - error (0, 0, "%s was removed, no comparison available", - finfo->fullname); - goto out; - } - } - else - { - if (vers->vn_rcs == NULL && vers->srcfile == NULL) - { - error (0, 0, "cannot find revision control file for %s", - finfo->fullname); - goto out; - } - else - { - if (vers->ts_user == NULL) - { - error (0, 0, "cannot find %s", finfo->fullname); - goto out; - } - else if (!strcmp (vers->ts_user, vers->ts_rcs)) - { - /* The user file matches some revision in the repository - Diff against the repository (for remote CVS, we might not - have a copy of the user file around). */ - user_file_rev = vers->vn_user; - } - } - } - - empty_file = diff_file_nodiff( finfo, vers, empty_file, &rev1_cache ); - if( empty_file == DIFF_SAME ) - { - /* In the server case, would be nice to send a "Checked-in" - response, so that the client can rewrite its timestamp. - server_checked_in by itself isn't the right thing (it - needs a server_register), but I'm not sure what is. - It isn't clear to me how "cvs status" handles this (that - is, for a client which sends Modified not Is-modified to - "cvs status"), but it does. */ - err = 0; - goto out; - } - else if( empty_file == DIFF_ERROR ) - goto out; - - /* Output an "Index:" line for patch to use */ - cvs_output ("Index: ", 0); - cvs_output (finfo->fullname, 0); - cvs_output ("\n", 1); - - tocvsPath = wrap_tocvs_process_file(finfo->file); - if( tocvsPath != NULL ) - { - /* Backup the current version of the file to CVS/,,filename */ - fname = xmalloc (strlen (finfo->file) - + sizeof CVSADM - + sizeof CVSPREFIX - + 10); - sprintf(fname,"%s/%s%s",CVSADM, CVSPREFIX, finfo->file); - if (unlink_file_dir (fname) < 0) - if (! existence_error (errno)) - error (1, errno, "cannot remove %s", fname); - rename_file (finfo->file, fname); - /* Copy the wrapped file to the current directory then go to work */ - copy_file (tocvsPath, finfo->file); - } - - /* Set up file labels appropriate for compatibility with the Larry Wall - * implementation of patch if the user didn't specify. This is irrelevant - * according to the POSIX.2 specification. - */ - label1 = NULL; - label2 = NULL; - if (!have_rev1_label) - { - if (empty_file == DIFF_ADDED) - label1 = - make_file_label (DEVNULL, NULL, NULL); - else - label1 = - make_file_label (finfo->fullname, use_rev1, - vers ? vers->srcfile : NULL); - } - - if (!have_rev2_label) - { - if (empty_file == DIFF_REMOVED) - label2 = - make_file_label (DEVNULL, NULL, NULL); - else - label2 = - make_file_label (finfo->fullname, use_rev2, - vers ? vers->srcfile : NULL); - } - - if (empty_file == DIFF_ADDED || empty_file == DIFF_REMOVED) - { - /* This is fullname, not file, possibly despite the POSIX.2 - * specification, because that's the way all the Larry Wall - * implementations of patch (are there other implementations?) want - * things and the POSIX.2 spec appears to leave room for this. - */ - cvs_output ("\ -===================================================================\n\ -RCS file: ", 0); - cvs_output (finfo->fullname, 0); - cvs_output ("\n", 1); - - cvs_output ("diff -N ", 0); - cvs_output (finfo->fullname, 0); - cvs_output ("\n", 1); - - if (empty_file == DIFF_ADDED) - { - if (use_rev2 == NULL) - status = diff_exec (DEVNULL, finfo->file, label1, label2, - diff_argc, diff_argv, RUN_TTY); - else - { - int retcode; - - tmp = cvs_temp_name (); - retcode = RCS_checkout (vers->srcfile, (char *) NULL, - use_rev2, (char *) NULL, - (*options - ? options - : vers->options), - tmp, (RCSCHECKOUTPROC) NULL, - (void *) NULL); - if( retcode != 0 ) - goto out; - - status = diff_exec (DEVNULL, tmp, label1, label2, - diff_argc, diff_argv, RUN_TTY); - } - } - else - { - int retcode; - - tmp = cvs_temp_name (); - retcode = RCS_checkout (vers->srcfile, (char *) NULL, - use_rev1, (char *) NULL, - *options ? options : vers->options, - tmp, (RCSCHECKOUTPROC) NULL, - (void *) NULL); - if (retcode != 0) - goto out; - - status = diff_exec (tmp, DEVNULL, label1, label2, - diff_argc, diff_argv, RUN_TTY); - } - } - else - { - status = RCS_exec_rcsdiff (vers->srcfile, diff_argc, diff_argv, - *options ? options : vers->options, - use_rev1, rev1_cache, use_rev2, - label1, label2, finfo->file); - - } - - if (label1) free (label1); - if (label2) free (label2); - - switch (status) - { - case -1: /* fork failed */ - error (1, errno, "fork failed while diffing %s", - vers->srcfile->path); - case 0: /* everything ok */ - err = 0; - break; - default: /* other error */ - err = status; - break; - } - -out: - if( tocvsPath != NULL ) - { - if (unlink_file_dir (finfo->file) < 0) - if (! existence_error (errno)) - error (1, errno, "cannot remove %s", finfo->file); - - rename_file (fname, finfo->file); - if (unlink_file (tocvsPath) < 0) - error (1, errno, "cannot remove %s", tocvsPath); - free (fname); - } - - /* Call CVS_UNLINK() rather than unlink_file() below to avoid the check - * for noexec. - */ - if( tmp != NULL ) - { - if (CVS_UNLINK(tmp) < 0) - error (0, errno, "cannot remove %s", tmp); - free (tmp); - } - if( rev1_cache != NULL ) - { - if( CVS_UNLINK( rev1_cache ) < 0 ) - error( 0, errno, "cannot remove %s", rev1_cache ); - free( rev1_cache ); - } - - freevers_ts (&vers); - diff_mark_errors (err); - return err; -} - -/* - * Remember the exit status for each file. - */ -static void -diff_mark_errors (err) - int err; -{ - if (err > diff_errors) - diff_errors = err; -} - -/* - * Print a warm fuzzy message when we enter a dir - * - * Don't try to diff directories that don't exist! -- DW - */ -/* ARGSUSED */ -static Dtype -diff_dirproc (callerdat, dir, pos_repos, update_dir, entries) - void *callerdat; - const char *dir; - const char *pos_repos; - const char *update_dir; - List *entries; -{ - /* XXX - check for dirs we don't want to process??? */ - - /* YES ... for instance dirs that don't exist!!! -- DW */ - if (!isdir (dir)) - return (R_SKIP_ALL); - - if (!quiet) - error (0, 0, "Diffing %s", update_dir); - return (R_PROCESS); -} - -/* - * Concoct the proper exit status - done with files - */ -/* ARGSUSED */ -static int -diff_filesdoneproc (callerdat, err, repos, update_dir, entries) - void *callerdat; - int err; - const char *repos; - const char *update_dir; - List *entries; -{ - return (diff_errors); -} - -/* - * Concoct the proper exit status - leaving directories - */ -/* ARGSUSED */ -static int -diff_dirleaveproc (callerdat, dir, err, update_dir, entries) - void *callerdat; - const char *dir; - int err; - const char *update_dir; - List *entries; -{ - return (diff_errors); -} - -/* - * verify that a file is different - */ -static enum diff_file -diff_file_nodiff( finfo, vers, empty_file, rev1_cache ) - struct file_info *finfo; - Vers_TS *vers; - enum diff_file empty_file; - char **rev1_cache; /* Cache the content of rev1 if we have to look - * it up. - */ -{ - Vers_TS *xvers; - int retcode; - - /* free up any old use_rev* variables and reset 'em */ - if (use_rev1) - free (use_rev1); - if (use_rev2) - free (use_rev2); - use_rev1 = use_rev2 = (char *) NULL; - - if (diff_rev1 || diff_date1) - { - /* special handling for TAG_HEAD */ - if (diff_rev1 && strcmp (diff_rev1, TAG_HEAD) == 0) - { - if (vers->vn_rcs != NULL && vers->srcfile != NULL) - use_rev1 = RCS_branch_head (vers->srcfile, vers->vn_rcs); - } - else - { - xvers = Version_TS (finfo, NULL, diff_rev1, diff_date1, 1, 0); - if (xvers->vn_rcs != NULL) - use_rev1 = xstrdup (xvers->vn_rcs); - freevers_ts (&xvers); - } - } - if (diff_rev2 || diff_date2) - { - /* special handling for TAG_HEAD */ - if (diff_rev2 && strcmp (diff_rev2, TAG_HEAD) == 0) - { - if (vers->vn_rcs != NULL && vers->srcfile != NULL) - use_rev2 = RCS_branch_head (vers->srcfile, vers->vn_rcs); - } - else - { - xvers = Version_TS (finfo, NULL, diff_rev2, diff_date2, 1, 0); - if (xvers->vn_rcs != NULL) - use_rev2 = xstrdup (xvers->vn_rcs); - freevers_ts (&xvers); - } - - if( use_rev1 == NULL || RCS_isdead( vers->srcfile, use_rev1 ) ) - { - /* The first revision does not exist. If EMPTY_FILES is - true, treat this as an added file. Otherwise, warn - about the missing tag. */ - if( use_rev2 == NULL || RCS_isdead( vers->srcfile, use_rev2 ) ) - /* At least in the case where DIFF_REV1 and DIFF_REV2 - * are both numeric (and non-existant (NULL), as opposed to - * dead?), we should be returning some kind of error (see - * basicb-8a0 in testsuite). The symbolic case may be more - * complicated. - */ - return DIFF_SAME; - if( empty_files ) - return DIFF_ADDED; - if( use_rev1 != NULL ) - { - if (diff_rev1) - { - error( 0, 0, - "Tag %s refers to a dead (removed) revision in file `%s'.", - diff_rev1, finfo->fullname ); - } - else - { - error( 0, 0, - "Date %s refers to a dead (removed) revision in file `%s'.", - diff_date1, finfo->fullname ); - } - error( 0, 0, - "No comparison available. Pass `-N' to `%s diff'?", - program_name ); - } - else if (diff_rev1) - error (0, 0, "tag %s is not in file %s", diff_rev1, - finfo->fullname); - else - error (0, 0, "no revision for date %s in file %s", - diff_date1, finfo->fullname); - return DIFF_ERROR; - } - - assert( use_rev1 != NULL ); - if( use_rev2 == NULL || RCS_isdead( vers->srcfile, use_rev2 ) ) - { - /* The second revision does not exist. If EMPTY_FILES is - true, treat this as a removed file. Otherwise warn - about the missing tag. */ - if (empty_files) - return DIFF_REMOVED; - if( use_rev2 != NULL ) - { - if (diff_rev2) - { - error( 0, 0, - "Tag %s refers to a dead (removed) revision in file `%s'.", - diff_rev2, finfo->fullname ); - } - else - { - error( 0, 0, - "Date %s refers to a dead (removed) revision in file `%s'.", - diff_date2, finfo->fullname ); - } - error( 0, 0, - "No comparison available. Pass `-N' to `%s diff'?", - program_name ); - } - else if (diff_rev2) - error (0, 0, "tag %s is not in file %s", diff_rev2, - finfo->fullname); - else - error (0, 0, "no revision for date %s in file %s", - diff_date2, finfo->fullname); - return DIFF_ERROR; - } - /* Now, see if we really need to do the diff. We can't assume that the - * files are different when the revs are. - */ - assert( use_rev2 != NULL ); - if( strcmp (use_rev1, use_rev2) == 0 ) - return DIFF_SAME; - /* else fall through and do the diff */ - } - - /* If we had a r1/d1 & r2/d2, then at this point we must have a C3P0... - * err... ok, then both rev1 & rev2 must have resolved to an existing, - * live version due to if statement we just closed. - */ - assert (!(diff_rev2 || diff_date2) || (use_rev1 && use_rev2)); - - if ((diff_rev1 || diff_date1) && - (use_rev1 == NULL || RCS_isdead (vers->srcfile, use_rev1))) - { - /* The first revision does not exist, and no second revision - was given. */ - if (empty_files) - { - if (empty_file == DIFF_REMOVED) - return DIFF_SAME; - if( user_file_rev && use_rev2 == NULL ) - use_rev2 = xstrdup( user_file_rev ); - return DIFF_ADDED; - } - if( use_rev1 != NULL ) - { - if (diff_rev1) - { - error( 0, 0, - "Tag %s refers to a dead (removed) revision in file `%s'.", - diff_rev1, finfo->fullname ); - } - else - { - error( 0, 0, - "Date %s refers to a dead (removed) revision in file `%s'.", - diff_date1, finfo->fullname ); - } - error( 0, 0, - "No comparison available. Pass `-N' to `%s diff'?", - program_name ); - } - else if ( diff_rev1 ) - error( 0, 0, "tag %s is not in file %s", diff_rev1, - finfo->fullname ); - else - error( 0, 0, "no revision for date %s in file %s", - diff_date1, finfo->fullname ); - return DIFF_ERROR; - } - - assert( !diff_rev1 || use_rev1 ); - - if (user_file_rev) - { - /* drop user_file_rev into first unused use_rev */ - if (!use_rev1) - use_rev1 = xstrdup (user_file_rev); - else if (!use_rev2) - use_rev2 = xstrdup (user_file_rev); - /* and if not, it wasn't needed anyhow */ - user_file_rev = NULL; - } - - /* Now, see if we really need to do the diff. We can't assume that the - * files are different when the revs are. - */ - if( use_rev1 && use_rev2) - { - if (strcmp (use_rev1, use_rev2) == 0) - return DIFF_SAME; - /* Fall through and do the diff. */ - } - /* Don't want to do the timestamp check with both use_rev1 & use_rev2 set. - * The timestamp check is just for the default case of diffing the - * workspace file against its base revision. - */ - else if( use_rev1 == NULL - || ( vers->vn_user != NULL - && strcmp( use_rev1, vers->vn_user ) == 0 ) ) - { - if (empty_file == DIFF_DIFFERENT - && vers->ts_user != NULL - && strcmp (vers->ts_rcs, vers->ts_user) == 0 - && (!(*options) || strcmp (options, vers->options) == 0)) - { - return DIFF_SAME; - } - if (use_rev1 == NULL - && (vers->vn_user[0] != '0' || vers->vn_user[1] != '\0')) - { - if (vers->vn_user[0] == '-') - use_rev1 = xstrdup (vers->vn_user + 1); - else - use_rev1 = xstrdup (vers->vn_user); - } - } - - /* If we already know that the file is being added or removed, - then we don't want to do an actual file comparison here. */ - if (empty_file != DIFF_DIFFERENT) - return empty_file; - - /* - * Run a quick cmp to see if we should bother with a full diff. - */ - - retcode = RCS_cmp_file( vers->srcfile, use_rev1, rev1_cache, - use_rev2, *options ? options : vers->options, - finfo->file ); - - return retcode == 0 ? DIFF_SAME : DIFF_DIFFERENT; -} diff --git a/contrib/cvs/src/edit.c b/contrib/cvs/src/edit.c deleted file mode 100644 index 4e0cf1e..0000000 --- a/contrib/cvs/src/edit.c +++ /dev/null @@ -1,1164 +0,0 @@ -/* Implementation for "cvs edit", "cvs watch on", and related commands - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. */ - -#include "cvs.h" -#include "getline.h" -#include "watch.h" -#include "edit.h" -#include "fileattr.h" - -static int watch_onoff PROTO ((int, char **)); - -static int setting_default; -static int turning_on; - -static int setting_tedit; -static int setting_tunedit; -static int setting_tcommit; - -static int onoff_fileproc PROTO ((void *callerdat, struct file_info *finfo)); - -static int -onoff_fileproc (callerdat, finfo) - void *callerdat; - struct file_info *finfo; -{ - char *watched = fileattr_get0 (finfo->file, "_watched"); - fileattr_set (finfo->file, "_watched", turning_on ? "" : NULL); - if (watched != NULL) - free (watched); - return 0; -} - - - -static int onoff_filesdoneproc PROTO ((void *, int, const char *, const char *, - List *)); - -static int -onoff_filesdoneproc (callerdat, err, repository, update_dir, entries) - void *callerdat; - int err; - const char *repository; - const char *update_dir; - List *entries; -{ - if (setting_default) - { - char *watched = fileattr_get0 (NULL, "_watched"); - fileattr_set (NULL, "_watched", turning_on ? "" : NULL); - if (watched != NULL) - free (watched); - } - return err; -} - -static int -watch_onoff (argc, argv) - int argc; - char **argv; -{ - int c; - int local = 0; - int err; - - optind = 0; - while ((c = getopt (argc, argv, "+lR")) != -1) - { - switch (c) - { - case 'l': - local = 1; - break; - case 'R': - local = 0; - break; - case '?': - default: - usage (watch_usage); - break; - } - } - argc -= optind; - argv += optind; - -#ifdef CLIENT_SUPPORT - if (current_parsed_root->isremote) - { - start_server (); - - ign_setup (); - - if (local) - send_arg ("-l"); - send_arg ("--"); - send_files (argc, argv, local, 0, SEND_NO_CONTENTS); - send_file_names (argc, argv, SEND_EXPAND_WILD); - send_to_server (turning_on ? "watch-on\012" : "watch-off\012", 0); - return get_responses_and_close (); - } -#endif /* CLIENT_SUPPORT */ - - setting_default = (argc <= 0); - - lock_tree_for_write (argc, argv, local, W_LOCAL, 0); - - err = start_recursion (onoff_fileproc, onoff_filesdoneproc, - (DIRENTPROC) NULL, (DIRLEAVEPROC) NULL, NULL, - argc, argv, local, W_LOCAL, 0, CVS_LOCK_NONE, - (char *) NULL, 0, (char *) NULL); - - Lock_Cleanup (); - return err; -} - -int -watch_on (argc, argv) - int argc; - char **argv; -{ - turning_on = 1; - return watch_onoff (argc, argv); -} - -int -watch_off (argc, argv) - int argc; - char **argv; -{ - turning_on = 0; - return watch_onoff (argc, argv); -} - -static int dummy_fileproc PROTO ((void *callerdat, struct file_info *finfo)); - -static int -dummy_fileproc (callerdat, finfo) - void *callerdat; - struct file_info *finfo; -{ - /* This is a pretty hideous hack, but the gist of it is that recurse.c - won't call cvs_notify_check unless there is a fileproc, so we - can't just pass NULL for fileproc. */ - return 0; -} - -static int ncheck_fileproc PROTO ((void *callerdat, struct file_info *finfo)); - -/* Check for and process notifications. Local only. I think that doing - this as a fileproc is the only way to catch all the - cases (e.g. foo/bar.c), even though that means checking over and over - for the same CVSADM_NOTIFY file which we removed the first time we - processed the directory. */ - -static int -ncheck_fileproc (callerdat, finfo) - void *callerdat; - struct file_info *finfo; -{ - int notif_type; - char *filename; - char *val; - char *cp; - char *watches; - - FILE *fp; - char *line = NULL; - size_t line_len = 0; - - /* We send notifications even if noexec. I'm not sure which behavior - is most sensible. */ - - fp = CVS_FOPEN (CVSADM_NOTIFY, "r"); - if (fp == NULL) - { - if (!existence_error (errno)) - error (0, errno, "cannot open %s", CVSADM_NOTIFY); - return 0; - } - - while (getline (&line, &line_len, fp) > 0) - { - notif_type = line[0]; - if (notif_type == '\0') - continue; - filename = line + 1; - cp = strchr (filename, '\t'); - if (cp == NULL) - continue; - *cp++ = '\0'; - val = cp; - cp = strchr (val, '\t'); - if (cp == NULL) - continue; - *cp++ = '+'; - cp = strchr (cp, '\t'); - if (cp == NULL) - continue; - *cp++ = '+'; - cp = strchr (cp, '\t'); - if (cp == NULL) - continue; - *cp++ = '\0'; - watches = cp; - cp = strchr (cp, '\n'); - if (cp == NULL) - continue; - *cp = '\0'; - - notify_do (notif_type, filename, getcaller (), val, watches, - finfo->repository); - } - free (line); - - if (ferror (fp)) - error (0, errno, "cannot read %s", CVSADM_NOTIFY); - if (fclose (fp) < 0) - error (0, errno, "cannot close %s", CVSADM_NOTIFY); - - if ( CVS_UNLINK (CVSADM_NOTIFY) < 0) - error (0, errno, "cannot remove %s", CVSADM_NOTIFY); - - return 0; -} - -static int send_notifications PROTO ((int, char **, int)); - -/* Look through the CVSADM_NOTIFY file and process each item there - accordingly. */ -static int -send_notifications (argc, argv, local) - int argc; - char **argv; - int local; -{ - int err = 0; - -#ifdef CLIENT_SUPPORT - /* OK, we've done everything which needs to happen on the client side. - Now we can try to contact the server; if we fail, then the - notifications stay in CVSADM_NOTIFY to be sent next time. */ - if (current_parsed_root->isremote) - { - if (strcmp (cvs_cmd_name, "release") != 0) - { - start_server (); - ign_setup (); - } - - err += start_recursion (dummy_fileproc, (FILESDONEPROC) NULL, - (DIRENTPROC) NULL, (DIRLEAVEPROC) NULL, NULL, - argc, argv, local, W_LOCAL, 0, 0, (char *)NULL, - 0, (char *) NULL); - - send_to_server ("noop\012", 0); - if (strcmp (cvs_cmd_name, "release") == 0) - err += get_server_responses (); - else - err += get_responses_and_close (); - } - else -#endif - { - /* Local. */ - - lock_tree_for_write (argc, argv, local, W_LOCAL, 0); - err += start_recursion (ncheck_fileproc, (FILESDONEPROC) NULL, - (DIRENTPROC) NULL, (DIRLEAVEPROC) NULL, NULL, - argc, argv, local, W_LOCAL, 0, 0, (char *)NULL, - 0, (char *) NULL); - Lock_Cleanup (); - } - return err; -} - -static int edit_fileproc PROTO ((void *callerdat, struct file_info *finfo)); - -static int -edit_fileproc (callerdat, finfo) - void *callerdat; - struct file_info *finfo; -{ - FILE *fp; - time_t now; - char *ascnow; - char *basefilename; - - if (noexec) - return 0; - - /* This is a somewhat screwy way to check for this, because it - doesn't help errors other than the nonexistence of the file - (e.g. permissions problems). It might be better to rearrange - the code so that CVSADM_NOTIFY gets written only after the - various actions succeed (but what if only some of them - succeed). */ - if (!isfile (finfo->file)) - { - error (0, 0, "no such file %s; ignored", finfo->fullname); - return 0; - } - - fp = open_file (CVSADM_NOTIFY, "a"); - - (void) time (&now); - ascnow = asctime (gmtime (&now)); - ascnow[24] = '\0'; - /* Fix non-standard format. */ - if (ascnow[8] == '0') ascnow[8] = ' '; - fprintf (fp, "E%s\t%s GMT\t%s\t%s\t", finfo->file, - ascnow, hostname, CurDir); - if (setting_tedit) - fprintf (fp, "E"); - if (setting_tunedit) - fprintf (fp, "U"); - if (setting_tcommit) - fprintf (fp, "C"); - fprintf (fp, "\n"); - - if (fclose (fp) < 0) - { - if (finfo->update_dir[0] == '\0') - error (0, errno, "cannot close %s", CVSADM_NOTIFY); - else - error (0, errno, "cannot close %s/%s", finfo->update_dir, - CVSADM_NOTIFY); - } - - xchmod (finfo->file, 1); - - /* Now stash the file away in CVSADM so that unedit can revert even if - it can't communicate with the server. We stash away a writable - copy so that if the user removes the working file, then restores it - with "cvs update" (which clears _editors but does not update - CVSADM_BASE), then a future "cvs edit" can still win. */ - /* Could save a system call by only calling mkdir_if_needed if - trying to create the output file fails. But copy_file isn't - set up to facilitate that. */ - mkdir_if_needed (CVSADM_BASE); - basefilename = xmalloc (10 + sizeof CVSADM_BASE + strlen (finfo->file)); - strcpy (basefilename, CVSADM_BASE); - strcat (basefilename, "/"); - strcat (basefilename, finfo->file); - copy_file (finfo->file, basefilename); - free (basefilename); - - { - Node *node; - - node = findnode_fn (finfo->entries, finfo->file); - if (node != NULL) - base_register (finfo, ((Entnode *) node->data)->version); - } - - return 0; -} - -static const char *const edit_usage[] = -{ - "Usage: %s %s [-lR] [-a ]... []...\n", - "-l\tLocal directory only, not recursive.\n", - "-R\tProcess directories recursively (default).\n", - "-a\tSpecify action to register for temporary watch, one of:\n", - " \t`edit', `unedit', `commit', `all', or `none' (defaults to `all').\n", - "(Specify the --help global option for a list of other help options.)\n", - NULL -}; - -int -edit (argc, argv) - int argc; - char **argv; -{ - int local = 0; - int c; - int err; - int a_omitted; - - if (argc == -1) - usage (edit_usage); - - a_omitted = 1; - setting_tedit = 0; - setting_tunedit = 0; - setting_tcommit = 0; - optind = 0; - while ((c = getopt (argc, argv, "+lRa:")) != -1) - { - switch (c) - { - case 'l': - local = 1; - break; - case 'R': - local = 0; - break; - case 'a': - a_omitted = 0; - if (strcmp (optarg, "edit") == 0) - setting_tedit = 1; - else if (strcmp (optarg, "unedit") == 0) - setting_tunedit = 1; - else if (strcmp (optarg, "commit") == 0) - setting_tcommit = 1; - else if (strcmp (optarg, "all") == 0) - { - setting_tedit = 1; - setting_tunedit = 1; - setting_tcommit = 1; - } - else if (strcmp (optarg, "none") == 0) - { - setting_tedit = 0; - setting_tunedit = 0; - setting_tcommit = 0; - } - else - usage (edit_usage); - break; - case '?': - default: - usage (edit_usage); - break; - } - } - argc -= optind; - argv += optind; - - if (a_omitted) - { - setting_tedit = 1; - setting_tunedit = 1; - 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, - (DIRENTPROC) NULL, (DIRLEAVEPROC) NULL, NULL, - argc, argv, local, W_LOCAL, 0, 0, (char *) NULL, - 0, (char *) NULL); - - err += send_notifications (argc, argv, local); - - return err; -} - -static int unedit_fileproc PROTO ((void *callerdat, struct file_info *finfo)); - -static int -unedit_fileproc (callerdat, finfo) - void *callerdat; - struct file_info *finfo; -{ - FILE *fp; - time_t now; - char *ascnow; - char *basefilename; - - if (noexec) - return 0; - - basefilename = xmalloc (10 + sizeof CVSADM_BASE + strlen (finfo->file)); - strcpy (basefilename, CVSADM_BASE); - strcat (basefilename, "/"); - strcat (basefilename, finfo->file); - if (!isfile (basefilename)) - { - /* This file apparently was never cvs edit'd (e.g. we are uneditting - a directory where only some of the files were cvs edit'd. */ - free (basefilename); - return 0; - } - - if (xcmp (finfo->file, basefilename) != 0) - { - printf ("%s has been modified; revert changes? ", finfo->fullname); - if (!yesno ()) - { - /* "no". */ - free (basefilename); - return 0; - } - } - rename_file (basefilename, finfo->file); - free (basefilename); - - fp = open_file (CVSADM_NOTIFY, "a"); - - (void) time (&now); - ascnow = asctime (gmtime (&now)); - ascnow[24] = '\0'; - /* Fix non-standard format. */ - if (ascnow[8] == '0') ascnow[8] = ' '; - fprintf (fp, "U%s\t%s GMT\t%s\t%s\t\n", finfo->file, - ascnow, hostname, CurDir); - - if (fclose (fp) < 0) - { - if (finfo->update_dir[0] == '\0') - error (0, errno, "cannot close %s", CVSADM_NOTIFY); - else - error (0, errno, "cannot close %s/%s", finfo->update_dir, - CVSADM_NOTIFY); - } - - /* Now update the revision number in CVS/Entries from CVS/Baserev. - The basic idea here is that we are reverting to the revision - that the user edited. If we wanted "cvs update" to update - CVS/Base as we go along (so that an unedit could revert to the - current repository revision), we would need: - - update (or all send_files?) (client) needs to send revision in - new Entry-base request. update (server/local) needs to check - revision against repository and send new Update-base response - (like Update-existing in that the file already exists. While - we are at it, might try to clean up the syntax by having the - mode only in a "Mode" response, not in the Update-base itself). */ - { - char *baserev; - Node *node; - Entnode *entdata; - - baserev = base_get (finfo); - node = findnode_fn (finfo->entries, finfo->file); - /* The case where node is NULL probably should be an error or - something, but I don't want to think about it too hard right - now. */ - if (node != NULL) - { - entdata = node->data; - if (baserev == NULL) - { - /* This can only happen if the CVS/Baserev file got - corrupted. We suspect it might be possible if the - user interrupts CVS, although I haven't verified - that. */ - error (0, 0, "%s not mentioned in %s", finfo->fullname, - CVSADM_BASEREV); - - /* Since we don't know what revision the file derives from, - keeping it around would be asking for trouble. */ - if (unlink_file (finfo->file) < 0) - error (0, errno, "cannot remove %s", finfo->fullname); - - /* This is cheesy, in a sense; why shouldn't we do the - update for the user? However, doing that would require - contacting the server, so maybe this is OK. */ - error (0, 0, "run update to complete the unedit"); - return 0; - } - Register (finfo->entries, finfo->file, baserev, entdata->timestamp, - entdata->options, entdata->tag, entdata->date, - entdata->conflict); - } - free (baserev); - base_deregister (finfo); - } - - xchmod (finfo->file, 0); - return 0; -} - -static const char *const unedit_usage[] = -{ - "Usage: %s %s [-lR] []...\n", - "-l\tLocal directory only, not recursive.\n", - "-R\tProcess directories recursively (default).\n", - "(Specify the --help global option for a list of other help options.)\n", - NULL -}; - -int -unedit (argc, argv) - int argc; - char **argv; -{ - int local = 0; - int c; - int err; - - if (argc == -1) - usage (unedit_usage); - - optind = 0; - while ((c = getopt (argc, argv, "+lR")) != -1) - { - switch (c) - { - case 'l': - local = 1; - break; - case 'R': - local = 0; - break; - case '?': - default: - usage (unedit_usage); - break; - } - } - argc -= optind; - argv += optind; - - /* No need to readlock since we aren't doing anything to the - repository. */ - err = start_recursion (unedit_fileproc, (FILESDONEPROC) NULL, - (DIRENTPROC) NULL, (DIRLEAVEPROC) NULL, NULL, - argc, argv, local, W_LOCAL, 0, 0, (char *)NULL, - 0, (char *) NULL); - - err += send_notifications (argc, argv, local); - - return err; -} - -void -mark_up_to_date (file) - const char *file; -{ - char *base; - - /* The file is up to date, so we better get rid of an out of - date file in CVSADM_BASE. */ - base = xmalloc (strlen (file) + 80); - strcpy (base, CVSADM_BASE); - strcat (base, "/"); - strcat (base, file); - if (unlink_file (base) < 0 && ! existence_error (errno)) - error (0, errno, "cannot remove %s", file); - free (base); -} - - - -void -editor_set (filename, editor, val) - const char *filename; - const char *editor; - const char *val; -{ - char *edlist; - char *newlist; - - edlist = fileattr_get0 (filename, "_editors"); - newlist = fileattr_modify (edlist, editor, val, '>', ','); - /* If the attributes is unchanged, don't rewrite the attribute file. */ - if (!((edlist == NULL && newlist == NULL) - || (edlist != NULL - && newlist != NULL - && strcmp (edlist, newlist) == 0))) - fileattr_set (filename, "_editors", newlist); - if (edlist != NULL) - free (edlist); - if (newlist != NULL) - free (newlist); -} - -struct notify_proc_args { - /* What kind of notification, "edit", "tedit", etc. */ - const char *type; - /* User who is running the command which causes notification. */ - const char *who; - /* User to be notified. */ - const char *notifyee; - /* File. */ - const char *file; -}; - - - -/* Pass as a static until we get around to fixing Parse_Info to pass along - a void * where we can stash it. */ -static struct notify_proc_args *notify_args; - - - -static int notify_proc PROTO ((const char *repository, const char *filter)); - -static int -notify_proc (repository, filter) - const char *repository; - const char *filter; -{ - FILE *pipefp; - char *prog; - char *expanded_prog; - const char *p; - char *q; - const char *srepos; - struct notify_proc_args *args = notify_args; - - srepos = Short_Repository (repository); - prog = xmalloc (strlen (filter) + strlen (args->notifyee) + 1); - /* Copy FILTER to PROG, replacing the first occurrence of %s with - the notifyee. We only allocated enough memory for one %s, and I doubt - there is a need for more. */ - for (p = filter, q = prog; *p != '\0'; ++p) - { - if (p[0] == '%') - { - if (p[1] == 's') - { - strcpy (q, args->notifyee); - q += strlen (q); - strcpy (q, p + 2); - q += strlen (q); - break; - } - else - continue; - } - *q++ = *p; - } - *q = '\0'; - - /* FIXME: why are we calling expand_proc? Didn't we already - expand it in Parse_Info, before passing it to notify_proc? */ - expanded_prog = expand_path (prog, "notify", 0); - if (!expanded_prog) - { - free (prog); - return 1; - } - - pipefp = run_popen (expanded_prog, "w"); - if (pipefp == NULL) - { - error (0, errno, "cannot write entry to notify filter: %s", prog); - free (prog); - free (expanded_prog); - return 1; - } - - fprintf (pipefp, "%s %s\n---\n", srepos, args->file); - fprintf (pipefp, "Triggered %s watch on %s\n", args->type, repository); - fprintf (pipefp, "By %s\n", args->who); - - /* Lots more potentially useful information we could add here; see - logfile_write for inspiration. */ - - free (prog); - free (expanded_prog); - return (pclose (pipefp)); -} - -/* FIXME: this function should have a way to report whether there was - an error so that server.c can know whether to report Notified back - to the client. */ -void -notify_do (type, filename, who, val, watches, repository) - int type; - const char *filename; - const char *who; - const char *val; - const char *watches; - const char *repository; -{ - static struct addremove_args blank; - struct addremove_args args; - char *watchers; - char *p; - char *endp; - char *nextp; - - /* Initialize fields to 0, NULL, or 0.0. */ - args = blank; - switch (type) - { - case 'E': - if (strpbrk (val, ",>;=\n") != NULL) - { - error (0, 0, "invalid character in editor value"); - return; - } - editor_set (filename, who, val); - break; - case 'U': - case 'C': - editor_set (filename, who, NULL); - break; - default: - return; - } - - watchers = fileattr_get0 (filename, "_watchers"); - p = watchers; - while (p != NULL) - { - char *q; - char *endq; - char *nextq; - char *notif; - - endp = strchr (p, '>'); - if (endp == NULL) - break; - nextp = strchr (p, ','); - - if ((size_t)(endp - p) == strlen (who) && strncmp (who, p, endp - p) == 0) - { - /* Don't notify user of their own changes. Would perhaps - be better to check whether it is the same working - directory, not the same user, but that is hairy. */ - p = nextp == NULL ? nextp : nextp + 1; - continue; - } - - /* Now we point q at a string which looks like - "edit+unedit+commit,"... and walk down it. */ - q = endp + 1; - notif = NULL; - while (q != NULL) - { - endq = strchr (q, '+'); - if (endq == NULL || (nextp != NULL && endq > nextp)) - { - if (nextp == NULL) - endq = q + strlen (q); - else - endq = nextp; - nextq = NULL; - } - else - nextq = endq + 1; - - /* If there is a temporary and a regular watch, send a single - notification, for the regular watch. */ - if (type == 'E' && endq - q == 4 && strncmp ("edit", q, 4) == 0) - { - notif = "edit"; - } - else if (type == 'U' - && endq - q == 6 && strncmp ("unedit", q, 6) == 0) - { - notif = "unedit"; - } - else if (type == 'C' - && endq - q == 6 && strncmp ("commit", q, 6) == 0) - { - notif = "commit"; - } - else if (type == 'E' - && endq - q == 5 && strncmp ("tedit", q, 5) == 0) - { - if (notif == NULL) - notif = "temporary edit"; - } - else if (type == 'U' - && endq - q == 7 && strncmp ("tunedit", q, 7) == 0) - { - if (notif == NULL) - notif = "temporary unedit"; - } - else if (type == 'C' - && endq - q == 7 && strncmp ("tcommit", q, 7) == 0) - { - if (notif == NULL) - notif = "temporary commit"; - } - q = nextq; - } - if (nextp != NULL) - ++nextp; - - if (notif != NULL) - { - struct notify_proc_args args; - size_t len = endp - p; - FILE *fp; - char *usersname; - char *line = NULL; - size_t line_len = 0; - - args.notifyee = NULL; - usersname = xmalloc (strlen (current_parsed_root->directory) - + sizeof CVSROOTADM - + sizeof CVSROOTADM_USERS - + 20); - strcpy (usersname, current_parsed_root->directory); - strcat (usersname, "/"); - strcat (usersname, CVSROOTADM); - strcat (usersname, "/"); - strcat (usersname, CVSROOTADM_USERS); - fp = CVS_FOPEN (usersname, "r"); - if (fp == NULL && !existence_error (errno)) - error (0, errno, "cannot read %s", usersname); - if (fp != NULL) - { - while (getline (&line, &line_len, fp) >= 0) - { - if (strncmp (line, p, len) == 0 - && line[len] == ':') - { - char *cp; - args.notifyee = xstrdup (line + len + 1); - - /* There may or may not be more - colon-separated fields added to this in the - future; in any case, we ignore them right - now, and if there are none we make sure to - chop off the final newline, if any. */ - cp = strpbrk (args.notifyee, ":\n"); - - if (cp != NULL) - *cp = '\0'; - break; - } - } - if (ferror (fp)) - error (0, errno, "cannot read %s", usersname); - if (fclose (fp) < 0) - error (0, errno, "cannot close %s", usersname); - } - free (usersname); - if (line != NULL) - free (line); - - if (args.notifyee == NULL) - { - char *tmp; - tmp = xmalloc (endp - p + 1); - strncpy (tmp, p, endp - p); - tmp[endp - p] = '\0'; - args.notifyee = tmp; - } - - notify_args = &args; - args.type = notif; - args.who = who; - args.file = filename; - - (void) Parse_Info (CVSROOTADM_NOTIFY, repository, notify_proc, 1); - - /* It's okay to cast out the const for the free() below since we - * just allocated this a few lines above. The const was for - * everybody else. - */ - free ((char *)args.notifyee); - } - - p = nextp; - } - if (watchers != NULL) - free (watchers); - - switch (type) - { - case 'E': - if (*watches == 'E') - { - args.add_tedit = 1; - ++watches; - } - if (*watches == 'U') - { - args.add_tunedit = 1; - ++watches; - } - if (*watches == 'C') - { - args.add_tcommit = 1; - } - watch_modify_watchers (filename, &args); - break; - case 'U': - case 'C': - args.remove_temp = 1; - watch_modify_watchers (filename, &args); - break; - } -} - -#ifdef CLIENT_SUPPORT -/* Check and send notifications. This is only for the client. */ -void -cvs_notify_check (repository, update_dir) - const char *repository; - const char *update_dir; -{ - FILE *fp; - char *line = NULL; - size_t line_len = 0; - - if (! server_started) - /* We are in the midst of a command which is not to talk to - the server (e.g. the first phase of a cvs edit). Just chill - out, we'll catch the notifications on the flip side. */ - return; - - /* We send notifications even if noexec. I'm not sure which behavior - is most sensible. */ - - fp = CVS_FOPEN (CVSADM_NOTIFY, "r"); - if (fp == NULL) - { - if (!existence_error (errno)) - error (0, errno, "cannot open %s", CVSADM_NOTIFY); - return; - } - while (getline (&line, &line_len, fp) > 0) - { - int notif_type; - char *filename; - char *val; - char *cp; - - notif_type = line[0]; - if (notif_type == '\0') - continue; - filename = line + 1; - cp = strchr (filename, '\t'); - if (cp == NULL) - continue; - *cp++ = '\0'; - val = cp; - - client_notify (repository, update_dir, filename, notif_type, val); - } - if (line) - free (line); - if (ferror (fp)) - error (0, errno, "cannot read %s", CVSADM_NOTIFY); - if (fclose (fp) < 0) - error (0, errno, "cannot close %s", CVSADM_NOTIFY); - - /* Leave the CVSADM_NOTIFY file there, until the server tells us it - has dealt with it. */ -} -#endif /* CLIENT_SUPPORT */ - - -static const char *const editors_usage[] = -{ - "Usage: %s %s [-lR] []...\n", - "-l\tProcess this directory only (not recursive).\n", - "-R\tProcess directories recursively (default).\n", - "(Specify the --help global option for a list of other help options.)\n", - NULL -}; - -static int editors_fileproc PROTO ((void *callerdat, struct file_info *finfo)); - -static int -editors_fileproc (callerdat, finfo) - void *callerdat; - struct file_info *finfo; -{ - char *them; - char *p; - - them = fileattr_get0 (finfo->file, "_editors"); - if (them == NULL) - return 0; - - cvs_output (finfo->fullname, 0); - - p = them; - while (1) - { - cvs_output ("\t", 1); - while (*p != '>' && *p != '\0') - cvs_output (p++, 1); - if (*p == '\0') - { - /* Only happens if attribute is misformed. */ - cvs_output ("\n", 1); - break; - } - ++p; - cvs_output ("\t", 1); - while (1) - { - while (*p != '+' && *p != ',' && *p != '\0') - cvs_output (p++, 1); - if (*p == '\0') - { - cvs_output ("\n", 1); - goto out; - } - if (*p == ',') - { - ++p; - break; - } - ++p; - cvs_output ("\t", 1); - } - cvs_output ("\n", 1); - } - out:; - free (them); - return 0; -} - -int -editors (argc, argv) - int argc; - char **argv; -{ - int local = 0; - int c; - - if (argc == -1) - usage (editors_usage); - - optind = 0; - while ((c = getopt (argc, argv, "+lR")) != -1) - { - switch (c) - { - case 'l': - local = 1; - break; - case 'R': - local = 0; - break; - case '?': - default: - usage (editors_usage); - break; - } - } - argc -= optind; - argv += optind; - -#ifdef CLIENT_SUPPORT - if (current_parsed_root->isremote) - { - start_server (); - ign_setup (); - - if (local) - send_arg ("-l"); - send_arg ("--"); - send_files (argc, argv, local, 0, SEND_NO_CONTENTS); - send_file_names (argc, argv, SEND_EXPAND_WILD); - send_to_server ("editors\012", 0); - return get_responses_and_close (); - } -#endif /* CLIENT_SUPPORT */ - - return start_recursion (editors_fileproc, (FILESDONEPROC) NULL, - (DIRENTPROC) NULL, (DIRLEAVEPROC) NULL, NULL, - argc, argv, local, W_LOCAL, 0, 1, (char *) NULL, - 0, (char *) NULL); -} diff --git a/contrib/cvs/src/edit.h b/contrib/cvs/src/edit.h deleted file mode 100644 index 9b20180..0000000 --- a/contrib/cvs/src/edit.h +++ /dev/null @@ -1,41 +0,0 @@ -/* Interface to "cvs edit", "cvs watch on", and related features - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. */ - -extern int watch_on PROTO ((int argc, char **argv)); -extern int watch_off PROTO ((int argc, char **argv)); - -#ifdef CLIENT_SUPPORT -/* Check to see if any notifications are sitting around in need of being - sent. These are the notifications stored in CVSADM_NOTIFY (edit,unedit); - commit calls notify_do directly. */ -extern void cvs_notify_check PROTO ((const char *repository, - const char *update_dir)); -#endif /* CLIENT_SUPPORT */ - -/* Issue a notification for file FILENAME. TYPE is 'E' for edit, 'U' - for unedit, and 'C' for commit. WHO is the user currently running. - For TYPE 'E', VAL is the time+host+directory data which goes in - _editors, and WATCHES is zero or more of E,U,C, in that order, to specify - what kinds of temporary watches to set. */ -extern void notify_do PROTO ((int type, const char *filename, const char *who, - const char *val, const char *watches, - const char *repository)); - -/* Set attributes to reflect the fact that EDITOR is editing FILENAME. - VAL is time+host+directory, or NULL if we are to say that EDITOR is - *not* editing FILENAME. */ -extern void editor_set PROTO ((const char *filename, const char *editor, - const char *val)); - -/* Take note of the fact that FILE is up to date (this munges CVS/Base; - processing of CVS/Entries is done separately). */ -extern void mark_up_to_date PROTO ((const char *file)); diff --git a/contrib/cvs/src/entries.c b/contrib/cvs/src/entries.c deleted file mode 100644 index 9592c3c..0000000 --- a/contrib/cvs/src/entries.c +++ /dev/null @@ -1,1263 +0,0 @@ -/* - * Copyright (C) 1986-2005 The Free Software Foundation, Inc. - * - * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot , - * and others. - * - * Portions Copyright (C) 1992, Brian Berliner and Jeff Polk - * Portions Copyright (C) 1989-1992, Brian Berliner - * - * You may distribute under the terms of the GNU General Public License as - * specified in the README file that comes with the CVS source distribution. - * - * Entries file to Files file - * - * Creates the file Files containing the names that comprise the project, from - * the Entries file. - */ - -/* - * $FreeBSD$ - */ -#include "cvs.h" -#include "getline.h" - -static Node *AddEntryNode PROTO((List * list, Entnode *entnode)); - -static Entnode *fgetentent PROTO((FILE *, char *, int *)); -static int fputentent PROTO((FILE *, Entnode *)); - -static Entnode *subdir_record PROTO((int, const char *, const char *)); - -static FILE *entfile; -static char *entfilename; /* for error messages */ - - - -/* - * Construct an Entnode - */ -static Entnode *Entnode_Create PROTO ((enum ent_type, const char *, - const char *, const char *, - const char *, const char *, - const char *, const char *)); - -static Entnode * -Entnode_Create(type, user, vn, ts, options, tag, date, ts_conflict) - enum ent_type type; - const char *user; - const char *vn; - const char *ts; - const char *options; - const char *tag; - const char *date; - const char *ts_conflict; -{ - Entnode *ent; - - /* Note that timestamp and options must be non-NULL */ - ent = (Entnode *) xmalloc (sizeof (Entnode)); - ent->type = type; - ent->user = xstrdup (user); - ent->version = xstrdup (vn); - ent->timestamp = xstrdup (ts ? ts : ""); - ent->options = xstrdup (options ? options : ""); - ent->tag = xstrdup (tag); - ent->date = xstrdup (date); - ent->conflict = xstrdup (ts_conflict); - - return ent; -} - -/* - * Destruct an Entnode - */ -static void Entnode_Destroy PROTO ((Entnode *)); - -static void -Entnode_Destroy (ent) - Entnode *ent; -{ - free (ent->user); - free (ent->version); - free (ent->timestamp); - free (ent->options); - if (ent->tag) - free (ent->tag); - if (ent->date) - free (ent->date); - if (ent->conflict) - free (ent->conflict); - free (ent); -} - -/* - * Write out the line associated with a node of an entries file - */ -static int write_ent_proc PROTO ((Node *, void *)); -static int -write_ent_proc (node, closure) - Node *node; - void *closure; -{ - Entnode *entnode = node->data; - - if (closure != NULL && entnode->type != ENT_FILE) - *(int *) closure = 1; - - if (fputentent(entfile, entnode)) - error (1, errno, "cannot write %s", entfilename); - - return (0); -} - -/* - * write out the current entries file given a list, making a backup copy - * first of course - */ -static void -write_entries (list) - List *list; -{ - int sawdir; - - sawdir = 0; - - /* open the new one and walk the list writing entries */ - entfilename = CVSADM_ENTBAK; - entfile = CVS_FOPEN (entfilename, "w+"); - if (entfile == NULL) - { - /* Make this a warning, not an error. For example, one user might - have checked out a working directory which, for whatever reason, - contains an Entries.Log file. A second user, without write access - to that working directory, might want to do a "cvs log". The - problem rewriting Entries shouldn't affect the ability of "cvs log" - to work, although the warning is probably a good idea so that - whether Entries gets rewritten is not an inexplicable process. */ - /* FIXME: should be including update_dir in message. */ - error (0, errno, "cannot rewrite %s", entfilename); - - /* Now just return. We leave the Entries.Log file around. As far - as I know, there is never any data lying around in 'list' that - is not in Entries.Log at this time (if there is an error writing - Entries.Log that is a separate problem). */ - return; - } - - (void) walklist (list, write_ent_proc, (void *) &sawdir); - if (! sawdir) - { - struct stickydirtag *sdtp; - - /* We didn't write out any directories. Check the list - private data to see whether subdirectory information is - known. If it is, we need to write out an empty D line. */ - sdtp = list->list->data; - if (sdtp == NULL || sdtp->subdirs) - if (fprintf (entfile, "D\n") < 0) - error (1, errno, "cannot write %s", entfilename); - } - if (fclose (entfile) == EOF) - error (1, errno, "error closing %s", entfilename); - - /* now, atomically (on systems that support it) rename it */ - rename_file (entfilename, CVSADM_ENT); - - /* now, remove the log file */ - if (unlink_file (CVSADM_ENTLOG) < 0 - && !existence_error (errno)) - error (0, errno, "cannot remove %s", CVSADM_ENTLOG); -} - - - -/* - * Removes the argument file from the Entries file if necessary. - */ -void -Scratch_Entry (list, fname) - List *list; - const char *fname; -{ - Node *node; - - if (trace) - (void) fprintf (stderr, "%s-> Scratch_Entry(%s)\n", - CLIENT_SERVER_STR, fname); - - /* hashlookup to see if it is there */ - if ((node = findnode_fn (list, fname)) != NULL) - { - if (!noexec) - { - entfilename = CVSADM_ENTLOG; - entfile = open_file (entfilename, "a"); - - if (fprintf (entfile, "R ") < 0) - error (1, errno, "cannot write %s", entfilename); - - write_ent_proc (node, NULL); - - if (fclose (entfile) == EOF) - error (1, errno, "error closing %s", entfilename); - } - - delnode (node); /* delete the node */ - -#ifdef SERVER_SUPPORT - if (server_active) - server_scratch (fname); -#endif - } -} - - - -/* - * Enters the given file name/version/time-stamp into the Entries file, - * removing the old entry first, if necessary. - */ -void -Register (list, fname, vn, ts, options, tag, date, ts_conflict) - List *list; - const char *fname; - const char *vn; - const char *ts; - const char *options; - const char *tag; - const char *date; - const char *ts_conflict; -{ - Entnode *entnode; - Node *node; - -#ifdef SERVER_SUPPORT - if (server_active) - { - server_register (fname, vn, ts, options, tag, date, ts_conflict); - } -#endif - - if (trace) - { - (void) fprintf (stderr, "%s-> Register(%s, %s, %s%s%s, %s, %s %s)\n", - CLIENT_SERVER_STR, - fname, vn, ts ? ts : "", - ts_conflict ? "+" : "", ts_conflict ? ts_conflict : "", - options, tag ? tag : "", date ? date : ""); - } - - entnode = Entnode_Create (ENT_FILE, fname, vn, ts, options, tag, date, - ts_conflict); - node = AddEntryNode (list, entnode); - - if (!noexec) - { - entfilename = CVSADM_ENTLOG; - entfile = CVS_FOPEN (entfilename, "a"); - - if (entfile == NULL) - { - /* Warning, not error, as in write_entries. */ - /* FIXME-update-dir: should be including update_dir in message. */ - error (0, errno, "cannot open %s", entfilename); - return; - } - - if (fprintf (entfile, "A ") < 0) - error (1, errno, "cannot write %s", entfilename); - - write_ent_proc (node, NULL); - - if (fclose (entfile) == EOF) - error (1, errno, "error closing %s", entfilename); - } -} - -/* - * Node delete procedure for list-private sticky dir tag/date info - */ -static void -freesdt (p) - Node *p; -{ - struct stickydirtag *sdtp = p->data; - - if (sdtp->tag) - free (sdtp->tag); - if (sdtp->date) - free (sdtp->date); - free ((char *) sdtp); -} - -/* Return the next real Entries line. On end of file, returns NULL. - On error, prints an error message and returns NULL. */ - -static Entnode * -fgetentent(fpin, cmd, sawdir) - FILE *fpin; - char *cmd; - int *sawdir; -{ - Entnode *ent; - char *line; - size_t line_chars_allocated; - register char *cp; - enum ent_type type; - char *l, *user, *vn, *ts, *options; - char *tag_or_date, *tag, *date, *ts_conflict; - int line_length; - - line = NULL; - line_chars_allocated = 0; - - ent = NULL; - while ((line_length = getline (&line, &line_chars_allocated, fpin)) > 0) - { - l = line; - - /* If CMD is not NULL, we are reading an Entries.Log file. - Each line in the Entries.Log file starts with a single - character command followed by a space. For backward - compatibility, the absence of a space indicates an add - command. */ - if (cmd != NULL) - { - if (l[1] != ' ') - *cmd = 'A'; - else - { - *cmd = l[0]; - l += 2; - } - } - - type = ENT_FILE; - - if (l[0] == 'D') - { - type = ENT_SUBDIR; - *sawdir = 1; - ++l; - /* An empty D line is permitted; it is a signal that this - Entries file lists all known subdirectories. */ - } - - if (l[0] != '/') - continue; - - user = l + 1; - if ((cp = strchr (user, '/')) == NULL) - continue; - *cp++ = '\0'; - vn = cp; - if ((cp = strchr (vn, '/')) == NULL) - continue; - *cp++ = '\0'; - ts = cp; - if ((cp = strchr (ts, '/')) == NULL) - continue; - *cp++ = '\0'; - options = cp; - if ((cp = strchr (options, '/')) == NULL) - continue; - *cp++ = '\0'; - tag_or_date = cp; - if ((cp = strchr (tag_or_date, '\n')) == NULL) - continue; - *cp = '\0'; - tag = (char *) NULL; - date = (char *) NULL; - if (*tag_or_date == 'T') - tag = tag_or_date + 1; - else if (*tag_or_date == 'D') - date = tag_or_date + 1; - - if ((ts_conflict = strchr (ts, '+'))) - *ts_conflict++ = '\0'; - - /* - * XXX - Convert timestamp from old format to new format. - * - * If the timestamp doesn't match the file's current - * mtime, we'd have to generate a string that doesn't - * match anyways, so cheat and base it on the existing - * string; it doesn't have to match the same mod time. - * - * For an unmodified file, write the correct timestamp. - */ - { - struct stat sb; - if (strlen (ts) > 30 && CVS_STAT (user, &sb) == 0) - { - char *c = ctime (&sb.st_mtime); - /* Fix non-standard format. */ - if (c[8] == '0') c[8] = ' '; - - if (!strncmp (ts + 25, c, 24)) - ts = time_stamp (user); - else - { - ts += 24; - ts[0] = '*'; - } - } - } - - ent = Entnode_Create (type, user, vn, ts, options, tag, date, - ts_conflict); - break; - } - - if (line_length < 0 && !feof (fpin)) - error (0, errno, "cannot read entries file"); - - free (line); - return ent; -} - -static int -fputentent(fp, p) - FILE *fp; - Entnode *p; -{ - switch (p->type) - { - case ENT_FILE: - break; - case ENT_SUBDIR: - if (fprintf (fp, "D") < 0) - return 1; - break; - } - - if (fprintf (fp, "/%s/%s/%s", p->user, p->version, p->timestamp) < 0) - return 1; - if (p->conflict) - { - if (fprintf (fp, "+%s", p->conflict) < 0) - return 1; - } - if (fprintf (fp, "/%s/", p->options) < 0) - return 1; - - if (p->tag) - { - if (fprintf (fp, "T%s\n", p->tag) < 0) - return 1; - } - else if (p->date) - { - if (fprintf (fp, "D%s\n", p->date) < 0) - return 1; - } - else - { - if (fprintf (fp, "\n") < 0) - return 1; - } - - return 0; -} - - -/* Read the entries file into a list, hashing on the file name. - - UPDATE_DIR is the name of the current directory, for use in error - messages, or NULL if not known (that is, noone has gotten around - to updating the caller to pass in the information). */ -List * -Entries_Open (aflag, update_dir) - int aflag; - char *update_dir; -{ - List *entries; - struct stickydirtag *sdtp = NULL; - Entnode *ent; - char *dirtag, *dirdate; - int dirnonbranch; - int do_rewrite = 0; - FILE *fpin; - int sawdir; - - /* get a fresh list... */ - entries = getlist (); - - /* - * Parse the CVS/Tag file, to get any default tag/date settings. Use - * list-private storage to tuck them away for Version_TS(). - */ - ParseTag (&dirtag, &dirdate, &dirnonbranch); - if (aflag || dirtag || dirdate) - { - sdtp = (struct stickydirtag *) xmalloc (sizeof (*sdtp)); - memset ((char *) sdtp, 0, sizeof (*sdtp)); - sdtp->aflag = aflag; - sdtp->tag = xstrdup (dirtag); - sdtp->date = xstrdup (dirdate); - sdtp->nonbranch = dirnonbranch; - - /* feed it into the list-private area */ - entries->list->data = sdtp; - entries->list->delproc = freesdt; - } - - sawdir = 0; - - fpin = CVS_FOPEN (CVSADM_ENT, "r"); - if (fpin == NULL) - { - if (update_dir != NULL) - error (0, 0, "in directory %s:", update_dir); - error (0, errno, "cannot open %s for reading", CVSADM_ENT); - } - else - { - while ((ent = fgetentent (fpin, (char *) NULL, &sawdir)) != NULL) - { - (void) AddEntryNode (entries, ent); - } - - if (fclose (fpin) < 0) - /* FIXME-update-dir: should include update_dir in message. */ - error (0, errno, "cannot close %s", CVSADM_ENT); - } - - fpin = CVS_FOPEN (CVSADM_ENTLOG, "r"); - if (fpin != NULL) - { - char cmd; - Node *node; - - while ((ent = fgetentent (fpin, &cmd, &sawdir)) != NULL) - { - switch (cmd) - { - case 'A': - (void) AddEntryNode (entries, ent); - break; - case 'R': - node = findnode_fn (entries, ent->user); - if (node != NULL) - delnode (node); - Entnode_Destroy (ent); - break; - default: - /* Ignore unrecognized commands. */ - Entnode_Destroy (ent); - break; - } - } - do_rewrite = 1; - if (fclose (fpin) < 0) - /* FIXME-update-dir: should include update_dir in message. */ - error (0, errno, "cannot close %s", CVSADM_ENTLOG); - } - - /* Update the list private data to indicate whether subdirectory - information is known. Nonexistent list private data is taken - to mean that it is known. */ - if (sdtp != NULL) - sdtp->subdirs = sawdir; - else if (! sawdir) - { - sdtp = (struct stickydirtag *) xmalloc (sizeof (*sdtp)); - memset ((char *) sdtp, 0, sizeof (*sdtp)); - sdtp->subdirs = 0; - entries->list->data = sdtp; - entries->list->delproc = freesdt; - } - - if (do_rewrite && !noexec) - write_entries (entries); - - /* clean up and return */ - if (dirtag) - free (dirtag); - if (dirdate) - free (dirdate); - return (entries); -} - -void -Entries_Close(list) - List *list; -{ - if (list) - { - if (!noexec) - { - if (isfile (CVSADM_ENTLOG)) - write_entries (list); - } - dellist(&list); - } -} - - -/* - * Free up the memory associated with the data section of an ENTRIES type - * node - */ -static void -Entries_delproc (node) - Node *node; -{ - Entnode *p = node->data; - - Entnode_Destroy(p); -} - -/* - * Get an Entries file list node, initialize it, and add it to the specified - * list - */ -static Node * -AddEntryNode (list, entdata) - List *list; - Entnode *entdata; -{ - Node *p; - - /* was it already there? */ - if ((p = findnode_fn (list, entdata->user)) != NULL) - { - /* take it out */ - delnode (p); - } - - /* get a node and fill in the regular stuff */ - p = getnode (); - p->type = ENTRIES; - p->delproc = Entries_delproc; - - /* this one gets a key of the name for hashing */ - /* FIXME This results in duplicated data --- the hash package shouldn't - assume that the key is dynamically allocated. The user's free proc - should be responsible for freeing the key. */ - p->key = xstrdup (entdata->user); - p->data = entdata; - - /* put the node into the list */ - addnode (list, p); - return (p); -} - -static char *root_template; - -static int -get_root_template(const char *repository, const char *path) -{ - if (root_template) { - if (strcmp(path, root_template) == 0) - return(0); - free(root_template); - } - if ((root_template = strdup(path)) == NULL) - return(-1); - return(0); -} - -/* - * Write out/Clear the CVS/Template file. - */ -void -WriteTemplate (dir, update_dir) - const char *dir; - const char *update_dir; -{ - char *tmp = NULL; - struct stat st1; - struct stat st2; - - if (Parse_Info(CVSROOTADM_RCSINFO, "cvs", get_root_template, 1) < 0) - return; - - if (asprintf(&tmp, "%s/%s", dir, CVSADM_TEMPLATE) < 0) - error (1, errno, "out of memory"); - - if (stat(root_template, &st1) == 0) { - if (stat(tmp, &st2) < 0 || st1.st_mtime != st2.st_mtime) { - FILE *fi; - FILE *fo; - - if ((fi = open_file(root_template, "r")) != NULL) { - if ((fo = open_file(tmp, "w")) != NULL) { - int n; - char buf[256]; - - while ((n = fread(buf, 1, sizeof(buf), fi)) > 0) - fwrite(buf, 1, n, fo); - fflush(fo); - if (ferror(fi) || ferror(fo)) { - fclose(fo); - remove(tmp); - error (1, errno, "error copying Template"); - } else { - struct timeval times[2]; - fclose(fo); - times[0].tv_sec = st1.st_mtime; - times[0].tv_usec = 0; - times[1] = times[0]; - utimes(tmp, times); - } - } - fclose(fi); - } - } - } - free(tmp); -} - -/* - * Write out/Clear the CVS/Tag file. - */ -void -WriteTag (dir, tag, date, nonbranch, update_dir, repository) - const char *dir; - const char *tag; - const char *date; - int nonbranch; - const char *update_dir; - const char *repository; -{ - FILE *fout; - char *tmp; - - if (noexec) - return; - - tmp = xmalloc ((dir ? strlen (dir) : 0) - + sizeof (CVSADM_TAG) - + 10); - if (dir == NULL) - (void) strcpy (tmp, CVSADM_TAG); - else - (void) sprintf (tmp, "%s/%s", dir, CVSADM_TAG); - - if (tag || date) - { - fout = open_file (tmp, "w+"); - if (tag) - { - if (nonbranch) - { - if (fprintf (fout, "N%s\n", tag) < 0) - error (1, errno, "write to %s failed", tmp); - } - else - { - if (fprintf (fout, "T%s\n", tag) < 0) - error (1, errno, "write to %s failed", tmp); - } - } - else - { - if (fprintf (fout, "D%s\n", date) < 0) - error (1, errno, "write to %s failed", tmp); - } - if (fclose (fout) == EOF) - error (1, errno, "cannot close %s", tmp); - } - else - if (unlink_file (tmp) < 0 && ! existence_error (errno)) - error (1, errno, "cannot remove %s", tmp); - free (tmp); -#ifdef SERVER_SUPPORT - if (server_active) - server_set_sticky (update_dir, repository, tag, date, nonbranch); -#endif -} - -/* Parse the CVS/Tag file for the current directory. - - If it contains a date, sets *DATEP to the date in a newly malloc'd - string, *TAGP to NULL, and *NONBRANCHP to an unspecified value. - - If it contains a branch tag, sets *TAGP to the tag in a newly - malloc'd string, *NONBRANCHP to 0, and *DATEP to NULL. - - If it contains a nonbranch tag, sets *TAGP to the tag in a newly - malloc'd string, *NONBRANCHP to 1, and *DATEP to NULL. - - If it does not exist, or contains something unrecognized by this - version of CVS, set *DATEP and *TAGP to NULL and *NONBRANCHP to - an unspecified value. - - If there is an error, print an error message, set *DATEP and *TAGP - to NULL, and return. */ -void -ParseTag (tagp, datep, nonbranchp) - char **tagp; - char **datep; - int *nonbranchp; -{ - FILE *fp; - - if (tagp) - *tagp = (char *) NULL; - if (datep) - *datep = (char *) NULL; - /* Always store a value here, even in the 'D' case where the value - is unspecified. Shuts up tools which check for references to - uninitialized memory. */ - if (nonbranchp != NULL) - *nonbranchp = 0; - fp = CVS_FOPEN (CVSADM_TAG, "r"); - if (fp) - { - char *line; - int line_length; - size_t line_chars_allocated; - - line = NULL; - line_chars_allocated = 0; - - if ((line_length = getline (&line, &line_chars_allocated, fp)) > 0) - { - /* Remove any trailing newline. */ - if (line[line_length - 1] == '\n') - line[--line_length] = '\0'; - switch (*line) - { - case 'T': - if (tagp != NULL) - *tagp = xstrdup (line + 1); - break; - case 'D': - if (datep != NULL) - *datep = xstrdup (line + 1); - break; - case 'N': - if (tagp != NULL) - *tagp = xstrdup (line + 1); - if (nonbranchp != NULL) - *nonbranchp = 1; - break; - default: - /* Silently ignore it; it may have been - written by a future version of CVS which extends the - syntax. */ - break; - } - } - - if (line_length < 0) - { - /* FIXME-update-dir: should include update_dir in messages. */ - if (feof (fp)) - error (0, 0, "cannot read %s: end of file", CVSADM_TAG); - else - error (0, errno, "cannot read %s", CVSADM_TAG); - } - - if (fclose (fp) < 0) - /* FIXME-update-dir: should include update_dir in message. */ - error (0, errno, "cannot close %s", CVSADM_TAG); - - free (line); - } - else if (!existence_error (errno)) - /* FIXME-update-dir: should include update_dir in message. */ - error (0, errno, "cannot open %s", CVSADM_TAG); -} - -/* - * This is called if all subdirectory information is known, but there - * aren't any subdirectories. It records that fact in the list - * private data. - */ - -void -Subdirs_Known (entries) - List *entries; -{ - struct stickydirtag *sdtp = entries->list->data; - - /* If there is no list private data, that means that the - subdirectory information is known. */ - if (sdtp != NULL && ! sdtp->subdirs) - { - FILE *fp; - - sdtp->subdirs = 1; - if (!noexec) - { - /* Create Entries.Log so that Entries_Close will do something. */ - entfilename = CVSADM_ENTLOG; - fp = CVS_FOPEN (entfilename, "a"); - if (fp == NULL) - { - int save_errno = errno; - - /* As in subdir_record, just silently skip the whole thing - if there is no CVSADM directory. */ - if (! isdir (CVSADM)) - return; - error (1, save_errno, "cannot open %s", entfilename); - } - else - { - if (fclose (fp) == EOF) - error (1, errno, "cannot close %s", entfilename); - } - } - } -} - -/* Record subdirectory information. */ - -static Entnode * -subdir_record (cmd, parent, dir) - int cmd; - const char *parent; - const char *dir; -{ - Entnode *entnode; - - /* None of the information associated with a directory is - currently meaningful. */ - entnode = Entnode_Create (ENT_SUBDIR, dir, "", "", "", - (char *) NULL, (char *) NULL, - (char *) NULL); - - if (!noexec) - { - if (parent == NULL) - entfilename = CVSADM_ENTLOG; - else - { - entfilename = xmalloc (strlen (parent) - + sizeof CVSADM_ENTLOG - + 10); - sprintf (entfilename, "%s/%s", parent, CVSADM_ENTLOG); - } - - entfile = CVS_FOPEN (entfilename, "a"); - if (entfile == NULL) - { - int save_errno = errno; - - /* It is not an error if there is no CVS administration - directory. Permitting this case simplifies some - calling code. */ - - if (parent == NULL) - { - if (! isdir (CVSADM)) - return entnode; - } - else - { - sprintf (entfilename, "%s/%s", parent, CVSADM); - if (! isdir (entfilename)) - { - free (entfilename); - entfilename = NULL; - return entnode; - } - } - - error (1, save_errno, "cannot open %s", entfilename); - } - - if (fprintf (entfile, "%c ", cmd) < 0) - error (1, errno, "cannot write %s", entfilename); - - if (fputentent (entfile, entnode) != 0) - error (1, errno, "cannot write %s", entfilename); - - if (fclose (entfile) == EOF) - error (1, errno, "error closing %s", entfilename); - - if (parent != NULL) - { - free (entfilename); - entfilename = NULL; - } - } - - return entnode; -} - -/* - * Record the addition of a new subdirectory DIR in PARENT. PARENT - * may be NULL, which means the current directory. ENTRIES is the - * current entries list; it may be NULL, which means that it need not - * be updated. - */ - -void -Subdir_Register (entries, parent, dir) - List *entries; - const char *parent; - const char *dir; -{ - Entnode *entnode; - - /* Ignore attempts to register ".". These can happen in the - server code. */ - if (dir[0] == '.' && dir[1] == '\0') - return; - - entnode = subdir_record ('A', parent, dir); - - if (entries != NULL && (parent == NULL || strcmp (parent, ".") == 0)) - (void) AddEntryNode (entries, entnode); - else - Entnode_Destroy (entnode); -} - -/* - * Record the removal of a subdirectory. The arguments are the same - * as for Subdir_Register. - */ - -void -Subdir_Deregister (entries, parent, dir) - List *entries; - const char *parent; - const char *dir; -{ - Entnode *entnode; - - entnode = subdir_record ('R', parent, dir); - Entnode_Destroy (entnode); - - if (entries != NULL && (parent == NULL || strcmp (parent, ".") == 0)) - { - Node *p; - - p = findnode_fn (entries, dir); - if (p != NULL) - delnode (p); - } -} - - - -/* OK, the following base_* code tracks the revisions of the files in - CVS/Base. We do this in a file CVS/Baserev. Separate from - CVS/Entries because it needs to go in separate data structures - anyway (the name in Entries must be unique), so this seemed - cleaner. The business of rewriting the whole file in - base_deregister and base_register is the kind of thing we used to - do for Entries and which turned out to be slow, which is why there - is now the Entries.Log machinery. So maybe from that point of - view it is a mistake to do this separately from Entries, I dunno. - - We also need something analogous for: - - 1. CVS/Template (so we can update the Template file automagically - without the user needing to check out a new working directory). - Updating would probably print a message (that part might be - optional, although probably it should be visible because not all - cvs commands would make the update happen and so it is a - user-visible behavior). Constructing version number for template - is a bit hairy (base it on the timestamp on the server? Or see if - the template is in checkoutlist and if yes use its versioning and - if no don't version it?).... - - 2. cvsignore (need to keep a copy in the working directory to do - "cvs release" on the client side; see comment at src/release.c - (release). Would also allow us to stop needing Questionable. */ - -enum base_walk { - /* Set the revision for FILE to *REV. */ - BASE_REGISTER, - /* Get the revision for FILE and put it in a newly malloc'd string - in *REV, or put NULL if not mentioned. */ - BASE_GET, - /* Remove FILE. */ - BASE_DEREGISTER -}; - -static void base_walk PROTO ((enum base_walk, struct file_info *, char **)); - -/* Read through the lines in CVS/Baserev, taking the actions as documented - for CODE. */ - -static void -base_walk (code, finfo, rev) - enum base_walk code; - struct file_info *finfo; - char **rev; -{ - FILE *fp; - char *line; - size_t line_allocated; - FILE *newf; - char *baserev_fullname; - char *baserevtmp_fullname; - - line = NULL; - line_allocated = 0; - newf = NULL; - - /* First compute the fullnames for the error messages. This - computation probably should be broken out into a separate function, - as recurse.c does it too and places like Entries_Open should be - doing it. */ - baserev_fullname = xmalloc (sizeof (CVSADM_BASEREV) - + strlen (finfo->update_dir) - + 2); - baserev_fullname[0] = '\0'; - baserevtmp_fullname = xmalloc (sizeof (CVSADM_BASEREVTMP) - + strlen (finfo->update_dir) - + 2); - baserevtmp_fullname[0] = '\0'; - if (finfo->update_dir[0] != '\0') - { - strcat (baserev_fullname, finfo->update_dir); - strcat (baserev_fullname, "/"); - strcat (baserevtmp_fullname, finfo->update_dir); - strcat (baserevtmp_fullname, "/"); - } - strcat (baserev_fullname, CVSADM_BASEREV); - strcat (baserevtmp_fullname, CVSADM_BASEREVTMP); - - fp = CVS_FOPEN (CVSADM_BASEREV, "r"); - if (fp == NULL) - { - if (!existence_error (errno)) - { - error (0, errno, "cannot open %s for reading", baserev_fullname); - goto out; - } - } - - switch (code) - { - case BASE_REGISTER: - case BASE_DEREGISTER: - newf = CVS_FOPEN (CVSADM_BASEREVTMP, "w"); - if (newf == NULL) - { - error (0, errno, "cannot open %s for writing", - baserevtmp_fullname); - goto out; - } - break; - case BASE_GET: - *rev = NULL; - break; - } - - if (fp != NULL) - { - while (getline (&line, &line_allocated, fp) >= 0) - { - char *linefile; - char *p; - char *linerev; - - if (line[0] != 'B') - /* Ignore, for future expansion. */ - continue; - - linefile = line + 1; - p = strchr (linefile, '/'); - if (p == NULL) - /* Syntax error, ignore. */ - continue; - linerev = p + 1; - p = strchr (linerev, '/'); - if (p == NULL) - continue; - - linerev[-1] = '\0'; - if (fncmp (linefile, finfo->file) == 0) - { - switch (code) - { - case BASE_REGISTER: - case BASE_DEREGISTER: - /* Don't copy over the old entry, we don't want it. */ - break; - case BASE_GET: - *p = '\0'; - *rev = xstrdup (linerev); - *p = '/'; - goto got_it; - } - } - else - { - linerev[-1] = '/'; - switch (code) - { - case BASE_REGISTER: - case BASE_DEREGISTER: - if (fprintf (newf, "%s\n", line) < 0) - error (0, errno, "error writing %s", - baserevtmp_fullname); - break; - case BASE_GET: - break; - } - } - } - if (ferror (fp)) - error (0, errno, "cannot read %s", baserev_fullname); - } - got_it: - - if (code == BASE_REGISTER) - { - if (fprintf (newf, "B%s/%s/\n", finfo->file, *rev) < 0) - error (0, errno, "error writing %s", - baserevtmp_fullname); - } - - out: - - if (line != NULL) - free (line); - - if (fp != NULL) - { - if (fclose (fp) < 0) - error (0, errno, "cannot close %s", baserev_fullname); - } - if (newf != NULL) - { - if (fclose (newf) < 0) - error (0, errno, "cannot close %s", baserevtmp_fullname); - rename_file (CVSADM_BASEREVTMP, CVSADM_BASEREV); - } - - free (baserev_fullname); - free (baserevtmp_fullname); -} - -/* Return, in a newly malloc'd string, the revision for FILE in CVS/Baserev, - or NULL if not listed. */ - -char * -base_get (finfo) - struct file_info *finfo; -{ - char *rev; - base_walk (BASE_GET, finfo, &rev); - return rev; -} - -/* Set the revision for FILE to REV. */ - -void -base_register (finfo, rev) - struct file_info *finfo; - char *rev; -{ - base_walk (BASE_REGISTER, finfo, &rev); -} - -/* Remove FILE. */ - -void -base_deregister (finfo) - struct file_info *finfo; -{ - base_walk (BASE_DEREGISTER, finfo, NULL); -} diff --git a/contrib/cvs/src/error.c b/contrib/cvs/src/error.c deleted file mode 100644 index 129ba9b..0000000 --- a/contrib/cvs/src/error.c +++ /dev/null @@ -1,255 +0,0 @@ -/* error.c -- error handler for noninteractive utilities - Copyright (C) 1990-1992 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. */ - -/* David MacKenzie */ -/* Brian Berliner added support for CVS */ - -#include "cvs.h" - -#include - -/* If non-zero, error will use the CVS protocol to stdout to report error - messages. This will only be set in the CVS server parent process; - most other code is run via do_cvs_command, which forks off a child - process and packages up its stderr in the protocol. */ -int error_use_protocol; - -#ifdef HAVE_VPRINTF - -#ifdef __STDC__ -#include -#define VA_START(args, lastarg) va_start(args, lastarg) -#else /* ! __STDC__ */ -#include -#define VA_START(args, lastarg) va_start(args) -#endif /* __STDC__ */ - -#else /* ! HAVE_VPRINTF */ - -#ifdef HAVE_DOPRNT -#define va_alist args -#define va_dcl int args; -#else /* ! HAVE_DOPRNT */ -#define va_alist a1, a2, a3, a4, a5, a6, a7, a8 -#define va_dcl char *a1, *a2, *a3, *a4, *a5, *a6, *a7, *a8; -#endif /* HAVE_DOPRNT */ - -#endif /* HAVE_VPRINTF */ - -#if STDC_HEADERS -#include -#include -#else /* ! STDC_HEADERS */ -#ifdef __STDC__ -void exit(int status); -#else /* ! __STDC__ */ -void exit (); -#endif /* __STDC__ */ -#endif /* STDC_HEADERS */ - -#ifndef strerror -extern char *strerror (); -#endif - -void -error_exit PROTO ((void)) -{ - rcs_cleanup (); - Lock_Cleanup (); -#ifdef SERVER_SUPPORT - if (server_active) - server_cleanup (0); -#endif -#ifdef SYSTEM_CLEANUP - /* Hook for OS-specific behavior, for example socket subsystems on - NT and OS2 or dealing with windows and arguments on Mac. */ - SYSTEM_CLEANUP (); -#endif - exit (EXIT_FAILURE); -} - -/* Print the program name and error message MESSAGE, which is a printf-style - format string with optional args. This is a very limited printf subset: - %s, %d, %c, %x and %% only (without anything between the % and the s, - d, &c). Callers who want something fancier can use sprintf. - - If ERRNUM is nonzero, print its corresponding system error message. - Exit with status EXIT_FAILURE if STATUS is nonzero. If MESSAGE is "", - no need to print a message. - - I think this is largely cleaned up to the point where it does the right - thing for the server, whether the normal server_active (child process) - case or the error_use_protocol (parent process) case. The one exception - is that STATUS nonzero for error_use_protocol probably doesn't work yet; - in that case still need to use the pending_error machinery in server.c. - - error() does not molest errno; some code (e.g. Entries_Open) depends - on being able to say something like: - error (0, 0, "foo"); - error (0, errno, "bar"); - - */ - -/* VARARGS */ -void -#if defined (__STDC__) -error (int status, int errnum, const char *message, ...) -#else -error (status, errnum, message, va_alist) - int status; - int errnum; - const char *message; - va_dcl -#endif -{ - int save_errno = errno; - - if (message[0] != '\0') - { - va_list args; - const char *p; - char *q; - char *str; - int num; - long lnum; - unsigned int unum; - unsigned long ulnum; - int ch; - char buf[100]; - - cvs_outerr (program_name, 0); - if (cvs_cmd_name && *cvs_cmd_name) - { - cvs_outerr (" ", 1); - if (status != 0) - cvs_outerr ("[", 1); - cvs_outerr (cvs_cmd_name, 0); - if (status != 0) - cvs_outerr (" aborted]", 0); - } - cvs_outerr (": ", 2); - - VA_START (args, message); - p = message; - while ((q = strchr (p, '%')) != NULL) - { - static const char msg[] = - "\ninternal error: bad % in error()\n"; - if (q - p > 0) - cvs_outerr (p, q - p); - - switch (q[1]) - { - case 's': - str = va_arg (args, char *); - cvs_outerr (str, strlen (str)); - break; - case 'd': - num = va_arg (args, int); - sprintf (buf, "%d", num); - cvs_outerr (buf, strlen (buf)); - break; - case 'l': - if (q[2] == 'd') - { - lnum = va_arg (args, long); - sprintf (buf, "%ld", lnum); - } - else if (q[2] == 'u') - { - ulnum = va_arg (args, unsigned long); - sprintf (buf, "%lu", ulnum); - } - else goto bad; - cvs_outerr (buf, strlen (buf)); - q++; - break; - case 'x': - unum = va_arg (args, unsigned int); - sprintf (buf, "%x", unum); - cvs_outerr (buf, strlen (buf)); - break; - case 'c': - ch = va_arg (args, int); - buf[0] = ch; - cvs_outerr (buf, 1); - break; - case '%': - cvs_outerr ("%", 1); - break; - default: - bad: - cvs_outerr (msg, sizeof (msg) - 1); - /* Don't just keep going, because q + 1 might point to the - terminating '\0'. */ - goto out; - } - p = q + 2; - } - cvs_outerr (p, strlen (p)); - out: - va_end (args); - - if (errnum != 0) - { - cvs_outerr (": ", 2); - cvs_outerr (strerror (errnum), 0); - } - cvs_outerr ("\n", 1); - } - - if (status) - error_exit (); - errno = save_errno; -} - -/* Print the program name and error message MESSAGE, which is a printf-style - format string with optional args to the file specified by FP. - If ERRNUM is nonzero, print its corresponding system error message. - Exit with status EXIT_FAILURE if STATUS is nonzero. */ -/* VARARGS */ -void -#if defined (HAVE_VPRINTF) && defined (__STDC__) -fperrmsg (FILE *fp, int status, int errnum, char *message, ...) -#else -fperrmsg (fp, status, errnum, message, va_alist) - FILE *fp; - int status; - int errnum; - char *message; - va_dcl -#endif -{ -#ifdef HAVE_VPRINTF - va_list args; -#endif - - fprintf (fp, "%s: ", program_name); -#ifdef HAVE_VPRINTF - VA_START (args, message); - vfprintf (fp, message, args); - va_end (args); -#else -#ifdef HAVE_DOPRNT - _doprnt (message, &args, fp); -#else - fprintf (fp, message, a1, a2, a3, a4, a5, a6, a7, a8); -#endif -#endif - if (errnum) - fprintf (fp, ": %s", strerror (errnum)); - putc ('\n', fp); - fflush (fp); - if (status) - error_exit (); -} diff --git a/contrib/cvs/src/error.h b/contrib/cvs/src/error.h deleted file mode 100644 index 1c8471d..0000000 --- a/contrib/cvs/src/error.h +++ /dev/null @@ -1,62 +0,0 @@ -/* error.h -- declaration for error-reporting function - Copyright (C) 1995 Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. */ - -#ifndef ERROR_H -#define ERROR_H - -/* Add prototype support. Normally this is done in cvs.h, but that - doesn't get included from lib/savecwd.c. */ -#ifndef PROTO -#if defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__) -#define PROTO(ARGS) ARGS -#else -#define PROTO(ARGS) () -#endif -#endif - -#ifndef __attribute__ -/* This feature is available in gcc versions 2.5 and later. */ -# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5) || __STRICT_ANSI__ -# define __attribute__(Spec) /* empty */ -# endif -/* The __-protected variants of `format' and `printf' attributes - are accepted by gcc versions 2.6.4 (effectively 2.7) and later. */ -# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7) -# define __format__ format -# define __printf__ printf -# define __noreturn__ noreturn -# endif -#endif - -#ifdef __STDC__ -void error (int, int, const char *, ...) \ - __attribute__ ((__format__ (__printf__, 3, 4))); -#else -void error (); -#endif - -/* Exit due to an error. Similar to error (1, 0, "message"), but call - it in the case where the message has already been printed. */ -#ifdef __STDC__ -void error_exit (void) __attribute__ ((__noreturn__)); -#else -void error_exit (); -#endif - -/* If non-zero, error will use the CVS protocol to report error - messages. This will only be set in the CVS server parent process; - most other code is run via do_cvs_command, which forks off a child - process and packages up its stderr in the protocol. */ -extern int error_use_protocol; - -#endif /* ERROR_H */ diff --git a/contrib/cvs/src/expand_path.c b/contrib/cvs/src/expand_path.c deleted file mode 100644 index 1c960f3..0000000 --- a/contrib/cvs/src/expand_path.c +++ /dev/null @@ -1,318 +0,0 @@ -/* expand_path.c -- expand environmental variables in passed in string - * - * Copyright (C) 1995-2005 The Free Software Foundation, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * The main routine is expand_path(), it is the routine that handles - * the '~' character in four forms: - * ~name - * ~name/ - * ~/ - * ~ - * and handles environment variables contained within the pathname - * which are defined by: - * ${var_name} (var_name is the name of the environ variable) - * $var_name (var_name ends w/ non-alphanumeric char other than '_') - */ - -#include "cvs.h" -#include - -static char *expand_variable PROTO((const char *env, const char *file, - int line)); - - - -/* User variables. */ - -List *variable_list = NULL; - -static void variable_delproc PROTO ((Node *)); - -static void -variable_delproc (node) - Node *node; -{ - free (node->data); -} - -/* Currently used by -s option; we might want a way to set user - variables in a file in the $CVSROOT/CVSROOT directory too. */ - -void -variable_set (nameval) - char *nameval; -{ - char *p; - char *name; - Node *node; - - p = nameval; - while (isalnum ((unsigned char) *p) || *p == '_') - ++p; - if (*p != '=') - error (1, 0, "illegal character in user variable name in %s", nameval); - if (p == nameval) - error (1, 0, "empty user variable name in %s", nameval); - name = xmalloc (p - nameval + 1); - strncpy (name, nameval, p - nameval); - name[p - nameval] = '\0'; - /* Make p point to the value. */ - ++p; - if (strchr (p, '\012') != NULL) - error (1, 0, "linefeed in user variable value in %s", nameval); - - if (variable_list == NULL) - variable_list = getlist (); - - node = findnode (variable_list, name); - if (node == NULL) - { - node = getnode (); - node->type = VARIABLE; - node->delproc = variable_delproc; - node->key = name; - node->data = xstrdup (p); - (void) addnode (variable_list, node); - } - else - { - /* Replace the old value. For example, this means that -s - options on the command line override ones from .cvsrc. */ - free (node->data); - node->data = xstrdup (p); - free (name); - } -} - - - -/* This routine will expand the pathname to account for ~ and $ - characters as described above. Returns a pointer to a newly - malloc'd string. If an error occurs, an error message is printed - via error() and NULL is returned. FILE and LINE are the filename - and linenumber to include in the error message. FILE must point - to something; LINE can be zero to indicate the line number is not - known. */ -char * -expand_path (name, file, line) - const char *name; - const char *file; - int line; -{ - size_t s, d, p; - char *e; - - char *mybuf = NULL; - size_t mybuf_size = 0; - char *buf = NULL; - size_t buf_size = 0; - - char *result; - - /* Sorry this routine is so ugly; it is a head-on collision - between the `traditional' unix *d++ style and the need to - dynamically allocate. It would be much cleaner (and probably - faster, not that this is a bottleneck for CVS) with more use of - strcpy & friends, but I haven't taken the effort to rewrite it - thusly. */ - - /* First copy from NAME to MYBUF, expanding $ as we go. */ - s = d = 0; - while (name[s] != '\0') - { - if (name[s] == '$') - { - p = d; - if (name[++s] == '{') - { - while (name[++s] != '}' && name[s] != '\0') - { - expand_string (&mybuf, &mybuf_size, p + 1); - mybuf[p++] = name[s]; - } - if (name[s] != '\0') ++s; - } - else - { - while (isalnum ((unsigned char) name[s]) || name[s] == '_') - { - expand_string (&mybuf, &mybuf_size, p + 1); - mybuf[p++] = name[s++]; - } - } - expand_string (&mybuf, &mybuf_size, p + 1); - mybuf[p] = '\0'; - e = expand_variable (mybuf + d, file, line); - - if (e) - { - p = strlen(e); - expand_string (&mybuf, &mybuf_size, d + p); - memcpy(mybuf + d, e, p); - d += p; - } - else - /* expand_variable has already printed an error message. */ - goto error_exit; - } - else - { - expand_string (&mybuf, &mybuf_size, d + 1); - mybuf[d++] = name[s++]; - } - } - expand_string (&mybuf, &mybuf_size, d + 1); - mybuf[d++] = '\0'; - - /* Then copy from MYBUF to BUF, expanding ~. */ - s = d = 0; - /* If you don't want ~username ~/ to be expanded simply remove - * This entire if statement including the else portion - */ - if (mybuf[s] == '~') - { - p = d; - while (mybuf[++s] != '/' && mybuf[s] != '\0') - { - expand_string (&buf, &buf_size, p + 1); - buf[p++] = name[s]; - } - expand_string (&buf, &buf_size, p + 1); - buf[p] = '\0'; - - if (p == d) - e = get_homedir (); - else - { -#ifdef GETPWNAM_MISSING - if (line != 0) - error (0, 0, - "%s:%d:tilde expansion not supported on this system", - file, line); - else - error (0, 0, "%s:tilde expansion not supported on this system", - file); - goto error_exit; -#else - struct passwd *ps; - ps = getpwnam (buf + d); - if (ps == NULL) - { - if (line != 0) - error (0, 0, "%s:%d: no such user %s", - file, line, buf + d); - else - error (0, 0, "%s: no such user %s", file, buf + d); - goto error_exit; - } - e = ps->pw_dir; -#endif - } - if (e == NULL) - error (1, 0, "cannot find home directory"); - - p = strlen(e); - expand_string (&buf, &buf_size, d + p); - memcpy(buf + d, e, p); - d += p; - } - /* Kill up to here */ - p = strlen(mybuf + s) + 1; - expand_string (&buf, &buf_size, d + p); - memcpy(buf + d, mybuf + s, p); - - /* OK, buf contains the value we want to return. Clean up and return - it. */ - free (mybuf); - /* Save a little memory with xstrdup; buf will tend to allocate - more than it needs to. */ - result = xstrdup (buf); - free (buf); - return result; - - error_exit: - if (mybuf != NULL) - free (mybuf); - if (buf != NULL) - free (buf); - return NULL; -} - -static char * -expand_variable (name, file, line) - const char *name; - const char *file; - int line; -{ - if (strcmp (name, CVSROOT_ENV) == 0) - return current_parsed_root->directory; - else if (strcmp (name, "RCSBIN") == 0) - { - error (0, 0, "RCSBIN internal variable is no longer supported"); - return NULL; - } - else if (strcmp (name, EDITOR1_ENV) == 0) - return Editor; - else if (strcmp (name, EDITOR2_ENV) == 0) - return Editor; - else if (strcmp (name, EDITOR3_ENV) == 0) - return Editor; - else if (strcmp (name, "USER") == 0) - return getcaller (); - else if (isalpha ((unsigned char) name[0])) - { - /* These names are reserved for future versions of CVS, - so that is why it is an error. */ - if (line != 0) - error (0, 0, "%s:%d: no such internal variable $%s", - file, line, name); - else - error (0, 0, "%s: no such internal variable $%s", - file, name); - return NULL; - } - else if (name[0] == '=') - { - Node *node; - /* Crazy syntax for a user variable. But we want - *something* that lets the user name a user variable - anything he wants, without interference from - (existing or future) internal variables. */ - node = findnode (variable_list, name + 1); - if (node == NULL) - { - if (line != 0) - error (0, 0, "%s:%d: no such user variable ${%s}", - file, line, name); - else - error (0, 0, "%s: no such user variable ${%s}", - file, name); - return NULL; - } - return node->data; - } - else - { - /* It is an unrecognized character. We return an error to - reserve these for future versions of CVS; it is plausible - that various crazy syntaxes might be invented for inserting - information about revisions, branches, etc. */ - if (line != 0) - error (0, 0, "%s:%d: unrecognized variable syntax %s", - file, line, name); - else - error (0, 0, "%s: unrecognized variable syntax %s", - file, name); - return NULL; - } -} diff --git a/contrib/cvs/src/fileattr.c b/contrib/cvs/src/fileattr.c deleted file mode 100644 index ca6bd0e..0000000 --- a/contrib/cvs/src/fileattr.c +++ /dev/null @@ -1,656 +0,0 @@ -/* Implementation for file attribute munging features. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. */ - -#include "cvs.h" -#include "getline.h" -#include "fileattr.h" -#include - -static void fileattr_read PROTO ((void)); -static int writeattr_proc PROTO ((Node *, void *)); - -/* Where to look for CVSREP_FILEATTR. */ -static char *fileattr_stored_repos; - -/* The in-memory attributes. */ -static List *attrlist; -static char *fileattr_default_attrs; -/* We have already tried to read attributes and failed in this directory - (for example, there is no CVSREP_FILEATTR file). */ -static int attr_read_attempted; - -/* Have the in-memory attributes been modified since we read them? */ -static int attrs_modified; - -/* More in-memory attributes: linked list of unrecognized - fileattr lines. We pass these on unchanged. */ -struct unrecog { - char *line; - struct unrecog *next; -}; -static struct unrecog *unrecog_head; - -/* Note that if noone calls fileattr_get, this is very cheap. No stat(), - no open(), no nothing. */ -void -fileattr_startdir (repos) - const char *repos; -{ - assert (fileattr_stored_repos == NULL); - fileattr_stored_repos = xstrdup (repos); - assert (attrlist == NULL); - attr_read_attempted = 0; - assert (unrecog_head == NULL); -} - -static void -fileattr_delproc (node) - Node *node; -{ - assert (node->data != NULL); - free (node->data); - node->data = NULL; -} - -/* Read all the attributes for the current directory into memory. */ -static void -fileattr_read () -{ - char *fname; - FILE *fp; - char *line = NULL; - size_t line_len = 0; - - /* If there are no attributes, don't waste time repeatedly looking - for the CVSREP_FILEATTR file. */ - if (attr_read_attempted) - return; - - /* If NULL was passed to fileattr_startdir, then it isn't kosher to look - at attributes. */ - assert (fileattr_stored_repos != NULL); - - fname = xmalloc (strlen (fileattr_stored_repos) - + 1 - + sizeof (CVSREP_FILEATTR) - + 1); - - strcpy (fname, fileattr_stored_repos); - strcat (fname, "/"); - strcat (fname, CVSREP_FILEATTR); - - attr_read_attempted = 1; - fp = CVS_FOPEN (fname, FOPEN_BINARY_READ); - if (fp == NULL) - { - if (!existence_error (errno)) - error (0, errno, "cannot read %s", fname); - free (fname); - return; - } - attrlist = getlist (); - while (1) { - int nread; - nread = getline (&line, &line_len, fp); - if (nread < 0) - break; - /* Remove trailing newline. */ - line[nread - 1] = '\0'; - if (line[0] == 'F') - { - char *p; - Node *newnode; - - p = strchr (line, '\t'); - if (p == NULL) - error (1, 0, - "file attribute database corruption: tab missing in %s", - fname); - *p++ = '\0'; - newnode = getnode (); - newnode->type = FILEATTR; - newnode->delproc = fileattr_delproc; - newnode->key = xstrdup (line + 1); - newnode->data = xstrdup (p); - if (addnode (attrlist, newnode) != 0) - /* If the same filename appears twice in the file, discard - any line other than the first for that filename. This - is the way that CVS has behaved since file attributes - were first introduced. */ - freenode (newnode); - } - else if (line[0] == 'D') - { - char *p; - /* Currently nothing to skip here, but for future expansion, - ignore anything located here. */ - p = strchr (line, '\t'); - if (p == NULL) - error (1, 0, - "file attribute database corruption: tab missing in %s", - fname); - ++p; - if (fileattr_default_attrs) free (fileattr_default_attrs); - fileattr_default_attrs = xstrdup (p); - } - else - { - /* Unrecognized type, we want to just preserve the line without - changing it, for future expansion. */ - struct unrecog *new; - - new = (struct unrecog *) xmalloc (sizeof (struct unrecog)); - new->line = xstrdup (line); - new->next = unrecog_head; - unrecog_head = new; - } - } - if (ferror (fp)) - error (0, errno, "cannot read %s", fname); - if (line != NULL) - free (line); - if (fclose (fp) < 0) - error (0, errno, "cannot close %s", fname); - attrs_modified = 0; - free (fname); -} - -char * -fileattr_get (filename, attrname) - const char *filename; - const char *attrname; -{ - Node *node; - size_t attrname_len = strlen (attrname); - char *p; - - if (attrlist == NULL) - fileattr_read (); - if (attrlist == NULL) - /* Either nothing has any attributes, or fileattr_read already printed - an error message. */ - return NULL; - - if (filename == NULL) - p = fileattr_default_attrs; - else - { - node = findnode (attrlist, filename); - if (node == NULL) - /* A file not mentioned has no attributes. */ - return NULL; - p = node->data; - } - while (p) - { - if (strncmp (attrname, p, attrname_len) == 0 - && p[attrname_len] == '=') - { - /* Found it. */ - return p + attrname_len + 1; - } - p = strchr (p, ';'); - if (p == NULL) - break; - ++p; - } - /* The file doesn't have this attribute. */ - return NULL; -} - -char * -fileattr_get0 (filename, attrname) - const char *filename; - const char *attrname; -{ - char *cp; - char *cpend; - char *retval; - - cp = fileattr_get (filename, attrname); - if (cp == NULL) - return NULL; - cpend = strchr (cp, ';'); - if (cpend == NULL) - cpend = cp + strlen (cp); - retval = xmalloc (cpend - cp + 1); - strncpy (retval, cp, cpend - cp); - retval[cpend - cp] = '\0'; - return retval; -} - -char * -fileattr_modify (list, attrname, attrval, namevalsep, entsep) - char *list; - const char *attrname; - const char *attrval; - int namevalsep; - int entsep; -{ - char *retval; - char *rp; - size_t attrname_len = strlen (attrname); - - /* Portion of list before the attribute to be replaced. */ - char *pre; - char *preend; - /* Portion of list after the attribute to be replaced. */ - char *post; - - char *p; - char *p2; - - p = list; - pre = list; - preend = NULL; - /* post is NULL unless set otherwise. */ - post = NULL; - p2 = NULL; - if (list != NULL) - { - while (1) { - p2 = strchr (p, entsep); - if (p2 == NULL) - { - p2 = p + strlen (p); - if (preend == NULL) - preend = p2; - } - else - ++p2; - if (strncmp (attrname, p, attrname_len) == 0 - && p[attrname_len] == namevalsep) - { - /* Found it. */ - preend = p; - if (preend > list) - /* Don't include the preceding entsep. */ - --preend; - - post = p2; - } - if (p2[0] == '\0') - break; - p = p2; - } - } - if (post == NULL) - post = p2; - - if (preend == pre && attrval == NULL && post == p2) - return NULL; - - retval = xmalloc ((preend - pre) - + 1 - + (attrval == NULL ? 0 : (attrname_len + 1 - + strlen (attrval))) - + 1 - + (p2 - post) - + 1); - if (preend != pre) - { - strncpy (retval, pre, preend - pre); - rp = retval + (preend - pre); - if (attrval != NULL) - *rp++ = entsep; - *rp = '\0'; - } - else - retval[0] = '\0'; - if (attrval != NULL) - { - strcat (retval, attrname); - rp = retval + strlen (retval); - *rp++ = namevalsep; - strcpy (rp, attrval); - } - if (post != p2) - { - rp = retval + strlen (retval); - if (preend != pre || attrval != NULL) - *rp++ = entsep; - strncpy (rp, post, p2 - post); - rp += p2 - post; - *rp = '\0'; - } - return retval; -} - -void -fileattr_set (filename, attrname, attrval) - const char *filename; - const char *attrname; - const char *attrval; -{ - Node *node; - char *p; - - if (filename == NULL) - { - p = fileattr_modify (fileattr_default_attrs, attrname, attrval, - '=', ';'); - if (fileattr_default_attrs != NULL) - free (fileattr_default_attrs); - fileattr_default_attrs = p; - attrs_modified = 1; - return; - } - if (attrlist == NULL) - fileattr_read (); - if (attrlist == NULL) - { - /* Not sure this is a graceful way to handle things - in the case where fileattr_read was unable to read the file. */ - /* No attributes existed previously. */ - attrlist = getlist (); - } - - node = findnode (attrlist, filename); - if (node == NULL) - { - if (attrval == NULL) - /* Attempt to remove an attribute which wasn't there. */ - return; - - /* First attribute for this file. */ - node = getnode (); - node->type = FILEATTR; - node->delproc = fileattr_delproc; - node->key = xstrdup (filename); - node->data = xmalloc (strlen (attrname) + 1 + strlen (attrval) + 1); - strcpy (node->data, attrname); - strcat (node->data, "="); - strcat (node->data, attrval); - addnode (attrlist, node); - } - - p = fileattr_modify (node->data, attrname, attrval, '=', ';'); - if (p == NULL) - delnode (node); - else - { - free (node->data); - node->data = p; - } - - attrs_modified = 1; -} - -char * -fileattr_getall (filename) - const char *filename; -{ - Node *node; - char *p; - - if (attrlist == NULL) - fileattr_read (); - if (attrlist == NULL) - /* Either nothing has any attributes, or fileattr_read already printed - an error message. */ - return NULL; - - if (filename == NULL) - p = fileattr_default_attrs; - else - { - node = findnode (attrlist, filename); - if (node == NULL) - /* A file not mentioned has no attributes. */ - return NULL; - p = node->data; - } - return xstrdup (p); -} - -void -fileattr_setall (filename, attrs) - const char *filename; - const char *attrs; -{ - Node *node; - - if (filename == NULL) - { - if (fileattr_default_attrs != NULL) - free (fileattr_default_attrs); - fileattr_default_attrs = xstrdup (attrs); - attrs_modified = 1; - return; - } - if (attrlist == NULL) - fileattr_read (); - if (attrlist == NULL) - { - /* Not sure this is a graceful way to handle things - in the case where fileattr_read was unable to read the file. */ - /* No attributes existed previously. */ - attrlist = getlist (); - } - - node = findnode (attrlist, filename); - if (node == NULL) - { - /* The file had no attributes. Add them if we have any to add. */ - if (attrs != NULL) - { - node = getnode (); - node->type = FILEATTR; - node->delproc = fileattr_delproc; - node->key = xstrdup (filename); - node->data = xstrdup (attrs); - addnode (attrlist, node); - } - } - else - { - if (attrs == NULL) - delnode (node); - else - { - free (node->data); - node->data = xstrdup (attrs); - } - } - - attrs_modified = 1; -} - -void -fileattr_newfile (filename) - const char *filename; -{ - Node *node; - - if (attrlist == NULL) - fileattr_read (); - - if (fileattr_default_attrs == NULL) - return; - - if (attrlist == NULL) - { - /* Not sure this is a graceful way to handle things - in the case where fileattr_read was unable to read the file. */ - /* No attributes existed previously. */ - attrlist = getlist (); - } - - node = getnode (); - node->type = FILEATTR; - node->delproc = fileattr_delproc; - node->key = xstrdup (filename); - node->data = xstrdup (fileattr_default_attrs); - addnode (attrlist, node); - attrs_modified = 1; -} - -static int -writeattr_proc (node, data) - Node *node; - void *data; -{ - FILE *fp = (FILE *)data; - fputs ("F", fp); - fputs (node->key, fp); - fputs ("\t", fp); - fputs (node->data, fp); - fputs ("\012", fp); - return 0; -} - -void -fileattr_write () -{ - FILE *fp; - char *fname; - mode_t omask; - struct unrecog *p; - - if (!attrs_modified) - return; - - if (noexec) - return; - - /* If NULL was passed to fileattr_startdir, then it isn't kosher to set - attributes. */ - assert (fileattr_stored_repos != NULL); - - fname = xmalloc (strlen (fileattr_stored_repos) - + 1 - + sizeof (CVSREP_FILEATTR) - + 1); - - strcpy (fname, fileattr_stored_repos); - strcat (fname, "/"); - strcat (fname, CVSREP_FILEATTR); - - if (list_isempty (attrlist) - && fileattr_default_attrs == NULL - && unrecog_head == NULL) - { - /* There are no attributes. */ - if (unlink_file (fname) < 0) - { - if (!existence_error (errno)) - { - error (0, errno, "cannot remove %s", fname); - } - } - - /* Now remove CVSREP directory, if empty. The main reason we bother - is that CVS 1.6 and earlier will choke if a CVSREP directory - exists, so provide the user a graceful way to remove it. */ - strcpy (fname, fileattr_stored_repos); - strcat (fname, "/"); - strcat (fname, CVSREP); - if (CVS_RMDIR (fname) < 0) - { - if (errno != ENOTEMPTY - - /* Don't know why we would be here if there is no CVSREP - directory, but it seemed to be happening anyway, so - check for it. */ - && !existence_error (errno)) - error (0, errno, "cannot remove %s", fname); - } - - free (fname); - return; - } - - omask = umask (cvsumask); - fp = CVS_FOPEN (fname, FOPEN_BINARY_WRITE); - if (fp == NULL) - { - if (existence_error (errno)) - { - /* Maybe the CVSREP directory doesn't exist. Try creating it. */ - char *repname; - - repname = xmalloc (strlen (fileattr_stored_repos) - + 1 - + sizeof (CVSREP) - + 1); - strcpy (repname, fileattr_stored_repos); - strcat (repname, "/"); - strcat (repname, CVSREP); - - if (CVS_MKDIR (repname, 0777) < 0 && errno != EEXIST) - { - error (0, errno, "cannot make directory %s", repname); - (void) umask (omask); - free (fname); - free (repname); - return; - } - free (repname); - - fp = CVS_FOPEN (fname, FOPEN_BINARY_WRITE); - } - if (fp == NULL) - { - error (0, errno, "cannot write %s", fname); - (void) umask (omask); - free (fname); - return; - } - } - (void) umask (omask); - - /* First write the "F" attributes. */ - walklist (attrlist, writeattr_proc, fp); - - /* Then the "D" attribute. */ - if (fileattr_default_attrs != NULL) - { - fputs ("D\t", fp); - fputs (fileattr_default_attrs, fp); - fputs ("\012", fp); - } - - /* Then any other attributes. */ - for (p = unrecog_head; p != NULL; p = p->next) - { - fputs (p->line, fp); - fputs ("\012", fp); - } - - if (fclose (fp) < 0) - error (0, errno, "cannot close %s", fname); - attrs_modified = 0; - free (fname); -} - -void -fileattr_free () -{ - /* Note that attrs_modified will ordinarily be zero, but there are - a few cases in which fileattr_write will fail to zero it (if - noexec is set, or error conditions). This probably is the way - it should be. */ - dellist (&attrlist); - if (fileattr_stored_repos != NULL) - free (fileattr_stored_repos); - fileattr_stored_repos = NULL; - 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); - } -} diff --git a/contrib/cvs/src/fileattr.h b/contrib/cvs/src/fileattr.h deleted file mode 100644 index 507807c..0000000 --- a/contrib/cvs/src/fileattr.h +++ /dev/null @@ -1,136 +0,0 @@ -/* Declarations for file attribute munging features. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. */ - -#ifndef FILEATTR_H - -/* File containing per-file attributes. The format of this file is in - cvs.texinfo but here is a quick summary. The file contains a - series of entries: - - ENT-TYPE FILENAME ATTRNAME = ATTRVAL - {; ATTRNAME = ATTRVAL} - - ENT-TYPE is 'F' for a file. - - ENT-TYPE is 'D', and FILENAME empty, for default attributes. - - Other ENT-TYPE are reserved for future expansion. - - Note that the order of the line is not significant; CVS is free to - rearrange them at its convenience. - - FIXME: this implementation doesn't handle '\0' in any of the - fields. We are encouraged to fix this (by cvs.texinfo). - - By convention, ATTRNAME starting with '_' is for an attribute given - special meaning by CVS; other ATTRNAMEs are for user-defined attributes - (or will be, once we add commands to manipulate user-defined attributes). - - Builtin attributes: - - _watched: Present means the file is watched and should be checked out - read-only. - - _watchers: Users with watches for this file. Value is - WATCHER > TYPE { , WATCHER > TYPE } - where WATCHER is a username, and TYPE is edit,unedit,commit separated by - + (or nothing if none; there is no "none" or "all" keyword). - - _editors: Users editing this file. Value is - EDITOR > VAL { , EDITOR > VAL } - where EDITOR is a username, and VAL is TIME+HOSTNAME+PATHNAME, where - TIME is when the "cvs edit" command happened, - and HOSTNAME and PATHNAME are for the working directory. */ - -#define CVSREP_FILEATTR "CVS/fileattr" - -/* Prepare for a new directory with repository REPOS. If REPOS is NULL, - then prepare for a "non-directory"; the caller can call fileattr_write - and fileattr_free, but must not call fileattr_get or fileattr_set. */ -extern void fileattr_startdir PROTO ((const char *repos)); - -/* Get the attribute ATTRNAME for file FILENAME. The return value - points into memory managed by the fileattr_* routines, should not - be altered by the caller, and is only good until the next call to - fileattr_clear or fileattr_set. It points to the value, terminated - by '\0' or ';'. Return NULL if said file lacks said attribute. - If FILENAME is NULL, return default attributes (attributes for - files created in the future). */ -extern char *fileattr_get PROTO ((const char *filename, const char *attrname)); - -/* Like fileattr_get, but return a pointer to a newly malloc'd string - terminated by '\0' (or NULL if said file lacks said attribute). */ -extern char *fileattr_get0 PROTO ((const char *filename, - const char *attrname)); - -/* This is just a string manipulation function; it does not manipulate - file attributes as such. - - LIST is in the format - - ATTRNAME NAMEVALSEP ATTRVAL {ENTSEP ATTRNAME NAMEVALSEP ATTRVAL} - - And we want to put in an attribute with name NAME and value VAL, - replacing the already-present attribute with name NAME if there is - one. Or if VAL is NULL remove attribute NAME. Return a new - malloc'd list; don't muck with the one passed in. If we are removing - the last attribute return NULL. LIST can be NULL to mean that we - started out without any attributes. - - Examples: - - fileattr_modify ("abc=def", "xxx", "val", '=', ';')) => "abc=def;xxx=val" - fileattr_modify ("abc=def", "abc", "val", '=', ';')) => "abc=val" - fileattr_modify ("abc=v1;def=v2", "abc", "val", '=', ';')) - => "abc=val;def=v2" - fileattr_modify ("abc=v1;def=v2", "def", "val", '=', ';')) - => "abc=v1;def=val" - fileattr_modify ("abc=v1;def=v2", "xxx", "val", '=', ';')) - => "abc=v1;def=v2;xxx=val" - fileattr_modify ("abc=v1;def=v2;ghi=v3", "def", "val", '=', ';')) - => "abc=v1;def=val;ghi=v3" -*/ - -extern char *fileattr_modify PROTO ((char *list, const char *attrname, - const char *attrval, int namevalsep, - int entsep)); - -/* Set attribute ATTRNAME for file FILENAME to ATTRVAL. If ATTRVAL is NULL, - the attribute is removed. Changes are not written to disk until the - next call to fileattr_write. If FILENAME is NULL, set attributes for - files created in the future. If ATTRVAL is NULL, remove that attribute. */ -extern void fileattr_set PROTO ((const char *filename, const char *attrname, - const char *attrval)); - -/* Get all the attributes for file FILENAME. They are returned as malloc'd - data in an unspecified format which is guaranteed only to be good for - passing to fileattr_setall, or NULL if no attributes. If FILENAME is - NULL, get default attributes. */ -extern char *fileattr_getall PROTO ((const char *filename)); - -/* Set the attributes for file FILENAME to ATTRS, overwriting all previous - attributes for that file. ATTRS was obtained from a previous call to - fileattr_getall (malloc'd data or NULL). */ -extern void fileattr_setall PROTO ((const char *filename, const char *attrs)); - -/* Set the attributes for file FILENAME in whatever manner is appropriate - for a newly created file. */ -extern void fileattr_newfile PROTO ((const char *filename)); - -/* Write out all modified attributes. */ -extern void fileattr_write PROTO ((void)); - -/* Free all memory allocated by fileattr_*. */ -extern void fileattr_free PROTO ((void)); - -#define FILEATTR_H 1 -#endif /* fileattr.h */ diff --git a/contrib/cvs/src/filesubr.c b/contrib/cvs/src/filesubr.c deleted file mode 100644 index 1e1f901..0000000 --- a/contrib/cvs/src/filesubr.c +++ /dev/null @@ -1,1100 +0,0 @@ -/* filesubr.c --- subroutines for dealing with files - Jim Blandy - - This file is part of GNU CVS. - - GNU CVS is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. */ - -/* These functions were moved out of subr.c because they need different - definitions under operating systems (like, say, Windows NT) with different - file system semantics. */ - -#include -#include "cvs.h" - -#include "xsize.h" - -static int deep_remove_dir PROTO((const char *path)); - -/* - * Copies "from" to "to". - */ -void -copy_file (from, to) - const char *from; - const char *to; -{ - struct stat sb; - struct utimbuf t; - int fdin, fdout; - - if (trace) - (void) fprintf (stderr, "%s-> copy(%s,%s)\n", - CLIENT_SERVER_STR, from, to); - if (noexec) - return; - - /* If the file to be copied is a link or a device, then just create - the new link or device appropriately. */ - if (islink (from)) - { - char *source = xreadlink (from); - symlink (source, to); - free (source); - return; - } - - if (isdevice (from)) - { -#if defined(HAVE_MKNOD) && defined(HAVE_STRUCT_STAT_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 - { - /* Not a link or a device... probably a regular file. */ - if ((fdin = open (from, O_RDONLY)) < 0) - error (1, errno, "cannot open %s for copying", from); - if (fstat (fdin, &sb) < 0) - error (1, errno, "cannot fstat %s", from); - if ((fdout = creat (to, (int) sb.st_mode & 07777)) < 0) - error (1, errno, "cannot create %s for copying", to); - if (sb.st_size > 0) - { - char buf[BUFSIZ]; - int n; - - for (;;) - { - n = read (fdin, buf, sizeof(buf)); - if (n == -1) - { -#ifdef EINTR - if (errno == EINTR) - continue; -#endif - error (1, errno, "cannot read file %s for copying", from); - } - else if (n == 0) - break; - - if (write(fdout, buf, n) != n) { - error (1, errno, "cannot write file %s for copying", to); - } - } - -#ifdef HAVE_FSYNC - if (fsync (fdout)) - error (1, errno, "cannot fsync file %s after copying", to); -#endif - } - - if (close (fdin) < 0) - error (0, errno, "cannot close %s", from); - if (close (fdout) < 0) - error (1, errno, "cannot close %s", to); - } - - /* preserve last access & modification times */ - memset ((char *) &t, 0, sizeof (t)); - t.actime = sb.st_atime; - t.modtime = sb.st_mtime; - (void) utime (to, &t); -} - -/* FIXME-krp: these functions would benefit from caching the char * & - stat buf. */ - -/* - * Returns non-zero if the argument file is a directory, or is a symbolic - * link which points to a directory. - */ -int -isdir (file) - const char *file; -{ - struct stat sb; - - if (stat (file, &sb) < 0) - return (0); - return (S_ISDIR (sb.st_mode)); -} - -/* - * Returns non-zero if the argument file is a symbolic link. - */ -int -islink (file) - const char *file; -{ -#ifdef S_ISLNK - struct stat sb; - - if (CVS_LSTAT (file, &sb) < 0) - return (0); - return (S_ISLNK (sb.st_mode)); -#else - return (0); -#endif -} - -/* - * Returns non-zero if the argument file is a block or - * character special device. - */ -int -isdevice (file) - const char *file; -{ - struct stat sb; - - if (CVS_LSTAT (file, &sb) < 0) - return (0); -#ifdef S_ISBLK - if (S_ISBLK (sb.st_mode)) - return 1; -#endif -#ifdef S_ISCHR - if (S_ISCHR (sb.st_mode)) - return 1; -#endif - return 0; -} - -/* - * Returns non-zero if the argument file exists. - */ -int -isfile (file) - const char *file; -{ - return isaccessible(file, F_OK); -} - -/* - * Returns non-zero if the argument file is readable. - */ -int -isreadable (file) - const char *file; -{ - return isaccessible(file, R_OK); -} - -/* - * Returns non-zero if the argument file is writable. - */ -int -iswritable (file) - const char *file; -{ - return isaccessible(file, W_OK); -} - -/* - * Returns non-zero if the argument file is accessable according to - * mode. If compiled with SETXID_SUPPORT also works if cvs has setxid - * bits set. - */ -int -isaccessible (file, mode) - const char *file; - const int mode; -{ -#ifdef SETXID_SUPPORT - struct stat sb; - int umask = 0; - int gmask = 0; - int omask = 0; - int uid, mask; - - if (stat(file, &sb) == -1) - return 0; - if (mode == F_OK) - return 1; - - uid = geteuid(); - if (uid == 0) /* superuser */ - { - if (!(mode & X_OK) || (sb.st_mode & (S_IXUSR|S_IXGRP|S_IXOTH))) - return 1; - - errno = EACCES; - return 0; - } - - if (mode & R_OK) - { - umask |= S_IRUSR; - gmask |= S_IRGRP; - omask |= S_IROTH; - } - if (mode & W_OK) - { - umask |= S_IWUSR; - gmask |= S_IWGRP; - omask |= S_IWOTH; - } - if (mode & X_OK) - { - umask |= S_IXUSR; - gmask |= S_IXGRP; - omask |= S_IXOTH; - } - - mask = sb.st_uid == uid ? umask : sb.st_gid == getegid() ? gmask : omask; - if ((sb.st_mode & mask) == mask) - return 1; - errno = EACCES; - return 0; -#else - return access(file, mode) == 0; -#endif -} - -/* - * Open a file and die if it fails - */ -FILE * -open_file (name, mode) - const char *name; - const char *mode; -{ - FILE *fp; - - if ((fp = fopen (name, mode)) == NULL) - error (1, errno, "cannot open %s", name); - return (fp); -} - -/* - * Make a directory and die if it fails - */ -void -make_directory (name) - const char *name; -{ - struct stat sb; - - if (stat (name, &sb) == 0 && (!S_ISDIR (sb.st_mode))) - error (0, 0, "%s already exists but is not a directory", name); - if (!noexec && mkdir (name, 0777) < 0) - error (1, errno, "cannot make directory %s", name); -} - -/* - * Make a path to the argument directory, printing a message if something - * goes wrong. - */ -void -make_directories (name) - const char *name; -{ - char *cp; - - if (noexec) - return; - - if (mkdir (name, 0777) == 0 || errno == EEXIST) - return; - if (! existence_error (errno)) - { - error (0, errno, "cannot make path to %s", name); - return; - } - if ((cp = strrchr (name, '/')) == NULL) - return; - *cp = '\0'; - make_directories (name); - *cp++ = '/'; - if (*cp == '\0') - return; - (void) mkdir (name, 0777); -} - -/* Create directory NAME if it does not already exist; fatal error for - other errors. Returns 0 if directory was created; 1 if it already - existed. */ -int -mkdir_if_needed (name) - const char *name; -{ - if (mkdir (name, 0777) < 0) - { - int save_errno = errno; - if (save_errno != EEXIST && !isdir (name)) - error (1, save_errno, "cannot make directory %s", name); - return 1; - } - return 0; -} - -/* - * Change the mode of a file, either adding write permissions, or removing - * all write permissions. Either change honors the current umask setting. - * - * Don't do anything if PreservePermissions is set to `yes'. This may - * have unexpected consequences for some uses of xchmod. - */ -void -xchmod (fname, writable) - const char *fname; - int writable; -{ - struct stat sb; - mode_t mode, oumask; - - if (preserve_perms) - return; - - if (stat (fname, &sb) < 0) - { - if (!noexec) - error (0, errno, "cannot stat %s", fname); - return; - } - oumask = umask (0); - (void) umask (oumask); - if (writable) - { - mode = sb.st_mode | (~oumask - & (((sb.st_mode & S_IRUSR) ? S_IWUSR : 0) - | ((sb.st_mode & S_IRGRP) ? S_IWGRP : 0) - | ((sb.st_mode & S_IROTH) ? S_IWOTH : 0))); - } - else - { - mode = sb.st_mode & ~(S_IWRITE | S_IWGRP | S_IWOTH) & ~oumask; - } - - if (trace) - (void) fprintf (stderr, "%s-> chmod(%s,%o)\n", - CLIENT_SERVER_STR, fname, - (unsigned int) mode); - if (noexec) - return; - - if (chmod (fname, mode) < 0) - error (0, errno, "cannot change mode of file %s", fname); -} - -/* - * Rename a file and die if it fails - */ -void -rename_file (from, to) - const char *from; - const char *to; -{ - if (trace) - (void) fprintf (stderr, "%s-> rename(%s,%s)\n", - CLIENT_SERVER_STR, from, to); - if (noexec) - return; - - if (rename (from, to) < 0) - error (1, errno, "cannot rename file %s to %s", from, to); -} - -/* - * unlink a file, if possible. - */ -int -unlink_file (f) - const char *f; -{ - if (trace) - (void) fprintf (stderr, "%s-> unlink_file(%s)\n", - CLIENT_SERVER_STR, f); - if (noexec) - return (0); - - return (CVS_UNLINK (f)); -} - -/* - * Unlink a file or dir, if possible. If it is a directory do a deep - * removal of all of the files in the directory. Return -1 on error - * (in which case errno is set). - */ -int -unlink_file_dir (f) - const char *f; -{ - struct stat sb; - - /* This is called by the server parent process in contexts where - it is not OK to send output (e.g. after we sent "ok" to the - client). */ - if (trace && !server_active) - (void) fprintf (stderr, "-> unlink_file_dir(%s)\n", f); - - if (noexec) - return (0); - - /* For at least some unices, if root tries to unlink() a directory, - instead of doing something rational like returning EISDIR, - the system will gleefully go ahead and corrupt the filesystem. - So we first call stat() to see if it is OK to call unlink(). This - doesn't quite work--if someone creates a directory between the - call to stat() and the call to unlink(), we'll still corrupt - the filesystem. Where is the Unix Haters Handbook when you need - it? */ - if (stat (f, &sb) < 0) - { - if (existence_error (errno)) - { - /* The file or directory doesn't exist anyhow. */ - return -1; - } - } - else if (S_ISDIR (sb.st_mode)) - return deep_remove_dir (f); - - return CVS_UNLINK (f); -} - -/* Remove a directory and everything it contains. Returns 0 for - * success, -1 for failure (in which case errno is set). - */ - -static int -deep_remove_dir (path) - const char *path; -{ - DIR *dirp; - struct dirent *dp; - - if (rmdir (path) != 0) - { - if (errno == ENOTEMPTY - || errno == EEXIST - /* Ugly workaround for ugly AIX 4.1 (and 3.2) header bug - (it defines ENOTEMPTY and EEXIST to 17 but actually - returns 87). */ - || (ENOTEMPTY == 17 && EEXIST == 17 && errno == 87)) - { - if ((dirp = CVS_OPENDIR (path)) == NULL) - /* If unable to open the directory return - * an error - */ - return -1; - - errno = 0; - while ((dp = CVS_READDIR (dirp)) != NULL) - { - char *buf; - - if (strcmp (dp->d_name, ".") == 0 || - strcmp (dp->d_name, "..") == 0) - continue; - - buf = xmalloc (strlen (path) + strlen (dp->d_name) + 5); - sprintf (buf, "%s/%s", path, dp->d_name); - - /* See comment in unlink_file_dir explanation of why we use - isdir instead of just calling unlink and checking the - status. */ - if (isdir(buf)) - { - if (deep_remove_dir(buf)) - { - CVS_CLOSEDIR(dirp); - free (buf); - return -1; - } - } - else - { - if (CVS_UNLINK (buf) != 0) - { - CVS_CLOSEDIR(dirp); - free (buf); - return -1; - } - } - free (buf); - - errno = 0; - } - if (errno != 0) - { - int save_errno = errno; - CVS_CLOSEDIR (dirp); - errno = save_errno; - return -1; - } - CVS_CLOSEDIR (dirp); - return rmdir (path); - } - else - return -1; - } - - /* Was able to remove the directory return 0 */ - return 0; -} - -/* Read NCHARS bytes from descriptor FD into BUF. - Return the number of characters successfully read. - The number returned is always NCHARS unless end-of-file or error. */ -static size_t -block_read (fd, buf, nchars) - int fd; - char *buf; - size_t nchars; -{ - char *bp = buf; - size_t nread; - - do - { - nread = read (fd, bp, nchars); - if (nread == (size_t)-1) - { -#ifdef EINTR - if (errno == EINTR) - continue; -#endif - return (size_t)-1; - } - - if (nread == 0) - break; - - bp += nread; - nchars -= nread; - } while (nchars != 0); - - return bp - buf; -} - - -/* - * Compare "file1" to "file2". Return non-zero if they don't compare exactly. - * If FILE1 and FILE2 are special files, compare their salient characteristics - * (i.e. major/minor device numbers, links, etc. - */ -int -xcmp (file1, file2) - const char *file1; - const char *file2; -{ - char *buf1, *buf2; - struct stat sb1, sb2; - int fd1, fd2; - int ret; - - if (CVS_LSTAT (file1, &sb1) < 0) - error (1, errno, "cannot lstat %s", file1); - if (CVS_LSTAT (file2, &sb2) < 0) - error (1, errno, "cannot lstat %s", file2); - - /* If FILE1 and FILE2 are not the same file type, they are unequal. */ - if ((sb1.st_mode & S_IFMT) != (sb2.st_mode & S_IFMT)) - return 1; - - /* If FILE1 and FILE2 are symlinks, they are equal if they point to - the same thing. */ -#ifdef S_ISLNK - if (S_ISLNK (sb1.st_mode) && S_ISLNK (sb2.st_mode)) - { - int result; - buf1 = xreadlink (file1); - buf2 = xreadlink (file2); - result = (strcmp (buf1, buf2) == 0); - free (buf1); - free (buf2); - return result; - } -#endif - - /* If FILE1 and FILE2 are devices, they are equal if their device - numbers match. */ - if (S_ISBLK (sb1.st_mode) || S_ISCHR (sb1.st_mode)) - { -#ifdef HAVE_STRUCT_STAT_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) - error (1, errno, "cannot open file %s for comparing", file1); - if ((fd2 = open (file2, O_RDONLY)) < 0) - error (1, errno, "cannot open file %s for comparing", file2); - - /* A generic file compare routine might compare st_dev & st_ino here - to see if the two files being compared are actually the same file. - But that won't happen in CVS, so we won't bother. */ - - if (sb1.st_size != sb2.st_size) - ret = 1; - else if (sb1.st_size == 0) - ret = 0; - else - { - /* FIXME: compute the optimal buffer size by computing the least - common multiple of the files st_blocks field */ - size_t buf_size = 8 * 1024; - size_t read1; - size_t read2; - - buf1 = xmalloc (buf_size); - buf2 = xmalloc (buf_size); - - do - { - read1 = block_read (fd1, buf1, buf_size); - if (read1 == (size_t)-1) - error (1, errno, "cannot read file %s for comparing", file1); - - read2 = block_read (fd2, buf2, buf_size); - if (read2 == (size_t)-1) - error (1, errno, "cannot read file %s for comparing", file2); - - /* assert (read1 == read2); */ - - ret = memcmp(buf1, buf2, read1); - } while (ret == 0 && read1 == buf_size); - - free (buf1); - free (buf2); - } - - (void) close (fd1); - (void) close (fd2); - return (ret); -} - -/* Generate a unique temporary filename. Returns a pointer to a newly - * malloc'd string containing the name. Returns successfully or not at - * all. - * - * THIS FUNCTION IS DEPRECATED!!! USE cvs_temp_file INSTEAD!!! - * - * and yes, I know about the way the rcs commands use temp files. I think - * they should be converted too but I don't have time to look into it right - * now. - */ -char * -cvs_temp_name () -{ - char *fn; - FILE *fp; - - fp = cvs_temp_file (&fn); - if (fp == NULL) - error (1, errno, "Failed to create temporary file %s", - fn ? fn : "(null)"); - if (fclose (fp) == EOF) - error (0, errno, "Failed to close temporary file %s", fn); - return fn; -} - -/* Generate a unique temporary filename and return an open file stream - * to the truncated file by that name - * - * INPUTS - * filename where to place the pointer to the newly allocated file - * name string - * - * OUTPUTS - * filename dereferenced, will point to the newly allocated file - * name string. This value is undefined if the function - * returns an error. - * - * RETURNS - * An open file pointer to a read/write mode empty temporary file with the - * unique file name or NULL on failure. - * - * ERRORS - * on error, errno will be set to some value either by CVS_FOPEN or - * whatever system function is called to generate the temporary file name - */ -/* There are at least four functions for generating temporary - * filenames. We use mkstemp (BSD 4.3) if possible, else tempnam (SVID 3), - * else mktemp (BSD 4.3), and as last resort tmpnam (POSIX). Reason is that - * mkstemp, tempnam, and mktemp both allow to specify the directory in which - * the temporary file will be created. - * - * And the _correct_ way to use the deprecated functions probably involves - * opening file descriptors using O_EXCL & O_CREAT and even doing the annoying - * NFS locking thing, but until I hear of more problems, I'm not going to - * bother. - */ -FILE * -cvs_temp_file (filename) - char **filename; -{ - char *fn; - FILE *fp; - - /* FIXME - I'd like to be returning NULL here in noexec mode, but I think - * some of the rcs & diff functions which rely on a temp file run in - * noexec mode too. - */ - - assert (filename != NULL); - -#ifdef HAVE_MKSTEMP - - { - int fd; - - fn = xmalloc (strlen (Tmpdir) + 11); - sprintf (fn, "%s/%s", Tmpdir, "cvsXXXXXX" ); - fd = mkstemp (fn); - - /* a NULL return will be interpreted by callers as an error and - * errno should still be set - */ - if (fd == -1) fp = NULL; - else if ((fp = CVS_FDOPEN (fd, "w+")) == NULL) - { - /* Attempt to close and unlink the file since mkstemp returned - * sucessfully and we believe it's been created and opened. - */ - int save_errno = errno; - if (close (fd)) - error (0, errno, "Failed to close temporary file %s", fn); - if (CVS_UNLINK (fn)) - error (0, errno, "Failed to unlink temporary file %s", fn); - errno = save_errno; - } - - if (fp == NULL) - { - free (fn); - fn = NULL; - } - /* mkstemp is defined to open mode 0600 using glibc 2.0.7+ */ - /* FIXME - configure can probably tell us which version of glibc we are - * linking to and not chmod for 2.0.7+ - */ - else chmod (fn, 0600); - - } - -#elif HAVE_TEMPNAM - - /* tempnam has been deprecated due to under-specification */ - - fn = tempnam (Tmpdir, "cvs"); - if (fn == NULL) fp = NULL; - else if ((fp = CVS_FOPEN (fn, "w+")) == NULL) - { - free (fn); - fn = NULL; - } - else chmod (fn, 0600); - - /* tempnam returns a pointer to a newly malloc'd string, so there's - * no need for a xstrdup - */ - -#elif HAVE_MKTEMP - - /* mktemp has been deprecated due to the BSD 4.3 specification specifying - * that XXXXXX will be replaced by a PID and a letter, creating only 26 - * possibilities, a security risk, and a race condition. - */ - - { - char *ifn; - - ifn = xmalloc (strlen (Tmpdir) + 11); - sprintf (ifn, "%s/%s", Tmpdir, "cvsXXXXXX" ); - fn = mktemp (ifn); - - if (fn == NULL) fp = NULL; - else fp = CVS_FOPEN (fn, "w+"); - - if (fp == NULL) free (ifn); - else chmod (fn, 0600); - - } - -#else /* use tmpnam if all else fails */ - - /* tmpnam is deprecated */ - - { - char ifn[L_tmpnam + 1]; - - fn = tmpnam (ifn); - - if (fn == NULL) fp = NULL; - else if ((fp = CVS_FOPEN (ifn, "w+")) != NULL) - { - fn = xstrdup (ifn); - chmod (fn, 0600); - } - - } - -#endif - - *filename = fn; - if (fn == NULL && fp != NULL) - { - fclose (fp); - fp = NULL; - } - return fp; -} - - - -#ifdef HAVE_READLINK -/* char * - * xreadlink ( const char *link ) - * - * Like the X/OPEN and 4.4BSD readlink() function, but allocates and returns - * its own buf. - * - * INPUTS - * link The original path. - * - * RETURNS - * The resolution of the final symbolic link in the path. - * - * ERRORS - * This function exits with a fatal error if it fails to read the link for - * any reason. - */ -#define MAXSIZE (SIZE_MAX < SSIZE_MAX ? SIZE_MAX : SSIZE_MAX) - -char * -xreadlink (link) - const char *link; -{ - char *file = NULL; - size_t buflen = BUFSIZ; - - /* Get the name of the file to which `from' is linked. */ - while (1) - { - ssize_t r; - size_t link_name_len; - - file = xrealloc (file, buflen); - r = readlink (link, file, buflen); - link_name_len = r; - - if (r < 0 -#ifdef ERANGE - /* AIX 4 and HP-UX report ERANGE if the buffer is too small. */ - && errno != ERANGE -#endif - ) - error (1, errno, "cannot readlink %s", link); - - /* If there is space for the NUL byte, set it and return. */ - if (r >= 0 && link_name_len < buflen) - { - file[link_name_len] = '\0'; - return file; - } - - if (buflen <= MAXSIZE / 2) - buflen *= 2; - else if (buflen < MAXSIZE) - buflen = MAXSIZE; - else - /* Our buffer cannot grow any bigger. */ - error (1, ENAMETOOLONG, "cannot readlink %s", link); - } -} -#endif /* HAVE_READLINK */ - - - -/* char * - * xresolvepath ( const char *path ) - * - * Like xreadlink(), but resolve all links in a path. - * - * INPUTS - * path The original path. - * - * RETURNS - * The path with any symbolic links expanded. - * - * ERRORS - * This function exits with a fatal error if it fails to read the link for - * any reason. - */ -char * -xresolvepath ( path ) - const char *path; -{ - char *hardpath; - char *owd; - - assert ( isdir ( path ) ); - - /* FIXME - If HAVE_READLINK is defined, we should probably walk the path - * bit by bit calling xreadlink(). - */ - - owd = xgetwd(); - if ( CVS_CHDIR ( path ) < 0) - error ( 1, errno, "cannot chdir to %s", path ); - if ( ( hardpath = xgetwd() ) == NULL ) - error (1, errno, "cannot getwd in %s", path); - if ( CVS_CHDIR ( owd ) < 0) - error ( 1, errno, "cannot chdir to %s", owd ); - free (owd); - return hardpath; -} - - - -/* Return a pointer into PATH's last component. */ -const char * -last_component (path) - const char *path; -{ - const char *last = strrchr (path, '/'); - - assert (path); - if (last && (last != path)) - return last + 1; - else - return path; -} - -/* Return the home directory. Returns a pointer to storage - managed by this function or its callees (currently getenv). - This function will return the same thing every time it is - called. Returns NULL if there is no home directory. - - Note that for a pserver server, this may return root's home - directory. What typically happens is that upon being started from - inetd, before switching users, the code in cvsrc.c calls - get_homedir which remembers root's home directory in the static - variable. Then the switch happens and get_homedir might return a - directory that we don't even have read or execute permissions for - (which is bad, when various parts of CVS try to read there). One - fix would be to make the value returned by get_homedir only good - until the next call (which would free the old value). Another fix - would be to just always malloc our answer, and let the caller free - it (that is best, because some day we may need to be reentrant). - - The workaround is to put -f in inetd.conf which means that - get_homedir won't get called until after the switch in user ID. - - The whole concept of a "home directory" on the server is pretty - iffy, although I suppose some people probably are relying on it for - .cvsrc and such, in the cases where it works. */ -char * -get_homedir () -{ - static char *home = NULL; - char *env; - struct passwd *pw; - - if (home != NULL) - return home; - - if (!server_active && (env = getenv ("HOME")) != NULL) - home = env; - else if ((pw = (struct passwd *) getpwuid (getuid ())) - && pw->pw_dir) - home = xstrdup (pw->pw_dir); - else - return 0; - - return home; -} - -/* Compose a path to a file in the home directory. This is necessary because - * of different behavior on UNIX and VMS. See the notes in vms/filesubr.c. - * - * A more clean solution would be something more along the lines of a - * "join a directory to a filename" kind of thing which was not specific to - * the homedir. This should aid portability between UNIX, Mac, Windows, VMS, - * and possibly others. This is already handled by Perl - it might be - * interesting to see how much of the code was written in C since Perl is under - * the GPL and the Artistic license - we might be able to use it. - */ -char * -strcat_filename_onto_homedir (dir, file) - const char *dir; - const char *file; -{ - char *path = xmalloc (strlen (dir) + 1 + strlen(file) + 1); - sprintf (path, "%s/%s", dir, file); - return path; -} - -/* See cvs.h for description. On unix this does nothing, because the - shell expands the wildcards. */ -void -expand_wild (argc, argv, pargc, pargv) - int argc; - char **argv; - int *pargc; - char ***pargv; -{ - int i; - assert (argv || !argc); - if (size_overflow_p (xtimes (argc, sizeof (char *)))) { - *pargc = 0; - *pargv = NULL; - error (0, 0, "expand_wild: too many arguments"); - return; - } - *pargc = argc; - *pargv = xmalloc (xtimes (argc, sizeof (char *))); - for (i = 0; i < argc; ++i) - (*pargv)[i] = xstrdup (argv[i]); -} - - - -#ifdef SERVER_SUPPORT -/* Case-insensitive string compare. I know that some systems - have such a routine, but I'm not sure I see any reasons for - dealing with the hair of figuring out whether they do (I haven't - looked into whether this is a performance bottleneck; I would guess - not). */ -int -cvs_casecmp (str1, str2) - const char *str1; - const char *str2; -{ - const char *p; - const char *q; - int pqdiff; - - p = str1; - q = str2; - while ((pqdiff = tolower (*p) - tolower (*q)) == 0) - { - if (*p == '\0') - return 0; - ++p; - ++q; - } - return pqdiff; -} -#endif /* SERVER_SUPPORT */ diff --git a/contrib/cvs/src/find_names.c b/contrib/cvs/src/find_names.c deleted file mode 100644 index 5bfd895..0000000 --- a/contrib/cvs/src/find_names.c +++ /dev/null @@ -1,427 +0,0 @@ -/* - * Copyright (C) 1986-2005 The Free Software Foundation, Inc. - * - * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot , - * and others. - * - * Portions Copyright (C) 1992, Brian Berliner and Jeff Polk - * Portions Copyright (C) 1989-1992, Brian Berliner - * - * You may distribute under the terms of the GNU General Public License as - * specified in the README file that comes with the CVS source distribution. - * - * Find Names - * - * Finds all the pertinent file names, both from the administration and from the - * repository - * - * Find Dirs - * - * Finds all pertinent sub-directories of the checked out instantiation and the - * repository (and optionally the attic) - */ - -#include "cvs.h" - -static int find_dirs PROTO((char *dir, List * list, int checkadm, - List *entries)); -static int find_rcs PROTO((char *dir, List * list)); -static int add_subdir_proc PROTO((Node *, void *)); -static int register_subdir_proc PROTO((Node *, void *)); - -/* - * add the key from entry on entries list to the files list - */ -static int add_entries_proc PROTO((Node *, void *)); -static int -add_entries_proc (node, closure) - Node *node; - void *closure; -{ - Node *fnode; - List *filelist = closure; - Entnode *entnode = node->data; - - if (entnode->type != ENT_FILE) - return (0); - - fnode = getnode (); - fnode->type = FILES; - fnode->key = xstrdup (node->key); - if (addnode (filelist, fnode) != 0) - freenode (fnode); - return (0); -} - -/* Find files in the repository and/or working directory. On error, - may either print a nonfatal error and return NULL, or just give - a fatal error. On success, return non-NULL (even if it is an empty - list). */ - -List * -Find_Names (repository, which, aflag, optentries) - char *repository; - int which; - int aflag; - List **optentries; -{ - List *entries; - List *files; - - /* make a list for the files */ - files = getlist (); - - /* look at entries (if necessary) */ - if (which & W_LOCAL) - { - /* parse the entries file (if it exists) */ - entries = Entries_Open (aflag, NULL); - if (entries != NULL) - { - /* walk the entries file adding elements to the files list */ - (void) walklist (entries, add_entries_proc, files); - - /* if our caller wanted the entries list, return it; else free it */ - if (optentries != NULL) - *optentries = entries; - else - Entries_Close (entries); - } - } - - if ((which & W_REPOS) && repository && !isreadable (CVSADM_ENTSTAT)) - { - /* search the repository */ - if (find_rcs (repository, files) != 0) - { - error (0, errno, "cannot open directory %s", repository); - goto error_exit; - } - - /* search the attic too */ - if (which & W_ATTIC) - { - char *dir; - dir = xmalloc (strlen (repository) + sizeof (CVSATTIC) + 10); - (void) sprintf (dir, "%s/%s", repository, CVSATTIC); - if (find_rcs (dir, files) != 0 - && !existence_error (errno)) - /* For now keep this a fatal error, seems less useful - for access control than the case above. */ - error (1, errno, "cannot open directory %s", dir); - free (dir); - } - } - - /* sort the list into alphabetical order and return it */ - sortlist (files, fsortcmp); - return (files); - error_exit: - dellist (&files); - return NULL; -} - -/* - * Add an entry from the subdirs list to the directories list. This - * is called via walklist. - */ - -static int -add_subdir_proc (p, closure) - Node *p; - void *closure; -{ - List *dirlist = closure; - Entnode *entnode = p->data; - Node *dnode; - - if (entnode->type != ENT_SUBDIR) - return 0; - - dnode = getnode (); - dnode->type = DIRS; - dnode->key = xstrdup (entnode->user); - if (addnode (dirlist, dnode) != 0) - freenode (dnode); - return 0; -} - -/* - * Register a subdirectory. This is called via walklist. - */ - -/*ARGSUSED*/ -static int -register_subdir_proc (p, closure) - Node *p; - void *closure; -{ - List *entries = (List *) closure; - - Subdir_Register (entries, (char *) NULL, p->key); - return 0; -} - -/* - * create a list of directories to traverse from the current directory - */ -List * -Find_Directories (repository, which, entries) - char *repository; - int which; - List *entries; -{ - List *dirlist; - - /* make a list for the directories */ - dirlist = getlist (); - - /* find the local ones */ - if (which & W_LOCAL) - { - List *tmpentries; - struct stickydirtag *sdtp; - - /* Look through the Entries file. */ - - if (entries != NULL) - tmpentries = entries; - else if (isfile (CVSADM_ENT)) - tmpentries = Entries_Open (0, NULL); - else - tmpentries = NULL; - - if (tmpentries != NULL) - sdtp = tmpentries->list->data; - - /* If we do have an entries list, then if sdtp is NULL, or if - sdtp->subdirs is nonzero, all subdirectory information is - recorded in the entries list. */ - if (tmpentries != NULL && (sdtp == NULL || sdtp->subdirs)) - walklist (tmpentries, add_subdir_proc, (void *) dirlist); - else - { - /* This is an old working directory, in which subdirectory - information is not recorded in the Entries file. Find - the subdirectories the hard way, and, if possible, add - it to the Entries file for next time. */ - - /* FIXME-maybe: find_dirs is bogus for this usage because - it skips CVSATTIC and CVSLCK directories--those names - should be special only in the repository. However, in - the interests of not perturbing this code, we probably - should leave well enough alone unless we want to write - a sanity.sh test case (which would operate by manually - hacking on the CVS/Entries file). */ - - if (find_dirs (".", dirlist, 1, tmpentries) != 0) - error (1, errno, "cannot open current directory"); - if (tmpentries != NULL) - { - if (! list_isempty (dirlist)) - walklist (dirlist, register_subdir_proc, - (void *) tmpentries); - else - Subdirs_Known (tmpentries); - } - } - - if (entries == NULL && tmpentries != NULL) - Entries_Close (tmpentries); - } - - /* look for sub-dirs in the repository */ - if ((which & W_REPOS) && repository) - { - /* search the repository */ - if (find_dirs (repository, dirlist, 0, entries) != 0) - error (1, errno, "cannot open directory %s", repository); - - /* We don't need to look in the attic because directories - never go in the attic. In the future, there hopefully will - be a better mechanism for detecting whether a directory in - the repository is alive or dead; it may or may not involve - moving directories to the attic. */ - } - - /* sort the list into alphabetical order and return it */ - sortlist (dirlist, fsortcmp); - return (dirlist); -} - -/* - * Finds all the ,v files in the argument directory, and adds them to the - * files list. Returns 0 for success and non-zero if the argument directory - * cannot be opened, in which case errno is set to indicate the error. - * In the error case LIST is left in some reasonable state (unchanged, or - * containing the files which were found before the error occurred). - */ -static int -find_rcs (dir, list) - char *dir; - List *list; -{ - Node *p; - struct dirent *dp; - DIR *dirp; - - /* set up to read the dir */ - if ((dirp = CVS_OPENDIR (dir)) == NULL) - return (1); - - /* read the dir, grabbing the ,v files */ - errno = 0; - while ((dp = CVS_READDIR (dirp)) != NULL) - { - if (CVS_FNMATCH (RCSPAT, dp->d_name, 0) == 0) - { - char *comma; - - comma = strrchr (dp->d_name, ','); /* strip the ,v */ - *comma = '\0'; - p = getnode (); - p->type = FILES; - p->key = xstrdup (dp->d_name); - if (addnode (list, p) != 0) - freenode (p); - } - errno = 0; - } - if (errno != 0) - { - int save_errno = errno; - (void) CVS_CLOSEDIR (dirp); - errno = save_errno; - return 1; - } - (void) CVS_CLOSEDIR (dirp); - return (0); -} - -/* - * Finds all the subdirectories of the argument dir and adds them to - * the specified list. Sub-directories without a CVS administration - * directory are optionally ignored. If ENTRIES is not NULL, all - * files on the list are ignored. Returns 0 for success or 1 on - * error, in which case errno is set to indicate the error. - */ -static int -find_dirs (dir, list, checkadm, entries) - char *dir; - List *list; - int checkadm; - List *entries; -{ - Node *p; - char *tmp = NULL; - size_t tmp_size = 0; - struct dirent *dp; - DIR *dirp; - int skip_emptydir = 0; - - /* First figure out whether we need to skip directories named - Emptydir. Except in the CVSNULLREPOS case, Emptydir is just - a normal directory name. */ - if (isabsolute (dir) - && strncmp (dir, current_parsed_root->directory, strlen (current_parsed_root->directory)) == 0 - && ISDIRSEP (dir[strlen (current_parsed_root->directory)]) - && strcmp (dir + strlen (current_parsed_root->directory) + 1, CVSROOTADM) == 0) - skip_emptydir = 1; - - /* set up to read the dir */ - if ((dirp = CVS_OPENDIR (dir)) == NULL) - return (1); - - /* read the dir, grabbing sub-dirs */ - errno = 0; - while ((dp = CVS_READDIR (dirp)) != NULL) - { - if (strcmp (dp->d_name, ".") == 0 || - strcmp (dp->d_name, "..") == 0 || - strcmp (dp->d_name, CVSATTIC) == 0 || - strcmp (dp->d_name, CVSLCK) == 0 || - strcmp (dp->d_name, CVSREP) == 0) - goto do_it_again; - - /* findnode() is going to be significantly faster than stat() - because it involves no system calls. That is why we bother - with the entries argument, and why we check this first. */ - if (entries != NULL && findnode (entries, dp->d_name) != NULL) - goto do_it_again; - - if (skip_emptydir - && strcmp (dp->d_name, CVSNULLREPOS) == 0) - goto do_it_again; - -#ifdef DT_DIR - if (dp->d_type != DT_DIR) - { - if (dp->d_type != DT_UNKNOWN && dp->d_type != DT_LNK) - goto do_it_again; -#endif - /* don't bother stating ,v files */ - if (CVS_FNMATCH (RCSPAT, dp->d_name, 0) == 0) - goto do_it_again; - - expand_string (&tmp, - &tmp_size, - strlen (dir) + strlen (dp->d_name) + 10); - sprintf (tmp, "%s/%s", dir, dp->d_name); - if (!isdir (tmp)) - goto do_it_again; - -#ifdef DT_DIR - } -#endif - - /* check for administration directories (if needed) */ - if (checkadm) - { - /* blow off symbolic links to dirs in local dir */ -#ifdef DT_DIR - if (dp->d_type != DT_DIR) - { - /* we're either unknown or a symlink at this point */ - if (dp->d_type == DT_LNK) - goto do_it_again; -#endif - /* Note that we only get here if we already set tmp - above. */ - if (islink (tmp)) - goto do_it_again; -#ifdef DT_DIR - } -#endif - - /* check for new style */ - expand_string (&tmp, - &tmp_size, - (strlen (dir) + strlen (dp->d_name) - + sizeof (CVSADM) + 10)); - (void) sprintf (tmp, "%s/%s/%s", dir, dp->d_name, CVSADM); - if (!isdir (tmp)) - goto do_it_again; - } - - /* put it in the list */ - p = getnode (); - p->type = DIRS; - p->key = xstrdup (dp->d_name); - if (addnode (list, p) != 0) - freenode (p); - - do_it_again: - errno = 0; - } - if (errno != 0) - { - int save_errno = errno; - (void) CVS_CLOSEDIR (dirp); - errno = save_errno; - return 1; - } - (void) CVS_CLOSEDIR (dirp); - if (tmp != NULL) - free (tmp); - return (0); -} diff --git a/contrib/cvs/src/hardlink.c b/contrib/cvs/src/hardlink.c deleted file mode 100644 index ed05033..0000000 --- a/contrib/cvs/src/hardlink.c +++ /dev/null @@ -1,307 +0,0 @@ -/* This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. */ - -/* Collect and manage hardlink info associated with a particular file. */ - -#include "cvs.h" - -#ifdef PRESERVE_PERMISSIONS_SUPPORT -# include "hardlink.h" - -/* The structure currently used to manage hardlink info is a list. - Therefore, most of the functions which manipulate hardlink data - are walklist procedures. This is not a very efficient implementation; - if someone decides to use a real hash table (for instance), then - much of this code can be rewritten to be a little less arcane. - - Each element of `hardlist' represents an inode. It is keyed on the - inode number, and points to a list of files. This is to make it - easy to find out what files are linked to a given file FOO: find - FOO's inode, look it up in hardlist, and retrieve the list of files - associated with that inode. - - Each file node, in turn, is represented by a `hardlink_info' struct, - which includes `status' and `links' fields. The `status' field should - be used by a procedure like commit_fileproc or update_fileproc to - record each file's status; that way, after all file links have been - recorded, CVS can check the linkage of files which are in doubt - (i.e. T_NEEDS_MERGE files). - - TODO: a diagram of an example hardlist would help here. */ - -/* TODO: change this to something with a marginal degree of - efficiency, like maybe a hash table. Yeah. */ - -List *hardlist; /* Record hardlink information for working files */ -char *working_dir; /* The top-level working directory, used for - constructing full pathnames. */ - -/* Return a pointer to FILEPATH's node in the hardlist. This means - looking up its inode, retrieving the list of files linked to that - inode, and then looking up FILE in that list. If the file doesn't - seem to exist, return NULL. */ -Node * -lookup_file_by_inode (filepath) - const char *filepath; -{ - char *inodestr, *file; - struct stat sb; - Node *hp, *p; - - /* Get file's basename, so that we can stat it. */ - file = strrchr (filepath, '/'); - if (file) - ++file; - else - file = (char *) 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) + 1); - if (stat (file, &sb) < 0) - { - if (existence_error (errno)) - { - /* The file doesn't exist; we may be doing an update on a - file that's been removed. A nonexistent file has no - link information, so return without changing hardlist. */ - free (inodestr); - return NULL; - } - error (1, errno, "cannot stat %s", file); - } - - sprintf (inodestr, "%lx", (unsigned long) sb.st_ino); - - /* Find out if this inode is already in the hardlist, adding - a new entry to the list if not. */ - hp = findnode (hardlist, inodestr); - if (hp == NULL) - { - hp = getnode (); - hp->type = NT_UNKNOWN; - hp->key = inodestr; - hp->data = getlist(); - hp->delproc = dellist; - (void) addnode (hardlist, hp); - } - else - { - free (inodestr); - } - - p = findnode (hp->data, filepath); - if (p == NULL) - { - p = getnode(); - p->type = NT_UNKNOWN; - p->key = xstrdup (filepath); - p->data = NULL; - (void) addnode (hp->data, p); - } - - return p; -} - -/* After a file has been checked out, add a node for it to the hardlist - (if necessary) and mark it as checked out. */ -void -update_hardlink_info (file) - const char *file; -{ - char *path; - Node *n; - struct hardlink_info *hlinfo; - - if (file[0] == '/') - { - path = xstrdup (file); - } - else - { - /* file is a relative pathname; assume it's from the current - working directory. */ - char *dir = xgetwd(); - path = xmalloc (strlen(dir) + strlen(file) + 2); - sprintf (path, "%s/%s", dir, file); - free (dir); - } - - n = lookup_file_by_inode (path); - if (n == NULL) - { - /* Something is *really* wrong if the file doesn't exist here; - update_hardlink_info should be called only when a file has - just been checked out to a working directory. */ - error (1, 0, "lost hardlink info for %s", file); - } - - if (n->data == NULL) - n->data = xmalloc (sizeof (struct hardlink_info)); - hlinfo = n->data; - hlinfo->status = T_UPTODATE; - hlinfo->checked_out = 1; -} - -/* Return a List with all the files known to be linked to FILE in - the working directory. Used by special_file_mismatch, to determine - whether it is safe to merge two files. - - FIXME: What is the memory allocation for the return value? We seem - to sometimes allocate a new list (getlist() call below) and sometimes - return an existing list (where we return n->data). */ -List * -list_linked_files_on_disk (file) - char *file; -{ - char *inodestr, *path; - struct stat sb; - Node *n; - - /* If hardlist is NULL, we have not been doing an operation that - would permit us to know anything about the file's hardlinks - (cvs update, cvs commit, etc). Return an empty list. */ - if (hardlist == NULL) - return getlist(); - - /* Get the full pathname of file (assuming the working directory) */ - if (file[0] == '/') - path = xstrdup (file); - else - { - char *dir = xgetwd(); - path = (char *) xmalloc (strlen(dir) + strlen(file) + 2); - sprintf (path, "%s/%s", dir, file); - free (dir); - } - - /* We do an extra lookup_file here just to make sure that there - is a node for `path' in the hardlist. If that were not so, - comparing the working directory linkage against the repository - linkage for a file would always fail. */ - (void) lookup_file_by_inode (path); - - if (stat (path, &sb) < 0) - error (1, errno, "cannot stat %s", 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) + 1); - sprintf (inodestr, "%lx", (unsigned long) sb.st_ino); - - /* Make sure the files linked to this inode are sorted. */ - n = findnode (hardlist, inodestr); - sortlist (n->data, fsortcmp); - - free (inodestr); - return n->data; -} - -/* Compare the files in the `key' fields of two lists, returning 1 if - the lists are equivalent and 0 otherwise. - - Only the basenames of each file are compared. This is an awful hack - that exists because list_linked_files_on_disk returns full paths - and the `hardlinks' structure of a RCSVers node contains only - basenames. That in turn is a result of the awful hack that only - basenames are stored in the RCS file. If anyone ever solves the - problem of correctly managing cross-directory hardlinks, this - function (along with most functions in this file) must be fixed. */ - -int -compare_linkage_lists (links1, links2) - List *links1; - List *links2; -{ - Node *n1, *n2; - char *p1, *p2; - - sortlist (links1, fsortcmp); - sortlist (links2, fsortcmp); - - n1 = links1->list->next; - n2 = links2->list->next; - - while (n1 != links1->list && n2 != links2->list) - { - /* Get the basenames of both files. */ - p1 = strrchr (n1->key, '/'); - if (p1 == NULL) - p1 = n1->key; - else - ++p1; - - p2 = strrchr (n2->key, '/'); - if (p2 == NULL) - p2 = n2->key; - else - ++p2; - - /* Compare the files' basenames. */ - if (strcmp (p1, p2) != 0) - return 0; - - n1 = n1->next; - n2 = n2->next; - } - - /* At this point we should be at the end of both lists; if not, - one file has more links than the other, and return 1. */ - return (n1 == links1->list && n2 == links2->list); -} - -/* Find a checked-out file in a list of filenames. Used by RCS_checkout - when checking out a new hardlinked file, to decide whether this file - can be linked to any others that already exist. The return value - is not currently used. */ - -int -find_checkedout_proc (node, data) - Node *node; - void *data; -{ - Node **uptodate = (Node **) data; - Node *link; - char *dir = xgetwd(); - char *path; - struct hardlink_info *hlinfo; - - /* If we have already found a file, don't do anything. */ - if (*uptodate != NULL) - return 0; - - /* 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 (strlen (dir) + strlen (node->key) + 2); - sprintf (path, "%s/%s", dir, node->key); - link = lookup_file_by_inode (path); - free (path); - free (dir); - - if (link == NULL) - { - /* We haven't seen this file -- maybe it hasn't been checked - out yet at all. */ - return 0; - } - - hlinfo = link->data; - if (hlinfo->checked_out) - { - /* This file has been checked out recently, so it's safe to - link to it. */ - *uptodate = link; - } - - return 0; -} -#endif /* PRESERVE_PERMISSIONS_SUPPORT */ diff --git a/contrib/cvs/src/hardlink.h b/contrib/cvs/src/hardlink.h deleted file mode 100644 index b227968..0000000 --- a/contrib/cvs/src/hardlink.h +++ /dev/null @@ -1,35 +0,0 @@ -/* This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. */ - -/* Data type definitions and declarations for hardlink management. */ - -/* This file should be #included in CVS source files after cvs.h - since it relies on types and macros defined there. */ - -/* The `checked_out' member of a hardlink_info struct is used only - when files are being checked out or updated. It is used only when - hardlinked files are being checked out. */ - -#ifdef PRESERVE_PERMISSIONS_SUPPORT -struct hardlink_info -{ - Ctype status; /* as returned from Classify_File() */ - int checked_out; /* has this file been checked out lately? */ -}; - -extern List *hardlist; -extern char *working_dir; - -Node *lookup_file_by_inode PROTO ((const char *)); -void update_hardlink_info PROTO ((const char *)); -List *list_linked_files_on_disk PROTO ((char *)); -int compare_linkage_lists PROTO ((List *, List *)); -int find_checkedout_proc PROTO ((Node *, void *)); -#endif /* PRESERVE_PERMISSIONS_SUPPORT */ diff --git a/contrib/cvs/src/hash.c b/contrib/cvs/src/hash.c deleted file mode 100644 index d9bc12c..0000000 --- a/contrib/cvs/src/hash.c +++ /dev/null @@ -1,528 +0,0 @@ -/* - * Copyright (C) 1986-2005 The Free Software Foundation, Inc. - * - * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot , - * and others. - * - * Portions Copyright (C) 1992, Brian Berliner and Jeff Polk - * - * You may distribute under the terms of the GNU General Public License as - * specified in the README file that comes with the CVS source distribution. - * - * Polk's hash list manager. So cool. - */ - -#include "cvs.h" -#include - -/* Global caches. The idea is that we maintain a linked list of "free"d - nodes or lists, and get new items from there. It has been suggested - to use an obstack instead, but off the top of my head, I'm not sure - that would gain enough to be worth worrying about. */ -static List *listcache = NULL; -static Node *nodecache = NULL; - -static void freenode_mem PROTO((Node * p)); - -/* hash function */ -static int -hashp (key) - const char *key; -{ - unsigned int h = 0; - unsigned int g; - - assert(key != NULL); - - while (*key != 0) - { - unsigned int c = *key++; - /* The FOLD_FN_CHAR is so that findnode_fn works. */ - h = (h << 4) + FOLD_FN_CHAR (c); - if ((g = h & 0xf0000000) != 0) - h = (h ^ (g >> 24)) ^ g; - } - - return (h % HASHSIZE); -} - -/* - * create a new list (or get an old one from the cache) - */ -List * -getlist () -{ - int i; - List *list; - Node *node; - - if (listcache != NULL) - { - /* get a list from the cache and clear it */ - list = listcache; - listcache = listcache->next; - list->next = (List *) NULL; - for (i = 0; i < HASHSIZE; i++) - list->hasharray[i] = (Node *) NULL; - } - else - { - /* make a new list from scratch */ - list = (List *) xmalloc (sizeof (List)); - memset ((char *) list, 0, sizeof (List)); - node = getnode (); - list->list = node; - node->type = HEADER; - node->next = node->prev = node; - } - return (list); -} - -/* - * free up a list - */ -void -dellist (listp) - List **listp; -{ - int i; - Node *p; - - if (*listp == (List *) NULL) - return; - - p = (*listp)->list; - - /* free each node in the list (except header) */ - while (p->next != p) - delnode (p->next); - - /* free any list-private data, without freeing the actual header */ - freenode_mem (p); - - /* free up the header nodes for hash lists (if any) */ - for (i = 0; i < HASHSIZE; i++) - { - if ((p = (*listp)->hasharray[i]) != (Node *) NULL) - { - /* put the nodes into the cache */ -#ifndef NOCACHE - p->type = NT_UNKNOWN; - p->next = nodecache; - nodecache = p; -#else - /* If NOCACHE is defined we turn off the cache. This can make - it easier to tools to determine where items were allocated - and freed, for tracking down memory leaks and the like. */ - free (p); -#endif - } - } - - /* put it on the cache */ -#ifndef NOCACHE - (*listp)->next = listcache; - listcache = *listp; -#else - free ((*listp)->list); - free (*listp); -#endif - *listp = (List *) NULL; -} - -/* - * get a new list node - */ -Node * -getnode () -{ - Node *p; - - if (nodecache != (Node *) NULL) - { - /* get one from the cache */ - p = nodecache; - nodecache = p->next; - } - else - { - /* make a new one */ - p = (Node *) xmalloc (sizeof (Node)); - } - - /* always make it clean */ - memset ((char *) p, 0, sizeof (Node)); - p->type = NT_UNKNOWN; - - return (p); -} - -/* - * remove a node from it's list (maybe hash list too) and free it - */ -void -delnode (p) - Node *p; -{ - if (p == (Node *) NULL) - return; - - /* take it out of the list */ - p->next->prev = p->prev; - p->prev->next = p->next; - - /* if it was hashed, remove it from there too */ - if (p->hashnext != (Node *) NULL) - { - p->hashnext->hashprev = p->hashprev; - p->hashprev->hashnext = p->hashnext; - } - - /* free up the storage */ - freenode (p); -} - -/* - * free up the storage associated with a node - */ -static void -freenode_mem (p) - Node *p; -{ - if (p->delproc != (void (*) ()) NULL) - p->delproc (p); /* call the specified delproc */ - else - { - if (p->data != NULL) /* otherwise free() it if necessary */ - free (p->data); - } - if (p->key != NULL) /* free the key if necessary */ - free (p->key); - - /* to be safe, re-initialize these */ - p->key = p->data = NULL; - p->delproc = (void (*) ()) NULL; -} - -/* - * free up the storage associated with a node and recycle it - */ -void -freenode (p) - Node *p; -{ - /* first free the memory */ - freenode_mem (p); - - /* then put it in the cache */ -#ifndef NOCACHE - p->type = NT_UNKNOWN; - p->next = nodecache; - nodecache = p; -#else - free (p); -#endif -} - -/* - * Link item P into list LIST before item MARKER. If P->KEY is non-NULL and - * that key is already in the hash table, return -1 without modifying any - * parameter. - * - * return 0 on success - */ -int -insert_before (list, marker, p) - List *list; - Node *marker; - Node *p; -{ - if (p->key != NULL) /* hash it too? */ - { - int hashval; - Node *q; - - hashval = hashp (p->key); - if (list->hasharray[hashval] == NULL) /* make a header for list? */ - { - q = getnode (); - q->type = HEADER; - list->hasharray[hashval] = q->hashnext = q->hashprev = q; - } - - /* put it into the hash list if it's not already there */ - for (q = list->hasharray[hashval]->hashnext; - q != list->hasharray[hashval]; q = q->hashnext) - { - if (strcmp (p->key, q->key) == 0) - return (-1); - } - q = list->hasharray[hashval]; - p->hashprev = q->hashprev; - p->hashnext = q; - p->hashprev->hashnext = p; - q->hashprev = p; - } - - p->next = marker; - p->prev = marker->prev; - marker->prev->next = p; - marker->prev = p; - - return (0); -} - -/* - * insert item p at end of list "list" (maybe hash it too) if hashing and it - * already exists, return -1 and don't actually put it in the list - * - * return 0 on success - */ -int -addnode (list, p) - List *list; - Node *p; -{ - return insert_before (list, list->list, p); -} - -/* - * Like addnode, but insert p at the front of `list'. This bogosity is - * necessary to preserve last-to-first output order for some RCS functions. - */ -int -addnode_at_front (list, p) - List *list; - Node *p; -{ - return insert_before (list, list->list->next, p); -} - -/* Look up an entry in hash list table and return a pointer to the - node. Return NULL if not found. Abort with a fatal error for - errors. */ -Node * -findnode (list, key) - List *list; - const char *key; -{ - Node *head, *p; - - /* This probably should be "assert (list != NULL)" (or if not we - should document the current behavior), but only if we check all - the callers to see if any are relying on this behavior. */ - if ((list == (List *) NULL)) - return ((Node *) NULL); - - assert (key != NULL); - - head = list->hasharray[hashp (key)]; - if (head == (Node *) NULL) - /* Not found. */ - return ((Node *) NULL); - - for (p = head->hashnext; p != head; p = p->hashnext) - if (strcmp (p->key, key) == 0) - return (p); - return ((Node *) NULL); -} - -/* - * Like findnode, but for a filename. - */ -Node * -findnode_fn (list, key) - List *list; - const char *key; -{ - Node *head, *p; - - /* This probably should be "assert (list != NULL)" (or if not we - should document the current behavior), but only if we check all - the callers to see if any are relying on this behavior. */ - if (list == (List *) NULL) - return ((Node *) NULL); - - assert (key != NULL); - - head = list->hasharray[hashp (key)]; - if (head == (Node *) NULL) - return ((Node *) NULL); - - for (p = head->hashnext; p != head; p = p->hashnext) - if (fncmp (p->key, key) == 0) - return (p); - return ((Node *) NULL); -} - -/* - * walk a list with a specific proc - */ -int -walklist (list, proc, closure) - List *list; - int (*proc) PROTO ((Node *, void *)); - void *closure; -{ - Node *head, *p; - int err = 0; - - if (list == NULL) - return (0); - - head = list->list; - for (p = head->next; p != head; p = p->next) - err += proc (p, closure); - return (err); -} - -int -list_isempty (list) - List *list; -{ - return list == NULL || list->list->next == list->list; -} - -static int (*client_comp) PROTO ((const Node *, const Node *)); -static int qsort_comp PROTO ((const void *, const void *)); - -static int -qsort_comp (elem1, elem2) - const void *elem1; - const void *elem2; -{ - Node **node1 = (Node **) elem1; - Node **node2 = (Node **) elem2; - return client_comp (*node1, *node2); -} - -/* - * sort the elements of a list (in place) - */ -void -sortlist (list, comp) - List *list; - int (*comp) PROTO ((const Node *, const Node *)); -{ - Node *head, *remain, *p, **array; - int i, n; - - if (list == NULL) - return; - - /* save the old first element of the list */ - head = list->list; - remain = head->next; - - /* count the number of nodes in the list */ - n = 0; - for (p = remain; p != head; p = p->next) - n++; - - /* allocate an array of nodes and populate it */ - array = (Node **) xmalloc (sizeof(Node *) * n); - i = 0; - for (p = remain; p != head; p = p->next) - array[i++] = p; - - /* sort the array of nodes */ - client_comp = comp; - qsort (array, n, sizeof(Node *), qsort_comp); - - /* rebuild the list from beginning to end */ - head->next = head->prev = head; - for (i = 0; i < n; i++) - { - p = array[i]; - p->next = head; - p->prev = head->prev; - p->prev->next = p; - head->prev = p; - } - - /* release the array of nodes */ - free (array); -} - -/* - * compare two files list node (for sort) - */ -int -fsortcmp (p, q) - const Node *p; - const Node *q; -{ - return (strcmp (p->key, q->key)); -} - -/* Debugging functions. Quite useful to call from within gdb. */ - -static char *nodetypestring PROTO ((Ntype)); - -static char * -nodetypestring (type) - Ntype type; -{ - switch (type) { - case NT_UNKNOWN: return("UNKNOWN"); - case HEADER: return("HEADER"); - case ENTRIES: return("ENTRIES"); - case FILES: return("FILES"); - case LIST: return("LIST"); - case RCSNODE: return("RCSNODE"); - case RCSVERS: return("RCSVERS"); - case DIRS: return("DIRS"); - case UPDATE: return("UPDATE"); - case LOCK: return("LOCK"); - case NDBMNODE: return("NDBMNODE"); - case FILEATTR: return("FILEATTR"); - case VARIABLE: return("VARIABLE"); - case RCSFIELD: return("RCSFIELD"); - case RCSCMPFLD: return("RCSCMPFLD"); - } - - return(""); -} - -static int printnode PROTO ((Node *, void *)); -static int -printnode (node, closure) - Node *node; - void *closure; -{ - if (node == NULL) - { - (void) printf("NULL node.\n"); - return(0); - } - - (void) printf("Node at %p: type = %s, key = %p = \"%s\", data = %p, next = %p, prev = %p\n", - (void *)node, nodetypestring(node->type), - (void *)node->key, node->key, node->data, - (void *)node->next, (void *)node->prev); - - return(0); -} - -/* This is global, not static, so that its name is unique and to avoid - compiler warnings about it not being used. But it is not used by CVS; - it exists so one can call it from a debugger. */ -void printlist PROTO ((List *)); - -void -printlist (list) - List *list; -{ - if (list == NULL) - { - (void) printf("NULL list.\n"); - return; - } - - (void) printf("List at %p: list = %p, HASHSIZE = %d, next = %p\n", - (void *)list, (void *)list->list, HASHSIZE, (void *)list->next); - - (void) walklist(list, printnode, NULL); - - return; -} diff --git a/contrib/cvs/src/hash.h b/contrib/cvs/src/hash.h deleted file mode 100644 index 77d095a..0000000 --- a/contrib/cvs/src/hash.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (C) 1986-2005 The Free Software Foundation, Inc. - * - * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot , - * and others. - * - * Portions Copyright (C) 1992, Brian Berliner and Jeff Polk - * - * You may distribute under the terms of the GNU General Public License as - * specified in the README file that comes with the CVS source distribution. - */ - -/* - * The number of buckets for the hash table contained in each list. This - * should probably be prime. - */ -#define HASHSIZE 151 - -/* - * Types of nodes - */ -enum ntype -{ - NT_UNKNOWN, HEADER, ENTRIES, FILES, LIST, RCSNODE, - RCSVERS, DIRS, UPDATE, LOCK, NDBMNODE, FILEATTR, - VARIABLE, RCSFIELD, RCSCMPFLD -}; -typedef enum ntype Ntype; - -struct hashnode -{ - Ntype type; - struct hashnode *next; - struct hashnode *prev; - struct hashnode *hashnext; - struct hashnode *hashprev; - char *key; - void *data; - void (*delproc) (); -}; -typedef struct hashnode Node; - -struct hashlist -{ - Node *list; - Node *hasharray[HASHSIZE]; - struct hashlist *next; -}; -typedef struct hashlist List; - -List *getlist PROTO((void)); -Node *findnode PROTO((List * list, const char *key)); -Node *findnode_fn PROTO((List * list, const char *key)); -Node *getnode PROTO((void)); -int insert_before PROTO((List * list, Node * marker, Node * p)); -int addnode PROTO((List * list, Node * p)); -int addnode_at_front PROTO((List * list, Node * p)); -int walklist PROTO((List * list, int (*)(Node *n, void *closure), void *closure)); -int list_isempty PROTO ((List *list)); -void dellist PROTO((List ** listp)); -void delnode PROTO((Node * p)); -void freenode PROTO((Node * p)); -void sortlist PROTO((List * list, int (*)(const Node *, const Node *))); -int fsortcmp PROTO((const Node * p, const Node * q)); diff --git a/contrib/cvs/src/history.c b/contrib/cvs/src/history.c deleted file mode 100644 index 78fa0fe..0000000 --- a/contrib/cvs/src/history.c +++ /dev/null @@ -1,1666 +0,0 @@ -/* - * Copyright (C) 1994-2005 The Free Software Foundation, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -/* **************** History of Users and Module **************** - * - * LOGGING: Append record to "${CVSROOT}/CVSROOTADM/CVSROOTADM_HISTORY". - * - * On For each Tag, Add, Checkout, Commit, Update or Release command, - * one line of text is written to a History log. - * - * X date | user | CurDir | special | rev(s) | argument '\n' - * - * where: [The spaces in the example line above are not in the history file.] - * - * X is a single character showing the type of event: - * T "Tag" cmd. - * O "Checkout" cmd. - * E "Export" cmd. - * F "Release" cmd. - * W "Update" cmd - No User file, Remove from Entries file. - * U "Update" cmd - File was checked out over User file. - * P "Update" cmd - User file was patched. - * G "Update" cmd - File was merged successfully. - * C "Update" cmd - File was merged and shows overlaps. - * M "Commit" cmd - "Modified" file. - * A "Commit" cmd - "Added" file. - * R "Commit" cmd - "Removed" file. - * - * date is a fixed length 8-char hex representation of a Unix time_t. - * [Starting here, variable fields are delimited by '|' chars.] - * - * user is the username of the person who typed the command. - * - * CurDir The directory where the action occurred. This should be the - * absolute path of the directory which is at the same level as - * the "Repository" field (for W,U,P,G,C & M,A,R). - * - * Repository For record types [W,U,P,G,C,M,A,R] this field holds the - * repository read from the administrative data where the - * command was typed. - * T "A" --> New Tag, "D" --> Delete Tag - * Otherwise it is the Tag or Date to modify. - * O,F,E A "" (null field) - * - * rev(s) Revision number or tag. - * T The Tag to apply. - * O,E The Tag or Date, if specified, else "" (null field). - * F "" (null field) - * W The Tag or Date, if specified, else "" (null field). - * U,P The Revision checked out over the User file. - * G,C The Revision(s) involved in merge. - * M,A,R RCS Revision affected. - * - * argument The module (for [TOEF]) or file (for [WUPGCMAR]) affected. - * - * - *** Report categories: "User" and "Since" modifiers apply to all reports. - * [For "sort" ordering see the "sort_order" routine.] - * - * Extract list of record types - * - * -e, -x [TOEFWUPGCMAR] - * - * Extracted records are simply printed, No analysis is performed. - * All "field" modifiers apply. -e chooses all types. - * - * Checked 'O'ut modules - * - * -o, -w - * Checked out modules. 'F' and 'O' records are examined and if - * the last record for a repository/file is an 'O', a line is - * printed. "-w" forces the "working dir" to be used in the - * comparison instead of the repository. - * - * Committed (Modified) files - * - * -c, -l, -w - * All 'M'odified, 'A'dded and 'R'emoved records are examined. - * "Field" modifiers apply. -l forces a sort by file within user - * and shows only the last modifier. -w works as in Checkout. - * - * Warning: Be careful with what you infer from the output of - * "cvs hi -c -l". It means the last time *you* - * changed the file, not the list of files for which - * you were the last changer!!! - * - * Module history for named modules. - * -m module, -l - * - * This is special. If one or more modules are specified, the - * module names are remembered and the files making up the - * modules are remembered. Only records matching exactly those - * files and repositories are shown. Sorting by "module", then - * filename, is implied. If -l ("last modified") is specified, - * then "update" records (types WUPCG), tag and release records - * are ignored and the last (by date) "modified" record. - * - * TAG history - * - * -T All Tag records are displayed. - * - *** Modifiers. - * - * Since ... [All records contain a timestamp, so any report - * category can be limited by date.] - * - * -D date - The "date" is parsed into a Unix "time_t" and - * records with an earlier time stamp are ignored. - * -r rev/tag - A "rev" begins with a digit. A "tag" does not. If - * you use this option, every file is searched for the - * indicated rev/tag. - * -t tag - The "tag" is searched for in the history file and no - * record is displayed before the tag is found. An - * error is printed if the tag is never found. - * -b string - Records are printed only back to the last reference - * to the string in the "module", "file" or - * "repository" fields. - * - * Field Selections [Simple comparisons on existing fields. All field - * selections are repeatable.] - * - * -a - All users. - * -u user - If no user is given and '-a' is not given, only - * records for the user typing the command are shown. - * ==> If -a or -u is not specified, just use "self". - * - * -f filematch - Only records in which the "file" field contains the - * string "filematch" are considered. - * - * -p repository - Only records in which the "repository" string is a - * prefix of the "repos" field are considered. - * - * -n modulename - Only records which contain "modulename" in the - * "module" field are considered. - * - * - * EXAMPLES: ("cvs history", "cvs his" or "cvs hi") - * - *** Checked out files for username. (default self, e.g. "dgg") - * cvs hi [equivalent to: "cvs hi -o -u dgg"] - * cvs hi -u user [equivalent to: "cvs hi -o -u user"] - * cvs hi -o [equivalent to: "cvs hi -o -u dgg"] - * - *** Committed (modified) files from the beginning of the file. - * cvs hi -c [-u user] - * - *** Committed (modified) files since Midnight, January 1, 1990: - * cvs hi -c -D 'Jan 1 1990' [-u user] - * - *** Committed (modified) files since tag "TAG" was stored in the history file: - * cvs hi -c -t TAG [-u user] - * - *** Committed (modified) files since tag "TAG" was placed on the files: - * cvs hi -c -r TAG [-u user] - * - *** Who last committed file/repository X? - * cvs hi -c -l -[fp] X - * - *** Modified files since tag/date/file/repos? - * cvs hi -c {-r TAG | -D Date | -b string} - * - *** Tag history - * cvs hi -T - * - *** History of file/repository/module X. - * cvs hi -[fpn] X - * - *** History of user "user". - * cvs hi -e -u user - * - *** Dump (eXtract) specified record types - * cvs hi -x [TOEFWUPGCMAR] - * - * - * FUTURE: J[Join], I[Import] (Not currently implemented.) - * - */ - -#include "cvs.h" -#include "history.h" -#include "savecwd.h" - -static struct hrec -{ - char *type; /* Type of record (In history record) */ - char *user; /* Username (In history record) */ - char *dir; /* "Compressed" Working dir (In history record) */ - char *repos; /* (Tag is special.) Repository (In history record) */ - char *rev; /* Revision affected (In history record) */ - char *file; /* Filename (In history record) */ - char *end; /* Ptr into repository to copy at end of workdir */ - char *mod; /* The module within which the file is contained */ - time_t date; /* Calculated from date stored in record */ - long idx; /* Index of record, for "stable" sort. */ -} *hrec_head; -static long hrec_idx; - - -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)); -static int within PROTO((char *find, char *string)); -static void expand_modules PROTO((void)); -static void read_hrecs PROTO((char *fname)); -static void report_hrecs PROTO((void)); -static void save_file PROTO((char *dir, char *name, char *module)); -static void save_module PROTO((char *module)); -static void save_user PROTO((char *name)); - -#define USER_INCREMENT 2 -#define FILE_INCREMENT 128 -#define MODULE_INCREMENT 5 -#define HREC_INCREMENT 128 - -static short report_count; - -static short extract; -static short extract_all; -static short v_checkout; -static short modified; -static short tag_report; -static short module_report; -static short working; -static short last_entry; -static short all_users; - -static short user_sort; -static short repos_sort; -static short file_sort; -static short module_sort; - -static short tz_local; -static time_t tz_seconds_east_of_GMT; -static char *tz_name = "+0000"; - -char *logHistory; - -/* -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 - with since_date, these are a mutually exclusive set; one overrides the - others. */ -static char *since_rev; -static char *since_tag; -static char *backto; -/* -D option, or 0 if not specified. RCS format. */ -static char * since_date; - -static struct hrec *last_since_tag; -static struct hrec *last_backto; - -/* Record types to look for, malloc'd. Probably could be statically - allocated, but only if we wanted to check for duplicates more than - we do. */ -static char *rec_types; - -static size_t hrec_count; -static size_t hrec_max; - -static char **user_list; /* Ptr to array of ptrs to user names */ -static size_t user_max; /* Number of elements allocated */ -static size_t user_count; /* Number of elements used */ - -static struct file_list_str -{ - char *l_file; - char *l_module; -} *file_list; /* Ptr to array file name structs */ -static size_t file_max; /* Number of elements allocated */ -static size_t file_count; /* Number of elements used */ - -static char **mod_list; /* Ptr to array of ptrs to module names */ -static size_t mod_max; /* Number of elements allocated */ -static size_t mod_count; /* Number of elements used */ - -static char *histfile; /* Ptr to the history file name */ - -/* This is pretty unclear. First of all, separating "flags" vs. - "options" (I think the distinction is that "options" take arguments) - is nonstandard, and not something we do elsewhere in CVS. Second of - all, what does "reports" mean? I think it means that you can only - supply one of those options, but "reports" hardly has that meaning in - a self-explanatory way. */ -static const char *const history_usg[] = -{ - "Usage: %s %s [-report] [-flags] [-options args] [files...]\n\n", - " Reports:\n", - " -T Produce report on all TAGs\n", - " -c Committed (Modified) files\n", - " -o Checked out modules\n", - " -m Look for specified module (repeatable)\n", - " -x [" ALL_HISTORY_REC_TYPES "] Extract by record type\n", - " -e Everything (same as -x, but all record types)\n", - " Flags:\n", - " -a All users (Default is self)\n", - " -l Last modified (committed or modified report)\n", - " -w Working directory must match\n", - " Options:\n", - " -D Since date (Many formats)\n", - " -b Back to record with str in module/file/repos field\n", - " -f Specified file (same as command line) (repeatable)\n", - " -n In module (repeatable)\n", - " -p In repository (repeatable)\n", - " -r Since rev or tag (looks inside RCS files!)\n", - " -t Since tag record placed in history file (by anyone).\n", - " -u For user name (repeatable)\n", - " -z Output for time zone (e.g. -z -0700)\n", - NULL}; - -/* Sort routine for qsort: - - If a user is selected at all, sort it first. User-within-file is useless. - - If a module was selected explicitly, sort next on module. - - Then sort by file. "File" is "repository/file" unless "working" is set, - then it is "workdir/file". (Revision order should always track date.) - - Always sort timestamp last. -*/ -static int -sort_order (l, r) - const PTR l; - const PTR r; -{ - int i; - const struct hrec *left = (const struct hrec *) l; - const struct hrec *right = (const struct hrec *) r; - - if (user_sort) /* If Sort by username, compare users */ - { - if ((i = strcmp (left->user, right->user)) != 0) - return (i); - } - if (module_sort) /* If sort by modules, compare module names */ - { - if (left->mod && right->mod) - if ((i = strcmp (left->mod, right->mod)) != 0) - return (i); - } - if (repos_sort) /* If sort by repository, compare them. */ - { - if ((i = strcmp (left->repos, right->repos)) != 0) - return (i); - } - if (file_sort) /* If sort by filename, compare files, NOT dirs. */ - { - if ((i = strcmp (left->file, right->file)) != 0) - return (i); - - if (working) - { - if ((i = strcmp (left->dir, right->dir)) != 0) - return (i); - - if ((i = strcmp (left->end, right->end)) != 0) - return (i); - } - } - - /* - * By default, sort by date, time - * XXX: This fails after 2030 when date slides into sign bit - */ - if ((i = ((long) (left->date) - (long) (right->date))) != 0) - return (i); - - /* For matching dates, keep the sort stable by using record index */ - return (left->idx - right->idx); -} - -int -history (argc, argv) - int argc; - char **argv; -{ - int i, c; - char *fname; - - if (argc == -1) - usage (history_usg); - - since_rev = xstrdup (""); - since_tag = xstrdup (""); - backto = xstrdup (""); - rec_types = xstrdup (""); - optind = 0; - while ((c = getopt (argc, argv, "+Tacelow?D:b:f:m:n:p:r:t:u:x:X:z:")) != -1) - { - switch (c) - { - case 'T': /* Tag list */ - report_count++; - tag_report++; - break; - case 'a': /* For all usernames */ - all_users++; - break; - case 'c': - report_count++; - modified = 1; - break; - case 'e': - report_count++; - extract_all++; - free (rec_types); - rec_types = xstrdup (ALL_HISTORY_REC_TYPES); - break; - case 'l': /* Find Last file record */ - last_entry = 1; - break; - case 'o': - report_count++; - v_checkout = 1; - break; - case 'w': /* Match Working Dir (CurDir) fields */ - working = 1; - break; - case 'X': /* Undocumented debugging flag */ -#ifdef DEBUG - histfile = optarg; -#endif - break; - - case 'D': /* Since specified date */ - if (*since_rev || *since_tag || *backto) - { - error (0, 0, "date overriding rev/tag/backto"); - *since_rev = *since_tag = *backto = '\0'; - } - since_date = Make_Date (optarg); - break; - case 'b': /* Since specified file/Repos */ - if (since_date || *since_rev || *since_tag) - { - error (0, 0, "backto overriding date/rev/tag"); - *since_rev = *since_tag = '\0'; - if (since_date != NULL) - free (since_date); - since_date = NULL; - } - free (backto); - backto = xstrdup (optarg); - break; - case 'f': /* For specified file */ - save_file (NULL, optarg, NULL); - break; - case 'm': /* Full module report */ - if (!module_report++) report_count++; - /* fall through */ - case 'n': /* Look for specified module */ - save_module (optarg); - break; - case 'p': /* For specified directory */ - save_file (optarg, NULL, NULL); - break; - case 'r': /* Since specified Tag/Rev */ - if (since_date || *since_tag || *backto) - { - error (0, 0, "rev overriding date/tag/backto"); - *since_tag = *backto = '\0'; - if (since_date != NULL) - free (since_date); - since_date = NULL; - } - free (since_rev); - since_rev = xstrdup (optarg); - break; - case 't': /* Since specified Tag/Rev */ - if (since_date || *since_rev || *backto) - { - error (0, 0, "tag overriding date/marker/file/repos"); - *since_rev = *backto = '\0'; - if (since_date != NULL) - free (since_date); - since_date = NULL; - } - free (since_tag); - since_tag = xstrdup (optarg); - break; - case 'u': /* For specified username */ - save_user (optarg); - break; - case 'x': - report_count++; - extract++; - { - char *cp; - - for (cp = optarg; *cp; cp++) - if (!strchr (ALL_HISTORY_REC_TYPES, *cp)) - error (1, 0, "%c is not a valid report type", *cp); - } - free (rec_types); - rec_types = xstrdup (optarg); - break; - case 'z': - tz_local = - (optarg[0] == 'l' || optarg[0] == 'L') - && (optarg[1] == 't' || optarg[1] == 'T') - && !optarg[2]; - if (tz_local) - tz_name = optarg; - else - { - /* - * Convert a known time with the given timezone to time_t. - * Use the epoch + 23 hours, so timezones east of GMT work. - */ - static char f[] = "1/1/1970 23:00 %s"; - char *buf = xmalloc (sizeof (f) - 2 + strlen (optarg)); - time_t t; - sprintf (buf, f, optarg); - t = get_date (buf, (struct timeb *) NULL); - free (buf); - if (t == (time_t) -1) - error (0, 0, "%s is not a known time zone", optarg); - else - { - /* - * Convert to seconds east of GMT, removing the - * 23-hour offset mentioned above. - */ - tz_seconds_east_of_GMT = (time_t)23 * 60 * 60 - t; - tz_name = optarg; - } - } - break; - case '?': - default: - usage (history_usg); - break; - } - } - argc -= optind; - argv += optind; - for (i = 0; i < argc; i++) - save_file (NULL, argv[i], 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: \"-Tcomxe\"."); - -#ifdef CLIENT_SUPPORT - if (current_parsed_root->isremote) - { - struct file_list_str *f1; - char **mod; - - /* We're the client side. Fire up the remote server. */ - start_server (); - - ign_setup (); - - if (tag_report) - send_arg("-T"); - if (all_users) - send_arg("-a"); - if (modified) - send_arg("-c"); - if (last_entry) - send_arg("-l"); - if (v_checkout) - send_arg("-o"); - if (working) - send_arg("-w"); - if (histfile) - send_arg("-X"); - if (since_date) - client_senddate (since_date); - if (backto[0] != '\0') - option_with_arg ("-b", backto); - for (f1 = file_list; f1 < &file_list[file_count]; ++f1) - { - if (f1->l_file[0] == '*') - option_with_arg ("-p", f1->l_file + 1); - else - option_with_arg ("-f", f1->l_file); - } - if (module_report) - send_arg("-m"); - for (mod = mod_list; mod < &mod_list[mod_count]; ++mod) - option_with_arg ("-n", *mod); - if (*since_rev) - option_with_arg ("-r", since_rev); - if (*since_tag) - option_with_arg ("-t", since_tag); - for (mod = user_list; mod < &user_list[user_count]; ++mod) - option_with_arg ("-u", *mod); - if (extract_all) - send_arg("-e"); - if (extract) - option_with_arg ("-x", rec_types); - option_with_arg ("-z", tz_name); - - send_to_server ("history\012", 0); - return get_responses_and_close (); - } -#endif - - if (all_users) - save_user (""); - - if (mod_list) - expand_modules (); - - if (tag_report) - { - if (!strchr (rec_types, 'T')) - { - rec_types = xrealloc (rec_types, strlen (rec_types) + 5); - (void) strcat (rec_types, "T"); - } - } - else if (extract || extract_all) - { - if (user_list) - user_sort++; - } - else if (modified) - { - free (rec_types); - rec_types = xstrdup ("MAR"); - /* - * If the user has not specified a date oriented flag ("Since"), sort - * by Repository/file before date. Default is "just" date. - */ - if (last_entry - || (!since_date && !*since_rev && !*since_tag && !*backto)) - { - repos_sort++; - file_sort++; - /* - * If we are not looking for last_modified and the user specified - * one or more users to look at, sort by user before filename. - */ - if (!last_entry && user_list) - user_sort++; - } - } - else if (module_report) - { - free (rec_types); - rec_types = xstrdup (last_entry ? "OMAR" : ALL_HISTORY_REC_TYPES); - module_sort++; - repos_sort++; - file_sort++; - working = 0; /* User's workdir doesn't count here */ - } - else - /* Must be "checkout" or default */ - { - free (rec_types); - rec_types = xstrdup ("OF"); - /* See comments in "modified" above */ - if (!last_entry && user_list) - user_sort++; - if (last_entry - || (!since_date && !*since_rev && !*since_tag && !*backto)) - file_sort++; - } - - /* If no users were specified, use self (-a saves a universal ("") user) */ - if (!user_list) - save_user (getcaller ()); - - /* If we're looking back to a Tag value, must consider "Tag" records */ - if (*since_tag && !strchr (rec_types, 'T')) - { - rec_types = xrealloc (rec_types, strlen (rec_types) + 5); - (void) strcat (rec_types, "T"); - } - - if (histfile) - fname = xstrdup (histfile); - else - { - fname = xmalloc (strlen (current_parsed_root->directory) + sizeof (CVSROOTADM) - + sizeof (CVSROOTADM_HISTORY) + 10); - (void) sprintf (fname, "%s/%s/%s", current_parsed_root->directory, - CVSROOTADM, CVSROOTADM_HISTORY); - } - - read_hrecs (fname); - if(hrec_count>0) - { - qsort ((PTR) hrec_head, hrec_count, - sizeof (struct hrec), sort_order); - } - report_hrecs (); - free (fname); - if (since_date != NULL) - free (since_date); - free (since_rev); - free (since_tag); - free (backto); - free (rec_types); - - return (0); -} - -void -history_write (type, update_dir, revs, name, repository) - int type; - const char *update_dir; - const char *revs; - const char *name; - const char *repository; -{ - char *fname; - char *workdir; - char *username = getcaller (); - int fd; - char *line; - char *slash = "", *cp; - const char *cp2, *repos; - int i; - static char *tilde = ""; - static char *PrCurDir = NULL; - - if (logoff) /* History is turned off by noexec or - * readonlyfs. - */ - return; - if (strchr (logHistory, type) == NULL) - return; - fname = xmalloc (strlen (current_parsed_root->directory) - + sizeof (CVSROOTADM) - + sizeof (CVSROOTADM_HISTORY) + 3); - (void) sprintf (fname, "%s/%s/%s", current_parsed_root->directory, - CVSROOTADM, CVSROOTADM_HISTORY); - - /* turn off history logging if the history file does not exist */ - /* FIXME: This should check for write permissions instead. This way, - * O_CREATE could be added back into the call to open() below and - * there would be no race condition involved in log rotation. - * - * Note that the new method of turning off logging would be either via - * the CVSROOT/config file (probably the quicker method, but would need - * to be added, or at least checked for, too) or by creating a dummy - * history file with 0444 permissions. - */ - if (!isfile (fname)) - { - logoff = 1; - goto out; - } - - if (trace) - fprintf (stderr, "%s-> fopen(%s,a)\n", - CLIENT_SERVER_STR, fname); - if (noexec) - goto out; - - if (!history_lock (current_parsed_root->directory)) - /* history_lock() will already have printed an error on failure. */ - goto out; - - fd = CVS_OPEN (fname, O_WRONLY | O_APPEND | OPEN_BINARY, 0666); - if (fd < 0) - { - if (! really_quiet) - { - error (0, errno, "warning: cannot write to history file %s", - fname); - } - goto out; - } - - repos = Short_Repository (repository); - - if (!PrCurDir) - { - char *pwdir; - - pwdir = get_homedir (); - PrCurDir = CurDir; - if (pwdir != NULL) - { - /* Assumes neither CurDir nor pwdir ends in '/' */ - i = strlen (pwdir); - if (!strncmp (CurDir, pwdir, i)) - { - PrCurDir += i; /* Point to '/' separator */ - tilde = "~"; - } - else - { - /* Try harder to find a "homedir" */ - struct saved_cwd cwd; - char *homedir; - - if (save_cwd (&cwd)) - error_exit (); - - if (CVS_CHDIR (pwdir) < 0 || (homedir = xgetwd ()) == NULL) - homedir = pwdir; - - if (restore_cwd (&cwd, NULL)) - error_exit (); - free_cwd (&cwd); - - i = strlen (homedir); - if (!strncmp (CurDir, homedir, i)) - { - PrCurDir += i; /* Point to '/' separator */ - tilde = "~"; - } - - if (homedir != pwdir) - free (homedir); - } - } - } - - if (type == 'T') - { - repos = update_dir; - update_dir = ""; - } - else if (update_dir && *update_dir) - slash = "/"; - else - update_dir = ""; - - workdir = xmalloc (strlen (tilde) + strlen (PrCurDir) + strlen (slash) - + strlen (update_dir) + 10); - (void) sprintf (workdir, "%s%s%s%s", tilde, PrCurDir, slash, update_dir); - - /* - * "workdir" is the directory where the file "name" is. ("^~" == $HOME) - * "repos" is the Repository, relative to $CVSROOT where the RCS file is. - * - * "$workdir/$name" is the working file name. - * "$CVSROOT/$repos/$name,v" is the RCS file in the Repository. - * - * First, note that the history format was intended to save space, not - * to be human readable. - * - * The working file directory ("workdir") and the Repository ("repos") - * usually end with the same one or more directory elements. To avoid - * duplication (and save space), the "workdir" field ends with - * an integer offset into the "repos" field. This offset indicates the - * beginning of the "tail" of "repos", after which all characters are - * duplicates. - * - * In other words, if the "workdir" field has a '*' (a very stupid thing - * to put in a filename) in it, then every thing following the last '*' - * is a hex offset into "repos" of the first character from "repos" to - * append to "workdir" to finish the pathname. - * - * It might be easier to look at an example: - * - * M273b3463|dgg|~/work*9|usr/local/cvs/examples|1.2|loginfo - * - * Indicates that the workdir is really "~/work/cvs/examples", saving - * 10 characters, where "~/work*d" would save 6 characters and mean that - * the workdir is really "~/work/examples". It will mean more on - * directories like: usr/local/gnu/emacs/dist-19.17/lisp/term - * - * "workdir" is always an absolute pathname (~/xxx is an absolute path) - * "repos" is always a relative pathname. So we can assume that we will - * never run into the top of "workdir" -- there will always be a '/' or - * a '~' at the head of "workdir" that is not matched by anything in - * "repos". On the other hand, we *can* run off the top of "repos". - * - * Only "compress" if we save characters. - */ - - if (!repos) - repos = ""; - - cp = workdir + strlen (workdir) - 1; - cp2 = repos + strlen (repos) - 1; - for (i = 0; cp2 >= repos && cp > workdir && *cp == *cp2--; cp--) - i++; - - if (i > 2) - { - i = strlen (repos) - i; - (void) sprintf ((cp + 1), "*%x", i); - } - - if (!revs) - revs = ""; - line = xmalloc (strlen (username) + strlen (workdir) + strlen (repos) - + strlen (revs) + strlen (name) + 100); - sprintf (line, "%c%08lx|%s|%s|%s|%s|%s\n", - type, (long) time ((time_t *) NULL), - username, workdir, repos, revs, name); - - /* Lessen some race conditions on non-Posix-compliant hosts. */ - if (lseek (fd, (off_t) 0, SEEK_END) == -1) - error (1, errno, "cannot seek to end of history file: %s", fname); - - if (write (fd, line, strlen (line)) < 0) - error (1, errno, "cannot write to history file: %s", fname); - free (line); - if (close (fd) != 0) - error (1, errno, "cannot close history file: %s", fname); - free (workdir); - out: - clear_history_lock (); - free (fname); -} - -/* - * save_user() adds a user name to the user list to select. Zero-length - * username ("") matches any user. - */ -static void -save_user (name) - char *name; -{ - if (user_count == user_max) - { - user_max = xsum (user_max, USER_INCREMENT); - if (user_count == user_max - || size_overflow_p (xtimes (user_max, sizeof (char *)))) - { - error (0, 0, "save_user: too many users"); - return; - } - user_list = xrealloc (user_list, xtimes (user_max, sizeof (char *))); - } - user_list[user_count++] = xstrdup (name); -} - -/* - * save_file() adds file name and associated module to the file list to select. - * - * If "dir" is null, store a file name as is. - * If "name" is null, store a directory name with a '*' on the front. - * Else, store concatenated "dir/name". - * - * Later, in the "select" stage: - * - if it starts with '*', it is prefix-matched against the repository. - * - if it has a '/' in it, it is matched against the repository/file. - * - else it is matched against the file name. - */ -static void -save_file (dir, name, module) - char *dir; - char *name; - char *module; -{ - char *cp; - struct file_list_str *fl; - - if (file_count == file_max) - { - file_max = xsum (file_max, FILE_INCREMENT); - if (file_count == file_max - || size_overflow_p (xtimes (file_max, sizeof (*fl)))) - { - error (0, 0, "save_file: too many files"); - return; - } - file_list = xrealloc (file_list, xtimes (file_max, sizeof (*fl))); - } - fl = &file_list[file_count++]; - fl->l_file = cp = xmalloc (dir ? strlen (dir) : 0 - + name ? strlen (name) : 0 - + 2); - fl->l_module = module; - - if (dir && *dir) - { - if (name && *name) - { - (void) strcpy (cp, dir); - (void) strcat (cp, "/"); - (void) strcat (cp, name); - } - else - { - *cp++ = '*'; - (void) strcpy (cp, dir); - } - } - else - { - if (name && *name) - { - (void) strcpy (cp, name); - } - else - { - error (0, 0, "save_file: null dir and file name"); - } - } -} - -static void -save_module (module) - char *module; -{ - if (mod_count == mod_max) - { - mod_max = xsum (mod_max, MODULE_INCREMENT); - if (mod_count == mod_max - || size_overflow_p (xtimes (mod_max, sizeof (char *)))) - { - error (0, 0, "save_module: too many modules"); - return; - } - mod_list = xrealloc (mod_list, xtimes (mod_max, sizeof (char *))); - } - mod_list[mod_count++] = xstrdup (module); -} - -static void -expand_modules () -{ -} - -/* fill_hrec - * - * Take a ptr to 7-part history line, ending with a newline, for example: - * - * M273b3463|dgg|~/work*9|usr/local/cvs/examples|1.2|loginfo - * - * 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(*line)) line++; \ - hr->here = line; \ - while ((c = *line++) && c != '|') ; \ - if (!c) return; line[-1] = '\0'; \ - } while (0) - -static void -fill_hrec (line, hr) - char *line; - struct hrec *hr; -{ - char *cp; - int c; - - hr->type = hr->user = hr->dir = hr->repos = hr->rev = hr->file = - hr->end = hr->mod = NULL; - hr->date = -1; - hr->idx = ++hrec_idx; - - while (isspace ((unsigned char) *line)) - line++; - - hr->type = line++; - hr->date = strtoul (line, &cp, 16); - if (cp == line || *cp != '|') - return; - line = cp + 1; - NEXT_BAR (user); - NEXT_BAR (dir); - if ((cp = strrchr (hr->dir, '*')) != NULL) - { - *cp++ = '\0'; - hr->end = line + strtoul (cp, NULL, 16); - } - else - hr->end = line - 1; /* A handy pointer to '\0' */ - NEXT_BAR (repos); - NEXT_BAR (rev); - if (strchr ("FOET", *(hr->type))) - hr->mod = line; - - NEXT_BAR (file); -} - - -#ifndef STAT_BLOCKSIZE -#if HAVE_STRUCT_STAT_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 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; -{ - unsigned char *cpstart, *cpend, *cp, *nl; - char *hrline; - int i; - int fd; - struct stat st_buf; - - if ((fd = CVS_OPEN (fname, O_RDONLY | OPEN_BINARY)) < 0) - error (1, errno, "cannot open history file: %s", fname); - - if (fstat (fd, &st_buf) < 0) - error (1, errno, "can't stat history file"); - - if (!(st_buf.st_size)) - error (1, 0, "history file is empty"); - - cpstart = xmalloc (2 * STAT_BLOCKSIZE(st_buf)); - cpstart[0] = '\0'; - cp = cpend = cpstart; - - hrec_max = HREC_INCREMENT; - hrec_head = xmalloc (hrec_max * sizeof (struct hrec)); - hrec_idx = 0; - - for (;;) - { - for (nl = cp; nl < cpend && *nl != '\n'; nl++) - if (!isprint(*nl)) *nl = ' '; - - if (nl >= cpend) - { - if (nl - cp >= STAT_BLOCKSIZE(st_buf)) - { - error(1, 0, "history line %ld too long (> %lu)", hrec_idx + 1, - (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) - { - cpend = nl + i; - *cpend = '\0'; - continue; - } - if (i < 0) - error (1, errno, "error reading history file"); - if (nl == cp) break; - error (0, 0, "warning: no newline at end of history file"); - } - *nl = '\0'; - - if (hrec_count == hrec_max) - { - struct hrec *old_head = hrec_head; - - hrec_max = xsum (hrec_max, HREC_INCREMENT); - if (hrec_count == hrec_max - || size_overflow_p (xtimes (hrec_max, sizeof (struct hrec)))) - error (1, 0, "Too many history records in history file."); - - hrec_head = xrealloc (hrec_head, - xtimes (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); - } - - /* 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. */ - - 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 - * records since the *last* occurrence of "since_tag". So what we have - * to do is bump hrec_head forward and reduce hrec_count accordingly. - */ - if (last_since_tag) - { - hrec_count -= (last_since_tag - hrec_head); - hrec_head = last_since_tag; - } - - /* Much the same thing is necessary for the "backto" option. */ - if (last_backto) - { - hrec_count -= (last_backto - hrec_head); - hrec_head = last_backto; - } -} - -/* Utility program for determining whether "find" is inside "string" */ -static int -within (find, string) - char *find, *string; -{ - int c, len; - - if (!find || !string) - return (0); - - c = *find++; - len = strlen (find); - - while (*string) - { - if (!(string = strchr (string, c))) - return (0); - string++; - if (!strncmp (find, string, len)) - return (1); - } - return (0); -} - -/* The purpose of "select_hrec" is to apply the selection criteria based on - * the command arguments and defaults and return a flag indicating whether - * this record should be remembered for printing. - */ -static int -select_hrec (hr) - struct hrec *hr; -{ - char **cpp, *cp, *cp2; - struct file_list_str *fl; - int count; - - /* basic validity checking */ - if (!hr->type || !hr->user || !hr->dir || !hr->repos || !hr->rev || - !hr->file || !hr->end) - { - error (0, 0, "warning: history line %ld invalid", hr->idx); - return (0); - } - - /* "Since" checking: The argument parser guarantees that only one of the - * following four choices is set: - * - * 1. If "since_date" is set, it contains the date specified on the - * command line. hr->date fields earlier than "since_date" are ignored. - * 2. If "since_rev" is set, it contains either an RCS "dotted" revision - * number (which is of limited use) or a symbolic TAG. Each RCS file - * is examined and the date on the specified revision (or the revision - * corresponding to the TAG) in the RCS file (CVSROOT/repos/file) is - * compared against hr->date as in 1. above. - * 3. If "since_tag" is set, matching tag records are saved. The field - * "last_since_tag" is set to the last one of these. Since we don't - * know where the last one will be, all records are saved from the - * first occurrence of the TAG. Later, at the end of "select_hrec" - * records before the last occurrence of "since_tag" are skipped. - * 4. If "backto" is set, all records with a module name or file name - * matching "backto" are saved. In addition, all records with a - * repository field with a *prefix* matching "backto" are saved. - * The field "last_backto" is set to the last one of these. As in - * 3. above, "select_hrec" adjusts to include the last one later on. - */ - if (since_date) - { - char *ourdate = date_from_time_t (hr->date); - count = RCS_datecmp (ourdate, since_date); - free (ourdate); - if (count < 0) - return (0); - } - else if (*since_rev) - { - Vers_TS *vers; - time_t t; - struct file_info finfo; - - memset (&finfo, 0, sizeof finfo); - finfo.file = hr->file; - /* Not used, so don't worry about it. */ - finfo.update_dir = NULL; - finfo.fullname = finfo.file; - finfo.repository = hr->repos; - finfo.entries = NULL; - finfo.rcs = NULL; - - vers = Version_TS (&finfo, (char *) NULL, since_rev, (char *) NULL, - 1, 0); - if (vers->vn_rcs) - { - if ((t = RCS_getrevtime (vers->srcfile, vers->vn_rcs, (char *) 0, 0)) - != (time_t) 0) - { - if (hr->date < t) - { - freevers_ts (&vers); - return (0); - } - } - } - freevers_ts (&vers); - } - else if (*since_tag) - { - if (*(hr->type) == 'T') - { - /* - * A 'T'ag record, the "rev" field holds the tag to be set, - * while the "repos" field holds "D"elete, "A"dd or a rev. - */ - if (within (since_tag, hr->rev)) - { - last_since_tag = hr; - return (1); - } - else - return (0); - } - if (!last_since_tag) - return (0); - } - else if (*backto) - { - if (within (backto, hr->file) || within (backto, hr->mod) || - within (backto, hr->repos)) - last_backto = hr; - else - return (0); - } - - /* User checking: - * - * Run down "user_list", match username ("" matches anything) - * If "" is not there and actual username is not there, return failure. - */ - if (user_list && hr->user) - { - for (cpp = user_list, count = user_count; count; cpp++, count--) - { - if (!**cpp) - break; /* null user == accept */ - if (!strcmp (hr->user, *cpp)) /* found listed user */ - break; - } - if (!count) - return (0); /* Not this user */ - } - - /* Record type checking: - * - * 1. If Record type is not in rec_types field, skip it. - * 2. If mod_list is null, keep everything. Otherwise keep only modules - * on mod_list. - * 3. If neither a 'T', 'F' nor 'O' record, run through "file_list". If - * file_list is null, keep everything. Otherwise, keep only files on - * file_list, matched appropriately. - */ - if (!strchr (rec_types, *(hr->type))) - return (0); - if (!strchr ("TFOE", *(hr->type))) /* Don't bother with "file" if "TFOE" */ - { - if (file_list) /* If file_list is null, accept all */ - { - for (fl = file_list, count = file_count; count; fl++, count--) - { - /* 1. If file_list entry starts with '*', skip the '*' and - * compare it against the repository in the hrec. - * 2. If file_list entry has a '/' in it, compare it against - * the concatenation of the repository and file from hrec. - * 3. Else compare the file_list entry against the hrec file. - */ - char *cmpfile = NULL; - - if (*(cp = fl->l_file) == '*') - { - cp++; - /* if argument to -p is a prefix of repository */ - if (!strncmp (cp, hr->repos, strlen (cp))) - { - hr->mod = fl->l_module; - break; - } - } - else - { - if (strchr (cp, '/')) - { - cmpfile = xmalloc (strlen (hr->repos) - + strlen (hr->file) - + 10); - (void) sprintf (cmpfile, "%s/%s", - hr->repos, hr->file); - cp2 = cmpfile; - } - else - { - cp2 = hr->file; - } - - /* if requested file is found within {repos}/file fields */ - if (within (cp, cp2)) - { - hr->mod = fl->l_module; - if (cmpfile != NULL) - free (cmpfile); - break; - } - if (cmpfile != NULL) - free (cmpfile); - } - } - if (!count) - return (0); /* String specified and no match */ - } - } - if (mod_list) - { - for (cpp = mod_list, count = mod_count; count; cpp++, count--) - { - if (hr->mod && !strcmp (hr->mod, *cpp)) /* found module */ - break; - } - if (!count) - return (0); /* Module specified & this record is not one of them. */ - } - - return (1); /* Select this record unless rejected above. */ -} - -/* The "sort_order" routine (when handed to qsort) has arranged for the - * hrecs files to be in the right order for the report. - * - * Most of the "selections" are done in the select_hrec routine, but some - * selections are more easily done after the qsort by "accept_hrec". - */ -static void -report_hrecs () -{ - struct hrec *hr, *lr; - struct tm *tm; - int i, count, ty; - char *cp; - int user_len, file_len, rev_len, mod_len, repos_len; - - if (*since_tag && !last_since_tag) - { - (void) printf ("No tag found: %s\n", since_tag); - return; - } - else if (*backto && !last_backto) - { - (void) printf ("No module, file or repository with: %s\n", backto); - return; - } - else if (hrec_count < 1) - { - (void) printf ("No records selected.\n"); - return; - } - - user_len = file_len = rev_len = mod_len = repos_len = 0; - - /* Run through lists and find maximum field widths */ - hr = lr = hrec_head; - hr++; - for (count = hrec_count; count--; lr = hr, hr++) - { - char *repos; - - if (!count) - hr = NULL; - if (!accept_hrec (lr, hr)) - continue; - - ty = *(lr->type); - repos = xstrdup (lr->repos); - if ((cp = strrchr (repos, '/')) != NULL) - { - if (lr->mod && !strcmp (++cp, lr->mod)) - { - (void) strcpy (cp, "*"); - } - } - if ((i = strlen (lr->user)) > user_len) - user_len = i; - if ((i = strlen (lr->file)) > file_len) - file_len = i; - if (ty != 'T' && (i = strlen (repos)) > repos_len) - repos_len = i; - if (ty != 'T' && (i = strlen (lr->rev)) > rev_len) - rev_len = i; - if (lr->mod && (i = strlen (lr->mod)) > mod_len) - mod_len = i; - free (repos); - } - - /* Walk through hrec array setting "lr" (Last Record) to each element. - * "hr" points to the record following "lr" -- It is NULL in the last - * pass. - * - * There are two sections in the loop below: - * 1. Based on the report type (e.g. extract, checkout, tag, etc.), - * decide whether the record should be printed. - * 2. Based on the record type, format and print the data. - */ - for (lr = hrec_head, hr = (lr + 1); hrec_count--; lr = hr, hr++) - { - char *workdir; - char *repos; - - if (!hrec_count) - hr = NULL; - if (!accept_hrec (lr, hr)) - continue; - - ty = *(lr->type); - if (!tz_local) - { - time_t t = lr->date + tz_seconds_east_of_GMT; - tm = gmtime (&t); - } - else - tm = localtime (&(lr->date)); - - (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); - if ((cp = strrchr (workdir, '/')) != NULL) - { - if (lr->mod && !strcmp (++cp, lr->mod)) - { - (void) strcpy (cp, "*"); - } - } - repos = xmalloc (strlen (lr->repos) + 10); - (void) strcpy (repos, lr->repos); - if ((cp = strrchr (repos, '/')) != NULL) - { - if (lr->mod && !strcmp (++cp, lr->mod)) - { - (void) strcpy (cp, "*"); - } - } - - switch (ty) - { - case 'T': - /* 'T'ag records: repository is a "tag type", rev is the tag */ - (void) printf (" %-*s [%s:%s]", mod_len, lr->mod, lr->rev, - repos); - if (working) - (void) printf (" {%s}", workdir); - break; - case 'F': - case 'E': - case 'O': - if (lr->rev && *(lr->rev)) - (void) printf (" [%s]", lr->rev); - (void) printf (" %-*s =%s%-*s %s", repos_len, repos, lr->mod, - mod_len + 1 - (int) strlen (lr->mod), - "=", workdir); - break; - case 'W': - case 'U': - case 'P': - case 'C': - case 'G': - case 'M': - case 'A': - case 'R': - (void) printf (" %-*s %-*s %-*s =%s= %s", rev_len, lr->rev, - file_len, lr->file, repos_len, repos, - lr->mod ? lr->mod : "", workdir); - break; - default: - (void) printf ("Hey! What is this junk? RecType[0x%2.2x]", ty); - break; - } - (void) putchar ('\n'); - free (workdir); - free (repos); - } -} - -static int -accept_hrec (lr, hr) - struct hrec *hr, *lr; -{ - int ty; - - ty = *(lr->type); - - if (last_since_tag && ty == 'T') - return (1); - - if (v_checkout) - { - if (ty != 'O') - return (0); /* Only interested in 'O' records */ - - /* We want to identify all the states that cause the next record - * ("hr") to be different from the current one ("lr") and only - * print a line at the allowed boundaries. - */ - - if (!hr || /* The last record */ - strcmp (hr->user, lr->user) || /* User has changed */ - strcmp (hr->mod, lr->mod) ||/* Module has changed */ - (working && /* If must match "workdir" */ - (strcmp (hr->dir, lr->dir) || /* and the 1st parts or */ - strcmp (hr->end, lr->end)))) /* the 2nd parts differ */ - - return (1); - } - else if (modified) - { - if (!last_entry || /* Don't want only last rec */ - !hr || /* Last entry is a "last entry" */ - strcmp (hr->repos, lr->repos) || /* Repository has changed */ - strcmp (hr->file, lr->file))/* File has changed */ - return (1); - - if (working) - { /* If must match "workdir" */ - if (strcmp (hr->dir, lr->dir) || /* and the 1st parts or */ - strcmp (hr->end, lr->end)) /* the 2nd parts differ */ - return (1); - } - } - else if (module_report) - { - if (!last_entry || /* Don't want only last rec */ - !hr || /* Last entry is a "last entry" */ - strcmp (hr->mod, lr->mod) ||/* Module has changed */ - strcmp (hr->repos, lr->repos) || /* Repository has changed */ - strcmp (hr->file, lr->file))/* File has changed */ - return (1); - } - else - { - /* "extract" and "tag_report" always print selected records. */ - return (1); - } - - return (0); -} diff --git a/contrib/cvs/src/history.h b/contrib/cvs/src/history.h deleted file mode 100644 index dadc421..0000000 --- a/contrib/cvs/src/history.h +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright (C) 2003-2005 The Free Software Foundation, Inc. - * - * Portions Copyright (C) 2003-2005 Derek Price, Ximbiot , - * and others. - * - * You may distribute under the terms of the GNU General Public License - * as specified in the README file that comes with the CVS source - * distribution. - * - * This is the header file for definitions and functions shared by history.c - * with other portions of CVS. - */ - -#define ALL_HISTORY_REC_TYPES "TOEFWUPCGMAR" diff --git a/contrib/cvs/src/ignore.c b/contrib/cvs/src/ignore.c deleted file mode 100644 index 65b2260..0000000 --- a/contrib/cvs/src/ignore.c +++ /dev/null @@ -1,503 +0,0 @@ -/* This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. */ - -/* - * .cvsignore file support contributed by David G. Grubbs - */ - -#include "cvs.h" -#include "getline.h" - -/* - * Ignore file section. - * - * "!" may be included any time to reset the list (i.e. ignore nothing); - * "*" may be specified to ignore everything. It stays as the first - * element forever, unless a "!" clears it out. - */ - -static char **ign_list; /* List of files to ignore in update - * and import */ -static char **s_ign_list = NULL; -static int ign_count; /* Number of active entries */ -static int s_ign_count = 0; -static int ign_size; /* This many slots available (plus - * one for a NULL) */ -static int ign_hold = -1; /* Index where first "temporary" item - * is held */ - -const char *ign_default = ". .. core RCSLOG tags TAGS RCS SCCS .make.state\ - .nse_depinfo #* .#* cvslog.* ,* CVS CVS.adm .del-* *.a *.olb *.o *.obj\ - *.so *.Z *~ *.old *.elc *.ln *.bak *.BAK *.orig *.rej *.exe _$* *$"; - -#define IGN_GROW 16 /* grow the list by 16 elements at a - * time */ - -/* Nonzero if we have encountered an -I ! directive, which means one should - no longer ask the server about what is in CVSROOTADM_IGNORE. */ -int ign_inhibit_server; - - - -/* - * To the "ignore list", add the hard-coded default ignored wildcards above, - * the wildcards found in $CVSROOT/CVSROOT/cvsignore, the wildcards found in - * ~/.cvsignore and the wildcards found in the CVSIGNORE environment - * variable. - */ -void -ign_setup () -{ - char *home_dir; - char *tmp; - - ign_inhibit_server = 0; - - /* Start with default list and special case */ - tmp = xstrdup (ign_default); - ign_add (tmp, 0); - free (tmp); - - /* The client handles another way, by (after it does its own ignore file - processing, and only if !ign_inhibit_server), letting the server - know about the files and letting it decide whether to ignore - them based on CVSROOOTADM_IGNORE. */ - if (!current_parsed_root->isremote) - { - char *file = xmalloc (strlen (current_parsed_root->directory) + sizeof (CVSROOTADM) - + sizeof (CVSROOTADM_IGNORE) + 10); - /* Then add entries found in repository, if it exists */ - (void) sprintf (file, "%s/%s/%s", current_parsed_root->directory, - CVSROOTADM, CVSROOTADM_IGNORE); - ign_add_file (file, 0); - free (file); - } - - /* Then add entries found in home dir, (if user has one) and file exists */ - home_dir = get_homedir (); - /* If we can't find a home directory, ignore ~/.cvsignore. This may - make tracking down problems a bit of a pain, but on the other - hand it might be obnoxious to complain when CVS will function - just fine without .cvsignore (and many users won't even know what - .cvsignore is). */ - if (home_dir) - { - char *file = strcat_filename_onto_homedir (home_dir, CVSDOTIGNORE); - ign_add_file (file, 0); - free (file); - } - - /* Then add entries found in CVSIGNORE environment variable. */ - ign_add (getenv (IGNORE_ENV), 0); - - /* Later, add ignore entries found in -I arguments */ -} - - - -/* - * Open a file and read lines, feeding each line to a line parser. Arrange - * for keeping a temporary list of wildcards at the end, if the "hold" - * argument is set. - */ -void -ign_add_file (file, hold) - char *file; - int hold; -{ - FILE *fp; - char *line = NULL; - size_t line_allocated = 0; - - /* restore the saved list (if any) */ - if (s_ign_list != NULL) - { - int i; - - for (i = 0; i < s_ign_count; i++) - ign_list[i] = s_ign_list[i]; - ign_count = s_ign_count; - ign_list[ign_count] = NULL; - - s_ign_count = 0; - free (s_ign_list); - s_ign_list = NULL; - } - - /* is this a temporary ignore file? */ - if (hold) - { - /* re-set if we had already done a temporary file */ - if (ign_hold >= 0) - { - int i; - - for (i = ign_hold; i < ign_count; i++) - free (ign_list[i]); - ign_count = ign_hold; - ign_list[ign_count] = NULL; - } - else - { - ign_hold = ign_count; - } - } - - /* load the file */ - fp = CVS_FOPEN (file, "r"); - if (fp == NULL) - { - if (! existence_error (errno)) - error (0, errno, "cannot open %s", file); - return; - } - while (getline (&line, &line_allocated, fp) >= 0) - ign_add (line, hold); - if (ferror (fp)) - error (0, errno, "cannot read %s", file); - if (fclose (fp) < 0) - error (0, errno, "cannot close %s", file); - free (line); -} - - - -/* Parse a line of space-separated wildcards and add them to the list. */ -void -ign_add (ign, hold) - char *ign; - int hold; -{ - if (!ign || !*ign) - return; - - for (; *ign; ign++) - { - char *mark; - char save; - - /* ignore whitespace before the token */ - if (isspace ((unsigned char) *ign)) - continue; - - /* If we have used up all the space, add some more. Do this before - processing `!', since an "empty" list still contains the `CVS' - entry. */ - if (ign_count >= ign_size) - { - ign_size += IGN_GROW; - ign_list = (char **) xrealloc ((char *) ign_list, - (ign_size + 1) * sizeof (char *)); - } - - /* - * if we find a single character !, we must re-set the ignore list - * (saving it if necessary). We also catch * as a special case in a - * global ignore file as an optimization - */ - if ((!*(ign+1) || isspace ((unsigned char) *(ign+1))) - && (*ign == '!' || *ign == '*')) - { - if (!hold) - { - /* permanently reset the ignore list */ - int i; - - for (i = 0; i < ign_count; i++) - free (ign_list[i]); - ign_count = 1; - /* Always ignore the "CVS" directory. */ - ign_list[0] = xstrdup("CVS"); - ign_list[1] = NULL; - - /* if we are doing a '!', continue; otherwise add the '*' */ - if (*ign == '!') - { - ign_inhibit_server = 1; - continue; - } - } - else if (*ign == '!') - { - /* temporarily reset the ignore list */ - int i; - - if (ign_hold >= 0) - { - for (i = ign_hold; i < ign_count; i++) - free (ign_list[i]); - ign_hold = -1; - } - if (s_ign_list) - { - /* Don't save the ignore list twice - if there are two - * bangs in a local .cvsignore file then we don't want to - * save the new list the first bang created. - * - * We still need to free the "new" ignore list. - */ - for (i = 0; i < ign_count; i++) - free (ign_list[i]); - } - else - { - /* Save the ignore list for later. */ - s_ign_list = xmalloc (ign_count * sizeof (char *)); - for (i = 0; i < ign_count; i++) - s_ign_list[i] = ign_list[i]; - s_ign_count = ign_count; - } - ign_count = 1; - /* Always ignore the "CVS" directory. */ - ign_list[0] = xstrdup ("CVS"); - ign_list[1] = NULL; - continue; - } - } - - /* find the end of this token */ - for (mark = ign; *mark && !isspace ((unsigned char) *mark); mark++) - /* do nothing */ ; - - save = *mark; - *mark = '\0'; - - ign_list[ign_count++] = xstrdup (ign); - ign_list[ign_count] = NULL; - - *mark = save; - if (save) - ign = mark; - else - ign = mark - 1; - } -} - - - -/* Return true if the given filename should be ignored by update or import, - * else return false. - */ -int -ign_name (name) - char *name; -{ - char **cpp = ign_list; - - if (cpp == NULL) - return 0; - - while (*cpp) - if (CVS_FNMATCH (*cpp++, name, 0) == 0) - return 1; - - return 0; -} - - - -/* FIXME: This list of dirs to ignore stuff seems not to be used. - Really? send_dirent_proc and update_dirent_proc both call - ignore_directory and do_module calls ign_dir_add. No doubt could - use some documentation/testsuite work. */ - -static char **dir_ign_list = NULL; -static int dir_ign_max = 0; -static int dir_ign_current = 0; - -/* Add a directory to list of dirs to ignore. */ -void -ign_dir_add (name) - char *name; -{ - /* Make sure we've got the space for the entry. */ - if (dir_ign_current <= dir_ign_max) - { - dir_ign_max += IGN_GROW; - dir_ign_list = - (char **) xrealloc (dir_ign_list, - (dir_ign_max + 1) * sizeof (char *)); - } - - dir_ign_list[dir_ign_current++] = xstrdup (name); -} - - -/* Return nonzero if NAME is part of the list of directories to ignore. */ - -int -ignore_directory (name) - const char *name; -{ - int i; - - if (!dir_ign_list) - return 0; - - i = dir_ign_current; - while (i--) - { - if (strncmp (name, dir_ign_list[i], strlen (dir_ign_list[i])+1) == 0) - return 1; - } - - return 0; -} - - - -/* - * Process the current directory, looking for files not in ILIST and - * not on the global ignore list for this directory. If we find one, - * call PROC passing it the name of the file and the update dir. - * ENTRIES is the entries list, which is used to identify known - * directories. ENTRIES may be NULL, in which case we assume that any - * directory with a CVS administration directory is known. - */ -void -ignore_files (ilist, entries, update_dir, proc) - List *ilist; - List *entries; - const char *update_dir; - Ignore_proc proc; -{ - int subdirs; - DIR *dirp; - struct dirent *dp; - struct stat sb; - char *file; - const char *xdir; - List *files; - Node *p; - - /* Set SUBDIRS if we have subdirectory information in ENTRIES. */ - if (entries == NULL) - subdirs = 0; - else - { - struct stickydirtag *sdtp = entries->list->data; - - subdirs = sdtp == NULL || sdtp->subdirs; - } - - /* we get called with update_dir set to "." sometimes... strip it */ - if (strcmp (update_dir, ".") == 0) - xdir = ""; - else - xdir = update_dir; - - dirp = CVS_OPENDIR ("."); - if (dirp == NULL) - { - error (0, errno, "cannot open current directory"); - return; - } - - ign_add_file (CVSDOTIGNORE, 1); - wrap_add_file (CVSDOTWRAPPER, 1); - - /* Make a list for the files. */ - files = getlist (); - - while (errno = 0, (dp = CVS_READDIR (dirp)) != NULL) - { - file = dp->d_name; - if (strcmp (file, ".") == 0 || strcmp (file, "..") == 0) - continue; - if (findnode_fn (ilist, file) != NULL) - continue; - if (subdirs) - { - Node *node; - - node = findnode_fn (entries, file); - if (node != NULL - && ((Entnode *) node->data)->type == ENT_SUBDIR) - { - char *p; - int dir; - - /* For consistency with past behaviour, we only ignore - this directory if there is a CVS subdirectory. - This will normally be the case, but the user may - have messed up the working directory somehow. */ - p = xmalloc (strlen (file) + sizeof CVSADM + 10); - sprintf (p, "%s/%s", file, CVSADM); - dir = isdir (p); - free (p); - if (dir) - continue; - } - } - - /* We could be ignoring FIFOs and other files which are neither - regular files nor directories here. */ - if (ign_name (file)) - continue; - - if ( -#ifdef DT_DIR - dp->d_type != DT_UNKNOWN || -#endif - CVS_LSTAT (file, &sb) != -1) - { - - if ( -#ifdef DT_DIR - dp->d_type == DT_DIR - || (dp->d_type == DT_UNKNOWN && S_ISDIR (sb.st_mode)) -#else - S_ISDIR (sb.st_mode) -#endif - ) - { - if (! subdirs) - { - char *temp; - - temp = xmalloc (strlen (file) + sizeof (CVSADM) + 10); - (void) sprintf (temp, "%s/%s", file, CVSADM); - if (isdir (temp)) - { - free (temp); - continue; - } - free (temp); - } - } -#ifdef S_ISLNK - else if ( -#ifdef DT_DIR - dp->d_type == DT_LNK - || (dp->d_type == DT_UNKNOWN && S_ISLNK(sb.st_mode)) -#else - S_ISLNK (sb.st_mode) -#endif - ) - { - continue; - } -#endif - } - - p = getnode (); - p->type = FILES; - p->key = xstrdup (file); - (void) addnode (files, p); - } - if (errno != 0) - error (0, errno, "error reading current directory"); - (void) CVS_CLOSEDIR (dirp); - - sortlist (files, fsortcmp); - for (p = files->list->next; p != files->list; p = p->next) - (*proc) (p->key, xdir); - dellist (&files); -} diff --git a/contrib/cvs/src/import.c b/contrib/cvs/src/import.c deleted file mode 100644 index bc918e0..0000000 --- a/contrib/cvs/src/import.c +++ /dev/null @@ -1,1653 +0,0 @@ -/* - * Copyright (C) 1986-2005 The Free Software Foundation, Inc. - * - * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot , - * and others. - * - * Portions Copyright (C) 1992, Brian Berliner and Jeff Polk - * Portions Copyright (C) 1989-1992, Brian Berliner - * - * You may distribute under the terms of the GNU General Public License as - * specified in the README file that comes with the CVS source distribution. - * - * "import" checks in the vendor release located in the current directory into - * the CVS source repository. The CVS vendor branch support is utilized. - * - * At least three arguments are expected to follow the options: - * repository Where the source belongs relative to the CVSROOT - * VendorTag Vendor's major tag - * VendorReleTag Tag for this particular release - * - * Additional arguments specify more Vendor Release Tags. - */ - -#include "cvs.h" -#include "savecwd.h" -#include - -static char *get_comment PROTO((const char *user)); -static int add_rev PROTO((char *message, RCSNode *rcs, char *vfile, - char *vers)); -static int add_tags PROTO((RCSNode *rcs, char *vfile, char *vtag, int targc, - char *targv[])); -static int import_descend PROTO((char *message, char *vtag, int targc, char *targv[])); -static int import_descend_dir PROTO((char *message, char *dir, char *vtag, - int targc, char *targv[])); -static int process_import_file PROTO((char *message, char *vfile, char *vtag, - int targc, char *targv[])); -static int update_rcs_file PROTO((char *message, char *vfile, char *vtag, int targc, - char *targv[], int inattic)); -static void add_log PROTO((int ch, char *fname)); - -static int repos_len; -static char *vhead; -static char *vbranch; -static FILE *logfp; -static char *repository; -static int conflicts; -static int use_file_modtime; -static char *keyword_opt = NULL; - -static const char *const import_usage[] = -{ - "Usage: %s %s [-d] [-k subst] [-I ign] [-m msg] [-b branch]\n", - " [-W spec] repository vendor-tag release-tags...\n", - "\t-d\tUse the file's modification time as the time of import.\n", - "\t-k sub\tSet default RCS keyword substitution mode.\n", - "\t-I ign\tMore files to ignore (! to reset).\n", - "\t-b bra\tVendor branch id.\n", - "\t-m msg\tLog message.\n", - "\t-W spec\tWrappers specification line.\n", - "(Specify the --help global option for a list of other help options)\n", - NULL -}; - -int -import (argc, argv) - int argc; - char **argv; -{ - char *message = NULL; - char *tmpfile; - char *cp; - int i, c, msglen, err; - List *ulist; - Node *p; - struct logfile_info *li; - - if (argc == -1) - usage (import_usage); - - ign_setup (); - wrap_setup (); - - vbranch = xstrdup (CVSBRANCH); - optind = 0; - while ((c = getopt (argc, argv, "+Qqdb:m:I:k:W:")) != -1) - { - switch (c) - { - case 'Q': - case 'q': - /* The CVS 1.5 client sends these options (in addition to - Global_option requests), so we must ignore them. */ - if (!server_active) - error (1, 0, - "-q or -Q must be specified before \"%s\"", - cvs_cmd_name); - break; - case 'd': - if (server_active) - { - /* CVS 1.10 and older clients will send this, but it - doesn't do any good. So tell the user we can't - cope, rather than silently losing. */ - error (0, 0, - "warning: not setting the time of import from the file"); - error (0, 0, "due to client limitations"); - } - use_file_modtime = 1; - break; - case 'b': - free (vbranch); - vbranch = xstrdup (optarg); - break; - case 'm': -#ifdef FORCE_USE_EDITOR - use_editor = 1; -#else - use_editor = 0; -#endif - if (message) free (message); - message = xstrdup(optarg); - break; - case 'I': - ign_add (optarg, 0); - break; - case 'k': - /* RCS_check_kflag returns strings of the form -kxx. We - only use it for validation, so we can free the value - as soon as it is returned. */ - free (RCS_check_kflag (optarg)); - keyword_opt = optarg; - break; - case 'W': - wrap_add (optarg, 0); - break; - case '?': - default: - usage (import_usage); - break; - } - } - argc -= optind; - argv += optind; - if (argc < 3) - usage (import_usage); - - /* This is for handling the Checkin-time request. It might seem a - bit odd to enable the use_file_modtime code even in the case - where Checkin-time was not sent for a particular file. The - effect is that we use the time of upload, rather than the time - when we call RCS_checkin. Since those times are both during - CVS's run, that seems OK, and it is easier to implement than - putting the "was Checkin-time sent" flag in CVS/Entries or some - such place. */ - - if (server_active) - use_file_modtime = 1; - - /* Don't allow "CVS" as any directory in module path. - * - * Could abstract this to valid_module_path, but I don't think we'll need - * to call it from anywhere else. - */ - /* for each "CVS" in path... */ - cp = argv[0]; - while ((cp = strstr(cp, "CVS")) != NULL) - { - if ( /* /^CVS/ OR m#/CVS#... */ - (cp == argv[0] || ISDIRSEP(*(cp-1))) - /* ...AND /CVS$/ OR m#CVS/# */ - && (*(cp+3) == '\0' || ISDIRSEP(*(cp+3))) - ) - { - error (0, 0, - "The word `CVS' is reserved by CVS and may not be used"); - error (1, 0, "as a directory in a path or as a file name."); - } - cp += 3; - } - - for (i = 1; i < argc; i++) /* check the tags for validity */ - { - int j; - - RCS_check_tag (argv[i]); - for (j = 1; j < i; j++) - if (strcmp (argv[j], argv[i]) == 0) - error (1, 0, "tag `%s' was specified more than once", argv[i]); - } - - /* XXX - this should be a module, not just a pathname */ - if (!isabsolute (argv[0]) && pathname_levels (argv[0]) == 0) - { - if (current_parsed_root == NULL) - { - error (0, 0, "missing CVSROOT environment variable\n"); - error (1, 0, "Set it or specify the '-d' option to %s.", - program_name); - } - repository = xmalloc (strlen (current_parsed_root->directory) - + strlen (argv[0]) - + 2); - (void) sprintf (repository, "%s/%s", current_parsed_root->directory, argv[0]); - repos_len = strlen (current_parsed_root->directory); - } - else - { - /* It is somewhere between a security hole and "unexpected" to - let the client start mucking around outside the cvsroot - (wouldn't get the right CVSROOT configuration, &c). */ - error (1, 0, "directory %s not relative within the repository", - argv[0]); - } - - /* - * Consistency checks on the specified vendor branch. It must be - * composed of only numbers and dots ('.'). Also, for now we only - * support branching to a single level, so the specified vendor branch - * must only have two dots in it (like "1.1.1"). - */ - { - regex_t pat; - int ret = regcomp (&pat, "^[1-9][0-9]*\\.[1-9][0-9]*\\.[1-9][0-9]*$", - REG_EXTENDED); - assert (!ret); - if (regexec (&pat, vbranch, 0, NULL, 0)) - { - error (1, 0, -"Only numeric branch specifications with two dots are\n" -"supported by import, not `%s'. For example: `1.1.1'.", - vbranch); - } - regfree (&pat); - } - - /* Set vhead to the branch's parent. */ - vhead = xstrdup (vbranch); - cp = strrchr (vhead, '.'); - *cp = '\0'; - -#ifdef CLIENT_SUPPORT - if (current_parsed_root->isremote) - { - /* For rationale behind calling start_server before do_editor, see - commit.c */ - start_server (); - } -#endif - - if (!server_active && use_editor) - { - do_editor ((char *) NULL, &message, - current_parsed_root->isremote ? (char *) NULL : repository, - (List *) NULL); - } - do_verify (&message, repository); - msglen = message == NULL ? 0 : strlen (message); - if (msglen == 0 || message[msglen - 1] != '\n') - { - char *nm = xmalloc (msglen + 2); - *nm = '\0'; - if (message != NULL) - { - (void) strcpy (nm, message); - free (message); - } - (void) strcat (nm + msglen, "\n"); - message = nm; - } - -#ifdef CLIENT_SUPPORT - if (current_parsed_root->isremote) - { - int err; - - if (vbranch[0] != '\0') - option_with_arg ("-b", vbranch); - option_with_arg ("-m", message ? message : ""); - if (keyword_opt != NULL) - option_with_arg ("-k", keyword_opt); - /* The only ignore processing which takes place on the server side - is the CVSROOT/cvsignore file. But if the user specified -I !, - the documented behavior is to not process said file. */ - if (ign_inhibit_server) - { - send_arg ("-I"); - send_arg ("!"); - } - wrap_send (); - - { - int i; - for (i = 0; i < argc; ++i) - send_arg (argv[i]); - } - - logfp = stdin; - 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 ( NULL )) - { - error (1, 0, "attempt to import the repository"); - } - - /* - * Make all newly created directories writable. Should really use a more - * sophisticated security mechanism here. - */ - (void) umask (cvsumask); - make_directories (repository); - - /* Create the logfile that will be logged upon completion */ - if ((logfp = cvs_temp_file (&tmpfile)) == NULL) - error (1, errno, "cannot create temporary file `%s'", - tmpfile ? tmpfile : "(null)"); - /* On systems where we can unlink an open file, do so, so it will go - away no matter how we exit. FIXME-maybe: Should be checking for - errors but I'm not sure which error(s) we get if we are on a system - where one can't unlink open files. */ - (void) CVS_UNLINK (tmpfile); - (void) fprintf (logfp, "\nVendor Tag:\t%s\n", argv[1]); - (void) fprintf (logfp, "Release Tags:\t"); - for (i = 2; i < argc; i++) - (void) fprintf (logfp, "%s\n\t\t", argv[i]); - (void) fprintf (logfp, "\n"); - - /* Just Do It. */ - err = import_descend (message, argv[1], argc - 2, argv + 2); - if (conflicts) - { - if (!really_quiet) - { - char buf[20]; - - cvs_output_tagged ("+importmergecmd", NULL); - cvs_output_tagged ("newline", NULL); - sprintf (buf, "%d", conflicts); - cvs_output_tagged ("conflicts", buf); - cvs_output_tagged ("text", " conflicts created by this import."); - cvs_output_tagged ("newline", NULL); - cvs_output_tagged ("text", - "Use the following command to help the merge:"); - cvs_output_tagged ("newline", NULL); - cvs_output_tagged ("newline", NULL); - cvs_output_tagged ("text", "\t"); - cvs_output_tagged ("text", program_name); - if (CVSroot_cmdline != NULL) - { - cvs_output_tagged ("text", " -d "); - cvs_output_tagged ("text", CVSroot_cmdline); - } - cvs_output_tagged ("text", " checkout -j"); - cvs_output_tagged ("mergetag1", ""); - cvs_output_tagged ("text", " -j"); - cvs_output_tagged ("mergetag2", argv[2]); - cvs_output_tagged ("text", " "); - cvs_output_tagged ("repository", argv[0]); - cvs_output_tagged ("newline", NULL); - cvs_output_tagged ("newline", NULL); - cvs_output_tagged ("-importmergecmd", NULL); - } - - /* FIXME: I'm not sure whether we need to put this information - into the loginfo. If we do, then note that it does not - report any required -d option. There is no particularly - clean way to tell the server about the -d option used by - the client. */ - (void) fprintf (logfp, "\n%d conflicts created by this import.\n", - conflicts); - (void) fprintf (logfp, - "Use the following command to help the merge:\n\n"); - (void) fprintf (logfp, "\t%s checkout ", program_name); - (void) fprintf (logfp, "-j%s:yesterday -j%s %s\n\n", - argv[1], argv[1], argv[0]); - } - else - { - if (!really_quiet) - cvs_output ("\nNo conflicts created by this import\n\n", 0); - (void) fprintf (logfp, "\nNo conflicts created by this import\n\n"); - } - - /* - * Write out the logfile and clean up. - */ - ulist = getlist (); - p = getnode (); - p->type = UPDATE; - p->delproc = update_delproc; - p->key = xstrdup ("- Imported sources"); - li = (struct logfile_info *) xmalloc (sizeof (struct logfile_info)); - li->type = T_TITLE; - li->tag = xstrdup (vbranch); - li->rev_old = li->rev_new = NULL; - p->data = li; - (void) addnode (ulist, p); - Update_Logfile (repository, message, logfp, ulist); - dellist (&ulist); - if (fclose (logfp) < 0) - error (0, errno, "error closing %s", tmpfile); - - /* Make sure the temporary file goes away, even on systems that don't let - you delete a file that's in use. */ - if (CVS_UNLINK (tmpfile) < 0 && !existence_error (errno)) - error (0, errno, "cannot remove %s", tmpfile); - free (tmpfile); - - if (message) - free (message); - free (repository); - free (vbranch); - free (vhead); - - return (err); -} - -/* Process all the files in ".", then descend into other directories. - Returns 0 for success, or >0 on error (in which case a message - will have been printed). */ -static int -import_descend (message, vtag, targc, targv) - char *message; - char *vtag; - int targc; - char *targv[]; -{ - DIR *dirp; - struct dirent *dp; - int err = 0; - List *dirlist = NULL; - - /* first, load up any per-directory ignore lists */ - ign_add_file (CVSDOTIGNORE, 1); - wrap_add_file (CVSDOTWRAPPER, 1); - - if (!current_parsed_root->isremote) - lock_dir_for_write (repository); - - if ((dirp = CVS_OPENDIR (".")) == NULL) - { - error (0, errno, "cannot open directory"); - err++; - } - else - { - errno = 0; - while ((dp = CVS_READDIR (dirp)) != NULL) - { - if (strcmp (dp->d_name, ".") == 0 || strcmp (dp->d_name, "..") == 0) - goto one_more_time_boys; - - /* CVS directories are created in the temp directory by - server.c because it doesn't special-case import. So - don't print a message about them, regardless of -I!. */ - if (server_active && strcmp (dp->d_name, CVSADM) == 0) - goto one_more_time_boys; - - if (ign_name (dp->d_name)) - { - add_log ('I', dp->d_name); - goto one_more_time_boys; - } - - if ( -#ifdef DT_DIR - (dp->d_type == DT_DIR - || (dp->d_type == DT_UNKNOWN && isdir (dp->d_name))) -#else - isdir (dp->d_name) -#endif - && !wrap_name_has (dp->d_name, WRAP_TOCVS) - ) - { - Node *n; - - if (dirlist == NULL) - dirlist = getlist(); - - n = getnode(); - n->key = xstrdup (dp->d_name); - addnode(dirlist, n); - } - else if ( -#ifdef DT_DIR - dp->d_type == DT_LNK - || (dp->d_type == DT_UNKNOWN && islink (dp->d_name)) -#else - islink (dp->d_name) -#endif - ) - { - add_log ('L', dp->d_name); - err++; - } - else - { -#ifdef CLIENT_SUPPORT - if (current_parsed_root->isremote) - err += client_process_import_file (message, dp->d_name, - vtag, targc, targv, - repository, - keyword_opt != NULL && - keyword_opt[0] == 'b', - use_file_modtime); - else -#endif - err += process_import_file (message, dp->d_name, - vtag, targc, targv); - } - one_more_time_boys: - errno = 0; - } - if (errno != 0) - { - error (0, errno, "cannot read directory"); - ++err; - } - (void) CVS_CLOSEDIR (dirp); - } - - if (!current_parsed_root->isremote) - Lock_Cleanup (); - - if (dirlist != NULL) - { - Node *head, *p; - - head = dirlist->list; - for (p = head->next; p != head; p = p->next) - { - err += import_descend_dir (message, p->key, vtag, targc, targv); - } - - dellist(&dirlist); - } - - return (err); -} - -/* - * Process the argument import file. - */ -static int -process_import_file (message, vfile, vtag, targc, targv) - char *message; - char *vfile; - char *vtag; - int targc; - char *targv[]; -{ - char *rcs; - int inattic = 0; - - rcs = xmalloc (strlen (repository) + strlen (vfile) + sizeof (RCSEXT) - + 5); - (void) sprintf (rcs, "%s/%s%s", repository, vfile, RCSEXT); - if (!isfile (rcs)) - { - char *attic_name; - - attic_name = xmalloc (strlen (repository) + strlen (vfile) + - sizeof (CVSATTIC) + sizeof (RCSEXT) + 10); - (void) sprintf (attic_name, "%s/%s/%s%s", repository, CVSATTIC, - vfile, RCSEXT); - if (!isfile (attic_name)) - { - int retval; - char *free_opt = NULL; - char *our_opt = keyword_opt; - - free (attic_name); - /* - * A new import source file; it doesn't exist as a ,v within the - * repository nor in the Attic -- create it anew. - */ - add_log ('N', vfile); - -#ifdef SERVER_SUPPORT - /* The most reliable information on whether the file is binary - is what the client told us. That is because if the client had - the wrong idea about binaryness, it corrupted the file, so - we might as well believe the client. */ - if (server_active) - { - Node *node; - List *entries; - - /* Reading all the entries for each file is fairly silly, and - probably slow. But I am too lazy at the moment to do - anything else. */ - entries = Entries_Open (0, NULL); - node = findnode_fn (entries, vfile); - if (node != NULL) - { - Entnode *entdata = node->data; - - if (entdata->type == ENT_FILE) - { - assert (entdata->options[0] == '-' - && entdata->options[1] == 'k'); - our_opt = xstrdup (entdata->options + 2); - free_opt = our_opt; - } - } - Entries_Close (entries); - } -#endif - - retval = add_rcs_file (message, rcs, vfile, vhead, our_opt, - vbranch, vtag, targc, targv, - NULL, 0, logfp); - if (free_opt != NULL) - free (free_opt); - free (rcs); - return retval; - } - free (attic_name); - inattic = 1; - } - - free (rcs); - /* - * an rcs file exists. have to do things the official, slow, way. - */ - return (update_rcs_file (message, vfile, vtag, targc, targv, inattic)); -} - -/* - * The RCS file exists; update it by adding the new import file to the - * (possibly already existing) vendor branch. - */ -static int -update_rcs_file (message, vfile, vtag, targc, targv, inattic) - char *message; - char *vfile; - char *vtag; - int targc; - char *targv[]; - int inattic; -{ - Vers_TS *vers; - int letter; - char *tocvsPath; - char *expand; - struct file_info finfo; - - memset (&finfo, 0, sizeof finfo); - finfo.file = vfile; - /* Not used, so don't worry about it. */ - finfo.update_dir = NULL; - finfo.fullname = finfo.file; - finfo.repository = repository; - finfo.entries = NULL; - finfo.rcs = NULL; - vers = Version_TS (&finfo, (char *) NULL, vbranch, (char *) NULL, - 1, 0); - if (vers->vn_rcs != NULL - && !RCS_isdead(vers->srcfile, vers->vn_rcs)) - { - int different; - - /* - * The rcs file does have a revision on the vendor branch. Compare - * this revision with the import file; if they match exactly, there - * is no need to install the new import file as a new revision to the - * branch. Just tag the revision with the new import tags. - * - * This is to try to cut down the number of "C" conflict messages for - * locally modified import source files. - */ - tocvsPath = wrap_tocvs_process_file (vfile); - /* FIXME: Why don't we pass tocvsPath to RCS_cmp_file if it is - not NULL? */ - expand = vers->srcfile->expand != NULL && - vers->srcfile->expand[0] == 'b' ? "-kb" : "-ko"; - different = RCS_cmp_file( vers->srcfile, vers->vn_rcs, (char **)NULL, - (char *)NULL, expand, vfile ); - if (tocvsPath) - if (unlink_file_dir (tocvsPath) < 0) - error (0, errno, "cannot remove %s", tocvsPath); - - if (!different) - { - int retval = 0; - - /* - * The two files are identical. Just update the tags, print the - * "U", signifying that the file has changed, but needs no - * attention, and we're done. - */ - if (add_tags (vers->srcfile, vfile, vtag, targc, targv)) - retval = 1; - add_log ('U', vfile); - freevers_ts (&vers); - return (retval); - } - } - - /* We may have failed to parse the RCS file; check just in case */ - if (vers->srcfile == NULL || - add_rev (message, vers->srcfile, vfile, vers->vn_rcs) || - add_tags (vers->srcfile, vfile, vtag, targc, targv)) - { - freevers_ts (&vers); - return (1); - } - - if (vers->srcfile->branch == NULL || inattic || - strcmp (vers->srcfile->branch, vbranch) != 0) - { - conflicts++; - letter = 'C'; - } - else - letter = 'U'; - add_log (letter, vfile); - - freevers_ts (&vers); - return (0); -} - -/* - * Add the revision to the vendor branch - */ -static int -add_rev (message, rcs, vfile, vers) - char *message; - RCSNode *rcs; - char *vfile; - char *vers; -{ - int locked, status, ierrno; - char *tocvsPath; - - if (noexec) - return (0); - - locked = 0; - if (vers != NULL) - { - /* Before RCS_lock existed, we were directing stdout, as well as - stderr, from the RCS command, to DEVNULL. I wouldn't guess that - was necessary, but I don't know for sure. */ - /* Earlier versions of this function printed a `fork failed' error - when RCS_lock returned an error code. That's not appropriate - now that RCS_lock is librarified, but should the error text be - preserved? */ - if (RCS_lock (rcs, vbranch, 1) != 0) - return 1; - locked = 1; - RCS_rewrite (rcs, NULL, NULL); - } - tocvsPath = wrap_tocvs_process_file (vfile); - - status = RCS_checkin (rcs, tocvsPath == NULL ? vfile : tocvsPath, - message, vbranch, 0, - (RCS_FLAGS_QUIET | RCS_FLAGS_KEEPFILE - | (use_file_modtime ? RCS_FLAGS_MODTIME : 0))); - ierrno = errno; - - if ((tocvsPath != NULL) && (unlink_file_dir (tocvsPath) < 0)) - error (0, errno, "cannot remove %s", tocvsPath); - - if (status) - { - if (!noexec) - { - 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); - } - if (locked) - { - (void) RCS_unlock(rcs, vbranch, 0); - RCS_rewrite (rcs, NULL, NULL); - } - return (1); - } - return (0); -} - -/* - * Add the vendor branch tag and all the specified import release tags to the - * RCS file. The vendor branch tag goes on the branch root (1.1.1) while the - * vendor release tags go on the newly added leaf of the branch (1.1.1.1, - * 1.1.1.2, ...). - */ -static int -add_tags (rcs, vfile, vtag, targc, targv) - RCSNode *rcs; - char *vfile; - char *vtag; - int targc; - char *targv[]; -{ - int i, ierrno; - Vers_TS *vers; - int retcode = 0; - struct file_info finfo; - - if (noexec) - return (0); - - if ((retcode = RCS_settag(rcs, vtag, vbranch)) != 0) - { - ierrno = errno; - 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); - } - RCS_rewrite (rcs, NULL, NULL); - - memset (&finfo, 0, sizeof finfo); - finfo.file = vfile; - /* Not used, so don't worry about it. */ - finfo.update_dir = NULL; - finfo.fullname = finfo.file; - finfo.repository = repository; - finfo.entries = NULL; - finfo.rcs = NULL; - vers = Version_TS (&finfo, NULL, vtag, NULL, 1, 0); - for (i = 0; i < targc; i++) - { - if ((retcode = RCS_settag (rcs, targv[i], vers->vn_rcs)) == 0) - RCS_rewrite (rcs, NULL, NULL); - else - { - ierrno = errno; - 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); - } - } - freevers_ts (&vers); - return (0); -} - -/* - * Stolen from rcs/src/rcsfnms.c, and adapted/extended. - */ -struct compair -{ - char *suffix, *comlead; -}; - -static const struct compair comtable[] = -{ - -/* - * comtable pairs each filename suffix with a comment leader. The comment - * leader is placed before each line generated by the $Log keyword. This - * table is used to guess the proper comment leader from the working file's - * suffix during initial ci (see InitAdmin()). Comment leaders are needed for - * languages without multiline comments; for others they are optional. - * - * I believe that the comment leader is unused if you are using RCS 5.7, which - * decides what leader to use based on the text surrounding the $Log keyword - * rather than a specified comment leader. - */ - {"a", "-- "}, /* Ada */ - {"ada", "-- "}, - {"adb", "-- "}, - {"asm", ";; "}, /* assembler (MS-DOS) */ - {"ads", "-- "}, /* Ada */ - {"bas", "' "}, /* Visual Basic code */ - {"bat", ":: "}, /* batch (MS-DOS) */ - {"body", "-- "}, /* Ada */ - {"c", " * "}, /* C */ - {"c++", "// "}, /* C++ in all its infinite guises */ - {"cc", "// "}, - {"cpp", "// "}, - {"cxx", "// "}, - {"m", "// "}, /* Objective-C */ - {"cl", ";;; "}, /* Common Lisp */ - {"cmd", ":: "}, /* command (OS/2) */ - {"cmf", "c "}, /* CM Fortran */ - {"cs", " * "}, /* C* */ - {"csh", "# "}, /* shell */ - {"dlg", " * "}, /* MS Windows dialog file */ - {"e", "# "}, /* efl */ - {"epsf", "% "}, /* encapsulated postscript */ - {"epsi", "% "}, /* encapsulated postscript */ - {"el", "; "}, /* Emacs Lisp */ - {"f", "c "}, /* Fortran */ - {"for", "c "}, - {"frm", "' "}, /* Visual Basic form */ - {"h", " * "}, /* C-header */ - {"hh", "// "}, /* C++ header */ - {"hpp", "// "}, - {"hxx", "// "}, - {"in", "# "}, /* for Makefile.in */ - {"l", " * "}, /* lex (conflict between lex and - * franzlisp) */ - {"mac", ";; "}, /* macro (DEC-10, MS-DOS, PDP-11, - * VMS, etc) */ - {"mak", "# "}, /* makefile, e.g. Visual C++ */ - {"me", ".\\\" "}, /* me-macros t/nroff */ - {"ml", "; "}, /* mocklisp */ - {"mm", ".\\\" "}, /* mm-macros t/nroff */ - {"ms", ".\\\" "}, /* ms-macros t/nroff */ - {"man", ".\\\" "}, /* man-macros t/nroff */ - {"1", ".\\\" "}, /* feeble attempt at man pages... */ - {"2", ".\\\" "}, - {"3", ".\\\" "}, - {"4", ".\\\" "}, - {"5", ".\\\" "}, - {"6", ".\\\" "}, - {"7", ".\\\" "}, - {"8", ".\\\" "}, - {"9", ".\\\" "}, - {"p", " * "}, /* pascal */ - {"pas", " * "}, - {"pl", "# "}, /* perl (conflict with Prolog) */ - {"ps", "% "}, /* postscript */ - {"psw", "% "}, /* postscript wrap */ - {"pswm", "% "}, /* postscript wrap */ - {"r", "# "}, /* ratfor */ - {"rc", " * "}, /* Microsoft Windows resource file */ - {"red", "% "}, /* psl/rlisp */ -#ifdef sparc - {"s", "! "}, /* assembler */ -#endif -#ifdef mc68000 - {"s", "| "}, /* assembler */ -#endif -#ifdef pdp11 - {"s", "/ "}, /* assembler */ -#endif -#ifdef vax - {"s", "# "}, /* assembler */ -#endif -#ifdef __ksr__ - {"s", "# "}, /* assembler */ - {"S", "# "}, /* Macro assembler */ -#endif - {"sh", "# "}, /* shell */ - {"sl", "% "}, /* psl */ - {"spec", "-- "}, /* Ada */ - {"tex", "% "}, /* tex */ - {"y", " * "}, /* yacc */ - {"ye", " * "}, /* yacc-efl */ - {"yr", " * "}, /* yacc-ratfor */ - {"", "# "}, /* default for empty suffix */ - {NULL, "# "} /* default for unknown suffix; */ -/* must always be last */ -}; - -static char * -get_comment (user) - const char *user; -{ - char *cp, *suffix; - char *suffix_path; - int i; - char *retval; - - suffix_path = xmalloc (strlen (user) + 5); - cp = strrchr (user, '.'); - if (cp != NULL) - { - cp++; - - /* - * Convert to lower-case, since we are not concerned about the - * case-ness of the suffix. - */ - (void) strcpy (suffix_path, cp); - for (cp = suffix_path; *cp; cp++) - if (isupper ((unsigned char) *cp)) - *cp = tolower (*cp); - suffix = suffix_path; - } - else - suffix = ""; /* will use the default */ - for (i = 0;; i++) - { - if (comtable[i].suffix == NULL) - { - /* Default. Note we'll always hit this case before we - ever return NULL. */ - retval = comtable[i].comlead; - break; - } - if (strcmp (suffix, comtable[i].suffix) == 0) - { - retval = comtable[i].comlead; - break; - } - } - free (suffix_path); - return retval; -} - -/* Create a new RCS file from scratch. - - This probably should be moved to rcs.c now that it is called from - places outside import.c. - - Return value is 0 for success, or nonzero for failure (in which - case an error message will have already been printed). */ -int -add_rcs_file (message, rcs, user, add_vhead, key_opt, - add_vbranch, vtag, targc, targv, - desctext, desclen, add_logfp) - /* Log message for the addition. Not used if add_vhead == NULL. */ - const char *message; - /* Filename of the RCS file to create. */ - const char *rcs; - /* Filename of the file to serve as the contents of the initial - revision. Even if add_vhead is NULL, we use this to determine - the modes to give the new RCS file. */ - const char *user; - - /* Revision number of head that we are adding. Normally 1.1 but - could be another revision as long as ADD_VBRANCH is a branch - from it. If NULL, then just add an empty file without any - revisions (similar to the one created by "rcs -i"). */ - const char *add_vhead; - - /* Keyword expansion mode, e.g., "b" for binary. NULL means the - default behavior. */ - const char *key_opt; - - /* Vendor branch to import to, or NULL if none. If non-NULL, then - vtag should also be non-NULL. */ - const char *add_vbranch; - const char *vtag; - int targc; - char *targv[]; - - /* If non-NULL, description for the file. If NULL, the description - will be empty. */ - const char *desctext; - size_t desclen; - - /* Write errors to here as well as via error (), or NULL if we should - use only error (). */ - FILE *add_logfp; -{ - FILE *fprcs, *fpuser; - struct stat sb; - struct tm *ftm; - time_t now; - char altdate1[MAXDATELEN]; - char *author; - int i, ierrno, err = 0; - mode_t mode; - char *tocvsPath; - const char *userfile; - char *free_opt = NULL; - mode_t file_type; - - if (noexec) - return (0); - - /* Note that as the code stands now, the -k option overrides any - settings in wrappers (whether CVSROOT/cvswrappers, -W, or - whatever). Some have suggested this should be the other way - around. As far as I know the documentation doesn't say one way - or the other. Before making a change of this sort, should think - about what is best, document it (in cvs.texinfo and NEWS), &c. */ - - if (key_opt == NULL) - { - if (wrap_name_has (user, WRAP_RCSOPTION)) - { - key_opt = free_opt = wrap_rcsoption (user, 0); - } - } - - tocvsPath = wrap_tocvs_process_file (user); - userfile = (tocvsPath == NULL ? user : tocvsPath); - - /* Opening in text mode is probably never the right thing for the - server (because the protocol encodes text files in a fashion - which does not depend on what the client or server OS is, as - documented in cvsclient.texi), but as long as the server just - runs on unix it is a moot point. */ - - /* If PreservePermissions is set, then make sure that the file - is a plain file before trying to open it. Longstanding (although - often unpopular) CVS behavior has been to follow symlinks, so we - maintain that behavior if PreservePermissions is not on. - - NOTE: this error message used to be `cannot fstat', but is now - `cannot lstat'. I don't see a way around this, since we must - stat the file before opening it. -twp */ - - if (CVS_LSTAT (userfile, &sb) < 0) - { - /* 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; - if (!preserve_perms || file_type == S_IFREG) - { - fpuser = CVS_FOPEN (userfile, - ((key_opt != NULL && strcmp (key_opt, "b") == 0) - ? "rb" - : "r") - ); - if (fpuser == NULL) - { - /* not fatal, continue import */ - if (add_logfp != NULL) - fperrmsg (add_logfp, 0, errno, - "ERROR: cannot read file %s", userfile); - error (0, errno, "ERROR: cannot read file %s", userfile); - goto read_error; - } - } - - fprcs = CVS_FOPEN (rcs, "w+b"); - if (fprcs == NULL) - { - ierrno = errno; - goto write_error_noclose; - } - - /* - * putadmin() - */ - if (add_vhead != NULL) - { - if (fprintf (fprcs, "head %s;\012", add_vhead) < 0) - goto write_error; - } - else - { - if (fprintf (fprcs, "head ;\012") < 0) - goto write_error; - } - - if (add_vbranch != NULL) - { - if (fprintf (fprcs, "branch %s;\012", add_vbranch) < 0) - goto write_error; - } - if (fprintf (fprcs, "access ;\012") < 0 || - fprintf (fprcs, "symbols ") < 0) - { - goto write_error; - } - - for (i = targc - 1; i >= 0; i--) - { - /* RCS writes the symbols backwards */ - assert (add_vbranch != NULL); - if (fprintf (fprcs, "%s:%s.1 ", targv[i], add_vbranch) < 0) - goto write_error; - } - - if (add_vbranch != NULL) - { - if (fprintf (fprcs, "%s:%s", vtag, add_vbranch) < 0) - goto write_error; - } - if (fprintf (fprcs, ";\012") < 0) - goto write_error; - - if (fprintf (fprcs, "locks ; strict;\012") < 0 || - /* XXX - make sure @@ processing works in the RCS file */ - fprintf (fprcs, "comment @%s@;\012", get_comment (user)) < 0) - { - goto write_error; - } - - if (key_opt != NULL && strcmp (key_opt, "kv") != 0) - { - if (fprintf (fprcs, "expand @%s@;\012", key_opt) < 0) - { - goto write_error; - } - } - - if (fprintf (fprcs, "\012") < 0) - goto write_error; - - /* Write the revision(s), with the date and author and so on - (that is "delta" rather than "deltatext" from rcsfile(5)). */ - if (add_vhead != NULL) - { - if (use_file_modtime) - now = sb.st_mtime; - else - (void) time (&now); - ftm = gmtime (&now); - (void) sprintf (altdate1, DATEFORM, - ftm->tm_year + (ftm->tm_year < 100 ? 0 : 1900), - ftm->tm_mon + 1, ftm->tm_mday, ftm->tm_hour, - ftm->tm_min, ftm->tm_sec); - author = getcaller (); - - if (fprintf (fprcs, "\012%s\012", add_vhead) < 0 || - fprintf (fprcs, "date %s; author %s; state Exp;\012", - altdate1, author) < 0) - goto write_error; - - if (fprintf (fprcs, "branches") < 0) - goto write_error; - if (add_vbranch != NULL) - { - if (fprintf (fprcs, " %s.1", add_vbranch) < 0) - goto write_error; - } - if (fprintf (fprcs, ";\012") < 0) - goto write_error; - - if (fprintf (fprcs, "next ;\012") < 0) - goto write_error; - -#ifdef PRESERVE_PERMISSIONS_SUPPORT - /* Store initial permissions if necessary. */ - if (preserve_perms) - { - if (file_type == S_IFLNK) - { - char *link = xreadlink (userfile); - if (fprintf (fprcs, "symlink\t@") < 0 || - expand_at_signs (link, strlen (link), fprcs) < 0 || - fprintf (fprcs, "@;\012") < 0) - goto write_error; - free (link); - } - else - { - if (fprintf (fprcs, "owner\t%u;\012", sb.st_uid) < 0) - goto write_error; - if (fprintf (fprcs, "group\t%u;\012", sb.st_gid) < 0) - goto write_error; - if (fprintf (fprcs, "permissions\t%o;\012", - sb.st_mode & 07777) < 0) - goto write_error; - switch (file_type) - { - case S_IFREG: break; - case S_IFCHR: - case S_IFBLK: -#ifdef HAVE_STRUCT_STAT_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, - "can't import %s: unknown kind of special file", - userfile); - } - } - } -#endif - - if (add_vbranch != NULL) - { - if (fprintf (fprcs, "\012%s.1\012", add_vbranch) < 0 || - fprintf (fprcs, "date %s; author %s; state Exp;\012", - altdate1, author) < 0 || - fprintf (fprcs, "branches ;\012") < 0 || - fprintf (fprcs, "next ;\012") < 0) - goto write_error; - -#ifdef PRESERVE_PERMISSIONS_SUPPORT - /* Store initial permissions if necessary. */ - if (preserve_perms) - { - if (file_type == S_IFLNK) - { - char *link = xreadlink (userfile); - if (fprintf (fprcs, "symlink\t@") < 0 || - expand_at_signs (link, strlen (link), fprcs) < 0 || - fprintf (fprcs, "@;\012") < 0) - goto write_error; - free (link); - } - else - { - if (fprintf (fprcs, "owner\t%u;\012", sb.st_uid) < 0 || - fprintf (fprcs, "group\t%u;\012", sb.st_gid) < 0 || - fprintf (fprcs, "permissions\t%o;\012", - sb.st_mode & 07777) < 0) - goto write_error; - - switch (file_type) - { - case S_IFREG: break; - case S_IFCHR: - case S_IFBLK: -#ifdef HAVE_STRUCT_STAT_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, - "cannot import %s: special file of unknown type", - userfile); - } - } - } -#endif - - if (fprintf (fprcs, "\012") < 0) - goto write_error; - } - } - - /* Now write the description (possibly empty). */ - if (fprintf (fprcs, "\012desc\012") < 0 || - fprintf (fprcs, "@") < 0) - goto write_error; - if (desctext != NULL) - { - /* The use of off_t not size_t for the second argument is very - strange, since we are dealing with something which definitely - fits in memory. */ - if (expand_at_signs (desctext, (off_t) desclen, fprcs) < 0) - goto write_error; - } - if (fprintf (fprcs, "@\012\012\012") < 0) - goto write_error; - - /* Now write the log messages and contents for the revision(s) (that - is, "deltatext" rather than "delta" from rcsfile(5)). */ - if (add_vhead != NULL) - { - if (fprintf (fprcs, "\012%s\012", add_vhead) < 0 || - fprintf (fprcs, "log\012@") < 0) - goto write_error; - if (add_vbranch != NULL) - { - /* We are going to put the log message in the revision on the - branch. So putting it here too seems kind of redundant, I - guess (and that is what CVS has always done, anyway). */ - if (fprintf (fprcs, "Initial revision\012") < 0) - goto write_error; - } - else - { - if (expand_at_signs (message, (off_t) strlen (message), fprcs) < 0) - goto write_error; - } - if (fprintf (fprcs, "@\012") < 0 || - fprintf (fprcs, "text\012@") < 0) - { - goto write_error; - } - - /* Now copy over the contents of the file, expanding at signs. - If preserve_perms is set, do this only for regular files. */ - if (!preserve_perms || file_type == S_IFREG) - { - char buf[8192]; - unsigned int len; - - while (1) - { - len = fread (buf, 1, sizeof buf, fpuser); - if (len == 0) - { - if (ferror (fpuser)) - error (1, errno, "cannot read file %s for copying", - user); - break; - } - if (expand_at_signs (buf, len, fprcs) < 0) - goto write_error; - } - } - if (fprintf (fprcs, "@\012\012") < 0) - goto write_error; - if (add_vbranch != NULL) - { - if (fprintf (fprcs, "\012%s.1\012", add_vbranch) < 0 || - fprintf (fprcs, "log\012@") < 0 || - expand_at_signs (message, - (off_t) strlen (message), fprcs) < 0 || - fprintf (fprcs, "@\012text\012") < 0 || - fprintf (fprcs, "@@\012") < 0) - goto write_error; - } - } - - if (fclose (fprcs) == EOF) - { - ierrno = errno; - goto write_error_noclose; - } - /* Close fpuser only if we opened it to begin with. */ - if (fpuser != NULL) - { - if (fclose (fpuser) < 0) - error (0, errno, "cannot close %s", user); - } - - /* - * Fix the modes on the RCS files. The user modes of the original - * user file are propagated to the group and other modes as allowed - * by the repository umask, except that all write permissions are - * turned off. - */ - mode = (sb.st_mode | - (sb.st_mode & S_IRWXU) >> 3 | - (sb.st_mode & S_IRWXU) >> 6) & - ~cvsumask & - ~(S_IWRITE | S_IWGRP | S_IWOTH); - if (chmod (rcs, mode) < 0) - { - ierrno = errno; - if (add_logfp != NULL) - 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++; - } - if (tocvsPath) - if (unlink_file_dir (tocvsPath) < 0) - error (0, errno, "cannot remove %s", tocvsPath); - if (free_opt != NULL) - free (free_opt); - return (err); - -write_error: - ierrno = errno; - if (fclose (fprcs) < 0) - error (0, errno, "cannot close %s", rcs); -write_error_noclose: - if (fclose (fpuser) < 0) - error (0, errno, "cannot close %s", user); - if (add_logfp != NULL) - 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) - fperrmsg (add_logfp, 0, 0, "ERROR: out of space - aborting"); - error (1, 0, "ERROR: out of space - aborting"); - } -read_error: - if (tocvsPath) - if (unlink_file_dir (tocvsPath) < 0) - error (0, errno, "cannot remove %s", tocvsPath); - - if (free_opt != NULL) - free (free_opt); - - return (err + 1); -} - -/* - * Write SIZE bytes at BUF to FP, expanding @ signs into double @ - * signs. If an error occurs, return a negative value and set errno - * to indicate the error. If not, return a nonnegative value. - */ -int -expand_at_signs (buf, size, fp) - const char *buf; - off_t size; - FILE *fp; -{ - register const char *cp, *next; - - cp = buf; - while ((next = memchr (cp, '@', size)) != NULL) - { - size_t len = ++next - cp; - if (fwrite (cp, 1, len, fp) != len) - return EOF; - if (putc ('@', fp) == EOF) - return EOF; - cp = next; - size -= len; - } - - if (fwrite (cp, 1, size, fp) != size) - return EOF; - - return 1; -} - -/* - * Write an update message to (potentially) the screen and the log file. - */ -static void -add_log (ch, fname) - int ch; - char *fname; -{ - if (!really_quiet) /* write to terminal */ - { - char buf[2]; - buf[0] = ch; - buf[1] = ' '; - cvs_output (buf, 2); - if (repos_len) - { - cvs_output (repository + repos_len + 1, 0); - cvs_output ("/", 1); - } - else if (repository[0] != '\0') - { - cvs_output (repository, 0); - cvs_output ("/", 1); - } - cvs_output (fname, 0); - cvs_output ("\n", 1); - } - - if (repos_len) /* write to logfile */ - (void) fprintf (logfp, "%c %s/%s\n", ch, - repository + repos_len + 1, fname); - else if (repository[0]) - (void) fprintf (logfp, "%c %s/%s\n", ch, repository, fname); - else - (void) fprintf (logfp, "%c %s\n", ch, fname); -} - -/* - * This is the recursive function that walks the argument directory looking - * for sub-directories that have CVS administration files in them and updates - * them recursively. - * - * Note that we do not follow symbolic links here, which is a feature! - */ -static int -import_descend_dir (message, dir, vtag, targc, targv) - char *message; - char *dir; - char *vtag; - int targc; - char *targv[]; -{ - struct saved_cwd cwd; - char *cp; - int ierrno, err; - char *rcs = NULL; - - if (islink (dir)) - return (0); - if (save_cwd (&cwd)) - { - fperrmsg (logfp, 0, 0, "ERROR: cannot get working directory"); - return (1); - } - - /* Concatenate DIR to the end of REPOSITORY. */ - if (repository[0] == '\0') - { - char *new = xstrdup (dir); - free (repository); - repository = new; - } - else - { - char *new = xmalloc (strlen (repository) + strlen (dir) + 10); - strcpy (new, repository); - (void) strcat (new, "/"); - (void) strcat (new, dir); - free (repository); - repository = new; - } - - if (!quiet && !current_parsed_root->isremote) - error (0, 0, "Importing %s", repository); - - if ( CVS_CHDIR (dir) < 0) - { - ierrno = errno; - fperrmsg (logfp, 0, ierrno, "ERROR: cannot chdir to %s", dir); - error (0, ierrno, "ERROR: cannot chdir to %s", dir); - err = 1; - goto out; - } - if (!current_parsed_root->isremote && !isdir (repository)) - { - rcs = xmalloc (strlen (repository) + sizeof (RCSEXT) + 5); - (void) sprintf (rcs, "%s%s", repository, RCSEXT); - if (isfile (repository) || isfile(rcs)) - { - 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; - goto out; - } - if (noexec == 0 && CVS_MKDIR (repository, 0777) < 0) - { - ierrno = errno; - fperrmsg (logfp, 0, ierrno, - "ERROR: cannot mkdir %s -- not added", repository); - error (0, ierrno, - "ERROR: cannot mkdir %s -- not added", repository); - err = 1; - goto out; - } - } - err = import_descend (message, vtag, targc, targv); - out: - if (rcs != NULL) - free (rcs); - if ((cp = strrchr (repository, '/')) != NULL) - *cp = '\0'; - else - repository[0] = '\0'; - if (restore_cwd (&cwd, NULL)) - error_exit (); - free_cwd (&cwd); - return (err); -} diff --git a/contrib/cvs/src/lock.c b/contrib/cvs/src/lock.c deleted file mode 100644 index d8e78fa..0000000 --- a/contrib/cvs/src/lock.c +++ /dev/null @@ -1,1166 +0,0 @@ -/* - * Copyright (C) 1986-2005 The Free Software Foundation, Inc. - * - * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot , - * and others. - * - * Portions Copyright (C) 1992, Brian Berliner and Jeff Polk - * Portions Copyright (C) 1989-1992, Brian Berliner - * - * You may distribute under the terms of the GNU General Public License as - * specified in the README file that comes with the CVS source distribution. - * - * Set Lock - * - * Lock file support for CVS. - * - * $FreeBSD$ - */ - -/* The node Concurrency in doc/cvs.texinfo has a brief introduction to - how CVS locks function, and some of the user-visible consequences of - their existence. Here is a summary of why they exist (and therefore, - the consequences of hacking CVS to read a repository without creating - locks): - - There are two uses. One is the ability to prevent there from being - two writers at the same time. This is necessary for any number of - reasons (fileattr code, probably others). Commit needs to lock the - whole tree so that nothing happens between the up-to-date check and - the actual checkin. - - The second use is the ability to ensure that there is not a writer - and a reader at the same time (several readers are allowed). Reasons - for this are: - - * Readlocks ensure that once CVS has found a collection of rcs - files using Find_Names, the files will still exist when it reads - them (they may have moved in or out of the attic). - - * Readlocks provide some modicum of consistency, although this is - kind of limited--see the node Concurrency in cvs.texinfo. - - * Readlocks ensure that the RCS file does not change between - RCS_parse and RCS_reparsercsfile time. This one strikes me as - important, although I haven't thought up what bad scenarios might - be. - - * Readlocks ensure that we won't find the file in the state in - which it is in between the calls to add_rcs_file and RCS_checkin in - commit.c (when a file is being added). This state is a state in - which the RCS file parsing routines in rcs.c cannot parse the file. - - * Readlocks ensure that a reader won't try to look at a - half-written fileattr file (fileattr is not updated atomically). - - (see also the description of anonymous read-only access in - "Password authentication security" node in doc/cvs.texinfo). - - While I'm here, I'll try to summarize a few random suggestions - which periodically get made about how locks might be different: - - 1. Check for EROFS. Maybe useful, although in the presence of NFS - EROFS does *not* mean that the file system is unchanging. - - 2. Provide an option to disable locks for operations which only - read (see above for some of the consequences). - - 3. Have a server internally do the locking. Probably a good - long-term solution, and many people have been working hard on code - changes which would eventually make it possible to have a server - which can handle various connections in one process, but there is - much, much work still to be done before this is feasible. */ - -#include "cvs.h" -#include - -#ifdef HAVE_NANOSLEEP -# include "xtime.h" -#else /* HAVE_NANOSLEEP */ -# if !defined HAVE_USLEEP && defined HAVE_SELECT - /* use select as a workaround */ -# include "xselect.h" -# endif /* !defined HAVE_USLEEP && defined HAVE_SELECT */ -#endif /* !HAVE_NANOSLEEP */ - - -struct lock { - /* This is the directory in which we may have a lock named by the - readlock variable, a lock named by the writelock variable, and/or - a lock named CVSLCK. The storage is not allocated along with the - struct lock; it is allocated by the Reader_Lock caller or in the - case of writelocks, it is just a pointer to the storage allocated - for the ->key field. */ - char *repository; - - /* The name of the master lock dir. Usually CVSLCK. */ - const char *lockdirname; - - /* The full path to the lock dir, if we are currently holding it. - * - * This will be LOCKDIRNAME catted onto REPOSITORY. We waste a little - * space by storing it, but save a later malloc/free. - */ - char *lockdir; - - /* Note there is no way of knowing whether the readlock and writelock - exist. The code which sets the locks doesn't use SIG_beginCrSect - to set a flag like we do for CVSLCK. */ -}; - -static void remove_locks PROTO((void)); -static int readers_exist PROTO((char *repository)); -static int set_lock PROTO ((struct lock *lock, int will_wait)); -static void clear_lock PROTO ((struct lock *lock)); -static void set_lockers_name PROTO((struct stat *statp)); -static int set_writelock_proc PROTO((Node * p, void *closure)); -static int unlock_proc PROTO((Node * p, void *closure)); -static int write_lock PROTO ((struct lock *lock)); -static void lock_simple_remove PROTO ((struct lock *lock)); -static void lock_wait PROTO((char *repository)); -static void lock_obtained PROTO((char *repository)); - -/* Malloc'd array containing the username of the whoever has the lock. - Will always be non-NULL in the cases where it is needed. */ -static char *lockers_name; -/* Malloc'd array specifying name of a readlock within a directory. - Or NULL if none. */ -static char *readlock; -/* Malloc'd array specifying name of a writelock within a directory. - Or NULL if none. */ -static char *writelock; -/* Malloc'd array specifying the name of a CVSLCK file (absolute pathname). - Will always be non-NULL in the cases where it is used. */ -static List *locklist; - -#define L_OK 0 /* success */ -#define L_ERROR 1 /* error condition */ -#define L_LOCKED 2 /* lock owned by someone else */ - -/* This is the (single) readlock which is set by Reader_Lock. The - repository field is NULL if there is no such lock. */ -static struct lock global_readlock = {NULL, CVSLCK, NULL}; - -static struct lock global_history_lock = {NULL, CVSHISTORYLCK, NULL}; -static struct lock global_val_tags_lock = {NULL, CVSVALTAGSLCK, NULL}; - -/* List of locks set by lock_tree_for_write. This is redundant - with locklist, sort of. */ -static List *lock_tree_list; - -/* If we set locks with lock_dir_for_write, then locked_dir contains - the malloc'd name of the repository directory which we have locked. - locked_list is the same thing packaged into a list and is redundant - with locklist the same way that lock_tree_list is. */ -static char *locked_dir; -static List *locked_list; - -/* LockDir from CVSROOT/config. */ -char *lock_dir; - -static char *lock_name PROTO ((const char *repository, const char *name)); - -/* Return a newly malloc'd string containing the name of the lock for the - repository REPOSITORY and the lock file name within that directory - NAME. Also create the directories in which to put the lock file - if needed (if we need to, could save system call(s) by doing - that only if the actual operation fails. But for now we'll keep - things simple). */ -static char * -lock_name (repository, name) - const char *repository; - const char *name; -{ - char *retval; - const char *p; - char *q; - const char *short_repos; - mode_t save_umask = 0; - int saved_umask = 0; - - if (lock_dir == NULL) - { - /* This is the easy case. Because the lock files go directly - in the repository, no need to create directories or anything. */ - retval = xmalloc (strlen (repository) + strlen (name) + 10); - (void) sprintf (retval, "%s/%s", repository, name); - } - else - { - struct stat sb; - mode_t new_mode = 0; - - /* The interesting part of the repository is the part relative - to CVSROOT. */ - assert (current_parsed_root != NULL); - assert (current_parsed_root->directory != NULL); - assert (strncmp (repository, current_parsed_root->directory, - strlen (current_parsed_root->directory)) == 0); - short_repos = repository + strlen (current_parsed_root->directory) + 1; - - if (strcmp (repository, current_parsed_root->directory) == 0) - short_repos = "."; - else - assert (short_repos[-1] == '/'); - - retval = xmalloc (strlen (lock_dir) - + strlen (short_repos) - + strlen (name) - + 10); - strcpy (retval, lock_dir); - q = retval + strlen (retval); - *q++ = '/'; - - strcpy (q, short_repos); - - /* In the common case, where the directory already exists, let's - keep it to one system call. */ - if (CVS_STAT (retval, &sb) < 0) - { - /* If we need to be creating more than one directory, we'll - get the existence_error here. */ - if (!existence_error (errno)) - error (1, errno, "cannot stat directory %s", retval); - } - else - { - if (S_ISDIR (sb.st_mode)) - goto created; - else - error (1, 0, "%s is not a directory", retval); - } - - /* Now add the directories one at a time, so we can create - them if needed. - - The idea behind the new_mode stuff is that the directory we - end up creating will inherit permissions from its parent - directory (we re-set new_mode with each EEXIST). CVSUMASK - isn't right, because typically the reason for LockDir is to - use a different set of permissions. We probably want to - inherit group ownership also (but we don't try to deal with - that, some systems do it for us either always or when g+s is on). - - We don't try to do anything about the permissions on the lock - files themselves. The permissions don't really matter so much - because the locks will generally be removed by the process - which created them. */ - - if (CVS_STAT (lock_dir, &sb) < 0) - error (1, errno, "cannot stat %s", lock_dir); - new_mode = sb.st_mode; - save_umask = umask (0000); - saved_umask = 1; - - p = short_repos; - while (1) - { - while (!ISDIRSEP (*p) && *p != '\0') - ++p; - if (ISDIRSEP (*p)) - { - strncpy (q, short_repos, p - short_repos); - q[p - short_repos] = '\0'; - if (!ISDIRSEP (q[p - short_repos - 1]) - && CVS_MKDIR (retval, new_mode) < 0) - { - int saved_errno = errno; - if (saved_errno != EEXIST) - error (1, errno, "cannot make directory %s", retval); - else - { - if (CVS_STAT (retval, &sb) < 0) - error (1, errno, "cannot stat %s", retval); - new_mode = sb.st_mode; - } - } - ++p; - } - else - { - strcpy (q, short_repos); - if (CVS_MKDIR (retval, new_mode) < 0 - && errno != EEXIST) - error (1, errno, "cannot make directory %s", retval); - goto created; - } - } - created:; - - strcat (retval, "/"); - strcat (retval, name); - - if (saved_umask) - { - assert (umask (save_umask) == 0000); - saved_umask = 0; - } - } - return retval; -} - -/* - * Clean up all outstanding locks - */ -void -Lock_Cleanup () -{ - /* FIXME: error handling here is kind of bogus; we sometimes will call - error, which in turn can call us again. For the moment work around - this by refusing to reenter this function (this is a kludge). */ - /* FIXME-reentrancy: the workaround isn't reentrant. */ - static int in_lock_cleanup = 0; - - if (trace) - (void) fprintf (stderr, "%s-> Lock_Cleanup()\n", CLIENT_SERVER_STR); - - if (in_lock_cleanup) - return; - in_lock_cleanup = 1; - - remove_locks (); - - dellist (&lock_tree_list); - - if (locked_dir != NULL) - { - dellist (&locked_list); - free (locked_dir); - locked_dir = NULL; - locked_list = NULL; - } - - if (global_history_lock.repository) clear_history_lock (); - if (global_val_tags_lock.repository) clear_val_tags_lock (); - - in_lock_cleanup = 0; -} - -/* - * Remove locks without discarding the lock information - */ -static void -remove_locks () -{ - /* clean up simple locks (if any) */ - if (global_readlock.repository != NULL) - { - lock_simple_remove (&global_readlock); - global_readlock.repository = NULL; - } - - /* clean up multiple locks (if any) */ - if (locklist != (List *) NULL) - { - (void) walklist (locklist, unlock_proc, NULL); - locklist = (List *) NULL; - } -} - -/* - * walklist proc for removing a list of locks - */ -static int -unlock_proc (p, closure) - Node *p; - void *closure; -{ - lock_simple_remove (p->data); - return (0); -} - - - -/* Remove the lock files. */ -static void -lock_simple_remove (lock) - struct lock *lock; -{ - char *tmp; - - /* If readlock is set, the lock directory *might* have been created, but - since Reader_Lock doesn't use SIG_beginCrSect the way that set_lock - does, we don't know that. That is why we need to check for - existence_error here. */ - if (readlock != NULL) - { - tmp = lock_name (lock->repository, readlock); - if (CVS_UNLINK (tmp) < 0 && ! existence_error (errno)) - error (0, errno, "failed to remove lock %s", tmp); - free (tmp); - } - - /* If writelock is set, the lock directory *might* have been created, but - since write_lock doesn't use SIG_beginCrSect the way that set_lock - does, we don't know that. That is why we need to check for - existence_error here. */ - if (writelock != NULL) - { - tmp = lock_name (lock->repository, writelock); - if (CVS_UNLINK (tmp) < 0 && ! existence_error (errno)) - error (0, errno, "failed to remove lock %s", tmp); - free (tmp); - } - - clear_lock (lock); -} - - - -/* - * Create a lock file for readers - */ -int -Reader_Lock (xrepository) - char *xrepository; -{ - int err = 0; - FILE *fp; - char *tmp; - - if (trace) - (void) fprintf (stderr, "%s-> Reader_Lock(%s)\n", CLIENT_SERVER_STR, - xrepository); - - if (noexec || readonlyfs) - return 0; - - /* we only do one directory at a time for read locks! */ - if (global_readlock.repository != NULL) - { - error (0, 0, "Reader_Lock called while read locks set - Help!"); - return 1; - } - - if (readlock == NULL) - { - readlock = xmalloc (strlen (hostname) + sizeof (CVSRFL) + 40); - (void) sprintf (readlock, -#ifdef HAVE_LONG_FILE_NAMES - "%s.%s.%ld", CVSRFL, hostname, -#else - "%s.%ld", CVSRFL, -#endif - (long) getpid ()); - } - - /* remember what we're locking (for Lock_Cleanup) */ - global_readlock.repository = xrepository; - - /* get the lock dir for our own */ - if (set_lock (&global_readlock, 1) != L_OK) - { - error (0, 0, "failed to obtain dir lock in repository `%s'", - xrepository); - if (readlock != NULL) - free (readlock); - readlock = NULL; - /* We don't set global_readlock.repository to NULL. I think this - only works because recurse.c will give a fatal error if we return - a nonzero value. */ - return 1; - } - - /* write a read-lock */ - tmp = lock_name (xrepository, readlock); - if ((fp = CVS_FOPEN (tmp, "w+")) == NULL || fclose (fp) == EOF) - { - error (0, errno, "cannot create read lock in repository `%s'", - xrepository); - if (readlock != NULL) - free (readlock); - readlock = NULL; - err = 1; - } - free (tmp); - - /* free the lock dir */ - clear_lock (&global_readlock); - - return err; -} - - - -/* - * Lock a list of directories for writing - */ -static char *lock_error_repos; -static int lock_error; - -static int Writer_Lock PROTO ((List * list)); - -static int -Writer_Lock (list) - List *list; -{ - char *wait_repos; - - if (noexec) - return 0; - - if (readonlyfs) { - error (0, 0, "write lock failed - read-only repository"); - return (1); - } - - /* We only know how to do one list at a time */ - if (locklist != (List *) NULL) - { - error (0, 0, "Writer_Lock called while write locks set - Help!"); - return 1; - } - - wait_repos = NULL; - for (;;) - { - /* try to lock everything on the list */ - lock_error = L_OK; /* init for set_writelock_proc */ - lock_error_repos = (char *) NULL; /* init for set_writelock_proc */ - locklist = list; /* init for Lock_Cleanup */ - if (lockers_name != NULL) - free (lockers_name); - lockers_name = xstrdup ("unknown"); - - (void) walklist (list, set_writelock_proc, NULL); - - switch (lock_error) - { - case L_ERROR: /* Real Error */ - if (wait_repos != NULL) - free (wait_repos); - Lock_Cleanup (); /* clean up any locks we set */ - error (0, 0, "lock failed - giving up"); - return 1; - - case L_LOCKED: /* Someone already had a lock */ - remove_locks (); /* clean up any locks we set */ - lock_wait (lock_error_repos); /* sleep a while and try again */ - wait_repos = xstrdup (lock_error_repos); - continue; - - case L_OK: /* we got the locks set */ - if (wait_repos != NULL) - { - lock_obtained (wait_repos); - free (wait_repos); - } - return 0; - - default: - if (wait_repos != NULL) - free (wait_repos); - error (0, 0, "unknown lock status %d in Writer_Lock", - lock_error); - return 1; - } - } -} - - - -/* - * walklist proc for setting write locks - */ -static int -set_writelock_proc (p, closure) - Node *p; - void *closure; -{ - /* if some lock was not OK, just skip this one */ - if (lock_error != L_OK) - return 0; - - /* apply the write lock */ - lock_error_repos = p->key; - lock_error = write_lock (p->data); - return 0; -} - - - -/* - * Create a lock file for writers returns L_OK if lock set ok, L_LOCKED if - * lock held by someone else or L_ERROR if an error occurred - */ -static int -write_lock (lock) - struct lock *lock; -{ - int status; - FILE *fp; - char *tmp; - - if (trace) - (void) fprintf (stderr, "%s-> write_lock(%s)\n", - CLIENT_SERVER_STR, lock->repository); - - if (writelock == NULL) - { - writelock = xmalloc (strlen (hostname) + sizeof (CVSWFL) + 40); - (void) sprintf (writelock, -#ifdef HAVE_LONG_FILE_NAMES - "%s.%s.%ld", CVSWFL, hostname, -#else - "%s.%ld", CVSWFL, -#endif - (long) getpid()); - } - - /* make sure the lock dir is ours (not necessarily unique to us!) */ - status = set_lock (lock, 0); - if (status == L_OK) - { - /* we now own a writer - make sure there are no readers */ - if (readers_exist (lock->repository)) - { - /* clean up the lock dir if we created it */ - if (status == L_OK) - { - clear_lock (lock); - } - - /* indicate we failed due to read locks instead of error */ - return L_LOCKED; - } - - /* write the write-lock file */ - tmp = lock_name (lock->repository, writelock); - if ((fp = CVS_FOPEN (tmp, "w+")) == NULL || fclose (fp) == EOF) - { - int xerrno = errno; - - if ( CVS_UNLINK (tmp) < 0 && ! existence_error (errno)) - error (0, errno, "failed to remove lock %s", tmp); - - /* free the lock dir if we created it */ - if (status == L_OK) - { - clear_lock (lock); - } - - /* return the error */ - error (0, xerrno, "cannot create write lock in repository `%s'", - lock->repository); - free (tmp); - return L_ERROR; - } - free (tmp); - return L_OK; - } - else - return status; -} - - - -/* - * readers_exist() returns 0 if there are no reader lock files remaining in - * the repository; else 1 is returned, to indicate that the caller should - * sleep a while and try again. - */ -static int -readers_exist (repository) - char *repository; -{ - char *lockdir; - char *line; - DIR *dirp; - struct dirent *dp; - struct stat sb; - int ret; -#ifdef CVS_FUDGELOCKS - time_t now; - (void)time (&now); -#endif - - lockdir = lock_name (repository, ""); - - assert (lockdir != NULL); - - lockdir[strlen (lockdir) - 1] = '\0'; /* remove trailing slash */ - - do { - if ((dirp = CVS_OPENDIR (lockdir)) == NULL) - error (1, 0, "cannot open directory %s", lockdir); - - ret = 0; - errno = 0; - while ((dp = CVS_READDIR (dirp)) != NULL) - { - if (CVS_FNMATCH (CVSRFLPAT, dp->d_name, 0) == 0) - { - line = xmalloc (strlen (lockdir) + 1 + strlen (dp->d_name) + 1); - (void)sprintf (line, "%s/%s", lockdir, dp->d_name); - if (CVS_STAT (line, &sb) != -1) - { -#ifdef CVS_FUDGELOCKS - /* - * If the create time of the file is more than CVSLCKAGE - * seconds ago, try to clean-up the lock file, and if - * successful, re-open the directory and try again. - */ - if (now >= (sb.st_ctime + CVSLCKAGE) && - CVS_UNLINK (line) != -1) - { - free (line); - ret = -1; - break; - } -#endif - set_lockers_name (&sb); - } - else - { - /* If the file doesn't exist, it just means that it - * disappeared between the time we did the readdir and the - * time we did the stat. - */ - if (!existence_error (errno)) - error (0, errno, "cannot stat %s", line); - } - errno = 0; - free (line); - ret = 1; - break; - } - errno = 0; - } - if (errno != 0) - error (0, errno, "error reading directory %s", repository); - - CVS_CLOSEDIR (dirp); - } while (ret < 0); - - if (lockdir != NULL) - free (lockdir); - return ret; -} - - - -/* - * Set the static variable lockers_name appropriately, based on the stat - * structure passed in. - */ -static void -set_lockers_name (statp) - struct stat *statp; -{ - struct passwd *pw; - - if (lockers_name != NULL) - free (lockers_name); - if ((pw = (struct passwd *)getpwuid (statp->st_uid)) != - (struct passwd *)NULL) - { - lockers_name = xstrdup (pw->pw_name); - } - else - { - lockers_name = xmalloc (20); - (void)sprintf (lockers_name, "uid%lu", (unsigned long) statp->st_uid); - } -} - - - -/* - * Persistently tries to make the directory "lckdir", which serves as a - * lock. - * - * #ifdef CVS_FUDGELOCKS - * If the create time on the directory is greater than CVSLCKAGE - * seconds old, just try to remove the directory. - * #endif - * - */ -static int -set_lock (lock, will_wait) - struct lock *lock; - int will_wait; -{ - int waited; - long us; - struct stat sb; - mode_t omask; - char *masterlock; - int status; -#ifdef CVS_FUDGELOCKS - time_t now; -#endif - - masterlock = lock_name (lock->repository, lock->lockdirname); - - /* - * Note that it is up to the callers of set_lock() to arrange for signal - * handlers that do the appropriate things, like remove the lock - * directory before they exit. - */ - waited = 0; - us = 1; - for (;;) - { - status = -1; - omask = umask (cvsumask); - SIG_beginCrSect (); - if (CVS_MKDIR (masterlock, 0777) == 0) - { - lock->lockdir = masterlock; - SIG_endCrSect (); - status = L_OK; - if (waited) - lock_obtained (lock->repository); - goto after_sig_unblock; - } - SIG_endCrSect (); - after_sig_unblock: - (void) umask (omask); - if (status != -1) - goto done; - - if (errno != EEXIST) - { - error (0, errno, - "failed to create lock directory for `%s' (%s)", - lock->repository, masterlock); - status = L_ERROR; - goto done; - } - - /* Find out who owns the lock. If the lock directory is - non-existent, re-try the loop since someone probably just - removed it (thus releasing the lock). */ - if (CVS_STAT (masterlock, &sb) < 0) - { - if (existence_error (errno)) - continue; - - error (0, errno, "couldn't stat lock directory `%s'", masterlock); - status = L_ERROR; - goto done; - } - -#ifdef CVS_FUDGELOCKS - /* - * If the create time of the directory is more than CVSLCKAGE seconds - * ago, try to clean-up the lock directory, and if successful, just - * quietly retry to make it. - */ - (void) time (&now); - if (now >= (sb.st_ctime + CVSLCKAGE)) - { - if (CVS_RMDIR (masterlock) >= 0) - continue; - } -#endif - - /* set the lockers name */ - set_lockers_name (&sb); - - /* if he wasn't willing to wait, return an error */ - if (!will_wait) - { - status = L_LOCKED; - goto done; - } - - /* if possible, try a very short sleep without a message */ - if (!waited && us < 1000) - { - us += us; -#if defined HAVE_NANOSLEEP - { - struct timespec ts; - ts.tv_sec = 0; - ts.tv_nsec = us * 1000; - (void)nanosleep (&ts, NULL); - continue; - } -#elif defined HAVE_USLEEP - (void)usleep (us); - continue; -#elif defined HAVE_SELECT - { - struct timeval tv; - tv.tv_sec = 0; - tv.tv_usec = us; - (void)select (0, (fd_set *)NULL, (fd_set *)NULL, (fd_set *)NULL, &tv); - continue; - } -#endif - } - - lock_wait (lock->repository); - waited = 1; - } -done: - if (!lock->lockdir) free (masterlock); - return status; -} - - - -/* - * Clear master lock. - * - * INPUTS - * lock The lock information. - * - * OUTPUTS - * Sets LOCK->lockdir to NULL after removing the directory it names and - * freeing the storage. - * - * ASSUMPTIONS - * If we own the master lock directory, its name is stored in LOCK->lockdir. - * We may free LOCK->lockdir. - * - */ -static void -clear_lock (lock) - struct lock *lock; -{ - SIG_beginCrSect (); - if (lock->lockdir) - { - if (CVS_RMDIR (lock->lockdir) < 0) - error (0, errno, "failed to remove lock dir `%s'", lock->lockdir); - free (lock->lockdir); - lock->lockdir = NULL; - } - SIG_endCrSect (); -} - - - -/* - * Print out a message that the lock is still held, then sleep a while. - */ -static void -lock_wait (repos) - char *repos; -{ - time_t now; - char *msg; - struct tm *tm_p; - - (void) time (&now); - tm_p = gmtime (&now); - msg = xmalloc (100 + strlen (lockers_name) + strlen (repos)); - sprintf (msg, "[%8.8s] waiting for %s's lock in %s", - (tm_p ? asctime (tm_p) : ctime (&now)) + 11, - lockers_name, repos); - error (0, 0, "%s", msg); - /* Call cvs_flusherr to ensure that the user sees this message as - soon as possible. */ - cvs_flusherr (); - free (msg); - (void) sleep (CVSLCKSLEEP); -} - -/* - * Print out a message when we obtain a lock. - */ -static void -lock_obtained (repos) - char *repos; -{ - time_t now; - char *msg; - struct tm *tm_p; - - (void) time (&now); - tm_p = gmtime (&now); - msg = xmalloc (100 + strlen (repos)); - sprintf (msg, "[%8.8s] obtained lock in %s", - (tm_p ? asctime (tm_p) : ctime (&now)) + 11, repos); - error (0, 0, "%s", msg); - /* Call cvs_flusherr to ensure that the user sees this message as - soon as possible. */ - cvs_flusherr (); - free (msg); -} - - - -static int lock_filesdoneproc PROTO ((void *callerdat, int err, - const char *repository, - const char *update_dir, - List *entries)); - -/* - * Create a list of repositories to lock - */ -/* ARGSUSED */ -static int -lock_filesdoneproc (callerdat, err, repository, update_dir, entries) - void *callerdat; - int err; - const char *repository; - const char *update_dir; - List *entries; -{ - Node *p; - - p = getnode (); - p->type = LOCK; - p->key = xstrdup (repository); - p->data = xmalloc (sizeof (struct lock)); - ((struct lock *)p->data)->repository = p->key; - ((struct lock *)p->data)->lockdirname = CVSLCK; - ((struct lock *)p->data)->lockdir = NULL; - - /* FIXME-KRP: this error condition should not simply be passed by. */ - if (p->key == NULL || addnode (lock_tree_list, p) != 0) - freenode (p); - return (err); -} - -void -lock_tree_for_write (argc, argv, local, which, aflag) - int argc; - char **argv; - int local; - int which; - int aflag; -{ - /* - * Run the recursion processor to find all the dirs to lock and lock all - * the dirs - */ - lock_tree_list = getlist (); - start_recursion ((FILEPROC) NULL, lock_filesdoneproc, - (DIRENTPROC) NULL, (DIRLEAVEPROC) NULL, NULL, argc, - argv, local, which, aflag, CVS_LOCK_NONE, - (char *) NULL, 0, (char *) NULL); - sortlist (lock_tree_list, fsortcmp); - if (Writer_Lock (lock_tree_list) != 0) - error (1, 0, "lock failed - giving up"); -} - -/* Lock a single directory in REPOSITORY. It is OK to call this if - a lock has been set with lock_dir_for_write; the new lock will replace - the old one. If REPOSITORY is NULL, don't do anything. */ -void -lock_dir_for_write (repository) - char *repository; -{ - if (repository != NULL - && (locked_dir == NULL - || strcmp (locked_dir, repository) != 0)) - { - Node *node; - - if (locked_dir != NULL) - Lock_Cleanup (); - - locked_dir = xstrdup (repository); - locked_list = getlist (); - node = getnode (); - node->type = LOCK; - node->key = xstrdup (repository); - node->data = xmalloc (sizeof (struct lock)); - ((struct lock *)node->data)->repository = node->key; - ((struct lock *)node->data)->lockdirname = CVSLCK; - ((struct lock *)node->data)->lockdir = NULL; - - (void) addnode (locked_list, node); - Writer_Lock (locked_list); - } -} - - - -/* This is the internal implementation behind history_lock & val_tags_lock. It - * gets a write lock for the history or val-tags file. - * - * RETURNS - * true, on success - * false, on error - */ -static int internal_lock PROTO ((struct lock *lock, const char *xrepository)); -static int -internal_lock (lock, xrepository) - struct lock *lock; - const char *xrepository; -{ - /* remember what we're locking (for Lock_Cleanup) */ - assert (!lock->repository); - lock->repository = xmalloc (strlen (xrepository) + sizeof (CVSROOTADM) + 2); - sprintf (lock->repository, "%s/%s", xrepository, CVSROOTADM); - - /* get the lock dir for our own */ - if (set_lock (lock, 1) != L_OK) - { - if (!really_quiet) - error (0, 0, "failed to obtain history lock in repository `%s'", - xrepository); - - return 0; - } - - return 1; -} - - - -/* This is the internal implementation behind history_lock & val_tags_lock. It - * removes the write lock for the history or val-tags file, when it exists. - */ -static void internal_clear_lock PROTO((struct lock *lock)); -static void -internal_clear_lock (lock) - struct lock *lock; -{ - SIG_beginCrSect (); - if (lock->repository) - { - free (lock->repository); - lock->repository = NULL; - } - SIG_endCrSect (); - - clear_lock (lock); -} - - - -/* Lock the CVSROOT/history file for write. - */ -int -history_lock (xrepository) - const char *xrepository; -{ - return internal_lock (&global_history_lock, xrepository); -} - - - -/* Remove the CVSROOT/history lock, if it exists. - */ -void -clear_history_lock () -{ - internal_clear_lock (&global_history_lock); -} - - - -/* Lock the CVSROOT/val-tags file for write. - */ -int -val_tags_lock (xrepository) - const char *xrepository; -{ - return internal_lock (&global_val_tags_lock, xrepository); -} - - - -/* Remove the CVSROOT/val-tags lock, if it exists. - */ -void -clear_val_tags_lock () -{ - internal_clear_lock (&global_val_tags_lock); -} diff --git a/contrib/cvs/src/log.c b/contrib/cvs/src/log.c deleted file mode 100644 index 0bf44c7..0000000 --- a/contrib/cvs/src/log.c +++ /dev/null @@ -1,1818 +0,0 @@ -/* - * Copyright (C) 1986-2008 The Free Software Foundation, Inc. - * - * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot , - * and others. - * - * Portions Copyright (C) 1992, Brian Berliner and Jeff Polk - * Portions Copyright (C) 1989-1992, Brian Berliner - * - * You may distribute under the terms of the GNU General Public License as - * specified in the README file that comes with the CVS source distribution. - * - * Print Log Information - * - * Prints the RCS "log" (rlog) information for the specified files. With no - * argument, prints the log information for all the files in the directory - * (recursive by default). - * - * $FreeBSD$ - */ - -#include "cvs.h" -#include - -/* This structure holds information parsed from the -r option. */ - -struct option_revlist -{ - /* The next -r option. */ - struct option_revlist *next; - /* The first revision to print. This is NULL if the range is - :rev, or if no revision is given. */ - char *first; - /* The last revision to print. This is NULL if the range is rev:, - or if no revision is given. If there is no colon, first and - last are the same. */ - char *last; - /* Nonzero if there was a trailing `.', which means to print only - the head revision of a branch. */ - int branchhead; - /* Nonzero if first and last are inclusive. */ - int inclusive; -}; - -/* This structure holds information derived from option_revlist given - a particular RCS file. */ - -struct revlist -{ - /* The next pair. */ - struct revlist *next; - /* The first numeric revision to print. */ - char *first; - /* The last numeric revision to print. */ - char *last; - /* The number of fields in these revisions (one more than - numdots). */ - int fields; - /* Whether first & last are to be included or excluded. */ - int inclusive; -}; - -/* This structure holds information parsed from the -d option. */ - -struct datelist -{ - /* The next date. */ - struct datelist *next; - /* The starting date. */ - char *start; - /* The ending date. */ - char *end; - /* Nonzero if the range is inclusive rather than exclusive. */ - int inclusive; -}; - -/* This structure is used to pass information through start_recursion. */ -struct log_data -{ - /* Nonzero if the -R option was given, meaning that only the name - of the RCS file should be printed. */ - int nameonly; - /* Nonzero if the -h option was given, meaning that only header - information should be printed. */ - int header; - /* Nonzero if the -t option was given, meaning that only the - header and the descriptive text should be printed. */ - int long_header; - /* Nonzero if the -N option was seen, meaning that tag information - should not be printed. */ - int notags; - /* Nonzero if the -b option was seen, meaning that revisions - on the default branch should be printed. */ - int default_branch; - /* Nonzero if the -S option was seen, meaning that the header/name - should be suppressed if no revisions are selected. */ - int sup_header; - /* If not NULL, the value given for the -r option, which lists - sets of revisions to be printed. */ - struct option_revlist *revlist; - /* If not NULL, the date pairs given for the -d option, which - select date ranges to print. */ - struct datelist *datelist; - /* If not NULL, the single dates given for the -d option, which - select specific revisions to print based on a date. */ - struct datelist *singledatelist; - /* If not NULL, the list of states given for the -s option, which - only prints revisions of given states. */ - List *statelist; - /* If not NULL, the list of login names given for the -w option, - which only prints revisions checked in by given users. */ - List *authorlist; -}; - -/* This structure is used to pass information through walklist. */ -struct log_data_and_rcs -{ - struct log_data *log_data; - struct revlist *revlist; - RCSNode *rcs; -}; - -static int rlog_proc PROTO((int argc, char **argv, char *xwhere, - char *mwhere, char *mfile, int shorten, - int local_specified, char *mname, char *msg)); -static Dtype log_dirproc PROTO ((void *callerdat, const char *dir, - const char *repository, - const char *update_dir, - List *entries)); -static int log_fileproc PROTO ((void *callerdat, struct file_info *finfo)); -static struct option_revlist *log_parse_revlist PROTO ((const char *)); -static void log_parse_date PROTO ((struct log_data *, const char *)); -static void log_parse_list PROTO ((List **, const char *)); -static struct revlist *log_expand_revlist PROTO ((RCSNode *, char *, - struct option_revlist *, - int)); -static void log_free_revlist PROTO ((struct revlist *)); -static int log_version_requested PROTO ((struct log_data *, struct revlist *, - RCSNode *, RCSVers *)); -static int log_symbol PROTO ((Node *, void *)); -static int log_count PROTO ((Node *, void *)); -static int log_fix_singledate PROTO ((Node *, void *)); -static int log_count_print PROTO ((Node *, void *)); -static void log_tree PROTO ((struct log_data *, struct revlist *, - RCSNode *, const char *)); -static void log_abranch PROTO ((struct log_data *, struct revlist *, - RCSNode *, const char *)); -static void log_version PROTO ((struct log_data *, struct revlist *, - RCSNode *, RCSVers *, int)); -static int log_branch PROTO ((Node *, void *)); -static int version_compare PROTO ((const char *, const char *, int)); - -static struct log_data log_data; -static int is_rlog; - -static const char *const log_usage[] = -{ - "Usage: %s %s [-lRhtNb] [-r[revisions]] [-d dates] [-s states]\n", - " [-w[logins]] [files...]\n", - "\t-l\tLocal directory only, no recursion.\n", - "\t-b\tList revisions on the default branch.\n", - "\t-h\tOnly print header.\n", - "\t-R\tOnly print name of RCS file.\n", - "\t-t\tOnly print header and descriptive text.\n", - "\t-N\tDo not list tags.\n", - "\t-n\tList tags (default).\n", - "\t-S\tDo not print name/header if no revisions selected. -d, -r,\n", - "\t\t-s, & -w have little effect in conjunction with -b, -h, -R, and\n", - "\t\t-t without this option.\n", - "\t-r[revisions]\tA comma-separated list of revisions to print:\n", - "\t rev1:rev2 Between rev1 and rev2, including rev1 and rev2.\n", - "\t rev1::rev2 Between rev1 and rev2, excluding rev1.\n", - "\t rev: rev and following revisions on the same branch.\n", - "\t rev:: After rev on the same branch.\n", - "\t :rev rev and previous revisions on the same branch.\n", - "\t ::rev rev and previous revisions on the same branch.\n", - "\t rev Just rev.\n", - "\t branch All revisions on the branch.\n", - "\t branch. The last revision on the branch.\n", - "\t-d dates\tA semicolon-separated list of dates\n", - "\t \t(D1key, "@@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; - char **argv; -{ - int c; - int err = 0; - int local = 0; - struct option_revlist **prl; - - is_rlog = (strcmp (cvs_cmd_name, "rlog") == 0); - - 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:hlNnSRr::s:tw::")) != -1) - { - switch (c) - { - case 'b': - log_data.default_branch = 1; - break; - case 'd': - log_parse_date (&log_data, optarg); - break; - case 'h': - log_data.header = 1; - break; - case 'l': - local = 1; - break; - case 'N': - log_data.notags = 1; - break; - case 'n': - log_data.notags = 0; - break; - case 'S': - log_data.sup_header = 1; - break; - case 'R': - log_data.nameonly = 1; - break; - case 'r': - *prl = log_parse_revlist (optarg); - prl = &(*prl)->next; - break; - case 's': - log_parse_list (&log_data.statelist, optarg); - break; - case 't': - log_data.long_header = 1; - break; - case 'w': - if (optarg != NULL) - log_parse_list (&log_data.authorlist, optarg); - else - log_parse_list (&log_data.authorlist, "@@MYSELF"); - break; - case '?': - default: - usage (log_usage); - break; - } - } - argc -= optind; - argv += optind; - - wrap_setup (); - -#ifdef CLIENT_SUPPORT - if (current_parsed_root->isremote) - { - struct datelist *p; - struct option_revlist *rp; - char datetmp[MAXDATELEN]; - - /* We're the local client. Fire up the remote server. */ - start_server (); - - if (is_rlog && !supported_request ("rlog")) - error (1, 0, "server does not support rlog"); - - ign_setup (); - - if (log_data.default_branch) - send_arg ("-b"); - - while (log_data.datelist != NULL) - { - p = log_data.datelist; - log_data.datelist = p->next; - assert (p->start != NULL && p->end != NULL); - 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); - free (p->start); - free (p->end); - free (p); - } - while (log_data.singledatelist != NULL) - { - p = log_data.singledatelist; - log_data.singledatelist = p->next; - assert (p->end != NULL); - 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); - 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.sup_header) - send_arg("-S"); - 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->inclusive) - 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_arg ("--"); - - if (is_rlog) - { - int i; - for (i = 0; i < argc; i++) - send_arg (argv[i]); - send_to_server ("rlog\012", 0); - } - else - { - send_files (argc, argv, local, 0, SEND_NO_CONTENTS); - send_file_names (argc, argv, SEND_EXPAND_WILD); - send_to_server ("log\012", 0); - } - err = get_responses_and_close (); - return err; - } -#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 ()); - - if (is_rlog) - { - DBM *db; - int i; - db = open_module (); - for (i = 0; i < argc; i++) - { - err += do_module (db, argv[i], MISC, "Logging", rlog_proc, - (char *) NULL, 0, local, 0, 0, (char *) NULL); - } - close_module (db); - } - else - { - err = rlog_proc (argc + 1, argv - 1, (char *) NULL, - (char *) NULL, (char *) NULL, 0, local, (char *) NULL, - (char *) NULL); - } - - 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); -} - - -static int -rlog_proc (argc, argv, xwhere, mwhere, mfile, shorten, local, mname, msg) - int argc; - char **argv; - char *xwhere; - char *mwhere; - char *mfile; - int shorten; - int local; - char *mname; - char *msg; -{ - /* Begin section which is identical to patch_proc--should this - be abstracted out somehow? */ - char *myargv[2]; - int err = 0; - int which; - char *repository; - char *where; - - if (is_rlog) - { - repository = xmalloc (strlen (current_parsed_root->directory) - + strlen (argv[0]) - + (mfile == NULL ? 0 : strlen (mfile) + 1) + 2); - (void)sprintf (repository, "%s/%s", - current_parsed_root->directory, argv[0]); - where = xmalloc (strlen (argv[0]) - + (mfile == NULL ? 0 : strlen (mfile) + 1) - + 1); - (void) strcpy (where, argv[0]); - - /* If mfile isn't null, we need to set up to do only part of theu - * module. - */ - if (mfile != NULL) - { - char *cp; - char *path; - - /* If the portion of the module is a path, put the dir part on - * repos. - */ - if ((cp = strrchr (mfile, '/')) != NULL) - { - *cp = '\0'; - (void)strcat (repository, "/"); - (void)strcat (repository, mfile); - (void)strcat (where, "/"); - (void)strcat (where, mfile); - mfile = cp + 1; - } - - /* take care of the rest */ - path = xmalloc (strlen (repository) + strlen (mfile) + 5); - (void)sprintf (path, "%s/%s", repository, mfile); - if (isdir (path)) - { - /* directory means repository gets the dir tacked on */ - (void)strcpy (repository, path); - (void)strcat (where, "/"); - (void)strcat (where, mfile); - } - else - { - myargv[0] = argv[0]; - myargv[1] = mfile; - argc = 2; - argv = myargv; - } - free (path); - } - - /* cd to the starting repository */ - if (CVS_CHDIR (repository) < 0) - { - error (0, errno, "cannot chdir to %s", repository); - free (repository); - free (where); - return 1; - } - /* End section which is identical to patch_proc. */ - - which = W_REPOS | W_ATTIC; - } - else - { - repository = NULL; - where = NULL; - which = W_LOCAL | W_REPOS | W_ATTIC; - } - - err = start_recursion (log_fileproc, (FILESDONEPROC) NULL, log_dirproc, - (DIRLEAVEPROC) NULL, (void *) &log_data, - argc - 1, argv + 1, local, which, 0, CVS_LOCK_READ, - where, 1, repository); - - if (!(which & W_LOCAL)) free (repository); - if (where) free (where); - - return err; -} - - - -/* - * Parse a revision list specification. - */ -static struct option_revlist * -log_parse_revlist (argstring) - const char *argstring; -{ - 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) - 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. */ - orig_copy = copy = xstrdup (argstring); - while (copy != NULL) - { - char *comma; - struct option_revlist *r; - - comma = strchr (copy, ','); - if (comma != NULL) - *comma++ = '\0'; - - r = (struct option_revlist *) xmalloc (sizeof *r); - r->next = NULL; - r->first = copy; - r->branchhead = 0; - r->last = strchr (copy, ':'); - if (r->last != NULL) - { - *r->last++ = '\0'; - r->inclusive = (*r->last != ':'); - if (!r->inclusive) - r->last++; - } - else - { - r->last = r->first; - r->inclusive = 1; - 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; -} - -/* - * Parse a date specification. - */ -static void -log_parse_date (log_data, argstring) - struct log_data *log_data; - const char *argstring; -{ - char *orig_copy, *copy; - - /* 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. */ - orig_copy = copy = xstrdup (argstring); - while (copy != NULL) - { - struct datelist *nd, **pd; - char *cpend, *cp, *ds, *de; - - nd = (struct datelist *) xmalloc (sizeof *nd); - - cpend = strchr (copy, ';'); - if (cpend != NULL) - *cpend++ = '\0'; - - pd = &log_data->datelist; - nd->inclusive = 0; - - if ((cp = strchr (copy, '>')) != NULL) - { - *cp++ = '\0'; - if (*cp == '=') - { - ++cp; - nd->inclusive = 1; - } - ds = cp; - de = copy; - } - else if ((cp = strchr (copy, '<')) != NULL) - { - *cp++ = '\0'; - if (*cp == '=') - { - ++cp; - nd->inclusive = 1; - } - ds = copy; - de = cp; - } - else - { - ds = NULL; - de = copy; - pd = &log_data->singledatelist; - } - - if (ds == NULL) - nd->start = NULL; - else if (*ds != '\0') - nd->start = Make_Date (ds); - else - { - /* 1970 was the beginning of time, as far as get_date and - Make_Date are concerned. FIXME: That is true only if time_t - is a POSIX-style time and there is nothing in ANSI that - mandates that. It would be cleaner to set a flag saying - whether or not there is a start date. */ - nd->start = Make_Date ("1/1/1970 UTC"); - } - - if (*de != '\0') - nd->end = Make_Date (de); - else - { - /* We want to set the end date to some time sufficiently far - in the future to pick up all revisions that have been - created since the specified date and the time `cvs log' - completes. FIXME: The date in question only makes sense - if time_t is a POSIX-style time and it is 32 bits - and signed. We should instead be setting a flag saying - whether or not there is an end date. Note that using - something like "next week" would break the testsuite (and, - perhaps less importantly, loses if the clock is set grossly - wrong). */ - nd->end = Make_Date ("2038-01-01"); - } - - nd->next = *pd; - *pd = nd; - - copy = cpend; - } - - free (orig_copy); -} - -/* - * Parse a comma separated list of items, and add each one to *PLIST. - */ -static void -log_parse_list (plist, argstring) - List **plist; - const char *argstring; -{ - while (1) - { - Node *p; - char *cp; - - p = getnode (); - - cp = strchr (argstring, ','); - if (cp == NULL) - p->key = xstrdup (argstring); - else - { - size_t len; - - len = cp - argstring; - p->key = xmalloc (len + 1); - strncpy (p->key, argstring, len); - p->key[len] = '\0'; - } - - if (*plist == NULL) - *plist = getlist (); - if (addnode (*plist, p) != 0) - freenode (p); - - if (cp == NULL) - break; - - argstring = cp + 1; - } -} - -static int printlock_proc PROTO ((Node *, void *)); - -static int -printlock_proc (lock, foo) - Node *lock; - void *foo; -{ - cvs_output ("\n\t", 2); - cvs_output (lock->data, 0); - cvs_output (": ", 2); - cvs_output (lock->key, 0); - return 0; -} - - - -/* - * Do an rlog on a file - */ -static int -log_fileproc (callerdat, finfo) - void *callerdat; - struct file_info *finfo; -{ - struct log_data *log_data = (struct log_data *) callerdat; - Node *p; - char *baserev; - int selrev = -1; - RCSNode *rcsfile; - char buf[50]; - struct revlist *revlist = NULL; - struct log_data_and_rcs log_data_and_rcs; - - rcsfile = finfo->rcs; - p = findnode (finfo->entries, finfo->file); - if (p != NULL) - { - Entnode *e = p->data; - baserev = e->version; - if (baserev[0] == '-') ++baserev; - } - else - baserev = NULL; - - if (rcsfile == NULL) - { - /* no rcs file. What *do* we know about this file? */ - if (baserev != NULL) - { - if (baserev[0] == '0' && baserev[1] == '\0') - { - if (!really_quiet) - error (0, 0, "%s has been added, but not committed", - finfo->file); - return 0; - } - } - - if (!really_quiet) - error (0, 0, "nothing known about %s", finfo->file); - - return 1; - } - - if (log_data->sup_header || !log_data->nameonly) - { - - /* We will need all the information in the RCS file. */ - RCS_fully_parse (rcsfile); - - /* Turn any symbolic revisions in the revision list into numeric - revisions. */ - revlist = log_expand_revlist (rcsfile, baserev, log_data->revlist, - log_data->default_branch); - if (log_data->sup_header - || (!log_data->header && !log_data->long_header)) - { - log_data_and_rcs.log_data = log_data; - log_data_and_rcs.revlist = revlist; - log_data_and_rcs.rcs = rcsfile; - - /* If any single dates were specified, we need to identify the - revisions they select. Each one selects the single - revision, which is otherwise selected, of that date or - earlier. The log_fix_singledate routine will fill in the - start date for each specific revision. */ - if (log_data->singledatelist != NULL) - walklist (rcsfile->versions, log_fix_singledate, - (void *)&log_data_and_rcs); - - selrev = walklist (rcsfile->versions, log_count_print, - (void *)&log_data_and_rcs); - if (log_data->sup_header && selrev == 0) - { - log_free_revlist (revlist); - return 0; - } - } - - } - - if (log_data->nameonly) - { - cvs_output (rcsfile->path, 0); - cvs_output ("\n", 1); - log_free_revlist (revlist); - return 0; - } - - /* The output here is intended to be exactly compatible with the - output of rlog. I'm not sure whether this code should be here - or in rcs.c; I put it here because it is specific to the log - function, even though it uses information gathered by the - functions in rcs.c. */ - - cvs_output ("\n", 1); - - cvs_output ("RCS file: ", 0); - cvs_output (rcsfile->path, 0); - - if (!is_rlog) - { - cvs_output ("\nWorking file: ", 0); - if (finfo->update_dir[0] != '\0') - { - cvs_output (finfo->update_dir, 0); - cvs_output ("/", 0); - } - cvs_output (finfo->file, 0); - } - - cvs_output ("\nhead:", 0); - if (rcsfile->head != NULL) - { - cvs_output (" ", 1); - cvs_output (rcsfile->head, 0); - } - - cvs_output ("\nbranch:", 0); - if (rcsfile->branch != NULL) - { - cvs_output (" ", 1); - cvs_output (rcsfile->branch, 0); - } - - cvs_output ("\nlocks:", 0); - if (rcsfile->strict_locks) - cvs_output (" strict", 0); - walklist (RCS_getlocks (rcsfile), printlock_proc, NULL); - - cvs_output ("\naccess list:", 0); - if (rcsfile->access != NULL) - { - const char *cp; - - cp = rcsfile->access; - while (*cp != '\0') - { - const char *cp2; - - cvs_output ("\n\t", 2); - cp2 = cp; - while (!isspace ((unsigned char) *cp2) && *cp2 != '\0') - ++cp2; - cvs_output (cp, cp2 - cp); - cp = cp2; - while (isspace ((unsigned char) *cp) && *cp != '\0') - ++cp; - } - } - - if (!log_data->notags) - { - List *syms; - - cvs_output ("\nsymbolic names:", 0); - syms = RCS_symbols (rcsfile); - walklist (syms, log_symbol, NULL); - } - - cvs_output ("\nkeyword substitution: ", 0); - if (rcsfile->expand == NULL) - cvs_output ("kv", 2); - else - cvs_output (rcsfile->expand, 0); - - cvs_output ("\ntotal revisions: ", 0); - sprintf (buf, "%d", walklist (rcsfile->versions, log_count, NULL)); - cvs_output (buf, 0); - - if (selrev >= 0) - { - cvs_output (";\tselected revisions: ", 0); - sprintf (buf, "%d", selrev); - cvs_output (buf, 0); - } - - cvs_output ("\n", 1); - - if (!log_data->header || log_data->long_header) - { - cvs_output ("description:\n", 0); - if (rcsfile->desc != NULL) - cvs_output (rcsfile->desc, 0); - } - - if (!log_data->header && ! log_data->long_header && rcsfile->head != NULL) - { - p = findnode (rcsfile->versions, rcsfile->head); - if (p == NULL) - error (1, 0, "can not find head revision in `%s'", - finfo->fullname); - while (p != NULL) - { - RCSVers *vers = p->data; - - log_version (log_data, revlist, rcsfile, vers, 1); - if (vers->next == NULL) - p = NULL; - else - { - p = findnode (rcsfile->versions, vers->next); - if (p == NULL) - error (1, 0, "can not find next revision `%s' in `%s'", - vers->next, finfo->fullname); - } - } - - log_tree (log_data, revlist, rcsfile, rcsfile->head); - } - - cvs_output("\ -=============================================================================\n", - 0); - - /* Free up the new revlist and restore the old one. */ - log_free_revlist (revlist); - - /* If singledatelist is not NULL, free up the start dates we added - to it. */ - if (log_data->singledatelist != NULL) - { - struct datelist *d; - - for (d = log_data->singledatelist; d != NULL; d = d->next) - { - if (d->start != NULL) - free (d->start); - d->start = NULL; - } - } - - return 0; -} - - - -/* - * Fix up a revision list in order to compare it against versions. - * Expand any symbolic revisions. - */ -static struct revlist * -log_expand_revlist (rcs, baserev, revlist, default_branch) - RCSNode *rcs; - char *baserev; - struct option_revlist *revlist; - int default_branch; -{ - struct option_revlist *r; - struct revlist *ret, **pr; - - ret = NULL; - pr = &ret; - for (r = revlist; r != NULL; r = r->next) - { - struct revlist *nr; - - nr = (struct revlist *) xmalloc (sizeof *nr); - nr->inclusive = r->inclusive; - - if (r->first == NULL && r->last == NULL) - { - /* If both first and last are NULL, it means that we want - just the head of the default branch, which is RCS_head. */ - nr->first = RCS_head (rcs); - if (!nr->first) - { - if (!really_quiet) - error (0, 0, "No head revision in archive `%s'.", - rcs->path); - nr->last = NULL; - nr->fields = 0; - } - else - { - nr->last = xstrdup (nr->first); - nr->fields = numdots (nr->first) + 1; - } - } - else if (r->branchhead) - { - char *branch; - - assert (r->first != NULL); - - /* Print just the head of the branch. */ - if (isdigit ((unsigned char) r->first[0])) - nr->first = RCS_getbranch (rcs, r->first, 1); - else - { - branch = RCS_whatbranch (rcs, r->first); - if (branch == NULL) - nr->first = NULL; - else - { - nr->first = RCS_getbranch (rcs, branch, 1); - free (branch); - } - } - if (!nr->first) - { - if (!really_quiet) - error (0, 0, "warning: no branch `%s' in `%s'", - r->first, rcs->path); - nr->last = NULL; - nr->fields = 0; - } - else - { - nr->last = xstrdup (nr->first); - nr->fields = numdots (nr->first) + 1; - } - } - else - { - if (r->first == NULL || isdigit ((unsigned char) r->first[0])) - nr->first = xstrdup (r->first); - else - { - if (baserev && strcmp (r->first, TAG_BASE) == 0) - nr->first = xstrdup (baserev); - else if (RCS_nodeisbranch (rcs, r->first)) - nr->first = RCS_whatbranch (rcs, r->first); - else - nr->first = RCS_gettag (rcs, r->first, 1, (int *) NULL); - if (nr->first == NULL && !really_quiet) - { - error (0, 0, "warning: no revision `%s' in `%s'", - r->first, rcs->path); - } - } - - if (r->last == r->first || (r->last != NULL && r->first != NULL && - strcmp (r->last, r->first) == 0)) - nr->last = xstrdup (nr->first); - else if (r->last == NULL || isdigit ((unsigned char) r->last[0])) - nr->last = xstrdup (r->last); - else - { - if (baserev && strcmp (r->last, TAG_BASE) == 0) - nr->last = xstrdup (baserev); - else if (RCS_nodeisbranch (rcs, r->last)) - nr->last = RCS_whatbranch (rcs, r->last); - else - nr->last = RCS_gettag (rcs, r->last, 1, (int *) NULL); - if (nr->last == NULL && !really_quiet) - { - error (0, 0, "warning: no revision `%s' in `%s'", - r->last, rcs->path); - } - } - - /* Process the revision numbers the same way that rlog - does. This code is a bit cryptic for my tastes, but - keeping the same implementation as rlog ensures a - certain degree of compatibility. */ - if (r->first == NULL && nr->last != NULL) - { - nr->fields = numdots (nr->last) + 1; - if (nr->fields < 2) - nr->first = xstrdup (".0"); - else - { - char *cp; - - nr->first = xstrdup (nr->last); - cp = strrchr (nr->first, '.'); - assert (cp); - strcpy (cp + 1, "0"); - } - } - else if (r->last == NULL && nr->first != NULL) - { - nr->fields = numdots (nr->first) + 1; - nr->last = xstrdup (nr->first); - if (nr->fields < 2) - nr->last[0] = '\0'; - else - { - char *cp; - - cp = strrchr (nr->last, '.'); - assert (cp); - *cp = '\0'; - } - } - else if (nr->first == NULL || nr->last == NULL) - nr->fields = 0; - else if (strcmp (nr->first, nr->last) == 0) - nr->fields = numdots (nr->last) + 1; - else - { - int ord; - int dots1 = numdots (nr->first); - int dots2 = numdots (nr->last); - if (dots1 > dots2 || (dots1 == dots2 && - version_compare (nr->first, nr->last, dots1 + 1) > 0)) - { - char *tmp = nr->first; - nr->first = nr->last; - nr->last = tmp; - nr->fields = dots2 + 1; - dots2 = dots1; - dots1 = nr->fields - 1; - } - else - nr->fields = dots1 + 1; - dots1 += (nr->fields & 1); - ord = version_compare (nr->first, nr->last, dots1); - if (ord > 0 || (nr->fields > 2 && ord < 0)) - { - error (0, 0, - "invalid branch or revision pair %s:%s in `%s'", - r->first, r->last, rcs->path); - free (nr->first); - nr->first = NULL; - free (nr->last); - nr->last = NULL; - nr->fields = 0; - } - else - { - if (nr->fields <= dots2 && (nr->fields & 1)) - { - char *p = xmalloc (strlen (nr->first) + 3); - strcpy (p, nr->first); - strcat (p, ".0"); - free (nr->first); - nr->first = p; - ++nr->fields; - } - while (nr->fields <= dots2) - { - char *p; - int i; - - nr->next = NULL; - *pr = nr; - nr = (struct revlist *) xmalloc (sizeof *nr); - nr->inclusive = 1; - nr->first = xstrdup ((*pr)->last); - nr->last = xstrdup ((*pr)->last); - nr->fields = (*pr)->fields; - p = (*pr)->last; - for (i = 0; i < nr->fields; i++) - p = strchr (p, '.') + 1; - p[-1] = '\0'; - p = strchr (nr->first + (p - (*pr)->last), '.'); - if (p != NULL) - { - *++p = '0'; - *++p = '\0'; - nr->fields += 2; - } - else - ++nr->fields; - pr = &(*pr)->next; - } - } - } - } - - nr->next = NULL; - *pr = nr; - pr = &nr->next; - } - - /* If the default branch was requested, add a revlist entry for - it. This is how rlog handles this option. */ - if (default_branch - && (rcs->head != NULL || rcs->branch != NULL)) - { - struct revlist *nr; - - nr = (struct revlist *) xmalloc (sizeof *nr); - if (rcs->branch != NULL) - nr->first = xstrdup (rcs->branch); - else - { - char *cp; - - nr->first = xstrdup (rcs->head); - assert (nr->first); - cp = strrchr (nr->first, '.'); - assert (cp); - *cp = '\0'; - } - nr->last = xstrdup (nr->first); - nr->fields = numdots (nr->first) + 1; - nr->inclusive = 1; - - nr->next = NULL; - *pr = nr; - } - - return ret; -} - -/* - * Free a revlist created by log_expand_revlist. - */ -static void -log_free_revlist (revlist) - struct revlist *revlist; -{ - struct revlist *r; - - r = revlist; - while (r != NULL) - { - struct revlist *next; - - if (r->first != NULL) - free (r->first); - if (r->last != NULL) - free (r->last); - next = r->next; - free (r); - r = next; - } -} - -/* - * Return nonzero if a revision should be printed, based on the - * options provided. - */ -static int -log_version_requested (log_data, revlist, rcs, vnode) - struct log_data *log_data; - struct revlist *revlist; - RCSNode *rcs; - RCSVers *vnode; -{ - /* Handle the list of states from the -s option. */ - if (log_data->statelist != NULL - && findnode (log_data->statelist, vnode->state) == NULL) - { - return 0; - } - - /* Handle the list of authors from the -w option. */ - if (log_data->authorlist != NULL) - { - if (vnode->author != NULL - && findnode (log_data->authorlist, vnode->author) == NULL) - { - return 0; - } - } - - /* rlog considers all the -d options together when it decides - whether to print a revision, so we must be compatible. */ - if (log_data->datelist != NULL || log_data->singledatelist != NULL) - { - struct datelist *d; - - for (d = log_data->datelist; d != NULL; d = d->next) - { - int cmp; - - cmp = RCS_datecmp (vnode->date, d->start); - if (cmp > 0 || (cmp == 0 && d->inclusive)) - { - cmp = RCS_datecmp (vnode->date, d->end); - if (cmp < 0 || (cmp == 0 && d->inclusive)) - break; - } - } - - if (d == NULL) - { - /* Look through the list of specific dates. We want to - select the revision with the exact date found in the - start field. The commit code ensures that it is - impossible to check in multiple revisions of a single - file in a single second, so checking the date this way - should never select more than one revision. */ - for (d = log_data->singledatelist; d != NULL; d = d->next) - { - if (d->start != NULL - && RCS_datecmp (vnode->date, d->start) == 0) - { - break; - } - } - - if (d == NULL) - return 0; - } - } - - /* If the -r or -b options were used, REVLIST will be non NULL, - and we print the union of the specified revisions. */ - if (revlist != NULL) - { - char *v; - int vfields; - struct revlist *r; - - /* This code is taken from rlog. */ - v = vnode->version; - vfields = numdots (v) + 1; - for (r = revlist; r != NULL; r = r->next) - { - if (vfields == r->fields + (r->fields & 1) && - (r->inclusive ? version_compare (v, r->first, r->fields) >= 0 : - version_compare (v, r->first, r->fields) > 0) - && version_compare (v, r->last, r->fields) <= 0) - { - return 1; - } - } - - /* If we get here, then the -b and/or the -r option was used, - but did not match this revision, so we reject it. */ - - return 0; - } - - /* By default, we print all revisions. */ - return 1; -} - - - -/* - * Output a single symbol. This is called via walklist. - */ -/*ARGSUSED*/ -static int -log_symbol (p, closure) - Node *p; - void *closure; -{ - cvs_output ("\n\t", 2); - cvs_output (p->key, 0); - cvs_output (": ", 2); - cvs_output (p->data, 0); - return 0; -} - - - -/* - * Count the number of entries on a list. This is called via walklist. - */ -/*ARGSUSED*/ -static int -log_count (p, closure) - Node *p; - void *closure; -{ - return 1; -} - - - -/* - * Sort out a single date specification by narrowing down the date - * until we find the specific selected revision. - */ -static int -log_fix_singledate (p, closure) - Node *p; - void *closure; -{ - struct log_data_and_rcs *data = (struct log_data_and_rcs *) closure; - Node *pv; - RCSVers *vnode; - struct datelist *holdsingle, *holddate; - int requested; - - pv = findnode (data->rcs->versions, p->key); - if (pv == NULL) - error (1, 0, "missing version `%s' in RCS file `%s'", - p->key, data->rcs->path); - vnode = pv->data; - - /* We are only interested if this revision passes any other tests. - Temporarily clear log_data->singledatelist to avoid confusing - log_version_requested. We also clear log_data->datelist, - because rlog considers all the -d options together. We don't - want to reject a revision because it does not match a date pair - if we are going to select it on the basis of the singledate. */ - holdsingle = data->log_data->singledatelist; - data->log_data->singledatelist = NULL; - holddate = data->log_data->datelist; - data->log_data->datelist = NULL; - requested = log_version_requested (data->log_data, data->revlist, - data->rcs, vnode); - data->log_data->singledatelist = holdsingle; - data->log_data->datelist = holddate; - - if (requested) - { - struct datelist *d; - - /* For each single date, if this revision is before the - specified date, but is closer than the previously selected - revision, select it instead. */ - for (d = data->log_data->singledatelist; d != NULL; d = d->next) - { - if (RCS_datecmp (vnode->date, d->end) <= 0 - && (d->start == NULL - || RCS_datecmp (vnode->date, d->start) > 0)) - { - if (d->start != NULL) - free (d->start); - d->start = xstrdup (vnode->date); - } - } - } - - return 0; -} - - - -/* - * Count the number of revisions we are going to print. - */ -static int -log_count_print (p, closure) - Node *p; - void *closure; -{ - struct log_data_and_rcs *data = (struct log_data_and_rcs *) closure; - Node *pv; - - pv = findnode (data->rcs->versions, p->key); - if (pv == NULL) - error (1, 0, "missing version `%s' in RCS file `%s'", - p->key, data->rcs->path); - if (log_version_requested (data->log_data, data->revlist, data->rcs, - pv->data)) - return 1; - else - return 0; -} - -/* - * Print the list of changes, not including the trunk, in reverse - * order for each branch. - */ -static void -log_tree (log_data, revlist, rcs, ver) - struct log_data *log_data; - struct revlist *revlist; - RCSNode *rcs; - const char *ver; -{ - Node *p; - RCSVers *vnode; - - p = findnode (rcs->versions, ver); - if (p == NULL) - error (1, 0, "missing version `%s' in RCS file `%s'", - ver, rcs->path); - vnode = p->data; - if (vnode->next != NULL) - log_tree (log_data, revlist, rcs, vnode->next); - if (vnode->branches != NULL) - { - Node *head, *branch; - - /* We need to do the branches in reverse order. This breaks - the List abstraction, but so does most of the branch - manipulation in rcs.c. */ - head = vnode->branches->list; - for (branch = head->prev; branch != head; branch = branch->prev) - { - log_abranch (log_data, revlist, rcs, branch->key); - log_tree (log_data, revlist, rcs, branch->key); - } - } -} - -/* - * Log the changes for a branch, in reverse order. - */ -static void -log_abranch (log_data, revlist, rcs, ver) - struct log_data *log_data; - struct revlist *revlist; - RCSNode *rcs; - const char *ver; -{ - Node *p; - RCSVers *vnode; - - p = findnode (rcs->versions, ver); - if (p == NULL) - error (1, 0, "missing version `%s' in RCS file `%s'", - ver, rcs->path); - vnode = p->data; - if (vnode->next != NULL) - log_abranch (log_data, revlist, rcs, vnode->next); - log_version (log_data, revlist, rcs, vnode, 0); -} - -/* - * Print the log output for a single version. - */ -static void -log_version (log_data, revlist, rcs, ver, trunk) - struct log_data *log_data; - struct revlist *revlist; - RCSNode *rcs; - RCSVers *ver; - int trunk; -{ - Node *p; - int year, mon, mday, hour, min, sec; - char buf[100]; - Node *padd, *pdel; - - if (! log_version_requested (log_data, revlist, rcs, ver)) - return; - - cvs_output ("----------------------------\nrevision ", 0); - cvs_output (ver->version, 0); - - p = findnode (RCS_getlocks (rcs), ver->version); - if (p != NULL) - { - cvs_output ("\tlocked by: ", 0); - cvs_output (p->data, 0); - cvs_output (";", 1); - } - - cvs_output ("\ndate: ", 0); - (void) sscanf (ver->date, SDATEFORM, &year, &mon, &mday, &hour, &min, - &sec); - if (year < 1900) - year += 1900; - sprintf (buf, "%04d%c%02d%c%02d %02d:%02d:%02d", - year, datesep, mon, datesep, mday, hour, min, sec); - cvs_output (buf, 0); - - cvs_output ("; author: ", 0); - cvs_output (ver->author, 0); - - cvs_output ("; state: ", 0); - cvs_output (ver->state, 0); - cvs_output (";", 1); - - if (! trunk) - { - padd = findnode (ver->other, ";add"); - pdel = findnode (ver->other, ";delete"); - } - else if (ver->next == NULL) - { - padd = NULL; - pdel = NULL; - } - else - { - Node *nextp; - RCSVers *nextver; - - nextp = findnode (rcs->versions, ver->next); - if (nextp == NULL) - error (1, 0, "missing version `%s' in `%s'", ver->next, - rcs->path); - nextver = nextp->data; - pdel = findnode (nextver->other, ";add"); - padd = findnode (nextver->other, ";delete"); - } - - if (padd != NULL) - { - assert (pdel); - cvs_output (" lines: +", 0); - cvs_output (padd->data, 0); - cvs_output (" -", 2); - cvs_output (pdel->data, 0); - } - - if (ver->branches != NULL) - { - cvs_output ("\nbranches:", 0); - walklist (ver->branches, log_branch, (void *) NULL); - } - - cvs_output ("\n", 1); - - p = findnode (ver->other, "log"); - /* The p->date == NULL case is the normal one for an empty log - message (rcs-14 in sanity.sh). I don't think the case where - p->data is "" can happen (getrcskey in rcs.c checks for an - empty string and set the value to NULL in that case). My guess - would be the p == NULL case would mean an RCS file which was - missing the "log" keyword (which is illegal according to - rcsfile.5). */ - if (p == NULL || p->data == NULL || *(char *)p->data == '\0') - cvs_output ("*** empty log message ***\n", 0); - else - { - /* FIXME: Technically, the log message could contain a null - byte. */ - cvs_output (p->data, 0); - if (((char *)p->data)[strlen (p->data) - 1] != '\n') - cvs_output ("\n", 1); - } -} - -/* - * Output a branch version. This is called via walklist. - */ -/*ARGSUSED*/ -static int -log_branch (p, closure) - Node *p; - void *closure; -{ - cvs_output (" ", 2); - if ((numdots (p->key) & 1) == 0) - cvs_output (p->key, 0); - else - { - char *f, *cp; - - f = xstrdup (p->key); - cp = strrchr (f, '.'); - *cp = '\0'; - cvs_output (f, 0); - free (f); - } - cvs_output (";", 1); - return 0; -} - -/* - * Print a warm fuzzy message - */ -/* ARGSUSED */ -static Dtype -log_dirproc (callerdat, dir, repository, update_dir, entries) - void *callerdat; - const char *dir; - const char *repository; - const char *update_dir; - List *entries; -{ - if (!isdir (dir)) - return (R_SKIP_ALL); - - if (!quiet) - error (0, 0, "Logging %s", update_dir); - return (R_PROCESS); -} - -/* - * Compare versions. This is taken from RCS compartial. - */ -static int -version_compare (v1, v2, len) - const char *v1; - const char *v2; - int len; -{ - while (1) - { - int d1, d2, r; - - if (*v1 == '\0') - return 1; - if (*v2 == '\0') - return -1; - - while (*v1 == '0') - ++v1; - for (d1 = 0; isdigit ((unsigned char) v1[d1]); ++d1) - ; - - while (*v2 == '0') - ++v2; - for (d2 = 0; isdigit ((unsigned char) v2[d2]); ++d2) - ; - - if (d1 != d2) - return d1 < d2 ? -1 : 1; - - r = memcmp (v1, v2, d1); - if (r != 0) - return r; - - --len; - if (len == 0) - return 0; - - v1 += d1; - v2 += d1; - - if (*v1 == '.') - ++v1; - if (*v2 == '.') - ++v2; - } -} diff --git a/contrib/cvs/src/login.c b/contrib/cvs/src/login.c deleted file mode 100644 index 1d20c97..0000000 --- a/contrib/cvs/src/login.c +++ /dev/null @@ -1,686 +0,0 @@ -/* - * Copyright (C) 1986-2005 The Free Software Foundation, Inc. - * - * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot , - * and others. - * - * Portions Copyright (c) 1995, Cyclic Software, Bloomington, IN, USA - * - * You may distribute under the terms of the GNU General Public License as - * specified in the README file that comes with CVS. - * - * Allow user to log in for an authenticating server. - */ - -#include "cvs.h" -#include "getline.h" - -#ifdef AUTH_CLIENT_SUPPORT /* This covers the rest of the file. */ - -/* 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 - _CRAY, since Cray is perhaps the only system on which our own - declaration won't work (some Crays declare the 2#$@% thing as - varadic, believe it or not). On Cray, getpass will be declared - in either stdlib.h or unistd.h. */ - -#ifndef CVS_PASSWORD_FILE -#define CVS_PASSWORD_FILE ".cvspass" -#endif - -/* If non-NULL, get_cvs_password() will just return this. */ -static char *cvs_password = NULL; - -static char *construct_cvspass_filename PROTO ((void)); - -/* The return value will need to be freed. */ -static char * -construct_cvspass_filename () -{ - char *homedir; - char *passfile; - - /* Environment should override file. */ - if ((passfile = getenv ("CVS_PASSFILE")) != NULL) - return xstrdup (passfile); - - /* Construct absolute pathname to user's password file. */ - /* todo: does this work under OS/2 ? */ - homedir = get_homedir (); - if (! homedir) - { - /* FIXME? This message confuses a lot of users, at least - on Win95 (which doesn't set HOMEDRIVE and HOMEPATH like - NT does). I suppose the answer for Win95 is to store the - passwords in the registry or something (??). And .cvsrc - and such too? Wonder what WinCVS does (about .cvsrc, the - right thing for a GUI is to just store the password in - memory only)... */ - error (1, 0, "could not find out home directory"); - return (char *) NULL; - } - - passfile = strcat_filename_onto_homedir (homedir, CVS_PASSWORD_FILE); - - /* Safety first and last, Scouts. */ - if (isfile (passfile)) - /* xchmod() is too polite. */ - chmod (passfile, 0600); - - return passfile; -} - - - -/* - * static char * - * password_entry_parseline ( - * const char *cvsroot_canonical, - * const unsigned char warn, - * const int linenumber, - * char *linebuf - * ); - * - * Internal function used by password_entry_operation. Parse a single line - * from a ~/.cvsroot password file and return a pointer to the password if the - * line refers to the same cvsroot as cvsroot_canonical - * - * INPUTS - * cvsroot_canonical the root we are looking for - * warn Boolean: print warnings for invalid lines? - * linenumber the line number for error messages - * linebuf the current line - * - * RETURNS - * NULL if the line doesn't match - * char *password as a pointer into linebuf - * - * NOTES - * This function temporarily alters linebuf, so it isn't thread safe when - * called on the same linebuf - */ -static char * -password_entry_parseline (cvsroot_canonical, warn, linenumber, linebuf) - const char *cvsroot_canonical; - const unsigned char warn; - const int linenumber; - char *linebuf; -{ - char *password = NULL; - char *p; - - /* look for '^/' */ - if (*linebuf == '/') - { - /* Yes: slurp '^/\d+\D' and parse the rest of the line according to version number */ - char *q; - unsigned long int entry_version = 0; - - if (isspace(*(linebuf + 1))) - { - /* special case since strtoul ignores leading white space */ - q = linebuf + 1; - } - else - { - entry_version = strtoul (linebuf + 1, &q, 10); - if (q != linebuf + 1) - /* assume a delimiting seperator */ - q++; - } - - switch (entry_version) - { - case 1: - /* this means the same normalize_cvsroot we are using was - * used to create this entry. strcmp is good enough for - * us. - */ - p = strchr (q, ' '); - if (p == NULL) - { - if (warn && !really_quiet) - error (0, 0, "warning: skipping invalid entry in password file at line %d", - linenumber); - } - else - { - *p = '\0'; - if (strcmp (cvsroot_canonical, q) == 0) - password = p + 1; - *p = ' '; - } - break; - case ULONG_MAX: - if (warn && !really_quiet) - { - error (0, errno, "warning: unable to convert version number in password file at line %d", - linenumber); - error (0, 0, "skipping entry"); - } - break; - case 0: - if (warn && !really_quiet) - error (0, 0, "warning: skipping entry with invalid version string in password file at line %d", - linenumber); - break; - default: - if (warn && !really_quiet) - error (0, 0, "warning: skipping entry with unknown version (%lu) in password file at line %d", - entry_version, linenumber); - break; - } - } - else - { - /* No: assume: - * - * ^cvsroot Aencoded_password$ - * - * as header comment specifies and parse accordingly - */ - cvsroot_t *tmp_root; - char *tmp_root_canonical; - - p = strchr (linebuf, ' '); - if (p == NULL) - { - if (warn && !really_quiet) - error (0, 0, "warning: skipping invalid entry in password file at line %d", linenumber); - return NULL;; - } - - *p = '\0'; - if ((tmp_root = parse_cvsroot (linebuf)) == NULL) - { - if (warn && !really_quiet) - error (0, 0, "warning: skipping invalid entry in password file at line %d", linenumber); - *p = ' '; - return NULL; - } - *p = ' '; - tmp_root_canonical = normalize_cvsroot (tmp_root); - if (strcmp (cvsroot_canonical, tmp_root_canonical) == 0) - password = p + 1; - - free (tmp_root_canonical); - free_cvsroot_t (tmp_root); - } - - return password; -} - - - -/* - * static char * - * password_entry_operation ( - * password_entry_operation_t operation, - * cvsroot_t *root, - * char *newpassword - * ); - * - * Search the password file and depending on the value of operation: - * - * Mode Action - * password_entry_lookup Return the password - * password_entry_delete Delete the entry from the file, if it - * exists. - * password_entry_add Replace the line with the new one, else - * append it. - * - * Because the user might be accessing multiple repositories, with - * different passwords for each one, the format of ~/.cvspass is: - * - * [user@]host:[port]/path Aencoded_password - * [user@]host:[port]/path Aencoded_password - * ... - * - * New entries are always of the form: - * - * /1 user@host:port/path Aencoded_password - * - * but the old format is supported for backwards compatibility. - * The entry version string wasn't strictly necessary, but it avoids the - * overhead of parsing some entries since we know it is already in canonical - * form and allows room for expansion later, say, if we want to allow spaces - * and/or other characters to be escaped in the string. Also, the new entries - * would have been ignored by old versions of CVS anyhow since those versions - * didn't know how to parse a port number. - * - * The "A" before "encoded_password" is a literal capital A. It's a - * version number indicating which form of scrambling we're doing on - * the password -- someday we might provide something more secure than - * the trivial encoding we do now, and when that day comes, it would - * be nice to remain backward-compatible. - * - * Like .netrc, the file's permissions are the only thing preventing - * it from being read by others. Unlike .netrc, we will not be - * fascist about it, at most issuing a warning, and never refusing to - * work. - * - * INPUTS - * operation operation to perform - * root cvsroot_t to look up - * newpassword prescrambled new password, for password_entry_add_mode - * - * RETURNS - * -1 if password_entry_lookup_mode not specified - * NULL on failed lookup - * pointer to a copy of the password string otherwise, which the caller is - * responsible for disposing of - */ - -typedef enum password_entry_operation_e { - password_entry_lookup, - password_entry_delete, - password_entry_add -} password_entry_operation_t; - -static char * -password_entry_operation (operation, root, newpassword) - password_entry_operation_t operation; - cvsroot_t *root; - char *newpassword; -{ - char *passfile; - FILE *fp; - char *cvsroot_canonical = NULL; - char *password = NULL; - int line_length; - long line = -1; - char *linebuf = NULL; - size_t linebuf_len; - char *p; - int save_errno = 0; - - if (root->method != pserver_method) - { - error (0, 0, "\ -internal error: can only call password_entry_operation with pserver method"); - error (1, 0, "CVSROOT: %s", root->original); - } - - cvsroot_canonical = normalize_cvsroot (root); - - /* Yes, the method below reads the user's password file twice when we have - * to delete an entry. It's inefficient, but we're not talking about a gig of - * data here. - */ - - passfile = construct_cvspass_filename (); - fp = CVS_FOPEN (passfile, "r"); - if (fp == NULL) - { - error (0, errno, "warning: failed to open %s for reading", passfile); - goto process; - } - - /* Check each line to see if we have this entry already. */ - line = 0; - while ((line_length = getline (&linebuf, &linebuf_len, fp)) >= 0) - { - line++; - password = password_entry_parseline (cvsroot_canonical, 1, line, - linebuf); - if (password != NULL) - /* this is it! break out and deal with linebuf */ - break; - } - if (line_length < 0 && !feof (fp)) - { - error (0, errno, "cannot read %s", passfile); - goto error_exit; - } - if (fclose (fp) < 0) - /* not fatal, unless it cascades */ - error (0, errno, "cannot close %s", passfile); - fp = NULL; - - /* Utter, total, raving paranoia, I know. */ - chmod (passfile, 0600); - - /* a copy to return or keep around so we can reuse linebuf */ - if (password != NULL) - { - /* chomp the EOL */ - p = strchr (password, '\n'); - if (p != NULL) - *p = '\0'; - password = xstrdup (password); - } - -process: - - /* might as well return now */ - if (operation == password_entry_lookup) - goto out; - - /* same here */ - if (operation == password_entry_delete && password == NULL) - { - error (0, 0, "Entry not found."); - goto out; - } - - /* okay, file errors can simply be fatal from now on since we don't do - * anything else if we're in lookup mode - */ - - /* copy the file with the entry deleted unless we're in add - * mode and the line we found contains the same password we're supposed to - * add - */ - if (!noexec && password != NULL && (operation == password_entry_delete - || (operation == password_entry_add - && strcmp (password, newpassword)))) - { - long found_at = line; - char *tmp_name; - FILE *tmp_fp; - - /* open the original file again */ - fp = CVS_FOPEN (passfile, "r"); - if (fp == NULL) - error (1, errno, "failed to open %s for reading", passfile); - - /* create and open a temp file */ - if ((tmp_fp = cvs_temp_file (&tmp_name)) == NULL) - error (1, errno, "unable to open temp file %s", - tmp_name ? tmp_name : "(null)"); - - line = 0; - while ((line_length = getline (&linebuf, &linebuf_len, fp)) >= 0) - { - line++; - if (line < found_at - || (line != found_at - && !password_entry_parseline (cvsroot_canonical, 0, line, - linebuf))) - { - if (fprintf (tmp_fp, "%s", linebuf) == EOF) - { - /* try and clean up anyhow */ - error (0, errno, "fatal error: cannot write %s", tmp_name); - if (fclose (tmp_fp) == EOF) - error (0, errno, "cannot close %s", tmp_name); - /* call CVS_UNLINK instead of unlink_file since the file - * got created in noexec mode - */ - if (CVS_UNLINK (tmp_name) < 0) - error (0, errno, "cannot remove %s", tmp_name); - /* but quit so we don't remove all the entries from a - * user's password file accidentally - */ - error (1, 0, "exiting"); - } - } - } - if (line_length < 0 && !feof (fp)) - { - error (0, errno, "cannot read %s", passfile); - goto error_exit; - } - if (fclose (fp) < 0) - /* not fatal, unless it cascades */ - error (0, errno, "cannot close %s", passfile); - if (fclose (tmp_fp) < 0) - /* not fatal, unless it cascades */ - /* FIXME - does copy_file return correct results if the file wasn't - * closed? should this be fatal? - */ - error (0, errno, "cannot close %s", tmp_name); - - /* FIXME: rename_file would make more sense (e.g. almost - * always faster). - * - * I don't think so, unless we change the way rename_file works to - * attempt a cp/rm sequence when rename fails since rename doesn't - * work across file systems and it isn't uncommon to have /tmp - * on its own partition. - * - * For that matter, it's probably not uncommon to have a home - * directory on an NFS mount. - */ - copy_file (tmp_name, passfile); - if (CVS_UNLINK (tmp_name) < 0) - error (0, errno, "cannot remove %s", tmp_name); - free (tmp_name); - } - - /* in add mode, if we didn't find an entry or found an entry with a - * different password, append the new line - */ - if (!noexec && operation == password_entry_add - && (password == NULL || strcmp (password, newpassword))) - { - if ((fp = CVS_FOPEN (passfile, "a")) == NULL) - error (1, errno, "could not open %s for writing", passfile); - - if (fprintf (fp, "/1 %s %s\n", cvsroot_canonical, newpassword) == EOF) - error (1, errno, "cannot write %s", passfile); - if (fclose (fp) < 0) - error (1, errno, "cannot close %s", passfile); - } - - /* Utter, total, raving paranoia, I know. */ - chmod (passfile, 0600); - - if (password) - { - free (password); - password = NULL; - } - if (linebuf) - free (linebuf); - -out: - free (cvsroot_canonical); - free (passfile); - return password; - -error_exit: - /* just exit when we're not in lookup mode */ - if (operation != password_entry_lookup) - error (1, 0, "fatal error: exiting"); - /* clean up and exit in lookup mode so we can try a login with a NULL - * password anyhow in case that's what we would have found - */ - save_errno = errno; - if (fp != NULL) - { - /* Utter, total, raving paranoia, I know. */ - chmod (passfile, 0600); - if(fclose (fp) < 0) - error (0, errno, "cannot close %s", passfile); - } - if (linebuf) - free (linebuf); - if (cvsroot_canonical) - free (cvsroot_canonical); - free (passfile); - errno = save_errno; - return NULL; -} - - - -/* Prompt for a password, and store it in the file "CVS/.cvspass". - */ - -static const char *const login_usage[] = -{ - "Usage: %s %s\n", - "(Specify the --help global option for a list of other help options)\n", - NULL -}; - -int -login (argc, argv) - int argc; - char **argv; -{ - char *typed_password; - char *cvsroot_canonical; - - if (argc < 0) - usage (login_usage); - - if (current_parsed_root->method != pserver_method) - { - error (0, 0, "can only use `login' command with the 'pserver' method"); - error (1, 0, "CVSROOT: %s", current_parsed_root->original); - } - - cvsroot_canonical = normalize_cvsroot(current_parsed_root); - printf ("Logging in to %s\n", cvsroot_canonical); - fflush (stdout); - - if (current_parsed_root->password) - { - typed_password = scramble (current_parsed_root->password); - } - else - { - char *tmp; - tmp = getpass ("CVS password: "); - /* Must deal with a NULL return value here. I haven't managed to - * disconnect the CVS process from the tty and force a NULL return - * in sanity.sh, but the Linux version of getpass is documented - * to return NULL when it can't open /dev/tty... - */ - if (!tmp) error (1, errno, "login: Failed to read password."); - typed_password = scramble (tmp); - memset (tmp, 0, strlen (tmp)); - } - - /* Force get_cvs_password() to use this one (when the client - * confirms the new password with the server), instead of - * consulting the file. We make a new copy because cvs_password - * will get zeroed by connect_to_server(). */ - cvs_password = xstrdup (typed_password); - - connect_to_pserver (current_parsed_root, NULL, NULL, 1, 0); - - password_entry_operation (password_entry_add, current_parsed_root, - typed_password); - - free_cvs_password (typed_password); - free (cvsroot_canonical); - - return 0; -} - - - -/* Free the password returned by get_cvs_password() and also free the - * saved cvs_password if they are different pointers. Be paranoid - * about the in-memory copy of the password and overwrite it with zero - * bytes before doing the free(). - */ -void -free_cvs_password (char *password) -{ - if (password && password != cvs_password) - { - memset (password, 0, strlen (password)); - free (password); - } - - if (cvs_password) - { - memset (cvs_password, 0, strlen (cvs_password)); - free (cvs_password); - cvs_password = NULL; - } -} - -/* Returns the _scrambled_ password in freshly allocated memory. The server - * must descramble before hashing and comparing. If password file not found, - * or password not found in the file, just return NULL. - */ -char * -get_cvs_password () -{ - if (current_parsed_root->password) - return scramble (current_parsed_root->password); - - /* If someone (i.e., login()) is calling connect_to_pserver() out of - context, then assume they have supplied the correct, scrambled - password. */ - if (cvs_password) - return xstrdup (cvs_password); - - if (getenv ("CVS_PASSWORD") != NULL) - { - /* In previous versions of CVS one could specify a password in - * CVS_PASSWORD. This is a bad idea, because in BSD variants - * of unix anyone can see the environment variable with 'ps'. - * But for users who were using that feature we want to at - * least let them know what is going on. After printing this - * warning, we should fall through to the regular error where - * we tell them to run "cvs login" (unless they already ran - * it, of course). - */ - error (0, 0, "CVS_PASSWORD is no longer supported; ignored"); - } - - if (current_parsed_root->method != pserver_method) - { - error (0, 0, "can only call get_cvs_password with pserver method"); - error (1, 0, "CVSROOT: %s", current_parsed_root->original); - } - - return password_entry_operation (password_entry_lookup, - current_parsed_root, NULL); -} - - - -static const char *const logout_usage[] = -{ - "Usage: %s %s\n", - "(Specify the --help global option for a list of other help options)\n", - NULL -}; - -/* Remove any entry for the CVSRoot repository found in .cvspass. */ -int -logout (argc, argv) - int argc; - char **argv; -{ - char *cvsroot_canonical; - - if (argc < 0) - usage (logout_usage); - - if (current_parsed_root->method != pserver_method) - { - error (0, 0, "can only use pserver method with `logout' command"); - error (1, 0, "CVSROOT: %s", current_parsed_root->original); - } - - /* Hmm. Do we want a variant of this command which deletes _all_ - the entries from the current .cvspass? Might be easier to - remember than "rm ~/.cvspass" but then again if people are - mucking with HOME (common in Win95 as the system doesn't set - it), then this variant of "cvs logout" might give a false sense - of security, in that it wouldn't delete entries from any - .cvspass files but the current one. */ - - if (!quiet) - { - cvsroot_canonical = normalize_cvsroot(current_parsed_root); - printf ("Logging out of %s\n", cvsroot_canonical); - fflush (stdout); - free (cvsroot_canonical); - } - - password_entry_operation (password_entry_delete, current_parsed_root, NULL); - - return 0; -} - -#endif /* AUTH_CLIENT_SUPPORT from beginning of file. */ diff --git a/contrib/cvs/src/logmsg.c b/contrib/cvs/src/logmsg.c deleted file mode 100644 index 6878aaf..0000000 --- a/contrib/cvs/src/logmsg.c +++ /dev/null @@ -1,988 +0,0 @@ -/* - * Copyright (C) 1986-2005 The Free Software Foundation, Inc. - * - * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot , - * and others. - * - * Portions Copyright (C) 1992, Brian Berliner and Jeff Polk - * Portions Copyright (C) 1989-1992, Brian Berliner - * - * You may distribute under the terms of the GNU General Public License as - * specified in the README file that comes with the CVS source distribution. - * - * $FreeBSD$ - */ - -#include - -#include "cvs.h" -#include "getline.h" - -static int find_type PROTO((Node * p, void *closure)); -static int fmt_proc PROTO((Node * p, void *closure)); -static int logfile_write PROTO((const char *repository, const char *filter, - const char *message, FILE * logfp, - List * changes)); -static int rcsinfo_proc PROTO((const char *repository, const char *template)); -static int title_proc PROTO((Node * p, void *closure)); -static int update_logfile_proc PROTO((const char *repository, - const char *filter)); -static void setup_tmpfile PROTO((FILE * xfp, char *xprefix, List * changes)); -static int editinfo_proc PROTO((const char *repository, const char *template)); -static int verifymsg_proc PROTO((const char *repository, const char *script)); - -static FILE *fp; -static char *str_list; -static char *str_list_format; /* The format for str_list's contents. */ -static char *editinfo_editor; -static char *verifymsg_script; -static Ctype type; - -/* - * Should the logmsg be re-read during the do_verify phase? - * RereadLogAfterVerify=no|stat|yes - * LOGMSG_REREAD_NEVER - never re-read the logmsg - * LOGMSG_REREAD_STAT - re-read the logmsg only if it has changed - * LOGMSG_REREAD_ALWAYS - always re-read the logmsg - */ -int RereadLogAfterVerify = LOGMSG_REREAD_ALWAYS; - -/* - * Puts a standard header on the output which is either being prepared for an - * editor session, or being sent to a logfile program. The modified, added, - * and removed files are included (if any) and formatted to look pretty. */ -static char *prefix; -static int col; -static char *tag; -static void -setup_tmpfile (xfp, xprefix, changes) - FILE *xfp; - char *xprefix; - List *changes; -{ - /* set up statics */ - fp = xfp; - prefix = xprefix; - - type = T_MODIFIED; - if (walklist (changes, find_type, NULL) != 0) - { - (void) fprintf (fp, "%sModified Files:\n", prefix); - col = 0; - (void) walklist (changes, fmt_proc, NULL); - (void) fprintf (fp, "\n"); - if (tag != NULL) - { - free (tag); - tag = NULL; - } - } - type = T_ADDED; - if (walklist (changes, find_type, NULL) != 0) - { - (void) fprintf (fp, "%sAdded Files:\n", prefix); - col = 0; - (void) walklist (changes, fmt_proc, NULL); - (void) fprintf (fp, "\n"); - if (tag != NULL) - { - free (tag); - tag = NULL; - } - } - type = T_REMOVED; - if (walklist (changes, find_type, NULL) != 0) - { - (void) fprintf (fp, "%sRemoved Files:\n", prefix); - col = 0; - (void) walklist (changes, fmt_proc, NULL); - (void) fprintf (fp, "\n"); - if (tag != NULL) - { - free (tag); - tag = NULL; - } - } -} - -/* - * Looks for nodes of a specified type and returns 1 if found - */ -static int -find_type (p, closure) - Node *p; - void *closure; -{ - struct logfile_info *li = p->data; - - if (li->type == type) - return (1); - else - return (0); -} - -/* - * Breaks the files list into reasonable sized lines to avoid line wrap... - * all in the name of pretty output. It only works on nodes whose types - * match the one we're looking for - */ -static int -fmt_proc (p, closure) - Node *p; - void *closure; -{ - struct logfile_info *li; - - li = p->data; - if (li->type == type) - { - if (li->tag == NULL - ? tag != NULL - : tag == NULL || strcmp (tag, li->tag) != 0) - { - if (col > 0) - (void) fprintf (fp, "\n"); - (void) fputs (prefix, fp); - col = strlen (prefix); - while (col < 6) - { - (void) fprintf (fp, " "); - ++col; - } - - if (li->tag == NULL) - (void) fprintf (fp, "No tag"); - else - (void) fprintf (fp, "Tag: %s", li->tag); - - if (tag != NULL) - free (tag); - tag = xstrdup (li->tag); - - /* Force a new line. */ - col = 70; - } - - if (col == 0) - { - (void) fprintf (fp, "%s\t", prefix); - col = 8; - } - else if (col > 8 && (col + (int) strlen (p->key)) > 70) - { - (void) fprintf (fp, "\n%s\t", prefix); - col = 8; - } - (void) fprintf (fp, "%s ", p->key); - col += strlen (p->key) + 1; - } - return (0); -} - -/* - * Builds a temporary file using setup_tmpfile() and invokes the user's - * editor on the file. The header garbage in the resultant file is then - * stripped and the log message is stored in the "message" argument. - * - * If REPOSITORY is non-NULL, process rcsinfo for that repository; if it - * is NULL, use the CVSADM_TEMPLATE file instead. REPOSITORY should be - * NULL when running in client mode. - */ -void -do_editor (dir, messagep, repository, changes) - const char *dir; - char **messagep; - const char *repository; - List *changes; -{ - static int reuse_log_message = 0; - char *line; - int line_length; - size_t line_chars_allocated; - char *fname; - struct stat pre_stbuf, post_stbuf; - int retcode = 0; - - assert (!current_parsed_root->isremote != !repository); - - if (noexec || reuse_log_message) - return; - - /* Abort creation of temp file if no editor is defined */ - if (strcmp (Editor, "") == 0 && !editinfo_editor) - error(1, 0, "no editor defined, must use -e or -m"); - - /* Create a temporary file */ - /* FIXME - It's possible we should be relying on cvs_temp_file to open - * the file here - we get race conditions otherwise. - */ - fname = cvs_temp_name (); - again: - if ((fp = CVS_FOPEN (fname, "w+")) == NULL) - error (1, 0, "cannot create temporary file %s", fname); - - if (*messagep) - { - (void) fputs (*messagep, fp); - - if ((*messagep)[0] == '\0' || - (*messagep)[strlen (*messagep) - 1] != '\n') - (void) fprintf (fp, "\n"); - } - else - (void) fprintf (fp, "\n"); - - if (repository != NULL) - /* tack templates on if necessary */ - (void) Parse_Info (CVSROOTADM_RCSINFO, repository, rcsinfo_proc, 1); - else - { - FILE *tfp; - char buf[1024]; - size_t n; - size_t nwrite; - - /* Why "b"? */ - tfp = CVS_FOPEN (CVSADM_TEMPLATE, "rb"); - if (tfp == NULL) - { - if (!existence_error (errno)) - error (1, errno, "cannot read %s", CVSADM_TEMPLATE); - } - else - { - while (!feof (tfp)) - { - char *p = buf; - n = fread (buf, 1, sizeof buf, tfp); - nwrite = n; - while (nwrite > 0) - { - n = fwrite (p, 1, nwrite, fp); - nwrite -= n; - p += n; - } - if (ferror (tfp)) - error (1, errno, "cannot read %s", CVSADM_TEMPLATE); - } - if (fclose (tfp) < 0) - error (0, errno, "cannot close %s", CVSADM_TEMPLATE); - } - } - - (void) fprintf (fp, - "%s----------------------------------------------------------------------\n", - CVSEDITPREFIX); - (void) fprintf (fp, - "%sEnter Log. Lines beginning with `%.*s' are removed automatically\n%s\n", - CVSEDITPREFIX, CVSEDITPREFIXLEN, CVSEDITPREFIX, - CVSEDITPREFIX); - if (dir != NULL && *dir) - (void) fprintf (fp, "%sCommitting in %s\n%s\n", CVSEDITPREFIX, - dir, CVSEDITPREFIX); - if (changes != NULL) - setup_tmpfile (fp, CVSEDITPREFIX, changes); - (void) fprintf (fp, - "%s----------------------------------------------------------------------\n", - CVSEDITPREFIX); - - /* finish off the temp file */ - if (fclose (fp) == EOF) - error (1, errno, "%s", fname); - if ( CVS_STAT (fname, &pre_stbuf) == -1) - pre_stbuf.st_mtime = 0; - - if (editinfo_editor) - free (editinfo_editor); - editinfo_editor = (char *) NULL; - if (!current_parsed_root->isremote && repository != NULL) - (void) Parse_Info (CVSROOTADM_EDITINFO, repository, editinfo_proc, 0); - - /* run the editor */ - run_setup (editinfo_editor ? editinfo_editor : Editor); - run_arg (fname); - if ((retcode = run_exec (RUN_TTY, RUN_TTY, RUN_TTY, - RUN_NORMAL | RUN_SIGIGNORE)) != 0) - error (editinfo_editor ? 1 : 0, retcode == -1 ? errno : 0, - editinfo_editor ? "Logfile verification failed" : - "warning: editor session failed"); - - /* put the entire message back into the *messagep variable */ - - fp = open_file (fname, "r"); - - if (*messagep) - free (*messagep); - - if ( CVS_STAT (fname, &post_stbuf) != 0) - error (1, errno, "cannot find size of temp file %s", fname); - - if (post_stbuf.st_size == 0) - *messagep = NULL; - else - { - /* On NT, we might read less than st_size bytes, but we won't - read more. So this works. */ - *messagep = (char *) xmalloc (post_stbuf.st_size + 1); - (*messagep)[0] = '\0'; - } - - line = NULL; - line_chars_allocated = 0; - - if (*messagep) - { - size_t message_len = post_stbuf.st_size + 1; - size_t offset = 0; - while (1) - { - line_length = getline (&line, &line_chars_allocated, fp); - if (line_length == -1) - { - if (ferror (fp)) - error (0, errno, "warning: cannot read %s", fname); - break; - } - if (strncmp (line, CVSEDITPREFIX, CVSEDITPREFIXLEN) == 0) - continue; - 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) - error (0, errno, "warning: cannot close %s", fname); - - /* canonicalize emply messages */ - if (*messagep != NULL && - (**messagep == '\0' || strcmp (*messagep, "\n") == 0)) - { - free (*messagep); - *messagep = NULL; - } - - if (pre_stbuf.st_mtime == post_stbuf.st_mtime || *messagep == NULL) - { - for (;;) - { - (void) printf ("\nLog message unchanged or not specified\n"); - (void) printf ("a)bort, c)ontinue, e)dit, !)reuse this message unchanged for remaining dirs\n"); - (void) printf ("Action: (continue) "); - (void) fflush (stdout); - line_length = getline (&line, &line_chars_allocated, stdin); - if (line_length < 0) - { - error (0, errno, "cannot read from stdin"); - if (unlink_file (fname) < 0) - error (0, errno, - "warning: cannot remove temp file %s", fname); - error (1, 0, "aborting"); - } - else if (line_length == 0 - || *line == '\n' || *line == 'c' || *line == 'C') - break; - if (*line == 'a' || *line == 'A') - { - if (unlink_file (fname) < 0) - error (0, errno, "warning: cannot remove temp file %s", fname); - error (1, 0, "aborted by user"); - } - if (*line == 'e' || *line == 'E') - goto again; - if (*line == '!') - { - reuse_log_message = 1; - break; - } - (void) printf ("Unknown input\n"); - } - } - if (line) - free (line); - if (unlink_file (fname) < 0) - error (0, errno, "warning: cannot remove temp file %s", fname); - free (fname); -} - -/* Runs the user-defined verification script as part of the commit or import - process. This verification is meant to be run whether or not the user - included the -m atribute. unlike the do_editor function, this is - independant of the running of an editor for getting a message. - */ -void -do_verify (messagep, repository) - char **messagep; - const char *repository; -{ - FILE *fp; - char *fname; - int retcode = 0; - - struct stat pre_stbuf, post_stbuf; - - if (current_parsed_root->isremote) - /* The verification will happen on the server. */ - return; - - /* FIXME? Do we really want to skip this on noexec? What do we do - for the other administrative files? */ - if (noexec || repository == NULL) - return; - - /* Get the name of the verification script to run */ - - if (Parse_Info (CVSROOTADM_VERIFYMSG, repository, verifymsg_proc, 0) > 0) - error (1, 0, "Message verification failed"); - - if (!verifymsg_script) - return; - - /* open a temporary file, write the message to the - temp file, and close the file. */ - - if ((fp = cvs_temp_file (&fname)) == NULL) - error (1, errno, "cannot create temporary file %s", - fname ? fname : "(null)"); - - if (*messagep != NULL) - fputs (*messagep, fp); - if (*messagep == NULL || - (*messagep)[0] == '\0' || - (*messagep)[strlen (*messagep) - 1] != '\n') - putc ('\n', fp); - if (fclose (fp) == EOF) - error (1, errno, "%s", fname); - - if (RereadLogAfterVerify == LOGMSG_REREAD_STAT) - { - /* Remember the status of the temp file for later */ - if ( CVS_STAT (fname, &pre_stbuf) != 0 ) - error (1, errno, "cannot stat temp file %s", fname); - - /* - * See if we need to sleep before running the verification - * script to avoid time-stamp races. - */ - sleep_past (pre_stbuf.st_mtime); - } - - run_setup (verifymsg_script); - run_arg (fname); - if ((retcode = run_exec (RUN_TTY, RUN_TTY, RUN_TTY, - RUN_NORMAL | RUN_SIGIGNORE)) != 0) - { - /* Since following error() exits, delete the temp file now. */ - if (unlink_file (fname) < 0) - error (0, errno, "cannot remove %s", fname); - - error (1, retcode == -1 ? errno : 0, - "Message verification failed"); - } - - /* Get the mod time and size of the possibly new log message - * in always and stat modes. - */ - if (RereadLogAfterVerify == LOGMSG_REREAD_ALWAYS || - RereadLogAfterVerify == LOGMSG_REREAD_STAT) - { - if ( CVS_STAT (fname, &post_stbuf) != 0 ) - error (1, errno, "cannot find size of temp file %s", fname); - } - - /* And reread the log message in `always' mode or in `stat' mode when it's - * changed - */ - if (RereadLogAfterVerify == LOGMSG_REREAD_ALWAYS || - (RereadLogAfterVerify == LOGMSG_REREAD_STAT && - (pre_stbuf.st_mtime != post_stbuf.st_mtime || - pre_stbuf.st_size != post_stbuf.st_size))) - { - /* put the entire message back into the *messagep variable */ - - if (*messagep) free (*messagep); - - if (post_stbuf.st_size == 0) - *messagep = NULL; - else - { - char *line = NULL; - int line_length; - size_t line_chars_allocated = 0; - char *p; - - if ( (fp = open_file (fname, "r")) == NULL ) - error (1, errno, "cannot open temporary file %s", fname); - - /* On NT, we might read less than st_size bytes, - but we won't read more. So this works. */ - p = *messagep = (char *) xmalloc (post_stbuf.st_size + 1); - *messagep[0] = '\0'; - - while (1) - { - line_length = getline (&line, - &line_chars_allocated, - fp); - if (line_length == -1) - { - if (ferror (fp)) - /* Fail in this case because otherwise we will have no - * log message - */ - error (1, errno, "cannot read %s", fname); - break; - } - if (strncmp (line, CVSEDITPREFIX, CVSEDITPREFIXLEN) == 0) - continue; - (void) strcpy (p, line); - p += line_length; - } - if (line) free (line); - if (fclose (fp) < 0) - error (0, errno, "warning: cannot close %s", fname); - } - } - - /* Delete the temp file */ - - if (unlink_file (fname) < 0) - error (0, errno, "cannot remove %s", fname); - free (fname); - free (verifymsg_script); - verifymsg_script = NULL; -} - -/* - * callback proc for Parse_Info for rcsinfo templates this routine basically - * copies the matching template onto the end of the tempfile we are setting - * up - */ -/* ARGSUSED */ -static int -rcsinfo_proc (repository, template) - const char *repository; - const char *template; -{ - static char *last_template; - FILE *tfp; - - /* nothing to do if the last one included is the same as this one */ - if (last_template && strcmp (last_template, template) == 0) - return (0); - if (last_template) - free (last_template); - last_template = xstrdup (template); - - if ((tfp = CVS_FOPEN (template, "r")) != NULL) - { - char *line = NULL; - size_t line_chars_allocated = 0; - - while (getline (&line, &line_chars_allocated, tfp) >= 0) - (void) fputs (line, fp); - if (ferror (tfp)) - error (0, errno, "warning: cannot read %s", template); - if (fclose (tfp) < 0) - error (0, errno, "warning: cannot close %s", template); - if (line) - free (line); - return (0); - } - else - { - error (0, errno, "Couldn't open rcsinfo template file %s", template); - return (1); - } -} - -/* - * Uses setup_tmpfile() to pass the updated message on directly to any - * logfile programs that have a regular expression match for the checked in - * directory in the source repository. The log information is fed into the - * specified program as standard input. - */ -static FILE *logfp; -static const char *message; -static List *changes; - -void -Update_Logfile (repository, xmessage, xlogfp, xchanges) - const char *repository; - const char *xmessage; - FILE *xlogfp; - List *xchanges; -{ - /* nothing to do if the list is empty */ - if (xchanges == NULL || xchanges->list->next == xchanges->list) - return; - - /* set up static vars for update_logfile_proc */ - message = xmessage; - logfp = xlogfp; - changes = xchanges; - - /* call Parse_Info to do the actual logfile updates */ - (void) Parse_Info (CVSROOTADM_LOGINFO, repository, update_logfile_proc, 1); -} - - - -/* - * callback proc to actually do the logfile write from Update_Logfile - */ -static int -update_logfile_proc (repository, filter) - const char *repository; - const char *filter; -{ - return logfile_write (repository, filter, message, logfp, changes); -} - - - -/* - * concatenate each filename/version onto str_list - */ -static int -title_proc (p, closure) - Node *p; - void *closure; -{ - char *c; - struct logfile_info *li = p->data; - - if (li->type == type) - { - /* Until we decide on the correct logging solution when we add - directories or perform imports, T_TITLE nodes will only - tack on the name provided, regardless of the format string. - You can verify that this assumption is safe by checking the - code in add.c (add_directory) and import.c (import). */ - - str_list = xrealloc (str_list, strlen (str_list) + 5); - (void) strcat (str_list, " "); - - if (li->type == T_TITLE) - { - str_list = xrealloc (str_list, - strlen (str_list) + strlen (p->key) + 5); - (void) strcat (str_list, p->key); - } - else - { - /* All other nodes use the format string. */ - - for (c = str_list_format; *c != '\0'; c++) - { - switch (*c) - { - case 's': - str_list = - xrealloc (str_list, - strlen (str_list) + strlen (p->key) + 5); - (void) strcat (str_list, p->key); - break; - case 'V': - str_list = - xrealloc (str_list, - (strlen (str_list) - + (li->rev_old ? strlen (li->rev_old) : 0) - + 10) - ); - (void) strcat (str_list, (li->rev_old - ? li->rev_old : "NONE")); - break; - case 'v': - str_list = - xrealloc (str_list, - (strlen (str_list) - + (li->rev_new ? strlen (li->rev_new) : 0) - + 10) - ); - (void) strcat (str_list, (li->rev_new - ? li->rev_new : "NONE")); - break; - /* All other characters, we insert an empty field (but - we do put in the comma separating it from other - fields). This way if future CVS versions add formatting - characters, one can write a loginfo file which at least - won't blow up on an old CVS. */ - /* Note that people who have to deal with spaces in file - and directory names are using space to get a known - delimiter for the directory name, so it's probably - not a good idea to ever define that as a formatting - character. */ - } - if (*(c + 1) != '\0') - { - str_list = xrealloc (str_list, strlen (str_list) + 5); - (void) strcat (str_list, ","); - } - } - } - } - return (0); -} - -/* - * Writes some stuff to the logfile "filter" and returns the status of the - * filter program. - */ -static int -logfile_write (repository, filter, message, logfp, changes) - const char *repository; - const char *filter; - const char *message; - FILE *logfp; - List *changes; -{ - FILE *pipefp; - char *prog; - char *cp; - int c; - int pipestatus; - char *fmt_percent; /* the location of the percent sign - that starts the format string. */ - - assert (repository); - - /* The user may specify a format string as part of the filter. - Originally, `%s' was the only valid string. The string that - was substituted for it was: - - ... - - Each file was either a new directory/import (T_TITLE), or a - added (T_ADDED), modified (T_MODIFIED), or removed (T_REMOVED) - file. - - It is desirable to preserve that behavior so lots of commitlog - scripts won't die when they get this new code. At the same - time, we'd like to pass other information about the files (like - version numbers, statuses, or checkin times). - - The solution is to allow a format string that allows us to - specify those other pieces of information. The format string - will be composed of `%' followed by a single format character, - or followed by a set of format characters surrounded by `{' and - `}' as separators. The format characters are: - - s = file name - V = old version number (pre-checkin) - v = new version number (post-checkin) - - For example, valid format strings are: - - %{} - %s - %{s} - %{sVv} - - There's no reason that more items couldn't be added (like - modification date or file status [added, modified, updated, - etc.]) -- the code modifications would be minimal (logmsg.c - (title_proc) and commit.c (check_fileproc)). - - The output will be a string of tokens separated by spaces. For - backwards compatibility, the the first token will be the - repository name. The rest of the tokens will be - comma-delimited lists of the information requested in the - format string. For example, if `/u/src/master' is the - repository, `%{sVv}' is the format string, and three files - (ChangeLog, Makefile, foo.c) were modified, the output might - be: - - /u/src/master ChangeLog,1.1,1.2 Makefile,1.3,1.4 foo.c,1.12,1.13 - - Why this duplicates the old behavior when the format string is - `%s' is left as an exercise for the reader. */ - - fmt_percent = strchr (filter, '%'); - if (fmt_percent) - { - int len; - const char *srepos; - char *fmt_begin, *fmt_end; /* beginning and end of the - format string specified in - filter. */ - char *fmt_continue; /* where the string continues - after the format string (we - might skip a '}') somewhere - in there... */ - - /* Grab the format string. */ - - if ((*(fmt_percent + 1) == ' ') || (*(fmt_percent + 1) == '\0')) - { - /* The percent stands alone. This is an error. We could - be treating ' ' like any other formatting character, but - using it as a formatting character seems like it would be - a mistake. */ - - /* Would be nice to also be giving the line number. */ - error (0, 0, "loginfo: '%%' not followed by formatting character"); - fmt_begin = fmt_percent + 1; - fmt_end = fmt_begin; - fmt_continue = fmt_begin; - } - else if (*(fmt_percent + 1) == '{') - { - /* The percent has a set of characters following it. */ - - fmt_begin = fmt_percent + 2; - fmt_end = strchr (fmt_begin, '}'); - if (fmt_end) - { - /* Skip over the '}' character. */ - - fmt_continue = fmt_end + 1; - } - else - { - /* There was no close brace -- assume that format - string continues to the end of the line. */ - - /* Would be nice to also be giving the line number. */ - error (0, 0, "loginfo: '}' missing"); - fmt_end = fmt_begin + strlen (fmt_begin); - fmt_continue = fmt_end; - } - } - else - { - /* The percent has a single character following it. FIXME: - %% should expand to a regular percent sign. */ - - fmt_begin = fmt_percent + 1; - fmt_end = fmt_begin + 1; - fmt_continue = fmt_end; - } - - len = fmt_end - fmt_begin; - str_list_format = xmalloc (len + 1); - strncpy (str_list_format, fmt_begin, len); - str_list_format[len] = '\0'; - - /* Allocate an initial chunk of memory. As we build up the string - we will realloc it. */ - if (!str_list) - str_list = xmalloc (1); - str_list[0] = '\0'; - - /* Add entries to the string. Don't bother looking for - entries if the format string is empty. */ - - if (str_list_format[0] != '\0') - { - type = T_TITLE; - (void) walklist (changes, title_proc, NULL); - type = T_ADDED; - (void) walklist (changes, title_proc, NULL); - type = T_MODIFIED; - (void) walklist (changes, title_proc, NULL); - type = T_REMOVED; - (void) walklist (changes, title_proc, NULL); - } - - free (str_list_format); - - /* Construct the final string. */ - - srepos = Short_Repository (repository); - - prog = cp = xmalloc ((fmt_percent - filter) + 2 * strlen (srepos) - + 2 * strlen (str_list) + strlen (fmt_continue) - + 10); - (void) memcpy (cp, filter, fmt_percent - filter); - cp += fmt_percent - filter; - *cp++ = '"'; - cp = shell_escape (cp, srepos); - cp = shell_escape (cp, str_list); - *cp++ = '"'; - (void) strcpy (cp, fmt_continue); - - /* To be nice, free up some memory. */ - - free (str_list); - str_list = (char *) NULL; - } - else - { - /* There's no format string. */ - prog = xstrdup (filter); - } - - if ((pipefp = run_popen (prog, "w")) == NULL) - { - if (!noexec) - error (0, 0, "cannot write entry to log filter: %s", prog); - free (prog); - return (1); - } - (void) fprintf (pipefp, "Update of %s\n", repository); - (void) fprintf (pipefp, "In directory %s:", hostname); - cp = xgetwd (); - if (cp == NULL) - fprintf (pipefp, "\n\n", - strerror (errno)); - else - { - fprintf (pipefp, "%s\n\n", cp); - free (cp); - } - - setup_tmpfile (pipefp, "", changes); - (void) fprintf (pipefp, "Log Message:\n%s\n", (message) ? message : ""); - if (logfp != (FILE *) 0) - { - (void) fprintf (pipefp, "Status:\n"); - rewind (logfp); - while ((c = getc (logfp)) != EOF) - (void) putc ((char) c, pipefp); - } - free (prog); - pipestatus = pclose (pipefp); - return ((pipestatus == -1) || (pipestatus == 127)) ? 1 : 0; -} - -/* - * We choose to use the *last* match within the editinfo file for this - * repository. This allows us to have a global editinfo program for the - * root of some hierarchy, for example, and different ones within different - * sub-directories of the root (like a special checker for changes made to - * the "src" directory versus changes made to the "doc" or "test" - * directories. - */ -/* ARGSUSED */ -static int -editinfo_proc(repository, editor) - const char *repository; - const char *editor; -{ - /* nothing to do if the last match is the same as this one */ - if (editinfo_editor && strcmp (editinfo_editor, editor) == 0) - return (0); - if (editinfo_editor) - free (editinfo_editor); - - editinfo_editor = xstrdup (editor); - return (0); -} - -/* This routine is calld by Parse_Info. it asigns the name of the - * message verification script to the global variable verify_script - */ -static int -verifymsg_proc (repository, script) - const char *repository; - const char *script; -{ - if (verifymsg_script && strcmp (verifymsg_script, script) == 0) - return (0); - if (verifymsg_script) - free (verifymsg_script); - verifymsg_script = xstrdup (script); - return (0); -} diff --git a/contrib/cvs/src/main.c b/contrib/cvs/src/main.c deleted file mode 100644 index 332946a..0000000 --- a/contrib/cvs/src/main.c +++ /dev/null @@ -1,1240 +0,0 @@ -/* - * Copyright (C) 1986-2008 The Free Software Foundation, Inc. - * - * Portions Copyright (C) 1998-2006 Derek Price, Ximbiot , - * and others. - * - * Portions Copyright (C) 1992, Brian Berliner and Jeff Polk - * Portions Copyright (C) 1989-1992, Brian Berliner - * - * You may distribute under the terms of the GNU General Public License - * as specified in the README file that comes with the CVS source distribution. - * - * This is the main C driver for the CVS system. - * - * Credit to Dick Grune, Vrije Universiteit, Amsterdam, for writing - * the shell-script CVS system that this is based on. - * - * $FreeBSD$ - */ - -#include -#include "cvs.h" -#include "prepend_args.h" - -#ifdef HAVE_WINSOCK_H -#include -#else -extern int gethostname (); -#endif - -const char *program_name; -const char *program_path; -const char *cvs_cmd_name; - -/* I'd dynamically allocate this, but it seems like gethostname - requires a fixed size array. If I'm remembering the RFCs right, - 256 should be enough. */ -#ifndef MAXHOSTNAMELEN -#define MAXHOSTNAMELEN 256 -#endif - -char hostname[MAXHOSTNAMELEN]; - -int use_editor = 1; -int use_cvsrc = 1; -int cvswrite = !CVSREAD_DFLT; -int really_quiet = 0; -int quiet = 0; -int trace = 0; -int noexec = 0; -int readonlyfs = 0; -int require_real_user = 0; -int logoff = 0; - -/* - * Zero if compression isn't supported or requested; non-zero to indicate - * a compression level to request from gzip. - */ -int gzip_level; - -/* Set if we should be writing CVSADM directories at top level. At - least for now we'll make the default be off (the CVS 1.9, not CVS - 1.9.2, behavior). */ -int top_level_admin = 0; - -mode_t cvsumask = UMASK_DFLT; - -char *CurDir; - -/* - * Defaults, for the environment variables that are not set - */ -char *Tmpdir = TMPDIR_DFLT; -char *Editor = EDITOR_DFLT; - - -/* When our working directory contains subdirectories with different - values in CVS/Root files, we maintain a list of them. */ -List *root_directories = NULL; - -static const struct cmd -{ - char *fullname; /* Full name of the function (e.g. "commit") */ - - /* Synonyms for the command, nick1 and nick2. We supply them - mostly for two reasons: (1) CVS has always supported them, and - we need to maintain compatibility, (2) if there is a need for a - version which is shorter than the fullname, for ease in typing. - Synonyms have the disadvantage that people will see "new" and - then have to think about it, or look it up, to realize that is - the operation they know as "add". Also, this means that one - cannot create a command "cvs new" with a different meaning. So - new synonyms are probably best used sparingly, and where used - should be abbreviations of the fullname (preferably consisting - of the first 2 or 3 or so letters). - - One thing that some systems do is to recognize any unique - abbreviation, for example "annotat" "annota", etc., for - "annotate". The problem with this is that scripts and user - habits will expect a certain abbreviation to be unique, and in - a future release of CVS it may not be. So it is better to - accept only an explicit list of abbreviations and plan on - supporting them in the future as well as now. */ - - char *nick1; - char *nick2; - - int (*func) (); /* Function takes (argc, argv) arguments. */ - unsigned long attr; /* Attributes. */ -} cmds[] = - -{ - { "add", "ad", "new", add, CVS_CMD_MODIFIES_REPOSITORY | CVS_CMD_USES_WORK_DIR }, - { "admin", "adm", "rcs", admin, CVS_CMD_MODIFIES_REPOSITORY | CVS_CMD_USES_WORK_DIR }, - { "annotate", "ann", "blame", annotate, CVS_CMD_USES_WORK_DIR }, - { "checkout", "co", "get", checkout, 0 }, - { "commit", "ci", "com", commit, CVS_CMD_MODIFIES_REPOSITORY | CVS_CMD_USES_WORK_DIR }, - { "diff", "di", "dif", diff, CVS_CMD_USES_WORK_DIR }, - { "edit", NULL, NULL, edit, CVS_CMD_MODIFIES_REPOSITORY | CVS_CMD_USES_WORK_DIR }, - { "editors", NULL, NULL, editors, CVS_CMD_USES_WORK_DIR }, - { "export", "exp", "ex", checkout, CVS_CMD_USES_WORK_DIR }, - { "history", "hi", "his", history, CVS_CMD_USES_WORK_DIR }, - { "import", "im", "imp", import, CVS_CMD_MODIFIES_REPOSITORY | CVS_CMD_USES_WORK_DIR | CVS_CMD_IGNORE_ADMROOT}, - { "init", NULL, NULL, init, CVS_CMD_MODIFIES_REPOSITORY }, -#if defined (HAVE_KERBEROS) && defined (SERVER_SUPPORT) - { "kserver", NULL, NULL, server, CVS_CMD_MODIFIES_REPOSITORY | CVS_CMD_USES_WORK_DIR }, /* placeholder */ -#endif - { "log", "lo", NULL, cvslog, CVS_CMD_USES_WORK_DIR }, -#ifdef AUTH_CLIENT_SUPPORT - { "login", "logon", "lgn", login, 0 }, - { "logout", NULL, NULL, logout, 0 }, -#endif /* AUTH_CLIENT_SUPPORT */ -#if (defined(AUTH_SERVER_SUPPORT) || defined (HAVE_GSSAPI)) && defined(SERVER_SUPPORT) - { "pserver", NULL, NULL, server, CVS_CMD_MODIFIES_REPOSITORY | CVS_CMD_USES_WORK_DIR }, /* placeholder */ -#endif - { "rannotate","rann", "ra", annotate, 0 }, - { "rdiff", "patch", "pa", patch, 0 }, - { "release", "re", "rel", release, 0 }, - { "remove", "rm", "delete", cvsremove, CVS_CMD_MODIFIES_REPOSITORY | CVS_CMD_USES_WORK_DIR }, - { "rlog", "rl", NULL, cvslog, 0 }, - { "rtag", "rt", "rfreeze", cvstag, CVS_CMD_MODIFIES_REPOSITORY }, -#ifdef SERVER_SUPPORT - { "server", NULL, NULL, server, CVS_CMD_MODIFIES_REPOSITORY | CVS_CMD_USES_WORK_DIR }, -#endif - { "status", "st", "stat", cvsstatus, CVS_CMD_USES_WORK_DIR }, - { "tag", "ta", "freeze", cvstag, CVS_CMD_MODIFIES_REPOSITORY | CVS_CMD_USES_WORK_DIR }, - { "unedit", NULL, NULL, unedit, CVS_CMD_MODIFIES_REPOSITORY | CVS_CMD_USES_WORK_DIR }, - { "update", "up", "upd", update, CVS_CMD_USES_WORK_DIR }, - { "version", "ve", "ver", version, 0 }, - { "watch", NULL, NULL, watch, CVS_CMD_MODIFIES_REPOSITORY | CVS_CMD_USES_WORK_DIR }, - { "watchers", NULL, NULL, watchers, CVS_CMD_USES_WORK_DIR }, - { NULL, NULL, NULL, NULL, 0 }, -}; - -static const char *const usg[] = -{ - /* CVS usage messages never have followed the GNU convention of - putting metavariables in uppercase. I don't know whether that - is a good convention or not, but if it changes it would have to - change in all the usage messages. For now, they consistently - use lowercase, as far as I know. Punctuation is pretty funky, - though. Sometimes they use none, as here. Sometimes they use - single quotes (not the TeX-ish `' stuff), as in --help-options. - Sometimes they use double quotes, as in cvs -H add. - - Most (not all) of the usage messages seem to have periods at - the end of each line. I haven't tried to duplicate this style - in --help as it is a rather different format from the rest. */ - - "Usage: %s [cvs-options] command [command-options-and-arguments]\n", - " where cvs-options are -q, -n, etc.\n", - " (specify --help-options for a list of options)\n", - " where command is add, admin, etc.\n", - " (specify --help-commands for a list of commands\n", - " or --help-synonyms for a list of command synonyms)\n", - " where command-options-and-arguments depend on the specific command\n", - " (specify -H followed by a command name for command-specific help)\n", - " Specify --help to receive this message\n", - "\n", - - /* Some people think that a bug-reporting address should go here. IMHO, - the web sites are better because anything else is very likely to go - obsolete in the years between a release and when someone might be - reading this help. Besides, we could never adequately discuss - bug reporting in a concise enough way to put in a help message. */ - - /* I was going to put this at the top, but usage() wants the %s to - be in the first line. */ - "The Concurrent Versions System (CVS) is a tool for version control.\n", - /* I really don't think I want to try to define "version control" - in one line. I'm not sure one can get more concise than the - paragraph in ../cvs.spec without assuming the reader knows what - version control means. */ - - "For CVS updates and additional information, see\n", - " the CVS home page at http://cvs.nongnu.org/\n", - NULL, -}; - -static const char *const cmd_usage[] = -{ - "CVS commands are:\n", - " add Add a new file/directory to the repository\n", - " admin Administration front end for rcs\n", - " annotate Show last revision where each line was modified\n", - " checkout Checkout sources for editing\n", - " commit Check files into the repository\n", - " diff Show differences between revisions\n", - " edit Get ready to edit a watched file\n", - " editors See who is editing a watched file\n", - " export Export sources from CVS, similar to checkout\n", - " history Show repository access history\n", - " import Import sources into CVS, using vendor branches\n", - " init Create a CVS repository if it doesn't exist\n", -#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", -#endif /* AUTH_CLIENT_SUPPORT */ -#if (defined(AUTH_SERVER_SUPPORT) || defined (HAVE_GSSAPI)) && defined(SERVER_SUPPORT) - " pserver Password server mode\n", -#endif - " rannotate Show last revision where each line of module was modified\n", - " 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", - " rlog Print out history information for a module\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", - " update Bring work tree in sync with repository\n", - " version Show current CVS version(s)\n", - " watch Set watches\n", - " watchers See who is watching a file\n", - "(Specify the --help option for a list of other help options)\n", - NULL, -}; - -static const char *const opt_usage[] = -{ - /* Omit -b because it is just for compatibility. */ - "CVS global options (specified before the command name) are:\n", - " -H Displays usage information for command.\n", - " -Q Cause CVS to be really quiet.\n", - " -q Cause CVS to be somewhat quiet.\n", - " -r Make checked-out files read-only.\n", - " -w Make checked-out files read-write (default).\n", - " -g Force group-write perms on checked-out files.\n", - " -n Do not execute anything that will change the disk.\n", - " -t Show trace of program execution -- try with -n.\n", - " -R Assume repository is read-only, such as CDROM\n", - " -v CVS version and copyright.\n", - " -T tmpdir Use 'tmpdir' for temporary files.\n", - " -e editor Use 'editor' for editing log information.\n", - " -d CVS_root Overrides $CVSROOT as the root of the CVS tree.\n", - " -f Do not use the ~/.cvsrc file.\n", -#ifdef CLIENT_SUPPORT - " -z # Use compression level '#' for net traffic.\n", -#ifdef ENCRYPTION - " -x Encrypt all net traffic.\n", -#endif - " -a Authenticate all net traffic.\n", -#endif - " -s VAR=VAL Set CVS user variable.\n", - "(Specify the --help option for a list of other help options)\n", - NULL -}; - - -static int -set_root_directory (p, ignored) - Node *p; - void *ignored; -{ - if (current_parsed_root == NULL && p->data != NULL) - { - current_parsed_root = p->data; - return 1; - } - return 0; -} - - -static const char * const* -cmd_synonyms () -{ - char ** synonyms; - char ** line; - const struct cmd *c = &cmds[0]; - /* Three more for title, "specify --help" line, and NULL. */ - int numcmds = 3; - - while (c->fullname != NULL) - { - numcmds++; - c++; - } - - synonyms = (char **) xmalloc(numcmds * sizeof(char *)); - line = synonyms; - *line++ = "CVS command synonyms are:\n"; - for (c = &cmds[0]; c->fullname != NULL; c++) - { - if (c->nick1 || c->nick2) - { - *line = xmalloc (strlen (c->fullname) - + (c->nick1 != NULL ? strlen (c->nick1) : 0) - + (c->nick2 != NULL ? strlen (c->nick2) : 0) - + 40); - sprintf(*line, " %-12s %s %s\n", c->fullname, - c->nick1 ? c->nick1 : "", - c->nick2 ? c->nick2 : ""); - line++; - } - } - *line++ = "(Specify the --help option for a list of other help options)\n"; - *line = NULL; - - return (const char * const*) synonyms; /* will never be freed */ -} - - -unsigned long int -lookup_command_attribute (cmd_name) - char *cmd_name; -{ - const struct cmd *cm; - - for (cm = cmds; cm->fullname; cm++) - { - if (strcmp (cmd_name, cm->fullname) == 0) - break; - } - if (!cm->fullname) - error (1, 0, "unknown command: %s", cmd_name); - return cm->attr; -} - - -static RETSIGTYPE -main_cleanup (sig) - int sig; -{ -#ifndef DONT_USE_SIGNALS - const char *name; - char temp[10]; - - switch (sig) - { -#ifdef SIGABRT - case SIGABRT: - name = "abort"; - break; -#endif -#ifdef SIGHUP - case SIGHUP: - name = "hangup"; - break; -#endif -#ifdef SIGINT - case SIGINT: - name = "interrupt"; - break; -#endif -#ifdef SIGQUIT - case SIGQUIT: - name = "quit"; - break; -#endif -#ifdef SIGPIPE - case SIGPIPE: - name = "broken pipe"; - break; -#endif -#ifdef SIGTERM - case SIGTERM: - name = "termination"; - break; -#endif - default: - /* This case should never be reached, because we list above all - the signals for which we actually establish a signal handler. */ - sprintf (temp, "%d", sig); - name = temp; - break; - } - - error (1, 0, "received %s signal", name); -#endif /* !DONT_USE_SIGNALS */ -} - -int -main (argc, argv) - int argc; - char **argv; -{ - cvsroot_t *CVSroot_parsed = NULL; - int cvsroot_update_env = 1; - char *cp, *end; - const struct cmd *cm; - int c, err = 0; - int tmpdir_update_env; - int free_Editor = 0; - int free_Tmpdir = 0; - - 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[] = "+QqgrwtnRvb:T:e:d:Hfz:s:xaU"; - static struct option long_options[] = - { - {"help", 0, NULL, 'H'}, - {"version", 0, NULL, 'v'}, - {"help-commands", 0, NULL, 1}, - {"help-synonyms", 0, NULL, 2}, - {"help-options", 0, NULL, 4}, - {"allow-root", required_argument, NULL, 3}, - {0, 0, 0, 0} - }; - /* `getopt_long' stores the option index here, but right now we - don't use it. */ - int option_index = 0; - -#ifdef SYSTEM_INITIALIZE - /* Hook for OS-specific behavior, for example socket subsystems on - NT and OS2 or dealing with windows and arguments on Mac. */ - SYSTEM_INITIALIZE (&argc, &argv); -#endif - -#ifdef HAVE_TZSET - /* On systems that have tzset (which is almost all the ones I know - of), it's a good idea to call it. */ - tzset (); -#endif - - /* - * Just save the last component of the path for error messages - */ - program_path = xstrdup (argv[0]); -#ifdef ARGV0_NOT_PROGRAM_NAME - /* On some systems, e.g. VMS, argv[0] is not the name of the command - which the user types to invoke the program. */ - program_name = "cvs"; -#else - program_name = last_component (argv[0]); -#endif - - /* - * Query the environment variables up-front, so that - * they can be overridden by command line arguments - */ - tmpdir_update_env = *Tmpdir; /* TMPDIR_DFLT must be set */ - if ((cp = getenv (TMPDIR_ENV)) != NULL) - { - Tmpdir = cp; - tmpdir_update_env = 0; /* it's already there */ - } - if ((cp = getenv (EDITOR1_ENV)) != NULL) - Editor = cp; - else if ((cp = getenv (EDITOR2_ENV)) != NULL) - Editor = cp; - else if ((cp = getenv (EDITOR3_ENV)) != NULL) - Editor = cp; - if (getenv (CVSREAD_ENV) != NULL) - cvswrite = 0; - if (getenv (CVSREADONLYFS_ENV) != NULL) { - readonlyfs = 1; - logoff = 1; - } - - prepend_default_options (getenv ("CVS_OPTIONS"), &argc, &argv); - - /* Set this to 0 to force getopt initialization. getopt() sets - this to 1 internally. */ - optind = 0; - - /* We have to parse the options twice because else there is no - chance to avoid reading the global options from ".cvsrc". Set - opterr to 0 for avoiding error messages about invalid options. - */ - opterr = 0; - - while ((c = getopt_long - (argc, argv, short_options, long_options, &option_index)) - != EOF) - { - if (c == 'f') - use_cvsrc = 0; - } - - /* - * Scan cvsrc file for global options. - */ - if (use_cvsrc) - read_cvsrc (&argc, &argv, "cvs"); - - optind = 0; - opterr = 1; - - while ((c = getopt_long - (argc, argv, short_options, long_options, &option_index)) - != EOF) - { - switch (c) - { - case 1: - /* --help-commands */ - usage (cmd_usage); - break; - case 2: - /* --help-synonyms */ - usage (cmd_synonyms()); - break; - case 4: - /* --help-options */ - usage (opt_usage); - break; - case 3: - /* --allow-root */ - root_allow_add (optarg); - break; - case 'Q': - really_quiet = 1; - /* FALL THROUGH */ - case 'q': - quiet = 1; - break; - case 'r': - cvswrite = 0; - break; - case 'w': - cvswrite = 1; - break; - case 'g': - /* - * force full group write perms (used for shared checked-out - * source trees, see manual page) - */ - umask(umask(077) & 007); - break; - case 't': - trace = 1; - break; - case 'R': - readonlyfs = 1; - logoff = 1; - break; - case 'n': - noexec = 1; - logoff = 1; - break; - case 'v': - (void) fputs ("\n", stdout); - version (0, (char **) NULL); - (void) fputs ("\n", stdout); - (void) fputs ("\ -Copyright (C) 2006 Free Software Foundation, Inc.\n\ -\n\ -Senior active maintainers include Larry Jones, Derek R. Price,\n\ -and Mark D. Baushke. Please see the AUTHORS and README files from the CVS\n\ -distribution kit for a complete list of contributors and copyrights.\n", - stdout); - (void) fputs ("\n", stdout); - (void) fputs ("CVS may be copied only under the terms of the GNU General Public License,\n", stdout); - (void) fputs ("a copy of which can be found with the CVS distribution kit.\n", stdout); - (void) fputs ("\n", stdout); - - (void) fputs ("Specify the --help option for further information about CVS\n", stdout); - -#ifdef SYSTEM_CLEANUP - /* Hook for OS-specific behavior, for example socket subsystems - * on NT and OS2 or dealing with windows and arguments on Mac. - */ - SYSTEM_CLEANUP (); -#endif - exit (0); - break; - case 'b': - /* This option used to specify the directory for RCS - executables. But since we don't run them any more, - this is a noop. Silently ignore it so that .cvsrc - and scripts and inetd.conf and such can work with - either new or old CVS. */ - break; - case 'T': - if (free_Tmpdir) free (Tmpdir); - Tmpdir = xstrdup (optarg); - free_Tmpdir = 1; - tmpdir_update_env = 1; /* need to update environment */ - break; - case 'e': - if (free_Editor) free (Editor); - Editor = xstrdup (optarg); - free_Editor = 1; - break; - case 'd': - if (CVSroot_cmdline != NULL) - free (CVSroot_cmdline); - CVSroot_cmdline = xstrdup (optarg); - break; - case 'H': - help = 1; - break; - case 'f': - use_cvsrc = 0; /* unnecessary, since we've done it above */ - break; - case 'z': - gzip_level = strtol (optarg, &end, 10); - if (*end != '\0' || gzip_level < 0 || gzip_level > 9) - error (1, 0, - "gzip compression level must be between 0 and 9"); - /* If no CLIENT_SUPPORT, we just silently ignore the gzip - * level, so that users can have it in their .cvsrc and not - * cause any trouble. - * - * We still parse the argument to -z for correctness since - * one user complained of being bitten by a run of - * `cvs -z -n up' which read -n as the argument to -z without - * complaining. */ - break; - case 's': - variable_set (optarg); - break; - case 'x': -#ifdef CLIENT_SUPPORT - cvsencrypt = 1; -#endif /* CLIENT_SUPPORT */ - /* If no CLIENT_SUPPORT, ignore -x, so that users can - have it in their .cvsrc and not cause any trouble. - If no ENCRYPTION, we still accept -x, but issue an - error if we are being run as a client. */ - break; - case 'a': -#ifdef CLIENT_SUPPORT - cvsauthenticate = 1; -#endif - /* If no CLIENT_SUPPORT, ignore -a, so that users can - have it in their .cvsrc and not cause any trouble. - We will issue an error later if stream - authentication is not supported. */ - break; - case 'U': -#ifdef SERVER_SUPPORT - require_real_user = 1; -#endif - break; - case '?': - default: - usage (usg); - } - } - - argc -= optind; - argv += optind; - if (argc < 1) - usage (usg); - - - /* Look up the command name. */ - - cvs_cmd_name = argv[0]; - for (cm = cmds; cm->fullname; cm++) - { - if (cm->nick1 && !strcmp (cvs_cmd_name, cm->nick1)) - break; - if (cm->nick2 && !strcmp (cvs_cmd_name, cm->nick2)) - break; - if (!strcmp (cvs_cmd_name, cm->fullname)) - break; - } - - if (!cm->fullname) - { - fprintf (stderr, "Unknown command: `%s'\n\n", cvs_cmd_name); - usage (cmd_usage); - } - else - cvs_cmd_name = cm->fullname; /* Global pointer for later use */ - - if (help) - { - argc = -1; /* some functions only check for this */ - err = (*(cm->func)) (argc, argv); - } - else - { - /* The user didn't ask for help, so go ahead and authenticate, - set up CVSROOT, and the rest of it. */ - - /* The UMASK environment variable isn't handled with the - others above, since we don't want to signal errors if the - user has asked for help. This won't work if somebody adds - a command-line flag to set the umask, since we'll have to - parse it before we get here. */ - - if ((cp = getenv (CVSUMASK_ENV)) != NULL) - { - /* FIXME: Should be accepting symbolic as well as numeric mask. */ - cvsumask = strtol (cp, &end, 8) & 0777; - if (*end != '\0') - error (1, errno, "invalid umask value in %s (%s)", - CVSUMASK_ENV, cp); - } - -#ifdef SERVER_SUPPORT - -# ifdef HAVE_KERBEROS - /* If we are invoked with a single argument "kserver", then we are - running as Kerberos server as root. Do the authentication as - the very first thing, to minimize the amount of time we are - running as root. */ - if (strcmp (cvs_cmd_name, "kserver") == 0) - { - kserver_authenticate_connection (); - - /* Pretend we were invoked as a plain server. */ - cvs_cmd_name = "server"; - } -# endif /* HAVE_KERBEROS */ - - -# if defined (AUTH_SERVER_SUPPORT) || defined (HAVE_GSSAPI) - if (strcmp (cvs_cmd_name, "pserver") == 0) - { - /* The reason that --allow-root is not a command option - is mainly the comment in server() about how argc,argv - might be from .cvsrc. I'm not sure about that, and - I'm not sure it is only true of command options, but - it seems easier to make it a global option. */ - - /* Gets username and password from client, authenticates, then - switches to run as that user and sends an ACK back to the - client. */ - pserver_authenticate_connection (); - - /* Pretend we were invoked as a plain server. */ - cvs_cmd_name = "server"; - } -# endif /* AUTH_SERVER_SUPPORT || HAVE_GSSAPI */ -#endif /* SERVER_SUPPORT */ - - server_active = strcmp (cvs_cmd_name, "server") == 0; - - /* This is only used for writing into the history file. For - remote connections, it might be nice to have hostname - and/or remote path, on the other hand I'm not sure whether - it is worth the trouble. */ - - if (server_active) - CurDir = xstrdup (""); - else - { - CurDir = xgetwd (); - if (CurDir == NULL) - error (1, errno, "cannot get working directory"); - } - - if (Tmpdir == NULL || Tmpdir[0] == '\0') - { - if (free_Tmpdir) free (Tmpdir); - Tmpdir = "/tmp"; - } - -#ifdef HAVE_PUTENV - if (tmpdir_update_env) - { - char *env; - env = xmalloc (strlen (TMPDIR_ENV) + strlen (Tmpdir) + 1 + 1); - (void) sprintf (env, "%s=%s", TMPDIR_ENV, Tmpdir); - (void) putenv (env); - /* do not free env, as putenv has control of it */ - } - { - char *env; - env = xmalloc (sizeof "CVS_PID=" + 32); /* XXX pid < 10^32 */ - (void) sprintf (env, "CVS_PID=%ld", (long) getpid ()); - (void) putenv (env); - } -#endif - -#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); -#endif -#ifdef SIGINT - (void) SIG_register (SIGINT, main_cleanup); -#endif -#ifdef SIGQUIT - (void) SIG_register (SIGQUIT, main_cleanup); -#endif -#ifdef SIGPIPE - (void) SIG_register (SIGPIPE, main_cleanup); -#endif -#ifdef SIGTERM - (void) SIG_register (SIGTERM, main_cleanup); -#endif -#endif /* !DONT_USE_SIGNALS */ - - gethostname(hostname, sizeof (hostname)); - -#ifdef KLUDGE_FOR_WNT_TESTSUITE - /* Probably the need for this will go away at some point once - we call fflush enough places (e.g. fflush (stdout) in - cvs_outerr). */ - (void) setvbuf (stdout, (char *) NULL, _IONBF, 0); - (void) setvbuf (stderr, (char *) NULL, _IONBF, 0); -#endif /* KLUDGE_FOR_WNT_TESTSUITE */ - - if (use_cvsrc) - read_cvsrc (&argc, &argv, cvs_cmd_name); - - /* Fiddling with CVSROOT doesn't make sense if we're running - * in server mode, since the client will send the repository - * directory after the connection is made. - */ - if (!server_active) - { - /* First check if a root was set via the command line. */ - if (CVSroot_cmdline) - { - if (!(CVSroot_parsed = parse_cvsroot (CVSroot_cmdline))) - error (1, 0, "Bad CVSROOT: `%s'.", CVSroot_cmdline); - } - - /* See if we are able to find a 'better' value for CVSroot - * in the CVSADM_ROOT directory. - * - * "cvs import" shouldn't check CVS/Root; in general it - * ignores CVS directories and CVS/Root is likely to - * specify a different repository than the one we are - * importing to, but if this is not import and no root was - * specified on the command line, set the root from the - * CVS/Root file. - */ - if (!CVSroot_parsed - && !(cm->attr & CVS_CMD_IGNORE_ADMROOT) - ) - CVSroot_parsed = Name_Root (NULL, NULL); - - /* Now, if there is no root on the command line and we didn't find - * one in a file, set it via the $CVSROOT env var. - */ - if (!CVSroot_parsed) - { - char *tmp = getenv (CVSROOT_ENV); - if (tmp) - { - if (!(CVSroot_parsed = parse_cvsroot (tmp))) - error (1, 0, "Bad CVSROOT: `%s'.", tmp); - cvsroot_update_env = 0; - } - } - -#ifdef CVSROOT_DFLT - if (!CVSroot_parsed) - { - if (!(CVSroot_parsed = parse_cvsroot (CVSROOT_DFLT))) - error (1, 0, "Bad CVSROOT: `%s'.", CVSROOT_DFLT); - } -#endif /* CVSROOT_DFLT */ - - /* Now we've reconciled CVSROOT from the command line, the - CVS/Root file, and the environment variable. Do the - last sanity checks on the variable. */ - if (!CVSroot_parsed) - { - error (0, 0, - "No CVSROOT specified! Please use the `-d' option"); - error (1, 0, - "or set the %s environment variable.", CVSROOT_ENV); - } - } - - /* Here begins the big loop over unique cvsroot values. We - need to call do_recursion once for each unique value found - in CVS/Root. Prime the list with the current value. */ - - /* Create the list. */ - assert (root_directories == NULL); - root_directories = getlist (); - - /* Prime it. */ - if (CVSroot_parsed) - { - Node *n; - n = getnode (); - n->type = NT_UNKNOWN; - n->key = xstrdup (CVSroot_parsed->original); - n->data = CVSroot_parsed; - - if (addnode (root_directories, n)) - error (1, 0, "cannot add initial CVSROOT %s", n->key); - } - - assert (current_parsed_root == NULL); - - /* If we're running the server, we want to execute this main - loop once and only once (we won't be serving multiple roots - from this connection, so there's no need to do it more than - once). To get out of the loop, we perform a "break" at the - end of things. */ - - while (server_active || - walklist (root_directories, set_root_directory, NULL)) - { - /* Fiddling with CVSROOT doesn't make sense if we're running - in server mode, since the client will send the repository - directory after the connection is made. */ - - if (!server_active) - { - /* Now we're 100% sure that we have a valid CVSROOT - variable. Parse it to see if we're supposed to do - remote accesses or use a special access method. */ - - if (trace) - fprintf (stderr, "%s-> main loop with CVSROOT=%s\n", - CLIENT_SERVER_STR, current_parsed_root->original); - - /* - * Check to see if the repository exists. - */ - if (!current_parsed_root->isremote) - { - char *path; - int save_errno; - - path = xmalloc (strlen (current_parsed_root->directory) - + strlen (CVSROOTADM) + 2); - sprintf (path, "%s/%s", current_parsed_root->directory, - CVSROOTADM); - if (!isaccessible (path, R_OK | X_OK)) - { - save_errno = errno; - /* If this is "cvs init", the root need not exist yet. - */ - if (strcmp (cvs_cmd_name, "init")) - error (1, save_errno, "%s", path); - } - free (path); - } - -#ifdef HAVE_PUTENV - /* Update the CVSROOT environment variable. */ - if (cvsroot_update_env) - { - static char *prev; - char *env; - - env = xmalloc (strlen (CVSROOT_ENV) - + strlen (current_parsed_root->original) - + 2); - sprintf (env, "%s=%s", CVSROOT_ENV, - current_parsed_root->original); - (void) putenv (env); - /* 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 - } - - /* Parse the CVSROOT/config file, but only for local. For the - server, we parse it after we know $CVSROOT. For the - client, it doesn't get parsed at all, obviously. The - presence of the parse_config call here is not mean to - predetermine whether CVSROOT/config overrides things from - read_cvsrc and other such places or vice versa. That sort - of thing probably needs more thought. */ - if (!server_active && !current_parsed_root->isremote) - { - /* If there was an error parsing the config file, parse_config - already printed an error. We keep going. Why? Because - if we didn't, then there would be no way to check in a new - CVSROOT/config file to fix the broken one! */ - parse_config (current_parsed_root->directory); - - /* Now is a convenient time to read CVSROOT/options */ - parseopts(current_parsed_root->directory); - } - -#ifdef CLIENT_SUPPORT - /* Need to check for current_parsed_root != NULL here since - * we could still be in server mode before the server function - * gets called below and sets the root - */ - if (current_parsed_root != NULL && current_parsed_root->isremote) - { - /* Create a new list for directory names that we've - sent to the server. */ - if (dirs_sent_to_server != NULL) - dellist (&dirs_sent_to_server); - dirs_sent_to_server = getlist (); - } -#endif - - err = (*(cm->func)) (argc, argv); - - /* Mark this root directory as done. When the server is - active, our list will be empty -- don't try and - remove it from the list. */ - - if (!server_active) - { - Node *n = findnode (root_directories, - current_parsed_root->original); - assert (n != NULL); - assert (n->data != NULL); - free_cvsroot_t (n->data); - n->data = NULL; - current_parsed_root = NULL; - } - - if (server_active) - { - server_active = 0; - break; - } - } /* end of loop for cvsroot values */ - - dellist (&root_directories); - } /* end of stuff that gets done if the user DOESN'T ask for help */ - - Lock_Cleanup (); - - /* It's okay to cast out the const below since we know we allocated this in - * this function. The const was to keep other functions from messing with - * this. - */ - free ((char *)program_path); - if (CVSroot_cmdline != NULL) - free (CVSroot_cmdline); - if (free_Editor) - free (Editor); - if (free_Tmpdir) - free (Tmpdir); - root_allow_free (); - -#ifdef SYSTEM_CLEANUP - /* Hook for OS-specific behavior, for example socket subsystems on - NT and OS2 or dealing with windows and arguments on Mac. */ - SYSTEM_CLEANUP (); -#endif - - /* This is exit rather than return because apparently that keeps - some tools which check for memory leaks happier. */ - exit (err ? EXIT_FAILURE : 0); - /* Keep picky/stupid compilers (e.g. Visual C++ 5.0) happy. */ - return 0; -} - -char * -Make_Date (rawdate) - char *rawdate; -{ - time_t unixtime; - - unixtime = get_date (rawdate, (struct timeb *) NULL); - if (unixtime == (time_t) - 1) - error (1, 0, "Can't parse date/time: %s", rawdate); - return date_from_time_t (unixtime); -} - -/* Convert a time_t to an RCS format date. This is mainly for the - use of "cvs history", because the CVSROOT/history file contains - time_t format dates; most parts of CVS will want to avoid using - time_t's directly, and instead use RCS_datecmp, Make_Date, &c. - Assuming that the time_t is in GMT (as it generally should be), - then the result will be in GMT too. - - Returns a newly malloc'd string. */ - -char * -date_from_time_t (unixtime) - time_t unixtime; -{ - struct tm *ftm; - char date[MAXDATELEN]; - char *ret; - - ftm = gmtime (&unixtime); - if (ftm == NULL) - /* This is a system, like VMS, where the system clock is in local - time. Hopefully using localtime here matches the "zero timezone" - hack I added to get_date (get_date of course being the relevant - issue for Make_Date, and for history.c too I think). */ - ftm = localtime (&unixtime); - - (void) sprintf (date, DATEFORM, - ftm->tm_year + (ftm->tm_year < 100 ? 0 : 1900), - ftm->tm_mon + 1, ftm->tm_mday, ftm->tm_hour, - ftm->tm_min, ftm->tm_sec); - ret = xstrdup (date); - return (ret); -} - -/* Convert a date to RFC822/1123 format. This is used in contexts like - dates to send in the protocol; it should not vary based on locale or - other such conventions for users. We should have another routine which - does that kind of thing. - - The SOURCE date is in our internal RCS format. DEST should point to - storage managed by the caller, at least MAXDATELEN characters. */ -void -date_to_internet (dest, source) - char *dest; - const char *source; -{ - struct tm date; - - date_to_tm (&date, source); - tm_to_internet (dest, &date); -} - -void -date_to_tm (dest, source) - struct tm *dest; - const char *source; -{ - if (sscanf (source, SDATEFORM, - &dest->tm_year, &dest->tm_mon, &dest->tm_mday, - &dest->tm_hour, &dest->tm_min, &dest->tm_sec) - != 6) - /* Is there a better way to handle errors here? I made this - non-fatal in case we are called from the code which can't - deal with fatal errors. */ - error (0, 0, "internal error: bad date %s", source); - - if (dest->tm_year > 100) - dest->tm_year -= 1900; - - dest->tm_mon -= 1; -} - -/* Convert a date to RFC822/1123 format. This is used in contexts like - dates to send in the protocol; it should not vary based on locale or - other such conventions for users. We should have another routine which - does that kind of thing. - - The SOURCE date is a pointer to a struct tm. DEST should point to - storage managed by the caller, at least MAXDATELEN characters. */ -void -tm_to_internet (dest, source) - char *dest; - const struct tm *source; -{ - /* Just to reiterate, these strings are from RFC822 and do not vary - according to locale. */ - static const char *const month_names[] = - {"Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; - - sprintf (dest, "%d %s %d %02d:%02d:%02d -0000", source->tm_mday, - source->tm_mon < 0 || source->tm_mon > 11 ? "???" : month_names[source->tm_mon], - source->tm_year + 1900, source->tm_hour, source->tm_min, source->tm_sec); -} - -void -usage (cpp) - register const char *const *cpp; -{ - (void) fprintf (stderr, *cpp++, program_name, cvs_cmd_name); - for (; *cpp; cpp++) - (void) fprintf (stderr, *cpp); - error_exit (); -} - -void -parseopts(root) - const char *root; -{ - char path[PATH_MAX]; - int save_errno; - char buf[1024]; - const char *p; - char *q; - FILE *fp; - - if (root == NULL) { - printf("no CVSROOT in parseopts\n"); - return; - } - p = strchr (root, ':'); - if (p) - p++; - else - p = root; - if (p == NULL) { - printf("mangled CVSROOT in parseopts\n"); - return; - } - (void) sprintf (path, "%s/%s/%s", p, CVSROOTADM, CVSROOTADM_OPTIONS); - if ((fp = fopen(path, "r")) != NULL) { - while (fgets(buf, sizeof buf, fp) != NULL) { - if (buf[0] == '#') - continue; - q = strrchr(buf, '\n'); - if (q) - *q = '\0'; - - if (!strcmp(buf, "iso8601")) { - datesep = '-'; - } - if (!strncmp(buf, "tag=", 4)) { - char *what; - char *rcs_localid; - - rcs_localid = buf + 4; - RCS_setlocalid(rcs_localid); - } - if (!strncmp(buf, "tagexpand=", 10)) { - char *what; - char *rcs_incexc; - - rcs_incexc = buf + 10; - RCS_setincexc(rcs_incexc); - } - /* - * OpenBSD has a "umask=" and "dlimit=" command, we silently - * ignore them here since they are not much use to us. cvsumask - * defaults to 002 already, and the dlimit (data size limit) - * should really be handled elsewhere (eg: login.conf). - */ - } - fclose(fp); - } -} diff --git a/contrib/cvs/src/mkmodules.c b/contrib/cvs/src/mkmodules.c deleted file mode 100644 index 751d4c7..0000000 --- a/contrib/cvs/src/mkmodules.c +++ /dev/null @@ -1,1054 +0,0 @@ -/* - * Copyright (C) 1986-2008 The Free Software Foundation, Inc. - * - * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot , - * and others. - * - * Portions Copyright (C) 1992, Brian Berliner and Jeff Polk - * Portions Copyright (C) 1989-1992, Brian Berliner - * - * You may distribute under the terms of the GNU General Public License as - * specified in the README file that comes with the CVS kit. */ - -#include -#include "cvs.h" -#include "getline.h" -#include "history.h" -#include "savecwd.h" - -#ifndef DBLKSIZ -#define DBLKSIZ 4096 /* since GNU ndbm doesn't define it */ -#endif - -static int checkout_file PROTO((char *file, char *temp)); -static char *make_tempfile PROTO((void)); -static void rename_rcsfile PROTO((char *temp, char *real)); - -#ifndef MY_NDBM -static void rename_dbmfile PROTO((char *temp)); -static void write_dbmfile PROTO((char *temp)); -#endif /* !MY_NDBM */ - -/* Structure which describes an administrative file. */ -struct admin_file { - /* Name of the file, within the CVSROOT directory. */ - char *filename; - - /* This is a one line description of what the file is for. It is not - currently used, although one wonders whether it should be, somehow. - If NULL, then don't process this file in mkmodules (FIXME?: a bit of - a kludge; probably should replace this with a flags field). */ - char *errormsg; - - /* Contents which the file should have in a new repository. To avoid - problems with brain-dead compilers which choke on long string constants, - this is a pointer to an array of char * terminated by NULL--each of - the strings is concatenated. - - If this field is NULL, the file is not created in a new - repository, but it can be added with "cvs add" (just as if one - had created the repository with a version of CVS which didn't - know about the file) and the checked-out copy will be updated - without having to add it to checkoutlist. */ - const char * const *contents; -}; - -static const char *const loginfo_contents[] = { - "# The \"loginfo\" file controls where \"cvs commit\" log information\n", - "# is sent. The first entry on a line is a regular expression which must match\n", - "# the directory that the change is being made to, relative to the\n", - "# $CVSROOT. If a match is found, then the remainder of the line is a filter\n", - "# program that should expect log information on its standard input.\n", - "#\n", - "# If the repository name does not match any of the regular expressions in this\n", - "# file, the \"DEFAULT\" line is used, if it is specified.\n", - "#\n", - "# If the name ALL appears as a regular expression it is always used\n", - "# in addition to the first matching regex or DEFAULT.\n", - "#\n", - "# You may specify a format string as part of the\n", - "# filter. The string is composed of a `%' followed\n", - "# by a single format character, or followed by a set of format\n", - "# characters surrounded by `{' and `}' as separators. The format\n", - "# characters are:\n", - "#\n", - "# s = file name\n", - "# V = old version number (pre-checkin)\n", - "# v = new version number (post-checkin)\n", - "#\n", - "# For example:\n", - "#DEFAULT (echo \"\"; id; echo %s; date; cat) >> $CVSROOT/CVSROOT/commitlog\n", - "# or\n", - "#DEFAULT (echo \"\"; id; echo %{sVv}; date; cat) >> $CVSROOT/CVSROOT/commitlog\n", - NULL -}; - -static const char *const rcsinfo_contents[] = { - "# The \"rcsinfo\" file is used to control templates with which the editor\n", - "# is invoked on commit and import.\n", - "#\n", - "# The first entry on a line is a regular expression which is tested\n", - "# against the directory that the change is being made to, relative to the\n", - "# $CVSROOT. For the first match that is found, then the remainder of the\n", - "# line is the name of the file that contains the template.\n", - "#\n", - "# If the repository name does not match any of the regular expressions in this\n", - "# file, the \"DEFAULT\" line is used, if it is specified.\n", - "#\n", - "# If the name \"ALL\" appears as a regular expression it is always used\n", - "# in addition to the first matching regex or \"DEFAULT\".\n", - NULL -}; - -static const char *const editinfo_contents[] = { - "# The \"editinfo\" file is used to allow verification of logging\n", - "# information. It works best when a template (as specified in the\n", - "# rcsinfo file) is provided for the logging procedure. Given a\n", - "# template with locations for, a bug-id number, a list of people who\n", - "# reviewed the code before it can be checked in, and an external\n", - "# process to catalog the differences that were code reviewed, the\n", - "# following test can be applied to the code:\n", - "#\n", - "# Making sure that the entered bug-id number is correct.\n", - "# Validating that the code that was reviewed is indeed the code being\n", - "# checked in (using the bug-id number or a seperate review\n", - "# number to identify this particular code set.).\n", - "#\n", - "# If any of the above test failed, then the commit would be aborted.\n", - "#\n", - "# Actions such as mailing a copy of the report to each reviewer are\n", - "# better handled by an entry in the loginfo file.\n", - "#\n", - "# One thing that should be noted is the the ALL keyword is not\n", - "# supported. There can be only one entry that matches a given\n", - "# repository.\n", - NULL -}; - -static const char *const verifymsg_contents[] = { - "# The \"verifymsg\" file is used to allow verification of logging\n", - "# information. It works best when a template (as specified in the\n", - "# rcsinfo file) is provided for the logging procedure. Given a\n", - "# template with locations for, a bug-id number, a list of people who\n", - "# reviewed the code before it can be checked in, and an external\n", - "# process to catalog the differences that were code reviewed, the\n", - "# following test can be applied to the code:\n", - "#\n", - "# Making sure that the entered bug-id number is correct.\n", - "# Validating that the code that was reviewed is indeed the code being\n", - "# checked in (using the bug-id number or a seperate review\n", - "# number to identify this particular code set.).\n", - "#\n", - "# If any of the above test failed, then the commit would be aborted.\n", - "#\n", - "# Actions such as mailing a copy of the report to each reviewer are\n", - "# better handled by an entry in the loginfo file.\n", - "#\n", - "# One thing that should be noted is the the ALL keyword is not\n", - "# supported. There can be only one entry that matches a given\n", - "# repository.\n", - NULL -}; - -static const char *const commitinfo_contents[] = { - "# The \"commitinfo\" file is used to control pre-commit checks.\n", - "# The filter on the right is invoked with the repository and a list \n", - "# of files to check. A non-zero exit of the filter program will \n", - "# cause the commit to be aborted.\n", - "#\n", - "# The first entry on a line is a regular expression which is tested\n", - "# against the directory that the change is being committed to, relative\n", - "# to the $CVSROOT. For the first match that is found, then the remainder\n", - "# of the line is the name of the filter to run.\n", - "#\n", - "# If the repository name does not match any of the regular expressions in this\n", - "# file, the \"DEFAULT\" line is used, if it is specified.\n", - "#\n", - "# If the name \"ALL\" appears as a regular expression it is always used\n", - "# in addition to the first matching regex or \"DEFAULT\".\n", - NULL -}; - -static const char *const taginfo_contents[] = { - "# The \"taginfo\" file is used to control pre-tag checks.\n", - "# The filter on the right is invoked with the following arguments:\n", - "#\n", - "# $1 -- tagname\n", - "# $2 -- operation \"add\" for tag, \"mov\" for tag -F, and \"del\" for tag -d\n", - "# $3 -- repository\n", - "# $4-> file revision [file revision ...]\n", - "#\n", - "# A non-zero exit of the filter program will cause the tag to be aborted.\n", - "#\n", - "# The first entry on a line is a regular expression which is tested\n", - "# against the directory that the change is being committed to, relative\n", - "# to the $CVSROOT. For the first match that is found, then the remainder\n", - "# of the line is the name of the filter to run.\n", - "#\n", - "# If the repository name does not match any of the regular expressions in this\n", - "# file, the \"DEFAULT\" line is used, if it is specified.\n", - "#\n", - "# If the name \"ALL\" appears as a regular expression it is always used\n", - "# in addition to the first matching regex or \"DEFAULT\".\n", - NULL -}; - -static const char *const checkoutlist_contents[] = { - "# The \"checkoutlist\" file is used to support additional version controlled\n", - "# administrative files in $CVSROOT/CVSROOT, such as template files.\n", - "#\n", - "# The first entry on a line is a filename which will be checked out from\n", - "# the corresponding RCS file in the $CVSROOT/CVSROOT directory.\n", - "# The remainder of the line is an error message to use if the file cannot\n", - "# be checked out.\n", - "#\n", - "# File format:\n", - "#\n", - "# [][]\n", - "#\n", - "# comment lines begin with '#'\n", - NULL -}; - -static const char *const cvswrappers_contents[] = { - "# This file affects handling of files based on their names.\n", - "#\n", -#if 0 /* see comments in wrap_add in wrapper.c */ - "# The -t/-f options allow one to treat directories of files\n", - "# as a single file, or to transform a file in other ways on\n", - "# its way in and out of CVS.\n", - "#\n", -#endif - "# The -m option specifies whether CVS attempts to merge files.\n", - "#\n", - "# The -k option specifies keyword expansion (e.g. -kb for binary).\n", - "#\n", - "# Format of wrapper file ($CVSROOT/CVSROOT/cvswrappers or .cvswrappers)\n", - "#\n", - "# wildcard [option value][option value]...\n", - "#\n", - "# where option is one of\n", - "# -f from cvs filter value: path to filter\n", - "# -t to cvs filter value: path to filter\n", - "# -m update methodology value: MERGE or COPY\n", - "# -k expansion mode value: b, o, kkv, &c\n", - "#\n", - "# and value is a single-quote delimited value.\n", - "# For example:\n", - "#*.gif -k 'b'\n", - NULL -}; - -static const char *const notify_contents[] = { - "# The \"notify\" file controls where notifications from watches set by\n", - "# \"cvs watch add\" or \"cvs edit\" are sent. The first entry on a line is\n", - "# a regular expression which is tested against the directory that the\n", - "# change is being made to, relative to the $CVSROOT. If it matches,\n", - "# then the remainder of the line is a filter program that should contain\n", - "# one occurrence of %s for the user to notify, and information on its\n", - "# standard input.\n", - "#\n", - "# \"ALL\" or \"DEFAULT\" can be used in place of the regular expression.\n", - "#\n", - "# For example:\n", - "#ALL mail -s \"CVS notification\" %s\n", - NULL -}; - -static const char *const modules_contents[] = { - "# Three different line formats are valid:\n", - "# key -a aliases...\n", - "# key [options] directory\n", - "# key [options] directory files...\n", - "#\n", - "# Where \"options\" are composed of:\n", - "# -o prog Run \"prog\" on \"cvs checkout\" of module.\n", - "# -e prog Run \"prog\" on \"cvs export\" of module.\n", - "# -t prog Run \"prog\" on \"cvs rtag\" of module.\n", - "# -u prog Run \"prog\" on \"cvs update\" of module.\n", - "# -d dir Place module in directory \"dir\" instead of module name.\n", - "# -l Top-level directory only -- do not recurse.\n", - "#\n", - "# NOTE: If you change any of the \"Run\" options above, you'll have to\n", - "# release and re-checkout any working directories of these modules.\n", - "#\n", - "# And \"directory\" is a path to a directory relative to $CVSROOT.\n", - "#\n", - "# The \"-a\" option specifies an alias. An alias is interpreted as if\n", - "# everything on the right of the \"-a\" had been typed on the command line.\n", - "#\n", - "# You can encode a module within a module by using the special '&'\n", - "# character to interpose another module into the current module. This\n", - "# can be useful for creating a module that consists of many directories\n", - "# spread out over the entire source repository.\n", - NULL -}; - -static const char *const config_contents[] = { - "# Set this to \"no\" if pserver shouldn't check system users/passwords\n", - "#SystemAuth=yes\n", - "\n", - "# Set `IgnoreUnknownConfigKeys' to `yes' to ignore unknown config\n", - "# keys which are supported in a future version of CVS.\n", - "# This option is intended to be useful as a transition for read-only\n", - "# mirror sites when sites may need to be updated later than the\n", - "# primary CVS repository.\n", - "#IgnoreUnknownConfigKeys=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 `" ALL_HISTORY_REC_TYPES "' to log all transactions to the\n", - "# history file, or a subset as needed (ie `TMAR' logs all write operations)\n", - "#LogHistory=" ALL_HISTORY_REC_TYPES "\n", - "\n", - "# Set `RereadLogAfterVerify' to `always' (the default) to allow the verifymsg\n", - "# script to change the log message. Set it to `stat' to force CVS to verify\n", - "# that the file has changed before reading it (this can take up to an extra\n", - "# second per directory being committed, so it is not recommended for large\n", - "# repositories. Set it to `never' (the previous CVS behavior) to prevent\n", - "# verifymsg scripts from changing the log message.\n", - "#RereadLogAfterVerify=always\n", - NULL -}; - -static const struct admin_file filelist[] = { - {CVSROOTADM_LOGINFO, - "no logging of 'cvs commit' messages is done without a %s file", - &loginfo_contents[0]}, - {CVSROOTADM_RCSINFO, - "a %s file can be used to configure 'cvs commit' templates", - rcsinfo_contents}, - {CVSROOTADM_EDITINFO, - "a %s file can be used to validate log messages", - editinfo_contents}, - {CVSROOTADM_VERIFYMSG, - "a %s file can be used to validate log messages", - verifymsg_contents}, - {CVSROOTADM_COMMITINFO, - "a %s file can be used to configure 'cvs commit' checking", - commitinfo_contents}, - {CVSROOTADM_TAGINFO, - "a %s file can be used to configure 'cvs tag' checking", - taginfo_contents}, - {CVSROOTADM_IGNORE, - "a %s file can be used to specify files to ignore", - NULL}, - {CVSROOTADM_CHECKOUTLIST, - "a %s file can specify extra CVSROOT files to auto-checkout", - checkoutlist_contents}, - {CVSROOTADM_WRAPPER, - "a %s file can be used to specify files to treat as wrappers", - cvswrappers_contents}, - {CVSROOTADM_NOTIFY, - "a %s file can be used to specify where notifications go", - notify_contents}, - {CVSROOTADM_MODULES, - /* modules is special-cased in mkmodules. */ - NULL, - modules_contents}, - {CVSROOTADM_READERS, - "a %s file specifies read-only users", - NULL}, - {CVSROOTADM_WRITERS, - "a %s file specifies read/write users", - NULL}, - - /* Some have suggested listing CVSROOTADM_PASSWD here too. This - would mean that CVS commands which operate on the - CVSROOTADM_PASSWD file would transmit hashed passwords over the - net. This might seem to be no big deal, as pserver normally - transmits cleartext passwords, but the difference is that - CVSROOTADM_PASSWD contains *all* passwords, not just the ones - currently being used. For example, it could be too easy to - accidentally give someone readonly access to CVSROOTADM_PASSWD - (e.g. via anonymous CVS or cvsweb), and then if there are any - guessable passwords for read/write access (usually there will be) - they get read/write access. - - Another worry is the implications of storing old passwords--if - someone used a password in the past they might be using it - elsewhere, using a similar password, etc, and so saving old - passwords, even hashed, is probably not a good idea. */ - - {CVSROOTADM_CONFIG, - "a %s file configures various behaviors", - config_contents}, - {NULL, NULL, NULL} -}; - -/* Rebuild the checked out administrative files in directory DIR. */ -int -mkmodules (dir) - char *dir; -{ - struct saved_cwd cwd; - char *temp; - char *cp, *last, *fname; -#ifdef MY_NDBM - DBM *db; -#endif - FILE *fp; - char *line = NULL; - size_t line_allocated = 0; - const struct admin_file *fileptr; - - if (noexec) - return 0; - - if (save_cwd (&cwd)) - error_exit (); - - if ( CVS_CHDIR (dir) < 0) - error (1, errno, "cannot chdir to %s", dir); - - /* - * First, do the work necessary to update the "modules" database. - */ - temp = make_tempfile (); - switch (checkout_file (CVSROOTADM_MODULES, temp)) - { - - case 0: /* everything ok */ -#ifdef MY_NDBM - /* open it, to generate any duplicate errors */ - if ((db = dbm_open (temp, O_RDONLY, 0666)) != NULL) - dbm_close (db); -#else - write_dbmfile (temp); - rename_dbmfile (temp); -#endif - rename_rcsfile (temp, CVSROOTADM_MODULES); - break; - - default: - error (0, 0, - "'cvs checkout' is less functional without a %s file", - CVSROOTADM_MODULES); - break; - } /* switch on checkout_file() */ - - if (unlink_file (temp) < 0 - && !existence_error (errno)) - error (0, errno, "cannot remove %s", temp); - free (temp); - - /* Checkout the files that need it in CVSROOT dir */ - for (fileptr = filelist; fileptr && fileptr->filename; fileptr++) { - if (fileptr->errormsg == NULL) - continue; - temp = make_tempfile (); - if (checkout_file (fileptr->filename, temp) == 0) - rename_rcsfile (temp, fileptr->filename); -#if 0 - /* - * If there was some problem other than the file not existing, - * checkout_file already printed a real error message. If the - * file does not exist, it is harmless--it probably just means - * that the repository was created with an old version of CVS - * which didn't have so many files in CVSROOT. - */ - else if (fileptr->errormsg) - error (0, 0, fileptr->errormsg, fileptr->filename); -#endif - if (unlink_file (temp) < 0 - && !existence_error (errno)) - error (0, errno, "cannot remove %s", temp); - free (temp); - } - - fp = CVS_FOPEN (CVSROOTADM_CHECKOUTLIST, "r"); - if (fp) - { - /* - * File format: - * [][] - * - * comment lines begin with '#' - */ - while (getline (&line, &line_allocated, fp) >= 0) - { - /* skip lines starting with # */ - if (line[0] == '#') - continue; - - if ((last = strrchr (line, '\n')) != NULL) - *last = '\0'; /* strip the newline */ - - /* Skip leading white space. */ - for (fname = line; - *fname && isspace ((unsigned char) *fname); - fname++) - ; - - /* Find end of filename. */ - for (cp = fname; *cp && !isspace ((unsigned char) *cp); cp++) - ; - *cp = '\0'; - - temp = make_tempfile (); - if (checkout_file (fname, temp) == 0) - { - rename_rcsfile (temp, fname); - } - else - { - /* Skip leading white space before the error message. */ - for (cp++; - cp < last && *cp && isspace ((unsigned char) *cp); - cp++) - ; - if (cp < last && *cp) - error (0, 0, "%s", cp); - } - if (unlink_file (temp) < 0 - && !existence_error (errno)) - error (0, errno, "cannot remove %s", temp); - free (temp); - } - if (line) - free (line); - if (ferror (fp)) - error (0, errno, "cannot read %s", CVSROOTADM_CHECKOUTLIST); - if (fclose (fp) < 0) - error (0, errno, "cannot close %s", CVSROOTADM_CHECKOUTLIST); - } - else - { - /* Error from CVS_FOPEN. */ - if (!existence_error (errno)) - error (0, errno, "cannot open %s", CVSROOTADM_CHECKOUTLIST); - } - - if (restore_cwd (&cwd, NULL)) - error_exit (); - free_cwd (&cwd); - - return (0); -} - -/* - * Yeah, I know, there are NFS race conditions here. - */ -static char * -make_tempfile () -{ - static int seed = 0; - int fd; - char *temp; - - if (seed == 0) - seed = getpid (); - temp = xmalloc (sizeof (BAKPREFIX) + 40); - while (1) - { - (void) sprintf (temp, "%s%d", BAKPREFIX, seed++); - if ((fd = CVS_OPEN (temp, O_CREAT|O_EXCL|O_RDWR, 0666)) != -1) - break; - if (errno != EEXIST) - error (1, errno, "cannot create temporary file %s", temp); - } - if (close(fd) < 0) - error(1, errno, "cannot close temporary file %s", temp); - return temp; -} - -/* Get a file. If the file does not exist, return 1 silently. If - there is an error, print a message and return 1 (FIXME: probably - not a very clean convention). On success, return 0. */ - -static int -checkout_file (file, temp) - char *file; - char *temp; -{ - char *rcs; - RCSNode *rcsnode; - int retcode = 0; - - if (noexec) - return 0; - - rcs = xmalloc (strlen (file) + 5); - strcpy (rcs, file); - strcat (rcs, RCSEXT); - if (!isfile (rcs)) - { - free (rcs); - return (1); - } - - rcsnode = RCS_parsercsfile (rcs); - if (!rcsnode) - { - /* Probably not necessary (?); RCS_parsercsfile already printed a - message. */ - error (0, 0, "Failed to parse `%s'.", rcs); - free (rcs); - return 1; - } - - retcode = RCS_checkout (rcsnode, NULL, NULL, NULL, NULL, temp, - (RCSCHECKOUTPROC) NULL, (void *) NULL); - if (retcode != 0) - { - /* Probably not necessary (?); RCS_checkout already printed a - message. */ - error (0, 0, "failed to check out %s file", - file); - } - freercsnode (&rcsnode); - free (rcs); - return (retcode); -} - -#ifndef MY_NDBM - -static void -write_dbmfile (temp) - char *temp; -{ - char line[DBLKSIZ], value[DBLKSIZ]; - FILE *fp; - DBM *db; - char *cp, *vp; - datum key, val; - int len, cont, err = 0; - - fp = open_file (temp, "r"); - if ((db = dbm_open (temp, O_RDWR | O_CREAT | O_TRUNC, 0666)) == NULL) - error (1, errno, "cannot open dbm file %s for creation", temp); - for (cont = 0; fgets (line, sizeof (line), fp) != NULL;) - { - if ((cp = strrchr (line, '\n')) != NULL) - *cp = '\0'; /* strip the newline */ - - /* - * Add the line to the value, at the end if this is a continuation - * line; otherwise at the beginning, but only after any trailing - * backslash is removed. - */ - vp = value; - if (cont) - vp += strlen (value); - - /* - * See if the line we read is a continuation line, and strip the - * backslash if so. - */ - len = strlen (line); - if (len > 0) - cp = &line[len - 1]; - else - cp = line; - if (*cp == '\\') - { - cont = 1; - *cp = '\0'; - } - else - { - cont = 0; - } - (void) strcpy (vp, line); - if (value[0] == '#') - continue; /* comment line */ - vp = value; - while (*vp && isspace ((unsigned char) *vp)) - vp++; - if (*vp == '\0') - continue; /* empty line */ - - /* - * If this was not a continuation line, add the entry to the database - */ - if (!cont) - { - key.dptr = vp; - while (*vp && !isspace ((unsigned char) *vp)) - vp++; - key.dsize = vp - key.dptr; - *vp++ = '\0'; /* NULL terminate the key */ - while (*vp && isspace ((unsigned char) *vp)) - vp++; /* skip whitespace to value */ - if (*vp == '\0') - { - error (0, 0, "warning: NULL value for key `%s'", key.dptr); - continue; - } - val.dptr = vp; - val.dsize = strlen (vp); - if (dbm_store (db, key, val, DBM_INSERT) == 1) - { - error (0, 0, "duplicate key found for `%s'", key.dptr); - err++; - } - } - } - dbm_close (db); - if (fclose (fp) < 0) - error (0, errno, "cannot close %s", temp); - if (err) - { - /* I think that the size of the buffer needed here is - just determined by sizeof (CVSROOTADM_MODULES), the - filenames created by make_tempfile, and other things that won't - overflow. */ - char dotdir[50], dotpag[50], dotdb[50]; - - (void) sprintf (dotdir, "%s.dir", temp); - (void) sprintf (dotpag, "%s.pag", temp); - (void) sprintf (dotdb, "%s.db", temp); - if (unlink_file (dotdir) < 0 - && !existence_error (errno)) - error (0, errno, "cannot remove %s", dotdir); - if (unlink_file (dotpag) < 0 - && !existence_error (errno)) - error (0, errno, "cannot remove %s", dotpag); - if (unlink_file (dotdb) < 0 - && !existence_error (errno)) - error (0, errno, "cannot remove %s", dotdb); - error (1, 0, "DBM creation failed; correct above errors"); - } -} - -static void -rename_dbmfile (temp) - char *temp; -{ - /* I think that the size of the buffer needed here is - just determined by sizeof (CVSROOTADM_MODULES), the - filenames created by make_tempfile, and other things that won't - overflow. */ - char newdir[50], newpag[50], newdb[50]; - char dotdir[50], dotpag[50], dotdb[50]; - char bakdir[50], bakpag[50], bakdb[50]; - - int dir1_errno = 0, pag1_errno = 0, db1_errno = 0; - int dir2_errno = 0, pag2_errno = 0, db2_errno = 0; - int dir3_errno = 0, pag3_errno = 0, db3_errno = 0; - - (void) sprintf (dotdir, "%s.dir", CVSROOTADM_MODULES); - (void) sprintf (dotpag, "%s.pag", CVSROOTADM_MODULES); - (void) sprintf (dotdb, "%s.db", CVSROOTADM_MODULES); - (void) sprintf (bakdir, "%s%s.dir", BAKPREFIX, CVSROOTADM_MODULES); - (void) sprintf (bakpag, "%s%s.pag", BAKPREFIX, CVSROOTADM_MODULES); - (void) sprintf (bakdb, "%s%s.db", BAKPREFIX, CVSROOTADM_MODULES); - (void) sprintf (newdir, "%s.dir", temp); - (void) sprintf (newpag, "%s.pag", temp); - (void) sprintf (newdb, "%s.db", temp); - - (void) chmod (newdir, 0666); - (void) chmod (newpag, 0666); - (void) chmod (newdb, 0666); - - /* don't mess with me */ - SIG_beginCrSect (); - - /* rm .#modules.dir .#modules.pag */ - if (unlink_file (bakdir) < 0) - dir1_errno = errno; - if (unlink_file (bakpag) < 0) - pag1_errno = errno; - if (unlink_file (bakdb) < 0) - db1_errno = errno; - - /* mv modules.dir .#modules.dir */ - if (CVS_RENAME (dotdir, bakdir) < 0) - dir2_errno = errno; - /* mv modules.pag .#modules.pag */ - if (CVS_RENAME (dotpag, bakpag) < 0) - pag2_errno = errno; - /* mv modules.db .#modules.db */ - if (CVS_RENAME (dotdb, bakdb) < 0) - db2_errno = errno; - - /* mv "temp".dir modules.dir */ - if (CVS_RENAME (newdir, dotdir) < 0) - dir3_errno = errno; - /* mv "temp".pag modules.pag */ - if (CVS_RENAME (newpag, dotpag) < 0) - pag3_errno = errno; - /* mv "temp".db modules.db */ - if (CVS_RENAME (newdb, dotdb) < 0) - db3_errno = errno; - - /* OK -- make my day */ - SIG_endCrSect (); - - /* I didn't want to call error() when we had signals blocked - (unnecessary?), but do it now. */ - if (dir1_errno && !existence_error (dir1_errno)) - error (0, dir1_errno, "cannot remove %s", bakdir); - if (pag1_errno && !existence_error (pag1_errno)) - error (0, pag1_errno, "cannot remove %s", bakpag); - if (db1_errno && !existence_error (db1_errno)) - error (0, db1_errno, "cannot remove %s", bakdb); - - if (dir2_errno && !existence_error (dir2_errno)) - error (0, dir2_errno, "cannot remove %s", bakdir); - if (pag2_errno && !existence_error (pag2_errno)) - error (0, pag2_errno, "cannot remove %s", bakpag); - if (db2_errno && !existence_error (db2_errno)) - error (0, db2_errno, "cannot remove %s", bakdb); - - if (dir3_errno && !existence_error (dir3_errno)) - error (0, dir3_errno, "cannot remove %s", bakdir); - if (pag3_errno && !existence_error (pag3_errno)) - error (0, pag3_errno, "cannot remove %s", bakpag); - if (db3_errno && !existence_error (db3_errno)) - error (0, db3_errno, "cannot remove %s", bakdb); -} - -#endif /* !MY_NDBM */ - -static void -rename_rcsfile (temp, real) - char *temp; - char *real; -{ - char *bak; - struct stat statbuf; - char *rcs; - - /* Set "x" bits if set in original. */ - rcs = xmalloc (strlen (real) + sizeof (RCSEXT) + 10); - (void) sprintf (rcs, "%s%s", real, RCSEXT); - statbuf.st_mode = 0; /* in case rcs file doesn't exist, but it should... */ - if (CVS_STAT (rcs, &statbuf) < 0 - && !existence_error (errno)) - error (0, errno, "cannot stat %s", rcs); - free (rcs); - - if (chmod (temp, 0444 | (statbuf.st_mode & 0111)) < 0) - error (0, errno, "warning: cannot chmod %s", temp); - bak = xmalloc (strlen (real) + sizeof (BAKPREFIX) + 10); - (void) sprintf (bak, "%s%s", BAKPREFIX, real); - - /* rm .#loginfo */ - if (unlink_file (bak) < 0 - && !existence_error (errno)) - error (0, errno, "cannot remove %s", bak); - - /* mv loginfo .#loginfo */ - if (CVS_RENAME (real, bak) < 0 - && !existence_error (errno)) - error (0, errno, "cannot rename %s to %s", real, bak); - - /* mv "temp" loginfo */ - if (CVS_RENAME (temp, real) < 0 - && !existence_error (errno)) - error (0, errno, "cannot rename %s to %s", temp, real); - - free (bak); -} - -/* - * Walk PATH backwards to the root directory looking for the root of a - * repository. - */ -static char * -in_repository (const char *path) -{ - char *cp = xstrdup (path); - - for (;;) - { - if (isdir (cp)) - { - int foundit; - char *adm = xmalloc (strlen(cp) + strlen(CVSROOTADM) + 2); - sprintf (adm, "%s/%s", cp, CVSROOTADM); - foundit = isdir (adm); - free (adm); - if (foundit) return cp; - } - - /* If last_component() returns the empty string, then cp either - * points at the system root or is the empty string itself. - */ - if (!*last_component (cp) || !strcmp (cp, ".") - || last_component(cp) == cp) - break; - - cp[strlen(cp) - strlen(last_component(cp)) - 1] = '\0'; - } - - return NULL; -} - - -const char *const init_usage[] = { - "Usage: %s %s\n", - "(Specify the --help global option for a list of other help options)\n", - NULL -}; - -int -init (argc, argv) - int argc; - char **argv; -{ - /* Name of CVSROOT directory. */ - char *adm; - /* Name of this administrative file. */ - char *info; - /* Name of ,v file for this administrative file. */ - char *info_v; - /* Exit status. */ - int err = 0; - - char *root_dir; - const struct admin_file *fileptr; - - assert (!server_active); - - umask (cvsumask); - - if (argc == -1 || argc > 1) - usage (init_usage); - -#ifdef CLIENT_SUPPORT - if (current_parsed_root->isremote) - { - start_server (); - - ign_setup (); - send_init_command (); - return get_responses_and_close (); - } -#endif /* CLIENT_SUPPORT */ - - root_dir = in_repository (current_parsed_root->directory); - - if (root_dir && strcmp (root_dir, current_parsed_root->directory)) - error (1, 0, - "Cannot initialize repository under existing CVSROOT: `%s'", - root_dir); - free (root_dir); - - /* Note: we do *not* create parent directories as needed like the - old cvsinit.sh script did. Few utilities do that, and a - non-existent parent directory is as likely to be a typo as something - which needs to be created. */ - mkdir_if_needed (current_parsed_root->directory); - - adm = xmalloc (strlen (current_parsed_root->directory) + sizeof (CVSROOTADM) + 2); - sprintf (adm, "%s/%s", current_parsed_root->directory, CVSROOTADM); - mkdir_if_needed (adm); - - /* This is needed because we pass "fileptr->filename" not "info" - to add_rcs_file below. I think this would be easy to change, - thus nuking the need for CVS_CHDIR here, but I haven't looked - closely (e.g. see wrappers calls within add_rcs_file). */ - 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); - info_v = xmalloc (strlen (adm) + 80); - for (fileptr = filelist; fileptr && fileptr->filename; ++fileptr) - { - if (fileptr->contents == NULL) - continue; - strcpy (info, adm); - strcat (info, "/"); - strcat (info, fileptr->filename); - strcpy (info_v, info); - strcat (info_v, RCSEXT); - if (isfile (info_v)) - /* We will check out this file in the mkmodules step. - Nothing else is required. */ - ; - else - { - int retcode; - - if (!isfile (info)) - { - FILE *fp; - const char * const *p; - - fp = open_file (info, "w"); - for (p = fileptr->contents; *p != NULL; ++p) - if (fputs (*p, fp) < 0) - error (1, errno, "cannot write %s", info); - if (fclose (fp) < 0) - error (1, errno, "cannot close %s", info); - } - /* The message used to say " of " and fileptr->filename after - "initial checkin" but I fail to see the point as we know what - file it is from the name. */ - retcode = add_rcs_file ("initial checkin", info_v, - fileptr->filename, "1.1", NULL, - - /* No vendor branch. */ - NULL, NULL, 0, NULL, - - NULL, 0, NULL); - if (retcode != 0) - /* add_rcs_file already printed an error message. */ - err = 1; - } - } - - /* Turn on history logging by default. The user can remove the file - to disable it. */ - strcpy (info, adm); - strcat (info, "/"); - strcat (info, CVSROOTADM_HISTORY); - if (!isfile (info)) - { - FILE *fp; - - 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); - free (info_v); - - mkmodules (adm); - - free (adm); - return err; -} diff --git a/contrib/cvs/src/modules.c b/contrib/cvs/src/modules.c deleted file mode 100644 index 5cbc2ec..0000000 --- a/contrib/cvs/src/modules.c +++ /dev/null @@ -1,1101 +0,0 @@ -/* - * Copyright (C) 1986-2005 The Free Software Foundation, Inc. - * - * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot , - * and others. - * - * Portions Copyright (C) 1992, Brian Berliner and Jeff Polk - * Portions Copyright (C) 1989-1992, Brian Berliner - * - * You may distribute under the terms of the GNU General Public License - * as specified in the README file that comes with the CVS source - * distribution. - * - * Modules - * - * Functions for accessing the modules file. - * - * The modules file supports basically three formats of lines: - * key [options] directory files... [ -x directory [files] ] ... - * key [options] directory [ -x directory [files] ] ... - * key -a aliases... - * - * The -a option allows an aliasing step in the parsing of the modules - * file. The "aliases" listed on a line following the -a are - * processed one-by-one, as if they were specified as arguments on the - * command line. - */ - -#include -#include "cvs.h" -#include "savecwd.h" - - -/* Defines related to the syntax of the modules file. */ - -/* Options in modules file. Note that it is OK to use GNU getopt features; - we already are arranging to make sure we are using the getopt distributed - with CVS. */ -#define CVSMODULE_OPTS "+ad:lo:e:s:t:" - -/* Special delimiter. */ -#define CVSMODULE_SPEC '&' - -struct sortrec -{ - /* Name of the module, malloc'd. */ - char *modname; - /* If Status variable is set, this is either def_status or the malloc'd - name of the status. If Status is not set, the field is left - uninitialized. */ - char *status; - /* Pointer to a malloc'd array which contains (1) the raw contents - of the options and arguments, excluding comments, (2) a '\0', - and (3) the storage for the "comment" field. */ - char *rest; - char *comment; -}; - -static int sort_order PROTO((const PTR l, const PTR r)); -static void save_d PROTO((char *k, int ks, char *d, int ds)); - - -/* - * Open the modules file, and die if the CVSROOT environment variable - * was not set. If the modules file does not exist, that's fine, and - * a warning message is displayed and a NULL is returned. - */ -DBM * -open_module () -{ - char *mfile; - DBM *retval; - - if (current_parsed_root == NULL) - { - error (0, 0, "must set the CVSROOT environment variable"); - error (1, 0, "or specify the '-d' global option"); - } - mfile = xmalloc (strlen (current_parsed_root->directory) - + sizeof (CVSROOTADM) - + sizeof (CVSROOTADM_MODULES) + 3); - (void) sprintf (mfile, "%s/%s/%s", current_parsed_root->directory, - CVSROOTADM, CVSROOTADM_MODULES); - retval = dbm_open (mfile, O_RDONLY, 0666); - free (mfile); - return retval; -} - -/* - * Close the modules file, if the open succeeded, that is - */ -void -close_module (db) - DBM *db; -{ - if (db != NULL) - dbm_close (db); -} - - - -/* - * This is the recursive function that processes a module name. - * It calls back the passed routine for each directory of a module - * It runs the post checkout or post tag proc from the modules file - */ -static int -my_module (db, mname, m_type, msg, callback_proc, where, shorten, - local_specified, run_module_prog, build_dirs, extra_arg, - stack) - DBM *db; - char *mname; - enum mtype m_type; - char *msg; - CALLBACKPROC callback_proc; - char *where; - int shorten; - int local_specified; - int run_module_prog; - int build_dirs; - char *extra_arg; - List *stack; -{ - char *checkout_prog = NULL; - char *export_prog = NULL; - char *tag_prog = NULL; - struct saved_cwd cwd; - int cwd_saved = 0; - char *line; - int modargc; - int xmodargc; - char **modargv = NULL; - char **xmodargv = NULL; - /* Found entry from modules file, including options and such. */ - char *value = NULL; - char *mwhere = NULL; - char *mfile = NULL; - char *spec_opt = NULL; - int alias = 0; - datum key, val; - char *cp; - int c, err = 0; - int nonalias_opt = 0; - -#ifdef SERVER_SUPPORT - int restore_server_dir = 0; - char *server_dir_to_restore = NULL; - if (trace) - { - char *buf; - - /* We use cvs_outerr, rather than fprintf to stderr, because - this may be called by server code with error_use_protocol - set. */ - buf = xmalloc (100 - + strlen (mname) - + strlen (msg) - + (where ? strlen (where) : 0) - + (extra_arg ? strlen (extra_arg) : 0)); - sprintf (buf, "%s-> my_module (%s, %s, %s, %s)\n", - CLIENT_SERVER_STR, - mname, msg, where ? where : "", - extra_arg ? extra_arg : ""); - cvs_outerr (buf, 0); - free (buf); - } -#endif - - /* Don't process absolute directories. Anything else could be a security - * problem. Before this check was put in place: - * - * $ cvs -d:fork:/cvsroot co /foo - * cvs server: warning: cannot make directory CVS in /: Permission denied - * cvs [server aborted]: cannot make directory /foo: Permission denied - * $ - */ - if (isabsolute (mname)) - error (1, 0, "Absolute module reference invalid: `%s'", mname); - - /* Similarly for directories that attempt to step above the root of the - * repository. - */ - if (pathname_levels (mname) > 0) - error (1, 0, "up-level in module reference (`..') invalid: `%s'.", - mname); - - /* if this is a directory to ignore, add it to that list */ - if (mname[0] == '!' && mname[1] != '\0') - { - ign_dir_add (mname+1); - goto do_module_return; - } - - /* strip extra stuff from the module name */ - strip_trailing_slashes (mname); - - /* - * Look up the module using the following scheme: - * 1) look for mname as a module name - * 2) look for mname as a directory - * 3) look for mname as a file - * 4) take mname up to the first slash and look it up as a module name - * (this is for checking out only part of a module) - */ - - /* look it up as a module name */ - key.dptr = mname; - key.dsize = strlen (key.dptr); - if (db != NULL) - val = dbm_fetch (db, key); - else - val.dptr = NULL; - if (val.dptr != NULL) - { - /* 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 (value, '#')) != NULL) - *cp = '\0'; - else - cp = value + val.dsize; - - /* Always strip trailing spaces */ - while (cp > value && isspace ((unsigned char) *--cp)) - *cp = '\0'; - - mwhere = xstrdup (mname); - goto found; - } - else - { - char *file; - char *attic_file; - char *acp; - int is_found = 0; - - /* check to see if mname is a directory or file */ - file = xmalloc (strlen (current_parsed_root->directory) - + strlen (mname) + sizeof(RCSEXT) + 2); - (void) sprintf (file, "%s/%s", current_parsed_root->directory, mname); - attic_file = xmalloc (strlen (current_parsed_root->directory) - + strlen (mname) - + sizeof (CVSATTIC) + sizeof (RCSEXT) + 3); - if ((acp = strrchr (mname, '/')) != NULL) - { - *acp = '\0'; - (void) sprintf (attic_file, "%s/%s/%s/%s%s", current_parsed_root->directory, - mname, CVSATTIC, acp + 1, RCSEXT); - *acp = '/'; - } - else - (void) sprintf (attic_file, "%s/%s/%s%s", - current_parsed_root->directory, - CVSATTIC, mname, RCSEXT); - - if (isdir (file)) - { - modargv = xmalloc (sizeof (*modargv)); - modargv[0] = xstrdup (mname); - modargc = 1; - is_found = 1; - } - else - { - (void) strcat (file, RCSEXT); - if (isfile (file) || isfile (attic_file)) - { - /* if mname was a file, we have to split it into "dir file" */ - if ((cp = strrchr (mname, '/')) != NULL && cp != mname) - { - modargv = xmalloc (2 * sizeof (*modargv)); - modargv[0] = xmalloc (strlen (mname) + 2); - strncpy (modargv[0], mname, cp - mname); - modargv[0][cp - mname] = '\0'; - modargv[1] = xstrdup (cp + 1); - modargc = 2; - } - else - { - /* - * the only '/' at the beginning or no '/' at all - * means the file we are interested in is in CVSROOT - * itself so the directory should be '.' - */ - if (cp == mname) - { - /* drop the leading / if specified */ - modargv = xmalloc (2 * sizeof (*modargv)); - modargv[0] = xstrdup ("."); - modargv[1] = xstrdup (mname + 1); - modargc = 2; - } - else - { - /* otherwise just copy it */ - modargv = xmalloc (2 * sizeof (*modargv)); - modargv[0] = xstrdup ("."); - modargv[1] = xstrdup (mname); - modargc = 2; - } - } - is_found = 1; - } - } - free (attic_file); - free (file); - - if (is_found) - { - assert (value == NULL); - - /* OK, we have now set up modargv with the actual - file/directory we want to work on. We duplicate a - small amount of code here because the vast majority of - the code after the "found" label does not pertain to - the case where we found a file/directory rather than - finding an entry in the modules file. */ - if (save_cwd (&cwd)) - error_exit (); - cwd_saved = 1; - - err += callback_proc (modargc, modargv, where, mwhere, mfile, - shorten, - local_specified, mname, msg); - - free_names (&modargc, modargv); - - /* cd back to where we started. */ - if (restore_cwd (&cwd, NULL)) - error_exit (); - free_cwd (&cwd); - cwd_saved = 0; - - goto do_module_return; - } - } - - /* look up everything to the first / as a module */ - if (mname[0] != '/' && (cp = strchr (mname, '/')) != NULL) - { - /* Make the slash the new end of the string temporarily */ - *cp = '\0'; - key.dptr = mname; - key.dsize = strlen (key.dptr); - - /* do the lookup */ - if (db != NULL) - val = dbm_fetch (db, key); - else - val.dptr = NULL; - - /* if we found it, clean up the value and life is good */ - if (val.dptr != NULL) - { - char *cp2; - - /* 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 (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); - mfile = cp + 1; - assert (strlen (mfile)); - - /* put the / back in mname */ - *cp = '/'; - - goto found; - } - - /* put the / back in mname */ - *cp = '/'; - } - - /* if we got here, we couldn't find it using our search, so give up */ - error (0, 0, "cannot find module `%s' - ignored", mname); - err++; - goto do_module_return; - - - /* - * At this point, we found what we were looking for in one - * of the many different forms. - */ - found: - - /* remember where we start */ - if (save_cwd (&cwd)) - error_exit (); - cwd_saved = 1; - - assert (value != NULL); - - /* search the value for the special delimiter and save for later */ - if ((cp = strchr (value, CVSMODULE_SPEC)) != NULL) - { - *cp = '\0'; /* null out the special char */ - spec_opt = cp + 1; /* save the options for later */ - - /* 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 */ - if (mfile != NULL) - spec_opt = NULL; - - /* - * value now contains one of the following: - * 1) dir - * 2) dir file - * 3) the value from modules without any special args - * [ args ] dir [file] [file] ... - * or -a module [ module ] ... - */ - - /* Put the value on a line with XXX prepended for getopt to eat */ - line = xmalloc (strlen (value) + 5); - strcpy(line, "XXX "); - strcpy(line + 4, value); - - /* turn the line into an argv[] array */ - line2argv (&xmodargc, &xmodargv, line, " \t"); - free (line); - modargc = xmodargc; - modargv = xmodargv; - - /* parse the args */ - optind = 0; - while ((c = getopt (modargc, modargv, CVSMODULE_OPTS)) != -1) - { - switch (c) - { - case 'a': - alias = 1; - break; - case 'd': - if (mwhere) - free (mwhere); - mwhere = xstrdup (optarg); - nonalias_opt = 1; - break; - case 'l': - local_specified = 1; - nonalias_opt = 1; - break; - case 'o': - if (checkout_prog) - free (checkout_prog); - checkout_prog = xstrdup (optarg); - nonalias_opt = 1; - break; - case 'e': - if (export_prog) - free (export_prog); - export_prog = xstrdup (optarg); - nonalias_opt = 1; - break; - case 't': - if (tag_prog) - free (tag_prog); - tag_prog = xstrdup (optarg); - nonalias_opt = 1; - break; - case '?': - error (0, 0, - "modules file has invalid option for key %s value %s", - key.dptr, value); - err++; - goto do_module_return; - } - } - modargc -= optind; - modargv += optind; - if (modargc == 0 && spec_opt == NULL) - { - error (0, 0, "modules file missing directory for module %s", mname); - ++err; - goto do_module_return; - } - - if (alias && nonalias_opt) - { - /* The documentation has never said it is legal to specify - -a along with another option. And I believe that in the past - CVS has ignored the options other than -a, more or less, in this - situation. */ - error (0, 0, "\ --a cannot be specified in the modules file along with other options"); - ++err; - goto do_module_return; - } - - /* if this was an alias, call ourselves recursively for each module */ - if (alias) - { - int i; - - for (i = 0; i < modargc; i++) - { - /* - * Recursion check: if an alias module calls itself or a module - * which causes the first to be called again, print an error - * message and stop recursing. - * - * Algorithm: - * - * 1. Check that MNAME isn't in the stack. - * 2. Push MNAME onto the stack. - * 3. Call do_module(). - * 4. Pop MNAME from the stack. - */ - if (stack && findnode (stack, mname)) - error (0, 0, - "module `%s' in modules file contains infinite loop", - mname); - else - { - if (!stack) stack = getlist(); - push_string (stack, mname); - err += my_module (db, modargv[i], m_type, msg, callback_proc, - where, shorten, local_specified, - run_module_prog, build_dirs, extra_arg, - stack); - pop_string (stack); - if (isempty (stack)) dellist (&stack); - } - } - goto do_module_return; - } - - if (mfile != NULL && modargc > 1) - { - error (0, 0, "\ -module `%s' is a request for a file in a module which is not a directory", - mname); - ++err; - goto do_module_return; - } - - /* otherwise, process this module */ - 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; - - if (!build_dirs) - 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; - -#ifdef SERVER_SUPPORT - /* We want to check out into the directory named by the module. - So we set a global variable which tells the server to glom that - directory name onto the front. A cleaner approach would be some - way of passing it down to the recursive call, through the - callback_proc, to start_recursion, and then into the update_dir in - the struct file_info. That way the "Updating foo" message could - print the actual directory we are checking out into. - - For local CVS, this is handled by the chdir call above - (directly or via the callback_proc). */ - if (server_active && spec_opt != NULL) - { - char *change_to; - - change_to = where ? where : (mwhere ? mwhere : mname); - server_dir_to_restore = server_dir; - restore_server_dir = 1; - server_dir = - xmalloc ((server_dir_to_restore != NULL - ? strlen (server_dir_to_restore) - : 0) - + strlen (change_to) - + 5); - server_dir[0] = '\0'; - if (server_dir_to_restore != NULL) - { - strcat (server_dir, server_dir_to_restore); - strcat (server_dir, "/"); - } - strcat (server_dir, change_to); - } -#endif - - while (spec_opt != NULL) - { - char *next_opt; - - cp = strchr (spec_opt, CVSMODULE_SPEC); - if (cp != NULL) - { - /* save the beginning of the next arg */ - next_opt = cp + 1; - - /* strip whitespace off the end */ - do - *cp = '\0'; - while (cp > spec_opt && isspace ((unsigned char) *--cp)); - } - else - next_opt = NULL; - - /* strip whitespace from front */ - while (isspace ((unsigned char) *spec_opt)) - spec_opt++; - - if (*spec_opt == '\0') - error (0, 0, "Mal-formed %c option for module %s - ignored", - CVSMODULE_SPEC, mname); - else - err += my_module (db, spec_opt, m_type, msg, callback_proc, - (char *) NULL, 0, local_specified, - run_module_prog, build_dirs, extra_arg, - stack); - spec_opt = next_opt; - } - -#ifdef SERVER_SUPPORT - if (server_active && restore_server_dir) - { - free (server_dir); - server_dir = server_dir_to_restore; - } -#endif - - /* cd back to where we started */ - if (restore_cwd (&cwd, NULL)) - error_exit (); - free_cwd (&cwd); - cwd_saved = 0; - - /* run checkout or tag prog if appropriate */ - if (err == 0 && run_module_prog) - { - if ((m_type == TAG && tag_prog != NULL) || - (m_type == CHECKOUT && checkout_prog != NULL) || - (m_type == EXPORT && export_prog != NULL)) - { - /* - * If a relative pathname is specified as the checkout, tag - * or export proc, try to tack on the current "where" value. - * if we can't find a matching program, just punt and use - * whatever is specified in the modules file. - */ - char *real_prog = NULL; - char *prog = (m_type == TAG ? tag_prog : - (m_type == CHECKOUT ? checkout_prog : export_prog)); - char *real_where = (where != NULL ? where : mwhere); - char *expanded_path; - - if ((*prog != '/') && (*prog != '.')) - { - real_prog = xmalloc (strlen (real_where) + strlen (prog) - + 10); - (void) sprintf (real_prog, "%s/%s", real_where, prog); - if (isfile (real_prog)) - prog = real_prog; - } - - /* XXX can we determine the line number for this entry??? */ - expanded_path = expand_path (prog, "modules", 0); - if (expanded_path != NULL) - { - run_setup (expanded_path); - run_arg (real_where); - - if (extra_arg) - run_arg (extra_arg); - - if (!quiet) - { - cvs_output (program_name, 0); - cvs_output (" ", 1); - cvs_output (cvs_cmd_name, 0); - 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); - } - if (real_prog) free (real_prog); - } - } - - do_module_return: - /* clean up */ - if (xmodargv != NULL) - free_names (&xmodargc, xmodargv); - if (mwhere) - free (mwhere); - if (checkout_prog) - free (checkout_prog); - if (export_prog) - free (export_prog); - if (tag_prog) - free (tag_prog); - if (cwd_saved) - free_cwd (&cwd); - if (value != NULL) - free (value); - - return (err); -} - - - -/* External face of do_module so that we can have an internal version which - * accepts a stack argument to track alias recursion. - */ -int -do_module (db, mname, m_type, msg, callback_proc, where, shorten, - local_specified, run_module_prog, build_dirs, extra_arg) - DBM *db; - char *mname; - enum mtype m_type; - char *msg; - CALLBACKPROC callback_proc; - char *where; - int shorten; - int local_specified; - int run_module_prog; - int build_dirs; - char *extra_arg; -{ - return my_module (db, mname, m_type, msg, callback_proc, where, shorten, - local_specified, run_module_prog, build_dirs, extra_arg, - NULL); -} - - - -/* - Read all the records from the modules database into an array. - - Sort the array depending on what format is desired. - - Print the array in the format desired. - - Currently, there are only two "desires": - - 1. Sort by module name and format the whole entry including switches, - files and the comment field: (Including aliases) - - modulename -s switches, one per line, even if - it has many switches. - Directories and files involved, formatted - to cover multiple lines if necessary. - # Comment, also formatted to cover multiple - # lines if necessary. - - 2. Sort by status field string and print: (*not* including aliases) - - modulename STATUS Directories and files involved, formatted - to cover multiple lines if necessary. - # Comment, also formatted to cover multiple - # lines if necessary. -*/ - -static struct sortrec *s_head; - -static int s_max = 0; /* Number of elements allocated */ -static int s_count = 0; /* Number of elements used */ - -static int Status; /* Nonzero if the user is - interested in status - information as well as - module name */ -static char def_status[] = "NONE"; - -/* Sort routine for qsort: - - If we want the "Status" field to be sorted, check it first. - - Then compare the "module name" fields. Since they are unique, we don't - have to look further. -*/ -static int -sort_order (l, r) - const PTR l; - const PTR r; -{ - int i; - const struct sortrec *left = (const struct sortrec *) l; - const struct sortrec *right = (const struct sortrec *) r; - - if (Status) - { - /* If Sort by status field, compare them. */ - if ((i = strcmp (left->status, right->status)) != 0) - return (i); - } - return (strcmp (left->modname, right->modname)); -} - -static void -save_d (k, ks, d, ds) - char *k; - int ks; - char *d; - int ds; -{ - char *cp, *cp2; - struct sortrec *s_rec; - - if (Status && *d == '-' && *(d + 1) == 'a') - return; /* We want "cvs co -s" and it is an alias! */ - - if (s_count == s_max) - { - s_max += 64; - s_head = (struct sortrec *) xrealloc ((char *) s_head, s_max * sizeof (*s_head)); - } - s_rec = &s_head[s_count]; - s_rec->modname = cp = xmalloc (ks + 1); - (void) strncpy (cp, k, ks); - *(cp + ks) = '\0'; - - s_rec->rest = cp2 = xmalloc (ds + 1); - cp = d; - *(cp + ds) = '\0'; /* Assumes an extra byte at end of static dbm buffer */ - - while (isspace ((unsigned char) *cp)) - cp++; - /* Turn into one ' ' -- makes the rest of this routine simpler */ - while (*cp) - { - if (isspace ((unsigned char) *cp)) - { - *cp2++ = ' '; - while (isspace ((unsigned char) *cp)) - cp++; - } - else - *cp2++ = *cp++; - } - *cp2 = '\0'; - - /* Look for the "-s statusvalue" text */ - if (Status) - { - s_rec->status = def_status; - - for (cp = s_rec->rest; (cp2 = strchr (cp, '-')) != NULL; cp = ++cp2) - { - if (*(cp2 + 1) == 's' && *(cp2 + 2) == ' ') - { - char *status_start; - - cp2 += 3; - status_start = cp2; - while (*cp2 != ' ' && *cp2 != '\0') - cp2++; - s_rec->status = xmalloc (cp2 - status_start + 1); - strncpy (s_rec->status, status_start, cp2 - status_start); - s_rec->status[cp2 - status_start] = '\0'; - cp = cp2; - break; - } - } - } - else - cp = s_rec->rest; - - /* Find comment field, clean up on all three sides & compress blanks */ - if ((cp2 = cp = strchr (cp, '#')) != NULL) - { - if (*--cp2 == ' ') - *cp2 = '\0'; - if (*++cp == ' ') - cp++; - s_rec->comment = cp; - } - else - s_rec->comment = ""; - - s_count++; -} - -/* Print out the module database as we know it. If STATUS is - non-zero, print out status information for each module. */ - -void -cat_module (status) - int status; -{ - DBM *db; - datum key, val; - int i, c, wid, argc, cols = 80, indent, fill; - int moduleargc; - struct sortrec *s_h; - char *cp, *cp2, **argv; - char **moduleargv; - - Status = status; - - /* Read the whole modules file into allocated records */ - if (!(db = open_module ())) - error (1, 0, "failed to open the modules file"); - - for (key = dbm_firstkey (db); key.dptr != NULL; key = dbm_nextkey (db)) - { - val = dbm_fetch (db, key); - if (val.dptr != NULL) - save_d (key.dptr, key.dsize, val.dptr, val.dsize); - } - - close_module (db); - - /* Sort the list as requested */ - qsort ((PTR) s_head, s_count, sizeof (struct sortrec), sort_order); - - /* - * Run through the sorted array and format the entries - * indent = space for modulename + space for status field - */ - indent = 12 + (status * 12); - fill = cols - (indent + 2); - for (s_h = s_head, i = 0; i < s_count; i++, s_h++) - { - char *line; - - /* Print module name (and status, if wanted) */ - line = xmalloc (strlen (s_h->modname) + 15); - sprintf (line, "%-12s", s_h->modname); - cvs_output (line, 0); - free (line); - if (status) - { - line = xmalloc (strlen (s_h->status) + 15); - sprintf (line, " %-11s", s_h->status); - cvs_output (line, 0); - free (line); - } - - line = xmalloc (strlen (s_h->modname) + strlen (s_h->rest) + 15); - /* Parse module file entry as command line and print options */ - (void) sprintf (line, "%s %s", s_h->modname, s_h->rest); - line2argv (&moduleargc, &moduleargv, line, " \t"); - free (line); - argc = moduleargc; - argv = moduleargv; - - optind = 0; - wid = 0; - while ((c = getopt (argc, argv, CVSMODULE_OPTS)) != -1) - { - if (!status) - { - if (c == 'a' || c == 'l') - { - char buf[5]; - - sprintf (buf, " -%c", c); - cvs_output (buf, 0); - wid += 3; /* Could just set it to 3 */ - } - else - { - char buf[10]; - - if (strlen (optarg) + 4 + wid > (unsigned) fill) - { - int j; - - cvs_output ("\n", 1); - for (j = 0; j < indent; ++j) - cvs_output (" ", 1); - wid = 0; - } - sprintf (buf, " -%c ", c); - cvs_output (buf, 0); - cvs_output (optarg, 0); - wid += strlen (optarg) + 4; - } - } - } - argc -= optind; - argv += optind; - - /* Format and Print all the files and directories */ - for (; argc--; argv++) - { - if (strlen (*argv) + wid > (unsigned) fill) - { - int j; - - cvs_output ("\n", 1); - for (j = 0; j < indent; ++j) - cvs_output (" ", 1); - wid = 0; - } - cvs_output (" ", 1); - cvs_output (*argv, 0); - wid += strlen (*argv) + 1; - } - cvs_output ("\n", 1); - - /* Format the comment field -- save_d (), compressed spaces */ - for (cp2 = cp = s_h->comment; *cp; cp2 = cp) - { - int j; - - for (j = 0; j < indent; ++j) - cvs_output (" ", 1); - cvs_output (" # ", 0); - if (strlen (cp2) < (unsigned) (fill - 2)) - { - cvs_output (cp2, 0); - cvs_output ("\n", 1); - break; - } - cp += fill - 2; - while (*cp != ' ' && cp > cp2) - cp--; - if (cp == cp2) - { - cvs_output (cp2, 0); - cvs_output ("\n", 1); - break; - } - - *cp++ = '\0'; - cvs_output (cp2, 0); - cvs_output ("\n", 1); - } - - free_names(&moduleargc, moduleargv); - /* FIXME-leak: here is where we would free s_h->modname, s_h->rest, - and if applicable, s_h->status. Not exactly a memory leak, - in the sense that we are about to exit(), but may be worth - noting if we ever do a multithreaded server or something of - the sort. */ - } - /* FIXME-leak: as above, here is where we would free s_head. */ -} diff --git a/contrib/cvs/src/myndbm.c b/contrib/cvs/src/myndbm.c deleted file mode 100644 index cb99cc2..0000000 --- a/contrib/cvs/src/myndbm.c +++ /dev/null @@ -1,331 +0,0 @@ -/* - * Copyright (C) 1986-2005 The Free Software Foundation, Inc. - * - * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot , - * and others. - * - * Portions Copyright (C) 1992, Brian Berliner and Jeff Polk - * Portions Copyright (C) 1989-1992, Brian Berliner - * - * You may distribute under the terms of the GNU General Public License as - * specified in the README file that comes with the CVS source distribution. - * - * A simple ndbm-emulator for CVS. It parses a text file of the format: - * - * key value - * - * at dbm_open time, and loads the entire file into memory. As such, it is - * probably only good for fairly small modules files. Ours is about 30K in - * size, and this code works fine. - */ - -#include -#include "cvs.h" -#include "getline.h" - -#ifdef MY_NDBM -# ifndef O_ACCMODE -# define O_ACCMODE (O_RDONLY | O_WRONLY | O_RDWR) -# endif /* defined O_ACCMODE */ - -static void mydbm_load_file PROTO ((FILE *, List *, char *)); - -/* Returns NULL on error in which case errno has been set to indicate - the error. Can also call error() itself. */ -/* ARGSUSED */ -DBM * -mydbm_open (file, flags, mode) - char *file; - int flags; - int mode; -{ - FILE *fp; - DBM *db; - - fp = CVS_FOPEN (file, (flags & O_ACCMODE) != O_RDONLY ? - FOPEN_BINARY_READWRITE : FOPEN_BINARY_READ); - if (fp == NULL && !(existence_error (errno) && (flags & O_CREAT))) - return ((DBM *) 0); - - db = (DBM *) xmalloc (sizeof (*db)); - db->dbm_list = getlist (); - db->modified = 0; - db->name = xstrdup (file); - - if (fp != NULL) - { - mydbm_load_file (fp, db->dbm_list, file); - if (fclose (fp) < 0) - error (0, errno, "cannot close %s", file); - } - return (db); -} - -static int write_item PROTO ((Node *, void *)); - -static int -write_item (node, data) - Node *node; - void *data; -{ - FILE *fp = (FILE *)data; - fputs (node->key, fp); - fputs (" ", fp); - fputs (node->data, fp); - fputs ("\012", fp); - return 0; -} - -void -mydbm_close (db) - DBM *db; -{ - if (db->modified) - { - FILE *fp; - fp = CVS_FOPEN (db->name, FOPEN_BINARY_WRITE); - if (fp == NULL) - error (1, errno, "cannot write %s", db->name); - walklist (db->dbm_list, write_item, (void *)fp); - if (fclose (fp) < 0) - error (0, errno, "cannot close %s", db->name); - } - free (db->name); - dellist (&db->dbm_list); - free ((char *) db); -} - -datum -mydbm_fetch (db, key) - DBM *db; - datum key; -{ - Node *p; - char *s; - datum val; - - /* make sure it's null-terminated */ - s = xmalloc (key.dsize + 1); - (void) strncpy (s, key.dptr, key.dsize); - s[key.dsize] = '\0'; - - p = findnode (db->dbm_list, s); - if (p) - { - val.dptr = p->data; - val.dsize = strlen (p->data); - } - else - { - val.dptr = (char *) NULL; - val.dsize = 0; - } - free (s); - return (val); -} - -datum -mydbm_firstkey (db) - DBM *db; -{ - Node *head, *p; - datum key; - - head = db->dbm_list->list; - p = head->next; - if (p != head) - { - key.dptr = p->key; - key.dsize = strlen (p->key); - } - else - { - key.dptr = (char *) NULL; - key.dsize = 0; - } - db->dbm_next = p->next; - return (key); -} - -datum -mydbm_nextkey (db) - DBM *db; -{ - Node *head, *p; - datum key; - - head = db->dbm_list->list; - p = db->dbm_next; - if (p != head) - { - key.dptr = p->key; - key.dsize = strlen (p->key); - } - else - { - key.dptr = (char *) NULL; - key.dsize = 0; - } - db->dbm_next = p->next; - return (key); -} - -/* Note: only updates the in-memory copy, which is written out at - mydbm_close time. Note: Also differs from DBM in that on duplication, - it gives a warning, rather than either DBM_INSERT or DBM_REPLACE - behavior. */ -int -mydbm_store (db, key, value, flags) - DBM *db; - datum key; - datum value; - int flags; -{ - Node *node; - - node = getnode (); - node->type = NDBMNODE; - - node->key = xmalloc (key.dsize + 1); - *node->key = '\0'; - strncat (node->key, key.dptr, key.dsize); - - node->data = xmalloc (value.dsize + 1); - *(char *)node->data = '\0'; - strncat (node->data, value.dptr, value.dsize); - - db->modified = 1; - if (addnode (db->dbm_list, node) == -1) - { - error (0, 0, "attempt to insert duplicate key `%s'", node->key); - freenode (node); - return 0; - } - return 0; -} - -static void -mydbm_load_file (fp, list, filename) - FILE *fp; - List *list; - char *filename; /* Used in error messages. */ -{ - char *line = NULL; - size_t line_size; - char *value; - size_t value_allocated; - char *cp, *vp; - int cont; - int line_length; - int line_num; - - value_allocated = 1; - value = xmalloc (value_allocated); - - cont = 0; - line_num=0; - while ((line_length = - getstr (&line, &line_size, fp, '\012', 0, GETLINE_NO_LIMIT)) >= 0) - { - line_num++; - if (line_length > 0 && line[line_length - 1] == '\012') - { - /* Strip the newline. */ - --line_length; - line[line_length] = '\0'; - } - if (line_length > 0 && line[line_length - 1] == '\015') - { - /* If the file (e.g. modules) was written on an NT box, it will - contain CRLF at the ends of lines. Strip them (we can't do - this by opening the file in text mode because we might be - running on unix). */ - --line_length; - line[line_length] = '\0'; - } - - /* - * Add the line to the value, at the end if this is a continuation - * line; otherwise at the beginning, but only after any trailing - * backslash is removed. - */ - if (!cont) - value[0] = '\0'; - - /* - * See if the line we read is a continuation line, and strip the - * backslash if so. - */ - if (line_length > 0) - cp = &line[line_length - 1]; - else - cp = line; - if (*cp == '\\') - { - cont = 1; - *cp = '\0'; - --line_length; - } - else - { - cont = 0; - } - expand_string (&value, - &value_allocated, - strlen (value) + line_length + 5); - strcat (value, line); - - if (value[0] == '#') - continue; /* comment line */ - vp = value; - while (*vp && isspace ((unsigned char) *vp)) - vp++; - if (*vp == '\0') - continue; /* empty line */ - - /* - * If this was not a continuation line, add the entry to the database - */ - if (!cont) - { - Node *p = getnode (); - char *kp; - - kp = vp; - while (*vp && !isspace ((unsigned char) *vp)) - vp++; - if (*vp) - *vp++ = '\0'; /* NULL terminate the key */ - p->type = NDBMNODE; - p->key = xstrdup (kp); - while (*vp && isspace ((unsigned char) *vp)) - vp++; /* skip whitespace to value */ - if (*vp == '\0') - { - if (!really_quiet) - error (0, 0, - "warning: NULL value for key `%s' at line %d of `%s'", - p->key, line_num, filename); - freenode (p); - continue; - } - p->data = xstrdup (vp); - if (addnode (list, p) == -1) - { - if (!really_quiet) - error (0, 0, - "duplicate key found for `%s' at line %d of `%s'", - p->key, line_num, filename); - freenode (p); - } - } - } - if (line_length < 0 && !feof (fp)) - /* FIXME: should give the name of the file. */ - error (0, errno, "cannot read file in mydbm_load_file"); - - free (line); - free (value); -} - -#endif /* MY_NDBM */ diff --git a/contrib/cvs/src/myndbm.h b/contrib/cvs/src/myndbm.h deleted file mode 100644 index de23519..0000000 --- a/contrib/cvs/src/myndbm.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (C) 1994-2005 The Free Software Foundation, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#ifdef MY_NDBM - -#define DBLKSIZ 4096 - -typedef struct -{ - List *dbm_list; /* cached database */ - Node *dbm_next; /* next key to return for nextkey() */ - - /* Name of the file to write to if modified is set. malloc'd. */ - char *name; - - /* Nonzero if the database has been modified and dbm_close needs to - write it out to disk. */ - int modified; -} DBM; - -typedef struct -{ - char *dptr; - int dsize; -} datum; - -/* - * So as not to conflict with other dbm_open, etc., routines that may - * be included by someone's libc, all of my emulation routines are prefixed - * by "my" and we define the "standard" ones to be "my" ones here. - */ -#define dbm_open mydbm_open -#define dbm_close mydbm_close -#define dbm_fetch mydbm_fetch -#define dbm_firstkey mydbm_firstkey -#define dbm_nextkey mydbm_nextkey -#define dbm_store mydbm_store -#define DBM_INSERT 0 -#define DBM_REPLACE 1 - -DBM *mydbm_open PROTO((char *file, int flags, int mode)); -void mydbm_close PROTO((DBM * db)); -datum mydbm_fetch PROTO((DBM * db, datum key)); -datum mydbm_firstkey PROTO((DBM * db)); -datum mydbm_nextkey PROTO((DBM * db)); -extern int mydbm_store PROTO ((DBM *, datum, datum, int)); - -#endif /* MY_NDBM */ diff --git a/contrib/cvs/src/no_diff.c b/contrib/cvs/src/no_diff.c deleted file mode 100644 index 45847a1..0000000 --- a/contrib/cvs/src/no_diff.c +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (C) 1986-2005 The Free Software Foundation, Inc. - * - * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot , - * and others. - * - * Portions Copyright (C) 1992, Brian Berliner and Jeff Polk - * Portions Copyright (C) 1989-1992, Brian Berliner - * - * You may distribute under the terms of the GNU General Public License as - * specified in the README file that comes with the CVS source distribution. - * - * No Difference - * - * The user file looks modified judging from its time stamp; however it needn't - * be. No_Difference() finds out whether it is or not. If it is not, it - * updates the administration. - * - * returns 0 if no differences are found and non-zero otherwise - */ - -#include "cvs.h" -#include - -int -No_Difference (finfo, vers) - struct file_info *finfo; - Vers_TS *vers; -{ - Node *p; - int ret; - char *ts, *options; - int retcode = 0; - char *tocvsPath; - - /* If ts_user is "Is-modified", we can only conclude the files are - different (since we don't have the file's contents). */ - if (vers->ts_user != NULL - && strcmp (vers->ts_user, "Is-modified") == 0) - return -1; - - if (!vers->srcfile || !vers->srcfile->path) - return (-1); /* different since we couldn't tell */ - -#ifdef PRESERVE_PERMISSIONS_SUPPORT - /* If special files are in use, then any mismatch of file metadata - information also means that the files should be considered different. */ - if (preserve_perms && special_file_mismatch (finfo, vers->vn_user, NULL)) - return 1; -#endif - - if (vers->entdata && vers->entdata->options) - options = xstrdup (vers->entdata->options); - else - options = xstrdup (""); - - tocvsPath = wrap_tocvs_process_file (finfo->file); - retcode = RCS_cmp_file( vers->srcfile, vers->vn_user, (char **)NULL, - (char *)NULL, options, - tocvsPath == NULL ? finfo->file : tocvsPath ); - if (retcode == 0) - { - /* no difference was found, so fix the entries file */ - ts = time_stamp (finfo->file); - Register (finfo->entries, finfo->file, - vers->vn_user ? vers->vn_user : vers->vn_rcs, ts, - options, vers->tag, vers->date, (char *) 0); -#ifdef SERVER_SUPPORT - if (server_active) - { - /* We need to update the entries line on the client side. */ - server_update_entries - (finfo->file, finfo->update_dir, finfo->repository, SERVER_UPDATED); - } -#endif - free (ts); - - /* update the entdata pointer in the vers_ts structure */ - p = findnode (finfo->entries, finfo->file); - assert (p); - vers->entdata = p->data; - - ret = 0; - } - else - ret = 1; /* files were really different */ - - if (tocvsPath) - { - /* Need to call unlink myself because the noexec variable - * has been set to 1. */ - if (trace) - (void) fprintf (stderr, "%s-> unlink (%s)\n", - CLIENT_SERVER_STR, tocvsPath); - if ( CVS_UNLINK (tocvsPath) < 0) - error (0, errno, "could not remove %s", tocvsPath); - } - - free (options); - return (ret); -} diff --git a/contrib/cvs/src/parseinfo.c b/contrib/cvs/src/parseinfo.c deleted file mode 100644 index bf1e095..0000000 --- a/contrib/cvs/src/parseinfo.c +++ /dev/null @@ -1,511 +0,0 @@ -/* - * Copyright (C) 1986-2008 The Free Software Foundation, Inc. - * - * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot , - * and others. - * - * Portions Copyright (C) 1992, Brian Berliner and Jeff Polk - * Portions Copyright (C) 1989-1992, Brian Berliner - * - * You may distribute under the terms of the GNU General Public License as - * specified in the README file that comes with the CVS source distribution. - * - * $FreeBSD$ - */ - -#include "cvs.h" -#include "getline.h" -#include -#include "history.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 matching "ALL", or if no lines match, the last line matching - * "DEFAULT". - * - * Return 0 for success, -1 if there was not an INFOFILE, and >0 for failure. - */ -int -Parse_Info (infofile, repository, callproc, all) - const char *infofile; - const char *repository; - CALLPROC callproc; - int all; -{ - int err = 0; - FILE *fp_info; - char *infopath; - char *line = NULL; - size_t line_allocated = 0; - char *default_value = NULL; - int default_line = 0; - char *expanded_value; - int callback_done, line_number; - char *cp, *exp, *value; - const char *srepos; - const char *regex_err; - - assert (repository); - - if (current_parsed_root == NULL) - { - /* XXX - should be error maybe? */ - error (0, 0, "CVSROOT variable not set"); - return (1); - } - - /* find the info file and open it */ - infopath = xmalloc (strlen (current_parsed_root->directory) - + strlen (infofile) - + sizeof (CVSROOTADM) - + 3); - (void) sprintf (infopath, "%s/%s/%s", current_parsed_root->directory, - CVSROOTADM, infofile); - fp_info = CVS_FOPEN (infopath, "r"); - if (fp_info == NULL) - { - /* If no file, don't do anything special. */ - if (!existence_error (errno)) - error (0, errno, "cannot open %s", infopath); - free (infopath); - return 0; - } - - /* strip off the CVSROOT if repository was absolute */ - srepos = Short_Repository (repository); - - if (trace) - (void) fprintf (stderr, "%s-> Parse_Info (%s, %s, %s)\n", -#ifdef SERVER_SUPPORT - server_active ? "S" : " ", -#else - "", -#endif - infopath, srepos, all ? "ALL" : "not ALL"); - - /* search the info file for lines that match */ - callback_done = line_number = 0; - while (getline (&line, &line_allocated, fp_info) >= 0) - { - line_number++; - - /* skip lines starting with # */ - if (line[0] == '#') - continue; - - /* skip whitespace at beginning of line */ - for (cp = line; *cp && isspace ((unsigned char) *cp); cp++) - ; - - /* if *cp is null, the whole line was blank */ - if (*cp == '\0') - continue; - - /* the regular expression is everything up to the first space */ - for (exp = cp; *cp && !isspace ((unsigned char) *cp); cp++) - ; - if (*cp != '\0') - *cp++ = '\0'; - - /* skip whitespace up to the start of the matching value */ - while (*cp && isspace ((unsigned char) *cp)) - cp++; - - /* no value to match with the regular expression is an error */ - if (*cp == '\0') - { - error (0, 0, "syntax error at line %d file %s; ignored", - line_number, infofile); - continue; - } - value = cp; - - /* strip the newline off the end of the value */ - if ((cp = strrchr (value, '\n')) != NULL) - *cp = '\0'; - - /* - * At this point, exp points to the regular expression, and value - * points to the value to call the callback routine with. Evaluate - * the regular expression against srepos and callback with the value - * if it matches. - */ - - /* save the default value so we have it later if we need it */ - if (strcmp (exp, "DEFAULT") == 0) - { - if (default_value != NULL) - { - error (0, 0, "Multiple `DEFAULT' lines (%d and %d) in %s file", - default_line, line_number, infofile); - free (default_value); - } - default_value = xstrdup(value); - default_line = line_number; - continue; - } - - /* - * For a regular expression of "ALL", do the callback always We may - * execute lots of ALL callbacks in addition to *one* regular matching - * callback or default - */ - if (strcmp (exp, "ALL") == 0) - { - if (!all) - error(0, 0, "Keyword `ALL' is ignored at line %d in %s file", - line_number, infofile); - else if ((expanded_value = expand_path (value, infofile, - line_number)) != NULL) - { - err += callproc (repository, expanded_value); - free (expanded_value); - } - else - err++; - continue; - } - - if (callback_done) - /* only first matching, plus "ALL"'s */ - continue; - - /* see if the repository matched this regular expression */ - if ((regex_err = re_comp (exp)) != NULL) - { - error (0, 0, "bad regular expression at line %d file %s: %s", - line_number, infofile, regex_err); - continue; - } - if (re_exec (srepos) == 0) - continue; /* no match */ - - /* it did, so do the callback and note that we did one */ - if ((expanded_value = expand_path (value, infofile, line_number)) != NULL) - { - err += callproc (repository, expanded_value); - free (expanded_value); - } - else - err++; - callback_done = 1; - } - if (ferror (fp_info)) - error (0, errno, "cannot read %s", infopath); - if (fclose (fp_info) < 0) - error (0, errno, "cannot close %s", infopath); - - /* if we fell through and didn't callback at all, do the default */ - if (callback_done == 0 && default_value != NULL) - { - if ((expanded_value = expand_path (default_value, infofile, default_line)) != NULL) - { - err += callproc (repository, expanded_value); - free (expanded_value); - } - else - err++; - } - - /* free up space if necessary */ - if (default_value != NULL) - free (default_value); - free (infopath); - if (line != NULL) - free (line); - - return (err); -} - - -/* Parse the CVS config file. The syntax right now is a bit ad hoc - but tries to draw on the best or more common features of the other - *info files and various unix (or non-unix) config file syntaxes. - Lines starting with # are comments. Settings are lines of the form - KEYWORD=VALUE. There is currently no way to have a multi-line - VALUE (would be nice if there was, probably). - - CVSROOT is the $CVSROOT directory - (current_parsed_root->directory might not be set yet, so this - function takes the cvsroot as a function argument). - - Returns 0 for success, negative value for failure. Call - error(0, ...) on errors in addition to the return value. */ -int -parse_config (cvsroot) - char *cvsroot; -{ - char *infopath; - FILE *fp_info; - char *line = NULL; - size_t line_allocated = 0; - size_t len; - char *p; - /* FIXME-reentrancy: If we do a multi-threaded server, this would need - to go to the per-connection data structures. */ - static int parsed = 0; - int ignore_unknown_config_keys = 0; - - /* Authentication code and serve_root might both want to call us. - Let this happen smoothly. */ - if (parsed) - return 0; - parsed = 1; - - infopath = xmalloc (strlen (cvsroot) - + sizeof (CVSROOTADM_CONFIG) - + sizeof (CVSROOTADM) - + 10); - if (infopath == NULL) - { - error (0, 0, "out of memory; cannot allocate infopath"); - goto error_return; - } - - strcpy (infopath, cvsroot); - strcat (infopath, "/"); - strcat (infopath, CVSROOTADM); - strcat (infopath, "/"); - strcat (infopath, CVSROOTADM_CONFIG); - - fp_info = CVS_FOPEN (infopath, "r"); - if (fp_info == NULL) - { - /* If no file, don't do anything special. */ - if (!existence_error (errno)) - { - /* Just a warning message; doesn't affect return - value, currently at least. */ - error (0, errno, "cannot open %s", infopath); - } - goto set_defaults_and_return; - } - - while (getline (&line, &line_allocated, fp_info) >= 0) - { - /* Skip comments. */ - if (line[0] == '#') - continue; - - /* At least for the moment we don't skip whitespace at the start - of the line. Too picky? Maybe. But being insufficiently - picky leads to all sorts of confusion, and it is a lot easier - to start out picky and relax it than the other way around. - - Is there any kind of written standard for the syntax of this - sort of config file? Anywhere in POSIX for example (I guess - makefiles are sort of close)? Red Hat Linux has a bunch of - these too (with some GUI tools which edit them)... - - Along the same lines, we might want a table of keywords, - with various types (boolean, string, &c), as a mechanism - for making sure the syntax is consistent. Any good examples - to follow there (Apache?)? */ - - /* Strip the trailing newline. There will be one unless we - read a partial line without a newline, and then got end of - file (or error?). */ - - len = strlen (line) - 1; - if (line[len] == '\n') - line[len] = '\0'; - - /* Skip blank lines. */ - if (line[0] == '\0') - continue; - - /* The first '=' separates keyword from value. */ - p = strchr (line, '='); - if (p == NULL) - { - /* Probably should be printing line number. */ - error (0, 0, "syntax error in %s: line '%s' is missing '='", - infopath, line); - goto error_return; - } - - *p++ = '\0'; - - if (strcmp (line, "RCSBIN") == 0) - { - /* This option used to specify the directory for RCS - executables. But since we don't run them any more, - this is a noop. Silently ignore it so that a - repository can work with either new or old CVS. */ - ; - } - else if (strcmp (line, "SystemAuth") == 0) - { - if (strcmp (p, "no") == 0) -#ifdef AUTH_SERVER_SUPPORT - system_auth = 0; -#else - /* Still parse the syntax but ignore the - option. That way the same config file can - be used for local and server. */ - ; -#endif - else if (strcmp (p, "yes") == 0) -#ifdef AUTH_SERVER_SUPPORT - system_auth = 1; -#else - ; -#endif - else - { - error (0, 0, "unrecognized value '%s' for SystemAuth", p); - goto error_return; - } - } - else if (strcmp (line, "tag") == 0) { - RCS_setlocalid(p); - } - else if (strcmp (line, "umask") == 0) { - cvsumask = (mode_t)(strtol(p, NULL, 8) & 0777); - } - else if (strcmp (line, "dlimit") == 0) { -#ifdef BSD -#include - struct rlimit rl; - - if (getrlimit(RLIMIT_DATA, &rl) != -1) { - rl.rlim_cur = atoi(p); - rl.rlim_cur *= 1024; - - (void) setrlimit(RLIMIT_DATA, &rl); - } -#endif /* BSD */ - } - else if (strcmp (line, "PreservePermissions") == 0) - { - if (strcmp (p, "no") == 0) - preserve_perms = 0; - else if (strcmp (p, "yes") == 0) - { -#ifdef PRESERVE_PERMISSIONS_SUPPORT - preserve_perms = 1; -#else - error (0, 0, "\ -warning: this CVS does not support PreservePermissions"); -#endif - } - else - { - error (0, 0, "unrecognized value '%s' for PreservePermissions", - p); - goto error_return; - } - } - else if (strcmp (line, "TopLevelAdmin") == 0) - { - if (strcmp (p, "no") == 0) - top_level_admin = 0; - else if (strcmp (p, "yes") == 0) - top_level_admin = 1; - else - { - error (0, 0, "unrecognized value '%s' for TopLevelAdmin", p); - goto error_return; - } - } - else if (strcmp (line, "LockDir") == 0) - { - if (lock_dir != NULL) - free (lock_dir); - lock_dir = xstrdup (p); - /* Could try some validity checking, like whether we can - 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) - { - if (logHistory) free (logHistory); - logHistory = xstrdup (p); - } - } - else if (strcmp (line, "RereadLogAfterVerify") == 0) - { - if (strcmp (p, "no") == 0 || strcmp (p, "never") == 0) - RereadLogAfterVerify = LOGMSG_REREAD_NEVER; - else if (strcmp (p, "yes") == 0 || strcmp (p, "always") == 0) - RereadLogAfterVerify = LOGMSG_REREAD_ALWAYS; - else if (strcmp (p, "stat") == 0) - RereadLogAfterVerify = LOGMSG_REREAD_STAT; - } - else if (strcmp(line, "LocalKeyword") == 0) - { - /* Recognize cvs-1.12-style keyword control rather than erroring out. */ - RCS_setlocalid(p); - } - else if (strcmp(line, "KeywordExpand") == 0) - { - /* Recognize cvs-1.12-style keyword control rather than erroring out. */ - RCS_setincexc(p); - } - else if (strcmp (line, "IgnoreUnknownConfigKeys") == 0) - { - if (strcmp (p, "no") == 0 || strcmp (p, "false") == 0 - || strcmp (p, "off") == 0 || strcmp (p, "0") == 0) - ignore_unknown_config_keys = 0; - else if (strcmp (p, "yes") == 0 || strcmp (p, "true") == 0 - || strcmp (p, "on") == 0 || strcmp (p, "1") == 0) - ignore_unknown_config_keys = 1; - else - { - error (0, 0, "%s: unrecognized value '%s' for '%s'", - infopath, p, line); - goto error_return; - } - } - else if (ignore_unknown_config_keys) - ; - else - { - /* We may be dealing with a keyword which was added in a - subsequent version of CVS. In that case it is a good idea - to complain, as (1) the keyword might enable a behavior like - alternate locking behavior, in which it is dangerous and hard - to detect if some CVS's have it one way and others have it - the other way, (2) in general, having us not do what the user - had in mind when they put in the keyword violates the - principle of least surprise. Note that one corollary is - adding new keywords to your CVSROOT/config file is not - particularly recommended unless you are planning on using - the new features. */ - error (0, 0, "%s: unrecognized keyword '%s'", - infopath, line); - goto error_return; - } - } - if (ferror (fp_info)) - { - error (0, errno, "cannot read %s", infopath); - goto error_return; - } - if (fclose (fp_info) < 0) - { - error (0, errno, "cannot close %s", infopath); - goto error_return; - } -set_defaults_and_return: - if (!logHistory) - logHistory = xstrdup (ALL_HISTORY_REC_TYPES); - free (infopath); - if (line != NULL) - free (line); - return 0; - - error_return: - if (!logHistory) - logHistory = xstrdup (ALL_HISTORY_REC_TYPES); - if (infopath != NULL) - free (infopath); - if (line != NULL) - free (line); - return -1; -} diff --git a/contrib/cvs/src/patch.c b/contrib/cvs/src/patch.c deleted file mode 100644 index 65f5051..0000000 --- a/contrib/cvs/src/patch.c +++ /dev/null @@ -1,849 +0,0 @@ -/* - * Copyright (C) 1986-2005 The Free Software Foundation, Inc. - * - * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot , - * and others. - * - * Portions Copyright (C) 1992, Brian Berliner and Jeff Polk - * Portions Copyright (C) 1989-1992, Brian Berliner - * - * You may distribute under the terms of the GNU General Public License as - * specified in the README file that comes with the CVS source distribution. - * - * Patch - * - * Create a Larry Wall format "patch" file between a previous release and the - * current head of a module, or between two releases. Can specify the - * release as either a date or a revision number. - * - * $FreeBSD$ - */ - -#include -#include "cvs.h" -#include "getline.h" - -static RETSIGTYPE patch_cleanup PROTO((void)); -static Dtype patch_dirproc PROTO ((void *callerdat, const char *dir, - const char *repos, const char *update_dir, - List *entries)); -static int patch_fileproc PROTO ((void *callerdat, struct file_info *finfo)); -static int patch_proc PROTO((int argc, char **argv, char *xwhere, - char *mwhere, char *mfile, int shorten, - int local_specified, char *mname, char *msg)); - -static int force_tag_match = 1; -static int patch_short = 0; -static int toptwo_diffs = 0; -static char *options = NULL; -static char *rev1 = NULL; -static int rev1_validated = 0; -static char *rev2 = NULL; -static int rev2_validated = 0; -static char *date1 = NULL; -static char *date2 = NULL; -static char *tmpfile1 = NULL; -static char *tmpfile2 = NULL; -static char *tmpfile3 = NULL; -static int unidiff = 0; - -static const char *const patch_usage[] = -{ - "Usage: %s %s [-flR] [-c|-u] [-s|-t] [-V %%d] [-k kopt]\n", - " -r rev|-D date [-r rev2 | -D date2] modules...\n", - "\t-f\tForce a head revision match if tag/date not found.\n", - "\t-l\tLocal directory only, not recursive\n", - "\t-R\tProcess directories recursively.\n", - "\t-c\tContext diffs (default)\n", - "\t-u\tUnidiff format.\n", - "\t-s\tShort patch - one liner per file.\n", - "\t-t\tTop two diffs - last change made to the file.\n", - "\t-V vers\tUse RCS Version \"vers\" for keyword expansion.\n", - "\t-k kopt\tSpecify keyword expansion mode.\n", - "\t-D date\tDate.\n", - "\t-r rev\tRevision - symbolic or numeric.\n", - "(Specify the --help global option for a list of other help options)\n", - NULL -}; - - - -int -patch (argc, argv) - int argc; - char **argv; -{ - register int i; - int local = 0; - int c; - int err = 0; - DBM *db; - - if (argc == -1) - usage (patch_usage); - - optind = 0; - while ((c = getopt (argc, argv, "+V:k:cuftsQqlRD:r:")) != -1) - { - switch (c) - { - case 'Q': - case 'q': - /* The CVS 1.5 client sends these options (in addition to - Global_option requests), so we must ignore them. */ - if (!server_active) - error (1, 0, - "-q or -Q must be specified before \"%s\"", - cvs_cmd_name); - break; - case 'f': - force_tag_match = 0; - break; - case 'l': - local = 1; - break; - case 'R': - local = 0; - break; - case 't': - toptwo_diffs = 1; - break; - case 's': - patch_short = 1; - break; - case 'D': - if (rev2 != NULL || date2 != NULL) - error (1, 0, - "no more than two revisions/dates can be specified"); - if (rev1 != NULL || date1 != NULL) - date2 = Make_Date (optarg); - else - date1 = Make_Date (optarg); - break; - case 'r': - if (rev2 != NULL || date2 != NULL) - error (1, 0, - "no more than two revisions/dates can be specified"); - if (rev1 != NULL || date1 != NULL) - rev2 = optarg; - else - rev1 = optarg; - break; - case 'k': - if (options) - free (options); - options = RCS_check_kflag (optarg); - break; - case 'V': - /* This option is pretty seriously broken: - 1. It is not clear what it does (does it change keyword - expansion behavior? If so, how? Or does it have - something to do with what version of RCS we are using? - Or the format we write RCS files in?). - 2. Because both it and -k use the options variable, - specifying both -V and -k doesn't work. - 3. At least as of CVS 1.9, it doesn't work (failed - assertion in RCS_checkout where it asserts that options - starts with -k). Few people seem to be complaining. - In the future (perhaps the near future), I have in mind - removing it entirely, and updating NEWS and cvs.texinfo, - but in case it is a good idea to give people more time - to complain if they would miss it, I'll just add this - quick and dirty error message for now. */ - error (1, 0, - "the -V option is obsolete and should not be used"); -#if 0 - if (atoi (optarg) <= 0) - error (1, 0, "must specify a version number to -V"); - if (options) - free (options); - options = xmalloc (strlen (optarg) + 1 + 2); /* for the -V */ - (void) sprintf (options, "-V%s", optarg); -#endif - break; - case 'u': - unidiff = 1; /* Unidiff */ - break; - case 'c': /* Context diff */ - unidiff = 0; - break; - case '?': - default: - usage (patch_usage); - break; - } - } - argc -= optind; - argv += optind; - - /* Sanity checks */ - if (argc < 1) - usage (patch_usage); - - if (toptwo_diffs && patch_short) - error (1, 0, "-t and -s options are mutually exclusive"); - if (toptwo_diffs && (date1 != NULL || date2 != NULL || - rev1 != NULL || rev2 != NULL)) - error (1, 0, "must not specify revisions/dates with -t option!"); - - if (!toptwo_diffs && (date1 == NULL && date2 == NULL && - rev1 == NULL && rev2 == NULL)) - error (1, 0, "must specify at least one revision/date!"); - if (date1 != NULL && date2 != NULL) - if (RCS_datecmp (date1, date2) >= 0) - error (1, 0, "second date must come after first date!"); - - /* if options is NULL, make it a NULL string */ - if (options == NULL) - options = xstrdup (""); - -#ifdef CLIENT_SUPPORT - if (current_parsed_root->isremote) - { - /* We're the client side. Fire up the remote server. */ - start_server (); - - ign_setup (); - - if (local) - send_arg("-l"); - if (!force_tag_match) - send_arg("-f"); - if (toptwo_diffs) - send_arg("-t"); - if (patch_short) - send_arg("-s"); - if (unidiff) - send_arg("-u"); - - if (rev1) - option_with_arg ("-r", rev1); - if (date1) - client_senddate (date1); - if (rev2) - option_with_arg ("-r", rev2); - if (date2) - client_senddate (date2); - if (options[0] != '\0') - send_arg (options); - - { - int i; - for (i = 0; i < argc; ++i) - send_arg (argv[i]); - } - - send_to_server ("rdiff\012", 0); - return get_responses_and_close (); - } -#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 -#ifdef SIGINT - (void)SIG_register (SIGINT, patch_cleanup); -#endif -#ifdef SIGQUIT - (void)SIG_register (SIGQUIT, patch_cleanup); -#endif -#ifdef SIGPIPE - (void)SIG_register (SIGPIPE, patch_cleanup); -#endif -#ifdef SIGTERM - (void)SIG_register (SIGTERM, patch_cleanup); -#endif - - db = open_module (); - for (i = 0; i < argc; i++) - err += do_module (db, argv[i], PATCH, "Patching", patch_proc, - (char *)NULL, 0, local, 0, 0, (char *)NULL); - close_module (db); - free (options); - patch_cleanup (); - return err; -} - - - -/* - * callback proc for doing the real work of patching - */ -/* ARGSUSED */ -static int -patch_proc (argc, argv, xwhere, mwhere, mfile, shorten, local_specified, - mname, msg) - int argc; - char **argv; - char *xwhere; - char *mwhere; - char *mfile; - int shorten; - int local_specified; - char *mname; - char *msg; -{ - char *myargv[2]; - int err = 0; - int which; - char *repository; - char *where; - - repository = xmalloc (strlen (current_parsed_root->directory) - + strlen (argv[0]) - + (mfile == NULL ? 0 : strlen (mfile) + 1) + 2); - (void)sprintf (repository, "%s/%s", - current_parsed_root->directory, argv[0]); - where = xmalloc (strlen (argv[0]) + (mfile == NULL ? 0 : strlen (mfile) + 1) - + 1); - (void)strcpy (where, argv[0]); - - /* if mfile isn't null, we need to set up to do only part of the module */ - if (mfile != NULL) - { - char *cp; - char *path; - - /* if the portion of the module is a path, put the dir part on repos */ - if ((cp = strrchr (mfile, '/')) != NULL) - { - *cp = '\0'; - (void)strcat (repository, "/"); - (void)strcat (repository, mfile); - (void)strcat (where, "/"); - (void)strcat (where, mfile); - mfile = cp + 1; - } - - /* take care of the rest */ - path = xmalloc (strlen (repository) + strlen (mfile) + 2); - (void)sprintf (path, "%s/%s", repository, mfile); - if (isdir (path)) - { - /* directory means repository gets the dir tacked on */ - (void)strcpy (repository, path); - (void)strcat (where, "/"); - (void)strcat (where, mfile); - } - else - { - myargv[0] = argv[0]; - myargv[1] = mfile; - argc = 2; - argv = myargv; - } - free (path); - } - - /* cd to the starting repository */ - if ( CVS_CHDIR (repository) < 0) - { - error (0, errno, "cannot chdir to %s", repository); - free (repository); - free (where); - return 1; - } - - if (force_tag_match) - which = W_REPOS | W_ATTIC; - else - which = W_REPOS; - - if (rev1 != NULL && !rev1_validated) - { - tag_check_valid (rev1, argc - 1, argv + 1, local_specified, 0, - repository); - rev1_validated = 1; - } - if (rev2 != NULL && !rev2_validated) - { - tag_check_valid (rev2, argc - 1, argv + 1, local_specified, 0, - repository); - rev2_validated = 1; - } - - /* start the recursion processor */ - err = start_recursion (patch_fileproc, (FILESDONEPROC)NULL, patch_dirproc, - (DIRLEAVEPROC)NULL, NULL, - argc - 1, argv + 1, local_specified, - which, 0, CVS_LOCK_READ, where, 1, repository); - free (repository); - free (where); - - return err; -} - - - -/* - * Called to examine a particular RCS file, as appropriate with the options - * that were set above. - */ -/* ARGSUSED */ -static int -patch_fileproc (callerdat, finfo) - void *callerdat; - struct file_info *finfo; -{ - struct utimbuf t; - char *vers_tag, *vers_head; - char *rcs = NULL; - char *rcs_orig = NULL; - RCSNode *rcsfile; - FILE *fp1, *fp2, *fp3; - int ret = 0; - int isattic = 0; - int retcode = 0; - char *file1; - char *file2; - char *strippath; - char *line1, *line2; - size_t line1_chars_allocated; - size_t line2_chars_allocated; - char *cp1, *cp2; - FILE *fp; - int line_length; - int dargc = 0; - size_t darg_allocated = 0; - char **dargv = NULL; - - line1 = NULL; - line1_chars_allocated = 0; - line2 = NULL; - line2_chars_allocated = 0; - vers_tag = vers_head = NULL; - - /* find the parsed rcs file */ - if ((rcsfile = finfo->rcs) == NULL) - { - ret = 1; - goto out2; - } - if ((rcsfile->flags & VALID) && (rcsfile->flags & INATTIC)) - isattic = 1; - - rcs_orig = rcs = xmalloc (strlen (finfo->file) + sizeof (RCSEXT) + 5); - (void) sprintf (rcs, "%s%s", finfo->file, RCSEXT); - - /* if vers_head is NULL, may have been removed from the release */ - if (isattic && rev2 == NULL && date2 == NULL) - vers_head = NULL; - else - { - vers_head = RCS_getversion (rcsfile, rev2, date2, force_tag_match, - (int *) NULL); - if (vers_head != NULL && RCS_isdead (rcsfile, vers_head)) - { - free (vers_head); - vers_head = NULL; - } - } - - if (toptwo_diffs) - { - if (vers_head == NULL) - { - ret = 1; - goto out2; - } - - if (!date1) - date1 = xmalloc (MAXDATELEN); - *date1 = '\0'; - if (RCS_getrevtime (rcsfile, vers_head, date1, 1) == (time_t)-1) - { - if (!really_quiet) - error (0, 0, "cannot find date in rcs file %s revision %s", - rcs, vers_head); - ret = 1; - goto out2; - } - } - vers_tag = RCS_getversion (rcsfile, rev1, date1, force_tag_match, - (int *) NULL); - if (vers_tag != NULL && RCS_isdead (rcsfile, vers_tag)) - { - free (vers_tag); - vers_tag = NULL; - } - - if ((vers_tag == NULL && vers_head == NULL) || - (vers_tag != NULL && vers_head != NULL && - strcmp (vers_head, vers_tag) == 0)) - { - /* Nothing known about specified revs or - * not changed between releases. - */ - ret = 0; - goto out2; - } - - if( patch_short && ( vers_tag == NULL || vers_head == NULL ) ) - { - /* For adds & removes with a short patch requested, we can print our - * error message now and get out. - */ - cvs_output ("File ", 0); - cvs_output (finfo->fullname, 0); - if (vers_tag == NULL) - { - cvs_output( " is new; ", 0 ); - cvs_output( rev2 ? rev2 : date2 ? date2 : "current", 0 ); - cvs_output( " revision ", 0 ); - cvs_output (vers_head, 0); - cvs_output ("\n", 1); - } - else - { - cvs_output( " is removed; ", 0 ); - cvs_output( rev1 ? rev1 : date1, 0 ); - cvs_output( " revision ", 0 ); - cvs_output( vers_tag, 0 ); - cvs_output ("\n", 1); - } - ret = 0; - goto out2; - } - - /* Create 3 empty files. I'm not really sure there is any advantage - * to doing so now rather than just waiting until later. - * - * There is - cvs_temp_file opens the file so that it can guarantee that - * we have exclusive write access to the file. Unfortunately we spoil that - * by closing it and reopening it again. Of course any better solution - * requires that the RCS functions accept open file pointers rather than - * simple file names. - */ - if ((fp1 = cvs_temp_file (&tmpfile1)) == NULL) - { - error (0, errno, "cannot create temporary file %s", - tmpfile1 ? tmpfile1 : "(null)"); - ret = 1; - goto out; - } - else - if (fclose (fp1) < 0) - error (0, errno, "warning: cannot close %s", tmpfile1); - if ((fp2 = cvs_temp_file (&tmpfile2)) == NULL) - { - error (0, errno, "cannot create temporary file %s", - tmpfile2 ? tmpfile2 : "(null)"); - ret = 1; - goto out; - } - else - if (fclose (fp2) < 0) - error (0, errno, "warning: cannot close %s", tmpfile2); - if ((fp3 = cvs_temp_file (&tmpfile3)) == NULL) - { - error (0, errno, "cannot create temporary file %s", - tmpfile3 ? tmpfile3 : "(null)"); - ret = 1; - goto out; - } - else - if (fclose (fp3) < 0) - error (0, errno, "warning: cannot close %s", tmpfile3); - - if (vers_tag != NULL) - { - retcode = RCS_checkout (rcsfile, (char *)NULL, vers_tag, - rev1, options, tmpfile1, - (RCSCHECKOUTPROC)NULL, (void *)NULL); - if (retcode != 0) - { - error (0, 0, - "cannot check out revision %s of %s", vers_tag, rcs); - ret = 1; - goto out; - } - memset ((char *) &t, 0, sizeof (t)); - if ((t.actime = t.modtime = RCS_getrevtime (rcsfile, vers_tag, - (char *) 0, 0)) != -1) - /* I believe this timestamp only affects the dates in our diffs, - and therefore should be on the server, not the client. */ - (void) utime (tmpfile1, &t); - } - else if (toptwo_diffs) - { - ret = 1; - goto out; - } - if (vers_head != NULL) - { - retcode = RCS_checkout (rcsfile, (char *)NULL, vers_head, - rev2, options, tmpfile2, - (RCSCHECKOUTPROC)NULL, (void *)NULL); - if (retcode != 0) - { - error (0, 0, - "cannot check out revision %s of %s", vers_head, rcs); - ret = 1; - goto out; - } - if ((t.actime = t.modtime = RCS_getrevtime (rcsfile, vers_head, - (char *)0, 0)) != -1) - /* I believe this timestamp only affects the dates in our diffs, - and therefore should be on the server, not the client. */ - (void)utime (tmpfile2, &t); - } - - if (unidiff) run_add_arg_p (&dargc, &darg_allocated, &dargv, "-u"); - else run_add_arg_p (&dargc, &darg_allocated, &dargv, "-c"); - switch (diff_exec (tmpfile1, tmpfile2, NULL, NULL, dargc, dargv, - tmpfile3)) - { - case -1: /* fork/wait failure */ - error (1, errno, "fork for diff failed on %s", rcs); - break; - case 0: /* nothing to do */ - break; - case 1: - /* - * The two revisions are really different, so read the first two - * lines of the diff output file, and munge them to include more - * reasonable file names that "patch" will understand, unless the - * user wanted a short patch. In that case, just output the short - * message. - */ - if( patch_short ) - { - cvs_output ("File ", 0); - cvs_output (finfo->fullname, 0); - cvs_output (" changed from revision ", 0); - cvs_output (vers_tag, 0); - cvs_output (" to ", 0); - cvs_output (vers_head, 0); - cvs_output ("\n", 1); - ret = 0; - goto out; - } - - /* Output an "Index:" line for patch to use */ - cvs_output ("Index: ", 0); - cvs_output (finfo->fullname, 0); - cvs_output ("\n", 1); - - /* Now the munging. */ - fp = open_file (tmpfile3, "r"); - if (getline (&line1, &line1_chars_allocated, fp) < 0 || - getline (&line2, &line2_chars_allocated, fp) < 0) - { - if (feof (fp)) - error (0, 0, "\ -failed to read diff file header %s for %s: end of file", tmpfile3, rcs); - else - error (0, errno, - "failed to read diff file header %s for %s", - tmpfile3, rcs); - ret = 1; - if (fclose (fp) < 0) - error (0, errno, "error closing %s", tmpfile3); - goto out; - } - if (!unidiff) - { - if (strncmp (line1, "*** ", 4) != 0 || - strncmp (line2, "--- ", 4) != 0 || - (cp1 = strchr (line1, '\t')) == NULL || - (cp2 = strchr (line2, '\t')) == NULL) - { - error (0, 0, "invalid diff header for %s", rcs); - ret = 1; - if (fclose (fp) < 0) - error (0, errno, "error closing %s", tmpfile3); - goto out; - } - } - else - { - if (strncmp (line1, "--- ", 4) != 0 || - strncmp (line2, "+++ ", 4) != 0 || - (cp1 = strchr (line1, '\t')) == NULL || - (cp2 = strchr (line2, '\t')) == NULL) - { - error (0, 0, "invalid unidiff header for %s", rcs); - ret = 1; - if (fclose (fp) < 0) - error (0, errno, "error closing %s", tmpfile3); - goto out; - } - } - assert (current_parsed_root != NULL); - assert (current_parsed_root->directory != NULL); - { - strippath = xmalloc (strlen (current_parsed_root->directory) - + 2); - (void)sprintf (strippath, "%s/", - current_parsed_root->directory); - } - /*else - strippath = xstrdup (REPOS_STRIP); */ - if (strncmp (rcs, strippath, strlen (strippath)) == 0) - rcs += strlen (strippath); - free (strippath); - if (vers_tag != NULL) - { - file1 = xmalloc (strlen (finfo->fullname) - + strlen (vers_tag) - + 10); - (void)sprintf (file1, "%s:%s", finfo->fullname, vers_tag); - } - else - { - file1 = xstrdup (DEVNULL); - } - file2 = xmalloc (strlen (finfo->fullname) - + (vers_head != NULL ? strlen (vers_head) : 10) - + 10); - (void)sprintf (file2, "%s:%s", finfo->fullname, - vers_head ? vers_head : "removed"); - - /* Note that the string "diff" is specified by POSIX (for -c) - and is part of the diff output format, not the name of a - program. */ - if (unidiff) - { - cvs_output ("diff -u ", 0); - cvs_output (file1, 0); - cvs_output (" ", 1); - cvs_output (file2, 0); - cvs_output ("\n", 1); - - cvs_output ("--- ", 0); - cvs_output (file1, 0); - cvs_output (cp1, 0); - cvs_output ("+++ ", 0); - } - else - { - cvs_output ("diff -c ", 0); - cvs_output (file1, 0); - cvs_output (" ", 1); - cvs_output (file2, 0); - cvs_output ("\n", 1); - - cvs_output ("*** ", 0); - cvs_output (file1, 0); - cvs_output (cp1, 0); - cvs_output ("--- ", 0); - } - - cvs_output (finfo->fullname, 0); - cvs_output (cp2, 0); - - /* spew the rest of the diff out */ - while ((line_length - = getline (&line1, &line1_chars_allocated, fp)) - >= 0) - cvs_output (line1, 0); - if (line_length < 0 && !feof (fp)) - error (0, errno, "cannot read %s", tmpfile3); - - if (fclose (fp) < 0) - error (0, errno, "cannot close %s", tmpfile3); - free (file1); - free (file2); - break; - default: - error (0, 0, "diff failed for %s", finfo->fullname); - } - out: - if (line1) - free (line1); - if (line2) - free (line2); - if (tmpfile1 != NULL) - { - if (CVS_UNLINK (tmpfile1) < 0) - error (0, errno, "cannot unlink %s", tmpfile1); - free (tmpfile1); - tmpfile1 = NULL; - } - if (tmpfile2 != NULL) - { - if (CVS_UNLINK (tmpfile2) < 0) - error (0, errno, "cannot unlink %s", tmpfile2); - free (tmpfile2); - tmpfile2 = NULL; - } - if (tmpfile3 != NULL) - { - if (CVS_UNLINK (tmpfile3) < 0) - error (0, errno, "cannot unlink %s", tmpfile3); - free (tmpfile3); - tmpfile3 = NULL; - } - - if (dargc) - { - run_arg_free_p (dargc, dargv); - free (dargv); - } - - out2: - if (vers_tag != NULL) - free (vers_tag); - if (vers_head != NULL) - free (vers_head); - if (rcs_orig) - free (rcs_orig); - return ret; -} - - - -/* - * Print a warm fuzzy message - */ -/* ARGSUSED */ -static Dtype -patch_dirproc (callerdat, dir, repos, update_dir, entries) - void *callerdat; - const char *dir; - const char *repos; - const char *update_dir; - List *entries; -{ - if (!quiet) - error (0, 0, "Diffing %s", update_dir); - return (R_PROCESS); -} - -/* - * Clean up temporary files - */ -static RETSIGTYPE -patch_cleanup () -{ - /* Note that the checks for existence_error are because we are - called from a signal handler, without SIG_begincrsect, so - we don't know whether the files got created. */ - - if (tmpfile1 != NULL) - { - if (unlink_file (tmpfile1) < 0 - && !existence_error (errno)) - error (0, errno, "cannot remove %s", tmpfile1); - free (tmpfile1); - } - if (tmpfile2 != NULL) - { - if (unlink_file (tmpfile2) < 0 - && !existence_error (errno)) - error (0, errno, "cannot remove %s", tmpfile2); - free (tmpfile2); - } - if (tmpfile3 != NULL) - { - if (unlink_file (tmpfile3) < 0 - && !existence_error (errno)) - error (0, errno, "cannot remove %s", tmpfile3); - free (tmpfile3); - } - tmpfile1 = tmpfile2 = tmpfile3 = NULL; -} diff --git a/contrib/cvs/src/rcs.c b/contrib/cvs/src/rcs.c deleted file mode 100644 index 3358e91..0000000 --- a/contrib/cvs/src/rcs.c +++ /dev/null @@ -1,9074 +0,0 @@ -/* - * Copyright (C) 1986-2005 The Free Software Foundation, Inc. - * - * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot , - * and others. - * - * Portions Copyright (C) 1992, Brian Berliner and Jeff Polk - * Portions Copyright (C) 1989-1992, Brian Berliner - * - * You may distribute under the terms of the GNU General Public License as - * specified in the README file that comes with the CVS source distribution. - * - * The routines contained in this file do all the rcs file parsing and - * manipulation - * - * $FreeBSD$ - */ - -#include -#include "cvs.h" -#include "edit.h" -#include "hardlink.h" - -/* These need to be source after cvs.h or HAVE_MMAP won't be set... */ -#ifdef HAVE_MMAP -# include -# ifndef HAVE_GETPAGESIZE -# include "getpagesize.h" -# endif -# ifndef MAP_FAILED -# define MAP_FAILED NULL -# endif -#endif - -#ifdef MMAP_FALLBACK_TEST -void *my_mmap(void *addr, size_t len, int prot, int flags, int fd, off_t offset) -{ - if (rand() & 1) return mmap(addr, len, prot, flags, fd, offset); - return NULL; -} -#define mmap my_mmap -#endif - -int datesep = '/'; -int preserve_perms = 0; - -/* The RCS -k options, and a set of enums that must match the array. - These come first so that we can use enum kflag in function - prototypes. */ -static const char *const kflags[] = - {"kv", "kvl", "k", "v", "o", "b", (char *) NULL}; -enum kflag { KFLAG_KV = 0, KFLAG_KVL, KFLAG_K, KFLAG_V, KFLAG_O, KFLAG_B }; - -/* A structure we use to buffer the contents of an RCS file. The - various fields are only referenced directly by the rcsbuf_* - functions. We declare the struct here so that we can allocate it - on the stack, rather than in memory. */ - -struct rcsbuffer -{ - /* Points to the current position in the buffer. */ - char *ptr; - /* Points just after the last valid character in the buffer. */ - char *ptrend; - /* The file. */ - FILE *fp; - /* The name of the file, used for error messages. */ - const char *filename; - /* The starting file position of the data in the buffer. */ - unsigned long pos; - /* The length of the value. */ - size_t vlen; - /* Whether the value contains an '@' string. If so, we can not - compress whitespace characters. */ - int at_string; - /* The number of embedded '@' characters in an '@' string. If - this is non-zero, we must search the string for pairs of '@' - and convert them to a single '@'. */ - int embedded_at; - /* Whether the buffer has been mmap'ed or not. */ - int mmapped; -}; - -static RCSNode *RCS_parsercsfile_i PROTO((FILE * fp, const char *rcsfile)); -static char *RCS_getdatebranch PROTO((RCSNode * rcs, const char *date, - const char *branch)); -static void rcsbuf_open PROTO ((struct rcsbuffer *, FILE *fp, - const char *filename, unsigned long pos)); -static void rcsbuf_close PROTO ((struct rcsbuffer *)); -static int rcsbuf_getkey PROTO ((struct rcsbuffer *, char **keyp, - char **valp)); -static int rcsbuf_getrevnum PROTO ((struct rcsbuffer *, char **revp)); -static char *rcsbuf_fill PROTO ((struct rcsbuffer *, char *ptr, char **keyp, - char **valp)); -static int rcsbuf_valcmp PROTO ((struct rcsbuffer *)); -static char *rcsbuf_valcopy PROTO ((struct rcsbuffer *, char *val, int polish, - size_t *lenp)); -static void rcsbuf_valpolish PROTO ((struct rcsbuffer *, char *val, int polish, - size_t *lenp)); -static void rcsbuf_valpolish_internal PROTO ((struct rcsbuffer *, char *to, - const char *from, size_t *lenp)); -static unsigned long rcsbuf_ftell PROTO ((struct rcsbuffer *)); -static void rcsbuf_get_buffered PROTO ((struct rcsbuffer *, char **datap, - size_t *lenp)); -static void rcsbuf_cache PROTO ((RCSNode *, struct rcsbuffer *)); -static void rcsbuf_cache_close PROTO ((void)); -static void rcsbuf_cache_open PROTO ((RCSNode *, long, FILE **, - struct rcsbuffer *)); -static int checkmagic_proc PROTO((Node *p, void *closure)); -static void do_branches PROTO((List * list, char *val)); -static void do_symbols PROTO((List * list, char *val)); -static void do_locks PROTO((List * list, char *val)); -static void free_rcsnode_contents PROTO((RCSNode *)); -static void free_rcsvers_contents PROTO((RCSVers *)); -static void rcsvers_delproc PROTO((Node * p)); -static char *translate_symtag PROTO((RCSNode *, const char *)); -static char *RCS_addbranch PROTO ((RCSNode *, const char *)); -static char *truncate_revnum_in_place PROTO ((char *)); -static char *truncate_revnum PROTO ((const char *)); -static char *printable_date PROTO((const char *)); -static char *escape_keyword_value PROTO ((const char *, int *)); -static void expand_keywords PROTO((RCSNode *, RCSVers *, const char *, - const char *, size_t, enum kflag, char *, - size_t, char **, size_t *)); -static void cmp_file_buffer PROTO((void *, const char *, size_t)); - -/* Routines for reading, parsing and writing RCS files. */ -static RCSVers *getdelta PROTO ((struct rcsbuffer *, char *, char **, - char **)); -static Deltatext *RCS_getdeltatext PROTO ((RCSNode *, FILE *, - struct rcsbuffer *)); -static void freedeltatext PROTO ((Deltatext *)); - -static void RCS_putadmin PROTO ((RCSNode *, FILE *)); -static void RCS_putdtree PROTO ((RCSNode *, char *, FILE *)); -static void RCS_putdesc PROTO ((RCSNode *, FILE *)); -static void putdelta PROTO ((RCSVers *, FILE *)); -static int putrcsfield_proc PROTO ((Node *, void *)); -static int putsymbol_proc PROTO ((Node *, void *)); -static void RCS_copydeltas PROTO ((RCSNode *, FILE *, struct rcsbuffer *, - FILE *, Deltatext *, char *)); -static int count_delta_actions PROTO ((Node *, void *)); -static void putdeltatext PROTO ((FILE *, Deltatext *)); - -static FILE *rcs_internal_lockfile PROTO ((char *)); -static void rcs_internal_unlockfile PROTO ((FILE *, char *)); -static char *rcs_lockfilename PROTO ((const char *)); - -/* The RCS file reading functions are called a lot, and they do some - string comparisons. This macro speeds things up a bit by skipping - the function call when the first characters are different. It - evaluates its arguments multiple times. */ -#define STREQ(a, b) (*(char *)(a) == *(char *)(b) && strcmp ((a), (b)) == 0) - -static char * getfullCVSname PROTO ((char *, char **)); - -/* - * We don't want to use isspace() from the C library because: - * - * 1. The definition of "whitespace" in RCS files includes ASCII - * backspace, but the C locale doesn't. - * 2. isspace is an very expensive function call in some implementations - * due to the addition of wide character support. - */ -static const char spacetab[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, /* 0x00 - 0x0f */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10 - 0x1f */ - 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x20 - 0x2f */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x30 - 0x3f */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x40 - 0x4f */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x50 - 0x5f */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x60 - 0x8f */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x70 - 0x7f */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x80 - 0x8f */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x90 - 0x9f */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xa0 - 0xaf */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xb0 - 0xbf */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xc0 - 0xcf */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xd0 - 0xdf */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xe0 - 0xef */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 /* 0xf0 - 0xff */ -}; - -#define whitespace(c) (spacetab[(unsigned char)c] != 0) - -static char *rcs_lockfile; -static int rcs_lockfd = -1; - - - -/* - * char * - * locate_rcs ( const char* file, const char *repository , int *inattic ) - * - * Find an RCS file in the repository, case insensitively when the cased name - * doesn't exist, we are running as the server, and a client has asked us to - * ignore case. - * - * Most parts of CVS will want to rely instead on RCS_parse which calls this - * function and is called by recurse.c which then puts the result in useful - * places like the rcs field of struct file_info. - * - * INPUTS - * - * repository the repository (including the directory) - * file the filename within that directory (without RCSEXT). - * inattic NULL or a pointer to the output boolean - * - * OUTPUTS - * - * inattic If this input was non-null, the destination will be - * set to true if the file was found in the attic or - * false if not. If no RCS file is found, this value - * is undefined. - * - * RETURNS - * - * a newly-malloc'd array containing the absolute pathname of the RCS - * file that was found or NULL when none was found. - * - * ERRORS - * - * errno can be set by the return value of the final call to - * locate_file_in_dir(). This should resolve to the system's existence error - * value (sometime ENOENT) if the Attic directory did not exist and ENOENT if - * the Attic was found but no matching files were found in the Attic or its - * parent. - */ -static char * -locate_rcs (repository, file, inattic) - const char *repository; - const char *file; - int *inattic; -{ - char *retval; - - /* First, try to find the file as cased. */ - retval = xmalloc (strlen (repository) - + sizeof (CVSATTIC) - + strlen (file) - + sizeof (RCSEXT) - + 3); - sprintf (retval, "%s/%s%s", repository, file, RCSEXT); - if (isreadable (retval)) - { - if (inattic) - *inattic = 0; - return retval; - } - sprintf (retval, "%s/%s/%s%s", repository, CVSATTIC, file, RCSEXT); - if (isreadable (retval)) - { - if (inattic) - *inattic = 1; - return retval; - } - free (retval); - - return NULL; -} - - - -/* A few generic thoughts on error handling, in particular the - printing of unexpected characters that we find in the RCS file - (that is, why we use '\x%x' rather than %c or some such). - - * Avoiding %c means we don't have to worry about what is printable - and other such stuff. In error handling, often better to keep it - simple. - - * Hex rather than decimal or octal because character set standards - tend to use hex. - - * Saying "character 0x%x" might make it sound like we are printing - a file offset. So we use '\x%x'. - - * Would be nice to print the offset within the file, but I can - imagine various portability hassles (in particular, whether - unsigned long is always big enough to hold file offsets). */ - -/* Parse an rcsfile given a user file name and a repository. If there is - an error, we print an error message and return NULL. If the file - does not exist, we return NULL without printing anything (I'm not - sure this allows the caller to do anything reasonable, but it is - the current behavior). */ -RCSNode * -RCS_parse (file, repos) - const char *file; - const char *repos; -{ - RCSNode *rcs; - FILE *fp; - RCSNode *retval = NULL; - char *rcsfile; - int inattic; - - /* We're creating a new RCSNode, so there is no hope of finding it - in the cache. */ - rcsbuf_cache_close (); - - if ((rcsfile = locate_rcs (repos, file, &inattic)) == NULL) - { - /* Handle the error cases */ - } - else if ((fp = CVS_FOPEN (rcsfile, FOPEN_BINARY_READ)) != NULL) - { - rcs = RCS_parsercsfile_i(fp, rcsfile); - if (rcs != NULL) - { - rcs->flags |= VALID; - if ( inattic ) - rcs->flags |= INATTIC; - } - - free ( rcsfile ); - retval = rcs; - } - else if (! existence_error (errno)) - { - error (0, errno, "cannot open %s", rcsfile); - free (rcsfile); - } - - return retval; -} - -/* - * Parse a specific rcsfile. - */ -RCSNode * -RCS_parsercsfile (rcsfile) - const char *rcsfile; -{ - FILE *fp; - RCSNode *rcs; - - /* We're creating a new RCSNode, so there is no hope of finding it - in the cache. */ - rcsbuf_cache_close (); - - /* open the rcsfile */ - if ((fp = CVS_FOPEN (rcsfile, FOPEN_BINARY_READ)) == NULL) - { - error (0, errno, "Couldn't open rcs file `%s'", rcsfile); - return (NULL); - } - - rcs = RCS_parsercsfile_i (fp, rcsfile); - - return (rcs); -} - - - -/* - */ -static RCSNode * -RCS_parsercsfile_i (fp, rcsfile) - FILE *fp; - const char *rcsfile; -{ - RCSNode *rdata; - struct rcsbuffer rcsbuf; - char *key, *value; - - /* make a node */ - rdata = (RCSNode *) xmalloc (sizeof (RCSNode)); - memset ((char *)rdata, 0, sizeof (RCSNode)); - rdata->refcount = 1; - rdata->path = xstrdup (rcsfile); - - /* Process HEAD, BRANCH, and EXPAND keywords from the RCS header. - - Most cvs operations on the main branch don't need any more - information. Those that do call RCS_reparsercsfile to parse - the rest of the header and the deltas. */ - - rcsbuf_open (&rcsbuf, fp, rcsfile, 0); - - if (! rcsbuf_getkey (&rcsbuf, &key, &value)) - goto l_error; - if (STREQ (key, RCSDESC)) - goto l_error; - - if (STREQ (RCSHEAD, key) && value != NULL) - rdata->head = rcsbuf_valcopy (&rcsbuf, value, 0, (size_t *)NULL); - - if (! rcsbuf_getkey (&rcsbuf, &key, &value)) - goto l_error; - if (STREQ (key, RCSDESC)) - goto l_error; - - if (STREQ (RCSBRANCH, key) && value != NULL) - { - char *cp; - - rdata->branch = rcsbuf_valcopy (&rcsbuf, value, 0, (size_t *)NULL); - if ((numdots (rdata->branch) & 1) != 0) - { - /* turn it into a branch if it's a revision */ - cp = strrchr (rdata->branch, '.'); - *cp = '\0'; - } - } - - /* Look ahead for expand, stopping when we see desc or a revision - number. */ - while (1) - { - char *cp; - - if (STREQ (RCSEXPAND, key)) - { - rdata->expand = rcsbuf_valcopy (&rcsbuf, value, 0, - (size_t *)NULL); - break; - } - - for (cp = key; - (isdigit ((unsigned char)*cp) || *cp == '.') && *cp != '\0'; - cp++) - /* do nothing */ ; - if (*cp == '\0') - break; - - if (STREQ (RCSDESC, key)) - break; - - if (! rcsbuf_getkey (&rcsbuf, &key, &value)) - break; - } - - rdata->flags |= PARTIAL; - - rcsbuf_cache (rdata, &rcsbuf); - - return rdata; - -l_error: - error (0, 0, "`%s' does not appear to be a valid rcs file", - rcsfile); - rcsbuf_close (&rcsbuf); - freercsnode (&rdata); - fclose (fp); - return NULL; -} - - - -/* Do the real work of parsing an RCS file. - - On error, die with a fatal error; if it returns at all it was successful. - - If PFP is NULL, close the file when done. Otherwise, leave it open - and store the FILE * in *PFP. */ -void -RCS_reparsercsfile (rdata, pfp, rcsbufp) - RCSNode *rdata; - FILE **pfp; - struct rcsbuffer *rcsbufp; -{ - FILE *fp; - char *rcsfile; - struct rcsbuffer rcsbuf; - Node *q, *kv; - RCSVers *vnode; - int gotkey; - char *cp; - char *key, *value; - - assert (rdata != NULL); - rcsfile = rdata->path; - - rcsbuf_cache_open (rdata, 0, &fp, &rcsbuf); - - /* make a node */ - /* This probably shouldn't be done until later: if a file has an - empty revision tree (which is permissible), rdata->versions - should be NULL. -twp */ - rdata->versions = getlist (); - - /* - * process all the special header information, break out when we get to - * the first revision delta - */ - gotkey = 0; - for (;;) - { - /* get the next key/value pair */ - if (!gotkey) - { - if (! rcsbuf_getkey (&rcsbuf, &key, &value)) - { - error (1, 0, "`%s' does not appear to be a valid rcs file", - rcsfile); - } - } - - gotkey = 0; - - /* Skip head, branch and expand tags; we already have them. */ - if (STREQ (key, RCSHEAD) - || STREQ (key, RCSBRANCH) - || STREQ (key, RCSEXPAND)) - { - continue; - } - - if (STREQ (key, "access")) - { - if (value != NULL) - { - /* We pass the POLISH parameter as 1 because - RCS_addaccess expects nothing but spaces. FIXME: - It would be easy and more efficient to change - RCS_addaccess. */ - if (rdata->access) - { - error (0, 0, - "Duplicate `access' keyword found in RCS file."); - free (rdata->access); - } - rdata->access = rcsbuf_valcopy (&rcsbuf, value, 1, NULL); - } - continue; - } - - /* We always save lock information, so that we can handle - -kkvl correctly when checking out a file. */ - if (STREQ (key, "locks")) - { - if (value != NULL) - { - if (rdata->locks_data) - { - error (0, 0, - "Duplicate `locks' keyword found in RCS file."); - free (rdata->locks_data); - } - rdata->locks_data = rcsbuf_valcopy (&rcsbuf, value, 0, NULL); - } - if (! rcsbuf_getkey (&rcsbuf, &key, &value)) - { - error (1, 0, "premature end of file reading %s", rcsfile); - } - if (STREQ (key, "strict") && value == NULL) - { - rdata->strict_locks = 1; - } - else - gotkey = 1; - continue; - } - - if (STREQ (RCSSYMBOLS, key)) - { - if (value != NULL) - { - if (rdata->symbols_data) - { - error (0, 0, - "Duplicate `%s' keyword found in RCS file.", - RCSSYMBOLS); - free (rdata->symbols_data); - } - rdata->symbols_data = rcsbuf_valcopy (&rcsbuf, value, 0, NULL); - } - continue; - } - - /* - * check key for '.''s and digits (probably a rev) if it is a - * revision or `desc', we are done with the headers and are down to the - * revision deltas, so we break out of the loop - */ - for (cp = key; - (isdigit ((unsigned char) *cp) || *cp == '.') && *cp != '\0'; - cp++) - /* do nothing */ ; - /* Note that when comparing with RCSDATE, we are not massaging - VALUE from the string found in the RCS file. This is OK - since we know exactly what to expect. */ - if (*cp == '\0' && strncmp (RCSDATE, value, (sizeof RCSDATE) - 1) == 0) - break; - - if (STREQ (key, RCSDESC)) - break; - - if (STREQ (key, "comment")) - { - if (rdata->comment) - { - error (0, 0, - "warning: duplicate key `%s' in RCS file `%s'", - key, rcsfile); - free (rdata->comment); - } - rdata->comment = rcsbuf_valcopy (&rcsbuf, value, 0, NULL); - continue; - } - if (rdata->other == NULL) - rdata->other = getlist (); - kv = getnode (); - kv->type = rcsbuf_valcmp (&rcsbuf) ? RCSCMPFLD : RCSFIELD; - kv->key = xstrdup (key); - kv->data = rcsbuf_valcopy (&rcsbuf, value, kv->type == RCSFIELD, - (size_t *) NULL); - if (addnode (rdata->other, kv) != 0) - { - error (0, 0, "warning: duplicate key `%s' in RCS file `%s'", - key, rcsfile); - freenode (kv); - } - - /* if we haven't grabbed it yet, we didn't want it */ - } - - /* We got out of the loop, so we have the first part of the first - revision delta in KEY (the revision) and VALUE (the date key - and its value). This is what getdelta expects to receive. */ - - while ((vnode = getdelta (&rcsbuf, rcsfile, &key, &value)) != NULL) - { - /* get the node */ - q = getnode (); - q->type = RCSVERS; - q->delproc = rcsvers_delproc; - q->data = vnode; - q->key = vnode->version; - - /* add the nodes to the list */ - if (addnode (rdata->versions, q)) - error (1, 0, "Multiple %s revision deltas found in `%s'", - q->key, rcsfile); - } - - /* Here KEY and VALUE are whatever caused getdelta to return NULL. */ - - if (STREQ (key, RCSDESC)) - { - if (rdata->desc != NULL) - { - error (0, 0, - "warning: duplicate key `%s' in RCS file `%s'", - key, rcsfile); - free (rdata->desc); - } - rdata->desc = rcsbuf_valcopy (&rcsbuf, value, 1, (size_t *) NULL); - } - - rdata->delta_pos = rcsbuf_ftell (&rcsbuf); - - if (pfp == NULL) - rcsbuf_cache (rdata, &rcsbuf); - else - { - *pfp = fp; - *rcsbufp = rcsbuf; - } - rdata->flags &= ~PARTIAL; -} - -/* Move RCS into or out of the Attic, depending on TOATTIC. If the - file is already in the desired place, return without doing - anything. At some point may want to think about how this relates - to RCS_rewrite but that is a bit hairy (if one wants renames to be - atomic, or that kind of thing). If there is an error, print a message - and return 1. On success, return 0. */ -int -RCS_setattic (rcs, toattic) - RCSNode *rcs; - int toattic; -{ - char *newpath; - const char *p; - char *q; - - /* Some systems aren't going to let us rename an open file. */ - rcsbuf_cache_close (); - - /* Could make the pathname computations in this file, and probably - in other parts of rcs.c too, easier if the REPOS and FILE - arguments to RCS_parse got stashed in the RCSNode. */ - - if (toattic) - { - mode_t omask; - - if (rcs->flags & INATTIC) - return 0; - - /* Example: rcs->path is "/foo/bar/baz,v". */ - newpath = xmalloc (strlen (rcs->path) + sizeof CVSATTIC + 5); - p = last_component (rcs->path); - strncpy (newpath, rcs->path, p - rcs->path); - strcpy (newpath + (p - rcs->path), CVSATTIC); - - /* Create the Attic directory if it doesn't exist. */ - omask = umask (cvsumask); - if (CVS_MKDIR (newpath, 0777) < 0 && errno != EEXIST) - error (0, errno, "cannot make directory %s", newpath); - (void) umask (omask); - - strcat (newpath, "/"); - strcat (newpath, p); - - if (CVS_RENAME (rcs->path, newpath) < 0) - { - int save_errno = errno; - - /* The checks for isreadable look awfully fishy, but - I'm going to leave them here for now until I - can think harder about whether they take care of - some cases which should be handled somehow. */ - - if (isreadable (rcs->path) || !isreadable (newpath)) - { - error (0, save_errno, "cannot rename %s to %s", - rcs->path, newpath); - free (newpath); - return 1; - } - } - } - else - { - if (!(rcs->flags & INATTIC)) - return 0; - - newpath = xmalloc (strlen (rcs->path)); - - /* Example: rcs->path is "/foo/bar/Attic/baz,v". */ - p = last_component (rcs->path); - strncpy (newpath, rcs->path, p - rcs->path - 1); - newpath[p - rcs->path - 1] = '\0'; - q = newpath + (p - rcs->path - 1) - (sizeof CVSATTIC - 1); - assert (strncmp (q, CVSATTIC, sizeof CVSATTIC - 1) == 0); - strcpy (q, p); - - if (CVS_RENAME (rcs->path, newpath) < 0) - { - error (0, errno, "failed to move `%s' out of the attic", - rcs->path); - free (newpath); - return 1; - } - } - - free (rcs->path); - rcs->path = newpath; - - return 0; -} - -/* - * Fully parse the RCS file. Store all keyword/value pairs, fetch the - * log messages for each revision, and fetch add and delete counts for - * each revision (we could fetch the entire text for each revision, - * but the only caller, log_fileproc, doesn't need that information, - * so we don't waste the memory required to store it). The add and - * delete counts are stored on the OTHER field of the RCSVERSNODE - * structure, under the names ";add" and ";delete", so that we don't - * waste the memory space of extra fields in RCSVERSNODE for code - * which doesn't need this information. - */ - -void -RCS_fully_parse (rcs) - RCSNode *rcs; -{ - FILE *fp; - struct rcsbuffer rcsbuf; - - RCS_reparsercsfile (rcs, &fp, &rcsbuf); - - while (1) - { - char *key, *value; - Node *vers; - RCSVers *vnode; - - /* Rather than try to keep track of how much information we - have read, just read to the end of the file. */ - if (!rcsbuf_getrevnum (&rcsbuf, &key)) - break; - - vers = findnode (rcs->versions, key); - if (!vers) - error (1, 0, - "Delta text %s without revision information in `%s'.", - key, rcs->path); - - vnode = vers->data; - - while (rcsbuf_getkey (&rcsbuf, &key, &value)) - { - if (!STREQ (key, "text")) - { - Node *kv; - - if (vnode->other == NULL) - vnode->other = getlist (); - kv = getnode (); - kv->type = rcsbuf_valcmp (&rcsbuf) ? RCSCMPFLD : RCSFIELD; - kv->key = xstrdup (key); - kv->data = rcsbuf_valcopy (&rcsbuf, value, kv->type == RCSFIELD, - (size_t *)NULL); - if (addnode (vnode->other, kv) != 0) - { - error (0, 0, - "\ -warning: duplicate key `%s' in version `%s' of RCS file `%s'", - key, vnode->version, rcs->path); - freenode (kv); - } - - continue; - } - - if (!STREQ (vnode->version, rcs->head)) - { - unsigned long add, del; - char buf[50]; - Node *kv; - - /* This is a change text. Store the add and delete - counts. */ - add = 0; - del = 0; - if (value != NULL) - { - size_t vallen; - const char *cp; - - rcsbuf_valpolish (&rcsbuf, value, 0, &vallen); - cp = value; - while (cp < value + vallen) - { - char op; - unsigned long count; - - op = *cp++; - if (op != 'a' && op != 'd') - error (1, 0, "\ -unrecognized operation '\\x%x' in %s revision %s", - op, rcs->path, vnode->version); - (void) strtoul (cp, (char **) &cp, 10); - if (*cp++ != ' ') - error (1, 0, "space expected in %s revision %s", - rcs->path, vnode->version); - count = strtoul (cp, (char **) &cp, 10); - if (*cp++ != '\012') - error (1, 0, "linefeed expected in %s revision %s", - rcs->path, vnode->version); - - if (op == 'd') - del += count; - else - { - add += count; - while (count != 0) - { - if (*cp == '\012') - --count; - else if (cp == value + vallen) - { - if (count != 1) - error (1, 0, "\ -premature end of value in %s revision %s", - rcs->path, vnode->version); - else - break; - } - ++cp; - } - } - } - } - - sprintf (buf, "%lu", add); - kv = getnode (); - kv->type = RCSFIELD; - kv->key = xstrdup (";add"); - kv->data = xstrdup (buf); - if (addnode (vnode->other, kv) != 0) - { - error (0, 0, - "\ -warning: duplicate key `%s' in version `%s' of RCS file `%s'", - key, vnode->version, rcs->path); - freenode (kv); - } - - sprintf (buf, "%lu", del); - kv = getnode (); - kv->type = RCSFIELD; - kv->key = xstrdup (";delete"); - kv->data = xstrdup (buf); - if (addnode (vnode->other, kv) != 0) - { - error (0, 0, - "\ -warning: duplicate key `%s' in version `%s' of RCS file `%s'", - key, vnode->version, rcs->path); - freenode (kv); - } - } - - /* We have found the "text" key which ends the data for - this revision. Break out of the loop and go on to the - next revision. */ - break; - } - } - - rcsbuf_cache (rcs, &rcsbuf); -} - - - -/* - * freercsnode - free up the info for an RCSNode - */ -void -freercsnode (rnodep) - RCSNode **rnodep; -{ - if (rnodep == NULL || *rnodep == NULL) - return; - - ((*rnodep)->refcount)--; - if ((*rnodep)->refcount != 0) - { - *rnodep = (RCSNode *) NULL; - return; - } - free ((*rnodep)->path); - if ((*rnodep)->head != (char *) NULL) - free ((*rnodep)->head); - if ((*rnodep)->branch != (char *) NULL) - free ((*rnodep)->branch); - free_rcsnode_contents (*rnodep); - free ((char *) *rnodep); - *rnodep = (RCSNode *) NULL; -} - -/* - * free_rcsnode_contents - free up the contents of an RCSNode without - * freeing the node itself, or the file name, or the head, or the - * path. This returns the RCSNode to the state it is in immediately - * after a call to RCS_parse. - */ -static void -free_rcsnode_contents (rnode) - RCSNode *rnode; -{ - dellist (&rnode->versions); - if (rnode->symbols != (List *) NULL) - dellist (&rnode->symbols); - if (rnode->symbols_data != (char *) NULL) - free (rnode->symbols_data); - if (rnode->expand != NULL) - free (rnode->expand); - if (rnode->other != (List *) NULL) - dellist (&rnode->other); - if (rnode->access != NULL) - free (rnode->access); - if (rnode->locks_data != NULL) - free (rnode->locks_data); - if (rnode->locks != (List *) NULL) - dellist (&rnode->locks); - if (rnode->comment != NULL) - free (rnode->comment); - if (rnode->desc != NULL) - free (rnode->desc); -} - -/* free_rcsvers_contents -- free up the contents of an RCSVers node, - but also free the pointer to the node itself. */ -/* Note: The `hardlinks' list is *not* freed, since it is merely a - pointer into the `hardlist' structure (defined in hardlink.c), and - that structure is freed elsewhere in the program. */ - -static void -free_rcsvers_contents (rnode) - RCSVers *rnode; -{ - if (rnode->branches != (List *) NULL) - dellist (&rnode->branches); - if (rnode->date != (char *) NULL) - free (rnode->date); - if (rnode->next != (char *) NULL) - free (rnode->next); - if (rnode->author != (char *) NULL) - free (rnode->author); - if (rnode->state != (char *) NULL) - free (rnode->state); - if (rnode->other != (List *) NULL) - dellist (&rnode->other); - if (rnode->other_delta != NULL) - dellist (&rnode->other_delta); - if (rnode->text != NULL) - freedeltatext (rnode->text); - free ((char *) rnode); -} - -/* - * rcsvers_delproc - free up an RCSVers type node - */ -static void -rcsvers_delproc (p) - Node *p; -{ - free_rcsvers_contents (p->data); -} - -/* These functions retrieve keys and values from an RCS file using a - buffer. We use this somewhat complex approach because it turns out - that for many common operations, CVS spends most of its time - reading keys, so it's worth doing some fairly hairy optimization. */ - -/* The number of bytes we try to read each time we need more data. */ - -#define RCSBUF_BUFSIZE (8192) - -/* The buffer we use to store data. This grows as needed. */ - -static char *rcsbuf_buffer = NULL; -static size_t rcsbuf_buffer_size = 0; - -/* Whether rcsbuf_buffer is in use. This is used as a sanity check. */ - -static int rcsbuf_inuse; - -/* Set up to start gathering keys and values from an RCS file. This - initializes RCSBUF. */ - -static void -rcsbuf_open (rcsbuf, fp, filename, pos) - struct rcsbuffer *rcsbuf; - FILE *fp; - const char *filename; - unsigned long pos; -{ -#ifdef HAVE_MMAP - void *p; - struct stat fs; - size_t mmap_off = 0; -#endif - - if (rcsbuf_inuse) - error (1, 0, "rcsbuf_open: internal error"); - rcsbuf_inuse = 1; - -#ifdef HAVE_MMAP - /* When we have mmap, it is much more efficient to let the system do the - * buffering and caching for us - */ - - if ( fstat (fileno(fp), &fs) < 0 ) - error ( 1, errno, "Could not stat RCS archive %s for mapping", filename ); - - if (pos) - { - size_t ps = getpagesize (); - mmap_off = ( pos / ps ) * ps; - } - - /* Map private here since this particular buffer is read only */ - p = mmap ( NULL, fs.st_size - mmap_off, PROT_READ | PROT_WRITE, - MAP_PRIVATE, fileno(fp), mmap_off ); - if (p != NULL && p != MAP_FAILED) - { - if (rcsbuf_buffer) free (rcsbuf_buffer); - rcsbuf_buffer = p; - rcsbuf_buffer_size = fs.st_size - mmap_off; - rcsbuf->mmapped = 1; - rcsbuf->ptr = rcsbuf_buffer + pos - mmap_off; - rcsbuf->ptrend = rcsbuf_buffer + fs.st_size - mmap_off; - rcsbuf->pos = mmap_off; - } - else - { -#ifndef MMAP_FALLBACK_TEST - error (0, errno, "Could not map memory to RCS archive %s", filename); -#endif -#endif /* HAVE_MMAP */ - if (rcsbuf_buffer_size < RCSBUF_BUFSIZE) - expand_string (&rcsbuf_buffer, &rcsbuf_buffer_size, RCSBUF_BUFSIZE); - - rcsbuf->mmapped = 0; - rcsbuf->ptr = rcsbuf_buffer; - rcsbuf->ptrend = rcsbuf_buffer; - rcsbuf->pos = pos; -#ifdef HAVE_MMAP - } -#endif /* HAVE_MMAP */ - rcsbuf->fp = fp; - rcsbuf->filename = filename; - rcsbuf->vlen = 0; - rcsbuf->at_string = 0; - rcsbuf->embedded_at = 0; -} - -/* Stop gathering keys from an RCS file. */ - -static void -rcsbuf_close (rcsbuf) - struct rcsbuffer *rcsbuf; -{ - if (! rcsbuf_inuse) - error (1, 0, "rcsbuf_close: internal error"); -#ifdef HAVE_MMAP - if (rcsbuf->mmapped) - { - munmap ( rcsbuf_buffer, rcsbuf_buffer_size ); - rcsbuf_buffer = NULL; - rcsbuf_buffer_size = 0; - } -#endif - rcsbuf_inuse = 0; -} - -/* Read a key/value pair from an RCS file. This sets *KEYP to point - to the key, and *VALUEP to point to the value. A missing or empty - value is indicated by setting *VALUEP to NULL. - - This function returns 1 on success, or 0 on EOF. If there is an - error reading the file, or an EOF in an unexpected location, it - gives a fatal error. - - This sets *KEYP and *VALUEP to point to storage managed by - rcsbuf_getkey. Moreover, *VALUEP has not been massaged from the - RCS format: it may contain embedded whitespace and embedded '@' - characters. Call rcsbuf_valcopy or rcsbuf_valpolish to do - appropriate massaging. */ - -/* Note that the extreme hair in rcsbuf_getkey is because profiling - statistics show that it was worth it. */ - -static int -rcsbuf_getkey (rcsbuf, keyp, valp) - struct rcsbuffer *rcsbuf; - char **keyp; - char **valp; -{ - register const char * const my_spacetab = spacetab; - register char *ptr, *ptrend; - char c; - -#define my_whitespace(c) (my_spacetab[(unsigned char)c] != 0) - - rcsbuf->vlen = 0; - rcsbuf->at_string = 0; - rcsbuf->embedded_at = 0; - - ptr = rcsbuf->ptr; - ptrend = rcsbuf->ptrend; - - /* Sanity check. */ - assert (ptr >= rcsbuf_buffer && ptr <= rcsbuf_buffer + rcsbuf_buffer_size); - assert (ptrend >= rcsbuf_buffer && ptrend <= rcsbuf_buffer + rcsbuf_buffer_size); - - /* If the pointer is more than RCSBUF_BUFSIZE bytes into the - buffer, move back to the start of the buffer. This keeps the - buffer from growing indefinitely. */ - if (!rcsbuf->mmapped && ptr - rcsbuf_buffer >= RCSBUF_BUFSIZE) - { - int len; - - len = ptrend - ptr; - - /* Sanity check: we don't read more than RCSBUF_BUFSIZE bytes - at a time, so we can't have more bytes than that past PTR. */ - assert (len <= RCSBUF_BUFSIZE); - - /* Update the POS field, which holds the file offset of the - first byte in the RCSBUF_BUFFER buffer. */ - rcsbuf->pos += ptr - rcsbuf_buffer; - - memcpy (rcsbuf_buffer, ptr, len); - ptr = rcsbuf_buffer; - ptrend = ptr + len; - rcsbuf->ptrend = ptrend; - } - - /* Skip leading whitespace. */ - - while (1) - { - if (ptr >= ptrend) - { - ptr = rcsbuf_fill (rcsbuf, ptr, (char **) NULL, (char **) NULL); - if (ptr == NULL) - return 0; - ptrend = rcsbuf->ptrend; - } - - c = *ptr; - if (! my_whitespace (c)) - break; - - ++ptr; - } - - /* We've found the start of the key. */ - - *keyp = ptr; - - if (c != ';') - { - while (1) - { - ++ptr; - if (ptr >= ptrend) - { - ptr = rcsbuf_fill (rcsbuf, ptr, keyp, (char **) NULL); - if (ptr == NULL) - error (1, 0, "EOF in key in RCS file %s", - rcsbuf->filename); - ptrend = rcsbuf->ptrend; - } - c = *ptr; - if (c == ';' || my_whitespace (c)) - break; - } - } - - /* Here *KEYP points to the key in the buffer, C is the character - we found at the of the key, and PTR points to the location in - the buffer where we found C. We must set *PTR to \0 in order - to terminate the key. If the key ended with ';', then there is - no value. */ - - *ptr = '\0'; - ++ptr; - - if (c == ';') - { - *valp = NULL; - rcsbuf->ptr = ptr; - return 1; - } - - /* C must be whitespace. Skip whitespace between the key and the - value. If we find ';' now, there is no value. */ - - while (1) - { - if (ptr >= ptrend) - { - ptr = rcsbuf_fill (rcsbuf, ptr, keyp, (char **) NULL); - if (ptr == NULL) - error (1, 0, "EOF while looking for value in RCS file %s", - rcsbuf->filename); - ptrend = rcsbuf->ptrend; - } - c = *ptr; - if (c == ';') - { - *valp = NULL; - rcsbuf->ptr = ptr + 1; - return 1; - } - if (! my_whitespace (c)) - break; - ++ptr; - } - - /* Now PTR points to the start of the value, and C is the first - character of the value. */ - - if (c != '@') - *valp = ptr; - else - { - char *pat; - size_t vlen; - - /* Optimize the common case of a value composed of a single - '@' string. */ - - rcsbuf->at_string = 1; - - ++ptr; - - *valp = ptr; - - while (1) - { - while ((pat = memchr (ptr, '@', ptrend - ptr)) == NULL) - { - /* Note that we pass PTREND as the PTR value to - rcsbuf_fill, so that we will wind up setting PTR to - the location corresponding to the old PTREND, so - that we don't search the same bytes again. */ - ptr = rcsbuf_fill (rcsbuf, ptrend, keyp, valp); - if (ptr == NULL) - error (1, 0, - "EOF while looking for end of string in RCS file %s", - rcsbuf->filename); - ptrend = rcsbuf->ptrend; - } - - /* Handle the special case of an '@' right at the end of - the known bytes. */ - if (pat + 1 >= ptrend) - { - /* Note that we pass PAT, not PTR, here. */ - pat = rcsbuf_fill (rcsbuf, pat, keyp, valp); - if (pat == NULL) - { - /* EOF here is OK; it just means that the last - character of the file was an '@' terminating a - value for a key type which does not require a - trailing ';'. */ - pat = rcsbuf->ptrend - 1; - - } - ptrend = rcsbuf->ptrend; - - /* Note that the value of PTR is bogus here. This is - OK, because we don't use it. */ - } - - if (pat + 1 >= ptrend || pat[1] != '@') - break; - - /* We found an '@' pair in the string. Keep looking. */ - ++rcsbuf->embedded_at; - ptr = pat + 2; - } - - /* Here PAT points to the final '@' in the string. */ - - *pat = '\0'; - - vlen = pat - *valp; - if (vlen == 0) - *valp = NULL; - rcsbuf->vlen = vlen; - - ptr = pat + 1; - } - - /* Certain keywords only have a '@' string. If there is no '@' - string, then the old getrcskey function assumed that they had - no value, and we do the same. */ - - { - char *k; - - k = *keyp; - if (STREQ (k, RCSDESC) - || STREQ (k, "text") - || STREQ (k, "log")) - { - if (c != '@') - *valp = NULL; - rcsbuf->ptr = ptr; - return 1; - } - } - - /* If we've already gathered a '@' string, try to skip whitespace - and find a ';'. */ - if (c == '@') - { - while (1) - { - char n; - - if (ptr >= ptrend) - { - ptr = rcsbuf_fill (rcsbuf, ptr, keyp, valp); - if (ptr == NULL) - error (1, 0, "EOF in value in RCS file %s", - rcsbuf->filename); - ptrend = rcsbuf->ptrend; - } - n = *ptr; - if (n == ';') - { - /* We're done. We already set everything up for this - case above. */ - rcsbuf->ptr = ptr + 1; - return 1; - } - if (! my_whitespace (n)) - break; - ++ptr; - } - - /* The value extends past the '@' string. We need to undo the - '@' stripping done in the default case above. This - case never happens in a plain RCS file, but it can happen - if user defined phrases are used. */ - ((*valp)--)[rcsbuf->vlen++] = '@'; - } - - /* Here we have a value which is not a simple '@' string. We need - to gather up everything until the next ';', including any '@' - strings. *VALP points to the start of the value. If - RCSBUF->VLEN is not zero, then we have already read an '@' - string, and PTR points to the data following the '@' string. - Otherwise, PTR points to the start of the value. */ - - while (1) - { - char *start, *psemi, *pat; - - /* Find the ';' which must end the value. */ - start = ptr; - while ((psemi = memchr (ptr, ';', ptrend - ptr)) == NULL) - { - int slen; - - /* Note that we pass PTREND as the PTR value to - rcsbuf_fill, so that we will wind up setting PTR to the - location corresponding to the old PTREND, so that we - don't search the same bytes again. */ - slen = start - *valp; - ptr = rcsbuf_fill (rcsbuf, ptrend, keyp, valp); - if (ptr == NULL) - error (1, 0, "EOF in value in RCS file %s", rcsbuf->filename); - start = *valp + slen; - ptrend = rcsbuf->ptrend; - } - - /* See if there are any '@' strings in the value. */ - pat = memchr (start, '@', psemi - start); - - if (pat == NULL) - { - size_t vlen; - - /* We're done with the value. Trim any trailing - whitespace. */ - - rcsbuf->ptr = psemi + 1; - - start = *valp; - while (psemi > start && my_whitespace (psemi[-1])) - --psemi; - *psemi = '\0'; - - vlen = psemi - start; - if (vlen == 0) - *valp = NULL; - rcsbuf->vlen = vlen; - - return 1; - } - - /* We found an '@' string in the value. We set RCSBUF->AT_STRING - and RCSBUF->EMBEDDED_AT to indicate that we won't be able to - compress whitespace correctly for this type of value. - Since this type of value never arises in a normal RCS file, - this should not be a big deal. It means that if anybody - adds a phrase which can have both an '@' string and regular - text, they will have to handle whitespace compression - themselves. */ - - rcsbuf->at_string = 1; - rcsbuf->embedded_at = -1; - - ptr = pat + 1; - - while (1) - { - while ((pat = memchr (ptr, '@', ptrend - ptr)) == NULL) - { - /* Note that we pass PTREND as the PTR value to - rcsbuff_fill, so that we will wind up setting PTR - to the location corresponding to the old PTREND, so - that we don't search the same bytes again. */ - ptr = rcsbuf_fill (rcsbuf, ptrend, keyp, valp); - if (ptr == NULL) - error (1, 0, - "EOF while looking for end of string in RCS file %s", - rcsbuf->filename); - ptrend = rcsbuf->ptrend; - } - - /* Handle the special case of an '@' right at the end of - the known bytes. */ - if (pat + 1 >= ptrend) - { - ptr = rcsbuf_fill (rcsbuf, ptr, keyp, valp); - if (ptr == NULL) - error (1, 0, "EOF in value in RCS file %s", - rcsbuf->filename); - ptrend = rcsbuf->ptrend; - } - - if (pat[1] != '@') - break; - - /* We found an '@' pair in the string. Keep looking. */ - ptr = pat + 2; - } - - /* Here PAT points to the final '@' in the string. */ - ptr = pat + 1; - } - -#undef my_whitespace -} - -/* Read an RCS revision number from an RCS file. This sets *REVP to - point to the revision number; it will point to space that is - managed by the rcsbuf functions, and is only good until the next - call to rcsbuf_getkey or rcsbuf_getrevnum. - - This function returns 1 on success, or 0 on EOF. If there is an - error reading the file, or an EOF in an unexpected location, it - gives a fatal error. */ - -static int -rcsbuf_getrevnum (rcsbuf, revp) - struct rcsbuffer *rcsbuf; - char **revp; -{ - char *ptr, *ptrend; - char c; - - ptr = rcsbuf->ptr; - ptrend = rcsbuf->ptrend; - - *revp = NULL; - - /* Skip leading whitespace. */ - - while (1) - { - if (ptr >= ptrend) - { - ptr = rcsbuf_fill (rcsbuf, ptr, (char **) NULL, (char **) NULL); - if (ptr == NULL) - return 0; - ptrend = rcsbuf->ptrend; - } - - c = *ptr; - if (! whitespace (c)) - break; - - ++ptr; - } - - if (! isdigit ((unsigned char) c) && c != '.') - error (1, 0, - "\ -unexpected '\\x%x' reading revision number in RCS file %s", - c, rcsbuf->filename); - - *revp = ptr; - - do - { - ++ptr; - if (ptr >= ptrend) - { - ptr = rcsbuf_fill (rcsbuf, ptr, revp, (char **) NULL); - if (ptr == NULL) - error (1, 0, - "unexpected EOF reading revision number in RCS file %s", - rcsbuf->filename); - ptrend = rcsbuf->ptrend; - } - - c = *ptr; - } - while (isdigit ((unsigned char) c) || c == '.'); - - if (! whitespace (c)) - error (1, 0, "\ -unexpected '\\x%x' reading revision number in RCS file %s", - c, rcsbuf->filename); - - *ptr = '\0'; - - rcsbuf->ptr = ptr + 1; - - return 1; -} - -/* Fill RCSBUF_BUFFER with bytes from the file associated with RCSBUF, - updating PTR and the PTREND field. If KEYP and *KEYP are not NULL, - then *KEYP points into the buffer, and must be adjusted if the - buffer is changed. Likewise for VALP. Returns the new value of - PTR, or NULL on error. */ - -static char * -rcsbuf_fill (rcsbuf, ptr, keyp, valp) - struct rcsbuffer *rcsbuf; - char *ptr; - char **keyp; - char **valp; -{ - int got; - - if (rcsbuf->mmapped) - return NULL; - - if (rcsbuf->ptrend - rcsbuf_buffer + RCSBUF_BUFSIZE > rcsbuf_buffer_size) - { - int poff, peoff, koff, voff; - - poff = ptr - rcsbuf_buffer; - peoff = rcsbuf->ptrend - rcsbuf_buffer; - koff = keyp == NULL ? 0 : *keyp - rcsbuf_buffer; - voff = valp == NULL ? 0 : *valp - rcsbuf_buffer; - - expand_string (&rcsbuf_buffer, &rcsbuf_buffer_size, - rcsbuf_buffer_size + RCSBUF_BUFSIZE); - - ptr = rcsbuf_buffer + poff; - rcsbuf->ptrend = rcsbuf_buffer + peoff; - if (keyp != NULL) - *keyp = rcsbuf_buffer + koff; - if (valp != NULL) - *valp = rcsbuf_buffer + voff; - } - - got = fread (rcsbuf->ptrend, 1, RCSBUF_BUFSIZE, rcsbuf->fp); - if (got == 0) - { - if (ferror (rcsbuf->fp)) - error (1, errno, "cannot read %s", rcsbuf->filename); - return NULL; - } - - rcsbuf->ptrend += got; - - return ptr; -} - -/* Test whether the last value returned by rcsbuf_getkey is a composite - value or not. */ - -static int -rcsbuf_valcmp (rcsbuf) - struct rcsbuffer *rcsbuf; -{ - return rcsbuf->at_string && rcsbuf->embedded_at < 0; -} - -/* Copy the value VAL returned by rcsbuf_getkey into a memory buffer, - returning the memory buffer. Polish the value like - rcsbuf_valpolish, q.v. */ - -static char * -rcsbuf_valcopy (rcsbuf, val, polish, lenp) - struct rcsbuffer *rcsbuf; - char *val; - int polish; - size_t *lenp; -{ - size_t vlen; - int embedded_at; - char *ret; - - if (val == NULL) - { - if (lenp != NULL) - *lenp = 0; - return NULL; - } - - vlen = rcsbuf->vlen; - embedded_at = rcsbuf->embedded_at < 0 ? 0 : rcsbuf->embedded_at; - - ret = xmalloc (vlen - embedded_at + 1); - - if (rcsbuf->at_string ? embedded_at == 0 : ! polish) - { - /* No special action to take. */ - memcpy (ret, val, vlen + 1); - if (lenp != NULL) - *lenp = vlen; - return ret; - } - - rcsbuf_valpolish_internal (rcsbuf, ret, val, lenp); - return ret; -} - -/* Polish the value VAL returned by rcsbuf_getkey. The POLISH - parameter is non-zero if multiple embedded whitespace characters - should be compressed into a single whitespace character. Note that - leading and trailing whitespace was already removed by - rcsbuf_getkey. Within an '@' string, pairs of '@' characters are - compressed into a single '@' character regardless of the value of - POLISH. If LENP is not NULL, set *LENP to the length of the value. */ - -static void -rcsbuf_valpolish (rcsbuf, val, polish, lenp) - struct rcsbuffer *rcsbuf; - char *val; - int polish; - size_t *lenp; -{ - if (val == NULL) - { - if (lenp != NULL) - *lenp= 0; - return; - } - - if (rcsbuf->at_string ? rcsbuf->embedded_at == 0 : ! polish) - { - /* No special action to take. */ - if (lenp != NULL) - *lenp = rcsbuf->vlen; - return; - } - - rcsbuf_valpolish_internal (rcsbuf, val, val, lenp); -} - -/* Internal polishing routine, called from rcsbuf_valcopy and - rcsbuf_valpolish. */ - -static void -rcsbuf_valpolish_internal (rcsbuf, to, from, lenp) - struct rcsbuffer *rcsbuf; - char *to; - const char *from; - size_t *lenp; -{ - size_t len; - - len = rcsbuf->vlen; - - if (! rcsbuf->at_string) - { - char *orig_to; - size_t clen; - - orig_to = to; - - for (clen = len; clen > 0; ++from, --clen) - { - char c; - - c = *from; - if (whitespace (c)) - { - /* Note that we know that clen can not drop to zero - while we have whitespace, because we know there is - no trailing whitespace. */ - while (whitespace (from[1])) - { - ++from; - --clen; - } - c = ' '; - } - *to++ = c; - } - - *to = '\0'; - - if (lenp != NULL) - *lenp = to - orig_to; - } - else - { - const char *orig_from; - char *orig_to; - int embedded_at; - size_t clen; - - orig_from = from; - orig_to = to; - - embedded_at = rcsbuf->embedded_at; - assert (embedded_at > 0); - - if (lenp != NULL) - *lenp = len - embedded_at; - - for (clen = len; clen > 0; ++from, --clen) - { - char c; - - c = *from; - *to++ = c; - if (c == '@') - { - ++from; - - /* Sanity check. - * - * FIXME: I restored this to an abort from an assert based on - * advice from Larry Jones that asserts should not be used to - * confirm the validity of an RCS file... This leaves two - * issues here: 1) I am uncertain that the fact that we will - * only find double '@'s hasn't already been confirmed; and: - * 2) If this is the proper place to spot the error in the RCS - * file, then we should print a much clearer error here for the - * user!!!!!!! - * - * - DRP - */ - if (*from != '@' || clen == 0) - abort (); - - --clen; - - --embedded_at; - if (embedded_at == 0) - { - /* We've found all the embedded '@' characters. - We can just memcpy the rest of the buffer after - this '@' character. */ - if (orig_to != orig_from) - memcpy (to, from + 1, clen - 1); - else - memmove (to, from + 1, clen - 1); - from += clen; - to += clen - 1; - break; - } - } - } - - /* Sanity check. */ - assert (from == orig_from + len - && to == orig_to + (len - rcsbuf->embedded_at)); - - *to = '\0'; - } -} - -#ifdef PRESERVE_PERMISSIONS_SUPPORT - -/* Copy the next word from the value VALP returned by rcsbuf_getkey into a - memory buffer, updating VALP and returning the memory buffer. Return - NULL when there are no more words. */ - -static char * -rcsbuf_valword (rcsbuf, valp) - struct rcsbuffer *rcsbuf; - char **valp; -{ - register const char * const my_spacetab = spacetab; - register char *ptr, *pat; - char c; - -# define my_whitespace(c) (my_spacetab[(unsigned char)c] != 0) - - if (*valp == NULL) - return NULL; - - for (ptr = *valp; my_whitespace (*ptr); ++ptr) ; - if (*ptr == '\0') - { - assert (ptr - *valp == rcsbuf->vlen); - *valp = NULL; - rcsbuf->vlen = 0; - return NULL; - } - - /* PTR now points to the start of a value. Find out whether it is - a num, an id, a string or a colon. */ - c = *ptr; - if (c == ':') - { - rcsbuf->vlen -= ++ptr - *valp; - *valp = ptr; - return xstrdup (":"); - } - - if (c == '@') - { - int embedded_at = 0; - size_t vlen; - - pat = ++ptr; - while ((pat = strchr (pat, '@')) != NULL) - { - if (pat[1] != '@') - break; - ++embedded_at; - pat += 2; - } - - /* Here PAT points to the final '@' in the string. */ - *pat++ = '\0'; - assert (rcsbuf->at_string); - vlen = rcsbuf->vlen - (pat - *valp); - rcsbuf->vlen = pat - ptr - 1; - rcsbuf->embedded_at = embedded_at; - ptr = rcsbuf_valcopy (rcsbuf, ptr, 0, (size_t *) NULL); - *valp = pat; - rcsbuf->vlen = vlen; - if (strchr (pat, '@') == NULL) - rcsbuf->at_string = 0; - else - rcsbuf->embedded_at = -1; - return ptr; - } - - /* *PTR is neither `:', `;' nor `@', so it should be the start of a num - or an id. Make sure it is not another special character. */ - if (c == '$' || c == '.' || c == ',') - { - error (1, 0, "invalid special character in RCS field in %s", - rcsbuf->filename); - } - - pat = ptr; - while (1) - { - /* Legitimate ID characters are digits, dots and any `graphic - printing character that is not a special.' This test ought - to do the trick. */ - c = *++pat; - if (!isprint ((unsigned char) c) || - c == ';' || c == '$' || c == ',' || c == '@' || c == ':') - break; - } - - /* PAT points to the last non-id character in this word, and C is - the character in its memory cell. Check to make sure that it - is a legitimate word delimiter -- whitespace or end. */ - if (c != '\0' && !my_whitespace (c)) - error (1, 0, "invalid special character in RCS field in %s", - rcsbuf->filename); - - *pat = '\0'; - rcsbuf->vlen -= pat - *valp; - *valp = pat; - return xstrdup (ptr); - -# undef my_whitespace -} - -#endif - -/* Return the current position of an rcsbuf. */ - -static unsigned long -rcsbuf_ftell (rcsbuf) - struct rcsbuffer *rcsbuf; -{ - return rcsbuf->pos + (rcsbuf->ptr - rcsbuf_buffer); -} - -/* Return a pointer to any data buffered for RCSBUF, along with the - length. */ - -static void -rcsbuf_get_buffered (rcsbuf, datap, lenp) - struct rcsbuffer *rcsbuf; - char **datap; - size_t *lenp; -{ - *datap = rcsbuf->ptr; - *lenp = rcsbuf->ptrend - rcsbuf->ptr; -} - -/* CVS optimizes by quickly reading some header information from a - file. If it decides it needs to do more with the file, it reopens - it. We speed that up here by maintaining a cache of a single open - file, to save the time it takes to reopen the file in the common - case. */ - -static RCSNode *cached_rcs; -static struct rcsbuffer cached_rcsbuf; - -/* Cache RCS and RCSBUF. This takes responsibility for closing - RCSBUF->FP. */ - -static void -rcsbuf_cache (rcs, rcsbuf) - RCSNode *rcs; - struct rcsbuffer *rcsbuf; -{ - if (cached_rcs != NULL) - rcsbuf_cache_close (); - cached_rcs = rcs; - ++rcs->refcount; - cached_rcsbuf = *rcsbuf; -} - -/* If there is anything in the cache, close it. */ - -static void -rcsbuf_cache_close () -{ - if (cached_rcs != NULL) - { - rcsbuf_close (&cached_rcsbuf); - if (fclose (cached_rcsbuf.fp) != 0) - error (0, errno, "cannot close %s", cached_rcsbuf.filename); - freercsnode (&cached_rcs); - cached_rcs = NULL; - } -} - -/* Open an rcsbuffer for RCS, getting it from the cache if possible. - Set *FPP to the file, and *RCSBUFP to the rcsbuf. The file should - be put at position POS. */ - -static void -rcsbuf_cache_open (rcs, pos, pfp, prcsbuf) - RCSNode *rcs; - long pos; - FILE **pfp; - struct rcsbuffer *prcsbuf; -{ - if (cached_rcs == rcs && !cached_rcsbuf.mmapped) - { - if (rcsbuf_ftell (&cached_rcsbuf) != pos) - { - if (fseek (cached_rcsbuf.fp, pos, SEEK_SET) != 0) - error (1, 0, "cannot fseek RCS file %s", - cached_rcsbuf.filename); - cached_rcsbuf.ptr = rcsbuf_buffer; - cached_rcsbuf.ptrend = rcsbuf_buffer; - cached_rcsbuf.pos = pos; - } - *pfp = cached_rcsbuf.fp; - - /* When RCS_parse opens a file using fopen_case, it frees the - filename which we cached in CACHED_RCSBUF and stores a new - file name in RCS->PATH. We avoid problems here by always - copying the filename over. FIXME: This is hackish. */ - cached_rcsbuf.filename = rcs->path; - - *prcsbuf = cached_rcsbuf; - - cached_rcs = NULL; - - /* Removing RCS from the cache removes a reference to it. */ - --rcs->refcount; - if (rcs->refcount <= 0) - error (1, 0, "rcsbuf_cache_open: internal error"); - } - else - { - /* FIXME: If these routines can be rewritten to not write to the - * rcs file buffer, there would be a considerably larger memory savings - * from using mmap since the shared file would never need be copied to - * process memory. - * - * If this happens, cached mmapped buffers would be usable, but don't - * forget to make sure rcs->pos < pos here... - */ - if (cached_rcs != NULL) - rcsbuf_cache_close (); - - *pfp = CVS_FOPEN (rcs->path, FOPEN_BINARY_READ); - if (*pfp == NULL) - error (1, 0, "unable to reopen `%s'", rcs->path); - if (pos != 0) - { - if (fseek (*pfp, pos, SEEK_SET) != 0) - error (1, 0, "cannot fseek RCS file %s", rcs->path); - } - rcsbuf_open (prcsbuf, *pfp, rcs->path, pos); - } -} - - -/* - * process the symbols list of the rcs file - */ -static void -do_symbols (list, val) - List *list; - char *val; -{ - Node *p; - char *cp = val; - char *tag, *rev; - - assert (cp); - - for (;;) - { - /* skip leading whitespace */ - while (whitespace (*cp)) - cp++; - - /* if we got to the end, we are done */ - if (*cp == '\0') - break; - - /* split it up into tag and rev */ - tag = cp; - cp = strchr (cp, ':'); - *cp++ = '\0'; - rev = cp; - while (!whitespace (*cp) && *cp != '\0') - cp++; - if (*cp != '\0') - *cp++ = '\0'; - - /* make a new node and add it to the list */ - p = getnode (); - p->key = xstrdup (tag); - p->data = xstrdup (rev); - (void) addnode (list, p); - } -} - -/* - * process the locks list of the rcs file - * Like do_symbols, but hash entries are keyed backwards: i.e. - * an entry like `user:rev' is keyed on REV rather than on USER. - */ -static void -do_locks (list, val) - List *list; - char *val; -{ - Node *p; - char *cp = val; - char *user, *rev; - - assert (cp); - - for (;;) - { - /* skip leading whitespace */ - while (whitespace (*cp)) - cp++; - - /* if we got to the end, we are done */ - if (*cp == '\0') - break; - - /* split it up into user and rev */ - user = cp; - cp = strchr (cp, ':'); - *cp++ = '\0'; - rev = cp; - while (!whitespace (*cp) && *cp != '\0') - cp++; - if (*cp != '\0') - *cp++ = '\0'; - - /* make a new node and add it to the list */ - p = getnode (); - p->key = xstrdup (rev); - p->data = xstrdup (user); - (void) addnode (list, p); - } -} - -/* - * process the branches list of a revision delta - */ -static void -do_branches (list, val) - List *list; - char *val; -{ - Node *p; - char *cp = val; - char *branch; - - for (;;) - { - /* skip leading whitespace */ - while (whitespace (*cp)) - cp++; - - /* if we got to the end, we are done */ - if (*cp == '\0') - break; - - /* find the end of this branch */ - branch = cp; - while (!whitespace (*cp) && *cp != '\0') - cp++; - if (*cp != '\0') - *cp++ = '\0'; - - /* make a new node and add it to the list */ - p = getnode (); - p->key = xstrdup (branch); - (void) addnode (list, p); - } -} - -/* - * Version Number - * - * Returns the requested version number of the RCS file, satisfying tags and/or - * dates, and walking branches, if necessary. - * - * The result is returned; null-string if error. - */ -char * -RCS_getversion (rcs, tag, date, force_tag_match, simple_tag) - RCSNode *rcs; - const char *tag; - const char *date; - int force_tag_match; - int *simple_tag; -{ - if (simple_tag != NULL) - *simple_tag = 0; - - /* make sure we have something to look at... */ - assert (rcs != NULL); - - if (tag && date) - { - char *branch, *rev; - - if (! RCS_nodeisbranch (rcs, tag)) - { - /* We can't get a particular date if the tag is not a - branch. */ - return NULL; - } - - /* Work out the branch. */ - if (! isdigit ((unsigned char) tag[0])) - branch = RCS_whatbranch (rcs, tag); - else - branch = xstrdup (tag); - - /* Fetch the revision of branch as of date. */ - rev = RCS_getdatebranch (rcs, date, branch); - free (branch); - return (rev); - } - else if (tag) - return RCS_gettag (rcs, tag, force_tag_match, simple_tag); - else if (date) - return RCS_getdate (rcs, date, force_tag_match); - else - return RCS_head (rcs); - -} - - - -/* - * Get existing revision number corresponding to tag or revision. - * Similar to RCS_gettag but less interpretation imposed. - * For example: - * -- If tag designates a magic branch, RCS_tag2rev - * returns the magic branch number. - * -- If tag is a branch tag, returns the branch number, not - * the revision of the head of the branch. - * If tag or revision is not valid or does not exist in file, - * return NULL. - */ -char * -RCS_tag2rev (rcs, tag) - RCSNode *rcs; - char *tag; -{ - char *rev, *pa, *pb; - int i; - - assert (rcs != NULL); - - if (rcs->flags & PARTIAL) - RCS_reparsercsfile (rcs, (FILE **) NULL, (struct rcsbuffer *) NULL); - - /* If a valid revision, try to look it up */ - if ( RCS_valid_rev (tag) ) - { - /* Make a copy so we can scribble on it */ - rev = xstrdup (tag); - - /* If revision exists, return the copy */ - if (RCS_exist_rev (rcs, tag)) - return rev; - - /* Nope, none such. If tag is not a branch we're done. */ - i = numdots (rev); - if ((i & 1) == 1 ) - { - pa = strrchr (rev, '.'); - if (i == 1 || *(pa-1) != RCS_MAGIC_BRANCH || *(pa-2) != '.') - { - free (rev); - error (1, 0, "revision `%s' does not exist", tag); - } - } - - /* Try for a real (that is, exists in the RCS deltas) branch - (RCS_exist_rev just checks for real revisions and revisions - which have tags pointing to them). */ - pa = RCS_getbranch (rcs, rev, 1); - if (pa != NULL) - { - free (pa); - return rev; - } - - /* Tag is branch, but does not exist, try corresponding - * magic branch tag. - * - * FIXME: assumes all magic branches are of - * form "n.n.n ... .0.n". I'll fix if somebody can - * send me a method to get a magic branch tag with - * the 0 in some other position -- - */ - pa = strrchr (rev, '.'); - if (!pa) - /* This might happen, for instance, if an RCS file only contained - * revisions 2.x and higher, and REV == "1". - */ - error (1, 0, "revision `%s' does not exist", tag); - - pb = xmalloc (strlen (rev) + 3); - *pa++ = 0; - (void) sprintf (pb, "%s.%d.%s", rev, RCS_MAGIC_BRANCH, pa); - free (rev); - rev = pb; - if (RCS_exist_rev (rcs, rev)) - return rev; - error (1, 0, "revision `%s' does not exist", tag); - } - - - RCS_check_tag (tag); /* exit if not a valid tag */ - - /* If tag is "HEAD", special case to get head RCS revision */ - if (tag && STREQ (tag, TAG_HEAD)) - return (RCS_head (rcs)); - - /* If valid tag let translate_symtag say yea or nay. */ - rev = translate_symtag (rcs, tag); - - if (rev) - return rev; - - /* Trust the caller to print warnings. */ - return NULL; -} - -/* - * Find the revision for a specific tag. - * If force_tag_match is set, return NULL if an exact match is not - * possible otherwise return RCS_head (). We are careful to look for - * and handle "magic" revisions specially. - * - * If the matched tag is a branch tag, find the head of the branch. - * - * Returns pointer to newly malloc'd string, or NULL. - */ -char * -RCS_gettag (rcs, symtag, force_tag_match, simple_tag) - RCSNode *rcs; - const char *symtag; - int force_tag_match; - int *simple_tag; -{ - char *tag; - - if (simple_tag != NULL) - *simple_tag = 0; - - /* make sure we have something to look at... */ - assert (rcs != NULL); - - /* XXX this is probably not necessary, --jtc */ - if (rcs->flags & PARTIAL) - RCS_reparsercsfile (rcs, (FILE **) NULL, (struct rcsbuffer *) NULL); - - /* If symtag is "HEAD", special case to get head RCS revision */ - if (symtag && STREQ (symtag, TAG_HEAD)) -#if 0 /* This #if 0 is only in the Cygnus code. Why? Death support? */ - if (force_tag_match && (rcs->flags & VALID) && (rcs->flags & INATTIC)) - return ((char *) NULL); /* head request for removed file */ - else -#endif - return RCS_head (rcs); - - if (!isdigit ((unsigned char) symtag[0])) - { - char *version; - - /* If we got a symbolic tag, resolve it to a numeric */ - version = translate_symtag (rcs, symtag); - if (version != NULL) - { - int dots; - char *magic, *branch, *cp; - - tag = version; - - /* - * If this is a magic revision, we turn it into either its - * physical branch equivalent (if one exists) or into - * its base revision, which we assume exists. - */ - dots = numdots (tag); - if (dots > 2 && (dots & 1) != 0) - { - branch = strrchr (tag, '.'); - cp = branch++ - 1; - while (*cp != '.') - cp--; - - /* see if we have .magic-branch. (".0.") */ - magic = xmalloc (strlen (tag) + 1); - (void) sprintf (magic, ".%d.", RCS_MAGIC_BRANCH); - if (strncmp (magic, cp, strlen (magic)) == 0) - { - /* it's magic. See if the branch exists */ - *cp = '\0'; /* turn it into a revision */ - (void) sprintf (magic, "%s.%s", tag, branch); - branch = RCS_getbranch (rcs, magic, 1); - free (magic); - if (branch != NULL) - { - free (tag); - return branch; - } - return tag; - } - free (magic); - } - } - else - { - /* The tag wasn't there, so return the head or NULL */ - if (force_tag_match) - return NULL; - else - return RCS_head (rcs); - } - } - else - tag = xstrdup (symtag); - - /* tag is always allocated and numeric now. */ - - /* - * numeric tag processing: - * 1) revision number - just return it - * 2) branch number - find head of branch - */ - - /* strip trailing dots */ - while (tag[strlen (tag) - 1] == '.') - tag[strlen (tag) - 1] = '\0'; - - if ((numdots (tag) & 1) == 0) - { - char *branch; - - /* we have a branch tag, so we need to walk the branch */ - branch = RCS_getbranch (rcs, tag, force_tag_match); - free (tag); - return branch; - } - else - { - Node *p; - - /* we have a revision tag, so make sure it exists */ - p = findnode (rcs->versions, tag); - if (p != NULL) - { - /* We have found a numeric revision for the revision tag. - To support expanding the RCS keyword Name, if - SIMPLE_TAG is not NULL, tell the the caller that this - is a simple tag which co will recognize. FIXME: Are - there other cases in which we should set this? In - particular, what if we expand RCS keywords internally - without calling co? */ - if (simple_tag != NULL) - *simple_tag = 1; - return tag; - } - else - { - /* The revision wasn't there, so return the head or NULL */ - free (tag); - if (force_tag_match) - return NULL; - else - return RCS_head (rcs); - } - } -} - -/* - * Return a "magic" revision as a virtual branch off of REV for the RCS file. - * A "magic" revision is one which is unique in the RCS file. By unique, I - * mean we return a revision which: - * - has a branch of 0 (see rcs.h RCS_MAGIC_BRANCH) - * - has a revision component which is not an existing branch off REV - * - has a revision component which is not an existing magic revision - * - is an even-numbered revision, to avoid conflicts with vendor branches - * The first point is what makes it "magic". - * - * As an example, if we pass in 1.37 as REV, we will look for an existing - * branch called 1.37.2. If it did not exist, we would look for an - * existing symbolic tag with a numeric part equal to 1.37.0.2. If that - * didn't exist, then we know that the 1.37.2 branch can be reserved by - * creating a symbolic tag with 1.37.0.2 as the numeric part. - * - * This allows us to fork development with very little overhead -- just a - * symbolic tag is used in the RCS file. When a commit is done, a physical - * branch is dynamically created to hold the new revision. - * - * Note: We assume that REV is an RCS revision and not a branch number. - */ -static char *check_rev; -char * -RCS_magicrev (rcs, rev) - RCSNode *rcs; - char *rev; -{ - int rev_num; - char *xrev, *test_branch, *local_branch_num; - - xrev = xmalloc (strlen (rev) + 14); /* enough for .0.number */ - check_rev = xrev; - - local_branch_num = getenv("CVS_LOCAL_BRANCH_NUM"); - if (local_branch_num) - { - rev_num = atoi(local_branch_num); - if (rev_num < 2) - rev_num = 2; - else - rev_num &= ~1; - } - else - rev_num = 2; - - /* only look at even numbered branches */ - for ( ; ; rev_num += 2) - { - /* see if the physical branch exists */ - (void) sprintf (xrev, "%s.%d", rev, rev_num); - test_branch = RCS_getbranch (rcs, xrev, 1); - if (test_branch != NULL) /* it did, so keep looking */ - { - free (test_branch); - continue; - } - - /* now, create a "magic" revision */ - (void) sprintf (xrev, "%s.%d.%d", rev, RCS_MAGIC_BRANCH, rev_num); - - /* walk the symbols list to see if a magic one already exists */ - if (walklist (RCS_symbols(rcs), checkmagic_proc, NULL) != 0) - continue; - - /* we found a free magic branch. Claim it as ours */ - return (xrev); - } -} - -/* - * walklist proc to look for a match in the symbols list. - * Returns 0 if the symbol does not match, 1 if it does. - */ -static int -checkmagic_proc (p, closure) - Node *p; - void *closure; -{ - if (STREQ (check_rev, p->data)) - return (1); - else - return (0); -} - -/* - * Given an RCSNode, returns non-zero if the specified revision number - * or symbolic tag resolves to a "branch" within the rcs file. - * - * FIXME: this is the same as RCS_nodeisbranch except for the special - * case for handling a null rcsnode. - */ -int -RCS_isbranch (rcs, rev) - RCSNode *rcs; - const char *rev; -{ - /* numeric revisions are easy -- even number of dots is a branch */ - if (isdigit ((unsigned char) *rev)) - return ((numdots (rev) & 1) == 0); - - /* assume a revision if you can't find the RCS info */ - if (rcs == NULL) - return (0); - - /* now, look for a match in the symbols list */ - return (RCS_nodeisbranch (rcs, rev)); -} - -/* - * Given an RCSNode, returns non-zero if the specified revision number - * or symbolic tag resolves to a "branch" within the rcs file. We do - * take into account any magic branches as well. - */ -int -RCS_nodeisbranch (rcs, rev) - RCSNode *rcs; - const char *rev; -{ - int dots; - char *version; - - assert (rcs != NULL); - - /* numeric revisions are easy -- even number of dots is a branch */ - if (isdigit ((unsigned char) *rev)) - return ((numdots (rev) & 1) == 0); - - version = translate_symtag (rcs, rev); - if (version == NULL) - return (0); - dots = numdots (version); - if ((dots & 1) == 0) - { - free (version); - return (1); - } - - /* got a symbolic tag match, but it's not a branch; see if it's magic */ - if (dots > 2) - { - char *magic; - char *branch = strrchr (version, '.'); - char *cp = branch - 1; - while (*cp != '.') - cp--; - - /* see if we have .magic-branch. (".0.") */ - magic = xmalloc (strlen (version) + 1); - (void) sprintf (magic, ".%d.", RCS_MAGIC_BRANCH); - if (strncmp (magic, cp, strlen (magic)) == 0) - { - free (magic); - free (version); - return (1); - } - free (magic); - } - free (version); - return (0); -} - -/* - * Returns a pointer to malloc'ed memory which contains the branch - * for the specified *symbolic* tag. Magic branches are handled correctly. - */ -char * -RCS_whatbranch (rcs, rev) - RCSNode *rcs; - const char *rev; -{ - char *version; - int dots; - - /* assume no branch if you can't find the RCS info */ - if (rcs == NULL) - return ((char *) NULL); - - /* now, look for a match in the symbols list */ - version = translate_symtag (rcs, rev); - if (version == NULL) - return ((char *) NULL); - dots = numdots (version); - if ((dots & 1) == 0) - return (version); - - /* got a symbolic tag match, but it's not a branch; see if it's magic */ - if (dots > 2) - { - char *magic; - char *branch = strrchr (version, '.'); - char *cp = branch++ - 1; - while (*cp != '.') - cp--; - - /* see if we have .magic-branch. (".0.") */ - magic = xmalloc (strlen (version) + 1); - (void) sprintf (magic, ".%d.", RCS_MAGIC_BRANCH); - if (strncmp (magic, cp, strlen (magic)) == 0) - { - /* yep. it's magic. now, construct the real branch */ - *cp = '\0'; /* turn it into a revision */ - (void) sprintf (magic, "%s.%s", version, branch); - free (version); - return (magic); - } - free (magic); - } - free (version); - return ((char *) NULL); -} - -/* - * Get the head of the specified branch. If the branch does not exist, - * return NULL or RCS_head depending on force_tag_match. - * Returns NULL or a newly malloc'd string. - */ -char * -RCS_getbranch (rcs, tag, force_tag_match) - RCSNode *rcs; - const char *tag; - int force_tag_match; -{ - Node *p, *head; - RCSVers *vn; - char *xtag; - char *nextvers; - char *cp; - - /* make sure we have something to look at... */ - assert (rcs != NULL); - - if (rcs->flags & PARTIAL) - RCS_reparsercsfile (rcs, (FILE **) NULL, (struct rcsbuffer *) NULL); - - /* find out if the tag contains a dot, or is on the trunk */ - cp = strrchr (tag, '.'); - - /* trunk processing is the special case */ - if (cp == NULL) - { - xtag = xmalloc (strlen (tag) + 1 + 1); /* +1 for an extra . */ - (void) strcpy (xtag, tag); - (void) strcat (xtag, "."); - for (cp = rcs->head; cp != NULL;) - { - if (strncmp (xtag, cp, strlen (xtag)) == 0) - break; - p = findnode (rcs->versions, cp); - if (p == NULL) - { - free (xtag); - if (force_tag_match) - return (NULL); - else - return (RCS_head (rcs)); - } - vn = p->data; - cp = vn->next; - } - free (xtag); - if (cp == NULL) - { - if (force_tag_match) - return (NULL); - else - return (RCS_head (rcs)); - } - return (xstrdup (cp)); - } - - /* if it had a `.', terminate the string so we have the base revision */ - *cp = '\0'; - - /* look up the revision this branch is based on */ - p = findnode (rcs->versions, tag); - - /* put the . back so we have the branch again */ - *cp = '.'; - - if (p == NULL) - { - /* if the base revision didn't exist, return head or NULL */ - if (force_tag_match) - return (NULL); - else - return (RCS_head (rcs)); - } - - /* find the first element of the branch we are looking for */ - vn = p->data; - if (vn->branches == NULL) - return (NULL); - xtag = xmalloc (strlen (tag) + 1 + 1); /* 1 for the extra '.' */ - (void) strcpy (xtag, tag); - (void) strcat (xtag, "."); - head = vn->branches->list; - for (p = head->next; p != head; p = p->next) - if (strncmp (p->key, xtag, strlen (xtag)) == 0) - break; - free (xtag); - - if (p == head) - { - /* we didn't find a match so return head or NULL */ - if (force_tag_match) - return (NULL); - else - return (RCS_head (rcs)); - } - - /* now walk the next pointers of the branch */ - nextvers = p->key; - do - { - p = findnode (rcs->versions, nextvers); - if (p == NULL) - { - /* a link in the chain is missing - return head or NULL */ - if (force_tag_match) - return (NULL); - else - return (RCS_head (rcs)); - } - vn = p->data; - nextvers = vn->next; - } while (nextvers != NULL); - - /* we have the version in our hand, so go for it */ - return (xstrdup (vn->version)); -} - -/* Returns the head of the branch which REV is on. REV can be a - branch tag or non-branch tag; symbolic or numeric. - - Returns a newly malloc'd string. Returns NULL if a symbolic name - isn't found. */ - -char * -RCS_branch_head (rcs, rev) - RCSNode *rcs; - char *rev; -{ - char *num; - char *br; - char *retval; - - assert (rcs != NULL); - - if (RCS_nodeisbranch (rcs, rev)) - return RCS_getbranch (rcs, rev, 1); - - if (isdigit ((unsigned char) *rev)) - num = xstrdup (rev); - else - { - num = translate_symtag (rcs, rev); - if (num == NULL) - return NULL; - } - br = truncate_revnum (num); - retval = RCS_getbranch (rcs, br, 1); - free (br); - free (num); - return retval; -} - -/* Get the branch point for a particular branch, that is the first - revision on that branch. For example, RCS_getbranchpoint (rcs, - "1.3.2") will normally return "1.3.2.1". TARGET may be either a - branch number or a revision number; if a revnum, find the - branchpoint of the branch to which TARGET belongs. - - Return RCS_head if TARGET is on the trunk or if the root node could - not be found (this is sort of backwards from our behavior on a branch; - the rationale is that the return value is a revision from which you - can start walking the next fields and end up at TARGET). - Return NULL on error. */ - -static char * -RCS_getbranchpoint (rcs, target) - RCSNode *rcs; - char *target; -{ - char *branch, *bp; - Node *vp; - RCSVers *rev; - int dots, isrevnum, brlen; - - dots = numdots (target); - isrevnum = dots & 1; - - if (dots == 1) - /* TARGET is a trunk revision; return rcs->head. */ - return (RCS_head (rcs)); - - /* Get the revision number of the node at which TARGET's branch is - rooted. If TARGET is a branch number, lop off the last field; - if it's a revision number, lop off the last *two* fields. */ - branch = xstrdup (target); - bp = strrchr (branch, '.'); - if (bp == NULL) - error (1, 0, "%s: confused revision number %s", - rcs->path, target); - if (isrevnum) - while (*--bp != '.') - ; - *bp = '\0'; - - vp = findnode (rcs->versions, branch); - if (vp == NULL) - { - error (0, 0, "%s: can't find branch point %s", rcs->path, target); - free (branch); - return NULL; - } - rev = vp->data; - - *bp++ = '.'; - while (*bp && *bp != '.') - ++bp; - brlen = bp - branch; - - vp = rev->branches->list->next; - while (vp != rev->branches->list) - { - /* BRANCH may be a genuine branch number, e.g. `1.1.3', or - maybe a full revision number, e.g. `1.1.3.6'. We have - found our branch point if the first BRANCHLEN characters - of the revision number match, *and* if the following - character is a dot. */ - if (strncmp (vp->key, branch, brlen) == 0 && vp->key[brlen] == '.') - break; - vp = vp->next; - } - - free (branch); - if (vp == rev->branches->list) - { - error (0, 0, "%s: can't find branch point %s", rcs->path, target); - return NULL; - } - else - return (xstrdup (vp->key)); -} - -/* - * Get the head of the RCS file. If branch is set, this is the head of the - * branch, otherwise the real head. - * Returns NULL or a newly malloc'd string. - */ -char * -RCS_head (rcs) - RCSNode *rcs; -{ - /* make sure we have something to look at... */ - assert (rcs != NULL); - - /* - * NOTE: we call getbranch with force_tag_match set to avoid any - * possibility of recursion - */ - if (rcs->branch) - return (RCS_getbranch (rcs, rcs->branch, 1)); - else - return (xstrdup (rcs->head)); -} - -/* - * Get the most recent revision, based on the supplied date, but use some - * funky stuff and follow the vendor branch maybe - */ -char * -RCS_getdate (rcs, date, force_tag_match) - RCSNode *rcs; - const char *date; - int force_tag_match; -{ - char *cur_rev = NULL; - char *retval = NULL; - Node *p; - RCSVers *vers = NULL; - - /* make sure we have something to look at... */ - assert (rcs != NULL); - - if (rcs->flags & PARTIAL) - RCS_reparsercsfile (rcs, (FILE **) NULL, (struct rcsbuffer *) NULL); - - /* if the head is on a branch, try the branch first */ - if (rcs->branch != NULL) - { - retval = RCS_getdatebranch (rcs, date, rcs->branch); - if (retval != NULL) - return (retval); - } - - /* otherwise if we have a trunk, try it */ - if (rcs->head) - { - p = findnode (rcs->versions, rcs->head); - if (p == NULL) - { - error (0, 0, "%s: head revision %s doesn't exist", rcs->path, - rcs->head); - } - while (p != NULL) - { - /* if the date of this one is before date, take it */ - vers = p->data; - if (RCS_datecmp (vers->date, date) <= 0) - { - cur_rev = vers->version; - break; - } - - /* if there is a next version, find the node */ - if (vers->next != NULL) - p = findnode (rcs->versions, vers->next); - else - p = (Node *) NULL; - } - } - else - error (0, 0, "%s: no head revision", rcs->path); - - /* - * at this point, either we have the revision we want, or we have the - * first revision on the trunk (1.1?) in our hands, or we've come up - * completely empty - */ - - /* if we found what we're looking for, and it's not 1.1 return it */ - if (cur_rev != NULL) - { - if (! STREQ (cur_rev, "1.1")) - return (xstrdup (cur_rev)); - - /* This is 1.1; if the date of 1.1 is not the same as that for the - 1.1.1.1 version, then return 1.1. This happens when the first - version of a file is created by a regular cvs add and commit, - and there is a subsequent cvs import of the same file. */ - p = findnode (rcs->versions, "1.1.1.1"); - if (p) - { - char *date_1_1 = vers->date; - - assert (p->data != NULL); - - vers = p->data; - if (RCS_datecmp (vers->date, date_1_1) != 0) - return xstrdup ("1.1"); - } - } - - /* look on the vendor branch */ - retval = RCS_getdatebranch (rcs, date, CVSBRANCH); - - /* - * if we found a match, return it; otherwise, we return the first - * revision on the trunk or NULL depending on force_tag_match and the - * date of the first rev - */ - if (retval != NULL) - return (retval); - - if (vers && (!force_tag_match || RCS_datecmp (vers->date, date) <= 0)) - return xstrdup (vers->version); - else - return NULL; -} - - - -/* - * Look up the last element on a branch that was put in before the specified - * date (return the rev or NULL) - */ -static char * -RCS_getdatebranch (rcs, date, branch) - RCSNode *rcs; - const char *date; - const char *branch; -{ - char *cur_rev = NULL; - char *cp; - char *xbranch, *xrev; - Node *p; - RCSVers *vers; - - /* look up the first revision on the branch */ - xrev = xstrdup (branch); - cp = strrchr (xrev, '.'); - if (cp == NULL) - { - free (xrev); - return (NULL); - } - *cp = '\0'; /* turn it into a revision */ - - assert (rcs != NULL); - - if (rcs->flags & PARTIAL) - RCS_reparsercsfile (rcs, (FILE **) NULL, (struct rcsbuffer *) NULL); - - p = findnode (rcs->versions, xrev); - free (xrev); - if (p == NULL) - return (NULL); - vers = p->data; - - /* Tentatively use this revision, if it is early enough. */ - if (RCS_datecmp (vers->date, date) <= 0) - cur_rev = vers->version; - - /* If no branches list, return now. This is what happens if the branch - is a (magic) branch with no revisions yet. */ - if (vers->branches == NULL) - return xstrdup (cur_rev); - - /* walk the branches list looking for the branch number */ - xbranch = xmalloc (strlen (branch) + 1 + 1); /* +1 for the extra dot */ - (void) strcpy (xbranch, branch); - (void) strcat (xbranch, "."); - for (p = vers->branches->list->next; p != vers->branches->list; p = p->next) - if (strncmp (p->key, xbranch, strlen (xbranch)) == 0) - break; - free (xbranch); - if (p == vers->branches->list) - { - /* This is what happens if the branch is a (magic) branch with - no revisions yet. Similar to the case where vers->branches == - NULL, except here there was a another branch off the same - branchpoint. */ - return xstrdup (cur_rev); - } - - p = findnode (rcs->versions, p->key); - - /* walk the next pointers until you find the end, or the date is too late */ - while (p != NULL) - { - vers = p->data; - if (RCS_datecmp (vers->date, date) <= 0) - cur_rev = vers->version; - else - break; - - /* if there is a next version, find the node */ - if (vers->next != NULL) - p = findnode (rcs->versions, vers->next); - else - p = (Node *) NULL; - } - - /* Return whatever we found, which may be NULL. */ - return xstrdup (cur_rev); -} - - - -/* - * Compare two dates in RCS format. Beware the change in format on January 1, - * 2000, when years go from 2-digit to full format. - */ -int -RCS_datecmp (date1, date2) - const char *date1, *date2; -{ - int length_diff = strlen (date1) - strlen (date2); - - return length_diff ? length_diff : strcmp (date1, date2); -} - - - -/* Look up revision REV in RCS and return the date specified for the - revision minus FUDGE seconds (FUDGE will generally be one, so that the - logically previous revision will be found later, or zero, if we want - the exact date). - - The return value is the date being returned as a time_t, or (time_t)-1 - on error (previously was documented as zero on error; I haven't checked - the callers to make sure that they really check for (time_t)-1, but - the latter is what this function really returns). If DATE is non-NULL, - then it must point to MAXDATELEN characters, and we store the same - return value there in DATEFORM format. */ -time_t -RCS_getrevtime (rcs, rev, date, fudge) - RCSNode *rcs; - const char *rev; - char *date; - int fudge; -{ - char tdate[MAXDATELEN]; - struct tm xtm, *ftm; - time_t revdate = 0; - Node *p; - RCSVers *vers; - - /* make sure we have something to look at... */ - assert (rcs != NULL); - - if (rcs->flags & PARTIAL) - RCS_reparsercsfile (rcs, (FILE **) NULL, (struct rcsbuffer *) NULL); - - /* look up the revision */ - p = findnode (rcs->versions, rev); - if (p == NULL) - return (-1); - vers = p->data; - - /* split up the date */ - if (sscanf (vers->date, SDATEFORM, &xtm.tm_year, &xtm.tm_mon, - &xtm.tm_mday, &xtm.tm_hour, &xtm.tm_min, &xtm.tm_sec) != 6) - error (1, 0, "%s: invalid date for revision %s (%s)", rcs->path, - rev, vers->date); - - /* If the year is from 1900 to 1999, RCS files contain only two - digits, and sscanf gives us a year from 0-99. If the year is - 2000+, RCS files contain all four digits and we subtract 1900, - because the tm_year field should contain years since 1900. */ - - if (xtm.tm_year >= 100 && xtm.tm_year < 2000) - error (0, 0, "%s: non-standard date format for revision %s (%s)", - rcs->path, rev, vers->date); - if (xtm.tm_year >= 1900) - xtm.tm_year -= 1900; - - /* put the date in a form getdate can grok */ - (void) sprintf (tdate, "%d/%d/%d GMT %d:%d:%d", xtm.tm_mon, - xtm.tm_mday, xtm.tm_year + 1900, xtm.tm_hour, - xtm.tm_min, xtm.tm_sec); - - /* turn it into seconds since the epoch */ - revdate = get_date (tdate, (struct timeb *) NULL); - if (revdate != (time_t) -1) - { - revdate -= fudge; /* remove "fudge" seconds */ - if (date) - { - /* put an appropriate string into ``date'' if we were given one */ - ftm = gmtime (&revdate); - (void) sprintf (date, DATEFORM, - ftm->tm_year + (ftm->tm_year < 100 ? 0 : 1900), - ftm->tm_mon + 1, ftm->tm_mday, ftm->tm_hour, - ftm->tm_min, ftm->tm_sec); - } - } - return revdate; -} - -List * -RCS_getlocks (rcs) - RCSNode *rcs; -{ - assert(rcs != NULL); - - if (rcs->flags & PARTIAL) - RCS_reparsercsfile (rcs, (FILE **) NULL, (struct rcsbuffer *) NULL); - - if (rcs->locks_data) { - rcs->locks = getlist (); - do_locks (rcs->locks, rcs->locks_data); - free(rcs->locks_data); - rcs->locks_data = NULL; - } - - return rcs->locks; -} - -List * -RCS_symbols(rcs) - RCSNode *rcs; -{ - assert(rcs != NULL); - - if (rcs->flags & PARTIAL) - RCS_reparsercsfile (rcs, (FILE **) NULL, (struct rcsbuffer *) NULL); - - if (rcs->symbols_data) { - rcs->symbols = getlist (); - do_symbols (rcs->symbols, rcs->symbols_data); - free(rcs->symbols_data); - rcs->symbols_data = NULL; - } - - return rcs->symbols; -} - -/* - * Return the version associated with a particular symbolic tag. - * Returns NULL or a newly malloc'd string. - */ -static char * -translate_symtag (rcs, tag) - RCSNode *rcs; - const char *tag; -{ - if (rcs->flags & PARTIAL) - RCS_reparsercsfile (rcs, (FILE **) NULL, (struct rcsbuffer *) NULL); - - if (rcs->symbols != NULL) - { - Node *p; - - /* The symbols have already been converted into a list. */ - p = findnode (rcs->symbols, tag); - if (p == NULL) - return NULL; - - return xstrdup (p->data); - } - - if (rcs->symbols_data != NULL) - { - size_t len; - char *cp, *last; - - /* Look through the RCS symbols information. This is like - do_symbols, but we don't add the information to a list. In - most cases, we will only be called once for this file, so - generating the list is unnecessary overhead. */ - - len = strlen (tag); - cp = rcs->symbols_data; - /* Keeping track of LAST below isn't strictly necessary, now that tags - * should be parsed for validity before they are accepted, but tags - * with spaces used to cause the code below to loop indefintely, so - * I have corrected for that. Now, in the event that I missed - * something, the server cannot be hung. -DRP - */ - last = NULL; - while ((cp = strchr (cp, tag[0])) != NULL) - { - if (cp == last) break; - if ((cp == rcs->symbols_data || whitespace (cp[-1])) - && strncmp (cp, tag, len) == 0 - && cp[len] == ':') - { - char *v, *r; - - /* We found the tag. Return the version number. */ - - cp += len + 1; - v = cp; - while (! whitespace (*cp) && *cp != '\0') - ++cp; - r = xmalloc (cp - v + 1); - strncpy (r, v, cp - v); - r[cp - v] = '\0'; - return r; - } - - while (! whitespace (*cp) && *cp != '\0') - ++cp; - if (*cp == '\0') - break; - last = cp; - } - } - - return NULL; -} - -/* - * The argument ARG is the getopt remainder of the -k option specified on the - * command line. This function returns malloc'ed space that can be used - * directly in calls to RCS V5, with the -k flag munged correctly. - */ -char * -RCS_check_kflag (arg) - const char *arg; -{ - static const char *const keyword_usage[] = - { - "%s %s: invalid RCS keyword expansion mode\n", - "Valid expansion modes include:\n", - " -kkv\tGenerate keywords using the default form.\n", - " -kkvl\tLike -kkv, except locker's name inserted.\n", - " -kk\tGenerate only keyword names in keyword strings.\n", - " -kv\tGenerate only keyword values in keyword strings.\n", - " -ko\tGenerate the old keyword string (no changes from checked in file).\n", - " -kb\tGenerate binary file unmodified (merges not allowed) (RCS 5.7).\n", - "(Specify the --help global option for a list of other help options)\n", - NULL, - }; - /* Big enough to hold any of the strings from kflags. */ - char karg[10]; - char const *const *cpp = NULL; - - if (arg) - { - for (cpp = kflags; *cpp != NULL; cpp++) - { - if (STREQ (arg, *cpp)) - break; - } - } - - if (arg == NULL || *cpp == NULL) - { - usage (keyword_usage); - } - - (void) sprintf (karg, "-k%s", *cpp); - return (xstrdup (karg)); -} - -/* - * Do some consistency checks on the symbolic tag... These should equate - * pretty close to what RCS checks, though I don't know for certain. - */ -void -RCS_check_tag (tag) - const char *tag; -{ - char *invalid = "$,.:;@"; /* invalid RCS tag characters */ - const char *cp; - - /* - * The first character must be an alphabetic letter. The remaining - * characters cannot be non-visible graphic characters, and must not be - * in the set of "invalid" RCS identifier characters. - */ - if (isalpha ((unsigned char) *tag)) - { - for (cp = tag; *cp; cp++) - { - if (!isgraph ((unsigned char) *cp)) - error (1, 0, "tag `%s' has non-visible graphic characters", - tag); - if (strchr (invalid, *cp)) - error (1, 0, "tag `%s' must not contain the characters `%s'", - tag, invalid); - } - } - else - error (1, 0, "tag `%s' must start with a letter", tag); -} - -/* - * TRUE if argument has valid syntax for an RCS revision or - * branch number. All characters must be digits or dots, first - * and last characters must be digits, and no two consecutive - * characters may be dots. - * - * Intended for classifying things, so this function doesn't - * call error. - */ -int -RCS_valid_rev (rev) - char *rev; -{ - char last, c; - last = *rev++; - if (!isdigit ((unsigned char) last)) - return 0; - while ((c = *rev++)) /* Extra parens placate -Wall gcc option */ - { - if (c == '.') - { - if (last == '.') - return 0; - continue; - } - last = c; - if (!isdigit ((unsigned char) c)) - return 0; - } - if (!isdigit ((unsigned char) last)) - return 0; - return 1; -} - -/* - * Return true if RCS revision with TAG is a dead revision. - */ -int -RCS_isdead (rcs, tag) - RCSNode *rcs; - const char *tag; -{ - Node *p; - RCSVers *version; - - assert (rcs != NULL); - - if (rcs->flags & PARTIAL) - RCS_reparsercsfile (rcs, (FILE **) NULL, (struct rcsbuffer *) NULL); - - p = findnode (rcs->versions, tag); - if (p == NULL) - return (0); - - version = p->data; - return (version->dead); -} - -/* Return the RCS keyword expansion mode. For example "b" for binary. - Returns a pointer into storage which is allocated and freed along with - the rest of the RCS information; the caller should not modify this - storage. Returns NULL if the RCS file does not specify a keyword - expansion mode; for all other errors, die with a fatal error. */ -char * -RCS_getexpand (rcs) - RCSNode *rcs; -{ - /* Since RCS_parsercsfile_i now reads expand, don't need to worry - about RCS_reparsercsfile. */ - assert (rcs != NULL); - return rcs->expand; -} - -/* Set keyword expansion mode to EXPAND. For example "b" for binary. */ -void -RCS_setexpand (rcs, expand) - RCSNode *rcs; - const char *expand; -{ - /* Since RCS_parsercsfile_i now reads expand, don't need to worry - about RCS_reparsercsfile. */ - assert (rcs != NULL); - if (rcs->expand != NULL) - free (rcs->expand); - rcs->expand = xstrdup (expand); -} - -/* RCS keywords, and a matching enum. */ -struct rcs_keyword -{ - const char *string; - size_t len; - int expandit; -}; -#define KEYWORD_INIT(s) (s), sizeof (s) - 1 -static struct rcs_keyword keywords[] = -{ - { KEYWORD_INIT ("Author"), 1 }, - { KEYWORD_INIT ("Date"), 1 }, - { KEYWORD_INIT ("CVSHeader"), 1 }, - { KEYWORD_INIT ("Header"), 1 }, - { KEYWORD_INIT ("Id"), 1 }, - { KEYWORD_INIT ("Locker"), 1 }, - { KEYWORD_INIT ("Log"), 1 }, - { KEYWORD_INIT ("Name"), 1 }, - { KEYWORD_INIT ("RCSfile"), 1 }, - { KEYWORD_INIT ("Revision"), 1 }, - { KEYWORD_INIT ("Source"), 1 }, - { KEYWORD_INIT ("State"), 1 }, - { NULL, 0, 0 }, - { NULL, 0, 0 } -}; -enum keyword -{ - KEYWORD_AUTHOR = 0, - KEYWORD_DATE, - KEYWORD_CVSHEADER, - KEYWORD_HEADER, - KEYWORD_ID, - KEYWORD_LOCKER, - KEYWORD_LOG, - KEYWORD_NAME, - KEYWORD_RCSFILE, - KEYWORD_REVISION, - KEYWORD_SOURCE, - KEYWORD_STATE, - KEYWORD_LOCALID -}; -enum keyword keyword_local = KEYWORD_ID; - -/* Convert an RCS date string into a readable string. This is like - the RCS date2str function. */ - -static char * -printable_date (rcs_date) - const char *rcs_date; -{ - int year, mon, mday, hour, min, sec; - char buf[100]; - - (void) sscanf (rcs_date, SDATEFORM, &year, &mon, &mday, &hour, &min, - &sec); - if (year < 1900) - year += 1900; - sprintf (buf, "%04d%c%02d%c%02d %02d:%02d:%02d", - year, datesep, mon, datesep, mday, hour, min, sec); - return xstrdup (buf); -} - -/* Escape the characters in a string so that it can be included in an - RCS value. */ - -static char * -escape_keyword_value (value, free_value) - const char *value; - int *free_value; -{ - char *ret, *t; - const char *s; - - for (s = value; *s != '\0'; s++) - { - char c; - - c = *s; - if (c == '\t' - || c == '\n' - || c == '\\' - || c == ' ' - || c == '$') - { - break; - } - } - - if (*s == '\0') - { - *free_value = 0; - return (char *) value; - } - - ret = xmalloc (strlen (value) * 4 + 1); - *free_value = 1; - - for (s = value, t = ret; *s != '\0'; s++, t++) - { - switch (*s) - { - default: - *t = *s; - break; - case '\t': - *t++ = '\\'; - *t = 't'; - break; - case '\n': - *t++ = '\\'; - *t = 'n'; - break; - case '\\': - *t++ = '\\'; - *t = '\\'; - break; - case ' ': - *t++ = '\\'; - *t++ = '0'; - *t++ = '4'; - *t = '0'; - break; - case '$': - *t++ = '\\'; - *t++ = '0'; - *t++ = '4'; - *t = '4'; - break; - } - } - - *t = '\0'; - - return ret; -} - -/* Expand RCS keywords in the memory buffer BUF of length LEN. This - applies to file RCS and version VERS. If NAME is not NULL, and is - not a numeric revision, then it is the symbolic tag used for the - checkout. EXPAND indicates how to expand the keywords. This - function sets *RETBUF and *RETLEN to the new buffer and length. - This function may modify the buffer BUF. If BUF != *RETBUF, then - RETBUF is a newly allocated buffer. */ - -static void -expand_keywords (rcs, ver, name, log, loglen, expand, buf, len, retbuf, retlen) - RCSNode *rcs; - RCSVers *ver; - const char *name; - const char *log; - size_t loglen; - enum kflag expand; - char *buf; - size_t len; - char **retbuf; - size_t *retlen; -{ - struct expand_buffer - { - struct expand_buffer *next; - char *data; - size_t len; - int free_data; - } *ebufs = NULL; - struct expand_buffer *ebuf_last = NULL; - size_t ebuf_len = 0; - char *locker; - char *srch, *srch_next; - size_t srch_len; - - if (expand == KFLAG_O || expand == KFLAG_B) - { - *retbuf = buf; - *retlen = len; - return; - } - - /* If we are using -kkvl, dig out the locker information if any. */ - locker = NULL; - if (expand == KFLAG_KVL) - { - Node *lock; - lock = findnode (RCS_getlocks(rcs), ver->version); - if (lock != NULL) - locker = xstrdup (lock->data); - } - - /* RCS keywords look like $STRING$ or $STRING: VALUE$. */ - srch = buf; - srch_len = len; - while ((srch_next = memchr (srch, '$', srch_len)) != NULL) - { - char *s, *send; - size_t slen; - const struct rcs_keyword *keyword; - enum keyword kw; - char *value; - int free_value; - char *sub; - size_t sublen; - - srch_len -= (srch_next + 1) - srch; - srch = srch_next + 1; - - /* Look for the first non alphabetic character after the '$'. */ - send = srch + srch_len; - for (s = srch; s < send; s++) - if (! isalpha ((unsigned char) *s)) - break; - - /* If the first non alphabetic character is not '$' or ':', - then this is not an RCS keyword. */ - if (s == send || (*s != '$' && *s != ':')) - continue; - - /* See if this is one of the keywords. */ - slen = s - srch; - for (keyword = keywords; keyword->string != NULL; keyword++) - { - if (keyword->expandit - && keyword->len == slen - && strncmp (keyword->string, srch, slen) == 0) - { - break; - } - } - if (keyword->string == NULL) - continue; - - kw = (enum keyword) (keyword - keywords); - - /* If the keyword ends with a ':', then the old value consists - of the characters up to the next '$'. If there is no '$' - before the end of the line, though, then this wasn't an RCS - keyword after all. */ - if (*s == ':') - { - for (; s < send; s++) - if (*s == '$' || *s == '\n') - break; - if (s == send || *s != '$') - continue; - } - - /* At this point we must replace the string from SRCH to S - with the expansion of the keyword KW. */ - - /* Get the value to use. */ - free_value = 0; - if (expand == KFLAG_K) - value = NULL; - else - { - switch (kw) - { - default: - abort (); - - case KEYWORD_AUTHOR: - value = ver->author; - break; - - case KEYWORD_DATE: - value = printable_date (ver->date); - free_value = 1; - break; - - case KEYWORD_CVSHEADER: - case KEYWORD_HEADER: - case KEYWORD_ID: - case KEYWORD_LOCALID: - { - const char *path; - int free_path; - char *date; - char *old_path; - - old_path = NULL; - if (kw == KEYWORD_HEADER || - (kw == KEYWORD_LOCALID && - keyword_local == KEYWORD_HEADER)) - path = rcs->path; - else if (kw == KEYWORD_CVSHEADER || - (kw == KEYWORD_LOCALID && - keyword_local == KEYWORD_CVSHEADER)) - path = getfullCVSname(rcs->path, &old_path); - else - path = last_component (rcs->path); - path = escape_keyword_value (path, &free_path); - date = printable_date (ver->date); - value = xmalloc (strlen (path) - + strlen (ver->version) - + strlen (date) - + strlen (ver->author) - + strlen (ver->state) - + (locker == NULL ? 0 : strlen (locker)) - + 20); - - sprintf (value, "%s %s %s %s %s%s%s", - path, ver->version, date, ver->author, - ver->state, - locker != NULL ? " " : "", - locker != NULL ? locker : ""); - if (free_path) - /* If free_path is set then we know we allocated path - * and we can discard the const. - */ - free ((char *)path); - if (old_path) - free (old_path); - free (date); - free_value = 1; - } - break; - - case KEYWORD_LOCKER: - value = locker; - break; - - case KEYWORD_LOG: - case KEYWORD_RCSFILE: - value = escape_keyword_value (last_component (rcs->path), - &free_value); - break; - - case KEYWORD_NAME: - if (name != NULL && ! isdigit ((unsigned char) *name)) - value = (char *) name; - else - value = NULL; - break; - - case KEYWORD_REVISION: - value = ver->version; - break; - - case KEYWORD_SOURCE: - value = escape_keyword_value (rcs->path, &free_value); - break; - - case KEYWORD_STATE: - value = ver->state; - break; - } - } - - sub = xmalloc (keyword->len - + (value == NULL ? 0 : strlen (value)) - + 10); - if (expand == KFLAG_V) - { - /* Decrement SRCH and increment S to remove the $ - characters. */ - --srch; - ++srch_len; - ++s; - sublen = 0; - } - else - { - strcpy (sub, keyword->string); - sublen = strlen (keyword->string); - if (expand != KFLAG_K) - { - sub[sublen] = ':'; - sub[sublen + 1] = ' '; - sublen += 2; - } - } - if (value != NULL) - { - strcpy (sub + sublen, value); - sublen += strlen (value); - } - if (expand != KFLAG_V && expand != KFLAG_K) - { - sub[sublen] = ' '; - ++sublen; - sub[sublen] = '\0'; - } - - if (free_value) - free (value); - - /* The Log keyword requires special handling. This behaviour - is taken from RCS 5.7. The special log message is what RCS - uses for ci -k. */ - if (kw == KEYWORD_LOG - && (sizeof "checked in with -k by " <= loglen - || log == NULL - || strncmp (log, "checked in with -k by ", - sizeof "checked in with -k by " - 1) != 0)) - { - char *start; - char *leader; - size_t leader_len, leader_sp_len; - const char *logend; - const char *snl; - int cnl; - char *date; - const char *sl; - - /* We are going to insert the trailing $ ourselves, before - the log message, so we must remove it from S, if we - haven't done so already. */ - if (expand != KFLAG_V) - ++s; - - /* CVS never has empty log messages, but old RCS files might. */ - if (log == NULL) - log = ""; - - /* Find the start of the line. */ - start = srch; - while (start > buf && start[-1] != '\n') - --start; - - /* Copy the start of the line to use as a comment leader. */ - leader_len = srch - start; - if (expand != KFLAG_V) - --leader_len; - leader = xmalloc (leader_len); - memcpy (leader, start, leader_len); - leader_sp_len = leader_len; - while (leader_sp_len > 0 && leader[leader_sp_len - 1] == ' ') - --leader_sp_len; - - /* RCS does some checking for an old style of Log here, - but we don't bother. RCS issues a warning if it - changes anything. */ - - /* Count the number of newlines in the log message so that - we know how many copies of the leader we will need. */ - cnl = 0; - logend = log + loglen; - for (snl = log; snl < logend; snl++) - if (*snl == '\n') - ++cnl; - - /* If the log message did not end in a newline, increment - * the newline count so we have space for the extra leader. - * Failure to do so results in a buffer overrun. - */ - if (loglen && snl[-1] != '\n') - ++cnl; - - date = printable_date (ver->date); - sub = xrealloc (sub, - (sublen - + sizeof "Revision" - + strlen (ver->version) - + strlen (date) - + strlen (ver->author) - + loglen - /* Use CNL + 2 below: One leader for each log - * line, plus the Revision/Author/Date line, - * plus a trailing blank line. - */ - + (cnl + 2) * leader_len - + 20)); - if (expand != KFLAG_V) - { - sub[sublen] = '$'; - ++sublen; - } - sub[sublen] = '\n'; - ++sublen; - memcpy (sub + sublen, leader, leader_len); - sublen += leader_len; - sprintf (sub + sublen, "Revision %s %s %s\n", - ver->version, date, ver->author); - sublen += strlen (sub + sublen); - free (date); - - sl = log; - while (sl < logend) - { - if (*sl == '\n') - { - memcpy (sub + sublen, leader, leader_sp_len); - sublen += leader_sp_len; - sub[sublen] = '\n'; - ++sublen; - ++sl; - } - else - { - const char *slnl; - - memcpy (sub + sublen, leader, leader_len); - sublen += leader_len; - for (slnl = sl; slnl < logend && *slnl != '\n'; ++slnl) - ; - if (slnl < logend) - ++slnl; - memcpy (sub + sublen, sl, slnl - sl); - sublen += slnl - sl; - if (slnl == logend && slnl[-1] != '\n') - { - /* There was no EOL at the end of the log message. Add - * one. - */ - sub[sublen] = '\n'; - ++sublen; - } - sl = slnl; - } - } - - memcpy (sub + sublen, leader, leader_sp_len); - sublen += leader_sp_len; - - free (leader); - } - - /* Now SUB contains a string which is to replace the string - from SRCH to S. SUBLEN is the length of SUB. */ - - if (srch + sublen == s) - { - memcpy (srch, sub, sublen); - free (sub); - } - else - { - struct expand_buffer *ebuf; - - /* We need to change the size of the buffer. We build a - list of expand_buffer structures. Each expand_buffer - structure represents a portion of the final output. We - concatenate them back into a single buffer when we are - done. This minimizes the number of potentially large - buffer copies we must do. */ - - if (ebufs == NULL) - { - ebufs = (struct expand_buffer *) xmalloc (sizeof *ebuf); - ebufs->next = NULL; - ebufs->data = buf; - ebufs->free_data = 0; - ebuf_len = srch - buf; - ebufs->len = ebuf_len; - ebuf_last = ebufs; - } - else - { - assert (srch >= ebuf_last->data); - assert (srch <= ebuf_last->data + ebuf_last->len); - ebuf_len -= ebuf_last->len - (srch - ebuf_last->data); - ebuf_last->len = srch - ebuf_last->data; - } - - ebuf = (struct expand_buffer *) xmalloc (sizeof *ebuf); - ebuf->data = sub; - ebuf->len = sublen; - ebuf->free_data = 1; - ebuf->next = NULL; - ebuf_last->next = ebuf; - ebuf_last = ebuf; - ebuf_len += sublen; - - ebuf = (struct expand_buffer *) xmalloc (sizeof *ebuf); - ebuf->data = s; - ebuf->len = srch_len - (s - srch); - ebuf->free_data = 0; - ebuf->next = NULL; - ebuf_last->next = ebuf; - ebuf_last = ebuf; - ebuf_len += srch_len - (s - srch); - } - - srch_len -= (s - srch); - srch = s; - } - - if (locker != NULL) - free (locker); - - if (ebufs == NULL) - { - *retbuf = buf; - *retlen = len; - } - else - { - char *ret; - - ret = xmalloc (ebuf_len); - *retbuf = ret; - *retlen = ebuf_len; - while (ebufs != NULL) - { - struct expand_buffer *next; - - memcpy (ret, ebufs->data, ebufs->len); - ret += ebufs->len; - if (ebufs->free_data) - free (ebufs->data); - next = ebufs->next; - free (ebufs); - ebufs = next; - } - } -} - - - -/* Check out a revision from an RCS file. - - If PFN is not NULL, then ignore WORKFILE and SOUT. Call PFN zero - or more times with the contents of the file. CALLERDAT is passed, - uninterpreted, to PFN. (The current code will always call PFN - exactly once for a non empty file; however, the current code - assumes that it can hold the entire file contents in memory, which - is not a good assumption, and might change in the future). - - Otherwise, if WORKFILE is not NULL, check out the revision to - WORKFILE. However, if WORKFILE is not NULL, and noexec is set, - then don't do anything. - - Otherwise, if WORKFILE is NULL, check out the revision to SOUT. If - SOUT is RUN_TTY, then write the contents of the revision to - standard output. When using SOUT, the output is generally a - temporary file; don't bother to get the file modes correct. When - NOEXEC is set, WORKFILEs are not written but SOUTs are. - - REV is the numeric revision to check out. It may be NULL, which - means to check out the head of the default branch. - - If NAMETAG is not NULL, and is not a numeric revision, then it is - the tag that should be used when expanding the RCS Name keyword. - - OPTIONS is a string such as "-kb" or "-kv" for keyword expansion - options. It may be NULL to use the default expansion mode of the - file, typically "-kkv". - - On an error which prevented checking out the file, either print a - nonfatal error and return 1, or give a fatal error. On success, - return 0. */ - -/* This function mimics the behavior of `rcs co' almost exactly. The - chief difference is in its support for preserving file ownership, - permissions, and special files across checkin and checkout -- see - comments in RCS_checkin for some issues about this. -twp */ - -int -RCS_checkout (rcs, workfile, rev, nametag, options, sout, pfn, callerdat) - RCSNode *rcs; - const char *workfile; - const char *rev; - const char *nametag; - const char *options; - const char *sout; - RCSCHECKOUTPROC pfn; - void *callerdat; -{ - int free_rev = 0; - enum kflag expand; - FILE *fp; - FILE *ofp = NULL; - struct stat sb; - struct rcsbuffer rcsbuf; - char *key; - char *value; - size_t len; - int free_value = 0; - char *log = NULL; - size_t loglen = 0; - Node *vp = NULL; -#ifdef PRESERVE_PERMISSIONS_SUPPORT - uid_t rcs_owner = (uid_t) -1; - gid_t rcs_group = (gid_t) -1; - mode_t rcs_mode; - int change_rcs_owner_or_group = 0; - int change_rcs_mode = 0; - int special_file = 0; - unsigned long devnum_long; - dev_t devnum = 0; -#endif - - if (trace) - { - (void) fprintf (stderr, "%s-> RCS_checkout (%s, %s, %s, %s, %s)\n", -#ifdef SERVER_SUPPORT - server_active ? "S" : " ", -#else - "", -#endif - rcs->path, - rev != NULL ? rev : "", - nametag != NULL ? nametag : "", - options != NULL ? options : "", - (pfn != NULL ? "(function)" - : (workfile != NULL - ? workfile - : (sout != RUN_TTY ? sout : "(stdout)")))); - } - - assert (rev == NULL || isdigit ((unsigned char) *rev)); - - if (noexec && !server_active && workfile != NULL) - return 0; - - assert (sout == RUN_TTY || workfile == NULL); - assert (pfn == NULL || (sout == RUN_TTY && workfile == NULL)); - - /* Some callers, such as Checkin or remove_file, will pass us a - branch. */ - if (rev != NULL && (numdots (rev) & 1) == 0) - { - rev = RCS_getbranch (rcs, rev, 1); - if (rev == NULL) - error (1, 0, "internal error: bad branch tag in checkout"); - free_rev = 1; - } - - if (rev == NULL || STREQ (rev, rcs->head)) - { - int gothead; - - /* We want the head revision. Try to read it directly. */ - - if (rcs->flags & PARTIAL) - RCS_reparsercsfile (rcs, &fp, &rcsbuf); - else - rcsbuf_cache_open (rcs, rcs->delta_pos, &fp, &rcsbuf); - - gothead = 0; - if (! rcsbuf_getrevnum (&rcsbuf, &key)) - error (1, 0, "unexpected EOF reading %s", rcs->path); - - if (!STREQ (rcs->head, key)) - error (1, 0, "Expected head revision %s, found %s.", - rcs->head, key); - - while (rcsbuf_getkey (&rcsbuf, &key, &value)) - { - if (STREQ (key, "log")) - { - if (log) - { - error (0, 0, -"Duplicate log keyword found for head revision in RCS file."); - free (log); - } - log = rcsbuf_valcopy (&rcsbuf, value, 0, &loglen); - } - else if (STREQ (key, "text")) - { - gothead = 1; - break; - } - } - - if (! gothead) - { - error (0, 0, "internal error: cannot find head text"); - if (free_rev) - /* It's okay to discard the const when free_rev is set, because - * we know we allocated it in this function. - */ - free ((char *)rev); - return 1; - } - - rcsbuf_valpolish (&rcsbuf, value, 0, &len); - - if (fstat (fileno (fp), &sb) < 0) - error (1, errno, "cannot fstat %s", rcs->path); - - rcsbuf_cache (rcs, &rcsbuf); - } - else - { - struct rcsbuffer *rcsbufp; - - /* It isn't the head revision of the trunk. We'll need to - walk through the deltas. */ - - fp = NULL; - if (rcs->flags & PARTIAL) - RCS_reparsercsfile (rcs, &fp, &rcsbuf); - - if (fp == NULL) - { - /* If RCS_deltas didn't close the file, we could use fstat - here too. Probably should change it thusly.... */ - if (stat (rcs->path, &sb) < 0) - error (1, errno, "cannot stat %s", rcs->path); - rcsbufp = NULL; - } - else - { - if (fstat (fileno (fp), &sb) < 0) - error (1, errno, "cannot fstat %s", rcs->path); - rcsbufp = &rcsbuf; - } - - RCS_deltas (rcs, fp, rcsbufp, rev, RCS_FETCH, &value, &len, - &log, &loglen); - free_value = 1; - } - - /* If OPTIONS is NULL or the empty string, then the old code would - invoke the RCS co program with no -k option, which means that - co would use the string we have stored in rcs->expand. */ - if ((options == NULL || options[0] == '\0') && rcs->expand == NULL) - expand = KFLAG_KV; - else - { - const char *ouroptions; - const char * const *cpp; - - if (options != NULL && options[0] != '\0') - { - assert (options[0] == '-' && options[1] == 'k'); - ouroptions = options + 2; - } - else - ouroptions = rcs->expand; - - for (cpp = kflags; *cpp != NULL; cpp++) - if (STREQ (*cpp, ouroptions)) - break; - - if (*cpp != NULL) - expand = (enum kflag) (cpp - kflags); - else - { - error (0, 0, - "internal error: unsupported substitution string -k%s", - ouroptions); - expand = KFLAG_KV; - } - } - -#ifdef PRESERVE_PERMISSIONS_SUPPORT - /* Handle special files and permissions, if that is desired. */ - if (preserve_perms) - { - RCSVers *vers; - Node *info; - - vp = findnode (rcs->versions, rev == NULL ? rcs->head : rev); - if (vp == NULL) - error (1, 0, "internal error: no revision information for %s", - rev == NULL ? rcs->head : rev); - vers = vp->data; - - /* First we look for symlinks, which are simplest to handle. */ - info = findnode (vers->other_delta, "symlink"); - if (info != NULL) - { - char *dest; - - if (pfn != NULL || (workfile == NULL && sout == RUN_TTY)) - error (1, 0, "symbolic link %s:%s cannot be piped", - rcs->path, vers->version); - if (workfile == NULL) - dest = sout; - else - dest = workfile; - - /* Remove `dest', just in case. It's okay to get ENOENT here, - since we just want the file not to be there. (TODO: decide - whether it should be considered an error for `dest' to exist - at this point. If so, the unlink call should be removed and - `symlink' should signal the error. -twp) */ - if (CVS_UNLINK (dest) < 0 && !existence_error (errno)) - error (1, errno, "cannot remove %s", dest); - if (symlink (info->data, dest) < 0) - error (1, errno, "cannot create symbolic link from %s to %s", - dest, (char *)info->data); - if (free_value) - free (value); - if (free_rev) - /* It's okay to discard the const when free_rev is set, because - * we know we allocated it in this function. - */ - free ((char *)rev); - return 0; - } - - /* Next, we look at this file's hardlinks field, and see whether - it is linked to any other file that has been checked out. - If so, we don't do anything else -- just link it to that file. - - If we are checking out a file to a pipe or temporary storage, - none of this should matter. Hence the `workfile != NULL' - wrapper around the whole thing. -twp */ - - if (workfile != NULL) - { - List *links = vers->hardlinks; - if (links != NULL) - { - Node *uptodate_link; - - /* For each file in the hardlinks field, check to see - if it exists, and if so, if it has been checked out - this iteration. When walklist returns, uptodate_link - should point to a hardlist node representing a file - in `links' which has recently been checked out, or - NULL if no file in `links' has yet been checked out. */ - - uptodate_link = NULL; - (void) walklist (links, find_checkedout_proc, &uptodate_link); - dellist (&links); - - /* If we've found a file that `workfile' is supposed to be - linked to, and it has been checked out since CVS was - invoked, then simply link workfile to that file and return. - - If one of these conditions is not met, then - workfile is the first one in its hardlink group to - be checked out, and we must continue with a full - checkout. */ - - if (uptodate_link != NULL) - { - struct hardlink_info *hlinfo = uptodate_link->data; - - if (link (uptodate_link->key, workfile) < 0) - error (1, errno, "cannot link %s to %s", - workfile, uptodate_link->key); - hlinfo->checked_out = 1; /* probably unnecessary */ - if (free_value) - free (value); - if (free_rev) - /* It's okay to discard the const when free_rev is set, - * because we know we allocated it in this function. - */ - free ((char *)rev); - return 0; - } - } - } - - info = findnode (vers->other_delta, "owner"); - if (info != NULL) - { - change_rcs_owner_or_group = 1; - rcs_owner = (uid_t) strtoul (info->data, NULL, 10); - } - info = findnode (vers->other_delta, "group"); - if (info != NULL) - { - change_rcs_owner_or_group = 1; - rcs_group = (gid_t) strtoul (info->data, NULL, 10); - } - info = findnode (vers->other_delta, "permissions"); - if (info != NULL) - { - change_rcs_mode = 1; - rcs_mode = (mode_t) strtoul (info->data, NULL, 8); - } - info = findnode (vers->other_delta, "special"); - if (info != NULL) - { - /* If the size of `devtype' changes, fix the sscanf call also */ - char devtype[16]; - - if (sscanf (info->data, "%15s %lu", - devtype, &devnum_long) < 2) - error (1, 0, "%s:%s has bad `special' newphrase %s", - workfile, vers->version, (char *)info->data); - devnum = devnum_long; - if (STREQ (devtype, "character")) - special_file = S_IFCHR; - else if (STREQ (devtype, "block")) - special_file = S_IFBLK; - else - error (0, 0, "%s is a special file of unsupported type `%s'", - workfile, (char *)info->data); - } - } -#endif /* PRESERVE_PERMISSIONS_SUPPORT */ - - if (expand != KFLAG_O && expand != KFLAG_B) - { - char *newvalue; - - /* Don't fetch the delta node again if we already have it. */ - if (vp == NULL) - { - vp = findnode (rcs->versions, rev == NULL ? rcs->head : rev); - if (vp == NULL) - error (1, 0, "internal error: no revision information for %s", - rev == NULL ? rcs->head : rev); - } - - expand_keywords (rcs, vp->data, nametag, log, loglen, - expand, value, len, &newvalue, &len); - - if (newvalue != value) - { - if (free_value) - free (value); - value = newvalue; - free_value = 1; - } - } - - if (free_rev) - /* It's okay to discard the const when free_rev is set, because - * we know we allocated it in this function. - */ - free ((char *)rev); - - if (log != NULL) - { - free (log); - log = NULL; - } - - if (pfn != NULL) - { -#ifdef PRESERVE_PERMISSIONS_SUPPORT - if (special_file) - error (1, 0, "special file %s cannot be piped to anything", - rcs->path); -#endif - /* The PFN interface is very simple to implement right now, as - we always have the entire file in memory. */ - if (len != 0) - pfn (callerdat, value, len); - } -#ifdef PRESERVE_PERMISSIONS_SUPPORT - else if (special_file) - { -# ifdef HAVE_MKNOD - char *dest; - - /* Can send either to WORKFILE or to SOUT, as long as SOUT is - not RUN_TTY. */ - dest = workfile; - if (dest == NULL) - { - if (sout == RUN_TTY) - error (1, 0, "special file %s cannot be written to stdout", - rcs->path); - dest = sout; - } - - /* Unlink `dest', just in case. It's okay if this provokes a - ENOENT error. */ - if (CVS_UNLINK (dest) < 0 && existence_error (errno)) - error (1, errno, "cannot remove %s", dest); - if (mknod (dest, special_file, devnum) < 0) - error (1, errno, "could not create special file %s", - dest); -# else - error (1, 0, -"cannot create %s: unable to create special files on this system", -workfile); -# endif - } -#endif - else - { - /* Not a special file: write to WORKFILE or SOUT. */ - if (workfile == NULL) - { - if (sout == RUN_TTY) - ofp = stdout; - else - { - /* Symbolic links should be removed before replacement, so that - `fopen' doesn't follow the link and open the wrong file. */ - if (islink (sout)) - if (unlink_file (sout) < 0) - error (1, errno, "cannot remove %s", sout); - ofp = CVS_FOPEN (sout, expand == KFLAG_B ? "wb" : "w"); - if (ofp == NULL) - error (1, errno, "cannot open %s", sout); - } - } - else - { - /* Output is supposed to go to WORKFILE, so we should open that - file. Symbolic links should be removed first (see above). */ - if (islink (workfile)) - if (unlink_file (workfile) < 0) - error (1, errno, "cannot remove %s", workfile); - - ofp = CVS_FOPEN (workfile, expand == KFLAG_B ? "wb" : "w"); - - /* If the open failed because the existing workfile was not - writable, try to chmod the file and retry the open. */ - if (ofp == NULL && errno == EACCES - && isfile (workfile) && !iswritable (workfile)) - { - xchmod (workfile, 1); - ofp = CVS_FOPEN (workfile, expand == KFLAG_B ? "wb" : "w"); - } - - if (ofp == NULL) - { - error (0, errno, "cannot open %s", workfile); - if (free_value) - free (value); - return 1; - } - } - - if (workfile == NULL && sout == RUN_TTY) - { - if (expand == KFLAG_B) - cvs_output_binary (value, len); - else - { - /* cvs_output requires the caller to check for zero - length. */ - if (len > 0) - cvs_output (value, len); - } - } - else - { - /* NT 4.0 is said to have trouble writing 2099999 bytes - (for example) in a single fwrite. So break it down - (there is no need to be writing that much at once - anyway; it is possible that LARGEST_FWRITE should be - somewhat larger for good performance, but for testing I - want to start with a small value until/unless a bigger - one proves useful). */ -#define LARGEST_FWRITE 8192 - size_t nleft = len; - size_t nstep = (len < LARGEST_FWRITE ? len : LARGEST_FWRITE); - char *p = value; - - while (nleft > 0) - { - if (fwrite (p, 1, nstep, ofp) != nstep) - { - error (0, errno, "cannot write %s", - (workfile != NULL - ? workfile - : (sout != RUN_TTY ? sout : "stdout"))); - if (free_value) - free (value); - return 1; - } - p += nstep; - nleft -= nstep; - if (nleft < nstep) - nstep = nleft; - } - } - } - - if (free_value) - free (value); - - if (workfile != NULL) - { - int ret; - -#ifdef PRESERVE_PERMISSIONS_SUPPORT - if (!special_file && fclose (ofp) < 0) - { - error (0, errno, "cannot close %s", workfile); - return 1; - } - - if (change_rcs_owner_or_group) - { - if (chown (workfile, rcs_owner, rcs_group) < 0) - error (0, errno, "could not change owner or group of %s", - workfile); - } - - ret = chmod (workfile, - change_rcs_mode - ? rcs_mode - : sb.st_mode & ~(S_IWRITE | S_IWGRP | S_IWOTH)); -#else - if (fclose (ofp) < 0) - { - error (0, errno, "cannot close %s", workfile); - return 1; - } - - ret = chmod (workfile, - sb.st_mode & ~(S_IWRITE | S_IWGRP | S_IWOTH)); -#endif - if (ret < 0) - { - error (0, errno, "cannot change mode of file %s", - workfile); - } - } - else if (sout != RUN_TTY) - { - if ( -#ifdef PRESERVE_PERMISSIONS_SUPPORT - !special_file && -#endif - fclose (ofp) < 0) - { - error (0, errno, "cannot close %s", sout); - return 1; - } - } - -#ifdef PRESERVE_PERMISSIONS_SUPPORT - /* If we are in the business of preserving hardlinks, then - mark this file as having been checked out. */ - if (preserve_perms && workfile != NULL) - update_hardlink_info (workfile); -#endif - - return 0; -} - -static RCSVers *RCS_findlock_or_tip PROTO ((RCSNode *rcs)); - -/* Find the delta currently locked by the user. From the `ci' man page: - - "If rev is omitted, ci tries to derive the new revision - number from the caller's last lock. If the caller has - locked the tip revision of a branch, the new revision is - appended to that branch. The new revision number is - obtained by incrementing the tip revision number. If the - caller locked a non-tip revision, a new branch is started - at that revision by incrementing the highest branch number - at that revision. The default initial branch and level - numbers are 1. - - If rev is omitted and the caller has no lock, but owns the - file and locking is not set to strict, then the revision - is appended to the default branch (normally the trunk; see - the -b option of rcs(1))." - - RCS_findlock_or_tip finds the unique revision locked by the caller - and returns its delta node. If the caller has not locked any - revisions (and is permitted to commit to an unlocked delta, as - described above), return the tip of the default branch. */ - -static RCSVers * -RCS_findlock_or_tip (rcs) - RCSNode *rcs; -{ - char *user = getcaller(); - Node *lock, *p; - List *locklist; - char *defaultrev = NULL; - - /* Find unique delta locked by caller. This code is very similar - to the code in RCS_unlock -- perhaps it could be abstracted - into a RCS_findlock function. */ - locklist = RCS_getlocks (rcs); - lock = NULL; - for (p = locklist->list->next; p != locklist->list; p = p->next) - { - if (STREQ (p->data, user)) - { - if (lock != NULL) - { - error (0, 0, "\ -%s: multiple revisions locked by %s; please specify one", rcs->path, user); - return NULL; - } - lock = p; - } - } - - if (lock != NULL) - { - /* Found an old lock, but check that the revision still exists. */ - p = findnode (rcs->versions, lock->key); - if (p == NULL) - { - error (0, 0, "%s: can't unlock nonexistent revision %s", - rcs->path, - lock->key); - return NULL; - } - return p->data; - } - - /* No existing lock. The RCS rule is that this is an error unless - locking is nonstrict AND the file is owned by the current - user. Trying to determine the latter is a portability nightmare - in the face of NT, VMS, AFS, and other systems with non-unix-like - ideas of users and owners. In the case of CVS, we should never get - here (as long as the traditional behavior of making sure to call - RCS_lock persists). Anyway, we skip the RCS error checks - and just return the default branch or head. The reasoning is that - those error checks are to make users lock before a checkin, and we do - that in other ways if at all anyway (e.g. rcslock.pl). */ - - defaultrev = RCS_getbranch (rcs, rcs->branch, 0); - p = findnode (rcs->versions, defaultrev); - if (defaultrev != NULL) - free (defaultrev); - if (!p) - { - error (0, 0, "RCS file `%s' does not contain its default revision.", - rcs->path); - return NULL; - } - - return p->data; -} - -/* Revision number string, R, must contain a `.'. - Return a newly-malloc'd copy of the prefix of R up - to but not including the final `.'. */ - -static char * -truncate_revnum (r) - const char *r; -{ - size_t len; - char *new_r; - char *dot = strrchr (r, '.'); - - assert (dot); - len = dot - r; - new_r = xmalloc (len + 1); - memcpy (new_r, r, len); - *(new_r + len) = '\0'; - return new_r; -} - -/* Revision number string, R, must contain a `.'. - R must be writable. Replace the rightmost `.' in R with - the NUL byte and return a pointer to that NUL byte. */ - -static char * -truncate_revnum_in_place (r) - char *r; -{ - char *dot = strrchr (r, '.'); - assert (dot); - *dot = '\0'; - return dot; -} - -/* Revision number strings, R and S, must each contain a `.'. - R and S must be writable and must have the same number of dots. - Truncate R and S for the comparison, then restored them to their - original state. - Return the result (see compare_revnums) of comparing R and S - ignoring differences in any component after the rightmost `.'. */ - -static int -compare_truncated_revnums (r, s) - char *r; - char *s; -{ - char *r_dot = truncate_revnum_in_place (r); - char *s_dot = truncate_revnum_in_place (s); - int cmp; - - assert (numdots (r) == numdots (s)); - - cmp = compare_revnums (r, s); - - *r_dot = '.'; - *s_dot = '.'; - - return cmp; -} - -/* Return a malloc'd copy of the string representing the highest branch - number on BRANCHNODE. If there are no branches on BRANCHNODE, return NULL. - FIXME: isn't the max rev always the last one? - If so, we don't even need a loop. */ - -static char *max_rev PROTO ((const RCSVers *)); - -static char * -max_rev (branchnode) - const RCSVers *branchnode; -{ - Node *head; - Node *bp; - char *max; - - if (branchnode->branches == NULL) - { - return NULL; - } - - max = NULL; - head = branchnode->branches->list; - for (bp = head->next; bp != head; bp = bp->next) - { - if (max == NULL || compare_truncated_revnums (max, bp->key) < 0) - { - max = bp->key; - } - } - assert (max); - - return truncate_revnum (max); -} - -/* Create BRANCH in RCS's delta tree. BRANCH may be either a branch - number or a revision number. In the former case, create the branch - with the specified number; in the latter case, create a new branch - rooted at node BRANCH with a higher branch number than any others. - Return the number of the tip node on the new branch. */ - -static char * -RCS_addbranch (rcs, branch) - RCSNode *rcs; - const char *branch; -{ - char *branchpoint, *newrevnum; - Node *nodep, *bp; - Node *marker; - RCSVers *branchnode; - - assert (branch); - - /* Append to end by default. */ - marker = NULL; - - branchpoint = xstrdup (branch); - if ((numdots (branchpoint) & 1) == 0) - { - truncate_revnum_in_place (branchpoint); - } - - /* Find the branch rooted at BRANCHPOINT. */ - nodep = findnode (rcs->versions, branchpoint); - if (nodep == NULL) - { - error (0, 0, "%s: can't find branch point %s", rcs->path, branchpoint); - free (branchpoint); - return NULL; - } - free (branchpoint); - branchnode = nodep->data; - - /* If BRANCH was a full branch number, make sure it is higher than MAX. */ - if ((numdots (branch) & 1) == 1) - { - if (branchnode->branches == NULL) - { - /* We have to create the first branch on this node, which means - appending ".2" to the revision number. */ - newrevnum = (char *) xmalloc (strlen (branch) + 3); - strcpy (newrevnum, branch); - strcat (newrevnum, ".2"); - } - else - { - char *max = max_rev (branchnode); - assert (max); - newrevnum = increment_revnum (max); - free (max); - } - } - else - { - newrevnum = xstrdup (branch); - - if (branchnode->branches != NULL) - { - Node *head; - Node *bp; - - /* Find the position of this new branch in the sorted list - of branches. */ - head = branchnode->branches->list; - for (bp = head->next; bp != head; bp = bp->next) - { - char *dot; - int found_pos; - - /* The existing list must be sorted on increasing revnum. */ - assert (bp->next == head - || compare_truncated_revnums (bp->key, - bp->next->key) < 0); - dot = truncate_revnum_in_place (bp->key); - found_pos = (compare_revnums (branch, bp->key) < 0); - *dot = '.'; - - if (found_pos) - { - break; - } - } - marker = bp; - } - } - - newrevnum = (char *) xrealloc (newrevnum, strlen (newrevnum) + 3); - strcat (newrevnum, ".1"); - - /* Add this new revision number to BRANCHPOINT's branches list. */ - if (branchnode->branches == NULL) - branchnode->branches = getlist(); - bp = getnode(); - bp->key = xstrdup (newrevnum); - - /* Append to the end of the list by default, that is, just before - the header node, `list'. */ - if (marker == NULL) - marker = branchnode->branches->list; - - { - int fail; - fail = insert_before (branchnode->branches, marker, bp); - assert (!fail); - } - - return newrevnum; -} - -/* Check in to RCSFILE with revision REV (which must be greater than - the largest revision) and message MESSAGE (which is checked for - legality). If FLAGS & RCS_FLAGS_DEAD, check in a dead revision. - If FLAGS & RCS_FLAGS_QUIET, tell ci to be quiet. If FLAGS & - RCS_FLAGS_MODTIME, use the working file's modification time for the - checkin time. WORKFILE is the working file to check in from, or - NULL to use the usual RCS rules for deriving it from the RCSFILE. - If FLAGS & RCS_FLAGS_KEEPFILE, don't unlink the working file; - unlinking the working file is standard RCS behavior, but is rarely - appropriate for CVS. - - This function should almost exactly mimic the behavior of `rcs ci'. The - principal point of difference is the support here for preserving file - ownership and permissions in the delta nodes. This is not a clean - solution -- precisely because it diverges from RCS's behavior -- but - it doesn't seem feasible to do this anywhere else in the code. [-twp] - - Return value is -1 for error (and errno is set to indicate the - error), positive for error (and an error message has been printed), - or zero for success. */ - -int -RCS_checkin (rcs, workfile_in, message, rev, citime, flags) - RCSNode *rcs; - const char *workfile_in; - const char *message; - const char *rev; - time_t citime; - int flags; -{ - RCSVers *delta, *commitpt; - Deltatext *dtext; - Node *nodep; - char *tmpfile, *changefile; - int dargc = 0; - size_t darg_allocated = 0; - char **dargv = NULL; - size_t bufsize; - int status, checkin_quiet; - struct tm *ftm; - time_t modtime; - int adding_branch = 0; - char *workfile = xstrdup (workfile_in); -#ifdef PRESERVE_PERMISSIONS_SUPPORT - struct stat sb; -#endif - - commitpt = NULL; - - if (rcs->flags & PARTIAL) - RCS_reparsercsfile (rcs, (FILE **) NULL, (struct rcsbuffer *) NULL); - - /* Get basename of working file. Is there a library function to - do this? I couldn't find one. -twp */ - if (workfile == NULL) - { - char *p; - int extlen = strlen (RCSEXT); - assert (rcs->path); - workfile = xstrdup (last_component (rcs->path)); - p = workfile + (strlen (workfile) - extlen); - assert (strncmp (p, RCSEXT, extlen) == 0); - *p = '\0'; - } - - /* If the filename is a symbolic link, follow it and replace it - with the destination of the link. We need to do this before - calling rcs_internal_lockfile, or else we won't put the lock in - the right place. */ - resolve_symlink (&(rcs->path)); - - checkin_quiet = flags & RCS_FLAGS_QUIET; - if (!checkin_quiet) - { - cvs_output (rcs->path, 0); - cvs_output (" <-- ", 7); - cvs_output (workfile, 0); - cvs_output ("\n", 1); - } - - /* Create new delta node. */ - delta = (RCSVers *) xmalloc (sizeof (RCSVers)); - memset (delta, 0, sizeof (RCSVers)); - delta->author = xstrdup (getcaller ()); - if (flags & RCS_FLAGS_MODTIME) - { - struct stat ws; - if (stat (workfile, &ws) < 0) - { - error (1, errno, "cannot stat %s", workfile); - } - modtime = ws.st_mtime; - } - else if (flags & RCS_FLAGS_USETIME) - modtime = citime; - else - (void) time (&modtime); - ftm = gmtime (&modtime); - delta->date = (char *) xmalloc (MAXDATELEN); - (void) sprintf (delta->date, DATEFORM, - ftm->tm_year + (ftm->tm_year < 100 ? 0 : 1900), - ftm->tm_mon + 1, ftm->tm_mday, ftm->tm_hour, - ftm->tm_min, ftm->tm_sec); - if (flags & RCS_FLAGS_DEAD) - { - delta->state = xstrdup (RCSDEAD); - delta->dead = 1; - } - else - delta->state = xstrdup ("Exp"); - -#ifdef PRESERVE_PERMISSIONS_SUPPORT - /* If permissions should be preserved on this project, then - save the permission info. */ - if (preserve_perms) - { - Node *np; - char buf[64]; /* static buffer should be safe: see usage. -twp */ - - delta->other_delta = getlist(); - - if (CVS_LSTAT (workfile, &sb) < 0) - error (1, errno, "cannot lstat %s", workfile); - - if (S_ISLNK (sb.st_mode)) - { - np = getnode(); - np->type = RCSFIELD; - np->key = xstrdup ("symlink"); - np->data = xreadlink (workfile); - addnode (delta->other_delta, np); - } - else - { - (void) sprintf (buf, "%u", sb.st_uid); - np = getnode(); - np->type = RCSFIELD; - np->key = xstrdup ("owner"); - np->data = xstrdup (buf); - addnode (delta->other_delta, np); - - (void) sprintf (buf, "%u", sb.st_gid); - np = getnode(); - np->type = RCSFIELD; - np->key = xstrdup ("group"); - np->data = xstrdup (buf); - addnode (delta->other_delta, np); - - (void) sprintf (buf, "%o", sb.st_mode & 07777); - np = getnode(); - np->type = RCSFIELD; - np->key = xstrdup ("permissions"); - np->data = xstrdup (buf); - addnode (delta->other_delta, np); - - /* Save device number. */ - switch (sb.st_mode & S_IFMT) - { - case S_IFREG: break; - case S_IFCHR: - case S_IFBLK: -# ifdef HAVE_STRUCT_STAT_ST_RDEV - np = getnode(); - np->type = RCSFIELD; - np->key = xstrdup ("special"); - sprintf (buf, "%s %lu", - ((sb.st_mode & S_IFMT) == S_IFCHR - ? "character" : "block"), - (unsigned long) sb.st_rdev); - np->data = xstrdup (buf); - addnode (delta->other_delta, np); -# else - error (0, 0, -"can't preserve %s: unable to save device files on this system", -workfile); -# endif - break; - - default: - error (0, 0, "special file %s has unknown type", workfile); - } - - /* Save hardlinks. */ - delta->hardlinks = list_linked_files_on_disk (workfile); - } - } -#endif - - /* Create a new deltatext node. */ - dtext = (Deltatext *) xmalloc (sizeof (Deltatext)); - memset (dtext, 0, sizeof (Deltatext)); - - dtext->log = make_message_rcslegal (message); - - /* If the delta tree is empty, then there's nothing to link the - new delta into. So make a new delta tree, snarf the working - file contents, and just write the new RCS file. */ - if (rcs->head == NULL) - { - char *newrev; - FILE *fout; - - /* Figure out what the first revision number should be. */ - if (rev == NULL || *rev == '\0') - newrev = xstrdup ("1.1"); - else if (numdots (rev) == 0) - { - newrev = (char *) xmalloc (strlen (rev) + 3); - strcpy (newrev, rev); - strcat (newrev, ".1"); - } - else - newrev = xstrdup (rev); - - /* Don't need to xstrdup NEWREV because it's already dynamic, and - not used for anything else. (Don't need to free it, either.) */ - rcs->head = newrev; - delta->version = xstrdup (newrev); - nodep = getnode(); - nodep->type = RCSVERS; - nodep->delproc = rcsvers_delproc; - nodep->data = delta; - nodep->key = delta->version; - (void) addnode (rcs->versions, nodep); - - dtext->version = xstrdup (newrev); - bufsize = 0; -#ifdef PRESERVE_PERMISSIONS_SUPPORT - if (preserve_perms && !S_ISREG (sb.st_mode)) - /* Pretend file is empty. */ - bufsize = 0; - else -#endif - get_file (workfile, workfile, - rcs->expand != NULL && STREQ (rcs->expand, "b") ? "rb" : "r", - &dtext->text, &bufsize, &dtext->len); - - if (!checkin_quiet) - { - cvs_output ("initial revision: ", 0); - cvs_output (rcs->head, 0); - cvs_output ("\n", 1); - } - - /* We are probably about to invalidate any cached file. */ - rcsbuf_cache_close (); - - fout = rcs_internal_lockfile (rcs->path); - RCS_putadmin (rcs, fout); - RCS_putdtree (rcs, rcs->head, fout); - RCS_putdesc (rcs, fout); - rcs->delta_pos = ftell (fout); - if (rcs->delta_pos == -1) - error (1, errno, "cannot ftell for %s", rcs->path); - putdeltatext (fout, dtext); - rcs_internal_unlockfile (fout, rcs->path); - - if ((flags & RCS_FLAGS_KEEPFILE) == 0) - { - if (unlink_file (workfile) < 0) - /* FIXME-update-dir: message does not include update_dir. */ - error (0, errno, "cannot remove %s", workfile); - } - - if (!checkin_quiet) - cvs_output ("done\n", 5); - - status = 0; - goto checkin_done; - } - - /* Derive a new revision number. From the `ci' man page: - - "If rev is a revision number, it must be higher than the - latest one on the branch to which rev belongs, or must - start a new branch. - - If rev is a branch rather than a revision number, the new - revision is appended to that branch. The level number is - obtained by incrementing the tip revision number of that - branch. If rev indicates a non-existing branch, that - branch is created with the initial revision numbered - rev.1." - - RCS_findlock_or_tip handles the case where REV is omitted. - RCS 5.7 also permits REV to be "$" or to begin with a dot, but - we do not address those cases -- every routine that calls - RCS_checkin passes it a numeric revision. */ - - if (rev == NULL || *rev == '\0') - { - /* Figure out where the commit point is by looking for locks. - If the commit point is at the tip of a branch (or is the - head of the delta tree), then increment its revision number - to obtain the new revnum. Otherwise, start a new - branch. */ - commitpt = RCS_findlock_or_tip (rcs); - if (commitpt == NULL) - { - status = 1; - goto checkin_done; - } - else if (commitpt->next == NULL - || STREQ (commitpt->version, rcs->head)) - delta->version = increment_revnum (commitpt->version); - else - delta->version = RCS_addbranch (rcs, commitpt->version); - } - else - { - /* REV is either a revision number or a branch number. Find the - tip of the target branch. */ - char *branch, *tip, *newrev, *p; - int dots, isrevnum; - - assert (isdigit ((unsigned char) *rev)); - - newrev = xstrdup (rev); - dots = numdots (newrev); - isrevnum = dots & 1; - - branch = xstrdup (rev); - if (isrevnum) - { - p = strrchr (branch, '.'); - *p = '\0'; - } - - /* Find the tip of the target branch. If we got a one- or two-digit - revision number, this will be the head of the tree. Exception: - if rev is a single-field revision equal to the branch number of - the trunk (usually "1") then we want to treat it like an ordinary - branch revision. */ - if (dots == 0) - { - tip = xstrdup (rcs->head); - assert (tip != NULL); - if (atoi (tip) != atoi (branch)) - { - newrev = (char *) xrealloc (newrev, strlen (newrev) + 3); - strcat (newrev, ".1"); - dots = isrevnum = 1; - } - } - else if (dots == 1) - tip = xstrdup (rcs->head); - else - tip = RCS_getbranch (rcs, branch, 1); - - /* If the branch does not exist, and we were supplied an exact - revision number, signal an error. Otherwise, if we were - given only a branch number, create it and set COMMITPT to - the branch point. */ - if (tip == NULL) - { - if (isrevnum) - { - error (0, 0, "%s: can't find branch point %s", - rcs->path, branch); - free (branch); - free (newrev); - status = 1; - goto checkin_done; - } - delta->version = RCS_addbranch (rcs, branch); - if (!delta->version) - { - free (branch); - free (newrev); - status = 1; - goto checkin_done; - } - adding_branch = 1; - p = strrchr (branch, '.'); - *p = '\0'; - tip = xstrdup (branch); - } - else - { - if (isrevnum) - { - /* NEWREV must be higher than TIP. */ - if (compare_revnums (tip, newrev) >= 0) - { - error (0, 0, - "%s: revision %s too low; must be higher than %s", - rcs->path, - newrev, tip); - free (branch); - free (newrev); - free (tip); - status = 1; - goto checkin_done; - } - delta->version = xstrdup (newrev); - } - else - /* Just increment the tip number to get the new revision. */ - delta->version = increment_revnum (tip); - } - - nodep = findnode (rcs->versions, tip); - commitpt = nodep->data; - - free (branch); - free (newrev); - free (tip); - } - - assert (delta->version != NULL); - - /* If COMMITPT is locked by us, break the lock. If it's locked - by someone else, signal an error. */ - nodep = findnode (RCS_getlocks (rcs), commitpt->version); - if (nodep != NULL) - { - if (! STREQ (nodep->data, delta->author)) - { - /* If we are adding a branch, then leave the old lock around. - That is sensible in the sense that when adding a branch, - we don't need to use the lock to tell us where to check - in. It is fishy in the sense that if it is our own lock, - we break it. However, this is the RCS 5.7 behavior (at - the end of addbranch in ci.c in RCS 5.7, it calls - removelock only if it is our own lock, not someone - else's). */ - - if (!adding_branch) - { - error (0, 0, "%s: revision %s locked by %s", - rcs->path, - nodep->key, (char *)nodep->data); - status = 1; - goto checkin_done; - } - } - else - delnode (nodep); - } - - dtext->version = xstrdup (delta->version); - - /* Obtain the change text for the new delta. If DELTA is to be the - new head of the tree, then its change text should be the contents - of the working file, and LEAFNODE's change text should be a diff. - Else, DELTA's change text should be a diff between LEAFNODE and - the working file. */ - - tmpfile = cvs_temp_name(); - status = RCS_checkout (rcs, NULL, commitpt->version, NULL, - ((rcs->expand != NULL - && STREQ (rcs->expand, "b")) - ? "-kb" - : "-ko"), - tmpfile, - (RCSCHECKOUTPROC)0, NULL); - if (status != 0) - error (1, 0, - "could not check out revision %s of `%s'", - commitpt->version, rcs->path); - - bufsize = 0; - changefile = cvs_temp_name(); - - /* Diff options should include --binary if the RCS file has -kb set - in its `expand' field. */ - run_add_arg_p (&dargc, &darg_allocated, &dargv, "-a"); - run_add_arg_p (&dargc, &darg_allocated, &dargv, "-n"); - if (rcs->expand && STREQ (rcs->expand, "b")) - run_add_arg_p (&dargc, &darg_allocated, &dargv, "--binary"); - - if (STREQ (commitpt->version, rcs->head) && - numdots (delta->version) == 1) - { - /* If this revision is being inserted on the trunk, the change text - for the new delta should be the contents of the working file ... */ - bufsize = 0; -#ifdef PRESERVE_PERMISSIONS_SUPPORT - if (preserve_perms && !S_ISREG (sb.st_mode)) - /* Pretend file is empty. */ - ; - else -#endif - get_file (workfile, workfile, - rcs->expand != NULL && STREQ (rcs->expand, "b") ? "rb" : "r", - &dtext->text, &bufsize, &dtext->len); - - /* ... and the change text for the old delta should be a diff. */ - commitpt->text = (Deltatext *) xmalloc (sizeof (Deltatext)); - memset (commitpt->text, 0, sizeof (Deltatext)); - - bufsize = 0; - switch (diff_exec (workfile, tmpfile, NULL, NULL, - dargc, dargv, changefile)) - { - case 0: - case 1: - break; - case -1: - /* FIXME-update-dir: message does not include update_dir. */ - error (1, errno, "error diffing %s", workfile); - break; - default: - /* FIXME-update-dir: message does not include update_dir. */ - error (1, 0, "error diffing %s", workfile); - break; - } - - /* OK, the text file case here is really dumb. Logically - speaking we want diff to read the files in text mode, - convert them to the canonical form found in RCS files - (which, we hope at least, is independent of OS--always - bare linefeeds), and then work with change texts in that - format. However, diff_exec both generates change - texts and produces output for user purposes (e.g. patch.c), - and there is no way to distinguish between the two cases. - So we actually implement the text file case by writing the - change text as a text file, then reading it as a text file. - This should cause no harm, but doesn't strike me as - immensely clean. */ - get_file (changefile, changefile, - rcs->expand != NULL && STREQ (rcs->expand, "b") ? "rb" : "r", - &commitpt->text->text, &bufsize, &commitpt->text->len); - - /* If COMMITPT->TEXT->TEXT is NULL, it means that CHANGEFILE - was empty and that there are no differences between revisions. - In that event, we want to force RCS_rewrite to write an empty - string for COMMITPT's change text. Leaving the change text - field set NULL won't work, since that means "preserve the original - change text for this delta." */ - if (commitpt->text->text == NULL) - { - commitpt->text->text = xstrdup (""); - commitpt->text->len = 0; - } - } - else - { - /* This file is not being inserted at the head, but on a side - branch somewhere. Make a diff from the previous revision - to the working file. */ - switch (diff_exec (tmpfile, workfile, NULL, NULL, - dargc, dargv, changefile)) - { - case 0: - case 1: - break; - case -1: - /* FIXME-update-dir: message does not include update_dir. */ - error (1, errno, "error diffing %s", workfile); - break; - default: - /* FIXME-update-dir: message does not include update_dir. */ - error (1, 0, "error diffing %s", workfile); - break; - } - /* See the comment above, at the other get_file invocation, - regarding binary vs. text. */ - get_file (changefile, changefile, - rcs->expand != NULL && STREQ (rcs->expand, "b") ? "rb" : "r", - &dtext->text, &bufsize, - &dtext->len); - if (dtext->text == NULL) - { - dtext->text = xstrdup (""); - dtext->len = 0; - } - } - - run_arg_free_p (dargc, dargv); - free (dargv); - - /* Update DELTA linkage. It is important not to do this before - the very end of RCS_checkin; if an error arises that forces - us to abort checking in, we must not have malformed deltas - partially linked into the tree. - - If DELTA and COMMITPT are on different branches, do nothing -- - DELTA is linked to the tree through COMMITPT->BRANCHES, and we - don't want to change `next' pointers. - - Otherwise, if the nodes are both on the trunk, link DELTA to - COMMITPT; otherwise, link COMMITPT to DELTA. */ - - if (numdots (commitpt->version) == numdots (delta->version)) - { - if (STREQ (commitpt->version, rcs->head)) - { - delta->next = rcs->head; - rcs->head = xstrdup (delta->version); - } - else - commitpt->next = xstrdup (delta->version); - } - - /* Add DELTA to RCS->VERSIONS. */ - if (rcs->versions == NULL) - rcs->versions = getlist(); - nodep = getnode(); - nodep->type = RCSVERS; - nodep->delproc = rcsvers_delproc; - nodep->data = delta; - nodep->key = delta->version; - (void) addnode (rcs->versions, nodep); - - /* Write the new RCS file, inserting the new delta at COMMITPT. */ - if (!checkin_quiet) - { - cvs_output ("new revision: ", 14); - cvs_output (delta->version, 0); - cvs_output ("; previous revision: ", 21); - cvs_output (commitpt->version, 0); - cvs_output ("\n", 1); - } - - RCS_rewrite (rcs, dtext, commitpt->version); - - if ((flags & RCS_FLAGS_KEEPFILE) == 0) - { - if (unlink_file (workfile) < 0) - /* FIXME-update-dir: message does not include update_dir. */ - error (1, errno, "cannot remove %s", workfile); - } - if (unlink_file (tmpfile) < 0) - error (0, errno, "cannot remove %s", tmpfile); - free (tmpfile); - if (unlink_file (changefile) < 0) - error (0, errno, "cannot remove %s", changefile); - free (changefile); - - if (!checkin_quiet) - cvs_output ("done\n", 5); - - checkin_done: - free (workfile); - - if (commitpt != NULL && commitpt->text != NULL) - { - freedeltatext (commitpt->text); - commitpt->text = NULL; - } - - freedeltatext (dtext); - if (status != 0) - { - /* If delta has not been added to a List, then freeing the Node key - * won't free delta->version. - */ - if (delta->version) free (delta->version); - free_rcsvers_contents (delta); - } - - return status; -} - - - -/* This structure is passed between RCS_cmp_file and cmp_file_buffer. */ -struct cmp_file_data -{ - const char *filename; - FILE *fp; - int different; -}; - -/* Compare the contents of revision REV1 of RCS file RCS with the - contents of REV2 if given, otherwise, compare with the contents of - the file FILENAME. OPTIONS is a string for the keyword - expansion options. Return 0 if the contents of the revision are - the same as the contents of the file, 1 if they are different. */ -int -RCS_cmp_file (rcs, rev1, rev1_cache, rev2, options, filename) - RCSNode *rcs; - const char *rev1; - char **rev1_cache; - const char *rev2; - const char *options; - const char *filename; -{ - int binary; - - if (options != NULL && options[0] != '\0') - binary = STREQ (options, "-kb"); - else - { - char *expand; - - expand = RCS_getexpand (rcs); - if (expand != NULL && STREQ (expand, "b")) - binary = 1; - else - binary = 0; - } - -#ifdef PRESERVE_PERMISSIONS_SUPPORT - /* If CVS is to deal properly with special files (when - PreservePermissions is on), the best way is to check out the - revision to a temporary file and call `xcmp' on the two disk - files. xcmp needs to handle non-regular files properly anyway, - so calling it simplifies RCS_cmp_file. We *could* just yank - the delta node out of the version tree and look for device - numbers, but writing to disk and calling xcmp is a better - abstraction (therefore probably more robust). -twp */ - - if (preserve_perms) - { - char *tmp; - int retcode; - - tmp = cvs_temp_name(); - retcode = RCS_checkout(rcs, NULL, rev, NULL, options, tmp, NULL, NULL); - if (retcode != 0) - return 1; - - retcode = xcmp (tmp, filename); - if (CVS_UNLINK (tmp) < 0) - error (0, errno, "cannot remove %s", tmp); - free (tmp); - return retcode; - } - else -#endif - { - FILE *fp; - struct cmp_file_data data; - const char *use_file1; - char *tmpfile = NULL; - - if (rev2 != NULL) - { - /* Open & cache rev1 */ - tmpfile = cvs_temp_name(); - if (RCS_checkout (rcs, NULL, rev1, NULL, options, tmpfile, - (RCSCHECKOUTPROC)0, NULL)) - error (1, errno, - "cannot check out revision %s of %s", - rev1, rcs->path); - use_file1 = tmpfile; - if (rev1_cache != NULL) - *rev1_cache = tmpfile; - } - else - use_file1 = filename; - - fp = CVS_FOPEN (use_file1, binary ? FOPEN_BINARY_READ : "r"); - if (fp == NULL) - /* FIXME-update-dir: should include update_dir in message. */ - error (1, errno, "cannot open file %s for comparing", use_file1); - - data.filename = use_file1; - data.fp = fp; - data.different = 0; - - if (RCS_checkout (rcs, (char *)NULL, rev2 ? rev2 : rev1, - (char *)NULL, options, RUN_TTY, cmp_file_buffer, - (void *)&data )) - error (1, errno, - "cannot check out revision %s of %s", - rev2 ? rev2 : rev1, rcs->path); - - /* If we have not yet found a difference, make sure that we are at - the end of the file. */ - if (!data.different) - { - if (getc (fp) != EOF) - data.different = 1; - } - - fclose (fp); - if (rev1_cache == NULL && tmpfile) - { - if (CVS_UNLINK (tmpfile ) < 0) - error (0, errno, "cannot remove %s", tmpfile); - free (tmpfile); - } - - return data.different; - } -} - - - -/* This is a subroutine of RCS_cmp_file. It is passed to - RCS_checkout. */ -#define CMP_BUF_SIZE (8 * 1024) - -static void -cmp_file_buffer (callerdat, buffer, len) - void *callerdat; - const char *buffer; - size_t len; -{ - struct cmp_file_data *data = (struct cmp_file_data *)callerdat; - char *filebuf; - - /* If we've already found a difference, we don't need to check - further. */ - if (data->different) - return; - - filebuf = xmalloc (len > CMP_BUF_SIZE ? CMP_BUF_SIZE : len); - - while (len > 0) - { - size_t checklen; - - checklen = len > CMP_BUF_SIZE ? CMP_BUF_SIZE : len; - if (fread (filebuf, 1, checklen, data->fp) != checklen) - { - if (ferror (data->fp)) - error (1, errno, "cannot read file %s for comparing", - data->filename); - data->different = 1; - free (filebuf); - return; - } - - if (memcmp (filebuf, buffer, checklen) != 0) - { - data->different = 1; - free (filebuf); - return; - } - - buffer += checklen; - len -= checklen; - } - - free (filebuf); -} - - - -/* For RCS file RCS, make symbolic tag TAG point to revision REV. - This validates that TAG is OK for a user to use. Return value is - -1 for error (and errno is set to indicate the error), positive for - error (and an error message has been printed), or zero for success. */ - -int -RCS_settag (rcs, tag, rev) - RCSNode *rcs; - const char *tag; - const char *rev; -{ - List *symbols; - Node *node; - - if (rcs->flags & PARTIAL) - RCS_reparsercsfile (rcs, (FILE **) NULL, (struct rcsbuffer *) NULL); - - /* FIXME: This check should be moved to RCS_check_tag. There is no - reason for it to be here. */ - if (STREQ (tag, TAG_BASE) - || STREQ (tag, TAG_HEAD)) - { - /* Print the name of the tag might be considered redundant - with the caller, which also prints it. Perhaps this helps - clarify why the tag name is considered reserved, I don't - know. */ - error (0, 0, "Attempt to add reserved tag name %s", tag); - return 1; - } - - /* A revision number of NULL means use the head or default branch. - If rev is not NULL, it may be a symbolic tag or branch number; - expand it to the correct numeric revision or branch head. */ - if (rev == NULL) - rev = rcs->branch ? rcs->branch : rcs->head; - - /* At this point rcs->symbol_data may not have been parsed. - Calling RCS_symbols will force it to be parsed into a list - which we can easily manipulate. */ - symbols = RCS_symbols (rcs); - if (symbols == NULL) - { - symbols = getlist (); - rcs->symbols = symbols; - } - node = findnode (symbols, tag); - if (node != NULL) - { - free (node->data); - node->data = xstrdup (rev); - } - else - { - node = getnode (); - node->key = xstrdup (tag); - node->data = xstrdup (rev); - (void) addnode_at_front (symbols, node); - } - - return 0; -} - -/* Delete the symbolic tag TAG from the RCS file RCS. Return 0 if - the tag was found (and removed), or 1 if it was not present. (In - either case, the tag will no longer be in RCS->SYMBOLS.) */ - -int -RCS_deltag (rcs, tag) - RCSNode *rcs; - const char *tag; -{ - List *symbols; - Node *node; - if (rcs->flags & PARTIAL) - RCS_reparsercsfile (rcs, (FILE **) NULL, (struct rcsbuffer *) NULL); - - symbols = RCS_symbols (rcs); - if (symbols == NULL) - return 1; - - node = findnode (symbols, tag); - if (node == NULL) - return 1; - - delnode (node); - - return 0; -} - -/* Set the default branch of RCS to REV. */ - -int -RCS_setbranch (rcs, rev) - RCSNode *rcs; - const char *rev; -{ - if (rcs->flags & PARTIAL) - RCS_reparsercsfile (rcs, (FILE **) NULL, (struct rcsbuffer *) NULL); - - if (rev && ! *rev) - rev = NULL; - - if (rev == NULL && rcs->branch == NULL) - return 0; - if (rev != NULL && rcs->branch != NULL && STREQ (rev, rcs->branch)) - return 0; - - if (rcs->branch != NULL) - free (rcs->branch); - rcs->branch = xstrdup (rev); - - return 0; -} - -/* Lock revision REV. LOCK_QUIET is 1 to suppress output. FIXME: - Most of the callers only call us because RCS_checkin still tends to - like a lock (a relic of old behavior inherited from the RCS ci - program). If we clean this up, only "cvs admin -l" will still need - to call RCS_lock. */ - -/* FIXME-twp: if a lock owned by someone else is broken, should this - send mail to the lock owner? Prompt user? It seems like such an - obscure situation for CVS as almost not worth worrying much - about. */ - -int -RCS_lock (rcs, rev, lock_quiet) - RCSNode *rcs; - const char *rev; - int lock_quiet; -{ - List *locks; - Node *p; - char *user; - char *xrev = NULL; - - if (rcs->flags & PARTIAL) - RCS_reparsercsfile (rcs, (FILE **) NULL, (struct rcsbuffer *) NULL); - - locks = RCS_getlocks (rcs); - if (locks == NULL) - locks = rcs->locks = getlist(); - user = getcaller(); - - /* A revision number of NULL means lock the head or default branch. */ - if (rev == NULL) - xrev = RCS_head (rcs); - else - xrev = RCS_gettag (rcs, rev, 1, (int *) NULL); - - /* Make sure that the desired revision exists. Technically, - we can update the locks list without even checking this, - but RCS 5.7 did this. And it can't hurt. */ - if (xrev == NULL || findnode (rcs->versions, xrev) == NULL) - { - if (!lock_quiet) - error (0, 0, "%s: revision %s absent", rcs->path, rev); - free (xrev); - return 1; - } - - /* Is this rev already locked? */ - p = findnode (locks, xrev); - if (p != NULL) - { - if (STREQ (p->data, user)) - { - /* We already own the lock on this revision, so do nothing. */ - free (xrev); - return 0; - } - -#if 0 - /* Well, first of all, "rev" below should be "xrev" to avoid - core dumps. But more importantly, should we really be - breaking the lock unconditionally? What CVS 1.9 does (via - RCS) is to prompt "Revision 1.1 is already locked by fred. - Do you want to break the lock? [ny](n): ". Well, we don't - want to interact with the user (certainly not at the - server/protocol level, and probably not in the command-line - client), but isn't it more sensible to give an error and - let the user run "cvs admin -u" if they want to break the - lock? */ - - /* Break the lock. */ - if (!lock_quiet) - { - cvs_output (rev, 0); - cvs_output (" unlocked\n", 0); - } - delnode (p); -#else - error (1, 0, "Revision %s is already locked by %s", xrev, (char *)p->data); -#endif - } - - /* Create a new lock. */ - p = getnode(); - p->key = xrev; /* already xstrdupped */ - p->data = xstrdup (getcaller()); - (void) addnode_at_front (locks, p); - - if (!lock_quiet) - { - cvs_output (xrev, 0); - cvs_output (" locked\n", 0); - } - - return 0; -} - -/* Unlock revision REV. UNLOCK_QUIET is 1 to suppress output. FIXME: - Like RCS_lock, this can become a no-op if we do the checkin - ourselves. - - If REV is not null and is locked by someone else, break their - lock and notify them. It is an open issue whether RCS_unlock - queries the user about whether or not to break the lock. */ - -int -RCS_unlock (rcs, rev, unlock_quiet) - RCSNode *rcs; - char *rev; - int unlock_quiet; -{ - Node *lock; - List *locks; - char *user; - char *xrev = NULL; - - user = getcaller(); - if (rcs->flags & PARTIAL) - RCS_reparsercsfile (rcs, (FILE **) NULL, (struct rcsbuffer *) NULL); - - /* If rev is NULL, unlock the revision held by the caller; if more - than one, make the user specify the revision explicitly. This - differs from RCS which unlocks the latest revision (first in - rcs->locks) held by the caller. */ - if (rev == NULL) - { - Node *p; - - /* No-ops: attempts to unlock an empty tree or an unlocked file. */ - if (rcs->head == NULL) - { - if (!unlock_quiet) - cvs_outerr ("can't unlock an empty tree\n", 0); - return 0; - } - - locks = RCS_getlocks (rcs); - if (locks == NULL) - { - if (!unlock_quiet) - cvs_outerr ("No locks are set.\n", 0); - return 0; - } - - lock = NULL; - for (p = locks->list->next; p != locks->list; p = p->next) - { - if (STREQ (p->data, user)) - { - if (lock != NULL) - { - if (!unlock_quiet) - error (0, 0, "\ -%s: multiple revisions locked by %s; please specify one", rcs->path, user); - return 1; - } - lock = p; - } - } - if (lock == NULL) - { - if (!unlock_quiet) - error (0, 0, "No locks are set for %s.\n", user); - return 0; /* no lock found, ergo nothing to do */ - } - xrev = xstrdup (lock->key); - } - else - { - xrev = RCS_gettag (rcs, rev, 1, (int *) NULL); - if (xrev == NULL) - { - error (0, 0, "%s: revision %s absent", rcs->path, rev); - return 1; - } - } - - lock = findnode (RCS_getlocks (rcs), xrev); - if (lock == NULL) - { - /* This revision isn't locked. */ - free (xrev); - return 0; - } - - if (! STREQ (lock->data, user)) - { - /* If the revision is locked by someone else, notify - them. Note that this shouldn't ever happen if RCS_unlock - is called with a NULL revision, since that means "whatever - revision is currently locked by the caller." */ - char *repos, *workfile; - if (!unlock_quiet) - error (0, 0, "\ -%s: revision %s locked by %s; breaking lock", rcs->path, xrev, (char *)lock->data); - repos = xstrdup (rcs->path); - workfile = strrchr (repos, '/'); - *workfile++ = '\0'; - notify_do ('C', workfile, user, NULL, NULL, repos); - free (repos); - } - - delnode (lock); - if (!unlock_quiet) - { - cvs_output (xrev, 0); - cvs_output (" unlocked\n", 0); - } - - free (xrev); - return 0; -} - -/* Add USER to the access list of RCS. Do nothing if already present. - FIXME-twp: check syntax of USER to make sure it's a valid id. */ - -void -RCS_addaccess (rcs, user) - RCSNode *rcs; - char *user; -{ - char *access, *a; - - if (rcs->flags & PARTIAL) - RCS_reparsercsfile (rcs, (FILE **) NULL, (struct rcsbuffer *) NULL); - - if (rcs->access == NULL) - rcs->access = xstrdup (user); - else - { - access = xstrdup (rcs->access); - for (a = strtok (access, " "); a != NULL; a = strtok (NULL, " ")) - { - if (STREQ (a, user)) - { - free (access); - return; - } - } - free (access); - rcs->access = (char *) xrealloc - (rcs->access, strlen (rcs->access) + strlen (user) + 2); - strcat (rcs->access, " "); - strcat (rcs->access, user); - } -} - -/* Remove USER from the access list of RCS. */ - -void -RCS_delaccess (rcs, user) - RCSNode *rcs; - char *user; -{ - char *p, *s; - int ulen; - - if (rcs->flags & PARTIAL) - RCS_reparsercsfile (rcs, (FILE **) NULL, (struct rcsbuffer *) NULL); - - if (rcs->access == NULL) - return; - - if (user == NULL) - { - free (rcs->access); - rcs->access = NULL; - return; - } - - p = rcs->access; - ulen = strlen (user); - while (p != NULL) - { - if (strncmp (p, user, ulen) == 0 && (p[ulen] == '\0' || p[ulen] == ' ')) - break; - p = strchr (p, ' '); - if (p != NULL) - ++p; - } - - if (p == NULL) - return; - - s = p + ulen; - while (*s != '\0') - *p++ = *s++; - *p = '\0'; -} - -char * -RCS_getaccess (rcs) - RCSNode *rcs; -{ - if (rcs->flags & PARTIAL) - RCS_reparsercsfile (rcs, (FILE **) NULL, (struct rcsbuffer *) NULL); - - return rcs->access; -} - -static int findtag PROTO ((Node *, void *)); - -/* Return a nonzero value if the revision specified by ARG is found. */ - -static int -findtag (node, arg) - Node *node; - void *arg; -{ - char *rev = (char *)arg; - - if (STREQ (node->data, rev)) - return 1; - else - return 0; -} - -static int findmagictag PROTO ((Node *, void *)); - -/* Return a nonzero value if a magic tag rooted at ARG is found. */ - -static int -findmagictag (node, arg) - Node *node; - void *arg; -{ - char *rev = (char *)arg; - size_t len = strlen (rev); - - if (strncmp (node->data, rev, len) == 0 && - strncmp ((char *)node->data + len, ".0.", 3) == 0) - return 1; - else - return 0; -} - -/* Delete revisions between REV1 and REV2. The changes between the two - revisions must be collapsed, and the result stored in the revision - immediately preceding the lower one. Return 0 for successful completion, - 1 otherwise. - - Solution: check out the revision preceding REV1 and the revision - following REV2. Use call_diff to find aggregate diffs between - these two revisions, and replace the delta text for the latter one - with the new aggregate diff. Alternatively, we could write a - function that takes two change texts and combines them to produce a - new change text, without checking out any revs or calling diff. It - would be hairy, but so, so cool. - - If INCLUSIVE is set, then TAG1 and TAG2, if non-NULL, tell us to - delete that revision as well (cvs admin -o tag1:tag2). If clear, - delete up to but not including that revision (cvs admin -o tag1::tag2). - This does not affect TAG1 or TAG2 being NULL; the meaning of the start - point in ::tag2 and :tag2 is the same and likewise for end points. */ - -int -RCS_delete_revs (rcs, tag1, tag2, inclusive) - RCSNode *rcs; - char *tag1; - char *tag2; - int inclusive; -{ - char *next; - Node *nodep; - RCSVers *revp = NULL; - RCSVers *beforep; - int status, found; - int save_noexec; - - char *branchpoint = NULL; - char *rev1 = NULL; - char *rev2 = NULL; - int rev1_inclusive = inclusive; - int rev2_inclusive = inclusive; - char *before = NULL; - char *after = NULL; - char *beforefile = NULL; - char *afterfile = NULL; - char *outfile = NULL; - - if (tag1 == NULL && tag2 == NULL) - return 0; - - /* Assume error status until everything is finished. */ - status = 1; - - /* Make sure both revisions exist. */ - if (tag1 != NULL) - { - rev1 = RCS_gettag (rcs, tag1, 1, NULL); - if (rev1 == NULL || (nodep = findnode (rcs->versions, rev1)) == NULL) - { - error (0, 0, "%s: Revision %s doesn't exist.", rcs->path, tag1); - goto delrev_done; - } - } - if (tag2 != NULL) - { - rev2 = RCS_gettag (rcs, tag2, 1, NULL); - if (rev2 == NULL || (nodep = findnode (rcs->versions, rev2)) == NULL) - { - error (0, 0, "%s: Revision %s doesn't exist.", rcs->path, tag2); - goto delrev_done; - } - } - - /* If rev1 is on the trunk and rev2 is NULL, rev2 should be - RCS->HEAD. (*Not* RCS_head(rcs), which may return rcs->branch - instead.) We need to check this special case early, in order - to make sure that rev1 and rev2 get ordered correctly. */ - if (rev2 == NULL && numdots (rev1) == 1) - { - rev2 = xstrdup (rcs->head); - rev2_inclusive = 1; - } - - if (rev2 == NULL) - rev2_inclusive = 1; - - if (rev1 != NULL && rev2 != NULL) - { - /* A range consisting of a branch number means the latest revision - on that branch. */ - if (RCS_isbranch (rcs, rev1) && STREQ (rev1, rev2)) - { - char *tmp = RCS_getbranch (rcs, rev1, 0); - free (rev1); - free (rev2); - rev1 = rev2 = tmp; - } - else - { - /* Make sure REV1 and REV2 are ordered correctly (in the - same order as the next field). For revisions on the - trunk, REV1 should be higher than REV2; for branches, - REV1 should be lower. */ - /* Shouldn't we just be giving an error in the case where - the user specifies the revisions in the wrong order - (that is, always swap on the trunk, never swap on a - branch, in the non-error cases)? It is not at all - clear to me that users who specify -o 1.4:1.2 really - meant to type -o 1.2:1.4, and the out of order usage - has never been documented, either by cvs.texinfo or - rcs(1). */ - char *temp; - int temp_inclusive; - if (numdots (rev1) == 1) - { - if (compare_revnums (rev1, rev2) <= 0) - { - temp = rev2; - rev2 = rev1; - rev1 = temp; - - temp_inclusive = rev2_inclusive; - rev2_inclusive = rev1_inclusive; - rev1_inclusive = temp_inclusive; - } - } - else if (compare_revnums (rev1, rev2) > 0) - { - temp = rev2; - rev2 = rev1; - rev1 = temp; - - temp_inclusive = rev2_inclusive; - rev2_inclusive = rev1_inclusive; - rev1_inclusive = temp_inclusive; - } - } - } - - /* Basically the same thing; make sure that the ordering is what we - need. */ - if (rev1 == NULL) - { - assert (rev2 != NULL); - if (numdots (rev2) == 1) - { - /* Swap rev1 and rev2. */ - int temp_inclusive; - - rev1 = rev2; - rev2 = NULL; - - temp_inclusive = rev2_inclusive; - rev2_inclusive = rev1_inclusive; - rev1_inclusive = temp_inclusive; - } - } - - /* Put the revision number preceding the first one to delete into - BEFORE (where "preceding" means according to the next field). - If the first revision to delete is the first revision on its - branch (e.g. 1.3.2.1), BEFORE should be the node on the trunk - at which the branch is rooted. If the first revision to delete - is the head revision of the trunk, set BEFORE to NULL. - - Note that because BEFORE may not be on the same branch as REV1, - it is not very handy for navigating the revision tree. It's - most useful just for checking out the revision preceding REV1. */ - before = NULL; - branchpoint = RCS_getbranchpoint (rcs, rev1 != NULL ? rev1 : rev2); - if (rev1 == NULL) - { - rev1 = xstrdup (branchpoint); - if (numdots (branchpoint) > 1) - { - char *bp; - bp = strrchr (branchpoint, '.'); - while (*--bp != '.') - ; - *bp = '\0'; - /* Note that this is exclusive, always, because the inclusive - flag doesn't affect the meaning when rev1 == NULL. */ - before = xstrdup (branchpoint); - *bp = '.'; - } - } - else if (! STREQ (rev1, branchpoint)) - { - /* Walk deltas from BRANCHPOINT on, looking for REV1. */ - nodep = findnode (rcs->versions, branchpoint); - revp = nodep->data; - while (revp->next != NULL && ! STREQ (revp->next, rev1)) - { - revp = nodep->data; - nodep = findnode (rcs->versions, revp->next); - } - if (revp->next == NULL) - { - error (0, 0, "%s: Revision %s doesn't exist.", rcs->path, rev1); - goto delrev_done; - } - if (rev1_inclusive) - before = xstrdup (revp->version); - else - { - before = rev1; - nodep = findnode (rcs->versions, before); - rev1 = xstrdup (((RCSVers *)nodep->data)->next); - } - } - else if (!rev1_inclusive) - { - before = rev1; - nodep = findnode (rcs->versions, before); - rev1 = xstrdup (((RCSVers *)nodep->data)->next); - } - else if (numdots (branchpoint) > 1) - { - /* Example: rev1 is "1.3.2.1", branchpoint is "1.3.2.1". - Set before to "1.3". */ - char *bp; - bp = strrchr (branchpoint, '.'); - while (*--bp != '.') - ; - *bp = '\0'; - before = xstrdup (branchpoint); - *bp = '.'; - } - - /* If any revision between REV1 and REV2 is locked or is a branch point, - we can't delete that revision and must abort. */ - after = NULL; - next = rev1; - found = 0; - while (!found && next != NULL) - { - nodep = findnode (rcs->versions, next); - revp = nodep->data; - - if (rev2 != NULL) - found = STREQ (revp->version, rev2); - next = revp->next; - - if ((!found && next != NULL) || rev2_inclusive || rev2 == NULL) - { - if (findnode (RCS_getlocks (rcs), revp->version)) - { - error (0, 0, "%s: can't remove locked revision %s", - rcs->path, - revp->version); - goto delrev_done; - } - if (revp->branches != NULL) - { - error (0, 0, "%s: can't remove branch point %s", - rcs->path, - revp->version); - goto delrev_done; - } - - /* Doing this only for the :: syntax is for compatibility. - See cvs.texinfo for somewhat more discussion. */ - if (!inclusive && - (walklist (RCS_symbols (rcs), findtag, revp->version) || - walklist (RCS_symbols (rcs), findmagictag, revp->version))) - { - /* We don't print which file this happens to on the theory - that the caller will print the name of the file in a - more useful fashion (fullname not rcs->path). */ - error (0, 0, "cannot remove revision %s because it has tags", - revp->version); - goto delrev_done; - } - - /* It's misleading to print the `deleting revision' output - here, since we may not actually delete these revisions. - But that's how RCS does it. Bleah. Someday this should be - moved to the point where the revs are actually marked for - deletion. -twp */ - cvs_output ("deleting revision ", 0); - cvs_output (revp->version, 0); - cvs_output ("\n", 1); - } - } - - if (rev2 == NULL) - ; - else if (found) - { - if (rev2_inclusive) - after = xstrdup (next); - else - after = xstrdup (revp->version); - } - else if (!inclusive) - { - /* In the case of an empty range, for example 1.2::1.2 or - 1.2::1.3, we want to just do nothing. */ - status = 0; - goto delrev_done; - } - else - { - /* This looks fishy in the cases where tag1 == NULL or tag2 == NULL. - Are those cases really impossible? */ - assert (tag1 != NULL); - assert (tag2 != NULL); - - error (0, 0, "%s: invalid revision range %s:%s", rcs->path, - tag1, tag2); - goto delrev_done; - } - - if (after == NULL && before == NULL) - { - /* The user is trying to delete all revisions. While an - RCS file without revisions makes sense to RCS (e.g. the - state after "rcs -i"), CVS has never been able to cope with - it. So at least for now we just make this an error. - - We don't include rcs->path in the message since "cvs admin" - already printed "RCS file:" and the name. */ - error (1, 0, "attempt to delete all revisions"); - } - - /* The conditionals at this point get really hairy. Here is the - general idea: - - IF before != NULL and after == NULL - THEN don't check out any revisions, just delete them - IF before == NULL and after != NULL - THEN only check out after's revision, and use it for the new deltatext - ELSE - check out both revisions and diff -n them. This could use - RCS_exec_rcsdiff with some changes, like being able - to suppress diagnostic messages and to direct output. */ - - if (after != NULL) - { - char *diffbuf; - size_t bufsize, len; - -#if defined (WOE32) && !defined (__CYGWIN32__) - /* FIXME: This is an awful kludge, but at least until I have - time to work on it a little more and test it, I'd rather - give a fatal error than corrupt the file. I think that we - need to use "-kb" and "--binary" and "rb" to get_file - (probably can do it always, not just for binary files, if - we are consistent between the RCS_checkout and the diff). */ - { - char *expand = RCS_getexpand (rcs); - if (expand != NULL && STREQ (expand, "b")) - error (1, 0, - "admin -o not implemented yet for binary on this system"); - } -#endif /* WOE32 */ - - afterfile = cvs_temp_name(); - status = RCS_checkout (rcs, NULL, after, NULL, "-ko", afterfile, - (RCSCHECKOUTPROC)0, NULL); - if (status > 0) - goto delrev_done; - - if (before == NULL) - { - /* We are deleting revisions from the head of the tree, - so must create a new head. */ - diffbuf = NULL; - bufsize = 0; - get_file (afterfile, afterfile, "r", &diffbuf, &bufsize, &len); - - save_noexec = noexec; - noexec = 0; - if (unlink_file (afterfile) < 0) - error (0, errno, "cannot remove %s", afterfile); - noexec = save_noexec; - - free (afterfile); - afterfile = NULL; - - free (rcs->head); - rcs->head = xstrdup (after); - } - else - { - int dargc = 0; - size_t darg_allocated = 0; - char **dargv = NULL; - - beforefile = cvs_temp_name(); - status = RCS_checkout (rcs, NULL, before, NULL, "-ko", beforefile, - (RCSCHECKOUTPROC)0, NULL); - if (status > 0) - goto delrev_done; - - outfile = cvs_temp_name(); - run_add_arg_p (&dargc, &darg_allocated, &dargv, "-a"); - run_add_arg_p (&dargc, &darg_allocated, &dargv, "-n"); - status = diff_exec (beforefile, afterfile, NULL, NULL, - dargc, dargv, outfile); - run_arg_free_p (dargc, dargv); - free (dargv); - - if (status == 2) - { - /* Not sure we need this message; will diff_exec already - have printed an error? */ - error (0, 0, "%s: could not diff", rcs->path); - status = 1; - goto delrev_done; - } - - diffbuf = NULL; - bufsize = 0; - get_file (outfile, outfile, "r", &diffbuf, &bufsize, &len); - } - - /* Save the new change text in after's delta node. */ - nodep = findnode (rcs->versions, after); - revp = nodep->data; - - assert (revp->text == NULL); - - revp->text = (Deltatext *) xmalloc (sizeof (Deltatext)); - memset ((Deltatext *) revp->text, 0, sizeof (Deltatext)); - revp->text->version = xstrdup (revp->version); - revp->text->text = diffbuf; - revp->text->len = len; - - /* If DIFFBUF is NULL, it means that OUTFILE is empty and that - there are no differences between the two revisions. In that - case, we want to force RCS_copydeltas to write an empty string - for the new change text (leaving the text field set NULL - means "preserve the original change text for this delta," so - we don't want that). */ - if (revp->text->text == NULL) - revp->text->text = xstrdup (""); - } - - /* Walk through the revisions (again) to mark each one as - outdated. (FIXME: would it be safe to use the `dead' field for - this? Doubtful.) */ - for (next = rev1; - next != NULL && (after == NULL || ! STREQ (next, after)); - next = revp->next) - { - nodep = findnode (rcs->versions, next); - revp = nodep->data; - revp->outdated = 1; - } - - /* Update delta links. If BEFORE == NULL, we're changing the - head of the tree and don't need to update any `next' links. */ - if (before != NULL) - { - /* If REV1 is the first node on its branch, then BEFORE is its - root node (on the trunk) and we have to update its branches - list. Otherwise, BEFORE is on the same branch as AFTER, and - we can just change BEFORE's `next' field to point to AFTER. - (This should be safe: since findnode manages its lists via - the `hashnext' and `hashprev' fields, rather than `next' and - `prev', mucking with `next' and `prev' should not corrupt the - delta tree's internal structure. Much. -twp) */ - - if (rev1 == NULL) - /* beforep's ->next field already should be equal to after, - which I think is always NULL in this case. */ - ; - else if (STREQ (rev1, branchpoint)) - { - nodep = findnode (rcs->versions, before); - revp = nodep->data; - nodep = revp->branches->list->next; - while (nodep != revp->branches->list && - ! STREQ (nodep->key, rev1)) - nodep = nodep->next; - assert (nodep != revp->branches->list); - if (after == NULL) - delnode (nodep); - else - { - free (nodep->key); - nodep->key = xstrdup (after); - } - } - else - { - nodep = findnode (rcs->versions, before); - beforep = nodep->data; - free (beforep->next); - beforep->next = xstrdup (after); - } - } - - status = 0; - - delrev_done: - if (rev1 != NULL) - free (rev1); - if (rev2 && rev2 != rev1) - free (rev2); - if (branchpoint != NULL) - free (branchpoint); - if (before != NULL) - free (before); - if (after != NULL) - free (after); - - save_noexec = noexec; - noexec = 0; - if (beforefile != NULL) - { - if (unlink_file (beforefile) < 0) - error (0, errno, "cannot remove %s", beforefile); - free (beforefile); - } - if (afterfile != NULL) - { - if (unlink_file (afterfile) < 0) - error (0, errno, "cannot remove %s", afterfile); - free (afterfile); - } - if (outfile != NULL) - { - if (unlink_file (outfile) < 0) - error (0, errno, "cannot remove %s", outfile); - free (outfile); - } - noexec = save_noexec; - - return status; -} - -/* - * TRUE if there exists a symbolic tag "tag" in file. - */ -int -RCS_exist_tag (rcs, tag) - RCSNode *rcs; - char *tag; -{ - - assert (rcs != NULL); - - if (findnode (RCS_symbols (rcs), tag)) - return 1; - return 0; - -} - -/* - * TRUE if RCS revision number "rev" exists. - * This includes magic branch revisions, not found in rcs->versions, - * but only in rcs->symbols, requiring a list walk to find them. - * Take advantage of list walk callback function already used by - * RCS_delete_revs, above. - */ -int -RCS_exist_rev (rcs, rev) - RCSNode *rcs; - char *rev; -{ - - assert (rcs != NULL); - - if (rcs->flags & PARTIAL) - RCS_reparsercsfile (rcs, (FILE **) NULL, (struct rcsbuffer *) NULL); - - if (findnode(rcs->versions, rev) != 0) - return 1; - - if (walklist (RCS_symbols(rcs), findtag, rev) != 0) - return 1; - - return 0; - -} - - -/* RCS_deltas and friends. Processing of the deltas in RCS files. */ - -struct line -{ - /* Text of this line. Part of the same malloc'd block as the struct - line itself (we probably should use the "struct hack" (char text[1]) - and save ourselves sizeof (char *) bytes). Does not include \n; - instead has_newline indicates the presence or absence of \n. */ - char *text; - /* Length of this line, not counting \n if has_newline is true. */ - size_t len; - /* Version in which it was introduced. */ - RCSVers *vers; - /* Nonzero if this line ends with \n. This will always be true - except possibly for the last line. */ - int has_newline; - /* Number of pointers to this struct line. */ - int refcount; -}; - -struct linevector -{ - /* How many lines in use for this linevector? */ - unsigned int nlines; - /* How many lines allocated for this linevector? */ - unsigned int lines_alloced; - /* Pointer to array containing a pointer to each line. */ - struct line **vector; -}; - -static void linevector_init PROTO ((struct linevector *)); - -/* Initialize *VEC to be a linevector with no lines. */ -static void -linevector_init (vec) - struct linevector *vec; -{ - vec->lines_alloced = 0; - vec->nlines = 0; - vec->vector = NULL; -} - -static int linevector_add PROTO ((struct linevector *vec, const char *text, - size_t len, RCSVers *vers, - unsigned int pos)); - -/* Given some text TEXT, add each of its lines to VEC before line POS - (where line 0 is the first line). The last line in TEXT may or may - not be \n terminated. - Set the version for each of the new lines to VERS. This - function returns non-zero for success. It returns zero if the line - number is out of range. - - Each of the lines in TEXT are copied to space which is managed with - the linevector (and freed by linevector_free). So the caller doesn't - need to keep TEXT around after the call to this function. */ -static int -linevector_add (vec, text, len, vers, pos) - struct linevector *vec; - const char *text; - size_t len; - RCSVers *vers; - unsigned int pos; -{ - const char *textend; - unsigned int i; - unsigned int nnew; - const char *p; - const char *nextline_text; - size_t nextline_len; - int nextline_newline; - struct line *q; - - if (len == 0) - return 1; - - textend = text + len; - - /* Count the number of lines we will need to add. */ - nnew = 1; - for (p = text; p < textend; ++p) - if (*p == '\n' && p + 1 < textend) - ++nnew; - - /* Expand VEC->VECTOR if needed. */ - if (vec->nlines + nnew >= vec->lines_alloced) - { - if (vec->lines_alloced == 0) - vec->lines_alloced = 10; - while (vec->nlines + nnew >= vec->lines_alloced) - vec->lines_alloced *= 2; - vec->vector = xrealloc (vec->vector, - vec->lines_alloced * sizeof (*vec->vector)); - } - - /* Make room for the new lines in VEC->VECTOR. */ - for (i = vec->nlines + nnew - 1; i >= pos + nnew; --i) - vec->vector[i] = vec->vector[i - nnew]; - - if (pos > vec->nlines) - return 0; - - /* Actually add the lines, to VEC->VECTOR. */ - i = pos; - nextline_text = text; - nextline_newline = 0; - for (p = text; p < textend; ++p) - if (*p == '\n') - { - nextline_newline = 1; - if (p + 1 == textend) - /* If there are no characters beyond the last newline, we - don't consider it another line. */ - break; - nextline_len = p - nextline_text; - q = (struct line *) xmalloc (sizeof (struct line) + nextline_len); - q->vers = vers; - q->text = (char *)q + sizeof (struct line); - q->len = nextline_len; - q->has_newline = nextline_newline; - q->refcount = 1; - memcpy (q->text, nextline_text, nextline_len); - vec->vector[i++] = q; - - nextline_text = (char *)p + 1; - nextline_newline = 0; - } - nextline_len = p - nextline_text; - q = (struct line *) xmalloc (sizeof (struct line) + nextline_len); - q->vers = vers; - q->text = (char *)q + sizeof (struct line); - q->len = nextline_len; - q->has_newline = nextline_newline; - q->refcount = 1; - memcpy (q->text, nextline_text, nextline_len); - vec->vector[i] = q; - - vec->nlines += nnew; - - return 1; -} - -static void linevector_copy PROTO ((struct linevector *, struct linevector *)); - -/* Copy FROM to TO, copying the vectors but not the lines pointed to. */ -static void -linevector_copy (to, from) - struct linevector *to; - struct linevector *from; -{ - unsigned int ln; - - for (ln = 0; ln < to->nlines; ++ln) - { - if (--to->vector[ln]->refcount == 0) - free (to->vector[ln]); - } - if (from->nlines > to->lines_alloced) - { - if (to->lines_alloced == 0) - to->lines_alloced = 10; - while (from->nlines > to->lines_alloced) - to->lines_alloced *= 2; - to->vector = (struct line **) - xrealloc (to->vector, to->lines_alloced * sizeof (*to->vector)); - } - memcpy (to->vector, from->vector, - from->nlines * sizeof (*to->vector)); - to->nlines = from->nlines; - for (ln = 0; ln < to->nlines; ++ln) - ++to->vector[ln]->refcount; -} - -static void linevector_free PROTO ((struct linevector *)); - -/* Free storage associated with linevector. */ -static void -linevector_free (vec) - struct linevector *vec; -{ - unsigned int ln; - - if (vec->vector != NULL) - { - for (ln = 0; ln < vec->nlines; ++ln) - if (vec->vector[ln] && --vec->vector[ln]->refcount == 0) - free (vec->vector[ln]); - - free (vec->vector); - } -} - -static char *month_printname PROTO ((char *)); - -/* Given a textual string giving the month (1-12), terminated with any - character not recognized by atoi, return the 3 character name to - print it with. I do not think it is a good idea to change these - strings based on the locale; they are standard abbreviations (for - example in rfc822 mail messages) which should be widely understood. - Returns a pointer into static readonly storage. */ -static char * -month_printname (month) - char *month; -{ - static const char *const months[] = - {"Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; - int mnum; - - mnum = atoi (month); - if (mnum < 1 || mnum > 12) - return "???"; - return (char *)months[mnum - 1]; -} - -static int -apply_rcs_changes PROTO ((struct linevector *, const char *, size_t, - const char *, RCSVers *, RCSVers *)); - -/* Apply changes to the line vector LINES. DIFFBUF is a buffer of - * length DIFFLEN holding the change text from an RCS file (the output - * of diff -n). NAME is used in error messages. The VERS field of - * any line added is set to ADDVERS. The VERS field of any line - * deleted is set to DELVERS, unless DELVERS is NULL, in which case - * the VERS field of deleted lines is unchanged. - * - * RETURNS - * Non-zero if the change text is applied successfully to ORIG_LINES. - * - * If the change text does not appear to apply to ORIG_LINES (e.g., a - * line number is invalid), this function will return zero and ORIG_LINES - * will remain unmolested. - * - * ERRORS - * If the change text is improperly formatted (e.g., it is not the output - * of diff -n), the function calls error with a status of 1, causing the - * program to exit. - */ -static int -apply_rcs_changes (orig_lines, diffbuf, difflen, name, addvers, delvers) - struct linevector *orig_lines; - const char *diffbuf; - size_t difflen; - const char *name; - RCSVers *addvers; - RCSVers *delvers; -{ - const char *p; - const char *q; - int op; - /* The RCS format throws us for a loop in that the deltafrags (if - we define a deltafrag as an add or a delete) need to be applied - in reverse order. So we stick them into a linked list. */ - struct deltafrag { - enum {FRAG_ADD, FRAG_DELETE} type; - unsigned long pos; - unsigned long nlines; - const char *new_lines; - size_t len; - struct deltafrag *next; - }; - struct deltafrag *dfhead; - struct deltafrag **dftail; - struct deltafrag *df; - unsigned long numlines, lastmodline, offset; - struct linevector lines; - int err; - - dfhead = NULL; - dftail = &dfhead; - numlines = orig_lines->nlines; /* start with init # of lines */ - for (p = diffbuf; p != NULL && p < diffbuf + difflen; ) - { - op = *p++; - if (op != 'a' && op != 'd') - /* Can't just skip over the deltafrag, because the value - of op determines the syntax. */ - error (1, 0, "unrecognized operation '\\x%x' in %s", - op, name); - *dftail = df = xmalloc (sizeof *df); - *(dftail = &df->next) = NULL; - - df->pos = strtoul (p, (char **) &q, 10); - - if (p == q) - error (1, 0, "number expected in %s", name); - p = q; - if (*p++ != ' ') - error (1, 0, "space expected in %s", name); - df->nlines = strtoul (p, (char **) &q, 10); - if (p == q) - error (1, 0, "number expected in %s", name); - p = q; - if (*p++ != '\012') - error (1, 0, "linefeed expected in %s", name); - - if (op == 'a') - { - unsigned int i; - - df->type = FRAG_ADD; - i = df->nlines; - /* The text we want is the number of lines specified, or - until the end of the value, whichever comes first (it - will be the former except in the case where we are - adding a line which does not end in newline). */ - for (q = p; i != 0; ++q) - if (*q == '\n') - --i; - else if (q == diffbuf + difflen) - { - if (i != 1) - error (1, 0, "premature end of change in %s", name); - else - break; - } - - /* Stash away a pointer to the text we are adding. */ - df->new_lines = p; - df->len = q - p; - - p = q; - numlines += df->nlines; - } - else - { - /* Correct for the fact that line numbers in RCS files - start with 1. */ - --df->pos; - - assert (op == 'd'); - df->type = FRAG_DELETE; - numlines -= df->nlines; - } - } - - /* New temp data structure to hold new org before - copy back into original structure. */ - lines.nlines = lines.lines_alloced = numlines; - lines.vector = xmalloc (numlines * sizeof *lines.vector); - - /* We changed the list order to first to last -- so the - list never gets larger than the size numlines. */ - lastmodline = 0; - - /* offset created when adding/removing lines - between new and original structure */ - offset = 0; - err = 0; - for (df = dfhead; df != NULL; ) - { - unsigned int ln; - unsigned long deltaend; - - if (df->pos > orig_lines->nlines) - err = 1; - - /* On error, just free the rest of the list. */ - if (!err) - { - /* Here we need to get to the line where the next insert will - begin, which is DF->pos in ORIG_LINES. We will fill up to - DF->pos - OFFSET in LINES with original items. */ - for (deltaend = df->pos - offset; - lastmodline < deltaend; - lastmodline++) - { - /* we need to copy from the orig structure into new one */ - lines.vector[lastmodline] = - orig_lines->vector[lastmodline + offset]; - lines.vector[lastmodline]->refcount++; - } - - switch (df->type) - { - case FRAG_ADD: - { - const char *textend, *p; - const char *nextline_text; - struct line *q; - int nextline_newline; - size_t nextline_len; - - textend = df->new_lines + df->len; - nextline_newline = 0; - nextline_text = df->new_lines; - for (p = df->new_lines; p < textend; ++p) - { - if (*p == '\n') - { - nextline_newline = 1; - if (p + 1 == textend) - { - /* If there are no characters beyond the - last newline, we don't consider it - another line. */ - break; - } - - nextline_len = p - nextline_text; - q = xmalloc (sizeof *q + nextline_len); - q->vers = addvers; - q->text = (char *)(q + 1); - q->len = nextline_len; - q->has_newline = nextline_newline; - q->refcount = 1; - memcpy (q->text, nextline_text, nextline_len); - lines.vector[lastmodline++] = q; - offset--; - - nextline_text = (char *)p + 1; - nextline_newline = 0; - } - } - nextline_len = p - nextline_text; - q = xmalloc (sizeof *q + nextline_len); - q->vers = addvers; - q->text = (char *)(q + 1); - q->len = nextline_len; - q->has_newline = nextline_newline; - q->refcount = 1; - memcpy (q->text, nextline_text, nextline_len); - lines.vector[lastmodline++] = q; - - /* For each line we add the offset between the #'s - decreases. */ - offset--; - break; - } - - case FRAG_DELETE: - /* we are removing this many lines from the source. */ - offset += df->nlines; - - if (df->pos + df->nlines > orig_lines->nlines) - err = 1; - else if (delvers) - for (ln = df->pos; ln < df->pos + df->nlines; ++ln) - if (orig_lines->vector[ln]->refcount > 1) - /* Annotate needs this but, since the original - * vector is disposed of before returning from - * this function, we only need keep track if - * there are multiple references. - */ - orig_lines->vector[ln]->vers = delvers; - break; - } - } - - df = df->next; - free (dfhead); - dfhead = df; - } - - if (err) - { - /* No reason to try and move a half-mutated and known invalid - * text into the output buffer. - */ - linevector_free (&lines); - } - else - { - /* add the rest of the remaining lines to the data vector */ - for (; lastmodline < numlines; lastmodline++) - { - /* we need to copy from the orig structure into new one */ - lines.vector[lastmodline] = orig_lines->vector[lastmodline - + offset]; - lines.vector[lastmodline]->refcount++; - } - - /* Move the lines vector to the original structure for output, - * first deleting the old. - */ - linevector_free (orig_lines); - orig_lines->vector = lines.vector; - orig_lines->lines_alloced = numlines; - orig_lines->nlines = lines.nlines; - } - - return !err; -} - -/* Apply an RCS change text to a buffer. The function name starts - with rcs rather than RCS because this does not take an RCSNode - argument. NAME is used in error messages. TEXTBUF is the text - buffer to change, and TEXTLEN is the size. DIFFBUF and DIFFLEN are - the change buffer and size. The new buffer is returned in *RETBUF - and *RETLEN. The new buffer is allocated by xmalloc. - - Return 1 for success. On failure, call error and return 0. */ - -int -rcs_change_text (name, textbuf, textlen, diffbuf, difflen, retbuf, retlen) - const char *name; - char *textbuf; - size_t textlen; - const char *diffbuf; - size_t difflen; - char **retbuf; - size_t *retlen; -{ - struct linevector lines; - int ret; - - *retbuf = NULL; - *retlen = 0; - - linevector_init (&lines); - - if (! linevector_add (&lines, textbuf, textlen, NULL, 0)) - error (1, 0, "cannot initialize line vector"); - - if (! apply_rcs_changes (&lines, diffbuf, difflen, name, NULL, NULL)) - { - error (0, 0, "invalid change text in %s", name); - ret = 0; - } - else - { - char *p; - size_t n; - unsigned int ln; - - n = 0; - for (ln = 0; ln < lines.nlines; ++ln) - /* 1 for \n */ - n += lines.vector[ln]->len + 1; - - p = xmalloc (n); - *retbuf = p; - - for (ln = 0; ln < lines.nlines; ++ln) - { - memcpy (p, lines.vector[ln]->text, lines.vector[ln]->len); - p += lines.vector[ln]->len; - if (lines.vector[ln]->has_newline) - *p++ = '\n'; - } - - *retlen = p - *retbuf; - assert (*retlen <= n); - - ret = 1; - } - - linevector_free (&lines); - - return ret; -} - -/* Walk the deltas in RCS to get to revision VERSION. - - If OP is RCS_ANNOTATE, then write annotations using cvs_output. - - If OP is RCS_FETCH, then put the contents of VERSION into a - newly-malloc'd array and put a pointer to it in *TEXT. Each line - is \n terminated; the caller is responsible for converting text - files if desired. The total length is put in *LEN. - - If FP is non-NULL, it should be a file descriptor open to the file - RCS with file position pointing to the deltas. We close the file - when we are done. - - If LOG is non-NULL, then *LOG is set to the log message of VERSION, - and *LOGLEN is set to the length of the log message. - - On error, give a fatal error. */ - -void -RCS_deltas (rcs, fp, rcsbuf, version, op, text, len, log, loglen) - RCSNode *rcs; - FILE *fp; - struct rcsbuffer *rcsbuf; - const char *version; - enum rcs_delta_op op; - char **text; - size_t *len; - char **log; - size_t *loglen; -{ - struct rcsbuffer rcsbuf_local; - char *branchversion; - char *cpversion; - char *key; - char *value; - size_t vallen; - RCSVers *vers; - RCSVers *prev_vers; - RCSVers *trunk_vers; - char *next; - int ishead, isnext, isversion, onbranch; - Node *node; - struct linevector headlines; - struct linevector curlines; - struct linevector trunklines; - int foundhead; - - assert (version); - - if (fp == NULL) - { - rcsbuf_cache_open (rcs, rcs->delta_pos, &fp, &rcsbuf_local); - rcsbuf = &rcsbuf_local; - } - - assert (rcsbuf); - - if (log) *log = NULL; - - ishead = 1; - vers = NULL; - prev_vers = NULL; - trunk_vers = NULL; - next = NULL; - onbranch = 0; - foundhead = 0; - - linevector_init (&curlines); - linevector_init (&headlines); - linevector_init (&trunklines); - - /* We set BRANCHVERSION to the version we are currently looking - for. Initially, this is the version on the trunk from which - VERSION branches off. If VERSION is not a branch, then - BRANCHVERSION is just VERSION. */ - branchversion = xstrdup (version); - cpversion = strchr (branchversion, '.'); - if (cpversion != NULL) - cpversion = strchr (cpversion + 1, '.'); - if (cpversion != NULL) - *cpversion = '\0'; - - do { - if (! rcsbuf_getrevnum (rcsbuf, &key)) - error (1, 0, "unexpected EOF reading RCS file %s", rcs->path); - - /* look up the revision */ - node = findnode (rcs->versions, key); - if (!node) - error (1, 0, - "Delta text %s without revision information in `%s'.", - key, rcs->path); - - if (next != NULL && ! STREQ (next, key)) - { - /* This is not the next version we need. It is a branch - version which we want to ignore. */ - isnext = 0; - isversion = 0; - } - else - { - isnext = 1; - - /* Stash the previous version. */ - prev_vers = vers; - - vers = node->data; - next = vers->next; - - /* Compare key and trunkversion now, because key points to - storage controlled by rcsbuf_getkey. */ - if (STREQ (branchversion, key)) - isversion = 1; - else - isversion = 0; - } - - while (1) - { - if (! rcsbuf_getkey (rcsbuf, &key, &value)) - error (1, 0, "%s does not appear to be a valid rcs file", - rcs->path); - - if (log != NULL - && isversion - && STREQ (key, "log") - && STREQ (branchversion, version)) - { - if (*log != NULL) - { - error (0, 0, "Duplicate `log' keyword in RCS file (`%s').", - rcs->path); - free (*log); - } - *log = rcsbuf_valcopy (rcsbuf, value, 0, loglen); - } - - if (STREQ (key, "text")) - { - rcsbuf_valpolish (rcsbuf, value, 0, &vallen); - if (ishead) - { - if (! linevector_add (&curlines, value, vallen, NULL, 0)) - error (1, 0, "invalid rcs file %s", rcs->path); - - ishead = 0; - } - else if (isnext) - { - if (! apply_rcs_changes (&curlines, value, vallen, - rcs->path, - onbranch ? vers : NULL, - onbranch ? NULL : prev_vers)) - error (1, 0, "invalid change text in %s", rcs->path); - } - break; - } - } - - if (isversion) - { - /* This is either the version we want, or it is the - branchpoint to the version we want. */ - if (STREQ (branchversion, version)) - { - /* This is the version we want. */ - linevector_copy (&headlines, &curlines); - foundhead = 1; - if (onbranch) - { - /* We have found this version by tracking up a - branch. Restore back to the lines we saved - when we left the trunk, and continue tracking - down the trunk. */ - onbranch = 0; - vers = trunk_vers; - next = vers->next; - linevector_copy (&curlines, &trunklines); - } - } - else - { - Node *p; - - /* We need to look up the branch. */ - onbranch = 1; - - if (numdots (branchversion) < 2) - { - unsigned int ln; - - /* We are leaving the trunk; save the current - lines so that we can restore them when we - continue tracking down the trunk. */ - trunk_vers = vers; - linevector_copy (&trunklines, &curlines); - - /* Reset the version information we have - accumulated so far. It only applies to the - changes from the head to this version. */ - for (ln = 0; ln < curlines.nlines; ++ln) - curlines.vector[ln]->vers = NULL; - } - - /* The next version we want is the entry on - VERS->branches which matches this branch. For - example, suppose VERSION is 1.21.4.3 and - BRANCHVERSION was 1.21. Then we look for an entry - starting with "1.21.4" and we'll put it (probably - 1.21.4.1) in NEXT. We'll advance BRANCHVERSION by - two dots (in this example, to 1.21.4.3). */ - - if (vers->branches == NULL) - error (1, 0, "missing expected branches in %s", - rcs->path); - if (!cpversion) - error (1, 0, "Invalid revision number in `%s'.", - rcs->path); - *cpversion = '.'; - ++cpversion; - cpversion = strchr (cpversion, '.'); - if (cpversion == NULL) - error (1, 0, "version number confusion in %s", - rcs->path); - for (p = vers->branches->list->next; - p != vers->branches->list; - p = p->next) - if (strncmp (p->key, branchversion, - cpversion - branchversion) == 0) - break; - if (p == vers->branches->list) - error (1, 0, "missing expected branch in %s", - rcs->path); - - next = p->key; - - cpversion = strchr (cpversion + 1, '.'); - if (cpversion != NULL) - *cpversion = '\0'; - } - } - if (op == RCS_FETCH && foundhead) - break; - } while (next != NULL); - - free (branchversion); - - rcsbuf_cache (rcs, rcsbuf); - - if (! foundhead) - error (1, 0, "could not find desired version %s in %s", - version, rcs->path); - - /* Now print out or return the data we have just computed. */ - switch (op) - { - case RCS_ANNOTATE: - { - unsigned int ln; - - for (ln = 0; ln < headlines.nlines; ++ln) - { - char *buf; - /* Period which separates year from month in date. */ - char *ym; - /* Period which separates month from day in date. */ - char *md; - RCSVers *prvers; - - prvers = headlines.vector[ln]->vers; - if (prvers == NULL) - prvers = vers; - - buf = xmalloc (strlen (prvers->version) + 24); - sprintf (buf, "%-12s (%-8.8s ", - prvers->version, - prvers->author); - cvs_output (buf, 0); - free (buf); - - /* Now output the date. */ - ym = strchr (prvers->date, '.'); - if (ym == NULL) - { - /* ??- is an ANSI trigraph. The ANSI way to - avoid it is \? but some pre ANSI compilers - complain about the unrecognized escape - sequence. Of course string concatenation - ("??" "-???") is also an ANSI-ism. Testing - __STDC__ seems to be a can of worms, since - compilers do all kinds of things with it. */ - cvs_output ("??", 0); - cvs_output ("-???", 0); - cvs_output ("-??", 0); - } - else - { - md = strchr (ym + 1, '.'); - if (md == NULL) - cvs_output ("??", 0); - else - cvs_output (md + 1, 2); - - cvs_output ("-", 1); - cvs_output (month_printname (ym + 1), 0); - cvs_output ("-", 1); - /* Only output the last two digits of the year. Our output - lines are long enough as it is without printing the - century. */ - cvs_output (ym - 2, 2); - } - cvs_output ("): ", 0); - if (headlines.vector[ln]->len != 0) - cvs_output (headlines.vector[ln]->text, - headlines.vector[ln]->len); - cvs_output ("\n", 1); - } - } - break; - case RCS_FETCH: - { - char *p; - size_t n; - unsigned int ln; - - assert (text != NULL); - assert (len != NULL); - - n = 0; - for (ln = 0; ln < headlines.nlines; ++ln) - /* 1 for \n */ - n += headlines.vector[ln]->len + 1; - p = xmalloc (n); - *text = p; - for (ln = 0; ln < headlines.nlines; ++ln) - { - memcpy (p, headlines.vector[ln]->text, - headlines.vector[ln]->len); - p += headlines.vector[ln]->len; - if (headlines.vector[ln]->has_newline) - *p++ = '\n'; - } - *len = p - *text; - assert (*len <= n); - } - break; - } - - linevector_free (&curlines); - linevector_free (&headlines); - linevector_free (&trunklines); - - return; -} - -/* Read the information for a single delta from the RCS buffer RCSBUF, - whose name is RCSFILE. *KEYP and *VALP are either NULL, or the - first key/value pair to read, as set by rcsbuf_getkey. Return NULL - if there are no more deltas. Store the key/value pair which - terminated the read in *KEYP and *VALP. */ - -static RCSVers * -getdelta (rcsbuf, rcsfile, keyp, valp) - struct rcsbuffer *rcsbuf; - char *rcsfile; - char **keyp; - char **valp; -{ - RCSVers *vnode; - char *key, *value, *cp; - Node *kv; - - /* Get revision number if it wasn't passed in. This uses - rcsbuf_getkey because it doesn't croak when encountering - unexpected input. As a result, we have to play unholy games - with `key' and `value'. */ - if (*keyp != NULL) - { - key = *keyp; - value = *valp; - } - else - { - if (! rcsbuf_getkey (rcsbuf, &key, &value)) - error (1, 0, "%s: unexpected EOF", rcsfile); - } - - /* Make sure that it is a revision number and not a cabbage - or something. */ - for (cp = key; - (isdigit ((unsigned char) *cp) || *cp == '.') && *cp != '\0'; - cp++) - /* do nothing */ ; - /* Note that when comparing with RCSDATE, we are not massaging - VALUE from the string found in the RCS file. This is OK since - we know exactly what to expect. */ - if (*cp != '\0' || strncmp (RCSDATE, value, (sizeof RCSDATE) - 1) != 0) - { - *keyp = key; - *valp = value; - return NULL; - } - - vnode = (RCSVers *) xmalloc (sizeof (RCSVers)); - memset (vnode, 0, sizeof (RCSVers)); - - vnode->version = xstrdup (key); - - /* Grab the value of the date from value. Note that we are not - massaging VALUE from the string found in the RCS file. */ - cp = value + (sizeof RCSDATE) - 1; /* skip the "date" keyword */ - while (whitespace (*cp)) /* take space off front of value */ - cp++; - - vnode->date = xstrdup (cp); - - /* Get author field. */ - if (! rcsbuf_getkey (rcsbuf, &key, &value)) - { - error (1, 0, "unexpected end of file reading %s", rcsfile); - } - if (! STREQ (key, "author")) - error (1, 0, "\ -unable to parse %s; `author' not in the expected place", rcsfile); - vnode->author = rcsbuf_valcopy (rcsbuf, value, 0, (size_t *) NULL); - - /* Get state field. */ - if (! rcsbuf_getkey (rcsbuf, &key, &value)) - { - error (1, 0, "unexpected end of file reading %s", rcsfile); - } - if (! STREQ (key, "state")) - error (1, 0, "\ -unable to parse %s; `state' not in the expected place", rcsfile); - vnode->state = rcsbuf_valcopy (rcsbuf, value, 0, (size_t *) NULL); - /* The value is optional, according to rcsfile(5). */ - if (value != NULL && STREQ (value, RCSDEAD)) - { - vnode->dead = 1; - } - - /* Note that "branches" and "next" are in fact mandatory, according - to doc/RCSFILES. */ - - /* fill in the branch list (if any branches exist) */ - if (! rcsbuf_getkey (rcsbuf, &key, &value)) - { - error (1, 0, "unexpected end of file reading %s", rcsfile); - } - if (STREQ (key, RCSDESC)) - { - *keyp = key; - *valp = value; - /* Probably could/should be a fatal error. */ - error (0, 0, "warning: 'branches' keyword missing from %s", rcsfile); - return vnode; - } - if (value != (char *) NULL) - { - vnode->branches = getlist (); - /* Note that we are not massaging VALUE from the string found - in the RCS file. */ - do_branches (vnode->branches, value); - } - - /* fill in the next field if there is a next revision */ - if (! rcsbuf_getkey (rcsbuf, &key, &value)) - { - error (1, 0, "unexpected end of file reading %s", rcsfile); - } - if (STREQ (key, RCSDESC)) - { - *keyp = key; - *valp = value; - /* Probably could/should be a fatal error. */ - error (0, 0, "warning: 'next' keyword missing from %s", rcsfile); - return vnode; - } - if (value != (char *) NULL) - vnode->next = rcsbuf_valcopy (rcsbuf, value, 0, (size_t *) NULL); - - /* - * XXX - this is where we put the symbolic link stuff??? - * (into newphrases in the deltas). - */ - while (1) - { - if (! rcsbuf_getkey (rcsbuf, &key, &value)) - error (1, 0, "unexpected end of file reading %s", rcsfile); - - /* The `desc' keyword is the end of the deltas. */ - if (strcmp (key, RCSDESC) == 0) - break; - -#ifdef PRESERVE_PERMISSIONS_SUPPORT - - /* The `hardlinks' value is a group of words, which must - be parsed separately and added as a list to vnode->hardlinks. */ - if (strcmp (key, "hardlinks") == 0) - { - char *word; - - vnode->hardlinks = getlist(); - while ((word = rcsbuf_valword (rcsbuf, &value)) != NULL) - { - Node *n = getnode(); - n->key = word; - addnode (vnode->hardlinks, n); - } - continue; - } -#endif - - /* Enable use of repositories created by certain obsolete - versions of CVS. This code should remain indefinately; - there is no procedure for converting old repositories, and - checking for it is harmless. */ - if (STREQ (key, RCSDEAD)) - { - vnode->dead = 1; - if (vnode->state != NULL) - free (vnode->state); - vnode->state = xstrdup (RCSDEAD); - continue; - } - /* if we have a new revision number, we're done with this delta */ - for (cp = key; - (isdigit ((unsigned char) *cp) || *cp == '.') && *cp != '\0'; - cp++) - /* do nothing */ ; - /* Note that when comparing with RCSDATE, we are not massaging - VALUE from the string found in the RCS file. This is OK - since we know exactly what to expect. */ - if (*cp == '\0' && strncmp (RCSDATE, value, strlen (RCSDATE)) == 0) - break; - - /* At this point, key and value represent a user-defined field - in the delta node. */ - if (vnode->other_delta == NULL) - vnode->other_delta = getlist (); - kv = getnode (); - kv->type = rcsbuf_valcmp (rcsbuf) ? RCSCMPFLD : RCSFIELD; - kv->key = xstrdup (key); - kv->data = rcsbuf_valcopy (rcsbuf, value, kv->type == RCSFIELD, - (size_t *) NULL); - if (addnode (vnode->other_delta, kv) != 0) - { - /* Complaining about duplicate keys in newphrases seems - questionable, in that we don't know what they mean and - doc/RCSFILES has no prohibition on several newphrases - with the same key. But we can't store more than one as - long as we store them in a List *. */ - error (0, 0, "warning: duplicate key `%s' in RCS file `%s'", - key, rcsfile); - freenode (kv); - } - } - - /* Return the key which caused us to fail back to the caller. */ - *keyp = key; - *valp = value; - - return vnode; -} - -static void -freedeltatext (d) - Deltatext *d; -{ - if (d->version != NULL) - free (d->version); - if (d->log != NULL) - free (d->log); - if (d->text != NULL) - free (d->text); - if (d->other != (List *) NULL) - dellist (&d->other); - free (d); -} - -static Deltatext * -RCS_getdeltatext (rcs, fp, rcsbuf) - RCSNode *rcs; - FILE *fp; - struct rcsbuffer *rcsbuf; -{ - char *num; - char *key, *value; - Node *p; - Deltatext *d; - - /* Get the revision number. */ - if (! rcsbuf_getrevnum (rcsbuf, &num)) - { - /* If num == NULL, it means we reached EOF naturally. That's - fine. */ - if (num == NULL) - return NULL; - else - error (1, 0, "%s: unexpected EOF", rcs->path); - } - - p = findnode (rcs->versions, num); - if (!p) - error (1, 0, - "Delta text %s without revision information in `%s'.", - num, rcs->path); - - d = (Deltatext *) xmalloc (sizeof (Deltatext)); - d->version = xstrdup (num); - - /* Get the log message. */ - if (! rcsbuf_getkey (rcsbuf, &key, &value)) - error (1, 0, "%s, delta %s: unexpected EOF", rcs->path, num); - if (! STREQ (key, "log")) - error (1, 0, "%s, delta %s: expected `log', got `%s'", - rcs->path, num, key); - d->log = rcsbuf_valcopy (rcsbuf, value, 0, (size_t *) NULL); - - /* Get random newphrases. */ - d->other = getlist(); - while (1) - { - if (! rcsbuf_getkey (rcsbuf, &key, &value)) - error (1, 0, "%s, delta %s: unexpected EOF", rcs->path, num); - - if (STREQ (key, "text")) - break; - - p = getnode(); - p->type = rcsbuf_valcmp (rcsbuf) ? RCSCMPFLD : RCSFIELD; - p->key = xstrdup (key); - p->data = rcsbuf_valcopy (rcsbuf, value, p->type == RCSFIELD, - (size_t *) NULL); - if (addnode (d->other, p) < 0) - { - error (0, 0, "warning: %s, delta %s: duplicate field `%s'", - rcs->path, num, key); - } - } - - /* Get the change text. We already know that this key is `text'. */ - d->text = rcsbuf_valcopy (rcsbuf, value, 0, &d->len); - - return d; -} - -/* RCS output functions, for writing RCS format files from RCSNode - structures. - - For most of this work, RCS 5.7 uses an `aprintf' function which aborts - program upon error. Instead, these functions check the output status - of the stream right before closing it, and aborts if an error condition - is found. The RCS solution is probably the better one: it produces - more overhead, but will produce a clearer diagnostic in the case of - catastrophic error. In either case, however, the repository will probably - not get corrupted. */ - -static int -putsymbol_proc (symnode, fparg) - Node *symnode; - void *fparg; -{ - FILE *fp = (FILE *) fparg; - - /* A fiddly optimization: this code used to just call fprintf, but - in an old repository with hundreds of tags this can get called - hundreds of thousands of times when doing a cvs tag. Since - tagging is a relatively common operation, and using putc and - fputs is just as comprehensible, the change is worthwhile. */ - putc ('\n', fp); - putc ('\t', fp); - fputs (symnode->key, fp); - putc (':', fp); - fputs (symnode->data, fp); - return 0; -} - -static int putlock_proc PROTO ((Node *, void *)); - -/* putlock_proc is like putsymbol_proc, but key and data are reversed. */ - -static int -putlock_proc (symnode, fp) - Node *symnode; - void *fp; -{ - return fprintf ((FILE *) fp, "\n\t%s:%s", (char *)symnode->data, symnode->key); -} - -static int -putrcsfield_proc (node, vfp) - Node *node; - void *vfp; -{ - FILE *fp = (FILE *) vfp; - - /* Some magic keys used internally by CVS start with `;'. Skip them. */ - if (node->key[0] == ';') - return 0; - - fprintf (fp, "\n%s\t", node->key); - if (node->data != NULL) - { - /* If the field's value contains evil characters, - it must be stringified. */ - /* FIXME: This does not quite get it right. "7jk8f" is not a legal - value for a value in a newpharse, according to doc/RCSFILES, - because digits are not valid in an "id". We might do OK by - always writing strings (enclosed in @@). Would be nice to - explicitly mention this one way or another in doc/RCSFILES. - A case where we are wrong in a much more clear-cut way is that - we let through non-graphic characters such as whitespace and - control characters. */ - - if (node->type == RCSCMPFLD || strpbrk (node->data, "$,.:;@") == NULL) - fputs (node->data, fp); - else - { - putc ('@', fp); - expand_at_signs (node->data, (off_t) strlen (node->data), fp); - putc ('@', fp); - } - } - - /* desc, log and text fields should not be terminated with semicolon; - all other fields should be. */ - if (! STREQ (node->key, "desc") && - ! STREQ (node->key, "log") && - ! STREQ (node->key, "text")) - { - putc (';', fp); - } - return 0; -} - -#ifdef PRESERVE_PERMISSIONS_SUPPORT - -/* Save a filename in a `hardlinks' RCS field. NODE->KEY will contain - a full pathname, but currently only basenames are stored in the RCS - node. Assume that the filename includes nasty characters and - @-escape it. */ - -static int -puthardlink_proc (node, vfp) - Node *node; - void *vfp; -{ - FILE *fp = (FILE *) vfp; - char *basename = strrchr (node->key, '/'); - - if (basename == NULL) - basename = node->key; - else - ++basename; - - putc ('\t', fp); - putc ('@', fp); - (void) expand_at_signs (basename, strlen (basename), fp); - putc ('@', fp); - - return 0; -} - -#endif - -/* Output the admin node for RCS into stream FP. */ - -static void -RCS_putadmin (rcs, fp) - RCSNode *rcs; - FILE *fp; -{ - fprintf (fp, "%s\t%s;\n", RCSHEAD, rcs->head ? rcs->head : ""); - if (rcs->branch) - fprintf (fp, "%s\t%s;\n", RCSBRANCH, rcs->branch); - - fputs ("access", fp); - if (rcs->access) - { - char *p, *s; - s = xstrdup (rcs->access); - for (p = strtok (s, " \n\t"); p != NULL; p = strtok (NULL, " \n\t")) - fprintf (fp, "\n\t%s", p); - free (s); - } - fputs (";\n", fp); - - fputs (RCSSYMBOLS, fp); - /* If we haven't had to convert the symbols to a list yet, don't - force a conversion now; just write out the string. */ - if (rcs->symbols == NULL && rcs->symbols_data != NULL) - { - fputs ("\n\t", fp); - fputs (rcs->symbols_data, fp); - } - else - walklist (RCS_symbols (rcs), putsymbol_proc, (void *) fp); - fputs (";\n", fp); - - fputs ("locks", fp); - if (rcs->locks_data) - fprintf (fp, "\t%s", rcs->locks_data); - else if (rcs->locks) - walklist (rcs->locks, putlock_proc, (void *) fp); - if (rcs->strict_locks) - fprintf (fp, "; strict"); - fputs (";\n", fp); - - if (rcs->comment) - { - fprintf (fp, "comment\t@"); - expand_at_signs (rcs->comment, (off_t) strlen (rcs->comment), fp); - fputs ("@;\n", fp); - } - if (rcs->expand && ! STREQ (rcs->expand, "kv")) - fprintf (fp, "%s\t@%s@;\n", RCSEXPAND, rcs->expand); - - walklist (rcs->other, putrcsfield_proc, (void *) fp); - - putc ('\n', fp); -} - -static void -putdelta (vers, fp) - RCSVers *vers; - FILE *fp; -{ - Node *bp, *start; - - /* Skip if no revision was supplied, or if it is outdated (cvs admin -o) */ - if (vers == NULL || vers->outdated) - return; - - fprintf (fp, "\n%s\n%s\t%s;\t%s %s;\t%s %s;\nbranches", - vers->version, - RCSDATE, vers->date, - "author", vers->author, - "state", vers->state ? vers->state : ""); - - if (vers->branches != NULL) - { - start = vers->branches->list; - for (bp = start->next; bp != start; bp = bp->next) - fprintf (fp, "\n\t%s", bp->key); - } - - fprintf (fp, ";\nnext\t%s;", vers->next ? vers->next : ""); - - walklist (vers->other_delta, putrcsfield_proc, fp); - -#ifdef PRESERVE_PERMISSIONS_SUPPORT - if (vers->hardlinks) - { - fprintf (fp, "\nhardlinks"); - walklist (vers->hardlinks, puthardlink_proc, fp); - putc (';', fp); - } -#endif - putc ('\n', fp); -} - -static void -RCS_putdtree (rcs, rev, fp) - RCSNode *rcs; - char *rev; - FILE *fp; -{ - RCSVers *versp; - Node *p, *branch; - - /* Previously, this function used a recursive implementation, but - if the trunk has a huge number of revisions and the program - stack is not big, a stack overflow could occur, so this - nonrecursive version was developed to be more safe. */ - Node *branchlist, *onebranch; - List *branches; - List *onebranchlist; - - if (rev == NULL) - return; - - branches = getlist(); - - for (; rev != NULL;) - { - /* Find the delta node for this revision. */ - p = findnode (rcs->versions, rev); - if (p == NULL) - { - error (1, 0, - "error parsing repository file %s, file may be corrupt.", - rcs->path); - } - - versp = p->data; - - /* Print the delta node and go for its `next' node. This - prints the trunk. If there are any branches printed on this - revision, mark we have some. */ - putdelta (versp, fp); - /* Store branch information into branch list so to write its - trunk afterwards */ - if (versp->branches != NULL) - { - branch = getnode(); - branch->data = versp->branches; - - addnode(branches, branch); - } - - rev = versp->next; - } - - /* If there are any branches printed on this revision, - print those trunks as well. */ - branchlist = branches->list; - for (branch = branchlist->next; - branch != branchlist; - branch = branch->next) - { - onebranchlist = (List *)(branch->data); - onebranch = onebranchlist->list; - for (p = onebranch->next; p != onebranch; p = p->next) - RCS_putdtree (rcs, p->key, fp); - - branch->data = NULL; /* so to prevent its freeing on dellist */ - } - - dellist(&branches); -} - -static void -RCS_putdesc (rcs, fp) - RCSNode *rcs; - FILE *fp; -{ - fprintf (fp, "\n\n%s\n@", RCSDESC); - if (rcs->desc != NULL) - { - off_t len = (off_t) strlen (rcs->desc); - if (len > 0) - { - expand_at_signs (rcs->desc, len, fp); - if (rcs->desc[len-1] != '\n') - putc ('\n', fp); - } - } - fputs ("@\n", fp); -} - -static void -putdeltatext (fp, d) - FILE *fp; - Deltatext *d; -{ - fprintf (fp, "\n\n%s\nlog\n@", d->version); - if (d->log != NULL) - { - int loglen = strlen (d->log); - expand_at_signs (d->log, (off_t) loglen, fp); - if (d->log[loglen-1] != '\n') - putc ('\n', fp); - } - putc ('@', fp); - - walklist (d->other, putrcsfield_proc, fp); - - fputs ("\ntext\n@", fp); - if (d->text != NULL) - expand_at_signs (d->text, (off_t) d->len, fp); - fputs ("@\n", fp); -} - -/* TODO: the whole mechanism for updating deltas is kludgey... more - sensible would be to supply all the necessary info in a `newdeltatext' - field for RCSVers nodes. -twp */ - -/* Copy delta text nodes from FIN to FOUT. If NEWDTEXT is non-NULL, it - is a new delta text node, and should be added to the tree at the - node whose revision number is INSERTPT. (Note that trunk nodes are - written in decreasing order, and branch nodes are written in - increasing order.) */ - -static void -RCS_copydeltas (rcs, fin, rcsbufin, fout, newdtext, insertpt) - RCSNode *rcs; - FILE *fin; - struct rcsbuffer *rcsbufin; - FILE *fout; - Deltatext *newdtext; - char *insertpt; -{ - int actions; - RCSVers *dadmin; - Node *np; - int insertbefore, found; - char *bufrest; - int nls; - size_t buflen; - char buf[8192]; - int got; - - /* Count the number of versions for which we have to do some - special operation. */ - actions = walklist (rcs->versions, count_delta_actions, (void *) NULL); - - /* Make a note of whether NEWDTEXT should be inserted - before or after its INSERTPT. */ - insertbefore = (newdtext != NULL && numdots (newdtext->version) == 1); - - while (actions != 0 || newdtext != NULL) - { - Deltatext *dtext; - - dtext = RCS_getdeltatext (rcs, fin, rcsbufin); - - /* We shouldn't hit EOF here, because that would imply that - some action was not taken, or that we could not insert - NEWDTEXT. */ - if (dtext == NULL) - error (1, 0, "internal error: EOF too early in RCS_copydeltas"); - - found = (insertpt != NULL && STREQ (dtext->version, insertpt)); - if (found && insertbefore) - { - putdeltatext (fout, newdtext); - newdtext = NULL; - insertpt = NULL; - } - - np = findnode (rcs->versions, dtext->version); - if (!np) - error (1, 0, - "Delta text %s without revision information in `%s'.", - dtext->version, rcs->path); - - dadmin = np->data; - - /* If this revision has been outdated, just skip it. */ - if (dadmin->outdated) - { - freedeltatext (dtext); - --actions; - continue; - } - - /* Update the change text for this delta. New change text - data may come from cvs admin -m, cvs admin -o, or cvs ci. */ - if (dadmin->text != NULL) - { - if (dadmin->text->log != NULL || dadmin->text->text != NULL) - --actions; - if (dadmin->text->log != NULL) - { - free (dtext->log); - dtext->log = dadmin->text->log; - dadmin->text->log = NULL; - } - if (dadmin->text->text != NULL) - { - free (dtext->text); - dtext->text = dadmin->text->text; - dtext->len = dadmin->text->len; - dadmin->text->text = NULL; - } - } - putdeltatext (fout, dtext); - freedeltatext (dtext); - - if (found && !insertbefore) - { - putdeltatext (fout, newdtext); - newdtext = NULL; - insertpt = NULL; - } - } - - /* Copy the rest of the file directly, without bothering to - interpret it. The caller will handle error checking by calling - ferror. - - We just wrote a newline to the file, either in putdeltatext or - in the caller. However, we may not have read the corresponding - newline from the file, because rcsbuf_getkey returns as soon as - it finds the end of the '@' string for the desc or text key. - Therefore, we may read three newlines when we should really - only write two, and we check for that case here. This is not - an semantically important issue; we only do it to make our RCS - files look traditional. */ - - nls = 3; - - rcsbuf_get_buffered (rcsbufin, &bufrest, &buflen); - if (buflen > 0) - { - if (bufrest[0] != '\n' - || strncmp (bufrest, "\n\n\n", buflen < 3 ? buflen : 3) != 0) - { - nls = 0; - } - else - { - if (buflen < 3) - nls -= buflen; - else - { - ++bufrest; - --buflen; - nls = 0; - } - } - - fwrite (bufrest, 1, buflen, fout); - } - if (!rcsbufin->mmapped) - { - /* This bit isn't necessary when using mmap since the entire file - * will already be available via the RCS buffer. Besides, the - * mmap code doesn't always keep the file pointer up to date, so - * this adds some data twice. - */ - while ((got = fread (buf, 1, sizeof buf, fin)) != 0) - { - if (nls > 0 - && got >= nls - && buf[0] == '\n' - && strncmp (buf, "\n\n\n", nls) == 0) - { - fwrite (buf + 1, 1, got - 1, fout); - } - else - { - fwrite (buf, 1, got, fout); - } - - nls = 0; - } - } -} - -/* A helper procedure for RCS_copydeltas. This is called via walklist - to count the number of RCS revisions for which some special action - is required. */ - -static int -count_delta_actions (np, ignore) - Node *np; - void *ignore; -{ - RCSVers *dadmin = np->data; - - if (dadmin->outdated) - return 1; - - if (dadmin->text != NULL - && (dadmin->text->log != NULL || dadmin->text->text != NULL)) - { - return 1; - } - - return 0; -} - -/* - * Clean up temporary files - */ -RETSIGTYPE -rcs_cleanup () -{ - /* Note that the checks for existence_error are because we are - called from a signal handler, so we don't know whether the - files got created. */ - - /* FIXME: Do not perform buffered I/O from an interrupt handler like - this (via error). However, I'm leaving the error-calling code there - in the hope that on the rare occasion the error call is actually made - (e.g., a fluky I/O error or permissions problem prevents the deletion - of a just-created file) reentrancy won't be an issue. */ - if (rcs_lockfile != NULL) - { - char *tmp = rcs_lockfile; - rcs_lockfile = NULL; - if (rcs_lockfd >= 0) - { - if (close (rcs_lockfd) != 0) - error (0, errno, "error closing lock file %s", tmp); - rcs_lockfd = -1; - } - if (unlink_file (tmp) < 0 - && !existence_error (errno)) - error (0, errno, "cannot remove %s", tmp); - } -} - -/* RCS_internal_lockfile and RCS_internal_unlockfile perform RCS-style - locking on the specified RCSFILE: for a file called `foo,v', open - for writing a file called `,foo,'. - - Note that we what do here is quite different from what RCS does. - RCS creates the ,foo, file before it reads the RCS file (if it - knows that it will be writing later), so that it actually serves as - a lock. We don't; instead we rely on CVS writelocks. This means - that if someone is running RCS on the file at the same time they - are running CVS on it, they might lose (we read the file, - then RCS writes it, then we write it, clobbering the - changes made by RCS). I believe the current sentiment about this - is "well, don't do that". - - A concern has been expressed about whether adopting the RCS - strategy would slow us down. I don't think so, since we need to - write the ,foo, file anyway (unless perhaps if O_EXCL is slower or - something). - - These do not perform quite the same function as the RCS -l option - for locking files: they are intended to prevent competing RCS - processes from stomping all over each other's laundry. Hence, - they are `internal' locking functions. - - If there is an error, give a fatal error; if we return we always - return a non-NULL value. */ - -static FILE * -rcs_internal_lockfile (rcsfile) - char *rcsfile; -{ - struct stat rstat; - FILE *fp; - static int first_call = 1; - - if (first_call) - { - first_call = 0; - /* clean up if we get a signal */ -#ifdef SIGABRT - (void) SIG_register (SIGABRT, rcs_cleanup); -#endif -#ifdef SIGHUP - (void) SIG_register (SIGHUP, rcs_cleanup); -#endif -#ifdef SIGINT - (void) SIG_register (SIGINT, rcs_cleanup); -#endif -#ifdef SIGQUIT - (void) SIG_register (SIGQUIT, rcs_cleanup); -#endif -#ifdef SIGPIPE - (void) SIG_register (SIGPIPE, rcs_cleanup); -#endif -#ifdef SIGTERM - (void) SIG_register (SIGTERM, rcs_cleanup); -#endif - } - - /* Get the lock file name: `,file,' for RCS file `file,v'. */ - assert (rcs_lockfile == NULL); - assert (rcs_lockfd < 0); - rcs_lockfile = rcs_lockfilename (rcsfile); - - /* Use the existing RCS file mode, or read-only if this is a new - file. (Really, this is a lie -- if this is a new file, - RCS_checkin uses the permissions from the working copy. For - actually creating the file, we use 0444 as a safe default mode.) */ - if (stat (rcsfile, &rstat) < 0) - { - if (existence_error (errno)) - rstat.st_mode = S_IRUSR | S_IRGRP | S_IROTH; - else - error (1, errno, "cannot stat %s", rcsfile); - } - - /* Try to open exclusively. POSIX.1 guarantees that O_EXCL|O_CREAT - guarantees an exclusive open. According to the RCS source, with - NFS v2 we must also throw in O_TRUNC and use an open mask that makes - the file unwriteable. For extensive justification, see the comments for - rcswriteopen() in rcsedit.c, in RCS 5.7. This is kind of pointless - in the CVS case; see comment at the start of this file concerning - general ,foo, file strategy. - - There is some sentiment that with NFSv3 and such, that one can - rely on O_EXCL these days. This might be true for unix (I - don't really know), but I am still pretty skeptical in the case - of the non-unix systems. */ - rcs_lockfd = open (rcs_lockfile, - OPEN_BINARY | O_WRONLY | O_CREAT | O_EXCL | O_TRUNC, - S_IRUSR | S_IRGRP | S_IROTH); - - if (rcs_lockfd < 0) - { - error (1, errno, "could not open lock file `%s'", rcs_lockfile); - } - - /* Force the file permissions, and return a stream object. */ - /* Because we change the modes later, we don't worry about - this in the non-HAVE_FCHMOD case. */ -#ifdef HAVE_FCHMOD - if (fchmod (rcs_lockfd, rstat.st_mode) < 0) - error (1, errno, "cannot change mode for %s", rcs_lockfile); -#endif - fp = fdopen (rcs_lockfd, FOPEN_BINARY_WRITE); - if (fp == NULL) - error (1, errno, "cannot fdopen %s", rcs_lockfile); - - return fp; -} - -static void -rcs_internal_unlockfile (fp, rcsfile) - FILE *fp; - char *rcsfile; -{ - assert (rcs_lockfile != NULL); - assert (rcs_lockfd >= 0); - - /* Abort if we could not write everything successfully to LOCKFILE. - This is not a great error-handling mechanism, but should prevent - corrupting the repository. */ - - if (ferror (fp)) - /* Using errno here may well be misleanding since the most recent - call that set errno may not have anything whatsoever to do with - the error that set the flag, but it's better than nothing. The - real solution is to check each call to fprintf rather than waiting - until the end like this. */ - error (1, errno, "error writing to lock file %s", rcs_lockfile); - - /* Flush and sync the file, or the user may be told the commit completed, - * while a server crash/power failure could still cause the data to be - * lost. - * - * Invoking rename(",," , ",v") on Linux and almost all UNIXs - * only flushes the inode for the target file to disk, it does not - * guarantee flush of the kernel buffers allocated for the ,,. - * Depending upon the load on the machine, the Linux kernel's flush daemon - * process may not flush for a while. In the meantime the CVS transaction - * could have been declared committed to the end CVS user (CVS process has - * returned the final "OK"). If the machine crashes prior to syncing the - * changes to disk, the committed transaction can be lost. - */ - if (fflush (fp) != 0) - error (1, errno, "error flushing file `%s' to kernel buffers", - rcs_lockfile); -#ifdef HAVE_FSYNC - if (fsync (rcs_lockfd) < 0) - error (1, errno, "error fsyncing file `%s'", rcs_lockfile); -#endif - - if (fclose (fp) == EOF) - error (1, errno, "error closing lock file %s", rcs_lockfile); - rcs_lockfd = -1; - - rename_file (rcs_lockfile, rcsfile); - - { - /* Use a temporary to make sure there's no interval - (after rcs_lockfile has been freed but before it's set to NULL) - during which the signal handler's use of rcs_lockfile would - reference freed memory. */ - char *tmp = rcs_lockfile; - rcs_lockfile = NULL; - free (tmp); - } -} - -static char * -rcs_lockfilename (rcsfile) - const char *rcsfile; -{ - char *lockfile, *lockp; - const char *rcsbase, *rcsp, *rcsend; - int rcslen; - - /* Create the lockfile name. */ - rcslen = strlen (rcsfile); - lockfile = (char *) xmalloc (rcslen + 10); - rcsbase = last_component (rcsfile); - rcsend = rcsfile + rcslen - sizeof(RCSEXT); - for (lockp = lockfile, rcsp = rcsfile; rcsp < rcsbase; ++rcsp) - *lockp++ = *rcsp; - *lockp++ = ','; - while (rcsp <= rcsend) - *lockp++ = *rcsp++; - *lockp++ = ','; - *lockp = '\0'; - - return lockfile; -} - -/* Rewrite an RCS file. The basic idea here is that the caller should - first call RCS_reparsercsfile, then munge the data structures as - desired (via RCS_delete_revs, RCS_settag, &c), then call RCS_rewrite. */ - -void -RCS_rewrite (rcs, newdtext, insertpt) - RCSNode *rcs; - Deltatext *newdtext; - char *insertpt; -{ - FILE *fin, *fout; - struct rcsbuffer rcsbufin; - - assert (rcs); - - if (noexec) - return; - - /* Make sure we're operating on an actual file and not a symlink. */ - resolve_symlink (&(rcs->path)); - - fout = rcs_internal_lockfile (rcs->path); - - RCS_putadmin (rcs, fout); - RCS_putdtree (rcs, rcs->head, fout); - RCS_putdesc (rcs, fout); - - /* Open the original RCS file and seek to the first delta text. */ - rcsbuf_cache_open (rcs, rcs->delta_pos, &fin, &rcsbufin); - - /* Update delta_pos to the current position in the output file. - Do NOT move these statements: they must be done after fin has - been positioned at the old delta_pos, but before any delta - texts have been written to fout. - */ - rcs->delta_pos = ftell (fout); - if (rcs->delta_pos == -1) - error (1, errno, "cannot ftell in RCS file %s", rcs->path); - - RCS_copydeltas (rcs, fin, &rcsbufin, fout, newdtext, insertpt); - - /* We don't want to call rcsbuf_cache here, since we're about to - delete the file. */ - rcsbuf_close (&rcsbufin); - if (ferror (fin)) - /* The only case in which using errno here would be meaningful - is if we happen to have left errno unmolested since the call - which produced the error (e.g. fread). That is pretty - fragile even if it happens to sometimes be true. The real - solution is to make sure that all the code which reads - from fin checks for errors itself (some does, some doesn't). */ - error (0, 0, "warning: ferror set while rewriting RCS file `%s'", rcs->path); - if (fclose (fin) < 0) - error (0, errno, "warning: closing RCS file `%s'", rcs->path); - - rcs_internal_unlockfile (fout, rcs->path); -} - -/* Abandon changes to an RCS file. */ - -void -RCS_abandon (rcs) - RCSNode *rcs; -{ - free_rcsnode_contents (rcs); - rcs->symbols_data = NULL; - rcs->expand = NULL; - rcs->access = NULL; - rcs->locks_data = NULL; - rcs->comment = NULL; - rcs->desc = NULL; - rcs->flags |= PARTIAL; -} - -/* - * For a given file with full pathname PATH and revision number REV, - * produce a file label suitable for passing to diff. The default - * file label as used by RCS 5.7 looks like this: - * - * FILENAME YYYY/MM/DD HH:MM:SS REVNUM - * - * The date and time used are the revision's last checkin date and time. - * If REV is NULL, use the working copy's mtime instead. - * - * /dev/null is not statted but assumed to have been created on the Epoch. - * At least using the POSIX.2 definition of patch, this should cause creation - * of files on platforms such as Windoze where the null IO device isn't named - * /dev/null to be parsed by patch properly. - */ -char * -make_file_label (path, rev, rcs) - const char *path; - const char *rev; - RCSNode *rcs; -{ - char datebuf[MAXDATELEN + 1]; - char *label; - - label = (char *) xmalloc (strlen (path) - + (rev == NULL ? 0 : strlen (rev) + 1) - + MAXDATELEN - + 2); - - if (rev) - { - char date[MAXDATELEN + 1]; - /* revs cannot be attached to /dev/null ... duh. */ - assert (strcmp(DEVNULL, path)); - RCS_getrevtime (rcs, rev, datebuf, 0); - (void) date_to_internet (date, datebuf); - (void) sprintf (label, "-L%s\t%s\t%s", path, date, rev); - } - else - { - struct stat sb; - struct tm *wm; - - if (strcmp(DEVNULL, path)) - { - const char *file = last_component (path); - if (CVS_STAT (file, &sb) < 0) - /* Assume that if the stat fails,then the later read for the - * diff will too. - */ - error (1, errno, "could not get info for `%s'", path); - wm = gmtime (&sb.st_mtime); - } - else - { - time_t t = 0; - wm = gmtime(&t); - } - - (void) tm_to_internet (datebuf, wm); - (void) sprintf (label, "-L%s\t%s", path, datebuf); - } - return label; -} - -void -RCS_setlocalid (arg) - const char *arg; -{ - char *copy, *next, *key; - - copy = xstrdup(arg); - next = copy; - key = strtok(next, "="); - - keywords[KEYWORD_LOCALID].string = xstrdup(key); - keywords[KEYWORD_LOCALID].len = strlen(key); - keywords[KEYWORD_LOCALID].expandit = 1; - - /* options? */ - while (key = strtok(NULL, ",")) { - if (!strcmp(key, keywords[KEYWORD_ID].string)) - keyword_local = KEYWORD_ID; - else if (!strcmp(key, keywords[KEYWORD_HEADER].string)) - keyword_local = KEYWORD_HEADER; - else if (!strcmp(key, keywords[KEYWORD_CVSHEADER].string)) - keyword_local = KEYWORD_CVSHEADER; - else - error(1, 0, "Unknown LocalId mode: %s", key); - } - free(copy); -} - -void -RCS_setincexc (arg) - const char *arg; -{ - char *key; - char *copy, *next; - int include = 0; - struct rcs_keyword *keyword; - - copy = xstrdup(arg); - next = copy; - switch (*next++) { - case 'e': - include = 0; - break; - case 'i': - include = 1; - break; - default: - free(copy); - return; - } - - if (include) - for (keyword = keywords; keyword->string != NULL; keyword++) - { - keyword->expandit = 0; - } - - key = strtok(next, ","); - while (key) { - for (keyword = keywords; keyword->string != NULL; keyword++) { - if (strcmp (keyword->string, key) == 0) - keyword->expandit = include; - } - key = strtok(NULL, ","); - } - free(copy); - return; -} - -#define ATTIC "/" CVSATTIC -static char * -getfullCVSname(CVSname, pathstore) - char *CVSname, **pathstore; -{ - if (current_parsed_root->directory) { - int rootlen; - char *c = NULL; - int alen = sizeof(ATTIC) - 1; - - *pathstore = xstrdup(CVSname); - if ((c = strrchr(*pathstore, '/')) != NULL) { - if (c - *pathstore >= alen) { - if (!strncmp(c - alen, ATTIC, alen)) { - while (*c != '\0') { - *(c - alen) = *c; - c++; - } - *(c - alen) = '\0'; - } - } - } - - rootlen = strlen(current_parsed_root->directory); - if (!strncmp(*pathstore, current_parsed_root->directory, rootlen) && - (*pathstore)[rootlen] == '/') - CVSname = (*pathstore + rootlen + 1); - else - CVSname = (*pathstore); - } - return CVSname; -} diff --git a/contrib/cvs/src/rcs.h b/contrib/cvs/src/rcs.h deleted file mode 100644 index 08b8a5f..0000000 --- a/contrib/cvs/src/rcs.h +++ /dev/null @@ -1,266 +0,0 @@ -/* - * Copyright (C) 1986-2005 The Free Software Foundation, Inc. - * - * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot , - * and others. - * - * Portions Copyright (C) 1992, Brian Berliner and Jeff Polk - * Portions Copyright (C) 1989-1992, Brian Berliner - * - * You may distribute under the terms of the GNU General Public License as - * specified in the README file that comes with the CVS source distribution. - * - * RCS source control definitions needed by rcs.c and friends - * - * $FreeBSD$ - */ - -/* 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" -#define RCSHEAD "head" -#define RCSBRANCH "branch" -#define RCSSYMBOLS "symbols" -#define RCSDATE "date" -#define RCSDESC "desc" -#define RCSEXPAND "expand" - -/* Used by the version of death support which resulted from old - versions of CVS (e.g. 1.5 if you define DEATH_SUPPORT and not - DEATH_STATE). Only a hacked up RCS (used by those old versions of - CVS) will put this into RCS files. Considered obsolete. */ -#define RCSDEAD "dead" - -#define DATEFORM "%02d.%02d.%02d.%02d.%02d.%02d" -#define SDATEFORM "%d.%d.%d.%d.%d.%d" - -/* - * Opaque structure definitions used by RCS specific lookup routines - */ -#define VALID 0x1 /* flags field contains valid data */ -#define INATTIC 0x2 /* RCS file is located in the Attic */ -#define PARTIAL 0x4 /* RCS file not completly parsed */ - -/* All the "char *" fields in RCSNode, Deltatext, and RCSVers are - '\0'-terminated (except "text" in Deltatext). This means that we - can't deal with fields containing '\0', which is a limitation that - RCS does not have. Would be nice to fix this some day. */ - -struct rcsnode -{ - /* Reference count for this structure. Used to deal with the - fact that there might be a pointer from the Vers_TS or might - not. Callers who increment this field are responsible for - calling freercsnode when they are done with their reference. */ - int refcount; - - /* Flags (INATTIC, PARTIAL, &c), see above. */ - int flags; - - /* File name of the RCS file. This is not necessarily the name - as specified by the user, but it is a name which can be passed to - system calls and a name which is OK to print in error messages - (the various names might differ in case). */ - char *path; - - /* Value for head keyword from RCS header, or NULL if empty. */ - char *head; - - /* Value for branch keyword from RCS header, or NULL if omitted. */ - char *branch; - - /* Raw data on symbolic revisions. The first time that RCS_symbols is - called, we parse these into ->symbols, and free ->symbols_data. */ - char *symbols_data; - - /* Value for expand keyword from RCS header, or NULL if omitted. */ - char *expand; - - /* List of nodes, the key of which is the symbolic name and the data - of which is the numeric revision that it corresponds to (malloc'd). */ - List *symbols; - - /* List of nodes (type RCSVERS), the key of which the numeric revision - number, and the data of which is an RCSVers * for the revision. */ - List *versions; - - /* Value for access keyword from RCS header, or NULL if empty. - FIXME: RCS_delaccess would also seem to use "" for empty. We - should pick one or the other. */ - char *access; - - /* Raw data on locked revisions. The first time that RCS_getlocks is - called, we parse these into ->locks, and free ->locks_data. */ - char *locks_data; - - /* List of nodes, the key of which is the numeric revision and the - data of which is the user that it corresponds to (malloc'd). */ - List *locks; - - /* Set for the strict keyword from the RCS header. */ - int strict_locks; - - /* Value for the comment keyword from RCS header (comment leader), or - NULL if omitted. */ - char *comment; - - /* Value for the desc field in the RCS file, or NULL if empty. */ - char *desc; - - /* File offset of the first deltatext node, so we can seek there. */ - long delta_pos; - - /* Newphrases from the RCS header. List of nodes, the key of which - is the "id" which introduces the newphrase, and the value of which - is the value from the newphrase. */ - List *other; -}; - -typedef struct rcsnode RCSNode; - -struct deltatext { - char *version; - - /* Log message, or NULL if we do not intend to change the log message - (that is, RCS_copydeltas should just use the log message from the - file). */ - char *log; - - /* Change text, or NULL if we do not intend to change the change text - (that is, RCS_copydeltas should just use the change text from the - file). Note that it is perfectly legal to have log be NULL and - text non-NULL, or vice-versa. */ - char *text; - size_t len; - - /* Newphrase fields from deltatext nodes. FIXME: duplicates the - other field in the rcsversnode, I think. */ - List *other; -}; -typedef struct deltatext Deltatext; - -struct rcsversnode -{ - /* Duplicate of the key by which this structure is indexed. */ - char *version; - - char *date; - char *author; - char *state; - char *next; - int dead; - int outdated; - Deltatext *text; - List *branches; - /* Newphrase fields from deltatext nodes. Also contains ";add" and - ";delete" magic fields (see rcs.c, log.c). I think this is - only used by log.c (where it looks up "log"). Duplicates the - other field in struct deltatext, I think. */ - List *other; - /* Newphrase fields from delta nodes. */ - List *other_delta; -#ifdef PRESERVE_PERMISSIONS_SUPPORT - /* Hard link information for each revision. */ - List *hardlinks; -#endif -}; -typedef struct rcsversnode RCSVers; - -/* - * CVS reserves all even-numbered branches for its own use. "magic" branches - * (see rcs.c) are contained as virtual revision numbers (within symbolic - * tags only) off the RCS_MAGIC_BRANCH, which is 0. CVS also reserves the - * ".1" branch for vendor revisions. So, if you do your own branching, you - * should limit your use to odd branch numbers starting at 3. - */ -#define RCS_MAGIC_BRANCH 0 - -/* The type of a function passed to RCS_checkout. */ -typedef void (*RCSCHECKOUTPROC) PROTO ((void *, const char *, size_t)); - -#ifdef __STDC__ -struct rcsbuffer; -#endif - -/* What RCS_deltas is supposed to do. */ -enum rcs_delta_op {RCS_ANNOTATE, RCS_FETCH}; - -/* - * exported interfaces - */ -RCSNode *RCS_parse PROTO((const char *file, const char *repos)); -RCSNode *RCS_parsercsfile PROTO((const char *rcsfile)); -void RCS_fully_parse PROTO((RCSNode *)); -void RCS_reparsercsfile PROTO((RCSNode *, FILE **, struct rcsbuffer *)); -extern int RCS_setattic PROTO ((RCSNode *, int)); - -char *RCS_check_kflag PROTO((const char *arg)); -char *RCS_getdate PROTO((RCSNode * rcs, const char *date, - int force_tag_match)); -char *RCS_gettag PROTO((RCSNode * rcs, const char *symtag, int force_tag_match, - int *simple_tag)); -int RCS_exist_rev PROTO((RCSNode *rcs, char *rev)); -int RCS_exist_tag PROTO((RCSNode *rcs, char *tag)); -char *RCS_tag2rev PROTO((RCSNode *rcs, char *tag)); -char *RCS_getversion PROTO((RCSNode * rcs, const char *tag, const char *date, - int force_tag_match, int *simple_tag)); -char *RCS_magicrev PROTO((RCSNode *rcs, char *rev)); -int RCS_isbranch PROTO((RCSNode *rcs, const char *rev)); -int RCS_nodeisbranch PROTO((RCSNode *rcs, const char *tag)); -char *RCS_whatbranch PROTO((RCSNode *rcs, const char *tag)); -char *RCS_head PROTO((RCSNode * rcs)); -int RCS_datecmp PROTO((const char *date1, const char *date2)); -time_t RCS_getrevtime PROTO((RCSNode * rcs, const char *rev, char *date, - int fudge)); -List *RCS_symbols PROTO((RCSNode *rcs)); -void RCS_check_tag PROTO((const char *tag)); -int RCS_valid_rev PROTO ((char *rev)); -List *RCS_getlocks PROTO((RCSNode *rcs)); -void freercsnode PROTO((RCSNode ** rnodep)); -char *RCS_getbranch PROTO((RCSNode * rcs, const char *tag, - int force_tag_match)); -char *RCS_branch_head PROTO ((RCSNode *rcs, char *rev)); - -int RCS_isdead PROTO((RCSNode *, const char *)); -char *RCS_getexpand PROTO ((RCSNode *)); -void RCS_setexpand PROTO ((RCSNode *, const char *)); -int RCS_checkout PROTO ((RCSNode *, const char *, const char *, const char *, - const char *, const char *, RCSCHECKOUTPROC, void *)); -int RCS_checkin PROTO ((RCSNode *rcs, const char *workfile, - const char *message, const char *rev, time_t citime, - int flags)); -int RCS_cmp_file PROTO((RCSNode *, const char *, char **, const char *, - const char *, const char *)); -int RCS_settag PROTO ((RCSNode *, const char *, const char *)); -int RCS_deltag PROTO ((RCSNode *, const char *)); -int RCS_setbranch PROTO((RCSNode *, const char *)); -int RCS_lock PROTO ((RCSNode *, const char *, int)); -int RCS_unlock PROTO ((RCSNode *, char *, int)); -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 *)); -void RCS_deltas PROTO ((RCSNode *, FILE *, struct rcsbuffer *, const char *, - enum rcs_delta_op, char **, size_t *, - char **, size_t *)); -void RCS_setincexc PROTO ((const char *arg)); -void RCS_setlocalid PROTO ((const char *arg)); -char *make_file_label PROTO ((const char *, const char *, RCSNode *)); - -extern int datesep; -extern int preserve_perms; - -/* From import.c. */ -extern int add_rcs_file PROTO ((const char *, const char *, const char *, - const char *, const char *, const char *, - const char *, int, char **, const char *, - size_t, FILE *)); diff --git a/contrib/cvs/src/rcscmds.c b/contrib/cvs/src/rcscmds.c deleted file mode 100644 index 18182ff..0000000 --- a/contrib/cvs/src/rcscmds.c +++ /dev/null @@ -1,628 +0,0 @@ -/* - * Copyright (C) 1986-2005 The Free Software Foundation, Inc. - * - * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot , - * and others. - * - * Portions Copyright (C) 1992, Brian Berliner and Jeff Polk - * Portions Copyright (C) 1989-1992, Brian Berliner - * - * You may distribute under the terms of the GNU General Public License as - * specified in the README file that comes with the CVS source distribution. - * - * The functions in this file provide an interface for performing - * operations directly on RCS files. - * - * $FreeBSD$ - */ - -#include "cvs.h" -#include -#include -#include "diffrun.h" - -/* This file, rcs.h, and rcs.c, together sometimes known as the "RCS - library", are intended to define our interface to RCS files. - - Whether there will also be a version of RCS which uses this - library, or whether the library will be packaged for uses beyond - CVS or RCS (many people would like such a thing) is an open - question. Some considerations: - - 1. An RCS library for CVS must have the capabilities of the - existing CVS code which accesses RCS files. In particular, simple - approaches will often be slow. - - 2. An RCS library should not use code from the current RCS - (5.7 and its ancestors). The code has many problems. Too few - comments, too many layers of abstraction, too many global variables - (the correct number for a library is zero), too much intricately - interwoven functionality, and too many clever hacks. Paul Eggert, - the current RCS maintainer, agrees. - - 3. More work needs to be done in terms of separating out the RCS - library from the rest of CVS (for example, cvs_output should be - replaced by a callback, and the declarations should be centralized - into rcs.h, and probably other such cleanups). - - 4. To be useful for RCS and perhaps for other uses, the library - may need features beyond those needed by CVS. - - 5. Any changes to the RCS file format *must* be compatible. Many, - many tools (not just CVS and RCS) can at least import this format. - RCS and CVS must preserve the current ability to import/export it - (preferably improved--magic branches are currently a roadblock). - See doc/RCSFILES in the CVS distribution for documentation of this - file format. - - On a related note, see the comments at diff_exec, later in this file, - for more on the diff library. */ - -static void RCS_output_diff_options PROTO ((int, char *const *, const char *, - const char *, const char *)); - - -/* Stuff to deal with passing arguments the way libdiff.a wants to deal - with them. This is a crufty interface; there is no good reason for it - to resemble a command line rather than something closer to "struct - log_data" in log.c. */ - -/* First call call_diff_setup to setup any initial arguments. The - argument will be parsed into whitespace separated words and added - to the global call_diff_argv list. - - Then, optionally, call call_diff_add_arg for each additional argument - that you'd like to pass to the diff library. - - Finally, call call_diff or call_diff3 to produce the diffs. */ - -static char **call_diff_argv; -static int call_diff_argc; -static size_t call_diff_argc_allocated; - -static void call_diff_add_arg PROTO ((const char *)); -static void call_diff_setup PROTO ((const char *prog, - int argc, char * const *argv)); -static int call_diff PROTO ((const char *out)); -static int call_diff3 PROTO ((char *out)); - -static void call_diff_write_output PROTO((const char *, size_t)); -static void call_diff_flush_output PROTO((void)); -static void call_diff_write_stdout PROTO((const char *)); -static void call_diff_error PROTO((const char *, const char *, const char *)); - - - -static void -call_diff_add_arg (s) - const char *s; -{ - run_add_arg_p (&call_diff_argc, &call_diff_argc_allocated, &call_diff_argv, - s); -} - - - -/* VARARGS */ -static void -call_diff_setup (prog, argc, argv) - const char *prog; - int argc; - char * const *argv; -{ - int i; - - /* clean out any malloc'ed values from call_diff_argv */ - run_arg_free_p (call_diff_argc, call_diff_argv); - call_diff_argc = 0; - - /* put each word into call_diff_argv, allocating it as we go */ - call_diff_add_arg (prog); - for (i = 0; i < argc; i++) - call_diff_add_arg (argv[i]); -} - - -/* Callback function for the diff library to write data to the output - file. This is used when we are producing output to stdout. */ - -static void -call_diff_write_output (text, len) - const char *text; - size_t len; -{ - if (len > 0) - cvs_output (text, len); -} - -/* Call back function for the diff library to flush the output file. - This is used when we are producing output to stdout. */ - -static void -call_diff_flush_output () -{ - cvs_flushout (); -} - -/* Call back function for the diff library to write to stdout. */ - -static void -call_diff_write_stdout (text) - const char *text; -{ - cvs_output (text, 0); -} - -/* Call back function for the diff library to write to stderr. */ - -static void -call_diff_error (format, a1, a2) - const char *format; - const char *a1; - const char *a2; -{ - /* FIXME: Should we somehow indicate that this error is coming from - the diff library? */ - error (0, 0, format, a1, a2); -} - -/* This set of callback functions is used if we are sending the diff - to stdout. */ - -static struct diff_callbacks call_diff_stdout_callbacks = -{ - call_diff_write_output, - call_diff_flush_output, - call_diff_write_stdout, - call_diff_error -}; - -/* This set of callback functions is used if we are sending the diff - to a file. */ - -static struct diff_callbacks call_diff_file_callbacks = -{ - (void (*) PROTO((const char *, size_t))) NULL, - (void (*) PROTO((void))) NULL, - call_diff_write_stdout, - call_diff_error -}; - - - -static int -call_diff (out) - const char *out; -{ - call_diff_add_arg (NULL); - - if (out == RUN_TTY) - return diff_run (call_diff_argc, call_diff_argv, NULL, - &call_diff_stdout_callbacks); - else - return diff_run (call_diff_argc, call_diff_argv, out, - &call_diff_file_callbacks); -} - - - -static int -call_diff3 (out) - char *out; -{ - if (out == RUN_TTY) - return diff3_run (call_diff_argc, call_diff_argv, NULL, - &call_diff_stdout_callbacks); - else - return diff3_run (call_diff_argc, call_diff_argv, out, - &call_diff_file_callbacks); -} - - - -/* Merge revisions REV1 and REV2. */ - -int -RCS_merge(rcs, path, workfile, options, rev1, rev2) - RCSNode *rcs; - const char *path; - const char *workfile; - const char *options; - const char *rev1; - const char *rev2; -{ - char *xrev1, *xrev2; - char *tmp1, *tmp2; - char *diffout = NULL; - int retval; - - if (options != NULL && options[0] != '\0') - assert (options[0] == '-' && options[1] == 'k'); - - cvs_output ("RCS file: ", 0); - cvs_output (rcs->path, 0); - cvs_output ("\n", 1); - - /* Calculate numeric revision numbers from rev1 and rev2 (may be - symbolic). */ - xrev1 = RCS_gettag (rcs, rev1, 0, NULL); - xrev2 = RCS_gettag (rcs, rev2, 0, NULL); - assert (xrev1 && xrev2); - - /* Check out chosen revisions. The error message when RCS_checkout - fails is not very informative -- it is taken verbatim from RCS 5.7, - and relies on RCS_checkout saying something intelligent upon failure. */ - cvs_output ("retrieving revision ", 0); - cvs_output (xrev1, 0); - cvs_output ("\n", 1); - - tmp1 = cvs_temp_name(); - if (RCS_checkout (rcs, NULL, xrev1, rev1, options, tmp1, - (RCSCHECKOUTPROC)0, NULL)) - { - cvs_outerr ("rcsmerge: co failed\n", 0); - error_exit(); - } - - cvs_output ("retrieving revision ", 0); - cvs_output (xrev2, 0); - cvs_output ("\n", 1); - - tmp2 = cvs_temp_name(); - if (RCS_checkout (rcs, NULL, xrev2, rev2, options, tmp2, - (RCSCHECKOUTPROC)0, NULL)) - { - cvs_outerr ("rcsmerge: co failed\n", 0); - error_exit(); - } - - /* Merge changes. */ - cvs_output ("Merging differences between ", 0); - cvs_output (xrev1, 0); - cvs_output (" and ", 0); - cvs_output (xrev2, 0); - cvs_output (" into ", 0); - cvs_output (workfile, 0); - cvs_output ("\n", 1); - - /* Remember that the first word in the `call_diff_setup' string is used now - only for diagnostic messages -- CVS no longer forks to run diff3. */ - diffout = cvs_temp_name(); - call_diff_setup ("diff3", 0, NULL); - call_diff_add_arg ("-E"); - call_diff_add_arg ("-am"); - - call_diff_add_arg ("-L"); - call_diff_add_arg (workfile); - call_diff_add_arg ("-L"); - call_diff_add_arg (xrev1); - call_diff_add_arg ("-L"); - call_diff_add_arg (xrev2); - - call_diff_add_arg ("--"); - call_diff_add_arg (workfile); - call_diff_add_arg (tmp1); - call_diff_add_arg (tmp2); - - retval = call_diff3 (diffout); - - if (retval == 1) - cvs_outerr ("rcsmerge: warning: conflicts during merge\n", 0); - else if (retval == 2) - error_exit(); - - if (diffout) - copy_file (diffout, workfile); - - /* Clean up. */ - { - int save_noexec = noexec; - noexec = 0; - if (unlink_file (tmp1) < 0) - { - if (!existence_error (errno)) - error (0, errno, "cannot remove temp file %s", tmp1); - } - free (tmp1); - if (unlink_file (tmp2) < 0) - { - if (!existence_error (errno)) - error (0, errno, "cannot remove temp file %s", tmp2); - } - free (tmp2); - if (diffout) - { - if (unlink_file (diffout) < 0) - { - if (!existence_error (errno)) - error (0, errno, "cannot remove temp file %s", diffout); - } - free (diffout); - } - free (xrev1); - free (xrev2); - noexec = save_noexec; - } - - return retval; -} - -/* Diff revisions and/or files. OPTS controls the format of the diff - (it contains options such as "-w -c", &c), or "" for the default. - OPTIONS controls keyword expansion, as a string starting with "-k", - or "" to use the default. REV1 is the first revision to compare - against; it must be non-NULL. If REV2 is non-NULL, compare REV1 - and REV2; if REV2 is NULL compare REV1 with the file in the working - directory, whose name is WORKFILE. LABEL1 and LABEL2 are default - file labels, and (if non-NULL) should be added as -L options - to diff. Output goes to stdout. - - Return value is 0 for success, -1 for a failure which set errno, - or positive for a failure which printed a message on stderr. - - This used to exec rcsdiff, but now calls RCS_checkout and diff_exec. - - An issue is what timezone is used for the dates which appear in the - diff output. rcsdiff uses the -z flag, which is not presently - processed by CVS diff, but I'm not sure exactly how hard to worry - about this--any such features are undocumented in the context of - CVS, and I'm not sure how important to users. */ -int -RCS_exec_rcsdiff (rcsfile, diff_argc, diff_argv, options, rev1, rev1_cache, - rev2, label1, label2, workfile) - RCSNode *rcsfile; - int diff_argc; - char * const *diff_argv; - const char *options; - const char *rev1; - const char *rev1_cache; - const char *rev2; - const char *label1; - const char *label2; - const char *workfile; -{ - char *tmpfile1 = NULL; - char *tmpfile2 = NULL; - const char *use_file1, *use_file2; - int status, retval; - - - cvs_output ("\ -===================================================================\n\ -RCS file: ", 0); - cvs_output (rcsfile->path, 0); - cvs_output ("\n", 1); - - /* Historically, `cvs diff' has expanded the $Name keyword to the - empty string when checking out revisions. This is an accident, - but no one has considered the issue thoroughly enough to determine - what the best behavior is. Passing NULL for the `nametag' argument - preserves the existing behavior. */ - - cvs_output ("retrieving revision ", 0); - cvs_output (rev1, 0); - cvs_output ("\n", 1); - - if (rev1_cache != NULL) - use_file1 = rev1_cache; - else - { - tmpfile1 = cvs_temp_name(); - status = RCS_checkout (rcsfile, NULL, rev1, NULL, options, tmpfile1, - (RCSCHECKOUTPROC)0, NULL); - if (status > 0) - { - retval = status; - goto error_return; - } - else if (status < 0) - { - error( 0, errno, - "cannot check out revision %s of %s", rev1, rcsfile->path ); - retval = 1; - goto error_return; - } - use_file1 = tmpfile1; - } - - if (rev2 == NULL) - { - assert (workfile != NULL); - use_file2 = workfile; - } - else - { - tmpfile2 = cvs_temp_name (); - cvs_output ("retrieving revision ", 0); - cvs_output (rev2, 0); - cvs_output ("\n", 1); - status = RCS_checkout (rcsfile, NULL, rev2, NULL, options, - tmpfile2, (RCSCHECKOUTPROC)0, NULL); - if (status > 0) - { - retval = status; - goto error_return; - } - else if (status < 0) - { - error (0, errno, - "cannot check out revision %s of %s", rev2, rcsfile->path); - return 1; - } - use_file2 = tmpfile2; - } - - RCS_output_diff_options (diff_argc, diff_argv, rev1, rev2, workfile); - status = diff_exec (use_file1, use_file2, label1, label2, - diff_argc, diff_argv, RUN_TTY); - if (status >= 0) - { - retval = status; - goto error_return; - } - else if (status < 0) - { - error (0, errno, - "cannot diff %s and %s", use_file1, use_file2); - retval = 1; - goto error_return; - } - - error_return: - { - /* Call CVS_UNLINK() below rather than unlink_file to avoid the check - * for noexec. - */ - if( tmpfile1 != NULL ) - { - if( CVS_UNLINK( tmpfile1 ) < 0 ) - { - if( !existence_error( errno ) ) - error( 0, errno, "cannot remove temp file %s", tmpfile1 ); - } - free( tmpfile1 ); - } - if( tmpfile2 != NULL ) - { - if( CVS_UNLINK( tmpfile2 ) < 0 ) - { - if( !existence_error( errno ) ) - error( 0, errno, "cannot remove temp file %s", tmpfile2 ); - } - free (tmpfile2); - } - } - - return retval; -} - - - -/* Show differences between two files. This is the start of a diff library. - - Some issues: - - * Should option parsing be part of the library or the caller? The - former allows the library to add options without changing the callers, - but it causes various problems. One is that something like --brief really - wants special handling in CVS, and probably the caller should retain - some flexibility in this area. Another is online help (the library could - have some feature for providing help, but how does that interact with - the help provided by the caller directly?). Another is that as things - stand currently, there is no separate namespace for diff options versus - "cvs diff" options like -l (that is, if the library adds an option which - conflicts with a CVS option, it is trouble). - - * This isn't required for a first-cut diff library, but if there - would be a way for the caller to specify the timestamps that appear - in the diffs (rather than the library getting them from the files), - that would clean up the kludgy utime() calls in patch.c. - - Show differences between FILE1 and FILE2. Either one can be - DEVNULL to indicate a nonexistent file (same as an empty file - currently, I suspect, but that may be an issue in and of itself). - OPTIONS is a list of diff options, or "" if none. At a minimum, - CVS expects that -c (update.c, patch.c) and -n (update.c) will be - supported. Other options, like -u, --speed-large-files, &c, will - be specified if the user specified them. - - OUT is a filename to send the diffs to, or RUN_TTY to send them to - stdout. Error messages go to stderr. Return value is 0 for - success, -1 for a failure which set errno, 1 for success (and some - differences were found), or >1 for a failure which printed a - message on stderr. */ - -int -diff_exec (file1, file2, label1, label2, dargc, dargv, out) - const char *file1; - const char *file2; - const char *label1; - const char *label2; - int dargc; - char * const *dargv; - const char *out; -{ -#ifdef PRESERVE_PERMISSIONS_SUPPORT - /* If either file1 or file2 are special files, pretend they are - /dev/null. Reason: suppose a file that represents a block - special device in one revision becomes a regular file. CVS - must find the `difference' between these files, but a special - file contains no data useful for calculating this metric. The - safe thing to do is to treat the special file as an empty file, - thus recording the regular file's full contents. Doing so will - create extremely large deltas at the point of transition - between device files and regular files, but this is probably - very rare anyway. - - There may be ways around this, but I think they are fraught - with danger. -twp */ - - if (preserve_perms && - strcmp (file1, DEVNULL) != 0 && - strcmp (file2, DEVNULL) != 0) - { - struct stat sb1, sb2; - - if (CVS_LSTAT (file1, &sb1) < 0) - error (1, errno, "cannot get file information for %s", file1); - if (CVS_LSTAT (file2, &sb2) < 0) - error (1, errno, "cannot get file information for %s", file2); - - if (!S_ISREG (sb1.st_mode) && !S_ISDIR (sb1.st_mode)) - file1 = DEVNULL; - if (!S_ISREG (sb2.st_mode) && !S_ISDIR (sb2.st_mode)) - file2 = DEVNULL; - } -#endif - - /* The first arg to call_diff_setup is used only for error reporting. */ - call_diff_setup ("diff", dargc, dargv); - if (label1) - call_diff_add_arg (label1); - if (label2) - call_diff_add_arg (label2); - call_diff_add_arg ("--"); - call_diff_add_arg (file1); - call_diff_add_arg (file2); - - return call_diff (out); -} - -/* Print the options passed to DIFF, in the format used by rcsdiff. - The rcsdiff code that produces this output is extremely hairy, and - it is not clear how rcsdiff decides which options to print and - which not to print. The code below reproduces every rcsdiff run - that I have seen. */ - -static void -RCS_output_diff_options (diff_argc, diff_argv, rev1, rev2, workfile) - int diff_argc; - char * const *diff_argv; - const char *rev1; - const char *rev2; - const char *workfile; -{ - int i; - - cvs_output ("diff", 0); - for (i = 0; i < diff_argc; i++) - { - cvs_output (" ", 1); - cvs_output (diff_argv[i], 0); - } - cvs_output (" -r", 3); - cvs_output (rev1, 0); - - if (rev2) - { - cvs_output (" -r", 3); - cvs_output (rev2, 0); - } - else - { - assert (workfile != NULL); - cvs_output (" ", 1); - cvs_output (workfile, 0); - } - cvs_output ("\n", 1); -} diff --git a/contrib/cvs/src/recurse.c b/contrib/cvs/src/recurse.c deleted file mode 100644 index fb865a9..0000000 --- a/contrib/cvs/src/recurse.c +++ /dev/null @@ -1,1299 +0,0 @@ -/* - * Copyright (C) 1986-2008 The Free Software Foundation, Inc. - * - * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot , - * and others. - * - * Portions Copyright (C) 1992, Brian Berliner and Jeff Polk - * Portions Copyright (C) 1989-1992, Brian Berliner - * - * You may distribute under the terms of the GNU General Public License as - * specified in the README file that comes with the CVS source distribution. - * - * General recursion handler - * - */ - -#include "cvs.h" -#include "savecwd.h" -#include "fileattr.h" -#include "edit.h" -#include - -static int do_dir_proc PROTO((Node * p, void *closure)); -static int do_file_proc PROTO((Node * p, void *closure)); -static void addlist PROTO((List ** listp, char *key)); -static int unroll_files_proc PROTO((Node *p, void *closure)); -static void addfile PROTO((List **listp, char *dir, char *file)); - -static char *update_dir; -static char *repository = NULL; -static List *filelist = NULL; /* holds list of files on which to operate */ -static List *dirlist = NULL; /* holds list of directories on which to operate */ - -struct recursion_frame { - FILEPROC fileproc; - FILESDONEPROC filesdoneproc; - DIRENTPROC direntproc; - DIRLEAVEPROC dirleaveproc; - void *callerdat; - Dtype flags; - int which; - int aflag; - int locktype; - int dosrcs; - char *repository; /* Keep track of repository for rtag */ -}; - -static int do_recursion PROTO ((struct recursion_frame *frame)); - -/* I am half tempted to shove a struct file_info * into the struct - recursion_frame (but then we would need to modify or create a - recursion_frame for each file), or shove a struct recursion_frame * - into the struct file_info (more tempting, although it isn't completely - clear that the struct file_info should contain info about recursion - processor internals). So instead use this struct. */ - -struct frame_and_file { - struct recursion_frame *frame; - struct file_info *finfo; -}; - -/* Similarly, we need to pass the entries list to do_dir_proc. */ - -struct frame_and_entries { - struct recursion_frame *frame; - List *entries; -}; - - -/* Start a recursive command. - - Command line arguments (ARGC, ARGV) dictate the directories and - files on which we operate. In the special case of no arguments, we - default to ".". */ -int -start_recursion (fileproc, filesdoneproc, direntproc, dirleaveproc, callerdat, - argc, argv, local, which, aflag, locktype, - update_preload, dosrcs, repository_in) - FILEPROC fileproc; - FILESDONEPROC filesdoneproc; - DIRENTPROC direntproc; - DIRLEAVEPROC dirleaveproc; - void *callerdat; - - int argc; - char **argv; - int local; - - /* This specifies the kind of recursion. There are several cases: - - 1. W_LOCAL is not set but W_REPOS or W_ATTIC is. The current - directory when we are called must be the repository and - recursion proceeds according to what exists in the repository. - - 2a. W_LOCAL is set but W_REPOS and W_ATTIC are not. The - current directory when we are called must be the working - directory. Recursion proceeds according to what exists in the - working directory, never (I think) consulting any part of the - repository which does not correspond to the working directory - ("correspond" == Name_Repository). - - 2b. W_LOCAL is set and so is W_REPOS or W_ATTIC. This is the - weird one. The current directory when we are called must be - the working directory. We recurse through working directories, - but we recurse into a directory if it is exists in the working - directory *or* it exists in the repository. If a directory - does not exist in the working directory, the direntproc must - either tell us to skip it (R_SKIP_ALL), or must create it (I - think those are the only two cases). */ - int which; - - int aflag; - int locktype; - char *update_preload; - int dosrcs; - /* Keep track of the repository string. This is only for the remote mode, - * specifically, r* commands (rtag, rdiff, co, ...) where xgetwd() was - * used to locate the repository. Things would break when xgetwd() was - * used with a symlinked repository because xgetwd() would return the true - * path and in some cases this would cause the path to be printed as other - * than the user specified in error messages and in other cases some of - * CVS's security assertions would fail. - */ - char *repository_in; -{ - int i, err = 0; -#ifdef CLIENT_SUPPORT - List *args_to_send_when_finished = NULL; -#endif - List *files_by_dir = NULL; - struct recursion_frame frame; - - frame.fileproc = fileproc; - frame.filesdoneproc = filesdoneproc; - frame.direntproc = direntproc; - frame.dirleaveproc = dirleaveproc; - frame.callerdat = callerdat; - frame.flags = local ? R_SKIP_DIRS : R_PROCESS; - frame.which = which; - frame.aflag = aflag; - frame.locktype = locktype; - frame.dosrcs = dosrcs; - - /* If our repository_in has a trailing "/.", remove it before storing it - * for do_recursion(). - * - * FIXME: This is somewhat of a hack in the sense that many of our callers - * painstakingly compute and add the trailing '.' we now remove. - */ - while (repository_in && strlen (repository_in) >= 2 - && repository_in[strlen (repository_in) - 2] == '/' - && repository_in[strlen (repository_in) - 1] == '.') - { - /* Beware the case where the string is exactly "/." or "//.". - * Paths with a leading "//" are special on some early UNIXes. - */ - if (strlen (repository_in) == 2 || strlen (repository_in) == 3) - repository_in[strlen (repository_in) - 1] = '\0'; - else - repository_in[strlen (repository_in) - 2] = '\0'; - } - frame.repository = repository_in; - - expand_wild (argc, argv, &argc, &argv); - - if (update_preload == NULL) - update_dir = xstrdup (""); - else - update_dir = xstrdup (update_preload); - - /* clean up from any previous calls to start_recursion */ - if (repository) - { - free (repository); - repository = (char *) NULL; - } - if (filelist) - dellist (&filelist); /* FIXME-krp: no longer correct. */ - if (dirlist) - dellist (&dirlist); - -#ifdef SERVER_SUPPORT - if (server_active) - { - for (i = 0; i < argc; ++i) - server_pathname_check (argv[i]); - } -#endif - - if (argc == 0) - { - int just_subdirs = (which & W_LOCAL) && !isdir (CVSADM); - -#ifdef CLIENT_SUPPORT - if (!just_subdirs - && CVSroot_cmdline == NULL - && current_parsed_root->isremote) - { - cvsroot_t *root = Name_Root (NULL, update_dir); - if (root) - { - if (strcmp (root->original, current_parsed_root->original)) - /* We're skipping this directory because it is for - * a different root. Therefore, we just want to - * do the subdirectories only. Processing files would - * cause a working directory from one repository to be - * processed against a different repository, which could - * cause all kinds of spurious conflicts and such. - * - * Question: what about the case of "cvs update foo" - * where we process foo/bar and not foo itself? That - * seems to be handled somewhere (else) but why should - * it be a separate case? Needs investigation... */ - just_subdirs = 1; - free_cvsroot_t (root); - } - } -#endif - - /* - * There were no arguments, so we'll probably just recurse. The - * exception to the rule is when we are called from a directory - * without any CVS administration files. That has always meant to - * process each of the sub-directories, so we pretend like we were - * called with the list of sub-dirs of the current dir as args - */ - if (just_subdirs) - { - dirlist = Find_Directories ((char *) NULL, W_LOCAL, (List *) NULL); - /* If there are no sub-directories, there is a certain logic in - favor of doing nothing, but in fact probably the user is just - confused about what directory they are in, or whether they - cvs add'd a new directory. In the case of at least one - sub-directory, at least when we recurse into them we - notice (hopefully) whether they are under CVS control. */ - if (list_isempty (dirlist)) - { - if (update_dir[0] == '\0') - error (0, 0, "in directory .:"); - else - error (0, 0, "in directory %s:", update_dir); - error (1, 0, - "there is no version here; run '%s checkout' first", - program_name); - } -#ifdef CLIENT_SUPPORT - else if (current_parsed_root->isremote && server_started) - { - /* In the the case "cvs update foo bar baz", a call to - send_file_names in update.c will have sent the - appropriate "Argument" commands to the server. In - this case, that won't have happened, so we need to - do it here. While this example uses "update", this - generalizes to other commands. */ - - /* This is the same call to Find_Directories as above. - FIXME: perhaps it would be better to write a - function that duplicates a list. */ - args_to_send_when_finished = Find_Directories ((char *) NULL, - W_LOCAL, - (List *) NULL); - } -#endif - } - else - addlist (&dirlist, "."); - - goto do_the_work; - } - - - /* - * There were arguments, so we have to handle them by hand. To do - * that, we set up the filelist and dirlist with the arguments and - * call do_recursion. do_recursion recognizes the fact that the - * lists are non-null when it starts and doesn't update them. - * - * explicitly named directories are stored in dirlist. - * explicitly named files are stored in filelist. - * other possibility is named entities whicha are not currently in - * the working directory. - */ - - for (i = 0; i < argc; i++) - { - /* if this argument is a directory, then add it to the list of - directories. */ - - if (!wrap_name_has (argv[i], WRAP_TOCVS) && isdir (argv[i])) - { - strip_trailing_slashes (argv[i]); - addlist (&dirlist, argv[i]); - } - else - { - /* otherwise, split argument into directory and component names. */ - char *dir; - char *comp; - char *file_to_try; - - /* Now break out argv[i] into directory part (DIR) and file part (COMP). - DIR and COMP will each point to a newly malloc'd string. */ - dir = xstrdup (argv[i]); - /* Its okay to discard the const below - we know we just allocated - * dir ourselves. - */ - comp = (char *)last_component (dir); - if (comp == dir) - { - /* no dir component. What we have is an implied "./" */ - dir = xstrdup("."); - } - else - { - char *p = comp; - - p[-1] = '\0'; - comp = xstrdup (p); - } - - /* if this argument exists as a file in the current - working directory tree, then add it to the files list. */ - - if (!(which & W_LOCAL)) - { - /* If doing rtag, we've done a chdir to the repository. */ - file_to_try = xmalloc (strlen (argv[i]) + sizeof (RCSEXT) + 5); - sprintf (file_to_try, "%s%s", argv[i], RCSEXT); - } - else - file_to_try = xstrdup (argv[i]); - - if (isfile (file_to_try)) - addfile (&files_by_dir, dir, comp); - else if (isdir (dir)) - { - if ((which & W_LOCAL) && isdir (CVSADM) && - !current_parsed_root->isremote) - { - /* otherwise, look for it in the repository. */ - char *tmp_update_dir; - char *repos; - char *reposfile; - - tmp_update_dir = xmalloc (strlen (update_dir) - + strlen (dir) - + 5); - strcpy (tmp_update_dir, update_dir); - - if (*tmp_update_dir != '\0') - (void) strcat (tmp_update_dir, "/"); - - (void) strcat (tmp_update_dir, dir); - - /* look for it in the repository. */ - repos = Name_Repository (dir, tmp_update_dir); - reposfile = xmalloc (strlen (repos) - + strlen (comp) - + 5); - (void) sprintf (reposfile, "%s/%s", repos, comp); - free (repos); - - if (!wrap_name_has (comp, WRAP_TOCVS) && isdir (reposfile)) - addlist (&dirlist, argv[i]); - else - addfile (&files_by_dir, dir, comp); - - free (tmp_update_dir); - free (reposfile); - } - else - addfile (&files_by_dir, dir, comp); - } - else - error (1, 0, "no such directory `%s'", dir); - - free (file_to_try); - free (dir); - free (comp); - } - } - - /* At this point we have looped over all named arguments and built - a coupla lists. Now we unroll the lists, setting up and - calling do_recursion. */ - - err += walklist (files_by_dir, unroll_files_proc, (void *) &frame); - dellist(&files_by_dir); - - /* then do_recursion on the dirlist. */ - if (dirlist != NULL) - { - do_the_work: - err += do_recursion (&frame); - } - - /* Free the data which expand_wild allocated. */ - free_names (&argc, argv); - - free (update_dir); - update_dir = NULL; - -#ifdef CLIENT_SUPPORT - if (args_to_send_when_finished != NULL) - { - /* FIXME (njc): in the multiroot case, we don't want to send - argument commands for those top-level directories which do - not contain any subdirectories which have files checked out - from current_parsed_root->original. If we do, and two repositories - have a module with the same name, nasty things could happen. - - This is hard. Perhaps we should send the Argument commands - later in this procedure, after we've had a chance to notice - which directores we're using (after do_recursion has been - called once). This means a _lot_ of rewriting, however. - - What we need to do for that to happen is descend the tree - and construct a list of directories which are checked out - from current_cvsroot. Now, we eliminate from the list all - of those directories which are immediate subdirectories of - another directory in the list. To say that the opposite - way, we keep the directories which are not immediate - subdirectories of any other in the list. Here's a picture: - - a - / \ - B C - / \ - D e - / \ - F G - / \ - H I - - The node in capitals are those directories which are - checked out from current_cvsroot. We want the list to - contain B, C, F, and G. D, H, and I are not included, - because their parents are also checked out from - current_cvsroot. - - The algorithm should be: - - 1) construct a tree of all directory names where each - element contains a directory name and a flag which notes if - that directory is checked out from current_cvsroot - - a0 - / \ - B1 C1 - / \ - D1 e0 - / \ - F1 G1 - / \ - H1 I1 - - 2) Recursively descend the tree. For each node, recurse - before processing the node. If the flag is zero, do - nothing. If the flag is 1, check the node's parent. If - the parent's flag is one, change the current entry's flag - to zero. - - a0 - / \ - B1 C1 - / \ - D0 e0 - / \ - F1 G1 - / \ - H0 I0 - - 3) Walk the tree and spit out "Argument" commands to tell - the server which directories to munge. - - Yuck. It's not clear this is worth spending time on, since - we might want to disable cvs commands entirely from - directories that do not have CVSADM files... - - Anyways, the solution as it stands has modified server.c - (dirswitch) to create admin files [via server.c - (create_adm_p)] in all path elements for a client's - "Directory xxx" command, which forces the server to descend - and serve the files there. client.c (send_file_names) has - also been modified to send only those arguments which are - appropriate to current_parsed_root->original. - - */ - - /* Construct a fake argc/argv pair. */ - - int our_argc = 0, i; - char **our_argv = NULL; - - if (! list_isempty (args_to_send_when_finished)) - { - Node *head, *p; - - head = args_to_send_when_finished->list; - - /* count the number of nodes */ - i = 0; - for (p = head->next; p != head; p = p->next) - i++; - our_argc = i; - - /* create the argument vector */ - our_argv = (char **) xmalloc (sizeof (char *) * our_argc); - - /* populate it */ - i = 0; - for (p = head->next; p != head; p = p->next) - our_argv[i++] = xstrdup (p->key); - } - - /* We don't want to expand widcards, since we've just created - a list of directories directly from the filesystem. */ - send_file_names (our_argc, our_argv, 0); - - /* Free our argc/argv. */ - if (our_argv != NULL) - { - for (i = 0; i < our_argc; i++) - free (our_argv[i]); - free (our_argv); - } - - dellist (&args_to_send_when_finished); - } -#endif - - return (err); -} - -/* - * Implement the recursive policies on the local directory. This may be - * called directly, or may be called by start_recursion - */ -static int -do_recursion (frame) - struct recursion_frame *frame; -{ - int err = 0; - int dodoneproc = 1; - char *srepository = NULL; - List *entries = NULL; - int locktype; - int process_this_directory = 1; - - /* do nothing if told */ - if (frame->flags == R_SKIP_ALL) - return (0); - - locktype = noexec ? CVS_LOCK_NONE : frame->locktype; - - /* The fact that locks are not active here is what makes us fail to have - the - - If someone commits some changes in one cvs command, - then an update by someone else will either get all the - changes, or none of them. - - property (see node Concurrency in cvs.texinfo). - - The most straightforward fix would just to readlock the whole - tree before starting an update, but that means that if a commit - gets blocked on a big update, it might need to wait a *long* - time. - - A more adequate fix would be a two-pass design for update, - checkout, etc. The first pass would go through the repository, - with the whole tree readlocked, noting what versions of each - file we want to get. The second pass would release all locks - (except perhaps short-term locks on one file at a - time--although I think RCS already deals with this) and - actually get the files, specifying the particular versions it wants. - - This could be sped up by separating out the data needed for the - first pass into a separate file(s)--for example a file - attribute for each file whose value contains the head revision - for each branch. The structure should be designed so that - commit can relatively quickly update the information for a - single file or a handful of files (file attributes, as - implemented in Jan 96, are probably acceptable; improvements - would be possible such as branch attributes which are in - separate files for each branch). */ - -#if defined(SERVER_SUPPORT) && defined(SERVER_FLOWCONTROL) - /* - * Now would be a good time to check to see if we need to stop - * generating data, to give the buffers a chance to drain to the - * remote client. We should not have locks active at this point, - * but if there are writelocks around, we cannot pause here. */ - if (server_active && locktype != CVS_LOCK_WRITE) - server_pause_check(); -#endif - - /* Check the value in CVSADM_ROOT and see if it's in the list. If - not, add it to our lists of CVS/Root directories and do not - process the files in this directory. Otherwise, continue as - usual. THIS_ROOT might be NULL if we're doing an initial - checkout -- check before using it. The default should be that - we process a directory's contents and only skip those contents - if a CVS/Root file exists. - - If we're running the server, we want to process all - directories, since we're guaranteed to have only one CVSROOT -- - our own. */ - - /* If -d was specified, it should override CVS/Root. - - In the single-repository case, it is long-standing CVS behavior - and makes sense - the user might want another access method, - another server (which mounts the same repository), &c. - - In the multiple-repository case, -d overrides all CVS/Root - files. That is the only plausible generalization I can - think of. */ - if (CVSroot_cmdline == NULL && !server_active) - { - cvsroot_t *this_root = Name_Root ((char *) NULL, update_dir); - if (this_root != NULL) - { - if (findnode (root_directories, this_root->original)) - { - process_this_directory = !strcmp (current_parsed_root->original, - this_root->original); - free_cvsroot_t (this_root); - } - else - { - /* Add it to our list. */ - - Node *n = getnode (); - n->type = NT_UNKNOWN; - n->key = xstrdup (this_root->original); - n->data = this_root; - - if (addnode (root_directories, n)) - error (1, 0, "cannot add new CVSROOT %s", - this_root->original); - - process_this_directory = 0; - } - } - } - - /* - * Fill in repository with the current repository - */ - if (frame->which & W_LOCAL) - { - if (isdir (CVSADM)) - { - repository = Name_Repository ((char *) NULL, update_dir); - srepository = repository; /* remember what to free */ - } - else - repository = NULL; - } - else - { - repository = frame->repository; - assert (repository != NULL); - } - - fileattr_startdir (repository); - - /* - * The filesdoneproc needs to be called for each directory where files - * processed, or each directory that is processed by a call where no - * directories were passed in. In fact, the only time we don't want to - * call back the filesdoneproc is when we are processing directories that - * were passed in on the command line (or in the special case of `.' when - * we were called with no args - */ - if (dirlist != NULL && filelist == NULL) - dodoneproc = 0; - - /* - * If filelist or dirlist is already set, we don't look again. Otherwise, - * find the files and directories - */ - if (filelist == NULL && dirlist == NULL) - { - /* both lists were NULL, so start from scratch */ - if (frame->fileproc != NULL && frame->flags != R_SKIP_FILES) - { - int lwhich = frame->which; - - /* be sure to look in the attic if we have sticky tags/date */ - if ((lwhich & W_ATTIC) == 0) - if (isreadable (CVSADM_TAG)) - lwhich |= W_ATTIC; - - /* In the !(which & W_LOCAL) case, we filled in repository - earlier in the function. In the (which & W_LOCAL) case, - the Find_Names function is going to look through the - Entries file. If we do not have a repository, that - does not make sense, so we insist upon having a - repository at this point. Name_Repository will give a - reasonable error message. */ - if (repository == NULL) - { - Name_Repository ((char *) NULL, update_dir); - assert (!"Not reached. Please report this problem to <" - PACKAGE_BUGREPORT ">"); - } - - /* find the files and fill in entries if appropriate */ - if (process_this_directory) - { - filelist = Find_Names (repository, lwhich, frame->aflag, - &entries); - if (filelist == NULL) - { - error (0, 0, "skipping directory %s", update_dir); - /* Note that Find_Directories and the filesdoneproc - in particular would do bad things ("? foo.c" in - the case of some filesdoneproc's). */ - goto skip_directory; - } - } - } - - /* find sub-directories if we will recurse */ - if (frame->flags != R_SKIP_DIRS) - dirlist = Find_Directories ( - process_this_directory ? repository : NULL, - frame->which, entries); - } - else - { - /* something was passed on the command line */ - if (filelist != NULL && frame->fileproc != NULL) - { - /* we will process files, so pre-parse entries */ - if (frame->which & W_LOCAL) - entries = Entries_Open (frame->aflag, NULL); - } - } - - /* process the files (if any) */ - if (process_this_directory && filelist != NULL && frame->fileproc) - { - struct file_info finfo_struct; - struct frame_and_file frfile; - - /* read lock it if necessary */ - if (repository) - { - if (locktype == CVS_LOCK_READ) - { - if (Reader_Lock (repository) != 0) - error (1, 0, "read lock failed - giving up"); - } - else if (locktype == CVS_LOCK_WRITE) - lock_dir_for_write (repository); - } - -#ifdef CLIENT_SUPPORT - /* For the server, we handle notifications in a completely different - place (server_notify). For local, we can't do them here--we don't - have writelocks in place, and there is no way to get writelocks - here. */ - if (current_parsed_root->isremote) - cvs_notify_check (repository, update_dir); -#endif /* CLIENT_SUPPORT */ - - finfo_struct.repository = repository; - finfo_struct.update_dir = update_dir; - finfo_struct.entries = entries; - /* do_file_proc will fill in finfo_struct.file. */ - - frfile.finfo = &finfo_struct; - frfile.frame = frame; - - /* process the files */ - err += walklist (filelist, do_file_proc, &frfile); - - /* unlock it */ - if (/* We only lock the repository above when repository is set */ - repository - /* and when asked for a read or write lock. */ - && locktype != CVS_LOCK_NONE) - Lock_Cleanup (); - - /* clean up */ - dellist (&filelist); - } - - /* call-back files done proc (if any) */ - if (process_this_directory && dodoneproc && frame->filesdoneproc != NULL) - err = frame->filesdoneproc (frame->callerdat, err, repository, - update_dir[0] ? update_dir : ".", - entries); - - skip_directory: - fileattr_write (); - fileattr_free (); - - /* process the directories (if necessary) */ - if (dirlist != NULL) - { - struct frame_and_entries frent; - - frent.frame = frame; - frent.entries = entries; - err += walklist (dirlist, do_dir_proc, (void *) &frent); - } -#if 0 - else if (frame->dirleaveproc != NULL) - err += frame->dirleaveproc (frame->callerdat, ".", err, "."); -#endif - dellist (&dirlist); - - if (entries) - { - Entries_Close (entries); - entries = NULL; - } - - /* free the saved copy of the pointer if necessary */ - if (srepository) - { - free (srepository); - } - repository = (char *) NULL; - - return err; -} - - - -/* - * Process each of the files in the list with the callback proc - */ -static int -do_file_proc (p, closure) - Node *p; - void *closure; -{ - struct frame_and_file *frfile = (struct frame_and_file *)closure; - struct file_info *finfo = frfile->finfo; - int ret; - char *tmp; - - finfo->file = p->key; - tmp = xmalloc (strlen (finfo->file) - + strlen (finfo->update_dir) - + 2); - tmp[0] = '\0'; - if (finfo->update_dir[0] != '\0') - { - strcat (tmp, finfo->update_dir); - strcat (tmp, "/"); - } - strcat (tmp, finfo->file); - - if (frfile->frame->dosrcs && repository) - { - finfo->rcs = RCS_parse (finfo->file, repository); - - /* OK, without W_LOCAL the error handling becomes relatively - simple. The file names came from readdir() on the - repository and so we know any ENOENT is an error - (e.g. symlink pointing to nothing). Now, the logic could - be simpler - since we got the name from readdir, we could - just be calling RCS_parsercsfile. */ - if (finfo->rcs == NULL - && !(frfile->frame->which & W_LOCAL)) - { - error (0, 0, "could not read RCS file for %s", tmp); - free (tmp); - cvs_flushout (); - return 0; - } - } - else - finfo->rcs = (RCSNode *) NULL; - finfo->fullname = tmp; - ret = frfile->frame->fileproc (frfile->frame->callerdat, finfo); - - freercsnode(&finfo->rcs); - free (tmp); - - /* Allow the user to monitor progress with tail -f. Doing this once - per file should be no big deal, but we don't want the performance - hit of flushing on every line like previous versions of CVS. */ - cvs_flushout (); - - return ret; -} - - - -/* - * Process each of the directories in the list (recursing as we go) - */ -static int -do_dir_proc (p, closure) - Node *p; - void *closure; -{ - struct frame_and_entries *frent = (struct frame_and_entries *) closure; - struct recursion_frame *frame = frent->frame; - struct recursion_frame xframe; - char *dir = p->key; - char *newrepos; - List *sdirlist; - char *srepository; - Dtype dir_return = R_PROCESS; - int stripped_dot = 0; - int err = 0; - struct saved_cwd cwd; - char *saved_update_dir; - int process_this_directory = 1; - - if (fncmp (dir, CVSADM) == 0) - { - /* This seems to most often happen when users (beginning users, - generally), try "cvs ci *" or something similar. On that - theory, it is possible that we should just silently skip the - CVSADM directories, but on the other hand, using a wildcard - like this isn't necessarily a practice to encourage (it operates - only on files which exist in the working directory, unlike - regular CVS recursion). */ - - /* FIXME-reentrancy: printed_cvs_msg should be in a "command - struct" or some such, so that it gets cleared for each new - command (this is possible using the remote protocol and a - custom-written client). The struct recursion_frame is not - far back enough though, some commands (commit at least) - will call start_recursion several times. An alternate solution - would be to take this whole check and move it to a new function - validate_arguments or some such that all the commands call - and which snips the offending directory from the argc,argv - vector. */ - static int printed_cvs_msg = 0; - if (!printed_cvs_msg) - { - error (0, 0, "warning: directory %s specified in argument", - dir); - error (0, 0, "\ -but CVS uses %s for its own purposes; skipping %s directory", - CVSADM, dir); - printed_cvs_msg = 1; - } - return 0; - } - - saved_update_dir = update_dir; - update_dir = xmalloc (strlen (saved_update_dir) - + strlen (dir) - + 5); - strcpy (update_dir, saved_update_dir); - - /* set up update_dir - skip dots if not at start */ - if (strcmp (dir, ".") != 0) - { - if (update_dir[0] != '\0') - { - (void) strcat (update_dir, "/"); - (void) strcat (update_dir, dir); - } - else - (void) strcpy (update_dir, dir); - - /* - * Here we need a plausible repository name for the sub-directory. We - * create one by concatenating the new directory name onto the - * previous repository name. The only case where the name should be - * used is in the case where we are creating a new sub-directory for - * update -d and in that case the generated name will be correct. - */ - if (repository == NULL) - newrepos = xstrdup (""); - else - { - newrepos = xmalloc (strlen (repository) + strlen (dir) + 5); - sprintf (newrepos, "%s/%s", repository, dir); - } - } - else - { - if (update_dir[0] == '\0') - (void) strcpy (update_dir, dir); - - if (repository == NULL) - newrepos = xstrdup (""); - else - newrepos = xstrdup (repository); - } - - /* Check to see that the CVSADM directory, if it exists, seems to be - well-formed. It can be missing files if the user hit ^C in the - middle of a previous run. We want to (a) make this a nonfatal - error, and (b) make sure we print which directory has the - problem. - - Do this before the direntproc, so that (1) the direntproc - doesn't have to guess/deduce whether we will skip the directory - (e.g. send_dirent_proc and whether to send the directory), and - (2) so that the warm fuzzy doesn't get printed if we skip the - directory. */ - if (frame->which & W_LOCAL) - { - char *cvsadmdir; - - cvsadmdir = xmalloc (strlen (dir) - + sizeof (CVSADM_REP) - + sizeof (CVSADM_ENT) - + 80); - - strcpy (cvsadmdir, dir); - strcat (cvsadmdir, "/"); - strcat (cvsadmdir, CVSADM); - if (isdir (cvsadmdir)) - { - strcpy (cvsadmdir, dir); - strcat (cvsadmdir, "/"); - strcat (cvsadmdir, CVSADM_REP); - if (!isfile (cvsadmdir)) - { - /* Some commands like update may have printed "? foo" but - if we were planning to recurse, and don't on account of - CVS/Repository, we want to say why. */ - error (0, 0, "ignoring %s (%s missing)", update_dir, - CVSADM_REP); - dir_return = R_SKIP_ALL; - } - - /* Likewise for CVS/Entries. */ - if (dir_return != R_SKIP_ALL) - { - strcpy (cvsadmdir, dir); - strcat (cvsadmdir, "/"); - strcat (cvsadmdir, CVSADM_ENT); - if (!isfile (cvsadmdir)) - { - /* Some commands like update may have printed "? foo" but - if we were planning to recurse, and don't on account of - CVS/Repository, we want to say why. */ - error (0, 0, "ignoring %s (%s missing)", update_dir, - CVSADM_ENT); - dir_return = R_SKIP_ALL; - } - } - } - free (cvsadmdir); - } - - /* Only process this directory if the root matches. This nearly - duplicates code in do_recursion. */ - - /* If -d was specified, it should override CVS/Root. - - In the single-repository case, it is long-standing CVS behavior - and makes sense - the user might want another access method, - another server (which mounts the same repository), &c. - - In the multiple-repository case, -d overrides all CVS/Root - files. That is the only plausible generalization I can - think of. */ - if (CVSroot_cmdline == NULL && !server_active) - { - cvsroot_t *this_root = Name_Root (dir, update_dir); - if (this_root != NULL) - { - if (findnode (root_directories, this_root->original)) - { - process_this_directory = !strcmp (current_parsed_root->original, - this_root->original); - free_cvsroot_t (this_root); - } - else - { - /* Add it to our list. */ - - Node *n = getnode (); - n->type = NT_UNKNOWN; - n->key = xstrdup (this_root->original); - n->data = this_root; - - if (addnode (root_directories, n)) - error (1, 0, "cannot add new CVSROOT %s", - this_root->original); - - process_this_directory = 0; - } - } - } - - /* call-back dir entry proc (if any) */ - if (dir_return == R_SKIP_ALL) - ; - else if (frame->direntproc != NULL) - { - /* If we're doing the actual processing, call direntproc. - Otherwise, assume that we need to process this directory - and recurse. FIXME. */ - - if (process_this_directory) - dir_return = frame->direntproc (frame->callerdat, dir, newrepos, - update_dir, frent->entries); - else - dir_return = R_PROCESS; - } - else - { - /* Generic behavior. I don't see a reason to make the caller specify - a direntproc just to get this. */ - if ((frame->which & W_LOCAL) && !isdir (dir)) - dir_return = R_SKIP_ALL; - } - - free (newrepos); - - /* only process the dir if the return code was 0 */ - if (dir_return != R_SKIP_ALL) - { - /* save our current directory and static vars */ - if (save_cwd (&cwd)) - error_exit (); - sdirlist = dirlist; - srepository = repository; - dirlist = NULL; - - /* cd to the sub-directory */ - if (CVS_CHDIR (dir) < 0) - error (1, errno, "could not chdir to %s", dir); - - /* honor the global SKIP_DIRS (a.k.a. local) */ - if (frame->flags == R_SKIP_DIRS) - dir_return = R_SKIP_DIRS; - - /* remember if the `.' will be stripped for subsequent dirs */ - if (strcmp (update_dir, ".") == 0) - { - update_dir[0] = '\0'; - stripped_dot = 1; - } - - /* make the recursive call */ - xframe = *frame; - xframe.flags = dir_return; - /* Keep track of repository, really just for r* commands (rtag, rdiff, - * co, ...) to tag_check_valid, since all the other commands use - * CVS/Repository to figure it out per directory. - */ - if (repository) - { - if (strcmp (dir, ".") == 0) - xframe.repository = xstrdup (repository); - else - { - xframe.repository = xmalloc (strlen (repository) - + strlen (dir) - + 2); - sprintf (xframe.repository, "%s/%s", repository, dir); - } - } - else - xframe.repository = NULL; - err += do_recursion (&xframe); - if (xframe.repository) - { - free (xframe.repository); - xframe.repository = NULL; - } - - /* put the `.' back if necessary */ - if (stripped_dot) - (void) strcpy (update_dir, "."); - - /* call-back dir leave proc (if any) */ - if (process_this_directory && frame->dirleaveproc != NULL) - err = frame->dirleaveproc (frame->callerdat, dir, err, update_dir, - frent->entries); - - /* get back to where we started and restore state vars */ - if (restore_cwd (&cwd, NULL)) - error_exit (); - free_cwd (&cwd); - dirlist = sdirlist; - repository = srepository; - } - - free (update_dir); - update_dir = saved_update_dir; - - return err; -} - -/* - * Add a node to a list allocating the list if necessary. - */ -static void -addlist (listp, key) - List **listp; - char *key; -{ - Node *p; - - if (*listp == NULL) - *listp = getlist (); - p = getnode (); - p->type = FILES; - p->key = xstrdup (key); - if (addnode (*listp, p) != 0) - freenode (p); -} - -static void -addfile (listp, dir, file) - List **listp; - char *dir; - char *file; -{ - Node *n; - List *fl; - - /* add this dir. */ - addlist (listp, dir); - - n = findnode (*listp, dir); - if (n == NULL) - { - error (1, 0, "can't find recently added dir node `%s' in start_recursion.", - dir); - } - - n->type = DIRS; - fl = n->data; - addlist (&fl, file); - n->data = fl; - return; -} - -static int -unroll_files_proc (p, closure) - Node *p; - void *closure; -{ - Node *n; - struct recursion_frame *frame = (struct recursion_frame *) closure; - int err = 0; - List *save_dirlist; - char *save_update_dir = NULL; - struct saved_cwd cwd; - - /* if this dir was also an explicitly named argument, then skip - it. We'll catch it later when we do dirs. */ - n = findnode (dirlist, p->key); - if (n != NULL) - return (0); - - /* otherwise, call dorecusion for this list of files. */ - filelist = p->data; - p->data = NULL; - save_dirlist = dirlist; - dirlist = NULL; - - if (strcmp(p->key, ".") != 0) - { - if (save_cwd (&cwd)) - error_exit (); - if ( CVS_CHDIR (p->key) < 0) - error (1, errno, "could not chdir to %s", p->key); - - save_update_dir = update_dir; - update_dir = xmalloc (strlen (save_update_dir) - + strlen (p->key) - + 5); - strcpy (update_dir, save_update_dir); - - if (*update_dir != '\0') - (void) strcat (update_dir, "/"); - - (void) strcat (update_dir, p->key); - } - - err += do_recursion (frame); - - if (save_update_dir != NULL) - { - free (update_dir); - update_dir = save_update_dir; - - if (restore_cwd (&cwd, NULL)) - error_exit (); - free_cwd (&cwd); - } - - dirlist = save_dirlist; - if (filelist) - dellist (&filelist); - return(err); -} diff --git a/contrib/cvs/src/release.c b/contrib/cvs/src/release.c deleted file mode 100644 index 27a16c0..0000000 --- a/contrib/cvs/src/release.c +++ /dev/null @@ -1,334 +0,0 @@ -/* - * Copyright (C) 1994-2005 The Free Software Foundation, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -/* - * Release: "cancel" a checkout in the history log. - * - * - Enter a line in the history log indicating the "release". - If asked to, - * delete the local working directory. - */ - -#include "cvs.h" -#include "savecwd.h" -#include "getline.h" - -static const char *const release_usage[] = -{ - "Usage: %s %s [-d] directories...\n", - "\t-d\tDelete the given directory.\n", - "(Specify the --help global option for a list of other help options)\n", - NULL -}; - -#ifdef SERVER_SUPPORT -static int release_server PROTO ((int argc, char **argv)); - -/* This is the server side of cvs release. */ -static int -release_server (argc, argv) - int argc; - char **argv; -{ - int i; - - /* Note that we skip argv[0]. */ - for (i = 1; i < argc; ++i) - history_write ('F', argv[i], "", argv[i], ""); - return 0; -} - -#endif /* SERVER_SUPPORT */ - -/* There are various things to improve about this implementation: - - 1. Using run_popen to run "cvs update" could be replaced by a - fairly simple start_recursion/classify_file loop--a win for - portability, performance, and cleanliness. In particular, there is - no particularly good way to find the right "cvs". - - 2. The fact that "cvs update" contacts the server slows things down; - it undermines the case for using "cvs release" rather than "rm -rf". - However, for correctly printing "? foo" and correctly handling - CVSROOTADM_IGNORE, we currently need to contact the server. (One - idea for how to fix this is to stash a copy of CVSROOTADM_IGNORE in - the working directories; see comment at base_* in entries.c for a - few thoughts on that). - - 3. Would be nice to take processing things on the client side one step - further, and making it like edit/unedit in terms of working well if - disconnected from the network, and then sending a delayed - notification. - - 4. Having separate network turnarounds for the "Notify" request - which we do as part of unedit, and for the "release" itself, is slow - and unnecessary. */ - -int -release (argc, argv) - int argc; - char **argv; -{ - FILE *fp; - int i, c; - char *line = NULL; - size_t line_allocated = 0; - char *update_cmd; - char *thisarg; - int arg_start_idx; - int err = 0; - short delete_flag = 0; - struct saved_cwd cwd; - -#ifdef SERVER_SUPPORT - if (server_active) - return release_server (argc, argv); -#endif - - /* Everything from here on is client or local. */ - if (argc == -1) - usage (release_usage); - optind = 0; - while ((c = getopt (argc, argv, "+Qdq")) != -1) - { - switch (c) - { - case 'Q': - case 'q': - error (1, 0, - "-q or -Q must be specified before \"%s\"", - cvs_cmd_name); - break; - case 'd': - delete_flag++; - break; - case '?': - default: - usage (release_usage); - break; - } - } - argc -= optind; - argv += optind; - - /* We're going to run "cvs -n -q update" and check its output; if - * the output is sufficiently unalarming, then we release with no - * questions asked. Else we prompt, then maybe release. - * (Well, actually we ask no matter what. Our notion of "sufficiently - * unalarming" doesn't take into account "? foo.c" files, so it is - * up to the user to take note of them, at least currently - * (ignore-193 in testsuite)). - */ - /* Construct the update command. Be sure to add authentication and - encryption if we are using them currently, else our child process may - not be able to communicate with the server. */ - update_cmd = xmalloc (strlen (program_path) - + strlen (current_parsed_root->original) - + 1 + 3 + 3 + 16 + 1); - sprintf (update_cmd, "%s %s%s-n -q -d %s update", - program_path, -#if defined (CLIENT_SUPPORT) || defined (SERVER_SUPPORT) - cvsauthenticate ? "-a " : "", - cvsencrypt ? "-x " : "", -#else - "", "", -#endif - current_parsed_root->original); - -#ifdef CLIENT_SUPPORT - /* Start the server; we'll close it after looping. */ - if (current_parsed_root->isremote) - { - start_server (); - ign_setup (); - } -#endif /* CLIENT_SUPPORT */ - - /* Remember the directory where "cvs release" was invoked because - all args are relative to this directory and we chdir around. - */ - if (save_cwd (&cwd)) - error_exit (); - - arg_start_idx = 0; - - for (i = arg_start_idx; i < argc; i++) - { - thisarg = argv[i]; - - if (isdir (thisarg)) - { - if (CVS_CHDIR (thisarg) < 0) - { - if (!really_quiet) - error (0, errno, "can't chdir to: %s", thisarg); - continue; - } - if (!isdir (CVSADM)) - { - if (!really_quiet) - error (0, 0, "no repository directory: %s", thisarg); - if (restore_cwd (&cwd, NULL)) - error_exit (); - continue; - } - } - else - { - if (!really_quiet) - error (0, 0, "no such directory: %s", thisarg); - continue; - } - - if (!really_quiet) - { - int line_length, status; - - /* The "release" command piggybacks on "update", which - does the real work of finding out if anything is not - up-to-date with the repository. Then "release" prompts - the user, telling her how many files have been - modified, and asking if she still wants to do the - release. */ - fp = run_popen (update_cmd, "r"); - if (fp == NULL) - error (1, 0, "cannot run command %s", update_cmd); - - c = 0; - - while ((line_length = getline (&line, &line_allocated, fp)) >= 0) - { - if (strchr ("MARCZ", *line)) - c++; - (void) fputs (line, stdout); - } - if (line_length < 0 && !feof (fp)) - error (0, errno, "cannot read from subprocess"); - - /* If the update exited with an error, then we just want to - complain and go on to the next arg. Especially, we do - not want to delete the local copy, since it's obviously - not what the user thinks it is. */ - status = pclose (fp); - if (status != 0) - { - error (0, 0, "unable to release `%s' (%d)", thisarg, status); - if (restore_cwd (&cwd, NULL)) - error_exit (); - continue; - } - - printf ("You have [%d] altered files in this repository.\n", - c); - printf ("Are you sure you want to release %sdirectory `%s': ", - delete_flag ? "(and delete) " : "", thisarg); - c = !yesno (); - if (c) /* "No" */ - { - (void) fprintf (stderr, "** `%s' aborted by user choice.\n", - cvs_cmd_name); - if (restore_cwd (&cwd, NULL)) - error_exit (); - continue; - } - } - - /* Note: client.c doesn't like to have other code - changing the current directory on it. So a fair amount - of effort is needed to make sure it doesn't get confused - about the directory and (for example) overwrite - CVS/Entries file in the wrong directory. See release-17 - through release-23. */ - - if (restore_cwd (&cwd, NULL)) - error_exit (); - - if (1 -#ifdef CLIENT_SUPPORT - && !(current_parsed_root->isremote - && (!supported_request ("noop") - || !supported_request ("Notify"))) -#endif - ) - { - int argc = 2; - char *argv[3]; - argv[0] = "dummy"; - argv[1] = thisarg; - argv[2] = NULL; - err += unedit (argc, argv); - if (restore_cwd (&cwd, NULL)) - error_exit (); - } - -#ifdef CLIENT_SUPPORT - if (current_parsed_root->isremote) - { - send_to_server ("Argument ", 0); - send_to_server (thisarg, 0); - send_to_server ("\012", 1); - send_to_server ("release\012", 0); - } - else -#endif /* CLIENT_SUPPORT */ - { - history_write ('F', thisarg, "", thisarg, ""); /* F == Free */ - } - - if (delete_flag) - { - /* FIXME? Shouldn't this just delete the CVS-controlled - files and, perhaps, the files that would normally be - ignored and leave everything else? */ - - if (unlink_file_dir (thisarg) < 0) - error (0, errno, "deletion of directory %s failed", thisarg); - } - -#ifdef CLIENT_SUPPORT - if (current_parsed_root->isremote) - { - /* FIXME: - * Is there a good reason why get_server_responses() isn't - * responsible for restoring its initial directory itself when - * finished? - */ - err += get_server_responses (); - - if (restore_cwd (&cwd, NULL)) - error_exit (); - } -#endif /* CLIENT_SUPPORT */ - } - - if (restore_cwd (&cwd, NULL)) - error_exit (); - free_cwd (&cwd); - -#ifdef CLIENT_SUPPORT - if (current_parsed_root->isremote) - { - /* Unfortunately, client.c doesn't offer a way to close - the connection without waiting for responses. The extra - network turnaround here is quite unnecessary other than - that.... */ - send_to_server ("noop\012", 0); - err += get_responses_and_close (); - } -#endif /* CLIENT_SUPPORT */ - - free (update_cmd); - if (line != NULL) - free (line); - return err; -} diff --git a/contrib/cvs/src/remove.c b/contrib/cvs/src/remove.c deleted file mode 100644 index a09cfd4..0000000 --- a/contrib/cvs/src/remove.c +++ /dev/null @@ -1,294 +0,0 @@ -/* - * Copyright (C) 1986-2005 The Free Software Foundation, Inc. - * - * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot , - * and others. - * - * Portions Copyright (C) 1992, Brian Berliner and Jeff Polk - * Portions Copyright (C) 1989-1992, Brian Berliner - * - * You may distribute under the terms of the GNU General Public License as - * specified in the README file that comes with the CVS source distribution. - * - * Remove a File - * - * Removes entries from the present version. The entries will be removed from - * the RCS repository upon the next "commit". - * - * "remove" accepts no options, only file names that are to be removed. The - * file must not exist in the current directory for "remove" to work - * correctly. - */ - -#include "cvs.h" - -#ifdef CLIENT_SUPPORT -static int remove_force_fileproc PROTO ((void *callerdat, - struct file_info *finfo)); -#endif -static int remove_fileproc PROTO ((void *callerdat, struct file_info *finfo)); -static Dtype remove_dirproc PROTO ((void *callerdat, const char *dir, - const char *repos, const char *update_dir, - List *entries)); - -static int force; -static int local; -static int removed_files; -static int existing_files; - -static const char *const remove_usage[] = -{ - "Usage: %s %s [-flR] [files...]\n", - "\t-f\tDelete the file before removing it.\n", - "\t-l\tProcess this directory only (not recursive).\n", - "\t-R\tProcess directories recursively.\n", - "(Specify the --help global option for a list of other help options)\n", - NULL -}; - -int -cvsremove (argc, argv) - int argc; - char **argv; -{ - int c, err; - - if (argc == -1) - usage (remove_usage); - - optind = 0; - while ((c = getopt (argc, argv, "+flR")) != -1) - { - switch (c) - { - case 'f': - force = 1; - break; - case 'l': - local = 1; - break; - case 'R': - local = 0; - break; - case '?': - default: - usage (remove_usage); - break; - } - } - argc -= optind; - argv += optind; - - wrap_setup (); - -#ifdef CLIENT_SUPPORT - if (current_parsed_root->isremote) { - /* Call expand_wild so that the local removal of files will - work. It's ok to do it always because we have to send the - file names expanded anyway. */ - expand_wild (argc, argv, &argc, &argv); - - if (force) - { - if (!noexec) - { - start_recursion (remove_force_fileproc, (FILESDONEPROC) NULL, - (DIRENTPROC) NULL, (DIRLEAVEPROC) NULL, - (void *) NULL, argc, argv, local, W_LOCAL, - 0, CVS_LOCK_NONE, (char *) NULL, 0, - (char *) NULL); - } - /* else FIXME should probably act as if the file doesn't exist - in doing the following checks. */ - } - - start_server (); - ign_setup (); - if (local) - send_arg("-l"); - send_arg ("--"); - /* 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 (); - } -#endif - - /* start the recursion processor */ - err = start_recursion (remove_fileproc, (FILESDONEPROC) NULL, - remove_dirproc, (DIRLEAVEPROC) NULL, NULL, - argc, argv, - local, W_LOCAL, 0, CVS_LOCK_READ, (char *) NULL, 1, - (char *) NULL); - - if (removed_files && !really_quiet) - error (0, 0, "use '%s commit' to remove %s permanently", program_name, - (removed_files == 1) ? "this file" : "these files"); - - if (existing_files) - error (0, 0, - ((existing_files == 1) ? - "%d file exists; remove it first" : - "%d files exist; remove them first"), - existing_files); - - return (err); -} - -#ifdef CLIENT_SUPPORT - -/* - * This is called via start_recursion if we are running as the client - * and the -f option was used. We just physically remove the file. - */ - -/*ARGSUSED*/ -static int -remove_force_fileproc (callerdat, finfo) - void *callerdat; - struct file_info *finfo; -{ - if (CVS_UNLINK (finfo->file) < 0 && ! existence_error (errno)) - error (0, errno, "unable to remove %s", finfo->fullname); - return 0; -} - -#endif - -/* - * remove the file, only if it has already been physically removed - */ -/* ARGSUSED */ -static int -remove_fileproc (callerdat, finfo) - void *callerdat; - struct file_info *finfo; -{ - Vers_TS *vers; - - if (force) - { - if (!noexec) - { - if ( CVS_UNLINK (finfo->file) < 0 && ! existence_error (errno)) - { - error (0, errno, "unable to remove %s", finfo->fullname); - } - } - /* else FIXME should probably act as if the file doesn't exist - in doing the following checks. */ - } - - vers = Version_TS (finfo, NULL, NULL, NULL, 0, 0); - - if (vers->ts_user != NULL) - { - existing_files++; - if (!quiet) - error (0, 0, "file `%s' still in working directory", - finfo->fullname); - } - else if (vers->vn_user == NULL) - { - if (!quiet) - error (0, 0, "nothing known about `%s'", finfo->fullname); - } - else if (vers->vn_user[0] == '0' && vers->vn_user[1] == '\0') - { - char *fname; - - /* - * It's a file that has been added, but not commited yet. So, - * remove the ,t file for it and scratch it from the - * entries file. */ - Scratch_Entry (finfo->entries, finfo->file); - fname = xmalloc (strlen (finfo->file) - + sizeof (CVSADM) - + sizeof (CVSEXT_LOG) - + 10); - (void) sprintf (fname, "%s/%s%s", CVSADM, finfo->file, CVSEXT_LOG); - if (unlink_file (fname) < 0 - && !existence_error (errno)) - error (0, errno, "cannot remove %s", CVSEXT_LOG); - if (!quiet) - error (0, 0, "removed `%s'", finfo->fullname); - -#ifdef SERVER_SUPPORT - if (server_active) - server_checked_in (finfo->file, finfo->update_dir, finfo->repository); -#endif - free (fname); - } - else if (vers->vn_user[0] == '-') - { - if (!quiet) - error (0, 0, "file `%s' already scheduled for removal", - finfo->fullname); - } - else if (vers->tag != NULL && isdigit ((unsigned char) *vers->tag)) - { - /* Commit will just give an error, and so there seems to be - little reason to allow the remove. I mean, conflicts that - arise out of parallel development are one thing, but conflicts - that arise from sticky tags are quite another. - - I would have thought that non-branch sticky tags should be the - same but at least now, removing a file with a non-branch sticky - tag means to delete the tag from the file. I'm not sure that - is a good behavior, but until it is changed, we need to allow - it. */ - error (0, 0, "\ -cannot remove file `%s' which has a numeric sticky tag of `%s'", - finfo->fullname, vers->tag); - } - else if (vers->date != NULL) - { - /* Commit will just give an error, and so there seems to be - little reason to allow the remove. */ - error (0, 0, "\ -cannot remove file `%s' which has a sticky date of `%s'", - finfo->fullname, vers->date); - } - else - { - char *fname; - - /* Re-register it with a negative version number. */ - fname = xmalloc (strlen (vers->vn_user) + 5); - (void) strcpy (fname, "-"); - (void) strcat (fname, vers->vn_user); - Register (finfo->entries, finfo->file, fname, vers->ts_rcs, vers->options, - vers->tag, vers->date, vers->ts_conflict); - if (!quiet) - error (0, 0, "scheduling `%s' for removal", finfo->fullname); - removed_files++; - -#ifdef SERVER_SUPPORT - if (server_active) - server_checked_in (finfo->file, finfo->update_dir, finfo->repository); -#endif - free (fname); - } - - freevers_ts (&vers); - return (0); -} - -/* - * Print a warm fuzzy message - */ -/* ARGSUSED */ -static Dtype -remove_dirproc (callerdat, dir, repos, update_dir, entries) - void *callerdat; - const char *dir; - const char *repos; - const char *update_dir; - List *entries; -{ - if (!quiet) - error (0, 0, "Removing %s", update_dir); - return (R_PROCESS); -} diff --git a/contrib/cvs/src/repos.c b/contrib/cvs/src/repos.c deleted file mode 100644 index 202d92d..0000000 --- a/contrib/cvs/src/repos.c +++ /dev/null @@ -1,211 +0,0 @@ -/* - * Copyright (C) 1986-2005 The Free Software Foundation, Inc. - * - * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot , - * and others. - * - * Portions Copyright (C) 1992, Brian Berliner and Jeff Polk - * Portions Copyright (C) 1989-1992, Brian Berliner - * - * You may distribute under the terms of the GNU General Public License as - * specified in the README file that comes with the CVS source distribution. - */ - -#include -#include "cvs.h" -#include "getline.h" - -/* Determine the name of the RCS repository for directory DIR in the - current working directory, or for the current working directory - itself if DIR is NULL. Returns the name in a newly-malloc'd - string. On error, gives a fatal error and does not return. - UPDATE_DIR is the path from where cvs was invoked (for use in error - messages), and should contain DIR as its last component. - UPDATE_DIR can be NULL to signify the directory in which cvs was - invoked. */ - -char * -Name_Repository (dir, update_dir) - const char *dir; - const char *update_dir; -{ - FILE *fpin; - const char *xupdate_dir; - char *repos = NULL; - size_t repos_allocated = 0; - char *tmp; - char *cp; - - if (update_dir && *update_dir) - xupdate_dir = update_dir; - else - xupdate_dir = "."; - - if (dir != NULL) - { - tmp = xmalloc (strlen (dir) + sizeof (CVSADM_REP) + 10); - (void) sprintf (tmp, "%s/%s", dir, CVSADM_REP); - } - else - tmp = xstrdup (CVSADM_REP); - - /* - * The assumption here is that the repository is always contained in the - * first line of the "Repository" file. - */ - fpin = CVS_FOPEN (tmp, "r"); - - if (fpin == NULL) - { - int save_errno = errno; - char *cvsadm; - - if (dir != NULL) - { - cvsadm = xmalloc (strlen (dir) + sizeof (CVSADM) + 10); - (void) sprintf (cvsadm, "%s/%s", dir, CVSADM); - } - else - cvsadm = xstrdup (CVSADM); - - if (!isdir (cvsadm)) - { - error (0, 0, "in directory %s:", xupdate_dir); - error (1, 0, "there is no version here; do '%s checkout' first", - program_name); - } - free (cvsadm); - - if (existence_error (save_errno)) - { - /* FIXME: This is a very poorly worded error message. It - occurs at least in the case where the user manually - creates a directory named CVS, so the error message - should be more along the lines of "CVS directory found - without administrative files; use CVS to create the CVS - directory, or rename it to something else if the - intention is to store something besides CVS - administrative files". */ - error (0, 0, "in directory %s:", xupdate_dir); - error (1, 0, "*PANIC* administration files missing"); - } - - error (1, save_errno, "cannot open %s", tmp); - } - - if (getline (&repos, &repos_allocated, fpin) < 0) - { - /* FIXME: should be checking for end of file separately. */ - error (0, 0, "in directory %s:", xupdate_dir); - error (1, errno, "cannot read %s", CVSADM_REP); - } - if (fclose (fpin) < 0) - error (0, errno, "cannot close %s", tmp); - free (tmp); - - if ((cp = strrchr (repos, '\n')) != NULL) - *cp = '\0'; /* strip the newline */ - - /* - * If this is a relative repository pathname, turn it into an absolute - * one by tacking on the CVSROOT environment variable. If the CVSROOT - * environment variable is not set, die now. - */ - if (! isabsolute(repos)) - { - char *newrepos; - - if (current_parsed_root == NULL) - { - error (0, 0, "in directory %s:", xupdate_dir); - error (0, 0, "must set the CVSROOT environment variable\n"); - 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 (current_parsed_root->directory) - + strlen (repos) + 2); - sprintf (newrepos, "%s/%s", current_parsed_root->directory, repos); - free (repos); - repos = newrepos; - } - - Sanitize_Repository_Name (repos); - - return repos; -} - - - -/* - * Return a pointer to the repository name relative to CVSROOT from a - * possibly fully qualified repository - */ -const char * -Short_Repository (repository) - const char *repository; -{ - if (repository == NULL) - return NULL; - - /* If repository matches CVSroot at the beginning, strip off CVSroot */ - /* And skip leading '/' in rep, in case CVSroot ended with '/'. */ - if (strncmp (current_parsed_root->directory, repository, - strlen (current_parsed_root->directory)) == 0) - { - const char *rep = repository + strlen (current_parsed_root->directory); - return (*rep == '/') ? rep+1 : rep; - } - else - return repository; -} - - - -/* Sanitize the repository name (in place) by removing trailing - * slashes and a trailing "." if present. It should be safe for - * callers to use strcat and friends to create repository names. - * Without this check, names like "/path/to/repos/./foo" and - * "/path/to/repos//foo" would be created. For example, one - * significant case is the CVSROOT-detection code in commit.c. It - * decides whether or not it needs to rebuild the administrative file - * database by doing a string compare. If we've done a `cvs co .' to - * get the CVSROOT files, "/path/to/repos/./CVSROOT" and - * "/path/to/repos/CVSROOT" are the arguments that are compared! - * - * This function ends up being called from the same places as - * strip_path, though what it does is much more conservative. Many - * comments about this operation (which was scattered around in - * several places in the source code) ran thus: - * - * ``repository ends with "/."; omit it. This sort of thing used - * to be taken care of by strip_path. Now we try to be more - * selective. I suspect that it would be even better to push it - * back further someday, so that the trailing "/." doesn't get into - * repository in the first place, but we haven't taken things that - * far yet.'' --Jim Kingdon (recurse.c, 07-Sep-97) - */ - -void -Sanitize_Repository_Name (repository) - char *repository; -{ - size_t len; - - assert (repository != NULL); - - strip_trailing_slashes (repository); - - len = strlen (repository); - if (len >= 2 - && repository[len - 1] == '.' - && ISDIRSEP (repository[len - 2])) - { - repository[len - 2] = '\0'; - } -} diff --git a/contrib/cvs/src/root.c b/contrib/cvs/src/root.c deleted file mode 100644 index 44d1f9a..0000000 --- a/contrib/cvs/src/root.c +++ /dev/null @@ -1,864 +0,0 @@ -/* - * Copyright (C) 1986-2008 The Free Software Foundation, Inc. - * - * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot , - * and others. - * - * Poritons Copyright (c) 1992, Mark D. Baushke - * - * You may distribute under the terms of the GNU General Public License as - * specified in the README file that comes with the CVS source distribution. - * - * Name of Root - * - * Determine the path to the CVSROOT and set "Root" accordingly. - */ - -#include "cvs.h" -#include -#include "getline.h" - -/* Printable names for things in the current_parsed_root->method enum variable. - Watch out if the enum is changed in cvs.h! */ - -const char method_names[][16] = { - "undefined", "local", "server (rsh)", "pserver", - "kserver", "gserver", "ext", "extssh", "fork" -}; - -#ifndef DEBUG - -cvsroot_t * -Name_Root (dir, update_dir) - const char *dir; - const char *update_dir; -{ - FILE *fpin; - cvsroot_t *ret; - const char *xupdate_dir; - char *root = NULL; - size_t root_allocated = 0; - char *tmp; - char *cvsadm; - char *cp; - int len; - - if (update_dir && *update_dir) - xupdate_dir = update_dir; - else - xupdate_dir = "."; - - if (dir != NULL) - { - cvsadm = xmalloc (strlen (dir) + sizeof (CVSADM) + 10); - (void) sprintf (cvsadm, "%s/%s", dir, CVSADM); - tmp = xmalloc (strlen (dir) + sizeof (CVSADM_ROOT) + 10); - (void) sprintf (tmp, "%s/%s", dir, CVSADM_ROOT); - } - else - { - cvsadm = xstrdup (CVSADM); - tmp = xstrdup (CVSADM_ROOT); - } - - /* - * Do not bother looking for a readable file if there is no cvsadm - * directory present. - * - * It is possible that not all repositories will have a CVS/Root - * file. This is ok, but the user will need to specify -d - * /path/name or have the environment variable CVSROOT set in - * order to continue. */ - if ((!isdir (cvsadm)) || (!isreadable (tmp))) - { - ret = NULL; - goto out; - } - - /* - * The assumption here is that the CVS Root is always contained in the - * first line of the "Root" file. - */ - fpin = open_file (tmp, "r"); - - if ((len = getline (&root, &root_allocated, fpin)) < 0) - { - int saved_errno = errno; - /* FIXME: should be checking for end of file separately; errno - is not set in that case. */ - error (0, 0, "in directory %s:", xupdate_dir); - error (0, saved_errno, "cannot read %s", CVSADM_ROOT); - error (0, 0, "please correct this problem"); - ret = NULL; - goto out; - } - fclose (fpin); - cp = root + len - 1; - if (*cp == '\n') - *cp = '\0'; /* strip the newline */ - - /* - * root now contains a candidate for CVSroot. It must be an - * absolute pathname or specify a remote server. - */ - - ret = parse_cvsroot (root); - if (ret == NULL) - { - error (0, 0, "in directory %s:", xupdate_dir); - error (0, 0, - "ignoring %s because it does not contain a valid root.", - CVSADM_ROOT); - goto out; - } - - if (!ret->isremote && !isdir (ret->directory)) - { - error (0, 0, "in directory %s:", xupdate_dir); - error (0, 0, - "ignoring %s because it specifies a non-existent repository %s", - CVSADM_ROOT, root); - free_cvsroot_t (ret); - ret = NULL; - goto out; - } - - - out: - free (cvsadm); - free (tmp); - if (root != NULL) - free (root); - return ret; -} - - - -/* - * Write the CVS/Root file so that the environment variable CVSROOT - * and/or the -d option to cvs will be validated or not necessary for - * future work. - */ -void -Create_Root (dir, rootdir) - const char *dir; - const char *rootdir; -{ - FILE *fout; - char *tmp; - - if (noexec) - return; - - /* record the current cvs root */ - - if (rootdir != NULL) - { - if (dir != NULL) - { - tmp = xmalloc (strlen (dir) + sizeof (CVSADM_ROOT) + 10); - (void) sprintf (tmp, "%s/%s", dir, CVSADM_ROOT); - } - else - tmp = xstrdup (CVSADM_ROOT); - - fout = open_file (tmp, "w+"); - if (fprintf (fout, "%s\n", rootdir) < 0) - error (1, errno, "write to %s failed", tmp); - if (fclose (fout) == EOF) - error (1, errno, "cannot close %s", tmp); - free (tmp); - } -} - -#endif /* ! DEBUG */ - - -/* The root_allow_* stuff maintains a list of legal CVSROOT - directories. Then we can check against them when a remote user - hands us a CVSROOT directory. */ - -static int root_allow_count; -static char **root_allow_vector; -static int root_allow_size; - -int -root_allow_used () -{ - return root_allow_count; -} - -void -root_allow_add (arg) - char *arg; -{ - char *p; - - if (root_allow_size <= root_allow_count) - { - if (root_allow_size == 0) - { - root_allow_size = 1; - root_allow_vector = - (char **) xmalloc (root_allow_size * sizeof (char *)); - } - else - { - root_allow_size *= 2; - root_allow_vector = - (char **) xrealloc (root_allow_vector, - root_allow_size * sizeof (char *)); - } - - if (root_allow_vector == NULL) - { - no_memory: - /* Strictly speaking, we're not supposed to output anything - now. But we're about to exit(), give it a try. */ - printf ("E Fatal server error, aborting.\n\ -error ENOMEM Virtual memory exhausted.\n"); - - error_exit (); - } - } - p = xmalloc (strlen (arg) + 1); - if (p == NULL) - goto no_memory; - strcpy (p, arg); - root_allow_vector[root_allow_count++] = p; -} - -void -root_allow_free () -{ - if (root_allow_vector != NULL) - free_names (&root_allow_count, root_allow_vector); - root_allow_size = 0; -} - -int -root_allow_ok (arg) - char *arg; -{ - int i; - - if (root_allow_count == 0) - { - /* Probably someone upgraded from CVS before 1.9.10 to 1.9.10 - or later without reading the documentation about - --allow-root. Printing an error here doesn't disclose any - particularly useful information to an attacker because a - CVS server configured in this way won't let *anyone* in. */ - - /* Note that we are called from a context where we can spit - back "error" rather than waiting for the next request which - expects responses. */ - printf ("\ -error 0 Server configuration missing --allow-root in inetd.conf\n"); - error_exit (); - } - - for (i = 0; i < root_allow_count; ++i) - if (strcmp (root_allow_vector[i], arg) == 0) - return 1; - return 0; -} - - - -/* This global variable holds the global -d option. It is NULL if -d - was not used, which means that we must get the CVSroot information - from the CVSROOT environment variable or from a CVS/Root file. */ -char *CVSroot_cmdline; - - - -/* FIXME - Deglobalize this. */ -cvsroot_t *current_parsed_root = NULL; - - - -/* allocate and initialize a cvsroot_t - * - * We must initialize the strings to NULL so we know later what we should - * free - * - * Some of the other zeroes remain meaningful as, "never set, use default", - * or the like - */ -static cvsroot_t * -new_cvsroot_t () -{ - cvsroot_t *newroot; - - /* gotta store it somewhere */ - newroot = xmalloc(sizeof(cvsroot_t)); - - newroot->original = NULL; - newroot->method = null_method; - newroot->isremote = 0; -#ifdef CLIENT_SUPPORT - newroot->username = NULL; - newroot->password = NULL; - newroot->hostname = NULL; - newroot->port = 0; - newroot->directory = NULL; - newroot->proxy_hostname = NULL; - newroot->proxy_port = 0; -#endif /* CLIENT_SUPPORT */ - - return newroot; -} - - - -/* Dispose of a cvsroot_t and its component parts */ -void -free_cvsroot_t (root) - cvsroot_t *root; -{ - if (root->original != NULL) - free (root->original); - if (root->directory != NULL) - free (root->directory); -#ifdef CLIENT_SUPPORT - if (root->username != NULL) - free (root->username); - if (root->password != NULL) - { - /* I like to be paranoid */ - memset (root->password, 0, strlen (root->password)); - free (root->password); - } - if (root->hostname != NULL) - free (root->hostname); - if (root->proxy_hostname != NULL) - free (root->proxy_hostname); -#endif /* CLIENT_SUPPORT */ - free (root); -} - - - -/* - * Parse a CVSROOT string to allocate and return a new cvsroot_t structure. - * Valid specifications are: - * - * :(gserver|kserver|pserver):[[user][:password]@]host[:[port]]/path - * [:(ext|server):][[user]@]host[:]/path - * [:local:[e:]]/path - * :fork:/path - * - * INPUTS - * root_in C String containing the CVSROOT to be parsed. - * - * RETURNS - * A pointer to a newly allocated cvsroot_t structure upon success and - * NULL upon failure. The caller is responsible for disposing of - * new structures with a call to free_cvsroot_t(). - * - * NOTES - * This would have been a lot easier to write in Perl. - * - * SEE ALSO - * free_cvsroot_t() - */ -cvsroot_t * -parse_cvsroot (root_in) - const char *root_in; -{ - cvsroot_t *newroot; /* the new root to be returned */ - char *cvsroot_save; /* what we allocated so we can dispose - * it when finished */ - char *firstslash; /* save where the path spec starts - * while we parse - * [[user][:password]@]host[:[port]] - */ - char *cvsroot_copy, *p, *q; /* temporary pointers for parsing */ -#ifdef CLIENT_SUPPORT - int check_hostname, no_port, no_password; -#endif /* CLIENT_SUPPORT */ - - assert (root_in); - - /* allocate some space */ - newroot = new_cvsroot_t(); - - /* save the original string */ - newroot->original = xstrdup (root_in); - - /* and another copy we can munge while parsing */ - cvsroot_save = cvsroot_copy = xstrdup (root_in); - - if (*cvsroot_copy == ':') - { - char *method = ++cvsroot_copy; - - /* Access method specified, as in - * "cvs -d :(gserver|kserver|pserver):[[user][:password]@]host[:[port]]/path", - * "cvs -d [:(ext|server):][[user]@]host[:]/path", - * "cvs -d :local:e:\path", - * "cvs -d :fork:/path". - * We need to get past that part of CVSroot before parsing the - * rest of it. - */ - - if (! (p = strchr (method, ':'))) - { - error (0, 0, "No closing `:' on method in CVSROOT."); - goto error_exit; - } - *p = '\0'; - cvsroot_copy = ++p; - -#ifdef CLIENT_SUPPORT - /* Look for method options, for instance, proxy, proxyport. - * We don't handle these, but we like to try and warn the user that - * they are being ignored. - */ - if ((p = strchr (method, ';')) != NULL) - { - *p++ = '\0'; - if (!really_quiet) - { - error (0, 0, -"WARNING: Ignoring method options found in CVSROOT: `%s'.", - p); - error (0, 0, -"Use CVS version 1.12.7 or later to handle method options."); - } - } -#endif /* CLIENT_SUPPORT */ - - /* Now we have an access method -- see if it's valid. */ - - if (strcmp (method, "local") == 0) - newroot->method = local_method; - else if (strcmp (method, "pserver") == 0) - newroot->method = pserver_method; - else if (strcmp (method, "kserver") == 0) - newroot->method = kserver_method; - else if (strcmp (method, "gserver") == 0) - newroot->method = gserver_method; - else if (strcmp (method, "server") == 0) - newroot->method = server_method; - else if (strcmp (method, "ext") == 0) - newroot->method = ext_method; - else if (strcmp (method, "extssh") == 0) - newroot->method = extssh_method; - else if (strcmp (method, "fork") == 0) - newroot->method = fork_method; - else - { - error (0, 0, "Unknown method (`%s') in CVSROOT.", method); - goto error_exit; - } - } - else - { - /* If the method isn't specified, assume EXT_METHOD if the string looks - like a relative path and LOCAL_METHOD otherwise. */ - - newroot->method = ((*cvsroot_copy != '/' && strchr (cvsroot_copy, '/')) - ? ext_method - : local_method); - } - - newroot->isremote = (newroot->method != local_method); - - if ((newroot->method != local_method) - && (newroot->method != fork_method)) - { - /* split the string into [[user][:password]@]host[:[port]] & /path - * - * this will allow some characters such as '@' & ':' to remain unquoted - * in the path portion of the spec - */ - if ((p = strchr (cvsroot_copy, '/')) == NULL) - { - error (0, 0, "CVSROOT requires a path spec:"); - error (0, 0, -":(gserver|kserver|pserver):[[user][:password]@]host[:[port]]/path"); - error (0, 0, "[:(ext|server):][[user]@]host[:]/path"); - goto error_exit; - } - firstslash = p; /* == NULL if '/' not in string */ - *p = '\0'; - - /* Don't parse username, password, hostname, or port without client - * support. - */ -#ifdef CLIENT_SUPPORT - /* Check to see if there is a username[:password] in the string. */ - if ((p = strchr (cvsroot_copy, '@')) != NULL) - { - *p = '\0'; - /* check for a password */ - if ((q = strchr (cvsroot_copy, ':')) != NULL) - { - *q = '\0'; - newroot->password = xstrdup (++q); - /* Don't check for *newroot->password == '\0' since - * a user could conceivably wish to specify a blank password - * - * (newroot->password == NULL means to use the - * password from .cvspass) - */ - } - - /* copy the username */ - if (*cvsroot_copy != '\0') - /* a blank username is impossible, so leave it NULL in that - * case so we know to use the default username - */ - newroot->username = xstrdup (cvsroot_copy); - - cvsroot_copy = ++p; - } - - /* now deal with host[:[port]] */ - - /* the port */ - if ((p = strchr (cvsroot_copy, ':')) != NULL) - { - *p++ = '\0'; - if (strlen(p)) - { - q = p; - if (*q == '-') q++; - while (*q) - { - if (!isdigit(*q++)) - { - error (0, 0, -"CVSROOT may only specify a positive, non-zero, integer port (not `%s').", - p); - error (0, 0, - "Perhaps you entered a relative pathname?"); - goto error_exit; - } - } - if ((newroot->port = atoi (p)) <= 0) - { - error (0, 0, -"CVSROOT may only specify a positive, non-zero, integer port (not `%s').", - p); - error (0, 0, "Perhaps you entered a relative pathname?"); - goto error_exit; - } - } - } - - /* copy host */ - if (*cvsroot_copy != '\0') - /* blank hostnames are invalid, but for now leave the field NULL - * and catch the error during the sanity checks later - */ - newroot->hostname = xstrdup (cvsroot_copy); - - /* restore the '/' */ - cvsroot_copy = firstslash; - *cvsroot_copy = '/'; -#endif /* CLIENT_SUPPORT */ - } - - /* - * Parse the path for all methods. - */ - /* Here & local_cvsroot() should be the only places this needs to be - * called on a CVSROOT now. cvsroot->original is saved for error messages - * and, otherwise, we want no trailing slashes. - */ - Sanitize_Repository_Name( cvsroot_copy ); - newroot->directory = xstrdup(cvsroot_copy); - - /* - * Do various sanity checks. - */ - -#if ! defined (CLIENT_SUPPORT) && ! defined (DEBUG) - if (newroot->method != local_method) - { - error (0, 0, "CVSROOT is set for a remote access method but your"); - error (0, 0, "CVS executable doesn't support it."); - goto error_exit; - } -#endif - -#if ! defined (SERVER_SUPPORT) && ! defined (DEBUG) - if (newroot->method == fork_method) - { - error (0, 0, "CVSROOT is set to use the :fork: access method but your"); - error (0, 0, "CVS executable doesn't support it."); - goto error_exit; - } -#endif - -#ifdef CLIENT_SUPPORT - if (newroot->username && ! newroot->hostname) - { - error (0, 0, "Missing hostname in CVSROOT."); - goto error_exit; - } - - check_hostname = 0; - no_password = 1; - no_port = 0; -#endif /* CLIENT_SUPPORT */ - switch (newroot->method) - { - case local_method: -#ifdef CLIENT_SUPPORT - if (newroot->username || newroot->hostname) - { - error (0, 0, "Can't specify hostname and username in CVSROOT"); - error (0, 0, "when using local access method."); - goto error_exit; - } - no_port = 1; - /* no_password already set */ -#endif /* CLIENT_SUPPORT */ - /* cvs.texinfo has always told people that CVSROOT must be an - absolute pathname. Furthermore, attempts to use a relative - pathname produced various errors (I couldn't get it to work), - so there would seem to be little risk in making this a fatal - error. */ - if (!isabsolute (newroot->directory)) - { - error (0, 0, "CVSROOT must be an absolute pathname (not `%s')", - newroot->directory); - error (0, 0, "when using local access method."); - goto error_exit; - } - break; -#ifdef CLIENT_SUPPORT - 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 (newroot->username || newroot->hostname) - { - error (0, 0, "Can't specify hostname and username in CVSROOT"); - error (0, 0, "when using fork access method."); - goto error_exit; - } - newroot->hostname = xstrdup("server"); /* for error messages */ - if (!isabsolute (newroot->directory)) - { - error (0, 0, "CVSROOT must be an absolute pathname (not `%s')", - newroot->directory); - error (0, 0, "when using fork access method."); - goto error_exit; - } - no_port = 1; - /* no_password already set */ - break; - case kserver_method: -# ifndef HAVE_KERBEROS - error (0, 0, "CVSROOT is set for a kerberos access method but your"); - error (0, 0, "CVS executable doesn't support it."); - goto error_exit; -# else - check_hostname = 1; - /* no_password already set */ - break; -# endif - case gserver_method: -# ifndef HAVE_GSSAPI - error (0, 0, "CVSROOT is set for a GSSAPI access method but your"); - error (0, 0, "CVS executable doesn't support it."); - goto error_exit; -# else - check_hostname = 1; - /* no_password already set */ - break; -# endif - case server_method: - case ext_method: - case extssh_method: - no_port = 1; - /* no_password already set */ - check_hostname = 1; - break; - case pserver_method: - no_password = 0; - check_hostname = 1; - break; -#endif /* CLIENT_SUPPORT */ - default: - error (1, 0, "Invalid method found in parse_cvsroot"); - } - -#ifdef CLIENT_SUPPORT - if (no_password && newroot->password) - { - error (0, 0, "CVSROOT password specification is only valid for"); - error (0, 0, "pserver connection method."); - goto error_exit; - } - - if (check_hostname && !newroot->hostname) - { - error (0, 0, "Didn't specify hostname in CVSROOT."); - goto error_exit; - } - - if (no_port && newroot->port) - { - error (0, 0, "CVSROOT port specification is only valid for gserver, kserver,"); - error (0, 0, "and pserver connection methods."); - goto error_exit; - } -#endif /* CLIENT_SUPPORT */ - - if (*newroot->directory == '\0') - { - error (0, 0, "Missing directory in CVSROOT."); - goto error_exit; - } - - /* Hooray! We finally parsed it! */ - free (cvsroot_save); - return newroot; - -error_exit: - free (cvsroot_save); - free_cvsroot_t (newroot); - return NULL; -} - - - -#ifdef AUTH_CLIENT_SUPPORT -/* Use root->username, root->hostname, root->port, and root->directory - * to create a normalized CVSROOT fit for the .cvspass file - * - * username defaults to the result of getcaller() - * port defaults to the result of get_cvs_port_number() - * - * FIXME - we could cache the canonicalized version of a root inside the - * cvsroot_t, but we'd have to un'const the input here and stop expecting the - * caller to be responsible for our return value - */ -char * -normalize_cvsroot (root) - const cvsroot_t *root; -{ - char *cvsroot_canonical; - char *p, *hostname, *username; - char port_s[64]; - - assert (root && root->hostname && root->directory); - - /* get the appropriate port string */ - sprintf (port_s, "%d", get_cvs_port_number (root)); - - /* use a lower case hostname since we know hostnames are case insensitive */ - /* Some logic says we should be tacking our domain name on too if it isn't - * there already, but for now this works. Reverse->Forward lookups are - * almost certainly too much since that would make CVS immune to some of - * the DNS trickery that makes life easier for sysadmins when they want to - * move a repository or the like - */ - p = hostname = xstrdup(root->hostname); - while (*p) - { - *p = tolower(*p); - p++; - } - - /* get the username string */ - username = root->username ? root->username : getcaller(); - cvsroot_canonical = xmalloc ( strlen(username) - + strlen(hostname) + strlen(port_s) - + strlen(root->directory) + 12); - sprintf (cvsroot_canonical, ":pserver:%s@%s:%s%s", - username, hostname, port_s, root->directory); - - free (hostname); - return cvsroot_canonical; -} -#endif /* AUTH_CLIENT_SUPPORT */ - - - -/* allocate and return a cvsroot_t structure set up as if we're using the local - * repository DIR. */ -cvsroot_t * -local_cvsroot (dir) - const char *dir; -{ - cvsroot_t *newroot = new_cvsroot_t(); - - newroot->original = xstrdup(dir); - newroot->method = local_method; - newroot->directory = xstrdup(dir); - /* Here and parse_cvsroot() should be the only places this needs to be - * called on a CVSROOT now. cvsroot->original is saved for error messages - * and, otherwise, we want no trailing slashes. - */ - Sanitize_Repository_Name( newroot->directory ); - return newroot; -} - - - -#ifdef DEBUG -/* This is for testing the parsing function. Use - - gcc -I. -I.. -I../lib -DDEBUG root.c -o root - - to compile. */ - -#include - -char *program_name = "testing"; -char *cvs_cmd_name = "parse_cvsroot"; /* XXX is this used??? */ - -/* Toy versions of various functions when debugging under unix. Yes, - these make various bad assumptions, but they're pretty easy to - debug when something goes wrong. */ - -void -error_exit PROTO ((void)) -{ - exit (1); -} - -int -isabsolute (dir) - const char *dir; -{ - return (dir && (*dir == '/')); -} - -void -main (argc, argv) - int argc; - char *argv[]; -{ - program_name = argv[0]; - - if (argc != 2) - { - fprintf (stderr, "Usage: %s \n", program_name); - exit (2); - } - - if ((current_parsed_root = parse_cvsroot (argv[1])) == NULL) - { - fprintf (stderr, "%s: Parsing failed.\n", program_name); - exit (1); - } - printf ("CVSroot: %s\n", argv[1]); - printf ("current_parsed_root->method: %s\n", method_names[current_parsed_root->method]); - printf ("current_parsed_root->username: %s\n", - current_parsed_root->username ? current_parsed_root->username : "NULL"); - printf ("current_parsed_root->hostname: %s\n", - current_parsed_root->hostname ? current_parsed_root->hostname : "NULL"); - printf ("current_parsed_root->directory: %s\n", current_parsed_root->directory); - - exit (0); - /* NOTREACHED */ -} -#endif diff --git a/contrib/cvs/src/root.h b/contrib/cvs/src/root.h deleted file mode 100644 index 089b694..0000000 --- a/contrib/cvs/src/root.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (C) 1986-2005 The Free Software Foundation, Inc. - * - * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot , - * and others. - * - * Portions Copyright (C) 1992, Brian Berliner and Jeff Polk - * Portions Copyright (C) 1989-1992, Brian Berliner - * - * You may distribute under the terms of the GNU General Public License as - * specified in the README file that comes with the CVS kit. - */ - -/* CVSroot data structures */ - -/* Access method specified in CVSroot. */ -typedef enum { - null_method, - local_method, - server_method, - pserver_method, - kserver_method, - gserver_method, - ext_method, - extssh_method, - fork_method -} CVSmethod; -extern const char method_names[][16]; /* change this in root.c if you change - the enum above */ - -typedef struct cvsroot_s { - char *original; /* The complete source CVSroot string. */ - CVSmethod method; /* One of the enum values above. */ - char *directory; /* The directory name. */ - unsigned char isremote; /* Nonzero if we are doing remote access. */ -#ifdef CLIENT_SUPPORT - char *username; /* The username or NULL if method == local. */ - char *password; /* The password or NULL if method == local. */ - char *hostname; /* The hostname or NULL if method == local. */ - int port; /* The port or zero if method == local. */ - char *proxy_hostname; /* The hostname of the proxy server, or NULL - * when method == local or no proxy will be - * used. - */ - int proxy_port; /* The port of the proxy or zero, as above. */ -#endif /* CLIENT_SUPPORT */ -} cvsroot_t; - -cvsroot_t *Name_Root PROTO((const char *dir, const char *update_dir)); -void free_cvsroot_t PROTO((cvsroot_t *root_in)); -cvsroot_t *parse_cvsroot PROTO((const char *root)); -cvsroot_t *local_cvsroot PROTO((const char *dir)); -void Create_Root PROTO((const char *dir, const char *rootdir)); -void root_allow_add PROTO ((char *)); -void root_allow_free PROTO ((void)); -int root_allow_ok PROTO ((char *)); -int root_allow_used PROTO ((void)); diff --git a/contrib/cvs/src/run.c b/contrib/cvs/src/run.c deleted file mode 100644 index 98ae911..0000000 --- a/contrib/cvs/src/run.c +++ /dev/null @@ -1,578 +0,0 @@ -/* run.c --- routines for executing subprocesses. - - This file is part of GNU CVS. - - GNU CVS is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. */ - -#include "cvs.h" - -#ifndef HAVE_UNISTD_H -extern int execvp PROTO((char *file, char **argv)); -#endif - -static void run_add_arg PROTO((const char *s)); - -extern char *strtok (); - -/* - * To exec a program under CVS, first call run_setup() to setup initial - * arguments. The argument to run_setup will be parsed into whitespace - * separated words and added to the global run_argv list. - * - * Then, optionally call run_arg() for each additional argument that you'd like - * to pass to the executed program. - * - * Finally, call run_exec() to execute the program with the specified arguments. - * The execvp() syscall will be used, so that the PATH is searched correctly. - * File redirections can be performed in the call to run_exec(). - */ -static char **run_argv; -static int run_argc; -static size_t run_argc_allocated; - - - -void -run_arg_free_p (int argc, char **argv) -{ - int i; - for (i = 0; i < argc; i++) - free (argv[i]); -} - - - -/* VARARGS */ -void -run_setup (prog) - const char *prog; -{ - char *cp; - char *run_prog; - - /* clean out any malloc'ed values from run_argv */ - run_arg_free_p (run_argc, run_argv); - run_argc = 0; - - run_prog = xstrdup (prog); - - /* put each word into run_argv, allocating it as we go */ - for (cp = strtok (run_prog, " \t"); cp; cp = strtok ((char *) NULL, " \t")) - run_add_arg (cp); - free (run_prog); -} - -void -run_arg (s) - const char *s; -{ - run_add_arg (s); -} - - - -void -run_add_arg_p (iargc, iarg_allocated, iargv, s) - int *iargc; - size_t *iarg_allocated; - char ***iargv; - const char *s; -{ - /* allocate more argv entries if we've run out */ - if (*iargc >= *iarg_allocated) - { - *iarg_allocated += 50; - *iargv = xrealloc (*iargv, *iarg_allocated * sizeof (char **)); - } - - if (s) - (*iargv)[(*iargc)++] = xstrdup (s); - else - (*iargv)[*iargc] = NULL; /* not post-incremented on purpose! */ -} - - - -static void -run_add_arg (s) - const char *s; -{ - run_add_arg_p (&run_argc, &run_argc_allocated, &run_argv, s); -} - - - -int -run_exec (stin, stout, sterr, flags) - const char *stin; - const char *stout; - const char *sterr; - int flags; -{ - int shin, shout, sherr; - int mode_out, mode_err; - int status; - int rc = -1; - int rerrno = 0; - int pid, w; - -#ifdef POSIX_SIGNALS - sigset_t sigset_mask, sigset_omask; - struct sigaction act, iact, qact; - -#else -#ifdef BSD_SIGNALS - int mask; - struct sigvec vec, ivec, qvec; - -#else - RETSIGTYPE (*istat) (), (*qstat) (); -#endif -#endif - - if (trace) - { -#ifdef SERVER_SUPPORT - cvs_outerr (server_active ? "S" : " ", 1); -#endif - cvs_outerr ("-> system(", 0); - run_print (stderr); - cvs_outerr (")\n", 0); - } - if (noexec && (flags & RUN_REALLY) == 0) - return 0; - - /* make sure that we are null terminated, since we didn't calloc */ - run_add_arg ((char *)0); - - /* setup default file descriptor numbers */ - shin = 0; - shout = 1; - sherr = 2; - - /* set the file modes for stdout and stderr */ - mode_out = mode_err = O_WRONLY | O_CREAT; - mode_out |= ((flags & RUN_STDOUT_APPEND) ? O_APPEND : O_TRUNC); - mode_err |= ((flags & RUN_STDERR_APPEND) ? O_APPEND : O_TRUNC); - - if (stin && (shin = open (stin, O_RDONLY)) == -1) - { - rerrno = errno; - error (0, errno, "cannot open %s for reading (prog %s)", - stin, run_argv[0]); - goto out0; - } - if (stout && (shout = open (stout, mode_out, 0666)) == -1) - { - rerrno = errno; - error (0, errno, "cannot open %s for writing (prog %s)", - stout, run_argv[0]); - goto out1; - } - if (sterr && (flags & RUN_COMBINED) == 0) - { - if ((sherr = open (sterr, mode_err, 0666)) == -1) - { - rerrno = errno; - error (0, errno, "cannot open %s for writing (prog %s)", - sterr, run_argv[0]); - goto out2; - } - } - - /* Make sure we don't flush this twice, once in the subprocess. */ - cvs_flushout(); - cvs_flusherr(); - - /* The output files, if any, are now created. Do the fork and dups. - - We use vfork not so much for a performance boost (the - performance boost, if any, is modest on most modern unices), - but for the sake of systems without a memory management unit, - which find it difficult or impossible to implement fork at all - (e.g. Amiga). The other solution is spawn (see - windows-NT/run.c). */ - -#ifdef HAVE_VFORK - pid = vfork (); -#else - pid = fork (); -#endif - if (pid == 0) - { - if (shin != 0) - { - (void) dup2 (shin, 0); - (void) close (shin); - } - if (shout != 1) - { - (void) dup2 (shout, 1); - (void) close (shout); - } - if (flags & RUN_COMBINED) - (void) dup2 (1, 2); - else if (sherr != 2) - { - (void) dup2 (sherr, 2); - (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]); - _exit (127); - } - else if (pid == -1) - { - rerrno = errno; - goto out; - } - - /* the parent. Ignore some signals for now */ -#ifdef POSIX_SIGNALS - if (flags & RUN_SIGIGNORE) - { - act.sa_handler = SIG_IGN; - (void) sigemptyset (&act.sa_mask); - act.sa_flags = 0; - (void) sigaction (SIGINT, &act, &iact); - (void) sigaction (SIGQUIT, &act, &qact); - } - else - { - (void) sigemptyset (&sigset_mask); - (void) sigaddset (&sigset_mask, SIGINT); - (void) sigaddset (&sigset_mask, SIGQUIT); - (void) sigprocmask (SIG_SETMASK, &sigset_mask, &sigset_omask); - } -#else -#ifdef BSD_SIGNALS - if (flags & RUN_SIGIGNORE) - { - memset ((char *)&vec, 0, sizeof (vec)); - vec.sv_handler = SIG_IGN; - (void) sigvec (SIGINT, &vec, &ivec); - (void) sigvec (SIGQUIT, &vec, &qvec); - } - else - mask = sigblock (sigmask (SIGINT) | sigmask (SIGQUIT)); -#else - istat = signal (SIGINT, SIG_IGN); - qstat = signal (SIGQUIT, SIG_IGN); -#endif -#endif - - /* wait for our process to die and munge return status */ -#ifdef POSIX_SIGNALS - while ((w = waitpid (pid, &status, 0)) == -1 && errno == EINTR) - ; -#else - while ((w = wait (&status)) != pid) - { - if (w == -1 && errno != EINTR) - break; - } -#endif - - if (w == -1) - { - rc = -1; - rerrno = errno; - } -#ifndef VMS /* status is return status */ - else if (WIFEXITED (status)) - rc = WEXITSTATUS (status); - else if (WIFSIGNALED (status)) - { - if (WTERMSIG (status) == SIGPIPE) - error (1, 0, "broken pipe"); - rc = 2; - } - else - rc = 1; -#else /* VMS */ - rc = WEXITSTATUS (status); -#endif /* VMS */ - - /* restore the signals */ -#ifdef POSIX_SIGNALS - if (flags & RUN_SIGIGNORE) - { - (void) sigaction (SIGINT, &iact, (struct sigaction *)NULL); - (void) sigaction (SIGQUIT, &qact, (struct sigaction *)NULL); - } - else - (void) sigprocmask (SIG_SETMASK, &sigset_omask, (sigset_t *)NULL); -#else -#ifdef BSD_SIGNALS - if (flags & RUN_SIGIGNORE) - { - (void) sigvec (SIGINT, &ivec, (struct sigvec *)NULL); - (void) sigvec (SIGQUIT, &qvec, (struct sigvec *)NULL); - } - else - (void) sigsetmask (mask); -#else - (void) signal (SIGINT, istat); - (void) signal (SIGQUIT, qstat); -#endif -#endif - - /* cleanup the open file descriptors */ - out: - if (sterr) - (void) close (sherr); - else - /* ensure things are received by the parent in the correct order - * relative to the protocol pipe - */ - cvs_flusherr(); - out2: - if (stout) - (void) close (shout); - else - /* ensure things are received by the parent in the correct order - * relative to the protocol pipe - */ - cvs_flushout(); - out1: - if (stin) - (void) close (shin); - - out0: - if (rerrno) - errno = rerrno; - return rc; -} - - - -void -run_print (fp) - FILE *fp; -{ - int i; - void (*outfn) PROTO ((const char *, size_t)); - - if (fp == stderr) - outfn = cvs_outerr; - else if (fp == stdout) - outfn = cvs_output; - else - { - error (1, 0, "internal error: bad argument to run_print"); - /* Solely to placate gcc -Wall. - FIXME: it'd be better to use a function named `fatal' that - is known never to return. Then kludges wouldn't be necessary. */ - outfn = NULL; - } - - for (i = 0; i < run_argc; i++) - { - (*outfn) ("'", 1); - (*outfn) (run_argv[i], 0); - (*outfn) ("'", 1); - if (i != run_argc - 1) - (*outfn) (" ", 1); - } -} - -/* Return value is NULL for error, or if noexec was set. If there was an - error, return NULL and I'm not sure whether errno was set (the Red Hat - Linux 4.1 popen manpage was kind of vague but discouraging; and the noexec - case complicates this even aside from popen behavior). */ - -FILE * -run_popen (cmd, mode) - const char *cmd; - const char *mode; -{ - if (trace) - (void) fprintf (stderr, "%s-> run_popen(%s,%s)\n", - CLIENT_SERVER_STR, cmd, mode); - if (noexec) - return (NULL); - - return (popen (cmd, mode)); -} - - - -/* Work around an OpenSSH problem: it can put its standard file - descriptors into nonblocking mode, which will mess us up if we - share file descriptions with it. The simplest workaround is - to create an intervening process between OpenSSH and the - actual stderr. */ - -static void -work_around_openssh_glitch (void) -{ - pid_t pid; - int stderr_pipe[2]; - struct stat sb; - - /* Do nothing unless stderr is a file that is affected by - nonblocking mode. */ - if (!(fstat (STDERR_FILENO, &sb) == 0 - && (S_ISFIFO (sb.st_mode) || S_ISSOCK (sb.st_mode) - || S_ISCHR (sb.st_mode) || S_ISBLK (sb.st_mode)))) - return; - - if (pipe (stderr_pipe) < 0) - error (1, errno, "cannot create pipe"); - pid = fork (); - if (pid < 0) - error (1, errno, "cannot fork"); - if (pid != 0) - { - /* Still in child of original process. Act like "cat -u". */ - char buf[1 << 13]; - ssize_t inbytes; - pid_t w; - int status; - - if (close (stderr_pipe[1]) < 0) - error (1, errno, "cannot close pipe"); - - while ((inbytes = read (stderr_pipe[0], buf, sizeof buf)) != 0) - { - size_t outbytes = 0; - - if (inbytes < 0) - { - if (errno == EINTR) - continue; - error (1, errno, "reading from pipe"); - } - - do - { - ssize_t w = write (STDERR_FILENO, - buf + outbytes, inbytes - outbytes); - if (w < 0) - { - if (errno == EINTR) - w = 0; - if (w < 0) - _exit (1); - } - outbytes += w; - } - while (inbytes != outbytes); - } - - /* Done processing output from grandchild. Propagate - its exit status back to the parent. */ - while ((w = waitpid (pid, &status, 0)) == -1 && errno == EINTR) - continue; - if (w < 0) - error (1, errno, "waiting for child"); - if (!WIFEXITED (status)) - { - if (WIFSIGNALED (status)) - raise (WTERMSIG (status)); - error (1, errno, "child did not exit cleanly"); - } - _exit (WEXITSTATUS (status)); - } - - /* Grandchild of original process. */ - if (close (stderr_pipe[0]) < 0) - error (1, errno, "cannot close pipe"); - - if (stderr_pipe[1] != STDERR_FILENO) - { - if (dup2 (stderr_pipe[1], STDERR_FILENO) < 0) - error (1, errno, "cannot dup2 pipe"); - if (close (stderr_pipe[1]) < 0) - error (1, errno, "cannot close pipe"); - } -} - - - -int -piped_child (command, tofdp, fromfdp, fix_stderr) - const char **command; - int *tofdp; - int *fromfdp; - int fix_stderr; -{ - int pid; - int to_child_pipe[2]; - int from_child_pipe[2]; - - if (pipe (to_child_pipe) < 0) - error (1, errno, "cannot create pipe"); - if (pipe (from_child_pipe) < 0) - error (1, errno, "cannot create pipe"); - -#ifdef USE_SETMODE_BINARY - setmode (to_child_pipe[0], O_BINARY); - setmode (to_child_pipe[1], O_BINARY); - setmode (from_child_pipe[0], O_BINARY); - setmode (from_child_pipe[1], O_BINARY); -#endif - - pid = fork (); - if (pid < 0) - error (1, errno, "cannot fork"); - if (pid == 0) - { - if (dup2 (to_child_pipe[0], STDIN_FILENO) < 0) - error (1, errno, "cannot dup2 pipe"); - if (close (to_child_pipe[1]) < 0) - error (1, errno, "cannot close pipe"); - if (close (from_child_pipe[0]) < 0) - error (1, errno, "cannot close pipe"); - if (dup2 (from_child_pipe[1], STDOUT_FILENO) < 0) - error (1, errno, "cannot dup2 pipe"); - - if (fix_stderr) - work_around_openssh_glitch (); - - /* Okay to cast out const below - execvp don't return nohow. */ - execvp ((char *)command[0], (char **)command); - error (1, errno, "cannot exec %s", command[0]); - } - if (close (to_child_pipe[0]) < 0) - error (1, errno, "cannot close pipe"); - if (close (from_child_pipe[1]) < 0) - error (1, errno, "cannot close pipe"); - - *tofdp = to_child_pipe[1]; - *fromfdp = from_child_pipe[0]; - return pid; -} - - -void -close_on_exec (fd) - int fd; -{ -#ifdef F_SETFD - if (fcntl (fd, F_SETFD, 1) == -1) - error (1, errno, "can't set close-on-exec flag on %d", fd); -#endif -} diff --git a/contrib/cvs/src/sanity.sh b/contrib/cvs/src/sanity.sh deleted file mode 100755 index dbcae19..0000000 --- a/contrib/cvs/src/sanity.sh +++ /dev/null @@ -1,30254 +0,0 @@ -#! /bin/sh -: -# sanity.sh -- a growing testsuite for cvs. -# -# The copyright notice said: "Copyright (C) 1992, 1993 Cygnus Support" -# I'm not adding new copyright notices for new years as our recent -# practice has been to include copying terms without copyright notices. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# Original Author: K. Richard Pixley - -# usage: -usage () -{ - echo "Usage: `basename $0` --help" - echo "Usage: `basename $0` [-eklrv] [-f FROM-TEST] [-h HOSTNAME] CVS-TO-TEST [TESTS-TO-RUN...]" -} - -exit_usage () -{ - usage 1>&2 - exit 2 -} - -exit_help () -{ - usage - echo - echo "-H|--help Display this text." - echo "-e|--skipfail Treat tests that would otherwise be nonfatally skipped" - echo " for reasons like missing tools as failures, exiting" - echo " with an error message. Also treat warnings as" - echo " failures." - echo "-f FROM-TEST Run TESTS-TO-RUN, skipping all tests in the list before" - echo " FROM-TEST." - echo "-h HOSTNAME Use :ext:HOSTNAME to run remote tests rather than" - echo " :fork:. Implies --remote and assumes that \$TESTDIR" - echo " resolves to the same directory on both the client and" - echo " the server." - echo "-k|--keep Try to keep directories created by individual tests" - echo " around, exiting after the first test which supports" - echo " --keep." - echo "-l|--link-root" - echo " Test CVS using a symlink to a real CVSROOT." - echo "-r|--remote Test remote instead of local cvs." - echo "-v|--verbose List test names as they are executed." - echo - echo "CVS-TO-TEST The path to the CVS executable to be tested." - echo "TESTS-TO-RUN The names of the tests to run (defaults to all tests)." - exit 2 -} - -# See TODO list at end of file. - -# required to make this script work properly. -unset CVSREAD - -# This will cause malloc to run slower but should also catch some common errors -# when CVS is linked with glibc 2.x. -MALLOC_CHECK_=2; export MALLOC_CHECK_ - -# We want to invoke a predictable set of i18n behaviors, not whatever -# the user running this script might have set. -# In particular: -# 'sort' and tabs and spaces (LC_COLLATE). -# Messages from getopt (LC_MESSAGES) (in the future, CVS itself might -# also alter its messages based on LC_MESSAGES). -LANG=C -export LANG -LC_ALL=C -export LC_ALL - - -# -# Initialize the test counts. -# -passed=0 -skipped=0 -warnings=0 - - - -# -# read our options -# -unset fromtest -unset remotehost -keep=false -linkroot=false -remote=false -skipfail=false -verbose=false -while getopts ef:h:Hklrv-: option ; do - # convert the long opts to short opts - if test x$option = x-; then - case "$OPTARG" in - [hH]|[hH][eE]|[hH][eE][lL]|[hH][eE][lL][pP]) - option=H; - OPTARG= - ;; - [kK]|[kK][eE]|[kK][eE][eE]|[kK][eE][eE][pP]) - option=k; - OPTARG= - ;; - l|li|lin|link|link-|link-r]|link-ro|link-roo|link-root) - option=l; - OPTARG= - ;; - [rR]|[rR][eE]|[rR][eE][mM]|[rR][eE][mM][oO]|[rR][eE][mM][oO][tT]|[rR][eE][mM][oO][tT][eE]) - option=k; - OPTARG= - ;; - s|sk|ski|skip|skipf|skipfa|skipfai|skipfail) - option=e - OPTARG= - ;; - v|ve|ver|verb|verbo|verbos|verbose) - option=v - OPTARG= - ;; - *) - option=\? - OPTARG= - esac - fi - case "$option" in - e) - skipfail=: - ;; - f) - fromtest="$OPTARG" - ;; - h) - # Set a remotehost to run the remote tests on via :ext: - # Implies `-r' and assumes that $TESTDIR resolves to the same - # directory on the client and the server. - remotehost="$OPTARG" - remote=: - ;; - H) - exit_help - ;; - k) - # The -k (keep) option will eventually cause all the tests to - # leave around the contents of the /tmp directory; right now only - # some implement it. Not originally intended to be useful with - # more than one test, but this should work if each test uses a - # uniquely named dir (use the name of the test). - keep=: - ;; - l) - linkroot=: - ;; - r) - remote=: - ;; - v) - verbose=: - ;; - \?) - exit_usage - ;; - esac -done - -# boot the arguments we used above -while test $OPTIND -gt 1 ; do - shift - OPTIND=`expr $OPTIND - 1` -done - -# Use full path for CVS executable, so that CVS_SERVER gets set properly -# for remote. -case $1 in -"") - exit_usage - ;; -/*) - testcvs=$1 - ;; -*) - testcvs=`pwd`/$1 - ;; -esac -shift - -# If $remotehost is set, warn if $TESTDIR isn't since we are pretty sure -# that its default value of `/tmp/cvs-sanity' will not resolve to the same -# directory on two different machines. -if test -n "$remotehost" && test -z "$TESTDIR"; then - echo "WARNING: CVS server hostname is set and \$TESTDIR is not. If" >&2 - echo "$remotehost is not the local machine, then it is unlikely that" >&2 - echo "the default value assigned to \$TESTDIR will resolve to the same" >&2 - echo "directory on both this client and the CVS server." >&2 -fi - - - -### -### GUTS -### - -# "debugger" -#set -x - -echo 'This test should produce no other output than this message, and a final "OK".' -echo '(Note that the test can take an hour or more to run and periodically stops' -echo 'for as long as one minute. Do not assume there is a problem just because' -echo 'nothing seems to happen for a long time. If you cannot live without' -echo 'running status, use the -v option or try the command:' -echo "\`tail -f check.log' from another window.)" - -# Regexp to match what CVS will call itself in output that it prints. -# FIXME: we don't properly quote this--if the name contains . we'll -# just spuriously match a few things; if the name contains other regexp -# special characters we are probably in big trouble. -PROG=`basename ${testcvs}` - -# Match the hostname -hostname="[-_.a-zA-Z0-9]*" - -# Regexp to match the name of a temporary file (from cvs_temp_name). -# This appears in certain diff output. -tempname="[-a-zA-Z0-9/.%_]*" - -# Regexp to match a date in RFC822 format (as amended by RFC1123). -RFCDATE="[a-zA-Z0-9 ][a-zA-Z0-9 ]* [0-9:][0-9:]* -0000" -RFCDATE_EPOCH="1 Jan 1970 00:00:00 -0000" - -# Regexp to match a date in standard Unix format as used by rdiff -# FIXCVS: There's no reason for rdiff to use a different date format -# than diff does -DATE="[a-zA-Z]* [a-zA-Z]* [ 1-3][0-9] [0-9:]* [0-9]*" - -# Which directories should Which and find_tool search for executables? -SEARCHPATH=$PATH:/usr/local/bin:/usr/contrib/bin:/usr/contrib:/usr/gnu/bin:/local/bin:/local/gnu/bin:/gnu/bin:/sw/bin:/usr/pkg/bin - -# Do not assume that `type -p cmd` is portable -# Usage: Which [-a] [-x|-f|-r] prog [$SEARCHPATH:/with/directories:/to/search] -Which() { - # Optional first argument for file type, defaults to -x. - # Second argument is the file or directory to be found. - # Third argument is the PATH to search. - # By default, print only the first file that matches, - # -a will cause all matches to be printed. - notevery=: - if [ "x$1" = "x-a" ]; then notevery=false; shift; fi - case "$1" in - -*) t=$1; shift ;; - *) t=-x ;; - esac - case "$1" in - # FIXME: Someday this may need to be fixed - # to deal better with C:\some\path\to\ssh values... - /*) test $t $1 && echo $1 ;; - *) for d in `IFS=:; echo ${2-$SEARCHPATH}` - do - test $t $d/$1 && { echo $d/$1; if $notevery; then break; fi; } - done - ;; - esac -} - - -# On cygwin32, we may not have /bin/sh. -if test -r /bin/sh; then - TESTSHELL="/bin/sh" -else - TESTSHELL=`Which -f sh` - if test ! -r "$TESTSHELL"; then - TESTSHELL="/bin/sh" - fi -fi - -# FIXME: try things (what things? checkins?) without -m. -# -# Some of these tests are written to expect -Q. But testing with -# -Q is kind of bogus, it is not the way users actually use CVS (usually). -# So new tests probably should invoke ${testcvs} directly, rather than ${CVS}. -# and then they've obviously got to do something with the output.... -# -CVS="${testcvs} -Q" - -LOGFILE=`pwd`/check.log - -# Save the previous log in case the person running the tests decides -# they want to look at it. The extension ".plog" is chosen for consistency -# with dejagnu. -if test -f check.log; then - mv check.log check.plog -fi - -# Create the log file so check.log can be tailed almost immediately after -# this script is started. Otherwise it can take up to a minute or two before -# the log file gets created when $remotehost is specified on some systems, -# which makes for a lot of failed `tail -f' attempts. -touch check.log - -# Workaround any X11Forwarding by ssh. Otherwise this text: -# Warning: No xauth data; using fake authentication data for X11 forwarding. -# has been known to end up in the test results below -# causing the test to fail. -[ -n "$DISPLAY" ] && unset DISPLAY - -# The default value of /tmp/cvs-sanity for TESTDIR is dubious, -# because it loses if two people/scripts try to run the tests -# at the same time. Some possible solutions: -# 1. Use /tmp/cvs-test$$. One disadvantage is that the old -# cvs-test* directories would pile up, because they wouldn't -# necessarily get removed. -# 2. Have everyone/everything running the testsuite set -# TESTDIR to some appropriate directory. -# 3. Have the default value of TESTDIR be some variation of -# `pwd`/cvs-sanity. The biggest problem here is that we have -# been fairly careful to test that CVS prints in messages the -# actual pathnames that we pass to it, rather than a different -# pathname for the same directory, as may come out of `pwd`. -# So this would be lost if everything was `pwd`-based. I suppose -# if we wanted to get baroque we could start making symlinks -# to ensure the two are different. -: ${CVS_RSH=rsh}; export CVS_RSH -if test -n "$remotehost"; then - # We need to set $tmp on the server since $TMPDIR is compared against - # messages generated by the server. - tmp=`$CVS_RSH $remotehost 'cd /tmp; /bin/pwd || pwd' 2>/dev/null` - if test $? != 0; then - echo "$CVS_RSH $remotehost failed." >&2 - exit 1 - fi -else - tmp=`(cd /tmp; /bin/pwd || pwd) 2>/dev/null` -fi - -# Now: -# 1) Set TESTDIR if it's not set already -# 2) Remove any old test remnants -# 3) Create $TESTDIR -# 4) Normalize TESTDIR with `cd && (/bin/pwd || pwd)` -# (This will match CVS output later) -: ${TESTDIR=$tmp/cvs-sanity} -# clean any old remnants (we need the chmod because some tests make -# directories read-only) -if test -d ${TESTDIR}; then - chmod -R a+wx ${TESTDIR} - rm -rf ${TESTDIR} -fi -# These exits are important. The first time I tried this, if the `mkdir && cd` -# failed then the build directory would get blown away. Some people probably -# wouldn't appreciate that. -mkdir ${TESTDIR} || exit 1 -cd ${TESTDIR} || exit 1 -# Ensure $TESTDIR is absolute -if echo "${TESTDIR}" |grep '^[^/]'; then - # Don't resolve this unless we have to. This keeps symlinks intact. This - # is important at least when testing using -h $remotehost, because the same - # value for $TESTDIR must resolve to the same directory on the client and - # the server and we likely used Samba, and possibly symlinks, to do this. - TESTDIR=`(/bin/pwd || pwd) 2>/dev/null` -fi - -if test -z "${TESTDIR}" || echo "${TESTDIR}" |grep '^[^/]'; then - echo "Unable to resolve TESTDIR to an absolute directory." >&2 - exit 1 -fi -cd ${TESTDIR} - -# Now set $TMPDIR if the user hasn't overridden it. -# -# We use a $TMPDIR under $TESTDIR by default so that two tests may be run at -# the same time without bumping heads without requiring the user to specify -# more than $TESTDIR. See the test for leftover cvs-serv* directories near the -# end of this script at the end of "The big loop". -: ${TMPDIR=$TESTDIR/tmp} -export TMPDIR -if test -d $TMPDIR; then :; else - mkdir $TMPDIR -fi - -# Make sure various tools work the way we expect, or try to find -# versions that do. -: ${AWK=awk} -: ${EXPR=expr} -: ${ID=id} -: ${TR=tr} - -# Keep track of tools that are found, but do NOT work as we hope -# in order to avoid them in future -badtools= -set_bad_tool () -{ - badtools=$badtools:$1 -} -is_bad_tool () -{ - case ":$badtools:" in *:$1:*) return 0 ;; *) return 1 ; esac -} - -version_test () -{ - vercmd=$1 - verbad=: - if RES=`$vercmd --version &1`; then - if test "X$RES" != "X--version" && test "X$RES" != "X" ; then - echo "$RES" - verbad=false - fi - fi - if $verbad; then - echo "The command \`$vercmd' does not support the --version option." - fi - # It does not really matter that --version is not supported - return 0 -} - -# Try to find a tool that satisfies all of the tests. -# Usage: list:of:colon:separated:alternatives test1 test2 test3 test4... -# Example: find_tool awk:gawk:nawk awk_tooltest1 awk_tooltest2 -find_tool () -{ - default_TOOL=$1 - echo find_tool: ${1+"$@"} >>$LOGFILE - cmds="`IFS=:; echo $1`"; shift; tooltests="${1+$@}" - if test -z "$tooltests"; then tooltests=version_test; fi - clist=; for cmd in $cmds; do clist="$clist `Which -a $cmd`"; done - # Make sure the default tool is just the first real command name - for default_TOOL in $clist `IFS=:; echo $default_TOOL`; do break; done - TOOL="" - for trytool in $clist ; do - pass=: - for tooltest in $tooltests; do - result=`eval $tooltest $trytool` - rc=$? - echo "Running $tooltest $trytool" >>$LOGFILE - if test -n "$result"; then - echo "$result" >>$LOGFILE - fi - if test "$rc" = "0"; then - echo "PASS: $tooltest $trytool" >>$LOGFILE - elif test "$rc" = "77"; then - echo "MARGINAL: $tooltest $trytool; rc=$rc" >>$LOGFILE - TOOL=$trytool - pass=false - else - set_bad_tool $trytool - echo "FAIL: $tooltest $trytool; rc=$rc" >>$LOGFILE - pass=false - fi - done - if $pass; then - echo $trytool - return 0 - fi - done - if test -n "$TOOL"; then - echo "Notice: The default version of \`$default_TOOL' is defective." >>$LOGFILE - echo "using \`$TOOL' and hoping for the best." >>$LOGFILE - echo "Notice: The default version of \`$default_TOOL' is defective." >&2 - echo "using \`$TOOL' and hoping for the best." >&2 - echo $TOOL - else - echo $default_TOOL - fi -} - -id_tool_test () -{ - id=$1 - if $id -u >/dev/null 2>&1 && $id -un >/dev/null 2>&1; then - return 0 - else - echo "Running these tests requires an \`id' program that understands the" - echo "-u and -n flags. Make sure that such an id (GNU, or many but not" - echo "all vendor-supplied versions) is in your path." - return 1 - fi -} - -ID=`find_tool id version_test id_tool_test` -echo "Using ID=$ID" >>$LOGFILE - -# You can't run CVS as root; print a nice error message here instead -# of somewhere later, after making a mess. -for pass in false :; do - case "`$ID -u 2>/dev/null`" in - "0") - echo "Test suite does not work correctly when run as root" >&2 - exit 1 - ;; - - *) - break - ;; - esac -done - -# Cause NextStep 3.3 users to lose in a more graceful fashion. -expr_tooltest1 () -{ -expr=$1 -if $expr 'abc -def' : 'abc -def' >/dev/null; then - # good, it works - return 0 -else - echo 'Running these tests requires an "expr" program that can handle' - echo 'multi-line patterns. Make sure that such an expr (GNU, or many but' - echo 'not all vendor-supplied versions) is in your path.' - return 1 -fi -} - -# Warn SunOS, SysVr3.2, etc., users that they may be partially losing -# if we can't find a GNU expr to ease their troubles... -expr_tooltest2 () -{ -expr=$1 -if $expr 'a -b' : 'a -c' >/dev/null; then - echo 'WARNING: you are using a version of expr that does not correctly' - echo 'match multi-line patterns. Some tests may spuriously pass or fail.' - echo 'You may wish to make sure GNU expr is in your path.' - return 1 -else - return 0 -fi -} - -expr_create_bar () -{ -echo 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' >${TESTDIR}/foo -cat ${TESTDIR}/foo ${TESTDIR}/foo ${TESTDIR}/foo ${TESTDIR}/foo >${TESTDIR}/bar -cat ${TESTDIR}/bar ${TESTDIR}/bar ${TESTDIR}/bar ${TESTDIR}/bar >${TESTDIR}/foo -cat ${TESTDIR}/foo ${TESTDIR}/foo ${TESTDIR}/foo ${TESTDIR}/foo >${TESTDIR}/bar -rm -f ${TESTDIR}/foo -} - -expr_tooltest3 () -{ -expr=$1 -# More SunOS lossage... -test ! -f ${TESTDIR}/bar && expr_create_bar -if $expr "`cat ${TESTDIR}/bar`" : "`cat ${TESTDIR}/bar`" >/dev/null; then - : good, it works -else - echo 'WARNING: you are using a version of expr that does not correctly' - echo 'match large patterns. Some tests may spuriously pass or fail.' - echo 'You may wish to make sure GNU expr is in your path.' - return 1 -fi -if $expr "`cat ${TESTDIR}/bar`x" : "`cat ${TESTDIR}/bar`y" >/dev/null; then - echo 'WARNING: you are using a version of expr that does not correctly' - echo 'match large patterns. Some tests may spuriously pass or fail.' - echo 'You may wish to make sure GNU expr is in your path.' - return 1 -fi -# good, it works -return 0 -} - -# That we should have to do this is total bogosity, but GNU expr -# version 1.9.4-1.12 uses the emacs definition of "$" instead of the unix -# (e.g. SunOS 4.1.3 expr) one. Rumor has it this will be fixed in the -# next release of GNU expr after 1.12 (but we still have to cater to the old -# ones for some time because they are in many linux distributions). -ENDANCHOR="$" -expr_set_ENDANCHOR () -{ -expr=$1 -ENDANCHOR="$" -if $expr 'abc -def' : 'abc$' >/dev/null; then - ENDANCHOR='\'\' - echo "Notice: An ENDANCHOR of dollar does not work." - echo "Using a workaround for GNU expr versions 1.9.4 thru 1.12" -fi -return 0 -} - -# Work around another GNU expr (version 1.10-1.12) bug/incompatibility. -# "." doesn't appear to match a newline (it does with SunOS 4.1.3 expr). -# Note that the workaround is not a complete equivalent of .* because -# the first parenthesized expression in the regexp must match something -# in order for expr to return a successful exit status. -# Rumor has it this will be fixed in the -# next release of GNU expr after 1.12 (but we still have to cater to the old -# ones for some time because they are in many linux distributions). -DOTSTAR='.*' -expr_set_DOTSTAR () -{ -expr=$1 -DOTSTAR='.*' -if $expr 'abc -def' : "a${DOTSTAR}f" >/dev/null; then - : good, it works -else - DOTSTAR='\(.\| -\)*' - echo "Notice: DOTSTAR changed from sane \`.*' value to \`$DOTSTAR\`" - echo "to workaround GNU expr version 1.10 thru 1.12 bug where \`.'" - echo "does not match a newline." -fi -return 0 -} - -# Now that we have DOTSTAR, make sure it works with big matches -expr_tooltest_DOTSTAR () -{ -expr=$1 -test ! -f ${TESTDIR}/bar && expr_create_bar -if $expr "`cat ${TESTDIR}/bar`" : "${DOTSTAR}xyzABC${DOTSTAR}$" >/dev/null; then - # good, it works - return 0 -else - echo 'WARNING: you are using a version of expr that does not correctly' - echo 'match large patterns. Some tests may spuriously pass or fail.' - echo 'You may wish to make sure GNU expr is in your path.' - return 77 -fi -} - -# FreeBSD 5.2 and 6.1 support 'expr [-e] expression' -# They get confused unless '--' is used before the expressions -# when those expressions begin with a '-' character, such as the -# output of an ls -l command. The EXPR_COMPAT environment variable may -# be used to go back to the non-POSIX behavior as an alternative. -# (GNU expr appears to accept the '--' argument and work correctly or -# not have it and still get the results we want.) -exprDASHDASH='false' -expr_set_DASHDASH () -{ -expr=$1 -exprDASHDASH='false' -# Not POSIX, but works on a lot of expr versions. -if $expr "-rw-rw-r--" : "-rw-rw-r--" >/dev/null 2>&1; then - # good, it works - return 0 -else - # Do things in the POSIX manner. - if $expr -- "-rw-rw-r--" : "-rw-rw-r--" >/dev/null 2>&1; then - exprDASHDASH=':' - return 0 - else - echo 'WARNING: Your $expr does not correctly handle' - echo 'leading "-" characters in regular expressions to' - echo 'be matched. You may wish to see if there is an' - echo 'environment variable or other setting to allow' - echo 'POSIX functionality to be enabled.' - return 77 - fi -fi -} - - -EXPR=`find_tool ${EXPR}:gexpr \ - version_test expr_tooltest1 expr_tooltest2 expr_tooltest3 \ -expr_set_ENDANCHOR expr_set_DOTSTAR expr_tooltest_DOTSTAR` - -# Set the ENDANCHOR and DOTSTAR for the chosen expr version. -expr_set_ENDANCHOR ${EXPR} >/dev/null -expr_tooltest_DOTSTAR ${EXPR} >/dev/null - -# Is $EXPR a POSIX or non-POSIX implementation -# with regard to command-line arguments? -expr_set_DASHDASH ${EXPR} -$exprDASHDASH && EXPR="$EXPR --" - -echo "Using EXPR=$EXPR" >>$LOGFILE -echo "Using ENDANCHOR=$ENDANCHOR" >>$LOGFILE -echo "Using DOTSTAR=$DOTSTAR" >>$LOGFILE - -# Cleanup -rm -f ${TESTDIR}/bar - -# Work around yet another GNU expr (version 1.10) bug/incompatibility. -# "+" is a special character, yet for unix expr (e.g. SunOS 4.1.3) -# it is not. I doubt that POSIX allows us to use \+ and assume it means -# (non-special) +, so here is another workaround -# Rumor has it this will be fixed in the -# next release of GNU expr after 1.12 (but we still have to cater to the old -# ones for some time because they are in many linux distributions). -PLUS='+' -if $EXPR 'a +b' : "a ${PLUS}b" >/dev/null; then - : good, it works -else - PLUS='\+' -fi - -# Likewise, for ? -QUESTION='?' -if $EXPR 'a?b' : "a${QUESTION}b" >/dev/null; then - : good, it works -else - QUESTION='\?' -fi - -# Now test the username to make sure it contains only valid characters -username=`$ID -un` -if $EXPR "${username}" : "${username}" >/dev/null; then - : good, it works -else - echo "Test suite does not work correctly when run by a username" >&2 - echo "containing regular expression meta-characters." >&2 - exit 1 -fi - -# Only 8 characters of $username appear in some output. -if test `echo $username |wc -c` -gt 8; then - username8=`echo $username |sed 's/^\(........\).*/\1/'` -else - username8=$username -fi - -# Rarely, we need to match any username, not just the name of the user -# running this test. -# -# I'm not really sure what characters should be here. a-zA-Z obviously. -# People complained when 0-9 were not allowed in usernames. Other than that -# I'm not sure. -anyusername="[-a-zA-Z0-9][-a-zA-Z0-9]*" - -# now make sure that tr works on NULs -tr_tooltest1 () -{ -tr=$1 -if $EXPR `echo "123" | $tr '2' '\0'` : "123" >/dev/null 2>&1; then - echo 'Warning: you are using a version of tr which does not correctly' - echo 'handle NUL bytes. Some tests may spuriously pass or fail.' - echo 'You may wish to make sure GNU tr is in your path.' - return 77 -fi -# good, it works -return 0 -} - -TR=`find_tool ${TR}:gtr version_test tr_tooltest1` -echo "Using TR=$TR" >>$LOGFILE - -# Awk testing - -awk_tooltest1 () -{ -awk=$1 -$awk 'BEGIN {printf("one\ntwo\nthree\nfour\nfive\nsix")}' abc -if $EXPR "`cat abc`" : \ -'one -two -three -four -five -six'; then - rm abc - return 0 -else - rm abc - echo "Notice: awk BEGIN clause or printf is not be working properly." - return 1 -fi -} - -# Format item %c check -awk_tooltest2 () -{ -awk=$1 -$awk 'BEGIN { printf "%c%c%c", 2, 3, 4 }' abc -if $EXPR "`cat abc`" : "123" ; then - : good, found it -else - echo "Notice: awk format %c string may not be working properly." - rm abc - return 77 -fi -rm abc -return 0 -} - -AWK=`find_tool gawk:nawk:awk version_test awk_tooltest1 awk_tooltest2` -echo "Using AWK=$AWK" >>$LOGFILE - -# Test that $1 works as a remote shell. If so, set $host, $CVS_RSH, & -# $save_CVS_RSH to match and return 0. Otherwise, set $skipreason and return -# 77. -depends_on_rsh () -{ - host=${remotehost-"`hostname`"} - result=`$1 $host 'echo test'` - rc=$? - if test $? != 0 || test "x$result" != "xtest"; then - skipreason="\`$1 $host' failed rc=$rc result=$result" - return 77 - fi - - save_CVS_RSH=$CVS_RSH - CVS_RSH=$1; export CVS_RSH - return 0 -} - -# Find a usable SSH. When a usable ssh is found, set $host, $CVS_RSH, and -# $save_CVS_RSH and return 0. Otherwise, set $skipreason and return 77. -depends_on_ssh () -{ - case "$CVS_RSH" in - *ssh*|*putty*) - tryssh=`Which $CVS_RSH` - if [ ! -n "$tryssh" ]; then - skipreason="Unable to find CVS_RSH=$CVS_RSH executable" - return 77 - elif [ ! -x "$tryssh" ]; then - skipreason="Unable to execute $tryssh program" - return 77 - fi - ;; - *) - # Look in the user's PATH for "ssh" - tryssh=`Which ssh` - if test ! -r "$tryssh"; then - skipreason="Unable to find ssh program" - return 77 - fi - ;; - esac - - depends_on_rsh "$tryssh" - return $? -} - -pass () -{ - echo "PASS: $1" >>${LOGFILE} - passed=`expr $passed + 1` -} - -# Like skip(), but don't fail when $skipfail is set. -skip_always () -{ - echo "SKIP: $1${2+ ($2)}" >>$LOGFILE - skipped=`expr $skipped + 1` -} - -skip () -{ - if $skipfail; then - fail "$1${2+ ($2)}" - else - echo "SKIP: $1${2+ ($2)}" >>$LOGFILE - fi - skipped=`expr $skipped + 1` -} - -warn () -{ - if $skipfail; then - fail "$1${2+ ($2)}" - else - echo "WARNING: $1${2+ ($2)}" >>$LOGFILE - fi - warnings=`expr $warnings + 1` -} - -# Convenience function for skipping tests run only in local mode. -localonly () -{ - skip_always $1 "only tested in local mode" -} - -fail () -{ - echo "FAIL: $1" | tee -a ${LOGFILE} - echo "*** Please see the \`TESTS' and \`check.log' files for more information." >&2 - # This way the tester can go and see what remnants were left - exit 1 -} - -verify_tmp_empty () -{ - # Test our temp directory for cvs-serv* directories and cvsXXXXXX temp - # files. We would like to not leave any behind. - if $remote && ls $TMPDIR/cvs-serv* >/dev/null 2>&1; then - # A true value means ls found files/directories with these names. - # Give the server some time to finish, then retry. - sleep 1 - if ls $TMPDIR/cvs-serv* >/dev/null 2>&1; then - warn "$1" "Found cvs-serv* directories in $TMPDIR." - # The above will exit if $skipfail - rm -rf $TMPDIR/cvs-serv* - fi - fi - if ls $TMPDIR/cvs?????? >/dev/null 2>&1; then - # A true value means ls found files/directories with these names. - warn "$1" "Found cvsXXXXXX temp files in $TMPDIR." - # The above will exit if $skipfail - rm -f ls $TMPDIR/cvs?????? - fi -} - -# Restore changes to CVSROOT admin files. -restore_adm () -{ - rm -rf $CVSROOT_DIRNAME/CVSROOT - cp -Rp $TESTDIR/CVSROOT.save $CVSROOT_DIRNAME/CVSROOT -} - -# See dotest and dotest_fail for explanation (this is the parts -# of the implementation common to the two). -dotest_internal () -{ - if $EXPR "`cat ${TESTDIR}/dotest.tmp`" : "$3${ENDANCHOR}" >/dev/null; then - # Why, I hear you ask, do we write this to the logfile - # even when the test passes? The reason is that the test - # may give us the regexp which we were supposed to match, - # but sometimes it may be useful to look at the exact - # text which was output. For example, suppose one wants - # to grep for a particular warning, and make _sure_ that - # CVS never hits it (even in cases where the tests might - # match it with .*). Or suppose one wants to see the exact - # date format output in a certain case (where the test will - # surely use a somewhat non-specific pattern). - cat ${TESTDIR}/dotest.tmp >>${LOGFILE} - pass "$1" - verify_tmp_empty "$1" - # expr can't distinguish between "zero characters matched" and "no match", - # so special-case it. - elif test -z "$3" && test ! -s ${TESTDIR}/dotest.tmp; then - pass "$1" - verify_tmp_empty "$1" - elif test x"$4" != x; then - if $EXPR "`cat ${TESTDIR}/dotest.tmp`" : "$4${ENDANCHOR}" >/dev/null; then - cat ${TESTDIR}/dotest.tmp >>${LOGFILE} - pass "$1" - verify_tmp_empty "$1" - else - echo "** expected: " >>${LOGFILE} - echo "$3" >>${LOGFILE} - echo "$3" > ${TESTDIR}/dotest.ex1 - echo "** or: " >>${LOGFILE} - echo "$4" >>${LOGFILE} - echo "$4" > ${TESTDIR}/dotest.ex2 - echo "** got: " >>${LOGFILE} - cat ${TESTDIR}/dotest.tmp >>${LOGFILE} - fail "$1" - fi - else - echo "** expected: " >>${LOGFILE} - echo "$3" >>${LOGFILE} - echo "$3" > ${TESTDIR}/dotest.exp - echo "** got: " >>${LOGFILE} - cat ${TESTDIR}/dotest.tmp >>${LOGFILE} - fail "$1" - fi -} - -dotest_all_in_one () -{ - if $EXPR "`cat ${TESTDIR}/dotest.tmp`" : \ - "`cat ${TESTDIR}/dotest.exp`" >/dev/null; then - return 0 - fi - return 1 -} - -# WARNING: this won't work with REs that match newlines.... -# -dotest_line_by_line () -{ - line=1 - while [ $line -le `wc -l <${TESTDIR}/dotest.tmp` ] ; do - if $EXPR "`sed -n ${line}p ${TESTDIR}/dotest.tmp`" : \ - "`sed -n ${line}p ${TESTDIR}/dotest.exp`" >/dev/null; then - : - elif test -z "`sed -n ${line}p ${TESTDIR}/dotest.tmp`" && - test -z "`sed -n ${line}p ${TESTDIR}/dotest.exp`"; then - : - else - echo "Line $line:" >> ${LOGFILE} - echo "**** expected: " >>${LOGFILE} - sed -n ${line}p ${TESTDIR}/dotest.exp >>${LOGFILE} - echo "**** got: " >>${LOGFILE} - sed -n ${line}p ${TESTDIR}/dotest.tmp >>${LOGFILE} - unset line - return 1 - fi - line=`expr $line + 1` - done - unset line - return 0 -} - -# If you are having trouble telling which line of a multi-line -# expression is not being matched, replace calls to dotest_internal() -# with calls to this function: -# -dotest_internal_debug () -{ - if test -z "$3"; then - if test -s ${TESTDIR}/dotest.tmp; then - echo "** expected: " >>${LOGFILE} - echo "$3" >>${LOGFILE} - echo "$3" > ${TESTDIR}/dotest.exp - rm -f ${TESTDIR}/dotest.ex2 - echo "** got: " >>${LOGFILE} - cat ${TESTDIR}/dotest.tmp >>${LOGFILE} - fail "$1" - else - pass "$1" - verify_tmp_empty "$1" - fi - else - echo "$3" > ${TESTDIR}/dotest.exp - if dotest_line_by_line "$1" "$2"; then - pass "$1" - verify_tmp_empty "$1" - else - if test x"$4" != x; then - mv ${TESTDIR}/dotest.exp ${TESTDIR}/dotest.ex1 - echo "$4" > ${TESTDIR}/dotest.exp - if dotest_line_by_line "$1" "$2"; then - pass "$1" - verify_tmp_empty "$1" - else - mv ${TESTDIR}/dotest.exp ${TESTDIR}/dotest.ex2 - echo "** expected: " >>${LOGFILE} - echo "$3" >>${LOGFILE} - echo "** or: " >>${LOGFILE} - echo "$4" >>${LOGFILE} - echo "** got: " >>${LOGFILE} - cat ${TESTDIR}/dotest.tmp >>${LOGFILE} - fail "$1" - fi - else - echo "** expected: " >>${LOGFILE} - echo "$3" >>${LOGFILE} - echo "** got: " >>${LOGFILE} - cat ${TESTDIR}/dotest.tmp >>${LOGFILE} - fail "$1" - fi - fi - fi -} - -# Usage: -# dotest TESTNAME COMMAND OUTPUT [OUTPUT2] -# TESTNAME is the name used in the log to identify the test. -# COMMAND is the command to run; for the test to pass, it exits with -# exitstatus zero. -# OUTPUT is a regexp which is compared against the output (stdout and -# stderr combined) from the test. It is anchored to the start and end -# of the output, so should start or end with ".*" if that is what is desired. -# Trailing newlines are stripped from the command's actual output before -# matching against OUTPUT. -# If OUTPUT2 is specified and the output matches it, then it is also -# a pass (partial workaround for the fact that some versions of expr -# lack \|). -dotest () -{ - rm -f ${TESTDIR}/dotest.ex? 2>&1 - eval "$2" >${TESTDIR}/dotest.tmp 2>&1 - status=$? - if test "$status" != 0; then - cat ${TESTDIR}/dotest.tmp >>${LOGFILE} - echo "exit status was $status" >>${LOGFILE} - fail "$1" - fi - dotest_internal "$@" -} - -# Like dotest except only 2 args and result must exactly match stdin -dotest_lit () -{ - rm -f ${TESTDIR}/dotest.ex? 2>&1 - eval "$2" >${TESTDIR}/dotest.tmp 2>&1 - status=$? - if test "$status" != 0; then - cat ${TESTDIR}/dotest.tmp >>${LOGFILE} - echo "exit status was $status" >>${LOGFILE} - fail "$1" - fi - cat >${TESTDIR}/dotest.exp - if cmp ${TESTDIR}/dotest.exp ${TESTDIR}/dotest.tmp >/dev/null 2>&1; then - pass "$1" - verify_tmp_empty "$1" - else - echo "** expected: " >>${LOGFILE} - cat ${TESTDIR}/dotest.exp >>${LOGFILE} - echo "** got: " >>${LOGFILE} - cat ${TESTDIR}/dotest.tmp >>${LOGFILE} - fail "$1" - fi -} - -# Like dotest except exitstatus should be nonzero. -dotest_fail () -{ - rm -f ${TESTDIR}/dotest.ex? 2>&1 - eval "$2" >${TESTDIR}/dotest.tmp 2>&1 - status=$? - if test "$status" = 0; then - cat ${TESTDIR}/dotest.tmp >>${LOGFILE} - echo "exit status was $status" >>${LOGFILE} - fail "$1" - fi - dotest_internal "$@" -} - -# Like dotest except output is sorted. -dotest_sort () -{ - rm -f ${TESTDIR}/dotest.ex? 2>&1 - eval "$2" >${TESTDIR}/dotest.tmp1 2>&1 - status=$? - if test "$status" != 0; then - cat ${TESTDIR}/dotest.tmp1 >>${LOGFILE} - echo "exit status was $status" >>${LOGFILE} - fail "$1" - fi - ${TR} ' ' ' ' < ${TESTDIR}/dotest.tmp1 | sort > ${TESTDIR}/dotest.tmp - dotest_internal "$@" -} - -# A function for fetching the timestamp of a revison of a file -getrlogdate () { - ${testcvs} -n rlog -N ${1+"$@"} | - while read token value; do - case "$token" in - date:) - echo $value | sed "s,;.*,," - break; - ;; - esac - done -} - -# Avoid picking up any stray .cvsrc, etc., from the user running the tests -mkdir home -HOME=${TESTDIR}/home; export HOME - -# Make sure this variable is not defined to anything that would -# change the format of rcs dates. Otherwise people using e.g., -# RCSINIT=-zLT get lots of spurious failures. -RCSINIT=; export RCSINIT - -# Remaining arguments are the names of tests to run. -# -# The testsuite is broken up into (hopefully manageably-sized) -# independently runnable tests, so that one can quickly get a result -# from a cvs or testsuite change, and to facilitate understanding the -# tests. - -if test x"$*" = x; then - # Basic/miscellaneous functionality - tests="version basica basicb basicc basic1 deep basic2" - tests="${tests} parseroot parseroot2 files spacefiles commit-readonly" - tests="${tests} commit-add-missing" - tests="$tests add-restricted" - tests="${tests} status" - # Branching, tagging, removing, adding, multiple directories - tests="${tests} rdiff rdiff-short" - tests="${tests} rdiff2 diff diffnl death death2 death-rtag" - tests="${tests} rm-update-message rmadd rmadd2 rmadd3 resurrection" - tests="${tests} dirs dirs2 branches branches2 tagc tagf " - tests="${tests} tag-log tag-space" - tests="${tests} rcslib multibranch import importb importc import-CVS" - tests="$tests import-quirks" - tests="${tests} update-p import-after-initial branch-after-import" - tests="${tests} join join2 join3 join4 join5 join6 join7 join8 join9" - tests="${tests} join-readonly-conflict join-admin join-admin-2" - tests="${tests} join-rm" - tests="${tests} new newb conflicts conflicts2 conflicts3 conflicts4" - tests="${tests} clean" - # Checking out various places (modules, checkout -d, &c) - tests="${tests} modules modules2 modules3 modules4 modules5 modules6" - tests="${tests} modules7 mkmodules co-d" - tests="${tests} cvsadm emptydir abspath abspath2 toplevel toplevel2" - tests="${tests} rstar-toplevel trailingslashes checkout_repository" - # Log messages, error messages. - tests="${tests} mflag editor errmsg1 errmsg2 adderrmsg opterrmsg" - # Watches, binary files, history browsing, &c. - tests="${tests} devcom devcom2 devcom3 watch4 watch5 watch6" - tests="${tests} unedit-without-baserev" - tests="${tests} ignore ignore-on-branch binfiles binfiles2 binfiles3" - tests="${tests} mcopy binwrap binwrap2" - tests="${tests} binwrap3 mwrap info taginfo config" - tests="${tests} serverpatch log log2 logopt ann ann-id" - # Repository Storage (RCS file format, CVS lock files, creating - # a repository without "cvs init", &c). - tests="${tests} crerepos crerepos-extssh rcs rcs2 rcs3 rcs4 rcs5 rcs6" - tests="$tests lockfiles backuprecover" - tests="${tests} sshstdio" - # More history browsing, &c. - tests="${tests} history" - tests="${tests} big modes modes2 modes3 stamps" - # PreservePermissions stuff: permissions, symlinks et al. - # tests="${tests} perms symlinks symlinks2 hardlinks" - # More tag and branch tests, keywords. - tests="${tests} sticky keyword keywordlog keywordname keyword2" - tests="${tests} head tagdate multibranch2 tag8k" - # "cvs admin", reserved checkouts. - tests="${tests} admin reserved" - # Nuts and bolts of diffing/merging (diff library, &c) - tests="${tests} diffmerge1 diffmerge2" - # Release of multiple directories - tests="${tests} release" - tests="${tests} recase" - # Multiple root directories and low-level protocol tests. - tests="${tests} multiroot multiroot2 multiroot3 multiroot4" - tests="$tests rmroot reposmv pserver server server2 server3" - tests="$tests client client2" - tests="${tests} dottedroot fork commit-d" -else - tests="$*" -fi - -# Now check the -f argument for validity. -if test -n "$fromtest"; then - # Don't allow spaces - they are our delimiters in tests - count=0 - for sub in $fromtest; do - count=`expr $count + 1` - done - if test $count != 1; then - echo "No such test \`$fromtest'." >&2 - exit 2 - fi - # make sure it is in $tests - case " $tests " in - *" $fromtest "*) - ;; - *) - echo "No such test \`$fromtest'." >&2 - exit 2 - ;; - esac -fi - - - -# a simple function to compare directory contents -# -# Returns: 0 for same, 1 for different -# -directory_cmp () -{ - OLDPWD=`pwd` - DIR_1=$1 - DIR_2=$2 - - cd $DIR_1 - find . -print | fgrep -v /CVS | sort > $TESTDIR/dc$$d1 - - # go back where we were to avoid symlink hell... - cd $OLDPWD - cd $DIR_2 - find . -print | fgrep -v /CVS | sort > $TESTDIR/dc$$d2 - - if diff $TESTDIR/dc$$d1 $TESTDIR/dc$$d2 >/dev/null 2>&1 - then - : - else - return 1 - fi - cd $OLDPWD - while read a - do - if test -f $DIR_1/"$a" ; then - cmp -s $DIR_1/"$a" $DIR_2/"$a" - if test $? -ne 0 ; then - return 1 - fi - fi - done < $TESTDIR/dc$$d1 - rm -f $TESTDIR/dc$$* - return 0 -} - - - -# -# The following 4 functions are used by the diffmerge1 test case. They set up, -# respectively, the four versions of the files necessary: -# -# 1. Ancestor revisions. -# 2. "Your" changes. -# 3. "My" changes. -# 4. Expected merge result. -# - -# Create ancestor revisions for diffmerge1 -diffmerge_create_older_files() { - # This test case was supplied by Noah Friedman: - cat >testcase01 <testcase02 <testcase03 <testcase04 <testcase05 <testcase06 <testcase07 <testcase08 <testcase09 <testcase10 <testcase01 <<\EOF -// Button.java - -package random.application; - -import random.util.*; - -public class Button -{ - /* Instantiates a Button with origin (0, 0) and zero width and height. - * You must call an initializer method to properly initialize the Button. - */ - public Button () - { - super (); - - _titleColor = Color.black; - _disabledTitleColor = Color.gray; - _titleFont = Font.defaultFont (); - } -} -EOF - - cat >testcase02 <<\EOF -y -a -a -a -a -EOF - - cat >testcase03 <<\EOF -x -s -a -b -s -b -s -y -EOF - - cat >testcase04 <<\EOF -s -m -s -v -s -m -s -EOF - - cat >testcase05 <<\EOF -v -s -m -s -s -s -s -s -s -s -s -s -s -v -EOF - - # Test case 6 and test case 7 both use the same input files, but they - # order the input files differently. In one case, a certain file is - # used as the older file, but in the other test case, that same file - # is used as the file which has changes. I could have put echo - # commands here, but since the echo lines would be the same as those - # in the previous function, I decided to save space and avoid repeating - # several lines of code. Instead, I merely swap the files: - mv testcase07 tmp - mv testcase06 testcase07 - mv tmp testcase06 - - # Make the date newer so that cvs thinks that the files are changed: - touch testcase06 testcase07 - - cat >testcase08 <<\EOF -no -changes -here - -First change has now added this in. - - no - changes - here - -Second change will change it here. - - no - changes - here - -Both changes move this line to the end of the file. -EOF - - cat >testcase09 <<\EOF - -m -a -{ -} -b -{ -} -c -{ -} -EOF - - cat >testcase10 <<\EOF - - fV ( BzQkV_URYYfYg ) (*jfle_Uecopdk)[0].jfle_Uecopd_KRLIep = ZpfgfYal_jUK; - - petRpY ( MtatRk ); - fV ( MtatRk != Zy ) UDTXUK_DUUZU ( BGKT_ZFDK_qjT_HGTG ); - - fV ( jfle_Uecopd_KRLIep < 16 ) - { - MtatRk = Uead_Ktz_qjT_jfle_Uecopd ( jfle_Uecopd_KRLIep, (uofd*)nRVVep ); - } - elke - { - MtatRk = ZreY_GttpfIRte_MtpeaL ( qjT_jfle_Uecopdk, qjT_jfle_Uecopd_BoRYt, HGTG_TvFD, KXbb, KXbb, &acI ); - fV ( MtatRk != Zy ) UDTXUK_DUUZU ( BGKT_ZFDK_qjT_HGTG ); - - MtatRk = MQfr_GttpfIRte_MtpeaL ( &acI, jfle_Uecopd_KRLIep * jfle_Uecopd_MfJe_fY_nEtek ); - OjZy MtatRk = Uead_GttpfIRte_MtpeaL ( &acI, jfle_Uecopd_MfJe_fY_nEtek, nRVVep ); - - Bloke_GttpfIRte_MtpeaL ( &acI ); -MTGTXM Uead_Ktz_qjT_jfle_Uecopd ( fYt Y, uofd *nRVVep ) -{ -MTGTXM MtatRk = Zy; - - fV ( Y < 16 ) - { - petRpY ( Uead_Mectopk ( noot_Uecopd.qVtHatabcY0 * noot_Uecopd.MectopkFepBlRktep + - Y * jfle_Uecopd_MfJe_fY_Mectopk, - jfle_Uecopd_MfJe_fY_Mectopk, - nRVVep ) ); - } - elke - { - petRpY ( Uead_Mectopk ( noot_Uecopd.qVtqfppHatabcY0 * noot_Uecopd.MectopkFepBlRktep + - ( Y - 16 ) * jfle_Uecopd_MfJe_fY_Mectopk, - jfle_Uecopd_MfJe_fY_Mectopk, - nRVVep ) ); - } - - petRpY ( MtatRk ); - -} - - -/**************************************************************************** -* * -* Uead Mectopk ( Uelatfue to tze cRppeYt raptftfoY ) * -* * -****************************************************************************/ - -MTGTXM Uead_Mectopk ( RfYt64 Mtapt_Mectop, RfYt64 KRL_Mectopk, uofd *nRVVep ) -{ -MTGTXM MtatRk = Zy; - - MtatRk = Uead_HfkQ ( FaptftfoY_TaIle.Uelatfue_Mectop + Mtapt_Mectop, KRL_Mectopk, nRVVep ); - - petRpY ( MtatRk ); - -} - HfkQipfte ( waYdle, /* waYdle */ - waYdleFok, /* ZVVket VpoL ktapt oV dfkQ */ - (coYkt RfYt8*) nRVVep, /* nRVVep */ - 0, /* MRrepVlRoRk KfxoYfkL */ - beYgtz /* nEtek to Apfte */ - ); - - petRpY ( Zy ); -} - -EOF -} - -# Create "my" revisions for diffmerge1 -diffmerge_create_my_files() { - # My working copy still has the Button() method, but I - # comment out some code at the top of the class. - cat >testcase01 <<\EOF -// Button.java - -package random.application; - -import random.util.*; - -public class Button -{ - /* Instantiates a Button with origin (0, 0) and zero width and height. - * You must call an initializer method to properly initialize the Button. - */ - public Button () - { - super (); - - // _titleColor = Color.black; - // _disabledTitleColor = Color.gray; - // _titleFont = Font.defaultFont (); - } - - /* Convenience constructor for instantiating a Button with - * bounds x, y, width, and height. Equivalent to - * foo = new Button (); - * foo.init (x, y, width, height); - */ - public Button (int x, int y, int width, int height) - { - this (); - init (x, y, width, height); - } -} -EOF - - cat >testcase02 <<\EOF -a -a -a -a -m -EOF - - cat >testcase03 <<\EOF -x -s -c -s -b -s -y -EOF - - cat >testcase04 <<\EOF -v -s -x -m -m -x -s -v -s -x -m -m -x -s -v -EOF - - # Note that in test case 5, there are no changes in the "mine" - # section, which explains why there is no command here which writes to - # file testcase05. - - # no changes for testcase06 - - # The two branches make the same changes: - cp ../yours/testcase07 . - - cat >testcase08 <<\EOF -no -changes -here - -First change will delete this line. - -First change will also delete this line. - - no - changes - here - -Second change has now changed it here. - - no - changes - here - -Both changes move this line to the end of the file. -EOF - - cat >testcase09 <<\EOF -m -a -{ -} -b -{ -} -c -{ -} -EOF - - cat >testcase10 <<\EOF - - petRpY ( MtatRk ); - fV ( MtatRk != Zy ) UDTXUK_DUUZU ( BGKT_ZFDK_qjT_HGTG ); - - MtatRk = MQfr_GttpfIRte_MtpeaL ( &acI, jfle_Uecopd_KRLIep * jfle_Uecopd_MfJe_fY_nEtek ); - OjZy MtatRk = Uead_GttpfIRte_MtpeaL ( &acI, jfle_Uecopd_MfJe_fY_nEtek, nRVVep ); - - Bloke_GttpfIRte_MtpeaL ( &acI ); -MTGTXM Uead_Ktz_qjT_jfle_Uecopd ( fYt Y, uofd *nRVVep ) -{ - fV ( Y < 16 ) - { - petRpY ( Uead_Mectopk ( noot_Uecopd.qVtHatabcY0 * noot_Uecopd.MectopkFepBlRktep + - Y * jfle_Uecopd_MfJe_fY_Mectopk, - jfle_Uecopd_MfJe_fY_Mectopk, - nRVVep ) ); - } - elke - { - petRpY ( Uead_Mectopk ( noot_Uecopd.qVtqfppHatabcY0 * noot_Uecopd.MectopkFepBlRktep + - ( Y - 16 ) * jfle_Uecopd_MfJe_fY_Mectopk, - jfle_Uecopd_MfJe_fY_Mectopk, - nRVVep ) ); - } - -} - - -/**************************************************************************** -* * -* Uead Mectopk ( Uelatfue to tze cRppeYt raptftfoY ) * -* * -****************************************************************************/ - -MTGTXM Uead_Mectopk ( RfYt64 Mtapt_Mectop, RfYt64 KRL_Mectopk, uofd *nRVVep ) -{ -MTGTXM MtatRk = Zy; - - MtatRk = Uead_HfkQ ( FaptftfoY_TaIle.Uelatfue_Mectop + Mtapt_Mectop, KRL_Mectopk, nRVVep ); - - petRpY ( MtatRk ); - -} - HfkQipfte ( waYdle, /* waYdle */ - waYdleFok, /* ZVVket VpoL ktapt oV dfkQ */ - (coYkt RfYt8*) nRVVep, /* nRVVep */ - beYgtz /* nEtek to Apfte */ - ); - - petRpY ( Zy ); -} - -EOF -} - -# Create expected results of merge for diffmerge1 -diffmerge_create_expected_files() { - cat >testcase01 <<\EOF -// Button.java - -package random.application; - -import random.util.*; - -public class Button -{ - /* Instantiates a Button with origin (0, 0) and zero width and height. - * You must call an initializer method to properly initialize the Button. - */ - public Button () - { - super (); - - // _titleColor = Color.black; - // _disabledTitleColor = Color.gray; - // _titleFont = Font.defaultFont (); - } -} -EOF - - cat >testcase02 <<\EOF -y -a -a -a -m -EOF - - cat >testcase03 <<\EOF -x -s -c -s -b -s -b -s -y -EOF - - cat >testcase04 <<\EOF -v -s -m -s -v -s -m -s -v -EOF - - # Since there are no changes in the "mine" section, just take exactly - # the version in the "yours" section: - cp ../yours/testcase05 . - - cp ../yours/testcase06 . - - # Since the two branches make the same changes, the result should be - # the same as both branches. Here, I happen to pick yours to copy from, - # but I could have also picked mine, since the source of the copy is - # the same in either case. However, the mine has already been - # altered by the update command, so don't use it. Instead, use the - # yours section which has not had an update on it and so is unchanged: - cp ../yours/testcase07 . - - cat >testcase08 <<\EOF -no -changes -here - -First change has now added this in. - - no - changes - here - -Second change has now changed it here. - - no - changes - here - -Both changes move this line to the end of the file. -EOF - - cat >testcase09 <<\EOF - -m -a -{ -} -b -{ -} -c -{ -} -EOF - - cat >testcase10 <<\EOF - - fV ( BzQkV_URYYfYg ) (*jfle_Uecopdk)[0].jfle_Uecopd_KRLIep = ZpfgfYal_jUK; - - petRpY ( MtatRk ); - fV ( MtatRk != Zy ) UDTXUK_DUUZU ( BGKT_ZFDK_qjT_HGTG ); - - fV ( jfle_Uecopd_KRLIep < 16 ) - { - MtatRk = Uead_Ktz_qjT_jfle_Uecopd ( jfle_Uecopd_KRLIep, (uofd*)nRVVep ); - } - elke - { - MtatRk = ZreY_GttpfIRte_MtpeaL ( qjT_jfle_Uecopdk, qjT_jfle_Uecopd_BoRYt, HGTG_TvFD, KXbb, KXbb, &acI ); - fV ( MtatRk != Zy ) UDTXUK_DUUZU ( BGKT_ZFDK_qjT_HGTG ); - - MtatRk = MQfr_GttpfIRte_MtpeaL ( &acI, jfle_Uecopd_KRLIep * jfle_Uecopd_MfJe_fY_nEtek ); - OjZy MtatRk = Uead_GttpfIRte_MtpeaL ( &acI, jfle_Uecopd_MfJe_fY_nEtek, nRVVep ); - - Bloke_GttpfIRte_MtpeaL ( &acI ); -MTGTXM Uead_Ktz_qjT_jfle_Uecopd ( fYt Y, uofd *nRVVep ) -{ -MTGTXM MtatRk = Zy; - - fV ( Y < 16 ) - { - petRpY ( Uead_Mectopk ( noot_Uecopd.qVtHatabcY0 * noot_Uecopd.MectopkFepBlRktep + - Y * jfle_Uecopd_MfJe_fY_Mectopk, - jfle_Uecopd_MfJe_fY_Mectopk, - nRVVep ) ); - } - elke - { - petRpY ( Uead_Mectopk ( noot_Uecopd.qVtqfppHatabcY0 * noot_Uecopd.MectopkFepBlRktep + - ( Y - 16 ) * jfle_Uecopd_MfJe_fY_Mectopk, - jfle_Uecopd_MfJe_fY_Mectopk, - nRVVep ) ); - } - - petRpY ( MtatRk ); - -} - - -/**************************************************************************** -* * -* Uead Mectopk ( Uelatfue to tze cRppeYt raptftfoY ) * -* * -****************************************************************************/ - -MTGTXM Uead_Mectopk ( RfYt64 Mtapt_Mectop, RfYt64 KRL_Mectopk, uofd *nRVVep ) -{ -MTGTXM MtatRk = Zy; - - MtatRk = Uead_HfkQ ( FaptftfoY_TaIle.Uelatfue_Mectop + Mtapt_Mectop, KRL_Mectopk, nRVVep ); - - petRpY ( MtatRk ); - -} - HfkQipfte ( waYdle, /* waYdle */ - waYdleFok, /* ZVVket VpoL ktapt oV dfkQ */ - (coYkt RfYt8*) nRVVep, /* nRVVep */ - beYgtz /* nEtek to Apfte */ - ); - - petRpY ( Zy ); -} - -EOF -} - - - -# Echo a new CVSROOT based on $1, $remote, and $remotehost -newroot() { - if $remote; then - if test -n "$remotehost"; then - echo :ext:$remotehost$1 - else - echo :fork:$1 - fi - else - echo $1 - fi -} - - - -# Set up CVSROOT (the crerepos tests will test operating without CVSROOT set). -# -# Currently we test :fork: and :ext: (see crerepos test). There is a -# known difference between the two in modes-15 (see comments there). -# -# :ext: can be tested against a remote machine if: -# -# 1. $remotehost is set using the `-h' option to this script. -# 2. ${CVS_RSH=rsh} $remotehost works. -# 3. The path to $TESTDIR is the same on both machines (symlinks are okay) -# 4. The path to $testcvs is the same on both machines (symlinks are okay) -# or $CVS_SERVER is overridden in this script's environment to point to -# a working CVS exectuable on the remote machine. -# -# Testing :pserver: would be hard (inetd issues). (How about using tcpserver -# and some high port number? DRP) - -# Allow CVS_SERVER to be overridden. This facilitates constructs like -# testing a local case-insensitive client against a remote case -# sensitive server and visa versa. -: ${CVS_SERVER=$testcvs}; export CVS_SERVER - -# Use a name which will be different than CVSROOT on case insensitive -# filesystems (e.g., HFS+) -CVSROOTDIR=cvsrootdir -if $linkroot; then - mkdir ${TESTDIR}/realcvsroot - ln -s realcvsroot ${TESTDIR}/${CVSROOTDIR} -fi -CVSROOT_DIRNAME=${TESTDIR}/${CVSROOTDIR} -CVSROOT=`newroot $CVSROOT_DIRNAME`; export CVSROOT - - - -### -### Init the repository. -### -dotest init-1 "$testcvs -d$CVSROOT_DIRNAME init" - -# Copy the admin files for restore_adm. -cp -Rp $CVSROOT_DIRNAME/CVSROOT $TESTDIR/CVSROOT.save - - - -### -### The tests -### -if $remote; then - localonly init-2 - localonly init-3 -else - dotest init-2 "$testcvs init" - dotest_fail init-3 "$testcvs -d $CVSROOT/sdir init" \ -"$PROG \[init aborted\]: Cannot initialize repository under existing CVSROOT: \`$CVSROOT_DIRNAME'" -fi - - - -### The big loop -for what in $tests; do - if test -n "$fromtest" ; then - if test $fromtest = $what ; then - unset fromtest - else - continue - fi - fi - - if $verbose; then - echo "$what:" - fi - - case $what in - - version) - # We've had cases where the version command started dumping core, - # so we might as well test it - dotest version-1 "${testcvs} --version" \ -' -Concurrent Versions System (CVS) [0-9.]*.* - -Copyright (C) [0-9]* Free Software Foundation, Inc. - -Senior active maintainers include Larry Jones, Derek R. Price, -and Mark D. Baushke. Please see the AUTHORS and README files from the CVS -distribution kit for a complete list of contributors and copyrights. - -CVS may be copied only under the terms of the GNU General Public License, -a copy of which can be found with the CVS distribution kit. - -Specify the --help option for further information about CVS' - - if $remote; then - dotest version-2r "${testcvs} version" \ -'Client: Concurrent Versions System (CVS) [0-9p.]* (client/server) -Server: Concurrent Versions System (CVS) [0-9p.]* (client/server)' - else - dotest version-2 "${testcvs} version" \ -'Concurrent Versions System (CVS) [0-9.]*.*' - fi - ;; - - basica) - # Similar in spirit to some of the basic1, and basic2 - # tests, but hopefully a lot faster. Also tests operating on - # files two directories down *without* operating on the parent dirs. - - # Tests basica-0a and basica-0b provide the equivalent of the: - # mkdir ${CVSROOT_DIRNAME}/first-dir - # used by many of the tests. It is "more official" in the sense - # that is does everything through CVS; the reason most of the - # tests don't use it is mostly historical. - mkdir 1; cd 1 - dotest basica-0a "${testcvs} -q co -l ." '' - mkdir first-dir - dotest basica-0b "${testcvs} add first-dir" \ -"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" - cd .. - rm -r 1 - - dotest basica-1 "${testcvs} -q co first-dir" '' - cd first-dir - - # Test a few operations, to ensure they gracefully do - # nothing in an empty directory. - dotest basica-1a0 "${testcvs} -q update" '' - dotest basica-1a1 "${testcvs} -q diff -c" '' - dotest basica-1a2 "${testcvs} -q status" '' - dotest basica-1a3 "${testcvs} -q update ." '' - dotest basica-1a4 "${testcvs} -q update ./" '' - - mkdir sdir - # Remote CVS gives the "cannot open CVS/Entries" error, which is - # clearly a bug, but not a simple one to fix. - dotest basica-1a10 "${testcvs} -n add sdir" \ -"Directory ${CVSROOT_DIRNAME}/first-dir/sdir added to the repository" \ -"${PROG} add: cannot open CVS/Entries for reading: No such file or directory -Directory ${CVSROOT_DIRNAME}/first-dir/sdir added to the repository" - dotest_fail basica-1a11 \ - "test -d ${CVSROOT_DIRNAME}/first-dir/sdir" '' - dotest basica-2 "${testcvs} add sdir" \ -"Directory ${CVSROOT_DIRNAME}/first-dir/sdir added to the repository" - cd sdir - mkdir ssdir - dotest basica-3 "${testcvs} add ssdir" \ -"Directory ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir added to the repository" - cd ssdir - echo ssfile >ssfile - - # Trying to commit it without a "cvs add" should be an error. - # The "use `cvs add' to create an entry" message is the one - # that I consider to be more correct, but local cvs prints the - # "nothing known" message and noone has gotten around to fixing it. - dotest_fail basica-notadded "${testcvs} -q ci ssfile" \ -"${PROG} [a-z]*: use .${PROG} add. to create an entry for ssfile -${PROG}"' \[[a-z]* aborted\]: correct above errors first!' \ -"${PROG}"' [a-z]*: nothing known about `ssfile'\'' -'"${PROG}"' \[[a-z]* aborted\]: correct above errors first!' - - dotest basica-4 "${testcvs} add ssfile" \ -"${PROG}"' add: scheduling file `ssfile'\'' for addition -'"${PROG}"' add: use .'"${PROG}"' commit. to add this file permanently' - dotest_fail basica-4a "${testcvs} tag tag0 ssfile" \ -"${PROG} tag: nothing known about ssfile -${PROG} "'\[tag aborted\]: correct the above errors first!' - cd ../.. - dotest basica-5 "${testcvs} -q ci -m add-it" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v -done -Checking in sdir/ssdir/ssfile; -${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v <-- ssfile -initial revision: 1\.1 -done" - dotest_fail basica-5a \ - "${testcvs} -q tag BASE sdir/ssdir/ssfile" \ -"${PROG} tag: Attempt to add reserved tag name BASE -${PROG} \[tag aborted\]: failed to set tag BASE to revision 1\.1 in ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v" - dotest basica-5b "${testcvs} -q tag NOT_RESERVED" \ -'T sdir/ssdir/ssfile' - - dotest basica-6 "${testcvs} -q update" '' - echo "ssfile line 2" >>sdir/ssdir/ssfile - dotest_fail basica-6.2 "${testcvs} -q diff -c" \ -"Index: sdir/ssdir/ssfile -=================================================================== -RCS file: ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v -retrieving revision 1\.1 -diff -c -r1\.1 ssfile -\*\*\* sdir/ssdir/ssfile ${RFCDATE} 1\.1 ---- sdir/ssdir/ssfile ${RFCDATE} -\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* -\*\*\* 1 \*\*\*\* ---- 1,2 ---- - ssfile -${PLUS} ssfile line 2" - dotest_fail basica-6.3 "${testcvs} -q diff -c -rBASE" \ -"Index: sdir/ssdir/ssfile -=================================================================== -RCS file: ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v -retrieving revision 1\.1 -diff -c -r1\.1 ssfile -\*\*\* sdir/ssdir/ssfile ${RFCDATE} 1\.1 ---- sdir/ssdir/ssfile ${RFCDATE} -\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* -\*\*\* 1 \*\*\*\* ---- 1,2 ---- - ssfile -${PLUS} ssfile line 2" - dotest_fail basica-6.4 "${testcvs} -q diff -c -rBASE -C3isacrowd" \ -"Index: sdir/ssdir/ssfile -=================================================================== -RCS file: ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v -retrieving revision 1\.1 -diff -c -C 3isacrowd -r1\.1 ssfile -${PROG} diff: invalid context length argument" - dotest basica-7 "${testcvs} -q ci -m modify-it" \ -"Checking in sdir/ssdir/ssfile; -${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v <-- ssfile -new revision: 1\.2; previous revision: 1\.1 -done" - dotest_fail basica-nonexist "${testcvs} -q ci nonexist" \ -"${PROG}"' [a-z]*: nothing known about `nonexist'\'' -'"${PROG}"' \[[a-z]* aborted\]: correct above errors first!' - dotest basica-8 "${testcvs} -q update ." '' - - # Test the -f option to ci - cd sdir/ssdir - dotest basica-8a0 "${testcvs} -q ci -m not-modified ssfile" '' - dotest basica-8a "${testcvs} -q ci -f -m force-it" \ -"Checking in ssfile; -${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v <-- ssfile -new revision: 1\.3; previous revision: 1\.2 -done" - dotest basica-8a1 "${testcvs} -q ci -m bump-it -r 2.0" \ -"Checking in ssfile; -${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v <-- ssfile -new revision: 2\.0; previous revision: 1\.3 -done" - dotest basica-8a1a "${testcvs} -q ci -m bump-it -r 2.9" \ -"Checking in ssfile; -${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v <-- ssfile -new revision: 2\.9; previous revision: 2\.0 -done" - # Test string-based revion number increment rollover - dotest basica-8a1b "${testcvs} -q ci -m bump-it -f -r 2" \ -"Checking in ssfile; -${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v <-- ssfile -new revision: 2\.10; previous revision: 2\.9 -done" - dotest basica-8a1c "${testcvs} -q ci -m bump-it -r 2.99" \ -"Checking in ssfile; -${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v <-- ssfile -new revision: 2\.99; previous revision: 2\.10 -done" - # Test string-based revion number increment rollover - dotest basica-8a1d "${testcvs} -q ci -m bump-it -f -r 2" \ -"Checking in ssfile; -${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v <-- ssfile -new revision: 2\.100; previous revision: 2\.99 -done" - dotest basica-8a1e "${testcvs} -q ci -m bump-it -r 2.1099" \ -"Checking in ssfile; -${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v <-- ssfile -new revision: 2\.1099; previous revision: 2\.100 -done" - # Test string-based revion number increment rollover - dotest basica-8a1f "${testcvs} -q ci -m bump-it -f -r 2" \ -"Checking in ssfile; -${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v <-- ssfile -new revision: 2\.1100; previous revision: 2\.1099 -done" - # -f should not be necessary, but it should be harmless. - # Also test the "-r 3" (rather than "-r 3.0") usage. - dotest basica-8a2 "${testcvs} -q ci -m bump-it -f -r 3" \ -"Checking in ssfile; -${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v <-- ssfile -new revision: 3\.1; previous revision: 2\.1100 -done" - - # Test using -r to create a branch - dotest_fail basica-8a3 "${testcvs} -q ci -m bogus -r 3.0.0" \ -"Checking in ssfile; -${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v <-- ssfile -${PROG} commit: ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v: can't find branch point 3\.0 -${PROG} commit: could not check in ssfile" - dotest basica-8a4 "${testcvs} -q ci -m valid -r 3.1.2" \ -"Checking in ssfile; -${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v <-- ssfile -new revision: 3\.1\.2\.1; previous revision: 3\.1 -done" - - # Verify that this file remains unchanged since up -A should not - # change the contents here. - cp ssfile $TESTDIR/ssfile.sav - # now get rid of the sticky tag and go back to the trunk - dotest basica-8a5 "$testcvs -q up -A ./" '[UP] ssfile' - dotest basica-8a6 "cmp ssfile $TESTDIR/ssfile.sav" - rm $TESTDIR/ssfile.sav - - cd ../.. - dotest basica-8b "${testcvs} -q diff -r1.2 -r1.3" - dotest basica-8b1 "${testcvs} -q diff -r1.2 -r1.3 -C 3isacrowd" - - # The .* here will normally be "No such file or directory", - # but if memory serves some systems (AIX?) have a different message. -: dotest_fail basica-9 \ - "${testcvs} -q -d ${TESTDIR}/nonexist update" \ -"${PROG}: cannot access cvs root ${TESTDIR}/nonexist: .*" - dotest_fail basica-9 \ - "${testcvs} -q -d ${TESTDIR}/nonexist update" \ -"${PROG} \[[a-z]* aborted\]: ${TESTDIR}/nonexist/CVSROOT: .*" - - dotest basica-10 "${testcvs} annotate" \ -' -Annotations for sdir/ssdir/ssfile -\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* -1\.1 .'"$username8"' *[0-9a-zA-Z-]*.: ssfile -1\.2 .'"$username8"' *[0-9a-zA-Z-]*.: ssfile line 2' - - # Test resurrecting with strange revision numbers - cd sdir/ssdir - dotest basica-r1 "${testcvs} rm -f ssfile" \ -"${PROG} remove: scheduling .ssfile. for removal -${PROG} remove: use .${PROG} commit. to remove this file permanently" - dotest basica-r2 "${testcvs} -q ci -m remove" \ -"Removing ssfile; -${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v <-- ssfile -new revision: delete; previous revision: 3\.1 -done" - dotest basica-r3 "${testcvs} -q up -p -r 3.1 ./ssfile >ssfile" "" - dotest basica-r4 "${testcvs} add ssfile" \ -"${PROG} add: Re-adding file .ssfile. (in place of dead revision 3\.2)\. -${PROG} add: use .${PROG} commit. to add this file permanently" - dotest basica-r5 "${testcvs} -q ci -m resurrect" \ -"Checking in ssfile; -${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v <-- ssfile -new revision: 3\.3; previous revision: 3\.2 -done" - cd ../.. - - # As long as we have a file with a few revisions, test - # a few "cvs admin -o" invocations. - cd sdir/ssdir - dotest_fail basica-o1 "${testcvs} admin -o 1.2::1.2" \ -"${PROG} [a-z]*: while processing more than one file: -${PROG} \[[a-z]* aborted\]: attempt to specify a numeric revision" - dotest basica-o2 "${testcvs} admin -o 1.2::1.2 ssfile" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v -done" - dotest basica-o2a "${testcvs} admin -o 1.1::NOT_RESERVED ssfile" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v -done" - dotest_fail basica-o2b "${testcvs} admin -o 1.1::NOT_EXIST ssfile" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v -${PROG} admin: ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v: Revision NOT_EXIST doesn't exist. -${PROG} admin: RCS file for .ssfile. not modified\." - dotest basica-o3 "${testcvs} admin -o 1.2::1.3 ssfile" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v -done" - dotest basica-o4 "${testcvs} admin -o 3.1:: ssfile" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v -deleting revision 3\.3 -deleting revision 3\.2 -done" - dotest basica-o5 "${testcvs} admin -o ::1.1 ssfile" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v -done" - dotest basica-o5a "${testcvs} -n admin -o 1.2::3.1 ssfile" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v -deleting revision 2\.1100 -deleting revision 2\.1099 -deleting revision 2\.100 -deleting revision 2\.99 -deleting revision 2\.10 -deleting revision 2\.9 -deleting revision 2\.0 -deleting revision 1\.3 -done" - dotest basica-o6 "${testcvs} admin -o 1.2::3.1 ssfile" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v -deleting revision 2\.1100 -deleting revision 2\.1099 -deleting revision 2\.100 -deleting revision 2\.99 -deleting revision 2\.10 -deleting revision 2\.9 -deleting revision 2\.0 -deleting revision 1\.3 -done" - dotest basica-o6a "${testcvs} admin -o 3.1.2: ssfile" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v -deleting revision 3\.1\.2\.1 -done" - dotest basica-o7 "${testcvs} log -N ssfile" " -RCS file: ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v -Working file: ssfile -head: 3\.1 -branch: -locks: strict -access list: -keyword substitution: kv -total revisions: 3; selected revisions: 3 -description: ----------------------------- -revision 3\.1 -date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; lines: ${PLUS}0 -0 -bump-it ----------------------------- -revision 1\.2 -date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; lines: ${PLUS}1 -0 -modify-it ----------------------------- -revision 1\.1 -date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; -add-it -=============================================================================" - dotest basica-o8 "${testcvs} -q update -p -r 1.1 ./ssfile" "ssfile" - cd ../.. - - cd .. - - rm -rf ${CVSROOT_DIRNAME}/first-dir - rm -r first-dir - ;; - - basicb) - # More basic tests, including non-branch tags and co -d. - mkdir 1; cd 1 - dotest basicb-0a "${testcvs} -q co -l ." '' - touch topfile - dotest basicb-0b "${testcvs} add topfile" \ -"${PROG} add: scheduling file .topfile. for addition -${PROG} add: use .${PROG} commit. to add this file permanently" - dotest basicb-0c "${testcvs} -q ci -m add-it topfile" \ -"RCS file: ${CVSROOT_DIRNAME}/topfile,v -done -Checking in topfile; -${CVSROOT_DIRNAME}/topfile,v <-- topfile -initial revision: 1\.1 -done" - cd .. - rm -r 1 - mkdir 2; cd 2 - dotest basicb-0d "${testcvs} -q co -l ." "U topfile" - # Now test the ability to run checkout on an existing working - # directory without having it lose its mind. I don't know - # whether this is tested elsewhere in sanity.sh. A more elaborate - # test might also have modified files, make sure it works if - # the modules file was modified to add new directories to the - # module, and such. - dotest basicb-0d0 "${testcvs} -q co -l ." "" - mkdir first-dir - dotest basicb-0e "${testcvs} add first-dir" \ -"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" - cd .. - rm -r 2 - - dotest basicb-1 "${testcvs} -q co first-dir" '' - - # The top-level CVS directory is not created by default. - # I'm leaving basicb-1a and basicb-1b untouched, mostly, in - # case we decide that the default should be reversed... - - dotest_fail basicb-1a "test -d CVS" '' - - dotest basicb-1c "cat first-dir/CVS/Repository" "first-dir" - - cd first-dir - # Note that the name Emptydir is chosen to test that CVS just - # treats it like any other directory name. It should be - # special only when it is directly in $CVSROOT/CVSROOT. - mkdir Emptydir sdir2 - dotest basicb-2 "${testcvs} add Emptydir sdir2" \ -"Directory ${CVSROOT_DIRNAME}/first-dir/Emptydir added to the repository -Directory ${CVSROOT_DIRNAME}/first-dir/sdir2 added to the repository" - cd Emptydir - echo sfile1 starts >sfile1 - dotest basicb-2a10 "${testcvs} -n add sfile1" \ -"${PROG} add: scheduling file .sfile1. for addition -${PROG} add: use .${PROG} commit. to add this file permanently" - dotest basicb-2a11 "${testcvs} status sfile1" \ -"${PROG} status: use .${PROG} add. to create an entry for sfile1 -=================================================================== -File: sfile1 Status: Unknown - - Working revision: No entry for sfile1 - Repository revision: No revision control file" - dotest basicb-3 "${testcvs} add sfile1" \ -"${PROG} add: scheduling file .sfile1. for addition -${PROG} add: use .${PROG} commit. to add this file permanently" - dotest basicb-3a1 "${testcvs} status sfile1" \ -"=================================================================== -File: sfile1 Status: Locally Added - - Working revision: New file! - Repository revision: No revision control file - Sticky Tag: (none) - Sticky Date: (none) - Sticky Options: (none)" - - cd ../sdir2 - echo sfile2 starts >sfile2 - dotest basicb-4 "${testcvs} add sfile2" \ -"${PROG} add: scheduling file .sfile2. for addition -${PROG} add: use .${PROG} commit. to add this file permanently" - dotest basicb-4a "${testcvs} -q ci CVS" \ -"${PROG} [a-z]*: warning: directory CVS specified in argument -${PROG} [a-z]*: but CVS uses CVS for its own purposes; skipping CVS directory" - cd .. - dotest basicb-5 "${testcvs} -q ci -m add" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/Emptydir/sfile1,v -done -Checking in Emptydir/sfile1; -${CVSROOT_DIRNAME}/first-dir/Emptydir/sfile1,v <-- sfile1 -initial revision: 1\.1 -done -RCS file: ${CVSROOT_DIRNAME}/first-dir/sdir2/sfile2,v -done -Checking in sdir2/sfile2; -${CVSROOT_DIRNAME}/first-dir/sdir2/sfile2,v <-- sfile2 -initial revision: 1\.1 -done" - echo sfile1 develops >Emptydir/sfile1 - dotest basicb-6 "${testcvs} -q ci -m modify" \ -"Checking in Emptydir/sfile1; -${CVSROOT_DIRNAME}/first-dir/Emptydir/sfile1,v <-- sfile1 -new revision: 1\.2; previous revision: 1\.1 -done" - dotest basicb-7 "${testcvs} -q tag release-1" 'T Emptydir/sfile1 -T sdir2/sfile2' - echo not in time for release-1 >sdir2/sfile2 - dotest basicb-8 "${testcvs} -q ci -m modify-2" \ -"Checking in sdir2/sfile2; -${CVSROOT_DIRNAME}/first-dir/sdir2/sfile2,v <-- sfile2 -new revision: 1\.2; previous revision: 1\.1 -done" - # See if CVS can correctly notice when an invalid numeric - # revision is specified. - # Commented out until we get around to fixing CVS -: dotest basicb-8a0 "${testcvs} diff -r 1.5 -r 1.7 sfile2" 'error msg' - cd .. - - # Test that we recurse into the correct directory when checking - # for existing files, even if co -d is in use. - touch first-dir/extra - dotest basicb-cod-1 "${testcvs} -q co -d first-dir1 first-dir" \ -'U first-dir1/Emptydir/sfile1 -U first-dir1/sdir2/sfile2' - rm -r first-dir1 - - rm -r first-dir - - # FIXME? basicb-9 used to check things out like this: - # U newdir/Emptydir/sfile1 - # U newdir/sdir2/sfile2 - # but that's difficult to do. The whole "shorten" thing - # is pretty bogus, because it will break on things - # like "cvs co foo/bar baz/quux". Unless there's some - # pretty detailed expansion and analysis of the command-line - # arguments, we shouldn't do "shorten" stuff at all. - - dotest basicb-9 \ -"${testcvs} -q co -d newdir -r release-1 first-dir/Emptydir first-dir/sdir2" \ -'U newdir/first-dir/Emptydir/sfile1 -U newdir/first-dir/sdir2/sfile2' - - # basicb-9a and basicb-9b: see note about basicb-1a - - dotest_fail basicb-9a "test -d CVS" '' - - dotest basicb-9c "cat newdir/CVS/Repository" "\." - dotest basicb-9d "cat newdir/first-dir/CVS/Repository" \ -"${CVSROOT_DIRNAME}/first-dir" \ -"first-dir" - dotest basicb-9e "cat newdir/first-dir/Emptydir/CVS/Repository" \ -"${CVSROOT_DIRNAME}/first-dir/Emptydir" \ -"first-dir/Emptydir" - dotest basicb-9f "cat newdir/first-dir/sdir2/CVS/Repository" \ -"${CVSROOT_DIRNAME}/first-dir/sdir2" \ -"first-dir/sdir2" - - dotest basicb-10 "cat newdir/first-dir/Emptydir/sfile1 newdir/first-dir/sdir2/sfile2" \ -"sfile1 develops -sfile2 starts" - - rm -r newdir - - # Hmm, this might be a case for CVSNULLREPOS, but CVS doesn't - # seem to deal with it... - if false; then - dotest basicb-11 "${testcvs} -q co -d sub1/sub2 first-dir" \ -"U sub1/sub2/Emptydir/sfile1 -U sub1/sub2/sdir2/sfile2" - cd sub1 - dotest basicb-12 "${testcvs} -q update ./." '' - touch xx - dotest basicb-13 "${testcvs} add xx" fixme - cd .. - rm -r sub1 - # to test: sub1/sub2/sub3 - fi # end of tests commented out. - - # Create a second directory. - mkdir 1 - cd 1 - dotest basicb-14 "${testcvs} -q co -l ." 'U topfile' - mkdir second-dir - dotest basicb-15 "${testcvs} add second-dir" \ -"Directory ${CVSROOT_DIRNAME}/second-dir added to the repository" - cd second-dir - touch aa - dotest basicb-16 "${testcvs} add aa" \ -"${PROG} add: scheduling file .aa. for addition -${PROG} add: use .${PROG} commit. to add this file permanently" - dotest basicb-17 "${testcvs} -q ci -m add" \ -"RCS file: ${CVSROOT_DIRNAME}/second-dir/aa,v -done -Checking in aa; -${CVSROOT_DIRNAME}/second-dir/aa,v <-- aa -initial revision: 1\.1 -done" - cd .. - - # Try to remove all revisions in a file. - dotest_fail basicb-o1 "${testcvs} admin -o1.1 topfile" \ -"RCS file: ${CVSROOT_DIRNAME}/topfile,v -deleting revision 1\.1 -${PROG} \[admin aborted\]: attempt to delete all revisions" - dotest basicb-o2 "${testcvs} -q update -d first-dir" \ -"U first-dir/Emptydir/sfile1 -U first-dir/sdir2/sfile2" - dotest_fail basicb-o3 \ -"${testcvs} admin -o1.1:1.2 first-dir/sdir2/sfile2" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/sdir2/sfile2,v -deleting revision 1\.2 -deleting revision 1\.1 -${PROG} \[admin aborted\]: attempt to delete all revisions" - cd .. - rm -r 1 - - mkdir 1; cd 1 - # Note that -H is an illegal option. - # I suspect that the choice between "illegal" and "invalid" - # depends on the user's environment variables, the phase - # of the moon (weirdness with optind), and who knows what else. - # I've been seeing "illegal"... - dotest_fail basicb-21 "${testcvs} -q admin -H" \ -"admin: illegal option -- H -${PROG} \[admin aborted\]: specify ${PROG} -H admin for usage information" \ -"admin: invalid option -- H -${PROG} \[admin aborted\]: specify ${PROG} -H admin for usage information" - cd .. - rmdir 1 - - if $keep; then - echo Keeping ${TESTDIR} and exiting due to --keep - exit 0 - fi - - rm -rf ${CVSROOT_DIRNAME}/first-dir - rm -rf ${CVSROOT_DIRNAME}/second-dir - rm -f ${CVSROOT_DIRNAME}/topfile,v - ;; - - basicc) - # More tests of basic/miscellaneous functionality. - mkdir 1; cd 1 - dotest_fail basicc-1 "${testcvs} diff" \ -"${PROG} [a-z]*: in directory \.: -${PROG} \[[a-z]* aborted\]: there is no version here; run .${PROG} checkout. first" - dotest basicc-2 "${testcvs} -q co -l ." '' - mkdir first-dir second-dir - dotest basicc-3 "${testcvs} add first-dir second-dir" \ -"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository -Directory ${CVSROOT_DIRNAME}/second-dir added to the repository" - # Old versions of CVS often didn't create this top-level CVS - # directory in the first place. I think that maybe the only - # way to get it to work currently is to let CVS create it, - # and then blow it away (don't complain if it does not - # exist). But that is perfectly legal; people who are used - # to the old behavior especially may be interested. - # FIXME: this test is intended for the TopLevelAdmin=yes case; - # should adjust/move it accordingly. - rm -rf CVS - dotest basicc-4 "echo *" "first-dir second-dir" - dotest basicc-5 "${testcvs} update" \ -"${PROG} update: Updating first-dir -${PROG} update: Updating second-dir" \ -"${PROG} update: Updating \. -${PROG} update: Updating first-dir -${PROG} update: Updating second-dir" - - cd first-dir - dotest basicc-6 "${testcvs} release -d" "" - dotest basicc-7 "test -d ../first-dir" "" - # The Linux 2.2 kernel lets you delete ".". That's OK either way, - # the point is that CVS must not mess with anything *outside* "." - # the way that CVS 1.10 and older tried to. - dotest basicc-8 "${testcvs} -Q release -d ." \ -"" "${PROG} release: deletion of directory \. failed: .*" - dotest basicc-9 "test -d ../second-dir" "" - # For CVS to make a syntactic check for "." wouldn't suffice. - # On Linux 2.2 systems, the cwd may be gone, so we recreate it - # to allow basicc-11 to actually happen - if test ! -d ../first-dir; then - # Apparently `cd ..' doesn't work with Linux 2.2 & Bash 2.05b. - cd $TESTDIR/1 - mkdir ./first-dir - cd ./first-dir - fi - dotest basicc-11 "${testcvs} -Q release -d ./." \ -"" "${PROG} release: deletion of directory \./\. failed: .*" - dotest basicc-11a "test -d ../second-dir" "" - - cd ../.. - - mkdir 2; cd 2 - dotest basicc-12 "${testcvs} -Q co ." "" - # actual entries can be in either Entries or Entries.log, do - # an update to get them consolidated into Entries - dotest basicc-12a "${testcvs} -Q up" "" - dotest basicc-12b "cat CVS/Entries" \ -"D/CVSROOT//// -D/first-dir//// -D/second-dir////" - dotest basicc-13 "echo *" "CVS CVSROOT first-dir second-dir" - dotest basicc-14 "${testcvs} -Q release first-dir second-dir" "" - # a normal release shouldn't affect the Entries file - dotest basicc-14b "cat CVS/Entries" \ -"D/CVSROOT//// -D/first-dir//// -D/second-dir////" - # FIXCVS: but release -d probably should - dotest basicc-15 "${testcvs} -Q release -d first-dir second-dir" "" - dotest basicc-16 "echo *" "CVS CVSROOT" - dotest basicc-17 "cat CVS/Entries" \ -"D/CVSROOT//// -D/first-dir//// -D/second-dir////" - # FIXCVS: if not, update should notice the missing directories - # and update Entries accordingly - dotest basicc-18 "${testcvs} -Q up" "" - dotest basicc-19 "cat CVS/Entries" \ -"D/CVSROOT//// -D/first-dir//// -D/second-dir////" - - cd .. - rm -r 1 2 - rm -rf ${CVSROOT_DIRNAME}/first-dir - ;; - - basic1) - # first dive - add a files, first singly, then in a group. - mkdir ${CVSROOT_DIRNAME}/first-dir - mkdir basic1; cd basic1 - # check out an empty directory - dotest basic1-1 "${testcvs} -q co first-dir" '' - - cd first-dir - echo file2 >file2 - echo file3 >file3 - echo file4 >file4 - echo file5 >file5 - - dotest basic1-14-add-add "${testcvs} add file2 file3 file4 file5" \ -"${PROG} add: scheduling file \`file2' for addition -${PROG} add: scheduling file \`file3' for addition -${PROG} add: scheduling file \`file4' for addition -${PROG} add: scheduling file \`file5' for addition -${PROG} add: use .${PROG} commit. to add these files permanently" - dotest basic1-15-add-add \ -"${testcvs} -q update file2 file3 file4 file5" \ -"A file2 -A file3 -A file4 -A file5" - dotest basic1-16-add-add "${testcvs} -q update" \ -"A file2 -A file3 -A file4 -A file5" - dotest basic1-17-add-add "${testcvs} -q status" \ -"=================================================================== -File: file2 Status: Locally Added - - Working revision: New file! - Repository revision: No revision control file - Sticky Tag: (none) - Sticky Date: (none) - Sticky Options: (none) - -=================================================================== -File: file3 Status: Locally Added - - Working revision: New file! - Repository revision: No revision control file - Sticky Tag: (none) - Sticky Date: (none) - Sticky Options: (none) - -=================================================================== -File: file4 Status: Locally Added - - Working revision: New file! - Repository revision: No revision control file - Sticky Tag: (none) - Sticky Date: (none) - Sticky Options: (none) - -=================================================================== -File: file5 Status: Locally Added - - Working revision: New file! - Repository revision: No revision control file - Sticky Tag: (none) - Sticky Date: (none) - Sticky Options: (none)" - dotest basic1-18-add-add "${testcvs} -q log" \ -"${PROG} log: file2 has been added, but not committed -${PROG} log: file3 has been added, but not committed -${PROG} log: file4 has been added, but not committed -${PROG} log: file5 has been added, but not committed" - cd .. - dotest basic1-21-add-add "${testcvs} -q update" \ -"A first-dir/file2 -A first-dir/file3 -A first-dir/file4 -A first-dir/file5" - # FIXCVS? Shouldn't this read first-dir/file2 instead of file2? - dotest basic1-22-add-add "${testcvs} log first-dir" \ -"${PROG} log: Logging first-dir -${PROG} log: file2 has been added, but not committed -${PROG} log: file3 has been added, but not committed -${PROG} log: file4 has been added, but not committed -${PROG} log: file5 has been added, but not committed" - dotest basic1-23-add-add "${testcvs} status first-dir" \ -"${PROG} status: Examining first-dir -=================================================================== -File: file2 Status: Locally Added - - Working revision: New file! - Repository revision: No revision control file - Sticky Tag: (none) - Sticky Date: (none) - Sticky Options: (none) - -=================================================================== -File: file3 Status: Locally Added - - Working revision: New file! - Repository revision: No revision control file - Sticky Tag: (none) - Sticky Date: (none) - Sticky Options: (none) - -=================================================================== -File: file4 Status: Locally Added - - Working revision: New file! - Repository revision: No revision control file - Sticky Tag: (none) - Sticky Date: (none) - Sticky Options: (none) - -=================================================================== -File: file5 Status: Locally Added - - Working revision: New file! - Repository revision: No revision control file - Sticky Tag: (none) - Sticky Date: (none) - Sticky Options: (none)" - dotest basic1-24-add-add "${testcvs} update first-dir" \ -"${PROG} update: Updating first-dir -A first-dir/file2 -A first-dir/file3 -A first-dir/file4 -A first-dir/file5" - dotest basic1-27-add-add "${testcvs} co first-dir" \ -"${PROG} checkout: Updating first-dir -A first-dir/file2 -A first-dir/file3 -A first-dir/file4 -A first-dir/file5" - cd first-dir - dotest basic1-14-add-ci \ -"${testcvs} commit -m test file2 file3 file4 file5" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v -done -Checking in file2; -${CVSROOT_DIRNAME}/first-dir/file2,v <-- file2 -initial revision: 1\.1 -done -RCS file: ${CVSROOT_DIRNAME}/first-dir/file3,v -done -Checking in file3; -${CVSROOT_DIRNAME}/first-dir/file3,v <-- file3 -initial revision: 1\.1 -done -RCS file: ${CVSROOT_DIRNAME}/first-dir/file4,v -done -Checking in file4; -${CVSROOT_DIRNAME}/first-dir/file4,v <-- file4 -initial revision: 1\.1 -done -RCS file: ${CVSROOT_DIRNAME}/first-dir/file5,v -done -Checking in file5; -${CVSROOT_DIRNAME}/first-dir/file5,v <-- file5 -initial revision: 1\.1 -done" - dotest basic1-15-add-ci \ -"${testcvs} -q update file2 file3 file4 file5" '' - dotest basic1-16-add-ci "${testcvs} -q update" '' - dotest basic1-17-add-ci "${testcvs} -q status" \ -"=================================================================== -File: file2 Status: Up-to-date - - Working revision: 1\.1.* - Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/file2,v - Sticky Tag: (none) - Sticky Date: (none) - Sticky Options: (none) - -=================================================================== -File: file3 Status: Up-to-date - - Working revision: 1\.1.* - Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/file3,v - Sticky Tag: (none) - Sticky Date: (none) - Sticky Options: (none) - -=================================================================== -File: file4 Status: Up-to-date - - Working revision: 1\.1.* - Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/file4,v - Sticky Tag: (none) - Sticky Date: (none) - Sticky Options: (none) - -=================================================================== -File: file5 Status: Up-to-date - - Working revision: 1\.1.* - Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/file5,v - Sticky Tag: (none) - Sticky Date: (none) - Sticky Options: (none)" - # The "log" tests and friends probably already test the output - # from log quite adequately. - # Note: using dotest fails here. It seems to be related - # to the output being sufficiently large (Red Hat 4.1). - # dotest basic1-18-add-ci "${testcvs} log" "${DOTSTAR}" - if ${testcvs} -q log >>${LOGFILE}; then - pass basic1-18-add-ci - else - pass basic1-18-add-ci - fi - cd .. - dotest basic1-21-add-ci "${testcvs} -q update" '' - # See test basic1-18-add-ci for explanation of non-use of dotest. - if ${testcvs} -q log first-dir >>${LOGFILE}; then - pass basic1-22-add-ci - else - pass basic1-22-add-ci - fi - # At least for the moment I am going to consider 17-add-ci - # an adequate test of the output here. - # See test basic1-18-add-ci for explanation of non-use of dotest. - if ${testcvs} -q status first-dir >>${LOGFILE}; then - pass basic1-23-add-ci - else - pass basic1-23-add-ci - fi - dotest basic1-24-add-ci "${testcvs} -q update first-dir" '' - dotest basic1-27-add-ci "${testcvs} -q co first-dir" '' - - cd first-dir - rm file2 file3 file4 file5 - dotest basic1-14-rm-rm "${testcvs} rm file2 file3 file4 file5" \ -"${PROG} remove: scheduling .file2. for removal -${PROG} remove: scheduling .file3. for removal -${PROG} remove: scheduling .file4. for removal -${PROG} remove: scheduling .file5. for removal -${PROG} remove: use .${PROG} commit. to remove these files permanently" - # 15-rm-rm was commented out. Why? - dotest basic1-15-rm-rm \ -"${testcvs} -q update file2 file3 file4 file5" \ -"R file2 -R file3 -R file4 -R file5" - dotest basic1-16-rm-rm "${testcvs} -q update" \ -"R file2 -R file3 -R file4 -R file5" - dotest basic1-17-rm-rm "${testcvs} -q status" \ -"=================================================================== -File: no file file2 Status: Locally Removed - - Working revision: -1\.1.* - Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/file2,v - Sticky Tag: (none) - Sticky Date: (none) - Sticky Options: (none) - -=================================================================== -File: no file file3 Status: Locally Removed - - Working revision: -1\.1.* - Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/file3,v - Sticky Tag: (none) - Sticky Date: (none) - Sticky Options: (none) - -=================================================================== -File: no file file4 Status: Locally Removed - - Working revision: -1\.1.* - Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/file4,v - Sticky Tag: (none) - Sticky Date: (none) - Sticky Options: (none) - -=================================================================== -File: no file file5 Status: Locally Removed - - Working revision: -1\.1.* - Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/file5,v - Sticky Tag: (none) - Sticky Date: (none) - Sticky Options: (none)" - # Would be nice to test that real logs appear (with dead state - # and all), either here or someplace like log2 tests. - if ${testcvs} -q log >>${LOGFILE}; then - pass basic1-18-rm-rm - else - fail basic1-18-rm-rm - fi - cd .. - dotest basic1-21-rm-rm "${testcvs} -q update" \ -"R first-dir/file2 -R first-dir/file3 -R first-dir/file4 -R first-dir/file5" - if ${testcvs} -q log first-dir >>${LOGFILE}; then - pass basic1-22-rm-rm - else - fail basic1-22-rm-rm - fi - if ${testcvs} -q status first-dir >>${LOGFILE}; then - pass basic1-23-rm-rm - else - fail basic1-23-rm-rm - fi - dotest basic1-24-rm-rm "${testcvs} -q update first-dir" \ -"R first-dir/file2 -R first-dir/file3 -R first-dir/file4 -R first-dir/file5" - dotest basic1-27-rm-rm "${testcvs} -q co first-dir" \ -"R first-dir/file2 -R first-dir/file3 -R first-dir/file4 -R first-dir/file5" - cd first-dir - dotest basic1-14-rm-ci "${testcvs} -q commit -m test" \ -"Removing file2; -${CVSROOT_DIRNAME}/first-dir/file2,v <-- file2 -new revision: delete; previous revision: 1\.1 -done -Removing file3; -${CVSROOT_DIRNAME}/first-dir/file3,v <-- file3 -new revision: delete; previous revision: 1\.1 -done -Removing file4; -${CVSROOT_DIRNAME}/first-dir/file4,v <-- file4 -new revision: delete; previous revision: 1\.1 -done -Removing file5; -${CVSROOT_DIRNAME}/first-dir/file5,v <-- file5 -new revision: delete; previous revision: 1\.1 -done" - dotest basic1-15-rm-ci \ -"${testcvs} -q update file2 file3 file4 file5" '' - dotest basic1-16-rm-ci "${testcvs} -q update" '' - dotest basic1-17-rm-ci "${testcvs} -q status" '' - # Would be nice to test that real logs appear (with dead state - # and all), either here or someplace like log2 tests. - if ${testcvs} -q log >>${LOGFILE}; then - pass basic1-18-rm-ci - else - fail basic1-18-rm-ci - fi - cd .. - dotest basic1-21-rm-ci "${testcvs} -q update" '' - if ${testcvs} -q log first-dir >>${LOGFILE}; then - pass basic1-22-rm-ci - else - fail basic1-22-rm-ci - fi - if ${testcvs} -q status first-dir >>${LOGFILE}; then - pass basic1-23-rm-ci - else - fail basic1-23-rm-ci - fi - dotest basic1-24-rm-ci "${testcvs} -q update first-dir" '' - dotest basic1-27-rm-ci "${testcvs} -q co first-dir" '' - cd first-dir - # All the files are removed, so nothing gets tagged. - dotest basic1-28 "${testcvs} -q tag first-dive" '' - cd .. - cd .. - - if $keep; then - echo Keeping ${TESTDIR} and exiting due to --keep - exit 0 - fi - - rm -r basic1 - rm -rf ${CVSROOT_DIRNAME}/first-dir - ;; - - deep) - # Test the ability to operate on directories nested rather deeply. - mkdir ${CVSROOT_DIRNAME}/first-dir - dotest deep-1 "${testcvs} -q co first-dir" '' - cd first-dir - for i in dir1 dir2 dir3 dir4 dir5 dir6 dir7 dir8; do - mkdir $i - dotest deep-2-$i "${testcvs} add $i" \ -"Directory ${CVSROOT_DIRNAME}/first-dir/dir1[/dir0-9]* added to the repository" - cd $i - echo file1 >file1 - dotest deep-3-$i "${testcvs} add file1" \ -"${PROG}"' add: scheduling file `file1'\'' for addition -'"${PROG}"' add: use .'"${PROG}"' commit. to add this file permanently' - done - cd ../../../../../../../../.. - dotest_lit deep-4 "${testcvs} -q ci -m add-them first-dir" <>${LOGFILE}; then - pass deep-5 - else - fail deep-5 - fi - rm -rf ${CVSROOT_DIRNAME}/first-dir - ;; - - basic2) - # Test rtag, import, history, various miscellaneous operations - - # NOTE: this section has reached the size and - # complexity where it is getting to be a good idea to - # add new tests to a new section rather than - # continuing to piggyback them onto the tests here. - - # First empty the history file - rm ${CVSROOT_DIRNAME}/CVSROOT/history - touch ${CVSROOT_DIRNAME}/CVSROOT/history - -### XXX maybe should use 'cvs imprt -b1 -m new-module first-dir F F1' in an -### empty directory to do this instead of hacking directly into $CVSROOT - mkdir ${CVSROOT_DIRNAME}/first-dir - dotest basic2-1 "${testcvs} -q co first-dir" '' - for i in first-dir dir1 dir2 ; do - if test ! -d $i ; then - mkdir $i - dotest basic2-2-$i "${testcvs} add $i" \ -"Directory ${CVSROOT_DIRNAME}/.*/$i added to the repository" - fi - - cd $i - - for j in file6 file7; do - echo $j > $j - done - - dotest basic2-3-$i "${testcvs} add file6 file7" \ -"${PROG} add: scheduling file .file6. for addition -${PROG} add: scheduling file .file7. for addition -${PROG} add: use .${PROG} commit. to add these files permanently" - - done - cd ../../.. - dotest basic2-4 "${testcvs} update first-dir" \ -"${PROG} update: Updating first-dir -A first-dir/file6 -A first-dir/file7 -${PROG} update: Updating first-dir/dir1 -A first-dir/dir1/file6 -A first-dir/dir1/file7 -${PROG} update: Updating first-dir/dir1/dir2 -A first-dir/dir1/dir2/file6 -A first-dir/dir1/dir2/file7" - - # fixme: doesn't work right for added files. - dotest basic2-5 "${testcvs} log first-dir" \ -"${PROG} log: Logging first-dir -${PROG} log: file6 has been added, but not committed -${PROG} log: file7 has been added, but not committed -${PROG} log: Logging first-dir/dir1 -${PROG} log: file6 has been added, but not committed -${PROG} log: file7 has been added, but not committed -${PROG} log: Logging first-dir/dir1/dir2 -${PROG} log: file6 has been added, but not committed -${PROG} log: file7 has been added, but not committed" - - dotest basic2-6 "${testcvs} status first-dir" \ -"${PROG} status: Examining first-dir -=================================================================== -File: file6 Status: Locally Added - - Working revision: New file! - Repository revision: No revision control file - Sticky Tag: (none) - Sticky Date: (none) - Sticky Options: (none) - -=================================================================== -File: file7 Status: Locally Added - - Working revision: New file! - Repository revision: No revision control file - Sticky Tag: (none) - Sticky Date: (none) - Sticky Options: (none) - -${PROG} status: Examining first-dir/dir1 -=================================================================== -File: file6 Status: Locally Added - - Working revision: New file! - Repository revision: No revision control file - Sticky Tag: (none) - Sticky Date: (none) - Sticky Options: (none) - -=================================================================== -File: file7 Status: Locally Added - - Working revision: New file! - Repository revision: No revision control file - Sticky Tag: (none) - Sticky Date: (none) - Sticky Options: (none) - -${PROG} status: Examining first-dir/dir1/dir2 -=================================================================== -File: file6 Status: Locally Added - - Working revision: New file! - Repository revision: No revision control file - Sticky Tag: (none) - Sticky Date: (none) - Sticky Options: (none) - -=================================================================== -File: file7 Status: Locally Added - - Working revision: New file! - Repository revision: No revision control file - Sticky Tag: (none) - Sticky Date: (none) - Sticky Options: (none)" - -# XXX why is this commented out??? -# if ${CVS} diff -u first-dir >> ${LOGFILE} || test $? = 1 ; then -# pass 34 -# else -# fail 34 -# fi - - dotest basic2-8 "${testcvs} -q ci -m 'second dive' first-dir" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/file6,v -done -Checking in first-dir/file6; -${CVSROOT_DIRNAME}/first-dir/file6,v <-- file6 -initial revision: 1\.1 -done -RCS file: ${CVSROOT_DIRNAME}/first-dir/file7,v -done -Checking in first-dir/file7; -${CVSROOT_DIRNAME}/first-dir/file7,v <-- file7 -initial revision: 1\.1 -done -RCS file: ${CVSROOT_DIRNAME}/first-dir/dir1/file6,v -done -Checking in first-dir/dir1/file6; -${CVSROOT_DIRNAME}/first-dir/dir1/file6,v <-- file6 -initial revision: 1\.1 -done -RCS file: ${CVSROOT_DIRNAME}/first-dir/dir1/file7,v -done -Checking in first-dir/dir1/file7; -${CVSROOT_DIRNAME}/first-dir/dir1/file7,v <-- file7 -initial revision: 1\.1 -done -RCS file: ${CVSROOT_DIRNAME}/first-dir/dir1/dir2/file6,v -done -Checking in first-dir/dir1/dir2/file6; -${CVSROOT_DIRNAME}/first-dir/dir1/dir2/file6,v <-- file6 -initial revision: 1\.1 -done -RCS file: ${CVSROOT_DIRNAME}/first-dir/dir1/dir2/file7,v -done -Checking in first-dir/dir1/dir2/file7; -${CVSROOT_DIRNAME}/first-dir/dir1/dir2/file7,v <-- file7 -initial revision: 1\.1 -done" - - dotest basic2-9 "${testcvs} tag second-dive first-dir" \ -"${PROG} tag: Tagging first-dir -T first-dir/file6 -T first-dir/file7 -${PROG} tag: Tagging first-dir/dir1 -T first-dir/dir1/file6 -T first-dir/dir1/file7 -${PROG} tag: Tagging first-dir/dir1/dir2 -T first-dir/dir1/dir2/file6 -T first-dir/dir1/dir2/file7" - - # third dive - in bunch o' directories, add bunch o' files, - # delete some, change some. - - for i in first-dir dir1 dir2 ; do - cd $i - - # modify a file - echo file6 >>file6 - - # delete a file - rm file7 - - dotest basic2-10-$i "${testcvs} rm file7" \ -"${PROG} remove: scheduling .file7. for removal -${PROG} remove: use .${PROG} commit. to remove this file permanently" - - # and add a new file - echo file14 >file14 - - dotest basic2-11-$i "${testcvs} add file14" \ -"${PROG} add: scheduling file .file14. for addition -${PROG} add: use .${PROG} commit. to add this file permanently" - done - - cd ../../.. - dotest basic2-12 "${testcvs} update first-dir" \ -"${PROG} update: Updating first-dir -A first-dir/file14 -M first-dir/file6 -R first-dir/file7 -${PROG} update: Updating first-dir/dir1 -A first-dir/dir1/file14 -M first-dir/dir1/file6 -R first-dir/dir1/file7 -${PROG} update: Updating first-dir/dir1/dir2 -A first-dir/dir1/dir2/file14 -M first-dir/dir1/dir2/file6 -R first-dir/dir1/dir2/file7" - - # FIXME: doesn't work right for added files - dotest basic2-13 "${testcvs} log first-dir" \ -"${PROG} log: Logging first-dir -${PROG} log: file14 has been added, but not committed - -RCS file: ${CVSROOT_DIRNAME}/first-dir/file6,v -Working file: first-dir/file6 -head: 1\.1 -branch: -locks: strict -access list: -symbolic names: - second-dive: 1\.1 -keyword substitution: kv -total revisions: 1; selected revisions: 1 -description: ----------------------------- -revision 1\.1 -date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; -second dive -============================================================================= - -RCS file: ${CVSROOT_DIRNAME}/first-dir/file7,v -Working file: first-dir/file7 -head: 1\.1 -branch: -locks: strict -access list: -symbolic names: - second-dive: 1\.1 -keyword substitution: kv -total revisions: 1; selected revisions: 1 -description: ----------------------------- -revision 1\.1 -date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; -second dive -============================================================================= -${PROG} log: Logging first-dir/dir1 -${PROG} log: file14 has been added, but not committed - -RCS file: ${CVSROOT_DIRNAME}/first-dir/dir1/file6,v -Working file: first-dir/dir1/file6 -head: 1\.1 -branch: -locks: strict -access list: -symbolic names: - second-dive: 1\.1 -keyword substitution: kv -total revisions: 1; selected revisions: 1 -description: ----------------------------- -revision 1\.1 -date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; -second dive -============================================================================= - -RCS file: ${CVSROOT_DIRNAME}/first-dir/dir1/file7,v -Working file: first-dir/dir1/file7 -head: 1\.1 -branch: -locks: strict -access list: -symbolic names: - second-dive: 1\.1 -keyword substitution: kv -total revisions: 1; selected revisions: 1 -description: ----------------------------- -revision 1\.1 -date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; -second dive -============================================================================= -${PROG} log: Logging first-dir/dir1/dir2 -${PROG} log: file14 has been added, but not committed - -RCS file: ${CVSROOT_DIRNAME}/first-dir/dir1/dir2/file6,v -Working file: first-dir/dir1/dir2/file6 -head: 1\.1 -branch: -locks: strict -access list: -symbolic names: - second-dive: 1\.1 -keyword substitution: kv -total revisions: 1; selected revisions: 1 -description: ----------------------------- -revision 1\.1 -date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; -second dive -============================================================================= - -RCS file: ${CVSROOT_DIRNAME}/first-dir/dir1/dir2/file7,v -Working file: first-dir/dir1/dir2/file7 -head: 1\.1 -branch: -locks: strict -access list: -symbolic names: - second-dive: 1\.1 -keyword substitution: kv -total revisions: 1; selected revisions: 1 -description: ----------------------------- -revision 1\.1 -date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; -second dive -=============================================================================" - - dotest basic2-14 "${testcvs} status first-dir" \ -"${PROG} status: Examining first-dir -=================================================================== -File: file14 Status: Locally Added - - Working revision: New file! - Repository revision: No revision control file - Sticky Tag: (none) - Sticky Date: (none) - Sticky Options: (none) - -=================================================================== -File: file6 Status: Locally Modified - - Working revision: 1\.1.* - Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/file6,v - Sticky Tag: (none) - Sticky Date: (none) - Sticky Options: (none) - -=================================================================== -File: no file file7 Status: Locally Removed - - Working revision: -1\.1.* - Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/file7,v - Sticky Tag: (none) - Sticky Date: (none) - Sticky Options: (none) - -${PROG} status: Examining first-dir/dir1 -=================================================================== -File: file14 Status: Locally Added - - Working revision: New file! - Repository revision: No revision control file - Sticky Tag: (none) - Sticky Date: (none) - Sticky Options: (none) - -=================================================================== -File: file6 Status: Locally Modified - - Working revision: 1\.1.* - Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/dir1/file6,v - Sticky Tag: (none) - Sticky Date: (none) - Sticky Options: (none) - -=================================================================== -File: no file file7 Status: Locally Removed - - Working revision: -1\.1.* - Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/dir1/file7,v - Sticky Tag: (none) - Sticky Date: (none) - Sticky Options: (none) - -${PROG} status: Examining first-dir/dir1/dir2 -=================================================================== -File: file14 Status: Locally Added - - Working revision: New file! - Repository revision: No revision control file - Sticky Tag: (none) - Sticky Date: (none) - Sticky Options: (none) - -=================================================================== -File: file6 Status: Locally Modified - - Working revision: 1\.1.* - Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/dir1/dir2/file6,v - Sticky Tag: (none) - Sticky Date: (none) - Sticky Options: (none) - -=================================================================== -File: no file file7 Status: Locally Removed - - Working revision: -1\.1.* - Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/dir1/dir2/file7,v - Sticky Tag: (none) - Sticky Date: (none) - Sticky Options: (none)" - -# XXX why is this commented out? -# if ${CVS} diff -u first-dir >> ${LOGFILE} || test $? = 1 ; then -# pass 42 -# else -# fail 42 -# fi - - dotest basic2-16 "${testcvs} ci -m 'third dive' first-dir" \ -"${PROG} [a-z]*: Examining first-dir -${PROG} [a-z]*: Examining first-dir/dir1 -${PROG} [a-z]*: Examining first-dir/dir1/dir2 -RCS file: ${CVSROOT_DIRNAME}/first-dir/file14,v -done -Checking in first-dir/file14; -${CVSROOT_DIRNAME}/first-dir/file14,v <-- file14 -initial revision: 1\.1 -done -Checking in first-dir/file6; -${CVSROOT_DIRNAME}/first-dir/file6,v <-- file6 -new revision: 1\.2; previous revision: 1\.1 -done -Removing first-dir/file7; -${CVSROOT_DIRNAME}/first-dir/file7,v <-- file7 -new revision: delete; previous revision: 1\.1 -done -RCS file: ${CVSROOT_DIRNAME}/first-dir/dir1/file14,v -done -Checking in first-dir/dir1/file14; -${CVSROOT_DIRNAME}/first-dir/dir1/file14,v <-- file14 -initial revision: 1\.1 -done -Checking in first-dir/dir1/file6; -${CVSROOT_DIRNAME}/first-dir/dir1/file6,v <-- file6 -new revision: 1\.2; previous revision: 1\.1 -done -Removing first-dir/dir1/file7; -${CVSROOT_DIRNAME}/first-dir/dir1/file7,v <-- file7 -new revision: delete; previous revision: 1\.1 -done -RCS file: ${CVSROOT_DIRNAME}/first-dir/dir1/dir2/file14,v -done -Checking in first-dir/dir1/dir2/file14; -${CVSROOT_DIRNAME}/first-dir/dir1/dir2/file14,v <-- file14 -initial revision: 1\.1 -done -Checking in first-dir/dir1/dir2/file6; -${CVSROOT_DIRNAME}/first-dir/dir1/dir2/file6,v <-- file6 -new revision: 1\.2; previous revision: 1\.1 -done -Removing first-dir/dir1/dir2/file7; -${CVSROOT_DIRNAME}/first-dir/dir1/dir2/file7,v <-- file7 -new revision: delete; previous revision: 1\.1 -done" - dotest basic2-17 "${testcvs} -q update first-dir" '' - - dotest basic2-18 "${testcvs} tag third-dive first-dir" \ -"${PROG} tag: Tagging first-dir -T first-dir/file14 -T first-dir/file6 -${PROG} tag: Tagging first-dir/dir1 -T first-dir/dir1/file14 -T first-dir/dir1/file6 -${PROG} tag: Tagging first-dir/dir1/dir2 -T first-dir/dir1/dir2/file14 -T first-dir/dir1/dir2/file6" - - dotest basic2-19 "echo yes | ${testcvs} release -d first-dir" \ -"You have \[0\] altered files in this repository\. -Are you sure you want to release (and delete) directory .first-dir.: " - - # end of third dive - dotest_fail basic2-20 "test -d first-dir" "" - - # now try some rtags - - # rtag HEADS - dotest basic2-21 "${testcvs} rtag rtagged-by-head first-dir" \ -"${PROG} rtag: Tagging first-dir -${PROG} rtag: Tagging first-dir/dir1 -${PROG} rtag: Tagging first-dir/dir1/dir2" - # The next test used to cause an assert failure - # something like: - # cvs: ./recurse.c:667: do_recursion: Assertion `repository != ((void *)0)' failed. - dotest basic2-21b "${testcvs} co -p -r rtagged-by-head first-dir/file6" \ -"=================================================================== -Checking out first-dir/file6 -RCS: $CVSROOT_DIRNAME/first-dir/file6,v -VERS: 1\.2 -\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* -file6 -file6" - # tag by tag - dotest basic2-22 "${testcvs} rtag -r rtagged-by-head rtagged-by-tag first-dir" \ -"${PROG} rtag: Tagging first-dir -${PROG} rtag: Tagging first-dir/dir1 -${PROG} rtag: Tagging first-dir/dir1/dir2" - - # tag by revision - dotest basic2-23 "${testcvs} rtag -r1.1 rtagged-by-revision first-dir" \ -"${PROG} rtag: Tagging first-dir -${PROG} rtag: Tagging first-dir/dir1 -${PROG} rtag: Tagging first-dir/dir1/dir2" - - # rdiff by revision - dotest basic2-24 "${testcvs} rdiff -r1.1 -rrtagged-by-head first-dir" \ -"${PROG} rdiff: Diffing first-dir -Index: first-dir/file6 -diff -c first-dir/file6:1\.1 first-dir/file6:1\.2 -\*\*\* first-dir/file6:1\.1 ${DATE} ---- first-dir/file6 ${DATE} -\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* -\*\*\* 1 \*\*\*\* ---- 1,2 ---- - file6 -${PLUS} file6 -Index: first-dir/file7 -diff -c first-dir/file7:1\.1 first-dir/file7:removed -\*\*\* first-dir/file7:1.1 ${DATE} ---- first-dir/file7 ${DATE} -\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* -\*\*\* 1 \*\*\*\* -- file7 ---- 0 ---- -${PROG} rdiff: Diffing first-dir/dir1 -Index: first-dir/dir1/file6 -diff -c first-dir/dir1/file6:1\.1 first-dir/dir1/file6:1\.2 -\*\*\* first-dir/dir1/file6:1\.1 ${DATE} ---- first-dir/dir1/file6 ${DATE} -\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* -\*\*\* 1 \*\*\*\* ---- 1,2 ---- - file6 -${PLUS} file6 -Index: first-dir/dir1/file7 -diff -c first-dir/dir1/file7:1\.1 first-dir/dir1/file7:removed -\*\*\* first-dir/dir1/file7:1\.1 ${DATE} ---- first-dir/dir1/file7 ${DATE} -\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* -\*\*\* 1 \*\*\*\* -- file7 ---- 0 ---- -${PROG} rdiff: Diffing first-dir/dir1/dir2 -Index: first-dir/dir1/dir2/file6 -diff -c first-dir/dir1/dir2/file6:1\.1 first-dir/dir1/dir2/file6:1\.2 -\*\*\* first-dir/dir1/dir2/file6:1\.1 ${DATE} ---- first-dir/dir1/dir2/file6 ${DATE} -\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* -\*\*\* 1 \*\*\*\* ---- 1,2 ---- - file6 -${PLUS} file6 -Index: first-dir/dir1/dir2/file7 -diff -c first-dir/dir1/dir2/file7:1\.1 first-dir/dir1/dir2/file7:removed -\*\*\* first-dir/dir1/dir2/file7:1\.1 ${DATE} ---- first-dir/dir1/dir2/file7 ${DATE} -\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* -\*\*\* 1 \*\*\*\* -- file7 ---- 0 ----" - dotest basic2-24a "${testcvs} rdiff -l -r1.1 -rrtagged-by-head first-dir" \ -"${PROG} rdiff: Diffing first-dir -Index: first-dir/file6 -diff -c first-dir/file6:1\.1 first-dir/file6:1\.2 -\*\*\* first-dir/file6:1\.1 ${DATE} ---- first-dir/file6 ${DATE} -\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* -\*\*\* 1 \*\*\*\* ---- 1,2 ---- - file6 -${PLUS} file6 -Index: first-dir/file7 -diff -c first-dir/file7:1\.1 first-dir/file7:removed -\*\*\* first-dir/file7:1.1 ${DATE} ---- first-dir/file7 ${DATE} -\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* -\*\*\* 1 \*\*\*\* -- file7 ---- 0 ----" - # now export by rtagged-by-head and rtagged-by-tag and compare. - dotest basic2-25 "${testcvs} export -r rtagged-by-head -d 1dir first-dir" \ -"${PROG} export: Updating 1dir -U 1dir/file14 -U 1dir/file6 -${PROG} export: Updating 1dir/dir1 -U 1dir/dir1/file14 -U 1dir/dir1/file6 -${PROG} export: Updating 1dir/dir1/dir2 -U 1dir/dir1/dir2/file14 -U 1dir/dir1/dir2/file6" - dotest_fail basic2-25a "test -d 1dir/CVS" - dotest_fail basic2-25b "test -d 1dir/dir1/CVS" - dotest_fail basic2-25c "test -d 1dir/dir1/dir2/CVS" - - dotest basic2-26 "${testcvs} export -r rtagged-by-tag first-dir" \ -"${PROG} export: Updating first-dir -U first-dir/file14 -U first-dir/file6 -${PROG} export: Updating first-dir/dir1 -U first-dir/dir1/file14 -U first-dir/dir1/file6 -${PROG} export: Updating first-dir/dir1/dir2 -U first-dir/dir1/dir2/file14 -U first-dir/dir1/dir2/file6" - dotest_fail basic2-26a "test -d first-dir/CVS" - dotest_fail basic2-26b "test -d first-dir/dir1/CVS" - dotest_fail basic2-26c "test -d first-dir/dir1/dir2/CVS" - - dotest basic2-27 "directory_cmp 1dir first-dir" - rm -r 1dir first-dir - - # checkout by revision vs export by rtagged-by-revision and compare. - mkdir export-dir - dotest basic2-28 "${testcvs} export -rrtagged-by-revision -d export-dir first-dir" \ -"${PROG} export: Updating export-dir -U export-dir/file14 -U export-dir/file6 -U export-dir/file7 -${PROG} export: Updating export-dir/dir1 -U export-dir/dir1/file14 -U export-dir/dir1/file6 -U export-dir/dir1/file7 -${PROG} export: Updating export-dir/dir1/dir2 -U export-dir/dir1/dir2/file14 -U export-dir/dir1/dir2/file6 -U export-dir/dir1/dir2/file7" - dotest_fail basic2-28a "test -d export-dir/CVS" - dotest_fail basic2-28b "test -d export-dir/dir1/CVS" - dotest_fail basic2-28c "test -d export-dir/dir1/dir2/CVS" - - dotest basic2-29 "${testcvs} co -r1.1 first-dir" \ -"${PROG} checkout: Updating first-dir -U first-dir/file14 -U first-dir/file6 -U first-dir/file7 -${PROG} checkout: Updating first-dir/dir1 -U first-dir/dir1/file14 -U first-dir/dir1/file6 -U first-dir/dir1/file7 -${PROG} checkout: Updating first-dir/dir1/dir2 -U first-dir/dir1/dir2/file14 -U first-dir/dir1/dir2/file6 -U first-dir/dir1/dir2/file7" - - # directory copies are done in an oblique way in order to avoid a bug in sun's tmp filesystem. - mkdir first-dir.cpy ; (cd first-dir ; tar cf - . | (cd ../first-dir.cpy ; tar xf -)) - - dotest basic2-30 "directory_cmp first-dir export-dir" - - # interrupt, while we've got a clean 1.1 here, let's import it - # into a couple of other modules. - cd export-dir - dotest_sort basic2-31 "${testcvs} import -m first-import second-dir first-immigration immigration1 immigration1_0" \ -" - -N second-dir/dir1/dir2/file14 -N second-dir/dir1/dir2/file6 -N second-dir/dir1/dir2/file7 -N second-dir/dir1/file14 -N second-dir/dir1/file6 -N second-dir/dir1/file7 -N second-dir/file14 -N second-dir/file6 -N second-dir/file7 -No conflicts created by this import -${PROG} import: Importing ${CVSROOT_DIRNAME}/second-dir/dir1 -${PROG} import: Importing ${CVSROOT_DIRNAME}/second-dir/dir1/dir2" - cd .. - - dotest basic2-32 "${testcvs} export -r HEAD second-dir" \ -"${PROG} export: Updating second-dir -U second-dir/file14 -U second-dir/file6 -U second-dir/file7 -${PROG} export: Updating second-dir/dir1 -U second-dir/dir1/file14 -U second-dir/dir1/file6 -U second-dir/dir1/file7 -${PROG} export: Updating second-dir/dir1/dir2 -U second-dir/dir1/dir2/file14 -U second-dir/dir1/dir2/file6 -U second-dir/dir1/dir2/file7" - - dotest basic2-33 "directory_cmp first-dir second-dir" - - rm -r second-dir - - rm -r export-dir first-dir - mkdir first-dir - (cd first-dir.cpy ; tar cf - . | (cd ../first-dir ; tar xf -)) - - # update the top, cancelling sticky tags, retag, update other copy, compare. - cd first-dir - dotest basic2-34 "${testcvs} update -A -l *file*" \ -"[UP] file6 -${PROG} update: file7 is no longer in the repository" - - # If we don't delete the tag first, cvs won't retag it. - # This would appear to be a feature. - dotest basic2-35 "${testcvs} tag -l -d rtagged-by-revision" \ -"${PROG} tag: Untagging \. -D file14 -D file6" - dotest basic2-36 "${testcvs} tag -l rtagged-by-revision" \ -"${PROG} tag: Tagging \. -T file14 -T file6" - - cd .. - mv first-dir 1dir - mv first-dir.cpy first-dir - cd first-dir - - dotest basic2-37 "${testcvs} -q diff -u" '' - - dotest basic2-38 "${testcvs} update" \ -"${PROG} update: Updating . -${PROG} update: Updating dir1 -${PROG} update: Updating dir1/dir2" - - cd .. - - #### FIXME: is this expected to work??? Need to investigate - #### and fix or remove the test. -# dotest basic2-39 "directory_cmp 1dir first-dir" - - rm -r 1dir first-dir - - # Test the cvs history command. - - # The reason that there are two patterns rather than using - # \(${TESTDIR}\|\) is that we are trying to - # make this portable. Perhaps at some point we should - # ditch that notion and require GNU expr (or dejagnu or....) - # since it seems to be so painful. - - # why are there two lines at the end of the local output - # which don't exist in the remote output? would seem to be - # a CVS bug. - dotest basic2-64 "${testcvs} his -x TOFWUPCGMAR -a" \ -"O [0-9-]* [0-9:]* ${PLUS}0000 ${username} first-dir =first-dir= ${TESTDIR}/\* -A [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file6 first-dir == ${TESTDIR} -A [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file7 first-dir == ${TESTDIR} -A [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file6 first-dir/dir1 == ${TESTDIR} -A [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file7 first-dir/dir1 == ${TESTDIR} -A [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file6 first-dir/dir1/dir2 == ${TESTDIR} -A [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file7 first-dir/dir1/dir2 == ${TESTDIR} -A [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file14 first-dir == ${TESTDIR} -M [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.2 file6 first-dir == ${TESTDIR} -R [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.2 file7 first-dir == ${TESTDIR} -A [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file14 first-dir/dir1 == ${TESTDIR} -M [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.2 file6 first-dir/dir1 == ${TESTDIR} -R [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.2 file7 first-dir/dir1 == ${TESTDIR} -A [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file14 first-dir/dir1/dir2 == ${TESTDIR} -M [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.2 file6 first-dir/dir1/dir2 == ${TESTDIR} -R [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.2 file7 first-dir/dir1/dir2 == ${TESTDIR} -F [0-9-]* [0-9:]* ${PLUS}0000 ${username} =first-dir= ${TESTDIR}/\* -T [0-9-]* [0-9:]* ${PLUS}0000 ${username} first-dir \[rtagged-by-head:A\] -T [0-9-]* [0-9:]* ${PLUS}0000 ${username} first-dir \[rtagged-by-tag:rtagged-by-head\] -T [0-9-]* [0-9:]* ${PLUS}0000 ${username} first-dir \[rtagged-by-revision:1\.1\] -O [0-9-]* [0-9:]* ${PLUS}0000 ${username} \[1\.1\] first-dir =first-dir= ${TESTDIR}/\* -U [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.2 file6 first-dir == ${TESTDIR}/first-dir -W [0-9-]* [0-9:]* ${PLUS}0000 ${username} file7 first-dir == ${TESTDIR}/first-dir" \ -"O [0-9-]* [0-9:]* ${PLUS}0000 ${username} first-dir =first-dir= /\* -A [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file6 first-dir == -A [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file7 first-dir == -A [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file6 first-dir/dir1 == -A [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file7 first-dir/dir1 == -A [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file6 first-dir/dir1/dir2 == -A [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file7 first-dir/dir1/dir2 == -A [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file14 first-dir == -M [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.2 file6 first-dir == -R [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.2 file7 first-dir == -A [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file14 first-dir/dir1 == -M [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.2 file6 first-dir/dir1 == -R [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.2 file7 first-dir/dir1 == -A [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.1 file14 first-dir/dir1/dir2 == -M [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.2 file6 first-dir/dir1/dir2 == -R [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.2 file7 first-dir/dir1/dir2 == -F [0-9-]* [0-9:]* ${PLUS}0000 ${username} =first-dir= /\* -T [0-9-]* [0-9:]* ${PLUS}0000 ${username} first-dir \[rtagged-by-head:A\] -T [0-9-]* [0-9:]* ${PLUS}0000 ${username} first-dir \[rtagged-by-tag:rtagged-by-head\] -T [0-9-]* [0-9:]* ${PLUS}0000 ${username} first-dir \[rtagged-by-revision:1\.1\] -O [0-9-]* [0-9:]* ${PLUS}0000 ${username} \[1\.1\] first-dir =first-dir= /\* -P [0-9-]* [0-9:]* ${PLUS}0000 ${username} 1\.2 file6 first-dir == -W [0-9-]* [0-9:]* ${PLUS}0000 ${username} file7 first-dir == " - - rm -rf ${CVSROOT_DIRNAME}/first-dir - rm -rf ${CVSROOT_DIRNAME}/second-dir - ;; - - parseroot) - mkdir 1; cd 1 - # Test odd cases involving CVSROOT. At the moment, that means we - # are testing roots with '/'s on the end, which CVS should parse off. - CVSROOT_save=${CVSROOT} - CVSROOT="${CVSROOT}/////" - dotest parseroot-1 "${testcvs} -q co CVSROOT/modules" \ -"U CVSROOT/modules" - dotest parseroot-2 "${testcvs} -q ci -fmnull-change CVSROOT/modules" \ -"Checking in CVSROOT/modules; -${CVSROOT_DIRNAME}/CVSROOT/modules,v <-- modules -new revision: 1\.2; previous revision: 1\.1 -done -${PROG} commit: Rebuilding administrative file database" - - if $remote; then - # I only test these when testing remote in case CVS was compiled - # without client support. - - # logout does not try to contact the server. - CVSROOT=":pserver;proxy=localhost;proxyport=8080:localhost/dev/null" - dotest parseroot-3r "$testcvs -d'$CVSROOT' logout" \ -"$PROG logout: WARNING: Ignoring method options found in CVSROOT: \`proxy=localhost;proxyport=8080'\. -$PROG logout: Use CVS version 1\.12\.7 or later to handle method options\. -Logging out of :pserver:$username@localhost:2401/dev/null -$PROG logout: warning: failed to open $HOME/\.cvspass for reading: No such file or directory -$PROG logout: Entry not found\." - fi - - if $keep; then - echo Keeping $TESTDIR and exiting due to --keep - exit 0 - fi - - CVSROOT=$CVSROOT_save - cd .. - rm -r 1 - ;; - - - - files) - # Test of how we specify files on the command line - # (recurse.c and that sort of thing). Vaguely similar to - # tests like basic* and deep. See modules and such tests - # for what happens when we throw in modules and co -d, &c. - - # This particular test is fairly carefully crafted, to spot - # one particular issue with remote. - mkdir 1; cd 1 - dotest files-1 "${testcvs} -q co -l ." "" - mkdir first-dir - dotest files-2 "${testcvs} add first-dir" \ -"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" - cd first-dir - touch tfile - dotest files-3 "${testcvs} add tfile" \ -"${PROG} add: scheduling file .tfile. for addition -${PROG} add: use .${PROG} commit. to add this file permanently" - dotest files-4 "${testcvs} -q ci -m add" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/tfile,v -done -Checking in tfile; -${CVSROOT_DIRNAME}/first-dir/tfile,v <-- tfile -initial revision: 1\.1 -done" - dotest files-5 "${testcvs} -q tag -b C" "T tfile" - dotest files-6 "$testcvs -q update -r C" "U tfile" - mkdir dir - dotest files-7 "${testcvs} add dir" \ -"Directory ${CVSROOT_DIRNAME}/first-dir/dir added to the repository ---> Using per-directory sticky tag .C'" - cd dir - touch .file - dotest files-6 "${testcvs} add .file" \ -"${PROG} add: scheduling file .\.file' for addition on branch .C. -${PROG} add: use .${PROG} commit. to add this file permanently" - mkdir sdir - dotest files-7 "${testcvs} add sdir" \ -"Directory ${CVSROOT_DIRNAME}/first-dir/dir/sdir added to the repository ---> Using per-directory sticky tag .C'" - cd sdir - mkdir ssdir - dotest files-8 "${testcvs} add ssdir" \ -"Directory ${CVSROOT_DIRNAME}/first-dir/dir/sdir/ssdir added to the repository ---> Using per-directory sticky tag .C'" - cd ssdir - touch .file - dotest files-9 "${testcvs} add .file" \ -"${PROG} add: scheduling file .\.file' for addition on branch .C. -${PROG} add: use .${PROG} commit. to add this file permanently" - cd ../.. - dotest files-10 "${testcvs} -q ci -m test" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/dir/Attic/\.file,v -done -Checking in \.file; -${CVSROOT_DIRNAME}/first-dir/dir/Attic/\.file,v <-- \.file -new revision: 1\.1\.2\.1; previous revision: 1\.1 -done -RCS file: ${CVSROOT_DIRNAME}/first-dir/dir/sdir/ssdir/Attic/\.file,v -done -Checking in sdir/ssdir/\.file; -${CVSROOT_DIRNAME}/first-dir/dir/sdir/ssdir/Attic/\.file,v <-- \.file -new revision: 1\.1\.2\.1; previous revision: 1\.1 -done" - dotest files-11 \ -"${testcvs} commit -m test -f ./.file ./sdir/ssdir/.file" \ -"Checking in \.file; -${CVSROOT_DIRNAME}/first-dir/dir/Attic/\.file,v <-- \.file -new revision: 1\.1\.2\.2; previous revision: 1\.1\.2\.1 -done -Checking in \./sdir/ssdir/\.file; -${CVSROOT_DIRNAME}/first-dir/dir/sdir/ssdir/Attic/\.file,v <-- \.file -new revision: 1\.1\.2\.2; previous revision: 1\.1\.2\.1 -done" - if $remote; then - # FIXCVS: - # This is a bug, looks like that toplevel_repos cruft in - # client.c is coming back to haunt us. - # May want to think about the whole issue, toplevel_repos - # has always been crufty and trying to patch it up again - # might be a mistake. - dotest files-12 \ -"${testcvs} commit -f -m test ./sdir/ssdir/.file ./.file" \ -"Checking in \./sdir/ssdir/\.file; -${CVSROOT_DIRNAME}/first-dir/dir/sdir/ssdir/Attic/\.file,v <-- \.file -new revision: 1\.1\.2\.3; previous revision: 1\.1\.2\.2 -done" - - # Sync up the version numbers so that the rest of the - # tests don't need to expect different numbers based - # local or remote. - dotest files-12-workaround \ -"${testcvs} commit -f -m test .file" \ -"Checking in \.file; -${CVSROOT_DIRNAME}/first-dir/dir/Attic/\.file,v <-- \.file -new revision: 1\.1\.2\.3; previous revision: 1\.1\.2\.2 -done" - else - dotest files-12 \ -"${testcvs} commit -f -m test ./sdir/ssdir/.file ./.file" \ -"Checking in \./sdir/ssdir/\.file; -${CVSROOT_DIRNAME}/first-dir/dir/sdir/ssdir/Attic/\.file,v <-- \.file -new revision: 1\.1\.2\.3; previous revision: 1\.1\.2\.2 -done -Checking in \.file; -${CVSROOT_DIRNAME}/first-dir/dir/Attic/\.file,v <-- \.file -new revision: 1\.1\.2\.3; previous revision: 1\.1\.2\.2 -done" - fi - dotest files-13 \ -"${testcvs} commit -fmtest ./sdir/../sdir/ssdir/..///ssdir/.file" \ -"Checking in \./sdir/\.\./sdir/ssdir/\.\.///ssdir/\.file; -${CVSROOT_DIRNAME}/first-dir/dir/sdir/ssdir/Attic/\.file,v <-- \.file -new revision: 1\.1\.2\.4; previous revision: 1\.1\.2\.3 -done" - if $remote; then - dotest files-14 \ -"${testcvs} commit -fmtest ../../first-dir/dir/.file" \ -"Checking in \.\./\.\./first-dir/dir/\.file; -${CVSROOT_DIRNAME}/first-dir/dir/Attic/\.file,v <-- .file -new revision: 1\.1\.2\.4; previous revision: 1\.1\.2\.3 -done" - else - dotest files-14 \ -"${testcvs} commit -fmtest ../../first-dir/dir/.file" \ -"Checking in \.\./\.\./first-dir/dir/\.file; -${CVSROOT_DIRNAME}/first-dir/dir/Attic/\.file,v <-- \.file -new revision: 1\.1\.2\.4; previous revision: 1\.1\.2\.3 -done" - fi - cd ../../.. - - rm -r 1 - rm -rf ${CVSROOT_DIRNAME}/first-dir - ;; - - spacefiles) - # More filename tests, in particular spaces in file names. - # (it might be better to just change a few of the names in - # basica or some other test instead, always good to keep the - # testsuite concise). - - mkdir 1; cd 1 - dotest spacefiles-1 "${testcvs} -q co -l ." "" - touch ./-c - dotest spacefiles-2 "${testcvs} add -- -c" \ -"${PROG} add: scheduling file .-c. for addition -${PROG} add: use .${PROG} commit. to add this file permanently" - dotest spacefiles-3 "${testcvs} -q ci -m add" \ -"RCS file: ${CVSROOT_DIRNAME}/-c,v -done -Checking in -c; -${CVSROOT_DIRNAME}/-c,v <-- -c -initial revision: 1\.1 -done" - mkdir 'first dir' - dotest spacefiles-4 "${testcvs} add 'first dir'" \ -"Directory ${CVSROOT_DIRNAME}/first dir added to the repository" - mkdir ./-b - dotest spacefiles-5 "${testcvs} add -- -b" \ -"Directory ${CVSROOT_DIRNAME}/-b added to the repository" - cd 'first dir' - touch 'a file' - dotest spacefiles-6 "${testcvs} add 'a file'" \ -"${PROG} add: scheduling file .a file. for addition -${PROG} add: use .${PROG} commit. to add this file permanently" - dotest spacefiles-7 "${testcvs} -q ci -m add" \ -"RCS file: ${CVSROOT_DIRNAME}/first dir/a file,v -done -Checking in a file; -${CVSROOT_DIRNAME}/first dir/a file,v <-- a file -initial revision: 1\.1 -done" - dotest spacefiles-8 "${testcvs} -q tag new-tag" "T a file" - cd ../.. - - mkdir 2; cd 2 - dotest spacefiles-10 "${testcvs} co -- -b" \ -"${PROG} checkout: Updating -b" - dotest spacefiles-11 "${testcvs} -q co -- -c" "U \./-c" - rm ./-c - dotest spacefiles-13 "${testcvs} -q co 'first dir'" \ -"U first dir/a file" - cd .. - - mkdir 3; cd 3 - dotest spacefiles-14 "${testcvs} -q co 'first dir/a file'" \ -"U first dir/a file" - cd .. - - rm -r 1 2 3 - rm -rf "${CVSROOT_DIRNAME}/first dir" - rm -r ${CVSROOT_DIRNAME}/-b - rm -f ${CVSROOT_DIRNAME}/-c,v - ;; - - commit-readonly) - mkdir 1; cd 1 - module=x - - : > junk - dotest commit-readonly-1 "$testcvs -Q import -m . $module X Y" '' - dotest commit-readonly-2 "$testcvs -Q co $module" '' - cd $module - - file=m - - # Include an rcs keyword to be expanded. - echo '$Id''$' > $file - - dotest commit-readonly-3 "$testcvs add $file" \ -"${PROG} add: scheduling file .$file. for addition -${PROG} add: use .${PROG} commit. to add this file permanently" - dotest commit-readonly-4 "$testcvs -Q ci -m . $file" \ -"RCS file: ${CVSROOT_DIRNAME}/$module/$file,v -done -Checking in $file; -${CVSROOT_DIRNAME}/$module/$file,v <-- $file -initial revision: 1\.1 -done" - - echo line2 >> $file - # Make the file read-only. - chmod a-w $file - - dotest commit-readonly-5 "$testcvs -Q ci -m . $file" \ -"Checking in $file; -${CVSROOT_DIRNAME}/$module/$file,v <-- $file -new revision: 1\.2; previous revision: 1\.1 -done" - - cd ../.. - rm -rf 1 - rm -rf ${CVSROOT_DIRNAME}/$module - ;; - - status) - # This tests for a bug in the status command which failed to - # notice resolved conflicts. - mkdir status; cd status - dotest status-init-1 "${testcvs} -q co -l ." "" - mkdir first-dir - dotest status-init-2 "${testcvs} add first-dir" \ -"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" - cd first-dir - echo a line >tfile - dotest status-init-3 "${testcvs} add tfile" \ -"${PROG} add: scheduling file .tfile. for addition -${PROG} add: use .${PROG} commit. to add this file permanently" - dotest status-init-4 "${testcvs} -q ci -m add" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/tfile,v -done -Checking in tfile; -${CVSROOT_DIRNAME}/first-dir/tfile,v <-- tfile -initial revision: 1\.1 -done" - cd .. - dotest status-init-5 "${testcvs} -q co -dsecond-dir first-dir" \ -"U second-dir/tfile" - cd second-dir - echo some junk >>tfile - dotest status-init-6 "${testcvs} -q ci -maline" \ -"Checking in tfile; -${CVSROOT_DIRNAME}/first-dir/tfile,v <-- tfile -new revision: 1\.2; previous revision: 1\.1 -done" - cd ../first-dir - echo force a conflict >>tfile - dotest status-init-7 "${testcvs} -q up" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/tfile,v -retrieving revision 1\.1 -retrieving revision 1\.2 -Merging differences between 1\.1 and 1\.2 into tfile -rcsmerge: warning: conflicts during merge -${PROG} update: conflicts found in tfile -C tfile" - - # Now note our status - dotest status-1 "${testcvs} status tfile" \ -"=================================================================== -File: tfile Status: Unresolved Conflict - - Working revision: 1\.2.* - Repository revision: 1\.2 ${CVSROOT_DIRNAME}/first-dir/tfile,v - Sticky Tag: (none) - Sticky Date: (none) - Sticky Options: (none)" - - # touch the file, leaving conflict markers in place - # and note our status - touch tfile - dotest status-2 "${testcvs} status tfile" \ -"=================================================================== -File: tfile Status: File had conflicts on merge - - Working revision: 1\.2.* - Repository revision: 1\.2 ${CVSROOT_DIRNAME}/first-dir/tfile,v - Sticky Tag: (none) - Sticky Date: (none) - Sticky Options: (none)" - - # resolve the conflict - echo resolution >tfile - dotest status-3 "${testcvs} status tfile" \ -"=================================================================== -File: tfile Status: Locally Modified - - Working revision: 1\.2.* - Repository revision: 1\.2 ${CVSROOT_DIRNAME}/first-dir/tfile,v - Sticky Tag: (none) - Sticky Date: (none) - Sticky Options: (none)" - - # Check that there are no problems just using CVS/Root too. - save_CVSROOT=$CVSROOT - unset CVSROOT - dotest status-3a "${testcvs} status tfile" \ -"=================================================================== -File: tfile Status: Locally Modified - - Working revision: 1\.2.* - Repository revision: 1\.2 ${CVSROOT_DIRNAME}/first-dir/tfile,v - Sticky Tag: (none) - Sticky Date: (none) - Sticky Options: (none)" - CVSROOT=$save_CVSROOT - export CVSROOT - - # FIXCVS: - # Update is supposed to re-Register() the file when it - # finds resolved conflicts: - dotest status-4 "grep 'Result of merge' CVS/Entries" \ -"/tfile/1\.2/Result of merge${PLUS}[a-zA-Z0-9 :]*//" - - cd .. - mkdir fourth-dir - dotest status-init-8 "$testcvs add fourth-dir" \ -"Directory $CVSROOT_DIRNAME/fourth-dir added to the repository" - cd fourth-dir - echo yet another line >t3file - dotest status-init-9 "$testcvs add t3file" \ -"$PROG add: scheduling file .t3file. for addition -$PROG add: use .$PROG commit. to add this file permanently" - dotest status-init-10 "$testcvs -q ci -m add" \ -"RCS file: $CVSROOT_DIRNAME/fourth-dir/t3file,v -done -Checking in t3file; -$CVSROOT_DIRNAME/fourth-dir/t3file,v <-- t3file -initial revision: 1\.1 -done" - cd ../first-dir - mkdir third-dir - dotest status-init-11 "$testcvs add third-dir" \ -"Directory $CVSROOT_DIRNAME/first-dir/third-dir added to the repository" - cd third-dir - echo another line >t2file - dotest status-init-12 "$testcvs add t2file" \ -"$PROG add: scheduling file .t2file. for addition -$PROG add: use .$PROG commit. to add this file permanently" - dotest status-init-13 "$testcvs -q ci -m add" \ -"RCS file: $CVSROOT_DIRNAME/first-dir/third-dir/t2file,v -done -Checking in t2file; -$CVSROOT_DIRNAME/first-dir/third-dir/t2file,v <-- t2file -initial revision: 1\.1 -done" - dotest status-5 "$testcvs status ../tfile" \ -"=================================================================== -File: tfile Status: Locally Modified - - Working revision: 1\.2.* - Repository revision: 1\.2 $CVSROOT_DIRNAME/first-dir/tfile,v - Sticky Tag: (none) - Sticky Date: (none) - Sticky Options: (none)" - dotest status-6 "$testcvs status ../../fourth-dir/t3file" \ -"=================================================================== -File: t3file Status: Up-to-date - - Working revision: 1\.1.* - Repository revision: 1\.1 $CVSROOT_DIRNAME/fourth-dir/t3file,v - Sticky Tag: (none) - Sticky Date: (none) - Sticky Options: (none)" - - if $keep; then - echo Keeping $TESTDIR and exiting due to --keep - exit 0 - fi - - cd ../../.. - rm -rf status - rm -rf $CVSROOT_DIRNAME/first-dir $CVSROOT_DIRNAME/fourth-dir - ;; - - rdiff) - # Test rdiff - # XXX for now this is just the most essential test... - cd ${TESTDIR} - - mkdir testimport - cd testimport - echo '$''Id$' > foo - echo '$''Name$' >> foo - echo '$''Id$' > bar - echo '$''Name$' >> bar - dotest_sort rdiff-1 \ - "${testcvs} import -I ! -m test-import-with-keyword trdiff TRDIFF T1" \ -' - -N trdiff/bar -N trdiff/foo -No conflicts created by this import' - dotest rdiff-2 \ - "${testcvs} co -ko trdiff" \ -"${PROG} checkout: Updating trdiff -U trdiff/bar -U trdiff/foo" - cd trdiff - echo something >> foo - dotest rdiff-3 \ - "${testcvs} ci -m added-something foo" \ -"Checking in foo; -${CVSROOT_DIRNAME}/trdiff/foo,v <-- foo -new revision: 1\.2; previous revision: 1\.1 -done" - echo '#ident "@(#)trdiff:$''Name$:$''Id$"' > new - echo "new file" >> new - dotest rdiff-4 \ - "${testcvs} add -m new-file-description new" \ -"${PROG} add: scheduling file \`new' for addition -${PROG} add: use .${PROG} commit. to add this file permanently" - dotest rdiff-5 \ - "${testcvs} commit -m added-new-file new" \ -"RCS file: ${CVSROOT_DIRNAME}/trdiff/new,v -done -Checking in new; -${CVSROOT_DIRNAME}/trdiff/new,v <-- new -initial revision: 1\.1 -done" - dotest rdiff-6 \ - "${testcvs} tag local-v0" \ -"${PROG} tag: Tagging . -T bar -T foo -T new" - dotest rdiff-7 \ - "${testcvs} status -v foo" \ -"=================================================================== -File: foo Status: Up-to-date - - Working revision: 1\.2.* - Repository revision: 1\.2 ${CVSROOT_DIRNAME}/trdiff/foo,v - Sticky Tag: (none) - Sticky Date: (none) - Sticky Options: -ko - - Existing Tags: - local-v0 (revision: 1\.2) - T1 (revision: 1\.1\.1\.1) - TRDIFF (branch: 1\.1\.1)" - - cd .. - rm -r trdiff - - dotest rdiff-8 \ - "${testcvs} rdiff -r T1 -r local-v0 trdiff" \ -"${PROG}"' rdiff: Diffing trdiff -Index: trdiff/foo -diff -c trdiff/foo:1\.1\.1\.1 trdiff/foo:1\.2 -\*\*\* trdiff/foo:1\.1\.1\.1 '"${DATE}"' ---- trdiff/foo '"${DATE}"' -\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* -\*\*\* 1,2 \*\*\*\* -! \$''Id: foo,v 1\.1\.1\.1 [0-9/]* [0-9:]* '"${username}"' Exp \$ -! \$''Name: T1 \$ ---- 1,3 ---- -! \$''Id: foo,v 1\.2 [0-9/]* [0-9:]* '"${username}"' Exp \$ -! \$''Name: local-v0 \$ -! something -Index: trdiff/new -diff -c /dev/null trdiff/new:1\.1 -\*\*\* /dev/null '"${DATE}"' ---- trdiff/new '"${DATE}"' -\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* -\*\*\* 0 \*\*\*\* ---- 1,2 ---- -'"${PLUS}"' #ident "@(#)trdiff:\$''Name: local-v0 \$:\$''Id: new,v 1\.1 [0-9/]* [0-9:]* '"${username}"' Exp \$" -'"${PLUS}"' new file' - - if $keep; then - echo Keeping ${TESTDIR} and exiting due to --keep - exit 0 - fi - - cd .. - rm -r testimport - rm -rf ${CVSROOT_DIRNAME}/trdiff - ;; - - rdiff-short) - # Test that the short patch behaves as expected - # 1) Added file. - # 2) Removed file. - # 3) Different revision number with no difference. - # 4) Different revision number with changes. - # 5) Against trunk. - # 6) Same revision number (no difference). - mkdir rdiff-short; cd rdiff-short - mkdir abc - dotest rdiff-short-init-1 \ -"${testcvs} -q import -I ! -m initial-import abc vendor initial" \ -' -No conflicts created by this import' - - dotest rdiff-short-init-2 "${testcvs} -q get abc" '' - cd abc - echo "abc" >file1.txt - dotest rdiff-short-init-3 "${testcvs} add file1.txt" \ -"${PROG} add: scheduling file .file1\.txt' for addition -${PROG} add: use .${PROG} commit. to add this file permanently" - dotest rdiff-short-init-4 \ -"${testcvs} commit -madd-file1 file1.txt" \ -"RCS file: ${CVSROOT_DIRNAME}/abc/file1\.txt,v -done -Checking in file1\.txt; -${CVSROOT_DIRNAME}/abc/file1\.txt,v <-- file1\.txt -initial revision: 1\.1 -done" - echo def >>file1.txt - dotest rdiff-short-init-5 \ -"${testcvs} commit -mchange-file1 file1.txt" \ -"Checking in file1\.txt; -${CVSROOT_DIRNAME}/abc/file1\.txt,v <-- file1\.txt -new revision: 1\.2; previous revision: 1\.1 -done" - echo "abc" >file1.txt - dotest rdiff-short-init-6 \ -"${testcvs} commit -mrestore-file1-rev1 file1.txt" \ -"Checking in file1\.txt; -${CVSROOT_DIRNAME}/abc/file1\.txt,v <-- file1\.txt -new revision: 1\.3; previous revision: 1\.2 -done" - dotest rdiff-short-init-7 \ -"${testcvs} tag -r 1.1 tag1 file1.txt" \ -"T file1\.txt" - dotest rdiff-short-init-8 \ -"${testcvs} tag -r 1.2 tag2 file1.txt" \ -"T file1\.txt" - dotest rdiff-short-init-9 \ -"${testcvs} tag -r 1.3 tag3 file1.txt" \ -"T file1\.txt" - echo "abc" >file2.txt - dotest rdiff-short-init-10 \ -"${testcvs} add file2.txt" \ -"${PROG} add: scheduling file .file2\.txt' for addition -${PROG} add: use .${PROG} commit. to add this file permanently" - dotest rdiff-add-remove-nodiff-init-11 \ -"${testcvs} commit -madd-file2 file2.txt" \ -"RCS file: ${CVSROOT_DIRNAME}/abc/file2\.txt,v -done -Checking in file2\.txt; -${CVSROOT_DIRNAME}/abc/file2\.txt,v <-- file2\.txt -initial revision: 1\.1 -done" - dotest rdiff-short-init-12 \ -"${testcvs} tag -r 1.1 tag4 file2.txt" \ -"T file2\.txt" - dotest rdiff-short-init-13 \ -"${testcvs} tag -r 1.1 tag5 file2.txt" \ -"T file2\.txt" - cd ../.. - rm -fr rdiff-short - - # 3) Different revision number with no difference. - dotest rdiff-short-no-real-change \ -"${testcvs} -q rdiff -s -r tag1 -r tag3 abc" - - # 4) Different revision number with changes. - dotest rdiff-short-real-change \ -"${testcvs} -q rdiff -s -r tag1 -r tag2 abc" \ -'File abc/file1.txt changed from revision 1\.1 to 1\.2' - - # 1) Added file. - # 2) Removed file. - dotest_sort rdiff-short-remove-add \ -"${testcvs} -q rdiff -s -r tag2 -r tag4 abc" \ -'File abc/file1\.txt is removed; tag2 revision 1\.2 -File abc/file2\.txt is new; tag4 revision 1\.1' - - # 6) Same revision number (no difference). - dotest rdiff-short-no-change \ -"${testcvs} -q rdiff -s -r tag4 -r tag5 abc" - - # 5) Against trunk. - # Check that the messages change when we diff against the trunk - # rather than a tag or date. - dotest rdiff-short-against-trunk-1 \ -"${testcvs} -q rdiff -s -rtag4 abc" \ -"File abc/file1\.txt is new; current revision 1\.3" - - dotest rdiff-short-against-trunk-2 \ -"${testcvs} -q rdiff -s -rtag2 abc" \ -"File abc/file1\.txt changed from revision 1\.2 to 1\.3 -File abc/file2\.txt is new; current revision 1\.1" - - rm -rf ${CVSROOT_DIRNAME}/abc - ;; - - rdiff2) - # Test for the segv problem reported by James Cribb - # Somewhere to work - mkdir rdiff2; cd rdiff2 - # Create a module "m" with files "foo" and "d/bar" - mkdir m; cd m - echo foo >foo - mkdir d - echo bar >d/bar - dotest_sort rdiff2-1 \ -"${testcvs} -q import -I ! -m initial-import m vendor initial" \ -' - -N m/d/bar -N m/foo -No conflicts created by this import' - - cd .. - rm -r m - - # Remove "foo" - dotest rdiff2-2 "${testcvs} get m" \ -"${PROG} checkout: Updating m -U m/foo -${PROG} checkout: Updating m/d -U m/d/bar" - cd m - dotest rdiff2-3 "${testcvs} rm -f foo" \ -"${PROG} remove: scheduling .foo. for removal -${PROG} remove: use .${PROG} commit. to remove this file permanently" - - dotest rdiff2-4 "${testcvs} commit -m Removed foo" \ -"Removing foo; -${CVSROOT_DIRNAME}/m/foo,v <-- foo -new revision: delete; previous revision: 1\.1\.1\.1 -done" - - # Modify "d/bar" - echo foo >d/bar - dotest rdiff2-5 "${testcvs} commit -m Changed d/bar" \ -"Checking in d/bar; -${CVSROOT_DIRNAME}/m/d/bar,v <-- bar -new revision: 1\.2; previous revision: 1\.1 -done" - - # Crash before showing d/bar diffs - dotest_fail rdiff2-6 "${testcvs} rdiff -t m" \ -"${PROG} rdiff: Diffing m -${PROG} rdiff: Diffing m/d -Index: m/d/bar -diff -c m/d/bar:1\.1\.1\.1 m/d/bar:1\.2 -\*\*\* m/d/bar:1\.1\.1\.1 ${DATE} ---- m/d/bar ${DATE} -\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* -\*\*\* 1 \*\*\*\* -! bar ---- 1 ---- -! foo" - if $keep; then - echo Keeping ${TESTDIR} and exiting due to --keep - exit 0 - fi - cd ../.. - rm -rf rdiff2 - rm -rf ${CVSROOT_DIRNAME}/m - ;; - - diff) - # Various tests specific to the "cvs diff" command. - # Related tests: - # death2: -N - # rcslib: cvs diff and $Name. - # rdiff: cvs rdiff. - # diffmerge*: nuts and bolts (stuff within diff library) - mkdir 1; cd 1 - dotest diff-1 "${testcvs} -q co -l ." '' - mkdir first-dir - dotest diff-2 "${testcvs} add first-dir" \ -"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" - cd first-dir - - # diff is anomalous. Most CVS commands print the "nothing - # known" message (or worse yet, no message in some cases) but - # diff says "I know nothing". Shrug. - dotest_fail diff-3 "${testcvs} diff xyzpdq" \ -"${PROG} diff: I know nothing about xyzpdq" - touch abc - dotest diff-4 "${testcvs} add abc" \ -"${PROG} add: scheduling file .abc. for addition -${PROG} add: use .${PROG} commit. to add this file permanently" - dotest diff-5 "${testcvs} -q ci -mtest" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/abc,v -done -Checking in abc; -${CVSROOT_DIRNAME}/first-dir/abc,v <-- abc -initial revision: 1\.1 -done" - echo "extern int gethostname ();" >abc - dotest diff-6 "${testcvs} -q ci -mtest" \ -"Checking in abc; -${CVSROOT_DIRNAME}/first-dir/abc,v <-- abc -new revision: 1\.2; previous revision: 1\.1 -done" - echo "#include " >abc - # check the behavior of the --ifdef=MACRO option - dotest_fail diff-7 "${testcvs} -q diff --ifdef=HAVE_WINSOCK_H" \ -"Index: abc -=================================================================== -RCS file: ${CVSROOT_DIRNAME}/first-dir/abc,v -retrieving revision 1\.2 -diff --ifdef HAVE_WINSOCK_H -r1\.2 abc -#ifndef HAVE_WINSOCK_H -extern int gethostname (); -#else /\* HAVE_WINSOCK_H \*/ -#include -#endif /\* HAVE_WINSOCK_H \*/" - - if $keep; then - echo Keeping ${TESTDIR} and exiting due to --keep - exit 0 - fi - - cd ../.. - rm -rf ${CVSROOT_DIRNAME}/first-dir - rm -r 1 - ;; - - diffnl) - # Test handling of 'cvs diff' of files without newlines - mkdir 1; cd 1 - dotest diffnl-000 "${testcvs} -q co -l ." '' - mkdir first-dir - dotest diffnl-001 "${testcvs} add first-dir" \ -"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" - cd first-dir - - ${AWK} 'BEGIN {printf("one\ntwo\nthree\nfour\nfive\nsix")}' abc - dotest diffnl-002 "${testcvs} add abc" \ -"${PROG} add: scheduling file .abc. for addition -${PROG} add: use .${PROG} commit. to add this file permanently" - dotest diffnl-003 "${testcvs} -q ci -mtest" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/abc,v -done -Checking in abc; -${CVSROOT_DIRNAME}/first-dir/abc,v <-- abc -initial revision: 1\.1 -done" - - # change to line near EOF - ${AWK} 'BEGIN {printf("one\ntwo\nthree\nfour\nsix")}' abc - dotest_fail diffnl-100 "${testcvs} diff abc" \ -"Index: abc -=================================================================== -RCS file: ${CVSROOT_DIRNAME}/first-dir/abc,v -retrieving revision 1\.1 -diff -r1\.1 abc -5d4 -< five" - dotest_fail diffnl-101 "${testcvs} diff -u abc" \ -"Index: abc -=================================================================== -RCS file: ${CVSROOT_DIRNAME}/first-dir/abc,v -retrieving revision 1\.1 -diff -u -r1\.1 abc ---- abc ${RFCDATE} 1\.1 -+++ abc ${RFCDATE} -@@ -2,5 +2,4 @@ - two - three - four --five - six -\\\\ No newline at end of file" - dotest diffnl-102 "${testcvs} -q ci -mtest abc" \ -"Checking in abc; -${CVSROOT_DIRNAME}/first-dir/abc,v <-- abc -new revision: 1\.2; previous revision: 1\.1 -done" - - # Change to last line - ${AWK} 'BEGIN {printf("one\ntwo\nthree\nfour\nseven")}' abc - dotest_fail diffnl-200 "${testcvs} diff abc" \ -"Index: abc -=================================================================== -RCS file: ${CVSROOT_DIRNAME}/first-dir/abc,v -retrieving revision 1\.2 -diff -r1\.2 abc -5c5 -< six -\\\\ No newline at end of file ---- -> seven -\\\\ No newline at end of file" - dotest_fail diffnl-201 "${testcvs} diff -u abc" \ -"Index: abc -=================================================================== -RCS file: ${CVSROOT_DIRNAME}/first-dir/abc,v -retrieving revision 1\.2 -diff -u -r1\.2 abc ---- abc ${RFCDATE} 1\.2 -+++ abc ${RFCDATE} -@@ -2,4 +2,4 @@ - two - three - four --six -\\\\ No newline at end of file -+seven -\\\\ No newline at end of file" - dotest diffnl-202 "${testcvs} ci -mtest abc" \ -"Checking in abc; -${CVSROOT_DIRNAME}/first-dir/abc,v <-- abc -new revision: 1\.3; previous revision: 1\.2 -done" - - # Addition of newline - echo "one -two -three -four -seven" > abc - dotest_fail diffnl-300 "${testcvs} diff abc" \ -"Index: abc -=================================================================== -RCS file: ${CVSROOT_DIRNAME}/first-dir/abc,v -retrieving revision 1\.3 -diff -r1\.3 abc -5c5 -< seven -\\\\ No newline at end of file ---- -> seven" - dotest_fail diffnl-301 "${testcvs} diff -u abc" \ -"Index: abc -=================================================================== -RCS file: ${CVSROOT_DIRNAME}/first-dir/abc,v -retrieving revision 1\.3 -diff -u -r1\.3 abc ---- abc ${RFCDATE} 1\.3 -+++ abc ${RFCDATE} -@@ -2,4 +2,4 @@ - two - three - four --seven -\\\\ No newline at end of file -+seven" - dotest diffnl-302 "${testcvs} ci -mtest abc" \ -"Checking in abc; -${CVSROOT_DIRNAME}/first-dir/abc,v <-- abc -new revision: 1\.4; previous revision: 1\.3 -done" - - # Removal of newline - ${AWK} 'BEGIN {printf("one\ntwo\nthree\nfour\nseven")}' abc - dotest_fail diffnl-400 "${testcvs} diff abc" \ -"Index: abc -=================================================================== -RCS file: ${CVSROOT_DIRNAME}/first-dir/abc,v -retrieving revision 1\.4 -diff -r1\.4 abc -5c5 -< seven ---- -> seven -\\\\ No newline at end of file" - dotest_fail diffnl-401 "${testcvs} diff -u abc" \ -"Index: abc -=================================================================== -RCS file: ${CVSROOT_DIRNAME}/first-dir/abc,v -retrieving revision 1\.4 -diff -u -r1\.4 abc ---- abc ${RFCDATE} 1\.4 -+++ abc ${RFCDATE} -@@ -2,4 +2,4 @@ - two - three - four --seven -+seven -\\\\ No newline at end of file" - - cd ../.. - rm -r 1 - rm -rf ${CVSROOT_DIRNAME}/first-dir - ;; - - death) - # next dive. test death support. - - # NOTE: this section has reached the size and - # complexity where it is getting to be a good idea to - # add new death support tests to a new section rather - # than continuing to piggyback them onto the tests here. - - mkdir ${CVSROOT_DIRNAME}/first-dir - if ${CVS} co first-dir ; then - pass 65 - else - fail 65 - fi - - cd first-dir - - # Create a directory with only dead files, to make sure CVS - # doesn't get confused by it. - mkdir subdir - dotest 65a0 "${testcvs} add subdir" \ -"Directory ${CVSROOT_DIRNAME}/first-dir/subdir added to the repository" - cd subdir - echo file in subdir >sfile - dotest 65a1 "${testcvs} add sfile" \ -"${PROG}"' add: scheduling file `sfile'\'' for addition -'"${PROG}"' add: use .'"${PROG}"' commit. to add this file permanently' - dotest 65a2 "${testcvs} -q ci -m add-it" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/subdir/sfile,v -done -Checking in sfile; -${CVSROOT_DIRNAME}/first-dir/subdir/sfile,v <-- sfile -initial revision: 1\.1 -done" - rm sfile - dotest 65a3 "${testcvs} rm sfile" \ -"${PROG}"' remove: scheduling `sfile'\'' for removal -'"${PROG}"' remove: use .'"${PROG}"' commit. to remove this file permanently' - dotest 65a4 "${testcvs} -q ci -m remove-it" \ -"Removing sfile; -${CVSROOT_DIRNAME}/first-dir/subdir/sfile,v <-- sfile -new revision: delete; previous revision: 1\.1 -done" - cd .. - dotest 65a5 "${testcvs} -q update -P" '' - dotest_fail 65a6 "test -d subdir" '' - - # add a file. - touch file1 - if ${CVS} add file1 2>> ${LOGFILE}; then - pass 66 - else - fail 66 - fi - - # commit - if ${CVS} ci -m test >> ${LOGFILE} 2>&1; then - pass 67 - else - fail 67 - fi - - # remove - rm file1 - if ${CVS} rm file1 2>> ${LOGFILE}; then - pass 68 - else - fail 68 - fi - - # commit - if ${CVS} ci -m test >>${LOGFILE} ; then - pass 69 - else - fail 69 - fi - - dotest_fail 69a0 "test -f file1" '' - # get the old contents of file1 back - if ${testcvs} update -p -r 1.1 file1 >file1 2>>${LOGFILE}; then - pass 69a1 - else - fail 69a1 - fi - dotest 69a2 "cat file1" '' - - # create second file - touch file2 - if ${CVS} add file1 file2 2>> ${LOGFILE}; then - pass 70 - else - fail 70 - fi - - # commit - if ${CVS} ci -m test >> ${LOGFILE} 2>&1; then - pass 71 - else - fail 71 - fi - - # log - if ${CVS} log file1 >> ${LOGFILE}; then - pass 72 - else - fail 72 - fi - - # file4 will be dead at the time of branching and stay dead. - echo file4 > file4 - dotest death-file4-add "${testcvs} add file4" \ -"${PROG}"' add: scheduling file `file4'\'' for addition -'"${PROG}"' add: use .'"${PROG}"' commit. to add this file permanently' - dotest death-file4-ciadd "${testcvs} -q ci -m add file4" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/file4,v -done -Checking in file4; -${CVSROOT_DIRNAME}/first-dir/file4,v <-- file4 -initial revision: 1\.1 -done" - rm file4 - dotest death-file4-rm "${testcvs} remove file4" \ -"${PROG}"' remove: scheduling `file4'\'' for removal -'"${PROG}"' remove: use .'"${PROG}"' commit. to remove this file permanently' - dotest death-file4-cirm "${testcvs} -q ci -m remove file4" \ -"Removing file4; -${CVSROOT_DIRNAME}/first-dir/file4,v <-- file4 -new revision: delete; previous revision: 1\.1 -done" - - # Tag the branchpoint. - dotest death-72a "${testcvs} -q tag bp_branch1" 'T file1 -T file2' - - # branch1 - if ${CVS} tag -b branch1 ; then - pass 73 - else - fail 73 - fi - - # and move to the branch. - if ${CVS} update -r branch1 ; then - pass 74 - else - fail 74 - fi - - dotest_fail death-file4-3 "test -f file4" '' - - # add a file in the branch - echo line1 from branch1 >> file3 - if ${CVS} add file3 2>> ${LOGFILE}; then - pass 75 - else - fail 75 - fi - - # commit - if ${CVS} ci -m test >> ${LOGFILE} 2>&1; then - pass 76 - else - fail 76 - fi - - dotest death-76a0 \ -"${testcvs} -q rdiff -r bp_branch1 -r branch1 first-dir" \ -"Index: first-dir/file3 -diff -c /dev/null first-dir/file3:1\.1\.2\.1 -\*\*\* /dev/null ${DATE} ---- first-dir/file3 ${DATE} -\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* -\*\*\* 0 \*\*\*\* ---- 1 ---- -${PLUS} line1 from branch1" - dotest death-76a1 \ -"${testcvs} -q rdiff -r branch1 -r bp_branch1 first-dir" \ -"Index: first-dir/file3 -diff -c first-dir/file3:1\.1\.2\.1 first-dir/file3:removed -\*\*\* first-dir/file3:1\.1\.2\.1 ${DATE} ---- first-dir/file3 ${DATE} -\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* -\*\*\* 1 \*\*\*\* -- line1 from branch1 ---- 0 ----" - - # remove - rm file3 - if ${CVS} rm file3 2>> ${LOGFILE}; then - pass 77 - else - fail 77 - fi - - # commit - if ${CVS} ci -m test >>${LOGFILE} ; then - pass 78 - else - fail 78 - fi - - # add again - echo line1 from branch1 >> file3 - if ${CVS} add file3 2>> ${LOGFILE}; then - pass 79 - else - fail 79 - fi - - # commit - if ${CVS} ci -m test >> ${LOGFILE} 2>&1; then - pass 80 - else - fail 80 - fi - - # change the first file - echo line2 from branch1 >> file1 - - # commit - if ${CVS} ci -m test >> ${LOGFILE} 2>&1; then - pass 81 - else - fail 81 - fi - - # remove the second - rm file2 - if ${CVS} rm file2 2>> ${LOGFILE}; then - pass 82 - else - fail 82 - fi - - # commit - if ${CVS} ci -m test >>${LOGFILE}; then - pass 83 - else - fail 83 - fi - - # back to the trunk. - if ${CVS} update -A 2>> ${LOGFILE}; then - pass 84 - else - fail 84 - fi - - dotest_fail death-file4-4 "test -f file4" '' - - if test -f file3 ; then - fail 85 - else - pass 85 - fi - - # join - dotest 86 "${testcvs} -q update -j branch1" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -retrieving revision 1\.3 -retrieving revision 1\.3\.2\.1 -Merging differences between 1\.3 and 1\.3\.2\.1 into file1 -${PROG} update: scheduling file2 for removal -U file3" - - dotest_fail death-file4-5 "test -f file4" '' - - if test -f file3 ; then - pass 87 - else - fail 87 - fi - - # Make sure that we joined the correct change to file1 - if echo line2 from branch1 | cmp - file1 >/dev/null; then - pass 87a - else - fail 87a - fi - - # update - if ${CVS} update ; then - pass 88 - else - fail 88 - fi - - # commit - dotest 89 "${testcvs} -q ci -m test" \ -"Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -new revision: 1\.4; previous revision: 1\.3 -done -Removing file2; -${CVSROOT_DIRNAME}/first-dir/file2,v <-- file2 -new revision: delete; previous revision: 1\.1 -done -Checking in file3; -${CVSROOT_DIRNAME}/first-dir/file3,v <-- file3 -new revision: 1\.2; previous revision: 1\.1 -done" - cd .. - mkdir 2 - cd 2 - dotest 89a "${testcvs} -q co first-dir" 'U first-dir/file1 -U first-dir/file3' - cd .. - rm -r 2 - cd first-dir - - # remove first file. - rm file1 - if ${CVS} rm file1 2>> ${LOGFILE}; then - pass 90 - else - fail 90 - fi - - # commit - if ${CVS} ci -m test >>${LOGFILE}; then - pass 91 - else - fail 91 - fi - - if test -f file1 ; then - fail 92 - else - pass 92 - fi - - # typo; try to get to the branch and fail - dotest_fail 92.1a "${testcvs} update -r brnach1" \ - "${PROG}"' \[update aborted\]: no such tag brnach1' - # Make sure we are still on the trunk - if test -f file1 ; then - fail 92.1b - else - pass 92.1b - fi - if test -f file3 ; then - pass 92.1c - else - fail 92.1c - fi - - # back to branch1 - if ${CVS} update -r branch1 2>> ${LOGFILE}; then - pass 93 - else - fail 93 - fi - - dotest_fail death-file4-6 "test -f file4" '' - - if test -f file1 ; then - pass 94 - else - fail 94 - fi - - # and join - dotest 95 "$testcvs -q update -j HEAD" \ -"$PROG update: file file1 has been removed in revision HEAD, but the destination is incompatibly modified -C file1 -$PROG update: file file3 exists, but has been added in revision HEAD" - - dotest_fail death-file4-7 "test -f file4" '' - - # file2 should not have been recreated. It was - # deleted on the branch, and has not been modified on - # the trunk. That means that there have been no - # changes between the greatest common ancestor (the - # trunk version) and HEAD. - dotest_fail death-file2-1 "test -f file2" '' - - cd .. ; rm -rf first-dir ${CVSROOT_DIRNAME}/first-dir - ;; - - death2) - # More tests of death support. - mkdir ${CVSROOT_DIRNAME}/first-dir - dotest death2-1 "${testcvs} -q co first-dir" '' - - cd first-dir - - # Add two files on the trunk. - echo "first revision" > file1 - echo "file4 first revision" > file4 - dotest death2-2 "${testcvs} add file1 file4" \ -"${PROG}"' add: scheduling file `file1'\'' for addition -'"${PROG}"' add: scheduling file `file4'\'' for addition -'"${PROG}"' add: use .'"${PROG}"' commit. to add these files permanently' - - dotest death2-3 "${testcvs} -q commit -m add" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -done -Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -initial revision: 1\.1 -done -RCS file: ${CVSROOT_DIRNAME}/first-dir/file4,v -done -Checking in file4; -${CVSROOT_DIRNAME}/first-dir/file4,v <-- file4 -initial revision: 1\.1 -done" - - # Make a branch and a non-branch tag. - dotest death2-4 "${testcvs} -q tag -b branch" \ -'T file1 -T file4' - dotest death2-5 "${testcvs} -q tag tag" \ -'T file1 -T file4' - - # Switch over to the branch. - dotest death2-6 "$testcvs -q update -r branch" \ -'[UP] file1 -[UP] file4' - - # Delete the file on the branch. - rm file1 - dotest death2-7 "${testcvs} rm file1" \ -"${PROG} remove: scheduling .file1. for removal -${PROG} remove: use .${PROG} commit. to remove this file permanently" - - # Test diff of the removed file before it is committed. - dotest_fail death2-diff-1 "${testcvs} -q diff file1" \ -"${PROG} diff: file1 was removed, no comparison available" - - dotest_fail death2-diff-2 "${testcvs} -q diff -N -c file1" \ -"Index: file1 -=================================================================== -RCS file: file1 -diff -N file1 -\*\*\* file1 ${RFCDATE} [0-9.]* ---- /dev/null ${RFCDATE_EPOCH} -\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* -\*\*\* 1 \*\*\*\* -- first revision ---- 0 ----" - - dotest death2-8 "${testcvs} -q ci -m removed" \ -"Removing file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -new revision: delete; previous revision: 1\.1 -done" - - # Test diff of a dead file. - dotest_fail death2-diff-3 \ -"${testcvs} -q diff -r1.1 -rbranch -c file1" \ -"${PROG} diff: Tag branch refers to a dead (removed) revision in file .file1.\. -${PROG} diff: No comparison available\. Pass .-N. to .${PROG} diff.${QUESTION}" - # and in reverse - dotest_fail death2-diff-3a \ -"${testcvs} -q diff -rbranch -r1.1 -c file1" \ -"${PROG} diff: Tag branch refers to a dead (removed) revision in file .file1.\. -${PROG} diff: No comparison available\. Pass .-N. to .${PROG} diff.${QUESTION}" - - dotest_fail death2-diff-4 \ -"${testcvs} -q diff -r1.1 -rbranch -N -c file1" \ -"Index: file1 -=================================================================== -RCS file: file1 -diff -N file1 -\*\*\* file1 ${RFCDATE} [0-9.]* ---- /dev/null ${RFCDATE_EPOCH} -\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* -\*\*\* 1 \*\*\*\* -- first revision ---- 0 ----" - # and in reverse - dotest_fail death2-diff-4a \ -"${testcvs} -q diff -rbranch -r1.1 -N -c file1" \ -"Index: file1 -=================================================================== -RCS file: file1 -diff -N file1 -\*\*\* /dev/null ${RFCDATE_EPOCH} ---- file1 ${RFCDATE} [0-9.]* -\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* -\*\*\* 0 \*\*\*\* ---- 1 ---- -+ first revision" - - - dotest_fail death2-diff-5 "${testcvs} -q diff -rtag -c ." \ -"${PROG} diff: file1 no longer exists, no comparison available" - - dotest_fail death2-diff-6 "${testcvs} -q diff -rtag -N -c ." \ -"Index: file1 -=================================================================== -RCS file: file1 -diff -N file1 -\*\*\* file1 [-a-zA-Z0-9: ]* [0-9.]* ---- /dev/null ${RFCDATE_EPOCH} -\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* -\*\*\* 1 \*\*\*\* -- first revision ---- 0 ----" - - # Test rdiff of a dead file. - dotest death2-rdiff-1 \ -"${testcvs} -q rtag -rbranch rdiff-tag first-dir" '' - - dotest death2-rdiff-2 "${testcvs} -q rdiff -rtag -rbranch first-dir" \ -"Index: first-dir/file1 -diff -c first-dir/file1:1\.1 first-dir/file1:removed -\*\*\* first-dir/file1:1\.1 [a-zA-Z0-9: ]* ---- first-dir/file1 [a-zA-Z0-9: ]* -\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* -\*\*\* 1 \*\*\*\* -- first revision ---- 0 ----" - - # Readd the file to the branch. - echo "second revision" > file1 - dotest death2-9 "${testcvs} add file1" \ -"${PROG}"' add: file `file1'\'' will be added on branch `branch'\'' from version 1\.1\.2\.1 -'"${PROG}"' add: use .'"${PROG}"' commit. to add this file permanently' - - # Test diff of the added file before it is committed. - dotest_fail death2-diff-7 "${testcvs} -q diff file1" \ -"${PROG} diff: file1 is a new entry, no comparison available" - - dotest_fail death2-diff-8 "${testcvs} -q diff -N -c file1" \ -"Index: file1 -=================================================================== -RCS file: file1 -diff -N file1 -\*\*\* /dev/null ${RFCDATE_EPOCH} ---- file1 ${RFCDATE} -\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* -\*\*\* 0 \*\*\*\* ---- 1 ---- -${PLUS} second revision" - - dotest death2-10 "${testcvs} -q commit -m add" \ -"Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -new revision: 1\.1\.2\.2; previous revision: 1\.1\.2\.1 -done" - - # Delete file4 from the branch - dotest death2-10a "${testcvs} rm -f file4" \ -"${PROG} remove: scheduling .file4. for removal -${PROG} remove: use .${PROG} commit. to remove this file permanently" - dotest death2-10b "${testcvs} -q ci -m removed" \ -"Removing file4; -${CVSROOT_DIRNAME}/first-dir/file4,v <-- file4 -new revision: delete; previous revision: 1\.1 -done" - - # Back to the trunk. - dotest death2-11 "${testcvs} -q update -A" \ -"[UP] file1 -U file4" - - # Add another file on the trunk. - echo "first revision" > file2 - dotest death2-12 "${testcvs} add file2" \ -"${PROG}"' add: scheduling file `file2'\'' for addition -'"${PROG}"' add: use .'"${PROG}"' commit. to add this file permanently' - dotest death2-13 "${testcvs} -q commit -m add" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v -done -Checking in file2; -${CVSROOT_DIRNAME}/first-dir/file2,v <-- file2 -initial revision: 1\.1 -done" - - # Modify file4 on the trunk. - echo "new file4 revision" > file4 - dotest death2-13a "${testcvs} -q commit -m mod" \ -"Checking in file4; -${CVSROOT_DIRNAME}/first-dir/file4,v <-- file4 -new revision: 1\.2; previous revision: 1\.1 -done" - - # Back to the branch. - # The ``no longer in the repository'' message doesn't really - # look right to me, but that's what CVS currently prints for - # this case. - dotest death2-14 "${testcvs} -q update -r branch" \ -"[UP] file1 -${PROG} update: file2 is no longer in the repository -${PROG} update: file4 is no longer in the repository" - - # Add a file on the branch with the same name. - echo "branch revision" > file2 - dotest death2-15 "${testcvs} add file2" \ -"${PROG}"' add: scheduling file `file2'\'' for addition on branch `branch'\'' -'"${PROG}"' add: use .'"${PROG}"' commit. to add this file permanently' - dotest death2-16 "${testcvs} -q commit -m add" \ -"Checking in file2; -${CVSROOT_DIRNAME}/first-dir/file2,v <-- file2 -new revision: 1\.1\.2\.2; previous revision: 1\.1\.2\.1 -done" - - # Add a new file on the branch. - echo "first revision" > file3 - dotest death2-17 "${testcvs} add file3" \ -"${PROG}"' add: scheduling file `file3'\'' for addition on branch `branch'\'' -'"${PROG}"' add: use .'"${PROG}"' commit. to add this file permanently' - dotest death2-18 "${testcvs} -q commit -m add" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/Attic/file3,v -done -Checking in file3; -${CVSROOT_DIRNAME}/first-dir/Attic/file3,v <-- file3 -new revision: 1\.1\.2\.1; previous revision: 1\.1 -done" - - # Test diff of a nonexistent tag - dotest_fail death2-diff-9 "${testcvs} -q diff -rtag -c file3" \ -"${PROG} diff: tag tag is not in file file3" - - dotest_fail death2-diff-10 "${testcvs} -q diff -rtag -N -c file3" \ -"Index: file3 -=================================================================== -RCS file: file3 -diff -N file3 -\*\*\* /dev/null ${RFCDATE_EPOCH} ---- file3 ${RFCDATE} [0-9.]* -\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* -\*\*\* 0 \*\*\*\* ---- 1 ---- -${PLUS} first revision" - - dotest_fail death2-diff-11 "${testcvs} -q diff -rtag -c ." \ -"Index: file1 -=================================================================== -RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -retrieving revision 1\.1 -retrieving revision 1\.1\.2\.2 -diff -c -r1\.1 -r1\.1\.2\.2 -\*\*\* file1 ${RFCDATE} [0-9.]* ---- file1 ${RFCDATE} [0-9.]* -\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* -\*\*\* 1 \*\*\*\* -! first revision ---- 1 ---- -! second revision -${PROG} diff: tag tag is not in file file2 -${PROG} diff: tag tag is not in file file3 -${PROG} diff: file4 no longer exists, no comparison available" - - dotest_fail death2-diff-12 "${testcvs} -q diff -rtag -c -N ." \ -"Index: file1 -=================================================================== -RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -retrieving revision 1\.1 -retrieving revision 1\.1\.2\.2 -diff -c -r1\.1 -r1\.1\.2\.2 -\*\*\* file1 ${RFCDATE} [0-9.]* ---- file1 ${RFCDATE} [0-9.]* -\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* -\*\*\* 1 \*\*\*\* -! first revision ---- 1 ---- -! second revision -Index: file2 -=================================================================== -RCS file: file2 -diff -N file2 -\*\*\* /dev/null ${RFCDATE_EPOCH} ---- file2 ${RFCDATE} [0-9.]* -\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* -\*\*\* 0 \*\*\*\* ---- 1 ---- -${PLUS} branch revision -Index: file3 -=================================================================== -RCS file: file3 -diff -N file3 -\*\*\* /dev/null ${RFCDATE_EPOCH} ---- file3 ${RFCDATE} [0-9.]* -\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* -\*\*\* 0 \*\*\*\* ---- 1 ---- -${PLUS} first revision -Index: file4 -=================================================================== -RCS file: file4 -diff -N file4 -\*\*\* file4 ${RFCDATE} [0-9.]* ---- /dev/null ${RFCDATE_EPOCH} -\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* -\*\*\* 1 \*\*\*\* -- file4 first revision ---- 0 ----" - - # Switch to the nonbranch tag. - dotest death2-19 "${testcvs} -q update -r tag" \ -"[UP] file1 -${PROG} update: file2 is no longer in the repository -${PROG} update: file3 is no longer in the repository -U file4" - - dotest_fail death2-20 "test -f file2" - - # Make sure diff only reports appropriate files. - dotest_fail death2-diff-13 "${testcvs} -q diff -r rdiff-tag" \ -"${PROG} diff: Tag rdiff-tag refers to a dead (removed) revision in file .file1.\. -${PROG} diff: No comparison available\. Pass .-N. to .${PROG} diff.${QUESTION}" - - dotest_fail death2-diff-14 "${testcvs} -q diff -r rdiff-tag -c -N" \ -"Index: file1 -=================================================================== -RCS file: file1 -diff -N file1 -\*\*\* /dev/null ${RFCDATE_EPOCH} ---- file1 ${RFCDATE} [0-9.]* -\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* -\*\*\* 0 \*\*\*\* ---- 1 ---- -${PLUS} first revision" - - # now back to the trunk - dotest death2-21 "$testcvs -q update -A" \ -'[UP] file1 -U file2 -U file4' - - # test merging with a dead file - dotest death2-22 "${testcvs} -q co first-dir" \ -"U first-dir/file1 -U first-dir/file2 -U first-dir/file4" - - cd first-dir - dotest death2-23 "${testcvs} rm -f file4" \ -"${PROG} remove: scheduling .file4. for removal -${PROG} remove: use .${PROG} commit. to remove this file permanently" - dotest death2-24 "${testcvs} -q ci -m removed file4" \ -"Removing file4; -${CVSROOT_DIRNAME}/first-dir/file4,v <-- file4 -new revision: delete; previous revision: 1\.2 -done" - cd .. - echo "new stuff" >file4 - dotest_fail death2-25 "${testcvs} up file4" \ -"${PROG} update: conflict: file4 is modified but no longer in the repository -C file4" - - cd .. ; rm -rf first-dir ${CVSROOT_DIRNAME}/first-dir - ;; - - - - death-rtag) - # This documents a bug in CVS that prevents rtag from tagging files - # in the Attic. - mkdir $CVSROOT_DIRNAME/death-rtag - dotest death-rtag-init-1 "$testcvs -Q co death-rtag" - cd death-rtag - echo "This is the file foo" > foo - echo "This is the file bar" > bar - dotest death-rtag-init-2 "$testcvs -Q add foo bar" - dotest death-rtag-init-3 "$testcvs -Q ci -m 'Add foo and bar.'" \ -"RCS file: $CVSROOT_DIRNAME/death-rtag/bar,v -done -Checking in bar; -$CVSROOT_DIRNAME/death-rtag/bar,v <-- bar -initial revision: 1\.[0-9]* -done -RCS file: $CVSROOT_DIRNAME/death-rtag/foo,v -done -Checking in foo; -$CVSROOT_DIRNAME/death-rtag/foo,v <-- foo -initial revision: 1\.[0-9]* -done" - dotest death-rtag-init-5 "$testcvs -Q tag -b mybranch" - - dotest death-rtag-1 "$testcvs -q rtag -rmybranch willtag death-rtag" - dotest death-rtag-2 "$testcvs -Q rm -f foo" - dotest death-rtag-3 "$testcvs -Q ci -m 'Remove foo.'" \ -"Removing foo; -$CVSROOT_DIRNAME/death-rtag/foo,v <-- foo -new revision: delete; previous revision: 1\.[0-9]* -done" - # commit something on the branch so that the moving tag is visible. - dotest death-rtag-3.2 "$testcvs -Q up -rmybranch" - echo some branch content >>foo - echo some branch content >>bar - dotest death-rtag-3.3 "$testcvs -Q ci -m 'Change foo.'" \ -"Checking in bar; -$CVSROOT_DIRNAME/death-rtag/bar,v <-- bar -new revision: 1\.1\.2\.1; previous revision: 1\.1 -done -Checking in foo; -$CVSROOT_DIRNAME/death-rtag/Attic/foo,v <-- foo -new revision: 1\.1\.2\.1; previous revision: 1\.1 -done" - dotest death-rtag-3.4 \ -"$testcvs -q rtag -rmybranch wontmove death-rtag" - dotest death-rtag-3.5 "$testcvs -q rtag -F wontmove death-rtag" - - cd .. - # Removing -f below avoids this bug. - dotest death-rtag-4 "$testcvs -q rtag -frmybranch wonttag death-rtag" - - # When the bug existed, `wonttag' would not have been present in - # foo,v. - # - # A second bug prevented `wontmove' from moving from the branch to - # the dead revision on the trunk (death-rtag-3.4 & death-rtag-3.5). - dotest death-rtag-5 "$testcvs -q rlog death-rtag" \ -" -RCS file: $CVSROOT_DIRNAME/death-rtag/bar,v -head: 1.[0-9]* -branch: -locks: strict -access list: -symbolic names: - wonttag: 1\.1\.2\.1 - wontmove: 1\.1 - willtag: 1\.1 - mybranch: 1\.1.0\.2 -keyword substitution: kv -$DOTSTAR -RCS file: $CVSROOT_DIRNAME/death-rtag/Attic/foo,v -head: 1.[0-9]* -branch: -locks: strict -access list: -symbolic names: - wonttag: 1\.1\.2\.1 - wontmove: 1\.2 - willtag: 1\.1 - mybranch: 1\.1.0\.2 -keyword substitution: kv -$DOTSTAR" - - if $keep; then - echo Keeping $TESTDIR and exiting due to --keep - exit 0 - fi - - rm -r death-rtag - rm -rf $CVSROOT_DIRNAME/death-rtag - ;; - - - - rm-update-message) - # FIXME - # local CVS prints a warning message when update notices a missing - # file and client/server CVS doesn't. These should be identical. - mkdir rm-update-message; cd rm-update-message - mkdir $CVSROOT_DIRNAME/rm-update-message - dotest rm-update-message-setup-1 "$testcvs -q co rm-update-message" '' - cd rm-update-message - file=x - echo >$file - dotest rm-update-message-setup-2 "$testcvs -q add $file" \ -"${PROG} add: use .${PROG} commit. to add this file permanently" - dotest rm-update-message-setup-3 "$testcvs -q ci -mcreate $file" \ -"RCS file: $CVSROOT_DIRNAME/rm-update-message/$file,v -done -Checking in $file; -$CVSROOT_DIRNAME/rm-update-message/$file,v <-- $file -initial revision: 1\.1 -done" - - rm $file - dotest rm-update-message-1 "$testcvs up $file" \ -"${PROG} update: warning: $file was lost -U $file" - - cd ../.. - if $keep; then :; else - rm -rf rm-update-message - rm -rf $CVSROOT_DIRNAME/rm-update-message - fi - ;; - - rmadd) - # More tests of adding and removing files. - # In particular ci -r. - # Other ci -r tests: - # * editor-9: checking in a modified file, - # where "ci -r" means a branch. - # * basica-8a1: checking in a modified file with numeric revision. - # * basica-8a2: likewise. - # * keywordlog-4: adding a new file with numeric revision. - mkdir 1; cd 1 - dotest rmadd-1 "${testcvs} -q co -l ." '' - mkdir first-dir - dotest rmadd-2 "${testcvs} add first-dir" \ -"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" - cd first-dir - echo first file1 >file1 - dotest rmadd-3 "${testcvs} add file1" \ -"${PROG} add: scheduling file .file1. for addition -${PROG} add: use .${PROG} commit. to add this file permanently" - - dotest_fail rmadd-4 "${testcvs} -q ci -r 1.2.2.4 -m add" \ -"${PROG} commit: cannot add file .file1' with revision .1\.2\.2\.4'; must be on trunk -${PROG} \[commit aborted\]: correct above errors first!" - dotest_fail rmadd-5 "${testcvs} -q ci -r 1.2.2 -m add" \ -"${PROG} commit: cannot add file .file1' with revision .1\.2\.2'; must be on trunk -${PROG} \[commit aborted\]: correct above errors first!" - dotest_fail rmadd-6 "${testcvs} -q ci -r mybranch -m add" \ -"${PROG} \[commit aborted\]: no such tag mybranch" - - # The thing with the trailing periods strikes me as a very - # bizarre behavior, but it would seem to be intentional - # (see commit.c). It probably could go away.... - dotest rmadd-7 "${testcvs} -q ci -r 7.... -m add" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -done -Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -initial revision: 7\.1 -done" - if $remote; then - # I guess remote doesn't set a sticky tag in this case. - # Kind of odd, in the sense that rmadd-24a does set one - # both local and remote. - dotest_fail rmadd-7a "test -f CVS/Tag" - echo T7 >CVS/Tag - else - dotest rmadd-7a "cat CVS/Tag" "T7" - fi - - dotest rmadd-8 "${testcvs} -q tag -b mybranch" "T file1" - dotest rmadd-9 "${testcvs} -q tag mynonbranch" "T file1" - - touch file2 - # The previous "cvs ci -r" set a sticky tag of '7'. Seems a - # bit odd, and I guess commit.c (findmaxrev) makes '7' sticky - # tags unnecessary (?). I kind of suspect that it should be - # saying "sticky tag is not a branch" like keywordlog-4b. - # Or something. - dotest rmadd-10 "${testcvs} add file2" \ -"${PROG} add: scheduling file .file2. for addition on branch .7' -${PROG} add: use .${PROG} commit. to add this file permanently" - # As in the previous example, CVS is confused.... - dotest rmadd-11 "${testcvs} -q ci -m add" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v -done -Checking in file2; -${CVSROOT_DIRNAME}/first-dir/file2,v <-- file2 -initial revision: 7\.1 -done" - - dotest rmadd-12 "${testcvs} -q update -A" "" - touch file3 - dotest rmadd-13 "${testcvs} add file3" \ -"${PROG} add: scheduling file .file3. for addition -${PROG} add: use .${PROG} commit. to add this file permanently" - # Huh? file2 is not up to date? Seems buggy to me.... - dotest_fail rmadd-14 "${testcvs} -q ci -r mybranch -m add" \ -"${PROG} commit: Up-to-date check failed for .file2' -${PROG} \[commit aborted\]: correct above errors first!" - # Whatever, let's not let file2 distract us.... - dotest rmadd-15 "${testcvs} -q ci -r mybranch -m add file3" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/Attic/file3,v -done -Checking in file3; -${CVSROOT_DIRNAME}/first-dir/Attic/file3,v <-- file3 -new revision: 1\.1\.2\.1; previous revision: 1\.1 -done" - - touch file4 - dotest rmadd-16 "${testcvs} add file4" \ -"${PROG} add: scheduling file .file4. for addition -${PROG} add: use .${PROG} commit. to add this file permanently" - # Same "Up-to-date check" issues as in rmadd-14. - # The "no such tag" thing is due to the fact that we only - # update val-tags when the tag is used (might be more of a - # bug than a feature, I dunno). - dotest_fail rmadd-17 \ -"${testcvs} -q ci -r mynonbranch -m add file4" \ -"${PROG} \[commit aborted\]: no such tag mynonbranch" - # Try to make CVS write val-tags. - dotest rmadd-18 "${testcvs} -q update -p -r mynonbranch file1" \ -"first file1" - # Oops, -p suppresses writing val-tags (probably a questionable - # behavior). - dotest_fail rmadd-19 \ -"${testcvs} -q ci -r mynonbranch -m add file4" \ -"${PROG} \[commit aborted\]: no such tag mynonbranch" - # Now make CVS write val-tags for real. - dotest rmadd-20 "$testcvs -q update -r mynonbranch file1" '[UP] file1' - # Oops - CVS isn't distinguishing between a branch tag and - # a non-branch tag. - dotest rmadd-21 \ -"${testcvs} -q ci -r mynonbranch -m add file4" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/Attic/file4,v -done -Checking in file4; -${CVSROOT_DIRNAME}/first-dir/Attic/file4,v <-- file4 -new revision: 1\.1\.2\.1; previous revision: 1\.1 -done" - - # OK, we add this one in a vanilla way, but then check in - # a modification with ci -r and sniff around for sticky tags. - echo file5 >file5 - dotest rmadd-22 "${testcvs} add file5" \ -"${PROG} add: scheduling file .file5. for addition -${PROG} add: use .${PROG} commit. to add this file permanently" - if $remote; then - # Interesting bug (or missing feature) here. findmaxrev - # gets the major revision from the Entries. Well, remote - # doesn't send the entries for files which are not involved. - dotest rmadd-23r "${testcvs} -q ci -m add" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/file5,v -done -Checking in file5; -${CVSROOT_DIRNAME}/first-dir/file5,v <-- file5 -initial revision: 1\.1 -done" - dotest rmadd-23-workaroundr \ -"${testcvs} -q ci -r 7 -m bump-it file5" \ -"Checking in file5; -${CVSROOT_DIRNAME}/first-dir/file5,v <-- file5 -new revision: 7\.1; previous revision: 1\.1 -done" - else - dotest rmadd-23 "${testcvs} -q ci -m add" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/file5,v -done -Checking in file5; -${CVSROOT_DIRNAME}/first-dir/file5,v <-- file5 -initial revision: 7\.1 -done" - fi - echo change it >file5 - dotest_fail rmadd-24 "${testcvs} -q ci -r 4.8 -m change file5" \ -"Checking in file5; -${CVSROOT_DIRNAME}/first-dir/file5,v <-- file5 -${PROG} commit: ${CVSROOT_DIRNAME}/first-dir/file5,v: revision 4\.8 too low; must be higher than 7\.1 -${PROG} commit: could not check in file5" - dotest rmadd-24a "${testcvs} -q ci -r 8.4 -m change file5" \ -"Checking in file5; -${CVSROOT_DIRNAME}/first-dir/file5,v <-- file5 -new revision: 8\.4; previous revision: 7\.1 -done" - # I'm not really sure that a sticky tag make sense here. - # It seems to be longstanding behavior for what that is worth. - dotest rmadd-25 "${testcvs} status file5" \ -"=================================================================== -File: file5 Status: Up-to-date - - Working revision: 8\.4.* - Repository revision: 8\.4 ${CVSROOT_DIRNAME}/first-dir/file5,v - Sticky Tag: 8\.4 - Sticky Date: (none) - Sticky Options: (none)" - - # now try forced revision with recursion - mkdir sub - dotest rmadd-26 "${testcvs} -q add sub" \ -"Directory ${CVSROOT_DIRNAME}/first-dir/sub added to the repository" - echo hello >sub/subfile - dotest rmadd-27 "${testcvs} -q add sub/subfile" \ -"${PROG} add: use .${PROG} commit. to add this file permanently" - - dotest rmadd-28 "${testcvs} -q ci -m. sub" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/sub/subfile,v -done -Checking in sub/subfile; -${CVSROOT_DIRNAME}/first-dir/sub/subfile,v <-- subfile -initial revision: 1\.1 -done" - - # lose the branch - dotest rmadd-29 "$testcvs -q up -A" \ -"[UP] file1 -$PROG update: file3 is no longer in the repository -$PROG update: file4 is no longer in the repository" - - # -f disables recursion - dotest rmadd-30 "${testcvs} -q ci -f -r9 -m." \ -"Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -new revision: 9\.1; previous revision: 7\.1 -done -Checking in file2; -${CVSROOT_DIRNAME}/first-dir/file2,v <-- file2 -new revision: 9\.1; previous revision: 7\.1 -done -Checking in file5; -${CVSROOT_DIRNAME}/first-dir/file5,v <-- file5 -new revision: 9\.1; previous revision: 8\.4 -done" - - # add -R to force recursion - dotest rmadd-31 "${testcvs} -q ci -f -r9 -R -m." \ -"Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -new revision: 9\.2; previous revision: 9\.1 -done -Checking in file2; -${CVSROOT_DIRNAME}/first-dir/file2,v <-- file2 -new revision: 9\.2; previous revision: 9\.1 -done -Checking in file5; -${CVSROOT_DIRNAME}/first-dir/file5,v <-- file5 -new revision: 9\.2; previous revision: 9\.1 -done -Checking in sub/subfile; -${CVSROOT_DIRNAME}/first-dir/sub/subfile,v <-- subfile -new revision: 9\.1; previous revision: 1\.1 -done" - - if $remote; then - # as noted above, remote doesn't set a sticky tag - : - else - dotest rmadd-32 "cat CVS/Tag" "T9" - dotest rmadd-33 "cat sub/CVS/Tag" "T9" - fi - - cd ../.. - rm -r 1 - rm -rf ${CVSROOT_DIRNAME}/first-dir - ;; - - rmadd2) - # Tests of undoing commits, including in the presence of - # adding and removing files. See join for a list of -j tests. - mkdir 1; cd 1 - dotest rmadd2-1 "${testcvs} -q co -l ." '' - mkdir first-dir - dotest rmadd2-2 "${testcvs} add first-dir" \ -"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" - cd first-dir - echo 'initial contents' >file1 - dotest rmadd2-3 "${testcvs} add file1" \ -"${PROG} add: scheduling file .file1. for addition -${PROG} add: use .${PROG} commit. to add this file permanently" - dotest rmadd2-4 "${testcvs} -q ci -m add" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -done -Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -initial revision: 1\.1 -done" - dotest rmadd2-4a "${testcvs} -Q tag tagone" "" - dotest rmadd2-5 "${testcvs} rm -f file1" \ -"${PROG} remove: scheduling .file1. for removal -${PROG} remove: use .${PROG} commit. to remove this file permanently" - dotest rmadd2-6 "${testcvs} -q ci -m remove" \ -"Removing file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -new revision: delete; previous revision: 1\.1 -done" - dotest rmadd2-7 "${testcvs} -q update -j 1.2 -j 1.1 file1" "U file1" - dotest rmadd2-8 "${testcvs} -q ci -m readd" \ -"Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -new revision: 1\.3; previous revision: 1\.2 -done" - echo 'new contents' >file1 - dotest rmadd2-9 "${testcvs} -q ci -m modify" \ -"Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -new revision: 1\.4; previous revision: 1\.3 -done" - dotest rmadd2-10 "${testcvs} -q update -j 1.4 -j 1.3 file1" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -retrieving revision 1\.4 -retrieving revision 1\.3 -Merging differences between 1\.4 and 1\.3 into file1" - dotest rmadd2-11 "${testcvs} -q ci -m undo" \ -"Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -new revision: 1\.5; previous revision: 1\.4 -done" - dotest rmadd2-12 "cat file1" "initial contents" - dotest rmadd2-13 "${testcvs} -q update -p -r 1.3" "initial contents" - - # Hmm, might be a bit odd that this works even if 1.3 is not - # the head. - dotest rmadd2-14 "${testcvs} -q update -j 1.3 -j 1.2 file1" \ -"${PROG} update: scheduling file1 for removal" - - # Check that -p can get arbitrary revisions of a removed file - dotest rmadd2-14a "${testcvs} -q update -p" "initial contents" - dotest rmadd2-14b "${testcvs} -q update -p -r 1.5" "initial contents" - dotest rmadd2-14c "${testcvs} -q update -p -r 1.3" "initial contents" - - dotest rmadd2-15 "${testcvs} -q ci -m re-remove" \ -"Removing file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -new revision: delete; previous revision: 1\.5 -done" - dotest rmadd2-16 "${testcvs} log -h file1" " -RCS file: ${CVSROOT_DIRNAME}/first-dir/Attic/file1,v -Working file: file1 -head: 1\.6 -branch: -locks: strict -access list: -symbolic names: - tagone: 1\.1 -keyword substitution: kv -total revisions: 6 -=============================================================================" - dotest rmadd2-17 "${testcvs} status -v file1" \ -"=================================================================== -File: no file file1 Status: Up-to-date - - Working revision: No entry for file1 - Repository revision: 1\.6 ${CVSROOT_DIRNAME}/first-dir/Attic/file1,v - - Existing Tags: - tagone (revision: 1.1)" - - cd ../.. - - rm -r 1 - rm -rf ${CVSROOT_DIRNAME}/first-dir - ;; - - rmadd3) - # This test demonstrates that CVS notices that file1 exists rather - # that deleting or writing over it after: - # - # cvs remove -f file1; touch file1; cvs add file1. - # - # According to the manual, this should work for: - # - # rm file1; cvs remove file1; cvs add file1 - # - # but in past version of CVS, new content in file1 would be - # erroneously deleted when file1 reappeared between the remove and - # the add. - # - # Later versions of CVS would refuse to perform the add, but still - # allow a subsequent local commit to erase the file from the - # workspace, possibly losing data. - mkdir 1; cd 1 - dotest rmadd3-init1 "${testcvs} -q co -l ." '' - mkdir first-dir - dotest rmadd3-init2 "${testcvs} add first-dir" \ -"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" - cd first-dir - - echo initial content for file1 >file1 - dotest rmadd3-init3 "${testcvs} add file1" \ -"${PROG} add: scheduling file \`file1' for addition -${PROG} add: use '${PROG} commit' to add this file permanently" - dotest rmadd3-init4 "${testcvs} -q ci -m add" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -done -Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -initial revision: 1\.1 -done" - - # Here begins the guts of this test, as detailed above. - dotest rmadd3-1 "${testcvs} rm -f file1" \ -"${PROG} remove: scheduling \`file1' for removal -${PROG} remove: use '${PROG} commit' to remove this file permanently" - - # Now recreate the file: - echo desired future contents for file1 >file1 - - # And attempt to resurrect it at the same time: - dotest_fail rmadd3-2 "${testcvs} add file1" \ -"${PROG} add: file1 should be removed and is still there (or is back again)" - - # Now prove that commit knows that it shouldn't erase files. - dotest_fail rmadd3-3 "${testcvs} -q ci -m." \ -"$PROG commit: \`file1' should be removed and is still there (or is back again) -$PROG \[commit aborted\]: correct above errors first!" - - # Then these should pass too: - dotest rmadd3-4 "test -f file1" - dotest rmadd3-5 "cat file1" "desired future contents for file1" - - if $keep; then - echo Keeping ${TESTDIR} and exiting due to --keep - exit 0 - fi - - cd ../.. - rm -r 1 - rm -rf ${CVSROOT_DIRNAME}/first-dir - ;; - - resurrection) - # This test tests a few file resurrection scenarios. - mkdir 1; cd 1 - dotest resurrection-init1 "$testcvs -q co -l ." '' - mkdir first-dir - dotest resurrection-init2 "$testcvs add first-dir" \ -"Directory $CVSROOT_DIRNAME/first-dir added to the repository" - cd first-dir - - echo initial content for file1 >file1 - dotest resurrection-init3 "$testcvs add file1" \ -"$PROG add: scheduling file \`file1' for addition -$PROG add: use '$PROG commit' to add this file permanently" - dotest resurrection-init4 "$testcvs -q ci -m add" \ -"RCS file: $CVSROOT_DIRNAME/first-dir/file1,v -done -Checking in file1; -$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 -initial revision: 1\.1 -done" - - dotest resurrection-init5 "$testcvs -Q rm -f file1" - - # The first test is that `cvs add' will resurrect a file before its - # removal has been committed. - dotest_sort resurrection-1 "$testcvs add file1" \ -"U file1 -$PROG add: file1, version 1\.1, resurrected" - dotest resurrection-2 "$testcvs -Q diff file1" "" - - dotest resurrection-init6 "$testcvs -Q tag -b resurrection" - dotest resurrection-init7 "$testcvs -Q rm -f file1" - dotest resurrection-init8 "$testcvs -Q ci -mrm" \ -"Removing file1; -$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 -new revision: delete; previous revision: 1\.1 -done" - - # The next test is that CVS will resurrect a committed removal. - dotest_sort resurrection-3 "$testcvs add file1" \ -"U file1 -$PROG add: Re-adding file \`file1' (in place of dead revision 1\.2)\. -$PROG add: Resurrecting file \`file1' from revision 1\.1\. -$PROG add: use 'cvs commit' to add this file permanently" - dotest resurrection-4 "$testcvs -q diff -r1.1 file1" "" - dotest resurrection-5 "$testcvs -q ci -mreadd" \ -"Checking in file1; -$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 -new revision: 1\.3; previous revision: 1\.2 -done" - - dotest resurrection-init9 "$testcvs -Q up -rresurrection" - dotest resurrection-init10 "$testcvs -Q rm -f file1" - dotest resurrection-init11 "$testcvs -Q ci -mrm-on-resurrection" \ -"Removing file1; -$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 -new revision: delete; previous revision: 1\.1 -done" - - # The next test is that CVS will resurrect a committed removal to a - # branch. - dotest_sort resurrection-6 "$testcvs add file1" \ -"U file1 -$PROG add: Resurrecting file \`file1' from revision 1\.1\. -$PROG add: file \`file1' will be added on branch \`resurrection' from version 1\.1\.2\.1 -$PROG add: use 'cvs commit' to add this file permanently" - dotest resurrection-7 "$testcvs -Q diff -r1.1 file1" "" - dotest resurrection-8 "$testcvs -q ci -mreadd" \ -"Checking in file1; -$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 -new revision: 1\.1\.2\.2; previous revision: 1\.1\.2\.1 -done" - - # The next few tests verify that an attempted resurrection of a file - # with no previous revision on the trunk fails. - touch file2 - dotest resurrection-9 "$testcvs -Q add file2" - dotest resurrection-10 "$testcvs -Q ci -mnew-file2" \ -"RCS file: $CVSROOT_DIRNAME/first-dir/Attic/file2,v -done -Checking in file2; -$CVSROOT_DIRNAME/first-dir/Attic/file2,v <-- file2 -new revision: 1\.1\.2\.1; previous revision: 1\.1 -done" - dotest resurrection-11 "$testcvs -Q up -A" - - # This command once caused an assertion failure. - dotest resurrection-12 "$testcvs add file2" \ -"$PROG add: File \`file2' has no previous revision to resurrect\." - - if $keep; then - echo Keeping $TESTDIR and exiting due to --keep - exit 0 - fi - - cd ../.. - rm -r 1 - rm -rf $CVSROOT_DIRNAME/first-dir - ;; - - dirs) - # Tests related to removing and adding directories. - # See also: - # conflicts (especially dir1 in conflicts-130): What happens if - # directory exists in repository and a non-CVS-controlled - # directory in the working directory? - # conflicts3-15. More cases, especially where CVS directory - # exists but without CVS/Repository and friends. - # conflicts3-22. Similar to conflicts-130 but there is a file - # in the directory. - # dirs2. Sort of similar to conflicts3-22 but somewhat different. - mkdir imp-dir; cd imp-dir - echo file1 >file1 - mkdir sdir - echo sfile >sdir/sfile - dotest_sort dirs-1 \ -"${testcvs} import -m import-it dir1 vend rel" " - -N dir1/file1 -N dir1/sdir/sfile -No conflicts created by this import -${PROG} import: Importing ${CVSROOT_DIRNAME}/dir1/sdir" - cd .. - - mkdir 1; cd 1 - dotest dirs-2 "${testcvs} -Q co dir1" "" - - # Various CVS administrators are in the habit of removing - # the repository directory for things they don't want any - # more. I've even been known to do it myself (on rare - # occasions). Not the usual recommended practice, but we want - # to try to come up with some kind of reasonable/documented/sensible - # behavior. - rm -rf ${CVSROOT_DIRNAME}/dir1/sdir - - dotest dirs-3 "${testcvs} update" \ -"${PROG} update: Updating dir1 -${PROG} update: Updating dir1/sdir -${PROG} update: cannot open directory ${CVSROOT_DIRNAME}/dir1/sdir: No such file or directory -${PROG} update: skipping directory dir1/sdir" - dotest dirs-3a "${testcvs} update -d" \ -"${PROG} update*: Updating dir1 -${PROG} update: Updating dir1/sdir -${PROG} update: cannot open directory ${CVSROOT_DIRNAME}/dir1/sdir: No such file or directory -${PROG} update: skipping directory dir1/sdir" - - # If we say "yes", then CVS gives errors about not being able to - # create lock files. - # The fact that it says "skipping directory " rather than - # "skipping directory dir1/sdir" is some kind of bug. - dotest dirs-4 "echo no | ${testcvs} release -d dir1/sdir" \ -"${PROG} update: cannot open directory ${CVSROOT_DIRNAME}/dir1/sdir: No such file or directory -${PROG} update: skipping directory -You have \[0\] altered files in this repository\. -Are you sure you want to release (and delete) directory .dir1/sdir': .. .release' aborted by user choice." - - # OK, if "cvs release" won't help, we'll try it the other way... - rm -r dir1/sdir - - dotest dirs-5 "cat dir1/CVS/Entries" \ -"/file1/1.1.1.1/[a-zA-Z0-9 :]*// -D/sdir////" - dotest dirs-6 "${testcvs} update" "${PROG} update: Updating dir1" - dotest dirs-7 "cat dir1/CVS/Entries" \ -"/file1/1.1.1.1/[a-zA-Z0-9 :]*// -D/sdir////" - dotest dirs-8 "${testcvs} update -d dir1" \ -"${PROG} update: Updating dir1" - - cd .. - - rm -r imp-dir 1 - - # clean up our repositories - rm -rf ${CVSROOT_DIRNAME}/dir1 - ;; - - dirs2) - # See "dirs" for a list of tests involving adding and - # removing directories. - mkdir 1; cd 1 - dotest dirs2-1 "${testcvs} -q co -l ." '' - mkdir first-dir - dotest dirs2-2 "${testcvs} add first-dir" \ -"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" - cd first-dir - mkdir sdir - dotest dirs2-3 "${testcvs} add sdir" \ -"Directory ${CVSROOT_DIRNAME}/first-dir/sdir added to the repository" - touch sdir/file1 - dotest dirs2-4 "${testcvs} add sdir/file1" \ -"${PROG} add: scheduling file .sdir/file1. for addition -${PROG} add: use .${PROG} commit. to add this file permanently" - dotest dirs2-5 "${testcvs} -q ci -m add" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/sdir/file1,v -done -Checking in sdir/file1; -${CVSROOT_DIRNAME}/first-dir/sdir/file1,v <-- file1 -initial revision: 1\.1 -done" - rm -r sdir/CVS - if $remote; then - # This is just like conflicts3-23 - dotest_fail dirs2-6 "${testcvs} update -d" \ -"${QUESTION} sdir -${PROG} update: Updating \. -${PROG} update: Updating sdir -${PROG} update: move away sdir/file1; it is in the way -C sdir/file1" - rm sdir/file1 - rm -r sdir/CVS - - # This is where things are not just like conflicts3-23 - dotest dirs2-7 "${testcvs} update -d" \ -"${QUESTION} sdir -${PROG} update: Updating \. -${PROG} update: Updating sdir -U sdir/file1" - else - dotest dirs2-6 "${testcvs} update -d" \ -"${PROG} update: Updating \. -${QUESTION} sdir" - rm sdir/file1 - dotest dirs2-7 "${testcvs} update -d" \ -"${PROG} update: Updating \. -${QUESTION} sdir" - fi - cd ../.. - - # Now, the same thing (more or less) on a branch. - mkdir 2; cd 2 - dotest dirs2-8 "${testcvs} -q co first-dir" 'U first-dir/sdir/file1' - cd first-dir - dotest dirs2-9 "${testcvs} -q tag -b br" "T sdir/file1" - rm -r sdir/CVS - if $remote; then - # Cute little quirk of val-tags; if we don't recurse into - # the directories where the tag is defined, val-tags won't - # get updated. - dotest_fail dirs2-10 "${testcvs} update -d -r br" \ -"${QUESTION} sdir -${PROG} \[update aborted\]: no such tag br" - dotest dirs2-10ar \ -"${testcvs} -q rdiff -u -r 1.1 -r br first-dir/sdir/file1" - dotest_fail dirs2-10-again "${testcvs} update -d -r br" \ -"${QUESTION} sdir -${PROG} update: Updating \. -${PROG} update: Updating sdir -${PROG} update: move away sdir/file1; it is in the way -C sdir/file1" - else - dotest_fail dirs2-10 "${testcvs} update -d -r br" \ -"${PROG} update: in directory sdir: -${PROG} \[update aborted\]: there is no version here; do '${PROG} checkout' first" - fi - cd ../.. - - # OK, the above tests make the situation somewhat harder - # than it might be, in the sense that they actually have a - # file which is alive on the branch we are updating. Let's - # try it where it is just a directory where all the files - # have been removed. - mkdir 3; cd 3 - dotest dirs2-11 "${testcvs} -q co -r br first-dir" \ -"U first-dir/sdir/file1" - cd first-dir - # Hmm, this doesn't mention the branch like add does. That's - # an odd non-orthogonality. - dotest dirs2-12 "${testcvs} rm -f sdir/file1" \ -"${PROG} remove: scheduling .sdir/file1. for removal -${PROG} remove: use .${PROG} commit. to remove this file permanently" - dotest dirs2-13 "${testcvs} -q ci -m remove" \ -"Removing sdir/file1; -${CVSROOT_DIRNAME}/first-dir/sdir/file1,v <-- file1 -new revision: delete; previous revision: 1\.1 -done" - cd ../../2/first-dir - if $remote; then - dotest dirs2-14 "${testcvs} update -d -r br" \ -"${QUESTION} sdir/file1 -${PROG} update: Updating \. -${PROG} update: Updating sdir" - else - dotest dirs2-14 "${testcvs} update -d -r br" \ -"${PROG} update: Updating \. -${QUESTION} sdir" - fi - cd ../.. - - rm -r 1 2 3 - rm -rf ${CVSROOT_DIRNAME}/first-dir - ;; - - branches) - # More branch tests, including branches off of branches - mkdir ${CVSROOT_DIRNAME}/first-dir - dotest branches-1 "${testcvs} -q co first-dir" '' - cd first-dir - echo 1:ancest >file1 - echo 2:ancest >file2 - echo 3:ancest >file3 - echo 4:trunk-1 >file4 - dotest branches-2 "${testcvs} add file1 file2 file3 file4" \ -"${PROG}"' add: scheduling file `file1'\'' for addition -'"${PROG}"' add: scheduling file `file2'\'' for addition -'"${PROG}"' add: scheduling file `file3'\'' for addition -'"${PROG}"' add: scheduling file `file4'\'' for addition -'"${PROG}"' add: use .'"${PROG}"' commit. to add these files permanently' - dotest branches-2a "${testcvs} -n -q ci -m dont-commit" "" - dotest_lit branches-3 "${testcvs} -q ci -m add-it" <file4 - dotest branches-3.2 "${testcvs} -q ci -m trunk-before-branch" \ -"Checking in file4; -${CVSROOT_DIRNAME}/first-dir/file4,v <-- file4 -new revision: 1\.2; previous revision: 1\.1 -done" - # The "cvs log file4" in test branches-14.3 will test that we - # didn't really add the tag. - dotest branches-3.3 "${testcvs} -qn tag dont-tag" \ -"T file1 -T file2 -T file3 -T file4" - # Modify this file before branching, to deal with the case where - # someone is hacking along, says "oops, I should be doing this on - # a branch", and only then creates the branch. - echo 1:br1 >file1 - dotest branches-4 "${testcvs} tag -b br1" "${PROG}"' tag: Tagging \. -T file1 -T file2 -T file3 -T file4' - dotest branches-5 "$testcvs update -r br1" \ -"$PROG update: Updating \. -M file1 -[UP] file2 -[UP] file3 -[UP] file4" - echo 2:br1 >file2 - echo 4:br1 >file4 - dotest branches-6 "${testcvs} -q ci -m modify" \ -"Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -new revision: 1\.1\.2\.1; previous revision: 1\.1 -done -Checking in file2; -${CVSROOT_DIRNAME}/first-dir/file2,v <-- file2 -new revision: 1\.1\.2\.1; previous revision: 1\.1 -done -Checking in file4; -${CVSROOT_DIRNAME}/first-dir/file4,v <-- file4 -new revision: 1\.2\.2\.1; previous revision: 1\.2 -done" - dotest branches-7 "${testcvs} -q tag -b brbr" 'T file1 -T file2 -T file3 -T file4' - dotest branches-8 "$testcvs -q update -r brbr" \ -'[UP] file1 -[UP] file2 -[UP] file3 -[UP] file4' - echo 1:brbr >file1 - echo 4:brbr >file4 - dotest branches-9 "${testcvs} -q ci -m modify" \ -"Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -new revision: 1\.1\.2\.1\.2\.1; previous revision: 1\.1\.2\.1 -done -Checking in file4; -${CVSROOT_DIRNAME}/first-dir/file4,v <-- file4 -new revision: 1\.2\.2\.1\.2\.1; previous revision: 1\.2\.2\.1 -done" - dotest branches-10 "cat file1 file2 file3 file4" '1:brbr -2:br1 -3:ancest -4:brbr' - dotest branches-11 "$testcvs -q update -r br1" \ -'U file1 -[UP] file2 -[UP] file3 -U file4' - dotest branches-12 "cat file1 file2 file3 file4" '1:br1 -2:br1 -3:ancest -4:br1' - echo 4:br1-2 >file4 - dotest branches-12.2 "${testcvs} -q ci -m change-on-br1" \ -"Checking in file4; -${CVSROOT_DIRNAME}/first-dir/file4,v <-- file4 -new revision: 1\.2\.2\.2; previous revision: 1\.2\.2\.1 -done" - dotest branches-13 "${testcvs} -q update -A" \ -'U file1 -U file2 -[UP] file3 -U file4' - dotest branches-14 "cat file1 file2 file3 file4" '1:ancest -2:ancest -3:ancest -4:trunk-2' - echo 4:trunk-3 >file4 - dotest branches-14.2 \ - "${testcvs} -q ci -m trunk-change-after-branch" \ -"Checking in file4; -${CVSROOT_DIRNAME}/first-dir/file4,v <-- file4 -new revision: 1\.3; previous revision: 1\.2 -done" - dotest branches-14.3 "${testcvs} log file4" \ -" -RCS file: ${CVSROOT_DIRNAME}/first-dir/file4,v -Working file: file4 -head: 1\.3 -branch: -locks: strict -access list: -symbolic names: - brbr: 1\.2\.2\.1\.0\.2 - br1: 1\.2\.0\.2 -keyword substitution: kv -total revisions: 6; selected revisions: 6 -description: ----------------------------- -revision 1\.3 -date: [0-9/: ]*; author: ${username}; state: Exp; lines: ${PLUS}1 -1 -trunk-change-after-branch ----------------------------- -revision 1\.2 -date: [0-9/: ]*; author: ${username}; state: Exp; lines: ${PLUS}1 -1 -branches: 1\.2\.2; -trunk-before-branch ----------------------------- -revision 1\.1 -date: [0-9/: ]*; author: ${username}; state: Exp; -add-it ----------------------------- -revision 1\.2\.2\.2 -date: [0-9/: ]*; author: ${username}; state: Exp; lines: ${PLUS}1 -1 -change-on-br1 ----------------------------- -revision 1\.2\.2\.1 -date: [0-9/: ]*; author: ${username}; state: Exp; lines: ${PLUS}1 -1 -branches: 1\.2\.2\.1\.2; -modify ----------------------------- -revision 1\.2\.2\.1\.2\.1 -date: [0-9/: ]*; author: ${username}; state: Exp; lines: ${PLUS}1 -1 -modify -=============================================================================" - dotest_fail branches-14.4 \ - "${testcvs} diff -c -r 1.1 -r 1.3 file4" \ -"Index: file4 -=================================================================== -RCS file: ${CVSROOT_DIRNAME}/first-dir/file4,v -retrieving revision 1\.1 -retrieving revision 1\.3 -diff -c -r1\.1 -r1\.3 -\*\*\* file4 ${RFCDATE} 1\.1 ---- file4 ${RFCDATE} 1\.3 -\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* -\*\*\* 1 \*\*\*\* -! 4:trunk-1 ---- 1 ---- -! 4:trunk-3" - dotest_fail branches-14.5 \ - "${testcvs} diff -c -r 1.1 -r 1.2.2.1 file4" \ -"Index: file4 -=================================================================== -RCS file: ${CVSROOT_DIRNAME}/first-dir/file4,v -retrieving revision 1\.1 -retrieving revision 1\.2\.2\.1 -diff -c -r1\.1 -r1\.2\.2\.1 -\*\*\* file4 ${RFCDATE} 1\.1 ---- file4 ${RFCDATE} 1\.2\.2\.1 -\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* -\*\*\* 1 \*\*\*\* -! 4:trunk-1 ---- 1 ---- -! 4:br1" - dotest branches-15 \ - "${testcvs} update -j 1.1.2.1 -j 1.1.2.1.2.1 file1" \ - "RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -retrieving revision 1\.1\.2\.1 -retrieving revision 1\.1\.2\.1\.2\.1 -Merging differences between 1\.1\.2\.1 and 1\.1\.2\.1\.2\.1 into file1 -rcsmerge: warning: conflicts during merge" - dotest branches-16 "cat file1" '<<<<<<< file1 -1:ancest -[=]====== -1:brbr -[>]>>>>>> 1\.1\.2\.1\.2\.1' - - dotest branches-o1 "${testcvs} -q admin -o ::brbr" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -done -RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v -done -RCS file: ${CVSROOT_DIRNAME}/first-dir/file3,v -done -RCS file: ${CVSROOT_DIRNAME}/first-dir/file4,v -done" - cd .. - - if $keep; then - echo Keeping ${TESTDIR} and exiting due to --keep - exit 0 - fi - - rm -rf ${CVSROOT_DIRNAME}/first-dir - rm -r first-dir - ;; - - branches2) - # More branch tests. - # Test that when updating a new subdirectory in a directory - # which was checked out on a branch, the new subdirectory is - # created on the appropriate branch. Test this when joining - # as well. - - mkdir ${CVSROOT_DIRNAME}/first-dir - mkdir trunk; cd trunk - - # Create a file. - dotest branches2-1 "${testcvs} -q co first-dir" - cd first-dir - echo "file1 first revision" > file1 - dotest branches2-2 "${testcvs} add file1" \ -"${PROG} add: scheduling file .file1. for addition -${PROG} add: use .${PROG} commit. to add this file permanently" - dotest branches2-3 "${testcvs} commit -m add file1" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -done -Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -initial revision: 1\.1 -done" - - # Tag the file. - dotest branches2-4 "${testcvs} -q tag tag1" 'T file1' - - # Make two branches. - dotest branches2-5 "${testcvs} -q rtag -b -r tag1 b1 first-dir" '' - dotest branches2-6 "${testcvs} -q rtag -b -r tag1 b2 first-dir" '' - - # Create some files and a subdirectory on branch b1. - cd ../.. - mkdir b1; cd b1 - dotest branches2-7 "${testcvs} -q co -r b1 first-dir" \ -"U first-dir/file1" - cd first-dir - echo "file2 first revision" > file2 - dotest branches2-8 "${testcvs} add file2" \ -"${PROG}"' add: scheduling file `file2'\'' for addition on branch `b1'\'' -'"${PROG}"' add: use .'"${PROG}"' commit. to add this file permanently' - mkdir dir1 - dotest branches2-9 "${testcvs} add dir1" \ -"Directory ${CVSROOT_DIRNAME}/first-dir/dir1 added to the repository ---> Using per-directory sticky tag "'`'"b1'" - echo "file3 first revision" > dir1/file3 - dotest branches2-10 "${testcvs} add dir1/file3" \ -"${PROG}"' add: scheduling file `dir1/file3'\'' for addition on branch `b1'\'' -'"${PROG}"' add: use .'"${PROG}"' commit. to add this file permanently' - dotest branches2-11 "${testcvs} -q ci -madd ." \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/Attic/file2,v -done -Checking in file2; -${CVSROOT_DIRNAME}/first-dir/Attic/file2,v <-- file2 -new revision: 1\.1\.2\.1; previous revision: 1\.1 -done -RCS file: ${CVSROOT_DIRNAME}/first-dir/dir1/Attic/file3,v -done -Checking in dir1/file3; -${CVSROOT_DIRNAME}/first-dir/dir1/Attic/file3,v <-- file3 -new revision: 1\.1\.2\.1; previous revision: 1\.1 -done" - - # Check out the second branch, and update the working - # directory to the first branch, to make sure the right - # happens with dir1. - cd ../.. - mkdir b2; cd b2 - dotest branches2-12 "${testcvs} -q co -r b2 first-dir" \ -'U first-dir/file1' - cd first-dir - dotest branches2-13 "${testcvs} update -d -r b1 dir1" \ -"${PROG} update: Updating dir1 -U dir1/file3" - dotest branches2-14 "${testcvs} -q status" \ -"=================================================================== -File: file1 Status: Up-to-date - - Working revision: 1\.1.* - Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/file1,v - Sticky Tag: b2 (branch: 1\.1\.4) - Sticky Date: (none) - Sticky Options: (none) - -=================================================================== -File: file3 Status: Up-to-date - - Working revision: 1\.1\.2\.1.* - Repository revision: 1\.1\.2\.1 ${CVSROOT_DIRNAME}/first-dir/dir1/Attic/file3,v - Sticky Tag: b1 (branch: 1\.1\.2) - Sticky Date: (none) - Sticky Options: (none)" - - # FIXME: Just clobbering the directory like this is a bit - # tacky, although people generally expect it to work. Maybe - # we should release it instead. We do it a few other places - # below as well. - rm -r dir1 - dotest branches2-15 "${testcvs} update -d -j b1 dir1" \ -"${PROG} update: Updating dir1 -U dir1/file3" - # FIXCVS: The `No revision control file' stuff seems to be - # CVS's way of telling us that we're adding the file on a - # branch, and the file is not on that branch yet. This - # should be nicer. - dotest branches2-16 "${testcvs} -q status" \ -"=================================================================== -File: file1 Status: Up-to-date - - Working revision: 1\.1.* - Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/file1,v - Sticky Tag: b2 (branch: 1\.1\.4) - Sticky Date: (none) - Sticky Options: (none) - -=================================================================== -File: file3 Status: Locally Added - - Working revision: New file! - Repository revision: No revision control file - Sticky Tag: b2 - MISSING from RCS file! - Sticky Date: (none) - Sticky Options: (none)" - - cd ../../trunk/first-dir - dotest branches2-17 "${testcvs} update -d -P dir1" \ -"${PROG} update: Updating dir1" - dotest_fail branches2-18 "test -d dir1" - dotest branches2-19 "${testcvs} update -d -P -r b1 dir1" \ -"${PROG} update: Updating dir1 -U dir1/file3" - dotest branches2-20 "${testcvs} -q status" \ -"=================================================================== -File: file1 Status: Up-to-date - - Working revision: 1\.1.* - Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/file1,v - Sticky Tag: (none) - Sticky Date: (none) - Sticky Options: (none) - -=================================================================== -File: file3 Status: Up-to-date - - Working revision: 1\.1\.2\.1.* - Repository revision: 1\.1\.2\.1 ${CVSROOT_DIRNAME}/first-dir/dir1/Attic/file3,v - Sticky Tag: b1 (branch: 1\.1\.2) - Sticky Date: (none) - Sticky Options: (none)" - - rm -r dir1 - dotest branches2-21 "${testcvs} update -d -P -j b1 dir1" \ -"${PROG} update: Updating dir1 -U dir1/file3" - dotest branches2-22 "${testcvs} -q status" \ -"=================================================================== -File: file1 Status: Up-to-date - - Working revision: 1\.1.* - Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/file1,v - Sticky Tag: (none) - Sticky Date: (none) - Sticky Options: (none) - -=================================================================== -File: file3 Status: Locally Added - - Working revision: New file! - Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/dir1/Attic/file3,v - Sticky Tag: (none) - Sticky Date: (none) - Sticky Options: (none)" - - cd ../.. - rm -r b1 b2 - - # Check out branch b1 twice. Crate a new directory in one - # working directory, then do a cvs update in the other - # working directory and see if the tags are right. - mkdir b1a - mkdir b1b - cd b1b - dotest branches2-23 "${testcvs} -q co -r b1 first-dir" \ -'U first-dir/file1 -U first-dir/file2 -U first-dir/dir1/file3' - cd ../b1a - dotest branches2-24 "${testcvs} -q co -r b1 first-dir" \ -'U first-dir/file1 -U first-dir/file2 -U first-dir/dir1/file3' - cd first-dir - mkdir dir2 - dotest branches2-25 "${testcvs} add dir2" \ -"Directory ${CVSROOT_DIRNAME}/first-dir/dir2 added to the repository ---> Using per-directory sticky tag "'`'"b1'" - echo "file4 first revision" > dir2/file4 - dotest branches2-26 "${testcvs} add dir2/file4" \ -"${PROG}"' add: scheduling file `dir2/file4'\'' for addition on branch `b1'\'' -'"${PROG}"' add: use .'"${PROG}"' commit. to add this file permanently' - dotest branches2-27 "${testcvs} -q commit -madd" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/dir2/Attic/file4,v -done -Checking in dir2/file4; -${CVSROOT_DIRNAME}/first-dir/dir2/Attic/file4,v <-- file4 -new revision: 1\.1\.2\.1; previous revision: 1\.1 -done" - - cd ../../b1b/first-dir - dotest branches2-28 "${testcvs} update -d dir2" \ -"${PROG} update: Updating dir2 -U dir2/file4" - cd dir2 - dotest branches2-29 "${testcvs} -q status" \ -"=================================================================== -File: file4 Status: Up-to-date - - Working revision: 1\.1\.2\.1.* - Repository revision: 1\.1\.2\.1 ${CVSROOT_DIRNAME}/first-dir/dir2/Attic/file4,v - Sticky Tag: b1 (branch: 1\.1\.2) - Sticky Date: (none) - Sticky Options: (none)" - dotest branches2-30 "cat CVS/Tag" 'Tb1' - - # Test update -A on a subdirectory - cd .. - rm -r dir2 - dotest branches2-31 "${testcvs} update -A -d dir2" \ -"${PROG} update: Updating dir2" - cd dir2 - dotest branches2-32 "${testcvs} -q status" '' - dotest_fail branches2-33 "test -f CVS/Tag" - - # Add a file on the trunk. - echo "file5 first revision" > file5 - dotest branches2-34 "${testcvs} add file5" \ -"${PROG}"' add: scheduling file `file5'\'' for addition -'"${PROG}"' add: use .'"${PROG}"' commit. to add this file permanently' - dotest branches2-35 "${testcvs} -q commit -madd" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/dir2/file5,v -done -Checking in file5; -${CVSROOT_DIRNAME}/first-dir/dir2/file5,v <-- file5 -initial revision: 1\.1 -done" - - cd ../../../trunk/first-dir - dotest branches2-36 "${testcvs} -q update -d dir2" 'U dir2/file5' - cd dir2 - dotest branches2-37 "${testcvs} -q status" \ -"=================================================================== -File: file5 Status: Up-to-date - - Working revision: 1\.1.* - Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/dir2/file5,v - Sticky Tag: (none) - Sticky Date: (none) - Sticky Options: (none)" - dotest_fail branches2-38 "test -f CVS/status" - - cd ../../.. - rm -rf ${CVSROOT_DIRNAME}/first-dir - rm -r trunk b1a b1b - ;; - - tagc) - # Test the tag -c option. - mkdir 1; cd 1 - dotest tagc-1 "${testcvs} -q co -l ." '' - mkdir first-dir - dotest tagc-2 "${testcvs} add first-dir" \ -"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" - cd first-dir - touch file1 file2 - dotest tagc-3 "${testcvs} add file1 file2" \ -"${PROG} add: scheduling file .file1. for addition -${PROG} add: scheduling file .file2. for addition -${PROG} add: use .${PROG} commit. to add these files permanently" - dotest tagc-4 "${testcvs} -q ci -m add" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -done -Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -initial revision: 1\.1 -done -RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v -done -Checking in file2; -${CVSROOT_DIRNAME}/first-dir/file2,v <-- file2 -initial revision: 1\.1 -done" - dotest tagc-5 "${testcvs} -q tag -c tag1" \ -"T file1 -T file2" - touch file1 file2 - dotest tagc-6 "${testcvs} -q tag -c tag2" \ -"T file1 -T file2" - # Avoid timestamp granularity bugs (FIXME: CVS should be - # doing the sleep, right?). - sleep 1 - echo myedit >>file1 - dotest tagc-6a "${testcvs} rm -f file2" \ -"${PROG} remove: scheduling .file2. for removal -${PROG} remove: use .${PROG} commit. to remove this file permanently" - touch file3 - dotest tagc-6b "${testcvs} add file3" \ -"${PROG} add: scheduling file .file3. for addition -${PROG} add: use .${PROG} commit. to add this file permanently" - dotest_fail tagc-7 "${testcvs} -q tag -c tag3" \ -"${PROG} tag: file1 is locally modified -${PROG} tag: file2 is locally modified -${PROG} tag: file3 is locally modified -${PROG} \[tag aborted\]: correct the above errors first!" - cd ../.. - mkdir 2 - cd 2 - dotest tagc-8 "${testcvs} -q co first-dir" \ -"U first-dir/file1 -U first-dir/file2" - cd ../1/first-dir - dotest tagc-9 "${testcvs} -q ci -m modify" \ -"Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -new revision: 1\.2; previous revision: 1\.1 -done -Removing file2; -${CVSROOT_DIRNAME}/first-dir/file2,v <-- file2 -new revision: delete; previous revision: 1\.1 -done -RCS file: ${CVSROOT_DIRNAME}/first-dir/file3,v -done -Checking in file3; -${CVSROOT_DIRNAME}/first-dir/file3,v <-- file3 -initial revision: 1\.1 -done" - cd ../../2/first-dir - dotest tagc-10 "${testcvs} -q tag -c tag4" \ -"${PROG} tag: file2 is no longer in the repository -T file1 -T file2" - cd ../.. - - rm -r 1 2 - rm -rf ${CVSROOT_DIRNAME}/first-dir - ;; - - update-p) - # Make sure `cvs update -p -rT FILE' works from a branch when - # FILE is already on the trunk and is being added to that branch. - - mkdir 1; cd 1 - module=x - - echo > unused-file - - # Create the module. - dotest update-p-1 \ - "$testcvs -Q import -m. $module X Y" '' - - file=F - # Check it out and tag it. - dotest update-p-2 "$testcvs -Q co $module" '' - cd $module - dotest update-p-3 "$testcvs -Q tag -b B" '' - echo v1 > $file - dotest update-p-4 "$testcvs -Q add $file" '' - dotest update-p-5 "$testcvs -Q ci -m. $file" \ -"RCS file: ${CVSROOT_DIRNAME}/$module/$file,v -done -Checking in $file; -${CVSROOT_DIRNAME}/$module/$file,v <-- $file -initial revision: 1\.1 -done" - dotest update-p-6 "$testcvs -Q tag T $file" '' - dotest update-p-7 "$testcvs -Q update -rB" '' - - # This merge effectively adds file F on branch B. - dotest update-p-8 "$testcvs -Q update -jT" '' - - # Before the fix that prompted the addition of this test, - # the following command would fail with this diagnostic: - # cvs update: conflict: F created independently by second party - dotest update-p-9 "$testcvs update -p -rT $file" \ -"=================================================================== -Checking out $file -RCS: ${CVSROOT_DIRNAME}/$module/$file,v -VERS: 1\.1 -\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* -v1" - - # Repeat the above, but with $file removed. - # This exercises a slightly different code path. - rm $file - # Before the fix that prompted the addition of this test, - # the following command would fail with this diagnostic: - # cvs update: warning: new-born F has disappeared - dotest update-p-10 "$testcvs update -p -rT $file" \ -"=================================================================== -Checking out $file -RCS: ${CVSROOT_DIRNAME}/$module/$file,v -VERS: 1\.1 -\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* -v1" - - # Exercise yet another code path: - # the one that involves reviving a `dead' file. - # And a little more, for good measure... - touch new - dotest update-p-a1 "$testcvs -Q add new" '' - dotest update-p-a2 "$testcvs -Q update -p new" '' - dotest update-p-a3 "$testcvs -Q rm -f new" '' - - # Both an update -A, *and* the following update are required - # to return to the state of being on the trunk with a $file - # that we can then remove. - dotest update-p-undead-0 "$testcvs update -A" \ -"$PROG update: Updating \. -$PROG update: warning: new-born $file has disappeared -[UP] unused-file" - dotest update-p-undead-1 "$testcvs update" \ -"${PROG} update: Updating \. -U $file" - dotest update-p-undead-2 "$testcvs -Q update -p -rT $file" v1 - dotest update-p-undead-3 "$testcvs -Q rm -f $file" '' - dotest update-p-undead-4 "$testcvs -Q update -p -rT $file" v1 - dotest update-p-undead-5 "$testcvs -Q ci -m. $file" \ -"Removing $file; -${CVSROOT_DIRNAME}/$module/$file,v <-- $file -new revision: delete; previous revision: 1\.1 -done" - dotest update-p-undead-6 "$testcvs -Q update -p -rT $file" v1 - echo v2 > $file - dotest update-p-undead-7 "$testcvs -Q update -p -rT $file" v1 - dotest update-p-undead-8 "$testcvs add $file" \ -"${PROG} add: Re-adding file .$file. (in place of dead revision 1\.2)\. -${PROG} add: use .${PROG} commit. to add this file permanently" - - dotest update-p-undead-9 "$testcvs -Q update -p -rT $file" v1 - - cd ../.. - rm -rf 1 - rm -rf ${CVSROOT_DIRNAME}/$module - ;; - - tagf) - # More tagging tests, including using tag -F -B to convert a - # branch tag to a regular tag and recovering thereof. - - # Setup; check in first-dir/file1 - mkdir 1; cd 1 - dotest tagf-1 "${testcvs} -q co -l ." '' - mkdir first-dir - dotest tagf-2 "${testcvs} add first-dir" \ -"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" - cd first-dir - touch file1 file2 - dotest tagf-3 "${testcvs} add file1 file2" \ -"${PROG} add: scheduling file .file1. for addition -${PROG} add: scheduling file .file2. for addition -${PROG} add: use .${PROG} commit. to add these files permanently" - dotest tagf-4 "${testcvs} -q ci -m add" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -done -Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -initial revision: 1\.1 -done -RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v -done -Checking in file2; -${CVSROOT_DIRNAME}/first-dir/file2,v <-- file2 -initial revision: 1\.1 -done" - - # Now create a branch and commit a revision there. - dotest tagf-5 "${testcvs} -q tag -b br" "T file1 -T file2" - dotest tagf-6 "$testcvs -q update -r br" \ -'U file1 -U file2' - echo brmod >> file1 - echo brmod >> file2 - dotest tagf-7 "${testcvs} -q ci -m modify" \ -"Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -new revision: 1\.1\.2\.1; previous revision: 1\.1 -done -Checking in file2; -${CVSROOT_DIRNAME}/first-dir/file2,v <-- file2 -new revision: 1\.1\.2\.1; previous revision: 1\.1 -done" - # Here we try to make it a non-branch tag, but will - # succeed in getting only warnings, even with -F - # because converting a branch tag to non-branch - # is potentially catastrophic. - dotest tagf-8a "${testcvs} -q tag -F br" \ -"${PROG} tag: file1: Not moving branch tag .br. from 1\.1\.2\.1 to 1\.1\\.2\.1\. -${PROG} tag: file2: Not moving branch tag .br. from 1\.1\.2\.1 to 1\.1\.2\.1\." - # however, if we *really* are sure we want to move a branch tag, - # "-F -B" will do the trick - dotest tagf-8 "${testcvs} -q tag -F -B br" "T file1 -T file2" - echo moremod >> file1 - echo moremod >> file2 - dotest tagf-9 "${testcvs} -q status -v file1" \ -"=================================================================== -File: file1 Status: Locally Modified - - Working revision: 1\.1\.2\.1.* - Repository revision: 1\.1\.2\.1 ${CVSROOT_DIRNAME}/first-dir/file1,v - Sticky Tag: br (revision: 1\.1\.2\.1) - Sticky Date: (none) - Sticky Options: (none) - - Existing Tags: - br (revision: 1\.1\.2\.1)" - - # Now, how do we recover? - dotest tagf-10 "${testcvs} -q tag -d br" "D file1 -D file2" - # This creates a new branch, 1.1.4. See the code in RCS_magicrev - # which will notice that there is a (non-magic) 1.1.2 and thus - # skip that number. - dotest tagf-11 "${testcvs} -q tag -r 1.1 -b br file1" "T file1" - # Fix it with admin -n (cf admin-18, admin-26-4). - dotest tagf-12 "${testcvs} -q admin -nbr:1.1.2 file2" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v -done" - # Another variation on the file2 test would be to use two working - # directories so that the update -r br would need to - # a merge to get from 1.1.2.1 to the head of the 1.1.2 branch. - dotest tagf-13 "${testcvs} -q update -r br" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -retrieving revision 1\.1\.2\.1 -retrieving revision 1\.1 -Merging differences between 1\.1\.2\.1 and 1\.1 into file1 -rcsmerge: warning: conflicts during merge -${PROG} update: conflicts found in file1 -C file1 -M file2" - # CVS is giving a conflict because we are trying to get back to - # 1.1.4. I'm not sure why it is a conflict rather than just - # "M file1". - dotest tagf-14 "cat file1" \ -"<<<<<<< file1 -brmod -moremod -[=]====== -[>]>>>>>> 1\.1" - echo resolve >file1 - dotest tagf-15 "${testcvs} -q ci -m recovered" \ -"Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -new revision: 1\.1\.4\.1; previous revision: 1\.1 -done -Checking in file2; -${CVSROOT_DIRNAME}/first-dir/file2,v <-- file2 -new revision: 1\.1\.2\.2; previous revision: 1\.1\.2\.1 -done" - # try accidentally deleting branch tag, "tag -d" - dotest_fail tagf-16 "${testcvs} tag -d br" \ -"${PROG} tag: Untagging \. -${PROG} tag: Not removing branch tag .br. from .${CVSROOT_DIRNAME}/first-dir/file1,v.\. -${PROG} tag: Not removing branch tag .br. from .${CVSROOT_DIRNAME}/first-dir/file2,v.\." - # try accidentally deleting branch tag, "rtag -d" - dotest_fail tagf-17 "${testcvs} rtag -d br first-dir" \ -"${PROG} rtag: Untagging first-dir -${PROG} rtag: Not removing branch tag .br. from .${CVSROOT_DIRNAME}/first-dir/file1,v.\. -${PROG} rtag: Not removing branch tag .br. from .${CVSROOT_DIRNAME}/first-dir/file2,v.\." - # try accidentally converting branch tag to non-branch tag "tag -F" - dotest tagf-18 "${testcvs} tag -r1.1 -F br file1" \ -"${PROG} tag: file1: Not moving branch tag .br. from 1\.1\.4\.1 to 1\.1\." - # try accidentally converting branch tag to non-branch tag "rtag -F" - dotest tagf-19 "${testcvs} rtag -r1.1 -F br first-dir" \ -"${PROG} rtag: Tagging first-dir -${PROG} rtag: first-dir/file1: Not moving branch tag .br. from 1\.1\.4\.1 to 1\.1\. -${PROG} rtag: first-dir/file2: Not moving branch tag .br. from 1\.1\.2\.2 to 1\.1\." - # create a non-branch tag - dotest tagf-20 "${testcvs} rtag regulartag first-dir" \ -"${PROG} rtag: Tagging first-dir" - # try accidentally converting non-branch tag to branch tag (tag -F -B -b) - dotest tagf-21 "${testcvs} tag -F -B -b regulartag file1" \ -"${PROG} tag: file1: Not moving non-branch tag .regulartag. from 1\.1 to 1\.1\.4\.1\.0\.2 due to .-B. option\." - # try accidentally converting non-branch tag to branch rtag (rtag -F -B -b) - dotest tagf-22 "${testcvs} rtag -F -B -b regulartag first-dir" \ -"${PROG} rtag: Tagging first-dir -${PROG} rtag: first-dir/file1: Not moving non-branch tag .regulartag. from 1\.1 to 1\.1\.0\.6 due to .-B. option\. -${PROG} rtag: first-dir/file2: Not moving non-branch tag .regulartag. from 1\.1 to 1\.1\.0\.4 due to .-B. option\." - # Try accidentally deleting non-branch: (tag -d -B) - dotest_fail tagf-23 "${testcvs} tag -d -B regulartag file1" \ -"${PROG} tag: Not removing non-branch tag .regulartag. from .${CVSROOT_DIRNAME}/first-dir/file1,v. due to .-B. option\." - # Try accidentally deleting non-branch: (rtag -d -B) - dotest_fail tagf-24 \ - "${testcvs} rtag -d -B regulartag first-dir" \ -"${PROG} rtag: Untagging first-dir -${PROG} rtag: Not removing non-branch tag .regulartag. from .${CVSROOT_DIRNAME}/first-dir/file1,v. due to .-B. option\. -${PROG} rtag: Not removing non-branch tag .regulartag. from .${CVSROOT_DIRNAME}/first-dir/file2,v. due to .-B. option\." - - # the following tests (throught the next commit) keep moving the same - # tag back and forth between 1.1.6 & 1.1.8 in file1 and between - # 1.1.4 and 1.1.6 in file2 since nothing was checked in on some of - # these branches and CVS only tracks branches via tags unless they contain data. - - # try intentionally converting non-branch tag to branch tag (tag -F -b) - dotest tagf-25a "${testcvs} tag -F -b regulartag file1" "T file1" - # try intentionally moving a branch tag to a newly created branch (tag -F -b -B) - dotest tagf-25b "${testcvs} tag -F -B -b -r1.1 regulartag file1" \ -"T file1" - # try intentionally converting mixed tags to branch tags (rtag -F -b) - dotest tagf-26a "${testcvs} rtag -F -b regulartag first-dir" \ -"${PROG} rtag: Tagging first-dir -${PROG} rtag: first-dir/file1: Not moving branch tag .regulartag. from 1\.1 to 1\.1\.0\.8\." - # try intentionally converting a branch to a new branch tag (rtag -F -b -B) - dotest tagf-26b "${testcvs} rtag -F -B -b -r1.1 regulartag first-dir" \ -"${PROG} rtag: Tagging first-dir" - # update to our new branch - dotest tagf-27 "${testcvs} update -r regulartag" \ -"${PROG} update: Updating \. -U file1 -U file2" - # commit some changes and see that all rev numbers look right - echo changes >> file1 - echo changes >> file2 - dotest tagf-28 "${testcvs} ci -m changes" \ -"${PROG} [a-z]*: Examining \. -Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -new revision: 1\.1\.8\.1; previous revision: 1\.1 -done -Checking in file2; -${CVSROOT_DIRNAME}/first-dir/file2,v <-- file2 -new revision: 1\.1\.6\.1; previous revision: 1\.1 -done" - # try intentional branch to non-branch (tag -F -B) - dotest tagf-29 "${testcvs} tag -F -B -r1.1 regulartag file1" \ -"T file1" - # try non-branch to non-branch (tag -F -B) - dotest tagf-29a "${testcvs} tag -F -B -r br regulartag file1" \ -"${PROG} tag: file1: Not moving non-branch tag .regulartag. from 1\.1 to 1\.1\.4\.1 due to .-B. option\." - # try mixed-branch to non-branch (rtag -F -B ) - dotest tagf-29b "${testcvs} rtag -F -B -r br regulartag first-dir" \ -"${PROG} rtag: Tagging first-dir -${PROG} rtag: first-dir/file1: Not moving non-branch tag .regulartag. from 1\.1 to 1\.1\.4\.1 due to .-B. option\." - # at this point, regulartag is a regular tag within - # file1 and file2 - - # try intentional branch to non-branch (rtag -F -B) - dotest tagf-30 "${testcvs} rtag -F -B -r1.1 br first-dir" \ -"${PROG} rtag: Tagging first-dir" - # create a branch tag so we can try to delete it. - dotest tagf-31 "${testcvs} rtag -b brtag first-dir" \ -"${PROG} rtag: Tagging first-dir" - - # try intentinal deletion of branch tag (tag -d -B) - dotest tagf-32 "${testcvs} tag -d -B brtag file1" "D file1" - # try intentinal deletion of branch tag (rtag -d -B) - dotest tagf-33 "${testcvs} rtag -d -B brtag first-dir" \ -"${PROG} rtag: Untagging first-dir" - - cd ../.. - - rm -r 1 - rm -rf ${CVSROOT_DIRNAME}/first-dir - ;; - - tag-log) - # Test log output for tags - mkdir 1; cd 1 - dotest tag-log-init-1 "$testcvs -q co -l ." - mkdir first-dir - dotest tag-log-init-2 "$testcvs add first-dir" \ -"Directory $CVSROOT_DIRNAME/first-dir added to the repository" - cd first-dir - touch file1 - dotest tag-log-init-3 "$testcvs add file1" \ -"${PROG}"' add: scheduling file `file1'\'' for addition -'"${PROG}"' add: use .'"${PROG}"' commit. to add this file permanently' - dotest tag-log-init-4 "$testcvs -Q ci -m add" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -done -Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -initial revision: 1\.1 -done" - - dotest tag-log-1 "$testcvs -Q tag mytag file1" '' - dotest tag-log-2 "$testcvs log -N file1" \ -" -RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -Working file: file1 -head: 1\.1 -branch: -locks: strict -access list: -keyword substitution: kv -total revisions: 1; selected revisions: 1 -description: ----------------------------- -revision 1\.1 -date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; -add -=============================================================================" - dotest tag-log-3 "$testcvs log -N -n file1" \ -" -RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -Working file: file1 -head: 1\.1 -branch: -locks: strict -access list: -symbolic names: - mytag: 1\.1 -keyword substitution: kv -total revisions: 1; selected revisions: 1 -description: ----------------------------- -revision 1\.1 -date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; -add -=============================================================================" - dotest tag-log-4 "$testcvs log file1" \ -" -RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -Working file: file1 -head: 1\.1 -branch: -locks: strict -access list: -symbolic names: - mytag: 1\.1 -keyword substitution: kv -total revisions: 1; selected revisions: 1 -description: ----------------------------- -revision 1\.1 -date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; -add -=============================================================================" - dotest tag-log-5 "$testcvs log -n file1" \ -" -RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -Working file: file1 -head: 1\.1 -branch: -locks: strict -access list: -symbolic names: - mytag: 1\.1 -keyword substitution: kv -total revisions: 1; selected revisions: 1 -description: ----------------------------- -revision 1\.1 -date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; -add -=============================================================================" - - cd ../.. - rm -fr 1 - rm -rf ${CVSROOT_DIRNAME}/first-dir - ;; - - tag-space) - # Test tags with spaces in the names. - # - # Prior to releases 1.11.18 & 1.12.10, some commands used with - # tags with spaces in the names could hang CVS. - - # Setup; check in first-dir/file1 - mkdir 1; cd 1 - dotest tag-space-init-1 "$testcvs -q co -l ." - mkdir first-dir - dotest tag-space-init-2 "$testcvs add first-dir" \ -"Directory $CVSROOT_DIRNAME/first-dir added to the repository" - cd first-dir - touch file1 - dotest tag-space-init-3 "$testcvs add file1" \ -"$PROG add: scheduling file \`file1' for addition -$PROG add: use '$PROG commit' to add this file permanently" - dotest tag-space-init-4 "$testcvs -Q ci -m add" \ -"RCS file: $CVSROOT_DIRNAME/first-dir/file1,v -done -Checking in file1; -$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 -initial revision: 1\.1 -done" - - # Reportedly, the following two tags make it past WinCVS. - dotest_fail tag-space-1 "$testcvs tag ' spacetag '" \ -"$PROG \[tag aborted\]: tag \` spacetag ' must start with a letter" - dotest_fail tag-space-2 "$testcvs tag 'spacetag '" \ -"$PROG \[tag aborted\]: tag \`spacetag ' has non-visible graphic characters" - - if $remote; then - # Verify that this isn't a client check. - dotest tag-space-3 "$testcvs server" \ -"E $PROG \[tag aborted\]: tag \` spacetag ' must start with a letter -error " < foo.c - dotest rcsdiff-2 "${testcvs} add -m new-file foo.c" \ -"${PROG} add: scheduling file .foo\.c. for addition -${PROG} add: use .${PROG} commit. to add this file permanently" - dotest rcsdiff-3 "${testcvs} commit -m rev1 foo.c" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/foo\.c,v -done -Checking in foo\.c; -${CVSROOT_DIRNAME}/first-dir/foo.c,v <-- foo\.c -initial revision: 1\.1 -done" - dotest rcsdiff-4 "${testcvs} tag first foo.c" "T foo\.c" - dotest rcsdiff-5 "${testcvs} update -p -r first foo.c" \ -"=================================================================== -Checking out foo\.c -RCS: ${CVSROOT_DIRNAME}/first-dir/foo\.c,v -VERS: 1\.1 -\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* -I am the first foo, and my name is \$""Name: first \$\." - - echo "I am the second foo, and my name is $""Name$." > foo.c - dotest rcsdiff-6 "${testcvs} commit -m rev2 foo.c" \ -"Checking in foo\.c; -${CVSROOT_DIRNAME}/first-dir/foo\.c,v <-- foo\.c -new revision: 1\.2; previous revision: 1\.1 -done" - dotest rcsdiff-7 "${testcvs} tag second foo.c" "T foo\.c" - dotest rcsdiff-8 "${testcvs} update -p -r second foo.c" \ -"=================================================================== -Checking out foo\.c -RCS: ${CVSROOT_DIRNAME}/first-dir/foo\.c,v -VERS: 1\.2 -\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* -I am the second foo, and my name is \$""Name: second \$\." - - dotest_fail rcsdiff-9 "${testcvs} diff -r first -r second" \ -"${PROG} diff: Diffing \. -Index: foo\.c -=================================================================== -RCS file: ${CVSROOT_DIRNAME}/first-dir/foo\.c,v -retrieving revision 1\.1 -retrieving revision 1\.2 -diff -r1\.1 -r1\.2 -1c1 -< I am the first foo, and my name is \$""Name: \$\. ---- -> I am the second foo, and my name is \$""Name: \$\." - - echo "I am the once and future foo, and my name is $""Name$." > foo.c - dotest_fail rcsdiff-10 "${testcvs} diff -r first" \ -"${PROG} diff: Diffing \. -Index: foo\.c -=================================================================== -RCS file: ${CVSROOT_DIRNAME}/first-dir/foo\.c,v -retrieving revision 1\.1 -diff -r1\.1 foo\.c -1c1 -< I am the first foo, and my name is \$""Name: \$\. ---- -> I am the once and future foo, and my name is \$""Name\$\." - - # Test handling of libdiff options. diff gets quite enough - # of a workout elsewhere in sanity.sh, so we assume that it's - # mostly working properly if it passes all the other tests. - # The main one we want to try is regex handling, since we are - # using CVS's regex matcher and not diff's. - - cat >rgx.c <rgx.c < file1 - echo '2' >> file1 - echo '3' >> file1 - dotest rcslib-merge-4 "${testcvs} -q add file1" \ -"${PROG} add: use .${PROG} commit. to add this file permanently" - dotest rcslib-merge-5 "${testcvs} -q commit -m '' file1" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -done -Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -initial revision: 1\.1 -done" - sed -e 's/2/two/' file1 > f; mv f file1 - dotest rcslib-merge-6 "${testcvs} -q commit -m '' file1" \ -"Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -new revision: 1\.2; previous revision: 1\.1 -done" - dotest rcslib-merge-7 "${testcvs} -q tag -b -r 1.1 patch1" "T file1" - dotest rcslib-merge-8 "${testcvs} -q update -r patch1" "[UP] file1" - dotest rcslib-merge-9 "${testcvs} -q status" \ -"=================================================================== -File: file1 Status: Up-to-date - - Working revision: 1\.1.* - Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/file1,v - Sticky Tag: patch1 (branch: 1\.1\.2) - Sticky Date: (none) - Sticky Options: (none)" - dotest rcslib-merge-10 "cat file1" \ -'$''Revision: 1\.1 $ -2 -3' - sed -e 's/3/three/' file1 > f; mv f file1 - dotest rcslib-merge-11 "${testcvs} -q commit -m '' file1" \ -"Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -new revision: 1\.1\.2\.1; previous revision: 1\.1 -done" - dotest rcslib-merge-12 "${testcvs} -q update -kv -j1.2" \ -"U file1 -RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -retrieving revision 1\.1 -retrieving revision 1\.2 -Merging differences between 1\.1 and 1\.2 into file1 -rcsmerge: warning: conflicts during merge" - dotest rcslib-merge-13 "cat file1" \ -"<<<<<<< file1 -1\.1\.2\.1 -2 -three -[=]====== -1\.2 -two -3 -[>]>>>>>> 1\.2" - - # Test behavior of symlinks in the repository. - if test -n "$remotehost"; then - # Create the link on the remote system. This is because Cygwin's - # Windows support creates *.lnk files for Windows. When creating - # these in an SMB share from UNIX, these links won't work from the - # UNIX side. - dotest rcslib-symlink-1remotehost "${CVS_RSH} $remotehost 'ln -s file1,v ${CVSROOT_DIRNAME}/first-dir/file2,v'" - else - dotest rcslib-symlink-1 "ln -s file1,v ${CVSROOT_DIRNAME}/first-dir/file2,v" - fi - dotest rcslib-symlink-2 "${testcvs} update file2" "U file2" - echo "This is a change" >> file2 - dotest rcslib-symlink-3 "${testcvs} ci -m because file2" \ -"Checking in file2; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file2 -new revision: 1\.1\.2\.2; previous revision: 1\.1\.2\.1 -done" - - # Switch as for rcslib-symlink-1 - if test -n "$remotehost"; then - dotest rcslib-symlink-4 "$CVS_RSH $remotehost 'ls -l $CVSROOT_DIRNAME/first-dir/file2,v'" \ -".*$CVSROOT_DIRNAME/first-dir/file2,v -> file1,v" - else - dotest rcslib-symlink-4 "ls -l $CVSROOT_DIRNAME/first-dir/file2,v" \ -".*$CVSROOT_DIRNAME/first-dir/file2,v -> file1,v" - fi - - # CVS was failing to check both the symlink and the file - # for timestamp changes for a while. Test that. - rm file1 - dotest rcslib-symlink-3a "${testcvs} -q up file1" \ -"${PROG} update: warning: file1 was lost -U file1" - echo "This is a change" >> file1 - dotest rcslib-symlink-3b "${testcvs} ci -m because file1" \ -"Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -new revision: 1\.1\.2\.[0-9]*; previous revision: 1\.1\.2\.[0-9]* -done" - dotest rcslib-symlink-3c "${testcvs} update file2" "[UP] file2" - - echo some new text >file3 - dotest rcslib-symlink-3d "${testcvs} -Q add file3" '' - dotest rcslib-symlink-3e "${testcvs} -Q ci -mtest file3" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/Attic/file3,v -done -Checking in file3; -${CVSROOT_DIRNAME}/first-dir/Attic/file3,v <-- file3 -new revision: 1\.1\.2\.1; previous revision: 1\.1 -done" - - rm -f ${CVSROOT_DIRNAME}/first-dir/file2,v - # As for rcslib-symlink-1 - if test -n "$remotehost"; then - dotest rcslib-symlink-3f "$CVS_RSH $remotehost 'ln -s Attic/file3,v ${CVSROOT_DIRNAME}/first-dir/file2,v'" - else - dotest rcslib-symlink-3f "ln -s Attic/file3,v ${CVSROOT_DIRNAME}/first-dir/file2,v" - fi - - dotest rcslib-symlink-3g "${testcvs} update file2" "U file2" - - # restore the link to file1 for the following tests - dotest rcslib-symlink-3i "${testcvs} -Q rm -f file3" '' - dotest rcslib-symlink-3j "${testcvs} -Q ci -mwhatever file3" \ -"Removing file3; -${CVSROOT_DIRNAME}/first-dir/Attic/file3,v <-- file3 -new revision: delete; previous revision: 1\.1\.2\.1 -done" - rm -f ${CVSROOT_DIRNAME}/first-dir/file2,v - rm -f ${CVSROOT_DIRNAME}/first-dir/Attic/file3,v - # As for rcslib-symlink-1 - if test -n "$remotehost"; then - dotest rcslib-symlink-3h "$CVS_RSH $remotehost 'ln -s file1,v ${CVSROOT_DIRNAME}/first-dir/file2,v'" - else - dotest rcslib-symlink-3h "ln -s file1,v ${CVSROOT_DIRNAME}/first-dir/file2,v" - fi - - # Test 5 reveals a problem with having symlinks in the - # repository. CVS will try to tag both of the files - # separately. After processing one, it will do the same - # operation to the other, which is actually the same file, - # so the tag will already be there. FIXME: do we bother - # changing operations to notice cases like this? This - # strikes me as a difficult problem. -Noel - dotest rcslib-symlink-5 "${testcvs} tag the_tag" \ -"${PROG} tag: Tagging . -T file1 -W file2 : the_tag already exists on version 1.1.2.3 : NOT MOVING tag to version 1.1.2.1" - # As for rcslib-symlink-1 - if test -n "$remotehost"; then - dotest rcslib-symlink-6 "$CVS_RSH $remotehost 'ls -l $CVSROOT_DIRNAME/first-dir/file2,v'" \ -".*$CVSROOT_DIRNAME/first-dir/file2,v -> file1,v" - else - dotest rcslib-symlink-6 "ls -l $CVSROOT_DIRNAME/first-dir/file2,v" \ -".*$CVSROOT_DIRNAME/first-dir/file2,v -> file1,v" - fi - - # Symlinks tend to interact poorly with the Attic. - cd .. - mkdir 2; cd 2 - dotest rcslib-symlink-7 "${testcvs} -q co first-dir" \ -"U first-dir/file1 -U first-dir/file2" - cd first-dir - dotest rcslib-symlink-8 "${testcvs} rm -f file2" \ -"${PROG} remove: scheduling .file2. for removal -${PROG} remove: use .${PROG} commit. to remove this file permanently" - dotest rcslib-symlink-9 "${testcvs} -q ci -m rm-it" \ -"Removing file2; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file2 -new revision: delete; previous revision: 1\.2 -done" - # OK, why this message happens twice is relatively clear - # (the check_* and rtag_* calls to start_recursion). - # Why it happens a third time I didn't try to find out. - dotest rcslib-symlink-10 \ -"${testcvs} -q rtag -b -r the_tag brtag first-dir" \ -"${PROG} rtag: could not read RCS file for file2 -${PROG} rtag: could not read RCS file for first-dir/file2 -${PROG} rtag: could not read RCS file for first-dir/file2" - - # Restore file1 for the next test. - dotest rcslib-long-symlink-init-1 "$testcvs -Q up -A" - dotest rcslib-long-symlink-init-2 "$testcvs -Q add file1" - dotest rcslib-long-symlink-init-3 "$testcvs -Q ci -mback" \ -"Checking in file1; -$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 -new revision: 1\.4; previous revision: 1\.3 -done" - - cd ../.. # $TESTDIR - - # CVS has a hard-coded default link path size of 127 characters. - # Make sure it knows how to exceed that. - longpath=$CVSROOT_DIRNAME - count=0 - while test $count -lt 10; do - count=`expr $count + 1` - longpath=$longpath/123456789012345678901234567890 - mkdir $longpath - done - cp $CVSROOT_DIRNAME/first-dir/file1,v $longpath - mkdir $CVSROOT_DIRNAME/second-dir - - # Switch as for rcslib-symlink-1 - if test -n "$remotehost"; then - dotest rcslib-long-symlink-1rh \ -"$CVS_RSH $remotehost 'ln -s $longpath/file1,v $CVSROOT_DIRNAME/second-dir/fileX,v'" - else - dotest rcslib-long-symlink-1 \ -"ln -s $longpath/file1,v $CVSROOT_DIRNAME/second-dir/fileX,v" - fi - - dotest rcslib-long-symlink-2 "$testcvs co second-dir" \ -"$PROG checkout: Updating second-dir -U second-dir/fileX" - - cd second-dir - echo change-it >>fileX - - # Writes actually cause symlinks to be resolved. - dotest rcslib-long-symlink-3 "$testcvs -q ci -mwrite-it" \ -"Checking in fileX; -$CVSROOT_DIRNAME/123456789012345678901234567890/123456789012345678901234567890/123456789012345678901234567890/123456789012345678901234567890/123456789012345678901234567890/123456789012345678901234567890/123456789012345678901234567890/123456789012345678901234567890/123456789012345678901234567890/123456789012345678901234567890/file1,v <-- fileX -new revision: 1\.5; previous revision: 1\.4 -done" - - if $keep; then - echo Keeping ${TESTDIR} and exiting due to --keep - exit 0 - fi - - cd .. - # Must remove the symlink first. Samba doesn't appear to show - # broken symlink across the SMB share, and rm -rf by itself - # will remove file1,v first and leave file2,v a broken link and the - # rm -rf will fail since it doesn't find file2,v and it still gets - # directory not empty errors removing cvsroot/first-dir. - # - # I'm not sure why I need to do this on $remotehost. The rm above - # rcslib-symlink-3j works fine, but the next one doesn't unless run - # remotely under Cygwin and using a TESTDIR on a Samba share. - if test -n "$remotehost"; then - $CVS_RSH $remotehost \ -"rm -f $CVSROOT_DIRNAME/first-dir/file2,v $CVSROOT_DIRNAME/second-dir/fileX,v" - fi - rm -rf $CVSROOT_DIRNAME/first-dir $CVSROOT_DIRNAME/second-dir \ - $CVSROOT_DIRNAME/123456789012345678901234567890 - rm -r first-dir second-dir 2 - ;; - - multibranch) - # Test the ability to have several branchpoints coming off the - # same revision. - mkdir ${CVSROOT_DIRNAME}/first-dir - dotest multibranch-1 "${testcvs} -q co first-dir" '' - cd first-dir - echo 1:trunk-1 >file1 - dotest multibranch-2 "${testcvs} add file1" \ -"${PROG}"' add: scheduling file `file1'\'' for addition -'"${PROG}"' add: use .'"${PROG}"' commit. to add this file permanently' - dotest_lit multibranch-3 "${testcvs} -q ci -m add-it" <file1 - dotest multibranch-7 "${testcvs} -q ci -m modify-on-br1" \ -"Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -new revision: 1\.1\.2\.1; previous revision: 1\.1 -done" - dotest multibranch-8 "${testcvs} -q update -r br2" '[UP] file1' - echo br2 adds a line >>file1 - dotest multibranch-9 "${testcvs} -q ci -m modify-on-br2" \ -"Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -new revision: 1\.1\.4\.1; previous revision: 1\.1 -done" - dotest multibranch-10 "${testcvs} -q update -r br1" '[UP] file1' - dotest multibranch-11 "cat file1" 'on-br1' - dotest multibranch-12 "${testcvs} -q update -r br2" '[UP] file1' - dotest multibranch-13 "cat file1" '1:trunk-1 -br2 adds a line' - - dotest multibranch-14 "${testcvs} log file1" \ -" -RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -Working file: file1 -head: 1\.1 -branch: -locks: strict -access list: -symbolic names: - br2: 1\.1\.0\.4 - br1: 1\.1\.0\.2 -keyword substitution: kv -total revisions: 3; selected revisions: 3 -description: ----------------------------- -revision 1\.1 -date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; -branches: 1\.1\.2; 1\.1\.4; -add-it ----------------------------- -revision 1\.1\.4\.1 -date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; lines: ${PLUS}1 -0 -modify-on-br2 ----------------------------- -revision 1\.1\.2\.1 -date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; lines: ${PLUS}1 -1 -modify-on-br1 -=============================================================================" - cd .. - - if $keep; then - echo Keeping ${TESTDIR} and exiting due to --keep - exit 0 - fi - - rm -rf ${CVSROOT_DIRNAME}/first-dir - rm -r first-dir - ;; - - import) # test death after import - # Tests of "cvs import": - # basic2 - # rdiff -- imports with keywords - # import -- more tests of imports with keywords - # importb -- -b option. - # importc -- bunch o' files in bunch o' directories - # modules3 - # mflag -- various -m messages - # ignore -- import and cvsignore - # binwrap -- import and -k wrappers - # info -- imports which are rejected by verifymsg - # head -- intended to test vendor branches and HEAD, - # although it doesn't really do it yet. - # import-CVS -- refuse to import directories named "CVS". - # import-quirks -- short tests of import quirks. - - # import - mkdir import-dir ; cd import-dir - - for i in 1 2 3 4 ; do - echo imported file"$i" > imported-f"$i" - done - - # This directory should be on the default ignore list, - # so it shouldn't get imported. - mkdir RCS - echo ignore.me >RCS/ignore.me - - echo 'import should not expand $''Id$' >>imported-f2 - cp imported-f2 ../imported-f2-orig.tmp - - dotest_sort import-96 \ -"${testcvs} import -m first-import first-dir vendor-branch junk-1_0" \ -" - -I first-dir/RCS -N first-dir/imported-f1 -N first-dir/imported-f2 -N first-dir/imported-f3 -N first-dir/imported-f4 -No conflicts created by this import" - - dotest import-96.5 "cmp ../imported-f2-orig.tmp imported-f2" '' - - cd .. - - # co - dotest import-97 "${testcvs} -q co first-dir" \ -"U first-dir/imported-f1 -U first-dir/imported-f2 -U first-dir/imported-f3 -U first-dir/imported-f4" - - cd first-dir - - for i in 1 2 3 4 ; do - dotest import-98-$i "test -f imported-f$i" '' - done - dotest_fail import-98.5 "test -d RCS" '' - - # remove - rm imported-f1 - dotest import-99 "${testcvs} rm imported-f1" \ -"${PROG}"' remove: scheduling `imported-f1'\'' for removal -'"${PROG}"' remove: use .'"${PROG}"' commit. to remove this file permanently' - - # change - echo local-change >> imported-f2 - - # commit - dotest import-100 "${testcvs} ci -m local-changes" \ -"${PROG} [a-z]*: Examining . -Removing imported-f1; -${CVSROOT_DIRNAME}/first-dir/imported-f1,v <-- imported-f1 -new revision: delete; previous revision: 1\.1\.1\.1 -done -Checking in imported-f2; -${CVSROOT_DIRNAME}/first-dir/imported-f2,v <-- imported-f2 -new revision: 1\.2; previous revision: 1\.1 -done" - - # log - dotest import-101 "${testcvs} log imported-f1" \ -" -RCS file: ${CVSROOT_DIRNAME}/first-dir/Attic/imported-f1,v -Working file: imported-f1 -head: 1\.2 -branch: -locks: strict -access list: -symbolic names: - junk-1_0: 1\.1\.1\.1 - vendor-branch: 1\.1\.1 -keyword substitution: kv -total revisions: 3; selected revisions: 3 -description: ----------------------------- -revision 1\.2 -date: [0-9/]* [0-9:]*; author: ${username}; state: dead; lines: ${PLUS}0 -0 -local-changes ----------------------------- -revision 1\.1 -date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; -branches: 1\.1\.1; -Initial revision ----------------------------- -revision 1\.1\.1\.1 -date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; lines: ${PLUS}0 -0 -first-import -=============================================================================" - - # update into the vendor branch. - dotest import-102 "$testcvs update -rvendor-branch" \ -"$PROG update: Updating . -U imported-f1 -[UP] imported-f2 -[UP] imported-f3 -[UP] imported-f4" - - # remove file4 on the vendor branch - rm imported-f4 - dotest import-103 "${testcvs} rm imported-f4" \ -"${PROG}"' remove: scheduling `imported-f4'\'' for removal -'"${PROG}"' remove: use .'"${PROG}"' commit. to remove this file permanently' - - # commit - dotest import-104 \ -"${testcvs} ci -m vendor-removed imported-f4" \ -"Removing imported-f4; -${CVSROOT_DIRNAME}/first-dir/imported-f4,v <-- imported-f4 -new revision: delete; previous revision: 1\.1\.1\.1 -done" - - # update to main line - dotest import-105 "$testcvs -q update -A" \ -"$PROG update: imported-f1 is no longer in the repository -[UP] imported-f2 -[UP] imported-f3" - - # second import - file4 deliberately unchanged - cd ../import-dir - for i in 1 2 3 ; do - echo rev 2 of file $i >> imported-f"$i" - done - cp imported-f2 ../imported-f2-orig.tmp - - dotest_sort import-106 \ -"${testcvs} import -m second-import first-dir vendor-branch junk-2_0" \ -" - - - ${PROG} checkout -j -jjunk-2_0 first-dir -2 conflicts created by this import. -C first-dir/imported-f1 -C first-dir/imported-f2 -I first-dir/RCS -U first-dir/imported-f3 -U first-dir/imported-f4 -Use the following command to help the merge:" - - dotest import-106.5 "cmp ../imported-f2-orig.tmp imported-f2" \ -'' - - cd .. - - rm imported-f2-orig.tmp - - # co - dotest import-107 "${testcvs} co first-dir" \ -"${PROG} checkout: Updating first-dir -[UP] first-dir/imported-f3 -[UP] first-dir/imported-f4" - - cd first-dir - - dotest_fail import-108 "test -f imported-f1" '' - - for i in 2 3 ; do - dotest import-109-$i "test -f imported-f$i" '' - done - - # check vendor branch for file4 - dotest import-110 "$testcvs -q update -rvendor-branch" \ -'U imported-f1 -[UP] imported-f2 -[UP] imported-f3 -[UP] imported-f4' - - dotest import-111 "test -f imported-f4" '' - - # update to main line - dotest import-112 "$testcvs -q update -A" \ -"$PROG update: imported-f1 is no longer in the repository -[UP] imported-f2 -[UP] imported-f3 -[UP] imported-f4" - - cd .. - - dotest import-113 \ -"${testcvs} -q co -jjunk-1_0 -jjunk-2_0 first-dir" \ -"${PROG} checkout: file first-dir/imported-f1 does not exist, but is present in revision junk-2_0 -RCS file: ${CVSROOT_DIRNAME}/first-dir/imported-f2,v -retrieving revision 1\.1\.1\.1 -retrieving revision 1\.1\.1\.2 -Merging differences between 1\.1\.1\.1 and 1\.1\.1\.2 into imported-f2 -rcsmerge: warning: conflicts during merge -first-dir/imported-f3 already contains the differences between 1\.1\.1\.1 and 1\.1\.1\.2 -first-dir/imported-f4 already contains the differences between 1\.1\.1\.1 and 1\.1\.1\.3" - - cd first-dir - - dotest_fail import-114 "test -f imported-f1" '' - - for i in 2 3 ; do - dotest import-115-$i "test -f imported-f$i" '' - done - - dotest import-116 'cat imported-f2' \ -'imported file2 -[<]<<<<<< imported-f2 -import should not expand \$''Id: imported-f2,v 1\.2 [0-9/]* [0-9:]* '"${username}"' Exp \$ -local-change -[=]====== -import should not expand \$''Id: imported-f2,v 1\.1\.1\.2 [0-9/]* [0-9:]* '"${username}"' Exp \$ -rev 2 of file 2 -[>]>>>>>> 1\.1\.1\.2' - - cd .. - rm -r first-dir - rm -rf ${CVSROOT_DIRNAME}/first-dir - rm -r import-dir - ;; - - importb) - # More cvs import tests, especially -b option. - - # OK, first we get some sources from the NetMunger project, and - # import them into the 1.1.1 vendor branch. - mkdir imp-dir - cd imp-dir - echo 'OpenMunger sources' >file1 - echo 'OpenMunger sources' >file2 - dotest_sort importb-1 \ -"${testcvs} import -m add first-dir openmunger openmunger-1_0" \ -" - -N first-dir/file1 -N first-dir/file2 -No conflicts created by this import" - cd .. - rm -r imp-dir - - # Now we put the sources we get from FreeMunger into 1.1.3 - mkdir imp-dir - cd imp-dir - echo 'FreeMunger sources' >file1 - echo 'FreeMunger sources' >file2 - # Not completely sure how the conflict detection is supposed to - # be working here (haven't really thought about it). - # We use an explicit -d option to test that it is reflected - # in the suggested checkout. - dotest_sort importb-2 \ -"${testcvs} -d ${CVSROOT} import -m add -b 1.1.3 first-dir freemunger freemunger-1_0" \ -" - - - ${PROG} -d ${CVSROOT} checkout -j -jfreemunger-1_0 first-dir -2 conflicts created by this import. -C first-dir/file1 -C first-dir/file2 -Use the following command to help the merge:" - cd .. - rm -r imp-dir - - # Now a test of main branch import (into second-dir, not first-dir). - mkdir imp-dir - cd imp-dir - echo 'my own stuff' >mine1.c - echo 'my own stuff' >mine2.c - dotest_fail importb-3 \ -"${testcvs} import -m add -b 1 second-dir dummy really_dumb_y" \ -"$PROG \[import aborted\]: Only numeric branch specifications with two dots are -supported by import, not \`1'\. For example: \`1\.1\.1'\." - : when we implement main-branch import, should be \ -"N second-dir/mine1\.c -N second-dir/mine2\.c - -No conflicts created by this import" - cd .. - rm -r imp-dir - - mkdir 1 - cd 1 - # when we implement main branch import, will want to - # add "second-dir" here. - dotest importb-4 "${testcvs} -q co first-dir" \ -"U first-dir/file1 -U first-dir/file2" - cd first-dir - dotest importb-5 "${testcvs} -q log file1" " -RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -Working file: file1 -head: 1\.1 -branch: 1\.1\.1 -locks: strict -access list: -symbolic names: - freemunger-1_0: 1\.1\.3\.1 - freemunger: 1\.1\.3 - openmunger-1_0: 1\.1\.1\.1 - openmunger: 1\.1\.1 -keyword substitution: kv -total revisions: 3; selected revisions: 3 -description: ----------------------------- -revision 1\.1 -date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; -branches: 1\.1\.1; 1\.1\.3; -Initial revision ----------------------------- -revision 1\.1\.3\.1 -date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; lines: ${PLUS}1 -1 -add ----------------------------- -revision 1\.1\.1\.1 -date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; lines: ${PLUS}0 -0 -add -=============================================================================" - - cd ../.. - rm -r 1 - rm -rf ${CVSROOT_DIRNAME}/first-dir ${CVSROOT_DIRNAME}/second-dir - ;; - - importc) - # Test importing a bunch o' files in a bunch o' directories. - # Also the -d option. - mkdir 1; cd 1 - mkdir adir bdir cdir - mkdir adir/sub1 adir/sub2 - mkdir adir/sub1/ssdir - mkdir bdir/subdir - touch adir/sub1/file1 adir/sub2/file2 adir/sub1/ssdir/ssfile - touch -t 197107040343 bdir/subdir/file1 - touch -t 203412251801 cdir/cfile - dotest_sort importc-1 \ -"${testcvs} import -d -m import-it first-dir vendor release" \ -" - -N first-dir/adir/sub1/file1 -N first-dir/adir/sub1/ssdir/ssfile -N first-dir/adir/sub2/file2 -N first-dir/bdir/subdir/file1 -N first-dir/cdir/cfile -No conflicts created by this import -${PROG} import: Importing ${CVSROOT_DIRNAME}/first-dir/adir -${PROG} import: Importing ${CVSROOT_DIRNAME}/first-dir/adir/sub1 -${PROG} import: Importing ${CVSROOT_DIRNAME}/first-dir/adir/sub1/ssdir -${PROG} import: Importing ${CVSROOT_DIRNAME}/first-dir/adir/sub2 -${PROG} import: Importing ${CVSROOT_DIRNAME}/first-dir/bdir -${PROG} import: Importing ${CVSROOT_DIRNAME}/first-dir/bdir/subdir -${PROG} import: Importing ${CVSROOT_DIRNAME}/first-dir/cdir" - cd .. - mkdir 2; cd 2 - dotest importc-2 "${testcvs} -q co first-dir" \ -"U first-dir/adir/sub1/file1 -U first-dir/adir/sub1/ssdir/ssfile -U first-dir/adir/sub2/file2 -U first-dir/bdir/subdir/file1 -U first-dir/cdir/cfile" - cd first-dir - dotest importc-3 "${testcvs} update adir/sub1" \ -"${PROG} update: Updating adir/sub1 -${PROG} update: Updating adir/sub1/ssdir" - dotest importc-4 "${testcvs} update adir/sub1 bdir/subdir" \ -"${PROG} update: Updating adir/sub1 -${PROG} update: Updating adir/sub1/ssdir -${PROG} update: Updating bdir/subdir" - - echo modify >>cdir/cfile - dotest importc-5 \ -"${testcvs} -q rtag -b -r release wip_test first-dir" "" - dotest importc-6 "$testcvs -q update -r wip_test" \ -'U adir/sub1/file1 -U adir/sub1/ssdir/ssfile -U adir/sub2/file2 -U bdir/subdir/file1 -M cdir/cfile' - - # This used to fail in local mode - dotest importc-7 "${testcvs} -q ci -m modify -r wip_test" \ -"Checking in cdir/cfile; -${CVSROOT_DIRNAME}/first-dir/cdir/cfile,v <-- cfile -new revision: 1\.1\.1\.1\.2\.1; previous revision: 1\.1\.1\.1 -done" - - # TODO: should also be testing "import -d" when we update - # an existing file. - dotest importc-8 "${testcvs} -q log cdir/cfile" " -RCS file: ${CVSROOT_DIRNAME}/first-dir/cdir/cfile,v -Working file: cdir/cfile -head: 1\.1 -branch: 1\.1\.1 -locks: strict -access list: -symbolic names: - wip_test: 1\.1\.1\.1\.0\.2 - release: 1\.1\.1\.1 - vendor: 1\.1\.1 -keyword substitution: kv -total revisions: 3; selected revisions: 3 -description: ----------------------------- -revision 1\.1 -date: 2034/12/2[4-6] [0-9][0-9]:01:[0-9][0-9]; author: ${username}; state: Exp; -branches: 1\.1\.1; -Initial revision ----------------------------- -revision 1\.1\.1\.1 -date: 2034/12/2[4-6] [0-9][0-9]:01:[0-9][0-9]; author: ${username}; state: Exp; lines: ${PLUS}0 -0 -branches: 1\.1\.1\.1\.2; -import-it ----------------------------- -revision 1\.1\.1\.1\.2\.1 -date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; lines: ${PLUS}1 -0 -modify -=============================================================================" - - dotest importc-9 "${testcvs} -q log bdir/subdir/file1" " -RCS file: ${CVSROOT_DIRNAME}/first-dir/bdir/subdir/file1,v -Working file: bdir/subdir/file1 -head: 1\.1 -branch: 1\.1\.1 -locks: strict -access list: -symbolic names: - wip_test: 1\.1\.1\.1\.0\.2 - release: 1\.1\.1\.1 - vendor: 1\.1\.1 -keyword substitution: kv -total revisions: 2; selected revisions: 2 -description: ----------------------------- -revision 1\.1 -date: 1971/07/0[3-5] [0-9][0-9]:43:[0-9][0-9]; author: ${username}; state: Exp; -branches: 1\.1\.1; -Initial revision ----------------------------- -revision 1\.1\.1\.1 -date: 1971/07/0[3-5] [0-9][0-9]:43:[0-9][0-9]; author: ${username}; state: Exp; lines: ${PLUS}0 -0 -import-it -=============================================================================" - cd .. - - # Now tests of absolute pathnames and .. as repository directory. - cd ../1 - dotest_fail importc-10 \ -"${testcvs} import -m imp ../other vendor release2" \ -"${PROG} \[[a-z]* aborted\]: directory \.\./other not relative within the repository" - dotest_fail importc-11 \ -"${testcvs} import -m imp ${TESTDIR}/other vendor release3" \ -"${PROG} \[[a-z]* aborted\]: directory ${TESTDIR}/other not relative within the repository" - dotest_fail importc-12 "test -d ${TESTDIR}/other" "" - cd .. - - rm -r 1 2 - rm -rf ${CVSROOT_DIRNAME}/first-dir - ;; - - import-CVS) - mkdir import-CVS - cd import-CVS - touch file1 file2 file3 - dotest_fail import-CVS-1 "$testcvs import -mimport CVS vtag rtag" \ -"$PROG import: The word \`CVS' is reserved by CVS and may not be used -$PROG \[import aborted\]: as a directory in a path or as a file name\." - dotest_fail import-CVS-1b \ -"$testcvs import -mimport CVS-/CVS vtag rtag" \ -"$PROG import: The word \`CVS' is reserved by CVS and may not be used -$PROG \[import aborted\]: as a directory in a path or as a file name\." - mkdir sdir - mkdir sdir/CVS - touch CVS sdir/CVS/file4 sdir/CVS/file5 sdir/file6 sdir/file7 - # Calling the imported directory import-CVS is dual purpose in the - # following test. It makes sure the path test which matched above - # wasn't too strict. - dotest_sort import-CVS-2 \ -"$testcvs import -I! -mimport import-CVS vtag rtag" \ -" - -I import-CVS/CVS -I import-CVS/sdir/CVS -N import-CVS/file1 -N import-CVS/file2 -N import-CVS/file3 -N import-CVS/sdir/file6 -N import-CVS/sdir/file7 -No conflicts created by this import -$PROG import: Importing $CVSROOT_DIRNAME/import-CVS/sdir" - - if $keep; then - echo Keeping ${TESTDIR} and exiting due to --keep - exit 0 - fi - - cd .. - rm -r import-CVS - rm -rf $CVSROOT_DIRNAME/import-CVS - ;; - - - - import-quirks) - # Short tests of quirky import behavior. - # - # For a list of other import tests with short descriptions, see the - # comment header of the "import" test. - mkdir import-quirks - cd import-quirks - touch file1 file2 file3 - - # CVS prior to 1.11.18 and 1.12.10 used to happily import to - # "branch 1.1", creating RCS archives with revisions like, - # "1.1..1". That double-dot is *not* a typo. - dotest_fail import-quirks-1 \ -"$testcvs import -b1.1. -mbad-bad-bad import-quirks VB RT" \ -"$PROG \[import aborted\]: Only numeric branch specifications with two dots are -supported by import, not \`1\.1\.'\. For example: \`1\.1\.1'\." - - dotest_fail import-quirks-2 \ -"$testcvs import -b1.1.1.. -mbad-bad-bad import-quirks VB RT" \ -"$PROG \[import aborted\]: Only numeric branch specifications with two dots are -supported by import, not \`1\.1\.1\.\.'\. For example: \`1\.1\.1'\." - - # Try a few odd numbers. This is hardly comprehensive. - dotest_sort import-quirks-2 \ -"$testcvs import -b10.10.101 -mthis-ones-ok import-quirks-2 VB RT" \ -" - -N import-quirks-2/file1 -N import-quirks-2/file2 -N import-quirks-2/file3 -No conflicts created by this import" - - dotest_sort import-quirks-3 \ -"$testcvs import -b2345678901.2345678901.2345678901 -mthis-ones-ok import-quirks-3 VB RT" \ -" - -N import-quirks-3/file1 -N import-quirks-3/file2 -N import-quirks-3/file3 -No conflicts created by this import" - - dotest_sort import-quirks-4 \ -"$testcvs import -b1.1.2 -mthis-ones-ok import-quirks-4 VB RT" \ -" - -N import-quirks-4/file1 -N import-quirks-4/file2 -N import-quirks-4/file3 -No conflicts created by this import" - - if $keep; then - echo Keeping $TESTDIR and exiting due to --keep - exit 0 - fi - - cd .. - rm -r import-quirks - rm -rf $CVSROOT_DIRNAME/import-quirks-2 \ - $CVSROOT_DIRNAME/import-quirks-3 \ - $CVSROOT_DIRNAME/import-quirks-4 - ;; - - - - import-after-initial) - # Properly handle the case in which the first version of a - # file is created by a regular cvs add and commit, and there - # is a subsequent cvs import of the same file. cvs update with - # a date tag must resort to searching the vendor branch only if - # the initial version of the file was created at the same time - # as the initial version on the vendor branch. - - mkdir 1; cd 1 - module=x - - echo > unused-file - - # Create the module. - dotest import-after-initial-1 \ - "$testcvs -Q import -m. $module X Y" '' - - file=m - # Check it out and add a file. - dotest import-after-initial-2 "$testcvs -Q co $module" '' - cd $module - echo original > $file - dotest import-after-initial-3 "${testcvs} -Q add $file" "" - dotest import-after-initial-4 "${testcvs} -Q ci -m. $file" \ -"RCS file: ${CVSROOT_DIRNAME}/$module/$file,v -done -Checking in $file; -${CVSROOT_DIRNAME}/$module/$file,v <-- $file -initial revision: 1\.1 -done" - - # Delay a little so the following import isn't done in the same - # second as the preceding commit. - sleep 2 - - # Do the first import of $file *after* $file already has an - # initial version. - mkdir sub - cd sub - echo newer-via-import > $file - dotest import-after-initial-5 \ - "$testcvs -Q import -m. $module X Y2" '' - cd .. - - # Sleep a second so we're sure to be after the second of the import. - sleep 1 - - dotest import-after-initial-6 \ - "$testcvs -Q update -p -D now $file" 'original' - - cd ../.. - rm -rf 1 - rm -rf ${CVSROOT_DIRNAME}/$module - ;; - - branch-after-import) - # Test branching after an import via both cvs tag -b and - # cvs add to verify that the HEAD remains at 1.1.1.1 - # This was a FreeBSD bug documented at the URL: - # http://www.freebsd.org/cgi/query-pr.cgi?pr=4033 - - mkdir branch-after-import - cd branch-after-import - - # OK, first we get some sources from the NetMunger project, - # and import them into the 1.1.1 vendor branch. - mkdir imp-dir - cd imp-dir - echo 'OpenMunger sources' >file1 - echo 'OpenMunger sources' >file2 - dotest_sort branch-after-import-1 \ -"${testcvs} import -m add first-dir openmunger openmunger-1_0" \ -' - -N first-dir/file1 -N first-dir/file2 -No conflicts created by this import' - cd .. - - # Next checkout the new module - dotest branch-after-import-2 \ -"${testcvs} -q co first-dir" \ -'U first-dir/file1 -U first-dir/file2' - cd first-dir - # Branch tag the file1 and cvs add file2, - # the branch should remain the same in both cases - # such that a new import will not require a conflict - # resolution. - dotest branch-after-import-3 \ -"${testcvs} tag -b TESTTOTRON file1" \ -'T file1' - dotest branch-after-import-4 \ -"$testcvs -q update -r TESTTOTRON" \ -"[UP] file1 -$PROG update: file2 is no longer in the repository" - - cp ../imp-dir/file2 . - dotest branch-after-import-5 \ -"${testcvs} add file2" \ -"${PROG} add: scheduling file .file2. for addition on branch .TESTTOTRON. -${PROG} add: use .${PROG} commit. to add this file permanently" - - dotest branch-after-import-6 \ -"${testcvs} commit -m cvs-add file2" \ -"Checking in file2; -${CVSROOT_DIRNAME}/first-dir/file2,v <-- file2 -new revision: 1\.1\.1\.1\.2\.2; previous revision: 1\.1\.1\.1\.2\.1 -done" - - if $keep; then - echo Keeping ${TESTDIR} and exiting due to --keep - exit 0 - fi - - cd ../.. - rm -r branch-after-import - rm -rf ${CVSROOT_DIRNAME}/first-dir - ;; - - join) - # Test doing joins which involve adding and removing files. - # Variety of scenarios (see list below), in the context of: - # * merge changes from T1 to T2 into the main line - # * merge changes from branch 'branch' into the main line - # * merge changes from branch 'branch' into branch 'br2'. - # See also binfile2, which does similar things with binary files. - # See also join2, which tests joining (and update -A) on only - # a single file, rather than a directory. - # See also rmadd2, which tests -j cases not involving branches - # (e.g. undoing a commit) - # See also join3, which tests some cases involving the greatest - # common ancestor. Here is a list of tests according to branch - # topology: - # - # --->bp---->trunk too many to mention - # \----->branch - # - # /----->branch1 - # --->bp---->trunk multibranch, multibranch2 - # \----->branch2 - # - # --->bp1----->bp2---->trunk join3 - # \->br1 \->br2 - # - # --->bp1----->trunk - # \----bp2---->branch branches - # \------>branch-of-branch - - # We check merging changes from T1 to T2 into the main line. - # Here are the interesting cases I can think of: - # 1) File added between T1 and T2, not on main line. - # File should be marked for addition. - # 2) File added between T1 and T2, also added on main line. - # Conflict. - # 3) File removed between T1 and T2, unchanged on main line. - # File should be marked for removal. - # 4) File removed between T1 and T2, modified on main line. - # If mod checked in, file should be marked for removal. - # If mod still in working directory, conflict. - # 5) File removed between T1 and T2, was never on main line. - # Nothing should happen. - # 6) File removed between T1 and T2, also removed on main line. - # Nothing should happen. - # 7) File not added between T1 and T2, added on main line. - # Nothing should happen. - # 8) File not modified between T1 and T2, removed on main line. - # Nothing should happen. - # 9) File modified between T1 and T2, removed on main line. - # Conflict. - # 10) File was never on branch, removed on main line. - # Nothing should happen. - - # We also check merging changes from a branch into the main - # line. Here are the interesting cases: - # 1) File added on branch, not on main line. - # File should be marked for addition. - # 2) File added on branch, also added on main line. - # Conflict. - # 3) File removed on branch, unchanged on main line. - # File should be marked for removal. - # 4) File removed on branch, modified on main line. - # Conflict. - # 5) File removed on branch, was never on main line. - # Nothing should happen. - # 6) File removed on branch, also removed on main line. - # Nothing should happen. - # 7) File added on main line, not added on branch. - # Nothing should happen. - # 8) File removed on main line, not modified on branch. - # Nothing should happen. - # 9) File modified on branch, removed on main line. - # Conflict. - # 10) File was never on branch, removed on main line. - # Nothing should happen. - - # In the tests below, fileN represents case N in the above - # lists. - - mkdir ${CVSROOT_DIRNAME}/first-dir - mkdir 1 - cd 1 - dotest join-1 "${testcvs} -q co first-dir" '' - - cd first-dir - - # Add two files. - echo 'first revision of file3' > file3 - echo 'first revision of file4' > file4 - echo 'first revision of file6' > file6 - echo 'first revision of file8' > file8 - echo 'first revision of file9' > file9 - dotest join-2 "${testcvs} add file3 file4 file6 file8 file9" \ -"${PROG}"' add: scheduling file `file3'\'' for addition -'"${PROG}"' add: scheduling file `file4'\'' for addition -'"${PROG}"' add: scheduling file `file6'\'' for addition -'"${PROG}"' add: scheduling file `file8'\'' for addition -'"${PROG}"' add: scheduling file `file9'\'' for addition -'"${PROG}"' add: use .'"${PROG}"' commit. to add these files permanently' - - dotest join-3 "${testcvs} -q commit -m add" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/file3,v -done -Checking in file3; -${CVSROOT_DIRNAME}/first-dir/file3,v <-- file3 -initial revision: 1\.1 -done -RCS file: ${CVSROOT_DIRNAME}/first-dir/file4,v -done -Checking in file4; -${CVSROOT_DIRNAME}/first-dir/file4,v <-- file4 -initial revision: 1\.1 -done -RCS file: ${CVSROOT_DIRNAME}/first-dir/file6,v -done -Checking in file6; -${CVSROOT_DIRNAME}/first-dir/file6,v <-- file6 -initial revision: 1\.1 -done -RCS file: ${CVSROOT_DIRNAME}/first-dir/file8,v -done -Checking in file8; -${CVSROOT_DIRNAME}/first-dir/file8,v <-- file8 -initial revision: 1\.1 -done -RCS file: ${CVSROOT_DIRNAME}/first-dir/file9,v -done -Checking in file9; -${CVSROOT_DIRNAME}/first-dir/file9,v <-- file9 -initial revision: 1\.1 -done" - - # Make a branch. - dotest join-4 "${testcvs} -q tag -b branch ." \ -'T file3 -T file4 -T file6 -T file8 -T file9' - - # Add file2, file7, and file10, modify file4, and remove - # file6, file8, and file9. - echo 'first revision of file2' > file2 - echo 'second revision of file4' > file4 - echo 'first revision of file7' > file7 - rm file6 file8 file9 - echo 'first revision of file10' > file10 - dotest join-5 "${testcvs} add file2 file7 file10" \ -"${PROG}"' add: scheduling file `file2'\'' for addition -'"${PROG}"' add: scheduling file `file7'\'' for addition -'"${PROG}"' add: scheduling file `file10'\'' for addition -'"${PROG}"' add: use .'"${PROG}"' commit. to add these files permanently' - dotest join-6 "${testcvs} rm file6 file8 file9" \ -"${PROG}"' remove: scheduling `file6'\'' for removal -'"${PROG}"' remove: scheduling `file8'\'' for removal -'"${PROG}"' remove: scheduling `file9'\'' for removal -'"${PROG}"' remove: use .'"${PROG}"' commit. to remove these files permanently' - dotest join-7 "${testcvs} -q ci -mx ." \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/file10,v -done -Checking in file10; -${CVSROOT_DIRNAME}/first-dir/file10,v <-- file10 -initial revision: 1\.1 -done -RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v -done -Checking in file2; -${CVSROOT_DIRNAME}/first-dir/file2,v <-- file2 -initial revision: 1\.1 -done -Checking in file4; -${CVSROOT_DIRNAME}/first-dir/file4,v <-- file4 -new revision: 1\.2; previous revision: 1\.1 -done -Removing file6; -${CVSROOT_DIRNAME}/first-dir/file6,v <-- file6 -new revision: delete; previous revision: 1\.1 -done -RCS file: ${CVSROOT_DIRNAME}/first-dir/file7,v -done -Checking in file7; -${CVSROOT_DIRNAME}/first-dir/file7,v <-- file7 -initial revision: 1\.1 -done -Removing file8; -${CVSROOT_DIRNAME}/first-dir/file8,v <-- file8 -new revision: delete; previous revision: 1\.1 -done -Removing file9; -${CVSROOT_DIRNAME}/first-dir/file9,v <-- file9 -new revision: delete; previous revision: 1\.1 -done" - - # Remove file10 - dotest join-7a "${testcvs} rm -f file10" \ -"${PROG}"' remove: scheduling `file10'\'' for removal -'"${PROG}"' remove: use .'"${PROG}"' commit. to remove this file permanently' - dotest join-7b "${testcvs} -q ci -mx ." \ -"Removing file10; -${CVSROOT_DIRNAME}/first-dir/file10,v <-- file10 -new revision: delete; previous revision: 1\.1 -done" - - # Check out the branch. - cd ../.. - mkdir 2 - cd 2 - dotest join-8 "${testcvs} -q co -r branch first-dir" \ -'U first-dir/file3 -U first-dir/file4 -U first-dir/file6 -U first-dir/file8 -U first-dir/file9' - - cd first-dir - - # Modify the files on the branch, so that T1 is not an - # ancestor of the main line, and add file5 - echo 'first branch revision of file3' > file3 - echo 'first branch revision of file4' > file4 - echo 'first branch revision of file5' > file5 - echo 'first branch revision of file6' > file6 - echo 'first branch revision of file9' > file9 - dotest join-9 "${testcvs} add file5" \ -"${PROG}"' add: scheduling file `file5'\'' for addition on branch `branch'\'' -'"${PROG}"' add: use .'"${PROG}"' commit. to add this file permanently' - dotest join-10 "${testcvs} -q ci -mx ." \ -"Checking in file3; -${CVSROOT_DIRNAME}/first-dir/file3,v <-- file3 -new revision: 1\.1\.2\.1; previous revision: 1\.1 -done -Checking in file4; -${CVSROOT_DIRNAME}/first-dir/file4,v <-- file4 -new revision: 1\.1\.2\.1; previous revision: 1\.1 -done -RCS file: ${CVSROOT_DIRNAME}/first-dir/Attic/file5,v -done -Checking in file5; -${CVSROOT_DIRNAME}/first-dir/Attic/file5,v <-- file5 -new revision: 1\.1\.2\.1; previous revision: 1\.1 -done -Checking in file6; -${CVSROOT_DIRNAME}/first-dir/Attic/file6,v <-- file6 -new revision: 1\.1\.2\.1; previous revision: 1\.1 -done -Checking in file9; -${CVSROOT_DIRNAME}/first-dir/Attic/file9,v <-- file9 -new revision: 1\.1\.2\.1; previous revision: 1\.1 -done" - - # Tag the current revisions on the branch. - dotest join-11 "${testcvs} -q tag T1 ." \ -'T file3 -T file4 -T file5 -T file6 -T file8 -T file9' - - # Add file1 and file2, modify file9, and remove the other files. - echo 'first branch revision of file1' > file1 - echo 'first branch revision of file2' > file2 - echo 'second branch revision of file9' > file9 - rm file3 file4 file5 file6 - dotest join-12 "${testcvs} add file1 file2" \ -"${PROG}"' add: scheduling file `file1'\'' for addition on branch `branch'\'' -'"${PROG}"' add: scheduling file `file2'\'' for addition on branch `branch'\'' -'"${PROG}"' add: use .'"${PROG}"' commit. to add these files permanently' - dotest join-13 "${testcvs} rm file3 file4 file5 file6" \ -"${PROG}"' remove: scheduling `file3'\'' for removal -'"${PROG}"' remove: scheduling `file4'\'' for removal -'"${PROG}"' remove: scheduling `file5'\'' for removal -'"${PROG}"' remove: scheduling `file6'\'' for removal -'"${PROG}"' remove: use .'"${PROG}"' commit. to remove these files permanently' - dotest join-14 "${testcvs} -q ci -mx ." \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/Attic/file1,v -done -Checking in file1; -${CVSROOT_DIRNAME}/first-dir/Attic/file1,v <-- file1 -new revision: 1\.1\.2\.1; previous revision: 1\.1 -done -Checking in file2; -${CVSROOT_DIRNAME}/first-dir/file2,v <-- file2 -new revision: 1\.1\.2\.2; previous revision: 1\.1\.2\.1 -done -Removing file3; -${CVSROOT_DIRNAME}/first-dir/file3,v <-- file3 -new revision: delete; previous revision: 1\.1\.2\.1 -done -Removing file4; -${CVSROOT_DIRNAME}/first-dir/file4,v <-- file4 -new revision: delete; previous revision: 1\.1\.2\.1 -done -Removing file5; -${CVSROOT_DIRNAME}/first-dir/Attic/file5,v <-- file5 -new revision: delete; previous revision: 1\.1\.2\.1 -done -Removing file6; -${CVSROOT_DIRNAME}/first-dir/Attic/file6,v <-- file6 -new revision: delete; previous revision: 1\.1\.2\.1 -done -Checking in file9; -${CVSROOT_DIRNAME}/first-dir/Attic/file9,v <-- file9 -new revision: 1\.1\.2\.2; previous revision: 1\.1\.2\.1 -done" - - # Tag the current revisions on the branch. - dotest join-15 "${testcvs} -q tag T2 ." \ -'T file1 -T file2 -T file8 -T file9' - - # Do a checkout with a merge. - cd ../.. - mkdir 3 - cd 3 - dotest join-16 "$testcvs -q co -jT1 -jT2 first-dir" \ -"U first-dir/file1 -U first-dir/file2 -$PROG checkout: file first-dir/file2 exists, but has been added in revision T2 -U first-dir/file3 -$PROG checkout: scheduling first-dir/file3 for removal -U first-dir/file4 -$PROG checkout: file first-dir/file4 has been removed in revision T2, but the destination is incompatibly modified -C first-dir/file4 -U first-dir/file7 -$PROG checkout: file first-dir/file9 does not exist, but is present in revision T2" - - # Verify that the right changes have been scheduled. - cd first-dir - dotest_fail join-17 "$testcvs -q update" \ -'A file1 -R file3 -C file4' - - # Modify file4 locally, and do an update with a merge. - cd ../../1/first-dir - echo 'third revision of file4' > file4 - dotest join-18 "$testcvs -q update -jT1 -jT2 ." \ -"U file1 -$PROG update: file file2 exists, but has been added in revision T2 -$PROG update: scheduling file3 for removal -M file4 -$PROG update: file file4 has been removed in revision T2, but the destination is incompatibly modified -C file4 -$PROG update: file file9 does not exist, but is present in revision T2" - - # Verify that the right changes have been scheduled. - dotest_fail join-19 "$testcvs -q update" \ -'A file1 -R file3 -C file4' - - # Do a checkout with a merge from a single revision. - - # FIXME: CVS currently gets this wrong. file2 has been - # added on both the branch and the main line, and so should - # be regarded as a conflict. However, given the way that - # CVS sets up the RCS file, there is no way to distinguish - # this case from the case of file2 having existed before the - # branch was made. This could be fixed by reserving - # a revision somewhere, perhaps 1.1, as an always dead - # revision which can be used as the source for files added - # on branches. - cd ../../3 - rm -r first-dir - dotest join-20 "$testcvs -q co -jbranch first-dir" \ -"U first-dir/file1 -U first-dir/file2 -RCS file: $CVSROOT_DIRNAME/first-dir/file2,v -retrieving revision 1\.1 -retrieving revision 1\.1\.2\.2 -Merging differences between 1\.1 and 1\.1\.2\.2 into file2 -U first-dir/file3 -$PROG checkout: scheduling first-dir/file3 for removal -U first-dir/file4 -$PROG checkout: file first-dir/file4 has been removed in revision branch, but the destination is incompatibly modified -C first-dir/file4 -U first-dir/file7 -$PROG checkout: file first-dir/file9 does not exist, but is present in revision branch" - - # Verify that the right changes have been scheduled. - # The M file2 line is a bug; see above join-20. - cd first-dir - dotest_fail join-21 "$testcvs -q update" \ -'A file1 -M file2 -R file3 -C file4' - - # Checkout the main line again. - cd ../../1 - rm -r first-dir - dotest join-22 "${testcvs} -q co first-dir" \ -'U first-dir/file2 -U first-dir/file3 -U first-dir/file4 -U first-dir/file7' - - # Modify file4 locally, and do an update with a merge from a - # single revision. - # The file2 handling is a bug; see above join-20. - cd first-dir - echo 'third revision of file4' > file4 - dotest join-23 "$testcvs -q update -jbranch ." \ -"U file1 -RCS file: $CVSROOT_DIRNAME/first-dir/file2,v -retrieving revision 1\.1 -retrieving revision 1\.1\.2\.2 -Merging differences between 1\.1 and 1\.1\.2\.2 into file2 -$PROG update: scheduling file3 for removal -M file4 -$PROG update: file file4 has been removed in revision branch, but the destination is incompatibly modified -C file4 -$PROG update: file file9 does not exist, but is present in revision branch" - - # Verify that the right changes have been scheduled. - # The M file2 line is a bug; see above join-20 - dotest_fail join-24 "$testcvs -q update" \ -'A file1 -M file2 -R file3 -C file4' - - cd .. - - # Checkout the main line again and make a new branch which we - # merge to. - rm -r first-dir - dotest join-25 "${testcvs} -q co first-dir" \ -'U first-dir/file2 -U first-dir/file3 -U first-dir/file4 -U first-dir/file7' - cd first-dir - dotest join-26 "${testcvs} -q tag -b br2" \ -"T file2 -T file3 -T file4 -T file7" - dotest join-27 "$testcvs -q update -r br2" \ -'[UP] file2 -[UP] file3 -[UP] file4 -[UP] file7' - # The handling of file8 and file9 here look fishy to me. I don't - # see why it should be different from the case where we merge to - # the trunk (e.g. join-23). - dotest join-28 "$testcvs -q update -j branch" \ -"U file1 -RCS file: $CVSROOT_DIRNAME/first-dir/file2,v -retrieving revision 1\.1 -retrieving revision 1\.1\.2\.2 -Merging differences between 1\.1 and 1\.1\.2\.2 into file2 -$PROG update: scheduling file3 for removal -$PROG update: file file4 has been removed in revision branch, but the destination is incompatibly modified -C file4 -U file8 -U file9" - # Verify that the right changes have been scheduled. - dotest_fail join-29 "$testcvs -q update" \ -"A file1 -M file2 -R file3 -C file4 -A file8 -A file9" - - # Checkout the mainline again to try updating and merging between two - # branches in the same step - # this seems a likely scenario - the user finishes up on branch and - # updates to br2 and merges in the same step - and there was a bug - # once that if the file was removed in the update then it wouldn't be - # readded in the merge - cd .. - rm -rf first-dir - dotest join-twobranch-1 "${testcvs} -q co -rbranch first-dir" \ -'U first-dir/file1 -U first-dir/file2 -U first-dir/file8 -U first-dir/file9' - cd first-dir - dotest join-twobranch-2 "$testcvs -q update -rbr2 -jbranch" \ -"$PROG update: file1 is no longer in the repository -U file1 -U file2 -RCS file: $CVSROOT_DIRNAME/first-dir/file2,v -retrieving revision 1\.1 -retrieving revision 1\.1\.2\.2 -Merging differences between 1\.1 and 1\.1\.2\.2 into file2 -U file3 -$PROG update: scheduling file3 for removal -U file4 -$PROG update: file file4 has been removed in revision branch, but the destination is incompatibly modified -C file4 -U file7 -$PROG update: file8 is no longer in the repository -U file8 -$PROG update: file9 is no longer in the repository -U file9" - # Verify that the right changes have been scheduled. - dotest_fail join-twobranch-3 "$testcvs -q update" \ -"A file1 -M file2 -R file3 -C file4 -A file8 -A file9" - - # Checkout the mainline again to try merging from the trunk - # to a branch. - cd .. - rm -r first-dir - dotest join-30 "${testcvs} -q co first-dir" \ -'U first-dir/file2 -U first-dir/file3 -U first-dir/file4 -U first-dir/file7' - cd first-dir - - # Tag the current revisions on the trunk. - dotest join-31 "${testcvs} -q tag T3 ." \ -'T file2 -T file3 -T file4 -T file7' - - # Modify file7. - echo 'second revision of file7' > file7 - dotest join-32 "${testcvs} -q ci -mx ." \ -"Checking in file7; -${CVSROOT_DIRNAME}/first-dir/file7,v <-- file7 -new revision: 1\.2; previous revision: 1\.1 -done" - - # And Tag again. - dotest join-33 "${testcvs} -q tag T4 ." \ -'T file2 -T file3 -T file4 -T file7' - - # Now update branch to T3. - cd ../../2/first-dir - dotest join-34 "${testcvs} -q up -jT3" \ -"${PROG} update: file file4 does not exist, but is present in revision T3 -U file7" - - # Verify that the right changes have been scheduled. - dotest join-35 "${testcvs} -q update" \ -'A file7' - - # Now update to T4. - # This is probably a bug, although in this particular case it just - # happens to do the right thing; see above join-20. - dotest join-36 "${testcvs} -q up -j T3 -j T4" \ -"A file7 -RCS file: ${CVSROOT_DIRNAME}/first-dir/file7,v -retrieving revision 1\.1 -retrieving revision 1\.2 -Merging differences between 1\.1 and 1\.2 into file7" - - # Verify that the right changes have been scheduled. - dotest join-37 "${testcvs} -q update" \ -'A file7' - - cd ../.. - - rm -r 1 2 3 - rm -rf ${CVSROOT_DIRNAME}/first-dir - ;; - - join2) - # More joining tests. - - # First the usual setup; create a directory first-dir, a file - # first-dir/file1, and a branch br1. - mkdir 1; cd 1 - dotest join2-1 "${testcvs} -q co -l ." '' - mkdir first-dir - dotest join2-2 "${testcvs} add first-dir" \ -"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" - cd first-dir - echo 'initial contents of file1' >file1 - dotest join2-3 "${testcvs} add file1" \ -"${PROG} add: scheduling file .file1. for addition -${PROG} add: use .${PROG} commit. to add this file permanently" - dotest join2-4 "${testcvs} -q ci -m add" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -done -Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -initial revision: 1\.1 -done" - dotest join2-5 "${testcvs} -q tag -b br1" "T file1" - dotest join2-6 "$testcvs -q update -r br1" '[UP] file1' - echo 'modify on branch' >>file1 - touch bradd - dotest join2-6a "${testcvs} add bradd" \ -"${PROG} add: scheduling file .bradd. for addition on branch .br1. -${PROG} add: use .${PROG} commit. to add this file permanently" - dotest join2-7 "${testcvs} -q ci -m modify" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/Attic/bradd,v -done -Checking in bradd; -${CVSROOT_DIRNAME}/first-dir/Attic/bradd,v <-- bradd -new revision: 1\.1\.2\.1; previous revision: 1\.1 -done -Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -new revision: 1\.1\.2\.1; previous revision: 1\.1 -done" - - # Here is the unusual/pathological part. We switch back to - # the trunk *for file1 only*, not for the whole directory. - dotest join2-8 "${testcvs} -q update -A file1" '[UP] file1' - dotest join2-9 "${testcvs} -q status file1" \ -"=================================================================== -File: file1 Status: Up-to-date - - Working revision: 1\.1.* - Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/file1,v - Sticky Tag: (none) - Sticky Date: (none) - Sticky Options: (none)" - dotest join2-10 "cat CVS/Tag" "Tbr1" - - dotest join2-11 "${testcvs} -q update -j br1 file1" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -retrieving revision 1\.1 -retrieving revision 1\.1\.2\.1 -Merging differences between 1\.1 and 1\.1\.2\.1 into file1" - dotest join2-12 "cat file1" "initial contents of file1 -modify on branch" - # We should have no sticky tag on file1 - dotest join2-13 "${testcvs} -q status file1" \ -"=================================================================== -File: file1 Status: Locally Modified - - Working revision: 1\.1.* - Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/file1,v - Sticky Tag: (none) - Sticky Date: (none) - Sticky Options: (none)" - dotest join2-14 "cat CVS/Tag" "Tbr1" - # And the checkin should go to the trunk - dotest join2-15 "${testcvs} -q ci -m modify file1" \ -"Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -new revision: 1\.2; previous revision: 1\.1 -done" - - # OK, the above is all well and good and has worked for some - # time. Now try the case where the file had been added on - # the branch. - dotest join2-16 "${testcvs} -q update -r br1" "[UP] file1" - # The workaround is to update the whole directory. - # The non-circumvented version won't work. The reason is that - # update removes the entry from CVS/Entries, so of course we get - # the tag from CVS/Tag and not Entries. I suppose maybe - # we could invent some new format in Entries which would handle - # this, but doing so, and handling it properly throughout - # CVS, would be a lot of work and I'm not sure this case justifies - # it. - dotest join2-17-circumvent "${testcvs} -q update -A" \ -"${PROG} update: bradd is no longer in the repository -[UP] file1" -: dotest join2-17 "${testcvs} -q update -A bradd" \ -"${PROG} update: warning: bradd is not (any longer) pertinent" - dotest join2-18 "${testcvs} -q update -j br1 bradd" "U bradd" - dotest join2-19 "${testcvs} -q status bradd" \ -"=================================================================== -File: bradd Status: Locally Added - - Working revision: New file! - Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/Attic/bradd,v - Sticky Tag: (none) - Sticky Date: (none) - Sticky Options: (none)" - dotest join2-20 "${testcvs} -q ci -m modify bradd" \ -"Checking in bradd; -${CVSROOT_DIRNAME}/first-dir/bradd,v <-- bradd -new revision: 1\.2; previous revision: 1\.1 -done" - - cd ../.. - rm -r 1 - rm -rf ${CVSROOT_DIRNAME}/first-dir - ;; - - join3) - # See "join" for a list of other joining/branching tests. - # First the usual setup; create a directory first-dir, a file - # first-dir/file1, and a branch br1. - mkdir 1; cd 1 - dotest join3-1 "${testcvs} -q co -l ." '' - mkdir first-dir - dotest join3-2 "${testcvs} add first-dir" \ -"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" - cd first-dir - echo 'initial contents of file1' >file1 - dotest join3-3 "${testcvs} add file1" \ -"${PROG} add: scheduling file .file1. for addition -${PROG} add: use .${PROG} commit. to add this file permanently" - dotest join3-4 "${testcvs} -q ci -m add" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -done -Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -initial revision: 1\.1 -done" - dotest join3-5 "${testcvs} -q tag -b br1" "T file1" - dotest join3-6 "$testcvs -q update -r br1" '[UP] file1' - echo 'br1:line1' >>file1 - dotest join3-7 "${testcvs} -q ci -m modify" \ -"Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -new revision: 1\.1\.2\.1; previous revision: 1\.1 -done" - - # Now back to the trunk for: - # another revision and another branch for file1. - # add file2, which will exist on trunk and br2 but not br1. - dotest join3-8 "${testcvs} -q update -A" "[UP] file1" - echo 'trunk:line1' > file2 - dotest join3-8a "${testcvs} add file2" \ -"${PROG} add: scheduling file .file2. for addition -${PROG} add: use .${PROG} commit. to add this file permanently" - echo 'trunk:line1' >>file1 - dotest join3-9 "${testcvs} -q ci -m modify" \ -"Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -new revision: 1\.2; previous revision: 1\.1 -done -RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v -done -Checking in file2; -${CVSROOT_DIRNAME}/first-dir/file2,v <-- file2 -initial revision: 1\.1 -done" - dotest join3-10 "${testcvs} -q tag -b br2" "T file1 -T file2" - - # Before we actually have any revision on br2, let's try a join - dotest join3-11 "${testcvs} -q update -r br1" "[UP] file1 -${PROG} update: file2 is no longer in the repository" - dotest join3-12 "${testcvs} -q update -j br2" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -retrieving revision 1\.1 -retrieving revision 1\.2 -Merging differences between 1\.1 and 1\.2 into file1 -rcsmerge: warning: conflicts during merge -U file2" - dotest join3-13 "cat file1" \ -"initial contents of file1 -[<]<<<<<< file1 -br1:line1 -[=]====== -trunk:line1 -[>]>>>>>> 1\.2" - rm file1 - - # OK, we'll try the same thing with a revision on br2. - dotest join3-14 "${testcvs} -q update -r br2 file1" \ -"${PROG} update: warning: file1 was lost -U file1" "U file1" - echo 'br2:line1' >>file1 - dotest join3-15 "${testcvs} -q ci -m modify file1" \ -"Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -new revision: 1\.2\.2\.1; previous revision: 1\.2 -done" - - # OK, now we can join br2 to br1 - dotest join3-16 "${testcvs} -q update -r br1 file1" "[UP] file1" - # It may seem odd, to merge a higher branch into a lower - # branch, but in fact CVS defines the ancestor as 1.1 - # and so it merges both the 1.1->1.2 and 1.2->1.2.2.1 changes. - # This seems like a reasonably plausible behavior. - dotest join3-17 "${testcvs} -q update -j br2 file1" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -retrieving revision 1\.1 -retrieving revision 1\.2\.2\.1 -Merging differences between 1\.1 and 1\.2\.2\.1 into file1 -rcsmerge: warning: conflicts during merge" - dotest join3-18 "cat file1" \ -"initial contents of file1 -[<]<<<<<< file1 -br1:line1 -[=]====== -trunk:line1 -br2:line1 -[>]>>>>>> 1\.2\.2\.1" - - cd ../.. - rm -r 1 - rm -rf ${CVSROOT_DIRNAME}/first-dir - ;; - - join4) - # Like join, but with local (uncommitted) modifications. - - mkdir ${CVSROOT_DIRNAME}/first-dir - mkdir 1 - cd 1 - dotest join4-1 "${testcvs} -q co first-dir" '' - - cd first-dir - - # Add two files. - echo 'first revision of file3' > file3 - echo 'first revision of file4' > file4 - echo 'first revision of file6' > file6 - echo 'first revision of file8' > file8 - echo 'first revision of file9' > file9 - dotest join4-2 "${testcvs} add file3 file4 file6 file8 file9" \ -"${PROG}"' add: scheduling file `file3'\'' for addition -'"${PROG}"' add: scheduling file `file4'\'' for addition -'"${PROG}"' add: scheduling file `file6'\'' for addition -'"${PROG}"' add: scheduling file `file8'\'' for addition -'"${PROG}"' add: scheduling file `file9'\'' for addition -'"${PROG}"' add: use .'"${PROG}"' commit. to add these files permanently' - - dotest join4-3 "${testcvs} -q commit -m add" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/file3,v -done -Checking in file3; -${CVSROOT_DIRNAME}/first-dir/file3,v <-- file3 -initial revision: 1\.1 -done -RCS file: ${CVSROOT_DIRNAME}/first-dir/file4,v -done -Checking in file4; -${CVSROOT_DIRNAME}/first-dir/file4,v <-- file4 -initial revision: 1\.1 -done -RCS file: ${CVSROOT_DIRNAME}/first-dir/file6,v -done -Checking in file6; -${CVSROOT_DIRNAME}/first-dir/file6,v <-- file6 -initial revision: 1\.1 -done -RCS file: ${CVSROOT_DIRNAME}/first-dir/file8,v -done -Checking in file8; -${CVSROOT_DIRNAME}/first-dir/file8,v <-- file8 -initial revision: 1\.1 -done -RCS file: ${CVSROOT_DIRNAME}/first-dir/file9,v -done -Checking in file9; -${CVSROOT_DIRNAME}/first-dir/file9,v <-- file9 -initial revision: 1\.1 -done" - - # Make a branch. - dotest join4-4 "${testcvs} -q tag -b branch ." \ -'T file3 -T file4 -T file6 -T file8 -T file9' - - # Add file10 - echo 'first revision of file10' > file10 - dotest join4-7a "${testcvs} add file10" \ -"${PROG}"' add: scheduling file `file10'\'' for addition -'"${PROG}"' add: use .'"${PROG}"' commit. to add this file permanently' - dotest join4-7b "${testcvs} -q ci -mx ." \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/file10,v -done -Checking in file10; -${CVSROOT_DIRNAME}/first-dir/file10,v <-- file10 -initial revision: 1\.1 -done" - - # Add file2 and file7, modify file4, and remove - # file6, file8, file9, and file10. - echo 'first revision of file2' > file2 - echo 'second revision of file4' > file4 - echo 'first revision of file7' > file7 - rm file6 file8 file9 file10 - dotest join4-5 "${testcvs} add file2 file7" \ -"${PROG}"' add: scheduling file `file2'\'' for addition -'"${PROG}"' add: scheduling file `file7'\'' for addition -'"${PROG}"' add: use .'"${PROG}"' commit. to add these files permanently' - dotest join4-6 "${testcvs} rm file6 file8 file9 file10" \ -"${PROG}"' remove: scheduling `file6'\'' for removal -'"${PROG}"' remove: scheduling `file8'\'' for removal -'"${PROG}"' remove: scheduling `file9'\'' for removal -'"${PROG}"' remove: scheduling `file10'\'' for removal -'"${PROG}"' remove: use .'"${PROG}"' commit. to remove these files permanently' - - # Check out the branch. - cd ../.. - mkdir 2 - cd 2 - dotest join4-8 "${testcvs} -q co -r branch first-dir" \ -'U first-dir/file3 -U first-dir/file4 -U first-dir/file6 -U first-dir/file8 -U first-dir/file9' - - cd first-dir - - # Modify the files on the branch, so that T1 is not an - # ancestor of the main line, and add file5 - echo 'first branch revision of file3' > file3 - echo 'first branch revision of file4' > file4 - echo 'first branch revision of file5' > file5 - echo 'first branch revision of file6' > file6 - echo 'first branch revision of file9' > file9 - dotest join4-9 "${testcvs} add file5" \ -"${PROG}"' add: scheduling file `file5'\'' for addition on branch `branch'\'' -'"${PROG}"' add: use .'"${PROG}"' commit. to add this file permanently' - dotest join4-10 "${testcvs} -q ci -mx ." \ -"Checking in file3; -${CVSROOT_DIRNAME}/first-dir/file3,v <-- file3 -new revision: 1\.1\.2\.1; previous revision: 1\.1 -done -Checking in file4; -${CVSROOT_DIRNAME}/first-dir/file4,v <-- file4 -new revision: 1\.1\.2\.1; previous revision: 1\.1 -done -RCS file: ${CVSROOT_DIRNAME}/first-dir/Attic/file5,v -done -Checking in file5; -${CVSROOT_DIRNAME}/first-dir/Attic/file5,v <-- file5 -new revision: 1\.1\.2\.1; previous revision: 1\.1 -done -Checking in file6; -${CVSROOT_DIRNAME}/first-dir/file6,v <-- file6 -new revision: 1\.1\.2\.1; previous revision: 1\.1 -done -Checking in file9; -${CVSROOT_DIRNAME}/first-dir/file9,v <-- file9 -new revision: 1\.1\.2\.1; previous revision: 1\.1 -done" - - # Tag the current revisions on the branch. - dotest join4-11 "${testcvs} -q tag T1 ." \ -'T file3 -T file4 -T file5 -T file6 -T file8 -T file9' - - # Add file1 and file2, modify file9, and remove the other files. - echo 'first branch revision of file1' > file1 - echo 'first branch revision of file2' > file2 - echo 'second branch revision of file9' > file9 - rm file3 file4 file5 file6 - dotest join4-12 "${testcvs} add file1 file2" \ -"${PROG}"' add: scheduling file `file1'\'' for addition on branch `branch'\'' -'"${PROG}"' add: scheduling file `file2'\'' for addition on branch `branch'\'' -'"${PROG}"' add: use .'"${PROG}"' commit. to add these files permanently' - dotest join4-13 "${testcvs} rm file3 file4 file5 file6" \ -"${PROG}"' remove: scheduling `file3'\'' for removal -'"${PROG}"' remove: scheduling `file4'\'' for removal -'"${PROG}"' remove: scheduling `file5'\'' for removal -'"${PROG}"' remove: scheduling `file6'\'' for removal -'"${PROG}"' remove: use .'"${PROG}"' commit. to remove these files permanently' - dotest join4-14 "${testcvs} -q ci -mx ." \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/Attic/file1,v -done -Checking in file1; -${CVSROOT_DIRNAME}/first-dir/Attic/file1,v <-- file1 -new revision: 1\.1\.2\.1; previous revision: 1\.1 -done -RCS file: ${CVSROOT_DIRNAME}/first-dir/Attic/file2,v -done -Checking in file2; -${CVSROOT_DIRNAME}/first-dir/Attic/file2,v <-- file2 -new revision: 1\.1\.2\.1; previous revision: 1\.1 -done -Removing file3; -${CVSROOT_DIRNAME}/first-dir/file3,v <-- file3 -new revision: delete; previous revision: 1\.1\.2\.1 -done -Removing file4; -${CVSROOT_DIRNAME}/first-dir/file4,v <-- file4 -new revision: delete; previous revision: 1\.1\.2\.1 -done -Removing file5; -${CVSROOT_DIRNAME}/first-dir/Attic/file5,v <-- file5 -new revision: delete; previous revision: 1\.1\.2\.1 -done -Removing file6; -${CVSROOT_DIRNAME}/first-dir/file6,v <-- file6 -new revision: delete; previous revision: 1\.1\.2\.1 -done -Checking in file9; -${CVSROOT_DIRNAME}/first-dir/file9,v <-- file9 -new revision: 1\.1\.2\.2; previous revision: 1\.1\.2\.1 -done" - - # Tag the current revisions on the branch. - dotest join4-15 "${testcvs} -q tag T2 ." \ -'T file1 -T file2 -T file8 -T file9' - - # Modify file4 locally, and do an update with a merge. - cd ../../1/first-dir - echo 'third revision of file4' > file4 - dotest join4-18 "$testcvs -q update -jT1 -jT2 ." \ -"U file1 -R file10 -A file2 -$PROG update: file file2 exists, but has been added in revision T2 -$PROG update: scheduling file3 for removal -M file4 -$PROG update: file file4 has been removed in revision T2, but the destination is incompatibly modified -C file4 -R file6 -A file7 -R file8 -R file9 -$PROG update: file file9 does not exist, but is present in revision T2" - - # Verify that the right changes have been scheduled. - dotest_fail join4-19 "${testcvs} -q update" \ -'A file1 -R file10 -A file2 -R file3 -C file4 -R file6 -A file7 -R file8 -R file9' - - cd ../.. - - rm -r 1 2 - rm -rf ${CVSROOT_DIRNAME}/first-dir - ;; - - join5) - # This test verifies that CVS can handle filenames starting with a - # dash (`-') properly. What used to happen was that CVS handled it - # just fine, until it went to pass them as arguments to the diff - # library, at which point it neglected to pass `--' before the file - # list, causing the diff library to attempt to interpret the file - # name as an argument. - mkdir join5; cd join5 - mkdir 1; cd 1 - dotest join5-init-1 "${testcvs} -Q co -l ." - mkdir join5 - dotest join5-init-2 "${testcvs} -Q add join5" - cd join5 - echo "there once was a file from harrisburg" >-file - echo "who's existance it seems was quiteabsurd" >>-file - dotest join5-init-3 "${testcvs} -Q add -- -file" - dotest join5-init-4 "${testcvs} -q ci -minitial" \ -"RCS file: ${CVSROOT_DIRNAME}/join5/-file,v -done -Checking in -file; -${CVSROOT_DIRNAME}/join5/-file,v <-- -file -initial revision: 1\.1 -done" - cd ../.. - - mkdir 2; cd 2 - dotest join5-init-5 "${testcvs} -Q co join5" - cd join5 - echo "it tested for free" >>-file - echo "when paid it should be" >>-file - dotest join5-init-4 "${testcvs} -q ci -msecond" \ -"Checking in -file; -${CVSROOT_DIRNAME}/join5/-file,v <-- -file -new revision: 1\.2; previous revision: 1\.1 -done" - cd ../.. - - cd 1/join5 - echo "but maybe it could charge bytheword" >>-file - # This is the test that used to spew complaints from diff3: - dotest join5 "${testcvs} up" \ -"${PROG} update: Updating \. -RCS file: ${CVSROOT_DIRNAME}/join5/-file,v -retrieving revision 1\.1 -retrieving revision 1\.2 -Merging differences between 1\.1 and 1\.2 into -file -rcsmerge: warning: conflicts during merge -${PROG} update: conflicts found in -file -C -file" - cd ../.. - - if $keep; then - echo Keeping ${TESTDIR} and exiting due to --keep - exit 0 - fi - - cd .. - rm -r join5 - rm -rf ${CVSROOT_DIRNAME}/join5 - ;; - - join6) - mkdir join6; cd join6 - mkdir 1; cd 1 - dotest join6-init-1 "${testcvs} -Q co -l ." - mkdir join6 - dotest join6-init-2 "${testcvs} -Q add join6" - cd join6 - echo aaa >temp.txt - echo bbb >>temp.txt - echo ccc >>temp.txt - dotest join6-1 "${testcvs} -Q add temp.txt" - dotest join6-2 "${testcvs} -q commit -minitial temp.txt" \ -"RCS file: ${CVSROOT_DIRNAME}/join6/temp\.txt,v -done -Checking in temp\.txt; -${CVSROOT_DIRNAME}/join6/temp.txt,v <-- temp\.txt -initial revision: 1\.1 -done" - cp temp.txt temp2.txt - echo ddd >>temp.txt - dotest join6-3 "${testcvs} -q commit -madd temp.txt" \ -"Checking in temp\.txt; -${CVSROOT_DIRNAME}/join6/temp.txt,v <-- temp\.txt -new revision: 1\.2; previous revision: 1\.1 -done" - - # The case where the merge target is up-to-date and its base revision - # matches the second argument to -j: CVS doesn't bother attempting - # the merge since it already knows that the target contains the - # change. - dotest join6-3.3 "${testcvs} update -j1.1 -j1.2 temp.txt" \ -"temp\.txt already contains the differences between 1\.1 and 1\.2" - dotest join6-3.4 "${testcvs} diff temp.txt" "" - - # The case where the merge target is modified but already contains - # the change. - echo bbb >temp.txt - echo ccc >>temp.txt - echo ddd >>temp.txt - dotest join6-3.5 "${testcvs} update -j1.1 -j1.2 temp.txt" \ -"M temp\.txt -RCS file: ${CVSROOT_DIRNAME}/join6/temp\.txt,v -retrieving revision 1\.1 -retrieving revision 1\.2 -Merging differences between 1\.1 and 1\.2 into temp\.txt -temp\.txt already contains the differences between 1\.1 and 1\.2" - dotest_fail join6-3.6 "${testcvs} diff temp.txt" \ -"Index: temp\.txt -=================================================================== -RCS file: ${CVSROOT_DIRNAME}/join6/temp\.txt,v -retrieving revision 1\.2 -diff -r1\.2 temp.txt -1d0 -< aaa" - - cp temp2.txt temp.txt - dotest_fail join6-4 "${testcvs} diff temp.txt" \ -"Index: temp.txt -=================================================================== -RCS file: ${CVSROOT_DIRNAME}/join6/temp\.txt,v -retrieving revision 1\.2 -diff -r1\.2 temp\.txt -4d3 -< ddd" - - dotest join6-5 "${testcvs} update -j1.1 -j1.2 temp.txt" \ -"M temp\.txt -RCS file: ${CVSROOT_DIRNAME}/join6/temp\.txt,v -retrieving revision 1\.1 -retrieving revision 1\.2 -Merging differences between 1\.1 and 1\.2 into temp\.txt" - dotest join6-6 "${testcvs} diff temp.txt" "" - mv temp.txt temp3.txt - dotest join6-7 "sed 's/ddd/dddd/' < temp3.txt > temp.txt" "" - dotest join6-8 "${testcvs} update -j1.1 -j1.2 temp.txt" \ -"M temp\.txt -RCS file: ${CVSROOT_DIRNAME}/join6/temp\.txt,v -retrieving revision 1\.1 -retrieving revision 1\.2 -Merging differences between 1\.1 and 1\.2 into temp\.txt -rcsmerge: warning: conflicts during merge" - dotest_fail join6-9 "${testcvs} diff temp.txt" \ -"Index: temp\.txt -=================================================================== -RCS file: ${CVSROOT_DIRNAME}/join6/temp.txt,v -retrieving revision 1\.2 -diff -r1\.2 temp\.txt -3a4,6 -> <<<<<<< temp\.txt -> dddd -> ======= -4a8 -> >>>>>>> 1\.2" - cp temp2.txt temp.txt - dotest join6-10 "${testcvs} -q ci -m del temp.txt" \ -"Checking in temp\.txt; -${CVSROOT_DIRNAME}/join6/temp.txt,v <-- temp\.txt -new revision: 1\.3; previous revision: 1\.2 -done" - cp temp3.txt temp.txt - dotest_fail join6-11 "${testcvs} diff temp.txt" \ -"Index: temp\.txt -=================================================================== -RCS file: ${CVSROOT_DIRNAME}/join6/temp.txt,v -retrieving revision 1\.3 -diff -r1\.3 temp\.txt -3a4 -> ddd" - dotest join6-12 "${testcvs} update -j1.2 -j1.3 temp.txt" \ -"M temp\.txt -RCS file: ${CVSROOT_DIRNAME}/join6/temp\.txt,v -retrieving revision 1\.2 -retrieving revision 1\.3 -Merging differences between 1\.2 and 1\.3 into temp\.txt" - dotest join6-13 "${testcvs} diff temp.txt" "" - - # The case where the merge target wasn't created until after the - # first tag was applied - rm temp2.txt temp3.txt - dotest join6-20 "${testcvs} -q tag -r1.1 t1" \ -"T temp.txt" - echo xxx >temp2.txt - dotest join6-21 "${testcvs} -Q add temp2.txt" - dotest join6-22 "${testcvs} -q ci -m." \ -"RCS file: ${CVSROOT_DIRNAME}/join6/temp2.txt,v -done -Checking in temp2\.txt; -${CVSROOT_DIRNAME}/join6/temp2\.txt,v <-- temp2\.txt -initial revision: 1\.1 -done" - dotest join6-23 "${testcvs} -q tag t2" \ -"T temp.txt -T temp2.txt" - echo xxx >>temp.txt - dotest join6-24 "${testcvs} -q ci -m." \ -"Checking in temp\.txt; -${CVSROOT_DIRNAME}/join6/temp.txt,v <-- temp\.txt -new revision: 1\.4; previous revision: 1\.3 -done" - dotest join6-25 "${testcvs} -q up -jt1 -jt2" \ -"RCS file: ${CVSROOT_DIRNAME}/join6/temp.txt,v -retrieving revision 1\.1 -retrieving revision 1\.3 -Merging differences between 1\.1 and 1\.3 into temp.txt -temp.txt already contains the differences between 1\.1 and 1\.3 -temp2.txt already contains the differences between creation and 1\.1" - - # Now for my next trick: delete the file, recreate it, and - # try to merge - dotest join6-30 "${testcvs} -q rm -f temp2.txt" \ -"${PROG} remove: use .${PROG} commit. to remove this file permanently" - dotest join6-31 "${testcvs} -q ci -m. temp2.txt" \ -"Removing temp2\.txt; -${CVSROOT_DIRNAME}/join6/temp2\.txt,v <-- temp2\.txt -new revision: delete; previous revision: 1\.1 -done" - echo new >temp2.txt - # FIXCVS: Local and remote really shouldn't be different and there - # really shouldn't be two different status lines for temp2.txt - if $remote; then - dotest_fail join6-32 "${testcvs} -q up -jt1 -jt2" \ -"? temp2\.txt -RCS file: ${CVSROOT_DIRNAME}/join6/temp.txt,v -retrieving revision 1\.1 -retrieving revision 1\.3 -Merging differences between 1\.1 and 1\.3 into temp.txt -temp.txt already contains the differences between 1\.1 and 1\.3 -${PROG} update: move away \./temp2\.txt; it is in the way -C temp2\.txt" - else - dotest join6-32 "${testcvs} -q up -jt1 -jt2" \ -"RCS file: ${CVSROOT_DIRNAME}/join6/temp.txt,v -retrieving revision 1\.1 -retrieving revision 1\.3 -Merging differences between 1\.1 and 1\.3 into temp.txt -temp.txt already contains the differences between 1\.1 and 1\.3 -${PROG} update: use .${PROG} add. to create an entry for temp2\.txt -U temp2\.txt -? temp2\.txt" - fi - - cd ../../.. - - if $keep; then - echo Keeping ${TESTDIR} and exiting due to --keep - exit 0 - fi - - rm -r join6 - rm -rf ${CVSROOT_DIRNAME}/join6 - ;; - - join7) - # This test deals with joins that happen with the -n switch - mkdir join7; cd join7 - mkdir impdir; cd impdir - echo aaa >temp.txt - echo bbb >>temp.txt - echo ccc >>temp.txt - dotest join7-1 \ -"${testcvs} -Q import -minitial join7 vendor vers-1" \ -"" - cd .. - dotest join7-2 "${testcvs} -Q co join7" "" - cd join7 - echo ddd >> temp.txt - dotest join7-3 "${testcvs} -Q ci -madded-line temp.txt" \ -"Checking in temp.txt; -$CVSROOT_DIRNAME/join7/temp.txt,v <-- temp.txt -new revision: 1\.2; previous revision: 1\.1 -done" - cd ../impdir - echo aaaa >temp.txt - echo bbbb >>temp.txt - echo ccc >>temp.txt - echo eee >>temp.txt - dotest join7-4 \ -"${testcvs} -Q import -minitial join7 vendor vers-2" \ -"" - cd ../join7 - dotest join7-5 \ -"${testcvs} -n update -jvers-1 -jvers-2 temp.txt" \ -"RCS file: $CVSROOT_DIRNAME/join7/temp.txt,v -retrieving revision 1\.1\.1\.1 -retrieving revision 1\.1\.1\.2 -Merging differences between 1\.1\.1\.1 and 1\.1\.1\.2 into temp.txt -rcsmerge: warning: conflicts during merge" - touch temp.txt - dotest join7-6 "${testcvs} -n update -jvers-1 -jvers-2 temp.txt" \ -"RCS file: $CVSROOT_DIRNAME/join7/temp.txt,v -retrieving revision 1\.1\.1\.1 -retrieving revision 1\.1\.1\.2 -Merging differences between 1\.1\.1\.1 and 1\.1\.1\.2 into temp.txt -rcsmerge: warning: conflicts during merge" \ -"RCS file: $CVSROOT_DIRNAME/join7/temp.txt,v -retrieving revision 1\.1\.1\.1 -retrieving revision 1\.1\.1\.2 -Merging differences between 1\.1\.1\.1 and 1\.1\.1\.2 into temp.txt -rcsmerge: warning: conflicts during merge" - - if $keep; then - echo Keeping ${TESTDIR} and exiting due to --keep - exit 0 - fi - - cd ../.. - rm -r join7 - rm -rf $CVSROOT_DIRNAME/join7 - ;; - - - - join8) - # In this test case, we have 2 projects, one called "pvcs" and one - # called "project". The "pvcs" project has modified the file, while - # the "project" project has caused a deletion. When "project" is - # merged into "pvcs", we expect CVS to detect a conflict. - mkdir join8; cd join8 - mkdir combine - mkdir base - mkdir pvcs - mkdir project - - echo "aaa" >base/file.txt - echo "bbb" >pvcs/file.txt - echo "ccc" >project/xxx.txt - - cd base - dotest join8-1 \ -"$testcvs import -b 1.1.101 -ko -m 'base import' join8 base base-1" \ -"N join8/file\.txt - -No conflicts created by this import" - - cd ../pvcs - dotest join8-2 \ -"$testcvs import -b 1.1.201 -ko -m 'pvcs import' join8 pvcs pvcs-1" \ -"C join8/file\.txt - -1 conflicts created by this import. -Use the following command to help the merge: - - $PROG checkout -j -jpvcs-1 join8" - - cd ../project - dotest join8-3 \ -"$testcvs import -b 1.1.301 -ko -m 'project import' join8 project project-1" \ -"N join8/xxx\.txt - -No conflicts created by this import" - - cd .. - dotest join8-4 \ -"$testcvs checkout -r pvcs-1 -j base-1 -j project-1 -d combine join8" \ -"$PROG checkout: Updating combine -U combine/file\.txt -$PROG checkout: file combine/file\.txt has been removed in revision project-1, but the destination is incompatibly modified -C combine/file.txt -U combine/xxx\.txt" - - dotest join8-5 \ -"$testcvs -Q up -pr base-1 combine/file.txt >combine/file.txt" - - dotest join8-6 \ -"$testcvs up -j base-1 -j project-1 combine" \ -"$PROG update: Updating combine -M combine/file\.txt -$PROG update: scheduling combine/file\.txt for removal -A combine/xxx\.txt -$PROG update: file combine/xxx\.txt exists, but has been added in revision project-1" - cd .. - - if $keep; then - echo Keeping $TESTDIR and exiting due to --keep - exit 0 - fi - - rm -r join8 - rm -rf $CVSROOT_DIRNAME/join8 - ;; - - - - join9) - # In this test case, we have 2 projects, one called "pvcs" and one - # called "project". The "pvcs" project has not modified the file, - # while the "project" project has caused a deletion. When "project" - # is merged into "pvcs", we expect CVS to remove the file without - # fuss, as there is no conflict. - mkdir join9; cd join9 - mkdir combine - mkdir base - mkdir pvcs - mkdir project - - echo "aaa" >base/file.txt - echo "aaa" >pvcs/file.txt - echo "ccc" >project/xxx.txt - - cd base - dotest join9-1 \ -"$testcvs import -b 1.1.101 -ko -m 'base import' join9 base base-1" \ -"N join9/file\.txt - -No conflicts created by this import" - - cd ../pvcs - dotest join9-2 \ -"$testcvs import -b 1.1.201 -ko -m 'pvcs import' join9 pvcs pvcs-1" \ -"C join9/file\.txt - -1 conflicts created by this import. -Use the following command to help the merge: - - $PROG checkout -j -jpvcs-1 join9" - - cd ../project - dotest join9-3 \ -"$testcvs import -b 1.1.301 -ko -m 'project import' join9 project project-1" \ -"N join9/xxx\.txt - -No conflicts created by this import" - - cd .. - dotest join9-4 \ -"$testcvs checkout -r pvcs-1 -j base-1 -j project-1 -d combine join9" \ -"$PROG checkout: Updating combine -U combine/file\.txt -$PROG checkout: scheduling combine/file\.txt for removal -U combine/xxx\.txt" - - cd .. - - if $keep; then - echo Keeping $TESTDIR and exiting due to --keep - exit 0 - fi - - rm -r join9 - rm -rf $CVSROOT_DIRNAME/join9 - ;; - - - - join-readonly-conflict) - # Previously, only tests 1 & 11 were being tested. I added the - # intermediate dotest's to try and diagnose a different failure - # - # Demonstrate that cvs-1.9.29 can fail on 2nd and subsequent - # conflict-evoking join attempts. - # Even with that version of CVS, This test failed only in - # client-server mode, and would have been noticed in normal - # operation only for files that were read-only (either due to - # use of cvs' global -r option, setting the CVSREAD envvar, - # or use of watch lists). - mkdir join-readonly-conflict; cd join-readonly-conflict - dotest join-readonly-conflict-1 "$testcvs -q co -l ." '' - module=join-readonly-conflict - mkdir $module - $testcvs -q add $module >>$LOGFILE 2>&1 - cd $module - - file=m - echo trunk > $file - dotest join-readonly-conflict-2 "$testcvs -Q add $file" '' - - dotest join-readonly-conflict-3 "$testcvs -q ci -m . $file" \ -"RCS file: $CVSROOT_DIRNAME/$module/$file,v -done -Checking in $file; -$CVSROOT_DIRNAME/$module/$file,v <-- $file -initial revision: 1\.1 -done" - - dotest join-readonly-conflict-4 "$testcvs tag -b B $file" "T $file" - dotest join-readonly-conflict-5 "$testcvs -q update -rB $file" \ -"[UP] $file" - echo branch B > $file - dotest join-readonly-conflict-6 "$testcvs -q ci -m . $file" \ -"Checking in $file; -$CVSROOT_DIRNAME/$module/$file,v <-- $file -new revision: 1\.1\.2\.1; previous revision: 1\.1 -done" - - rm $file - dotest join-readonly-conflict-7 "$testcvs -Q update -A $file" '' - # Make sure $file is read-only. This can happen more realistically - # via patch -- which could be used to apply a delta, yet would - # preserve a file's read-only permissions. - echo conflict > $file; chmod u-w $file - dotest join-readonly-conflict-8 "$testcvs update -r B $file" \ -"RCS file: $CVSROOT_DIRNAME/$module/$file,v -retrieving revision 1\.1 -retrieving revision 1\.1\.2\.1 -Merging differences between 1\.1 and 1\.1\.2\.1 into $file -rcsmerge: warning: conflicts during merge -${PROG} update: conflicts found in $file -C $file" - - # restore to the trunk - rm -f $file - dotest join-readonly-conflict-9 "$testcvs -Q update -A $file" '' - - # This one would fail because cvs couldn't open the existing - # (and read-only) .# file for writing. - echo conflict > $file - - # verify that the backup file is not writable - if test -w ".#$file.1.1"; then - fail "join-readonly-conflict-10 : .#$file.1.1 is writable" - else - pass "join-readonly-conflict-10" - fi - dotest join-readonly-conflict-11 "$testcvs update -r B $file" \ -"RCS file: $CVSROOT_DIRNAME/$module/$file,v -retrieving revision 1\.1 -retrieving revision 1\.1\.2\.1 -Merging differences between 1\.1 and 1\.1\.2\.1 into $file -rcsmerge: warning: conflicts during merge -${PROG} update: conflicts found in $file -C m" - - cd ../.. - if $keep; then :; else - rm -rf join-readonly-conflict - rm -rf $CVSROOT_DIRNAME/$module - fi - ;; - - join-admin) - mkdir 1; cd 1 - dotest join-admin-1 "$testcvs -q co -l ." '' - module=x - mkdir $module - $testcvs -q add $module >>$LOGFILE 2>&1 - cd $module - - # Create a file so applying the first tag works. - echo foo > a - $testcvs -Q add a > /dev/null 2>&1 - $testcvs -Q ci -m. a > /dev/null 2>&1 - - $testcvs -Q tag -b B - $testcvs -Q tag -b M1 - echo '$''Id$' > b - $testcvs -Q add b > /dev/null 2>&1 - $testcvs -Q ci -m. b > /dev/null 2>&1 - $testcvs -Q tag -b M2 - - $testcvs -Q update -r B - $testcvs -Q update -kk -jM1 -jM2 - $testcvs -Q ci -m. b >/dev/null 2>&1 - - $testcvs -Q update -A - - # Verify that the -kk flag from the update did not - # propagate to the repository. - dotest join-admin-1 "$testcvs status b" \ -"=================================================================== -File: b Status: Up-to-date - - Working revision: 1\.1.* - Repository revision: 1\.1 ${CVSROOT_DIRNAME}/x/b,v - Sticky Tag: (none) - Sticky Date: (none) - Sticky Options: (none)" - - cd ../.. - rm -rf 1 - rm -rf ${CVSROOT_DIRNAME}/$module - ;; - - join-admin-2) - # Show that when a merge (via update -kk -jtag1 -jtag2) first - # removes a file, then modifies another containing an $Id...$ line, - # the resulting file contains the unexpanded `$Id.$' string, as - # -kk requires. - mkdir 1; cd 1 - dotest join-admin-2-1 "$testcvs -q co -l ." '' - module=x - mkdir $module - dotest join-admin-2-2 "$testcvs -q add $module" \ -"Directory ${CVSROOT_DIRNAME}/x added to the repository" - cd $module - - # Create a file so applying the first tag works. - echo '$''Id$' > e0 - cp e0 e - dotest join-admin-2-3 "$testcvs -Q add e" '' - dotest join-admin-2-4 "$testcvs -Q ci -m. e" \ -"RCS file: ${CVSROOT_DIRNAME}/x/e,v -done -Checking in e; -${CVSROOT_DIRNAME}/x/e,v <-- e -initial revision: 1\.1 -done" - - dotest join-admin-2-5 "$testcvs -Q tag -b T" '' "${QUESTION} e0" - dotest join-admin-2-6 "$testcvs -Q update -r T" '' "${QUESTION} e0" - cp e0 e - dotest join-admin-2-7 "$testcvs -Q ci -m. e" \ -"Checking in e; -${CVSROOT_DIRNAME}/x/e,v <-- e -new revision: 1\.1\.2\.1; previous revision: 1\.1 -done" - - dotest join-admin-2-8 "$testcvs -Q update -A" '' "${QUESTION} e0" - dotest join-admin-2-9 "$testcvs -Q tag -b M1" '' "${QUESTION} e0" - - echo '$''Id$' > b - dotest join-admin-2-10 "$testcvs -Q add b" '' - cp e0 e - dotest join-admin-2-11 "$testcvs -Q ci -m. b e" \ -"RCS file: ${CVSROOT_DIRNAME}/x/b,v -done -Checking in b; -${CVSROOT_DIRNAME}/x/b,v <-- b -initial revision: 1\.1 -done -Checking in e; -${CVSROOT_DIRNAME}/x/e,v <-- e -new revision: 1\.2; previous revision: 1\.1 -done" - - dotest join-admin-2-12 "$testcvs -Q tag -b M2" '' "${QUESTION} e0" - - dotest join-admin-2-13 "$testcvs -Q update -r T" '' "${QUESTION} e0" - dotest join-admin-2-14 "$testcvs update -kk -jM1 -jM2" \ -"${PROG} update: Updating . -U b -U e -RCS file: ${CVSROOT_DIRNAME}/x/e,v -retrieving revision 1\.1 -retrieving revision 1\.2 -Merging differences between 1\.1 and 1\.2 into e -e already contains the differences between 1\.1 and 1\.2 -${QUESTION} e0" \ -"${QUESTION} e0 -${PROG} update: Updating . -U b -U e -RCS file: ${CVSROOT_DIRNAME}/x/e,v -retrieving revision 1\.1 -retrieving revision 1\.2 -Merging differences between 1\.1 and 1\.2 into e -e already contains the differences between 1\.1 and 1\.2" - - # Verify that the $Id.$ string is not expanded. - dotest join-admin-2-15 "cat e" '$''Id$' - - cd ../.. - rm -rf 1 - rm -rf ${CVSROOT_DIRNAME}/$module - ;; - - join-rm) - # This first half of this test checks that a single-argument merge - # from a branch is capable of removing files. - # - # The second half verifies that an update to another location with an - # uncommitted removal will transfer the destination branch of the - # removal. - - module=join-rm - mkdir $module; cd $module - - dotest join-rm-init-1 "$testcvs -q co -l ." '' - mkdir $module - dotest join-rm-init-2 "$testcvs -q add $module" \ -"Directory $CVSROOT_DIRNAME/$module added to the repository" - cd $module - - # add some files. - touch a b c d e f g - dotest join-rm-init-3 "$testcvs -Q add a b c d e f g" - dotest join-rm-init-4 "$testcvs -Q ci -m add-em" \ -"RCS file: $CVSROOT_DIRNAME/join-rm/a,v -done -Checking in a; -$CVSROOT_DIRNAME/join-rm/a,v <-- a -initial revision: 1\.1 -done -RCS file: $CVSROOT_DIRNAME/join-rm/b,v -done -Checking in b; -$CVSROOT_DIRNAME/join-rm/b,v <-- b -initial revision: 1\.1 -done -RCS file: $CVSROOT_DIRNAME/join-rm/c,v -done -Checking in c; -$CVSROOT_DIRNAME/join-rm/c,v <-- c -initial revision: 1\.1 -done -RCS file: $CVSROOT_DIRNAME/join-rm/d,v -done -Checking in d; -$CVSROOT_DIRNAME/join-rm/d,v <-- d -initial revision: 1\.1 -done -RCS file: $CVSROOT_DIRNAME/join-rm/e,v -done -Checking in e; -$CVSROOT_DIRNAME/join-rm/e,v <-- e -initial revision: 1\.1 -done -RCS file: $CVSROOT_DIRNAME/join-rm/f,v -done -Checking in f; -$CVSROOT_DIRNAME/join-rm/f,v <-- f -initial revision: 1\.1 -done -RCS file: $CVSROOT_DIRNAME/join-rm/g,v -done -Checking in g; -$CVSROOT_DIRNAME/join-rm/g,v <-- g -initial revision: 1\.1 -done" - - # create the branch and update to it - dotest join-rm-init-5 "$testcvs -Q tag -b br" - dotest join-rm-init-6 "$testcvs -Q up -rbr" - - # remove a few files from the branch - dotest join-rm-init-7 "$testcvs -Q rm -f b d g" - dotest join-rm-init-8 "$testcvs -Q ci -mrm" \ -"Removing b; -$CVSROOT_DIRNAME/join-rm/b,v <-- b -new revision: delete; previous revision: 1\.1 -done -Removing d; -$CVSROOT_DIRNAME/join-rm/d,v <-- d -new revision: delete; previous revision: 1\.1 -done -Removing g; -$CVSROOT_DIRNAME/join-rm/g,v <-- g -new revision: delete; previous revision: 1\.1 -done" - - # update to the trunk - dotest join-rm-init-9 "$testcvs -Q up -A" - - # now for the test - try and merge the removals. - dotest join-rm-1 "$testcvs -q up -jbr" \ -"$PROG update: scheduling b for removal -$PROG update: scheduling d for removal -$PROG update: scheduling g for removal" - - # And make sure the merge took - dotest join-rm-2 "$testcvs -qn up" \ -"R b -R d -R g" - - dotest join-rm-3 "$testcvs -q ci -m 'save the merge'" \ -"Removing b; -$CVSROOT_DIRNAME/join-rm/b,v <-- b -new revision: delete; previous revision: 1\.1 -done -Removing d; -$CVSROOT_DIRNAME/join-rm/d,v <-- d -new revision: delete; previous revision: 1\.1 -done -Removing g; -$CVSROOT_DIRNAME/join-rm/g,v <-- g -new revision: delete; previous revision: 1\.1 -done" - - # and verify that it was the head revision which was removed. - dotest join-rm-4 "$testcvs -q log b" " -RCS file: $CVSROOT_DIRNAME/join-rm/Attic/b,v -Working file: b -head: 1\.2 -branch: -locks: strict -access list: -symbolic names: - br: 1\.1\.0\.2 -keyword substitution: kv -total revisions: 3; selected revisions: 3 -description: ----------------------------- -revision 1\.2 -date: [0-9/]* [0-9:]*; author: $username; state: dead; lines: ${PLUS}0 -0 -save the merge ----------------------------- -revision 1\.1 -date: [0-9/]* [0-9:]*; author: $username; state: Exp; -branches: 1.1.2; -add-em ----------------------------- -revision 1\.1\.2\.1 -date: [0-9/]* [0-9:]*; author: $username; state: dead; lines: ${PLUS}0 -0 -rm -=============================================================================" - - # go back to the branch to set up for the second set of tests - dotest join-rm-init-10 "$testcvs -Q up -rbr" - dotest join-rm-init-11 "$testcvs -Q rm -f a" - dotest join-rm-init-12 "$testcvs -Q ci -m rma" \ -"Removing a; -$CVSROOT_DIRNAME/join-rm/a,v <-- a -new revision: delete; previous revision: 1\.1 -done" - - # now the test: update to the trunk - # - # FIXCVS: This update should merge the removal to the trunk. It does - # not. - dotest join-rm-5 "$testcvs -q up -A" \ -'U a -U c -U e -U f' - - # and verify that there is no sticky tag - dotest join-rm-6 "$testcvs status a" \ -"=================================================================== -File: a Status: Up-to-date - - Working revision: 1\.1.* - Repository revision: 1\.1 $CVSROOT_DIRNAME/join-rm/a,v - Sticky Tag: (none) - Sticky Date: (none) - Sticky Options: (none)" - - if $keep; then - echo Keeping $TESTDIR and exiting due to --keep - exit 0 - fi - - cd ../.. - rm -rf $CVSROOT_DIRNAME/$module - rm -r $module - ;; - - new) # look for stray "no longer pertinent" messages. - mkdir ${CVSROOT_DIRNAME}/first-dir - - if ${CVS} co first-dir ; then - pass 117 - else - fail 117 - fi - - cd first-dir - touch a - - if ${CVS} add a 2>>${LOGFILE}; then - pass 118 - else - fail 118 - fi - - if ${CVS} ci -m added >>${LOGFILE} 2>&1; then - pass 119 - else - fail 119 - fi - - rm a - - if ${CVS} rm a 2>>${LOGFILE}; then - pass 120 - else - fail 120 - fi - - if ${CVS} ci -m removed >>${LOGFILE} ; then - pass 121 - else - fail 121 - fi - - if ${CVS} update -A 2>&1 | grep longer ; then - fail 122 - else - pass 122 - fi - - if ${CVS} update -rHEAD 2>&1 | grep longer ; then - fail 123 - else - pass 123 - fi - - cd .. - rm -r first-dir - rm -rf ${CVSROOT_DIRNAME}/first-dir - ;; - - newb) - # Test removing a file on a branch and then checking it out. - - # We call this "newb" only because it, like the "new" tests, - # has something to do with "no longer pertinent" messages. - # Not necessarily the most brilliant nomenclature. - - # Create file 'a'. - mkdir ${CVSROOT_DIRNAME}/first-dir - dotest newb-123a "${testcvs} -q co first-dir" '' - cd first-dir - touch a - dotest newb-123b "${testcvs} add a" \ -"${PROG} add: scheduling file .a. for addition -${PROG} add: use .${PROG} commit. to add this file permanently" - dotest newb-123c "${testcvs} -q ci -m added" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/a,v -done -Checking in a; -${CVSROOT_DIRNAME}/first-dir/a,v <-- a -initial revision: 1\.1 -done" - - # Make a branch. - dotest newb-123d "${testcvs} -q tag -b branch" "T a" - - # Check out the branch. - cd .. - rm -r first-dir - mkdir 1 - cd 1 - dotest newb-123e "${testcvs} -q co -r branch first-dir" \ -"U first-dir/a" - - # Remove 'a' on another copy of the branch. - cd .. - mkdir 2 - cd 2 - dotest newb-123f "${testcvs} -q co -r branch first-dir" \ -"U first-dir/a" - cd first-dir - rm a - dotest newb-123g "${testcvs} rm a" \ -"${PROG} remove: scheduling .a. for removal -${PROG} remove: use .${PROG} commit. to remove this file permanently" - dotest newb-123h "${testcvs} -q ci -m removed" \ -"Removing a; -${CVSROOT_DIRNAME}/first-dir/a,v <-- a -new revision: delete; previous revision: 1\.1 -done" - - # Check out the file on the branch. This should report - # that the file is not pertinent, but it should not - # say anything else. - cd .. - rm -r first-dir - dotest newb-123i "${testcvs} -q co -r branch first-dir/a" \ -"${PROG} checkout: warning: first-dir/a is not (any longer) pertinent" - - # Update the other copy, and make sure that a is removed. - cd ../1/first-dir - # "Entry Invalid" is a rather strange output here. Something like - # "Removed in Repository" would make more sense. - dotest newb-123j0 "${testcvs} status a" \ -"${PROG} status: a is no longer in the repository -=================================================================== -File: a Status: Entry Invalid - - Working revision: 1\.1.* - Repository revision: 1\.1\.2\.1 ${CVSROOT_DIRNAME}/first-dir/a,v - Sticky Tag: branch (branch: 1\.1\.2) - Sticky Date: (none) - Sticky Options: (none)" - dotest newb-123j "${testcvs} -q update" \ -"${PROG} update: a is no longer in the repository" - - if test -f a; then - fail newb-123k - else - pass newb-123k - fi - - cd ../.. - rm -r 1 2 - rm -rf ${CVSROOT_DIRNAME}/first-dir - ;; - - conflicts) - mkdir ${CVSROOT_DIRNAME}/first-dir - - mkdir 1 - cd 1 - - dotest conflicts-124 "${testcvs} -q co first-dir" '' - - cd first-dir - touch a - - dotest conflicts-125 "${testcvs} add a" \ -"${PROG} add: scheduling file .a. for addition -${PROG} add: use .${PROG} commit. to add this file permanently" - dotest conflicts-126 "${testcvs} -q ci -m added" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/a,v -done -Checking in a; -${CVSROOT_DIRNAME}/first-dir/a,v <-- a -initial revision: 1\.1 -done" - - cd ../.. - mkdir 2 - cd 2 - - dotest conflicts-126.5 "${testcvs} co -p first-dir" \ -"${PROG} checkout: Updating first-dir -=================================================================== -Checking out first-dir/a -RCS: ${CVSROOT_DIRNAME}/first-dir/a,v -VERS: 1\.1 -\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*" - if ${CVS} co first-dir ; then - pass 127 - else - fail 127 - fi - cd first-dir - if test -f a; then - pass 127a - else - fail 127a - fi - - cd ../../1/first-dir - echo add a line >>a - mkdir dir1 - dotest conflicts-127b "${testcvs} add dir1" \ -"Directory ${CVSROOT_DIRNAME}/first-dir/dir1 added to the repository" - dotest conflicts-128 "${testcvs} -q ci -m changed" \ -"Checking in a; -${CVSROOT_DIRNAME}/first-dir/a,v <-- a -new revision: 1\.2; previous revision: 1\.1 -done" - cd ../.. - - # Similar to conflicts-126.5, but now the file has nonempty - # contents. - mkdir 3 - cd 3 - dotest conflicts-128.5 "${testcvs} co -p -l first-dir" \ -"${PROG} checkout: Updating first-dir -=================================================================== -Checking out first-dir/a -RCS: ${CVSROOT_DIRNAME}/first-dir/a,v -VERS: 1\.2 -\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* -add a line" - cd .. - rmdir 3 - - # Now go over the to the other working directory and - # start testing conflicts - cd 2/first-dir - echo add a conflicting line >>a - dotest_fail conflicts-129 "${testcvs} -q ci -m changed" \ -"${PROG}"' commit: Up-to-date check failed for `a'\'' -'"${PROG}"' \[commit aborted\]: correct above errors first!' - mkdir dir1 - mkdir sdir - dotest conflicts-status-0 "${testcvs} status a" \ -"=================================================================== -File: a Status: Needs Merge - - Working revision: 1\.1.* - Repository revision: 1\.2 ${CVSROOT_DIRNAME}/first-dir/a,v - Sticky Tag: (none) - Sticky Date: (none) - Sticky Options: (none)" - dotest conflicts-129a "${testcvs} -nq update a" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/a,v -retrieving revision 1\.1 -retrieving revision 1\.2 -Merging differences between 1\.1 and 1\.2 into a -rcsmerge: warning: conflicts during merge -${PROG} update: conflicts found in a -C a" - dotest conflicts-130 "${testcvs} -q update" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/a,v -retrieving revision 1\.1 -retrieving revision 1\.2 -Merging differences between 1\.1 and 1\.2 into a -rcsmerge: warning: conflicts during merge -${PROG} update: conflicts found in a -C a -${QUESTION} dir1 -${QUESTION} sdir" \ -"${QUESTION} dir1 -${QUESTION} sdir -RCS file: ${CVSROOT_DIRNAME}/first-dir/a,v -retrieving revision 1\.1 -retrieving revision 1\.2 -Merging differences between 1\.1 and 1\.2 into a -rcsmerge: warning: conflicts during merge -${PROG} update: conflicts found in a -C a" - rmdir dir1 sdir - - dotest conflicts-status-1 "${testcvs} status a" \ -"=================================================================== -File: a Status: Unresolved Conflict - - Working revision: 1\.2.* - Repository revision: 1\.2 ${CVSROOT_DIRNAME}/first-dir/a,v - Sticky Tag: (none) - Sticky Date: (none) - Sticky Options: (none)" - dotest_fail conflicts-131 "${testcvs} -q ci -m try" \ -"${PROG} commit: file .a. had a conflict and has not been modified -${PROG} \[commit aborted\]: correct above errors first!" - - # Try to check in the file with the conflict markers in it. - # Make sure we detect any one of the three conflict markers - mv a aa - grep '^<<<<<<<' aa >a - dotest conflicts-status-2 "${testcvs} -nq ci -m try a" \ -"${PROG} commit: warning: file .a. seems to still contain conflict indicators" - - grep '^=======' aa >a - dotest conflicts-status-3 "${testcvs} -nq ci -m try a" \ -"${PROG} commit: warning: file .a. seems to still contain conflict indicators" - - grep '^>>>>>>>' aa >a - dotest conflicts-status-4 "${testcvs} -qn ci -m try a" \ -"${PROG} commit: warning: file .a. seems to still contain conflict indicators" - - mv aa a - echo lame attempt at resolving it >>a - dotest conflicts-status-5 "${testcvs} status a" \ -"=================================================================== -File: a Status: File had conflicts on merge - - Working revision: 1\.2.* - Repository revision: 1\.2 ${CVSROOT_DIRNAME}/first-dir/a,v - Sticky Tag: (none) - Sticky Date: (none) - Sticky Options: (none)" - dotest conflicts-132 "${testcvs} -q ci -m try" \ -"${PROG} commit: warning: file .a. seems to still contain conflict indicators -Checking in a; -${CVSROOT_DIRNAME}/first-dir/a,v <-- a -new revision: 1\.3; previous revision: 1\.2 -done" - - # OK, the user saw the warning (good user), and now - # resolves it for real. - echo resolve conflict >a - dotest conflicts-status-6 "${testcvs} status a" \ -"=================================================================== -File: a Status: Locally Modified - - Working revision: 1\.3.* - Repository revision: 1\.3 ${CVSROOT_DIRNAME}/first-dir/a,v - Sticky Tag: (none) - Sticky Date: (none) - Sticky Options: (none)" - dotest conflicts-133 "${testcvs} -q ci -m resolved" \ -"Checking in a; -${CVSROOT_DIRNAME}/first-dir/a,v <-- a -new revision: 1\.4; previous revision: 1\.3 -done" - dotest conflicts-status-7 "${testcvs} status a" \ -"=================================================================== -File: a Status: Up-to-date - - Working revision: 1\.4.* - Repository revision: 1\.4 ${CVSROOT_DIRNAME}/first-dir/a,v - Sticky Tag: (none) - Sticky Date: (none) - Sticky Options: (none)" - - # Now test that we can add a file in one working directory - # and have an update in another get it. - cd ../../1/first-dir - echo abc >abc - if ${testcvs} add abc >>${LOGFILE} 2>&1; then - pass 134 - else - fail 134 - fi - if ${testcvs} ci -m 'add abc' abc >>${LOGFILE} 2>&1; then - pass 135 - else - fail 135 - fi - cd ../../2 - mkdir first-dir/dir1 first-dir/sdir - dotest conflicts-136 "${testcvs} -q update first-dir" \ -'[UP] first-dir/abc -'"${QUESTION}"' first-dir/dir1 -'"${QUESTION}"' first-dir/sdir' \ -''"${QUESTION}"' first-dir/dir1 -'"${QUESTION}"' first-dir/sdir -[UP] first-dir/abc' - dotest conflicts-137 'test -f first-dir/abc' '' - rmdir first-dir/dir1 first-dir/sdir - - # Now test something similar, but in which the parent directory - # (not the directory in question) has the Entries.Static flag - # set. - cd ../1/first-dir - mkdir subdir - if ${testcvs} add subdir >>${LOGFILE}; then - pass 138 - else - fail 138 - fi - cd ../.. - mkdir 3 - cd 3 - if ${testcvs} -q co first-dir/abc first-dir/subdir \ - >>${LOGFILE}; then - pass 139 - else - fail 139 - fi - cd ../1/first-dir/subdir - echo sss >sss - if ${testcvs} add sss >>${LOGFILE} 2>&1; then - pass 140 - else - fail 140 - fi - if ${testcvs} ci -m adding sss >>${LOGFILE} 2>&1; then - pass 140 - else - fail 140 - fi - cd ../../../3/first-dir - if ${testcvs} -q update >>${LOGFILE}; then - pass 141 - else - fail 141 - fi - if test -f subdir/sss; then - pass 142 - else - fail 142 - fi - cd ../.. - rm -r 1 2 3 ; rm -rf ${CVSROOT_DIRNAME}/first-dir - ;; - - conflicts2) - # More conflicts tests; separate from conflicts to keep each - # test a manageable size. - mkdir ${CVSROOT_DIRNAME}/first-dir - - mkdir 1 - cd 1 - - dotest conflicts2-142a1 "${testcvs} -q co first-dir" '' - - cd first-dir - touch a abc - - dotest conflicts2-142a2 "${testcvs} add a abc" \ -"${PROG} add: scheduling file .a. for addition -${PROG} add: scheduling file .abc. for addition -${PROG} add: use .${PROG} commit. to add these files permanently" - dotest conflicts2-142a3 "${testcvs} -q ci -m added" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/a,v -done -Checking in a; -${CVSROOT_DIRNAME}/first-dir/a,v <-- a -initial revision: 1\.1 -done -RCS file: ${CVSROOT_DIRNAME}/first-dir/abc,v -done -Checking in abc; -${CVSROOT_DIRNAME}/first-dir/abc,v <-- abc -initial revision: 1\.1 -done" - - cd ../.. - mkdir 2 - cd 2 - - dotest conflicts2-142a4 "${testcvs} -q co first-dir" 'U first-dir/a -U first-dir/abc' - cd .. - - # BEGIN TESTS USING THE FILE A - # FIXME: would be cleaner to separate them out into their own - # tests; conflicts2 is getting long. - # Now test that if one person modifies and commits a - # file and a second person removes it, it is a - # conflict - cd 1/first-dir - echo modify a >>a - dotest conflicts2-142b2 "${testcvs} -q ci -m modify-a" \ -"Checking in a; -${CVSROOT_DIRNAME}/first-dir/a,v <-- a -new revision: 1\.2; previous revision: 1\.1 -done" - cd ../../2/first-dir - rm a - dotest conflicts2-142b3 "${testcvs} rm a" \ -"${PROG} remove: scheduling .a. for removal -${PROG} remove: use .${PROG} commit. to remove this file permanently" - dotest_fail conflicts2-142b4 "${testcvs} -q update" \ -"${PROG} update: conflict: removed a was modified by second party -C a" - # Resolve the conflict by deciding not to remove the file - # after all. - dotest_sort conflicts2-142b5 "${testcvs} add a" "U a -${PROG} add: a, version 1\.1, resurrected" - dotest conflicts2-142b5b1 "$testcvs status a" \ -"=================================================================== -File: a Status: Needs Patch - - Working revision: 1\.1.* - Repository revision: 1\.2 $CVSROOT_DIRNAME/first-dir/a,v - Sticky Tag: (none) - Sticky Date: (none) - Sticky Options: (none)" - dotest conflicts2-142b6 "${testcvs} -q update" 'U a' - - # Now one level up. - cd .. - dotest conflicts2-142b7 "${testcvs} rm -f first-dir/a" \ -"${PROG} remove: scheduling .first-dir/a. for removal -${PROG} remove: use .${PROG} commit. to remove this file permanently" - - if $remote; then - # Haven't investigated this one. - dotest_fail conflicts2-142b8r "$testcvs add first-dir/a" \ -"${PROG} add: in directory \.: -${PROG} \[add aborted\]: there is no version here; do '${PROG} checkout' first" - cd first-dir - else - dotest conflicts2-142b8 "${testcvs} add first-dir/a" \ -"U first-dir/a -${PROG} add: first-dir/a, version 1\.2, resurrected" - cd first-dir - # Now recover from the damage that the 142b8 test did. - dotest conflicts2-142b9 "${testcvs} rm -f a" \ -"${PROG} remove: scheduling .a. for removal -${PROG} remove: use .${PROG} commit. to remove this file permanently" - fi - - dotest_sort conflicts2-142b10 "${testcvs} add a" "U a -${PROG} add: a, version 1\.2, resurrected" - # As with conflicts2-142b6, check that things are normal again. - dotest conflicts2-142b11 "${testcvs} -q update" '' - cd ../.. - # END TESTS USING THE FILE A - - # Now test that if one person removes a file and - # commits it, and a second person removes it, is it - # not a conflict. - cd 1/first-dir - rm abc - dotest conflicts2-142c0 "${testcvs} rm abc" \ -"${PROG} remove: scheduling .abc. for removal -${PROG} remove: use .${PROG} commit. to remove this file permanently" - dotest conflicts2-142c1 "${testcvs} -q ci -m remove-abc" \ -"Removing abc; -${CVSROOT_DIRNAME}/first-dir/abc,v <-- abc -new revision: delete; previous revision: 1\.1 -done" - cd ../../2/first-dir - rm abc - dotest conflicts2-142c2 "${testcvs} rm abc" \ -"${PROG} remove: scheduling .abc. for removal -${PROG} remove: use .${PROG} commit. to remove this file permanently" - dotest conflicts2-142c3 "${testcvs} update" \ -"${PROG} update: Updating \." - cd ../.. - - # conflicts2-142d*: test that if one party adds a file, and another - # party has a file of the same name, cvs notices - cd 1/first-dir - touch aa.c - echo 'contents unchanged' >same.c - dotest conflicts2-142d0 "${testcvs} add aa.c same.c" \ -"${PROG} add: scheduling file .aa\.c. for addition -${PROG} add: scheduling file .same\.c. for addition -${PROG} add: use .${PROG} commit. to add these files permanently" - dotest conflicts2-142d1 "${testcvs} -q ci -m added" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/aa\.c,v -done -Checking in aa\.c; -${CVSROOT_DIRNAME}/first-dir/aa\.c,v <-- aa\.c -initial revision: 1\.1 -done -RCS file: ${CVSROOT_DIRNAME}/first-dir/same\.c,v -done -Checking in same\.c; -${CVSROOT_DIRNAME}/first-dir/same\.c,v <-- same\.c -initial revision: 1\.1 -done" - cd ../../2/first-dir - echo "don't you dare obliterate this text" >aa.c - echo 'contents unchanged' >same.c - # Note the discrepancy between local and remote in the handling - # of same.c. I kind - # of suspect that the local CVS behavior is the more useful one - # although I do sort of wonder whether we should make people run - # cvs add just to get them in that habit (also, trying to implement - # the local CVS behavior for remote without the cvs add seems - # pretty difficult). - if $remote; then - dotest_fail conflicts2-142d2 "${testcvs} -q update" \ -"${QUESTION} aa\.c -${QUESTION} same\.c -${PROG} update: move away \./aa\.c; it is in the way -C aa\.c -${PROG} update: move away \./same\.c; it is in the way -C same\.c" - else - dotest_fail conflicts2-142d2 "${testcvs} -q update" \ -"${PROG} [a-z]*: move away aa\.c; it is in the way -C aa\.c -U same\.c" - fi - dotest conflicts2-142d3 "${testcvs} -q status aa.c" \ -"${PROG} status: move away aa\.c; it is in the way -=================================================================== -File: aa\.c Status: Unresolved Conflict - - Working revision: No entry for aa\.c - Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/aa\.c,v" - - # Could also be testing the case in which the cvs add happened - # before the commit by the other user. - # This message seems somewhat bogus. I mean, parallel development - # means that we get to work in parallel if we choose, right? And - # then at commit time it would be a conflict. - dotest_fail conflicts2-142d4 "${testcvs} -q add aa.c" \ -"${PROG} add: aa.c added independently by second party" - - # The user might want to see just what the conflict is. - # Don't bother, diff seems to kind of lose its mind, with or - # without -N. This is a CVS bug(s). - #dotest conflicts2-142d5 "${testcvs} -q diff -r HEAD -N aa.c" fixme - - # Now: "how can the user resolve this conflict", I hear you cry. - # Well, one way is to forget about the file in the working - # directory. - # Since it didn't let us do the add in conflicts2-142d4, there - # is no need to run cvs rm here. - #dotest conflicts2-142d6 "${testcvs} -q rm -f aa.c" fixme - dotest conflicts2-142d6 "rm aa.c" '' - dotest conflicts2-142d7 "${testcvs} -q update aa.c" "U aa\.c" - dotest conflicts2-142d8 "cat aa.c" '' - - # The other way is to use the version from the working directory - # instead of the version from the repository. Unfortunately, - # there doesn't seem to be any particularly clear way to do - # this (?). - - cd ../.. - - rm -r 1 2; rm -rf ${CVSROOT_DIRNAME}/first-dir - ;; - - conflicts3) - # More tests of conflicts and/or multiple working directories - # in general. - - mkdir 1; cd 1 - dotest conflicts3-1 "${testcvs} -q co -l ." '' - mkdir first-dir - dotest conflicts3-2 "${testcvs} add first-dir" \ -"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" - cd .. - mkdir 2; cd 2 - dotest conflicts3-3 "${testcvs} -q co -l first-dir" '' - cd ../1/first-dir - touch file1 file2 - dotest conflicts3-4 "${testcvs} add file1 file2" \ -"${PROG} add: scheduling file .file1. for addition -${PROG} add: scheduling file .file2. for addition -${PROG} add: use .${PROG} commit. to add these files permanently" - dotest conflicts3-5 "${testcvs} -q ci -m add-them" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -done -Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -initial revision: 1\.1 -done -RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v -done -Checking in file2; -${CVSROOT_DIRNAME}/first-dir/file2,v <-- file2 -initial revision: 1\.1 -done" - cd ../../2/first-dir - # Check that -n doesn't make CVS lose its mind as it creates - # (or rather, doesn't) a new file. - dotest conflicts3-6 "${testcvs} -nq update" \ -"U file1 -U file2" - dotest_fail conflicts3-7 "test -f file1" '' - dotest conflicts3-8 "${testcvs} -q update" \ -"U file1 -U file2" - dotest conflicts3-9 "test -f file2" '' - - # OK, now remove two files at once - dotest conflicts3-10 "${testcvs} rm -f file1 file2" \ -"${PROG} remove: scheduling .file1. for removal -${PROG} remove: scheduling .file2. for removal -${PROG} remove: use .${PROG} commit. to remove these files permanently" - dotest conflicts3-11 "${testcvs} -q ci -m remove-them" \ -"Removing file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -new revision: delete; previous revision: 1\.1 -done -Removing file2; -${CVSROOT_DIRNAME}/first-dir/file2,v <-- file2 -new revision: delete; previous revision: 1\.1 -done" - cd ../../1/first-dir - dotest conflicts3-12 "${testcvs} -n -q update" \ -"${PROG} update: file1 is no longer in the repository -${PROG} update: file2 is no longer in the repository" - dotest conflicts3-13 "${testcvs} -q update" \ -"${PROG} update: file1 is no longer in the repository -${PROG} update: file2 is no longer in the repository" - - # OK, now add a directory to both working directories - # and see that CVS doesn't lose its mind. - mkdir sdir - dotest conflicts3-14 "${testcvs} add sdir" \ -"Directory ${CVSROOT_DIRNAME}/first-dir/sdir added to the repository" - touch sdir/sfile - dotest conflicts3-14a "${testcvs} add sdir/sfile" \ -"${PROG} add: scheduling file .sdir/sfile. for addition -${PROG} add: use .${PROG} commit. to add this file permanently" - dotest conflicts3-14b "${testcvs} -q ci -m add" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/sdir/sfile,v -done -Checking in sdir/sfile; -${CVSROOT_DIRNAME}/first-dir/sdir/sfile,v <-- sfile -initial revision: 1\.1 -done" - - cd ../../2/first-dir - - # Create a CVS directory without the proper administrative - # files in it. This can happen for example if you hit ^C - # in the middle of a checkout. - mkdir sdir - mkdir sdir/CVS - # OK, in the local case CVS sees that the directory exists - # in the repository and recurses into it. In the remote case - # CVS can't see the repository and has no way of knowing - # that sdir is even a directory (stat'ing everything would be - # too slow). The remote behavior makes more sense to me (but - # would this affect other cases?). - if $remote; then - dotest conflicts3-15 "${testcvs} -q update" \ -"${QUESTION} sdir" - else - dotest conflicts3-15 "${testcvs} -q update" \ -"${QUESTION} sdir -${PROG} update: ignoring sdir (CVS/Repository missing)" - touch sdir/CVS/Repository - dotest conflicts3-16 "${testcvs} -q update" \ -"${QUESTION} sdir -${PROG} update: ignoring sdir (CVS/Entries missing)" - cd .. - dotest conflicts3-16a "${testcvs} -q update first-dir" \ -"${QUESTION} first-dir/sdir -${PROG} update: ignoring first-dir/sdir (CVS/Entries missing)" - cd first-dir - fi - rm -r sdir - - # OK, now the same thing, but the directory doesn't exist - # in the repository. - mkdir newdir - mkdir newdir/CVS - dotest conflicts3-17 "${testcvs} -q update" "${QUESTION} newdir" - echo "D/newdir////" >> CVS/Entries - dotest conflicts3-18 "${testcvs} -q update" \ -"${PROG} [a-z]*: ignoring newdir (CVS/Repository missing)" - touch newdir/CVS/Repository - dotest conflicts3-19 "${testcvs} -q update" \ -"${PROG} [a-z]*: ignoring newdir (CVS/Entries missing)" - cd .. - dotest conflicts3-20 "${testcvs} -q update first-dir" \ -"${PROG} [a-z]*: ignoring first-dir/newdir (CVS/Entries missing)" - cd first-dir - rm -r newdir - - # The previous tests have left CVS/Entries in something of a mess. - # While we "should" be able to deal with that (maybe), for now - # we just start over. - cd .. - rm -r first-dir - dotest conflicts3-20a "${testcvs} -q co -l first-dir" '' - cd first-dir - - dotest conflicts3-21 "${testcvs} -q update -d sdir" "U sdir/sfile" - rm -r sdir/CVS - dotest conflicts3-22 "${testcvs} -q update" "${QUESTION} sdir" - if $remote; then - dotest_fail conflicts3-23 "${testcvs} -q update -PdA" \ -"${QUESTION} sdir -${PROG} update: move away sdir/sfile; it is in the way -C sdir/sfile" - else - dotest conflicts3-23 "${testcvs} -q update -PdA" \ -"${QUESTION} sdir" - fi - - # Not that it should really affect much, but let's do the case - # where sfile has been removed. For example, suppose that sdir - # had been a CVS-controlled directory which was then removed - # by removing each file (and using update -P or some such). Then - # suppose that the build process creates an sdir directory which - # is not supposed to be under CVS. - rm -r sdir - dotest conflicts3-24 "${testcvs} -q update -d sdir" "U sdir/sfile" - rm sdir/sfile - dotest conflicts3-25 "${testcvs} rm sdir/sfile" \ -"${PROG} remove: scheduling .sdir/sfile. for removal -${PROG} remove: use .${PROG} commit. to remove this file permanently" - dotest conflicts3-26 "${testcvs} ci -m remove sdir/sfile" \ -"Removing sdir/sfile; -${CVSROOT_DIRNAME}/first-dir/sdir/sfile,v <-- sfile -new revision: delete; previous revision: 1\.1 -done" - rm -r sdir/CVS - dotest conflicts3-27 "${testcvs} -q update" "${QUESTION} sdir" - dotest conflicts3-28 "${testcvs} -q update -PdA" \ -"${QUESTION} sdir" - - cd ../.. - - rm -r 1 2 - rm -rf ${CVSROOT_DIRNAME}/first-dir - ;; - - conflicts4) - mkdir conflicts4; cd conflicts4 - mkdir 1; cd 1 - dotest conflicts4-1 "$testcvs -q co -l ." - mkdir first-dir - dotest conflicts4-2 "${testcvs} add first-dir" \ -"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" - cd .. - mkdir 2; cd 2 - dotest conflicts4-3 "${testcvs} -q co -l first-dir" '' - cd ../1/first-dir - echo baseline >file1 - dotest conflicts4-4 "${testcvs} -q add file1" \ -"$PROG add: use .$PROG commit. to add this file permanently" - dotest conflicts4-5 "${testcvs} -q ci -m add-it" \ -"RCS file: $CVSROOT_DIRNAME/first-dir/file1,v -done -Checking in file1; -$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 -initial revision: 1\.1 -done" - cd ../../2/first-dir - dotest conflicts4-6 "${testcvs} -q update" "U file1" - # Make a local change - echo wibble2 >> file1 - dotest conflicts4-7 "${testcvs} -q ci -m update2" \ -"Checking in file1; -$CVSROOT_DIRNAME/first-dir/file1,v <-- file1 -new revision: 1\.2; previous revision: 1\.1 -done" - cd ../../1/first-dir - echo wibble1 >>file1 - dotest conflicts4-8 "${testcvs} -Q update" \ -"RCS file: $CVSROOT_DIRNAME/first-dir/file1,v -retrieving revision 1\.1 -retrieving revision 1\.2 -Merging differences between 1\.1 and 1\.2 into file1 -rcsmerge: warning: conflicts during merge -cvs update: conflicts found in file1" - dotest_fail conflicts4-9 "${testcvs} -q update" \ -"C file1" - - if $remote; then - cat >$TESTDIR/conflicts4/serveme <$TESTDIR/conflicts4/client.out -EOF - # Cygwin. Pthffffffffft! - if test -n "$remotehost"; then - $CVS_RSH $remotehost "chmod +x $TESTDIR/conflicts4/serveme" - else - chmod +x $TESTDIR/conflicts4/serveme - fi - save_CVS_SERVER=$CVS_SERVER - CVS_SERVER=$TESTDIR/conflicts4/serveme; export CVS_SERVER - dotest_fail conflicts4-10r "$testcvs -q up" "C file1" - dotest conflicts4-11r "cat $TESTDIR/conflicts4/client.out" \ -"$DOTSTAR -Argument -- -Directory . -$CVSROOT_DIRNAME/first-dir -Entry /file1/1.2/$PLUS=// -Modified file1 -u=.*,g=.*,o=.* -59 -baseline -""<<<<<<< file1 -wibble1 -""======= -wibble2 -"">>>>>>> 1.2 -update" - - cat >$TESTDIR/conflicts4/serveme <$TESTDIR/conflicts4/client.out -EOF - - dotest_fail conflicts4-12r "$testcvs -q up" "C file1" - dotest conflicts4-13r "cat $TESTDIR/conflicts4/client.out" \ -"$DOTSTAR -Argument -- -Directory . -$CVSROOT_DIRNAME/first-dir -Entry /file1/1.2/$PLUS=// -Unchanged file1 -update" - - CVS_SERVER=$save_CVS_SERVER; export CVS_SERVER - fi - - if $keep; then - echo Keeping $TESTDIR and exiting due to --keep - exit 0 - fi - - cd ../../.. - rm -rf conflicts4 - rm -rf $CVSROOT_DIRNAME/first-dir - ;; - - clean) - # Test update -C (overwrite local mods w/ repository copies) - mkdir 1; cd 1 - dotest clean-1 "${testcvs} -q co -l ." '' - mkdir first-dir - dotest clean-2 "${testcvs} add first-dir" \ -"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" - cd first-dir - echo "The usual boring test text." > cleanme.txt - dotest clean-3 "${testcvs} add cleanme.txt" \ -"${PROG} add: scheduling file .cleanme\.txt. for addition -${PROG} add: use .${PROG} commit. to add this file permanently" - dotest clean-4 "${testcvs} -q ci -m clean-3" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/cleanme\.txt,v -done -Checking in cleanme\.txt; -${CVSROOT_DIRNAME}/first-dir/cleanme\.txt,v <-- cleanme\.txt -initial revision: 1\.1 -done" - # Okay, preparation is done, now test. - # Check that updating an unmodified copy works. - dotest clean-5 "${testcvs} -q update" '' - # Check that updating -C an unmodified copy works. - dotest clean-6 "${testcvs} -q update -C" '' - # Check that updating a modified copy works. - echo "fish" >> cleanme.txt - dotest clean-7 "${testcvs} -q update" 'M cleanme\.txt' - # Check that updating -C a modified copy works. - dotest clean-8 "${testcvs} -q update -C" \ -"(Locally modified cleanme\.txt moved to \.#cleanme\.txt\.1\.1) -U cleanme\.txt" - # And check that the backup copy really was made. - dotest clean-9 "cat .#cleanme.txt.1.1" \ -"The usual boring test text\. -fish" - - # Do it all again, this time naming the file explicitly. - rm .#cleanme.txt.1.1 - dotest clean-10 "${testcvs} -q update cleanme.txt" '' - dotest clean-11 "${testcvs} -q update -C cleanme.txt" '' - echo "bluegill" >> cleanme.txt - dotest clean-12 "${testcvs} -q update cleanme.txt" 'M cleanme\.txt' - dotest clean-13 "${testcvs} -q update -C cleanme.txt" \ -"(Locally modified cleanme\.txt moved to \.#cleanme\.txt\.1\.1) -U cleanme\.txt" - # And check that the backup copy really was made. - dotest clean-14 "cat .#cleanme.txt.1.1" \ -"The usual boring test text\. -bluegill" - - # Now try with conflicts - cd .. - dotest clean-15 "${testcvs} -q co -d second-dir first-dir" \ -'U second-dir/cleanme\.txt' - cd second-dir - echo "conflict test" >> cleanme.txt - dotest clean-16 "${testcvs} -q ci -m." \ -"Checking in cleanme\.txt; -${CVSROOT_DIRNAME}/first-dir/cleanme\.txt,v <-- cleanme\.txt -new revision: 1\.2; previous revision: 1\.1 -done" - cd ../first-dir - echo "fish" >> cleanme.txt - dotest clean-17 "${testcvs} -nq update" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/cleanme\.txt,v -retrieving revision 1\.1 -retrieving revision 1\.2 -Merging differences between 1\.1 and 1\.2 into cleanme\.txt -rcsmerge: warning: conflicts during merge -${PROG} update: conflicts found in cleanme\.txt -C cleanme\.txt" - dotest clean-18 "${testcvs} -q update -C" \ -"(Locally modified cleanme\.txt moved to \.#cleanme\.txt\.1\.1) -U cleanme\.txt" - dotest clean-19 "cat .#cleanme.txt.1.1" \ -"The usual boring test text\. -fish" - - # Done. Clean up. - cd ../.. - rm -rf 1 - rm -rf ${CVSROOT_DIRNAME}/first-dir - ;; - - modules) - # Tests of various ways to define and use modules. - # Roadmap to various modules tests: - # -a: - # error on incorrect placement: modules - # error combining with other options: modules2-a* - # infinite loops: modules148a1.1 - modules148a1.2 - # use to specify a file more than once: modules3 - # use with ! feature: modules4 - # regular modules: modules, modules2, cvsadm - # ampersand modules: modules2 - # -s: modules. - # -d: modules, modules3, cvsadm - # -i, -o, -u, -e, -t: modules5 - # slashes in module names: modules3 - # invalid module definitions: modules6 - - ############################################################ - # These tests are to make sure that administrative files get - # rebuilt, regardless of how and where files are checked - # out. - ############################################################ - # Check out the whole repository - mkdir 1; cd 1 - dotest modules-1 "${testcvs} -q co ." 'U CVSROOT/checkoutlist -U CVSROOT/commitinfo -U CVSROOT/config -U CVSROOT/cvswrappers -U CVSROOT/editinfo -U CVSROOT/loginfo -U CVSROOT/modules -U CVSROOT/notify -U CVSROOT/rcsinfo -U CVSROOT/taginfo -U CVSROOT/verifymsg' - echo "# made a change" >>CVSROOT/modules - dotest modules-1d "${testcvs} -q ci -m add-modules" \ -"Checking in CVSROOT/modules; -${CVSROOT_DIRNAME}/CVSROOT/modules,v <-- modules -new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* -done -${PROG} commit: Rebuilding administrative file database" - cd .. - rm -rf 1 - - ############################################################ - # Check out CVSROOT - mkdir 1; cd 1 - dotest modules-2 "${testcvs} -q co CVSROOT" 'U CVSROOT/checkoutlist -U CVSROOT/commitinfo -U CVSROOT/config -U CVSROOT/cvswrappers -U CVSROOT/editinfo -U CVSROOT/loginfo -U CVSROOT/modules -U CVSROOT/notify -U CVSROOT/rcsinfo -U CVSROOT/taginfo -U CVSROOT/verifymsg' - echo "# made a change" >>CVSROOT/modules - dotest modules-2d "${testcvs} -q ci -m add-modules" \ -"Checking in CVSROOT/modules; -${CVSROOT_DIRNAME}/CVSROOT/modules,v <-- modules -new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* -done -${PROG} commit: Rebuilding administrative file database" - cd .. - rm -rf 1 - - ############################################################ - # Check out CVSROOT in some other directory - mkdir ${CVSROOT_DIRNAME}/somedir - mkdir 1; cd 1 - dotest modules-3 "${testcvs} -q co somedir" '' - cd somedir - dotest modules-3d "${testcvs} -q co CVSROOT" 'U CVSROOT/checkoutlist -U CVSROOT/commitinfo -U CVSROOT/config -U CVSROOT/cvswrappers -U CVSROOT/editinfo -U CVSROOT/loginfo -U CVSROOT/modules -U CVSROOT/notify -U CVSROOT/rcsinfo -U CVSROOT/taginfo -U CVSROOT/verifymsg' - echo "# made a change" >>CVSROOT/modules - dotest modules-3g "${testcvs} -q ci -m add-modules" \ -"Checking in CVSROOT/modules; -${CVSROOT_DIRNAME}/CVSROOT/modules,v <-- modules -new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* -done -${PROG} commit: Rebuilding administrative file database" - cd ../.. - rm -rf 1 - rm -rf ${CVSROOT_DIRNAME}/somedir - ############################################################ - # end rebuild tests - ############################################################ - - - mkdir ${CVSROOT_DIRNAME}/first-dir - - mkdir 1 - cd 1 - - dotest modules-143 "${testcvs} -q co first-dir" "" - - cd first-dir - mkdir subdir - dotest modules-143a "${testcvs} add subdir" \ -"Directory ${CVSROOT_DIRNAME}/first-dir/subdir added to the repository" - - cd subdir - mkdir ssdir - dotest modules-143b "${testcvs} add ssdir" \ -"Directory ${CVSROOT_DIRNAME}/first-dir/subdir/ssdir added to the repository" - - touch a b - - dotest modules-144 "${testcvs} add a b" \ -"${PROG} add: scheduling file .a. for addition -${PROG} add: scheduling file .b. for addition -${PROG} add: use .${PROG} commit. to add these files permanently" - - dotest modules-145 "${testcvs} ci -m added" \ -"${PROG} [a-z]*: Examining . -${PROG} [a-z]*: Examining ssdir -RCS file: ${CVSROOT_DIRNAME}/first-dir/subdir/a,v -done -Checking in a; -${CVSROOT_DIRNAME}/first-dir/subdir/a,v <-- a -initial revision: 1\.1 -done -RCS file: ${CVSROOT_DIRNAME}/first-dir/subdir/b,v -done -Checking in b; -${CVSROOT_DIRNAME}/first-dir/subdir/b,v <-- b -initial revision: 1\.1 -done" - - cd .. - dotest modules-146 "${testcvs} -q co CVSROOT" \ -"U CVSROOT/checkoutlist -U CVSROOT/commitinfo -U CVSROOT/config -U CVSROOT/cvswrappers -U CVSROOT/editinfo -U CVSROOT/loginfo -U CVSROOT/modules -U CVSROOT/notify -U CVSROOT/rcsinfo -U CVSROOT/taginfo -U CVSROOT/verifymsg" - - # Here we test that CVS can deal with CVSROOT (whose repository - # is at top level) in the same directory as subdir (whose repository - # is a subdirectory of first-dir). TODO: Might want to check that - # files can actually get updated in this state. - dotest modules-147 "${testcvs} -q update" "" - - cat >CVSROOT/modules < A was blocked, but not A -> B -> A or deeper). -infinitealias2 -a infinitealias2/ -infinitealias3 -a infinitealias4/ -infinitealias4 -a aliasmodule infinitealias5 -infinitealias5 -a infinitealias3/ -# Options must come before arguments. It is possible this should -# be relaxed at some point (though the result would be bizarre for -# -a); for now test the current behavior. -bogusalias first-dir/subdir/a -a -EOF - dotest modules-148 "${testcvs} ci -m 'add modules' CVSROOT/modules" \ -"Checking in CVSROOT/modules; -${CVSROOT_DIRNAME}/CVSROOT/modules,v <-- modules -new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* -done -${PROG} commit: Rebuilding administrative file database" - - cd .. - # The "statusmod" module contains an error; trying to use it - # will produce "modules file missing directory" I think. - # However, that shouldn't affect the ability of "cvs co -c" or - # "cvs co -s" to do something reasonable with it. - dotest modules-148a0 "${testcvs} co -c" 'aliasmodule -a first-dir/subdir/a -aliasnested -a first-dir/subdir/ssdir -bogusalias first-dir/subdir/a -a -dirmodule first-dir/subdir -infinitealias -a infinitealias -infinitealias2 -a infinitealias2/ -infinitealias3 -a infinitealias4/ -infinitealias4 -a aliasmodule infinitealias5 -infinitealias5 -a infinitealias3/ -namedmodule -d nameddir first-dir/subdir -realmodule first-dir/subdir a -statusmod -s Mungeable -topfiles -a first-dir/file1 first-dir/file2 -world -a \.' - # There is code in modules.c:save_d which explicitly skips - # modules defined with -a, which is why aliasmodule is not - # listed. - dotest modules-148a1 "${testcvs} co -s" \ -'statusmod Mungeable -bogusalias NONE first-dir/subdir/a -a -dirmodule NONE first-dir/subdir -namedmodule NONE first-dir/subdir -realmodule NONE first-dir/subdir a' - - # Check that infinite loops are avoided - dotest modules-148a1.1 "${testcvs} co infinitealias" \ -"$PROG checkout: module \`infinitealias' in modules file contains infinite loop" \ -"$PROG server: module \`infinitealias' in modules file contains infinite loop -$PROG checkout: module \`infinitealias' in modules file contains infinite loop" - # Prior to 1.11.12 & 1.12.6, the inifinte alias loop check did not - # strip slashes. - dotest modules-148a1.2 "${testcvs} co infinitealias2" \ -"$PROG checkout: module \`infinitealias2' in modules file contains infinite loop" \ -"$PROG server: module \`infinitealias2' in modules file contains infinite loop -$PROG checkout: module \`infinitealias2' in modules file contains infinite loop" - # Prior to 1.11.12 & 1.12.6, the inifinte alias loop check did not - # notice when A -> B -> A, it only noticed A -> A. - dotest modules-148a1.3 "${testcvs} co infinitealias3/" \ -"$PROG checkout: module \`infinitealias3' in modules file contains infinite loop" \ -"$PROG server: module \`infinitealias3' in modules file contains infinite loop -$PROG checkout: module \`infinitealias3' in modules file contains infinite loop" - - # Test that real modules check out to realmodule/a, not subdir/a. - dotest modules-149a1 "${testcvs} co realmodule" "U realmodule/a" - dotest modules-149a2 "test -d realmodule && test -f realmodule/a" "" - dotest_fail modules-149a3 "test -f realmodule/b" "" - dotest modules-149a4 "${testcvs} -q co realmodule" "" - dotest modules-149a5 "echo yes | ${testcvs} release -d realmodule" \ -"You have \[0\] altered files in this repository\. -Are you sure you want to release (and delete) directory .realmodule.: " - - dotest_fail modules-149b1 "${testcvs} co realmodule/a" \ -"${PROG}"' checkout: module `realmodule/a'\'' is a request for a file in a module which is not a directory' \ -"${PROG}"' server: module `realmodule/a'\'' is a request for a file in a module which is not a directory -'"${PROG}"' \[checkout aborted\]: cannot expand modules' - - # Now test the ability to check out a single file from a directory - dotest modules-150c "${testcvs} co dirmodule/a" "U dirmodule/a" - dotest modules-150d "test -d dirmodule && test -f dirmodule/a" "" - dotest_fail modules-150e "test -f dirmodule/b" "" - dotest modules-150f "echo yes | ${testcvs} release -d dirmodule" \ -"You have \[0\] altered files in this repository\. -Are you sure you want to release (and delete) directory .dirmodule.: " - # Now test the ability to correctly reject a non-existent filename. - # For maximum studliness we would check that an error message is - # being output. - # We accept a zero exit status because it is what CVS does - # (Dec 95). Probably the exit status should be nonzero, - # however. - dotest modules-150g1 "${testcvs} co dirmodule/nonexist" \ -"${PROG} checkout: warning: new-born dirmodule/nonexist has disappeared" - # We tolerate the creation of the dirmodule directory, since that - # is what CVS does, not because we view that as preferable to not - # creating it. - dotest_fail modules-150g2 "test -f dirmodule/a || test -f dirmodule/b" "" - rm -r dirmodule - - # Now test that a module using -d checks out to the specified - # directory. - dotest modules-150h1 "${testcvs} -q co namedmodule" \ -'U nameddir/a -U nameddir/b' - dotest modules-150h2 "test -f nameddir/a && test -f nameddir/b" "" - echo add line >>nameddir/a - dotest modules-150h3 "${testcvs} -q co namedmodule" 'M nameddir/a' - rm nameddir/a - dotest modules-150h4 "${testcvs} -q co namedmodule" 'U nameddir/a' - dotest modules-150h99 "echo yes | ${testcvs} release -d nameddir" \ -"You have \[0\] altered files in this repository\. -Are you sure you want to release (and delete) directory .nameddir.: " - - # Now test that alias modules check out to subdir/a, not - # aliasmodule/a. - dotest modules-151 "${testcvs} co aliasmodule" "" - dotest_fail modules-152 "test -d aliasmodule" "" - echo abc >>first-dir/subdir/a - dotest modules-153 "${testcvs} -q co aliasmodule" "M first-dir/subdir/a" - - cd .. - rm -r 1 - - mkdir 2 - cd 2 - dotest modules-155a0 "${testcvs} co aliasnested" \ -"${PROG} checkout: Updating first-dir/subdir/ssdir" - dotest modules-155a1 "test -d first-dir" '' - dotest modules-155a2 "test -d first-dir/subdir" '' - dotest modules-155a3 "test -d first-dir/subdir/ssdir" '' - # Test that nothing extraneous got created. - dotest modules-155a4 "ls" "first-dir" \ -"CVS -first-dir" - cd .. - rm -r 2 - - # Test checking out everything. - mkdir 1 - cd 1 - dotest modules-155b "${testcvs} -q co world" \ -"U CVSROOT/${DOTSTAR} -U first-dir/subdir/a -U first-dir/subdir/b" - cd .. - rm -r 1 - - # Test checking out a module which lists at least two - # specific files twice. At one time, this failed over - # remote CVS. - mkdir 1 - cd 1 - dotest modules-155c1 "${testcvs} -q co first-dir" \ -"U first-dir/subdir/a -U first-dir/subdir/b" - - cd first-dir - echo 'first revision' > file1 - echo 'first revision' > file2 - dotest modules-155c2 "${testcvs} add file1 file2" \ -"${PROG}"' add: scheduling file `file1'\'' for addition -'"${PROG}"' add: scheduling file `file2'\'' for addition -'"${PROG}"' add: use .'"${PROG}"' commit. to add these files permanently' - dotest modules-155c3 "${testcvs} -q ci -m add-it" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -done -Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -initial revision: 1\.1 -done -RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v -done -Checking in file2; -${CVSROOT_DIRNAME}/first-dir/file2,v <-- file2 -initial revision: 1\.1 -done" - - cd .. - rm -r first-dir - dotest modules-155c4 "${testcvs} -q co topfiles" \ -"U first-dir/file1 -U first-dir/file2" - dotest modules-155c5 "${testcvs} -q co topfiles" "" - - # Make sure the right thing happens if we remove a file. - cd first-dir - dotest modules-155c6 "${testcvs} -q rm -f file1" \ -"${PROG} remove: use .${PROG} commit. to remove this file permanently" - dotest modules-155c7 "${testcvs} -q ci -m remove-it" \ -"Removing file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -new revision: delete; previous revision: 1\.1 -done" - cd .. - rm -r first-dir - dotest modules-155c8 "${testcvs} -q co topfiles" \ -"${PROG} checkout: warning: first-dir/file1 is not (any longer) pertinent -U first-dir/file2" - - cd .. - rm -r 1 - - rm -rf ${CVSROOT_DIRNAME}/first-dir - ;; - - modules2) - # More tests of modules, in particular the & feature. - mkdir 1; cd 1 - dotest modules2-setup-1 "${testcvs} -q co -l ." '' - mkdir first-dir second-dir third-dir - dotest modules2-setup-2 \ -"${testcvs} add first-dir second-dir third-dir" \ -"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository -Directory ${CVSROOT_DIRNAME}/second-dir added to the repository -Directory ${CVSROOT_DIRNAME}/third-dir added to the repository" - cd third-dir - touch file3 - dotest modules2-setup-3 "${testcvs} add file3" \ -"${PROG} add: scheduling file .file3. for addition -${PROG} add: use .${PROG} commit. to add this file permanently" - dotest modules2-setup-4 "${testcvs} -q ci -m add file3" \ -"RCS file: ${CVSROOT_DIRNAME}/third-dir/file3,v -done -Checking in file3; -${CVSROOT_DIRNAME}/third-dir/file3,v <-- file3 -initial revision: 1\.1 -done" - cd ../.. - rm -r 1 - - mkdir 1 - cd 1 - - dotest modules2-1 "${testcvs} -q co CVSROOT/modules" \ -'U CVSROOT/modules' - cd CVSROOT - cat >> modules << EOF -ampermodule &first-dir &second-dir -combmodule third-dir file3 &first-dir -ampdirmod -d newdir &first-dir &second-dir -badmod -d newdir -messymod first-dir &messymodchild -messymodchild -d sdir/child second-dir -EOF - # Depending on whether the user also ran the modules test - # we will be checking in revision 1.2 or 1.3. - dotest modules2-2 "${testcvs} -q ci -m add-modules" \ -"Checking in modules; -${CVSROOT_DIRNAME}/CVSROOT/modules,v <-- modules -new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* -done -${PROG} commit: Rebuilding administrative file database" - - cd .. - - dotest modules2-3 "${testcvs} -q co ampermodule" '' - dotest modules2-4 "test -d ampermodule/first-dir" '' - dotest modules2-5 "test -d ampermodule/second-dir" '' - - # Test ability of cvs release to handle multiple arguments - # See comment at "release" for list of other cvs release tests. - cd ampermodule - if ${testcvs} release -d first-dir second-dir <>${LOGFILE} -yes -yes -EOF - then - pass modules2-6 - else - fail modules2-6 - fi - dotest_fail modules2-7 "test -d first-dir" '' - dotest_fail modules2-8 "test -d second-dir" '' - - cd .. - - # There used to be a nasty-hack that made CVS skip creation of the - # module dir (in this case ampermodule) when -n was specified - dotest modules2-ampermod-1 "${testcvs} -q co -n ampermodule" '' - dotest modules2-ampermod-2 "test -d ampermodule/first-dir" '' - dotest modules2-ampermod-3 "test -d ampermodule/second-dir" '' - - # Test release of a module - if echo yes |${testcvs} release -d ampermodule >>${LOGFILE}; then - pass modules2-ampermod-release-1 - else - fail modules2-ampermod-release-1 - fi - dotest_fail modules2-ampermod-release-2 "test -d ampermodule" '' - - # and the '-n' test again, but in conjunction with '-d' - dotest modules2-ampermod-4 "${testcvs} -q co -n -d newname ampermodule" '' - dotest modules2-ampermod-5 "test -d newname/first-dir" '' - dotest modules2-ampermod-6 "test -d newname/second-dir" '' - rm -rf newname - - # Now we create another directory named first-dir and make - # sure that CVS doesn't get them mixed up. - mkdir first-dir - # Note that this message should say "Updating ampermodule/first-dir" - # I suspect. This is a long-standing behavior/bug.... - dotest modules2-9 "${testcvs} co ampermodule" \ -"${PROG} checkout: Updating first-dir -${PROG} checkout: Updating second-dir" - touch ampermodule/first-dir/amper1 - cd ampermodule - dotest modules2-10 "${testcvs} add first-dir/amper1" \ -"${PROG} add: scheduling file .first-dir/amper1. for addition -${PROG} add: use .${PROG} commit. to add this file permanently" - cd .. - - # As with the "Updating xxx" message, the "U first-dir/amper1" - # message (instead of "U ampermodule/first-dir/amper1") is - # rather fishy. - dotest modules2-12 "${testcvs} co ampermodule" \ -"${PROG} checkout: Updating first-dir -A first-dir/amper1 -${PROG} checkout: Updating second-dir" - - if $remote; then - dotest modules2-13 "${testcvs} -q ci -m add-it ampermodule" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/amper1,v -done -Checking in ampermodule/first-dir/amper1; -${CVSROOT_DIRNAME}/first-dir/amper1,v <-- amper1 -initial revision: 1\.1 -done" - else - # Trying this as above led to a "protocol error" message. - # Work around this bug. - cd ampermodule - dotest modules2-13 "${testcvs} -q ci -m add-it" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/amper1,v -done -Checking in first-dir/amper1; -${CVSROOT_DIRNAME}/first-dir/amper1,v <-- amper1 -initial revision: 1\.1 -done" - cd .. - fi - cd .. - rm -r 1 - - # Now test the "combmodule" module (combining regular modules - # and ampersand modules in the same module definition). - mkdir 1; cd 1 - dotest modules2-14 "${testcvs} co combmodule" \ -"U combmodule/file3 -${PROG} checkout: Updating first-dir -U first-dir/amper1" - dotest modules2-15 "test -f combmodule/file3" "" - dotest modules2-16 "test -f combmodule/first-dir/amper1" "" - cd combmodule - rm -r first-dir - # At least for now there is no way to tell CVS that - # some files/subdirectories come from one repository directory, - # and others from another. - # This seems like a pretty sensible behavior to me, in the - # sense that first-dir doesn't "really" exist within - # third-dir, so CVS just acts as if there is nothing there - # to do. - dotest modules2-17 "${testcvs} update -d" \ -"${PROG} update: Updating \." - - cd .. - dotest modules2-18 "${testcvs} -q co combmodule" \ -"U first-dir/amper1" - dotest modules2-19 "test -f combmodule/first-dir/amper1" "" - cd .. - rm -r 1 - - # Now test the "ampdirmod" and "badmod" modules to be sure that - # options work with ampersand modules but don't prevent the - # "missing directory" error message. - mkdir 1; cd 1 - dotest modules2-20 "${testcvs} co ampdirmod" \ -"${PROG} checkout: Updating first-dir -U first-dir/amper1 -${PROG} checkout: Updating second-dir" - dotest modules2-21 "test -f newdir/first-dir/amper1" "" - dotest modules2-22 "test -d newdir/second-dir" "" - dotest_fail modules2-23 "${testcvs} co badmod" \ -"${PROG} checkout: modules file missing directory for module badmod" \ -"${PROG} server: modules file missing directory for module badmod -${PROG} \[checkout aborted\]: cannot expand modules" - cd .. - rm -r 1 - - # Confirm that a rename with added depth nested in an ampersand - # module works. - mkdir 1; cd 1 - dotest modules2-nestedrename-1 "${testcvs} -q co messymod" \ -"U messymod/amper1" - dotest modules2-nestedrename-2 "test -d messymod/sdir" '' - dotest modules2-nestedrename-3 "test -d messymod/sdir/CVS" '' - dotest modules2-nestedrename-4 "test -d messymod/sdir/child" '' - dotest modules2-nestedrename-5 "test -d messymod/sdir/child/CVS" '' - cd ..; rm -r 1 - - # FIXME: client/server has a bug. It should be working like a local - # repository in this case, but fails to check out the second module - # in the list when a branch is specified. - mkdir 1; cd 1 - dotest modules2-ampertag-setup-1 \ -"${testcvs} -Q rtag tag first-dir second-dir third-dir" \ -'' - dotest modules2-ampertag-1 "${testcvs} -q co -rtag ampermodule" \ -"U first-dir/amper1" - if $remote; then - dotest_fail modules2-ampertag-2 "test -d ampermodule/second-dir" '' - dotest_fail modules2-ampertag-3 "test -d ampermodule/second-dir/CVS" '' - else - dotest modules2-ampertag-2 "test -d ampermodule/second-dir" '' - dotest modules2-ampertag-3 "test -d ampermodule/second-dir/CVS" '' - fi - cd ..; rm -r 1 - - # Test for tag files when an ampermod is renamed with more path - # elements than it started with. - # - # FIXME: This is currently broken in the remote case, possibly only - # because the messymodchild isn't being checked out at all. - mkdir 1; cd 1 -# dotest modules2-tagfiles-setup-1 \ -#"${testcvs} -Q rtag -b branch first-dir second-dir" \ -#'' - dotest modules2-tagfiles-1 "${testcvs} -q co -rtag messymod" \ -"U messymod/amper1" - if $remote; then - dotest_fail modules2-tagfiles-2r "test -d messymod/sdir" '' - else - dotest modules2-tagfiles-2 "cat messymod/sdir/CVS/Tag" 'Ttag' - fi - cd ..; rm -r 1 - - # Test that CVS gives an error if one combines -a with - # other options. - # Probably would be better to break this out into a separate - # test. Although it is short, it shares no files/state with - # the rest of the modules2 tests. - mkdir 1; cd 1 - dotest modules2-a0.5 "${testcvs} -q co CVSROOT/modules" \ -'U CVSROOT/modules' - cd CVSROOT - echo 'aliasopt -a -d onedir first-dir' >modules - dotest modules2-a0 "${testcvs} -q ci -m add-modules" \ -"Checking in modules; -${CVSROOT_DIRNAME}/CVSROOT/modules,v <-- modules -new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* -done -${PROG} commit: Rebuilding administrative file database" - cd .. - dotest_fail modules2-a1 "${testcvs} -q co aliasopt" \ -"${PROG} checkout: -a cannot be specified in the modules file along with other options" \ -"${PROG} server: -a cannot be specified in the modules file along with other options -${PROG} \[checkout aborted\]: cannot expand modules" - cd ..; rm -r 1 - - # Clean up. - rm -rf ${CVSROOT_DIRNAME}/first-dir - rm -rf ${CVSROOT_DIRNAME}/second-dir - rm -rf ${CVSROOT_DIRNAME}/third-dir - ;; - - modules3) - # More tests of modules, in particular what happens if several - # modules point to the same file. - - # First just set up a directory first-dir and a file file1 in it. - mkdir 1; cd 1 - - dotest modules3-0 "${testcvs} -q co -l ." '' - mkdir first-dir - dotest modules3-1 "${testcvs} add first-dir" \ -"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" - - cd first-dir - echo file1 >file1 - dotest modules3-2 "${testcvs} add file1" \ -"${PROG} add: scheduling file \`file1' for addition -${PROG} add: use '${PROG} commit' to add this file permanently" - dotest modules3-3 "${testcvs} -q ci -m add-it" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -done -Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -initial revision: 1\.1 -done" - cd .. - - dotest modules3-4 "${testcvs} -q update -d CVSROOT" \ -"U CVSROOT${DOTSTAR}" - cd CVSROOT - cat >modules < file1 - dotest modules4-4 "${testcvs} add file1" \ -"${PROG}"' add: scheduling file `file1'\'' for addition -'"${PROG}"' add: use .'"${PROG}"' commit. to add this file permanently' - - echo file2 > subdir/file2 - dotest modules4-5 "${testcvs} add subdir/file2" \ -"${PROG}"' add: scheduling file `subdir/file2'\'' for addition -'"${PROG}"' add: use .'"${PROG}"' commit. to add this file permanently' - - echo file3 > subdir_long/file3 - dotest modules4-6 "${testcvs} add subdir_long/file3" \ -"${PROG}"' add: scheduling file `subdir_long/file3'\'' for addition -'"${PROG}"' add: use .'"${PROG}"' commit. to add this file permanently' - - dotest modules4-7 "${testcvs} -q ci -m add-it" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -done -Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -initial revision: 1\.1 -done -RCS file: ${CVSROOT_DIRNAME}/first-dir/subdir/file2,v -done -Checking in subdir/file2; -${CVSROOT_DIRNAME}/first-dir/subdir/file2,v <-- file2 -initial revision: 1\.1 -done -RCS file: ${CVSROOT_DIRNAME}/first-dir/subdir_long/file3,v -done -Checking in subdir_long/file3; -${CVSROOT_DIRNAME}/first-dir/subdir_long/file3,v <-- file3 -initial revision: 1\.1 -done" - - cd .. - - dotest modules4-8 "${testcvs} -q update -d CVSROOT" \ -"U CVSROOT${DOTSTAR}" - cd CVSROOT - cat >modules <> ${CVSROOT_DIRNAME}/$i.sh <CVSROOT/modules <>realmodule/a - dotest modules5-13 "${testcvs} -q ci -m." \ -"Checking in realmodule/a; -${CVSROOT_DIRNAME}/first-dir/subdir/a,v <-- a -new revision: 1\.2; previous revision: 1\.1 -done" - else - dotest modules5-11 "${testcvs} -q co realmodule" \ -"checkout script invoked in ${TESTDIR}/1 -args: realmodule" - dotest modules5-12 "${testcvs} -q update" '' - echo "change" >>realmodule/a - dotest modules5-13 "${testcvs} -q ci -m." \ -"Checking in realmodule/a; -${CVSROOT_DIRNAME}/first-dir/subdir/a,v <-- a -new revision: 1\.2; previous revision: 1\.1 -done" - fi - dotest modules5-14 "echo yes | ${testcvs} release -d realmodule" \ -"You have \[0\] altered files in this repository\. -Are you sure you want to release (and delete) directory .realmodule.: " - dotest modules5-15 "${testcvs} -q rtag -Dnow MYTAG realmodule" \ -"tag script invoked in ${TESTDIR}/1 -args: realmodule MYTAG" \ -"tag script invoked in ${TMPDIR}/cvs-serv[0-9a-z]* -args: realmodule MYTAG" - if $remote; then - dotest modules5-16 "${testcvs} -q export -r MYTAG realmodule" \ -"U realmodule/a -export script invoked in ${TMPDIR}/cvs-serv[0-9a-z]* -args: realmodule" - else - dotest modules5-16 "${testcvs} -q export -r MYTAG realmodule" \ -"U realmodule/a -export script invoked in ${TESTDIR}/1 -args: realmodule" - fi - rm -r realmodule - - dotest_fail modules5-17 "${testcvs} co realmodule/a" \ -"${PROG}"' checkout: module `realmodule/a'\'' is a request for a file in a module which is not a directory' \ -"${PROG}"' server: module `realmodule/a'\'' is a request for a file in a module which is not a directory -'"${PROG}"' \[checkout aborted\]: cannot expand modules' - - # Now test the ability to check out a single file from a directory - if $remote; then - dotest modules5-18 "${testcvs} co dirmodule/a" \ -"U dirmodule/a -${PROG} checkout: Executing ..${CVSROOT_DIRNAME}/checkout\.sh. .dirmodule.. -checkout script invoked in ${TMPDIR}/cvs-serv[0-9a-z]* -args: dirmodule" - else - dotest modules5-18 "${testcvs} co dirmodule/a" \ -"U dirmodule/a -${PROG} checkout: Executing ..${CVSROOT_DIRNAME}/checkout\.sh. .dirmodule.. -checkout script invoked in ${TESTDIR}/1 -args: dirmodule" - fi - dotest modules5-19 "test -d dirmodule && test -f dirmodule/a" "" - dotest_fail modules5-20 "test -f dirmodule/b" "" - dotest modules5-21 "echo yes | ${testcvs} release -d dirmodule" \ -"You have \[0\] altered files in this repository\. -Are you sure you want to release (and delete) directory .dirmodule.: " - - # Now test the ability to correctly reject a non-existent filename. - # For maximum studliness we would check that an error message is - # being output. - # We accept a zero exit status because it is what CVS does - # (Dec 95). Probably the exit status should be nonzero, - # however. - if $remote; then - dotest modules5-22 "${testcvs} co dirmodule/nonexist" \ -"${PROG} checkout: warning: new-born dirmodule/nonexist has disappeared -${PROG} checkout: Executing ..${CVSROOT_DIRNAME}/checkout\.sh. .dirmodule.. -checkout script invoked in ${TMPDIR}/cvs-serv[0-9a-z]* -args: dirmodule" - else - dotest modules5-22 "${testcvs} co dirmodule/nonexist" \ -"${PROG} checkout: warning: new-born dirmodule/nonexist has disappeared -${PROG} checkout: Executing ..${CVSROOT_DIRNAME}/checkout\.sh. .dirmodule.. -checkout script invoked in ${TESTDIR}/1 -args: dirmodule" - fi - # We tolerate the creation of the dirmodule directory, since that - # is what CVS does, not because we view that as preferable to not - # creating it. - dotest_fail modules5-23 "test -f dirmodule/a || test -f dirmodule/b" "" - rm -r dirmodule - - # Now test that a module using -d checks out to the specified - # directory. - if $remote; then - dotest modules5-24 "${testcvs} -q co namedmodule" \ -"U nameddir/a -U nameddir/b -checkout script invoked in ${TMPDIR}/cvs-serv[0-9a-z]* -args: nameddir" - else - dotest modules5-24 "${testcvs} -q co namedmodule" \ -"U nameddir/a -U nameddir/b -checkout script invoked in ${TESTDIR}/1 -args: nameddir" - fi - dotest modules5-25 "test -f nameddir/a && test -f nameddir/b" "" - echo add line >>nameddir/a - # This seems suspicious: when we checkout an existing directory, - # the checkout script gets executed in addition to the update - # script. Is that by design or accident? - if $remote; then - dotest modules5-26 "${testcvs} -q co namedmodule" \ -"M nameddir/a -checkout script invoked in ${TMPDIR}/cvs-serv[0-9a-z]* -args: nameddir" - else - dotest modules5-26 "${testcvs} -q co namedmodule" \ -"M nameddir/a -checkout script invoked in ${TESTDIR}/1 -args: nameddir" - fi - rm nameddir/a - - if $remote; then - dotest modules5-27 "${testcvs} -q co namedmodule" \ -"U nameddir/a -checkout script invoked in ${TMPDIR}/cvs-serv[0-9a-z]* -args: nameddir" - else - dotest modules5-27 "${testcvs} -q co namedmodule" \ -"U nameddir/a -checkout script invoked in ${TESTDIR}/1 -args: nameddir" - fi - dotest modules5-28 "echo yes | ${testcvs} release -d nameddir" \ -"You have \[0\] altered files in this repository\. -Are you sure you want to release (and delete) directory .nameddir.: " - - # Now try the same tests with -d on command line - # FIXCVS? The manual says the modules programs get the module name, - # but they really get the directory name. - if $remote; then - dotest modules5-29 "${testcvs} co -d mydir realmodule" \ -"U mydir/a -${PROG} checkout: Executing ..${CVSROOT_DIRNAME}/checkout\.sh. .mydir.. -checkout script invoked in ${TMPDIR}/cvs-serv[0-9a-z]* -args: mydir" - else - dotest modules5-29 "${testcvs} co -d mydir realmodule" \ -"U mydir/a -${PROG} checkout: Executing ..${CVSROOT_DIRNAME}/checkout\.sh. .mydir.. -checkout script invoked in ${TESTDIR}/1 -args: mydir" - fi - dotest modules5-30 "test -d mydir && test -f mydir/a" "" - dotest_fail modules5-31 "test -d realmodule || test -f mydir/b" "" - if $remote; then - dotest modules5-32 "${testcvs} -q co -d mydir realmodule" \ -"checkout script invoked in ${TMPDIR}/cvs-serv[0-9a-z]* -args: mydir" - dotest modules5-33 "${testcvs} -q update" '' - echo "change" >>mydir/a - dotest modules5-34 "${testcvs} -q ci -m." \ -"Checking in mydir/a; -${CVSROOT_DIRNAME}/first-dir/subdir/a,v <-- a -new revision: 1\.3; previous revision: 1\.2 -done" - else - dotest modules5-32 "${testcvs} -q co -d mydir realmodule" \ -"checkout script invoked in ${TESTDIR}/1 -args: mydir" - dotest modules5-33 "${testcvs} -q update" '' - echo "change" >>mydir/a - dotest modules5-34 "${testcvs} -q ci -m." \ -"Checking in mydir/a; -${CVSROOT_DIRNAME}/first-dir/subdir/a,v <-- a -new revision: 1\.3; previous revision: 1\.2 -done" - fi - dotest modules5-35 "echo yes | ${testcvs} release -d mydir" \ -"You have \[0\] altered files in this repository\. -Are you sure you want to release (and delete) directory .mydir.: " - if $remote; then - dotest modules5-36 "${testcvs} -q rtag -Dnow MYTAG2 realmodule" \ -"tag script invoked in ${TMPDIR}/cvs-serv[0-9a-z]* -args: realmodule MYTAG2" - dotest modules5-37 "${testcvs} -q export -r MYTAG2 -d mydir realmodule" \ -"U mydir/a -export script invoked in ${TMPDIR}/cvs-serv[0-9a-z]* -args: mydir" - else - dotest modules5-36 "${testcvs} -q rtag -Dnow MYTAG2 realmodule" \ -"tag script invoked in ${TESTDIR}/1 -args: realmodule MYTAG2" - dotest modules5-37 "${testcvs} -q export -r MYTAG2 -d mydir realmodule" \ -"U mydir/a -export script invoked in ${TESTDIR}/1 -args: mydir" - fi - rm -r mydir - - # Now test the ability to check out a single file from a directory - if $remote; then - dotest modules5-38 "${testcvs} co -d mydir dirmodule/a" \ -"U mydir/a -${PROG} checkout: Executing ..${CVSROOT_DIRNAME}/checkout\.sh. .mydir.. -checkout script invoked in ${TMPDIR}/cvs-serv[0-9a-z]* -args: mydir" - else - dotest modules5-38 "${testcvs} co -d mydir dirmodule/a" \ -"U mydir/a -${PROG} checkout: Executing ..${CVSROOT_DIRNAME}/checkout\.sh. .mydir.. -checkout script invoked in ${TESTDIR}/1 -args: mydir" - fi - dotest modules5-39 "test -d mydir && test -f mydir/a" "" - dotest_fail modules5-40 "test -d dirmodule || test -f mydir/b" "" - dotest modules5-41 "echo yes | ${testcvs} release -d mydir" \ -"You have \[0\] altered files in this repository\. -Are you sure you want to release (and delete) directory .mydir.: " - - # Now test the ability to correctly reject a non-existent filename. - # For maximum studliness we would check that an error message is - # being output. - # We accept a zero exit status because it is what CVS does - # (Dec 95). Probably the exit status should be nonzero, - # however. - if $remote; then - dotest modules5-42 "${testcvs} co -d mydir dirmodule/nonexist" \ -"${PROG} checkout: warning: new-born mydir/nonexist has disappeared -${PROG} checkout: Executing ..${CVSROOT_DIRNAME}/checkout\.sh. .mydir.. -checkout script invoked in ${TMPDIR}/cvs-serv[0-9a-z]* -args: mydir" - else - dotest modules5-42 "${testcvs} co -d mydir dirmodule/nonexist" \ -"${PROG} checkout: warning: new-born mydir/nonexist has disappeared -${PROG} checkout: Executing ..${CVSROOT_DIRNAME}/checkout\.sh. .mydir.. -checkout script invoked in ${TESTDIR}/1 -args: mydir" - fi - # We tolerate the creation of the mydir directory, since that - # is what CVS does, not because we view that as preferable to not - # creating it. - dotest_fail modules5-43 "test -f mydir/a || test -f mydir/b" "" - rm -r mydir - - if $remote; then - dotest modules5-44 "${testcvs} -q co -d mydir namedmodule" \ -"U mydir/a -U mydir/b -checkout script invoked in ${TMPDIR}/cvs-serv[0-9a-z]* -args: mydir" - else - dotest modules5-44 "${testcvs} -q co -d mydir namedmodule" \ -"U mydir/a -U mydir/b -checkout script invoked in ${TESTDIR}/1 -args: mydir" - fi - dotest modules5-45 "test -f mydir/a && test -f mydir/b" "" - dotest_fail modules5-46 "test -d namedir" - echo add line >>mydir/a - # This seems suspicious: when we checkout an existing directory, - # the checkout script gets executed in addition to the update - # script. Is that by design or accident? - if $remote; then - dotest modules5-47 "${testcvs} -q co -d mydir namedmodule" \ -"M mydir/a -checkout script invoked in ${TMPDIR}/cvs-serv[0-9a-z]* -args: mydir" - else - dotest modules5-47 "${testcvs} -q co -d mydir namedmodule" \ -"M mydir/a -checkout script invoked in ${TESTDIR}/1 -args: mydir" - fi - rm mydir/a - - if $remote; then - dotest modules5-48 "${testcvs} -q co -d mydir namedmodule" \ -"U mydir/a -checkout script invoked in ${TMPDIR}/cvs-serv[0-9a-z]* -args: mydir" - else - dotest modules5-48 "${testcvs} -q co -d mydir namedmodule" \ -"U mydir/a -checkout script invoked in ${TESTDIR}/1 -args: mydir" - fi - dotest modules5-49 "echo yes | ${testcvs} release -d mydir" \ -"You have \[0\] altered files in this repository\. -Are you sure you want to release (and delete) directory .mydir.: " - - cd .. - rm -rf 1 ${CVSROOT_DIRNAME}/first-dir ${CVSROOT_DIRNAME}/*.sh - ;; - - modules6) - # - # Test invalid module definitions - # - # See the header comment for the `modules' test for an index of - # the complete suite of modules tests. - # - - # - # There was a bug in CVS through 1.11.1p1 where a bad module name - # would cause the previous line to be parsed as the module - # definition. This test proves this doesn't happen anymore. - # - mkdir modules6 - cd modules6 - dotest module6-setup-1 "${testcvs} -Q co CVSROOT" "" - cd CVSROOT - echo "longmodulename who cares" >modules - echo "badname" >>modules - # This test almost isn't setup since it generates the error message - # we are looking for if `-Q' isn't specified, but I want to test the - # filename in the message later. - dotest modules6-setup-2 "${testcvs} -Q ci -mbad-modules" \ -"Checking in modules; -${CVSROOT_DIRNAME}/CVSROOT/modules,v <-- modules -new revision: [0-9.]*; previous revision: [0-9.]* -done -${PROG} commit: Rebuilding administrative file database" - - # Here's where CVS would report not being able to find `lename' - cd .. - dotest_fail modules6-1 "${testcvs} -q co badname" \ -"${PROG} checkout: warning: NULL value for key .badname. at line 2 of .${CVSROOT_DIRNAME}/CVSROOT/modules. -${PROG} checkout: cannot find module .badname. - ignored" \ -"${PROG} server: warning: NULL value for key .badname. at line 2 of .${CVSROOT_DIRNAME}/CVSROOT/modules. -${PROG} server: cannot find module .badname. - ignored -${PROG} \[checkout aborted\]: cannot expand modules" - - # cleanup - cd CVSROOT - echo "# empty modules file" >modules - dotest modules6-cleanup-1 "${testcvs} -Q ci -mempty-modules" \ -"Checking in modules; -${CVSROOT_DIRNAME}/CVSROOT/modules,v <-- modules -new revision: [0-9.]*; previous revision: [0-9.]* -done -${PROG} commit: Rebuilding administrative file database" - cd ../.. - - if $keep; then :; else - rm -r modules6 - fi - ;; - - - - modules7) - # - # Test tag problems vs an empty CVSROOT/val-tags file - # - # See the header comment for the `modules' test for an index of - # the complete suite of modules tests. - # - mkdir modules7 - cd modules7 - dotest modules7-1 "$testcvs -Q co -d top ." - cd top - mkdir zero one - dotest modules7-2 "$testcvs -Q add zero one" - cd one - echo 'file1 contents' > file1 - dotest modules7-2 "$testcvs -Q add file1" - dotest modules7-3 "$testcvs -Q ci -mnew file1" \ -"RCS file: $CVSROOT_DIRNAME/one/file1,v -done -Checking in file1; -$CVSROOT_DIRNAME/one/file1,v <-- file1 -initial revision: 1\.1 -done" - dotest modules7-4 "$testcvs -Q tag mytag file1" - cd ../CVSROOT - echo 'all -a zero one' > modules - dotest modules7-5 "$testcvs -Q ci -mall-module" \ -"Checking in modules; -$CVSROOT_DIRNAME/CVSROOT/modules,v <-- modules -new revision: [0-9.]*; previous revision: [0-9.]* -done -$PROG commit: Rebuilding administrative file database" - cd ../.. - mkdir myexport - cd myexport - # FIXCVS: The export should NOT be aborted here - dotest_fail modules7-6 "$testcvs export -rmytag all" \ -"$PROG \[export aborted\]: no such tag mytag" - cd .. - rm -fr myexport - mkdir myexport - cd myexport - # FIXCVS: Workaround is to have mytag listed in val-tags - echo 'mytag y' > $CVSROOT_DIRNAME/CVSROOT/val-tags - dotest modules7-7 "$testcvs export -rmytag all" \ -"$PROG export: Updating zero -$PROG export: Updating one -U one/file1" - dotest modules7-8 'cat one/file1' 'file1 contents' - - if $keep; then - echo Keeping $TESTDIR and exiting due to --keep - exit 0 - fi - - # cleanup - cd ../top/CVSROOT - echo "# empty modules file" >modules - dotest modules7-cleanup-1 "$testcvs -Q ci -mempty-modules" \ -"Checking in modules; -$CVSROOT_DIRNAME/CVSROOT/modules,v <-- modules -new revision: [0-9.]*; previous revision: [0-9.]* -done -$PROG commit: Rebuilding administrative file database" - cd ../../.. - rm -fr modules7 - rm -rf $CVSROOT_DIRNAME/zero $CVSROOT_DIRNAME/one - ;; - - - mkmodules) - # When a file listed in checkoutlist doesn't exist, cvs-1.10.4 - # would fail to remove the CVSROOT/.#[0-9]* temporary file it - # creates while mkmodules is in the process of trying to check - # out the missing file. - - mkdir 1; cd 1 - dotest mkmodules-temp-file-removal-1 "${testcvs} -Q co CVSROOT" '' - cd CVSROOT - echo no-such-file >> checkoutlist - dotest mkmodules-temp-file-removal-2 "${testcvs} -Q ci -m. checkoutlist" \ -"Checking in checkoutlist; -$CVSROOT_DIRNAME/CVSROOT/checkoutlist,v <-- checkoutlist -new revision: 1\.2; previous revision: 1\.1 -done -${PROG} commit: Rebuilding administrative file database" - - dotest mkmodules-temp-file-removal-3 "echo $CVSROOT_DIRNAME/CVSROOT/.#[0-9]*" \ - "$CVSROOT_DIRNAME/CVSROOT/\.#\[0-9\]\*" - - # Versions 1.11.6 & 1.12.1 and earlier of CVS printed most of the - # white space included before error messages in checkoutlist. - echo "no-such-file Failed to update no-such-file." >checkoutlist - dotest mkmodules-error-message-1 "${testcvs} -Q ci -m. checkoutlist" \ -"Checking in checkoutlist; -$CVSROOT_DIRNAME/CVSROOT/checkoutlist,v <-- checkoutlist -new revision: 1\.3; previous revision: 1\.2 -done -${PROG} commit: Rebuilding administrative file database -${PROG} commit: Failed to update no-such-file\." - - # Versions 1.11.6 & 1.12.1 and earlier of CVS used the error string - # from the checkoutlist file as the format string passed to error()'s - # printf. Check that this is no longer the case by verifying that - # printf format patterns remain unchanged. - echo "no-such-file Failed to update %s %lx times because %s happened %d times." >checkoutlist - dotest mkmodules-error-message-2 "${testcvs} -Q ci -m. checkoutlist" \ -"Checking in checkoutlist; -$CVSROOT_DIRNAME/CVSROOT/checkoutlist,v <-- checkoutlist -new revision: 1\.4; previous revision: 1\.3 -done -${PROG} commit: Rebuilding administrative file database -${PROG} commit: Failed to update %s %lx times because %s happened %d times\." - - dotest mkmodules-cleanup-1 "${testcvs} -Q up -pr1.1 checkoutlist >checkoutlist" - dotest mkmodules-cleanup-2 "${testcvs} -Q ci -m. checkoutlist" \ -"Checking in checkoutlist; -$CVSROOT_DIRNAME/CVSROOT/checkoutlist,v <-- checkoutlist -new revision: 1\.5; previous revision: 1\.4 -done -${PROG} commit: Rebuilding administrative file database" - - cd ../.. - rm -rf 1 - ;; - - co-d) - # Some tests of various permutations of co-d when directories exist - # and checkouts lengthen. - # - # Interestingly enough, these same tests pass when the directory - # lengthening happens via the modules file. Go figure. - module=co-d - mkdir $module; cd $module - mkdir top; cd top - dotest co-d-init-1 "$testcvs -Q co -l ." - mkdir $module - dotest co-d-init-2 "$testcvs -Q add $module" - cd $module - echo content >file1 - echo different content >file2 - dotest co-d-init-3 "$testcvs -Q add file1 file2" - dotest co-d-init-4 "$testcvs -Q ci -madd-em" \ -"RCS file: $CVSROOT_DIRNAME/co-d/file1,v -done -Checking in file1; -$CVSROOT_DIRNAME/co-d/file1,v <-- file1 -initial revision: 1\.1 -done -RCS file: $CVSROOT_DIRNAME/co-d/file2,v -done -Checking in file2; -$CVSROOT_DIRNAME/co-d/file2,v <-- file2 -initial revision: 1\.1 -done" - cd ../.. - - mkdir 2; cd 2 - dotest co-d-1 "$testcvs -q co -d dir $module" \ -"U dir/file1 -U dir/file2" - dotest co-d-1.2 "cat dir/CVS/Repository" "$module" - - # FIXCVS: This should work. Correct expected result: - # - #"U dir2/sdir/file1 - #U dir2/sdir/file2" - dotest_fail co-d-2 "$testcvs -q co -d dir2/sdir $module" \ -"$PROG \[checkout aborted\]: could not change directory to requested checkout directory \`dir2': No such file or directory" - # FIXCVS: - # dotest co-d-2.2 "cat dir4/CVS/Repository" "CVSROOT/Emptydir" - # dotest co-d-2.3 "cat dir5/CVS/Repository" "$module" - - mkdir dir3 - dotest co-d-3 "$testcvs -q co -d dir3 $module" \ -"U dir3/file1 -U dir3/file2" - dotest co-d-3.2 "cat dir3/CVS/Repository" "$module" - - if $remote; then - # FIXCVS: As for co-d-2. - mkdir dir4 - dotest_fail co-d-4r "$testcvs -q co -d dir4/sdir $module" \ -"$PROG \[checkout aborted\]: could not change directory to requested checkout directory \`dir4': No such file or directory" - - # FIXCVS: As for co-d-2. - mkdir dir5 - mkdir dir5/sdir - dotest_fail co-d-5r "$testcvs -q co -d dir5/sdir $module" \ -"$PROG \[checkout aborted\]: could not change directory to requested checkout directory \`dir5': No such file or directory" - else - mkdir dir4 - dotest co-d-4 "$testcvs -q co -d dir4/sdir $module" \ -"U dir4/sdir/file1 -U dir4/sdir/file2" - # CVS only creates administration directories for directories it - # creates, and the last portion of the path passed to -d - # regardless. - dotest_fail co-d-4.2 "test -d dir4/CVS" - dotest co-d-4.3 "cat dir4/sdir/CVS/Repository" "$module" - - mkdir dir5 - mkdir dir5/sdir - dotest co-d-5 "$testcvs -q co -d dir5/sdir $module" \ -"U dir5/sdir/file1 -U dir5/sdir/file2" - # CVS only creates administration directories for directories it - # creates, and the last portion of the path passed to -d - # regardless. - dotest_fail co-d-5.2 "test -d dir5/CVS" - dotest co-d-5.3 "cat dir5/sdir/CVS/Repository" "$module" - fi - - # clean up - if $keep; then - echo Keeping ${TESTDIR} and exiting due to --keep - exit 0 - fi - - cd ../.. - rm -rf $CVSROOT_DIRNAME/$module - rm -r $module - ;; - - cvsadm) - # These test check the content of CVS' administrative - # files as they are checked out in various configurations. - # (As a side note, I'm not using the "-q" flag in any of - # this code, which should provide some extra checking for - # those messages which don't seem to be checked thoroughly - # anywhere else.) To do a thorough test, we need to make - # a bunch of modules in various configurations. - # - # <1mod> is a directory at the top level of cvsroot - # ``foo bar'' - # <2mod> is a directory at the second level of cvsroot - # ``foo bar/baz'' - # <1d1mod> is a directory at the top level which is - # checked out into another directory - # ``foo -d bar baz'' - # <1d2mod> is a directory at the second level which is - # checked out into another directory - # ``foo -d bar baz/quux'' - # <2d1mod> is a directory at the top level which is - # checked out into a directory that is two deep - # ``foo -d bar/baz quux'' - # <2d2mod> is a directory at the second level which is - # checked out into a directory that is two deep - # ``foo -d bar/baz quux'' - # - # The tests do each of these types separately and in twos. - # We also repeat each test -d flag for 1-deep and 2-deep - # directories. - # - # Each test should check the output for the Repository - # file, since that is the one which varies depending on - # the directory and how it was checked out. - # - # Yes, this is verbose, but at least it's very thorough. - - # convenience variables - REP=${CVSROOT} - - # First, set TopLevelAdmin=yes so we're sure to get - # top-level CVS directories. - mkdir 1; cd 1 - dotest cvsadm-setup-1 "${testcvs} -q co CVSROOT/config" \ -"U CVSROOT/config" - cd CVSROOT - echo "TopLevelAdmin=yes" >config - dotest cvsadm-setup-2 "${testcvs} -q ci -m yes-top-level" \ -"Checking in config; -${CVSROOT_DIRNAME}/CVSROOT/config,v <-- config -new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* -done -${PROG} commit: Rebuilding administrative file database" - cd ../.. - rm -r 1 - - # Second, check out the modules file and edit it. - mkdir 1; cd 1 - dotest cvsadm-1 "${testcvs} co CVSROOT/modules" \ -"U CVSROOT/modules" - - # Test CVS/Root once. Since there is only one part of - # the code which writes CVS/Root files (Create_Admin), - # there is no point in testing this every time. - dotest cvsadm-1a "cat CVS/Root" ${REP} - dotest cvsadm-1b "cat CVS/Repository" "\." - dotest cvsadm-1c "cat CVSROOT/CVS/Root" ${REP} - dotest cvsadm-1d "cat CVSROOT/CVS/Repository" "CVSROOT" - # All of the defined module names begin with a number. - # All of the top-level directory names begin with "dir". - # All of the subdirectory names begin with "sub". - # All of the top-level modules begin with "mod". - echo "# Module defs for cvsadm tests" > CVSROOT/modules - echo "1mod mod1" >> CVSROOT/modules - echo "1mod-2 mod1-2" >> CVSROOT/modules - echo "2mod mod2/sub2" >> CVSROOT/modules - echo "2mod-2 mod2-2/sub2-2" >> CVSROOT/modules - echo "1d1mod -d dir1d1 mod1" >> CVSROOT/modules - echo "1d1mod-2 -d dir1d1-2 mod1-2" >> CVSROOT/modules - echo "1d2mod -d dir1d2 mod2/sub2" >> CVSROOT/modules - echo "1d2mod-2 -d dir1d2-2 mod2-2/sub2-2" >> CVSROOT/modules - echo "2d1mod -d dir2d1/sub2d1 mod1" >> CVSROOT/modules - echo "2d1mod-2 -d dir2d1-2/sub2d1-2 mod1-2" >> CVSROOT/modules - echo "2d2mod -d dir2d2/sub2d2 mod2/sub2" >> CVSROOT/modules - echo "2d2mod-2 -d dir2d2-2/sub2d2-2 mod2-2/sub2-2" >> CVSROOT/modules - dotest cvsadm-1e "${testcvs} ci -m add-modules" \ -"${PROG} [a-z]*: Examining . -${PROG} [a-z]*: Examining CVSROOT -Checking in CVSROOT/modules; -${CVSROOT_DIRNAME}/CVSROOT/modules,v <-- modules -new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* -done -${PROG} commit: Rebuilding administrative file database" \ -"${PROG} commit: Examining . -${PROG} commit: Examining CVSROOT" - rm -rf CVS CVSROOT; - - # Create the various modules - dotest cvsadm-2 "${testcvs} -q co -l ." '' - mkdir mod1 - mkdir mod1-2 - mkdir mod2 - mkdir mod2/sub2 - mkdir mod2-2 - mkdir mod2-2/sub2-2 - dotest cvsadm-2a "${testcvs} add mod1 mod1-2 mod2 mod2/sub2 mod2-2 mod2-2/sub2-2" \ -"Directory ${CVSROOT_DIRNAME}/mod1 added to the repository -Directory ${CVSROOT_DIRNAME}/mod1-2 added to the repository -Directory ${CVSROOT_DIRNAME}/mod2 added to the repository -Directory ${CVSROOT_DIRNAME}/mod2/sub2 added to the repository -Directory ${CVSROOT_DIRNAME}/mod2-2 added to the repository -Directory ${CVSROOT_DIRNAME}/mod2-2/sub2-2 added to the repository" - - # Populate the directories for the halibut - echo "file1" > mod1/file1 - echo "file1-2" > mod1-2/file1-2 - echo "file2" > mod2/sub2/file2 - echo "file2-2" > mod2-2/sub2-2/file2-2 - dotest cvsadm-2aa "${testcvs} add mod1/file1 mod1-2/file1-2 mod2/sub2/file2 mod2-2/sub2-2/file2-2" \ -"${PROG} add: scheduling file .mod1/file1. for addition -${PROG} add: scheduling file .mod1-2/file1-2. for addition -${PROG} add: scheduling file .mod2/sub2/file2. for addition -${PROG} add: scheduling file .mod2-2/sub2-2/file2-2. for addition -${PROG} add: use .${PROG} commit. to add these files permanently" - - dotest cvsadm-2b "${testcvs} ci -m yup mod1 mod1-2 mod2 mod2-2" \ -"${PROG} [a-z]*: Examining mod1 -${PROG} [a-z]*: Examining mod1-2 -${PROG} [a-z]*: Examining mod2 -${PROG} [a-z]*: Examining mod2/sub2 -${PROG} [a-z]*: Examining mod2-2 -${PROG} [a-z]*: Examining mod2-2/sub2-2 -RCS file: ${CVSROOT_DIRNAME}/mod1/file1,v -done -Checking in mod1/file1; -${CVSROOT_DIRNAME}/mod1/file1,v <-- file1 -initial revision: 1.1 -done -RCS file: ${CVSROOT_DIRNAME}/mod1-2/file1-2,v -done -Checking in mod1-2/file1-2; -${CVSROOT_DIRNAME}/mod1-2/file1-2,v <-- file1-2 -initial revision: 1.1 -done -RCS file: ${CVSROOT_DIRNAME}/mod2/sub2/file2,v -done -Checking in mod2/sub2/file2; -${CVSROOT_DIRNAME}/mod2/sub2/file2,v <-- file2 -initial revision: 1.1 -done -RCS file: ${CVSROOT_DIRNAME}/mod2-2/sub2-2/file2-2,v -done -Checking in mod2-2/sub2-2/file2-2; -${CVSROOT_DIRNAME}/mod2-2/sub2-2/file2-2,v <-- file2-2 -initial revision: 1.1 -done" - # Finished creating the modules -- clean up. - rm -rf CVS mod1 mod1-2 mod2 mod2-2 - # Done. - - ################################################## - ## Start the dizzying array of possibilities. - ## Begin with each module type separately. - ################################################## - - # Pattern -- after each checkout, first check the top-level - # CVS directory. Then, check the directories in numerical - # order. - - dotest cvsadm-3 "${testcvs} co 1mod" \ -"${PROG} checkout: Updating 1mod -U 1mod/file1" - dotest cvsadm-3b "cat CVS/Repository" "\." - dotest cvsadm-3d "cat 1mod/CVS/Repository" "mod1" - rm -rf CVS 1mod - - dotest cvsadm-4 "${testcvs} co 2mod" \ -"${PROG} checkout: Updating 2mod -U 2mod/file2" - dotest cvsadm-4b "cat CVS/Repository" "\." - dotest cvsadm-4d "cat 2mod/CVS/Repository" "mod2/sub2" - rm -rf CVS 2mod - - dotest cvsadm-5 "${testcvs} co 1d1mod" \ -"${PROG} checkout: Updating dir1d1 -U dir1d1/file1" - dotest cvsadm-5b "cat CVS/Repository" "\." - dotest cvsadm-5d "cat dir1d1/CVS/Repository" "mod1" - rm -rf CVS dir1d1 - - dotest cvsadm-6 "${testcvs} co 1d2mod" \ -"${PROG} checkout: Updating dir1d2 -U dir1d2/file2" - dotest cvsadm-6b "cat CVS/Repository" "\." - dotest cvsadm-6d "cat dir1d2/CVS/Repository" "mod2/sub2" - rm -rf CVS dir1d2 - - dotest cvsadm-7 "${testcvs} co 2d1mod" \ -"${PROG} checkout: Updating dir2d1/sub2d1 -U dir2d1/sub2d1/file1" - dotest cvsadm-7b "cat CVS/Repository" "\." - dotest cvsadm-7d "cat dir2d1/CVS/Repository" "\." - dotest cvsadm-7f "cat dir2d1/sub2d1/CVS/Repository" "mod1" - rm -rf CVS dir2d1 - - dotest cvsadm-8 "${testcvs} co 2d2mod" \ -"${PROG} checkout: Updating dir2d2/sub2d2 -U dir2d2/sub2d2/file2" - dotest cvsadm-8b "cat CVS/Repository" "\." - dotest cvsadm-8d "cat dir2d2/CVS/Repository" "mod2" - dotest cvsadm-8f "cat dir2d2/sub2d2/CVS/Repository" "mod2/sub2" - rm -rf CVS dir2d2 - - ################################################## - ## You are in a shell script of twisted little - ## module combination statements, all alike. - ################################################## - - ### 1mod - - dotest cvsadm-9 "${testcvs} co 1mod 1mod-2" \ -"${PROG} checkout: Updating 1mod -U 1mod/file1 -${PROG} checkout: Updating 1mod-2 -U 1mod-2/file1-2" - # the usual for the top level - dotest cvsadm-9b "cat CVS/Repository" "\." - # the usual for 1mod - dotest cvsadm-9d "cat 1mod/CVS/Repository" "mod1" - # the usual for 1mod copy - dotest cvsadm-9f "cat 1mod-2/CVS/Repository" "mod1-2" - rm -rf CVS 1mod 1mod-2 - - # 1mod 2mod redmod bluemod - dotest cvsadm-10 "${testcvs} co 1mod 2mod" \ -"${PROG} checkout: Updating 1mod -U 1mod/file1 -${PROG} checkout: Updating 2mod -U 2mod/file2" - # the usual for the top level - dotest cvsadm-10b "cat CVS/Repository" "\." - # the usual for 1mod - dotest cvsadm-10d "cat 1mod/CVS/Repository" "mod1" - # the usual for 2dmod - dotest cvsadm-10f "cat 2mod/CVS/Repository" "mod2/sub2" - rm -rf CVS 1mod 2mod - - dotest cvsadm-11 "${testcvs} co 1mod 1d1mod" \ -"${PROG} checkout: Updating 1mod -U 1mod/file1 -${PROG} checkout: Updating dir1d1 -U dir1d1/file1" - # the usual for the top level - dotest cvsadm-11b "cat CVS/Repository" "\." - # the usual for 1mod - dotest cvsadm-11d "cat 1mod/CVS/Repository" "mod1" - # the usual for 1d1mod - dotest cvsadm-11f "cat dir1d1/CVS/Repository" "mod1" - rm -rf CVS 1mod dir1d1 - - dotest cvsadm-12 "${testcvs} co 1mod 1d2mod" \ -"${PROG} checkout: Updating 1mod -U 1mod/file1 -${PROG} checkout: Updating dir1d2 -U dir1d2/file2" - # the usual for the top level - dotest cvsadm-12b "cat CVS/Repository" "\." - # the usual for 1mod - dotest cvsadm-12d "cat 1mod/CVS/Repository" "mod1" - # the usual for 1d2mod - dotest cvsadm-12f "cat dir1d2/CVS/Repository" "mod2/sub2" - rm -rf CVS 1mod dir1d2 - - dotest cvsadm-13 "${testcvs} co 1mod 2d1mod" \ -"${PROG} checkout: Updating 1mod -U 1mod/file1 -${PROG} checkout: Updating dir2d1/sub2d1 -U dir2d1/sub2d1/file1" - # the usual for the top level - dotest cvsadm-13b "cat CVS/Repository" "\." - # the usual for 1mod - dotest cvsadm-13d "cat 1mod/CVS/Repository" "mod1" - # the usual for 2d1mod - dotest cvsadm-13f "cat dir2d1/CVS/Repository" "\." - dotest cvsadm-13h "cat dir2d1/sub2d1/CVS/Repository" "mod1" - rm -rf CVS 1mod dir2d1 - - dotest cvsadm-14 "${testcvs} co 1mod 2d2mod" \ -"${PROG} checkout: Updating 1mod -U 1mod/file1 -${PROG} checkout: Updating dir2d2/sub2d2 -U dir2d2/sub2d2/file2" - # the usual for the top level - dotest cvsadm-14b "cat CVS/Repository" "\." - # the usual for 1mod - dotest cvsadm-14d "cat 1mod/CVS/Repository" "mod1" - # the usual for 2d2mod - dotest cvsadm-14f "cat dir2d2/CVS/Repository" "mod2" - dotest cvsadm-14h "cat dir2d2/sub2d2/CVS/Repository" "mod2/sub2" - rm -rf CVS 1mod dir2d2 - - - ### 2mod - - dotest cvsadm-15 "${testcvs} co 2mod 2mod-2" \ -"${PROG} checkout: Updating 2mod -U 2mod/file2 -${PROG} checkout: Updating 2mod-2 -U 2mod-2/file2-2" - # the usual for the top level - dotest cvsadm-15b "cat CVS/Repository" "\." - # the usual for 2mod - dotest cvsadm-15d "cat 2mod/CVS/Repository" "mod2/sub2" - # the usual for 2mod copy - dotest cvsadm-15f "cat 2mod-2/CVS/Repository" "mod2-2/sub2-2" - rm -rf CVS 2mod 2mod-2 - - - dotest cvsadm-16 "${testcvs} co 2mod 1d1mod" \ -"${PROG} checkout: Updating 2mod -U 2mod/file2 -${PROG} checkout: Updating dir1d1 -U dir1d1/file1" - # the usual for the top level - dotest cvsadm-16b "cat CVS/Repository" "\." - # the usual for 2mod - dotest cvsadm-16d "cat 2mod/CVS/Repository" "mod2/sub2" - # the usual for 1d1mod - dotest cvsadm-16f "cat dir1d1/CVS/Repository" "mod1" - rm -rf CVS 2mod dir1d1 - - dotest cvsadm-17 "${testcvs} co 2mod 1d2mod" \ -"${PROG} checkout: Updating 2mod -U 2mod/file2 -${PROG} checkout: Updating dir1d2 -U dir1d2/file2" - # the usual for the top level - dotest cvsadm-17b "cat CVS/Repository" "\." - # the usual for 2mod - dotest cvsadm-17d "cat 2mod/CVS/Repository" "mod2/sub2" - # the usual for 1d2mod - dotest cvsadm-17f "cat dir1d2/CVS/Repository" "mod2/sub2" - rm -rf CVS 2mod dir1d2 - - dotest cvsadm-18 "${testcvs} co 2mod 2d1mod" \ -"${PROG} checkout: Updating 2mod -U 2mod/file2 -${PROG} checkout: Updating dir2d1/sub2d1 -U dir2d1/sub2d1/file1" - # the usual for the top level - dotest cvsadm-18b "cat CVS/Repository" "\." - # the usual for 2mod - dotest cvsadm-18d "cat 2mod/CVS/Repository" "mod2/sub2" - # the usual for 2d1mod - dotest cvsadm-18f "cat dir2d1/CVS/Repository" "\." - dotest cvsadm-18h "cat dir2d1/sub2d1/CVS/Repository" "mod1" - rm -rf CVS 2mod dir2d1 - - dotest cvsadm-19 "${testcvs} co 2mod 2d2mod" \ -"${PROG} checkout: Updating 2mod -U 2mod/file2 -${PROG} checkout: Updating dir2d2/sub2d2 -U dir2d2/sub2d2/file2" - # the usual for the top level - dotest cvsadm-19b "cat CVS/Repository" "\." - # the usual for 2mod - dotest cvsadm-19d "cat 2mod/CVS/Repository" "mod2/sub2" - # the usual for 2d2mod - dotest cvsadm-19f "cat dir2d2/CVS/Repository" "mod2" - dotest cvsadm-19h "cat dir2d2/sub2d2/CVS/Repository" "mod2/sub2" - rm -rf CVS 2mod dir2d2 - - - ### 1d1mod - - dotest cvsadm-20 "${testcvs} co 1d1mod 1d1mod-2" \ -"${PROG} checkout: Updating dir1d1 -U dir1d1/file1 -${PROG} checkout: Updating dir1d1-2 -U dir1d1-2/file1-2" - # the usual for the top level - dotest cvsadm-20b "cat CVS/Repository" "\." - # the usual for 1d1mod - dotest cvsadm-20d "cat dir1d1/CVS/Repository" "mod1" - # the usual for 1d1mod copy - dotest cvsadm-20f "cat dir1d1-2/CVS/Repository" "mod1-2" - rm -rf CVS dir1d1 dir1d1-2 - - dotest cvsadm-21 "${testcvs} co 1d1mod 1d2mod" \ -"${PROG} checkout: Updating dir1d1 -U dir1d1/file1 -${PROG} checkout: Updating dir1d2 -U dir1d2/file2" - # the usual for the top level - dotest cvsadm-21b "cat CVS/Repository" "\." - # the usual for 1d1mod - dotest cvsadm-21d "cat dir1d1/CVS/Repository" "mod1" - # the usual for 1d2mod - dotest cvsadm-21f "cat dir1d2/CVS/Repository" "mod2/sub2" - rm -rf CVS dir1d1 dir1d2 - - dotest cvsadm-22 "${testcvs} co 1d1mod 2d1mod" \ -"${PROG} checkout: Updating dir1d1 -U dir1d1/file1 -${PROG} checkout: Updating dir2d1/sub2d1 -U dir2d1/sub2d1/file1" - # the usual for the top level - dotest cvsadm-22b "cat CVS/Repository" "\." - # the usual for 1d1mod - dotest cvsadm-22d "cat dir1d1/CVS/Repository" "mod1" - # the usual for 2d1mod - dotest cvsadm-22f "cat dir2d1/CVS/Repository" "\." - dotest cvsadm-22h "cat dir2d1/sub2d1/CVS/Repository" "mod1" - rm -rf CVS dir1d1 dir2d1 - - dotest cvsadm-23 "${testcvs} co 1d1mod 2d2mod" \ -"${PROG} checkout: Updating dir1d1 -U dir1d1/file1 -${PROG} checkout: Updating dir2d2/sub2d2 -U dir2d2/sub2d2/file2" - # the usual for the top level - dotest cvsadm-23b "cat CVS/Repository" "\." - # the usual for 1d1mod - dotest cvsadm-23d "cat dir1d1/CVS/Repository" "mod1" - # the usual for 2d2mod - dotest cvsadm-23f "cat dir2d2/CVS/Repository" "mod2" - dotest cvsadm-23h "cat dir2d2/sub2d2/CVS/Repository" "mod2/sub2" - rm -rf CVS dir1d1 dir2d2 - - - ### 1d2mod - - dotest cvsadm-24 "${testcvs} co 1d2mod 1d2mod-2" \ -"${PROG} checkout: Updating dir1d2 -U dir1d2/file2 -${PROG} checkout: Updating dir1d2-2 -U dir1d2-2/file2-2" - # the usual for the top level - dotest cvsadm-24b "cat CVS/Repository" "\." - # the usual for 1d2mod - dotest cvsadm-24d "cat dir1d2/CVS/Repository" "mod2/sub2" - # the usual for 1d2mod copy - dotest cvsadm-24f "cat dir1d2-2/CVS/Repository" "mod2-2/sub2-2" - rm -rf CVS dir1d2 dir1d2-2 - - dotest cvsadm-25 "${testcvs} co 1d2mod 2d1mod" \ -"${PROG} checkout: Updating dir1d2 -U dir1d2/file2 -${PROG} checkout: Updating dir2d1/sub2d1 -U dir2d1/sub2d1/file1" - # the usual for the top level - dotest cvsadm-25b "cat CVS/Repository" "\." - # the usual for 1d2mod - dotest cvsadm-25d "cat dir1d2/CVS/Repository" "mod2/sub2" - # the usual for 2d1mod - dotest cvsadm-25f "cat dir2d1/CVS/Repository" "\." - dotest cvsadm-25h "cat dir2d1/sub2d1/CVS/Repository" "mod1" - rm -rf CVS dir1d2 dir2d1 - - dotest cvsadm-26 "${testcvs} co 1d2mod 2d2mod" \ -"${PROG} checkout: Updating dir1d2 -U dir1d2/file2 -${PROG} checkout: Updating dir2d2/sub2d2 -U dir2d2/sub2d2/file2" - # the usual for the top level - dotest cvsadm-26b "cat CVS/Repository" "\." - # the usual for 1d2mod - dotest cvsadm-26d "cat dir1d2/CVS/Repository" "mod2/sub2" - # the usual for 2d2mod - dotest cvsadm-26f "cat dir2d2/CVS/Repository" "mod2" - dotest cvsadm-26h "cat dir2d2/sub2d2/CVS/Repository" "mod2/sub2" - rm -rf CVS dir1d2 dir2d2 - - - # 2d1mod - - dotest cvsadm-27 "${testcvs} co 2d1mod 2d1mod-2" \ -"${PROG} checkout: Updating dir2d1/sub2d1 -U dir2d1/sub2d1/file1 -${PROG} checkout: Updating dir2d1-2/sub2d1-2 -U dir2d1-2/sub2d1-2/file1-2" - # the usual for the top level - dotest cvsadm-27b "cat CVS/Repository" "\." - # the usual for 2d1mod - dotest cvsadm-27d "cat dir2d1/CVS/Repository" "\." - dotest cvsadm-27f "cat dir2d1/sub2d1/CVS/Repository" "mod1" - # the usual for 2d1mod - dotest cvsadm-27h "cat dir2d1-2/CVS/Repository" "\." - dotest cvsadm-27j "cat dir2d1-2/sub2d1-2/CVS/Repository" "mod1-2" - rm -rf CVS dir2d1 dir2d1-2 - - dotest cvsadm-28 "${testcvs} co 2d1mod 2d2mod" \ -"${PROG} checkout: Updating dir2d1/sub2d1 -U dir2d1/sub2d1/file1 -${PROG} checkout: Updating dir2d2/sub2d2 -U dir2d2/sub2d2/file2" - # the usual for the top level - dotest cvsadm-28b "cat CVS/Repository" "\." - # the usual for 2d1mod - dotest cvsadm-28d "cat dir2d1/CVS/Repository" "\." - dotest cvsadm-28f "cat dir2d1/sub2d1/CVS/Repository" "mod1" - # the usual for 2d2mod - dotest cvsadm-28h "cat dir2d2/CVS/Repository" "mod2" - dotest cvsadm-28j "cat dir2d2/sub2d2/CVS/Repository" "mod2/sub2" - rm -rf CVS dir2d1 dir2d2 - - - # 2d2mod - - dotest cvsadm-29 "${testcvs} co 2d2mod 2d2mod-2" \ -"${PROG} checkout: Updating dir2d2/sub2d2 -U dir2d2/sub2d2/file2 -${PROG} checkout: Updating dir2d2-2/sub2d2-2 -U dir2d2-2/sub2d2-2/file2-2" - # the usual for the top level - dotest cvsadm-29b "cat CVS/Repository" "\." - # the usual for 2d2mod - dotest cvsadm-29d "cat dir2d2/CVS/Repository" "mod2" - dotest cvsadm-29f "cat dir2d2/sub2d2/CVS/Repository" "mod2/sub2" - # the usual for 2d2mod - dotest cvsadm-29h "cat dir2d2-2/CVS/Repository" "mod2-2" - dotest cvsadm-29j "cat dir2d2-2/sub2d2-2/CVS/Repository" \ -"mod2-2/sub2-2" - rm -rf CVS dir2d2 dir2d2-2 - - ################################################## - ## And now, all of that again using the "-d" flag - ## on the command line. - ################################################## - - dotest cvsadm-1d3 "${testcvs} co -d dir 1mod" \ -"${PROG} checkout: Updating dir -U dir/file1" - dotest cvsadm-1d3b "cat CVS/Repository" "\." - dotest cvsadm-1d3d "cat dir/CVS/Repository" "mod1" - rm -rf CVS dir - - dotest cvsadm-1d4 "${testcvs} co -d dir 2mod" \ -"${PROG} checkout: Updating dir -U dir/file2" - dotest cvsadm-1d4b "cat CVS/Repository" "\." - dotest cvsadm-1d4d "cat dir/CVS/Repository" "mod2/sub2" - rm -rf CVS dir - - dotest cvsadm-1d5 "${testcvs} co -d dir 1d1mod" \ -"${PROG} checkout: Updating dir -U dir/file1" - dotest cvsadm-1d5b "cat CVS/Repository" "\." - dotest cvsadm-1d5d "cat dir/CVS/Repository" "mod1" - rm -rf CVS dir - - dotest cvsadm-1d6 "${testcvs} co -d dir 1d2mod" \ -"${PROG} checkout: Updating dir -U dir/file2" - dotest cvsadm-1d6b "cat CVS/Repository" "\." - dotest cvsadm-1d6d "cat dir/CVS/Repository" "mod2/sub2" - rm -rf CVS dir - - dotest cvsadm-1d7 "${testcvs} co -d dir 2d1mod" \ -"${PROG} checkout: Updating dir -U dir/file1" - dotest cvsadm-1d7b "cat CVS/Repository" "\." - dotest cvsadm-1d7d "cat dir/CVS/Repository" "mod1" - rm -rf CVS dir - - dotest cvsadm-1d8 "${testcvs} co -d dir 2d2mod" \ -"${PROG} checkout: Updating dir -U dir/file2" - dotest cvsadm-1d8b "cat CVS/Repository" "\." - dotest cvsadm-1d8d "cat dir/CVS/Repository" "mod2/sub2" - rm -rf CVS dir - - ################################################## - ## Los Combonaciones - ################################################## - - ### 1mod - - dotest cvsadm-1d9 "${testcvs} co -d dir 1mod 1mod-2" \ -"${PROG} checkout: Updating dir/1mod -U dir/1mod/file1 -${PROG} checkout: Updating dir/1mod-2 -U dir/1mod-2/file1-2" - # the usual for the top level - dotest cvsadm-1d9b "cat CVS/Repository" "\." - # the usual for the dir level - dotest cvsadm-1d9d "cat dir/CVS/Repository" "\." - # the usual for 1mod - dotest cvsadm-1d9f "cat dir/1mod/CVS/Repository" "mod1" - # the usual for 1mod copy - dotest cvsadm-1d9h "cat dir/1mod-2/CVS/Repository" "mod1-2" - rm -rf CVS dir - - # 1mod 2mod redmod bluemod - dotest cvsadm-1d10 "${testcvs} co -d dir 1mod 2mod" \ -"${PROG} checkout: Updating dir/1mod -U dir/1mod/file1 -${PROG} checkout: Updating dir/2mod -U dir/2mod/file2" - dotest cvsadm-1d10b "cat CVS/Repository" "\." - # the usual for the dir level - dotest cvsadm-1d10d "cat dir/CVS/Repository" "\." - # the usual for 1mod - dotest cvsadm-1d10f "cat dir/1mod/CVS/Repository" "mod1" - # the usual for 2dmod - dotest cvsadm-1d10h "cat dir/2mod/CVS/Repository" "mod2/sub2" - rm -rf CVS dir - - dotest cvsadm-1d11 "${testcvs} co -d dir 1mod 1d1mod" \ -"${PROG} checkout: Updating dir/1mod -U dir/1mod/file1 -${PROG} checkout: Updating dir/dir1d1 -U dir/dir1d1/file1" - dotest cvsadm-1d11b "cat CVS/Repository" "\." - # the usual for the dir level - dotest cvsadm-1d11d "cat dir/CVS/Repository" "\." - # the usual for 1mod - dotest cvsadm-1d11f "cat dir/1mod/CVS/Repository" "mod1" - # the usual for 1d1mod - dotest cvsadm-1d11h "cat dir/dir1d1/CVS/Repository" "mod1" - rm -rf CVS dir - - dotest cvsadm-1d12 "${testcvs} co -d dir 1mod 1d2mod" \ -"${PROG} checkout: Updating dir/1mod -U dir/1mod/file1 -${PROG} checkout: Updating dir/dir1d2 -U dir/dir1d2/file2" - dotest cvsadm-1d12b "cat CVS/Repository" "\." - # the usual for the dir level - dotest cvsadm-1d12d "cat dir/CVS/Repository" "\." - # the usual for 1mod - dotest cvsadm-1d12f "cat dir/1mod/CVS/Repository" "mod1" - # the usual for 1d2mod - dotest cvsadm-1d12h "cat dir/dir1d2/CVS/Repository" "mod2/sub2" - rm -rf CVS dir - - dotest cvsadm-1d13 "${testcvs} co -d dir 1mod 2d1mod" \ -"${PROG} checkout: Updating dir/1mod -U dir/1mod/file1 -${PROG} checkout: Updating dir/dir2d1/sub2d1 -U dir/dir2d1/sub2d1/file1" - dotest cvsadm-1d13b "cat CVS/Repository" "\." - # the usual for the dir level - dotest cvsadm-1d13d "cat dir/CVS/Repository" "\." - # the usual for 1mod - dotest cvsadm-1d13f "cat dir/1mod/CVS/Repository" "mod1" - # the usual for 2d1mod - dotest cvsadm-1d13h "cat dir/dir2d1/CVS/Repository" "\." - dotest cvsadm-1d13j "cat dir/dir2d1/sub2d1/CVS/Repository" "mod1" - rm -rf CVS dir - - dotest cvsadm-1d14 "${testcvs} co -d dir 1mod 2d2mod" \ -"${PROG} checkout: Updating dir/1mod -U dir/1mod/file1 -${PROG} checkout: Updating dir/dir2d2/sub2d2 -U dir/dir2d2/sub2d2/file2" - dotest cvsadm-1d14b "cat CVS/Repository" "\." - # the usual for the dir level - dotest cvsadm-1d14d "cat dir/CVS/Repository" "\." - # the usual for 1mod - dotest cvsadm-1d14f "cat dir/1mod/CVS/Repository" "mod1" - # the usual for 2d2mod - dotest cvsadm-1d14h "cat dir/dir2d2/CVS/Repository" "mod2" - dotest cvsadm-1d14j "cat dir/dir2d2/sub2d2/CVS/Repository" "mod2/sub2" - rm -rf CVS dir - - - ### 2mod - - dotest cvsadm-1d15 "${testcvs} co -d dir 2mod 2mod-2" \ -"${PROG} checkout: Updating dir/2mod -U dir/2mod/file2 -${PROG} checkout: Updating dir/2mod-2 -U dir/2mod-2/file2-2" - dotest cvsadm-1d15b "cat CVS/Repository" "\." - # the usual for the dir level - dotest cvsadm-1d15d "cat dir/CVS/Repository" "mod2" - # the usual for 2mod - dotest cvsadm-1d15f "cat dir/2mod/CVS/Repository" "mod2/sub2" - # the usual for 2mod copy - dotest cvsadm-1d15h "cat dir/2mod-2/CVS/Repository" "mod2-2/sub2-2" - rm -rf CVS dir - - dotest cvsadm-1d16 "${testcvs} co -d dir 2mod 1d1mod" \ -"${PROG} checkout: Updating dir/2mod -U dir/2mod/file2 -${PROG} checkout: Updating dir/dir1d1 -U dir/dir1d1/file1" - dotest cvsadm-1d16b "cat CVS/Repository" "\." - # the usual for the dir level - dotest cvsadm-1d16d "cat dir/CVS/Repository" "mod2" - # the usual for 2mod - dotest cvsadm-1d16f "cat dir/2mod/CVS/Repository" "mod2/sub2" - # the usual for 1d1mod - dotest cvsadm-1d16h "cat dir/dir1d1/CVS/Repository" "mod1" - rm -rf CVS dir - - dotest cvsadm-1d17 "${testcvs} co -d dir 2mod 1d2mod" \ -"${PROG} checkout: Updating dir/2mod -U dir/2mod/file2 -${PROG} checkout: Updating dir/dir1d2 -U dir/dir1d2/file2" - dotest cvsadm-1d17b "cat CVS/Repository" "\." - # the usual for the dir level - dotest cvsadm-1d17d "cat dir/CVS/Repository" "mod2" - # the usual for 2mod - dotest cvsadm-1d17f "cat dir/2mod/CVS/Repository" "mod2/sub2" - # the usual for 1d2mod - dotest cvsadm-1d17h "cat dir/dir1d2/CVS/Repository" "mod2/sub2" - rm -rf CVS dir - - dotest cvsadm-1d18 "${testcvs} co -d dir 2mod 2d1mod" \ -"${PROG} checkout: Updating dir/2mod -U dir/2mod/file2 -${PROG} checkout: Updating dir/dir2d1/sub2d1 -U dir/dir2d1/sub2d1/file1" - dotest cvsadm-1d18b "cat CVS/Repository" "\." - # the usual for the dir level - dotest cvsadm-1d18d "cat dir/CVS/Repository" "mod2" - # the usual for 2mod - dotest cvsadm-1d18f "cat dir/2mod/CVS/Repository" "mod2/sub2" - # the usual for 2d1mod - dotest cvsadm-1d18h "cat dir/dir2d1/CVS/Repository" "\." - dotest cvsadm-1d18j "cat dir/dir2d1/sub2d1/CVS/Repository" "mod1" - rm -rf CVS dir - - dotest cvsadm-1d19 "${testcvs} co -d dir 2mod 2d2mod" \ -"${PROG} checkout: Updating dir/2mod -U dir/2mod/file2 -${PROG} checkout: Updating dir/dir2d2/sub2d2 -U dir/dir2d2/sub2d2/file2" - dotest cvsadm-1d19b "cat CVS/Repository" "\." - # the usual for the dir level - dotest cvsadm-1d19d "cat dir/CVS/Repository" "mod2" - # the usual for 2mod - dotest cvsadm-1d19f "cat dir/2mod/CVS/Repository" "mod2/sub2" - # the usual for 2d2mod - dotest cvsadm-1d19h "cat dir/dir2d2/CVS/Repository" "mod2" - dotest cvsadm-1d19j "cat dir/dir2d2/sub2d2/CVS/Repository" "mod2/sub2" - rm -rf CVS dir - - - ### 1d1mod - - dotest cvsadm-1d20 "${testcvs} co -d dir 1d1mod 1d1mod-2" \ -"${PROG} checkout: Updating dir/dir1d1 -U dir/dir1d1/file1 -${PROG} checkout: Updating dir/dir1d1-2 -U dir/dir1d1-2/file1-2" - dotest cvsadm-1d20b "cat CVS/Repository" "\." - # the usual for the dir level - dotest cvsadm-1d20d "cat dir/CVS/Repository" "\." - # the usual for 1d1mod - dotest cvsadm-1d20f "cat dir/dir1d1/CVS/Repository" "mod1" - # the usual for 1d1mod copy - dotest cvsadm-1d20h "cat dir/dir1d1-2/CVS/Repository" "mod1-2" - rm -rf CVS dir - - dotest cvsadm-1d21 "${testcvs} co -d dir 1d1mod 1d2mod" \ -"${PROG} checkout: Updating dir/dir1d1 -U dir/dir1d1/file1 -${PROG} checkout: Updating dir/dir1d2 -U dir/dir1d2/file2" - dotest cvsadm-1d21b "cat CVS/Repository" "\." - # the usual for the dir level - dotest cvsadm-1d21d "cat dir/CVS/Repository" "\." - # the usual for 1d1mod - dotest cvsadm-1d21f "cat dir/dir1d1/CVS/Repository" "mod1" - # the usual for 1d2mod - dotest cvsadm-1d21h "cat dir/dir1d2/CVS/Repository" "mod2/sub2" - rm -rf CVS dir - - dotest cvsadm-1d22 "${testcvs} co -d dir 1d1mod 2d1mod" \ -"${PROG} checkout: Updating dir/dir1d1 -U dir/dir1d1/file1 -${PROG} checkout: Updating dir/dir2d1/sub2d1 -U dir/dir2d1/sub2d1/file1" - dotest cvsadm-1d22b "cat CVS/Repository" "\." - # the usual for the dir level - dotest cvsadm-1d22d "cat dir/CVS/Repository" "\." - # the usual for 1d1mod - dotest cvsadm-1d22f "cat dir/dir1d1/CVS/Repository" "mod1" - # the usual for 2d1mod - dotest cvsadm-1d22h "cat dir/dir2d1/CVS/Repository" "\." - dotest cvsadm-1d22j "cat dir/dir2d1/sub2d1/CVS/Repository" "mod1" - rm -rf CVS dir - - dotest cvsadm-1d23 "${testcvs} co -d dir 1d1mod 2d2mod" \ -"${PROG} checkout: Updating dir/dir1d1 -U dir/dir1d1/file1 -${PROG} checkout: Updating dir/dir2d2/sub2d2 -U dir/dir2d2/sub2d2/file2" - dotest cvsadm-1d23b "cat CVS/Repository" "\." - # the usual for the dir level - dotest cvsadm-1d23d "cat dir/CVS/Repository" "\." - # the usual for 1d1mod - dotest cvsadm-1d23f "cat dir/dir1d1/CVS/Repository" "mod1" - # the usual for 2d2mod - dotest cvsadm-1d23h "cat dir/dir2d2/CVS/Repository" "mod2" - dotest cvsadm-1d23j "cat dir/dir2d2/sub2d2/CVS/Repository" "mod2/sub2" - rm -rf CVS dir - - - ### 1d2mod - - dotest cvsadm-1d24 "${testcvs} co -d dir 1d2mod 1d2mod-2" \ -"${PROG} checkout: Updating dir/dir1d2 -U dir/dir1d2/file2 -${PROG} checkout: Updating dir/dir1d2-2 -U dir/dir1d2-2/file2-2" - dotest cvsadm-1d24b "cat CVS/Repository" "\." - # the usual for the dir level - dotest cvsadm-1d24d "cat dir/CVS/Repository" "mod2" - # the usual for 1d2mod - dotest cvsadm-1d24f "cat dir/dir1d2/CVS/Repository" "mod2/sub2" - # the usual for 1d2mod copy - dotest cvsadm-1d24h "cat dir/dir1d2-2/CVS/Repository" "mod2-2/sub2-2" - rm -rf CVS dir - - dotest cvsadm-1d25 "${testcvs} co -d dir 1d2mod 2d1mod" \ -"${PROG} checkout: Updating dir/dir1d2 -U dir/dir1d2/file2 -${PROG} checkout: Updating dir/dir2d1/sub2d1 -U dir/dir2d1/sub2d1/file1" - dotest cvsadm-1d25b "cat CVS/Repository" "\." - # the usual for the dir level - dotest cvsadm-1d25d "cat dir/CVS/Repository" "mod2" - # the usual for 1d2mod - dotest cvsadm-1d25f "cat dir/dir1d2/CVS/Repository" "mod2/sub2" - # the usual for 2d1mod - dotest cvsadm-1d25h "cat dir/dir2d1/CVS/Repository" "\." - dotest cvsadm-1d25j "cat dir/dir2d1/sub2d1/CVS/Repository" "mod1" - rm -rf CVS dir - - dotest cvsadm-1d26 "${testcvs} co -d dir 1d2mod 2d2mod" \ -"${PROG} checkout: Updating dir/dir1d2 -U dir/dir1d2/file2 -${PROG} checkout: Updating dir/dir2d2/sub2d2 -U dir/dir2d2/sub2d2/file2" - dotest cvsadm-1d26b "cat CVS/Repository" "\." - # the usual for the dir level - dotest cvsadm-1d26d "cat dir/CVS/Repository" "mod2" - # the usual for 1d2mod - dotest cvsadm-1d26f "cat dir/dir1d2/CVS/Repository" "mod2/sub2" - # the usual for 2d2mod - dotest cvsadm-1d26h "cat dir/dir2d2/CVS/Repository" "mod2" - dotest cvsadm-1d26j "cat dir/dir2d2/sub2d2/CVS/Repository" "mod2/sub2" - rm -rf CVS dir - - - # 2d1mod - - dotest cvsadm-1d27 "${testcvs} co -d dir 2d1mod 2d1mod-2" \ -"${PROG} checkout: Updating dir/dir2d1/sub2d1 -U dir/dir2d1/sub2d1/file1 -${PROG} checkout: Updating dir/dir2d1-2/sub2d1-2 -U dir/dir2d1-2/sub2d1-2/file1-2" - dotest cvsadm-1d27b "cat CVS/Repository" "\." - # the usual for the dir level - dotest cvsadm-1d27d "cat dir/CVS/Repository" "CVSROOT/Emptydir" - # the usual for 2d1mod - dotest cvsadm-1d27f "cat dir/dir2d1/CVS/Repository" "\." - dotest cvsadm-1d27h "cat dir/dir2d1/sub2d1/CVS/Repository" "mod1" - # the usual for 2d1mod - dotest cvsadm-1d27j "cat dir/dir2d1-2/CVS/Repository" "\." - dotest cvsadm-1d27l "cat dir/dir2d1-2/sub2d1-2/CVS/Repository" \ -"mod1-2" - rm -rf CVS dir - - dotest cvsadm-1d28 "${testcvs} co -d dir 2d1mod 2d2mod" \ -"${PROG} checkout: Updating dir/dir2d1/sub2d1 -U dir/dir2d1/sub2d1/file1 -${PROG} checkout: Updating dir/dir2d2/sub2d2 -U dir/dir2d2/sub2d2/file2" - dotest cvsadm-1d28b "cat CVS/Repository" "\." - # the usual for the dir level - dotest cvsadm-1d28d "cat dir/CVS/Repository" "CVSROOT/Emptydir" - # the usual for 2d1mod - dotest cvsadm-1d28f "cat dir/dir2d1/CVS/Repository" "\." - dotest cvsadm-1d28h "cat dir/dir2d1/sub2d1/CVS/Repository" "mod1" - # the usual for 2d2mod - dotest cvsadm-1d28j "cat dir/dir2d2/CVS/Repository" "mod2" - dotest cvsadm-1d28l "cat dir/dir2d2/sub2d2/CVS/Repository" "mod2/sub2" - rm -rf CVS dir - - - # 2d2mod - - dotest cvsadm-1d29 "${testcvs} co -d dir 2d2mod 2d2mod-2" \ -"${PROG} checkout: Updating dir/dir2d2/sub2d2 -U dir/dir2d2/sub2d2/file2 -${PROG} checkout: Updating dir/dir2d2-2/sub2d2-2 -U dir/dir2d2-2/sub2d2-2/file2-2" - dotest cvsadm-1d29b "cat CVS/Repository" "\." - # the usual for the dir level - dotest cvsadm-1d29d "cat dir/CVS/Repository" "\." - # the usual for 2d2mod - dotest cvsadm-1d29f "cat dir/dir2d2/CVS/Repository" "mod2" - dotest cvsadm-1d29h "cat dir/dir2d2/sub2d2/CVS/Repository" "mod2/sub2" - # the usual for 2d2mod - dotest cvsadm-1d29j "cat dir/dir2d2-2/CVS/Repository" "mod2-2" - dotest cvsadm-1d29l "cat dir/dir2d2-2/sub2d2-2/CVS/Repository" \ -"mod2-2/sub2-2" - rm -rf CVS dir - - ################################################## - ## And now, some of that again using the "-d" flag - ## on the command line, but use a longer path. - ################################################## - - dotest_fail cvsadm-2d3-1 "${testcvs} co -d dir/dir2 1mod" \ -"${PROG} \[checkout aborted\]: could not change directory to requested checkout directory .dir.: No such file or directory" - - if $remote; then :; else - # Remote can't handle this, even with the "mkdir dir". - # This was also true of CVS 1.9. - - mkdir dir - dotest cvsadm-2d3 "${testcvs} co -d dir/dir2 1mod" \ -"${PROG} checkout: Updating dir/dir2 -U dir/dir2/file1" - dotest cvsadm-2d3b "cat CVS/Repository" "\." - dotest_fail cvsadm-2d3d "test -f dir/CVS/Repository" "" - dotest cvsadm-2d3f "cat dir/dir2/CVS/Repository" "mod1" - rm -rf CVS dir - - mkdir dir - dotest cvsadm-2d4 "${testcvs} co -d dir/dir2 2mod" \ -"${PROG} checkout: Updating dir/dir2 -U dir/dir2/file2" - dotest cvsadm-2d4b "cat CVS/Repository" "\." - dotest cvsadm-2d4f "cat dir/dir2/CVS/Repository" "mod2/sub2" - rm -rf CVS dir - - mkdir dir - dotest cvsadm-2d5 "${testcvs} co -d dir/dir2 1d1mod" \ -"${PROG} checkout: Updating dir/dir2 -U dir/dir2/file1" - dotest cvsadm-2d5b "cat CVS/Repository" "\." - dotest cvsadm-2d5f "cat dir/dir2/CVS/Repository" "mod1" - rm -rf CVS dir - - mkdir dir - dotest cvsadm-2d6 "${testcvs} co -d dir/dir2 1d2mod" \ -"${PROG} checkout: Updating dir/dir2 -U dir/dir2/file2" - dotest cvsadm-2d6b "cat CVS/Repository" "\." - dotest cvsadm-2d6f "cat dir/dir2/CVS/Repository" "mod2/sub2" - rm -rf CVS dir - - mkdir dir - dotest cvsadm-2d7 "${testcvs} co -d dir/dir2 2d1mod" \ -"${PROG} checkout: Updating dir/dir2 -U dir/dir2/file1" - dotest cvsadm-2d7b "cat CVS/Repository" "\." - dotest cvsadm-2d7f "cat dir/dir2/CVS/Repository" "mod1" - rm -rf CVS dir - - mkdir dir - dotest cvsadm-2d8 "${testcvs} co -d dir/dir2 2d2mod" \ -"${PROG} checkout: Updating dir/dir2 -U dir/dir2/file2" - dotest cvsadm-2d8b "cat CVS/Repository" "\." - dotest cvsadm-2d8f "cat dir/dir2/CVS/Repository" "mod2/sub2" - rm -rf CVS dir - - ################################################## - ## And now, a few of those tests revisited to - ## test the behavior of the -N flag. - ################################################## - - dotest cvsadm-N3 "${testcvs} co -N 1mod" \ -"${PROG} checkout: Updating 1mod -U 1mod/file1" - dotest cvsadm-N3b "cat CVS/Repository" "\." - dotest cvsadm-N3d "cat 1mod/CVS/Repository" "mod1" - rm -rf CVS 1mod - - dotest cvsadm-N4 "${testcvs} co -N 2mod" \ -"${PROG} checkout: Updating 2mod -U 2mod/file2" - dotest cvsadm-N4b "cat CVS/Repository" "\." - dotest cvsadm-N4d "cat 2mod/CVS/Repository" "mod2/sub2" - rm -rf CVS 2mod - - dotest cvsadm-N5 "${testcvs} co -N 1d1mod" \ -"${PROG} checkout: Updating dir1d1 -U dir1d1/file1" - dotest cvsadm-N5b "cat CVS/Repository" "\." - dotest cvsadm-N5d "cat dir1d1/CVS/Repository" "mod1" - rm -rf CVS dir1d1 - - dotest cvsadm-N6 "${testcvs} co -N 1d2mod" \ -"${PROG} checkout: Updating dir1d2 -U dir1d2/file2" - dotest cvsadm-N6b "cat CVS/Repository" "\." - dotest cvsadm-N6d "cat dir1d2/CVS/Repository" "mod2/sub2" - rm -rf CVS dir1d2 - - dotest cvsadm-N7 "${testcvs} co -N 2d1mod" \ -"${PROG} checkout: Updating dir2d1/sub2d1 -U dir2d1/sub2d1/file1" - dotest cvsadm-N7b "cat CVS/Repository" "\." - dotest cvsadm-N7d "cat dir2d1/CVS/Repository" "\." - dotest cvsadm-N7f "cat dir2d1/sub2d1/CVS/Repository" "mod1" - rm -rf CVS dir2d1 - - dotest cvsadm-N8 "${testcvs} co -N 2d2mod" \ -"${PROG} checkout: Updating dir2d2/sub2d2 -U dir2d2/sub2d2/file2" - dotest cvsadm-N8b "cat CVS/Repository" "\." - dotest cvsadm-N8d "cat dir2d2/CVS/Repository" "mod2" - dotest cvsadm-N8f "cat dir2d2/sub2d2/CVS/Repository" "mod2/sub2" - rm -rf CVS dir2d2 - - ## the ones in one-deep directories - - dotest cvsadm-N1d3 "${testcvs} co -N -d dir 1mod" \ -"${PROG} checkout: Updating dir/1mod -U dir/1mod/file1" - dotest cvsadm-N1d3b "cat CVS/Repository" "\." - dotest cvsadm-N1d3d "cat dir/CVS/Repository" "\." - dotest cvsadm-N1d3f "cat dir/1mod/CVS/Repository" "mod1" - rm -rf CVS dir - - dotest cvsadm-N1d4 "${testcvs} co -N -d dir 2mod" \ -"${PROG} checkout: Updating dir/2mod -U dir/2mod/file2" - dotest cvsadm-N1d4b "cat CVS/Repository" "\." - dotest cvsadm-N1d4d "cat dir/CVS/Repository" "mod2" - dotest cvsadm-N1d4f "cat dir/2mod/CVS/Repository" "mod2/sub2" - rm -rf CVS dir - - dotest cvsadm-N1d5 "${testcvs} co -N -d dir 1d1mod" \ -"${PROG} checkout: Updating dir/dir1d1 -U dir/dir1d1/file1" - dotest cvsadm-N1d5b "cat CVS/Repository" "\." - dotest cvsadm-N1d5d "cat dir/CVS/Repository" "\." - dotest cvsadm-N1d5d "cat dir/dir1d1/CVS/Repository" "mod1" - rm -rf CVS dir - - dotest cvsadm-N1d6 "${testcvs} co -N -d dir 1d2mod" \ -"${PROG} checkout: Updating dir/dir1d2 -U dir/dir1d2/file2" - dotest cvsadm-N1d6b "cat CVS/Repository" "\." - dotest cvsadm-N1d6d "cat dir/CVS/Repository" "mod2" - dotest cvsadm-N1d6f "cat dir/dir1d2/CVS/Repository" "mod2/sub2" - rm -rf CVS dir - - dotest cvsadm-N1d7 "${testcvs} co -N -d dir 2d1mod" \ -"${PROG} checkout: Updating dir/dir2d1/sub2d1 -U dir/dir2d1/sub2d1/file1" - dotest cvsadm-N1d7b "cat CVS/Repository" "\." - dotest cvsadm-N1d7d "cat dir/CVS/Repository" "CVSROOT/Emptydir" - dotest cvsadm-N1d7f "cat dir/dir2d1/CVS/Repository" "\." - dotest cvsadm-N1d7h "cat dir/dir2d1/sub2d1/CVS/Repository" "mod1" - rm -rf CVS dir - - dotest cvsadm-N1d8 "${testcvs} co -N -d dir 2d2mod" \ -"${PROG} checkout: Updating dir/dir2d2/sub2d2 -U dir/dir2d2/sub2d2/file2" - dotest cvsadm-N1d8b "cat CVS/Repository" "\." - dotest cvsadm-N1d8d "cat dir/CVS/Repository" "\." - dotest cvsadm-N1d8d "cat dir/dir2d2/CVS/Repository" "mod2" - dotest cvsadm-N1d8d "cat dir/dir2d2/sub2d2/CVS/Repository" \ -"mod2/sub2" - rm -rf CVS dir - - ## the ones in two-deep directories - - mkdir dir - dotest cvsadm-N2d3 "${testcvs} co -N -d dir/dir2 1mod" \ -"${PROG} checkout: Updating dir/dir2/1mod -U dir/dir2/1mod/file1" - dotest cvsadm-N2d3b "cat CVS/Repository" "\." - dotest cvsadm-N2d3f "cat dir/dir2/CVS/Repository" "\." - dotest cvsadm-N2d3h "cat dir/dir2/1mod/CVS/Repository" "mod1" - rm -rf CVS dir - - mkdir dir - dotest cvsadm-N2d4 "${testcvs} co -N -d dir/dir2 2mod" \ -"${PROG} checkout: Updating dir/dir2/2mod -U dir/dir2/2mod/file2" - dotest cvsadm-N2d4b "cat CVS/Repository" "\." - dotest cvsadm-N2d4f "cat dir/dir2/CVS/Repository" "mod2" - dotest cvsadm-N2d4h "cat dir/dir2/2mod/CVS/Repository" "mod2/sub2" - rm -rf CVS dir - - mkdir dir - dotest cvsadm-N2d5 "${testcvs} co -N -d dir/dir2 1d1mod" \ -"${PROG} checkout: Updating dir/dir2/dir1d1 -U dir/dir2/dir1d1/file1" - dotest cvsadm-N2d5b "cat CVS/Repository" "\." - dotest cvsadm-N2d5f "cat dir/dir2/CVS/Repository" "\." - dotest cvsadm-N2d5h "cat dir/dir2/dir1d1/CVS/Repository" "mod1" - rm -rf CVS dir - - mkdir dir - dotest cvsadm-N2d6 "${testcvs} co -N -d dir/dir2 1d2mod" \ -"${PROG} checkout: Updating dir/dir2/dir1d2 -U dir/dir2/dir1d2/file2" - dotest cvsadm-N2d6b "cat CVS/Repository" "\." - dotest cvsadm-N2d6f "cat dir/dir2/CVS/Repository" "mod2" - dotest cvsadm-N2d6h "cat dir/dir2/dir1d2/CVS/Repository" "mod2/sub2" - rm -rf CVS dir - - mkdir dir - dotest cvsadm-N2d7 "${testcvs} co -N -d dir/dir2 2d1mod" \ -"${PROG} checkout: Updating dir/dir2/dir2d1/sub2d1 -U dir/dir2/dir2d1/sub2d1/file1" - dotest cvsadm-N2d7b "cat CVS/Repository" "\." - dotest cvsadm-N2d7f "cat dir/dir2/CVS/Repository" "CVSROOT/Emptydir" - dotest cvsadm-N2d7g "cat dir/dir2/dir2d1/CVS/Repository" "\." - dotest cvsadm-N2d7h "cat dir/dir2/dir2d1/sub2d1/CVS/Repository" \ -"mod1" - rm -rf CVS dir - - mkdir dir - dotest cvsadm-N2d8 "${testcvs} co -N -d dir/dir2 2d2mod" \ -"${PROG} checkout: Updating dir/dir2/dir2d2/sub2d2 -U dir/dir2/dir2d2/sub2d2/file2" - dotest cvsadm-N2d8b "cat CVS/Repository" "\." - dotest cvsadm-N2d8f "cat dir/dir2/CVS/Repository" "\." - dotest cvsadm-N2d8h "cat dir/dir2/dir2d2/CVS/Repository" "mod2" - dotest cvsadm-N2d8j "cat dir/dir2/dir2d2/sub2d2/CVS/Repository" \ -"mod2/sub2" - rm -rf CVS dir - - fi # end of tests to be skipped for remote - - ################################################## - ## That's enough of that, thank you very much. - ################################################## - - dotest cvsadm-cleanup-1 "${testcvs} -q co CVSROOT/config" \ -"U CVSROOT/config" - cd CVSROOT - echo "# empty file" >config - dotest cvsadm-cleanup-2 "${testcvs} -q ci -m cvsadm-cleanup" \ -"Checking in config; -${CVSROOT_DIRNAME}/CVSROOT/config,v <-- config -new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* -done -${PROG} commit: Rebuilding administrative file database" - cd .. - rm -rf CVSROOT CVS - - # remove our junk - cd .. - rm -rf 1 - rm -rf ${CVSROOT_DIRNAME}/1mod - rm -rf ${CVSROOT_DIRNAME}/1mod-2 - rm -rf ${CVSROOT_DIRNAME}/2mod - rm -rf ${CVSROOT_DIRNAME}/2mod-2 - rm -rf ${CVSROOT_DIRNAME}/mod1 - rm -rf ${CVSROOT_DIRNAME}/mod1-2 - rm -rf ${CVSROOT_DIRNAME}/mod2 - rm -rf ${CVSROOT_DIRNAME}/mod2-2 - ;; - - emptydir) - # Various tests of the Emptydir (CVSNULLREPOS) code. See also: - # cvsadm: tests of Emptydir in various module definitions - # basicb: Test that "Emptydir" is non-special in ordinary contexts - - mkdir 1; cd 1 - dotest emptydir-1 "${testcvs} co CVSROOT/modules" \ -"U CVSROOT/modules" - echo "# Module defs for emptydir tests" > CVSROOT/modules - echo "2d1mod -d dir2d1/sub/sub2d1 mod1" >> CVSROOT/modules - echo "2d1moda -d dir2d1/suba moda/modasub" >> CVSROOT/modules - echo "2d1modb -d dir2d1/suba mod1" >> CVSROOT/modules - echo "comb -a 2d1modb 2d1moda" >> CVSROOT/modules - - dotest emptydir-2 "${testcvs} ci -m add-modules" \ -"${PROG} [a-z]*: Examining CVSROOT -Checking in CVSROOT/modules; -${CVSROOT_DIRNAME}/CVSROOT/modules,v <-- modules -new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* -done -${PROG} commit: Rebuilding administrative file database" \ -"${PROG} commit: Examining CVSROOT" - rm -rf CVS CVSROOT - - mkdir ${CVSROOT_DIRNAME}/mod1 ${CVSROOT_DIRNAME}/moda - # Populate. Not sure we really need to do this. - dotest emptydir-3 "${testcvs} -q co -l ." "" - dotest emptydir-3a "${testcvs} co mod1 moda" \ -"${PROG} checkout: Updating mod1 -${PROG} checkout: Updating moda" - echo "file1" > mod1/file1 - mkdir moda/modasub - dotest emptydir-3b "${testcvs} add moda/modasub" \ -"Directory ${CVSROOT_DIRNAME}/moda/modasub added to the repository" - echo "filea" > moda/modasub/filea - dotest emptydir-4 "${testcvs} add mod1/file1 moda/modasub/filea" \ -"${PROG} add: scheduling file .mod1/file1. for addition -${PROG} add: scheduling file .moda/modasub/filea. for addition -${PROG} add: use .${PROG} commit. to add these files permanently" - dotest emptydir-5 "${testcvs} -q ci -m yup" \ -"RCS file: ${CVSROOT_DIRNAME}/mod1/file1,v -done -Checking in mod1/file1; -${CVSROOT_DIRNAME}/mod1/file1,v <-- file1 -initial revision: 1\.1 -done -RCS file: ${CVSROOT_DIRNAME}/moda/modasub/filea,v -done -Checking in moda/modasub/filea; -${CVSROOT_DIRNAME}/moda/modasub/filea,v <-- filea -initial revision: 1\.1 -done" - rm -rf mod1 moda CVS - # End Populate. - - dotest emptydir-6 "${testcvs} co 2d1mod" \ -"${PROG} checkout: Updating dir2d1/sub/sub2d1 -U dir2d1/sub/sub2d1/file1" - cd dir2d1 - touch emptyfile - # It doesn't make any sense to add a file (or do much of anything - # else) in Emptydir; Emptydir is a placeholder indicating that - # the working directory doesn't correspond to anything in - # the repository. - dotest_fail emptydir-7 "${testcvs} add emptyfile" \ -"${PROG} \[add aborted\]: cannot add to ${CVSROOT_DIRNAME}/CVSROOT/Emptydir" - mkdir emptydir - dotest_fail emptydir-8 "${testcvs} add emptydir" \ -"${PROG} \[[a-z]* aborted\]: cannot add to ${CVSROOT_DIRNAME}/CVSROOT/Emptydir" - cd .. - rm -rf CVS dir2d1 - - # OK, while we have an Emptydir around, test a few obscure - # things about it. - mkdir edir; cd edir - dotest emptydir-9 "${testcvs} -q co -l CVSROOT" \ -"U CVSROOT${DOTSTAR}" - cd CVSROOT - dotest_fail emptydir-10 "test -d Emptydir" '' - # This tests the code in find_dirs which skips Emptydir. - dotest emptydir-11 "${testcvs} -q -n update -d -P" '' - cd ../.. - rm -r edir - cd .. - - # Now start playing with moda. - mkdir 2; cd 2 - dotest emptydir-12 "${testcvs} -q co 2d1moda" \ -"U dir2d1/suba/filea" - # OK, this is the crux of the matter. This used to show "Emptydir", - # but everyone seemed to think it should show "moda". This - # usually works better, but not always as shown by the following - # test. - dotest emptydir-13 "cat dir2d1/CVS/Repository" "moda" - dotest_fail emptydir-14 "${testcvs} co comb" \ -"${PROG} checkout: existing repository ${CVSROOT_DIRNAME}/moda/modasub does not match ${CVSROOT_DIRNAME}/mod1 -${PROG} checkout: ignoring module 2d1modb -${PROG} checkout: Updating dir2d1/suba" - dotest emptydir-15 "cat dir2d1/CVS/Repository" "moda" - cd .. - - # Test the effect of a non-cvs directory already existing with the - # same name as one in the modules file. - mkdir 3; cd 3 - mkdir dir2d1 - dotest emptydir-16 "${testcvs} co 2d1mod" \ -"${PROG} checkout: Updating dir2d1/sub/sub2d1 -U dir2d1/sub/sub2d1/file1" - dotest emptydir-17 "test -d dir2d1/CVS" - - # clean up - if $keep; then - echo Keeping ${TESTDIR} and exiting due to --keep - exit 0 - fi - - cd .. - rm -r 1 2 3 - rm -rf ${CVSROOT_DIRNAME}/mod1 ${CVSROOT_DIRNAME}/moda - # I guess for the moment the convention is going to be - # that we don't need to remove ${CVSROOT_DIRNAME}/CVSROOT/Emptydir - ;; - - abspath) - - # These tests test the thituations thin thwitch thoo theck - # things thout twith thabsolute thaths. Threally. - - # - # CHECKOUTS - # - - # Create a few modules to use - mkdir ${CVSROOT_DIRNAME}/mod1 ${CVSROOT_DIRNAME}/mod2 - dotest abspath-1a "${testcvs} co mod1 mod2" \ -"${PROG} checkout: Updating mod1 -${PROG} checkout: Updating mod2" - - # Populate the module - echo "file1" > mod1/file1 - echo "file2" > mod2/file2 - cd mod1 - dotest abspath-1ba "${testcvs} add file1" \ -"${PROG} add: scheduling file .file1. for addition -${PROG} add: use .${PROG} commit. to add this file permanently" - cd .. - cd mod2 - dotest abspath-1bb "${testcvs} add file2" \ -"${PROG} add: scheduling file .file2. for addition -${PROG} add: use .${PROG} commit. to add this file permanently" - cd .. - - dotest abspath-1c "${testcvs} ci -m yup mod1 mod2" \ -"${PROG} [a-z]*: Examining mod1 -${PROG} [a-z]*: Examining mod2 -RCS file: ${CVSROOT_DIRNAME}/mod1/file1,v -done -Checking in mod1/file1; -${CVSROOT_DIRNAME}/mod1/file1,v <-- file1 -initial revision: 1.1 -done -RCS file: ${CVSROOT_DIRNAME}/mod2/file2,v -done -Checking in mod2/file2; -${CVSROOT_DIRNAME}/mod2/file2,v <-- file2 -initial revision: 1.1 -done" - # Finished creating the module -- clean up. - rm -rf CVS mod1 mod2 - # Done. - - # Try checking out the module in a local directory - if $remote; then - dotest_fail abspath-2a "${testcvs} co -d ${TESTDIR}/1 mod1" \ -"${PROG} \[checkout aborted\]: absolute pathname .${TESTDIR}/1. illegal for server" - dotest abspath-2a-try2 "${testcvs} co -d 1 mod1" \ -"${PROG} checkout: Updating 1 -U 1/file1" - else - dotest abspath-2a "${testcvs} co -d ${TESTDIR}/1 mod1" \ -"${PROG} checkout: Updating ${TESTDIR}/1 -U ${TESTDIR}/1/file1" - fi # remote workaround - - dotest abspath-2b "cat ${TESTDIR}/1/CVS/Repository" "mod1" - - # Done. Clean up. - rm -rf ${TESTDIR}/1 - - - # Now try in a subdirectory. We're not covering any more - # code here, but we might catch a future error if someone - # changes the checkout code. - - # Note that for the same reason that the shell command - # "touch 1/2/3" requires directories 1 and 1/2 to already - # exist, we expect ${TESTDIR}/1 to already exist. I believe - # this is the behavior of CVS 1.9 and earlier. - if $remote; then :; else - dotest_fail abspath-3.1 "${testcvs} co -d ${TESTDIR}/1/2 mod1" \ -"${PROG} \[checkout aborted\]: could not change directory to requested checkout directory .${TESTDIR}/1.: No such file or directory" - fi - dotest_fail abspath-3.2 "${testcvs} co -d 1/2 mod1" \ -"${PROG} \[checkout aborted\]: could not change directory to requested checkout directory .1.: No such file or directory" - - mkdir 1 - - if $remote; then - # The server wants the directory to exist, but that is - # a bug, it should only need to exist on the client side. - # See also cvsadm-2d3. - dotest_fail abspath-3a "${testcvs} co -d 1/2 mod1" \ -"${PROG} \[checkout aborted\]: could not change directory to requested checkout directory .1.: No such file or directory" - cd 1 - dotest abspath-3a-try2 "${testcvs} co -d 2 mod1" \ -"${PROG} checkout: Updating 2 -U 2/file1" - cd .. - rm -rf 1/CVS - else - dotest abspath-3a "${testcvs} co -d ${TESTDIR}/1/2 mod1" \ -"${PROG} checkout: Updating ${TESTDIR}/1/2 -U ${TESTDIR}/1/2/file1" - fi # remote workaround - dotest abspath-3b "cat ${TESTDIR}/1/2/CVS/Repository" "mod1" - - # For all the same reasons that we want "1" to already - # exist, we don't to mess with it to traverse it, for - # example by creating a CVS directory. - - dotest_fail abspath-3c "test -d ${TESTDIR}/1/CVS" '' - # Done. Clean up. - rm -rf ${TESTDIR}/1 - - - # Now try someplace where we don't have permission. - mkdir ${TESTDIR}/barf - chmod -w ${TESTDIR}/barf - dotest_fail abspath-4r "${testcvs} co -d ${TESTDIR}/barf/sub mod1" \ -"${PROG} \[checkout aborted\]: absolute pathname .${TESTDIR}/barf/sub. illegal for server" \ -"${PROG} \[checkout aborted\]: cannot make directory sub: Permission denied" - chmod +w ${TESTDIR}/barf - rmdir ${TESTDIR}/barf - # Done. Nothing to clean up. - - - # Try checking out two modules into the same directory. - if $remote; then - dotest abspath-5ar "${testcvs} co -d 1 mod1 mod2" \ -"${PROG} checkout: Updating 1/mod1 -U 1/mod1/file1 -${PROG} checkout: Updating 1/mod2 -U 1/mod2/file2" - else - dotest abspath-5a "${testcvs} co -d ${TESTDIR}/1 mod1 mod2" \ -"${PROG} checkout: Updating ${TESTDIR}/1/mod1 -U ${TESTDIR}/1/mod1/file1 -${PROG} checkout: Updating ${TESTDIR}/1/mod2 -U ${TESTDIR}/1/mod2/file2" - fi # end remote workaround - dotest abspath-5b "cat ${TESTDIR}/1/CVS/Repository" "\." - dotest abspath-5c "cat ${TESTDIR}/1/mod1/CVS/Repository" "mod1" - dotest abspath-5d "cat ${TESTDIR}/1/mod2/CVS/Repository" "mod2" - # Done. Clean up. - rm -rf ${TESTDIR}/1 - - - # Try checking out the top-level module. - if $remote; then - dotest abspath-6ar "${testcvs} co -d 1 ." \ -"${PROG} checkout: Updating 1 -${PROG} checkout: Updating 1/CVSROOT -${DOTSTAR} -${PROG} checkout: Updating 1/mod1 -U 1/mod1/file1 -${PROG} checkout: Updating 1/mod2 -U 1/mod2/file2" - else - dotest abspath-6a "${testcvs} co -d ${TESTDIR}/1 ." \ -"${PROG} checkout: Updating ${TESTDIR}/1 -${PROG} checkout: Updating ${TESTDIR}/1/CVSROOT -${DOTSTAR} -${PROG} checkout: Updating ${TESTDIR}/1/mod1 -U ${TESTDIR}/1/mod1/file1 -${PROG} checkout: Updating ${TESTDIR}/1/mod2 -U ${TESTDIR}/1/mod2/file2" - fi # end of remote workaround - dotest abspath-6b "cat ${TESTDIR}/1/CVS/Repository" "\." - dotest abspath-6c "cat ${TESTDIR}/1/CVSROOT/CVS/Repository" "CVSROOT" - dotest abspath-6c "cat ${TESTDIR}/1/mod1/CVS/Repository" "mod1" - dotest abspath-6d "cat ${TESTDIR}/1/mod2/CVS/Repository" "mod2" - # Done. Clean up. - rm -rf ${TESTDIR}/1 - - # Test that an absolute pathname to some other directory - # doesn't mess with the current working directory. - mkdir 1 - cd 1 - if $remote; then - dotest_fail abspath-7ar "${testcvs} -q co -d ../2 mod2" \ -"${PROG} checkout: protocol error: .\.\./2. contains more leading \.\. -${PROG} \[checkout aborted\]: than the 0 which Max-dotdot specified" - cd .. - dotest abspath-7a-try2r "${testcvs} -q co -d 2 mod2" \ -"U 2/file2" - cd 1 - else - dotest abspath-7a "${testcvs} -q co -d ${TESTDIR}/2 mod2" \ -"U ${TESTDIR}/2/file2" - fi # remote workaround - dotest abspath-7b "ls" "" - dotest abspath-7c "${testcvs} -q co mod1" \ -"U mod1/file1" - cd mod1 - if $remote; then - cd ../.. - dotest abspath-7dr "${testcvs} -q co -d 3 mod2" \ -"U 3/file2" - cd 1/mod1 - else - dotest abspath-7d "${testcvs} -q co -d ${TESTDIR}/3 mod2" \ -"U ${TESTDIR}/3/file2" - fi # remote workaround - dotest abspath-7e "${testcvs} -q update -d" "" - cd ../.. - rm -r 1 2 3 - - # - # FIXME: do other functions here (e.g. update /tmp/foo) - # - - # Finished with all tests. Remove the module. - rm -rf ${CVSROOT_DIRNAME}/mod1 ${CVSROOT_DIRNAME}/mod2 - - ;; - - - - abspath2) - # More absolute path checks. The following used to attempt to create - # directories in /: - # - # $ cvs -d:fork:/cvsroot co /foo - # cvs checkout: warning: cannot make directory CVS in /: Permission denied - # cvs [checkout aborted]: cannot make directory /foo: Permission denied - # $ - # - # The -z9 in this test also checks for an old server bug where the - # server would block indefinitely attempting to read an EOF from the - # client in the compression buffer shutdown routine. - dotest_fail abspath2-1 "$testcvs -z9 co /foo" \ -"$PROG \[checkout aborted\]: Absolute module reference invalid: \`/foo'" \ -"$PROG \[server aborted\]: Absolute module reference invalid: \`/foo' -$PROG \[checkout aborted\]: end of file from server (consult above messages if any)" - ;; - - - - toplevel) - # test the feature that cvs creates a CVS subdir also for - # the toplevel directory - - # First set the TopLevelAdmin setting. - mkdir 1; cd 1 - dotest toplevel-1a "${testcvs} -q co CVSROOT/config" \ -"U CVSROOT/config" - cd CVSROOT - echo "TopLevelAdmin=yes" >config - dotest toplevel-1b "${testcvs} -q ci -m yes-top-level" \ -"Checking in config; -${CVSROOT_DIRNAME}/CVSROOT/config,v <-- config -new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* -done -${PROG} commit: Rebuilding administrative file database" - cd ../.. - rm -r 1 - - mkdir 1; cd 1 - dotest toplevel-1 "${testcvs} -q co -l ." '' - mkdir top-dir second-dir - dotest toplevel-2 "${testcvs} add top-dir second-dir" \ -"Directory ${CVSROOT_DIRNAME}/top-dir added to the repository -Directory ${CVSROOT_DIRNAME}/second-dir added to the repository" - cd top-dir - - touch file1 - dotest toplevel-3 "${testcvs} add file1" \ -"${PROG} add: scheduling file .file1. for addition -${PROG} add: use .${PROG} commit. to add this file permanently" - dotest toplevel-4 "${testcvs} -q ci -m add" \ -"RCS file: ${CVSROOT_DIRNAME}/top-dir/file1,v -done -Checking in file1; -${CVSROOT_DIRNAME}/top-dir/file1,v <-- file1 -initial revision: 1\.1 -done" - cd .. - - cd second-dir - touch file2 - dotest toplevel-3s "${testcvs} add file2" \ -"${PROG} add: scheduling file .file2. for addition -${PROG} add: use .${PROG} commit. to add this file permanently" - dotest toplevel-4s "${testcvs} -q ci -m add" \ -"RCS file: ${CVSROOT_DIRNAME}/second-dir/file2,v -done -Checking in file2; -${CVSROOT_DIRNAME}/second-dir/file2,v <-- file2 -initial revision: 1\.1 -done" - - cd ../.. - rm -r 1; mkdir 1; cd 1 - dotest toplevel-5 "${testcvs} co top-dir" \ -"${PROG} checkout: Updating top-dir -U top-dir/file1" - - dotest toplevel-6 "${testcvs} update top-dir" \ -"${PROG} update: Updating top-dir" - dotest toplevel-7 "${testcvs} update" \ -"${PROG} update: Updating \. -${PROG} update: Updating top-dir" - - dotest toplevel-8 "${testcvs} update -d top-dir" \ -"${PROG} update: Updating top-dir" - # There is some sentiment that - # "${PROG} update: Updating \. - # ${PROG} update: Updating top-dir" - # is correct but it isn't clear why that would be correct instead - # of the remote CVS behavior (which also updates CVSROOT). - # - # The DOTSTAR matches of a bunch of lines like - # "U CVSROOT/checkoutlist". Trying to match them more precisely - # seemed to cause trouble. For example CVSROOT/cvsignore will - # be present or absent depending on whether we ran the "ignore" - # test or not. - dotest toplevel-9 "${testcvs} update -d" \ -"${PROG} update: Updating \. -${PROG} update: Updating CVSROOT -${DOTSTAR} -${PROG} update: Updating top-dir" - - cd .. - rm -r 1; mkdir 1; cd 1 - dotest toplevel-10 "${testcvs} co top-dir" \ -"${PROG} checkout: Updating top-dir -U top-dir/file1" - - # This tests more or less the same thing, in a particularly - # "real life" example. - dotest toplevel-11 "${testcvs} -q update -d second-dir" \ -"U second-dir/file2" - - # Now remove the CVS directory (people may do this manually, - # especially if they formed their habits with CVS - # 1.9 and older, which didn't create it. Or perhaps the working - # directory itself was created with 1.9 or older). - rm -r CVS - # Now set the permissions so we can't recreate it. - if test -n "$remotehost"; then - # Cygwin again. - $CVS_RSH $remotehost "chmod -w $TESTDIR/1" - else - chmod -w ../1 - fi - # Now see whether CVS has trouble because it can't create CVS. - # First string is for local, second is for remote. - dotest toplevel-12 "${testcvs} co top-dir" \ -"${PROG} checkout: warning: cannot make directory CVS in \.: Permission denied -${PROG} checkout: Updating top-dir" \ -"${PROG} checkout: warning: cannot make directory CVS in \.: Permission denied -${PROG} checkout: in directory \.: -${PROG} checkout: cannot open CVS/Entries for reading: No such file or directory -${PROG} checkout: Updating top-dir" - - chmod +w ../1 - - dotest toplevel-cleanup-1 "${testcvs} -q co CVSROOT/config" \ -"U CVSROOT/config" - cd CVSROOT - echo "# empty file" >config - dotest toplevel-cleanup-2 "${testcvs} -q ci -m toplevel-cleanup" \ -"Checking in config; -${CVSROOT_DIRNAME}/CVSROOT/config,v <-- config -new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* -done -${PROG} commit: Rebuilding administrative file database" - - cd ../.. - rm -r 1 - rm -rf ${CVSROOT_DIRNAME}/top-dir ${CVSROOT_DIRNAME}/second-dir - ;; - - toplevel2) - # Similar to toplevel, but test the case where TopLevelAdmin=no. - - # First set the TopLevelAdmin setting. - mkdir 1; cd 1 - dotest toplevel2-1a "${testcvs} -q co CVSROOT/config" \ -"U CVSROOT/config" - cd CVSROOT - echo "TopLevelAdmin=no" >config - dotest toplevel2-1b "${testcvs} -q ci -m no-top-level" \ -"Checking in config; -${CVSROOT_DIRNAME}/CVSROOT/config,v <-- config -new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* -done -${PROG} commit: Rebuilding administrative file database" - cd ../.. - rm -r 1 - - # Now set up some directories and subdirectories - mkdir 1; cd 1 - dotest toplevel2-1 "${testcvs} -q co -l ." '' - mkdir top-dir second-dir - dotest toplevel2-2 "${testcvs} add top-dir second-dir" \ -"Directory ${CVSROOT_DIRNAME}/top-dir added to the repository -Directory ${CVSROOT_DIRNAME}/second-dir added to the repository" - cd top-dir - - touch file1 - dotest toplevel2-3 "${testcvs} add file1" \ -"${PROG} add: scheduling file .file1. for addition -${PROG} add: use .${PROG} commit. to add this file permanently" - dotest toplevel2-4 "${testcvs} -q ci -m add" \ -"RCS file: ${CVSROOT_DIRNAME}/top-dir/file1,v -done -Checking in file1; -${CVSROOT_DIRNAME}/top-dir/file1,v <-- file1 -initial revision: 1\.1 -done" - cd .. - - cd second-dir - touch file2 - dotest toplevel2-3s "${testcvs} add file2" \ -"${PROG} add: scheduling file .file2. for addition -${PROG} add: use .${PROG} commit. to add this file permanently" - dotest toplevel2-4s "${testcvs} -q ci -m add" \ -"RCS file: ${CVSROOT_DIRNAME}/second-dir/file2,v -done -Checking in file2; -${CVSROOT_DIRNAME}/second-dir/file2,v <-- file2 -initial revision: 1\.1 -done" - - cd ../.. - rm -r 1; mkdir 1; cd 1 - dotest toplevel2-5 "${testcvs} co top-dir" \ -"${PROG} checkout: Updating top-dir -U top-dir/file1" - - dotest toplevel2-6 "${testcvs} update top-dir" \ -"${PROG} update: Updating top-dir" - dotest toplevel2-7 "${testcvs} update" \ -"${PROG} update: Updating top-dir" - - dotest toplevel2-8 "${testcvs} update -d top-dir" \ -"${PROG} update: Updating top-dir" - # Contrast this with toplevel-9, which has TopLevelAdmin=yes. - dotest toplevel2-9 "${testcvs} update -d" \ -"${PROG} update: Updating top-dir" - - cd .. - rm -r 1; mkdir 1; cd 1 - dotest toplevel2-10 "${testcvs} co top-dir" \ -"${PROG} checkout: Updating top-dir -U top-dir/file1" - # This tests more or less the same thing, in a particularly - # "real life" example. With TopLevelAdmin=yes, this command - # would give us second-dir and CVSROOT directories too. - dotest toplevel2-11 "${testcvs} -q update -d" "" - - dotest toplevel2-cleanup-1 "${testcvs} -q co CVSROOT/config" \ -"U CVSROOT/config" - cd CVSROOT - echo "# empty file" >config - dotest toplevel2-cleanup-2 "${testcvs} -q ci -m toplevel2-cleanup" \ -"Checking in config; -${CVSROOT_DIRNAME}/CVSROOT/config,v <-- config -new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* -done -${PROG} commit: Rebuilding administrative file database" - cd ../.. - rm -r 1 - rm -rf ${CVSROOT_DIRNAME}/top-dir ${CVSROOT_DIRNAME}/second-dir - ;; - - - - rstar-toplevel) - # This test used to confirm a bug that existed in the r* commands - # run against the top-level project prior to CVS 1.11.18 & 1.12.10. - # - # The assertion failure was something like: - # do_recursion: Assertion \`strstr (repository, \"/\./\") == ((void \*)0)' failed\..*" - dotest rstar-toplevel-1 "$testcvs -q rlog ." \ -" -RCS file: $CVSROOT_DIRNAME/CVSROOT$DOTSTAR" - - if $keep; then - echo Keeping ${TESTDIR} and exiting due to --keep - exit 0 - fi - ;; - - - - trailingslashes) - # Some tests of CVS's reactions to path specifications containing - # trailing slashes. - mkdir trailingslashes; cd trailingslashes - dotest trailingslashes-init-1 "$testcvs -Q co -ldt ." - dotest trailingslashes-init-2 "$testcvs -Q co -dt2 ." - cd t - echo "Ahh'll be baaack." >topfile - dotest trailingslashes-init-3 "$testcvs -Q add topfile" - dotest trailingslashes-init-4 "$testcvs -Q ci -mto-top" \ -"RCS file: $CVSROOT_DIRNAME/topfile,v -done -Checking in topfile; -$CVSROOT_DIRNAME/topfile,v <-- topfile -initial revision: 1\.1 -done" - - # First, demonstrate the usual case. - cd ../t2 - dotest trailingslashes-1 "$testcvs -q up CVSROOT" - dotest_fail trailingslashes-1a "test -f topfile" - - # Now the one that used to fail in remote mode prior to 1.11.24 - # & 1.12.14. Formerly TODO item #205. - dotest trailingslashes-2 "$testcvs -q up CVSROOT/" - dotest_fail trailingslashes-2a "test -f topfile" - - if $keep; then - echo Keeping $TESTDIR and exiting due to --keep - exit 0 - fi - - cd ../.. - rm -rf trailingslashes $CVSROOT_DIRNAME/topfile,v - ;; - - - - checkout_repository) - dotest_fail checkout_repository-1 \ -"${testcvs} co -d ${CVSROOT_DIRNAME} CVSROOT" \ -"${PROG} \[checkout aborted\]: Cannot check out files into the repository itself" \ -"${PROG} \[checkout aborted\]: absolute pathname \`${CVSROOT_DIRNAME}' illegal for server" - - # The behavior of the client/server test below should be correct. - # The CVS client currently has no way of knowing that the client and - # server are the same machine and thus skips the $CVSROOT checks. - # I think checking for this case in CVS would be bloat since this - # should be a fairly rare occurance. - cd ${CVSROOT_DIRNAME} - dotest_fail checkout_repository-2 "${testcvs} co CVSROOT" \ -"${PROG} \[checkout aborted\]: Cannot check out files into the repository itself" \ -"${PROG} checkout: Updating CVSROOT -${PROG} checkout: move away CVSROOT/checkoutlist; it is in the way -C CVSROOT/checkoutlist -${PROG} checkout: move away CVSROOT/commitinfo; it is in the way -C CVSROOT/commitinfo -${PROG} checkout: move away CVSROOT/config; it is in the way -C CVSROOT/config -${PROG} checkout: move away CVSROOT/cvswrappers; it is in the way -C CVSROOT/cvswrappers -${PROG} checkout: move away CVSROOT/editinfo; it is in the way -C CVSROOT/editinfo -${PROG} checkout: move away CVSROOT/loginfo; it is in the way -C CVSROOT/loginfo -${PROG} checkout: move away CVSROOT/modules; it is in the way -C CVSROOT/modules -${PROG} checkout: move away CVSROOT/notify; it is in the way -C CVSROOT/notify -${PROG} checkout: move away CVSROOT/rcsinfo; it is in the way -C CVSROOT/rcsinfo -${PROG} checkout: move away CVSROOT/taginfo; it is in the way -C CVSROOT/taginfo -${PROG} checkout: move away CVSROOT/verifymsg; it is in the way -C CVSROOT/verifymsg" - - dotest checkout_repository-3 \ -"${testcvs} co -p CVSROOT/modules >/dev/null" \ -"=================================================================== -Checking out CVSROOT/modules -RCS: ${CVSROOT_DIRNAME}/CVSROOT/modules,v -VERS: 1\.[0-9]* -\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*" - cd ${TESTDIR} - ;; - - mflag) - for message in '' ' ' ' - ' ' test' ; do - # Set up - mkdir a-dir; cd a-dir - # Test handling of -m during import - echo testa >>test - if ${testcvs} import -m "$message" a-dir A A1 >>${LOGFILE} 2>&1;then - pass 156 - else - fail 156 - fi - # Must import twice since the first time uses inline code that - # avoids RCS call. - echo testb >>test - if ${testcvs} import -m "$message" a-dir A A2 >>${LOGFILE} 2>&1;then - pass 157 - else - fail 157 - fi - # Test handling of -m during ci - cd ..; rm -r a-dir - if ${testcvs} co a-dir >>${LOGFILE} 2>&1; then - pass 158 - else - fail 158 - fi - cd a-dir - echo testc >>test - if ${testcvs} ci -m "$message" >>${LOGFILE} 2>&1; then - pass 159 - else - fail 159 - fi - # Test handling of -m during rm/ci - rm test; - if ${testcvs} rm test >>${LOGFILE} 2>&1; then - pass 160 - else - fail 160 - fi - if ${testcvs} ci -m "$message" >>${LOGFILE} 2>&1; then - pass 161 - else - fail 161 - fi - # Clean up - cd .. - rm -r a-dir - rm -rf ${CVSROOT_DIRNAME}/a-dir - done - ;; - - editor) - # More tests of log messages, in this case the ability to - # run an external editor. - # TODO: - # * also test $EDITOR, $CVSEDITOR, &c. - # * test what happens if up-to-date check fails. - - # Our "editor" puts "x" at the start of each line, so we - # can see the "CVS:" lines. - cat >${TESTDIR}/editme <${TESTDIR}/edit.new -mv ${TESTDIR}/edit.new \$1 -exit 0 -EOF - chmod +x ${TESTDIR}/editme - - mkdir 1; cd 1 - dotest editor-1 "${testcvs} -q co -l ." '' - mkdir first-dir - dotest editor-2 "${testcvs} add first-dir" \ -"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" - cd first-dir - touch file1 file2 - dotest editor-3 "${testcvs} add file1 file2" \ -"${PROG} add: scheduling file .file1. for addition -${PROG} add: scheduling file .file2. for addition -${PROG} add: use .${PROG} commit. to add these files permanently" - dotest editor-4 "${testcvs} -e ${TESTDIR}/editme -q ci" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -done -Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -initial revision: 1\.1 -done -RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v -done -Checking in file2; -${CVSROOT_DIRNAME}/first-dir/file2,v <-- file2 -initial revision: 1\.1 -done" - dotest editor-5 "${testcvs} -q tag -b br" "T file1 -T file2" - dotest editor-6 "$testcvs -q update -r br" \ -'U file1 -U file2' - echo modify >>file1 - dotest editor-7 "${testcvs} -e ${TESTDIR}/editme -q ci" \ -"Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -new revision: 1\.1\.2\.1; previous revision: 1\.1 -done" - # OK, now we want to make sure "ci -r" puts in the branch - # where appropriate. Note that we can check in on the branch - # without being on the branch, because there is not a revision - # already on the branch. If there were a revision on the branch, - # CVS would correctly give an up-to-date check failed. - dotest editor-8 "$testcvs -q update -A" \ -'U file1 -U file2' - echo add a line >>file2 - dotest editor-9 "${testcvs} -q -e ${TESTDIR}/editme ci -rbr file2" \ -"Checking in file2; -${CVSROOT_DIRNAME}/first-dir/file2,v <-- file2 -new revision: 1\.1\.2\.1; previous revision: 1\.1 -done" - - dotest editor-log-file1 "${testcvs} log -N file1" " -RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -Working file: file1 -head: 1\.1 -branch: -locks: strict -access list: -keyword substitution: kv -total revisions: 2; selected revisions: 2 -description: ----------------------------- -revision 1\.1 -date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; -branches: 1\.1\.2; -xCVS: ---------------------------------------------------------------------- -xCVS: Enter Log. Lines beginning with .CVS:. are removed automatically -xCVS: -xCVS: Committing in . -xCVS: -xCVS: Added Files: -xCVS: file1 file2 -xCVS: ---------------------------------------------------------------------- ----------------------------- -revision 1\.1\.2\.1 -date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; lines: ${PLUS}1 -0 -xCVS: ---------------------------------------------------------------------- -xCVS: Enter Log. Lines beginning with .CVS:. are removed automatically -xCVS: -xCVS: Committing in . -xCVS: -xCVS: Modified Files: -xCVS: Tag: br -xCVS: file1 -xCVS: ---------------------------------------------------------------------- -=============================================================================" - - # The only difference between the two expect strings is the - # presence or absence of "Committing in ." for 1.1.2.1. - dotest editor-log-file2 "${testcvs} log -N file2" " -RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v -Working file: file2 -head: 1\.1 -branch: -locks: strict -access list: -keyword substitution: kv -total revisions: 2; selected revisions: 2 -description: ----------------------------- -revision 1\.1 -date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; -branches: 1\.1\.2; -xCVS: ---------------------------------------------------------------------- -xCVS: Enter Log. Lines beginning with .CVS:. are removed automatically -xCVS: -xCVS: Committing in . -xCVS: -xCVS: Added Files: -xCVS: file1 file2 -xCVS: ---------------------------------------------------------------------- ----------------------------- -revision 1\.1\.2\.1 -date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; lines: ${PLUS}1 -0 -xCVS: ---------------------------------------------------------------------- -xCVS: Enter Log. Lines beginning with .CVS:. are removed automatically -xCVS: -xCVS: Modified Files: -xCVS: Tag: br -xCVS: file2 -xCVS: ---------------------------------------------------------------------- -=============================================================================" " -RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v -Working file: file2 -head: 1\.1 -branch: -locks: strict -access list: -keyword substitution: kv -total revisions: 2; selected revisions: 2 -description: ----------------------------- -revision 1\.1 -date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; -branches: 1\.1\.2; -xCVS: ---------------------------------------------------------------------- -xCVS: Enter Log. Lines beginning with .CVS:. are removed automatically -xCVS: -xCVS: Committing in . -xCVS: -xCVS: Added Files: -xCVS: file1 file2 -xCVS: ---------------------------------------------------------------------- ----------------------------- -revision 1\.1\.2\.1 -date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; lines: ${PLUS}1 -0 -xCVS: ---------------------------------------------------------------------- -xCVS: Enter Log. Lines beginning with .CVS:. are removed automatically -xCVS: -xCVS: Committing in . -xCVS: -xCVS: Modified Files: -xCVS: Tag: br -xCVS: file2 -xCVS: ---------------------------------------------------------------------- -=============================================================================" - - # Test CVS's response to an unchanged log message - cat >${TESTDIR}/editme <${TESTDIR}/editme <\$1 -exit 0 -EOF - chmod +x ${TESTDIR}/editme - dotest_fail editor-emptylog-1 "echo a |${testcvs} -e ${TESTDIR}/editme ci -f file1" \ -" -Log message unchanged or not specified -a)bort, c)ontinue, e)dit, !)reuse this message unchanged for remaining dirs -Action: (continue) ${PROG} \[[a-z]* aborted\]: aborted by user" - - # Test CVS's response to a log message with one blank line - cat >${TESTDIR}/editme <\$1 -exit 0 -EOF - chmod +x ${TESTDIR}/editme - dotest_fail editor-emptylog-1 "echo a |${testcvs} -e ${TESTDIR}/editme ci -f file1" \ -" -Log message unchanged or not specified -a)bort, c)ontinue, e)dit, !)reuse this message unchanged for remaining dirs -Action: (continue) ${PROG} \[[a-z]* aborted\]: aborted by user" - - # Test CVS's response to a log message with only comments - cat >${TESTDIR}/editme <${TESTDIR}/edit.new -mv ${TESTDIR}/edit.new \$1 -exit 0 -EOF - chmod +x ${TESTDIR}/editme - dotest_fail editor-emptylog-1 "echo a |${testcvs} -e ${TESTDIR}/editme ci -f file1" \ -" -Log message unchanged or not specified -a)bort, c)ontinue, e)dit, !)reuse this message unchanged for remaining dirs -Action: (continue) ${PROG} \[[a-z]* aborted\]: aborted by user" - - # Test CVS's response to a log message that is zero bytes - # in length. This caused core dumps in cvs 1.11.5 on Solaris - # hosts. - cd .. - dotest editor-emptylog-continue-1 "${testcvs} -q co CVSROOT/loginfo" \ -"U CVSROOT/loginfo" - - cd CVSROOT - echo 'DEFAULT (echo Start-Log;cat;echo End-Log) >> \$CVSROOT/CVSROOT/commitlog' > loginfo - dotest editor-emptylog-continue-2 "${testcvs} commit -m add loginfo" \ -"Checking in loginfo; -${CVSROOT_DIRNAME}/CVSROOT/loginfo,v <-- loginfo -new revision: 1\.2; previous revision: 1\.1 -done -${PROG} commit: Rebuilding administrative file database" - - cd ../first-dir - cat >${TESTDIR}/editme <>${LOGFILE}; then - pass 163 - else - fail 163 - fi - if ${testcvs} ci -m added >>${LOGFILE} 2>&1; then - pass 164 - else - fail 164 - fi - cd ../.. - mkdir 2 - cd 2 - if ${testcvs} -q co 1dir >>${LOGFILE}; then - pass 165 - else - fail 165 - fi - chmod a-w 1dir - cd ../1/1dir - rm foo; - if ${testcvs} rm foo >>${LOGFILE} 2>&1; then - pass 166 - else - fail 166 - fi - if ${testcvs} ci -m removed >>${LOGFILE} 2>&1; then - pass 167 - else - fail 167 - fi - - cd ../../2/1dir - # The second case in the local and remote versions of errmsg1-168 - # below happens on Cygwin under Windows, where write privileges - # aren't enforced properly. - if $remote; then - dotest errmsg1-168r "${testcvs} -q update" \ -"${PROG} update: foo is no longer in the repository -${PROG} update: unable to remove \./foo: Permission denied" \ -"${PROG} update: foo is no longer in the repository" - else - dotest errmsg1-168 "${testcvs} -q update" \ -"${PROG} update: foo is no longer in the repository -${PROG} update: unable to remove foo: Permission denied" \ -"${PROG} update: foo is no longer in the repository" - fi - - cd .. - chmod u+w 1dir - cd .. - rm -r 1 2 - rm -rf ${CVSROOT_DIRNAME}/1dir - ;; - - errmsg2) - # More tests of various miscellaneous error handling, - # and cvs add behavior in general. - # See also test basicb-4a, concerning "cvs ci CVS". - # Too many tests to mention test the simple cases of - # adding files and directories. - # Test basicb-2a10 tests cvs -n add. - - # First the usual setup; create a directory first-dir. - mkdir 1; cd 1 - dotest errmsg2-1 "${testcvs} -q co -l ." '' - mkdir first-dir - dotest errmsg2-2 "${testcvs} add first-dir" \ -"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" - cd first-dir - dotest_fail errmsg2-3 "${testcvs} add CVS" \ -"${PROG} [a-z]*: cannot add special file .CVS.; skipping" - touch file1 - # For the most part add returns a failure exitstatus if - # there are any errors, even if the remaining files are - # processed without incident. The "cannot add - # special file" message fits this pattern, at - # least currently. - dotest_fail errmsg2-4 "${testcvs} add CVS file1" \ -"${PROG} add: cannot add special file .CVS.; skipping -${PROG} add: scheduling file .file1. for addition -${PROG} add: use .${PROG} commit. to add this file permanently" - # I'm not sure these tests completely convey the various strange - # behaviors that CVS had before it specially checked for "." and - # "..". Suffice it to say that these are unlikely to work right - # without a special case. - dotest_fail errmsg2-5 "${testcvs} add ." \ -"${PROG} [a-z]*: cannot add special file .\..; skipping" - dotest_fail errmsg2-6 "${testcvs} add .." \ -"${PROG} [a-z]*: cannot add special file .\.\..; skipping" - # Make sure that none of the error messages left droppings - # which interfere with normal operation. - dotest errmsg2-7 "${testcvs} -q ci -m add-file1" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -done -Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -initial revision: 1\.1 -done" - mkdir sdir - cd .. - dotest errmsg2-8 "${testcvs} add first-dir/sdir" \ -"Directory ${CVSROOT_DIRNAME}/first-dir/sdir added to the repository" - # while we're here... check commit with no CVS directory - dotest_fail errmsg2-8a "${testcvs} -q ci first-dir nonexistant" \ -"${PROG} [a-z]*: nothing known about .nonexistant' -${PROG} \[[a-z]* aborted\]: correct above errors first!" - dotest_fail errmsg2-8b "${testcvs} -q ci nonexistant first-dir" \ -"${PROG} [a-z]*: nothing known about .nonexistant' -${PROG} \[[a-z]* aborted\]: correct above errors first!" - dotest errmsg2-8c "${testcvs} -q ci first-dir" "" - - cd first-dir - - touch file10 - mkdir sdir10 - dotest errmsg2-10 "${testcvs} add file10 sdir10" \ -"${PROG} add: scheduling file .file10. for addition -Directory ${CVSROOT_DIRNAME}/first-dir/sdir10 added to the repository -${PROG} add: use .${PROG} commit. to add this file permanently" - dotest errmsg2-11 "${testcvs} -q ci -m add-file10" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/file10,v -done -Checking in file10; -${CVSROOT_DIRNAME}/first-dir/file10,v <-- file10 -initial revision: 1\.1 -done" - # Try to see that there are no droppings left by - # any of the previous tests. - dotest errmsg2-12 "${testcvs} -q update" "" - - # Now test adding files with '/' in the name, both one level - # down and more than one level down. - cd .. - mkdir first-dir/sdir10/ssdir - dotest errmsg2-13 "${testcvs} add first-dir/sdir10/ssdir" \ -"Directory ${CVSROOT_DIRNAME}/first-dir/sdir10/ssdir added to the repository" - - touch first-dir/sdir10/ssdir/ssfile - dotest errmsg2-14 \ - "${testcvs} add first-dir/sdir10/ssdir/ssfile" \ -"${PROG} add: scheduling file .first-dir/sdir10/ssdir/ssfile. for addition -${PROG} add: use .${PROG} commit. to add this file permanently" - touch first-dir/file15 - dotest errmsg2-15 "${testcvs} add first-dir/file15" \ -"${PROG} add: scheduling file .first-dir/file15. for addition -${PROG} add: use .${PROG} commit. to add this file permanently" - - # Now the case where we try to give it a directory which is not - # under CVS control. - mkdir bogus-dir - touch bogus-dir/file16 - # The first message, from local CVS, is nice. The second one - # is not nice; would be good to fix remote CVS to give a clearer - # message (e.g. the one from local CVS). But at least it is an - # error message. - dotest_fail errmsg2-16 "${testcvs} add bogus-dir/file16" \ -"${PROG} add: in directory bogus-dir: -${PROG} \[add aborted\]: there is no version here; do .${PROG} checkout. first" \ -"${PROG} add: cannot open CVS/Entries for reading: No such file or directory -${PROG} \[add aborted\]: no repository" - rm -r bogus-dir - - # One error condition we don't test for is trying to add a file - # or directory which already is there. - - dotest errmsg2-17 "${testcvs} -q ci -m checkin" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/file15,v -done -Checking in first-dir/file15; -${CVSROOT_DIRNAME}/first-dir/file15,v <-- file15 -initial revision: 1\.1 -done -RCS file: ${CVSROOT_DIRNAME}/first-dir/sdir10/ssdir/ssfile,v -done -Checking in first-dir/sdir10/ssdir/ssfile; -${CVSROOT_DIRNAME}/first-dir/sdir10/ssdir/ssfile,v <-- ssfile -initial revision: 1\.1 -done" - dotest errmsg2-18 "${testcvs} -Q tag test" '' - - # trying to import the repository - - if $remote; then :; else - cd ${CVSROOT_DIRNAME} - dotest_fail errmsg2-20 "${testcvs} import -mtest . A B" \ -"${PROG} \[import aborted\]: attempt to import the repository" - dotest_fail errmsg2-21 "${testcvs} import -mtest first-dir A B" \ -"${PROG} \[import aborted\]: attempt to import the repository" - fi - - cd .. - rm -r 1 - rm -rf ${CVSROOT_DIRNAME}/first-dir - ;; - - adderrmsg) - # Test some of the error messages the 'add' command can return and - # their reactions to '-q'. - - # First the usual setup; create a directory first-dir. - mkdir 1; cd 1 - dotest adderrmsg-init1 "${testcvs} -q co -l ." '' - mkdir adderrmsg-dir - dotest adderrmsg-init2 "${testcvs} add adderrmsg-dir" \ -"Directory ${CVSROOT_DIRNAME}/adderrmsg-dir added to the repository" - cd adderrmsg-dir - - # try to add the admin dir - dotest_fail adderrmsg-1 "${testcvs} add CVS" \ -"${PROG} [a-z]*: cannot add special file .CVS.; skipping" - # might not want to see this message when you 'cvs add *' - dotest_fail adderrmsg-2 "${testcvs} -q add CVS" "" - - # to test some other messages - touch file1 - dotest adderrmsg-3 "${testcvs} add file1" \ -"${PROG} add: scheduling file .file1. for addition -${PROG} add: use .${PROG} commit. to add this file permanently" - - # add it twice - dotest_fail adderrmsg-4 "${testcvs} add file1" \ -"${PROG} add: file1 has already been entered" - dotest_fail adderrmsg-5 "${testcvs} -q add file1" "" - - dotest adderrmsg-6 "${testcvs} -q ci -madd" \ -"RCS file: ${CVSROOT_DIRNAME}/adderrmsg-dir/file1,v -done -Checking in file1; -${CVSROOT_DIRNAME}/adderrmsg-dir/file1,v <-- file1 -initial revision: 1\.1 -done" - - # file in Entries & repository - dotest_fail adderrmsg-7 "${testcvs} add file1" \ -"${PROG} add: file1 already exists, with version number 1\.1" - dotest_fail adderrmsg-8 "${testcvs} -q add file1" "" - - # clean up - cd ../.. - if $keep; then :; else - rm -r 1 - rm -rf ${CVSROOT_DIRNAME}/adderrmsg-dir - fi - ;; - - opterrmsg) - # Test some option parsing error messages - - # No init is necessary since these error messages are printed b4 - # CVS looks for a sandbox or repository - - # -z used to accept non-numeric arguments. This bit someone who - # attempted `cvs -z -n up' when the -n was read as the argument to - # -z. - dotest_fail opterrmsg-1 "${testcvs} -z -n up" \ -"${PROG}: gzip compression level must be between 0 and 9" - - # Some general -z checks - dotest_fail opterrmsg-2 "${testcvs} -z -1 up" \ -"${PROG}: gzip compression level must be between 0 and 9" - dotest_fail opterrmsg-3 "${testcvs} -z10 up" \ -"${PROG}: gzip compression level must be between 0 and 9" - ;; - - devcom) - mkdir ${CVSROOT_DIRNAME}/first-dir - mkdir 1 - cd 1 - dotest devcom-1 "${testcvs} -q co first-dir" - - cd first-dir - echo abb >abb - dotest devcom-2 "${testcvs} add abb" \ -"$PROG add: scheduling file \`abb' for addition -$PROG add: use '$PROG commit' to add this file permanently" - - dotest devcom-3 "${testcvs} -q ci -m added" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/abb,v -done -Checking in abb; -${CVSROOT_DIRNAME}/first-dir/abb,v <-- abb -initial revision: 1\.1 -done" - - dotest_fail devcom-4 "${testcvs} watch" "Usage${DOTSTAR}" - - dotest devcom-5 "${testcvs} watch on" - - echo abc >abc - dotest devcom-6 "${testcvs} add abc" \ -"$PROG add: scheduling file \`abc' for addition -$PROG add: use '$PROG commit' to add this file permanently" - - dotest devcom-7 "${testcvs} -q ci -m added" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/abc,v -done -Checking in abc; -${CVSROOT_DIRNAME}/first-dir/abc,v <-- abc -initial revision: 1\.1 -done" - - cd ../.. - mkdir 2 - cd 2 - - dotest devcom-8 "${testcvs} -q co first-dir" \ -"U first-dir/abb -U first-dir/abc" - - cd first-dir - dotest_fail devcom-9 "test -w abb" - dotest_fail devcom-9 "test -w abc" - - dotest devcom-10 "${testcvs} editors" "" - - dotest devcom-11 "${testcvs} edit abb" - - # Here we test for the traditional ISO C ctime() date format. - # We assume the C locale; I guess that works provided we set - # LC_ALL at the start of this script but whether these - # strings should vary based on locale does not strike me as - # self-evident. - dotest devcom-12 "${testcvs} editors" \ -"abb ${username} [SMTWF][uoehra][neduit] [JFAMSOND][aepuco][nbrylgptvc] [0-9 ][0-9] [0-9:]* [0-9][0-9][0-9][0-9] GMT [-a-zA-Z_.0-9]* ${TESTDIR}/2/first-dir" - - echo aaaa >>abb - dotest devcom-13 "${testcvs} ci -m modify abb" \ -"Checking in abb; -${CVSROOT_DIRNAME}/first-dir/abb,v <-- abb -new revision: 1\.2; previous revision: 1\.1 -done" - - # Unedit of a file not being edited should be a noop. - dotest devcom-14 "${testcvs} unedit abb" '' - - dotest devcom-15 "${testcvs} editors" "" - - dotest_fail devcom-16 "test -w abb" - - dotest devcom-17 "${testcvs} edit abc" - - # Unedit of an unmodified file. - dotest devcom-18 "${testcvs} unedit abc" - dotest devcom-19 "${testcvs} edit abc" - - echo changedabc >abc - # Try to unedit a modified file; cvs should ask for confirmation - dotest devcom-20 "echo no | ${testcvs} unedit abc" \ -"abc has been modified; revert changes? " - - dotest devcom-21 "echo changedabc | cmp - abc" - - # OK, now confirm the unedit - dotest devcom-22 "echo yes | ${testcvs} unedit abc" \ -"abc has been modified; revert changes? " - - dotest devcom-23 "echo abc | cmp - abc" - - dotest devcom-24 "${testcvs} watchers" '' - - # FIXME: This probably should be an error message instead - # of silently succeeding and printing nothing. - dotest devcom-a-nonexist "${testcvs} watchers nonexist" '' - - dotest devcom-a1 "${testcvs} watch add" '' - dotest devcom-a2 "${testcvs} watchers" \ -"abb ${username} edit unedit commit -abc ${username} edit unedit commit" - dotest devcom-a3 "${testcvs} watch remove -a unedit abb" '' - dotest devcom-a4 "${testcvs} watchers abb" \ -"abb ${username} edit commit" - - # Check tagging and checking out while we have a CVS - # directory in the repository. - dotest devcom-t0 "${testcvs} -q tag tag" \ -'T abb -T abc' - cd ../.. - mkdir 3 - cd 3 - - # Test commented out because the bug it tests for is not fixed - # The error is: - # cvs watchers: cannot open CVS/Entries for reading: No such file or directory - # cvs: ../../work/ccvs/src/fileattr.c:75: fileattr_read: Assertion `fileattr_stored_repos != ((void *)0)' failed. -: dotest devcom-t-nonexist "${testcvs} watchers nonexist" fixme - - dotest devcom-t1 "${testcvs} -q co -rtag first-dir/abb" \ -'U first-dir/abb' - cd .. - # Since first-dir/abb is readonly, use -f. - rm -rf 3 - - # Test checking out the directory rather than the file. - mkdir 3 - cd 3 - dotest devcom-t2 "${testcvs} -q co -rtag first-dir" \ -'U first-dir/abb -U first-dir/abc' - cd .. - # Since the files are readonly, use -f. - rm -rf 3 - - # Now do it again, after removing the val-tags file created - # by devcom-t1 to force CVS to search the repository - # containing CVS directories. - rm -f ${CVSROOT_DIRNAME}/CVSROOT/val-tags - mkdir 3 - cd 3 - dotest devcom-t3 "${testcvs} -q co -rtag first-dir" \ -'U first-dir/abb -U first-dir/abc' - cd .. - # Since the files are readonly, use -f. - rm -rf 3 - - # Now remove all the file attributes - cd 2/first-dir - dotest devcom-b0 "${testcvs} watch off" '' - dotest devcom-b1 "${testcvs} watch remove" '' - # Test that CVS 1.6 and earlier can handle the repository. - dotest_fail devcom-b2 "test -d ${CVSROOT_DIRNAME}/first-dir/CVS" - - # Now test watching just some, not all, files. - dotest devcom-some0 "${testcvs} watch on abc" '' - cd ../.. - mkdir 3 - cd 3 - dotest devcom-some1 "${testcvs} -q co first-dir" 'U first-dir/abb -U first-dir/abc' - dotest devcom-some2 "test -w first-dir/abb" '' - dotest_fail devcom-some3 "test -w first-dir/abc" '' - cd .. - - if $keep; then - echo Keeping ${TESTDIR} and exiting due to --keep - exit 0 - fi - - # Use -f because of the readonly files. - rm -rf 1 2 3 - rm -rf ${CVSROOT_DIRNAME}/first-dir - ;; - - devcom2) - # More watch tests, most notably setting watches on - # files in various different states. - mkdir ${CVSROOT_DIRNAME}/first-dir - mkdir 1 - cd 1 - dotest devcom2-1 "${testcvs} -q co first-dir" '' - cd first-dir - - # This should probably be an error; setting a watch on a totally - # unknown file is more likely to be a typo than intentional. - # But that isn't the currently implemented behavior. - dotest devcom2-2 "${testcvs} watch on w1" '' - - touch w1 w2 w3 nw1 - dotest devcom2-3 "${testcvs} add w1 w2 w3 nw1" "${DOTSTAR}" - # Letting the user set the watch here probably can be considered - # a feature--although it leads to a few potentially strange - # consequences like one user can set the watch and another actually - # adds the file. - dotest devcom2-4 "${testcvs} watch on w2" '' - dotest devcom2-5 "${testcvs} -q ci -m add-them" "${DOTSTAR}" - - # Note that this test differs in a subtle way from devcom-some0; - # in devcom-some0 the watch is creating a new fileattr file, and - # here we are modifying an existing one. - dotest devcom2-6 "${testcvs} watch on w3" '' - - # Now test that all the watches got set on the correct files - # FIXME: CVS should have a way to report whether watches are - # set, I think. The "check it out and see if it read-only" is - # sort of OK, but is complicated by CVSREAD and doesn't help - # if the file is added and not yet committed or some such. - # Probably "cvs status" should report "watch: on" if watch is on - # (and nothing if watch is off, so existing behavior is preserved). - cd ../.. - mkdir 2 - cd 2 - dotest devcom2-7 "${testcvs} -q co first-dir" 'U first-dir/nw1 -U first-dir/w1 -U first-dir/w2 -U first-dir/w3' - dotest devcom2-8 "test -w first-dir/nw1" '' - dotest_fail devcom2-9 "test -w first-dir/w1" '' - dotest_fail devcom2-10 "test -w first-dir/w2" '' - dotest_fail devcom2-11 "test -w first-dir/w3" '' - - cd first-dir - # OK, now we want to try files in various states with cvs edit. - dotest devcom2-12 "${testcvs} edit w4" \ -"${PROG} edit: no such file w4; ignored" - # Try the same thing with a per-directory watch set. - dotest devcom2-13 "${testcvs} watch on" '' - dotest devcom2-14 "${testcvs} edit w5" \ -"${PROG} edit: no such file w5; ignored" - dotest devcom2-15 "${testcvs} editors" '' - dotest devcom2-16 "${testcvs} editors w4" '' - # Make sure there are no droppings lying around - dotest devcom2-17 "cat ${CVSROOT_DIRNAME}/first-dir/CVS/fileattr" \ -"Fw1 _watched= -Fw2 _watched= -Fw3 _watched= -Fnw1 _watched= -D _watched=" - cd .. - - # Do a little error testing - dotest devcom2-18 "${testcvs} -q co -d first+dir first-dir" \ -"U first${PLUS}dir/nw1 -U first${PLUS}dir/w1 -U first${PLUS}dir/w2 -U first${PLUS}dir/w3" - cd first+dir - dotest_fail devcom2-19 "${testcvs} edit" \ -"${PROG} \[[a-z]* aborted\]: current directory (${TESTDIR}/2/first${PLUS}dir) contains an invalid character (${PLUS},>;=\\\\t\\\\n)" - - # Make sure there are no droppings lying around - dotest devcom2-20 "cat ${CVSROOT_DIRNAME}/first-dir/CVS/fileattr" \ -"Fw1 _watched= -Fw2 _watched= -Fw3 _watched= -Fnw1 _watched= -D _watched=" - - cd ../.. - - # Use -f because of the readonly files. - rm -rf 1 2 - rm -rf ${CVSROOT_DIRNAME}/first-dir - ;; - - devcom3) - # More watch tests, most notably handling of features designed - # for future expansion. - mkdir ${CVSROOT_DIRNAME}/first-dir - mkdir 1 - cd 1 - dotest devcom3-1 "${testcvs} -q co first-dir" '' - cd first-dir - - touch w1 w2 - dotest devcom3-2 "${testcvs} add w1 w2" "${DOTSTAR}" - dotest devcom3-3 "${testcvs} watch on w1 w2" '' - dotest devcom3-4 "${testcvs} -q ci -m add-them" "${DOTSTAR}" - - # OK, since we are about to delve into CVS's internals, make - # sure that we seem to be correct about how they work. - dotest devcom3-5 "cat ${CVSROOT_DIRNAME}/first-dir/CVS/fileattr" \ -"Fw1 _watched= -Fw2 _watched=" - # Now write a few more lines, just as if we were a newer version - # of CVS implementing some new feature. - cat <<'EOF' >>${CVSROOT_DIRNAME}/first-dir/CVS/fileattr -Enew line here -G@#$^!@#=& -EOF - # Now get CVS to write to the fileattr file.... - dotest devcom3-6 "${testcvs} watch off w1" '' - # ...and make sure that it hasn't clobbered our new lines. - # Note that writing these lines in another order would be OK - # too. - dotest devcom3-7 "cat ${CVSROOT_DIRNAME}/first-dir/CVS/fileattr" \ -"Fw2 _watched= -G@#..!@#=& -Enew line here" - - # See what CVS does when a file name is duplicated. The - # behavior of all versions of CVS since file attributes were - # implemented is that it nukes the duplications. This seems - # reasonable enough, although it means it isn't clear how - # useful duplicates would be for purposes of future - # expansion. But in the interests of keeping behaviors - # predictable, might as well test for it, I guess. - echo 'Fw2 duplicate=' >>${CVSROOT_DIRNAME}/first-dir/CVS/fileattr - dotest devcom3-8 "${testcvs} watch on w1" '' - dotest devcom3-9 "cat ${CVSROOT_DIRNAME}/first-dir/CVS/fileattr" \ -"Fw2 _watched= -Fw1 _watched= -Enew line here -G@#..!@#=&" - - # Now test disconnected "cvs edit" and the format of the - # CVS/Notify file. - if $remote; then - CVS_SERVER_save=${CVS_SERVER} - CVS_SERVER=${TESTDIR}/cvs-none; export CVS_SERVER - - # The ${DOTSTAR} below matches the exact CVS server error message, - # which in :fork: mode is: - # "$PROG \[edit aborted\]: cannot exec $TESTDIR/cvs-none: ${DOTSTAR}", - # but which is: - # "bash2: line 1: $TESTDIR/cvs-none: No such file or directory" - # when testing across an :ext:/ssh link to my Linux 2.4 box. - # - # I can't even test for the second part of the error message, - # from the client, which varies more consistently, usually either - # "end of file from server" (if the process doing the exec exits - # before the parent gets around to sending data to it) or - # "received broken pipe signal" (if it is the other way around), - # since HP-UX fails to output it. - dotest_fail devcom3-9ar "${testcvs} edit w1 2>/dev/null" - dotest devcom3-9br "test -w w1" "" - dotest devcom3-9cr "cat CVS/Notify" \ -"Ew1 [SMTWF][uoehra][neduit] [JFAMSOND][aepuco][nbrylgptvc] [0-9 ][0-9] [0-9:]* [0-9][0-9][0-9][0-9] GMT [-a-zA-Z_.0-9]* ${TESTDIR}/1/first-dir EUC" - CVS_SERVER=${CVS_SERVER_save}; export CVS_SERVER - dotest devcom3-9dr "${testcvs} -q update" "" - dotest_fail devcom3-9er "test -f CVS/Notify" "" - dotest devcom3-9fr "${testcvs} watchers w1" \ -"w1 ${username} tedit tunedit tcommit" - dotest devcom3-9gr "${testcvs} unedit w1" "" - dotest devcom3-9hr "${testcvs} watchers w1" "" - fi - - cd ../.. - # OK, now change the tab to a space, and see that CVS gives - # a reasonable error (this is database corruption but CVS should - # not lose its mind). - sed -e 's/Fw2 /Fw2 /' <${CVSROOT_DIRNAME}/first-dir/CVS/fileattr \ - >${CVSROOT_DIRNAME}/first-dir/CVS/fileattr.new - mv ${CVSROOT_DIRNAME}/first-dir/CVS/fileattr.new \ - ${CVSROOT_DIRNAME}/first-dir/CVS/fileattr - mkdir 2; cd 2 - dotest_fail devcom3-10 "${testcvs} -Q co ." \ -"${PROG} \[checkout aborted\]: file attribute database corruption: tab missing in ${CVSROOT_DIRNAME}/first-dir/CVS/fileattr" - cd .. - - # Use -f because of the readonly files. - rm -rf 1 2 - rm -rf ${CVSROOT_DIRNAME}/first-dir - ;; - - watch4) - # More watch tests, including adding directories. - mkdir 1; cd 1 - dotest watch4-0a "${testcvs} -q co -l ." '' - mkdir first-dir - dotest watch4-0b "${testcvs} add first-dir" \ -"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" - - cd first-dir - dotest watch4-1 "${testcvs} watch on" '' - # This is just like the 173 test - touch file1 - dotest watch4-2 "${testcvs} add file1" \ -"${PROG} add: scheduling file .file1. for addition -${PROG} add: use .${PROG} commit. to add this file permanently" - dotest watch4-3 "${testcvs} -q ci -m add" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -done -Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -initial revision: 1\.1 -done" - # Now test the analogous behavior for directories. - mkdir subdir - dotest watch4-4 "${testcvs} add subdir" \ -"Directory ${CVSROOT_DIRNAME}/first-dir/subdir added to the repository" - cd subdir - touch sfile - dotest watch4-5 "${testcvs} add sfile" \ -"${PROG} add: scheduling file .sfile. for addition -${PROG} add: use .${PROG} commit. to add this file permanently" - dotest watch4-6 "${testcvs} -q ci -m add" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/subdir/sfile,v -done -Checking in sfile; -${CVSROOT_DIRNAME}/first-dir/subdir/sfile,v <-- sfile -initial revision: 1\.1 -done" - cd ../../.. - mkdir 2; cd 2 - dotest watch4-7 "${testcvs} -q co first-dir" "U first-dir/file1 -U first-dir/subdir/sfile" - dotest_fail watch4-8 "test -w first-dir/file1" '' - dotest_fail watch4-9 "test -w first-dir/subdir/sfile" '' - cd first-dir - dotest watch4-10 "${testcvs} edit file1" '' - echo 'edited in 2' >file1 - cd ../.. - - cd 1/first-dir - dotest watch4-11 "${testcvs} edit file1" '' - echo 'edited in 1' >file1 - dotest watch4-12 "${testcvs} -q ci -m edit-in-1" \ -"Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -new revision: 1\.2; previous revision: 1\.1 -done" - cd ../.. - cd 2/first-dir - dotest watch4-13 "${testcvs} -q update" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -retrieving revision 1\.1 -retrieving revision 1\.2 -Merging differences between 1\.1 and 1\.2 into file1 -rcsmerge: warning: conflicts during merge -${PROG} update: conflicts found in file1 -C file1" - if (echo yes | ${testcvs} unedit file1) >>${LOGFILE}; then - pass watch4-14 - else - fail watch4-15 - fi - # This could plausibly be defined to either go back to the revision - # which was cvs edit'd (the status quo), or back to revision 1.2 - # (that is, the merge could update CVS/Base/file1). We pick the - # former because it is easier to implement, not because we have - # thought much about which is better. - dotest watch4-16 "cat file1" '' - # Make sure CVS really thinks we are at 1.1. - dotest watch4-17 "${testcvs} -q update" "U file1" - dotest watch4-18 "cat file1" "edited in 1" - cd ../.. - - # As a sanity check, make sure we are in the right place. - dotest watch4-cleanup-1 "test -d 1" '' - dotest watch4-cleanup-1 "test -d 2" '' - # Specify -f because of the readonly files. - rm -rf 1 2 - rm -rf ${CVSROOT_DIRNAME}/first-dir - ;; - - watch5) - # This test was designed to catch a problem in server - # mode where an 'cvs edit'd file disappeared from the - # CVS/Base directory when 'cvs status' or 'cvs update' - # was called on the file after the file was touched. - # - # This test is still here to prevent the bug from - # being reintroduced. - # - # The rationale for having CVS/Base stay around is that - # CVS/Base should be there if "cvs edit" has been run (this - # may be helpful as a "cvs editors" analogue, it is - # client-side and based on working directory not username; - # but more importantly, it isn't clear why a "cvs status" - # would act like an unedit, and even if it does, it would - # need to make the file read-only again). - - mkdir watch5; cd watch5 - dotest watch5-0a "${testcvs} -q co -l ." '' - mkdir first-dir - dotest watch5-0b "${testcvs} add first-dir" \ -"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" - - cd first-dir - dotest watch5-1 "${testcvs} watch on" '' - # This is just like the 173 test - touch file1 - dotest watch5-2 "${testcvs} add file1" \ -"${PROG} add: scheduling file .file1. for addition -${PROG} add: use .${PROG} commit. to add this file permanently" - dotest watch5-3 "${testcvs} -q ci -m add" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -done -Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -initial revision: 1\.1 -done" - dotest watch5-4 "${testcvs} edit file1" '' - dotest watch5-5 "test -f CVS/Base/file1" '' - if ${testcvs} status file1 >>${LOGFILE} 2>&1; then - pass watch5-6 - else - fail watch5-6 - fi - dotest watch5-7 "test -f CVS/Base/file1" '' - - # Here's where the file used to dissappear - touch file1 - if ${testcvs} status file1 >>${LOGFILE} 2>&1; then - pass watch5-8 - else - fail watch5-8 - fi - dotest watch5-10 "test -f CVS/Base/file1" '' - - # Make sure update won't remove the file either - touch file1 - dotest watch5-11 "${testcvs} -q up" '' - dotest watch5-12 "test -f CVS/Base/file1" '' - - cd ../.. - rm -r watch5 - rm -rf ${CVSROOT_DIRNAME}/first-dir - ;; - - - - watch6) - # Check that `cvs watch on' does not reset the fileattr file. - mkdir watch6; cd watch6 - - dotest watch6-setup-1 "$testcvs -Q co -ldtop ." - cd top - mkdir watch6 - dotest watch6-setup-2 "$testcvs -Q add watch6" - - cd .. - dotest watch6-setup-3 "$testcvs -Q co watch6" - cd watch6 - - mkdir subdir - dotest watch6-setup-4 "$testcvs -Q add subdir" - cd subdir - - # START watch add/remove sequence - dotest watch6-1 "$testcvs -Q watch add" - dotest watch6-2 \ -"grep '_watchers' $CVSROOT_DIRNAME/watch6/subdir/CVS/fileattr >/dev/null" - - dotest watch6-3 "$testcvs watch on" - dotest watch6-4 \ -"grep '_watchers' $CVSROOT_DIRNAME/watch6/subdir/CVS/fileattr >/dev/null" - dotest watch6-5 \ -"grep '_watched' $CVSROOT_DIRNAME/watch6/subdir/CVS/fileattr >/dev/null" - - dotest watch6-6 "$testcvs watch off" - dotest watch6-7 \ -"grep '_watchers' $CVSROOT_DIRNAME/watch6/subdir/CVS/fileattr >/dev/null" - dotest_fail watch6-8 \ -"grep '_watched' $CVSROOT_DIRNAME/watch6/subdir/CVS/fileattr >/dev/null" - - dotest watch6-9 "$testcvs watch remove" - dotest_fail watch6-10 \ -"test -d $CVSROOT_DIRNAME/test-directory/subdir/CVS" - dotest_fail watch6-11 \ -"test -f $CVSROOT_DIRNAME/test-directory/subdir/CVS/fileattr" - # END watch add/remove sequence - - echo Hi there >afile - dotest watch6-12 "$testcvs -Q add afile" - dotest watch6-13 "$testcvs ci -m 'A file' afile" \ -"RCS file: $CVSROOT_DIRNAME/watch6/subdir/afile,v -done -Checking in afile; -$CVSROOT_DIRNAME/watch6/subdir/afile,v <-- afile -initial revision: 1\.1 -done" - - # START watch add/remove sequence - dotest watch6-14 "$testcvs -Q watch add" - dotest watch6-15 \ -"grep '_watchers' $CVSROOT_DIRNAME/watch6/subdir/CVS/fileattr >/dev/null" - - dotest watch6-16 "$testcvs watch on" - dotest watch6-17 \ -"grep '_watchers' $CVSROOT_DIRNAME/watch6/subdir/CVS/fileattr >/dev/null" - dotest watch6-18 \ -"grep '_watched' $CVSROOT_DIRNAME/watch6/subdir/CVS/fileattr >/dev/null" - - dotest watch6-19 "$testcvs watch off" - dotest watch6-20 \ -"grep '_watchers' $CVSROOT_DIRNAME/watch6/subdir/CVS/fileattr >/dev/null" - dotest_fail watch6-21 \ -"grep '_watched' $CVSROOT_DIRNAME/watch6/subdir/CVS/fileattr >/dev/null" - - dotest watch6-22 "$testcvs watch remove" - dotest_fail watch6-23 \ -"test -d $CVSROOT_DIRNAME/test-directory/subdir/CVS" - dotest_fail watch6-24 \ -"test -f $CVSROOT_DIRNAME/test-directory/subdir/CVS/fileattr" - # END watch add/remove sequence - - if $keep; then - echo Keeping $TESTDIR and exiting due to --keep - exit 0 - fi - cd ../../.. - rm -r watch6 - rm -rf $CVSROOT_DIRNAME/watch6 - ;; - - - - unedit-without-baserev) - mkdir 1; cd 1 - module=x - - file=m - echo foo > $file - dotest unedit-without-baserev-1 \ - "$testcvs -Q import -m . $module X Y" '' - dotest unedit-without-baserev-2 "$testcvs -Q co $module" '' - cd $module - - dotest unedit-without-baserev-3 "$testcvs -Q edit $file" '' - - echo add a line >> $file - rm -f CVS/Baserev - - # This will fail on most systems. - echo "yes" | dotest unedit-without-baserev-4 "${testcvs} -Q unedit $file" \ -"m has been modified; revert changes${QUESTION} ${PROG} unedit: m not mentioned in CVS/Baserev -${PROG} unedit: run update to complete the unedit" - - # SunOS4.1.4 systems make it this far, but with a corrupted - # CVS/Entries file. Demonstrate the corruption! - dotest unedit-without-baserev-5 "cat CVS/Entries" \ - "/$file/1\.1\.1\.1/${DOTSTAR}" - - dotest unedit-without-baserev-6 "${testcvs} -q update" \ -"${PROG} update: warning: m was lost -U m" - - # OK, those were the easy cases. Now tackle the hard one - # (the reason that CVS/Baserev was invented rather than just - # getting the revision from CVS/Entries). This is very - # similar to watch4-10 through watch4-18 but with Baserev - # missing. - cd ../.. - mkdir 2; cd 2 - dotest unedit-without-baserev-7 "${testcvs} -Q co x" '' - cd x - - dotest unedit-without-baserev-10 "${testcvs} edit m" '' - echo 'edited in 2' >m - cd ../.. - - cd 1/x - dotest unedit-without-baserev-11 "${testcvs} edit m" '' - echo 'edited in 1' >m - dotest unedit-without-baserev-12 "${testcvs} -q ci -m edit-in-1" \ -"Checking in m; -${CVSROOT_DIRNAME}/x/m,v <-- m -new revision: 1\.2; previous revision: 1\.1 -done" - cd ../.. - cd 2/x - dotest unedit-without-baserev-13 "${testcvs} -q update" \ -"RCS file: ${CVSROOT_DIRNAME}/x/m,v -retrieving revision 1\.1\.1\.1 -retrieving revision 1\.2 -Merging differences between 1\.1\.1\.1 and 1\.2 into m -rcsmerge: warning: conflicts during merge -${PROG} update: conflicts found in m -C m" - rm CVS/Baserev - dotest unedit-without-baserev-14 "echo yes | ${testcvs} unedit m" \ -"m has been modified; revert changes${QUESTION} ${PROG} unedit: m not mentioned in CVS/Baserev -${PROG} unedit: run update to complete the unedit" - dotest unedit-without-baserev-15 "${testcvs} -q update" \ -"${PROG} update: warning: m was lost -U m" - # The following tests are kind of degenerate compared with - # watch4-16 through watch4-18 but might as well make sure that - # nothing seriously wrong has happened to the working directory. - dotest unedit-without-baserev-16 "cat m" 'edited in 1' - # Make sure CVS really thinks we are at 1.2. - dotest unedit-without-baserev-17 "${testcvs} -q update" "" - dotest unedit-without-baserev-18 "cat m" "edited in 1" - - cd ../.. - rm -rf 1 - rm -r 2 - rm -rf ${CVSROOT_DIRNAME}/$module - ;; - - ignore) - # On Windows, we can't check out CVSROOT, because the case - # insensitivity means that this conflicts with cvsroot. - mkdir ignore - cd ignore - - dotest ignore-1 "${testcvs} -q co CVSROOT" "U CVSROOT/${DOTSTAR}" - cd CVSROOT - echo rootig.c >cvsignore - dotest ignore-2 "${testcvs} add cvsignore" \ -"${PROG}"' add: scheduling file `cvsignore'"'"' for addition -'"${PROG}"' add: use .'"${PROG}"' commit. to add this file permanently' - - # As of Jan 96, local CVS prints "Examining ." and remote doesn't. - # Accept either. - dotest ignore-3 " ${testcvs} ci -m added" \ -"${PROG} [a-z]*: Examining \. -RCS file: ${CVSROOT_DIRNAME}/CVSROOT/cvsignore,v -done -Checking in cvsignore; -${CVSROOT_DIRNAME}/CVSROOT/cvsignore,v <-- cvsignore -initial revision: 1\.1 -done -${PROG} commit: Rebuilding administrative file database" - - cd .. - if echo "yes" | ${testcvs} release -d CVSROOT >>${LOGFILE} ; then - pass ignore-4 - else - fail ignore-4 - fi - - # CVS looks at the home dir from getpwuid, not HOME (is that correct - # behavior?), so this is hard to test and we won't try. - # echo foobar.c >${HOME}/.cvsignore - CVSIGNORE=envig.c; export CVSIGNORE - mkdir dir-to-import - cd dir-to-import - touch foobar.c bar.c rootig.c defig.o envig.c optig.c - # We use sort because we can't predict the order in which - # the files will be listed. - dotest_sort ignore-5 "${testcvs} import -m m -I optig.c ignore/first-dir tag1 tag2" \ -' - -I ignore/first-dir/defig.o -I ignore/first-dir/envig.c -I ignore/first-dir/optig.c -I ignore/first-dir/rootig.c -N ignore/first-dir/bar.c -N ignore/first-dir/foobar.c -No conflicts created by this import' - dotest_sort ignore-6 "${testcvs} import -m m -I ! ignore/second-dir tag3 tag4" \ -' - -N ignore/second-dir/bar.c -N ignore/second-dir/defig.o -N ignore/second-dir/envig.c -N ignore/second-dir/foobar.c -N ignore/second-dir/optig.c -N ignore/second-dir/rootig.c -No conflicts created by this import' - cd .. - rm -r dir-to-import - - mkdir 1 - cd 1 - dotest ignore-7 "${testcvs} -q co -dsecond-dir ignore/second-dir" \ -'U second-dir/bar.c -U second-dir/defig.o -U second-dir/envig.c -U second-dir/foobar.c -U second-dir/optig.c -U second-dir/rootig.c' - dotest ignore-8 "${testcvs} -q co -dfirst-dir ignore/first-dir" 'U first-dir/bar.c -U first-dir/foobar.c' - cd first-dir - touch rootig.c defig.o envig.c optig.c notig.c - dotest ignore-9 "${testcvs} -q update -I optig.c" "${QUESTION} notig.c" - # The fact that CVS requires us to specify -I CVS here strikes me - # as a bug. - dotest_sort ignore-10 "${testcvs} -q update -I ! -I CVS" \ -"${QUESTION} defig.o -${QUESTION} envig.c -${QUESTION} notig.c -${QUESTION} optig.c -${QUESTION} rootig.c" - - # Now test that commands other than update also print "? notig.c" - # where appropriate. Only test this for remote, because local - # CVS only prints it on update. - rm optig.c - if $remote; then - dotest ignore-11r "${testcvs} -q diff" "${QUESTION} notig.c" - - # Force the server to be contacted. Ugh. Having CVS - # contact the server for the sole purpose of checking - # the CVSROOT/cvsignore file does not seem like such a - # good idea, so I imagine this will continue to be - # necessary. Oh well, at least we test CVS's ablity to - # handle a file with a modified timestamp but unmodified - # contents. - touch bar.c - - dotest ignore-11r "${testcvs} -q ci -m commit-it" "${QUESTION} notig.c" - fi - - # now test .cvsignore files - cd .. - echo notig.c >first-dir/.cvsignore - echo foobar.c >second-dir/.cvsignore - touch first-dir/notig.c second-dir/notig.c second-dir/foobar.c - dotest_sort ignore-12 "${testcvs} -qn update" \ -"${QUESTION} first-dir/.cvsignore -${QUESTION} second-dir/.cvsignore -${QUESTION} second-dir/notig.c" - dotest_sort ignore-13 "${testcvs} -qn update -I! -I CVS" \ -"${QUESTION} first-dir/.cvsignore -${QUESTION} first-dir/defig.o -${QUESTION} first-dir/envig.c -${QUESTION} first-dir/rootig.c -${QUESTION} second-dir/.cvsignore -${QUESTION} second-dir/notig.c" - - echo yes | dotest ignore-14 "${testcvs} release -d first-dir" \ -"${QUESTION} \.cvsignore -You have \[0\] altered files in this repository. -Are you sure you want to release (and delete) directory .first-dir': " - - echo add a line >>second-dir/foobar.c - rm second-dir/notig.c second-dir/.cvsignore - echo yes | dotest ignore-15 "${testcvs} release -d second-dir" \ -"M foobar.c -You have \[1\] altered files in this repository. -Are you sure you want to release (and delete) directory .second-dir': " - - cd ../.. - if $keep; then :; else - rm -r ignore - rm -rf ${CVSROOT_DIRNAME}/ignore - fi - ;; - - ignore-on-branch) - # Test that CVS _doesn't_ ignore files on branches because they were - # added to the trunk. - mkdir ignore-on-branch; cd ignore-on-branch - mkdir $CVSROOT_DIRNAME/ignore-on-branch - - # create file1 & file2 on trunk - dotest ignore-on-branch-setup-1 "$testcvs -q co -dsetup ignore-on-branch" '' - cd setup - echo file1 >file1 - dotest ignore-on-branch-setup-2 "$testcvs -q add file1" \ -"${PROG} add: use .${PROG} commit. to add this file permanently" - dotest ignore-on-branch-setup-3 "$testcvs -q ci -mfile1 file1" \ -"RCS file: $CVSROOT_DIRNAME/ignore-on-branch/file1,v -done -Checking in file1; -$CVSROOT_DIRNAME/ignore-on-branch/file1,v <-- file1 -initial revision: 1\.1 -done" - dotest ignore-on-branch-setup-4 "$testcvs -q tag -b branch" 'T file1' - echo file2 >file2 - dotest ignore-on-branch-setup-5 "$testcvs -q add file2" \ -"${PROG} add: use .${PROG} commit. to add this file permanently" - dotest ignore-on-branch-setup-6 "$testcvs -q ci -mtrunk file2" \ -"RCS file: $CVSROOT_DIRNAME/ignore-on-branch/file2,v -done -Checking in file2; -$CVSROOT_DIRNAME/ignore-on-branch/file2,v <-- file2 -initial revision: 1\.1 -done" - - cd .. - - # Check out branch. - # - # - This was the original failure case - file2 would not be flagged - # with a '?' - dotest ignore-on-branch-1 "$testcvs -q co -rbranch ignore-on-branch" \ -'U ignore-on-branch/file1' - cd ignore-on-branch - echo file2 on branch >file2 - dotest ignore-on-branch-2 "$testcvs -nq update" '? file2' - - # Now set up for a join. One of the original fixes for this would - # print out a 'U' and a '?' during a join which added a file. - if $remote; then - dotest ignore-on-branch-3 "$testcvs -q tag -b branch2" \ -'? file2 -T file1' - else - dotest ignore-on-branch-3 "$testcvs -q tag -b branch2" 'T file1' - fi - dotest ignore-on-branch-4 "$testcvs -q add file2" \ -"${PROG} add: use .${PROG} commit. to add this file permanently" - dotest ignore-on-branch-5 "$testcvs -q ci -mbranch file2" \ -"Checking in file2; -$CVSROOT_DIRNAME/ignore-on-branch/file2,v <-- file2 -new revision: 1\.1\.2\.2; previous revision: 1\.1\.2\.1 -done" - dotest ignore-on-branch-6 "$testcvs -q up -rbranch2" \ -"[UP] file1 -$PROG update: file2 is no longer in the repository" - dotest ignore-on-branch-7 "$testcvs -q up -jbranch" 'U file2' - - cd ../.. - if $keep; then :; else - rm -r ignore-on-branch - rm -rf $CVSROOT_DIRNAME/ignore-on-branch - fi - ;; - - binfiles) - # Test cvs's ability to handle binary files. - # List of binary file tests: - # * conflicts, "cvs admin": binfiles - # * branching and joining: binfiles2 - # * adding and removing files: binfiles3 - # * -k wrappers: binwrap, binwrap2, binwrap3 - # * "cvs import" and wrappers: binwrap, binwrap2, binwrap3 - # * -k option to "cvs import": none yet, as far as I know. - mkdir ${CVSROOT_DIRNAME}/first-dir - mkdir 1; cd 1 - dotest binfiles-1 "${testcvs} -q co first-dir" '' - ${AWK} 'BEGIN { printf "%c%c%c@%c%c", 2, 10, 137, 13, 10 }' \ - binfile.dat - cat binfile.dat binfile.dat >binfile2.dat - cd first-dir - cp ../binfile.dat binfile - dotest binfiles-2 "${testcvs} add -kb binfile" \ -"${PROG}"' add: scheduling file `binfile'\'' for addition -'"${PROG}"' add: use .'"${PROG}"' commit. to add this file permanently' - dotest binfiles-3 "${testcvs} -q ci -m add-it" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/binfile,v -done -Checking in binfile; -${CVSROOT_DIRNAME}/first-dir/binfile,v <-- binfile -initial revision: 1\.1 -done" - cd ../.. - mkdir 2; cd 2 - dotest binfiles-4 "${testcvs} -q co first-dir" 'U first-dir/binfile' - cd first-dir - dotest binfiles-5 "cmp ../../1/binfile.dat binfile" '' - # Testing that sticky options is -kb is the closest thing we have - # to testing that binary files work right on non-unix machines - # (until there is automated testing for such machines, of course). - dotest binfiles-5.5 "${testcvs} status binfile" \ -"=================================================================== -File: binfile Status: Up-to-date - - Working revision: 1\.1.* - Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/binfile,v - Sticky Tag: (none) - Sticky Date: (none) - Sticky Options: -kb" - - # Test that "-kk" does not override "-kb" - cd ../.. - mkdir 2a; cd 2a - dotest binfiles-5.5a0 "${testcvs} -q co -kk first-dir" 'U first-dir/binfile' - cd first-dir - # Testing that sticky options is -kb is the closest thing we have - # to testing that binary files work right on non-unix machines - # (until there is automated testing for such machines, of course). - dotest binfiles-5.5a1 "${testcvs} status binfile" \ -"=================================================================== -File: binfile Status: Up-to-date - - Working revision: 1\.1.* - Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/binfile,v - Sticky Tag: (none) - Sticky Date: (none) - Sticky Options: -kb" - - # Test whether the default options from the RCS file are - # also used when operating on files instead of whole - # directories - cd ../.. - mkdir 3; cd 3 - dotest binfiles-5.5b0 "${testcvs} -q co first-dir/binfile" \ -'U first-dir/binfile' - cd first-dir - dotest binfiles-5.5b1 "${testcvs} status binfile" \ -"=================================================================== -File: binfile Status: Up-to-date - - Working revision: 1\.1.* - Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/binfile,v - Sticky Tag: (none) - Sticky Date: (none) - Sticky Options: -kb" - cd ../.. - rm -r 3 - # test that "-kk" does not override "-kb" - mkdir 3; cd 3 - dotest binfiles-5.5c0 "${testcvs} -q co -kk first-dir/binfile" \ -'U first-dir/binfile' - cd first-dir - dotest binfiles-5.5c1 "${testcvs} status binfile" \ -"=================================================================== -File: binfile Status: Up-to-date - - Working revision: 1\.1.* - Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/binfile,v - Sticky Tag: (none) - Sticky Date: (none) - Sticky Options: -kb" - cd ../.. - rm -r 3 - cd 2/first-dir - - cp ../../1/binfile2.dat binfile - dotest binfiles-6 "${testcvs} -q ci -m modify-it" \ -"Checking in binfile; -${CVSROOT_DIRNAME}/first-dir/binfile,v <-- binfile -new revision: 1\.2; previous revision: 1\.1 -done" - cd ../../1/first-dir - dotest binfiles-7 "${testcvs} -q update" '[UP] binfile' - dotest binfiles-8 "cmp ../binfile2.dat binfile" '' - - # Now test handling of conflicts with binary files. - cp ../binfile.dat binfile - dotest binfiles-con0 "${testcvs} -q ci -m modify-it" \ -"Checking in binfile; -${CVSROOT_DIRNAME}/first-dir/binfile,v <-- binfile -new revision: 1\.3; previous revision: 1\.2 -done" - cd ../../2/first-dir - echo 'edits in dir 2' >binfile - dotest binfiles-con1 "${testcvs} -q update" \ -"$PROG update: nonmergeable file needs merge -${PROG} update: revision 1\.3 from repository is now in binfile -${PROG} update: file from working directory is now in \.#binfile\.1\.2 -C binfile" - - dotest_fail binfiles-con1b "$testcvs -q up" "C binfile" - - dotest binfiles-con2 "cmp binfile ../../1/binfile.dat" '' - dotest binfiles-con3 "cat .#binfile.1.2" 'edits in dir 2' - - cp ../../1/binfile2.dat binfile - dotest binfiles-con4 "${testcvs} -q ci -m resolve-it" \ -"Checking in binfile; -${CVSROOT_DIRNAME}/first-dir/binfile,v <-- binfile -new revision: 1\.4; previous revision: 1\.3 -done" - cd ../../1/first-dir - dotest binfiles-con5 "${testcvs} -q update" '[UP] binfile' - - dotest binfiles-9 "${testcvs} -q update -A" '' - # "-kk" no longer does anything with "-kb" - dotest binfiles-10 "${testcvs} -q update -kk" '' - dotest binfiles-11 "${testcvs} -q update" '' - # "-kk" no longer does anything with "-kb" - dotest binfiles-12 "${testcvs} -q update -A" '' - dotest binfiles-13 "${testcvs} -q update -A" '' - - cd ../.. - - mkdir 3 - cd 3 - dotest binfiles-13a0 "${testcvs} -q co -r HEAD first-dir" \ -'U first-dir/binfile' - cd first-dir - dotest binfiles-13a1 "${testcvs} status binfile" \ -"=================================================================== -File: binfile Status: Up-to-date - - Working revision: 1\.4.* - Repository revision: 1\.4 ${CVSROOT_DIRNAME}/first-dir/binfile,v - Sticky Tag: HEAD (revision: 1\.4) - Sticky Date: (none) - Sticky Options: -kb" - cd ../.. - rm -r 3 - - cd 2/first-dir - echo 'this file is $''RCSfile$' >binfile - dotest binfiles-14a "${testcvs} -q ci -m modify-it" \ -"Checking in binfile; -${CVSROOT_DIRNAME}/first-dir/binfile,v <-- binfile -new revision: 1\.5; previous revision: 1\.4 -done" - dotest binfiles-14b "cat binfile" 'this file is $''RCSfile$' - # See binfiles-5.5 for discussion of -kb. - dotest binfiles-14c "${testcvs} status binfile" \ -"=================================================================== -File: binfile Status: Up-to-date - - Working revision: 1\.5.* - Repository revision: 1\.5 ${CVSROOT_DIRNAME}/first-dir/binfile,v - Sticky Tag: (none) - Sticky Date: (none) - Sticky Options: -kb" - dotest binfiles-14d "${testcvs} admin -kv binfile" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/binfile,v -done" - # cvs admin doesn't change the checked-out file or its sticky - # kopts. There probably should be a way which does (but - # what if the file is modified? And do we try to version - # control the kopt setting?) - dotest binfiles-14e "cat binfile" 'this file is $''RCSfile$' - dotest binfiles-14f "${testcvs} status binfile" \ -"=================================================================== -File: binfile Status: Up-to-date - - Working revision: 1\.5.* - Repository revision: 1\.5 ${CVSROOT_DIRNAME}/first-dir/binfile,v - Sticky Tag: (none) - Sticky Date: (none) - Sticky Options: -kb" - dotest binfiles-14g "${testcvs} -q update -A" '[UP] binfile' - dotest binfiles-14h "cat binfile" 'this file is binfile,v' - dotest binfiles-14i "${testcvs} status binfile" \ -"=================================================================== -File: binfile Status: Up-to-date - - Working revision: 1\.5.* - Repository revision: 1\.5 ${CVSROOT_DIRNAME}/first-dir/binfile,v - Sticky Tag: (none) - Sticky Date: (none) - Sticky Options: -kv" - - # Do sticky options work when used with 'cvs update'? - echo "Not a binary file." > nibfile - dotest binfiles-sticky1 "${testcvs} -q add nibfile" \ -"${PROG} add: use .${PROG} commit. to add this file permanently" - dotest binfiles-sticky2 "${testcvs} -q ci -m add-it nibfile" \ - "RCS file: ${CVSROOT_DIRNAME}/first-dir/nibfile,v -done -Checking in nibfile; -${CVSROOT_DIRNAME}/first-dir/nibfile,v <-- nibfile -initial revision: 1\.1 -done" - dotest binfiles-sticky3 "${testcvs} -q update -kb nibfile" \ - '[UP] nibfile' - dotest binfiles-sticky4 "${testcvs} -q status nibfile" \ -"=================================================================== -File: nibfile Status: Up-to-date - - Working revision: 1\.1.* - Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/nibfile,v - Sticky Tag: (none) - Sticky Date: (none) - Sticky Options: -kb" - - # Now test that -A can clear the sticky option. - dotest binfiles-sticky5 "${testcvs} -q update -A nibfile" \ -"[UP] nibfile" - dotest binfiles-sticky6 "${testcvs} -q status nibfile" \ -"=================================================================== -File: nibfile Status: Up-to-date - - Working revision: 1\.1.* - Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/nibfile,v - Sticky Tag: (none) - Sticky Date: (none) - Sticky Options: (none)" - dotest binfiles-15 "${testcvs} -q admin -kb nibfile" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/nibfile,v -done" - dotest binfiles-16 "${testcvs} -q update nibfile" "[UP] nibfile" - dotest binfiles-17 "${testcvs} -q status nibfile" \ -"=================================================================== -File: nibfile Status: Up-to-date - - Working revision: 1\.1.* - Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/nibfile,v - Sticky Tag: (none) - Sticky Date: (none) - Sticky Options: -kb" - - dotest binfiles-o1 "${testcvs} admin -o1.3:: binfile" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/binfile,v -deleting revision 1\.5 -deleting revision 1\.4 -done" - dotest binfiles-o2 "${testcvs} admin -o::1.3 binfile" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/binfile,v -deleting revision 1\.2 -deleting revision 1\.1 -done" - dotest binfiles-o3 "${testcvs} -q log -h -N binfile" " -RCS file: ${CVSROOT_DIRNAME}/first-dir/binfile,v -Working file: binfile -head: 1\.3 -branch: -locks: strict -access list: -keyword substitution: v -total revisions: 1 -=============================================================================" - - # Check that the contents were right. This isn't the hard case - # (in which RCS_delete_revs does a diff), but might as well. - dotest binfiles-o4 "${testcvs} -q update binfile" "U binfile" - dotest binfiles-o5 "cmp binfile ../../1/binfile.dat" "" - - cd ../.. - rm -rf ${CVSROOT_DIRNAME}/first-dir - rm -r 1 - rm -r 2 - ;; - - binfiles2) - # Test cvs's ability to handle binary files, particularly branching - # and joining. The key thing we are worrying about is that CVS - # doesn't print "cannot merge binary files" or some such, in - # situations where no merging is required. - # See also "join" which does this with non-binary files. - # - # Cases (we are merging from the branch to the trunk): - # binfile.dat) File added on branch, not on trunk. - # File should be marked for addition. - # brmod) File modified on branch, not on trunk. - # File should be copied over to trunk (no merging is needed). - # brmod-trmod) File modified on branch, also on trunk. - # This is a conflict. Present the user with both files and - # let them figure it out. - # brmod-wdmod) File modified on branch, not modified in the trunk - # repository, but modified in the (trunk) working directory. - # This is also a conflict. - - mkdir ${CVSROOT_DIRNAME}/first-dir - mkdir 1; cd 1 - dotest binfiles2-1 "${testcvs} -q co first-dir" '' - cd first-dir - - # The most important thing here is that binfile, binfile2, &c - # each be distinct from each other. We also make sure to include - # a few likely end-of-line patterns to make sure nothing is - # being munged as if in text mode. - ${AWK} 'BEGIN { printf "%c%c%c@%c%c", 2, 10, 137, 13, 10 }' \ - ../binfile - cat ../binfile ../binfile >../binfile2 - cat ../binfile2 ../binfile >../binfile3 - - # FIXCVS: unless a branch has at least one file on it, - # tag_check_valid won't know it exists. So if brmod didn't - # exist, we would have to invent it. - cp ../binfile brmod - cp ../binfile brmod-trmod - cp ../binfile brmod-wdmod - dotest binfiles2-1a \ -"${testcvs} add -kb brmod brmod-trmod brmod-wdmod" \ -"${PROG} add: scheduling file .brmod. for addition -${PROG} add: scheduling file .brmod-trmod. for addition -${PROG} add: scheduling file .brmod-wdmod. for addition -${PROG} add: use .${PROG} commit. to add these files permanently" - dotest binfiles2-1b "${testcvs} -q ci -m add" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/brmod,v -done -Checking in brmod; -${CVSROOT_DIRNAME}/first-dir/brmod,v <-- brmod -initial revision: 1\.1 -done -RCS file: ${CVSROOT_DIRNAME}/first-dir/brmod-trmod,v -done -Checking in brmod-trmod; -${CVSROOT_DIRNAME}/first-dir/brmod-trmod,v <-- brmod-trmod -initial revision: 1\.1 -done -RCS file: ${CVSROOT_DIRNAME}/first-dir/brmod-wdmod,v -done -Checking in brmod-wdmod; -${CVSROOT_DIRNAME}/first-dir/brmod-wdmod,v <-- brmod-wdmod -initial revision: 1\.1 -done" - dotest binfiles2-2 "${testcvs} -q tag -b br" 'T brmod -T brmod-trmod -T brmod-wdmod' - dotest binfiles2-3 "$testcvs -q update -r br" \ -'U brmod -U brmod-trmod -U brmod-wdmod' - cp ../binfile binfile.dat - dotest binfiles2-4 "${testcvs} add -kb binfile.dat" \ -"${PROG} add: scheduling file .binfile\.dat. for addition on branch .br. -${PROG} add: use .${PROG} commit. to add this file permanently" - cp ../binfile2 brmod - cp ../binfile2 brmod-trmod - cp ../binfile2 brmod-wdmod - dotest binfiles2-5 "${testcvs} -q ci -m br-changes" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/Attic/binfile\.dat,v -done -Checking in binfile\.dat; -${CVSROOT_DIRNAME}/first-dir/Attic/binfile\.dat,v <-- binfile\.dat -new revision: 1\.1\.2\.1; previous revision: 1\.1 -done -Checking in brmod; -${CVSROOT_DIRNAME}/first-dir/brmod,v <-- brmod -new revision: 1\.1\.2\.1; previous revision: 1\.1 -done -Checking in brmod-trmod; -${CVSROOT_DIRNAME}/first-dir/brmod-trmod,v <-- brmod-trmod -new revision: 1\.1\.2\.1; previous revision: 1\.1 -done -Checking in brmod-wdmod; -${CVSROOT_DIRNAME}/first-dir/brmod-wdmod,v <-- brmod-wdmod -new revision: 1\.1\.2\.1; previous revision: 1\.1 -done" - dotest binfiles2-6 "${testcvs} -q update -A" \ -"${PROG} update: binfile\.dat is no longer in the repository -[UP] brmod -[UP] brmod-trmod -[UP] brmod-wdmod" - dotest_fail binfiles2-7 "test -f binfile.dat" '' - dotest binfiles2-7-brmod "cmp ../binfile brmod" - cp ../binfile3 brmod-trmod - dotest binfiles2-7a "${testcvs} -q ci -m tr-modify" \ -"Checking in brmod-trmod; -${CVSROOT_DIRNAME}/first-dir/brmod-trmod,v <-- brmod-trmod -new revision: 1\.2; previous revision: 1\.1 -done" - cp ../binfile3 brmod-wdmod - - dotest binfiles2-8 "${testcvs} -q update -j br" \ -"U binfile\.dat -U brmod -${PROG} update: nonmergeable file needs merge -${PROG} update: revision 1.1.2.1 from repository is now in brmod-trmod -${PROG} update: file from working directory is now in .#brmod-trmod.1.2 -C brmod-trmod -M brmod-wdmod -${PROG} update: nonmergeable file needs merge -${PROG} update: revision 1.1.2.1 from repository is now in brmod-wdmod -${PROG} update: file from working directory is now in .#brmod-wdmod.1.1 -C brmod-wdmod" - - dotest binfiles2-9 "cmp ../binfile binfile.dat" - dotest binfiles2-9-brmod "cmp ../binfile2 brmod" - dotest binfiles2-9-brmod-trmod "cmp ../binfile2 brmod-trmod" - dotest binfiles2-9-brmod-trmod "cmp ../binfile2 brmod-wdmod" - dotest binfiles2-9a-brmod-trmod "cmp ../binfile3 .#brmod-trmod.1.2" - dotest binfiles2-9a-brmod-wdmod "cmp ../binfile3 .#brmod-wdmod.1.1" - - # Test that everything was properly scheduled. - dotest binfiles2-10 "${testcvs} -q ci -m checkin" \ -"Checking in binfile\.dat; -${CVSROOT_DIRNAME}/first-dir/binfile\.dat,v <-- binfile\.dat -new revision: 1\.2; previous revision: 1\.1 -done -Checking in brmod; -${CVSROOT_DIRNAME}/first-dir/brmod,v <-- brmod -new revision: 1\.2; previous revision: 1\.1 -done -Checking in brmod-trmod; -${CVSROOT_DIRNAME}/first-dir/brmod-trmod,v <-- brmod-trmod -new revision: 1\.3; previous revision: 1\.2 -done -Checking in brmod-wdmod; -${CVSROOT_DIRNAME}/first-dir/brmod-wdmod,v <-- brmod-wdmod -new revision: 1\.2; previous revision: 1\.1 -done" - - dotest_fail binfiles2-o1 "${testcvs} -q admin -o :1.2 brmod-trmod" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/brmod-trmod,v -deleting revision 1\.2 -${PROG} admin: ${CVSROOT_DIRNAME}/first-dir/brmod-trmod,v: can't remove branch point 1\.1 -${PROG} admin: RCS file for .brmod-trmod. not modified\." - dotest binfiles2-o2 "${testcvs} -q admin -o 1.1.2.1: brmod-trmod" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/brmod-trmod,v -deleting revision 1\.1\.2\.1 -done" - dotest binfiles2-o3 "${testcvs} -q admin -o :1.2 brmod-trmod" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/brmod-trmod,v -deleting revision 1\.2 -deleting revision 1\.1 -done" - dotest binfiles2-o4 "${testcvs} -q log -N brmod-trmod" " -RCS file: ${CVSROOT_DIRNAME}/first-dir/brmod-trmod,v -Working file: brmod-trmod -head: 1\.3 -branch: -locks: strict -access list: -keyword substitution: b -total revisions: 1; selected revisions: 1 -description: ----------------------------- -revision 1\.3 -date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; -checkin -=============================================================================" - cd .. - cd .. - - rm -rf ${CVSROOT_DIRNAME}/first-dir - rm -r 1 - ;; - - binfiles3) - # More binary file tests, especially removing, adding, &c. - # See "binfiles" for a list of binary file tests. - mkdir ${CVSROOT_DIRNAME}/first-dir - mkdir 1; cd 1 - dotest binfiles3-1 "${testcvs} -q co first-dir" '' - ${AWK} 'BEGIN { printf "%c%c%c@%c%c", 2, 10, 137, 13, 10 }' \ - binfile.dat - cd first-dir - echo hello >file1 - dotest binfiles3-2 "${testcvs} add file1" \ -"${PROG} add: scheduling file .file1. for addition -${PROG} add: use .${PROG} commit. to add this file permanently" - dotest binfiles3-3 "${testcvs} -q ci -m add-it" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -done -Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -initial revision: 1\.1 -done" - rm file1 - dotest binfiles3-4 "${testcvs} rm file1" \ -"${PROG} remove: scheduling .file1. for removal -${PROG} remove: use .${PROG} commit. to remove this file permanently" - dotest binfiles3-5 "${testcvs} -q ci -m remove-it" \ -"Removing file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -new revision: delete; previous revision: 1\.1 -done" - cp ../binfile.dat file1 - dotest binfiles3-6 "${testcvs} add -kb file1" \ -"${PROG} add: Re-adding file .file1. (in place of dead revision 1\.2)\. -${PROG} add: use .${PROG} commit. to add this file permanently" - # The idea behind this test is to make sure that the file - # gets opened in binary mode to send to "cvs ci". - dotest binfiles3-6a "cat CVS/Entries" \ -"/file1/0/[A-Za-z0-9 :]*/-kb/ -D" - # TODO: This just tests the case where the old keyword - # expansion mode is the default (RCS_getexpand == NULL - # in checkaddfile()); should also test the case in which - # we are changing it from one non-default value to another. - dotest binfiles3-7 "${testcvs} -q ci -m readd-it" \ -"${PROG} commit: changing keyword expansion mode to -kb -Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -new revision: 1\.3; previous revision: 1\.2 -done" - dotest binfiles3-8 "${testcvs} -q log -h -N file1" " -RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -Working file: file1 -head: 1\.3 -branch: -locks: strict -access list: -keyword substitution: b -total revisions: 3 -=============================================================================" - - # OK, now test admin -o on a binary file. See "admin" - # test for a more complete list of admin -o tests. - cp ${TESTDIR}/1/binfile.dat ${TESTDIR}/1/binfile4.dat - echo '%%$$##@@!!jjiiuull' | ${TR} j '\000' >>${TESTDIR}/1/binfile4.dat - cp ${TESTDIR}/1/binfile4.dat ${TESTDIR}/1/binfile5.dat - echo 'aawwee%$$##@@!!jjil' | ${TR} w '\000' >>${TESTDIR}/1/binfile5.dat - - cp ../binfile4.dat file1 - dotest binfiles3-9 "${testcvs} -q ci -m change" \ -"Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -new revision: 1\.4; previous revision: 1\.3 -done" - cp ../binfile5.dat file1 - dotest binfiles3-10 "${testcvs} -q ci -m change" \ -"Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -new revision: 1\.5; previous revision: 1\.4 -done" - dotest binfiles3-11 "${testcvs} admin -o 1.3::1.5 file1" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -deleting revision 1\.4 -done" - dotest binfiles3-12 "${testcvs} -q update -r 1.3 file1" "U file1" - dotest binfiles3-13 "cmp file1 ${TESTDIR}/1/binfile.dat" "" - - cd ../.. - rm -r 1 - rm -rf ${CVSROOT_DIRNAME}/first-dir - ;; - - mcopy) - # See comment at "mwrap" test for list of other wrappers tests. - # Test cvs's ability to handle nonmergeable files specified with - # -m 'COPY' in wrappers. Similar to the binfiles2 test, - # which tests the same thing for binary files - # (which are non-mergeable in the same sense). - # - # Cases (we are merging from the branch to the trunk): - # brmod) File modified on branch, not on trunk. - # File should be copied over to trunk (no merging is needed). - # brmod-trmod) File modified on branch, also on trunk. - # This is a conflict. Present the user with both files and - # let them figure it out. - # brmod-wdmod) File modified on branch, not modified in the trunk - # repository, but modified in the (trunk) working directory. - # This is also a conflict. - - # For the moment, remote CVS can't pass wrappers from CVSWRAPPERS - # (see wrap_send). So skip these tests for remote. - if $remote; then :; else - - mkdir ${CVSROOT_DIRNAME}/first-dir - mkdir 1; cd 1 - dotest mcopy-1 "${testcvs} -q co first-dir" '' - cd first-dir - - # FIXCVS: unless a branch has at least one file on it, - # tag_check_valid won't know it exists. So if brmod didn't - # exist, we would have to invent it. - echo 'brmod initial contents' >brmod - echo 'brmod-trmod initial contents' >brmod-trmod - echo 'brmod-wdmod initial contents' >brmod-wdmod - echo "* -m 'COPY'" >.cvswrappers - dotest mcopy-1a \ -"${testcvs} add .cvswrappers brmod brmod-trmod brmod-wdmod" \ -"${PROG} add: scheduling file .\.cvswrappers. for addition -${PROG} add: scheduling file .brmod. for addition -${PROG} add: scheduling file .brmod-trmod. for addition -${PROG} add: scheduling file .brmod-wdmod. for addition -${PROG} add: use .${PROG} commit. to add these files permanently" - dotest mcopy-1b "${testcvs} -q ci -m add" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/\.cvswrappers,v -done -Checking in \.cvswrappers; -${CVSROOT_DIRNAME}/first-dir/\.cvswrappers,v <-- \.cvswrappers -initial revision: 1\.1 -done -RCS file: ${CVSROOT_DIRNAME}/first-dir/brmod,v -done -Checking in brmod; -${CVSROOT_DIRNAME}/first-dir/brmod,v <-- brmod -initial revision: 1\.1 -done -RCS file: ${CVSROOT_DIRNAME}/first-dir/brmod-trmod,v -done -Checking in brmod-trmod; -${CVSROOT_DIRNAME}/first-dir/brmod-trmod,v <-- brmod-trmod -initial revision: 1\.1 -done -RCS file: ${CVSROOT_DIRNAME}/first-dir/brmod-wdmod,v -done -Checking in brmod-wdmod; -${CVSROOT_DIRNAME}/first-dir/brmod-wdmod,v <-- brmod-wdmod -initial revision: 1\.1 -done" - - # NOTE: .cvswrappers files are broken (see comment in - # src/wrapper.c). So doing everything via the environment - # variable is a workaround. Better would be to test them - # both. - CVSWRAPPERS="* -m 'COPY'" - export CVSWRAPPERS - dotest mcopy-2 "${testcvs} -q tag -b br" 'T \.cvswrappers -T brmod -T brmod-trmod -T brmod-wdmod' - dotest mcopy-3 "$testcvs -q update -r br" \ -'U .cvswrappers -U brmod -U brmod-trmod -U brmod-wdmod' - echo 'modify brmod on br' >brmod - echo 'modify brmod-trmod on br' >brmod-trmod - echo 'modify brmod-wdmod on br' >brmod-wdmod - dotest mcopy-5 "${testcvs} -q ci -m br-changes" \ -"Checking in brmod; -${CVSROOT_DIRNAME}/first-dir/brmod,v <-- brmod -new revision: 1\.1\.2\.1; previous revision: 1\.1 -done -Checking in brmod-trmod; -${CVSROOT_DIRNAME}/first-dir/brmod-trmod,v <-- brmod-trmod -new revision: 1\.1\.2\.1; previous revision: 1\.1 -done -Checking in brmod-wdmod; -${CVSROOT_DIRNAME}/first-dir/brmod-wdmod,v <-- brmod-wdmod -new revision: 1\.1\.2\.1; previous revision: 1\.1 -done" - dotest mcopy-6 "$testcvs -q update -A" \ -'U .cvswrappers -U brmod -U brmod-trmod -U brmod-wdmod' - dotest mcopy-7 "cat brmod brmod-trmod brmod-wdmod" \ -"brmod initial contents -brmod-trmod initial contents -brmod-wdmod initial contents" - - echo 'modify brmod-trmod again on trunk' >brmod-trmod - dotest mcopy-7a "${testcvs} -q ci -m tr-modify" \ -"Checking in brmod-trmod; -${CVSROOT_DIRNAME}/first-dir/brmod-trmod,v <-- brmod-trmod -new revision: 1\.2; previous revision: 1\.1 -done" - echo 'modify brmod-wdmod in working dir' >brmod-wdmod - - dotest mcopy-8 "${testcvs} -q update -j br" \ -"U brmod -${PROG} update: nonmergeable file needs merge -${PROG} update: revision 1.1.2.1 from repository is now in brmod-trmod -${PROG} update: file from working directory is now in .#brmod-trmod.1.2 -C brmod-trmod -M brmod-wdmod -${PROG} update: nonmergeable file needs merge -${PROG} update: revision 1.1.2.1 from repository is now in brmod-wdmod -${PROG} update: file from working directory is now in .#brmod-wdmod.1.1 -C brmod-wdmod" - - dotest mcopy-9 "cat brmod brmod-trmod brmod-wdmod" \ -"modify brmod on br -modify brmod-trmod on br -modify brmod-wdmod on br" - dotest mcopy-9a "cat .#brmod-trmod.1.2 .#brmod-wdmod.1.1" \ -"modify brmod-trmod again on trunk -modify brmod-wdmod in working dir" - - # Test that everything was properly scheduled. - dotest mcopy-10 "${testcvs} -q ci -m checkin" \ -"Checking in brmod; -${CVSROOT_DIRNAME}/first-dir/brmod,v <-- brmod -new revision: 1\.2; previous revision: 1\.1 -done -Checking in brmod-trmod; -${CVSROOT_DIRNAME}/first-dir/brmod-trmod,v <-- brmod-trmod -new revision: 1\.3; previous revision: 1\.2 -done -Checking in brmod-wdmod; -${CVSROOT_DIRNAME}/first-dir/brmod-wdmod,v <-- brmod-wdmod -new revision: 1\.2; previous revision: 1\.1 -done" - cd .. - cd .. - - rm -rf ${CVSROOT_DIRNAME}/first-dir - rm -r 1 - unset CVSWRAPPERS - - fi # end of tests to be skipped for remote - - ;; - - binwrap) - # Test the ability to specify binary-ness based on file name. - # See "mwrap" for a list of other wrappers tests. - - mkdir dir-to-import - cd dir-to-import - touch foo.c foo.exe - - # While we're here, test for rejection of duplicate tag names. - dotest_fail binwrap-0 \ - "${testcvs} import -m msg -I ! first-dir dup dup" \ -"${PROG} \[[a-z]* aborted\]: tag .dup. was specified more than once" - - if ${testcvs} import -m message -I ! -W "*.exe -k 'b'" \ - first-dir tag1 tag2 >>${LOGFILE}; then - pass binwrap-1 - else - fail binwrap-1 - fi - cd .. - rm -r dir-to-import - dotest binwrap-2 "${testcvs} -q co first-dir" 'U first-dir/foo.c -U first-dir/foo.exe' - dotest binwrap-3 "${testcvs} -q status first-dir" \ -"=================================================================== -File: foo\.c Status: Up-to-date - - Working revision: 1\.1\.1\.1.* - Repository revision: 1\.1\.1\.1 ${CVSROOT_DIRNAME}/first-dir/foo\.c,v - Sticky Tag: (none) - Sticky Date: (none) - Sticky Options: (none) - -=================================================================== -File: foo\.exe Status: Up-to-date - - Working revision: 1\.1\.1\.1.* - Repository revision: 1\.1\.1\.1 ${CVSROOT_DIRNAME}/first-dir/foo\.exe,v - Sticky Tag: (none) - Sticky Date: (none) - Sticky Options: -kb" - rm -r first-dir - rm -rf ${CVSROOT_DIRNAME}/first-dir - ;; - - binwrap2) - # Test the ability to specify binary-ness based on file name. - # See "mwrap" for a list of other wrappers tests. - - mkdir dir-to-import - cd dir-to-import - touch foo.c foo.exe - - # Specify that all files are binary except *.c. - # The order seems to matter, with the earlier rules taking - # precedence. I'm not sure whether that is good or not, - # but it is the current behavior. - if ${testcvs} import -m message -I ! \ - -W "*.c -k 'o'" -W "* -k 'b'" \ - first-dir tag1 tag2 >>${LOGFILE}; then - pass binwrap2-1 - else - fail binwrap2-1 - fi - cd .. - rm -r dir-to-import - dotest binwrap2-2 "${testcvs} -q co first-dir" 'U first-dir/foo.c -U first-dir/foo.exe' - dotest binwrap2-3 "${testcvs} -q status first-dir" \ -"=================================================================== -File: foo\.c Status: Up-to-date - - Working revision: 1\.1\.1\.1.* - Repository revision: 1\.1\.1\.1 ${CVSROOT_DIRNAME}/first-dir/foo\.c,v - Sticky Tag: (none) - Sticky Date: (none) - Sticky Options: -ko - -=================================================================== -File: foo\.exe Status: Up-to-date - - Working revision: 1\.1\.1\.1.* - Repository revision: 1\.1\.1\.1 ${CVSROOT_DIRNAME}/first-dir/foo\.exe,v - Sticky Tag: (none) - Sticky Date: (none) - Sticky Options: -kb" - rm -r first-dir - rm -rf ${CVSROOT_DIRNAME}/first-dir - ;; - - binwrap3) - # Test communication of file-specified -k wrappers between - # client and server, in `import': - # - # 1. Set up a directory tree, populate it with files. - # 2. Give each directory a different .cvswrappers file. - # 3. Give the server its own .cvswrappers file. - # 4. Import the whole tree, see if the right files got set - # to binary. - # - # The tree has a top ("0th") level, and two subdirs, sub1/ - # and sub2/; sub2/ contains directory subsub/. Every - # directory has a .cvswrappers file as well as regular - # files. - # - # In the file names, "foo-b.*" should end up binary, and - # "foo-t.*" should end up text. Don't worry about the two - # letter extensions; they're just there to help me keep - # things straight. - # - # Here's the directory tree: - # - # ./ - # .cvswrappers - # foo-b.c0 - # foo-b.sb - # foo-t.c1 - # foo-t.st - # - # sub1/ sub2/ - # .cvswrappers .cvswrappers - # foo-b.c1 foo-b.sb - # foo-b.sb foo-b.st - # foo-t.c0 foo-t.c0 - # foo-t.st foo-t.c1 - # foo-t.c2 - # foo-t.c3 - # - # subsub/ - # .cvswrappers - # foo-b.c3 - # foo-b.sb - # foo-t.c0 - # foo-t.c1 - # foo-t.c2 - # foo-t.st - - binwrap3_line1="This is a test file " - binwrap3_line2="containing little of use " - binwrap3_line3="except this non-haiku" - - binwrap3_text="${binwrap3_line1}${binwrap3_line2}${binwrap3_line3}" - - cd ${TESTDIR} - - # On Windows, we can't check out CVSROOT, because the case - # insensitivity means that this conflicts with cvsroot. - mkdir wnt - cd wnt - - mkdir binwrap3 # the 0th dir - mkdir binwrap3/sub1 - mkdir binwrap3/sub2 - mkdir binwrap3/sub2/subsub - - echo "bar*" > binwrap3/.cvswrappers - echo "*.c0 -k 'b'" >> binwrap3/.cvswrappers - echo "whatever -k 'b'" >> binwrap3/.cvswrappers - echo ${binwrap3_text} > binwrap3/foo-b.c0 - echo ${binwrap3_text} > binwrap3/bar-t.c0 - echo ${binwrap3_text} > binwrap3/foo-b.sb - echo ${binwrap3_text} > binwrap3/foo-t.sb - echo ${binwrap3_text} > binwrap3/foo-t.c1 - echo ${binwrap3_text} > binwrap3/foo-t.st - - echo "bar* -k 'kv'" > binwrap3/sub1/.cvswrappers - echo "*.c1 -k 'b'" >> binwrap3/sub1/.cvswrappers - echo "whatever -k 'b'" >> binwrap3/sub1/.cvswrappers - echo ${binwrap3_text} > binwrap3/sub1/foo-b.c1 - echo ${binwrap3_text} > binwrap3/sub1/bar-t.c1 - echo ${binwrap3_text} > binwrap3/sub1/foo-b.sb - echo ${binwrap3_text} > binwrap3/sub1/foo-t.sb - echo ${binwrap3_text} > binwrap3/sub1/foo-t.c0 - echo ${binwrap3_text} > binwrap3/sub1/foo-t.st - - echo "bar*" > binwrap3/sub2/.cvswrappers - echo "*.st -k 'b'" >> binwrap3/sub2/.cvswrappers - echo ${binwrap3_text} > binwrap3/sub2/foo-b.sb - echo ${binwrap3_text} > binwrap3/sub2/foo-t.sb - echo ${binwrap3_text} > binwrap3/sub2/foo-b.st - echo ${binwrap3_text} > binwrap3/sub2/bar-t.st - echo ${binwrap3_text} > binwrap3/sub2/foo-t.c0 - echo ${binwrap3_text} > binwrap3/sub2/foo-t.c1 - echo ${binwrap3_text} > binwrap3/sub2/foo-t.c2 - echo ${binwrap3_text} > binwrap3/sub2/foo-t.c3 - - echo "bar* -k 'kv'" > binwrap3/sub2/subsub/.cvswrappers - echo "*.c3 -k 'b'" >> binwrap3/sub2/subsub/.cvswrappers - echo "foo -k 'b'" >> binwrap3/sub2/subsub/.cvswrappers - echo "c0* -k 'b'" >> binwrap3/sub2/subsub/.cvswrappers - echo ${binwrap3_text} > binwrap3/sub2/subsub/foo-b.c3 - echo ${binwrap3_text} > binwrap3/sub2/subsub/bar-t.c3 - echo ${binwrap3_text} > binwrap3/sub2/subsub/foo-b.sb - echo ${binwrap3_text} > binwrap3/sub2/subsub/foo-t.sb - echo ${binwrap3_text} > binwrap3/sub2/subsub/foo-t.c0 - echo ${binwrap3_text} > binwrap3/sub2/subsub/foo-t.c1 - echo ${binwrap3_text} > binwrap3/sub2/subsub/foo-t.c2 - echo ${binwrap3_text} > binwrap3/sub2/subsub/foo-t.st - - # Now set up CVSROOT/cvswrappers, the easy way: - dotest binwrap3-1 "${testcvs} -q co CVSROOT" "[UP] CVSROOT${DOTSTAR}" - cd CVSROOT - # This destroys anything currently in cvswrappers, but - # presumably other tests will take care of it themselves if - # they use cvswrappers: - echo "foo-t.sb" > cvswrappers - echo "foo*.sb -k 'b'" >> cvswrappers - dotest binwrap3-2 "${testcvs} -q ci -m cvswrappers-mod" \ -"Checking in cvswrappers; -${CVSROOT_DIRNAME}/CVSROOT/cvswrappers,v <-- cvswrappers -new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* -done -${PROG} commit: Rebuilding administrative file database" - cd .. - - # Avoid environmental interference - CVSWRAPPERS_save=${CVSWRAPPERS} - unset CVSWRAPPERS - - # Do the import - cd binwrap3 - # Not importing .cvswrappers tests whether the client is really - # letting the server know "honestly" whether the file is binary, - # rather than just letting the server see the .cvswrappers file. - dotest binwrap3-2a \ -"${testcvs} import -m . -I .cvswrappers binwrap3 tag1 tag2" \ -"[NI] ${DOTSTAR}" - - # OK, now test "cvs add". - cd .. - rm -r binwrap3 - dotest binwrap3-2b "${testcvs} co binwrap3" "${DOTSTAR}" - cd binwrap3 - cd sub2 - echo "*.newbin -k 'b'" > .cvswrappers - echo .cvswrappers >.cvsignore - echo .cvsignore >>.cvsignore - touch file1.newbin file1.txt - dotest binwrap3-2c "${testcvs} add file1.newbin file1.txt" \ -"${PROG} add: scheduling file .file1\.newbin. for addition -${PROG} add: scheduling file .file1\.txt. for addition -${PROG} add: use .${PROG} commit. to add these files permanently" - dotest binwrap3-2d "${testcvs} -q ci -m add" \ -"RCS file: ${CVSROOT_DIRNAME}/binwrap3/sub2/file1\.newbin,v -done -Checking in file1\.newbin; -${CVSROOT_DIRNAME}/binwrap3/sub2/file1\.newbin,v <-- file1\.newbin -initial revision: 1\.1 -done -RCS file: ${CVSROOT_DIRNAME}/binwrap3/sub2/file1\.txt,v -done -Checking in file1\.txt; -${CVSROOT_DIRNAME}/binwrap3/sub2/file1\.txt,v <-- file1\.txt -initial revision: 1\.1 -done" - cd .. - - # Now check out the module and see which files are binary. - cd .. - rm -r binwrap3 - dotest binwrap3-3 "${testcvs} co binwrap3" "${DOTSTAR}" - cd binwrap3 - - # Running "cvs status" and matching output is too - # error-prone, too likely to falsely fail. Instead, we'll - # just grep the Entries lines: - - dotest binwrap3-top1 "grep foo-b.c0 ./CVS/Entries" \ - "/foo-b.c0/1.1.1.1/[A-Za-z0-9 :]*/-kb/" - - dotest binwrap3-top2 "grep foo-b.sb ./CVS/Entries" \ - "/foo-b.sb/1.1.1.1/[A-Za-z0-9 :]*/-kb/" - - dotest binwrap3-top3 "grep foo-t.c1 ./CVS/Entries" \ - "/foo-t.c1/1.1.1.1/[A-Za-z0-9 :]*//" - - dotest binwrap3-top4 "grep foo-t.st ./CVS/Entries" \ - "/foo-t.st/1.1.1.1/[A-Za-z0-9 :]*//" - - dotest binwrap3-top5 "grep foo-t.sb ./CVS/Entries" \ - "/foo-t.sb/1.1.1.1/[A-Za-z0-9 :]*//" - - dotest binwrap3-top6 "grep bar-t.c0 ./CVS/Entries" \ - "/bar-t.c0/1.1.1.1/[A-Za-z0-9 :]*//" - - dotest binwrap3-sub1-1 "grep foo-b.c1 sub1/CVS/Entries" \ - "/foo-b.c1/1.1.1.1/[A-Za-z0-9 :]*/-kb/" - - dotest binwrap3-sub1-2 "grep foo-b.sb sub1/CVS/Entries" \ - "/foo-b.sb/1.1.1.1/[A-Za-z0-9 :]*/-kb/" - - dotest binwrap3-sub1-3 "grep foo-t.c0 sub1/CVS/Entries" \ - "/foo-t.c0/1.1.1.1/[A-Za-z0-9 :]*//" - - dotest binwrap3-sub1-4 "grep foo-t.st sub1/CVS/Entries" \ - "/foo-t.st/1.1.1.1/[A-Za-z0-9 :]*//" - - dotest binwrap3-sub1-5 "grep foo-t.sb sub1/CVS/Entries" \ - "/foo-t.sb/1.1.1.1/[A-Za-z0-9 :]*//" - - dotest binwrap3-sub1-6 "grep bar-t.c1 sub1/CVS/Entries" \ - "/bar-t.c1/1.1.1.1/[A-Za-z0-9 :]*//" - - dotest binwrap3-sub2-1 "grep foo-b.sb sub2/CVS/Entries" \ - "/foo-b.sb/1.1.1.1/[A-Za-z0-9 :]*/-kb/" - - dotest binwrap3-sub2-2 "grep foo-b.st sub2/CVS/Entries" \ - "/foo-b.st/1.1.1.1/[A-Za-z0-9 :]*/-kb/" - - dotest binwrap3-sub2-3 "grep foo-t.c0 sub2/CVS/Entries" \ - "/foo-t.c0/1.1.1.1/[A-Za-z0-9 :]*//" - - dotest binwrap3-sub2-4 "grep foo-t.c1 sub2/CVS/Entries" \ - "/foo-t.c1/1.1.1.1/[A-Za-z0-9 :]*//" - - dotest binwrap3-sub2-5 "grep foo-t.c2 sub2/CVS/Entries" \ - "/foo-t.c2/1.1.1.1/[A-Za-z0-9 :]*//" - - dotest binwrap3-sub2-6 "grep foo-t.c3 sub2/CVS/Entries" \ - "/foo-t.c3/1.1.1.1/[A-Za-z0-9 :]*//" - - dotest binwrap3-sub2-7 "grep foo-t.sb sub2/CVS/Entries" \ - "/foo-t.sb/1.1.1.1/[A-Za-z0-9 :]*//" - - dotest binwrap3-sub2-8 "grep bar-t.st sub2/CVS/Entries" \ - "/bar-t.st/1.1.1.1/[A-Za-z0-9 :]*//" - - dotest binwrap3-subsub1 "grep foo-b.c3 sub2/subsub/CVS/Entries" \ - "/foo-b.c3/1.1.1.1/[A-Za-z0-9 :]*/-kb/" - - dotest binwrap3-subsub2 "grep foo-b.sb sub2/subsub/CVS/Entries" \ - "/foo-b.sb/1.1.1.1/[A-Za-z0-9 :]*/-kb/" - - dotest binwrap3-subsub3 "grep foo-t.c0 sub2/subsub/CVS/Entries" \ - "/foo-t.c0/1.1.1.1/[A-Za-z0-9 :]*//" - - dotest binwrap3-subsub4 "grep foo-t.c1 sub2/subsub/CVS/Entries" \ - "/foo-t.c1/1.1.1.1/[A-Za-z0-9 :]*//" - - dotest binwrap3-subsub5 "grep foo-t.c2 sub2/subsub/CVS/Entries" \ - "/foo-t.c2/1.1.1.1/[A-Za-z0-9 :]*//" - - dotest binwrap3-subsub6 "grep foo-t.st sub2/subsub/CVS/Entries" \ - "/foo-t.st/1.1.1.1/[A-Za-z0-9 :]*//" - - dotest binwrap3-subsub7 "grep foo-t.sb sub2/subsub/CVS/Entries" \ - "/foo-t.sb/1.1.1.1/[A-Za-z0-9 :]*//" - - dotest binwrap3-subsub8 "grep bar-t.c3 sub2/subsub/CVS/Entries" \ - "/bar-t.c3/1.1.1.1/[A-Za-z0-9 :]*//" - - dotest binwrap3-sub2-add1 "grep file1.newbin sub2/CVS/Entries" \ - "/file1.newbin/1.1/[A-Za-z0-9 :]*/-kb/" - dotest binwrap3-sub2-add2 "grep file1.txt sub2/CVS/Entries" \ - "/file1.txt/1.1/[A-Za-z0-9 :]*//" - - # Restore and clean up - cd .. - rm -r binwrap3 CVSROOT - cd .. - rm -r wnt - rm -rf ${CVSROOT_DIRNAME}/binwrap3 - CVSWRAPPERS=${CVSWRAPPERS_save} - ;; - - mwrap) - # Tests of various wrappers features: - # -m 'COPY' and cvs update: mwrap - # -m 'COPY' and joining: mcopy - # -k: binwrap, binwrap2 - # -t/-f: hasn't been written yet. - # - # Tests of different ways of specifying wrappers: - # CVSROOT/cvswrappers: mwrap - # -W: binwrap, binwrap2 - # .cvswrappers in working directory, local: mcopy - # CVSROOT/cvswrappers, .cvswrappers remote: binwrap3 - # CVSWRAPPERS environment variable: mcopy - - # This test is similar to binfiles-con1; -m 'COPY' specifies - # non-mergeableness the same way that -kb does. - - # On Windows, we can't check out CVSROOT, because the case - # insensitivity means that this conflicts with cvsroot. - mkdir wnt - cd wnt - - dotest mwrap-c1 "${testcvs} -q co CVSROOT" "[UP] CVSROOT${DOTSTAR}" - cd CVSROOT - echo "* -m 'COPY'" >>cvswrappers - dotest mwrap-c2 "${testcvs} -q ci -m wrapper-mod" \ -"Checking in cvswrappers; -${CVSROOT_DIRNAME}/CVSROOT/cvswrappers,v <-- cvswrappers -new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* -done -${PROG} commit: Rebuilding administrative file database" - cd .. - mkdir m1; cd m1 - dotest mwrap-1 "${testcvs} -q co -l ." '' - mkdir first-dir - dotest mwrap-2 "${testcvs} add first-dir" \ -"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" - cd first-dir - touch aa - dotest mwrap-3 "${testcvs} add aa" \ -"${PROG} add: scheduling file .aa. for addition -${PROG} add: use .${PROG} commit. to add this file permanently" - dotest mwrap-4 "${testcvs} -q ci -m add" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/aa,v -done -Checking in aa; -${CVSROOT_DIRNAME}/first-dir/aa,v <-- aa -initial revision: 1\.1 -done" - cd ../.. - mkdir m2; cd m2 - dotest mwrap-5 "${testcvs} -q co first-dir" "U first-dir/aa" - cd first-dir - echo "changed in m2" >aa - dotest mwrap-6 "${testcvs} -q ci -m m2-mod" \ -"Checking in aa; -${CVSROOT_DIRNAME}/first-dir/aa,v <-- aa -new revision: 1\.2; previous revision: 1\.1 -done" - cd ../.. - cd m1/first-dir - echo "changed in m1" >aa - dotest mwrap-7 "$testcvs -nq update" \ -"${PROG} update: nonmergeable file needs merge -${PROG} update: revision 1\.2 from repository is now in aa -${PROG} update: file from working directory is now in \.#aa\.1\.1 -C aa" - dotest mwrap-8 "${testcvs} -q update" \ -"$PROG update: nonmergeable file needs merge -${PROG} update: revision 1\.2 from repository is now in aa -${PROG} update: file from working directory is now in \.#aa\.1\.1 -C aa" - dotest mwrap-9 "cat aa" "changed in m2" - dotest mwrap-10 "cat .#aa.1.1" "changed in m1" - cd ../.. - cd CVSROOT - echo '# comment out' >cvswrappers - dotest mwrap-ce "${testcvs} -q ci -m wrapper-mod" \ -"Checking in cvswrappers; -${CVSROOT_DIRNAME}/CVSROOT/cvswrappers,v <-- cvswrappers -new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* -done -${PROG} commit: Rebuilding administrative file database" - cd .. - rm -r CVSROOT - rm -r m1 m2 - cd .. - rm -r wnt - rm -rf ${CVSROOT_DIRNAME}/first-dir - ;; - - info) - # Administrative file tests. - # Here is a list of where each administrative file is tested: - # loginfo: info - # modules: modules, modules2, modules3 - # cvsignore: ignore - # verifymsg: info - # cvswrappers: mwrap - # taginfo: taginfo - # config: config - - # On Windows, we can't check out CVSROOT, because the case - # insensitivity means that this conflicts with cvsroot. - mkdir wnt - cd wnt - - dotest info-1 "${testcvs} -q co CVSROOT" "[UP] CVSROOT${DOTSTAR}" - cd CVSROOT - rm -f $TESTDIR/testlog $TESTDIR/testlog2 - echo "ALL sh -c \"echo x\${=MYENV}\${=OTHER}y\${=ZEE}=\$USER=\$CVSROOT= >>$TESTDIR/testlog; cat >/dev/null\"" > loginfo - # The following cases test the format string substitution - echo "ALL echo %{sVv} >>$TESTDIR/testlog2; cat >/dev/null" >> loginfo - echo "ALL echo %{v} >>$TESTDIR/testlog2; cat >/dev/null" >> loginfo - echo "ALL echo %s >>$TESTDIR/testlog2; cat >/dev/null" >> loginfo - echo "ALL echo %{V}AX >>$TESTDIR/testlog2; cat >/dev/null" >> loginfo - echo "first-dir echo %sux >>$TESTDIR/testlog2; cat >/dev/null" \ - >> loginfo - - # Might be nice to move this to crerepos tests; it should - # work to create a loginfo file if you didn't create one - # with "cvs init". - : dotest info-2 "${testcvs} add loginfo" \ -"${PROG}"' add: scheduling file `loginfo'"'"' for addition -'"${PROG}"' add: use .'"${PROG}"' commit. to add this file permanently' - - dotest info-3 "${testcvs} -q ci -m new-loginfo" \ -"Checking in loginfo; -${CVSROOT_DIRNAME}/CVSROOT/loginfo,v <-- loginfo -new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* -done -${PROG} commit: Rebuilding administrative file database" - cd .. - - mkdir ${CVSROOT_DIRNAME}/first-dir - dotest info-5 "${testcvs} -q co first-dir" '' - cd first-dir - touch file1 - dotest info-6 "${testcvs} add file1" \ -"${PROG}"' add: scheduling file `file1'\'' for addition -'"${PROG}"' add: use .'"${PROG}"' commit. to add this file permanently' - echo "cvs -s OTHER=not-this -s MYENV=env-" >>$HOME/.cvsrc - dotest info-6a "${testcvs} -q -s OTHER=value ci -m add-it" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -done -Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -initial revision: 1\.1 -done -${PROG} commit: loginfo:1: no such user variable \${=ZEE}" - echo line0 >>file1 - dotest info-6b "${testcvs} -q -sOTHER=foo ci -m mod-it" \ -"Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -new revision: 1\.2; previous revision: 1\.1 -done -${PROG} commit: loginfo:1: no such user variable \${=ZEE}" - echo line1 >>file1 - dotest info-7 "${testcvs} -q -s OTHER=value -s ZEE=z ci -m mod-it" \ -"Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -new revision: 1\.3; previous revision: 1\.2 -done" - cd .. - dotest info-9 "cat $TESTDIR/testlog" "xenv-valueyz=${username}=${CVSROOT_DIRNAME}=" - dotest info-10 "cat $TESTDIR/testlog2" \ -'first-dir file1,NONE,1.1 -first-dir 1.1 -first-dir file1 -first-dir NONEAX -first-dir file1ux -first-dir file1,1.1,1.2 -first-dir 1.2 -first-dir file1 -first-dir 1.1AX -first-dir file1ux -first-dir file1,1.2,1.3 -first-dir 1.3 -first-dir file1 -first-dir 1.2AX -first-dir file1ux' - - cd CVSROOT - echo '# do nothing' >loginfo - dotest info-11 "${testcvs} -q -s ZEE=garbage ci -m nuke-loginfo" \ -"Checking in loginfo; -${CVSROOT_DIRNAME}/CVSROOT/loginfo,v <-- loginfo -new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* -done -${PROG} commit: Rebuilding administrative file database" - - # Now test verifymsg - cat >${TESTDIR}/vscript < /dev/null; then - exit 0 -elif sed 1q < \$1 | grep '^BugId:[ ]*new$' > /dev/null; then - echo A new bugid was found. >> \$1 - exit 0 -else - echo "No BugId found." - sleep 1 - exit 1 -fi -EOF - cat >${TESTDIR}/vscript2 </dev/null 2>&1; then - exit 1 -else - exit 0 -fi -EOF - # Grumble, grumble, mumble, search for "Cygwin". - if test -n "$remotehost"; then - $CVS_RSH $remotehost "chmod +x ${TESTDIR}/vscript*" - else - chmod +x ${TESTDIR}/vscript* - fi - echo "^first-dir/yet-another\\(/\\|\$\\) ${TESTDIR}/vscript2" >>verifymsg - echo "^first-dir\\(/\\|\$\\) ${TESTDIR}/vscript" >>verifymsg - echo "^missing-script\$ ${TESTDIR}/bogus" >>verifymsg - echo "^missing-var\$ ${TESTDIR}/vscript \${=Bogus}" >>verifymsg - # first test the directory independant verifymsg - dotest info-v1 "${testcvs} -q ci -m add-verification" \ -"Checking in verifymsg; -${CVSROOT_DIRNAME}/CVSROOT/verifymsg,v <-- verifymsg -new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* -done -${PROG} commit: Rebuilding administrative file database" - - cd ../first-dir - echo line2 >>file1 - dotest_fail info-v2 "${testcvs} -q ci -m bogus" \ -"No BugId found\. -${PROG} \[commit aborted\]: Message verification failed" - - cat >${TESTDIR}/comment.tmp <>config - dotest info-rereadlog-1 "${testcvs} -q ci -m add-RereadLogAfterVerify=always" \ -"Checking in config; -${CVSROOT_DIRNAME}/CVSROOT/config,v <-- config -new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* -done -${PROG} commit: Rebuilding administrative file database" - cd ../first-dir - echo line3 >>file1 - cat >${TESTDIR}/comment.tmp < config.new - mv config.new config - echo "RereadLogAfterVerify=stat" >>config - dotest info-reread-4 "${testcvs} -q ci -m add-RereadLogAfterVerify=stat" \ -"Checking in config; -${CVSROOT_DIRNAME}/CVSROOT/config,v <-- config -new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* -done -${PROG} commit: Rebuilding administrative file database" - cd ../first-dir - echo line4 >>file1 - cat >${TESTDIR}/comment.tmp < config.new - mv config.new config - echo "RereadLogAfterVerify=never" >>config - dotest info-reread-7 "${testcvs} -q ci -m add-RereadLogAfterVerify=never" \ -"Checking in config; -${CVSROOT_DIRNAME}/CVSROOT/config,v <-- config -new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* -done -${PROG} commit: Rebuilding administrative file database" - cd ../first-dir - echo line5 >>file1 - cat >${TESTDIR}/comment.tmp <verifymsg - echo 'DEFAULT true' >>verifymsg - echo '# defaults' >config - dotest info-multdef "${testcvs} -q ci -m multdef" \ -"Checking in config; -${CVSROOT_DIRNAME}/CVSROOT/config,v <-- config -new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* -done -Checking in verifymsg; -${CVSROOT_DIRNAME}/CVSROOT/verifymsg,v <-- verifymsg -new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* -done -${PROG} commit: Rebuilding administrative file database" - - cd ../CVSROOT - echo '# do nothing' >verifymsg - dotest info-cleanup-verifymsg "${testcvs} -q ci -m nuke-verifymsg" \ -"${PROG} commit: Multiple .DEFAULT. lines (1 and 2) in verifymsg file -Checking in verifymsg; -${CVSROOT_DIRNAME}/CVSROOT/verifymsg,v <-- verifymsg -new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* -done -${PROG} commit: Rebuilding administrative file database" - rm ${TESTDIR}/vscript* - cd .. - - dotest_fail info-cleanup-0 "${testcvs} -n release -d CVSROOT" \ -"${PROG} \[release aborted\]: cannot run command ${DOTSTAR}" - - if echo "yes" | ${testcvs} release -d CVSROOT >>${LOGFILE} ; then - pass info-cleanup - else - fail info-cleanup - fi - if echo "yes" | ${testcvs} release -d first-dir >>${LOGFILE} ; then - pass info-cleanup-2 - else - fail info-cleanup-2 - fi - cd .. - rm -r wnt - rm $HOME/.cvsrc - rm -rf ${CVSROOT_DIRNAME}/first-dir - ;; - - taginfo) - # Tests of the CVSROOT/taginfo file. See the comment at the - # "info" tests for a full list of administrative file tests. - - # Tests to add: - # -F to move - - mkdir 1; cd 1 - dotest taginfo-1 "${testcvs} -q co CVSROOT" "U CVSROOT/${DOTSTAR}" - cd CVSROOT - cat >${TESTDIR}/1/loggit <>${TESTDIR}/1/taglog - exit 0 -fi -EOF - # #^@&!^@ Cygwin. - if test -n "$remotehost"; then - $CVS_RSH $remotehost "chmod +x ${TESTDIR}/1/loggit" - else - chmod +x ${TESTDIR}/1/loggit - fi - echo "ALL ${TESTDIR}/1/loggit" >taginfo - dotest taginfo-2 "${testcvs} -q ci -m check-in-taginfo" \ -"Checking in taginfo; -${CVSROOT_DIRNAME}/CVSROOT/taginfo,v <-- taginfo -new revision: 1\.2; previous revision: 1\.1 -done -${PROG} commit: Rebuilding administrative file database" - cd .. - - # taginfo-3 used to rely on the top-level CVS directory - # being created to add "first-dir" to the repository. Since - # that won't happen anymore, we create the directory in the - # repository. - mkdir ${CVSROOT_DIRNAME}/first-dir - dotest taginfo-3 "${testcvs} -q co first-dir" '' - - cd first-dir - echo first >file1 - dotest taginfo-4 "${testcvs} add file1" \ -"${PROG} add: scheduling file .file1. for addition -${PROG} add: use .${PROG} commit. to add this file permanently" - dotest taginfo-5 "${testcvs} -q ci -m add-it" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -done -Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -initial revision: 1\.1 -done" - dotest taginfo-6 "${testcvs} -q tag tag1" "T file1" - dotest taginfo-7 "${testcvs} -q tag -b br" "T file1" - dotest taginfo-8 "$testcvs -q update -r br" '[UP] file1' - echo add text on branch >>file1 - dotest taginfo-9 "${testcvs} -q ci -m modify-on-br" \ -"Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -new revision: 1\.1\.2\.1; previous revision: 1\.1 -done" - dotest taginfo-10 "${testcvs} -q tag -F -c brtag" "T file1" - - dotest_fail taginfo-11 "${testcvs} -q tag rejectme" \ -"${PROG} tag: Pre-tag check failed -${PROG} \[tag aborted\]: correct the above errors first!" - - # When we are using taginfo to allow/disallow, it would be - # convenient to be able to use "cvs -n tag" to test whether - # the allow/disallow functionality is working as expected. - dotest taginfo-12 "${testcvs} -nq tag rejectme" "T file1" - - # But when taginfo is used for logging, it is a pain for -n - # to call taginfo, since taginfo doesn't know whether -n was - # specified or not. - dotest taginfo-13 "${testcvs} -nq tag would-be-tag" "T file1" - - # Deleting: the cases are basically either the tag existed, - # or it didn't exist. - dotest taginfo-14 "${testcvs} -q tag -d tag1" "D file1" - dotest taginfo-15 "${testcvs} -q tag -d tag1" "" - - # Likewise with rtag. - dotest taginfo-16 "${testcvs} -q rtag tag1 first-dir" "" - dotest taginfo-17 "${testcvs} -q rtag -d tag1 first-dir" "" - dotest taginfo-18 "${testcvs} -q rtag -d tag1 first-dir" "" - - # The "br" example should be passing 1.1.2 or 1.1.0.2. - # But it turns out that is very hard to implement, since - # check_fileproc doesn't know what branch number it will - # get. Probably the whole thing should be re-architected - # so that taginfo only allows/denies tagging, and a new - # hook, which is done from tag_fileproc, does logging. - # That would solve this, some more subtle races, and also - # the fact that it is nice for users to run "-n tag foo" to - # see whether a tag would be allowed. Failing that, - # I suppose passing "1.1.branch" or "branch" for "br" - # would be an improvement. - dotest taginfo-examine "cat ${TESTDIR}/1/taglog" \ -"tag1 add ${CVSROOT_DIRNAME}/first-dir file1 1.1 -br add ${CVSROOT_DIRNAME}/first-dir file1 1.1 -brtag mov ${CVSROOT_DIRNAME}/first-dir file1 1.1.2.1 -tag1 del ${CVSROOT_DIRNAME}/first-dir file1 1.1 -tag1 del ${CVSROOT_DIRNAME}/first-dir -tag1 add ${CVSROOT_DIRNAME}/first-dir file1 1.1 -tag1 del ${CVSROOT_DIRNAME}/first-dir file1 1.1 -tag1 del ${CVSROOT_DIRNAME}/first-dir" - - cd .. - cd CVSROOT - echo '# Keep life simple' > taginfo - dotest taginfo-cleanup-1 "${testcvs} -q ci -m check-in-taginfo" \ -"Checking in taginfo; -${CVSROOT_DIRNAME}/CVSROOT/taginfo,v <-- taginfo -new revision: 1\.3; previous revision: 1\.2 -done -${PROG} commit: Rebuilding administrative file database" - cd .. - cd .. - rm -r 1 - rm -rf ${CVSROOT_DIRNAME}/first-dir - ;; - - config) - # Tests of the CVSROOT/config file. See the comment at the - # "info" tests for a full list of administrative file tests. - - # On Windows, we can't check out CVSROOT, because the case - # insensitivity means that this conflicts with cvsroot. - mkdir wnt - cd wnt - - dotest config-1 "${testcvs} -q co CVSROOT" "U CVSROOT/${DOTSTAR}" - cd CVSROOT - echo 'bogus line' >config - # We can't rely on specific revisions, since other tests - # might need to modify CVSROOT/config - dotest config-3 "${testcvs} -q ci -m change-to-bogus-line" \ -"Checking in config; -${CVSROOT_DIRNAME}/CVSROOT/config,v <-- config -new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* -done -${PROG} commit: Rebuilding administrative file database" - echo 'BogusOption=yes' >config - dotest config-4 "${testcvs} -q ci -m change-to-bogus-opt" \ -"${PROG} [a-z]*: syntax error in ${CVSROOT_DIRNAME}/CVSROOT/config: line 'bogus line' is missing '=' -Checking in config; -${CVSROOT_DIRNAME}/CVSROOT/config,v <-- config -new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* -done -${PROG} commit: Rebuilding administrative file database" - echo '# No config is a good config' > config - dotest config-5 "${testcvs} -q ci -m change-to-comment" \ -"${PROG} [a-z]*: ${CVSROOT_DIRNAME}/CVSROOT/config: unrecognized keyword 'BogusOption' -Checking in config; -${CVSROOT_DIRNAME}/CVSROOT/config,v <-- config -new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* -done -${PROG} commit: Rebuilding administrative file database" - dotest config-6 "${testcvs} -q update" '' - echo 'IgnoreUnknownConfigKeys=yes' > config - echo 'BogusOption=yes' >> config - dotest config-7 "${testcvs} -q ci -m change-to-comment" \ -"Checking in config; -${CVSROOT_DIRNAME}/CVSROOT/config,v <-- config -new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* -done -${PROG} commit: Rebuilding administrative file database" - dotest config-8 "${testcvs} -q update" '' - echo '# No config is a good config' > config - dotest config-9 "${testcvs} -q ci -m change-to-comment" \ -"Checking in config; -${CVSROOT_DIRNAME}/CVSROOT/config,v <-- config -new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* -done -${PROG} commit: Rebuilding administrative file database" - dotest config-10 "${testcvs} -q update" '' - - cd .. - rm -r CVSROOT - cd .. - rm -r wnt - ;; - - serverpatch) - # Test remote CVS handling of unpatchable files. This isn't - # much of a test for local CVS. - # We test this with some keyword expansion games, but the situation - # also arises if the user modifies the file while CVS is running. - mkdir ${CVSROOT_DIRNAME}/first-dir - mkdir 1 - cd 1 - dotest serverpatch-1 "${testcvs} -q co first-dir" '' - - cd first-dir - - # Add a file with an RCS keyword. - echo '$''Name$' > file1 - echo '1' >> file1 - dotest serverpatch-2 "${testcvs} add file1" \ -"${PROG}"' add: scheduling file `file1'\'' for addition -'"${PROG}"' add: use .'"${PROG}"' commit. to add this file permanently' - - dotest serverpatch-3 "${testcvs} -q commit -m add" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -done -Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -initial revision: 1\.1 -done" - - # Tag the file. - dotest serverpatch-4 "${testcvs} -q tag tag file1" 'T file1' - - # Check out a tagged copy of the file. - cd ../.. - mkdir 2 - cd 2 - dotest serverpatch-5 "${testcvs} -q co -r tag first-dir" \ -'U first-dir/file1' - - # Remove the tag. Prior to 1.11.23, this left the tag string in the - # expansion of the Name keyword. - dotest serverpatch-6 "$testcvs -q update -A first-dir" \ -'U first-dir/file1' - - # Modify and check in the first copy. - cd ../1/first-dir - echo '2' >> file1 - dotest serverpatch-7 "${testcvs} -q ci -mx file1" \ -"Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -new revision: 1\.2; previous revision: 1\.1 -done" - - # Now update the second copy. Prior to 1.11.23, the patch would fail - # using remote CVS, forcing the file to be refetched. - cd ../../2/first-dir - dotest serverpatch-8 "${testcvs} -q update" \ -'[UP] file1' - - cd ../.. - rm -r 1 2 - rm -rf ${CVSROOT_DIRNAME}/first-dir - ;; - - log) - # Test selecting revisions with cvs log. - # See also log2 tests for more tests. - # See also branches-14.3 for logging with a branch off of a branch. - # See also multibranch-14 for logging with several branches off the - # same branchpoint. - # Tests of each option to cvs log: - # -h: admin-19a-log - # -N: log, log2, admin-19a-log - # -b, -r: log - # -d: logopt, rcs - # -s: logopt, rcs3 - # -R: logopt, rcs3 - # -w, -t: not tested yet (TODO) - - # Check in a file with a few revisions and branches. - mkdir ${CVSROOT_DIRNAME}/first-dir - dotest log-1 "${testcvs} -q co first-dir" '' - cd first-dir - echo 'first revision' > file1 - echo 'first revision' > file2 - dotest log-2 "${testcvs} add file1 file2" \ -"${PROG} add: scheduling file .file1. for addition -${PROG} add: scheduling file .file2. for addition -${PROG} add: use .${PROG} commit. to add these files permanently" - - # While we're at it, check multi-line comments, input from file, - # and trailing whitespace trimming - echo 'line 1 ' >${TESTDIR}/comment.tmp - echo ' ' >>${TESTDIR}/comment.tmp - echo 'line 2 ' >>${TESTDIR}/comment.tmp - echo ' ' >>${TESTDIR}/comment.tmp - echo ' ' >>${TESTDIR}/comment.tmp - dotest log-3 "${testcvs} -q commit -F ${TESTDIR}/comment.tmp" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -done -Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -initial revision: 1\.1 -done -RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v -done -Checking in file2; -${CVSROOT_DIRNAME}/first-dir/file2,v <-- file2 -initial revision: 1\.1 -done" - rm -f ${TESTDIR}/comment.tmp - - echo 'second revision' > file1 - echo 'second revision' > file2 - dotest log-4 "${testcvs} -q ci -m2 file1 file2" \ -"Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -new revision: 1\.2; previous revision: 1\.1 -done -Checking in file2; -${CVSROOT_DIRNAME}/first-dir/file2,v <-- file2 -new revision: 1\.2; previous revision: 1\.1 -done" - - dotest log-5 "${testcvs} -q tag -b branch file1" 'T file1' - dotest log-5a "${testcvs} -q tag tag1 file2" 'T file2' - - echo 'third revision' > file1 - echo 'third revision' > file2 - dotest log-6 "${testcvs} -q ci -m3 file1 file2" \ -"Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -new revision: 1\.3; previous revision: 1\.2 -done -Checking in file2; -${CVSROOT_DIRNAME}/first-dir/file2,v <-- file2 -new revision: 1\.3; previous revision: 1\.2 -done" - - dotest log-6a "${testcvs} -q tag tag2 file2" 'T file2' - - dotest log-7 "${testcvs} -q update -r branch" \ -"[UP] file1 -${PROG} update: file2 is no longer in the repository" - - echo 'first branch revision' > file1 - dotest log-8 "${testcvs} -q ci -m1b file1" \ -"Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -new revision: 1\.2\.2\.1; previous revision: 1\.2 -done" - - dotest log-9 "${testcvs} -q tag tag file1" 'T file1' - - echo 'second branch revision' > file1 - dotest log-10 "${testcvs} -q ci -m2b file1" \ -"Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -new revision: 1\.2\.2\.2; previous revision: 1\.2\.2\.1 -done" - - # Set up a bunch of shell variables to make the later tests - # easier to describe.= - log_header1=" -RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -Working file: file1 -head: 1\.3 -branch: -locks: strict -access list:" - rlog_header1=" -RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -head: 1\.3 -branch: -locks: strict -access list:" - log_tags1='symbolic names: - tag: 1\.2\.2\.1 - branch: 1\.2\.0\.2' - log_keyword='keyword substitution: kv' - log_dash='---------------------------- -revision' - log_date="date: [0-9/]* [0-9:]*; author: ${username}; state: Exp;" - log_lines=" lines: ${PLUS}1 -1" - log_rev1="${log_dash} 1\.1 -${log_date} -line 1 - -line 2" - log_rev2="${log_dash} 1\.2 -${log_date}${log_lines} -branches: 1\.2\.2; -2" - log_rev3="${log_dash} 1\.3 -${log_date}${log_lines} -3" - log_rev1b="${log_dash} 1\.2\.2\.1 -${log_date}${log_lines} -1b" - log_rev2b="${log_dash} 1\.2\.2\.2 -${log_date}${log_lines} -2b" - log_trailer='=============================================================================' - - # Now, finally, test the log output. - - dotest log-11 "${testcvs} log file1" \ -"${log_header1} -${log_tags1} -${log_keyword} -total revisions: 5; selected revisions: 5 -description: -${log_rev3} -${log_rev2} -${log_rev1} -${log_rev2b} -${log_rev1b} -${log_trailer}" - - dotest log-12 "${testcvs} log -N file1" \ -"${log_header1} -${log_keyword} -total revisions: 5; selected revisions: 5 -description: -${log_rev3} -${log_rev2} -${log_rev1} -${log_rev2b} -${log_rev1b} -${log_trailer}" - - dotest log-13 "${testcvs} log -b file1" \ -"${log_header1} -${log_tags1} -${log_keyword} -total revisions: 5; selected revisions: 3 -description: -${log_rev3} -${log_rev2} -${log_rev1} -${log_trailer}" - - dotest log-14 "${testcvs} log -r file1" \ -"${log_header1} -${log_tags1} -${log_keyword} -total revisions: 5; selected revisions: 1 -description: -${log_rev3} -${log_trailer}" - - dotest log-14a "${testcvs} log -rHEAD file1" \ -"${log_header1} -${log_tags1} -${log_keyword} -total revisions: 5; selected revisions: 1 -description: -${log_rev3} -${log_trailer}" - - # The user might not realize that "-r" must not take a space. - # In the error message, HEAD is a file name, not a tag name (which - # might be confusing itself). - dotest_fail log-14b "${testcvs} log -r HEAD file1" \ -"${PROG} log: nothing known about HEAD -${log_header1} -${log_tags1} -${log_keyword} -total revisions: 5; selected revisions: 1 -description: -${log_rev3} -${log_trailer}" - -# Check that unusual syntax works correctly. - - dotest log-14c "${testcvs} log -r: file1" \ -"${log_header1} -${log_tags1} -${log_keyword} -total revisions: 5; selected revisions: 1 -description: -${log_rev3} -${log_trailer}" - dotest log-14d "${testcvs} log -r, file1" \ -"${log_header1} -${log_tags1} -${log_keyword} -total revisions: 5; selected revisions: 1 -description: -${log_rev3} -${log_trailer}" - dotest log-14e "${testcvs} log -r. file1" \ -"${log_header1} -${log_tags1} -${log_keyword} -total revisions: 5; selected revisions: 1 -description: -${log_rev3} -${log_trailer}" - dotest log-14f "${testcvs} log -r:: file1" \ -"${log_header1} -${log_tags1} -${log_keyword} -total revisions: 5; selected revisions: 0 -description: -${log_trailer}" - - dotest log-15 "${testcvs} log -r1.2 file1" \ -"${log_header1} -${log_tags1} -${log_keyword} -total revisions: 5; selected revisions: 1 -description: -${log_rev2} -${log_trailer}" - - dotest log-16 "${testcvs} log -r1.2.2 file1" \ -"${log_header1} -${log_tags1} -${log_keyword} -total revisions: 5; selected revisions: 2 -description: -${log_rev2b} -${log_rev1b} -${log_trailer}" - - # This test would fail with the old invocation of rlog, but it - # works with the builtin log support. - dotest log-17 "${testcvs} log -rbranch file1" \ -"${log_header1} -${log_tags1} -${log_keyword} -total revisions: 5; selected revisions: 2 -description: -${log_rev2b} -${log_rev1b} -${log_trailer}" - - dotest log-18 "${testcvs} log -r1.2.2. file1" \ -"${log_header1} -${log_tags1} -${log_keyword} -total revisions: 5; selected revisions: 1 -description: -${log_rev2b} -${log_trailer}" - - # Multiple -r options are undocumented; see comments in - # cvs.texinfo about whether they should be deprecated. - dotest log-18a "${testcvs} log -r1.2.2.2 -r1.3:1.3 file1" \ -"${log_header1} -${log_tags1} -${log_keyword} -total revisions: 5; selected revisions: 2 -description: -${log_rev3} -${log_rev2b} -${log_trailer}" - - # This test would fail with the old invocation of rlog, but it - # works with the builtin log support. - dotest log-19 "${testcvs} log -rbranch. file1" \ -"${log_header1} -${log_tags1} -${log_keyword} -total revisions: 5; selected revisions: 1 -description: -${log_rev2b} -${log_trailer}" - - dotest log-20 "${testcvs} log -r1.2: file1" \ -"${log_header1} -${log_tags1} -${log_keyword} -total revisions: 5; selected revisions: 2 -description: -${log_rev3} -${log_rev2} -${log_trailer}" - - dotest log-20a "${testcvs} log -r1.2:: file1" \ -"${log_header1} -${log_tags1} -${log_keyword} -total revisions: 5; selected revisions: 1 -description: -${log_rev3} -${log_trailer}" - - dotest log-21 "${testcvs} log -r:1.2 file1" \ -"${log_header1} -${log_tags1} -${log_keyword} -total revisions: 5; selected revisions: 2 -description: -${log_rev2} -${log_rev1} -${log_trailer}" - - dotest log-21a "${testcvs} log -r::1.2 file1" \ -"${log_header1} -${log_tags1} -${log_keyword} -total revisions: 5; selected revisions: 2 -description: -${log_rev2} -${log_rev1} -${log_trailer}" - - dotest log-22 "${testcvs} log -r1.1:1.2 file1" \ -"${log_header1} -${log_tags1} -${log_keyword} -total revisions: 5; selected revisions: 2 -description: -${log_rev2} -${log_rev1} -${log_trailer}" - - dotest log-22a "${testcvs} log -r1.1::1.2 file1" \ -"${log_header1} -${log_tags1} -${log_keyword} -total revisions: 5; selected revisions: 1 -description: -${log_rev2} -${log_trailer}" - - dotest log-22b "${testcvs} log -r1.1::1.3 file1" \ -"${log_header1} -${log_tags1} -${log_keyword} -total revisions: 5; selected revisions: 2 -description: -${log_rev3} -${log_rev2} -${log_trailer}" - - # Test BASE pseudotag - dotest log-23 "${testcvs} log -rBASE file1" \ -"${log_header1} -${log_tags1} -${log_keyword} -total revisions: 5; selected revisions: 1 -description: -${log_rev2b} -${log_trailer}" - - dotest log-24 "${testcvs} -q up -r1.2 file1" "[UP] file1" - dotest log-25 "${testcvs} log -rBASE file1" \ -"${log_header1} -${log_tags1} -${log_keyword} -total revisions: 5; selected revisions: 1 -description: -${log_rev2} -${log_trailer}" - - dotest log-26 "${testcvs} -q up -rbranch file1" "[UP] file1" - - # Now the same tests but with rlog - - dotest log-r11 "${testcvs} rlog first-dir/file1" \ -"${rlog_header1} -${log_tags1} -${log_keyword} -total revisions: 5; selected revisions: 5 -description: -${log_rev3} -${log_rev2} -${log_rev1} -${log_rev2b} -${log_rev1b} -${log_trailer}" - - dotest log-r12 "${testcvs} rlog -N first-dir/file1" \ -"${rlog_header1} -${log_keyword} -total revisions: 5; selected revisions: 5 -description: -${log_rev3} -${log_rev2} -${log_rev1} -${log_rev2b} -${log_rev1b} -${log_trailer}" - - dotest log-r13 "${testcvs} rlog -b first-dir/file1" \ -"${rlog_header1} -${log_tags1} -${log_keyword} -total revisions: 5; selected revisions: 3 -description: -${log_rev3} -${log_rev2} -${log_rev1} -${log_trailer}" - - dotest log-r14 "${testcvs} rlog -r first-dir/file1" \ -"${rlog_header1} -${log_tags1} -${log_keyword} -total revisions: 5; selected revisions: 1 -description: -${log_rev3} -${log_trailer}" - - dotest log-r14a "${testcvs} rlog -rHEAD first-dir/file1" \ -"${rlog_header1} -${log_tags1} -${log_keyword} -total revisions: 5; selected revisions: 1 -description: -${log_rev3} -${log_trailer}" - - dotest_fail log-r14b "${testcvs} rlog -r HEAD first-dir/file1" \ -"${PROG} rlog: cannot find module .HEAD. - ignored -${rlog_header1} -${log_tags1} -${log_keyword} -total revisions: 5; selected revisions: 1 -description: -${log_rev3} -${log_trailer}" - - dotest log-r14c "${testcvs} rlog -r: first-dir/file1" \ -"${rlog_header1} -${log_tags1} -${log_keyword} -total revisions: 5; selected revisions: 1 -description: -${log_rev3} -${log_trailer}" - dotest log-r14d "${testcvs} rlog -r, first-dir/file1" \ -"${rlog_header1} -${log_tags1} -${log_keyword} -total revisions: 5; selected revisions: 1 -description: -${log_rev3} -${log_trailer}" - dotest log-r14e "${testcvs} rlog -r. first-dir/file1" \ -"${rlog_header1} -${log_tags1} -${log_keyword} -total revisions: 5; selected revisions: 1 -description: -${log_rev3} -${log_trailer}" - dotest log-r14f "${testcvs} rlog -r:: first-dir/file1" \ -"${rlog_header1} -${log_tags1} -${log_keyword} -total revisions: 5; selected revisions: 0 -description: -${log_trailer}" - - dotest log-r15 "${testcvs} rlog -r1.2 first-dir/file1" \ -"${rlog_header1} -${log_tags1} -${log_keyword} -total revisions: 5; selected revisions: 1 -description: -${log_rev2} -${log_trailer}" - - dotest log-r16 "${testcvs} rlog -r1.2.2 first-dir/file1" \ -"${rlog_header1} -${log_tags1} -${log_keyword} -total revisions: 5; selected revisions: 2 -description: -${log_rev2b} -${log_rev1b} -${log_trailer}" - - dotest log-r17 "${testcvs} rlog -rbranch first-dir/file1" \ -"${rlog_header1} -${log_tags1} -${log_keyword} -total revisions: 5; selected revisions: 2 -description: -${log_rev2b} -${log_rev1b} -${log_trailer}" - - dotest log-r18 "${testcvs} rlog -r1.2.2. first-dir/file1" \ -"${rlog_header1} -${log_tags1} -${log_keyword} -total revisions: 5; selected revisions: 1 -description: -${log_rev2b} -${log_trailer}" - - dotest log-r18a "${testcvs} rlog -r1.2.2.2 -r1.3:1.3 first-dir/file1" \ -"${rlog_header1} -${log_tags1} -${log_keyword} -total revisions: 5; selected revisions: 2 -description: -${log_rev3} -${log_rev2b} -${log_trailer}" - - dotest log-r19 "${testcvs} rlog -rbranch. first-dir/file1" \ -"${rlog_header1} -${log_tags1} -${log_keyword} -total revisions: 5; selected revisions: 1 -description: -${log_rev2b} -${log_trailer}" - - dotest log-r20 "${testcvs} rlog -r1.2: first-dir/file1" \ -"${rlog_header1} -${log_tags1} -${log_keyword} -total revisions: 5; selected revisions: 2 -description: -${log_rev3} -${log_rev2} -${log_trailer}" - - dotest log-r20a "${testcvs} rlog -r1.2:: first-dir/file1" \ -"${rlog_header1} -${log_tags1} -${log_keyword} -total revisions: 5; selected revisions: 1 -description: -${log_rev3} -${log_trailer}" - - dotest log-r21 "${testcvs} rlog -r:1.2 first-dir/file1" \ -"${rlog_header1} -${log_tags1} -${log_keyword} -total revisions: 5; selected revisions: 2 -description: -${log_rev2} -${log_rev1} -${log_trailer}" - - dotest log-r21a "${testcvs} rlog -r::1.2 first-dir/file1" \ -"${rlog_header1} -${log_tags1} -${log_keyword} -total revisions: 5; selected revisions: 2 -description: -${log_rev2} -${log_rev1} -${log_trailer}" - - dotest log-r22 "${testcvs} rlog -r1.1:1.2 first-dir/file1" \ -"${rlog_header1} -${log_tags1} -${log_keyword} -total revisions: 5; selected revisions: 2 -description: -${log_rev2} -${log_rev1} -${log_trailer}" - - dotest log-r22a "${testcvs} rlog -r1.1::1.2 first-dir/file1" \ -"${rlog_header1} -${log_tags1} -${log_keyword} -total revisions: 5; selected revisions: 1 -description: -${log_rev2} -${log_trailer}" - - dotest log-r22b "${testcvs} rlog -r1.1::1.3 first-dir/file1" \ -"${rlog_header1} -${log_tags1} -${log_keyword} -total revisions: 5; selected revisions: 2 -description: -${log_rev3} -${log_rev2} -${log_trailer}" - - # Test BASE pseudotag - dotest log-r23 "${testcvs} rlog -rBASE first-dir/file1" \ -"${PROG} rlog: warning: no revision .BASE. in .${CVSROOT_DIRNAME}/first-dir/file1,v. -${rlog_header1} -${log_tags1} -${log_keyword} -total revisions: 5; selected revisions: 0 -description: -${log_trailer}" - - dotest log-r24 "${testcvs} -q up -r1.2 file1" "[UP] file1" - dotest log-r25 "${testcvs} rlog -rBASE first-dir/file1" \ -"${PROG} rlog: warning: no revision .BASE. in .${CVSROOT_DIRNAME}/first-dir/file1,v. -${rlog_header1} -${log_tags1} -${log_keyword} -total revisions: 5; selected revisions: 0 -description: -${log_trailer}" - - # Test when head is dead - - dotest log-d0 "${testcvs} -q up -A" \ -"[UP] file1 -U file2" - dotest log-d1 "${testcvs} -q rm -f file1" \ -"${PROG} remove: use .${PROG} commit. to remove this file permanently" - dotest log-d2 "${testcvs} -q ci -m4" \ -"Removing file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -new revision: delete; previous revision: 1\.3 -done" - - log_header1=" -RCS file: ${CVSROOT_DIRNAME}/first-dir/Attic/file1,v -Working file: file1 -head: 1\.4 -branch: -locks: strict -access list:" - rlog_header1=" -RCS file: ${CVSROOT_DIRNAME}/first-dir/Attic/file1,v -head: 1\.4 -branch: -locks: strict -access list:" - log_header2=" -RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v -Working file: file2 -head: 1\.3 -branch: -locks: strict -access list:" - rlog_header2=" -RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v -head: 1\.3 -branch: -locks: strict -access list:" - log_tags2='symbolic names: - tag2: 1\.3 - tag1: 1\.2' - log_rev4="${log_dash} 1\.4 -date: [0-9/]* [0-9:]*; author: ${username}; state: dead; lines: ${PLUS}0 -0 -4" - log_rev22="${log_dash} 1\.2 -${log_date}${log_lines} -2" - - dotest log-d3 "${testcvs} log -rbranch file1" \ -"${log_header1} -${log_tags1} -${log_keyword} -total revisions: 6; selected revisions: 2 -description: -${log_rev2b} -${log_rev1b} -${log_trailer}" - dotest log-rd3 "${testcvs} rlog -rbranch first-dir/file1" \ -"${rlog_header1} -${log_tags1} -${log_keyword} -total revisions: 6; selected revisions: 2 -description: -${log_rev2b} -${log_rev1b} -${log_trailer}" - dotest log-d4 "${testcvs} -q log -rbranch" \ -"${log_header1} -${log_tags1} -${log_keyword} -total revisions: 6; selected revisions: 2 -description: -${log_rev2b} -${log_rev1b} -${log_trailer} -${PROG} log: warning: no revision .branch. in .${CVSROOT_DIRNAME}/first-dir/file2,v. -${log_header2} -${log_tags2} -${log_keyword} -total revisions: 3; selected revisions: 0 -description: -${log_trailer}" - dotest log-d4a "${testcvs} -q log -t -rbranch" \ -"${log_header1} -${log_tags1} -${log_keyword} -total revisions: 6 -description: -${log_trailer} -${PROG} log: warning: no revision .branch. in .${CVSROOT_DIRNAME}/first-dir/file2,v. -${log_header2} -${log_tags2} -${log_keyword} -total revisions: 3 -description: -${log_trailer}" - dotest log-d4b "${testcvs} -q log -tS -rbranch" \ -"${log_header1} -${log_tags1} -${log_keyword} -total revisions: 6; selected revisions: 2 -description: -${log_trailer} -${PROG} log: warning: no revision .branch. in .${CVSROOT_DIRNAME}/first-dir/file2,v." - dotest log-d4c "${testcvs} -q log -h -rbranch" \ -"${log_header1} -${log_tags1} -${log_keyword} -total revisions: 6 -${log_trailer} -${PROG} log: warning: no revision .branch. in .${CVSROOT_DIRNAME}/first-dir/file2,v. -${log_header2} -${log_tags2} -${log_keyword} -total revisions: 3 -${log_trailer}" - dotest log-d4d "${testcvs} -q log -hS -rbranch" \ -"${log_header1} -${log_tags1} -${log_keyword} -total revisions: 6; selected revisions: 2 -${log_trailer} -${PROG} log: warning: no revision .branch. in .${CVSROOT_DIRNAME}/first-dir/file2,v." - dotest log-d4e "${testcvs} -q log -R -rbranch" \ -"${CVSROOT_DIRNAME}/first-dir/Attic/file1,v -${CVSROOT_DIRNAME}/first-dir/file2,v" - dotest log-d4f "${testcvs} -q log -R -S -rbranch" \ -"${CVSROOT_DIRNAME}/first-dir/Attic/file1,v -${PROG} log: warning: no revision .branch. in .${CVSROOT_DIRNAME}/first-dir/file2,v." - dotest log-rd4 "${testcvs} -q rlog -rbranch first-dir" \ -"${rlog_header1} -${log_tags1} -${log_keyword} -total revisions: 6; selected revisions: 2 -description: -${log_rev2b} -${log_rev1b} -${log_trailer} -${PROG} rlog: warning: no revision .branch. in .${CVSROOT_DIRNAME}/first-dir/file2,v. -${rlog_header2} -${log_tags2} -${log_keyword} -total revisions: 3; selected revisions: 0 -description: -${log_trailer}" - dotest log-rd4a "${testcvs} -q rlog -t -rbranch first-dir" \ -"${rlog_header1} -${log_tags1} -${log_keyword} -total revisions: 6 -description: -${log_trailer} -${PROG} rlog: warning: no revision .branch. in .${CVSROOT_DIRNAME}/first-dir/file2,v. -${rlog_header2} -${log_tags2} -${log_keyword} -total revisions: 3 -description: -${log_trailer}" - dotest log-rd4b "${testcvs} -q rlog -St -rbranch first-dir" \ -"${rlog_header1} -${log_tags1} -${log_keyword} -total revisions: 6; selected revisions: 2 -description: -${log_trailer} -${PROG} rlog: warning: no revision .branch. in .${CVSROOT_DIRNAME}/first-dir/file2,v." - dotest log-rd4c "${testcvs} -q rlog -h -rbranch first-dir" \ -"${rlog_header1} -${log_tags1} -${log_keyword} -total revisions: 6 -${log_trailer} -${PROG} rlog: warning: no revision .branch. in .${CVSROOT_DIRNAME}/first-dir/file2,v. -${rlog_header2} -${log_tags2} -${log_keyword} -total revisions: 3 -${log_trailer}" - dotest log-rd4d "${testcvs} -q rlog -Sh -rbranch first-dir" \ -"${rlog_header1} -${log_tags1} -${log_keyword} -total revisions: 6; selected revisions: 2 -${log_trailer} -${PROG} rlog: warning: no revision .branch. in .${CVSROOT_DIRNAME}/first-dir/file2,v." - dotest log-rd4e "${testcvs} -q rlog -R -rbranch first-dir" \ -"${CVSROOT_DIRNAME}/first-dir/Attic/file1,v -${CVSROOT_DIRNAME}/first-dir/file2,v" - dotest log-rd4f "${testcvs} -q rlog -R -S -rbranch first-dir" \ -"${CVSROOT_DIRNAME}/first-dir/Attic/file1,v -${PROG} rlog: warning: no revision .branch. in .${CVSROOT_DIRNAME}/first-dir/file2,v." - dotest log-d5 "${testcvs} log -r1.2.2.1:1.2.2.2 file1" \ -"${log_header1} -${log_tags1} -${log_keyword} -total revisions: 6; selected revisions: 2 -description: -${log_rev2b} -${log_rev1b} -${log_trailer}" - dotest log-rd5 "${testcvs} rlog -r1.2.2.1:1.2.2.2 first-dir/file1" \ -"${rlog_header1} -${log_tags1} -${log_keyword} -total revisions: 6; selected revisions: 2 -description: -${log_rev2b} -${log_rev1b} -${log_trailer}" - dotest log-d6 "${testcvs} -q log -r1.2.2.1:1.2.2.2" \ -"${log_header1} -${log_tags1} -${log_keyword} -total revisions: 6; selected revisions: 2 -description: -${log_rev2b} -${log_rev1b} -${log_trailer} -${log_header2} -${log_tags2} -${log_keyword} -total revisions: 3; selected revisions: 0 -description: -${log_trailer}" - dotest log-rd6 "${testcvs} -q rlog -r1.2.2.1:1.2.2.2 first-dir" \ -"${rlog_header1} -${log_tags1} -${log_keyword} -total revisions: 6; selected revisions: 2 -description: -${log_rev2b} -${log_rev1b} -${log_trailer} -${rlog_header2} -${log_tags2} -${log_keyword} -total revisions: 3; selected revisions: 0 -description: -${log_trailer}" - dotest log-d7 "${testcvs} log -r1.2:1.3 file1" \ -"${log_header1} -${log_tags1} -${log_keyword} -total revisions: 6; selected revisions: 2 -description: -${log_rev3} -${log_rev2} -${log_trailer}" - dotest log-rd7 "${testcvs} -q rlog -r1.2:1.3 first-dir/file1" \ -"${rlog_header1} -${log_tags1} -${log_keyword} -total revisions: 6; selected revisions: 2 -description: -${log_rev3} -${log_rev2} -${log_trailer}" - dotest log-d8 "${testcvs} -q log -rtag1:tag2" \ -"${PROG} log: warning: no revision .tag1. in .${CVSROOT_DIRNAME}/first-dir/Attic/file1,v. -${PROG} log: warning: no revision .tag2. in .${CVSROOT_DIRNAME}/first-dir/Attic/file1,v. -${log_header1} -${log_tags1} -${log_keyword} -total revisions: 6; selected revisions: 0 -description: -${log_trailer} -${log_header2} -${log_tags2} -${log_keyword} -total revisions: 3; selected revisions: 2 -description: -${log_rev3} -${log_rev22} -${log_trailer}" - dotest log-d8a "${testcvs} -q log -rtag1:tag2 -S" \ -"${PROG} log: warning: no revision .tag1. in .${CVSROOT_DIRNAME}/first-dir/Attic/file1,v. -${PROG} log: warning: no revision .tag2. in .${CVSROOT_DIRNAME}/first-dir/Attic/file1,v. -${log_header2} -${log_tags2} -${log_keyword} -total revisions: 3; selected revisions: 2 -description: -${log_rev3} -${log_rev22} -${log_trailer}" - dotest log-rd8 "${testcvs} -q rlog -rtag1:tag2 first-dir" \ -"${PROG} rlog: warning: no revision .tag1. in .${CVSROOT_DIRNAME}/first-dir/Attic/file1,v. -${PROG} rlog: warning: no revision .tag2. in .${CVSROOT_DIRNAME}/first-dir/Attic/file1,v. -${rlog_header1} -${log_tags1} -${log_keyword} -total revisions: 6; selected revisions: 0 -description: -${log_trailer} -${rlog_header2} -${log_tags2} -${log_keyword} -total revisions: 3; selected revisions: 2 -description: -${log_rev3} -${log_rev22} -${log_trailer}" - dotest log-rd8a "${testcvs} -q rlog -rtag1:tag2 -S first-dir" \ -"${PROG} rlog: warning: no revision .tag1. in .${CVSROOT_DIRNAME}/first-dir/Attic/file1,v. -${PROG} rlog: warning: no revision .tag2. in .${CVSROOT_DIRNAME}/first-dir/Attic/file1,v. -${rlog_header2} -${log_tags2} -${log_keyword} -total revisions: 3; selected revisions: 2 -description: -${log_rev3} -${log_rev22} -${log_trailer}" - - dotest log-d99 "${testcvs} -q up -rbranch" \ -"[UP] file1 -${PROG} update: file2 is no longer in the repository" - - # Now test outdating revisions - - dotest log-o0 "${testcvs} admin -o 1.2.2.2:: file1" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/Attic/file1,v -done" - dotest log-o1 "${testcvs} admin -o ::1.2.2.1 file1" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/Attic/file1,v -done" - dotest log-o2 "${testcvs} admin -o 1.2.2.1:: file1" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/Attic/file1,v -deleting revision 1\.2\.2\.2 -done" - dotest log-o3 "${testcvs} log file1" \ -"${log_header1} -${log_tags1} -${log_keyword} -total revisions: 5; selected revisions: 5 -description: -${log_rev4} -${log_rev3} -${log_rev2} -${log_rev1} -${log_rev1b} -${log_trailer}" - dotest log-ro3 "${testcvs} rlog first-dir/file1" \ -"${rlog_header1} -${log_tags1} -${log_keyword} -total revisions: 5; selected revisions: 5 -description: -${log_rev4} -${log_rev3} -${log_rev2} -${log_rev1} -${log_rev1b} -${log_trailer}" - dotest log-o4 "${testcvs} -q update -p -r 1.2.2.1 file1" \ -"first branch revision" - - cd .. - rm -r first-dir - rm -rf ${CVSROOT_DIRNAME}/first-dir - ;; - - log2) - # More "cvs log" tests, for example the file description. - - # Check in a file - mkdir ${CVSROOT_DIRNAME}/first-dir - dotest log2-1 "${testcvs} -q co first-dir" '' - cd first-dir - echo 'first revision' > file1 - dotest log2-2 "${testcvs} add -m file1-is-for-testing file1" \ -"${PROG}"' add: scheduling file `file1'\'' for addition -'"${PROG}"' add: use .'"${PROG}"' commit. to add this file permanently' - dotest log2-3 "${testcvs} -q commit -m 1" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -done -Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -initial revision: 1\.1 -done" - # Setting the file description with add -m doesn't yet work - # client/server, so skip log2-4 for remote. - if $remote; then :; else - - dotest log2-4 "${testcvs} log -N file1" " -RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -Working file: file1 -head: 1\.1 -branch: -locks: strict -access list: -keyword substitution: kv -total revisions: 1; selected revisions: 1 -description: -file1-is-for-testing ----------------------------- -revision 1\.1 -date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; -1 -=============================================================================" - - fi # end of tests skipped for remote - - dotest log2-5 "${testcvs} admin -t-change-description file1" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -done" - dotest log2-6 "${testcvs} log -N file1" " -RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -Working file: file1 -head: 1\.1 -branch: -locks: strict -access list: -keyword substitution: kv -total revisions: 1; selected revisions: 1 -description: -change-description ----------------------------- -revision 1\.1 -date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; -1 -=============================================================================" - - echo 'longer description' >${TESTDIR}/descrip - echo 'with two lines' >>${TESTDIR}/descrip - dotest log2-7 "${testcvs} admin -t${TESTDIR}/descrip file1" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -done" - dotest_fail log2-7a "${testcvs} admin -t${TESTDIR}/nonexist file1" \ -"${PROG} \[[a-z]* aborted\]: can't stat ${TESTDIR}/nonexist: No such file or directory" - dotest log2-8 "${testcvs} log -N file1" " -RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -Working file: file1 -head: 1\.1 -branch: -locks: strict -access list: -keyword substitution: kv -total revisions: 1; selected revisions: 1 -description: -longer description -with two lines ----------------------------- -revision 1\.1 -date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; -1 -=============================================================================" - - # TODO: `cvs admin -t "my message" file1' is a request to - # read the message from stdin and to operate on two files. - # Should test that there is an error because "my message" - # doesn't exist. - - dotest log2-9 "echo change from stdin | ${testcvs} admin -t -q file1" "" - dotest log2-10 "${testcvs} log -N file1" " -RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -Working file: file1 -head: 1\.1 -branch: -locks: strict -access list: -keyword substitution: kv -total revisions: 1; selected revisions: 1 -description: -change from stdin ----------------------------- -revision 1\.1 -date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; -1 -=============================================================================" - - cd .. - rm ${TESTDIR}/descrip - rm -r first-dir - rm -rf ${CVSROOT_DIRNAME}/first-dir - - ;; - - logopt) - # Some tests of log.c's option parsing and such things. - mkdir 1; cd 1 - dotest logopt-1 "${testcvs} -q co -l ." '' - mkdir first-dir - dotest logopt-2 "${testcvs} add first-dir" \ -"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" - cd first-dir - echo hi >file1 - dotest logopt-3 "${testcvs} add file1" \ -"${PROG} add: scheduling file .file1. for addition -${PROG} add: use .${PROG} commit. to add this file permanently" - dotest logopt-4 "${testcvs} -q ci -m add file1" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -done -Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -initial revision: 1\.1 -done" - cd .. - - dotest logopt-5 "${testcvs} log -R -d 2038-01-01" \ -"${PROG} log: Logging \. -${PROG} log: Logging first-dir -${CVSROOT_DIRNAME}/first-dir/file1,v" - dotest logopt-6 "${testcvs} log -d 2038-01-01 -R" \ -"${PROG} log: Logging \. -${PROG} log: Logging first-dir -${CVSROOT_DIRNAME}/first-dir/file1,v" - dotest logopt-6a "${testcvs} log -Rd 2038-01-01" \ -"${PROG} log: Logging \. -${PROG} log: Logging first-dir -${CVSROOT_DIRNAME}/first-dir/file1,v" - dotest logopt-7 "${testcvs} log -s Exp -R" \ -"${PROG} log: Logging \. -${PROG} log: Logging first-dir -${CVSROOT_DIRNAME}/first-dir/file1,v" - - cd .. - rm -r 1 - rm -rf ${CVSROOT_DIRNAME}/first-dir - ;; - - ann) - # Tests of "cvs annotate". See also: - # basica-10 A simple annotate test - # rcs Annotate and the year 2000 - # keywordlog Annotate and $Log. - mkdir 1; cd 1 - dotest ann-1 "${testcvs} -q co -l ." '' - mkdir first-dir - dotest ann-2 "${testcvs} add first-dir" \ -"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" - cd first-dir - cat >file1 <file1 <file1 <file1 < $file - - dotest ann-id-3 "$testcvs add $file" \ -"${PROG} add: scheduling file .$file. for addition -${PROG} add: use .${PROG} commit. to add this file permanently" - dotest ann-id-4 "$testcvs -Q ci -m . $file" \ -"RCS file: ${CVSROOT_DIRNAME}/$module/$file,v -done -Checking in $file; -${CVSROOT_DIRNAME}/$module/$file,v <-- $file -initial revision: 1\.1 -done" - - echo line2 >> $file - dotest ann-id-5 "$testcvs -Q ci -m . $file" \ -"Checking in $file; -${CVSROOT_DIRNAME}/$module/$file,v <-- $file -new revision: 1\.2; previous revision: 1\.1 -done" - - # The version number after $file,v should be `1.2'. - # 1.9.28.1 puts `1.1' there. - dotest ann-id-6 "$testcvs -Q ann $file" \ -" -Annotations for $file -\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* -1.2 ($username8 *[0-9a-zA-Z-]*): "'\$'"Id: $file,v 1.1 [0-9/]* [0-9:]* $username Exp "'\$'" -1.2 ($username8 *[0-9a-zA-Z-]*): line2" - - cd ../.. - rm -rf 1 - rm -rf ${CVSROOT_DIRNAME}/$module - ;; - - crerepos) - # Various tests relating to creating repositories, operating - # on repositories created with old versions of CVS, etc. - - CVS_SERVER_save=$CVS_SERVER - - # Because this test is all about -d options and such, it - # at least to some extent needs to be different for remote vs. - # local. - if $remote; then - - # Use :ext: rather than :fork:. Most of the tests use :fork:, - # so we want to make sure that we test :ext: _somewhere_. - # Make sure 'rsh' works first. - depends_on_rsh "$CVS_RSH" - if test $? -eq 77; then - skip crerepos "$skipreason" - continue - fi - - # For remote, just create the repository. We don't yet do - # the various other tests above for remote but that should be - # changed. - mkdir crerepos - mkdir crerepos/CVSROOT - - # Make sure server ignores real ${HOME}/.cvsrc: - cat >$TESTDIR/cvs-setHome <>${LOGFILE}; then - pass crerepos-5 - else - fail crerepos-5 - fi - rm -rf CVS - cd .. - # The directory 1 should be empty - dotest crerepos-6 "rmdir 1" - - CREREPOS_ROOT=${TESTDIR}/crerepos - - fi - - if $remote; then - # Test that CVS rejects a relative path in CVSROOT. - mkdir 1; cd 1 - # Note that having the client reject the pathname (as :fork: - # does), does _not_ test for the bugs we are trying to catch - # here. The point is that malicious clients might send all - # manner of things and the server better protect itself. - dotest_fail crerepos-6a-r \ -"${testcvs} -q -d :ext:`hostname`:../crerepos get ." \ -"${PROG} [a-z]*: CVSROOT may only specify a positive, non-zero, integer port (not .\.\..)\. -${PROG} [a-z]*: Perhaps you entered a relative pathname${QUESTION} -${PROG} \[[a-z]* aborted\]: Bad CVSROOT: .:ext:${hostname}:\.\./crerepos.\." - cd .. - rm -r 1 - else # local - # Test that CVS rejects a relative path in CVSROOT. - - mkdir 1; cd 1 - # Set CVS_RSH=false since ocassionally (e.g. when CVS_RSH=ssh on - # some systems) some rsh implementations will block because they - # can look up '..' and want to ask the user about the unknown host - # key or somesuch. Which error message we get depends on whether - # false finishes running before we try to talk to it or not. - dotest_fail crerepos-6a "CVS_RSH=false ${testcvs} -q -d ../crerepos get ." \ -"${PROG} \[checkout aborted\]: .*" \ -"${PROG} checkout: CVSROOT is set for a remote access method but your -${PROG} checkout: CVS executable doesn't support it\. -${PROG} \[checkout aborted\]: Bad CVSROOT: .\.\./crerepos.\." - cd .. - rm -r 1 - - mkdir 1; cd 1 - dotest_fail crerepos-6b "${testcvs} -d crerepos init" \ -"${PROG} init: CVSROOT must be an absolute pathname (not .crerepos.) -${PROG} init: when using local access method\. -${PROG} \[init aborted\]: Bad CVSROOT: .crerepos.\." - cd .. - rm -r 1 - fi # end of tests to be skipped for remote - - # CVS better not create a history file--if the administrator - # doesn't need it and wants to save on disk space, they just - # delete it. - dotest_fail crerepos-7 \ -"test -f ${TESTDIR}/crerepos/CVSROOT/history" '' - - # Now test mixing repositories. This kind of thing tends to - # happen accidentally when people work with several repositories. - mkdir 1; cd 1 - dotest crerepos-8 "${testcvs} -q co -l ." '' - mkdir first-dir - dotest crerepos-9 "${testcvs} add first-dir" \ -"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" - cd first-dir - touch file1 - dotest crerepos-10 "${testcvs} add file1" \ -"${PROG} add: scheduling file .file1. for addition -${PROG} add: use .${PROG} commit. to add this file permanently" - dotest crerepos-11 "${testcvs} -q ci -m add-it" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -done -Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -initial revision: 1\.1 -done" - cd ../.. - rm -r 1 - - mkdir 1; cd 1 - dotest crerepos-12 "${testcvs} -d ${CREREPOS_ROOT} -q co -l ." '' - mkdir crerepos-dir - dotest crerepos-13 "${testcvs} add crerepos-dir" \ -"Directory ${TESTDIR}/crerepos/crerepos-dir added to the repository" - cd crerepos-dir - touch cfile - dotest crerepos-14 "${testcvs} add cfile" \ -"${PROG} add: scheduling file .cfile. for addition -${PROG} add: use .${PROG} commit. to add this file permanently" - dotest crerepos-15 "${testcvs} -q ci -m add-it" \ -"RCS file: ${TESTDIR}/crerepos/crerepos-dir/cfile,v -done -Checking in cfile; -${TESTDIR}/crerepos/crerepos-dir/cfile,v <-- cfile -initial revision: 1\.1 -done" - cd ../.. - rm -r 1 - - mkdir 1; cd 1 - dotest crerepos-16 "${testcvs} co first-dir" \ -"${PROG} checkout: Updating first-dir -U first-dir/file1" - dotest crerepos-17 "${testcvs} -d ${CREREPOS_ROOT} co crerepos-dir" \ -"${PROG} checkout: Updating crerepos-dir -U crerepos-dir/cfile" - dotest crerepos-18 "${testcvs} update" \ -"${PROG} update: Updating first-dir -${PROG} update: Updating crerepos-dir" - - cd .. - - CVS_SERVER=$CVS_SERVER_save; export CVS_SERVER - - if $keep; then - echo Keeping ${TESTDIR} and exiting due to --keep - exit 0 - fi - - rm -f $TESTDIR/cvs-setHome - rm -r 1 - rm -rf ${CVSROOT_DIRNAME}/first-dir ${TESTDIR}/crerepos - ;; - - - - crerepos-extssh) - # Various tests relating to creating repositories, operating - # on repositories created with old versions of CVS, etc. - - CVS_SERVER_save=$CVS_SERVER - - # Because this test is all about -d options and such, it - # at least to some extent needs to be different for remote vs. - # local. - if $remote; then - - # Use :extssh: rather than :fork:. Most of the tests use :fork:, - # so we want to make sure that we test :extssh: _somewhere_. - # Make sure 'ssh' works first. - depends_on_rsh "$CVS_RSH" - if test $? -eq 77; then - skip crerepos "$skipreason" - continue - fi - - # For remote, just create the repository. We don't yet do - # the various other tests above for remote but that should be - # changed. - mkdir crerepos - mkdir crerepos/CVSROOT - - # Make sure server ignores real ${HOME}/.cvsrc: - cat >$TESTDIR/cvs-setHome <>${LOGFILE}; then - pass crerepos-extssh-5 - else - fail crerepos-extssh-5 - fi - rm -rf CVS - cd .. - # The directory 1 should be empty - dotest crerepos-extssh-6 "rmdir 1" - - CREREPOS_ROOT=${TESTDIR}/crerepos - - fi - - if $remote; then - # Test that CVS rejects a relative path in CVSROOT. - mkdir 1; cd 1 - # Note that having the client reject the pathname (as :fork: - # does), does _not_ test for the bugs we are trying to catch - # here. The point is that malicious clients might send all - # manner of things and the server better protect itself. - dotest_fail crerepos-extssh-6a-r \ -"${testcvs} -q -d :extssh:`hostname`:../crerepos get ." \ -"${PROG} [a-z]*: CVSROOT may only specify a positive, non-zero, integer port (not .\.\..)\. -${PROG} [a-z]*: Perhaps you entered a relative pathname${QUESTION} -${PROG} \[[a-z]* aborted\]: Bad CVSROOT: .:extssh:${hostname}:\.\./crerepos.\." - cd .. - rm -r 1 - else # local - # Test that CVS rejects a relative path in CVSROOT. - - mkdir 1; cd 1 - # Set CVS_RSH=false since ocassionally (e.g. when CVS_RSH=ssh on - # some systems) some rsh implementations will block because they - # can look up '..' and want to ask the user about the unknown host - # key or somesuch. Which error message we get depends on whether - # false finishes running before we try to talk to it or not. - dotest_fail crerepos-extssh-6a "CVS_RSH=false ${testcvs} -q -d ../crerepos get ." \ -"${PROG} \[checkout aborted\]: .*" \ -"${PROG} checkout: CVSROOT is set for a remote access method but your -${PROG} checkout: CVS executable doesn't support it\. -${PROG} \[checkout aborted\]: Bad CVSROOT: .\.\./crerepos.\." - cd .. - rm -r 1 - - mkdir 1; cd 1 - dotest_fail crerepos-extssh-6b "${testcvs} -d crerepos init" \ -"${PROG} init: CVSROOT must be an absolute pathname (not .crerepos.) -${PROG} init: when using local access method\. -${PROG} \[init aborted\]: Bad CVSROOT: .crerepos.\." - cd .. - rm -r 1 - fi # end of tests to be skipped for remote - - # CVS better not create a history file--if the administrator - # doesn't need it and wants to save on disk space, they just - # delete it. - dotest_fail crerepos-extssh-7 \ -"test -f ${TESTDIR}/crerepos/CVSROOT/history" '' - - # Now test mixing repositories. This kind of thing tends to - # happen accidentally when people work with several repositories. - mkdir 1; cd 1 - dotest crerepos-extssh-8 "${testcvs} -q co -l ." '' - mkdir first-dir - dotest crerepos-extssh-9 "${testcvs} add first-dir" \ -"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" - cd first-dir - touch file1 - dotest crerepos-extssh-10 "${testcvs} add file1" \ -"${PROG} add: scheduling file .file1. for addition -${PROG} add: use .${PROG} commit. to add this file permanently" - dotest crerepos-extssh-11 "${testcvs} -q ci -m add-it" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -done -Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -initial revision: 1\.1 -done" - cd ../.. - rm -r 1 - - mkdir 1; cd 1 - dotest crerepos-extssh-12 "${testcvs} -d ${CREREPOS_ROOT} -q co -l ." '' - mkdir crerepos-dir - dotest crerepos-extssh-13 "${testcvs} add crerepos-dir" \ -"Directory ${TESTDIR}/crerepos/crerepos-dir added to the repository" - cd crerepos-dir - touch cfile - dotest crerepos-extssh-14 "${testcvs} add cfile" \ -"${PROG} add: scheduling file .cfile. for addition -${PROG} add: use .${PROG} commit. to add this file permanently" - dotest crerepos-extssh-15 "${testcvs} -q ci -m add-it" \ -"RCS file: ${TESTDIR}/crerepos/crerepos-dir/cfile,v -done -Checking in cfile; -${TESTDIR}/crerepos/crerepos-dir/cfile,v <-- cfile -initial revision: 1\.1 -done" - cd ../.. - rm -r 1 - - mkdir 1; cd 1 - dotest crerepos-extssh-16 "${testcvs} co first-dir" \ -"${PROG} checkout: Updating first-dir -U first-dir/file1" - dotest crerepos-extssh-17 "${testcvs} -d ${CREREPOS_ROOT} co crerepos-dir" \ -"${PROG} checkout: Updating crerepos-dir -U crerepos-dir/cfile" - dotest crerepos-extssh-18 "${testcvs} update" \ -"${PROG} update: Updating first-dir -${PROG} update: Updating crerepos-dir" - - cd .. - - CVS_SERVER=$CVS_SERVER_save; export CVS_SERVER - - if $keep; then - echo Keeping ${TESTDIR} and exiting due to --keep - exit 0 - fi - - rm -f $TESTDIR/cvs-setHome - rm -r 1 - rm -rf ${CVSROOT_DIRNAME}/first-dir ${TESTDIR}/crerepos - ;; - - - - rcs) - # Test ability to import an RCS file. Note that this format - # is fixed--files written by RCS5, and other software which - # implements this format, will be out there "forever" and - # CVS must always be able to import such files. - - # See tests admin-13, admin-25 and rcs-8a for exporting RCS files. - - mkdir ${CVSROOT_DIRNAME}/first-dir - - # Currently the way to import an RCS file is to copy it - # directly into the repository. - # - # This file was written by RCS 5.7, and then the dates were - # hacked so that we test year 2000 stuff. Note also that - # "author" names are just strings, as far as importing - # RCS files is concerned--they need not correspond to user - # IDs on any particular system. - # - # I also tried writing a file with the RCS supplied with - # HPUX A.09.05. According to "man rcsintro" this is - # "Revision Number: 3.0; Release Date: 83/05/11". There - # were a few minor differences like whitespace but at least - # in simple cases like this everything else seemed the same - # as the file written by RCS 5.7 (so I won't try to make it - # a separate test case). - - cat <${CVSROOT_DIRNAME}/first-dir/file1,v -head 1.3; -access; -symbols; -locks; strict; -comment @# @; - - -1.3 -date 2000.11.24.15.58.37; author kingdon; state Exp; -branches; -next 1.2; - -1.2 -date 96.11.24.15.57.41; author kingdon; state Exp; -branches; -next 1.1; - -1.1 -date 96.11.24.15.56.05; author kingdon; state Exp; -branches; -next ; - - -desc -@file1 is for testing CVS -@ - - -1.3 -log -@delete second line; modify twelfth line -@ -text -@This is the first line -This is the third line -This is the fourth line -This is the fifth line -This is the sixth line -This is the seventh line -This is the eighth line -This is the ninth line -This is the tenth line -This is the eleventh line -This is the twelfth line (and what a line it is) -This is the thirteenth line -@ - - -1.2 -log -@add more lines -@ -text -@a1 1 -This is the second line -d11 1 -a11 1 -This is the twelfth line -@ - - -1.1 -log -@add file1 -@ -text -@d2 12 -@ -EOF - dotest rcs-1 "${testcvs} -q co first-dir" 'U first-dir/file1' - cd first-dir - dotest rcs-2 "${testcvs} -q log" " -RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -Working file: file1 -head: 1\.3 -branch: -locks: strict -access list: -symbolic names: -keyword substitution: kv -total revisions: 3; selected revisions: 3 -description: -file1 is for testing CVS ----------------------------- -revision 1\.3 -date: 2000/11/24 15:58:37; author: kingdon; state: Exp; lines: ${PLUS}1 -2 -delete second line; modify twelfth line ----------------------------- -revision 1\.2 -date: 1996/11/24 15:57:41; author: kingdon; state: Exp; lines: ${PLUS}12 -0 -add more lines ----------------------------- -revision 1\.1 -date: 1996/11/24 15:56:05; author: kingdon; state: Exp; -add file1 -=============================================================================" - - # Note that the dates here are chosen so that (a) we test - # at least one date after 2000, (b) we will notice if the - # month and day are getting mixed up with each other. - # TODO: also test that year isn't getting mixed up with month - # or day, for example 01-02-03. - - # ISO8601 format. There are many, many, other variations - # specified by ISO8601 which we should be testing too. - dotest rcs-3 "${testcvs} -q log -d '1996-12-11<'" " -RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -Working file: file1 -head: 1\.3 -branch: -locks: strict -access list: -symbolic names: -keyword substitution: kv -total revisions: 3; selected revisions: 1 -description: -file1 is for testing CVS ----------------------------- -revision 1\.3 -date: 2000/11/24 15:58:37; author: kingdon; state: Exp; lines: ${PLUS}1 -2 -delete second line; modify twelfth line -=============================================================================" - - # RFC822 format (as amended by RFC1123). - dotest rcs-4 "${testcvs} -q log -d '<3 Apr 2000 00:00'" \ -" -RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -Working file: file1 -head: 1\.3 -branch: -locks: strict -access list: -symbolic names: -keyword substitution: kv -total revisions: 3; selected revisions: 2 -description: -file1 is for testing CVS ----------------------------- -revision 1\.2 -date: 1996/11/24 15:57:41; author: kingdon; state: Exp; lines: ${PLUS}12 -0 -add more lines ----------------------------- -revision 1\.1 -date: 1996/11/24 15:56:05; author: kingdon; state: Exp; -add file1 -=============================================================================" - - # Intended behavior for "cvs annotate" is that it displays the - # last two digits of the year. Make sure it does that rather - # than some bogosity like "100". - dotest rcs-4a "${testcvs} annotate file1" \ -" -Annotations for file1 -\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* -1\.1 (kingdon 24-Nov-96): This is the first line -1\.2 (kingdon 24-Nov-96): This is the third line -1\.2 (kingdon 24-Nov-96): This is the fourth line -1\.2 (kingdon 24-Nov-96): This is the fifth line -1\.2 (kingdon 24-Nov-96): This is the sixth line -1\.2 (kingdon 24-Nov-96): This is the seventh line -1\.2 (kingdon 24-Nov-96): This is the eighth line -1\.2 (kingdon 24-Nov-96): This is the ninth line -1\.2 (kingdon 24-Nov-96): This is the tenth line -1\.2 (kingdon 24-Nov-96): This is the eleventh line -1\.3 (kingdon 24-Nov-00): This is the twelfth line (and what a line it is) -1\.2 (kingdon 24-Nov-96): This is the thirteenth line" - - # Probably should split this test into two at this point (file1 - # above this line and file2 below), as the two share little - # data/setup. - - # OK, here is another one. This one was written by hand based on - # doc/RCSFILES and friends. One subtle point is that none of - # the lines end with newlines; that is a feature which we - # should be testing. - cat <${CVSROOT_DIRNAME}/first-dir/file2,v -head 1.5 ; - branch 1.2.6; -access ; -symbols branch:1.2.6; -locks; -testofanewphrase @without newphrase we'd have trouble extending @@ all@ ; -1.5 date 71.01.01.01.00.00; author joe; state bogus; branches; next 1.4; -1.4 date 71.01.01.00.00.05; author joe; state bogus; branches; next 1.3; -1.3 date 70.12.31.15.00.05; author joe; state bogus; branches; next 1.2; -1.2 date 70.12.31.12.15.05; author me; state bogus; branches 1.2.6.1; next 1.1; -1.1 date 70.12.31.11.00.05; author joe; state bogus; branches; next; newph; -1.2.6.1 date 71.01.01.08.00.05; author joe; state Exp; branches; next; -desc @@ -1.5 log @@ newphrase1; newphrase2 42; text @head revision@ -1.4 log @@ text @d1 1 -a1 1 -new year revision@ -1.3 log @@ text @d1 1 -a1 1 -old year revision@ -1.2 log @@ text @d1 1 -a1 1 -mid revision@ 1.1 - -log @@ text @d1 1 -a1 1 -start revision@ -1.2.6.1 log @@ text @d1 1 -a1 1 -branch revision@ -EOF - # ' Match the single quote in above here doc -- for font-lock mode. - - # First test the default branch. - dotest rcs-5 "${testcvs} -q update file2" "U file2" - dotest rcs-6 "cat file2" "branch revision" - - # Check in a revision on the branch to force CVS to - # interpret every revision in the file. - dotest rcs-6a "$testcvs -q update -r branch file2" 'U file2' - echo "next branch revision" > file2 - dotest rcs-6b "${testcvs} -q ci -m mod file2" \ -"Checking in file2; -${CVSROOT_DIRNAME}/first-dir/file2,v <-- file2 -new revision: 1\.2\.6\.2; previous revision: 1\.2\.6\.1 -done" - - # Now get rid of the default branch, it will get in the way. - dotest rcs-7 "${testcvs} admin -b file2" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v -done" - # But we do want to make sure that "cvs admin" leaves the newphrases - # in the file. - # The extra whitespace regexps are for the RCS library, which does - # not preserve whitespace in the dogmatic manner of RCS 5.7. -twp - dotest rcs-8 \ -"grep testofanewphrase ${CVSROOT_DIRNAME}/first-dir/file2,v" \ -"testofanewphrase[ ][ ]*@without newphrase we'd have trouble extending @@ all@[ ]*;" - # The easiest way to test for newphrases in deltas and deltatexts - # is to just look at the whole file, I guess. - dotest rcs-8a "cat ${CVSROOT_DIRNAME}/first-dir/file2,v" \ -"head 1\.5; -access; -symbols - branch:1.2.6; -locks; - -testofanewphrase @without newphrase we'd have trouble extending @@ all@; - -1\.5 -date 71\.01\.01\.01\.00\.00; author joe; state bogus; -branches; -next 1\.4; - -1\.4 -date 71\.01\.01\.00\.00\.05; author joe; state bogus; -branches; -next 1\.3; - -1\.3 -date 70\.12\.31\.15\.00\.05; author joe; state bogus; -branches; -next 1\.2; - -1\.2 -date 70\.12\.31\.12\.15\.05; author me; state bogus; -branches - 1\.2\.6\.1; -next 1\.1; - -1\.1 -date 70\.12\.31\.11\.00\.05; author joe; state bogus; -branches; -next ; -newph ; - -1\.2\.6\.1 -date 71\.01\.01\.08\.00\.05; author joe; state Exp; -branches; -next 1\.2\.6\.2; - -1\.2\.6\.2 -date [0-9.]*; author ${username}; state Exp; -branches; -next ; - - -desc -@@ - - -1\.5 -log -@@ -newphrase1 ; -newphrase2 42; -text -@head revision@ - - -1\.4 -log -@@ -text -@d1 1 -a1 1 -new year revision@ - - -1\.3 -log -@@ -text -@d1 1 -a1 1 -old year revision@ - - -1\.2 -log -@@ -text -@d1 1 -a1 1 -mid revision@ - - -1\.1 -log -@@ -text -@d1 1 -a1 1 -start revision@ - - -1\.2\.6\.1 -log -@@ -text -@d1 1 -a1 1 -branch revision@ - - -1\.2\.6\.2 -log -@mod -@ -text -@d1 1 -a1 1 -next branch revision -@" - - dotest rcs-9 "${testcvs} -q update -p -D '1970-12-31 11:30 UT' file2" \ -"start revision" - - dotest rcs-10 "${testcvs} -q update -p -D '1970-12-31 12:30 UT' file2" \ -"mid revision" - - dotest rcs-11 "${testcvs} -q update -p -D '1971-01-01 00:30 UT' file2" \ -"new year revision" - - # Same test as rcs-10, but with am/pm. - dotest rcs-12 "${testcvs} -q update -p -D 'December 31, 1970 12:30pm UT' file2" \ -"mid revision" - - # Same test as rcs-11, but with am/pm. - dotest rcs-13 "${testcvs} -q update -p -D 'January 1, 1971 12:30am UT' file2" \ -"new year revision" - - # OK, now make sure cvs log doesn't have any trouble with the - # newphrases and such. - dotest rcs-14 "${testcvs} -q log file2" " -RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v -Working file: file2 -head: 1\.5 -branch: -locks: -access list: -symbolic names: - branch: 1\.2\.6 -keyword substitution: kv -total revisions: 7; selected revisions: 7 -description: ----------------------------- -revision 1\.5 -date: 1971/01/01 01:00:00; author: joe; state: bogus; lines: ${PLUS}1 -1 -\*\*\* empty log message \*\*\* ----------------------------- -revision 1\.4 -date: 1971/01/01 00:00:05; author: joe; state: bogus; lines: ${PLUS}1 -1 -\*\*\* empty log message \*\*\* ----------------------------- -revision 1\.3 -date: 1970/12/31 15:00:05; author: joe; state: bogus; lines: ${PLUS}1 -1 -\*\*\* empty log message \*\*\* ----------------------------- -revision 1\.2 -date: 1970/12/31 12:15:05; author: me; state: bogus; lines: ${PLUS}1 -1 -branches: 1\.2\.6; -\*\*\* empty log message \*\*\* ----------------------------- -revision 1\.1 -date: 1970/12/31 11:00:05; author: joe; state: bogus; -\*\*\* empty log message \*\*\* ----------------------------- -revision 1\.2\.6\.2 -date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; lines: ${PLUS}1 -1 -mod ----------------------------- -revision 1\.2\.6\.1 -date: 1971/01/01 08:00:05; author: joe; state: Exp; lines: ${PLUS}1 -1 -\*\*\* empty log message \*\*\* -=============================================================================" - # Now test each date format for "cvs log -d". - # Earlier than 1971-01-01 - dotest rcs-15 "${testcvs} -q log -d '<1971-01-01 00:00 GMT' file2 \ - | grep revision" \ -"total revisions: 7; selected revisions: 3 -revision 1\.3 -revision 1\.2 -revision 1\.1" - # Later than 1971-01-01 - dotest rcs-16 "${testcvs} -q log -d '1971-01-01 00:00 GMT<' file2 \ - | grep revision" \ -"total revisions: 7; selected revisions: 4 -revision 1\.5 -revision 1\.4 -revision 1\.2\.6\.2 -revision 1\.2\.6\.1" - # Alternate syntaxes for later and earlier; multiple -d options - dotest rcs-17 "${testcvs} -q log -d '>1971-01-01 00:00 GMT' \ - -d '1970-12-31 12:15 GMT>' file2 | grep revision" \ -"total revisions: 7; selected revisions: 5 -revision 1\.5 -revision 1\.4 -revision 1\.1 -revision 1\.2\.6\.2 -revision 1\.2\.6\.1" - # Range, and single date - dotest rcs-18 "${testcvs} -q log -d '1970-12-31 11:30 GMT' \ - -d '1971-01-01 00:00:05 GMT<1971-01-01 01:00:01 GMT' \ - file2 | grep revision" \ -"total revisions: 7; selected revisions: 2 -revision 1\.5 -revision 1\.1" - # Alternate range syntax; equality - dotest rcs-19 "${testcvs} -q log \ - -d '1971-01-01 01:00:01 GMT>=1971-01-01 00:00:05 GMT' \ - file2 | grep revision" \ -"total revisions: 7; selected revisions: 2 -revision 1\.5 -revision 1\.4" - - cd .. - - rm -r first-dir - rm -rf ${CVSROOT_DIRNAME}/first-dir - ;; - - rcs2) - # More date tests. Might as well do this as a separate - # test from "rcs", so that we don't need to perturb the - # "written by RCS 5.7" RCS file. - mkdir ${CVSROOT_DIRNAME}/first-dir - # Significance of various dates: - # * At least one Y2K standard refers to recognizing 9 Sep 1999 - # (as an example of a pre-2000 date, I guess). - # * At least one Y2K standard refers to recognizing 1 Jan 2001 - # (as an example of a post-2000 date, I guess). - # * Many Y2K standards refer to 2000 being a leap year. - cat <${CVSROOT_DIRNAME}/first-dir/file1,v -head 1.7; access; symbols; locks; strict; -1.7 date 2004.08.31.01.01.01; author sue; state; branches; next 1.6; -1.6 date 2004.02.29.01.01.01; author sue; state; branches; next 1.5; -1.5 date 2003.02.28.01.01.01; author sue; state; branches; next 1.4; -1.4 date 2001.01.01.01.01.01; author sue; state; branches; next 1.3; -1.3 date 2000.02.29.01.01.01; author sue; state; branches; next 1.2; -1.2 date 99.09.09.01.01.01; author sue; state; branches; next 1.1; -1.1 date 98.09.10.01.01.01; author sue; state; branches; next; -desc @a test file@ -1.7 log @@ text @head revision@ -1.6 log @@ text @d1 1 -a1 1 -2004 was a great year for leaping@ -1.5 log @@ text @d1 1 -a1 1 -2003 wasn't@ -1.4 log @@ text @d1 1 -a1 1 -two year hiatus@ -1.3 log @@ text @d1 1 -a1 1 -2000 is also a good year for leaping@ -1.2 log @@ text @d1 1 -a1 1 -Tonight we're going to party like it's a certain year@ -1.1 log @@ text @d1 1 -a1 1 -Need to start somewhere@ -EOF - # ' Match the 3rd single quote in the here doc -- for font-lock mode. - - dotest rcs2-1 "${testcvs} -q co first-dir" 'U first-dir/file1' - cd first-dir - - # 9 Sep 1999 - dotest rcs2-2 "${testcvs} -q update -p -D '1999-09-09 11:30 UT' file1" \ -"Tonight we're going to party like it's a certain year" - # 1 Jan 2001. - dotest rcs2-3 "${testcvs} -q update -p -D '2001-01-01 11:30 UT' file1" \ -"two year hiatus" - # 29 Feb 2000 - dotest rcs2-4 "${testcvs} -q update -p -D '2000-02-29 11:30 UT' file1" \ -"2000 is also a good year for leaping" - # 29 Feb 2003 is invalid - dotest_fail rcs2-5 "${testcvs} -q update -p -D '2003-02-29 11:30 UT' file1" \ -"${PROG} \[[a-z]* aborted\]: Can't parse date/time: 2003-02-29 11:30 UT" - - dotest rcs2-6 "${testcvs} -q update -p -D 2007-01-07 file1" \ -"head revision" - # This assumes that the clock of the machine running the tests - # is set to at least the year 1998 or so. There don't seem - # to be a lot of ways to test the relative date code (short - # of something like LD_LIBRARY_PRELOAD'ing in our own - # getttimeofday, or hacking the CVS source with testing - # features, which always seems to be problematic since then - # someone feels like documenting them and things go downhill - # from there). - # - # These tests can be expected to fail 3 times every 400 years - # starting Feb. 29, 2096 (because 8 years from that date would - # be Feb. 29, 2100, which is an invalid date -- 2100 isn't a - # leap year because it's divisible by 100 but not by 400). - - dotest rcs2-7 "${testcvs} -q update -p -D '96 months' file1" \ -"head revision" - dotest rcs2-8 "${testcvs} -q update -p -D '8 years' file1" \ -"head revision" - - cd .. - rm -r first-dir - rm -rf ${CVSROOT_DIRNAME}/first-dir - ;; - - rcs3) - # More RCS file tests, in particular at least some of the - # error handling issues. - mkdir ${CVSROOT_DIRNAME}/first-dir - cat <${CVSROOT_DIRNAME}/first-dir/file1,v -head 1.1; access; symbols; locks; expand o; 1.1 date 2007.03.20.04.03.02 -; author jeremiah ;state ; branches; next;desc@@1.1log@@text@head@ -EOF - mkdir 1; cd 1 - # CVS requires whitespace between "desc" and its value. - # The rcsfile(5) manpage doesn't really seem to answer the - # question one way or the other (it has a grammar but almost - # nothing about lexical analysis). - dotest_fail rcs3-1 "${testcvs} -q co first-dir" \ -"${PROG} \[checkout aborted\]: EOF while looking for value in RCS file ${CVSROOT_DIRNAME}/first-dir/file1,v" - cat <${CVSROOT_DIRNAME}/first-dir/file1,v -head 1.1; access; symbols; locks; expand o; 1.1 date 2007.03.20.04.03.02 -; author jeremiah ;state ; branches; next;desc @@1.1log@@text@head@ -EOF - # Whitespace issues, likewise. - dotest_fail rcs3-2 "${testcvs} -q co first-dir" \ -"${PROG} \[checkout aborted\]: unexpected '.x6c' reading revision number in RCS file ${CVSROOT_DIRNAME}/first-dir/file1,v" - cat <${CVSROOT_DIRNAME}/first-dir/file1,v -head 1.1; access; symbols; locks; expand o; 1.1 date 2007.03.20.04.03.02 -; author jeremiah ;state ; branches; next;desc @@1.1 log@@text@head@ -EOF - # Charming array of different messages for similar - # whitespace issues (depending on where the whitespace is). - dotest_fail rcs3-3 "${testcvs} -q co first-dir" \ -"${PROG} \[checkout aborted\]: EOF while looking for value in RCS file ${CVSROOT_DIRNAME}/first-dir/file1,v" - cat <${CVSROOT_DIRNAME}/first-dir/file1,v -head 1.1; access; symbols; locks; expand o; 1.1 date 2007.03.20.04.03.02 -; author jeremiah ;state ; branches; next;desc @@1.1 log @@text @head@ -EOF - dotest rcs3-4 "${testcvs} -q co first-dir" 'U first-dir/file1' - - # Ouch, didn't expect this one. FIXCVS. Or maybe just remove - # the feature, if this is a -s problem? - dotest_fail rcs3-5 "${testcvs} log -s nostate first-dir/file1" \ -"${DOTSTAR}ssertion.*failed${DOTSTAR}" "${DOTSTAR}failed assertion${DOTSTAR}" - cd first-dir - dotest_fail rcs3-5a "${testcvs} log -s nostate file1" \ -"${DOTSTAR}ssertion.*failed${DOTSTAR}" "${DOTSTAR}failed assertion${DOTSTAR}" - cd .. - - # See remote code above for rationale for cd. - cd first-dir - dotest rcs3-6 "${testcvs} log -R file1" \ -"${CVSROOT_DIRNAME}/first-dir/file1,v" - - # OK, now put an extraneous '\0' at the end. - ${AWK} >${CVSROOT_DIRNAME}/first-dir/file1,v - dotest_fail rcs3-7 "${testcvs} log -s nostate file1" \ -"${PROG} \[log aborted\]: unexpected '.x0' reading revision number in RCS file ${CVSROOT_DIRNAME}/first-dir/file1,v" - - cd ../.. - rm -r 1 - rm -rf ${CVSROOT_DIRNAME}/first-dir - ;; - - rcs4) - # Fix a bug that shows up when checking out files by date with the - # "-D date" command line option. There is code in the original to - # handle a special case. If the date search finds revision 1.1 it - # is supposed to check whether revision 1.1.1.1 has the same date - # stamp, which would indicate that the file was originally brought - # in with "cvs import". In that case it is supposed to return the - # vendor branch version 1.1.1.1. - # - # However, there is a bug in the code. It actually compares - # the date of revision 1.1 for equality with the date given - # on the command line -- clearly wrong. This commit fixes - # the coding bug. - # - # There is an additional bug which is _not_ fixed yet. - # The date comparison should not be a strict - # equality test. It should allow a fudge factor of, say, 2-3 - # seconds. Old versions of CVS created the two revisions - # with two separate invocations of the RCS "ci" command. We - # have many old files in the tree in which the dates of - # revisions 1.1 and 1.1.1.1 differ by 1 second. - - mkdir rcs4 - cd rcs4 - - mkdir imp-dir - cd imp-dir - echo 'OpenMunger sources' >file1 - - # choose a time in the past to demonstrate the problem - TZ=GMT touch -t 200012010123 file1 - - dotest_sort rcs4-1 \ -"${testcvs} import -d -m add rcs4-dir openmunger openmunger-1_0" \ -' - -N rcs4-dir/file1 -No conflicts created by this import' - echo 'OpenMunger sources release 1.1 extras' >>file1 - TZ=GMT touch -t 200112011234 file1 - dotest_sort rcs4-2 \ -"${testcvs} import -d -m add rcs4-dir openmunger openmunger-1_1" \ -' - -No conflicts created by this import -U rcs4-dir/file1' - cd .. - # Next checkout the new module - dotest rcs4-3 \ -"${testcvs} -q co rcs4-dir" \ -'U rcs4-dir/file1' - cd rcs4-dir - echo 'local change' >> file1 - - # commit a local change - dotest rcs4-4 \ -"${testcvs} -q commit -m hack file1" \ -"Checking in file1; -${CVSROOT_DIRNAME}/rcs4-dir/file1,v <-- file1 -new revision: 1\.2; previous revision: 1\.1 -done" - # now see if we get version 1.1 or 1.1.1.1 when we ask for - # a checkout by time... it really should be 1.1.1.1 as - # that was indeed the version that was visible at the target - # time. - dotest rcs4-5 \ -"${testcvs} -q update -D 'October 1, 2001 UTC' file1" \ -'[UP] file1' - dotest rcs4-6 \ -"${testcvs} -q status file1" \ -'=================================================================== -File: file1 Status: Up-to-date - - Working revision: 1\.1\.1\.1.* - Repository revision: 1\.1\.1\.1 '${CVSROOT_DIRNAME}'/rcs4-dir/file1,v - Sticky Tag: (none) - Sticky Date: 2001\.10\.01\.00\.00\.00 - Sticky Options: (none)' - - if $keep; then - echo Keeping ${TESTDIR} and exiting due to --keep - exit 0 - fi - - cd ../.. - rm -r rcs4 - rm -rf ${CVSROOT_DIRNAME}/rcs4-dir - ;; - - - - rcs5) - # Some tests of the $Log keyword and log message without a trailing - # EOL. This used to look ugly and, in the worst case, could cause - # a seg fault due to a buffer overflow. - # - # Note that it should not be possible to create this situation via a - # CVS server (and any client), since the server itself inserts the - # trailing EOL onto log messages that are missing one. Still, we - # shouldn't segfault due to a corrupt RCS file and I think that a log - # message without the trailing EOL doesn't actually violate the RCS - # spec, though it doesn't appear to be possible to create such a log - # message using RCS 5.7. - - mkdir $CVSROOT_DIRNAME/rcs5 - cat <<\EOF >$CVSROOT_DIRNAME/rcs5/file1,v -head 1.1; -access; -symbols; -locks; -expand kv; - -1.1 date 2007.03.20.04.03.02; author jeremiah; state Ext; branches; next; - -desc -@@ - -1.1 -log -@he always had very fine wine@ -text -@line1 -/* -EOF -echo ' * Revision history: $''Log$' >>$CVSROOT_DIRNAME/rcs5/file1,v - cat <<\EOF >>$CVSROOT_DIRNAME/rcs5/file1,v - */ -line5 -@ -EOF - - mkdir rcs5 - cd rcs5 - dotest rcs5-1 "$testcvs -Q co rcs5" - dotest rcs5-2 "cat rcs5/file1" \ -"line1 -/\\* - \\* Revision history: "'\$'"Log: file1,v "'\$'" - \\* Revision history: Revision 1\.1 2007/03/20 04:03:02 jeremiah - \\* Revision history: he always had very fine wine - \\* Revision history: - \\*/ -line5" - - cd .. - rm -r rcs5 - rm -rf $CVSROOT_DIRNAME/rcs5 - ;; - - - - rcs6) - # Test that CVS notices a specific type of corruption in the RCS - # archive. In the past, this type of corruption had turned up after - # a user ineptly attempted to delete a revision from an arcvhive - # manually. - mkdir rcs6; cd rcs6 - - # Make the project. - dotest rcs6-init-1 "$testcvs -Q co -ld top .; cd top" - mkdir rcs6 - dotest rcs6-init-2 "$testcvs -Q add rcs6" - cd rcs6 - - # Populate it. - echo some words >afile - dotest rcs6-init-3 "$testcvs -Q add afile" - dotest rcs6-init-4 "$testcvs -Q ci -mnewfile afile" \ -"RCS file: $CVSROOT_DIRNAME/rcs6/afile,v -done -Checking in afile; -$CVSROOT_DIRNAME/rcs6/afile,v <-- afile -initial revision: 1\.1 -done" - echo more words >>afile - dotest rcs6-init-5 "$testcvs -Q ci -mrev2 afile" \ -"Checking in afile; -$CVSROOT_DIRNAME/rcs6/afile,v <-- afile -new revision: 1\.2; previous revision: 1\.1 -done" - - # Corrupt the archive. - sed -e '8,12d' \ - -e 's/^head 1\.2/head 1.1/' \ - <$CVSROOT_DIRNAME/rcs6/afile,v \ - >$CVSROOT_DIRNAME/rcs6/cfile,v - - # Update used to work. - dotest_fail rcs6-1 "$testcvs -q up" \ -"$PROG \[update aborted\]: Expected head revision 1\.1, found 1\.2\." - - # Then a commit hosed the archive further without any warnings. - # Updating to an old revision (e.g. 1.1) would have reported the - # corruption. A second commit would have deleted data from the - # file. - - if $keep; then - echo Keeping $TESTDIR and exiting due to --keep - exit 0 - fi - - cd ../../.. - rm -r rcs6 - rm -rf $CVSROOT_DIRNAME/rcs6 - ;; - - - - lockfiles) - # Tests of CVS lock files. - # TODO-maybe: Add a test where we arrange for a loginfo - # script (or some such) to ensure that locks are in place - # so then we can see how they are behaving. - - mkdir 1; cd 1 - mkdir sdir - mkdir sdir/ssdir - echo file >sdir/ssdir/file1 - dotest lockfiles-1 \ -"${testcvs} -Q import -m import-it first-dir bar baz" "" - cd .. - - mkdir 2; cd 2 - dotest lockfiles-2 "${testcvs} -q co first-dir" \ -"U first-dir/sdir/ssdir/file1" - dotest lockfiles-3 "${testcvs} -Q co CVSROOT" "" - cd CVSROOT - echo "LockDir=${TESTDIR}/locks" >config - dotest lockfiles-4 "${testcvs} -q ci -m config-it" \ -"Checking in config; -${CVSROOT_DIRNAME}/CVSROOT/config,v <-- config -new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* -done -${PROG} commit: Rebuilding administrative file database" - cd ../first-dir/sdir/ssdir - # The error message appears twice because Lock_Cleanup only - # stops recursing after the first attempt. - dotest_fail lockfiles-5 "${testcvs} -q update" \ -"${PROG} \[update aborted\]: cannot stat ${TESTDIR}/locks: No such file or directory -${PROG} \[update aborted\]: cannot stat ${TESTDIR}/locks: No such file or directory" - mkdir ${TESTDIR}/locks - # Grumble, mumble. Cygwin. - if test -n "$remotehost"; then - $CVS_RSH $remotehost "chmod u=rwx,g=r,o= ${TESTDIR}/locks" - else - chmod u=rwx,g=r,o= ${TESTDIR}/locks - fi - umask 0077 - CVSUMASK=0077; export CVSUMASK - dotest lockfiles-6 "${testcvs} -q update" "" - # TODO: should also be testing that CVS continues to honor the - # umask and CVSUMASK normally. In the case of the umask, CVS - # doesn't seem to use it for much (although it perhaps should). - dotest lockfiles-7 "ls ${TESTDIR}/locks/first-dir/sdir/ssdir" "" - - # The policy is that when CVS creates new lock directories, they - # inherit the permissions from the parent directory. CVSUMASK - # isn't right, because typically the reason for LockDir is to - # use a different set of permissions. - # - # Bah! Cygwin! - if test -n "$remotehost"; then - dotest lockfiles-7a "$CVS_RSH $remotehost 'ls -ld ${TESTDIR}/locks/first-dir'" \ -"drwxr-----.*first-dir" - dotest lockfiles-7b "$CVS_RSH $remotehost 'ls -ld ${TESTDIR}/locks/first-dir/sdir/ssdir'" \ -"drwxr-----.*first-dir/sdir/ssdir" - else - dotest lockfiles-7a "ls -ld ${TESTDIR}/locks/first-dir" \ -"drwxr-----.*first-dir" - dotest lockfiles-7b "ls -ld ${TESTDIR}/locks/first-dir/sdir/ssdir" \ -"drwxr-----.*first-dir/sdir/ssdir" - fi - - cd ../../.. - dotest lockfiles-8 "${testcvs} -q update" "" - dotest lockfiles-9 "${testcvs} -q co -l ." "" - - ### - ### There are race conditions in the following tests, but hopefully - ### the 5 seconds the first process waits to remove the lockdir and - ### the 30 seconds CVS waits betweens checks will be significant - ### enough to render the case moot. - ### - # Considers the following cases: - # - # Lock Present - # Operation Allowed (case #) - # - # Read Write - # _______ ______ - # Read |Yes (1) No (3) - # Write |No (7) No (9) - # - # Tests do not appear in same ordering as table. The odd numbering - # scheme maintains correspondance with a larger table on 1.12.x: - # 1. Read when read locks are present... - # 3. Don't read when write locks present... - # 7. Don't write when read locks are present... - # 9. Don't write when write locks are present... - - # 3. Don't read when write locks present... - mkdir "$TESTDIR/locks/first-dir/#cvs.lock" - (sleep 5; rmdir "$TESTDIR/locks/first-dir/#cvs.lock")& - dotest lockfiles-10 "$testcvs -q co -l first-dir" \ -"$PROG checkout: \[[0-9:]*\] waiting for $username's lock in $CVSROOT_DIRNAME/first-dir -$PROG checkout: \[[0-9:]*\] obtained lock in $CVSROOT_DIRNAME/first-dir" - - # 1. Read when read locks are present... - touch "$TESTDIR/locks/first-dir/#cvs.rfl.test.lock" - dotest lockfiles-11 "$testcvs -q co -l first-dir" - rm "$TESTDIR/locks/first-dir/#cvs.rfl.test.lock" - - # 7. Don't write when read locks are present... - echo I always have trouble coming up with witty text for the test files >>first-dir/sdir/ssdir/file1 - touch "$TESTDIR/locks/first-dir/sdir/ssdir/#cvs.rfl.test.lock" - (sleep 5; rm "$TESTDIR/locks/first-dir/sdir/ssdir/#cvs.rfl.test.lock")& - dotest lockfiles-13 "$testcvs -q ci -mconflict first-dir" \ -"$PROG commit: \[[0-9:]*\] waiting for $username's lock in $CVSROOT_DIRNAME/first-dir/sdir/ssdir -$PROG commit: \[[0-9:]*\] obtained lock in $CVSROOT_DIRNAME/first-dir/sdir/ssdir -Checking in first-dir/sdir/ssdir/file1; -$CVSROOT_DIRNAME/first-dir/sdir/ssdir/file1,v <-- file1 -new revision: 1\.2; previous revision: 1\.1 -done" - - # 9. Don't write when write locks are present... - echo yet this poem would probably only give longfellow bile >>first-dir/sdir/ssdir/file1 - mkdir "$TESTDIR/locks/first-dir/sdir/ssdir/#cvs.lock" - (sleep 5; rmdir "$TESTDIR/locks/first-dir/sdir/ssdir/#cvs.lock")& - dotest lockfiles-19 "$testcvs -q ci -mnot-up-to-date first-dir" \ -"$PROG commit: \[[0-9:]*\] waiting for $username's lock in $CVSROOT_DIRNAME/first-dir/sdir/ssdir -$PROG commit: \[[0-9:]*\] obtained lock in $CVSROOT_DIRNAME/first-dir/sdir/ssdir -Checking in first-dir/sdir/ssdir/file1; -$CVSROOT_DIRNAME/first-dir/sdir/ssdir/file1,v <-- file1 -new revision: 1\.3; previous revision: 1\.2 -done" - - # 10. Don't write when history locks are present... - echo have you ever heard a poem quite so vile\? >>first-dir/sdir/ssdir/file1 - mkdir "$TESTDIR/locks/CVSROOT/#cvs.history.lock" - (sleep 5; rmdir "$TESTDIR/locks/CVSROOT/#cvs.history.lock")& - dotest lockfiles-20 "$testcvs -q ci -mnot-up-to-date first-dir" \ -"Checking in first-dir/sdir/ssdir/file1; -$CVSROOT_DIRNAME/first-dir/sdir/ssdir/file1,v <-- file1 -new revision: 1\.4; previous revision: 1\.3 -done -$PROG commit: \[[0-9:]*\] waiting for $username's lock in $CVSROOT_DIRNAME/CVSROOT -$PROG commit: \[[0-9:]*\] obtained lock in $CVSROOT_DIRNAME/CVSROOT" - - dotest lockfiles-21 "$testcvs -Q tag newtag first-dir" - - rm -f $CVSROOT_DIRNAME/CVSROOT/val-tags - mkdir "$TESTDIR/locks/CVSROOT/#cvs.val-tags.lock" - (sleep 5; rmdir "$TESTDIR/locks/CVSROOT/#cvs.val-tags.lock")& - dotest lockfiles-22 "$testcvs -q up -r newtag first-dir" \ -"$PROG update: \[[0-9:]*\] waiting for $username's lock in $CVSROOT_DIRNAME/CVSROOT -$PROG update: \[[0-9:]*\] obtained lock in $CVSROOT_DIRNAME/CVSROOT -[UP] first-dir/sdir/ssdir/file1" - - cd CVSROOT - echo "# nobody here but us comments" >config - dotest lockfiles-cleanup-1 "${testcvs} -q ci -m config-it" \ -"Checking in config; -${CVSROOT_DIRNAME}/CVSROOT/config,v <-- config -new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* -done -${PROG} commit: Rebuilding administrative file database" - cd ../.. - # Perhaps should restore the umask and CVSUMASK to what they - # were before. But the other tests "should" not care about them... - umask 0077 - unset CVSUMASK - rm -r ${TESTDIR}/locks - rm -r 1 2 - rm -rf ${CVSROOT_DIRNAME}/first-dir - ;; - - backuprecover) - # Tests to make sure we get the expected behavior - # when we recover a repository from an old backup - # - # Details: - # Backup will be older than some developer's workspaces - # This means the first attempt at an update will fail - # The workaround for this is to replace the CVS - # directories with those from a "new" checkout from - # the recovered repository. Due to this, multiple - # merges should cause conflicts (the same data - # will be merged more than once). - # A workspace updated before the date of the recovered - # copy will not need any extra attention - # - # Note that backuprecover-15 is probably a failure case - # If nobody else had a more recent update, the data would be lost - # permanently - # Granted, the developer should have been notified not to do this - # by now, but still... - # - mkdir backuprecover; cd backuprecover - mkdir 1; cd 1 - dotest backuprecover-1 "${testcvs} -q co -l ." '' - mkdir first-dir - dotest backuprecover-2 "${testcvs} add first-dir" \ -"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" - cd first-dir - mkdir dir - dotest backuprecover-3 "${testcvs} add dir" \ -"Directory ${CVSROOT_DIRNAME}/first-dir/dir added to the repository" - touch file1 dir/file2 - dotest backuprecover-4 "${testcvs} -q add file1 dir/file2" \ -"${PROG} add: use .${PROG} commit. to add these files permanently" - dotest backuprecover-5 "${testcvs} -q ci -mtest" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -done -Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -initial revision: 1\.1 -done -RCS file: ${CVSROOT_DIRNAME}/first-dir/dir/file2,v -done -Checking in dir/file2; -${CVSROOT_DIRNAME}/first-dir/dir/file2,v <-- file2 -initial revision: 1\.1 -done" - echo "Line one" >>file1 - echo " is the place" >>file1 - echo " we like to begin" >>file1 - echo "Anything else" >>file1 - echo " looks like" >>file1 - echo " a sin" >>file1 - echo "File 2" >>dir/file2 - echo " is the place" >>dir/file2 - echo " the rest of it goes" >>dir/file2 - echo "Why I don't use" >>dir/file2 - echo " something like 'foo'" >>dir/file2 - echo " God only knows" >>dir/file2 - dotest backuprecover-6 "${testcvs} -q ci -mtest" \ -"Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -new revision: 1\.2; previous revision: 1\.1 -done -Checking in dir/file2; -${CVSROOT_DIRNAME}/first-dir/dir/file2,v <-- file2 -new revision: 1\.2; previous revision: 1\.1 -done" - - # Simulate the lazy developer - # (he did some work but didn't check it in...) - cd ../.. - mkdir 2; cd 2 - dotest backuprecover-7 "${testcvs} -Q co first-dir" '' - cd first-dir - sed -e "s/looks like/just looks like/" file1 >tmp; mv tmp file1 - sed -e "s/don't use/don't just use/" dir/file2 >tmp; mv tmp dir/file2 - - # developer 1 is on a roll - cd ../../1/first-dir - echo "I need some more words" >>file1 - echo " to fill up this space" >>file1 - echo " anything else would be a disgrace" >>file1 - echo "My rhymes cross many boundries" >>dir/file2 - echo " this time it's files" >>dir/file2 - echo " a word that fits here would be something like dials" >>dir/file2 - dotest backuprecover-8 "${testcvs} -q ci -mtest" \ -"Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -new revision: 1\.3; previous revision: 1\.2 -done -Checking in dir/file2; -${CVSROOT_DIRNAME}/first-dir/dir/file2,v <-- file2 -new revision: 1\.3; previous revision: 1\.2 -done" - - # Save a backup copy - cp -r ${CVSROOT_DIRNAME}/first-dir ${CVSROOT_DIRNAME}/backup - - # Simulate developer 3 - cd ../.. - mkdir 3; cd 3 - dotest backuprecover-9a "${testcvs} -Q co first-dir" '' - cd first-dir - echo >>file1 - echo >>dir/file2 - echo "Developer 1 makes very lame rhymes" >>file1 - echo " I think he should quit and become a mime" >>file1 - echo "What the %*^# kind of rhyme crosses a boundry?" >>dir/file2 - echo " I think you should quit and get a job in the foundry" >>dir/file2 - dotest backuprecover-9b "${testcvs} -q ci -mtest" \ -"Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -new revision: 1\.4; previous revision: 1\.3 -done -Checking in dir/file2; -${CVSROOT_DIRNAME}/first-dir/dir/file2,v <-- file2 -new revision: 1\.4; previous revision: 1\.3 -done" - - # Developer 4 so we can simulate a conflict later... - cd ../.. - mkdir 4; cd 4 - dotest backuprecover-10 "${testcvs} -Q co first-dir" '' - cd first-dir - sed -e "s/quit and/be fired so he can/" dir/file2 >tmp; mv tmp dir/file2 - - # And back to developer 1 - cd ../../1/first-dir - dotest backuprecover-11 "${testcvs} -Q update" '' - echo >>file1 - echo >>dir/file2 - echo "Oh yeah, well rhyme this" >>file1 - echo " developer three" >>file1 - echo " you want opposition" >>file1 - echo " you found some in me!" >>file1 - echo "I'll give you mimes" >>dir/file2 - echo " and foundries galore!" >>dir/file2 - echo " your head will spin" >>dir/file2 - echo " once you find what's in store!" >>dir/file2 - dotest backuprecover-12 "${testcvs} -q ci -mtest" \ -"Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -new revision: 1\.5; previous revision: 1\.4 -done -Checking in dir/file2; -${CVSROOT_DIRNAME}/first-dir/dir/file2,v <-- file2 -new revision: 1\.5; previous revision: 1\.4 -done" - - # developer 3'll do a bit of work that never gets checked in - cd ../../3/first-dir - dotest backuprecover-13 "${testcvs} -Q update" '' - sed -e "s/very/some extremely/" file1 >tmp; mv tmp file1 - dotest backuprecover-14 "${testcvs} -q ci -mtest" \ -"Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -new revision: 1\.6; previous revision: 1\.5 -done" - echo >>file1 - echo "Tee hee hee hee" >>file1 - echo >>dir/file2 - echo "Find what's in store?" >>dir/file2 - echo " Oh, I'm so sure!" >>dir/file2 - echo " You've got an ill, and I have the cure!" >>dir/file2 - - # Slag the original and restore it a few revisions back - rm -rf ${CVSROOT_DIRNAME}/first-dir - mv ${CVSROOT_DIRNAME}/backup ${CVSROOT_DIRNAME}/first-dir - - # Have developer 1 try an update and lose some data - # - # Feel free to imagine the horrific scream of despair - cd ../../1/first-dir - dotest backuprecover-15 "${testcvs} update" \ -"${PROG} update: Updating . -U file1 -${PROG} update: Updating dir -U dir/file2" - - # Developer 3 tries the same thing (he has an office) - # but fails without losing data since all of his files have - # uncommitted changes - cd ../../3/first-dir - dotest_fail backuprecover-16 "${testcvs} update" \ -"${PROG} update: Updating \. -${PROG} \[update aborted\]: could not find desired version 1\.6 in ${CVSROOT_DIRNAME}/first-dir/file1,v" - - # create our workspace fixin' script - cd ../.. - echo \ -"#!/bin/sh - -# This script will copy the CVS database dirs from the checked out -# version of a newly recovered repository and replace the CVS -# database dirs in a workspace with later revisions than those in the -# recovered repository -cd repos-first-dir -DATADIRS=\`find . -name CVS -print\` -cd ../first-dir -find . -name CVS -print | xargs rm -rf -for file in \${DATADIRS}; do - cp -r ../repos-first-dir/\${file} \${file} -done" >fixit - - # We only need to fix the workspaces of developers 3 and 4 - # (1 lost all her data and 2 has an update date from - # before the date the backup was made) - cd 3 - dotest backuprecover-17 \ - "${testcvs} -Q co -d repos-first-dir first-dir" '' - cd ../4 - dotest backuprecover-18 \ - "${testcvs} -Q co -d repos-first-dir first-dir" '' - sh ../fixit - cd ../3; sh ../fixit - - # (re)commit developer 3's stuff - cd first-dir - dotest backuprecover-19 "${testcvs} -q ci -mrecover/merge" \ -"Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -new revision: 1\.4; previous revision: 1\.3 -done -Checking in dir/file2; -${CVSROOT_DIRNAME}/first-dir/dir/file2,v <-- file2 -new revision: 1\.4; previous revision: 1\.3 -done" - - # and we should get a conflict on developer 4's stuff - cd ../../4/first-dir - dotest backuprecover-20 "${testcvs} update" \ -"${PROG} update: Updating \. -RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -retrieving revision 1\.3 -retrieving revision 1\.4 -Merging differences between 1\.3 and 1\.4 into file1 -rcsmerge: warning: conflicts during merge -${PROG} update: conflicts found in file1 -C file1 -${PROG} update: Updating dir -RCS file: ${CVSROOT_DIRNAME}/first-dir/dir/file2,v -retrieving revision 1\.3 -retrieving revision 1\.4 -Merging differences between 1\.3 and 1\.4 into file2 -rcsmerge: warning: conflicts during merge -${PROG} update: conflicts found in dir/file2 -C dir/file2" - sed -e \ -"/^<<<<<<>>>>>>/d" file1 >tmp; mv tmp file1 - sed -e \ -"/^<<<<<<>>>>>>/d -s/quit and/be fired so he can/" dir/file2 >tmp; mv tmp dir/file2 - dotest backuprecover-21 "${testcvs} -q ci -mrecover/merge" \ -"Checking in dir/file2; -${CVSROOT_DIRNAME}/first-dir/dir/file2,v <-- file2 -new revision: 1\.5; previous revision: 1\.4 -done" - - # go back and commit developer 2's stuff to prove it can still be done - cd ../../2/first-dir - dotest backuprecover-22 "${testcvs} -Q update" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -retrieving revision 1\.2 -retrieving revision 1\.4 -Merging differences between 1\.2 and 1\.4 into file1 -RCS file: ${CVSROOT_DIRNAME}/first-dir/dir/file2,v -retrieving revision 1\.2 -retrieving revision 1\.5 -Merging differences between 1\.2 and 1\.5 into file2" - dotest backuprecover-23 "${testcvs} -q ci -mtest" \ -"Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -new revision: 1\.5; previous revision: 1\.4 -done -Checking in dir/file2; -${CVSROOT_DIRNAME}/first-dir/dir/file2,v <-- file2 -new revision: 1\.6; previous revision: 1\.5 -done" - - # and restore the data to developer 1 - cd ../../1/first-dir - dotest backuprecover-24 "${testcvs} -Q update" '' - - cd ../../.. - rm -r backuprecover - rm -rf ${CVSROOT_DIRNAME}/first-dir - ;; - - - - sshstdio) - # CVS_RSH=ssh can have a problem with a non-blocking stdio - # in some cases. So, this test is all about testing :ext: - # with CVS_RSH=ssh. The problem is that not all machines - # will necessarily have ssh available, so be prepared to - # skip this test. - - # Are we able to run find and use an ssh? - if $remote; then :; else - continue - fi - - depends_on_ssh - if test $? -eq 77; then - skip sshstdio "$skipreason" - continue - fi - - SSHSTDIO_ROOT=:ext:$host$CVSROOT_DIRNAME - - mkdir sshstdio; cd sshstdio - dotest sshstdio-1 "$testcvs -d $SSHSTDIO_ROOT -q co -l ." - mkdir first-dir - dotest sshstdio-2 "$testcvs add first-dir" \ - "Directory $CVSROOT_DIRNAME/first-dir added to the repository" - cd first-dir - a='aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' - c='aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' - # Generate 1024 lines of $a - cnt=0 - echo $a > aaa - while [ $cnt -lt 5 ] ; do - cnt=`expr $cnt + 1` ; - mv aaa aaa.old - cat aaa.old aaa.old aaa.old aaa.old > aaa - done - dotest sshstdio-3 "$testcvs -q add aaa" \ -"$PROG add: use .$PROG commit. to add this file permanently" - dotest sshstdio-4 "$testcvs -q ci -mcreate aaa" \ -"RCS file: $CVSROOT_DIRNAME/first-dir/aaa,v -done -Checking in aaa; -$CVSROOT_DIRNAME/first-dir/aaa,v <-- aaa -initial revision: 1\.1 -done" - # replace lines 1, 512, 513, 1024 with $c - sed 510q < aaa > aaa.old - (echo $c; cat aaa.old; echo $c; \ - echo $c; cat aaa.old; echo $c) > aaa - dotest sshstdio-5 "$testcvs -q ci -mmodify-it aaa" \ -"Checking in aaa; -$CVSROOT_DIRNAME/first-dir/aaa,v <-- aaa -new revision: 1\.2; previous revision: 1\.1 -done" - cat > wrapper.sh <&1 < /dev/null | cat -EOF - chmod +x wrapper.sh - ./wrapper.sh \ - $testcvs -z5 -Q diff --side-by-side -W 500 -r 1.1 -r 1.2 \ - aaa \ - |sed -e \ -'/^Write failed flushing stdout buffer\. $/d; - /^write stdout: Broken pipe $/d; - :retry; - /Write failed flushing stdout buffer\. $/{ - N; - s/Write failed flushing stdout buffer\. \n//; - b retry; -} - /write stdout: Broken pipe $/{ - N; - s/write stdout: Broken pipe \n//; - b retry; -}' \ - > wrapper.dif - - $testcvs -z5 -Q diff --side-by-side -W 500 -r 1.1 -r 1.2 \ - aaa > good.dif - - dotest sshstdio-6 "cmp wrapper.dif good.dif" - - if $keep; then - echo Keeping $TESTDIR and exiting due to --keep - exit 0 - fi - - cd ../.. - CVS_RSH=$save_CVS_RSH; export CVS_RSH - rm -r sshstdio - rm -rf $CVSROOT_DIRNAME/first-dir - ;; - - - - parseroot2) - # Test some :ext: roots for consistancy. - if $remote; then :; else - continue - fi - - depends_on_rsh "$CVS_RSH" - if test $? -eq 77; then - skip parseroot2 "$skipreason" - continue - fi - - # Test checking out and subsequently updating with some different - # CVSROOTs. - - # A standard case, hostname:dirname. - mkdir parseroot2; cd parseroot2 - save_CVSROOT=$CVSROOT - CVSROOT=$host:$CVSROOT_DIRNAME - dotest parseroot2-1 "$testcvs -Q co CVSROOT" - cd CVSROOT - dotest parseroot2-2 "$testcvs -Q up" - cd .. - - # A degenerate remote case, just the server name and the directory - # name, with no :'s to help parsing. It can be mistaken for a - # relative directory name. - rm -r CVSROOT - CVSROOT=$host$CVSROOT_DIRNAME - dotest parseroot2-3 "$testcvs -Q co CVSROOT" - cd CVSROOT - dotest parseroot2-4 "$testcvs -Q up" - - if $keep; then - echo Keeping $TESTDIR and exiting due to --keep - exit 0 - fi - - cd ../.. - CVSROOT=$save_CVSROOT - rm -r parseroot2 - ;; - - - - history) - # CVSROOT/history tests: - # history: various "cvs history" invocations - # basic2: Generating the CVSROOT/history file via CVS commands. - - # Put in some data for the history file (discarding what was - # there before). Note that this file format is fixed; the - # user may wish to analyze data from a previous version of - # CVS. If we phase out this format, it should be done - # slowly and carefully. - cat >${CVSROOT_DIRNAME}/CVSROOT/history </*0|ccvs||ccvs -O3396c677|anonymous|/src|ccvs||src -O3397c677|kingdon|/*0|ccvs||ccvs -M339cafae|nk||ccvs/src|1.229|sanity.sh -M339cafff|anonymous||ccvs/src|1.23|Makefile -M339dc339|kingdon|~/work/*0|ccvs/src|1.231|sanity.sh -W33a6eada|anonymous|*4|ccvs/emx||Makefile.in -C3b235f50|kingdon||ccvs/emx|1.3|README -M3b23af50|kingdon|~/work/*0|ccvs/doc|1.281|cvs.texinfo -EOF - dotest history-1 "${testcvs} history -e -a" \ -"O 1997-06-04 19:48 ${PLUS}0000 anonymous ccvs =ccvs= /\* -O 1997-06-05 14:00 ${PLUS}0000 anonymous ccvs =src= /\* -M 1997-06-10 01:38 ${PLUS}0000 anonymous 1\.23 Makefile ccvs/src == -W 1997-06-17 19:51 ${PLUS}0000 anonymous Makefile\.in ccvs/emx == /emx -O 1997-06-06 08:12 ${PLUS}0000 kingdon ccvs =ccvs= /\* -M 1997-06-10 21:12 ${PLUS}0000 kingdon 1\.231 sanity\.sh ccvs/src == ~/work/ccvs/src -C 2001-06-10 11:51 ${PLUS}0000 kingdon 1\.3 README ccvs/emx == -M 2001-06-10 17:33 ${PLUS}0000 kingdon 1\.281 cvs\.texinfo ccvs/doc == ~/work/ccvs/doc -M 1997-06-10 01:36 ${PLUS}0000 nk 1\.229 sanity\.sh ccvs/src == " - - dotest history-2 "${testcvs} history -e -a -D '10 Jun 1997 13:00 UT'" \ -"W 1997-06-17 19:51 ${PLUS}0000 anonymous Makefile\.in ccvs/emx == /emx -M 1997-06-10 21:12 ${PLUS}0000 kingdon 1\.231 sanity\.sh ccvs/src == ~/work/ccvs/src -C 2001-06-10 11:51 ${PLUS}0000 kingdon 1\.3 README ccvs/emx == -M 2001-06-10 17:33 ${PLUS}0000 kingdon 1\.281 cvs\.texinfo ccvs/doc == ~/work/ccvs/doc" - - dotest history-3 "${testcvs} history -e -a -D '10 Jun 2001 13:00 UT'" \ -"M 2001-06-10 17:33 ${PLUS}0000 kingdon 1\.281 cvs\.texinfo ccvs/doc == ~/work/ccvs/doc" - - dotest history-4 "${testcvs} history -ac sanity.sh" \ -"M 1997-06-10 21:12 ${PLUS}0000 kingdon 1\.231 sanity\.sh ccvs/src == ~/work/ccvs/src -M 1997-06-10 01:36 ${PLUS}0000 nk 1\.229 sanity\.sh ccvs/src == " - - dotest history-5 "${testcvs} history -a -xCGUWAMR README sanity.sh" \ -"M 1997-06-10 21:12 ${PLUS}0000 kingdon 1\.231 sanity\.sh ccvs/src == ~/work/ccvs/src -C 2001-06-10 11:51 ${PLUS}0000 kingdon 1\.3 README ccvs/emx == -M 1997-06-10 01:36 ${PLUS}0000 nk 1\.229 sanity\.sh ccvs/src == " - - dotest history-6 "${testcvs} history -xCGUWAMR -a -f README -f sanity.sh" \ -"M 1997-06-10 21:12 ${PLUS}0000 kingdon 1\.231 sanity\.sh ccvs/src == ~/work/ccvs/src -C 2001-06-10 11:51 ${PLUS}0000 kingdon 1\.3 README ccvs/emx == -M 1997-06-10 01:36 ${PLUS}0000 nk 1\.229 sanity\.sh ccvs/src == " - - dotest history-7 "${testcvs} history -xCGUWAMR -a -f sanity.sh README" \ -"M 1997-06-10 21:12 ${PLUS}0000 kingdon 1\.231 sanity\.sh ccvs/src == ~/work/ccvs/src -C 2001-06-10 11:51 ${PLUS}0000 kingdon 1\.3 README ccvs/emx == -M 1997-06-10 01:36 ${PLUS}0000 nk 1\.229 sanity\.sh ccvs/src == " - - dotest history-8 "${testcvs} history -ca -D '1970-01-01 00:00 UT'" \ -"M 1997-06-10 01:36 ${PLUS}0000 nk 1\.229 sanity.sh ccvs/src == -M 1997-06-10 01:38 ${PLUS}0000 anonymous 1\.23 Makefile ccvs/src == -M 1997-06-10 21:12 ${PLUS}0000 kingdon 1\.231 sanity.sh ccvs/src == ~/work/ccvs/src -M 2001-06-10 17:33 ${PLUS}0000 kingdon 1\.281 cvs.texinfo ccvs/doc == ~/work/ccvs/doc" - - dotest history-9 "${testcvs} history -acl" \ -"M 2001-06-10 17:33 ${PLUS}0000 kingdon 1\.281 cvs.texinfo ccvs/doc == ~/work/ccvs/doc -M 1997-06-10 01:38 ${PLUS}0000 anonymous 1\.23 Makefile ccvs/src == -M 1997-06-10 21:12 ${PLUS}0000 kingdon 1\.231 sanity.sh ccvs/src == ~/work/ccvs/src" - - dotest history-10 "${testcvs} history -lca -D '1970-01-01 00:00 UT'" \ -"M 2001-06-10 17:33 ${PLUS}0000 kingdon 1\.281 cvs.texinfo ccvs/doc == ~/work/ccvs/doc -M 1997-06-10 01:38 ${PLUS}0000 anonymous 1\.23 Makefile ccvs/src == -M 1997-06-10 21:12 ${PLUS}0000 kingdon 1\.231 sanity.sh ccvs/src == ~/work/ccvs/src" - - dotest history-11 "${testcvs} history -aw" \ -"O 1997-06-04 19:48 ${PLUS}0000 anonymous ccvs =ccvs= /\* -O 1997-06-05 14:00 ${PLUS}0000 anonymous ccvs =src= /\* -O 1997-06-06 08:12 ${PLUS}0000 kingdon ccvs =ccvs= /\*" - - dotest history-12 "${testcvs} history -aw -D'1970-01-01 00:00 UT'" \ -"O 1997-06-04 19:48 ${PLUS}0000 anonymous ccvs =ccvs= /\* -O 1997-06-05 14:00 ${PLUS}0000 anonymous ccvs =src= /\* -O 1997-06-06 08:12 ${PLUS}0000 kingdon ccvs =ccvs= /\*" - ;; - - big) - - # Test ability to operate on big files. Intention is to - # test various realloc'ing code in RCS_deltas, rcsgetkey, - # etc. "big" is currently defined to be 1000 lines (64000 - # bytes), which in terms of files that users will use is not - # large, merely average, but my reasoning is that this - # should be big enough to make sure realloc'ing is going on - # and that raising it a lot would start to stress resources - # on machines which run the tests, without any significant - # benefit. - - mkdir ${CVSROOT_DIRNAME}/first-dir - dotest big-1 "${testcvs} -q co first-dir" '' - cd first-dir - for i in 0 1 2 3 4 5 6 7 8 9; do - for j in 0 1 2 3 4 5 6 7 8 9; do - for k in 0 1 2 3 4 5 6 7 8 9; do - echo \ -"This is line ($i,$j,$k) which goes into the file file1 for testing" >>file1 - done - done - done - dotest big-2 "${testcvs} add file1" \ -"${PROG} add: scheduling file .file1. for addition -${PROG} add: use .${PROG} commit. to add this file permanently" - dotest big-3 "${testcvs} -q ci -m add" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -done -Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -initial revision: 1\.1 -done" - cd .. - mkdir 2 - cd 2 - dotest big-4 "${testcvs} -q get first-dir" "U first-dir/file1" - cd ../first-dir - echo "add a line to the end" >>file1 - dotest big-5 "${testcvs} -q ci -m modify" \ -"Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -new revision: 1\.2; previous revision: 1\.1 -done" - cd ../2/first-dir - # The idea here is particularly to test the Rcs-diff response - # and the reallocing thereof, for remote. - dotest big-6 "${testcvs} -q update" "[UP] file1" - cd ../.. - - if $keep; then - echo Keeping ${TESTDIR} and exiting due to --keep - exit 0 - fi - - rm -r first-dir 2 - rm -rf ${CVSROOT_DIRNAME}/first-dir - ;; - - modes) - # Test repository permissions (CVSUMASK and so on). - # Although the tests in this section "cheat" by testing - # repository permissions, which are sort of not a user-visible - # sort of thing, the modes do have user-visible consequences, - # such as whether a second user can check out the files. But - # it would be awkward to test the consequences, so we don't. - - # Solaris /bin/sh doesn't support export -n. I'm not sure - # what we can do about this, other than hope that whoever - # is running the tests doesn't have CVSUMASK set. - #export -n CVSUMASK # if unset, defaults to 002 - - umask 077 - mkdir 1; cd 1 - dotest modes-1 "${testcvs} -q co -l ." '' - mkdir first-dir - dotest modes-2 "${testcvs} add first-dir" \ -"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" - cd first-dir - touch aa - dotest modes-3 "${testcvs} add aa" \ -"${PROG} add: scheduling file .aa. for addition -${PROG} add: use .${PROG} commit. to add this file permanently" - dotest modes-4 "${testcvs} -q ci -m add" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/aa,v -done -Checking in aa; -${CVSROOT_DIRNAME}/first-dir/aa,v <-- aa -initial revision: 1\.1 -done" - # Yawn. Cygwin. - if test -n "$remotehost"; then - dotest modes-5remotehost "$CVS_RSH $remotehost 'ls -l ${CVSROOT_DIRNAME}/first-dir/aa,v'" \ -"-r--r--r-- .*" - else - dotest modes-5 "ls -l ${CVSROOT_DIRNAME}/first-dir/aa,v" \ -"-r--r--r-- .*" - fi - - # Test for whether we can set the execute bit. - chmod +x aa - echo change it >>aa - dotest modes-6 "${testcvs} -q ci -m set-execute-bit" \ -"Checking in aa; -${CVSROOT_DIRNAME}/first-dir/aa,v <-- aa -new revision: 1\.2; previous revision: 1\.1 -done" - # If CVS let us update the execute bit, it would be set here. - # But it doesn't, and as far as I know that is longstanding - # CVS behavior. - # - # Yeah, yeah. Search for "Cygwin". - if test -n "$remotehost"; then - dotest modes-7remotehost "$CVS_RSH $remotehost 'ls -l ${CVSROOT_DIRNAME}/first-dir/aa,v'" \ -"-r--r--r-- .*" - else - dotest modes-7 "ls -l ${CVSROOT_DIRNAME}/first-dir/aa,v" \ -"-r--r--r-- .*" - fi - - # OK, now manually change the modes and see what happens. - # - # Cygwin, already. - if test -n "$remotehost"; then - $CVS_RSH $remotehost "chmod g=r,o= ${CVSROOT_DIRNAME}/first-dir/aa,v" - else - chmod g=r,o= ${CVSROOT_DIRNAME}/first-dir/aa,v - fi - echo second line >>aa - dotest modes-7a "${testcvs} -q ci -m set-execute-bit" \ -"Checking in aa; -${CVSROOT_DIRNAME}/first-dir/aa,v <-- aa -new revision: 1\.3; previous revision: 1\.2 -done" - # Cygwin. - if test -n "$remotehost"; then - dotest modes-7bremotehost "$CVS_RSH $remotehost 'ls -l ${CVSROOT_DIRNAME}/first-dir/aa,v'" \ -"-r--r----- .*" - else - dotest modes-7b "ls -l ${CVSROOT_DIRNAME}/first-dir/aa,v" \ -"-r--r----- .*" - fi - - CVSUMASK=007 - export CVSUMASK - touch ab - # Might as well test the execute bit too. - chmod +x ab - dotest modes-8 "${testcvs} add ab" \ -"${PROG} add: scheduling file .ab. for addition -${PROG} add: use .${PROG} commit. to add this file permanently" - dotest modes-9 "${testcvs} -q ci -m add" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/ab,v -done -Checking in ab; -${CVSROOT_DIRNAME}/first-dir/ab,v <-- ab -initial revision: 1\.1 -done" - if $remote; then - # The problem here is that the CVSUMASK environment variable - # needs to be set on the server (e.g. .bashrc). This is, of - # course, bogus, but that is the way it is currently. - if test -n "$remotehost"; then - dotest modes-10remotehost "$CVS_RSH $remotehost 'ls -l ${CVSROOT_DIRNAME}/first-dir/ab,v'" \ -"-r--r--r--.*" - else - dotest modes-10r "ls -l ${CVSROOT_DIRNAME}/first-dir/ab,v" \ -"-r-xr-x---.*" "-r-xr-xr-x.*" - fi - else - dotest modes-10 "ls -l ${CVSROOT_DIRNAME}/first-dir/ab,v" \ -"-r-xr-x---.*" - fi - - # OK, now add a file on a branch. Check that the mode gets - # set the same way (it is a different code path in CVS). - dotest modes-11 "${testcvs} -q tag -b br" 'T aa -T ab' - dotest modes-12 "$testcvs -q update -r br" \ -'[UP] aa -U ab' - touch ac - dotest modes-13 "${testcvs} add ac" \ -"${PROG} add: scheduling file .ac. for addition on branch .br. -${PROG} add: use .${PROG} commit. to add this file permanently" - # Not sure it really makes sense to refer to a "previous revision" - # when we are just now adding the file; as far as I know - # that is longstanding CVS behavior, for what it's worth. - dotest modes-14 "${testcvs} -q ci -m add" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/Attic/ac,v -done -Checking in ac; -${CVSROOT_DIRNAME}/first-dir/Attic/ac,v <-- ac -new revision: 1\.1\.2\.1; previous revision: 1\.1 -done" - if $remote; then - # The problem here is that the CVSUMASK environment variable - # needs to be set on the server (e.g. .bashrc). This is, of - # course, bogus, but that is the way it is currently. The - # first match is for the :ext: method (where the CVSUMASK - # won't be set), while the second is for the :fork: method - # (where it will be). - if test -n "$remotehost"; then - dotest modes-15r \ -"$CVS_RSH $remotehost 'ls -l ${CVSROOT_DIRNAME}/first-dir/Attic/ac,v'" \ -"-r--r--r--.*" - else - dotest modes-15r \ -"ls -l ${CVSROOT_DIRNAME}/first-dir/Attic/ac,v" \ -"-r--r--r--.*" "-r--r-----.*" - fi - else - dotest modes-15 \ -"ls -l ${CVSROOT_DIRNAME}/first-dir/Attic/ac,v" \ -"-r--r-----.*" - fi - - cd ../.. - rm -r 1 - rm -rf ${CVSROOT_DIRNAME}/first-dir - # Perhaps should restore the umask and CVSUMASK. But the other - # tests "should" not care about them... - ;; - - modes2) - # More tests of file permissions in the working directory - # and that sort of thing. - - # The usual setup, file first-dir/aa with two revisions. - mkdir 1; cd 1 - dotest modes2-1 "${testcvs} -q co -l ." '' - mkdir first-dir - dotest modes2-2 "${testcvs} add first-dir" \ -"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" - cd first-dir - touch aa - dotest modes2-3 "${testcvs} add aa" \ -"${PROG} add: scheduling file .aa. for addition -${PROG} add: use .${PROG} commit. to add this file permanently" - dotest modes2-4 "${testcvs} -q ci -m add" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/aa,v -done -Checking in aa; -${CVSROOT_DIRNAME}/first-dir/aa,v <-- aa -initial revision: 1\.1 -done" - echo "more money" >> aa - dotest modes2-5 "${testcvs} -q ci -m add" \ -"Checking in aa; -${CVSROOT_DIRNAME}/first-dir/aa,v <-- aa -new revision: 1\.2; previous revision: 1\.1 -done" - - # OK, here is the test. The idea is to see what - # No_Difference does if it can't open the file. - # If we don't change the st_mtime, CVS doesn't even try to read - # the file. Note that some versions of "touch" require that we - # do this while the file is still writable. - touch aa - chmod a= aa - # Don't try this when permissions are broken, as with Cygwin. - if ls ${CVSROOT_DIRNAME}/first-dir >/dev/null 2>&1; then :; else - dotest_fail modes2-6 "${testcvs} -q update -r 1.1 aa" \ -"${PROG} \[update aborted\]: cannot open file aa for comparing: Permission denied" \ -"${PROG} \[update aborted\]: reading aa: Permission denied" - fi - - chmod u+rwx aa - cd ../.. - rm -r 1 - rm -rf ${CVSROOT_DIRNAME}/first-dir - ;; - - modes3) - # Repository permissions. Particularly, what happens if we - # can't read/write in the repository. - # TODO: the case where we can access the repository, just not - # the attic (may that one can remain a fatal error, seems less - # useful for access control). - mkdir 1; cd 1 - dotest modes3-1 "${testcvs} -q co -l ." '' - mkdir first-dir second-dir - dotest modes3-2 "${testcvs} add first-dir second-dir" \ -"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository -Directory ${CVSROOT_DIRNAME}/second-dir added to the repository" - touch first-dir/aa second-dir/ab - dotest modes3-3 "${testcvs} add first-dir/aa second-dir/ab" \ -"${PROG} add: scheduling file .first-dir/aa. for addition -${PROG} add: scheduling file .second-dir/ab. for addition -${PROG} add: use .${PROG} commit. to add these files permanently" - dotest modes3-4 "${testcvs} -q ci -m add" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/aa,v -done -Checking in first-dir/aa; -${CVSROOT_DIRNAME}/first-dir/aa,v <-- aa -initial revision: 1\.1 -done -RCS file: ${CVSROOT_DIRNAME}/second-dir/ab,v -done -Checking in second-dir/ab; -${CVSROOT_DIRNAME}/second-dir/ab,v <-- ab -initial revision: 1\.1 -done" - if test -n "$remotehost"; then - $CVS_RSH $remotehost "chmod a= ${CVSROOT_DIRNAME}/first-dir" - else - chmod a= ${CVSROOT_DIRNAME}/first-dir - fi - if ls ${CVSROOT_DIRNAME}/first-dir >/dev/null 2>&1; then - # Avoid this test under Cygwin since permissions work differently - # there. - # - # This test also gets avoided under Mac OS X since the system `ls' - # is broken and exits with a 0 status despite the permission - # denied error. - if test -n "$remotehost"; then - cygwin_hack=false - else - cygwin_hack=: - fi - else - cygwin_hack=false - fi - - cd $TESTDIR/1 - if $cygwin_hack; then :; else - dotest modes3-5 "${testcvs} update" \ -"${PROG} update: Updating \. -${PROG} update: Updating first-dir -${PROG} update: cannot open directory ${CVSROOT_DIRNAME}/first-dir: Permission denied -${PROG} update: skipping directory first-dir -${PROG} update: Updating second-dir" - fi - - # OK, I can see why one might say the above case could be a - # fatal error, because normally users without access to first-dir - # won't have it in their working directory. But the next - # one is more of a problem if it is fatal. - # - # The second text string below is for Cygwin again, and again it - # should really be XFAIL under Cygwin, but for now deal with the - # passing opendir by accepting the alternate string. - rm -r first-dir - dotest modes3-6 "${testcvs} update -dP" \ -"${PROG} update: Updating . -${PROG} update: Updating CVSROOT -U ${DOTSTAR} -${PROG} update: Updating first-dir -${PROG} update: cannot open directory ${CVSROOT_DIRNAME}/first-dir: Permission denied -${PROG} update: skipping directory first-dir -${PROG} update: Updating second-dir" \ -"${PROG} update: Updating . -${PROG} update: Updating CVSROOT -U ${DOTSTAR} -${PROG} update: Updating first-dir -${PROG} update: Updating second-dir" - - cd .. - rm -r 1 - chmod u+rwx ${CVSROOT_DIRNAME}/first-dir - rm -rf ${CVSROOT_DIRNAME}/first-dir ${CVSROOT_DIRNAME}/second-dir - ;; - - stamps) - # Test timestamps. - mkdir 1; cd 1 - dotest stamps-1 "${testcvs} -q co -l ." '' - mkdir first-dir - dotest stamps-2 "${testcvs} add first-dir" \ -"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" - cd first-dir - touch aa - echo '$''Id$' >kw - # Cygwin, *cough*, puts the year in the time column until the minute - # is no longer the current minute. Sleep 60 seconds to avoid this - # problem. - sleep 60 - ls -l aa >${TESTDIR}/1/stamp.aa.touch - ls -l kw >${TESTDIR}/1/stamp.kw.touch - # "sleep 1" would suffice if we could assume ls --full-time, but - # that is as far as I know unique to GNU ls. Is there some POSIX.2 - # way to get the timestamp of a file, including the seconds? - sleep 60 - dotest stamps-3 "${testcvs} add aa kw" \ -"${PROG} add: scheduling file .aa. for addition -${PROG} add: scheduling file .kw. for addition -${PROG} add: use .${PROG} commit. to add these files permanently" - ls -l aa >${TESTDIR}/1/stamp.aa.add - ls -l kw >${TESTDIR}/1/stamp.kw.add - # "cvs add" should not muck with the timestamp. - dotest stamps-4aa \ -"cmp ${TESTDIR}/1/stamp.aa.touch ${TESTDIR}/1/stamp.aa.add" '' - dotest stamps-4kw \ -"cmp ${TESTDIR}/1/stamp.kw.touch ${TESTDIR}/1/stamp.kw.add" '' - sleep 60 - dotest stamps-5 "${testcvs} -q ci -m add" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/aa,v -done -Checking in aa; -${CVSROOT_DIRNAME}/first-dir/aa,v <-- aa -initial revision: 1\.1 -done -RCS file: ${CVSROOT_DIRNAME}/first-dir/kw,v -done -Checking in kw; -${CVSROOT_DIRNAME}/first-dir/kw,v <-- kw -initial revision: 1\.1 -done" - # Cygwin, *cough*, puts the year in the time column until the minute - # is no longer the current minute. Sleep 60 seconds to avoid this - # problem. - sleep 60 - ls -l aa >${TESTDIR}/1/stamp.aa.ci - ls -l kw >${TESTDIR}/1/stamp.kw.ci - # If there are no keywords, "cvs ci" leaves the timestamp alone - # If there are, it sets the timestamp to the date of the commit. - # I'm not sure how logical this is, but it is intentional. - # If we wanted to get fancy we would make sure the time as - # reported in "cvs log kw" matched stamp.kw.ci. But that would - # be a lot of work. - dotest stamps-6aa \ - "cmp ${TESTDIR}/1/stamp.aa.add ${TESTDIR}/1/stamp.aa.ci" '' - if cmp ${TESTDIR}/1/stamp.kw.add ${TESTDIR}/1/stamp.kw.ci >/dev/null - then - fail stamps-6kw - else - pass stamps-6kw - fi - cd ../.. - sleep 60 - mkdir 2 - cd 2 - dotest stamps-7 "${testcvs} -q get first-dir" "U first-dir/aa -U first-dir/kw" - cd first-dir - ls -l aa >${TESTDIR}/1/stamp.aa.get - ls -l kw >${TESTDIR}/1/stamp.kw.get - # On checkout, CVS should set the timestamp to the date that the - # file was committed. Could check that the time as reported in - # "cvs log aa" matches stamp.aa.get, but that would be a lot of - # work. - if cmp ${TESTDIR}/1/stamp.aa.ci ${TESTDIR}/1/stamp.aa.get >/dev/null - then - fail stamps-8aa - else - pass stamps-8aa - fi - dotest stamps-8kw \ - "cmp ${TESTDIR}/1/stamp.kw.ci ${TESTDIR}/1/stamp.kw.get" '' - - # Now we want to see what "cvs update" does. - sleep 60 - echo add a line >>aa - echo add a line >>kw - dotest stamps-9 "${testcvs} -q ci -m change-them" \ -"Checking in aa; -${CVSROOT_DIRNAME}/first-dir/aa,v <-- aa -new revision: 1\.2; previous revision: 1\.1 -done -Checking in kw; -${CVSROOT_DIRNAME}/first-dir/kw,v <-- kw -new revision: 1\.2; previous revision: 1\.1 -done" - - # Cygwin, *cough*, puts the year in the time column until the minute - # is no longer the current minute. Sleep 60 seconds to avoid this - # problem. - sleep 60 - ls -l aa >${TESTDIR}/1/stamp.aa.ci2 - ls -l kw >${TESTDIR}/1/stamp.kw.ci2 - cd ../.. - cd 1/first-dir - sleep 60 - dotest stamps-10 "${testcvs} -q update" '[UP] aa -[UP] kw' - # this doesn't serve any function other than being able to - # look at it manually, as we have no machinery for dates being - # newer or older than other dates. - date >${TESTDIR}/1/stamp.debug.update - ls -l aa >${TESTDIR}/1/stamp.aa.update - ls -l kw >${TESTDIR}/1/stamp.kw.update - # stamp.aa.update and stamp.kw.update should both be approximately - # the same as stamp.debug.update. Perhaps we could be testing - # this in a more fancy fashion by "touch stamp.before" before - # stamps-10, "touch stamp.after" after, and then using ls -t - # to check them. But for now we just make sure that the *.update - # stamps differ from the *.ci2 ones. - # As for the rationale, this is so that if one updates and gets - # a new revision, then "make" will be sure to regard those files - # as newer than .o files which may be sitting around. - if cmp ${TESTDIR}/1/stamp.aa.update ${TESTDIR}/1/stamp.aa.ci2 \ - >/dev/null - then - fail stamps-11aa - else - pass stamps-11aa - fi - if cmp ${TESTDIR}/1/stamp.kw.update ${TESTDIR}/1/stamp.kw.ci2 \ - >/dev/null - then - fail stamps-11kw - else - pass stamps-11kw - fi - - cd ../.. - - if $keep; then - echo Keeping ${TESTDIR} and exiting due to --keep - exit 0 - fi - - rm -r 1 2 - rm -rf ${CVSROOT_DIRNAME}/first-dir - ;; - - perms) - # short cut around checking out and committing CVSROOT - rm -f ${CVSROOT_DIRNAME}/CVSROOT/config - echo 'PreservePermissions=yes' > ${CVSROOT_DIRNAME}/CVSROOT/config - chmod 444 ${CVSROOT_DIRNAME}/CVSROOT/config - - mkdir 1; cd 1 - dotest perms-1 "${testcvs} -q co -l ." '' - mkdir first-dir - dotest perms-2 "${testcvs} add first-dir" \ -"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" - cd first-dir - - touch foo - chmod 431 foo - dotest perms-3 "${testcvs} add foo" \ -"${PROG} add: scheduling file .foo. for addition -${PROG} add: use .${PROG} commit. to add this file permanently" - dotest perms-4 "${testcvs} -q ci -m ''" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/foo,v -done -Checking in foo; -${CVSROOT_DIRNAME}/first-dir/foo,v <-- foo -initial revision: 1\.1 -done" - - # Test checking out files with different permissions. - cd ../.. - mkdir 2; cd 2 - dotest perms-5 "${testcvs} -q co first-dir" "U first-dir/foo" - cd first-dir - if $remote; then :; else - # PreservePermissions not yet implemented for remote. - dotest perms-6 "ls -l foo" "-r---wx--x .* foo" - fi - - cd ../.. - rm -rf 1 2 - rm -rf ${CVSROOT_DIRNAME}/first-dir - - rm -f ${CVSROOT_DIRNAME}/CVSROOT/config - touch ${CVSROOT_DIRNAME}/CVSROOT/config - chmod 444 ${CVSROOT_DIRNAME}/CVSROOT/config - ;; - - symlinks) - # short cut around checking out and committing CVSROOT - rm -f ${CVSROOT_DIRNAME}/CVSROOT/config - echo 'PreservePermissions=yes' > ${CVSROOT_DIRNAME}/CVSROOT/config - chmod 444 ${CVSROOT_DIRNAME}/CVSROOT/config - - mkdir 1; cd 1 - dotest symlinks-1 "${testcvs} -q co -l ." '' - mkdir first-dir - dotest symlinks-2 "${testcvs} add first-dir" \ -"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" - cd first-dir - - dotest symlinks-2.1 "ln -s ${TESTDIR}/fumble slink" "" - dotest symlinks-3 "${testcvs} add slink" \ -"${PROG} add: scheduling file .slink. for addition -${PROG} add: use .${PROG} commit. to add this file permanently" - if $remote; then - # Remote doesn't implement PreservePermissions, and in its - # absence the correct behavior is to follow the symlink. - dotest_fail symlinks-4r "${testcvs} -q ci -m ''" \ -"${PROG} \[commit aborted\]: reading slink: No such file or directory" - else - dotest symlinks-4 "${testcvs} -q ci -m ''" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/slink,v -done -Checking in slink; -${CVSROOT_DIRNAME}/first-dir/slink,v <-- slink -initial revision: 1\.1 -done" - - # Test checking out symbolic links. - cd ../.. - mkdir 2; cd 2 - dotest symlinks-5 "${testcvs} -q co first-dir" "U first-dir/slink" - cd first-dir - dotest symlinks-6 "ls -l slink" \ -"l[rwx\-]* .* slink -> ${TESTDIR}/fumble" - fi - - cd ../.. - rm -rf 1 2 - rm -rf ${CVSROOT_DIRNAME}/first-dir - - rm -f ${CVSROOT_DIRNAME}/CVSROOT/config - touch ${CVSROOT_DIRNAME}/CVSROOT/config - chmod 444 ${CVSROOT_DIRNAME}/CVSROOT/config - ;; - - symlinks2) - # Symlinks in working directory without PreservePermissions. - # Also see: symlinks: with PreservePermissions - # rcslib-symlink-*: symlinks in repository. - mkdir 1; cd 1 - dotest symlinks2-1 "${testcvs} -q co -l ." '' - mkdir first-dir - dotest symlinks2-2 "${testcvs} add first-dir" \ -"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" - cd first-dir - echo nonsymlink > slink - dotest symlinks2-3 "${testcvs} add slink" \ -"${PROG} add: scheduling file .slink. for addition -${PROG} add: use .${PROG} commit. to add this file permanently" - dotest symlinks2-4 "${testcvs} -q ci -m ''" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/slink,v -done -Checking in slink; -${CVSROOT_DIRNAME}/first-dir/slink,v <-- slink -initial revision: 1\.1 -done" - rm slink - # Choose name cvslog.* so it is in default ignore list. - echo second file >cvslog.file2 - dotest symlinks2-5 "ln -s cvslog.file2 slink" "" - dotest symlinks2-6 "${testcvs} -q ci -m linkify" \ -"Checking in slink; -${CVSROOT_DIRNAME}/first-dir/slink,v <-- slink -new revision: 1\.2; previous revision: 1\.1 -done" - dotest symlinks2-7 "${testcvs} -q update -r 1.1 slink" "[UP] slink" - dotest symlinks2-8 "cat slink" "nonsymlink" - dotest symlinks2-9 "ls -l slink" "-[-rwx]* .* slink" - cd ../.. - - rm -rf 1 - rm -rf ${CVSROOT_DIRNAME}/first-dir - ;; - - hardlinks) - # short cut around checking out and committing CVSROOT - rm -f ${CVSROOT_DIRNAME}/CVSROOT/config - echo 'PreservePermissions=yes' > ${CVSROOT_DIRNAME}/CVSROOT/config - chmod 444 ${CVSROOT_DIRNAME}/CVSROOT/config - - mkdir 1; cd 1 - dotest hardlinks-1 "${testcvs} -q co -l ." '' - mkdir first-dir - dotest hardlinks-2 "${testcvs} add first-dir" \ -"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" - cd first-dir - - # Make up some ugly filenames, to test that they get - # encoded properly in the delta nodes. Note that `dotest' screws - # up if some arguments have embedded spaces. - if touch aaaa - then - pass hardlinks-2.1 - else - fail hardlinks-2.1 - fi - - if ln aaaa b.b.b.b - then - pass hardlinks-2.2 - else - fail hardlinks-2.2 - fi - - if ln aaaa 'dd dd dd' - then - pass hardlinks-2.3 - else - fail hardlinks-2.3 - fi - - dotest hardlinks-3 "${testcvs} add [abd]*" \ -"${PROG} add: scheduling file .aaaa. for addition -${PROG} add: scheduling file .b\.b\.b\.b. for addition -${PROG} add: scheduling file .dd dd dd. for addition -${PROG} add: use .${PROG} commit. to add these files permanently" - dotest hardlinks-4 "${testcvs} -q ci -m ''" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/aaaa,v -done -Checking in aaaa; -${CVSROOT_DIRNAME}/first-dir/aaaa,v <-- aaaa -initial revision: 1\.1 -done -RCS file: ${CVSROOT_DIRNAME}/first-dir/b\.b\.b\.b,v -done -Checking in b\.b\.b\.b; -${CVSROOT_DIRNAME}/first-dir/b\.b\.b\.b,v <-- b\.b\.b\.b -initial revision: 1\.1 -done -RCS file: ${CVSROOT_DIRNAME}/first-dir/dd dd dd,v -done -Checking in dd dd dd; -${CVSROOT_DIRNAME}/first-dir/dd dd dd,v <-- dd dd dd -initial revision: 1\.1 -done" - # Test checking out hardlinked files. - cd ../.. - mkdir 2; cd 2 - if $remote; then - # Remote does not implement PreservePermissions. - dotest hardlinks-5r "${testcvs} -q co first-dir" \ -"U first-dir/aaaa -U first-dir/b\.b\.b\.b -U first-dir/dd dd dd" - cd first-dir - dotest hardlinks-6r "ls -l [abd]*" \ -"-[rwx\-]* *1 .* aaaa --[rwx\-]* *1 .* b\.b\.b\.b --[rwx\-]* *1 .* dd dd dd" - else - dotest hardlinks-5 "${testcvs} -q co first-dir" \ -"U first-dir/aaaa -U first-dir/b\.b\.b\.b -U first-dir/dd dd dd" - cd first-dir - # To make sure that the files are properly hardlinked, it - # would be nice to do `ls -i' and make sure all the inodes - # match. But I think that would require expr to support - # tagged regexps, and I don't think we can rely on that. - # So instead we just see that each file has the right - # number of links. -twp - dotest hardlinks-6 "ls -l [abd]*" \ -"-[rwx\-]* *3 .* aaaa --[rwx\-]* *3 .* b\.b\.b\.b --[rwx\-]* *3 .* dd dd dd" - fi - - cd ../.. - rm -rf 1 2 - rm -rf ${CVSROOT_DIRNAME}/first-dir - - rm -f ${CVSROOT_DIRNAME}/CVSROOT/config - touch ${CVSROOT_DIRNAME}/CVSROOT/config - chmod 444 ${CVSROOT_DIRNAME}/CVSROOT/config - ;; - - sticky) - # More tests of sticky tags, particularly non-branch sticky tags. - # See many tests (e.g. multibranch) for ordinary sticky tag - # operations such as adding files on branches. - # See "head" test for interaction between stick tags and HEAD. - mkdir 1; cd 1 - dotest sticky-1 "${testcvs} -q co -l ." '' - mkdir first-dir - dotest sticky-2 "${testcvs} add first-dir" \ -"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" - cd first-dir - - touch file1 - dotest sticky-3 "${testcvs} add file1" \ -"${PROG} add: scheduling file .file1. for addition -${PROG} add: use .${PROG} commit. to add this file permanently" - dotest sticky-4 "${testcvs} -q ci -m add" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -done -Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -initial revision: 1\.1 -done" - dotest sticky-5 "${testcvs} -q tag tag1" "T file1" - echo add a line >>file1 - dotest sticky-6 "${testcvs} -q ci -m modify" \ -"Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -new revision: 1\.2; previous revision: 1\.1 -done" - dotest sticky-7 "${testcvs} -q update -r tag1" "[UP] file1" - dotest sticky-8 "cat file1" '' - dotest sticky-9 "${testcvs} -q update" '' - dotest sticky-10 "cat file1" '' - touch file2 - dotest_fail sticky-11 "${testcvs} add file2" \ -"${PROG} add: cannot add file on non-branch tag tag1" - dotest sticky-12 "${testcvs} -q update -A" "[UP] file1 -${QUESTION} file2" "${QUESTION} file2 -[UP] file1" - dotest sticky-13 "${testcvs} add file2" \ -"${PROG} add: scheduling file .file2. for addition -${PROG} add: use .${PROG} commit. to add this file permanently" - dotest sticky-14 "${testcvs} -q ci -m add" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v -done -Checking in file2; -${CVSROOT_DIRNAME}/first-dir/file2,v <-- file2 -initial revision: 1\.1 -done" - - # Now back to tag1 - dotest sticky-15 "${testcvs} -q update -r tag1" "[UP] file1 -${PROG} update: file2 is no longer in the repository" - - rm file1 - dotest sticky-16 "${testcvs} rm file1" \ -"${PROG} remove: scheduling .file1. for removal -${PROG} remove: use .${PROG} commit. to remove this file permanently" - # Hmm, this command seems to silently remove the tag from - # the file. This appears to be intentional. - # The silently part especially strikes me as odd, though. - dotest sticky-17 "${testcvs} -q ci -m remove-it" "" - dotest sticky-18 "${testcvs} -q update -A" "U file1 -U file2" - dotest sticky-19 "${testcvs} -q update -r tag1" \ -"${PROG} update: file1 is no longer in the repository -${PROG} update: file2 is no longer in the repository" - dotest sticky-20 "${testcvs} -q update -A" "U file1 -U file2" - - # Now try with a numeric revision. - dotest sticky-21 "${testcvs} -q update -r 1.1 file1" "U file1" - dotest sticky-22 "${testcvs} rm -f file1" \ -"${PROG} remove: cannot remove file .file1. which has a numeric sticky tag of .1\.1." - # The old behavior was that remove allowed this and then commit - # gave an error, which was somewhat hard to clear. I mean, you - # could get into a long elaborate discussion of this being a - # conflict and two ways to resolve it, but I don't really see - # why CVS should have a concept of conflict that arises, not from - # parallel development, but from CVS's own sticky tags. - - # Ditto with a sticky date. - # - # I'm kind of surprised that the "file1 was lost" doesn't crop - # up elsewhere in the testsuite. It is a long-standing - # discrepency between local and remote CVS and should probably - # be cleaned up at some point. - dotest sticky-23 "${testcvs} -q update -Dnow file1" \ -"${PROG} update: warning: file1 was lost -U file1" "U file1" - dotest sticky-24 "${testcvs} rm -f file1" \ -"${PROG} remove: cannot remove file .file1. which has a sticky date of .[0-9.]*." - - dotest sticky-25 "${testcvs} -q update -A" \ -"${PROG} update: warning: file1 was lost -U file1" "U file1" - - cd ../.. - rm -r 1 - rm -rf ${CVSROOT_DIRNAME}/first-dir - ;; - - keyword) - # Test keyword expansion. - # Various other tests relate to our ability to correctly - # set the keyword expansion mode. - # "binfiles" tests "cvs admin -k". - # "binfiles" and "binfiles2" test "cvs add -k". - # "rdiff" tests "cvs co -k". - # "binfiles" (and this test) test "cvs update -k". - # "binwrap" tests setting the mode from wrappers. - # "keyword2" tests "cvs update -kk -j" with text and binary files - # I don't think any test is testing "cvs import -k". - # Other keyword expansion tests: - # keywordlog - $Log. - mkdir 1; cd 1 - dotest keyword-1 "${testcvs} -q co -l ." '' - mkdir first-dir - dotest keyword-2 "${testcvs} add first-dir" \ -"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" - cd first-dir - - echo '$''Author$' > file1 - echo '$''Date$' >> file1 - echo '$''Header$' >> file1 - echo '$''Id$' >> file1 - echo '$''Locker$' >> file1 - echo '$''Name$' >> file1 - echo '$''RCSfile$' >> file1 - echo '$''Revision$' >> file1 - echo '$''Source$' >> file1 - echo '$''State$' >> file1 - echo '$''Nonkey$' >> file1 - # Omit the trailing dollar sign - echo '$''Date' >> file1 - # Put two keywords on one line - echo '$''State$' '$''State$' >> file1 - # Use a header for Log - echo 'xx $''Log$' >> file1 - - dotest keyword-3 "${testcvs} add file1" \ -"${PROG} add: scheduling file .file1. for addition -${PROG} add: use .${PROG} commit. to add this file permanently" - dotest keyword-4 "${testcvs} -q ci -m add" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -done -Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -initial revision: 1\.1 -done" - dotest keyword-5 "cat file1" \ -'\$'"Author: ${username} "'\$'" -"'\$'"Date: [0-9][0-9][0-9][0-9]/[0-9][0-9]/[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9] "'\$'" -"'\$'"Header: ${CVSROOT_DIRNAME}/first-dir/file1,v 1\.1 [0-9/]* [0-9:]* ${username} Exp "'\$'" -"'\$'"Id: file1,v 1\.1 [0-9/]* [0-9:]* ${username} Exp "'\$'" -"'\$'"Locker: "'\$'" -"'\$'"Name: "'\$'" -"'\$'"RCSfile: file1,v "'\$'" -"'\$'"Revision: 1\.1 "'\$'" -"'\$'"Source: ${CVSROOT_DIRNAME}/first-dir/file1,v "'\$'" -"'\$'"State: Exp "'\$'" -"'\$'"Nonkey"'\$'" -"'\$'"Date -"'\$'"State: Exp "'\$'" "'\$'"State: Exp "'\$'" -xx "'\$'"Log: file1,v "'\$'" -xx Revision 1\.1 [0-9/]* [0-9:]* ${username} -xx add -xx" - - # Use cvs admin to lock the RCS file in order to check -kkvl - # vs. -kkv. CVS does not normally lock RCS files, but some - # people use cvs admin to enforce reserved checkouts. - dotest keyword-6 "${testcvs} admin -l file1" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -1\.1 locked -done" - - dotest keyword-7 "$testcvs update -kkv file1" '[UP] file1' - dotest keyword-8 "cat file1" \ -'\$'"Author: ${username} "'\$'" -"'\$'"Date: [0-9][0-9][0-9][0-9]/[0-9][0-9]/[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9] "'\$'" -"'\$'"Header: ${CVSROOT_DIRNAME}/first-dir/file1,v 1\.1 [0-9/]* [0-9:]* ${username} Exp "'\$'" -"'\$'"Id: file1,v 1\.1 [0-9/]* [0-9:]* ${username} Exp "'\$'" -"'\$'"Locker: "'\$'" -"'\$'"Name: "'\$'" -"'\$'"RCSfile: file1,v "'\$'" -"'\$'"Revision: 1\.1 "'\$'" -"'\$'"Source: ${CVSROOT_DIRNAME}/first-dir/file1,v "'\$'" -"'\$'"State: Exp "'\$'" -"'\$'"Nonkey"'\$'" -"'\$'"Date -"'\$'"State: Exp "'\$'" "'\$'"State: Exp "'\$'" -xx "'\$'"Log: file1,v "'\$'" -xx Revision 1\.1 [0-9/]* [0-9:]* ${username} -xx add -xx" - - dotest keyword-9 "$testcvs update -kkvl file1" '[UP] file1' - dotest keyword-10 "cat file1" \ -'\$'"Author: ${username} "'\$'" -"'\$'"Date: [0-9][0-9][0-9][0-9]/[0-9][0-9]/[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9] "'\$'" -"'\$'"Header: ${CVSROOT_DIRNAME}/first-dir/file1,v 1\.1 [0-9/]* [0-9:]* ${username} Exp ${username} "'\$'" -"'\$'"Id: file1,v 1\.1 [0-9/]* [0-9:]* ${username} Exp ${username} "'\$'" -"'\$'"Locker: ${username} "'\$'" -"'\$'"Name: "'\$'" -"'\$'"RCSfile: file1,v "'\$'" -"'\$'"Revision: 1\.1 "'\$'" -"'\$'"Source: ${CVSROOT_DIRNAME}/first-dir/file1,v "'\$'" -"'\$'"State: Exp "'\$'" -"'\$'"Nonkey"'\$'" -"'\$'"Date -"'\$'"State: Exp "'\$'" "'\$'"State: Exp "'\$'" -xx "'\$'"Log: file1,v "'\$'" -xx Revision 1\.1 [0-9/]* [0-9:]* ${username} -xx add -xx" - - dotest keyword-11 "${testcvs} update -kk file1" '[UP] file1' - dotest keyword-12 "cat file1" \ -'\$'"Author"'\$'" -"'\$'"Date"'\$'" -"'\$'"Header"'\$'" -"'\$'"Id"'\$'" -"'\$'"Locker"'\$'" -"'\$'"Name"'\$'" -"'\$'"RCSfile"'\$'" -"'\$'"Revision"'\$'" -"'\$'"Source"'\$'" -"'\$'"State"'\$'" -"'\$'"Nonkey"'\$'" -"'\$'"Date -"'\$'"State"'\$'" "'\$'"State"'\$'" -xx "'\$'"Log"'\$'" -xx Revision 1\.1 [0-9/]* [0-9:]* ${username} -xx add -xx" - - dotest keyword-13 "$testcvs update -kv file1" '[UP] file1' - dotest keyword-14 "cat file1" \ -"${username} -[0-9][0-9][0-9][0-9]/[0-9][0-9]/[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9] -${CVSROOT_DIRNAME}/first-dir/file1,v 1\.1 [0-9/]* [0-9:]* ${username} Exp -file1,v 1\.1 [0-9/]* [0-9:]* ${username} Exp - - -file1,v -1\.1 -${CVSROOT_DIRNAME}/first-dir/file1,v -Exp -"'\$'"Nonkey"'\$'" -"'\$'"Date -Exp Exp -xx file1,v -xx Revision 1\.1 [0-9/]* [0-9:]* ${username} -xx add -xx" - - dotest keyword-15 "${testcvs} update -ko file1" "U file1" - dotest keyword-16 "cat file1" \ -'\$'"Author"'\$'" -"'\$'"Date"'\$'" -"'\$'"Header"'\$'" -"'\$'"Id"'\$'" -"'\$'"Locker"'\$'" -"'\$'"Name"'\$'" -"'\$'"RCSfile"'\$'" -"'\$'"Revision"'\$'" -"'\$'"Source"'\$'" -"'\$'"State"'\$'" -"'\$'"Nonkey"'\$'" -"'\$'"Date -"'\$'"State"'\$'" "'\$'"State"'\$'" -xx "'\$'"Log"'\$' - - # Test the Name keyword. First go back to normal expansion. - - dotest keyword-17 "${testcvs} update -A file1" "U file1" - - echo '$''Name$' > file1 - dotest keyword-18 "${testcvs} ci -m modify file1" \ -"Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -new revision: 1\.2; previous revision: 1\.1 -done" - dotest keyword-19 "${testcvs} -q tag tag1" "T file1" - echo "change" >> file1 - dotest keyword-20 "${testcvs} -q ci -m mod2 file1" \ -"Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -new revision: 1\.3; previous revision: 1\.2 -done" - - # Prior to 1.11.23, remote CVS would fail the patch checksum test - # and refetch the file here, failing this test. - dotest keyword-21 "$testcvs -q update -r tag1" 'U file1' - - dotest keyword-22 "cat file1" '\$'"Name: tag1 "'\$' - - # The update used to fail the first time with a checksum failure - # here, then the server would send the whole failure. This was fixed - # in 1.11.23. - dotest keyword-23 "$testcvs update -A file1" "U file1" - dotest keyword-24 "cat file1" '\$'"Name: "'\$'" -change" - - cd ../.. - rm -r 1 - rm -rf ${CVSROOT_DIRNAME}/first-dir - ;; - - keywordlog) - # Test the Log keyword. - mkdir 1; cd 1 - dotest keywordlog-1 "${testcvs} -q co -l ." '' - mkdir first-dir - dotest keywordlog-2 "${testcvs} add first-dir" \ -"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" - cd first-dir - echo initial >file1 - dotest keywordlog-3 "${testcvs} add file1" \ -"${PROG} add: scheduling file .file1. for addition -${PROG} add: use .${PROG} commit. to add this file permanently" - - # See "rmadd" for a list of other tests of cvs ci -r. - dotest keywordlog-4 "${testcvs} -q ci -r 1.3 -m add file1" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -done -Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -initial revision: 1\.3 -done" - - cd ../.. - mkdir 2; cd 2 - dotest keywordlog-4a "${testcvs} -q co first-dir" "U first-dir/file1" - cd ../1/first-dir - - echo 'xx $''Log$' >> file1 - cat >${TESTDIR}/comment.tmp <> file1 - dotest keywordlog-10 "${testcvs} ci -m modify file1" \ -"Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -new revision: 1\.5; previous revision: 1\.4 -done" - dotest keywordlog-11 "cat file1" \ -"initial -xx "'\$'"Log: file1,v "'\$'" -xx Revision 1\.5 [0-9/]* [0-9:]* ${username} -xx modify -xx -xx Revision 1\.4 [0-9/]* [0-9:]* ${username} -xx First log line -xx Second log line -xx -change" - - cd ../../2/first-dir - dotest keywordlog-12 "${testcvs} -q update" "[UP] file1" - dotest keywordlog-13 "cat file1" \ -"initial -xx "'\$'"Log: file1,v "'\$'" -xx Revision 1\.5 [0-9/]* [0-9:]* ${username} -xx modify -xx -xx Revision 1\.4 [0-9/]* [0-9:]* ${username} -xx First log line -xx Second log line -xx -change" - - cd ../../1/first-dir - dotest keywordlog-14 "${testcvs} -q update -r br" "[UP] file1" - echo br-change >>file1 - dotest keywordlog-15 "${testcvs} -q ci -m br-modify" \ -"Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -new revision: 1\.4\.2\.1; previous revision: 1\.4 -done" - dotest keywordlog-16 "cat file1" \ -"initial -xx "'\$'"Log: file1,v "'\$'" -xx Revision 1\.4\.2\.1 [0-9/]* [0-9:]* ${username} -xx br-modify -xx -xx Revision 1\.4 [0-9/]* [0-9:]* ${username} -xx First log line -xx Second log line -xx -br-change" - cd ../../2/first-dir - dotest keywordlog-17 "${testcvs} -q update -r br" "[UP] file1" - dotest keywordlog-18 "cat file1" \ -"initial -xx "'\$'"Log: file1,v "'\$'" -xx Revision 1\.4\.2\.1 [0-9/]* [0-9:]* ${username} -xx br-modify -xx -xx Revision 1\.4 [0-9/]* [0-9:]* ${username} -xx First log line -xx Second log line -xx -br-change" - cd ../.. - dotest keywordlog-19 "${testcvs} -q co -p -r br first-dir/file1" \ -"initial -xx "'\$'"Log: file1,v "'\$'" -xx Revision 1\.4\.2\.1 [0-9/]* [0-9:]* ${username} -xx br-modify -xx -xx Revision 1\.4 [0-9/]* [0-9:]* ${username} -xx First log line -xx Second log line -xx -br-change" - dotest keywordlog-20 "${testcvs} -q co -p first-dir/file1" \ -"initial -xx "'\$'"Log: file1,v "'\$'" -xx Revision 1\.5 [0-9/]* [0-9:]* ${username} -xx modify -xx -xx Revision 1\.4 [0-9/]* [0-9:]* ${username} -xx First log line -xx Second log line -xx -change" - dotest keywordlog-21 "${testcvs} -q co -p -r 1.4 first-dir/file1" \ -"initial -xx "'\$'"Log: file1,v "'\$'" -xx Revision 1\.4 [0-9/]* [0-9:]* ${username} -xx First log line -xx Second log line -xx" - - cd 2/first-dir - # OK, the basic rule for keyword expansion is that it - # happens on checkout. And the rule for annotate is that - # it annotates a checked-in revision, rather than a checked-out - # file. So, although it is kind of confusing that the latest - # revision does not appear in the annotated output, and the - # annotated output does not quite match what you'd get with - # update or checkout, the behavior is more or less logical. - # The same issue occurs with annotate and other keywords, - # I think, although it is particularly noticeable for $Log. - dotest keywordlog-22 "${testcvs} ann -r br file1" \ -" -Annotations for file1 -\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* -1\.3 ($username8 *[0-9a-zA-Z-]*): initial -1\.4\.2\.1 ($username8 *[0-9a-zA-Z-]*): xx "'\$'"Log: file1,v "'\$'" -1\.4\.2\.1 ($username8 *[0-9a-zA-Z-]*): xx Revision 1\.4 [0-9/]* [0-9:]* $username -1\.4\.2\.1 ($username8 *[0-9a-zA-Z-]*): xx First log line -1\.4\.2\.1 ($username8 *[0-9a-zA-Z-]*): xx Second log line -1\.4\.2\.1 ($username8 *[0-9a-zA-Z-]*): xx -1\.4\.2\.1 ($username8 *[0-9a-zA-Z-]*): br-change" - dotest keywordlog-23 "${testcvs} ann -r HEAD file1" \ -" -Annotations for file1 -\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* -1\.3 ($username8 *[0-9a-zA-Z-]*): initial -1\.5 ($username8 *[0-9a-zA-Z-]*): xx "'\$'"Log: file1,v "'\$'" -1\.5 ($username8 *[0-9a-zA-Z-]*): xx Revision 1\.4 [0-9/]* [0-9:]* $username -1\.5 ($username8 *[0-9a-zA-Z-]*): xx First log line -1\.5 ($username8 *[0-9a-zA-Z-]*): xx Second log line -1\.5 ($username8 *[0-9a-zA-Z-]*): xx -1\.5 ($username8 *[0-9a-zA-Z-]*): change" - cd ../.. - - # - # test the operation of 'admin -o' in conjunction with keywords - # (especially Log - this used to munge the RCS file for all time) - # - - dotest keywordlog-24 \ -"${testcvs} admin -oHEAD 1/first-dir/file1" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -deleting revision 1\.5 -done" - - dotest keywordlog-25 \ -"${testcvs} -q co -p first-dir/file1" \ -"initial -xx "'\$'"Log: file1,v "'\$'" -xx Revision 1\.4 [0-9/]* [0-9:]* ${username} -xx First log line -xx Second log line -xx" - - if $keep; then - echo Keeping ${TESTDIR} and exiting due to --keep - exit 0 - fi - - rm -r 1 2 - rm -rf ${CVSROOT_DIRNAME}/first-dir - ;; - - keywordname) - # Test the Name keyword. - # See the keyword test for a descriptions of some other tests that - # test keyword expansion modes. - mkdir keywordname; cd keywordname - mkdir 1; cd 1 - dotest keywordname-init-1 "${testcvs} -q co -l ." '' - mkdir first-dir - dotest keywordname-init-2 "${testcvs} add first-dir" \ -"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" - cd first-dir - - echo '$'"Name$" >file1 - echo '$'"Name$" >file2 - dotest keywordname-init-3 "${testcvs} add file1 file2" \ -"${PROG} add: scheduling file .file1. for addition -${PROG} add: scheduling file .file2. for addition -${PROG} add: use .${PROG} commit. to add these files permanently" - - # See "rmadd" for a list of other tests of cvs ci -r. - dotest keywordname-init-4 "${testcvs} -q ci -r 1.3 -m add" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -done -Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -initial revision: 1\.3 -done -RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v -done -Checking in file2; -${CVSROOT_DIRNAME}/first-dir/file2,v <-- file2 -initial revision: 1\.3 -done" - dotest keywordname-init-5b "cat file1" \ -'\$''Name: \$' - dotest keywordname-init-5c "cat file2" \ -'\$''Name: \$' - - dotest keywordname-init-6 "$testcvs -q up -A" - dotest keywordname-init-6b "cat file1" \ -'\$''Name: \$' - dotest keywordname-init-6c "cat file2" \ -'\$''Name: \$' - - dotest keywordname-init-7 "${testcvs} -q tag -b br" \ -"T file1 -T file2" - - echo new data >>file1 - dotest keywordname-init-8 "${testcvs} -q ci -mchange" \ -"Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -new revision: 1\.4; previous revision: 1\.3 -done" - - # First check out a branch. - # - # There used to be a bug where static tags would be substituted for - # Name keywords but not branch tags. - # - # Prior to 1.11.23, there also used to be a bug where keyword - # substitutions were not performed unless the file was otherwise - # updated. When this bug was present, keywordname-update-1 would - # report a patch checksum failure and refetch file1 in client/server - # mode and no `br' would have been substituted into Name's value for - # file2, meaning keywordname-update-3 would also fail. - dotest keywordname-update-1 "$testcvs -q up -rbr" \ -'U file1 -U file2' - dotest keywordname-update-2 "cat file1" '\$''Name: br \$' - - # For the same reason keywordname-update-1 would fail above, no `br' - # would have been substituted into Name's value here prior to - # 1.11.23. - dotest keywordname-update-3 "cat file2" '\$''Name: br \$' - - # Now verify that updating to the trunk leaves no substitution for - # $Name - dotest keywordname-update-4 "${testcvs} -q tag firsttag" \ -"T file1 -T file2" - # This used to fail in the same manner as keywordname-update-1. - dotest keywordname-update-5 "$testcvs -q up -A" \ -'U file1 -U file2' - dotest keywordname-update-6 "cat file1" \ -'\$''Name: \$ -new data' - dotest keywordname-update-7 "cat file2" '\$''Name: \$' - - # This used to fail in the same manner as keywordname-update-1. - dotest keywordname-update-8 "$testcvs -q up -rfirsttag" \ -'U file1 -U file2' - dotest keywordname-update-9 "cat file1" '\$''Name: firsttag \$' - - # This used to fail in the same manner as keywordname-update-3. - dotest keywordname-update-10 "cat file2" '\$''Name: firsttag \$' - - # And reverify the trunk update when the change is actually removed. - dotest keywordname-update-11 "$testcvs -q up -A" \ -'U file1 -U file2' - dotest keywordname-update-12 "cat file1" \ -'\$''Name: \$ -new data' - dotest keywordname-update-13 "cat file2" '\$''Name: \$' - - cd ../.. - - # now verify that a fresh checkout substitutes all the $Name fields - mkdir 2; cd 2 - dotest keywordname-checkout-1 \ -"${testcvs} -q co -rfirsttag first-dir" \ -"U first-dir/file1 -U first-dir/file2" - cd first-dir - dotest keywordname-checkout-2 "cat file1" '\$'"Name: firsttag "'\$' - dotest keywordname-checkout-3 "cat file2" '\$'"Name: firsttag "'\$' - - cd ../.. - - if $keep; then - echo Keeping ${TESTDIR} and exiting due to --keep - exit 0 - fi - - cd .. - rm -r keywordname - rm -rf ${CVSROOT_DIRNAME}/first-dir - ;; - - keyword2) - # Test merging on files with keywords: - # without -kk - # with -kk - # on text files - # on binary files - # Note: This test assumes that CVS has already passed the binfiles - # test sequence - # Note2: We are testing positive on binary corruption here - # we probably really DON'T want to 'cvs update -kk' a binary file... - mkdir 1; cd 1 - dotest keyword2-1 "${testcvs} -q co -l ." '' - mkdir first-dir - dotest keyword2-2 "${testcvs} add first-dir" \ -"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" - cd first-dir - - echo '$''Revision$' >> file1 - echo "I" >>file1 - echo "like" >>file1 - echo "long" >>file1 - echo "files!" >>file1 - echo "" >>file1 - echo "a test line for our times" >>file1 - echo "" >>file1 - echo "They" >>file1 - echo "make" >>file1 - echo "diff" >>file1 - echo "look like it" >>file1 - echo "did a much better" >>file1 - echo "job." >>file1 - dotest keyword2-3 "${testcvs} add file1" \ -"${PROG} add: scheduling file .file1. for addition -${PROG} add: use .${PROG} commit. to add this file permanently" - - ${AWK} 'BEGIN { printf "%c%c%c%sRevision: 1.1 $@%c%c", \ - 2, 10, 137, "$", 13, 10 }' \ - ../binfile.dat - cp ../binfile.dat . - dotest keyword2-5 "${testcvs} add -kb binfile.dat" \ -"${PROG} add: scheduling file .binfile\.dat. for addition -${PROG} add: use .${PROG} commit. to add this file permanently" - - dotest keyword2-6 "${testcvs} -q ci -m add" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/binfile\.dat,v -done -Checking in binfile\.dat; -${CVSROOT_DIRNAME}/first-dir/binfile\.dat,v <-- binfile\.dat -initial revision: 1\.1 -done -RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -done -Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -initial revision: 1\.1 -done" - - dotest keyword2-7 "${testcvs} -q tag -b branch" \ -"T binfile\.dat -T file1" - - sed -e 's/our/the best of and the worst of/' file1 >f; mv f file1 - dotest keyword2-8 "${testcvs} -q ci -m change" \ -"Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -new revision: 1\.2; previous revision: 1\.1 -done" - - dotest keyword2-9 "$testcvs -q update -r branch" \ -'U binfile\.dat -[UP] file1' - - echo "what else do we have?" >>file1 - dotest keyword2-10 "${testcvs} -q ci -m change" \ -"Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -new revision: 1\.1\.2\.1; previous revision: 1\.1 -done" - - # Okay, first a conflict in file1 - should be okay with binfile.dat - dotest keyword2-11 "$testcvs -q update -A -j branch" \ -"U binfile\.dat -U file1 -RCS file: $CVSROOT_DIRNAME/first-dir/file1,v -retrieving revision 1\.1 -retrieving revision 1\.1\.2\.1 -Merging differences between 1\.1 and 1\.1\.2\.1 into file1 -rcsmerge: warning: conflicts during merge" - - dotest_fail keyword2-12 "${testcvs} diff file1" \ -"Index: file1 -=================================================================== -RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -retrieving revision 1\.2 -diff -r1\.2 file1 -0a1 -> <<<<<<< file1 -1a3,5 -> ======= -> \\\$""Revision: 1\.1\.2\.1 \\\$ -> >>>>>>> 1\.1\.2\.1 -14a19 -> what else do we have${QUESTION}" - - # Here's the problem... shouldn't -kk a binary file... - rm file1 - dotest keyword2-13 "${testcvs} -q update -A -kk -j branch" \ -"${PROG} update: warning: file1 was lost -U file1 -RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -retrieving revision 1\.1 -retrieving revision 1\.1\.2\.1 -Merging differences between 1\.1 and 1\.1\.2\.1 into file1" - - # binfile won't get checked in, but it is now corrupt and could - # have been checked in if it had changed on the branch... - dotest keyword2-14 "${testcvs} -q ci -m change" \ -"Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -new revision: 1\.3; previous revision: 1\.2 -done" - - # "-kk" no longer corrupts binary files - dotest keyword2-15 "cmp binfile.dat ../binfile.dat" '' - - # Okay, restore everything and make CVS try and merge a binary file... - # "-kk" no longer affects binary files - dotest keyword2-16 "${testcvs} -q update -A" \ -"[UP] file1" - dotest keyword2-17 "${testcvs} -q tag -b branch2" \ -"T binfile\.dat -T file1" - dotest keyword2-18 "$testcvs -q update -r branch2" \ -'U binfile\.dat -[UP] file1' - - ${AWK} 'BEGIN { printf "%c%c%c@%c%c", 2, 10, 137, 13, 10 }' \ - >binfile.dat - dotest keyword2-19 "${testcvs} -q ci -m badbadbad" \ -"Checking in binfile\.dat; -${CVSROOT_DIRNAME}/first-dir/binfile\.dat,v <-- binfile\.dat -new revision: 1\.1\.4\.1; previous revision: 1\.1 -done" - # "-kk" no longer affects binary files - - # XXXX: do not ask, why we get the "U binfile.dat" line twice - # looks like a bug! - dotest keyword2-20 "${testcvs} -q update -A -kk -j branch2" \ -"U binfile\.dat -U binfile\.dat -U file1" - - cd ../.. - rm -r 1 - rm -rf ${CVSROOT_DIRNAME}/first-dir - ;; - - head) - # Testing handling of the HEAD special tag. - # There are many cases involving added and removed files - # which we don't yet try to deal with. - # TODO: We also could be paying much closer attention to - # "head of the trunk" versus "head of the default branch". - # That is what "cvs import" is doing here (but I didn't really - # fully follow through on writing the tests for that case). - mkdir imp-dir - cd imp-dir - echo 'imported contents' >file1 - # It may seem like we don't do much with file2, but do note that - # the "cvs diff" invocations do also diff file2 (and come up empty). - echo 'imported contents' >file2 - dotest_sort head-1 "${testcvs} import -m add first-dir tag1 tag2" \ -" - -N first-dir/file1 -N first-dir/file2 -No conflicts created by this import" - cd .. - rm -r imp-dir - mkdir 1 - cd 1 - dotest head-2 "${testcvs} -q co first-dir" \ -"U first-dir/file1 -U first-dir/file2" - cd first-dir - echo 'add a line on trunk' >> file1 - dotest head-3 "${testcvs} -q ci -m modify" \ -"Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -new revision: 1\.2; previous revision: 1\.1 -done" - dotest head-4 "${testcvs} -q tag trunktag" "T file1 -T file2" - echo 'add a line on trunk after trunktag' >> file1 - dotest head-5 "${testcvs} -q ci -m modify" \ -"Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -new revision: 1\.3; previous revision: 1\.2 -done" - dotest head-6 "${testcvs} -q tag -b br1" "T file1 -T file2" - dotest head-7 "$testcvs -q update -r br1" \ -'[UP] file1 -[UP] file2' - echo 'modify on branch' >>file1 - dotest head-8 "${testcvs} -q ci -m modify" \ -"Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -new revision: 1\.3\.2\.1; previous revision: 1\.3 -done" - dotest head-9 "${testcvs} -q tag brtag" "T file1 -T file2" - echo 'modify on branch after brtag' >>file1 - dotest head-10 "${testcvs} -q ci -m modify" \ -"Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -new revision: 1\.3\.2\.2; previous revision: 1\.3\.2\.1 -done" - # With no sticky tags, HEAD is the head of the trunk. - dotest head-trunk-setup "$testcvs -q update -A" \ -'[UP] file1 -[UP] file2' - dotest head-trunk-update "${testcvs} -q update -r HEAD -p file1" \ -"imported contents -add a line on trunk -add a line on trunk after trunktag" - # and diff thinks so too. Case (a) from the comment in - # cvs.texinfo (Common options). - dotest_fail head-trunk-diff "${testcvs} -q diff -c -r HEAD -r br1" \ -"Index: file1 -=================================================================== -RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -retrieving revision 1\.3 -retrieving revision 1\.3\.2\.2 -diff -c -r1\.3 -r1\.3\.2\.2 -\*\*\* file1 ${RFCDATE} 1\.3 ---- file1 ${RFCDATE} 1\.3\.2\.2 -\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* -\*\*\* 1,3 \*\*\*\* ---- 1,5 ---- - imported contents - add a line on trunk - add a line on trunk after trunktag -${PLUS} modify on branch -${PLUS} modify on branch after brtag" - - # With a branch sticky tag, HEAD is the head of the trunk. - dotest head-br1-setup "$testcvs -q update -r br1" \ -'[UP] file1 -[UP] file2' - dotest head-br1-update "${testcvs} -q update -r HEAD -p file1" \ -"imported contents -add a line on trunk -add a line on trunk after trunktag" - # But diff thinks that HEAD is "br1". Case (b) from cvs.texinfo. - # Probably people are relying on it. - dotest head-br1-diff "${testcvs} -q diff -c -r HEAD -r br1" "" - - # With a nonbranch sticky tag on a branch, - # HEAD is the head of the trunk - dotest head-brtag-setup "$testcvs -q update -r brtag" \ -'[UP] file1 -[UP] file2' - dotest head-brtag-update "${testcvs} -q update -r HEAD -p file1" \ -"imported contents -add a line on trunk -add a line on trunk after trunktag" - - # CVS 1.9 and older thought that HEAD is "brtag" (this was - # noted as "strange, maybe accidental"). But "br1" makes a - # whole lot more sense. - dotest head-brtag-diff "${testcvs} -q diff -c -r HEAD -r br1" "" - - # With a nonbranch sticky tag on the trunk, HEAD is the head - # of the trunk, I think. - dotest head-trunktag-setup "$testcvs -q update -r trunktag" \ -'[UP] file1 -[UP] file2' - dotest head-trunktag-check "cat file1" "imported contents -add a line on trunk" - dotest head-trunktag-update "${testcvs} -q update -r HEAD -p file1" \ -"imported contents -add a line on trunk -add a line on trunk after trunktag" - # Like head-brtag-diff, there is a non-branch sticky tag. - dotest_fail head-trunktag-diff \ - "${testcvs} -q diff -c -r HEAD -r br1" \ -"Index: file1 -=================================================================== -RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -retrieving revision 1\.3 -retrieving revision 1\.3\.2\.2 -diff -c -r1\.3 -r1\.3\.2\.2 -\*\*\* file1 ${RFCDATE} 1\.3 ---- file1 ${RFCDATE} 1\.3\.2\.2 -\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* -\*\*\* 1,3 \*\*\*\* ---- 1,5 ---- - imported contents - add a line on trunk - add a line on trunk after trunktag -${PLUS} modify on branch -${PLUS} modify on branch after brtag" - - # Also might test what happens if we setup with update -r - # HEAD. In general, if sticky tags matter, does the - # behavior of "update -r " (without -p) depend on the - # sticky tags before or after the update? - - # Note that we are testing both the case where this deletes - # a revision (file1) and the case where it does not (file2) - dotest_fail head-o0a "${testcvs} admin -o ::br1" \ -"${PROG} admin: Administrating \. -RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -${PROG} admin: cannot remove revision 1\.3\.2\.1 because it has tags -${PROG} admin: RCS file for .file1. not modified\. -RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v -done" - dotest head-o0b "${testcvs} tag -d brtag" \ -"${PROG} tag: Untagging \. -D file1 -D file2" - dotest head-o1 "${testcvs} admin -o ::br1" \ -"${PROG} admin: Administrating \. -RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -deleting revision 1\.3\.2\.1 -done -RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v -done" - cd ../.. - rm -r 1 - rm -rf ${CVSROOT_DIRNAME}/first-dir - ;; - - tagdate) - # Test combining -r and -D. - # - # Note that this is not a complete test. It relies on the fact - # that update, checkout and export have a LOT of shared code. - # Notice: - # 1) checkout is never tested at all with -r -D - # 2) update never uses an argument to '-D' besides 'now' - # (this test does not provide enough data to prove - # that 'cvs update' with both a '-r' and a '-D' - # specified does not ignore '-D': a 'cvs up - # -r -Dnow' and a 'cvs up -r' - # should specify the same file revision). - # 3) export uses '-r -D', hopefully completing this behavior test - # for checkout and update as well. - # - mkdir 1; cd 1 - save_TZ=$TZ - TZ=UTC; export TZ - dotest tagdate-1 "${testcvs} -q co -l ." '' - mkdir first-dir - dotest tagdate-2 "${testcvs} add first-dir" \ -"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" - cd first-dir - - echo trunk-1 >file1 - dotest tagdate-3 "${testcvs} add file1" \ -"${PROG} add: scheduling file .file1. for addition -${PROG} add: use .${PROG} commit. to add this file permanently" - dotest tagdate-4 "${testcvs} -q ci -m add" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -done -Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -initial revision: 1\.1 -done" - date_T1=`getrlogdate -r1.1 first-dir/file1` - - dotest tagdate-5 "${testcvs} -q tag -b br1" "T file1" - dotest tagdate-6 "${testcvs} -q tag -b br2" "T file1" - echo trunk-2 >file1 - dotest tagdate-7 "${testcvs} -q ci -m modify-on-trunk" \ -"Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -new revision: 1\.2; previous revision: 1\.1 -done" - date_T2=`getrlogdate -r1.2 first-dir/file1` - - # We are testing -r -D where br1 is a (magic) branch without - # any revisions. First the case where br2 doesn't have any - # revisions either: - dotest tagdate-8 "${testcvs} -q update -p -r br1 -D now" "trunk-1" - dotest tagdate-9 "${testcvs} -q update -r br2" "[UP] file1" - echo br2-1 >file1 - dotest tagdate-10 "${testcvs} -q ci -m modify-on-br2" \ -"Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -new revision: 1\.1\.4\.1; previous revision: 1\.1 -done" - date_T3=`getrlogdate -r1.1.4.1 first-dir/file1` - - # Then the case where br2 does have revisions: - dotest tagdate-11 "${testcvs} -q update -p -r br1 -D now" "trunk-1" - - # For some reason, doing this on a branch seems to be relevant. - dotest_fail tagdate-12 "${testcvs} -q update -j:yesterday" \ -"${PROG} \[update aborted\]: argument to join may not contain a date specifier without a tag" - # And check export - - echo br2-2 >file1 - dotest tagdate-13 "${testcvs} -q ci -m modify-2-on-br2" \ -"Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -new revision: 1\.1\.4\.2; previous revision: 1\.1\.4\.1 -done" - date_T4=`getrlogdate -r1.1.4.2 first-dir/file1` - - cd ../.. - mkdir 2; cd 2 - dotest tagdate-14 "${testcvs} -q export -r br2 -D'$date_T3' first-dir" \ -"[UP] first-dir/file1" - dotest tagdate-15 "cat first-dir/file1" "br2-1" - - # Now for annotate - cd ../1/first-dir - dotest tagdate-16 "${testcvs} annotate -rbr2 -D'$date_T3'" \ -" -Annotations for file1 -\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* -1\.1\.4\.1 ($username8 *[0-9a-zA-Z-]*): br2-1" - - dotest tagdate-17 "${testcvs} annotate -rbr2 -Dnow" \ -" -Annotations for file1 -\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* -1\.1\.4\.2 ($username8 *[0-9a-zA-Z-]*): br2-2" - - # Now check to see what happens when we add files to br2 and trunk - echo br2-1 > file3 - dotest tagdate-18 "${testcvs} add file3" \ -"${PROG} add: scheduling file \`file3' for addition on branch \`br2' -${PROG} add: use .${PROG} commit. to add this file permanently" - dotest tagdate-19 "${testcvs} -q ci -m add file3" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/Attic/file3,v -done -Checking in file3; -${CVSROOT_DIRNAME}/first-dir/Attic/file3,v <-- file3 -new revision: 1\.1\.2\.1; previous revision: 1\.1 -done" - date_T5=`getrlogdate -r1.1 first-dir/file3` - date_T6=`getrlogdate -r1.1.2.1 first-dir/file3` - - cd ../.. - mkdir 3; cd 3 - dotest tagdate-20 "${testcvs} -Q co first-dir" '' - cd first-dir - echo trunk-1 > file2 - dotest tagdate-21 "${testcvs} add file2" \ -"${PROG} add: scheduling file .file2. for addition -${PROG} add: use .${PROG} commit. to add this file permanently" - dotest tagdate-22 "${testcvs} -q ci -m add file2" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v -done -Checking in file2; -${CVSROOT_DIRNAME}/first-dir/file2,v <-- file2 -initial revision: 1\.1 -done" - date_T7=`getrlogdate -r1.1 first-dir/file2` - echo "trunk-2" >file2 - dotest tagdate-23 "${testcvs} -q ci -m update file2" \ -"Checking in file2; -${CVSROOT_DIRNAME}/first-dir/file2,v <-- file2 -new revision: 1\.2; previous revision: 1\.1 -done" - date_T8=`getrlogdate -r1.2 first-dir/file2` - - cd ../../1/first-dir - echo br2-1 > file2 - dotest tagdate-24 "${testcvs} add file2" \ -"${PROG} add: scheduling file \`file2' for addition on branch \`br2' -${PROG} add: use .${PROG} commit. to add this file permanently" - dotest tagdate-25 "${testcvs} -q ci -m add file2" \ -"Checking in file2; -${CVSROOT_DIRNAME}/first-dir/file2,v <-- file2 -new revision: 1\.2\.2\.2; previous revision: 1\.2\.2\.1 -done" - date_T9=`getrlogdate -r1.2.2.2 first-dir/file2` - cd ../.. - - # Time Rev Branch Comments - # T0 trunk first-dir created - # T1 1.1 trunk first-dir/file1 committed "trunk-1" - # br1 branch created - # br2 branch created - # T2 1.2 trunk first-dir/file1 committed "trunk-2" - # T3 1.1.4.1 br2 first-dir/file1 committed "br2-1" - # +60s - # T4 1.1.4.2 br2 first-dir/file1 committed "br2-2" - # T5 1.1 trunk first-dir/file3 dead - # T6 1.1.2.1 br2 first-dir/file3 committed "br2-1" - # T7 1.1 trunk first-dir/file2 committed "trunk-1" - # T8 1.2 trunk first-dir/file2 committed "trunk-2" - # T8 1.2.2.1 br2 first-dir/file2 dead - # T9 1.2.2.2 br2 first-dir/file2 committed "br2-1" - # - - mkdir 4; cd 4 - (echo Dates for tagdate-26-* are:;\ - echo " date_T1='$date_T1'";\ - echo " date_T2='$date_T2'";\ - echo " date_T3='$date_T3'";\ - echo " date_T4='$date_T4'";\ - echo " date_T5='$date_T5'";\ - echo " date_T6='$date_T6'";\ - echo " date_T7='$date_T7'";\ - echo " date_T8='$date_T8'";\ - echo " date_T9='$date_T9'") >>$LOGFILE - dotest tagdate-26-trunk-t1 \ -"${testcvs} co -D'$date_T1' -d first-dir-trunk-t1 first-dir" \ -"${PROG} checkout: Updating first-dir-trunk-t1 -U first-dir-trunk-t1/file1" - dotest tagdate-26-br2-t1 \ -"${testcvs} co -r br2 -D'$date_T1' -d first-dir-br2-t1 first-dir" \ -"${PROG} checkout: Updating first-dir-br2-t1 -U first-dir-br2-t1/file1" - dotest tagdate-26-trunk-t2 \ -"${testcvs} co -D'$date_T2' -d first-dir-trunk-t2 first-dir" \ -"${PROG} checkout: Updating first-dir-trunk-t2 -U first-dir-trunk-t2/file1" - dotest tagdate-26-br2-t2 \ -"${testcvs} co -r br2 -D'$date_T2' -d first-dir-br2-t2 first-dir" \ -"${PROG} checkout: Updating first-dir-br2-t2 -U first-dir-br2-t2/file1" - dotest tagdate-26-br2-t3 \ -"${testcvs} co -r br2 -D'$date_T3' -d first-dir-br2-t3 first-dir" \ -"${PROG} checkout: Updating first-dir-br2-t3 -U first-dir-br2-t3/file1" - dotest tagdate-26-br2-t4 \ -"${testcvs} co -r br2 -D'$date_T4' -d first-dir-br2-t4 first-dir" \ -"${PROG} checkout: Updating first-dir-br2-t4 -U first-dir-br2-t4/file1" - dotest tagdate-26-br2-t6 \ -"${testcvs} co -r br2 -D'$date_T6' -d first-dir-br2-t6 first-dir" \ -"${PROG} checkout: Updating first-dir-br2-t6 -U first-dir-br2-t6/file1 -U first-dir-br2-t6/file3" - dotest tagdate-26-trunk-t7 \ -"${testcvs} co -D'$date_T7' -d first-dir-trunk-t7 first-dir" \ -"${PROG} checkout: Updating first-dir-trunk-t7 -U first-dir-trunk-t7/file1 -U first-dir-trunk-t7/file2" - dotest tagdate-26-br2-t7 \ -"${testcvs} co -r br2 -D'$date_T7' -d first-dir-br2-t7 first-dir" \ -"${PROG} checkout: Updating first-dir-br2-t7 -U first-dir-br2-t7/file1 -U first-dir-br2-t7/file3" - dotest tagdate-26-trunk-t8 \ -"${testcvs} co -D'$date_T8' -d first-dir-trunk-t8 first-dir" \ -"${PROG} checkout: Updating first-dir-trunk-t8 -U first-dir-trunk-t8/file1 -U first-dir-trunk-t8/file2" - dotest tagdate-26-br2-t8 \ -"${testcvs} co -r br2 -D'$date_T8' -d first-dir-br2-t8 first-dir" \ -"${PROG} checkout: Updating first-dir-br2-t8 -U first-dir-br2-t8/file1 -U first-dir-br2-t8/file3" - dotest tagdate-26-br2-t9 \ -"${testcvs} co -r br2 -D'$date_T9' -d first-dir-br2-t9 first-dir" \ -"${PROG} checkout: Updating first-dir-br2-t9 -U first-dir-br2-t9/file1 -U first-dir-br2-t9/file2 -U first-dir-br2-t9/file3" - dotest tagdate-27-trunk-t1 \ -"${testcvs} status first-dir-trunk-t1" \ -"${PROG} status: Examining first-dir-trunk-t1 -=================================================================== -File: file1 Status: Up-to-date - - Working revision: 1\.1[^.]* - Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/file1,v - Sticky Tag: (none) - Sticky Date: [0-9.]* - Sticky Options: (none)" - dotest tagdate-27-br2-t1 \ -"${testcvs} status first-dir-br2-t1" \ -"${PROG} status: Examining first-dir-br2-t1 -=================================================================== -File: file1 Status: Needs Patch - - Working revision: 1\.1[^.]* - Repository revision: 1\.1\.4\.2 ${CVSROOT_DIRNAME}/first-dir/file1,v - Sticky Tag: br2 (branch: 1\.1\.4) - Sticky Date: (none) - Sticky Options: (none)" - dotest tagdate-27-trunk-t2 \ -"${testcvs} status first-dir-trunk-t2" \ -"${PROG} status: Examining first-dir-trunk-t2 -=================================================================== -File: file1 Status: Up-to-date - - Working revision: 1\.2[^.]* - Repository revision: 1\.2 ${CVSROOT_DIRNAME}/first-dir/file1,v - Sticky Tag: (none) - Sticky Date: [0-9.]* - Sticky Options: (none)" - dotest tagdate-27-br2-t2 \ -"${testcvs} status first-dir-br2-t2" \ -"${PROG} status: Examining first-dir-br2-t2 -=================================================================== -File: file1 Status: Needs Patch - - Working revision: 1\.1[^.]* - Repository revision: 1\.1\.4\.2 ${CVSROOT_DIRNAME}/first-dir/file1,v - Sticky Tag: br2 (branch: 1\.1\.4) - Sticky Date: (none) - Sticky Options: (none)" - dotest tagdate-27-br2-t3 \ -"${testcvs} status first-dir-br2-t3" \ -"${PROG} status: Examining first-dir-br2-t3 -=================================================================== -File: file1 Status: Needs Patch - - Working revision: 1\.1\.4\.1[^.]* - Repository revision: 1\.1\.4\.2 ${CVSROOT_DIRNAME}/first-dir/file1,v - Sticky Tag: br2 (branch: 1\.1\.4) - Sticky Date: (none) - Sticky Options: (none)" - dotest tagdate-27-br2-t4 \ -"${testcvs} status first-dir-br2-t4" \ -"${PROG} status: Examining first-dir-br2-t4 -=================================================================== -File: file1 Status: Up-to-date - - Working revision: 1\.1\.4\.2[^.]* - Repository revision: 1\.1\.4\.2 ${CVSROOT_DIRNAME}/first-dir/file1,v - Sticky Tag: br2 (branch: 1\.1\.4) - Sticky Date: (none) - Sticky Options: (none)" - dotest tagdate-27-br2-t6 \ -"${testcvs} status first-dir-br2-t6" \ -"${PROG} status: Examining first-dir-br2-t6 -=================================================================== -File: file1 Status: Up-to-date - - Working revision: 1\.1\.4\.2[^.]* - Repository revision: 1\.1\.4\.2 ${CVSROOT_DIRNAME}/first-dir/file1,v - Sticky Tag: br2 (branch: 1\.1\.4) - Sticky Date: (none) - Sticky Options: (none) - -=================================================================== -File: file3 Status: Up-to-date - - Working revision: 1\.1\.2\.1[^.]* - Repository revision: 1\.1\.2\.1 ${CVSROOT_DIRNAME}/first-dir/Attic/file3,v - Sticky Tag: br2 (branch: 1\.1\.2) - Sticky Date: (none) - Sticky Options: (none)" - dotest tagdate-27-trunk-t7 \ -"${testcvs} status first-dir-trunk-t7" \ -"${PROG} status: Examining first-dir-trunk-t7 -=================================================================== -File: file1 Status: Up-to-date - - Working revision: 1\.2[^.]* - Repository revision: 1\.2 ${CVSROOT_DIRNAME}/first-dir/file1,v - Sticky Tag: (none) - Sticky Date: [0-9.]* - Sticky Options: (none) - -=================================================================== -File: file2 Status: Up-to-date - - Working revision: 1\.1[^.]* - Repository revision: 1\.1 ${CVSROOT_DIRNAME}/first-dir/file2,v - Sticky Tag: (none) - Sticky Date: [0-9.]* - Sticky Options: (none)" - dotest tagdate-27-br2-t7 \ -"${testcvs} status first-dir-br2-t7" \ -"${PROG} status: Examining first-dir-br2-t7 -=================================================================== -File: file1 Status: Up-to-date - - Working revision: 1\.1\.4\.2[^.]* - Repository revision: 1\.1\.4\.2 ${CVSROOT_DIRNAME}/first-dir/file1,v - Sticky Tag: br2 (branch: 1\.1\.4) - Sticky Date: (none) - Sticky Options: (none) - -=================================================================== -File: file3 Status: Up-to-date - - Working revision: 1\.1\.2\.1[^.]* - Repository revision: 1\.1\.2\.1 ${CVSROOT_DIRNAME}/first-dir/Attic/file3,v - Sticky Tag: br2 (branch: 1\.1\.2) - Sticky Date: (none) - Sticky Options: (none)" - dotest tagdate-27-trunk-t8 \ -"${testcvs} status first-dir-trunk-t8" \ -"${PROG} status: Examining first-dir-trunk-t8 -=================================================================== -File: file1 Status: Up-to-date - - Working revision: 1\.2[^.]* - Repository revision: 1\.2 ${CVSROOT_DIRNAME}/first-dir/file1,v - Sticky Tag: (none) - Sticky Date: [0-9.]* - Sticky Options: (none) - -=================================================================== -File: file2 Status: Up-to-date - - Working revision: 1\.2[^.]* - Repository revision: 1\.2 ${CVSROOT_DIRNAME}/first-dir/file2,v - Sticky Tag: (none) - Sticky Date: [0-9.]* - Sticky Options: (none)" - dotest tagdate-27-br2-t8 \ -"${testcvs} status first-dir-br2-t8" \ -"${PROG} status: Examining first-dir-br2-t8 -=================================================================== -File: file1 Status: Up-to-date - - Working revision: 1\.1\.4\.2[^.]* - Repository revision: 1\.1\.4\.2 ${CVSROOT_DIRNAME}/first-dir/file1,v - Sticky Tag: br2 (branch: 1\.1\.4) - Sticky Date: (none) - Sticky Options: (none) - -=================================================================== -File: file3 Status: Up-to-date - - Working revision: 1\.1\.2\.1[^.]* - Repository revision: 1\.1\.2\.1 ${CVSROOT_DIRNAME}/first-dir/Attic/file3,v - Sticky Tag: br2 (branch: 1\.1\.2) - Sticky Date: (none) - Sticky Options: (none)" - dotest tagdate-27-br2-t9 \ -"${testcvs} status first-dir-br2-t9" \ -"${PROG} status: Examining first-dir-br2-t9 -=================================================================== -File: file1 Status: Up-to-date - - Working revision: 1\.1\.4\.2[^.]* - Repository revision: 1\.1\.4\.2 ${CVSROOT_DIRNAME}/first-dir/file1,v - Sticky Tag: br2 (branch: 1\.1\.4) - Sticky Date: (none) - Sticky Options: (none) - -=================================================================== -File: file2 Status: Up-to-date - - Working revision: 1\.2\.2\.2[^.]* - Repository revision: 1\.2\.2\.2 ${CVSROOT_DIRNAME}/first-dir/file2,v - Sticky Tag: br2 (branch: 1\.2\.2) - Sticky Date: (none) - Sticky Options: (none) - -=================================================================== -File: file3 Status: Up-to-date - - Working revision: 1\.1\.2\.1[^.]* - Repository revision: 1\.1\.2\.1 ${CVSROOT_DIRNAME}/first-dir/Attic/file3,v - Sticky Tag: br2 (branch: 1\.1\.2) - Sticky Date: (none) - Sticky Options: (none)" - - # Now check the contents of the files - dotest tagdate-28-trunk-t1 'cat first-dir-trunk-t1/file1' 'trunk-1' - dotest tagdate-28-br2-t1 'cat first-dir-br2-t1/file1' 'trunk-1' - dotest tagdate-28-trunk-t2 'cat first-dir-trunk-t2/file1' 'trunk-2' - dotest tagdate-28-br2-t2 'cat first-dir-br2-t2/file1' 'trunk-1' - dotest tagdate-28-br2-t3 'cat first-dir-br2-t3/file1' 'br2-1' - dotest tagdate-28-br2-t4 'cat first-dir-br2-t4/file1' 'br2-2' - dotest tagdate-28-br2-t6a 'cat first-dir-br2-t6/file1' "br2-2" - dotest tagdate-28-br2-t6b 'cat first-dir-br2-t6/file3' "br2-1" - dotest tagdate-28-trunk-t7a 'cat first-dir-trunk-t7/file1' "trunk-2" - dotest tagdate-28-trunk-t7b 'cat first-dir-trunk-t7/file2' "trunk-1" - dotest tagdate-28-br2-t7a 'cat first-dir-br2-t7/file1' "br2-2" - dotest tagdate-28-br2-t7b 'cat first-dir-br2-t7/file3' "br2-1" - dotest tagdate-28-trunk-t8a 'cat first-dir-trunk-t8/file1' "trunk-2" - dotest tagdate-28-trunk-t8b 'cat first-dir-trunk-t8/file2' "trunk-2" - dotest tagdate-28-br2-t8a 'cat first-dir-br2-t8/file1' "br2-2" - dotest tagdate-28-br2-t8c 'cat first-dir-br2-t8/file3' "br2-1" - dotest tagdate-28-br2-t9a 'cat first-dir-br2-t9/file1' "br2-2" - dotest tagdate-28-br2-t9b 'cat first-dir-br2-t9/file2' "br2-1" - dotest tagdate-28-br2-t9c 'cat first-dir-br2-t9/file3' "br2-1" - cd .. - - unset date_T1 date_T2 date_T3 date_T4 date_T5 - unset date_T6 date_T7 date_T8 date_T9 - TZ=$save_TZ - - if $keep; then - echo Keeping ${TESTDIR} and exiting due to --keep - exit 0 - fi - - rm -r 1 2 3 4 - rm -rf ${CVSROOT_DIRNAME}/first-dir - ;; - - multibranch2) - # Commit the first delta on branch A when there is an older - # branch, B, that already has a delta. A and B come from the - # same branch point. Then verify that branches A and B are - # in the right order. - mkdir 1; cd 1 - dotest multibranch2-1 "${testcvs} -q co -l ." '' - mkdir first-dir - dotest multibranch2-2 "${testcvs} add first-dir" \ -"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" - cd first-dir - - echo trunk-1 >file1 - echo trunk-1 >file2 - dotest multibranch2-3 "${testcvs} add file1 file2" \ -"${PROG} add: scheduling file .file1. for addition -${PROG} add: scheduling file .file2. for addition -${PROG} add: use .${PROG} commit. to add these files permanently" - dotest multibranch2-4 "${testcvs} -q ci -m add" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -done -Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -initial revision: 1\.1 -done -RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v -done -Checking in file2; -${CVSROOT_DIRNAME}/first-dir/file2,v <-- file2 -initial revision: 1\.1 -done" - dotest multibranch2-5 "${testcvs} -q tag -b A" "T file1 -T file2" - dotest multibranch2-6 "${testcvs} -q tag -b B" "T file1 -T file2" - - dotest multibranch2-7 "$testcvs -q update -r B" \ -'[UP] file1 -[UP] file2' - echo branch-B >file1 - echo branch-B >file2 - dotest multibranch2-8 "${testcvs} -q ci -m modify-on-B" \ -"Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -new revision: 1\.1\.4\.1; previous revision: 1\.1 -done -Checking in file2; -${CVSROOT_DIRNAME}/first-dir/file2,v <-- file2 -new revision: 1\.1\.4\.1; previous revision: 1\.1 -done" - - dotest multibranch2-9 "${testcvs} -q update -r A" '[UP] file1 -[UP] file2' - echo branch-A >file1 - # When using cvs-1.9.20, this commit gets a failed assertion in rcs.c. - dotest multibranch2-10 "${testcvs} -q ci -m modify-on-A" \ -"Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -new revision: 1\.1\.2\.1; previous revision: 1\.1 -done" - - dotest multibranch2-11 "${testcvs} -q log file1" \ -" -RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -Working file: file1 -head: 1\.1 -branch: -locks: strict -access list: -symbolic names: - B: 1\.1\.0\.4 - A: 1\.1\.0\.2 -keyword substitution: kv -total revisions: 3; selected revisions: 3 -description: ----------------------------- -revision 1\.1 -date: [0-9/]* [0-9:]*; author: $username; state: Exp; -branches: 1\.1\.2; 1\.1\.4; -add ----------------------------- -revision 1\.1\.4\.1 -date: [0-9/]* [0-9:]*; author: $username; state: Exp; lines: ${PLUS}1 -1 -modify-on-B ----------------------------- -revision 1\.1\.2\.1 -date: [0-9/]* [0-9:]*; author: $username; state: Exp; lines: ${PLUS}1 -1 -modify-on-A -=============================================================================" - - # This one is more concise. - dotest multibranch2-12 "${testcvs} -q log -r1.1 file1" \ -" -RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -Working file: file1 -head: 1\.1 -branch: -locks: strict -access list: -symbolic names: - B: 1\.1\.0\.4 - A: 1\.1\.0\.2 -keyword substitution: kv -total revisions: 3; selected revisions: 1 -description: ----------------------------- -revision 1\.1 -date: [0-9/]* [0-9:]*; author: $username; state: Exp; -branches: 1\.1\.2; 1\.1\.4; -add -=============================================================================" - - # OK, try very much the same thing except we run update -j to - # bring the changes from B to A. Probably tests many of the - # same code paths but might as well keep it separate, I guess. - - dotest multibranch2-13 "${testcvs} -q update -r B" "[UP] file1 -[UP] file2" - dotest multibranch2-14 "${testcvs} -q update -r A -j B file2" \ -"[UP] file2 -RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v -retrieving revision 1.1 -retrieving revision 1.1.4.1 -Merging differences between 1.1 and 1.1.4.1 into file2" - dotest multibranch2-15 "${testcvs} -q ci -m commit-on-A file2" \ -"Checking in file2; -${CVSROOT_DIRNAME}/first-dir/file2,v <-- file2 -new revision: 1\.1\.2\.1; previous revision: 1\.1 -done" - cd ../.. - rm -r 1 - rm -rf ${CVSROOT_DIRNAME}/first-dir - ;; - - tag8k) - # In cvs-1.9.27, there is a bug that can cause an abort. - # It happens when you commit a change to a ,v file that has - # just the right amount of tag/branch info to align one of the - # semicolons in the branch info to be on a 8k-byte boundary. - # The result: rcsbuf_getkey got an abort. This failure doesn't - # corrupt the ,v file -- that would be really serious. But it - # does leave stale write locks that have to be removed manually. - - mkdir 1 - cd 1 - - module=x - - : > junk - dotest tag8k-1 "$testcvs -Q import -m . $module X Y" '' - dotest tag8k-2 "$testcvs -Q co $module" '' - cd $module - - file=m - : > $file - dotest tag8k-3 "$testcvs add $file" \ -"${PROG} add: scheduling file .$file. for addition -${PROG} add: use .${PROG} commit. to add this file permanently" - dotest tag8k-4 "$testcvs -Q ci -m . $file" \ -"RCS file: ${CVSROOT_DIRNAME}/$module/$file,v -done -Checking in $file; -${CVSROOT_DIRNAME}/$module/$file,v <-- $file -initial revision: 1\.1 -done" - - # It seems there have to be at least two versions. - echo a > $file - dotest tag8k-5 "$testcvs -Q ci -m . $file" \ -"Checking in $file; -${CVSROOT_DIRNAME}/$module/$file,v <-- $file -new revision: 1\.2; previous revision: 1\.1 -done" - - # Add just under 8K worth of tags. - t=TAG--------------------------------------------------------------------- - t=$t$t - t=$t$t$t$t$t - # Now $t is 720 bytes long. - - # Apply some tags with that long prefix. - dotest tag8k-6 "$testcvs -Q tag $t-0 $file" '' - dotest tag8k-7 "$testcvs -Q tag $t-1 $file" '' - dotest tag8k-8 "$testcvs -Q tag $t-2 $file" '' - dotest tag8k-9 "$testcvs -Q tag $t-3 $file" '' - dotest tag8k-10 "$testcvs -Q tag $t-4 $file" '' - dotest tag8k-11 "$testcvs -Q tag $t-5 $file" '' - dotest tag8k-12 "$testcvs -Q tag $t-6 $file" '' - dotest tag8k-13 "$testcvs -Q tag $t-7 $file" '' - dotest tag8k-14 "$testcvs -Q tag $t-8 $file" '' - dotest tag8k-15 "$testcvs -Q tag $t-9 $file" '' - dotest tag8k-16 "$testcvs -Q tag $t-a $file" '' - - # Extract the author value. - name=`sed -n 's/.*; author \([^;]*\);.*/\1/p' ${CVSROOT_DIRNAME}/$module/$file,v|sed 1q` - - # Form a suffix string of length (16 - length($name)). - # CAREFUL: this will lose if $name is longer than 16. - sed_pattern=`echo $name|sed s/././g` - suffix=`echo 1234567890123456|sed s/$sed_pattern//` - - # Add a final tag with length chosen so that it will push the - # offset of the `;' in the 2nd occurrence of `;\tauthor' in the - # ,v file to exactly 8192. - dotest tag8k-17 "$testcvs -Q tag "x8bytes-$suffix" $file" '' - - # This commit would fail with 1.9.27. - echo a >> $file - dotest tag8k-18 "$testcvs -Q ci -m . $file" \ -"Checking in $file; -${CVSROOT_DIRNAME}/$module/$file,v <-- $file -new revision: 1\.3; previous revision: 1\.2 -done" - cd ../.. - rm -r 1 - rm -rf ${CVSROOT_DIRNAME}/$module - ;; - - - admin) - # More "cvs admin" tests. - # The basicb-21 test tests rejecting an illegal option. - # For -l and -u, see "reserved" and "keyword" tests. - # "binfiles" test has a test of "cvs admin -k". - # "log2" test has tests of -t and -q options to cvs admin. - # "rcs" tests -b option also. - # For -o, see: - # admin-22-o1 through admin-23 (various cases not involving ::) - # binfiles2-o* (:rev, rev on trunk; rev:, deleting entire branch) - # basicb-o* (attempt to delete all revisions) - # basica-o1 through basica-o3 (basic :: usage) - # head-o1 (::branch, where this deletes a revision or is noop) - # branches-o1 (::branch, similar, with different branch topology) - # log-o1 (1.3.2.1::) - # binfiles-o1 (1.3:: and ::1.3; binary files) - # binfiles3-9 (binary files) - # Also could be testing: - # 1.3.2.6::1.3.2.8 - # 1.3.2.6::1.3.2 - # 1.3.2.1::1.3.2.6 - # 1.3::1.3.2.6 (error? or synonym for ::1.3.2.6?) - # -n: admin, tagf tests. - - mkdir 1; cd 1 - dotest admin-1 "${testcvs} -q co -l ." '' - mkdir first-dir - dotest admin-2 "${testcvs} add first-dir" \ -"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" - cd first-dir - - dotest_fail admin-3 "${testcvs} -q admin -i file1" \ -"${PROG} admin: the -i option to admin is not supported -${PROG} admin: run add or import to create an RCS file -${PROG} \[admin aborted\]: specify ${PROG} -H admin for usage information" - dotest_fail admin-4 "${testcvs} -q log file1" \ -"${PROG} log: nothing known about file1" - dotest_fail admin-4a "${testcvs} -q admin file1" \ -"${PROG} admin: nothing known about file1" - - # Set up some files, file2 a plain one and file1 with a revision - # on a branch. - touch file1 file2 - dotest admin-5 "${testcvs} add file1 file2" \ -"${PROG} add: scheduling file .file1. for addition -${PROG} add: scheduling file .file2. for addition -${PROG} add: use .${PROG} commit. to add these files permanently" - dotest admin-6 "${testcvs} -q ci -m add" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -done -Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -initial revision: 1\.1 -done -RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v -done -Checking in file2; -${CVSROOT_DIRNAME}/first-dir/file2,v <-- file2 -initial revision: 1\.1 -done" - dotest admin-7 "${testcvs} -q tag -b br" "T file1 -T file2" - dotest admin-8 "$testcvs -q update -r br" \ -'U file1 -U file2' - echo 'add a line on the branch' >> file1 - echo 'add a file on the branch' >> file3 - dotest admin-9a "${testcvs} -q add file3" \ -"${PROG} add: use .${PROG} commit. to add this file permanently" - dotest admin-9b "${testcvs} -q ci -m modify-on-branch" \ -"Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -new revision: 1\.1\.2\.1; previous revision: 1\.1 -done -RCS file: ${CVSROOT_DIRNAME}/first-dir/Attic/file3,v -done -Checking in file3; -${CVSROOT_DIRNAME}/first-dir/Attic/file3,v <-- file3 -new revision: 1\.1\.2\.1; previous revision: 1\.1 -done" - dotest admin-10 "$testcvs -q update -A" \ -"U file1 -U file2 -$PROG update: file3 is no longer in the repository" - - # Check that we can administer files in the repository that - # aren't in the working directory. - dotest admin-10-1 "${testcvs} admin ." \ -"${PROG} admin: Administrating . -RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -done -RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v -done" - dotest admin-10-2 "${testcvs} -q admin file3" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/Attic/file3,v -done" - - # Try to recurse with a numeric revision arg. - # If we wanted to comprehensive about this, we would also test - # this for -l, -u, and all the different -o syntaxes. - dotest_fail admin-10a "${testcvs} -q admin -b1.1.2" \ -"${PROG} [a-z]*: while processing more than one file: -${PROG} \[[a-z]* aborted\]: attempt to specify a numeric revision" - dotest_fail admin-10b "${testcvs} -q admin -m1.1:bogus file1 file2" \ -"${PROG} [a-z]*: while processing more than one file: -${PROG} \[[a-z]* aborted\]: attempt to specify a numeric revision" - - # try a bad symbolic revision - dotest_fail admin-10c "${testcvs} -q admin -bBOGUS" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -${PROG} admin: ${CVSROOT_DIRNAME}/first-dir/file1,v: Symbolic name BOGUS is undefined. -${PROG} admin: RCS file for .file1. not modified\. -RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v -${PROG} admin: ${CVSROOT_DIRNAME}/first-dir/file2,v: Symbolic name BOGUS is undefined. -${PROG} admin: RCS file for .file2. not modified\." - - # Note that -s option applies to the new default branch, not - # the old one. - # Also note that the implementation of -a via "rcs" requires - # no space between -a and the argument. However, we expect - # to change that once CVS parses options. - dotest admin-11 "${testcvs} -q admin -afoo,bar -abaz \ --b1.1.2 -cxx -U -sfoo file1" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -done" - dotest admin-11a "${testcvs} log -N file1" " -RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -Working file: file1 -head: 1\.1 -branch: 1\.1\.2 -locks: -access list: - foo - bar - baz -keyword substitution: kv -total revisions: 2; selected revisions: 2 -description: ----------------------------- -revision 1\.1 -date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; -branches: 1\.1\.2; -add ----------------------------- -revision 1\.1\.2\.1 -date: [0-9/]* [0-9:]*; author: ${username}; state: foo; lines: ${PLUS}1 -0 -modify-on-branch -=============================================================================" - dotest admin-12 "${testcvs} -q admin -bbr file1" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -done" - dotest admin-12a "${testcvs} log -N file1" " -RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -Working file: file1 -head: 1\.1 -branch: 1\.1\.2 -locks: -access list: - foo - bar - baz -keyword substitution: kv -total revisions: 2; selected revisions: 2 -description: ----------------------------- -revision 1\.1 -date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; -branches: 1\.1\.2; -add ----------------------------- -revision 1\.1\.2\.1 -date: [0-9/]* [0-9:]*; author: ${username}; state: foo; lines: ${PLUS}1 -0 -modify-on-branch -=============================================================================" - - # "cvs log" doesn't print the comment leader. RCS 5.7 will print - # the comment leader only if one specifies "-V4" to rlog. So it - # seems like the only way to test it is by looking at the RCS file - # directly. This also serves as a test of exporting RCS files - # (analogous to the import tests in "rcs"). - # Rather than try to write a rigorous check for whether the - # file CVS exports is legal, we just write a simpler - # test for what CVS actually exports, and figure we can revise - # the check as needed (within the confines of the RCS5 format as - # documented in RCSFILES). - # Note that we must accept either 2 or 4 digit year. - dotest admin-13 "cat ${CVSROOT_DIRNAME}/first-dir/file1,v" \ -"head 1\.1; -branch 1\.1\.2; -access - foo - bar - baz; -symbols - br:1\.1\.0\.2; -locks; -comment @xx@; - - -1\.1 -date [0-9][0-9]*\.[0-9][0-9]\.[0-9][0-9]\.[0-9][0-9]\.[0-9][0-9]\.[0-9][0-9]; author ${username}; state Exp; -branches - 1\.1\.2\.1; -next ; - -1\.1\.2\.1 -date [0-9][0-9]*\.[0-9][0-9]\.[0-9][0-9]\.[0-9][0-9]\.[0-9][0-9]\.[0-9][0-9]; author ${username}; state foo; -branches; -next ; - - -desc -@@ - - -1\.1 -log -@add -@ -text -@@ - - -1\.1\.2\.1 -log -@modify-on-branch -@ -text -@a0 1 -add a line on the branch -@" - dotest_fail admin-14-1 "${testcvs} -q admin \ --m1.1.1.1:changed-bogus-log-message file2" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v -cvs admin: ${CVSROOT_DIRNAME}/first-dir/file2,v: no such revision 1\.1\.1\.1 -cvs admin: RCS file for .file2. not modified." - dotest admin-14-2 "${testcvs} -q log file2" " -RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v -Working file: file2 -head: 1\.1 -branch: -locks: strict -access list: -symbolic names: - br: 1\.1\.0\.2 -keyword substitution: kv -total revisions: 1; selected revisions: 1 -description: ----------------------------- -revision 1\.1 -date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; -add -=============================================================================" - - dotest admin-14-3 "${testcvs} -q admin -aauth3 -aauth2,foo \ --soneone:1.1 -m1.1:changed-log-message -ntagone: file2" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v -done" - dotest admin-15 "${testcvs} -q log file2" " -RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v -Working file: file2 -head: 1\.1 -branch: -locks: strict -access list: - auth3 - auth2 - foo -symbolic names: - tagone: 1\.1 - br: 1\.1\.0\.2 -keyword substitution: kv -total revisions: 1; selected revisions: 1 -description: ----------------------------- -revision 1\.1 -date: [0-9/]* [0-9:]*; author: ${username}; state: oneone; -changed-log-message -=============================================================================" - - dotest admin-16 "${testcvs} -q admin \ --A${CVSROOT_DIRNAME}/first-dir/file2,v -b -L -Nbr:1.1 file1" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -done" - dotest admin-17 "${testcvs} -q log file1" " -RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -Working file: file1 -head: 1\.1 -branch: -locks: strict -access list: - foo - bar - baz - auth3 - auth2 -symbolic names: - br: 1\.1 -keyword substitution: kv -total revisions: 2; selected revisions: 2 -description: ----------------------------- -revision 1\.1 -date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; -branches: 1\.1\.2; -add ----------------------------- -revision 1\.1\.2\.1 -date: [0-9/]* [0-9:]*; author: ${username}; state: foo; lines: ${PLUS}1 -0 -modify-on-branch -=============================================================================" - - dotest_fail admin-18 "${testcvs} -q admin -nbr:1.1.2 file1" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -${PROG} admin: ${CVSROOT_DIRNAME}/first-dir/file1,v: symbolic name br already bound to 1\.1 -${PROG} admin: RCS file for .file1. not modified\." - dotest admin-19 "${testcvs} -q admin -ebaz -ebar,auth3 -nbr file1" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -done" - dotest admin-20 "${testcvs} -q log file1" " -RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -Working file: file1 -head: 1\.1 -branch: -locks: strict -access list: - foo - auth2 -symbolic names: -keyword substitution: kv -total revisions: 2; selected revisions: 2 -description: ----------------------------- -revision 1\.1 -date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; -branches: 1\.1\.2; -add ----------------------------- -revision 1.1.2.1 -date: [0-9/]* [0-9:]*; author: ${username}; state: foo; lines: ${PLUS}1 -0 -modify-on-branch -=============================================================================" - - # OK, this is starting to get ridiculous, in terms of - # testing a feature (access lists) which doesn't do anything - # useful, but what about nonexistent files and - # relative pathnames in admin -A? - dotest_fail admin-19a-nonexist \ -"${testcvs} -q admin -A${TESTDIR}/foo/bar file1" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -${PROG} admin: Couldn't open rcs file .${TESTDIR}/foo/bar.: No such file or directory -${PROG} \[admin aborted\]: cannot continue" - - # In the remote case, we are cd'd off into the temp directory - # and so these tests give "No such file or directory" errors. - if $remote; then :; else - dotest admin-19a-admin "${testcvs} -q admin -A../../${CVSROOTDIR}/first-dir/file2,v file1" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -done" - dotest admin-19a-log "${testcvs} -q log -h -N file1" " -RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -Working file: file1 -head: 1\.1 -branch: -locks: strict -access list: - foo - auth2 - auth3 -keyword substitution: kv -total revisions: 2 -=============================================================================" - fi # end of tests skipped for remote - - # Now test that plain -e works right. - dotest admin-19a-2 "${testcvs} -q admin -e file1" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -done" - dotest admin-19a-3 "${testcvs} -q log -h -N file1" " -RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -Working file: file1 -head: 1\.1 -branch: -locks: strict -access list: -keyword substitution: kv -total revisions: 2 -=============================================================================" - - # Put the access list back, to avoid special cases later. - dotest admin-19a-4 "${testcvs} -q admin -afoo,auth2 file1" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -done" - - # Add another revision to file2, so we can delete one. - echo 'add a line' >> file2 - dotest admin-21 "${testcvs} -q ci -m modify file2" \ -"Checking in file2; -${CVSROOT_DIRNAME}/first-dir/file2,v <-- file2 -new revision: 1\.2; previous revision: 1\.1 -done" - dotest admin-22 "${testcvs} -q admin -o1.1 file2" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v -deleting revision 1\.1 -done" - # Test admin -o. More variants that we could be testing: - # * REV: [on branch] - # * REV1:REV2 [deleting whole branch] - # * high branch numbers (e.g. 1.2.2.3.2.3) - # ... and probably others. See RCS_delete_revs for ideas. - - echo first rev > aaa - dotest admin-22-o1 "${testcvs} add aaa" \ -"${PROG} add: scheduling file .aaa. for addition -${PROG} add: use .${PROG} commit. to add this file permanently" - dotest admin-22-o2 "${testcvs} -q ci -m first aaa" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/aaa,v -done -Checking in aaa; -${CVSROOT_DIRNAME}/first-dir/aaa,v <-- aaa -initial revision: 1\.1 -done" - echo second rev >> aaa - dotest admin-22-o3 "${testcvs} -q ci -m second aaa" \ -"Checking in aaa; -${CVSROOT_DIRNAME}/first-dir/aaa,v <-- aaa -new revision: 1\.2; previous revision: 1\.1 -done" - echo third rev >> aaa - dotest admin-22-o4 "${testcvs} -q ci -m third aaa" \ -"Checking in aaa; -${CVSROOT_DIRNAME}/first-dir/aaa,v <-- aaa -new revision: 1\.3; previous revision: 1\.2 -done" - echo fourth rev >> aaa - dotest admin-22-o5 "${testcvs} -q ci -m fourth aaa" \ -"Checking in aaa; -${CVSROOT_DIRNAME}/first-dir/aaa,v <-- aaa -new revision: 1\.4; previous revision: 1\.3 -done" - echo fifth rev >>aaa - dotest admin-22-o6 "${testcvs} -q ci -m fifth aaa" \ -"Checking in aaa; -${CVSROOT_DIRNAME}/first-dir/aaa,v <-- aaa -new revision: 1\.5; previous revision: 1\.4 -done" - echo sixth rev >> aaa - dotest admin-22-o7 "${testcvs} -q ci -m sixth aaa" \ -"Checking in aaa; -${CVSROOT_DIRNAME}/first-dir/aaa,v <-- aaa -new revision: 1\.6; previous revision: 1\.5 -done" - dotest admin-22-o8 "${testcvs} admin -l1.6 aaa" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/aaa,v -1\.6 locked -done" - dotest admin-22-o9 "${testcvs} log -r1.6 aaa" " -RCS file: ${CVSROOT_DIRNAME}/first-dir/aaa,v -Working file: aaa -head: 1\.6 -branch: -locks: strict - ${username}: 1\.6 -access list: -symbolic names: -keyword substitution: kv -total revisions: 6; selected revisions: 1 -description: ----------------------------- -revision 1\.6 locked by: ${username}; -date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; lines: ${PLUS}1 -0 -sixth -=============================================================================" - dotest_fail admin-22-o10 "${testcvs} admin -o1.5: aaa" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/aaa,v -${PROG} admin: ${CVSROOT_DIRNAME}/first-dir/aaa,v: can't remove locked revision 1\.6 -${PROG} admin: RCS file for .aaa. not modified\." - dotest admin-22-o11 "${testcvs} admin -u aaa" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/aaa,v -1\.6 unlocked -done" - dotest admin-22-o12 "${testcvs} admin -o1.5: aaa" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/aaa,v -deleting revision 1\.6 -deleting revision 1\.5 -done" - dotest admin-22-o13 "${testcvs} log aaa" " -RCS file: ${CVSROOT_DIRNAME}/first-dir/aaa,v -Working file: aaa -head: 1\.4 -branch: -locks: strict -access list: -symbolic names: -keyword substitution: kv -total revisions: 4; selected revisions: 4 -description: ----------------------------- -revision 1\.4 -date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; lines: ${PLUS}1 -0 -fourth ----------------------------- -revision 1\.3 -date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; lines: ${PLUS}1 -0 -third ----------------------------- -revision 1\.2 -date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; lines: ${PLUS}1 -0 -second ----------------------------- -revision 1\.1 -date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; -first -=============================================================================" - - dotest admin-22-o14 "${testcvs} tag -b -r1.3 br1 aaa" "T aaa" - dotest admin-22-o15 "${testcvs} update -rbr1 aaa" "U aaa" - echo new branch rev >> aaa - dotest admin-22-o16 "${testcvs} ci -m new-branch aaa" \ -"Checking in aaa; -${CVSROOT_DIRNAME}/first-dir/aaa,v <-- aaa -new revision: 1\.3\.2\.1; previous revision: 1\.3 -done" - dotest_fail admin-22-o17 "${testcvs} admin -o1.2:1.4 aaa" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/aaa,v -deleting revision 1\.4 -${PROG} admin: ${CVSROOT_DIRNAME}/first-dir/aaa,v: can't remove branch point 1\.3 -${PROG} admin: RCS file for .aaa. not modified\." - dotest admin-22-o18 "${testcvs} update -p -r1.4 aaa" \ -"=================================================================== -Checking out aaa -RCS: ${CVSROOT_DIRNAME}/first-dir/aaa,v -VERS: 1\.4 -\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* -first rev -second rev -third rev -fourth rev" - echo second branch rev >> aaa - dotest admin-22-o19 "${testcvs} ci -m branch-two aaa" \ -"Checking in aaa; -${CVSROOT_DIRNAME}/first-dir/aaa,v <-- aaa -new revision: 1\.3\.2\.2; previous revision: 1\.3\.2\.1 -done" - echo third branch rev >> aaa - dotest admin-22-o20 "${testcvs} ci -m branch-three aaa" \ -"Checking in aaa; -${CVSROOT_DIRNAME}/first-dir/aaa,v <-- aaa -new revision: 1\.3\.2\.3; previous revision: 1\.3\.2\.2 -done" - echo fourth branch rev >> aaa - dotest admin-22-o21 "${testcvs} ci -m branch-four aaa" \ -"Checking in aaa; -${CVSROOT_DIRNAME}/first-dir/aaa,v <-- aaa -new revision: 1\.3\.2\.4; previous revision: 1\.3\.2\.3 -done" - dotest admin-22-o22 "${testcvs} admin -o:1.3.2.3 aaa" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/aaa,v -deleting revision 1\.3\.2\.1 -deleting revision 1\.3\.2\.2 -deleting revision 1\.3\.2\.3 -done" - dotest admin-22-o23 "${testcvs} log aaa" " -RCS file: ${CVSROOT_DIRNAME}/first-dir/aaa,v -Working file: aaa -head: 1\.4 -branch: -locks: strict -access list: -symbolic names: - br1: 1\.3\.0\.2 -keyword substitution: kv -total revisions: 5; selected revisions: 5 -description: ----------------------------- -revision 1\.4 -date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; lines: ${PLUS}1 -0 -fourth ----------------------------- -revision 1\.3 -date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; lines: ${PLUS}1 -0 -branches: 1\.3\.2; -third ----------------------------- -revision 1\.2 -date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; lines: ${PLUS}1 -0 -second ----------------------------- -revision 1\.1 -date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; -first ----------------------------- -revision 1\.3\.2\.4 -date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; lines: ${PLUS}4 -0 -branch-four -=============================================================================" - - dotest admin-22-o24 "${testcvs} -q update -p -r 1.3.2.4 aaa" \ -"first rev -second rev -third rev -new branch rev -second branch rev -third branch rev -fourth branch rev" - - # The bit here about how there is a "tagone" tag pointing to - # a nonexistent revision is documented by rcs. I dunno, I - # wonder whether the "cvs admin -o" should give a warning in - # this case. - dotest admin-23 "${testcvs} -q log file2" " -RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v -Working file: file2 -head: 1\.2 -branch: -locks: strict -access list: - auth3 - auth2 - foo -symbolic names: - tagone: 1\.1 - br: 1\.1\.0\.2 -keyword substitution: kv -total revisions: 1; selected revisions: 1 -description: ----------------------------- -revision 1\.2 -date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; -modify -=============================================================================" - - dotest admin-25 "cat ${CVSROOT_DIRNAME}/first-dir/file1,v" \ -"head 1\.1; -access - foo - auth2; -symbols; -locks; strict; -comment @xx@; - - -1\.1 -date [0-9][0-9]*\.[0-9][0-9]\.[0-9][0-9]\.[0-9][0-9]\.[0-9][0-9]\.[0-9][0-9]; author ${username}; state Exp; -branches - 1\.1\.2\.1; -next ; - -1\.1\.2\.1 -date [0-9][0-9]*\.[0-9][0-9]\.[0-9][0-9]\.[0-9][0-9]\.[0-9][0-9]\.[0-9][0-9]; author ${username}; state foo; -branches; -next ; - - -desc -@@ - - -1\.1 -log -@add -@ -text -@@ - - -1\.1\.2\.1 -log -@modify-on-branch -@ -text -@a0 1 -add a line on the branch -@" - - # Tests of cvs admin -n. Make use of the results of - # admin-1 through admin-25. - # FIXME: We probably shouldn't make use of those results; - # this test is way too long as it is. - - # tagtwo should be a revision - # - dotest admin-26-1 "${testcvs} admin -ntagtwo:tagone file2" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v -done" - - # br1 should be a branch - # - dotest admin-26-2 "${testcvs} admin -nbr1:br file2" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v -done" - - # Attach some tags using RCS versions - # - dotest admin-26-3 "${testcvs} admin -ntagthree:1.1 file2" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v -done" - - dotest admin-26-4 "${testcvs} admin -nbr2:1.1.2 file2" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v -done" - - dotest admin-26-5 "${testcvs} admin -nbr4:1.1.0.2 file2" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v -done" - - # Check results so far - # - dotest admin-26-6 "${testcvs} status -v file2" \ -"=================================================================== -File: file2 Status: Up-to-date - - Working revision: 1\.2.* - Repository revision: 1\.2 ${CVSROOT_DIRNAME}/first-dir/file2,v - Sticky Tag: (none) - Sticky Date: (none) - Sticky Options: (none) - - Existing Tags: - br4 (branch: 1\.1\.2) - br2 (branch: 1\.1\.2) - tagthree (revision: 1\.1) - br1 (branch: 1\.1\.2) - tagtwo (revision: 1\.1) - tagone (revision: 1\.1) - br (branch: 1\.1\.2)" - - - # Add a couple more revisions - # - echo "nuthr_line" >> file2 - dotest admin-27-1 "${testcvs} commit -m nuthr_line file2" \ -"Checking in file2; -${CVSROOT_DIRNAME}/first-dir/file2,v <-- file2 -new revision: 1\.3; previous revision: 1\.2 -done" - - echo "yet_another" >> file2 - dotest admin-27-2 "${testcvs} commit -m yet_another file2" \ -"Checking in file2; -${CVSROOT_DIRNAME}/first-dir/file2,v <-- file2 -new revision: 1\.4; previous revision: 1\.3 -done" - - # Fail trying to reattach existing tag with -n - # - dotest admin-27-3 "${testcvs} admin -ntagfour:1.1 file2" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v -done" - - dotest_fail admin-27-4 "${testcvs} admin -ntagfour:1.3 file2" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v -${PROG} admin: ${CVSROOT_DIRNAME}/first-dir/file2,v: symbolic name tagfour already bound to 1\.1 -${PROG} admin: RCS file for .file2. not modified\." - - # Succeed at reattaching existing tag, using -N - # - dotest admin-27-5 "${testcvs} admin -Ntagfour:1.3 file2" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v -done" - - # Fail on some bogus operations - # Try to attach to nonexistant tag - # - dotest_fail admin-28-1 "${testcvs} admin -ntagsix:tagfive file2" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v -${PROG} admin: ${CVSROOT_DIRNAME}/first-dir/file2,v: Symbolic name or revision tagfive is undefined\. -${PROG} admin: RCS file for .file2. not modified\." - - # Try a some nonexisting numeric target tags - # - dotest_fail admin-28-2 "${testcvs} admin -ntagseven:2.1 file2" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v -${PROG} \[admin aborted\]: revision .2\.1. does not exist" - - dotest_fail admin-28-3 "${testcvs} admin -ntageight:2.1.2 file2" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v -${PROG} \[admin aborted\]: revision .2\.1\.2. does not exist" - - # Try some invalid targets - # - dotest_fail admin-28-4 "${testcvs} admin -ntagnine:1.a.2 file2" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v -${PROG} \[admin aborted\]: tag .1\.a\.2. must start with a letter" - - # Confirm that a missing tag is not a fatal error. - dotest admin-28-5.1 "${testcvs} -Q tag BO+GUS file1" '' - dotest_fail admin-28-5.2 "${testcvs} admin -ntagten:BO+GUS file2 file1" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v -${PROG} admin: ${CVSROOT_DIRNAME}/first-dir/file2,v: Symbolic name or revision BO${PLUS}GUS is undefined\. -${PROG} admin: RCS file for .file2. not modified\. -RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -done" - - dotest_fail admin-28-6 "${testcvs} admin -nq.werty:tagfour file2" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v -${PROG} \[admin aborted\]: tag .q\.werty. must not contain the characters ..*" - - # Verify the archive - # - dotest admin-29 "cat ${CVSROOT_DIRNAME}/first-dir/file2,v" \ -"head 1\.4; -access - auth3 - auth2 - foo; -symbols - tagfour:1\.3 - br4:1\.1\.0\.2 - br2:1\.1\.0\.2 - tagthree:1\.1 - br1:1\.1\.0\.2 - tagtwo:1\.1 - tagone:1\.1 - br:1\.1\.0\.2; -locks; strict; -comment @# @; - - -1\.4 -date [0-9][0-9]*\.[0-9][0-9]\.[0-9][0-9]\.[0-9][0-9]\.[0-9][0-9]\.[0-9][0-9]; author ${username}; state Exp; -branches; -next 1\.3; - -1\.3 -date [0-9][0-9]*\.[0-9][0-9]\.[0-9][0-9]\.[0-9][0-9]\.[0-9][0-9]\.[0-9][0-9]; author ${username}; state Exp; -branches; -next 1\.2; - -1\.2 -date [0-9][0-9]*\.[0-9][0-9]\.[0-9][0-9]\.[0-9][0-9]\.[0-9][0-9]\.[0-9][0-9]; author ${username}; state Exp; -branches; -next ; - - -desc -@@ - - -1\.4 -log -@yet_another -@ -text -@add a line -nuthr_line -yet_another -@ - - -1\.3 -log -@nuthr_line -@ -text -@d3 1 -@ - - -1\.2 -log -@modify -@ -text -@d2 1 -@" - - dotest_fail admin-30 "${testcvs} admin -mbr:another-log-message \ -file2 aaa file3" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v -${PROG} admin: ${CVSROOT_DIRNAME}/first-dir/file2,v: no such revision br: 1\.1 -${PROG} admin: RCS file for .file2. not modified. -RCS file: ${CVSROOT_DIRNAME}/first-dir/aaa,v -${PROG} admin: ${CVSROOT_DIRNAME}/first-dir/aaa,v: no such revision br -${PROG} admin: RCS file for .aaa. not modified. -RCS file: ${CVSROOT_DIRNAME}/first-dir/Attic/file3,v -done" - dotest admin-31 "${testcvs} log" \ -"${PROG} log: Logging \. - -RCS file: ${CVSROOT_DIRNAME}/first-dir/aaa,v -Working file: aaa -head: 1\.4 -branch: -locks: strict -access list: -symbolic names: - br1: 1\.3\.0\.2 -keyword substitution: kv -total revisions: 5; selected revisions: 5 -description: ----------------------------- -revision 1\.4 -date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; lines: ${PLUS}1 -0 -fourth ----------------------------- -revision 1\.3 -date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; lines: ${PLUS}1 -0 -branches: 1\.3\.2; -third ----------------------------- -revision 1\.2 -date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; lines: ${PLUS}1 -0 -second ----------------------------- -revision 1\.1 -date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; -first ----------------------------- -revision 1\.3\.2\.4 -date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; lines: ${PLUS}4 -0 -branch-four -============================================================================= - -RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -Working file: file1 -head: 1\.1 -branch: -locks: strict -access list: - foo - auth2 -symbolic names: - tagten: 1\.1 - BO${PLUS}GUS: 1\.1 -keyword substitution: kv -total revisions: 2; selected revisions: 2 -description: ----------------------------- -revision 1\.1 -date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; -branches: 1\.1\.2; -add ----------------------------- -revision 1\.1\.2\.1 -date: [0-9/]* [0-9:]*; author: ${username}; state: foo; lines: ${PLUS}1 -0 -modify-on-branch -============================================================================= - -RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v -Working file: file2 -head: 1\.4 -branch: -locks: strict -access list: - auth3 - auth2 - foo -symbolic names: - tagfour: 1\.3 - br4: 1\.1\.0\.2 - br2: 1\.1\.0\.2 - tagthree: 1\.1 - br1: 1\.1\.0\.2 - tagtwo: 1\.1 - tagone: 1\.1 - br: 1\.1\.0\.2 -keyword substitution: kv -total revisions: 3; selected revisions: 3 -description: ----------------------------- -revision 1\.4 -date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; lines: ${PLUS}1 -0 -yet_another ----------------------------- -revision 1\.3 -date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; lines: ${PLUS}1 -0 -nuthr_line ----------------------------- -revision 1\.2 -date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; -modify -============================================================================= - -RCS file: ${CVSROOT_DIRNAME}/first-dir/Attic/file3,v -Working file: file3 -head: 1\.1 -branch: -locks: strict -access list: -symbolic names: - br: 1\.1\.0\.2 -keyword substitution: kv -total revisions: 2; selected revisions: 2 -description: ----------------------------- -revision 1\.1 -date: [0-9/]* [0-9:]*; author: ${username}; state: dead; -branches: 1\.1\.2; -file file3 was initially added on branch br\. ----------------------------- -revision 1\.1\.2\.1 -date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; lines: ${PLUS}1 -0 -another-log-message -=============================================================================" - - cd ../.. - if $keep; then - echo Keeping ${TESTDIR} and exiting due to --keep - exit 0 - fi - # clean up our after ourselves - rm -r 1 - rm -rf ${CVSROOT_DIRNAME}/first-dir - ;; - - reserved) - # Tests of reserved checkouts. Eventually this will test - # rcslock.pl (or equivalent) and all kinds of stuff. Right - # now it just does some very basic checks on cvs admin -u - # and cvs admin -l. - # Also should test locking on a branch (and making sure that - # locks from one branch don't get mixed up with those from - # another. Both the case where one of the branches is the - # main branch, and in which neither one is). - # See also test keyword, which tests that keywords and -kkvl - # do the right thing in the presence of locks. - - # The usual setup, directory first-dir containing file file1. - mkdir 1; cd 1 - dotest reserved-1 "${testcvs} -q co -l ." '' - mkdir first-dir - dotest reserved-2 "${testcvs} add first-dir" \ -"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" - cd first-dir - touch file1 - dotest reserved-3 "${testcvs} add file1" \ -"${PROG} add: scheduling file .file1. for addition -${PROG} add: use .${PROG} commit. to add this file permanently" - dotest reserved-4 "${testcvs} -q ci -m add" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -done -Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -initial revision: 1\.1 -done" - - dotest reserved-5 "${testcvs} -q admin -l file1" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -1\.1 locked -done" - dotest reserved-6 "${testcvs} log -N file1" " -RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -Working file: file1 -head: 1\.1 -branch: -locks: strict - ${username}: 1\.1 -access list: -keyword substitution: kv -total revisions: 1; selected revisions: 1 -description: ----------------------------- -revision 1\.1 locked by: ${username}; -date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; -add -=============================================================================" - - # Note that this just tests the owner of the lock giving - # it up. It doesn't test breaking a lock. - dotest reserved-7 "${testcvs} -q admin -u file1" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -1\.1 unlocked -done" - - dotest reserved-8 "${testcvs} log -N file1" " -RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -Working file: file1 -head: 1\.1 -branch: -locks: strict -access list: -keyword substitution: kv -total revisions: 1; selected revisions: 1 -description: ----------------------------- -revision 1\.1 -date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; -add -=============================================================================" - - # rcslock.pl tests. Of course, the point isn't to test - # rcslock.pl from the distribution but equivalent - # functionality (for example, many sites may have an old - # rcslock.pl). The functionality of this hook falls - # short of the real rcslock.pl though. - # Note that we can use rlog or look at the RCS file directly, - # but we can't use "cvs log" because "cvs commit" has a lock. - - cat >${TESTDIR}/lockme <&2 - exit 1 -fi -EOF - # Cygwin. Blaaarg. - if test -n "$remotehost"; then - $CVS_RSH $remotehost "chmod +x ${TESTDIR}/lockme" - else - chmod +x ${TESTDIR}/lockme - fi - - echo stuff > a-lock - dotest reserved-9 "${testcvs} add a-lock" \ -"${PROG} add: scheduling file .a-lock. for addition -${PROG} add: use .${PROG} commit. to add this file permanently" - dotest reserved-10 "${testcvs} -q ci -m new a-lock" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/a-lock,v -done -Checking in a-lock; -${CVSROOT_DIRNAME}/first-dir/a-lock,v <-- a-lock -initial revision: 1\.1 -done" - # FIXME: the contents of CVSROOT fluctuate a lot - # here. Maybe the expect pattern should just - # confirm that commitinfo is one of the files checked out, - # but for now we just check that CVS exited with success. - cd .. - if ${testcvs} -q co CVSROOT >>${LOGFILE} ; then - pass reserved-11 - else - fail reserved-11 - fi - cd CVSROOT - echo "DEFAULT ${TESTDIR}/lockme" >>commitinfo - dotest reserved-12 "${testcvs} -q ci -m rcslock commitinfo" \ -"Checking in commitinfo; -${CVSROOT_DIRNAME}/CVSROOT/commitinfo,v <-- commitinfo -new revision: 1\.2; previous revision: 1\.1 -done -${PROG} commit: Rebuilding administrative file database" - cd ..; cd first-dir - - # Simulate (approximately) what a-lock would look like - # if someone else had locked revision 1.1. - sed -e 's/locks; strict;/locks fred:1.1; strict;/' ${CVSROOT_DIRNAME}/first-dir/a-lock,v > a-lock,v - # Cygwin. - if test -n "$remotehost"; then - $CVS_RSH $remotehost "chmod 644 ${CVSROOT_DIRNAME}/first-dir/a-lock,v" - else - chmod 644 ${CVSROOT_DIRNAME}/first-dir/a-lock,v - fi - dotest reserved-13 "mv a-lock,v ${CVSROOT_DIRNAME}/first-dir/a-lock,v" - # Cygwin. Blah. - if test -n "$remotehost"; then - $CVS_RSH $remotehost "chmod 444 ${CVSROOT_DIRNAME}/first-dir/a-lock,v" - else - chmod 444 ${CVSROOT_DIRNAME}/first-dir/a-lock,v - fi - echo more stuff >> a-lock - dotest_fail reserved-13b "${testcvs} ci -m '' a-lock" \ -"fred has file a-lock locked for version 1\.1 -${PROG} commit: Pre-commit check failed -${PROG} \[commit aborted\]: correct above errors first!" - # OK, now test "cvs admin -l" in the case where someone - # else has the file locked. - dotest_fail reserved-13c "${testcvs} admin -l a-lock" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/a-lock,v -${PROG} \[admin aborted\]: Revision 1\.1 is already locked by fred" - - dotest reserved-14 "${testcvs} admin -u1.1 a-lock" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/a-lock,v -${PROG} admin: ${CVSROOT_DIRNAME}/first-dir/a-lock,v: revision 1\.1 locked by fred; breaking lock -1\.1 unlocked -done" - dotest reserved-15 "${testcvs} -q ci -m success a-lock" \ -"Checking in a-lock; -${CVSROOT_DIRNAME}/first-dir/a-lock,v <-- a-lock -new revision: 1\.2; previous revision: 1\.1 -done" - - # Now test for a bug involving branches and locks - sed -e 's/locks; strict;/locks fred:1.2; strict;/' ${CVSROOT_DIRNAME}/first-dir/a-lock,v > a-lock,v - chmod 644 ${CVSROOT_DIRNAME}/first-dir/a-lock,v - dotest reserved-16 \ -"mv a-lock,v ${CVSROOT_DIRNAME}/first-dir/a-lock,v" "" - chmod 444 ${CVSROOT_DIRNAME}/first-dir/a-lock,v - dotest reserved-17 "${testcvs} -q tag -b br a-lock" "T a-lock" - dotest reserved-18 "$testcvs -q update -r br a-lock" '[UP] a-lock' - echo edit it >>a-lock - dotest reserved-19 "${testcvs} -q ci -m modify a-lock" \ -"Checking in a-lock; -${CVSROOT_DIRNAME}/first-dir/a-lock,v <-- a-lock -new revision: 1\.2\.2\.1; previous revision: 1\.2 -done" - - # undo commitinfo changes - cd ../CVSROOT - echo '# vanilla commitinfo' >commitinfo - dotest reserved-cleanup-1 "${testcvs} -q ci -m back commitinfo" \ -"Checking in commitinfo; -${CVSROOT_DIRNAME}/CVSROOT/commitinfo,v <-- commitinfo -new revision: 1\.3; previous revision: 1\.2 -done -${PROG} commit: Rebuilding administrative file database" - cd ..; rm -r CVSROOT; cd first-dir - - cd ../.. - rm -r 1 - rm ${TESTDIR}/lockme - rm -rf ${CVSROOT_DIRNAME}/first-dir - ;; - - diffmerge1) - # Make sure CVS can merge correctly in circumstances where it - # used to mess up (due to a bug which existed in diffutils 2.7 - # and 2.6, but not 2.5, and which has been fixed in CVS's diff - # lib by Paul Eggert, bless his bitty heart). - - # This first test involves two working copies, "mine" and - # "yours", checked out from the same repository at the same - # time. In yours, you remove some text from the end of the - # file and check it in; meanwhile, "me" has commented out some - # lines earlier in the file, and I go to check it in right - # after you checked yours in. CVS naturally tells me the file - # is not up-to-date, so I run cvs update, but it updates - # incorrectly, leaving in the lines of text you just deleted. - # Bad! I'm in too much of a hurry to actually look at the - # file, so I check it in and go home, and so your changes have - # been lost. Later you discover this, and you suspect me of - # deliberately sabotaging your work, so you let all the air - # out of my tires. Only after a series of expensive lawsuits - # and countersuits do we discover that this was all CVS's - # fault. - # - # Luckily, this problem has been fixed now, as our test will - # handily confirm, no doubt: - - # First make a repository containing the original text: - - # We should be here anyway, but cd to it just in case: - cd ${TESTDIR} - - mkdir diffmerge1 - cd diffmerge1 - - # These are the files we both start out with: - mkdir import - cd import - diffmerge_create_older_files - - dotest diffmerge1_import \ - "${testcvs} import -m import diffmerge1 tag1 tag2" \ - "${DOTSTAR}No conflicts created by this import" - cd .. - - # Check out two working copies, one for "you" and one for - # "me". If no branch is used and cvs detects that only one - # of the two people made changes, then cvs does not run the - # merge algorithm. But if a branch is used, then cvs does run - # the merge algorithm (even in this case of only one of the two - # people having made changes). CVS used to have a bug in this - # case. Therefore, it is important to test this case by - # using a branch: - ${testcvs} rtag -b tag diffmerge1 >/dev/null 2>&1 - ${testcvs} checkout -r tag diffmerge1 >/dev/null 2>&1 - mv diffmerge1 yours - ${testcvs} checkout diffmerge1 >/dev/null 2>&1 - mv diffmerge1 mine - - # In your working copy, you'll make changes, and - # then check in your changes before I check in mine: - cd yours - diffmerge_create_your_files - dotest diffmerge1_yours "${testcvs} -q ci -m yours" \ -"Checking in testcase01; -${CVSROOT_DIRNAME}/diffmerge1/testcase01,v <-- testcase01 -new revision: 1\.1\.1\.1\.2\.1; previous revision: 1\.1\.1\.1 -done -Checking in testcase02; -${CVSROOT_DIRNAME}/diffmerge1/testcase02,v <-- testcase02 -new revision: 1\.1\.1\.1\.2\.1; previous revision: 1\.1\.1\.1 -done -Checking in testcase03; -${CVSROOT_DIRNAME}/diffmerge1/testcase03,v <-- testcase03 -new revision: 1\.1\.1\.1\.2\.1; previous revision: 1\.1\.1\.1 -done -Checking in testcase04; -${CVSROOT_DIRNAME}/diffmerge1/testcase04,v <-- testcase04 -new revision: 1\.1\.1\.1\.2\.1; previous revision: 1\.1\.1\.1 -done -Checking in testcase05; -${CVSROOT_DIRNAME}/diffmerge1/testcase05,v <-- testcase05 -new revision: 1\.1\.1\.1\.2\.1; previous revision: 1\.1\.1\.1 -done -Checking in testcase06; -${CVSROOT_DIRNAME}/diffmerge1/testcase06,v <-- testcase06 -new revision: 1\.1\.1\.1\.2\.1; previous revision: 1\.1\.1\.1 -done -Checking in testcase07; -${CVSROOT_DIRNAME}/diffmerge1/testcase07,v <-- testcase07 -new revision: 1\.1\.1\.1\.2\.1; previous revision: 1\.1\.1\.1 -done -Checking in testcase08; -${CVSROOT_DIRNAME}/diffmerge1/testcase08,v <-- testcase08 -new revision: 1\.1\.1\.1\.2\.1; previous revision: 1\.1\.1\.1 -done -Checking in testcase09; -${CVSROOT_DIRNAME}/diffmerge1/testcase09,v <-- testcase09 -new revision: 1\.1\.1\.1\.2\.1; previous revision: 1\.1\.1\.1 -done -Checking in testcase10; -${CVSROOT_DIRNAME}/diffmerge1/testcase10,v <-- testcase10 -new revision: 1\.1\.1\.1\.2\.1; previous revision: 1\.1\.1\.1 -done" - - # Change my copy. Then I - # update, after both my modifications and your checkin: - cd ../mine - diffmerge_create_my_files - dotest diffmerge1_mine "${testcvs} -q update -j tag" \ -"M testcase01 -RCS file: ${CVSROOT_DIRNAME}/diffmerge1/testcase01,v -retrieving revision 1\.1\.1\.1 -retrieving revision 1\.1\.1\.1\.2\.1 -Merging differences between 1\.1\.1\.1 and 1\.1\.1\.1\.2\.1 into testcase01 -M testcase02 -RCS file: ${CVSROOT_DIRNAME}/diffmerge1/testcase02,v -retrieving revision 1\.1\.1\.1 -retrieving revision 1\.1\.1\.1\.2\.1 -Merging differences between 1\.1\.1\.1 and 1\.1\.1\.1\.2\.1 into testcase02 -M testcase03 -RCS file: ${CVSROOT_DIRNAME}/diffmerge1/testcase03,v -retrieving revision 1\.1\.1\.1 -retrieving revision 1\.1\.1\.1\.2\.1 -Merging differences between 1\.1\.1\.1 and 1\.1\.1\.1\.2\.1 into testcase03 -M testcase04 -RCS file: ${CVSROOT_DIRNAME}/diffmerge1/testcase04,v -retrieving revision 1\.1\.1\.1 -retrieving revision 1\.1\.1\.1\.2\.1 -Merging differences between 1\.1\.1\.1 and 1\.1\.1\.1\.2\.1 into testcase04 -RCS file: ${CVSROOT_DIRNAME}/diffmerge1/testcase05,v -retrieving revision 1\.1\.1\.1 -retrieving revision 1\.1\.1\.1\.2\.1 -Merging differences between 1\.1\.1\.1 and 1\.1\.1\.1\.2\.1 into testcase05 -RCS file: ${CVSROOT_DIRNAME}/diffmerge1/testcase06,v -retrieving revision 1\.1\.1\.1 -retrieving revision 1\.1\.1\.1\.2\.1 -Merging differences between 1\.1\.1\.1 and 1\.1\.1\.1\.2\.1 into testcase06 -M testcase07 -RCS file: ${CVSROOT_DIRNAME}/diffmerge1/testcase07,v -retrieving revision 1\.1\.1\.1 -retrieving revision 1\.1\.1\.1\.2\.1 -Merging differences between 1\.1\.1\.1 and 1\.1\.1\.1\.2\.1 into testcase07 -testcase07 already contains the differences between 1\.1\.1\.1 and 1\.1\.1\.1\.2\.1 -M testcase08 -RCS file: ${CVSROOT_DIRNAME}/diffmerge1/testcase08,v -retrieving revision 1\.1\.1\.1 -retrieving revision 1\.1\.1\.1\.2\.1 -Merging differences between 1\.1\.1\.1 and 1\.1\.1\.1\.2\.1 into testcase08 -M testcase09 -RCS file: ${CVSROOT_DIRNAME}/diffmerge1/testcase09,v -retrieving revision 1\.1\.1\.1 -retrieving revision 1\.1\.1\.1\.2\.1 -Merging differences between 1\.1\.1\.1 and 1\.1\.1\.1\.2\.1 into testcase09 -M testcase10 -RCS file: ${CVSROOT_DIRNAME}/diffmerge1/testcase10,v -retrieving revision 1\.1\.1\.1 -retrieving revision 1\.1\.1\.1\.2\.1 -Merging differences between 1\.1\.1\.1 and 1\.1\.1\.1\.2\.1 into testcase10" - - # So if your changes didn't make it into my working copy, or - # in any case if the files do not look like the final text - # in the files in directory comp_me, then the test flunks: - cd .. - mkdir comp_me - cd comp_me - diffmerge_create_expected_files - cd .. - rm mine/.#* - - # If you have GNU's version of diff, you may try - # uncommenting the following line which will give more - # fine-grained information about how cvs differed from the - # correct result: - #dotest diffmerge1_cmp "diff -u --recursive --exclude=CVS comp_me mine" '' - dotest diffmerge1_cmp "directory_cmp comp_me mine" - - # Clean up after ourselves: - cd .. - if $keep; then :; else - rm -rf diffmerge1 ${CVSROOT_DIRNAME}/diffmerge1 - fi - ;; - - diffmerge2) - - # FIXME: This test should be rewritten to be much more concise. - # It currently weighs in at something like 600 lines, but the - # same thing could probably be tested in more like 50-100 lines. - mkdir diffmerge2 - - # This tests for another diffmerge bug reported by Martin - # Tomes; actually, his bug was probably caused by an initial - # fix for the bug in test diffmerge1, and likely wasn't ever - # a problem in CVS as long as one was using a normal - # distribution of diff or a version of CVS that has the diff - # lib in it. - # - # Nevertheless, once burned twice cautious, so we test for his - # bug here. - # - # Here is his report, more or less verbatim: - # ------------------------------------------ - # - # Put the attached file (sgrid.h,v) into your repository - # somewhere, check out the module and do this: - # - # cvs update -j Review_Phase_2_Enhancements sgrid.h - # cvs diff -r Review_V1p3 sgrid.h - # - # As there have been no changes made on the trunk there - # should be no differences, however this is output: - # - # % cvs diff -r Review_V1p3 sgrid.h - # Index: sgrid.h - # =================================================================== - # RCS file: /usr/local/repository/play/fred/sgrid.h,v - # retrieving revision 1.1.2.1 - # diff -r1.1.2.1 sgrid.h - # 178a179,184 - # > /*-------------------------------------------------------------- - # > INLINE FUNCTION : HORIZONTALLINES - # > NOTES : Description at the end of the file - # > ----------------------------------------------------------------*/ - # > uint16 horizontalLines( void ); - # > - # - # I did a cvs diff -c -r 1.1 -r 1.1.2.1 sgrid.h and patched those - # differences to sgrid.h version 1.1 and got the correct result - # so it looks like the built in patch is faulty. - # ------------------------------------------------------------------- - # - # This is the RCS file, sgrid.h,v, that he sent: - - echo "head 1.1; -access; -symbols - Review_V1p3:1.1.2.1 - Review_V1p3C:1.1.2.1 - Review_1p3A:1.1.2.1 - Review_V1p3A:1.1.2.1 - Review_Phase_2_Enhancements:1.1.0.2 - Review_V1p2:1.1 - Review_V1p2B:1.1 - Review_V1p2A:1.1 - Review_V1p1:1.1 - Review_1p1:1.1; -locks; strict; -comment @ * @; - - -1.1 -date 97.04.02.11.20.05; author colinl; state Exp; -branches - 1.1.2.1; -next ; - -1.1.2.1 -date 97.06.09.10.00.07; author colinl; state Exp; -branches; -next ; - - -desc -@@ - - -1.1 -log -@Project: DEV1175 -DCN: -Tested By: Colin Law -Reviewed By: -Reason for Change: Initial Revision of all files - -Design Change Details: - -Implications: -@ -text -@/* \$""Header: L:/gpanels/dis/sgrid.h_v 1.1.1.0 24 Jan 1996 14:59:20 PAULT \$ */ -/* - * \$""Log: L:/gpanels/dis/sgrid.h_v \$ - * - * Rev 1.1.1.0 24 Jan 1996 14:59:20 PAULT - * Branched - * - * Rev 1.1 24 Jan 1996 12:09:52 PAULT - * Consolidated 4100 code merged to trunk - * - * Rev 1.0.2.0 01 Jun 1995 14:18:58 DAVEH - * Branched - * - * Rev 1.0 19 Apr 1995 16:32:48 COLINL - * Initial revision. -*/ -/***************************************************************************** -FILE : SGRID.H -VERSION : 2.1 -AUTHOR : Dave Hartley -SYSTEM : Borland C++ -DESCRIPTION : The declaration of the scrolling grid class - -*****************************************************************************/ -#if !defined(__SGRID_H) -#define __SGRID_H - -#if !defined(__SCROLL_H) -#include -#endif - -#if !defined(__GKI_H) -#include \"gki.h\" -#endif - -#if defined PRINTING_SUPPORT -class Printer; -#endif - -/***************************************************************************** -CLASS : ScrollingGrid -DESCRIPTION: This class inherits from a grid and a scrollable, and - can therefore use all the PUBLIC services provided by these - classes. A description of these can be found in - GRID.H and SCROLL.H. - A scrolling grid is a set of horizontal and vertical lines - that scroll and continually update to provide a complete grid - -*****************************************************************************/ - -class ScrollingGrid : public Scrollable -{ - public: -#if defined _WINDOWS -/*--------------------------------------------------------------------------- -FUNCTION : CONSTRUCTOR -DESCRIPTION : sets up the details of the grid, ready for painting -ARGUMENTS : name : sgColour - - the colour of the grid - sgLineType - - the syle of line - sgHorizontalTotal - - the total number of horizontal grid lines - verticalSpacingMin - - the min distance between the vertical grid lines - on the scrolling axis - currentTimestamp - - timestamp value now - ticksPerSecond - - number of timestamp ticks per second - ticksPerPixel - - number of timestamp ticks per pixel required - -RETURN : None -NOTES : ----------------------------------------------------------------------------*/ - ScrollingGrid( GkiColour sgColour, GkiLineType sgLineType, - uint16 sgHorizontalTotal, - uint16 verticalSpacingMin, uint32 currentTimestamp, - uint16 ticksPerSecond, uint32 ticksPerPixel ); -#else -/*--------------------------------------------------------------------------- -FUNCTION : CONSTRUCTOR -DESCRIPTION : sets up the details of the grid, ready for painting -ARGUMENTS : name : sgColour - - the colour of the grid - sgLineType - - the syle of line - sgHorizontalTotal ( THE MAX NUMBER OF LINES IS 100 ) - - the total number of horizontal grid lines - sgVerticalSpacing - - the distance between the vertical grid lines - on the scrolling axis - -RETURN : None -NOTES : If the caller does not get the total grid lines value, synced - with the overall size of the viewport, the spacing between - grid lines will not be consistent. - ----------------------------------------------------------------------------*/ - ScrollingGrid( GkiColour sgColour, GkiLineType sgLineType - , uint16 sgHorizontalTotal, uint16 sgVerticalSpacing ); -#endif -/*--------------------------------------------------------------------------- -FUNCTION : DESTRUCTOR -DESCRIPTION : tidies it all up -ARGUMENTS : name : - -RETURN : None -NOTES : ----------------------------------------------------------------------------*/ - ~ScrollingGrid( void ); - -/*--------------------------------------------------------------------------- -FUNCTION : ATTACH -DESCRIPTION : This service overloads the base class service, as it does - additional work at the time of attachment. - -ARGUMENTS : name : tDrawingArea - - the scrolled viewport to attach this trend to - -RETURN : None -NOTES : ----------------------------------------------------------------------------*/ - void attach( SViewport *tDrawingArea ); - -#if defined _WINDOWS -/*--------------------------------------------------------------------------- -FUNCTION : calculateVerticalSpacing -DESCRIPTION : determines optimum spacing along time axis -ARGUMENTS : -RETURN : None -NOTES : ----------------------------------------------------------------------------*/ - void calculateVerticalSpacing(); - -/*--------------------------------------------------------------------------- -FUNCTION : gridSpacingTicks -DESCRIPTION : Provides the grid spacing in the time axis in ticks -ARGUMENTS : -RETURN : Number of ticks -NOTES : ----------------------------------------------------------------------------*/ - uint32 gridSpacingTicks(); - -#endif - -/*--------------------------------------------------------------------------- -INLINE FUNCTION : HORIZONTALLINES -NOTES : Description at the end of the file ----------------------------------------------------------------------------*/ - uint16 horizontalLines( void ); - -#if defined _WINDOWS -// In Windows the OnDraw() function replaces paint() -/*--------------------------------------------------------------------------- -FUNCTION : ScrollingGrid OnDraw -DESCRIPTION : Paints the given area of the grid. - Pure virtual -ARGUMENTS : pDC pointer to the device context to use for display - Note that the device context operates in the coords - of the window owning the viewport -RETURN : None -NOTES : ----------------------------------------------------------------------------*/ - virtual void OnDraw( CDC *pDC ); - -#else // not Windows - -/*--------------------------------------------------------------------------- -FUNCTION : PAINT -DESCRIPTION : This extends the standard grid paint method to paint the - viewport relative to its current position. - -ARGUMENTS : name : - -RETURN : None -NOTES : ----------------------------------------------------------------------------*/ - void paint( void ); -#endif - -/*--------------------------------------------------------------------------- -FUNCTION : P A I N T T E X T M A R K E R S -DESCRIPTION : this service allow the text markers to be painted seperatley - from the grid lines - -ARGUMENTS : name : - -RETURN : None -NOTES : ----------------------------------------------------------------------------*/ - void paintTextMarkers(); - -#if defined PRINTING_SUPPORT -/*--------------------------------------------------------------------------- -FUNCTION : P R I N T -DESCRIPTION : This print service prints a grid marker ( being either a - timestamp or a date, IF there is one at the plot position - given - -ARGUMENTS : name : - displayPosition - - Where in the log to look to see if there is an - entry to print - - - printerPtr - the printer to print to - -RETURN : None -NOTES : ----------------------------------------------------------------------------*/ - void print( uint16 currentPrintPos, Printer *printerPtr ); -#endif - -/*--------------------------------------------------------------------------- -FUNCTION : S E T D R I V E D I R E C T I O N -DESCRIPTION : Sets direction for update and scrolling forwards or backwards -ARGUMENTS : direction - required direction -RETURN : None -NOTES : ----------------------------------------------------------------------------*/ - void setDriveDirection( ScrollDirection direction ); - -/*--------------------------------------------------------------------------- -FUNCTION : S E T U P -DESCRIPTION : service that will setup the grid prior to a paint - -ARGUMENTS : name : - - newTimestamp - - - - newTimeBase - the number of ticks that represent a plot point on - the trendgraph. - -RETURN : None -NOTES : ----------------------------------------------------------------------------*/ - void setup( uint32 newTimestamp, uint32 newTimeBase ); - -#if defined PRINTING_SUPPORT -/*--------------------------------------------------------------------------- -FUNCTION : S E T U P F O R P R I N T -DESCRIPTION : This service iis to be called prior to printing. It allows - the grid to prepare its markers ready for the print - commands - -ARGUMENTS : name : - -RETURN : None -NOTES : ----------------------------------------------------------------------------*/ - void setupForPrint(); -#endif - -/*--------------------------------------------------------------------------- -FUNCTION : UPDATE -DESCRIPTION : When this service is called it will calculate what needs to - be painted and fill in the display again. - -ARGUMENTS : name : timeStamp - - the reference time of this update. - -RETURN : None -NOTES : ----------------------------------------------------------------------------*/ - void update( uint32 timeStamp ); - -/*--------------------------------------------------------------------------- -FUNCTION : U P D A T E B U F F E R -DESCRIPTION : When a display update is not required, use this method. It - updates the internal data ready for a call to paint that - will then show the grid in the right position - -ARGUMENTS : name : - -RETURN : None -NOTES : ----------------------------------------------------------------------------*/ - void updateBuffer( void ); - - private: - -/*--------------------------------------------------------------------------- -FUNCTION : M A K E G R I D M A R K E R -DESCRIPTION : service that perpares a string for display. The string will - either be a short date, or short time. this is determined - by the current setting of the dateMarker flag - -ARGUMENTS : name : timestampVal - - the value to convert - - storePtr - - the place to put the string - -RETURN : None -NOTES : ----------------------------------------------------------------------------*/ - void makeGridMarker( uint32 timestampVal, char *storePtr ); - -/*--------------------------------------------------------------------------- -FUNCTION : P A I N T G R I D M A R K E R -DESCRIPTION : given a position will put the string on the display - -ARGUMENTS : name : - yPos - - were it goes on the Y-axis - - gridMarkerPtr - - what it is - -RETURN : None -NOTES : ----------------------------------------------------------------------------*/ - void paintGridMarker( uint16 yPos, char *gridMarkerPtr ); - -#if defined _WINDOWS -/*--------------------------------------------------------------------------- -FUNCTION : PAINTHORIZONTALLINES -DESCRIPTION : responsible for painting the grids horizontal lines -ARGUMENTS : pRectToDraw pointer to rectangle that needs refreshing. - in viewport coords - pDC pointer to device context to use - -RETURN : None -NOTES : ----------------------------------------------------------------------------*/ - void paintHorizontalLines(RectCoords* pRectToDraw, CDC* pDC ); -#else -/*--------------------------------------------------------------------------- -FUNCTION : PAINTHORIZONTALLINES -DESCRIPTION : responsible for painting the grids horizontal lines -ARGUMENTS : name: xStart - - the starting X co-ordinate for the horizontal line - xEnd - - the ending X co-ordinate for the horizontal line - -RETURN : None -NOTES : Remember lines are drawn from origin. The origin in a - horizontal viewport will be the top. ----------------------------------------------------------------------------*/ - void paintHorizontalLines( uint16 xStart, uint16 xEnd ); -#endif - -#if defined _WINDOWS -/*--------------------------------------------------------------------------- -FUNCTION : PAINTVERTICALLINES -DESCRIPTION : responsible for painting the grids vertical lines -ARGUMENTS : pRectToDraw pointer to rectangle that needs refreshing. - in viewport coords - offset offset from rhs that rightmost line would be - drawn if rectangle included whole viewport - pDC pointer to device context to use -RETURN : None -NOTES : ----------------------------------------------------------------------------*/ - void paintVerticalLines( RectCoords* pRectToDraw, uint16 offset, - CDC* pDC ); -#else -/*--------------------------------------------------------------------------- -FUNCTION : PAINTVERTICALLINES -DESCRIPTION : responsible for painting the grids vertical lines -ARGUMENTS : name : yStart - - the starting Y co-ordinate for the vertical line - yEnd - - the ending Y co-ordinate for the vertical line - offset - - a starting point offset that determines at what X - position the first line will be drawn - - -RETURN : None -NOTES : ----------------------------------------------------------------------------*/ - void paintVerticalLines( uint16 yStart, uint16 yEnd, uint16 offset ); -#endif - -#if defined _WINDOWS -/*--------------------------------------------------------------------------- -FUNCTION : PAINTVERTICALLINE -DESCRIPTION : paints one line at the position specified, and length -ARGUMENTS : name : yStart - - the starting point on the y axis for the line - yEnd - - the end point on the y axis for the line - xPosition - - The horizontal offset from the start of the viewport - pDC pointer to device context to use - -RETURN : None -NOTES : There is not an equivalent horizontal method as yet. This - is a seperate method because the service is useful to a - derivation of this class ----------------------------------------------------------------------------*/ - void paintVerticalLine( uint16 yStart, uint16 yEnd - , uint16 xPosition, CDC *pDC ); -#else -/*--------------------------------------------------------------------------- -FUNCTION : PAINTVERTICALLINE -DESCRIPTION : paints one line at the position specified, and length -ARGUMENTS : name : yStart - - the starting point on the y axis for the line - yEnd - - the end point on the y axis for the line - xPosition - - The horizontal offset from the start of the viewport - -RETURN : None -NOTES : There is not an equivalent horizontal method as yet. This - is a seperate method because the service is useful to a - derivation of this class ----------------------------------------------------------------------------*/ - void paintVerticalLine( uint16 yStart, uint16 yEnd - , uint16 xPosition ); -#endif - -/*--------------------------------------------------------------------------- -INLINE FUNCTION : VERTICALSPACING -NOTES : Description at the end of the file ----------------------------------------------------------------------------*/ - uint16 verticalSpacing( void ); - - - // Position in viewport that we are now writing to if going forwards - // Note that if this is greater than viewport length then we have - // just scrolled and value must be adjusted before use. - sint16 forwardsOutputPosition; - - // Position in viewport that we are now writing to if going backwards - // Note that if this is less than zero then we have - // just scrolled and value must be adjusted before use. - sint16 backwardsOutputPosition; - - // position in grid cycle of forwards output position. - // if zero then it is time to output a grid line - sint16 forwardsIntervalCount; - - // position in grid cycle of forwards output position. - // if zero then it is time to output a grid line - sint16 backwardsIntervalCount; - - uint32 lastUpdateTimestamp; - uint32 timeBase; // ticks per pixel - uint16 currentOutputPosition; - uint16 gridTimestampSpacing; - uint16 intervalCount; - uint16 horizontalTotal; - uint16 vSpacing; -#if defined PRINTING_SUPPORT - uint16 numberOfGridMarkersPrinted; -#endif - bool firstTime; // indicates first time through - bool dateMarker; - - GkiLineType lineType; - GkiColour gridColour; - - #if defined _WINDOWS - uint16 ticksPerSec; // number of time ticks per second - uint16 vSpacingMin; // minimum pixels per division along time axis - CPen *pPen; // the pen to use for drawing in windows - #endif - -}; - - -/***************************************************************************** - I N L I N E F U N C T I O N S -*****************************************************************************/ - -/*--------------------------------------------------------------------------- -FUNCTION : HORIZONTALLINES -DESCRIPTION : supplies the number of horizontal lines in the grid -ARGUMENTS : name : - -RETURN : -NOTES : ----------------------------------------------------------------------------*/ -inline uint16 ScrollingGrid::horizontalLines( void ) -{ - return( horizontalTotal ); -} -/*--------------------------------------------------------------------------- -FUNCTION : VERTICALSPACING -DESCRIPTION : returns the distance between adjacent vertical lines -ARGUMENTS : name : - -RETURN : None -NOTES : ----------------------------------------------------------------------------*/ -inline uint16 ScrollingGrid::verticalSpacing( void ) -{ - return( vSpacing ); -} - -#endif -@ - - -1.1.2.1 -log -@DEV1194:DS4 Provision of major and minor grid lines -@ -text -@d1 1 -a1 1 -/* \$""Header: /usr/local/repository/cmnsrc/review/src/sgrid.h,v 1.1 1997/04/02 11:20:05 colinl Exp \$ */ -d3 1 -a3 12 - * \$""Log: sgrid.h,v \$ - * Revision 1.1 1997/04/02 11:20:05 colinl - * Project: DEV1175 - * DCN: - * Tested By: Colin Law - * Reviewed By: - * Reason for Change: Initial Revision of all files - * - * Design Change Details: - * - * Implications: - * -d58 6 -a63 5 -ARGUMENTS : name : majorColour colour for major grid lines - minorColour colour for minor grid lines - sgLineType line type for minor grid lines - yMajorGridLines number of major y lines on grid - yMinorGridLines number of major y lines on grid -d77 2 -a78 3 - ScrollingGrid( GkiColour majorColour, GkiColour minorColour, - GkiLineType sgLineType, - uint16 yMajorGridLines, uint16 yMinorGridLines, -a137 17 -FUNCTION : DrawHorizontalGridLines - -DESCRIPTION : Draws major or minor grid lines -ARGUMENTS : pDC device context - pPen pen to use - numLines total lines required - yLow, yHigh, xLow, xHigh rectangle to draw in - yMax max y value -RETURN : None -NOTES : ----------------------------------------------------------------------------*/ - void DrawHorizontalGridLines( CDC* pDC, CPen* pPen, - uint16 numLines, - uint16 yLow, uint16 yHigh, uint16 xLow, uint16 xHigh, - uint16 yMax ); - -/*--------------------------------------------------------------------------- -d148 6 -d448 1 -a448 2 - uint16 m_yMajorGridLines; - uint16 m_yMinorGridLines; -d456 2 -a457 3 - GkiLineType lineType; // line type for minor grid lines - GkiColour m_majorColour; - GkiColour m_minorColour; -d462 1 -a462 2 - CPen *pMajorPen; // pen to use for drawing major grid lines - CPen *pMinorPen; // pen to use for drawing minor grid lines -d472 12 -@" > diffmerge2/sgrid.h,v - - # We have to put the RCS file in the repository by hand for - # this test: - mkdir ${CVSROOT_DIRNAME}/diffmerge2 - cp diffmerge2/sgrid.h,v ${CVSROOT_DIRNAME}/diffmerge2/sgrid.h,v - rm -rf diffmerge2 - dotest diffmerge2_co \ - "${testcvs} co diffmerge2" "${DOTSTAR}U ${DOTSTAR}" - cd diffmerge2 - dotest diffmerge2_update \ - "${testcvs} update -j Review_Phase_2_Enhancements sgrid.h" \ - "${DOTSTAR}erging ${DOTSTAR}" - # This is the one that counts -- there should be no output: - dotest diffmerge2_diff \ - "${testcvs} diff -r Review_V1p3 sgrid.h" '' - - cd .. - rm -rf diffmerge2 - rm -rf ${CVSROOT_DIRNAME}/diffmerge2 - ;; - - release) - # Tests of "cvs release", particularly multiple arguments. - # Other CVS release tests: - # info-cleanup-0 for "cvs -n release". - # ignore-193 for the text of the question that cvs release asks. - # Also for interactions with cvsignore. - # basicc: "-d .", global -Q, no arguments (is a noop), - # "cvs release" without -d, multiple arguments. - # dirs-4: repository directory has been deleted. - # modules2-6: multiple arguments. - - # First the usual setup; create a directory first-dir. - mkdir 1; cd 1 - dotest release-1 "${testcvs} -q co -l ." '' - mkdir first-dir - dotest release-2 "${testcvs} add first-dir" \ -"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" - cd first-dir - mkdir dir1 - dotest release-3 "${testcvs} add dir1" \ -"Directory ${CVSROOT_DIRNAME}/first-dir/dir1 added to the repository" - mkdir dir2 - dotest release-4 "${testcvs} add dir2" \ -"Directory ${CVSROOT_DIRNAME}/first-dir/dir2 added to the repository" - cd dir2 - mkdir dir3 - dotest release-5 "${testcvs} add dir3" \ -"Directory ${CVSROOT_DIRNAME}/first-dir/dir2/dir3 added to the repository" - - cd ../.. - dotest release-6 "${testcvs} release -d first-dir/dir2/dir3 first-dir/dir1" \ -"You have .0. altered files in this repository. -Are you sure you want to release (and delete) directory .first-dir/dir2/dir3.: \ -You have .0. altered files in this repository. -Are you sure you want to release (and delete) directory .first-dir/dir1.: " <file - echo FiLe >FiLe - if cmp file FiLe >/dev/null; then - client_sensitive=false - else - client_sensitive=: - fi - if test -n "$remotehost"; then - $CVS_RSH $remotehost 'echo file >file' - $CVS_RSH $remotehost 'echo FiLe >FiLe' - if $CVS_RSH $remotehost 'cmp file FiLe >/dev/null'; then - server_sensitive=false - else - server_sensitive=: - fi - else - server_sensitive=$client_sensitive - fi - - # The first test (recase-1 & recase-2) is for a remove of a file then - # a readd in a different case. - mkdir $CVSROOT_DIRNAME/first-dir - dotest recase-init-1 "$testcvs -Q co first-dir" - cd first-dir - - echo this file has no content >file - dotest recase-init-2 "$testcvs -Q add file" - dotest recase-init-3 "$testcvs -Q ci -madd" \ -"RCS file: $CVSROOT_DIRNAME/first-dir/file,v -done -Checking in file; -$CVSROOT_DIRNAME/first-dir/file,v <-- file -initial revision: 1\.1 -done" - dotest recase-init-4 "$testcvs -Q tag first" - - # Now remove the file. - dotest recase-init-5 "$testcvs -Q rm -f file" - dotest recase-init-6 "$testcvs -Q ci -mrm" \ -"Removing file; -$CVSROOT_DIRNAME/first-dir/file,v <-- file -new revision: delete; previous revision: 1\.1 -done" - - # Now the test - readd in a different case. - echo this file needs some content >FiLe - if $server_sensitive; then - dotest recase-1ss "$testcvs add FiLe" \ -"$PROG add: scheduling file \`FiLe' for addition -$PROG add: use '$PROG commit' to add this file permanently" - dotest recase-2ss "$testcvs -q ci -mrecase" \ -"RCS file: $CVSROOT_DIRNAME/first-dir/FiLe,v -done -Checking in FiLe; -$CVSROOT_DIRNAME/first-dir/FiLe,v <-- FiLe -initial revision: 1\.1 -done" - else # server insensitive - dotest recase-1si "$testcvs add FiLe" \ -"$PROG add: Re-adding file \`FiLe' (in place of dead revision 1\.2)\. -$PROG add: use '$PROG commit' to add this file permanently" - dotest recase-2si "$testcvs -q ci -mrecase" \ -"Checking in FiLe; -$CVSROOT_DIRNAME/first-dir/FiLe,v <-- FiLe -new revision: 1\.3; previous revision: 1\.2 -done" - fi - - # Now verify that a checkout will still work - cd ../.. - mkdir 2; cd 2 - dotest recase-3 "$testcvs -q co first-dir" \ -"U first-dir/FiLe" - - cd first-dir - # Prove that we can still get status and log information on - # conflicting case files (1 in Attic, one in parent). - if $remote; then - if $client_sensitive; then - file=file - fIlE=fIlE - else # client insensitive - # Because FiLe is present on a case insensitive client, it is the - # only one ever found and queried or altered. - file=FiLe - fIlE=FiLe - fi - else # ! $remote - file=file - fIlE=fIlE - fi - if $server_sensitive; then - if $client_sensitive; then - # Client finds Entry only for FiLe. Others returned by server. - dotest recase-4sscs "$testcvs status file" \ -"=================================================================== -File: no file file Status: Up-to-date - - Working revision: No entry for file - Repository revision: 1\.2 $CVSROOT_DIRNAME/first-dir/Attic/file,v" - dotest recase-5sscs "$testcvs log file" \ -" -RCS file: $CVSROOT_DIRNAME/first-dir/Attic/file,v -Working file: file -head: 1\.2 -branch: -locks: strict -access list: -symbolic names: - first: 1\.1 -keyword substitution: kv -total revisions: 2; selected revisions: 2 -description: ----------------------------- -revision 1\.2 -date: [0-9/]* [0-9:]*; author: $username; state: dead; lines: +0 -0 -rm ----------------------------- -revision 1\.1 -date: [0-9/]* [0-9:]*; author: $username; state: Exp; -add -=============================================================================" - dotest recase-6sscs "$testcvs status FiLe" \ -"=================================================================== -File: FiLe Status: Up-to-date - - Working revision: 1\.1.* - Repository revision: 1\.1 $CVSROOT_DIRNAME/first-dir/FiLe,v - Sticky Tag: (none) - Sticky Date: (none) - Sticky Options: (none)" - dotest recase-7sscs "$testcvs log FiLe" \ -" -RCS file: $CVSROOT_DIRNAME/first-dir/FiLe,v -Working file: FiLe -head: 1\.1 -branch: -locks: strict -access list: -symbolic names: -keyword substitution: kv -total revisions: 1; selected revisions: 1 -description: ----------------------------- -revision 1\.1 -date: [0-9/]* [0-9:]*; author: $username; state: Exp; -recase -=============================================================================" - else # server sensitive && client insensitive - # Client finds same Entry for file & FiLe. - dotest recase-4ssci "$testcvs status file" \ -"=================================================================== -File: FiLe Status: Up-to-date - - Working revision: 1\.1.* - Repository revision: 1\.1 $CVSROOT_DIRNAME/first-dir/FiLe,v - Sticky Tag: (none) - Sticky Date: (none) - Sticky Options: (none)" - dotest recase-5ssci "$testcvs log file" \ -" -RCS file: $CVSROOT_DIRNAME/first-dir/FiLe,v -Working file: FiLe -head: 1\.1 -branch: -locks: strict -access list: -symbolic names: -keyword substitution: kv -total revisions: 1; selected revisions: 1 -description: ----------------------------- -revision 1\.1 -date: [0-9/]* [0-9:]*; author: $username; state: Exp; -recase -=============================================================================" - dotest recase-6ss "$testcvs status FiLe" \ -"=================================================================== -File: FiLe Status: Up-to-date - - Working revision: 1\.1.* - Repository revision: 1\.1 $CVSROOT_DIRNAME/first-dir/FiLe,v - Sticky Tag: (none) - Sticky Date: (none) - Sticky Options: (none)" - dotest recase-7ss "$testcvs log FiLe" \ -" -RCS file: $CVSROOT_DIRNAME/first-dir/FiLe,v -Working file: FiLe -head: 1\.1 -branch: -locks: strict -access list: -symbolic names: -keyword substitution: kv -total revisions: 1; selected revisions: 1 -description: ----------------------------- -revision 1\.1 -date: [0-9/]* [0-9:]*; author: $username; state: Exp; -recase -=============================================================================" - fi - else # server insensitive - # There is only one archive when the server is insensitive, but the - # printed file/archive name can vary. - dotest recase-4si "$testcvs status file" \ -"=================================================================== -File: $file Status: Up-to-date - - Working revision: 1\.3.* - Repository revision: 1\.3 $CVSROOT_DIRNAME/first-dir/$file,v - Sticky Tag: (none) - Sticky Date: (none) - Sticky Options: (none)" - dotest recase-5si "$testcvs log file" \ -" -RCS file: $CVSROOT_DIRNAME/first-dir/$file,v -Working file: $file -head: 1\.3 -branch: -locks: strict -access list: -symbolic names: - first: 1\.1 -keyword substitution: kv -total revisions: 3; selected revisions: 3 -description: ----------------------------- -revision 1\.3 -date: [0-9/]* [0-9:]*; author: $username; state: Exp; lines: +1 -1 -recase ----------------------------- -revision 1\.2 -date: [0-9/]* [0-9:]*; author: $username; state: dead; lines: +0 -0 -rm ----------------------------- -revision 1\.1 -date: [0-9/]* [0-9:]*; author: $username; state: Exp; -add -=============================================================================" - dotest recase-6si "$testcvs status FiLe" \ -"=================================================================== -File: FiLe Status: Up-to-date - - Working revision: 1\.3.* - Repository revision: 1\.3 $CVSROOT_DIRNAME/first-dir/FiLe,v - Sticky Tag: (none) - Sticky Date: (none) - Sticky Options: (none)" - dotest recase-7si "$testcvs log FiLe" \ -" -RCS file: $CVSROOT_DIRNAME/first-dir/FiLe,v -Working file: FiLe -head: 1\.3 -branch: -locks: strict -access list: -symbolic names: - first: 1\.1 -keyword substitution: kv -total revisions: 3; selected revisions: 3 -description: ----------------------------- -revision 1\.3 -date: [0-9/]* [0-9:]*; author: $username; state: Exp; lines: +1 -1 -recase ----------------------------- -revision 1\.2 -date: [0-9/]* [0-9:]*; author: $username; state: dead; lines: +0 -0 -rm ----------------------------- -revision 1\.1 -date: [0-9/]* [0-9:]*; author: $username; state: Exp; -add -=============================================================================" - fi - - # And when the file does not exist on the client, we go with the - # client Entries match. - if $client_sensitive && $server_sensitive; then - dotest recase-8sscs "$testcvs status fIlE" \ -"$PROG status: nothing known about fIlE -=================================================================== -File: no file fIlE Status: Unknown - - Working revision: No entry for fIlE - Repository revision: No revision control file" - else # !$client_sensitive || !$server_sensitive - dotest recase-8anyi "$testcvs status fIlE" \ -"=================================================================== -File: $fIlE Status: Up-to-date - - Working revision: 1\.[0-9]*.* - Repository revision: 1\.[0-9]* $CVSROOT_DIRNAME/first-dir/$fIlE,v - Sticky Tag: (none) - Sticky Date: (none) - Sticky Options: (none)" - fi - - # and an update - if $server_sensitive; then - dotest recase-9ss "$testcvs -q up -rfirst" \ -"$PROG update: FiLe is no longer in the repository -U file" - - if $client_sensitive; then - dotest recase-10sscs "$testcvs -q up -A" \ -"U FiLe -$PROG update: file is no longer in the repository" - else # client insensitive - # FIXCVS: This should remove the offending file first. - dotest_fail recase-10ssci "$testcvs -q up -A" \ -"$PROG update: move away \./FiLe; it is in the way -C FiLe -$PROG update: file is no longer in the repository" - - cd .. - rm -r first-dir - dotest recase-11ssci "$testcvs -q co first-dir" \ -"U first-dir/FiLe" - cd first-dir - fi - - # - # See what happens when cased names clash. - # - - # Copy the archive - if test -n "$remotehost"; then - $CVS_RSH $remotehost "cp $CVSROOT_DIRNAME/first-dir/FiLe,v \ - $CVSROOT_DIRNAME/first-dir/FILE,v" - else - cp $CVSROOT_DIRNAME/first-dir/FiLe,v \ - $CVSROOT_DIRNAME/first-dir/FILE,v - fi - - if $client_sensitive; then - dotest recase-12sscs "$testcvs -q up" "U FILE" - else # client insensitive - dotest_fail recase-12ssci "$testcvs -q up" \ -"$PROG update: move away \./FILE; it is in the way -C FILE" - fi - else # server insensitive - dotest recase-9si "$testcvs -q up -rfirst" "U FiLe" - dotest recase-10si "$testcvs -q up -A" "U FiLe" - fi - - # Prove that we can still get status and log information on - # conflicting case files (1 in Attic, two in parent). - if $server_sensitive; then - if $client_sensitive; then - # Client finds Entry only for FiLe. Others returned by server. - dotest recase-13sscs "$testcvs status file" \ -"=================================================================== -File: no file file Status: Up-to-date - - Working revision: No entry for file - Repository revision: 1\.2 $CVSROOT_DIRNAME/first-dir/Attic/file,v" - dotest recase-14sscs "$testcvs log file" \ -" -RCS file: $CVSROOT_DIRNAME/first-dir/Attic/file,v -Working file: file -head: 1\.2 -branch: -locks: strict -access list: -symbolic names: - first: 1\.1 -keyword substitution: kv -total revisions: 2; selected revisions: 2 -description: ----------------------------- -revision 1\.2 -date: [0-9/]* [0-9:]*; author: $username; state: dead; lines: +0 -0 -rm ----------------------------- -revision 1\.1 -date: [0-9/]* [0-9:]*; author: $username; state: Exp; -add -=============================================================================" - dotest recase-15sscs "$testcvs status FiLe" \ -"=================================================================== -File: FiLe Status: Up-to-date - - Working revision: 1\.1.* - Repository revision: 1\.1 $CVSROOT_DIRNAME/first-dir/FiLe,v - Sticky Tag: (none) - Sticky Date: (none) - Sticky Options: (none)" - dotest recase-16sscs "$testcvs log FiLe" \ -" -RCS file: $CVSROOT_DIRNAME/first-dir/FiLe,v -Working file: FiLe -head: 1\.1 -branch: -locks: strict -access list: -symbolic names: -keyword substitution: kv -total revisions: 1; selected revisions: 1 -description: ----------------------------- -revision 1\.1 -date: [0-9/]* [0-9:]*; author: $username; state: Exp; -recase -=============================================================================" - dotest recase-17sscs "$testcvs status FILE" \ -"=================================================================== -File: FILE Status: Up-to-date - - Working revision: 1.1.* - Repository revision: 1.1 ${CVSROOT_DIRNAME}/first-dir/FILE,v - Sticky Tag: (none) - Sticky Date: (none) - Sticky Options: (none)" - dotest recase-18sscs "$testcvs log FILE" \ -" -RCS file: $CVSROOT_DIRNAME/first-dir/FILE,v -Working file: FILE -head: 1\.1 -branch: -locks: strict -access list: -symbolic names: -keyword substitution: kv -total revisions: 1; selected revisions: 1 -description: ----------------------------- -revision 1\.1 -date: [0-9/]* [0-9:]*; author: $username; state: Exp; -recase -=============================================================================" - else # $server_sensitive && !$client_sensitive - # Client finds same Entry for file & FiLe. - dotest recase-13ssci "$testcvs status file" \ -"=================================================================== -File: FiLe Status: Up-to-date - - Working revision: 1\.1.* - Repository revision: 1\.1 $CVSROOT_DIRNAME/first-dir/FiLe,v - Sticky Tag: (none) - Sticky Date: (none) - Sticky Options: (none)" - dotest recase-16ssci "$testcvs log FiLe" \ -" -RCS file: $CVSROOT_DIRNAME/first-dir/FiLe,v -Working file: FiLe -head: 1\.1 -branch: -locks: strict -access list: -symbolic names: -keyword substitution: kv -total revisions: 1; selected revisions: 1 -description: ----------------------------- -revision 1\.1 -date: [0-9/]* [0-9:]*; author: $username; state: Exp; -recase -=============================================================================" - dotest recase-17ssci "$testcvs status FILE" \ -"=================================================================== -File: FiLe Status: Up-to-date - - Working revision: 1\.1.* - Repository revision: 1\.1 $CVSROOT_DIRNAME/first-dir/FiLe,v - Sticky Tag: (none) - Sticky Date: (none) - Sticky Options: (none)" - dotest recase-18ssci "$testcvs log FILE" \ -" -RCS file: $CVSROOT_DIRNAME/first-dir/FiLe,v -Working file: FiLe -head: 1\.1 -branch: -locks: strict -access list: -symbolic names: -keyword substitution: kv -total revisions: 1; selected revisions: 1 -description: ----------------------------- -revision 1\.1 -date: [0-9/]* [0-9:]*; author: $username; state: Exp; -recase -=============================================================================" - fi - else # !$server_sensitive - # Skip these when the server is case insensitive - nothing - # has changed since recase-[4-7]si - : - fi - - if $client_sensitive && $server_sensitive; then - dotest recase-19sscs "$testcvs status fIlE" \ -"$PROG status: nothing known about fIlE -=================================================================== -File: no file fIlE Status: Unknown - - Working revision: No entry for fIlE - Repository revision: No revision control file" - else # !$client_sensitive || !$server_sensitive - dotest recase-19anyi "$testcvs status fIlE" \ -"=================================================================== -File: $fIlE Status: Up-to-date - - Working revision: 1\.[0-9]*.* - Repository revision: 1\.[0-9]* $CVSROOT_DIRNAME/first-dir/$fIlE,v - Sticky Tag: (none) - Sticky Date: (none) - Sticky Options: (none)" - fi - - # And last but not least, prove that a checkout is still possible. - cd ../.. - mkdir 3; cd 3 - if $server_sensitive; then - if $client_sensitive; then - dotest recase-20sscs "$testcvs -q co first-dir" \ -"U first-dir/FILE -U first-dir/FiLe" - else # $server_senstive && !$client_sensitive - dotest_fail recase-20ssci "$testcvs -q co first-dir" \ -"U first-dir/FILE -$PROG checkout: move away first-dir/FiLe; it is in the way -C first-dir/FiLe" - fi - else # !$server_sensitive - # Skip these since nothing has changed. - : - fi - - if $keep; then - echo Keeping ${TESTDIR} and exiting due to --keep - exit 0 - fi - - cd .. - rm -r 1 2 3 - if $server_sensitive && test -n "$remotehost"; then - # It is necessary to remove one of the case-conflicted files before - # recursively removing the rest under Cygwin on a Samba share or - # Samba returns a permission denied error due to its case - # confusion. - $CVS_RSH $remotehost "rm -f $CVSROOT_DIRNAME/first-dir/FILE,v" - fi - rm -rf $CVSROOT_DIRNAME/first-dir - ;; - - - - multiroot) - # - # set up two repositories - # - - CVSROOT1_DIRNAME=${TESTDIR}/root1 - CVSROOT2_DIRNAME=${TESTDIR}/root2 - CVSROOT1=`newroot $CVSROOT1_DIRNAME` - CVSROOT2=`newroot $CVSROOT2_DIRNAME` - testcvs1="${testcvs} -d ${CVSROOT1}" - testcvs2="${testcvs} -d ${CVSROOT2}" - - dotest multiroot-setup-1 "mkdir $CVSROOT1_DIRNAME $CVSROOT2_DIRNAME" - dotest multiroot-setup-2 "$testcvs -d$CVSROOT1_DIRNAME init" - dotest multiroot-setup-3 "$testcvs -d$CVSROOT2_DIRNAME init" - - # - # create some directories in root1 - # - mkdir 1; cd 1 - dotest multiroot-setup-4 "${testcvs1} co -l ." \ -"${PROG} checkout: Updating ." - mkdir mod1-1 mod1-2 - dotest multiroot-setup-5 "${testcvs1} add mod1-1 mod1-2" \ -"Directory ${CVSROOT1_DIRNAME}/mod1-1 added to the repository -Directory ${CVSROOT1_DIRNAME}/mod1-2 added to the repository" - echo file1-1 > mod1-1/file1-1 - echo file1-2 > mod1-2/file1-2 - dotest multiroot-setup-6 "${testcvs1} add mod1-1/file1-1 mod1-2/file1-2" \ -"${PROG} add: scheduling file .mod1-1/file1-1. for addition -${PROG} add: scheduling file .mod1-2/file1-2. for addition -${PROG} add: use .${PROG} commit. to add these files permanently" - dotest multiroot-setup-7 "${testcvs1} commit -m is" \ -"${PROG} [a-z]*: Examining \. -${PROG} [a-z]*: Examining mod1-1 -${PROG} [a-z]*: Examining mod1-2 -RCS file: ${CVSROOT1_DIRNAME}/mod1-1/file1-1,v -done -Checking in mod1-1/file1-1; -${CVSROOT1_DIRNAME}/mod1-1/file1-1,v <-- file1-1 -initial revision: 1.1 -done -RCS file: ${CVSROOT1_DIRNAME}/mod1-2/file1-2,v -done -Checking in mod1-2/file1-2; -${CVSROOT1_DIRNAME}/mod1-2/file1-2,v <-- file1-2 -initial revision: 1.1 -done" - cd .. - rm -rf 1 - - # - # create some directories in root2 - # - mkdir 1; cd 1 - dotest multiroot-setup-8 "${testcvs2} co -l ." \ -"${PROG} checkout: Updating ." - mkdir mod2-1 mod2-2 - dotest multiroot-setup-9 "${testcvs2} add mod2-1 mod2-2" \ -"Directory ${CVSROOT2_DIRNAME}/mod2-1 added to the repository -Directory ${CVSROOT2_DIRNAME}/mod2-2 added to the repository" - echo file2-1 > mod2-1/file2-1 - echo file2-2 > mod2-2/file2-2 - dotest multiroot-setup-6 "${testcvs2} add mod2-1/file2-1 mod2-2/file2-2" \ -"${PROG} add: scheduling file .mod2-1/file2-1. for addition -${PROG} add: scheduling file .mod2-2/file2-2. for addition -${PROG} add: use .${PROG} commit. to add these files permanently" - dotest multiroot-setup-10 "${testcvs2} commit -m anyone" \ -"${PROG} [a-z]*: Examining \. -${PROG} [a-z]*: Examining mod2-1 -${PROG} [a-z]*: Examining mod2-2 -RCS file: ${CVSROOT2_DIRNAME}/mod2-1/file2-1,v -done -Checking in mod2-1/file2-1; -${CVSROOT2_DIRNAME}/mod2-1/file2-1,v <-- file2-1 -initial revision: 1.1 -done -RCS file: ${CVSROOT2_DIRNAME}/mod2-2/file2-2,v -done -Checking in mod2-2/file2-2; -${CVSROOT2_DIRNAME}/mod2-2/file2-2,v <-- file2-2 -initial revision: 1.1 -done" - cd .. - rm -rf 1 - - # check out a few directories, from simple/shallow to - # complex/deep - mkdir 1; cd 1 - - # OK, this case is kind of weird. If we just run things from - # here, without CVS/Root, then CVS will contact the server - # mentioned in CVSROOT (which is irrelevant) which will print - # some messages. Our workaround is to make sure we have a - # CVS/Root file at top level. In the future, it is possible - # the best behavior will be to extend the existing behavior - # ("being called from a directory without CVS administration - # has always meant to process each of the sub-dirs") to also - # do that if there is no CVSROOT, CVS/Root, or -d at top level. - # - # The local case could stumble through the tests without creating - # the top-level CVS/Root, but we create it for local and for - # remote to reduce special cases later in the test. - dotest multiroot-workaround "${testcvs1} -q co -l ." "" - - dotest multiroot-setup-11 "${testcvs1} co mod1-1 mod1-2" \ -"${PROG} checkout: Updating mod1-1 -U mod1-1/file1-1 -${PROG} checkout: Updating mod1-2 -U mod1-2/file1-2" - dotest multiroot-setup-12 "${testcvs2} co mod2-1 mod2-2" \ -"${PROG} checkout: Updating mod2-1 -U mod2-1/file2-1 -${PROG} checkout: Updating mod2-2 -U mod2-2/file2-2" - cd mod1-2 - dotest multiroot-setup-13 "${testcvs2} co mod2-2" \ -"${PROG} checkout: Updating mod2-2 -U mod2-2/file2-2" - cd .. - cd mod2-2 - dotest multiroot-setup-14 "${testcvs1} co mod1-2" \ -"${PROG} checkout: Updating mod1-2 -U mod1-2/file1-2" - cd .. - - # - # Make sure that the Root and Repository files contain the - # correct information. - # - dotest multiroot-cvsadm-1a "cat mod1-1/CVS/Root" "${CVSROOT1}" - dotest multiroot-cvsadm-1b "cat mod1-1/CVS/Repository" "mod1-1" - dotest multiroot-cvsadm-2a "cat mod2-1/CVS/Root" "${CVSROOT2}" - dotest multiroot-cvsadm-2b "cat mod2-1/CVS/Repository" "mod2-1" - dotest multiroot-cvsadm-3a "cat mod1-2/CVS/Root" "${CVSROOT1}" - dotest multiroot-cvsadm-3b "cat mod1-2/CVS/Repository" "mod1-2" - dotest multiroot-cvsadm-3c "cat mod1-2/mod2-2/CVS/Root" "${CVSROOT2}" - dotest multiroot-cvsadm-3d "cat mod1-2/mod2-2/CVS/Repository" "mod2-2" - dotest multiroot-cvsadm-4a "cat mod2-2/CVS/Root" "${CVSROOT2}" - dotest multiroot-cvsadm-4b "cat mod2-2/CVS/Repository" "mod2-2" - dotest multiroot-cvsadm-4c "cat mod2-2/mod1-2/CVS/Root" "${CVSROOT1}" - dotest multiroot-cvsadm-4d "cat mod2-2/mod1-2/CVS/Repository" "mod1-2" - - # - # Start testing various cvs commands. Begin with commands - # without extra arguments (e.g. "cvs update", "cvs diff", - # etc. - # - - # Do at least one command with both CVSROOTs to make sure - # that there's not some kind of unexpected dependency on the - # choice of which CVSROOT is specified on the command line. - - dotest multiroot-update-1a "${testcvs1} update" \ -"${PROG} update: Updating \. -${PROG} update: Updating mod1-1 -${PROG} update: Updating mod1-2 -${PROG} update: Updating mod1-2/mod2-2 -${PROG} update: cannot open directory ${CVSROOT1_DIRNAME}/mod2-2: No such file or directory -${PROG} update: skipping directory mod1-2/mod2-2 -${PROG} update: Updating mod2-1 -${PROG} update: cannot open directory ${CVSROOT1_DIRNAME}/mod2-1: No such file or directory -${PROG} update: skipping directory mod2-1 -${PROG} update: Updating mod2-2 -${PROG} update: cannot open directory ${CVSROOT1_DIRNAME}/mod2-2: No such file or directory -${PROG} update: skipping directory mod2-2" - - # Same deal but with -d ${CVSROOT2}. - dotest multiroot-update-1b "${testcvs2} update" \ -"${PROG} update: Updating \. -${PROG} update: Updating mod1-1 -${PROG} update: cannot open directory ${CVSROOT2_DIRNAME}/mod1-1: No such file or directory -${PROG} update: skipping directory mod1-1 -${PROG} update: Updating mod1-2 -${PROG} update: cannot open directory ${CVSROOT2_DIRNAME}/mod1-2: No such file or directory -${PROG} update: skipping directory mod1-2 -${PROG} update: Updating mod2-1 -${PROG} update: Updating mod2-2 -${PROG} update: Updating mod2-2/mod1-2 -${PROG} update: cannot open directory ${CVSROOT2_DIRNAME}/mod1-2: No such file or directory -${PROG} update: skipping directory mod2-2/mod1-2" - - # modify all files and do a diff - - echo bobby >> mod1-1/file1-1 - echo brown >> mod1-2/file1-2 - echo goes >> mod2-1/file2-1 - echo down >> mod2-2/file2-2 - - dotest_fail multiroot-diff-1 "${testcvs} diff" \ -"${PROG} diff: Diffing \. -${PROG} diff: Diffing mod1-1 -Index: mod1-1/file1-1 -=================================================================== -RCS file: ${TESTDIR}/root1/mod1-1/file1-1,v -retrieving revision 1\.1 -diff -r1\.1 file1-1 -1a2 -> bobby -${PROG} diff: Diffing mod1-2 -Index: mod1-2/file1-2 -=================================================================== -RCS file: ${TESTDIR}/root1/mod1-2/file1-2,v -retrieving revision 1\.1 -diff -r1\.1 file1-2 -1a2 -> brown -${PROG} diff: Diffing mod2-2/mod1-2 -${PROG} diff: Diffing mod1-2/mod2-2 -${PROG} diff: Diffing mod2-1 -Index: mod2-1/file2-1 -=================================================================== -RCS file: ${TESTDIR}/root2/mod2-1/file2-1,v -retrieving revision 1\.1 -diff -r1\.1 file2-1 -1a2 -> goes -${PROG} diff: Diffing mod2-2 -Index: mod2-2/file2-2 -=================================================================== -RCS file: ${TESTDIR}/root2/mod2-2/file2-2,v -retrieving revision 1\.1 -diff -r1\.1 file2-2 -1a2 -> down" \ -"${PROG} diff: Diffing \. -${PROG} diff: Diffing mod1-1 -Index: mod1-1/file1-1 -=================================================================== -RCS file: ${TESTDIR}/root1/mod1-1/file1-1,v -retrieving revision 1\.1 -diff -r1\.1 file1-1 -1a2 -> bobby -${PROG} diff: Diffing mod1-2 -Index: mod1-2/file1-2 -=================================================================== -RCS file: ${TESTDIR}/root1/mod1-2/file1-2,v -retrieving revision 1\.1 -diff -r1\.1 file1-2 -1a2 -> brown -${PROG} diff: Diffing mod2-2 -${PROG} diff: Diffing mod2-2/mod1-2 -${PROG} diff: Diffing mod1-2 -${PROG} diff: Diffing mod1-2/mod2-2 -${PROG} diff: Diffing mod2-1 -Index: mod2-1/file2-1 -=================================================================== -RCS file: ${TESTDIR}/root2/mod2-1/file2-1,v -retrieving revision 1\.1 -diff -r1\.1 file2-1 -1a2 -> goes -${PROG} diff: Diffing mod2-2 -Index: mod2-2/file2-2 -=================================================================== -RCS file: ${TESTDIR}/root2/mod2-2/file2-2,v -retrieving revision 1\.1 -diff -r1\.1 file2-2 -1a2 -> down" - - dotest multiroot-commit-1 "${testcvs} commit -m actually" \ -"${PROG} [a-z]*: Examining \. -${PROG} [a-z]*: Examining mod1-1 -${PROG} [a-z]*: Examining mod1-2 -${PROG} [a-z]*: Examining mod2-2/mod1-2 -Checking in mod1-1/file1-1; -${TESTDIR}/root1/mod1-1/file1-1,v <-- file1-1 -new revision: 1.2; previous revision: 1.1 -done -Checking in mod1-2/file1-2; -${TESTDIR}/root1/mod1-2/file1-2,v <-- file1-2 -new revision: 1.2; previous revision: 1.1 -done -${PROG} [a-z]*: Examining mod1-2/mod2-2 -${PROG} [a-z]*: Examining mod2-1 -${PROG} [a-z]*: Examining mod2-2 -Checking in mod2-1/file2-1; -${TESTDIR}/root2/mod2-1/file2-1,v <-- file2-1 -new revision: 1.2; previous revision: 1.1 -done -Checking in mod2-2/file2-2; -${TESTDIR}/root2/mod2-2/file2-2,v <-- file2-2 -new revision: 1.2; previous revision: 1.1 -done" - - dotest multiroot-update-2 "${testcvs} update" \ -"${PROG} update: Updating \. -${PROG} [a-z]*: Updating mod1-1 -${PROG} [a-z]*: Updating mod1-2 -${PROG} [a-z]*: Updating mod2-2/mod1-2 -U mod2-2/mod1-2/file1-2 -${PROG} [a-z]*: Updating mod1-2/mod2-2 -U mod1-2/mod2-2/file2-2 -${PROG} update: Updating mod2-1 -${PROG} update: Updating mod2-2" \ -"${PROG} update: Updating \. -${PROG} update: Updating mod1-1 -${PROG} update: Updating mod1-2 -${PROG} update: Updating mod2-2 -${PROG} update: Updating mod2-2/mod1-2 -P mod2-2/mod1-2/file1-2 -${PROG} update: Updating mod1-2 -${PROG} update: Updating mod1-2/mod2-2 -P mod1-2/mod2-2/file2-2 -${PROG} update: Updating mod2-1 -${PROG} update: Updating mod2-2" - - dotest multiroot-tag-1 "${testcvs} tag cattle" \ -"${PROG} tag: Tagging \. -${PROG} tag: Tagging mod1-1 -T mod1-1/file1-1 -${PROG} tag: Tagging mod1-2 -T mod1-2/file1-2 -${PROG} tag: Tagging mod2-2/mod1-2 -${PROG} tag: Tagging mod1-2/mod2-2 -T mod1-2/mod2-2/file2-2 -${PROG} tag: Tagging mod2-1 -T mod2-1/file2-1 -${PROG} tag: Tagging mod2-2" \ -"${PROG} tag: Tagging \. -${PROG} tag: Tagging mod1-1 -T mod1-1/file1-1 -${PROG} tag: Tagging mod1-2 -T mod1-2/file1-2 -${PROG} tag: Tagging mod2-2 -${PROG} tag: Tagging mod2-2/mod1-2 -${PROG} tag: Tagging mod1-2 -${PROG} tag: Tagging mod1-2/mod2-2 -T mod1-2/mod2-2/file2-2 -${PROG} tag: Tagging mod2-1 -T mod2-1/file2-1 -${PROG} tag: Tagging mod2-2" - - echo anotherfile1-1 > mod1-1/anotherfile1-1 - echo anotherfile2-1 > mod2-1/anotherfile2-1 - echo anotherfile1-2 > mod2-2/mod1-2/anotherfile1-2 - echo anotherfile2-2 > mod1-2/mod2-2/anotherfile2-2 - - if $remote; then - cd mod1-1 - dotest multiroot-add-1ar "${testcvs} add anotherfile1-1" \ -"${PROG} add: scheduling file .anotherfile1-1. for addition -${PROG} add: use .${PROG} commit. to add this file permanently" - cd ../mod2-1 - dotest multiroot-add-1br "${testcvs} add anotherfile2-1" \ -"${PROG} add: scheduling file .anotherfile2-1. for addition -${PROG} add: use .${PROG} commit. to add this file permanently" - cd ../mod2-2/mod1-2 - dotest multiroot-add-1cr "${testcvs} add anotherfile1-2" \ -"${PROG} add: scheduling file .anotherfile1-2. for addition -${PROG} add: use .${PROG} commit. to add this file permanently" - cd ../../mod1-2/mod2-2 - dotest multiroot-add-1dr "${testcvs} add anotherfile2-2" \ -"${PROG} add: scheduling file .anotherfile2-2. for addition -${PROG} add: use .${PROG} commit. to add this file permanently" - cd ../.. - else - dotest multiroot-add-1 "${testcvs} add mod1-1/anotherfile1-1 mod2-1/anotherfile2-1 mod2-2/mod1-2/anotherfile1-2 mod1-2/mod2-2/anotherfile2-2" \ -"${PROG} add: scheduling file .mod1-1/anotherfile1-1. for addition -${PROG} add: scheduling file .mod2-1/anotherfile2-1. for addition -${PROG} add: scheduling file .mod2-2/mod1-2/anotherfile1-2. for addition -${PROG} add: scheduling file .mod1-2/mod2-2/anotherfile2-2. for addition -${PROG} add: use .${PROG} commit. to add these files permanently" - fi - - dotest multiroot-status-1 "${testcvs} status -v" \ -"${PROG} status: Examining \. -${PROG} status: Examining mod1-1 -=================================================================== -File: anotherfile1-1 Status: Locally Added - - Working revision: New file! - Repository revision: No revision control file - Sticky Tag: (none) - Sticky Date: (none) - Sticky Options: (none) - -=================================================================== -File: file1-1 Status: Up-to-date - - Working revision: 1\.2.* - Repository revision: 1\.2 ${CVSROOT1_DIRNAME}/mod1-1/file1-1,v - Sticky Tag: (none) - Sticky Date: (none) - Sticky Options: (none) - - Existing Tags: - cattle (revision: 1\.2) - -${PROG} status: Examining mod1-2 -=================================================================== -File: file1-2 Status: Up-to-date - - Working revision: 1\.2.* - Repository revision: 1\.2 ${CVSROOT1_DIRNAME}/mod1-2/file1-2,v - Sticky Tag: (none) - Sticky Date: (none) - Sticky Options: (none) - - Existing Tags: - cattle (revision: 1\.2) - -${PROG} status: Examining mod2-2/mod1-2 -=================================================================== -File: anotherfile1-2 Status: Locally Added - - Working revision: New file! - Repository revision: No revision control file - Sticky Tag: (none) - Sticky Date: (none) - Sticky Options: (none) - -=================================================================== -File: file1-2 Status: Up-to-date - - Working revision: 1\.2.* - Repository revision: 1\.2 ${CVSROOT1_DIRNAME}/mod1-2/file1-2,v - Sticky Tag: (none) - Sticky Date: (none) - Sticky Options: (none) - - Existing Tags: - cattle (revision: 1\.2) - -${PROG} status: Examining mod1-2/mod2-2 -=================================================================== -File: anotherfile2-2 Status: Locally Added - - Working revision: New file! - Repository revision: No revision control file - Sticky Tag: (none) - Sticky Date: (none) - Sticky Options: (none) - -=================================================================== -File: file2-2 Status: Up-to-date - - Working revision: 1\.2.* - Repository revision: 1\.2 ${CVSROOT2_DIRNAME}/mod2-2/file2-2,v - Sticky Tag: (none) - Sticky Date: (none) - Sticky Options: (none) - - Existing Tags: - cattle (revision: 1\.2) - -${PROG} status: Examining mod2-1 -=================================================================== -File: anotherfile2-1 Status: Locally Added - - Working revision: New file! - Repository revision: No revision control file - Sticky Tag: (none) - Sticky Date: (none) - Sticky Options: (none) - -=================================================================== -File: file2-1 Status: Up-to-date - - Working revision: 1\.2.* - Repository revision: 1\.2 ${CVSROOT2_DIRNAME}/mod2-1/file2-1,v - Sticky Tag: (none) - Sticky Date: (none) - Sticky Options: (none) - - Existing Tags: - cattle (revision: 1\.2) - -${PROG} status: Examining mod2-2 -=================================================================== -File: file2-2 Status: Up-to-date - - Working revision: 1\.2.* - Repository revision: 1\.2 ${CVSROOT2_DIRNAME}/mod2-2/file2-2,v - Sticky Tag: (none) - Sticky Date: (none) - Sticky Options: (none) - - Existing Tags: - cattle (revision: 1\.2)" \ -"${PROG} status: Examining \. -${PROG} status: Examining mod1-1 -=================================================================== -File: anotherfile1-1 Status: Locally Added - - Working revision: New file! - Repository revision: No revision control file - Sticky Tag: (none) - Sticky Date: (none) - Sticky Options: (none) - -=================================================================== -File: file1-1 Status: Up-to-date - - Working revision: 1\.2.* - Repository revision: 1\.2 ${CVSROOT1_DIRNAME}/mod1-1/file1-1,v - Sticky Tag: (none) - Sticky Date: (none) - Sticky Options: (none) - - Existing Tags: - cattle (revision: 1\.2) - -${PROG} status: Examining mod1-2 -=================================================================== -File: file1-2 Status: Up-to-date - - Working revision: 1\.2.* - Repository revision: 1\.2 ${CVSROOT1_DIRNAME}/mod1-2/file1-2,v - Sticky Tag: (none) - Sticky Date: (none) - Sticky Options: (none) - - Existing Tags: - cattle (revision: 1\.2) - -${PROG} status: Examining mod2-2 -${PROG} status: Examining mod2-2/mod1-2 -=================================================================== -File: anotherfile1-2 Status: Locally Added - - Working revision: New file! - Repository revision: No revision control file - Sticky Tag: (none) - Sticky Date: (none) - Sticky Options: (none) - -=================================================================== -File: file1-2 Status: Up-to-date - - Working revision: 1\.2.* - Repository revision: 1\.2 ${CVSROOT1_DIRNAME}/mod1-2/file1-2,v - Sticky Tag: (none) - Sticky Date: (none) - Sticky Options: (none) - - Existing Tags: - cattle (revision: 1\.2) - -${PROG} status: Examining mod1-2 -${PROG} status: Examining mod1-2/mod2-2 -=================================================================== -File: anotherfile2-2 Status: Locally Added - - Working revision: New file! - Repository revision: No revision control file - Sticky Tag: (none) - Sticky Date: (none) - Sticky Options: (none) - -=================================================================== -File: file2-2 Status: Up-to-date - - Working revision: 1\.2.* - Repository revision: 1\.2 ${CVSROOT2_DIRNAME}/mod2-2/file2-2,v - Sticky Tag: (none) - Sticky Date: (none) - Sticky Options: (none) - - Existing Tags: - cattle (revision: 1\.2) - -${PROG} status: Examining mod2-1 -=================================================================== -File: anotherfile2-1 Status: Locally Added - - Working revision: New file! - Repository revision: No revision control file - Sticky Tag: (none) - Sticky Date: (none) - Sticky Options: (none) - -=================================================================== -File: file2-1 Status: Up-to-date - - Working revision: 1\.2.* - Repository revision: 1\.2 ${CVSROOT2_DIRNAME}/mod2-1/file2-1,v - Sticky Tag: (none) - Sticky Date: (none) - Sticky Options: (none) - - Existing Tags: - cattle (revision: 1\.2) - -${PROG} status: Examining mod2-2 -=================================================================== -File: file2-2 Status: Up-to-date - - Working revision: 1\.2.* - Repository revision: 1\.2 ${CVSROOT2_DIRNAME}/mod2-2/file2-2,v - Sticky Tag: (none) - Sticky Date: (none) - Sticky Options: (none) - - Existing Tags: - cattle (revision: 1\.2)" - - dotest multiroot-commit-2 "${testcvs} commit -m reading" \ -"${PROG} [a-z]*: Examining \. -${PROG} [a-z]*: Examining mod1-1 -${PROG} [a-z]*: Examining mod1-2 -${PROG} [a-z]*: Examining mod2-2/mod1-2 -RCS file: ${CVSROOT1_DIRNAME}/mod1-1/anotherfile1-1,v -done -Checking in mod1-1/anotherfile1-1; -${CVSROOT1_DIRNAME}/mod1-1/anotherfile1-1,v <-- anotherfile1-1 -initial revision: 1\.1 -done -RCS file: ${CVSROOT1_DIRNAME}/mod1-2/anotherfile1-2,v -done -Checking in mod2-2/mod1-2/anotherfile1-2; -${CVSROOT1_DIRNAME}/mod1-2/anotherfile1-2,v <-- anotherfile1-2 -initial revision: 1\.1 -done -${PROG} [a-z]*: Examining mod1-2/mod2-2 -${PROG} [a-z]*: Examining mod2-1 -${PROG} [a-z]*: Examining mod2-2 -RCS file: ${CVSROOT2_DIRNAME}/mod2-2/anotherfile2-2,v -done -Checking in mod1-2/mod2-2/anotherfile2-2; -${CVSROOT2_DIRNAME}/mod2-2/anotherfile2-2,v <-- anotherfile2-2 -initial revision: 1\.1 -done -RCS file: ${CVSROOT2_DIRNAME}/mod2-1/anotherfile2-1,v -done -Checking in mod2-1/anotherfile2-1; -${CVSROOT2_DIRNAME}/mod2-1/anotherfile2-1,v <-- anotherfile2-1 -initial revision: 1\.1 -done" - - dotest multiroot-update-3 "${testcvs} update" \ -"${PROG} update: Updating \. -${PROG} [a-z]*: Updating mod1-1 -${PROG} [a-z]*: Updating mod1-2 -U mod1-2/anotherfile1-2 -${PROG} [a-z]*: Updating mod2-2/mod1-2 -${PROG} [a-z]*: Updating mod1-2/mod2-2 -${PROG} [a-z]*: Updating mod2-1 -${PROG} [a-z]*: Updating mod2-2 -U mod2-2/anotherfile2-2" \ -"${PROG} update: Updating \. -${PROG} update: Updating mod1-1 -${PROG} update: Updating mod1-2 -U mod1-2/anotherfile1-2 -${PROG} update: Updating mod2-2 -${PROG} update: Updating mod2-2/mod1-2 -${PROG} update: Updating mod1-2 -${PROG} update: Updating mod1-2/mod2-2 -${PROG} update: Updating mod2-1 -${PROG} update: Updating mod2-2 -U mod2-2/anotherfile2-2" - - dotest multiroot-log-1 "${testcvs} log" \ -"${PROG} log: Logging \. -${PROG} log: Logging mod1-1 - -RCS file: ${CVSROOT1_DIRNAME}/mod1-1/anotherfile1-1,v -Working file: mod1-1/anotherfile1-1 -head: 1\.1 -branch: -locks: strict -access list: -symbolic names: -keyword substitution: kv -total revisions: 1; selected revisions: 1 -description: ----------------------------- -revision 1\.1 -date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; -reading -============================================================================= - -RCS file: ${CVSROOT1_DIRNAME}/mod1-1/file1-1,v -Working file: mod1-1/file1-1 -head: 1\.2 -branch: -locks: strict -access list: -symbolic names: - cattle: 1\.2 -keyword substitution: kv -total revisions: 2; selected revisions: 2 -description: ----------------------------- -revision 1\.2 -date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; lines: ${PLUS}1 -0 -actually ----------------------------- -revision 1\.1 -date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; -is -============================================================================= -${PROG} log: Logging mod1-2 - -RCS file: ${CVSROOT1_DIRNAME}/mod1-2/anotherfile1-2,v -Working file: mod1-2/anotherfile1-2 -head: 1\.1 -branch: -locks: strict -access list: -symbolic names: -keyword substitution: kv -total revisions: 1; selected revisions: 1 -description: ----------------------------- -revision 1\.1 -date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; -reading -============================================================================= - -RCS file: ${CVSROOT1_DIRNAME}/mod1-2/file1-2,v -Working file: mod1-2/file1-2 -head: 1\.2 -branch: -locks: strict -access list: -symbolic names: - cattle: 1\.2 -keyword substitution: kv -total revisions: 2; selected revisions: 2 -description: ----------------------------- -revision 1\.2 -date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; lines: ${PLUS}1 -0 -actually ----------------------------- -revision 1\.1 -date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; -is -============================================================================= -${PROG} log: Logging mod2-2/mod1-2 - -RCS file: ${CVSROOT1_DIRNAME}/mod1-2/anotherfile1-2,v -Working file: mod2-2/mod1-2/anotherfile1-2 -head: 1\.1 -branch: -locks: strict -access list: -symbolic names: -keyword substitution: kv -total revisions: 1; selected revisions: 1 -description: ----------------------------- -revision 1\.1 -date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; -reading -============================================================================= - -RCS file: ${CVSROOT1_DIRNAME}/mod1-2/file1-2,v -Working file: mod2-2/mod1-2/file1-2 -head: 1\.2 -branch: -locks: strict -access list: -symbolic names: - cattle: 1\.2 -keyword substitution: kv -total revisions: 2; selected revisions: 2 -description: ----------------------------- -revision 1\.2 -date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; lines: ${PLUS}1 -0 -actually ----------------------------- -revision 1\.1 -date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; -is -============================================================================= -${PROG} log: Logging mod1-2/mod2-2 - -RCS file: ${CVSROOT2_DIRNAME}/mod2-2/anotherfile2-2,v -Working file: mod1-2/mod2-2/anotherfile2-2 -head: 1\.1 -branch: -locks: strict -access list: -symbolic names: -keyword substitution: kv -total revisions: 1; selected revisions: 1 -description: ----------------------------- -revision 1\.1 -date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; -reading -============================================================================= - -RCS file: ${CVSROOT2_DIRNAME}/mod2-2/file2-2,v -Working file: mod1-2/mod2-2/file2-2 -head: 1\.2 -branch: -locks: strict -access list: -symbolic names: - cattle: 1\.2 -keyword substitution: kv -total revisions: 2; selected revisions: 2 -description: ----------------------------- -revision 1\.2 -date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; lines: ${PLUS}1 -0 -actually ----------------------------- -revision 1\.1 -date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; -anyone -============================================================================= -${PROG} log: Logging mod2-1 - -RCS file: ${CVSROOT2_DIRNAME}/mod2-1/anotherfile2-1,v -Working file: mod2-1/anotherfile2-1 -head: 1\.1 -branch: -locks: strict -access list: -symbolic names: -keyword substitution: kv -total revisions: 1; selected revisions: 1 -description: ----------------------------- -revision 1\.1 -date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; -reading -============================================================================= - -RCS file: ${CVSROOT2_DIRNAME}/mod2-1/file2-1,v -Working file: mod2-1/file2-1 -head: 1\.2 -branch: -locks: strict -access list: -symbolic names: - cattle: 1\.2 -keyword substitution: kv -total revisions: 2; selected revisions: 2 -description: ----------------------------- -revision 1\.2 -date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; lines: ${PLUS}1 -0 -actually ----------------------------- -revision 1\.1 -date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; -anyone -============================================================================= -${PROG} log: Logging mod2-2 - -RCS file: ${CVSROOT2_DIRNAME}/mod2-2/anotherfile2-2,v -Working file: mod2-2/anotherfile2-2 -head: 1\.1 -branch: -locks: strict -access list: -symbolic names: -keyword substitution: kv -total revisions: 1; selected revisions: 1 -description: ----------------------------- -revision 1\.1 -date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; -reading -============================================================================= - -RCS file: ${CVSROOT2_DIRNAME}/mod2-2/file2-2,v -Working file: mod2-2/file2-2 -head: 1\.2 -branch: -locks: strict -access list: -symbolic names: - cattle: 1\.2 -keyword substitution: kv -total revisions: 2; selected revisions: 2 -description: ----------------------------- -revision 1\.2 -date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; lines: ${PLUS}1 -0 -actually ----------------------------- -revision 1\.1 -date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; -anyone -=============================================================================" \ -"${PROG} log: Logging \. -${PROG} log: Logging mod1-1 - -RCS file: ${CVSROOT1_DIRNAME}/mod1-1/anotherfile1-1,v -Working file: mod1-1/anotherfile1-1 -head: 1\.1 -branch: -locks: strict -access list: -symbolic names: -keyword substitution: kv -total revisions: 1; selected revisions: 1 -description: ----------------------------- -revision 1\.1 -date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; -reading -============================================================================= - -RCS file: ${CVSROOT1_DIRNAME}/mod1-1/file1-1,v -Working file: mod1-1/file1-1 -head: 1\.2 -branch: -locks: strict -access list: -symbolic names: - cattle: 1\.2 -keyword substitution: kv -total revisions: 2; selected revisions: 2 -description: ----------------------------- -revision 1\.2 -date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; lines: ${PLUS}1 -0 -actually ----------------------------- -revision 1\.1 -date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; -is -============================================================================= -${PROG} log: Logging mod1-2 - -RCS file: ${CVSROOT1_DIRNAME}/mod1-2/anotherfile1-2,v -Working file: mod1-2/anotherfile1-2 -head: 1\.1 -branch: -locks: strict -access list: -symbolic names: -keyword substitution: kv -total revisions: 1; selected revisions: 1 -description: ----------------------------- -revision 1\.1 -date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; -reading -============================================================================= - -RCS file: ${CVSROOT1_DIRNAME}/mod1-2/file1-2,v -Working file: mod1-2/file1-2 -head: 1\.2 -branch: -locks: strict -access list: -symbolic names: - cattle: 1\.2 -keyword substitution: kv -total revisions: 2; selected revisions: 2 -description: ----------------------------- -revision 1\.2 -date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; lines: ${PLUS}1 -0 -actually ----------------------------- -revision 1\.1 -date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; -is -============================================================================= -${PROG} log: Logging mod2-2 -${PROG} log: Logging mod2-2/mod1-2 - -RCS file: ${CVSROOT1_DIRNAME}/mod1-2/anotherfile1-2,v -Working file: mod2-2/mod1-2/anotherfile1-2 -head: 1\.1 -branch: -locks: strict -access list: -symbolic names: -keyword substitution: kv -total revisions: 1; selected revisions: 1 -description: ----------------------------- -revision 1\.1 -date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; -reading -============================================================================= - -RCS file: ${CVSROOT1_DIRNAME}/mod1-2/file1-2,v -Working file: mod2-2/mod1-2/file1-2 -head: 1\.2 -branch: -locks: strict -access list: -symbolic names: - cattle: 1\.2 -keyword substitution: kv -total revisions: 2; selected revisions: 2 -description: ----------------------------- -revision 1\.2 -date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; lines: ${PLUS}1 -0 -actually ----------------------------- -revision 1\.1 -date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; -is -============================================================================= -${PROG} log: Logging mod1-2 -${PROG} log: Logging mod1-2/mod2-2 - -RCS file: ${CVSROOT2_DIRNAME}/mod2-2/anotherfile2-2,v -Working file: mod1-2/mod2-2/anotherfile2-2 -head: 1\.1 -branch: -locks: strict -access list: -symbolic names: -keyword substitution: kv -total revisions: 1; selected revisions: 1 -description: ----------------------------- -revision 1\.1 -date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; -reading -============================================================================= - -RCS file: ${CVSROOT2_DIRNAME}/mod2-2/file2-2,v -Working file: mod1-2/mod2-2/file2-2 -head: 1\.2 -branch: -locks: strict -access list: -symbolic names: - cattle: 1\.2 -keyword substitution: kv -total revisions: 2; selected revisions: 2 -description: ----------------------------- -revision 1\.2 -date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; lines: ${PLUS}1 -0 -actually ----------------------------- -revision 1\.1 -date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; -anyone -============================================================================= -${PROG} log: Logging mod2-1 - -RCS file: ${CVSROOT2_DIRNAME}/mod2-1/anotherfile2-1,v -Working file: mod2-1/anotherfile2-1 -head: 1\.1 -branch: -locks: strict -access list: -symbolic names: -keyword substitution: kv -total revisions: 1; selected revisions: 1 -description: ----------------------------- -revision 1\.1 -date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; -reading -============================================================================= - -RCS file: ${CVSROOT2_DIRNAME}/mod2-1/file2-1,v -Working file: mod2-1/file2-1 -head: 1\.2 -branch: -locks: strict -access list: -symbolic names: - cattle: 1\.2 -keyword substitution: kv -total revisions: 2; selected revisions: 2 -description: ----------------------------- -revision 1\.2 -date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; lines: ${PLUS}1 -0 -actually ----------------------------- -revision 1\.1 -date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; -anyone -============================================================================= -${PROG} log: Logging mod2-2 - -RCS file: ${CVSROOT2_DIRNAME}/mod2-2/anotherfile2-2,v -Working file: mod2-2/anotherfile2-2 -head: 1\.1 -branch: -locks: strict -access list: -symbolic names: -keyword substitution: kv -total revisions: 1; selected revisions: 1 -description: ----------------------------- -revision 1\.1 -date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; -reading -============================================================================= - -RCS file: ${CVSROOT2_DIRNAME}/mod2-2/file2-2,v -Working file: mod2-2/file2-2 -head: 1\.2 -branch: -locks: strict -access list: -symbolic names: - cattle: 1\.2 -keyword substitution: kv -total revisions: 2; selected revisions: 2 -description: ----------------------------- -revision 1\.2 -date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; lines: ${PLUS}1 -0 -actually ----------------------------- -revision 1\.1 -date: [0-9/]* [0-9:]*; author: ${username}; state: Exp; -anyone -=============================================================================" - - - # After the simple cases, let's execute some commands which - # refer to parts of our checked-out tree (e.g. "cvs update - # mod1-1 mod2-2") - - if $keep; then - echo Keeping ${TESTDIR} and exiting due to --keep - exit 0 - fi - - # clean up after ourselves - cd .. - rm -r 1 - - # clean up our repositories - rm -rf root1 root2 - ;; - - multiroot2) - # More multiroot tests. In particular, nested directories. - - CVSROOT1_DIRNAME=${TESTDIR}/root1 - CVSROOT2_DIRNAME=${TESTDIR}/root2 - CVSROOT1=`newroot $CVSROOT1_DIRNAME` - CVSROOT2=`newroot $CVSROOT2_DIRNAME` - - dotest multiroot2-1 "$testcvs -d$CVSROOT1_DIRNAME init" - dotest multiroot2-2 "$testcvs -d$CVSROOT2_DIRNAME init" - - mkdir imp-dir; cd imp-dir - echo file1 >file1 - mkdir sdir - echo sfile >sdir/sfile - mkdir sdir/ssdir - echo ssfile >sdir/ssdir/ssfile - dotest_sort multiroot2-3 \ -"${testcvs} -d ${CVSROOT1} import -m import-to-root1 dir1 vend rel" " - -N dir1/file1 -N dir1/sdir/sfile -N dir1/sdir/ssdir/ssfile -No conflicts created by this import -${PROG} import: Importing ${TESTDIR}/root1/dir1/sdir -${PROG} import: Importing ${TESTDIR}/root1/dir1/sdir/ssdir" - cd sdir - dotest_sort multiroot2-4 \ -"${testcvs} -d ${CVSROOT2} import -m import-to-root2 sdir vend2 rel2" " - -N sdir/sfile -N sdir/ssdir/ssfile -No conflicts created by this import -${PROG} import: Importing ${TESTDIR}/root2/sdir/ssdir" - cd ../.. - - mkdir 1; cd 1 - # Get TopLevelAdmin-like behavior. - dotest multiroot2-5 "${testcvs} -d ${CVSROOT1} -q co -l ." - dotest multiroot2-5 "${testcvs} -d ${CVSROOT1} -q co dir1" \ -"U dir1/file1 -U dir1/sdir/sfile -U dir1/sdir/ssdir/ssfile" - cd dir1 - dotest multiroot2-6 "${testcvs} -Q release -d sdir" "" - dotest multiroot2-7 "${testcvs} -d ${CVSROOT2} -q co sdir" \ -"U sdir/sfile -U sdir/ssdir/ssfile" - cd .. - # This has one subtle effect - it deals with Entries.Log - # so that the next test doesn't get trace messages for - # Entries.Log - dotest multiroot2-8 "${testcvs} update" \ -"${PROG} update: Updating \. -${PROG} update: Updating dir1 -${PROG} update: Updating dir1/sdir -${PROG} update: Updating dir1/sdir/ssdir" \ -"${PROG} update: Updating \. -${PROG} update: Updating dir1 -${PROG} update: Updating dir1 -${PROG} update: Updating dir1/sdir -${PROG} update: Updating dir1/sdir/ssdir" - # Two reasons we don't run this on the server: (1) the server - # also prints some trace messages, and (2) the server trace - # messages are subject to out-of-order bugs (this one is hard - # to work around). - if $remote; then :; else - dotest multiroot2-9a "${testcvs} -t update" \ -" *-> main loop with CVSROOT=${TESTDIR}/root1 -${PROG} update: Updating \. - *-> Reader_Lock(${TESTDIR}/root1) - *-> Lock_Cleanup() -${PROG} update: Updating dir1 - *-> Reader_Lock(${TESTDIR}/root1/dir1) - *-> Lock_Cleanup() - *-> main loop with CVSROOT=${TESTDIR}/root2 -${PROG} update: Updating dir1/sdir - *-> Reader_Lock(${TESTDIR}/root2/sdir) - *-> Lock_Cleanup() -${PROG} update: Updating dir1/sdir/ssdir - *-> Reader_Lock(${TESTDIR}/root2/sdir/ssdir) - *-> Lock_Cleanup() - *-> Lock_Cleanup()" - fi - - dotest multiroot2-9 "${testcvs} -q tag tag1" \ -"T dir1/file1 -T dir1/sdir/sfile -T dir1/sdir/ssdir/ssfile" - echo "change it" >>dir1/file1 - echo "change him too" >>dir1/sdir/sfile - dotest multiroot2-10 "${testcvs} -q ci -m modify" \ -"Checking in dir1/file1; -${TESTDIR}/root1/dir1/file1,v <-- file1 -new revision: 1\.2; previous revision: 1\.1 -done -Checking in dir1/sdir/sfile; -${TESTDIR}/root2/sdir/sfile,v <-- sfile -new revision: 1\.2; previous revision: 1\.1 -done" - dotest multiroot2-11 "${testcvs} -q tag tag2" \ -"T dir1/file1 -T dir1/sdir/sfile -T dir1/sdir/ssdir/ssfile" - dotest_fail multiroot2-12 \ -"${testcvs} -q diff -u -r tag1 -r tag2" \ -"Index: dir1/file1 -=================================================================== -RCS file: ${TESTDIR}/root1/dir1/file1,v -retrieving revision 1\.1\.1\.1 -retrieving revision 1\.2 -diff -u -r1\.1\.1\.1 -r1\.2 ---- dir1/file1 ${RFCDATE} 1\.1\.1\.1 -${PLUS}${PLUS}${PLUS} dir1/file1 ${RFCDATE} 1\.2 -@@ -1 ${PLUS}1,2 @@ - file1 -${PLUS}change it -Index: dir1/sdir/sfile -=================================================================== -RCS file: ${TESTDIR}/root2/sdir/sfile,v -retrieving revision 1\.1\.1\.1 -retrieving revision 1\.2 -diff -u -r1\.1\.1\.1 -r1\.2 ---- dir1/sdir/sfile ${RFCDATE} 1\.1\.1\.1 -${PLUS}${PLUS}${PLUS} dir1/sdir/sfile ${RFCDATE} 1\.2 -@@ -1 ${PLUS}1,2 @@ - sfile -${PLUS}change him too" - - if $keep; then - echo Keeping ${TESTDIR} and exiting due to --keep - exit 0 - fi - - # clean up after ourselves - cd .. - rm -r imp-dir 1 - - # clean up our repositories - rm -rf root1 root2 - ;; - - multiroot3) - # More multiroot tests. Directories are side-by-side, not nested. - # Not drastically different from multiroot but it covers somewhat - # different stuff. - - CVSROOT1=`newroot ${TESTDIR}/root1` - CVSROOT2=`newroot ${TESTDIR}/root2` - - mkdir 1; cd 1 - dotest multiroot3-1 "$testcvs -d$TESTDIR/root1 init" - dotest multiroot3-2 "${testcvs} -d ${CVSROOT1} -q co -l ." "" - mkdir dir1 - dotest multiroot3-3 "${testcvs} add dir1" \ -"Directory ${TESTDIR}/root1/dir1 added to the repository" - dotest multiroot3-4 "$testcvs -d$TESTDIR/root2 init" - rm -r CVS - dotest multiroot3-5 "${testcvs} -d ${CVSROOT2} -q co -l ." "" - mkdir dir2 - - # OK, the problem is that CVS/Entries doesn't look quite right, - # I suppose because of the "rm -r". - # For local this fixes it up. - dotest multiroot3-6 "${testcvs} -d ${CVSROOT1} -q co dir1" "" - if $remote; then - # For remote that doesn't do it. Use the quick and dirty fix. - echo "D/dir1////" >CVS/Entries - echo "D/dir2////" >>CVS/Entries - fi - - dotest multiroot3-7 "${testcvs} add dir2" \ -"Directory ${TESTDIR}/root2/dir2 added to the repository" - - touch dir1/file1 dir2/file2 - if $remote; then - # Trying to add them both in one command doesn't work, - # because add.c doesn't do multiroot (it doesn't use recurse.c). - # Furthermore, it can't deal with the parent directory - # having a different root from the child, hence the cd. - cd dir1 - dotest multiroot3-8 "${testcvs} add file1" \ -"${PROG} add: scheduling file .file1. for addition -${PROG} add: use .${PROG} commit. to add this file permanently" - cd .. - dotest multiroot3-8a "${testcvs} add dir2/file2" \ -"${PROG} add: scheduling file .dir2/file2. for addition -${PROG} add: use .${PROG} commit. to add this file permanently" - else - dotest multiroot3-8 "${testcvs} add dir1/file1 dir2/file2" \ -"${PROG} add: scheduling file .dir1/file1. for addition -${PROG} add: scheduling file .dir2/file2. for addition -${PROG} add: use .${PROG} commit. to add these files permanently" - fi - - dotest multiroot3-9 "${testcvs} -q ci -m add-them" \ -"RCS file: ${TESTDIR}/root2/dir2/file2,v -done -Checking in dir2/file2; -${TESTDIR}/root2/dir2/file2,v <-- file2 -initial revision: 1\.1 -done -RCS file: ${TESTDIR}/root1/dir1/file1,v -done -Checking in dir1/file1; -${TESTDIR}/root1/dir1/file1,v <-- file1 -initial revision: 1\.1 -done" - - # That this is an error is good - we are asking CVS to do - # something which doesn't make sense. - dotest_fail multiroot3-10 \ -"${testcvs} -q -d ${CVSROOT1} diff dir1/file1 dir2/file2" \ -"${PROG} diff: failed to create lock directory for .${TESTDIR}/root1/dir2' (${TESTDIR}/root1/dir2/#cvs.lock): No such file or directory -${PROG} diff: failed to obtain dir lock in repository .${TESTDIR}/root1/dir2' -${PROG} \[diff aborted\]: read lock failed - giving up" - - # This one is supposed to work. - dotest multiroot3-11 "${testcvs} -q diff dir1/file1 dir2/file2" "" - - # make sure we can't access across repositories - mkdir 1a - cd 1a - dotest_fail multiroot3-12 \ -"$testcvs -d $CVSROOT1 -q co ../root2/dir2" \ -"$PROG \[checkout aborted\]: up-level in module reference (\`..') invalid: \`\.\./root2/dir2'\." \ -"$PROG \[server aborted\]: up-level in module reference (\`..') invalid: \`\.\./root2/dir2'\. -$PROG \[checkout aborted\]: end of file from server (consult above messages if any)" - dotest_fail multiroot3-13 \ -"$testcvs -d $CVSROOT2 -q co ../root1/dir1" \ -"$PROG \[checkout aborted\]: up-level in module reference (\`..') invalid: \`\.\./root1/dir1'\." \ -"$PROG \[server aborted\]: up-level in module reference (\`..') invalid: \`\.\./root1/dir1'\. -$PROG \[checkout aborted\]: end of file from server (consult above messages if any)" - dotest_fail multiroot3-14 \ -"$testcvs -d $CVSROOT1 -q co ./../root2/dir2" \ -"$PROG \[checkout aborted\]: up-level in module reference (\`..') invalid: \`\./\.\./root2/dir2'\." \ -"$PROG \[server aborted\]: up-level in module reference (\`..') invalid: \`\./\.\./root2/dir2'\. -$PROG \[checkout aborted\]: end of file from server (consult above messages if any)" - dotest_fail multiroot3-15 \ -"$testcvs -d $CVSROOT2 -q co ./../root1/dir1" \ -"$PROG \[checkout aborted\]: up-level in module reference (\`..') invalid: \`\./\.\./root1/dir1'\." \ -"$PROG \[server aborted\]: up-level in module reference (\`..') invalid: \`\./\.\./root1/dir1'\. -$PROG \[checkout aborted\]: end of file from server (consult above messages if any)" - dotest_fail multiroot3-16 \ -"$testcvs -d $CVSROOT1 -q co -p ../root2/dir2" \ -"$PROG \[checkout aborted\]: up-level in module reference (\`..') invalid: \`\.\./root2/dir2'\." \ -"$PROG \[server aborted\]: up-level in module reference (\`..') invalid: \`\.\./root2/dir2'\. -$PROG \[checkout aborted\]: end of file from server (consult above messages if any)" - dotest_fail multiroot3-17 \ -"$testcvs -d $CVSROOT1 -q co -p ./../root1/dir1" \ -"$PROG \[checkout aborted\]: up-level in module reference (\`..') invalid: \`\./\.\./root1/dir1'\." \ -"$PROG \[server aborted\]: up-level in module reference (\`..') invalid: \`\./\.\./root1/dir1'\. -$PROG \[checkout aborted\]: end of file from server (consult above messages if any)" - - if $keep; then - echo Keeping $TESTDIR and exiting due to --keep - exit 0 - fi - - cd ../.. - - rm -r 1 - rm -rf ${TESTDIR}/root1 ${TESTDIR}/root2 - unset CVSROOT1 - unset CVSROOT2 - ;; - - multiroot4) - # More multiroot tests, in particular we have two roots with - # similarly-named directories and we try to see that CVS can - # keep them separate. - - CVSROOT1=`newroot ${TESTDIR}/root1` - CVSROOT2=`newroot ${TESTDIR}/root2` - - mkdir 1; cd 1 - dotest multiroot4-1 "$testcvs -d$TESTDIR/root1 init" - dotest multiroot4-2 "${testcvs} -d ${CVSROOT1} -q co -l ." "" - mkdir dircom - dotest multiroot4-3 "${testcvs} add dircom" \ -"Directory ${TESTDIR}/root1/dircom added to the repository" - cd dircom - touch file1 - dotest multiroot4-4 "${testcvs} add file1" \ -"${PROG} add: scheduling file .file1. for addition -${PROG} add: use .${PROG} commit. to add this file permanently" - dotest multiroot4-5 "${testcvs} -q ci -m add" \ -"RCS file: ${TESTDIR}/root1/dircom/file1,v -done -Checking in file1; -${TESTDIR}/root1/dircom/file1,v <-- file1 -initial revision: 1\.1 -done" - cd ../.. - mkdir 2; cd 2 - dotest multiroot4-6 "$testcvs -d$TESTDIR/root2 init" - dotest multiroot4-7 "${testcvs} -d ${CVSROOT2} -q co -l ." "" - mkdir dircom - dotest multiroot4-8 "${testcvs} add dircom" \ -"Directory ${TESTDIR}/root2/dircom added to the repository" - cd dircom - touch file2 - dotest multiroot4-9 "${testcvs} add file2" \ -"${PROG} add: scheduling file .file2. for addition -${PROG} add: use .${PROG} commit. to add this file permanently" - dotest multiroot4-10 "${testcvs} -q ci -m add" \ -"RCS file: ${TESTDIR}/root2/dircom/file2,v -done -Checking in file2; -${TESTDIR}/root2/dircom/file2,v <-- file2 -initial revision: 1\.1 -done" - - cd ../.. - cd 1/dircom - # This may look contrived; the real world example which inspired - # it was that a user was changing from local to remote. Cases - # like switching servers (among those mounting the same - # repository) and so on would also look the same. - mkdir sdir2 - dotest multiroot4-11 "${testcvs} -d ${CVSROOT2} add sdir2" \ -"Directory ${TESTDIR}/root2/dircom/sdir2 added to the repository" - - dotest multiroot4-12 "${testcvs} -q update" "" - cd .. - dotest multiroot4-13 "${testcvs} -q update dircom" "" - cd .. - - rm -r 1 2 - rm -rf ${TESTDIR}/root1 ${TESTDIR}/root2 - unset CVSROOT1 - unset CVSROOT2 - ;; - - rmroot) - # When the Entries/Root file is removed from an existing - # workspace, CVS should assume $CVSROOT instead - # - # Right now only checking that CVS exits normally on an - # update once CVS/Root is deleted - # - # There was a time when this would core dump when run in - # client/server mode - - mkdir 1; cd 1 - dotest rmroot-setup-1 "${testcvs} -q co -l ." '' - mkdir first-dir - dotest rmroot-setup-2 "${testcvs} add first-dir" \ -"Directory ${CVSROOT_DIRNAME}/first-dir added to the repository" - cd first-dir - touch file1 file2 - dotest rmroot-setup-3 "${testcvs} add file1 file2" \ -"${PROG} add: scheduling file .file1. for addition -${PROG} add: scheduling file .file2. for addition -${PROG} add: use .${PROG} commit. to add these files permanently" - dotest rmroot-setup-4 "${testcvs} -q commit -minit" \ -"RCS file: ${CVSROOT_DIRNAME}/first-dir/file1,v -done -Checking in file1; -${CVSROOT_DIRNAME}/first-dir/file1,v <-- file1 -initial revision: 1\.1 -done -RCS file: ${CVSROOT_DIRNAME}/first-dir/file2,v -done -Checking in file2; -${CVSROOT_DIRNAME}/first-dir/file2,v <-- file2 -initial revision: 1\.1 -done" - rm CVS/Root - dotest rmroot-1 "${testcvs} -q update" '' - - cd ../.. - rm -rf 1 - ;; - - reposmv) - # More tests of repositories and specifying them. - # Similar to crerepos but that test is probably getting big - # enough. - CVSROOT1=`newroot ${TESTDIR}/root1` - CVSROOT_MOVED=`newroot ${TESTDIR}/root-moved` - - dotest reposmv-setup-1 "$testcvs -d$TESTDIR/root1 init" - mkdir imp-dir; cd imp-dir - echo file1 >file1 - dotest reposmv-setup-2 \ -"${testcvs} -d ${CVSROOT1} import -m add dir1 vendor release" \ -"N dir1/file1 - -No conflicts created by this import" - cd .. - - mkdir 1; cd 1 - dotest reposmv-1 "${testcvs} -d ${CVSROOT1} -Q co dir1" "" - mv ${TESTDIR}/root1 ${TESTDIR}/root-moved - cd dir1 - - # If we didn't have a relative repository, get one now. - dotest reposmv-1a "cat CVS/Repository" \ -"${TESTDIR}/root1/dir1" "dir1" - echo dir1 >CVS/Repository - - # There were some duplicated warnings and such; only test - # for the part of the error message which makes sense. - # Bug: "skipping directory " without filename. - if $remote; then - dotest_fail reposmv-2r "${testcvs} update" \ -"Cannot access ${TESTDIR}/root1/CVSROOT -No such file or directory" - else - dotest reposmv-2 "${testcvs} update" "${DOTSTAR} -${PROG} update: ignoring CVS/Root because it specifies a non-existent repository ${TESTDIR}/root1 -${PROG} update: cannot open directory ${CVSROOT_DIRNAME}/dir1: No such file or directory -${PROG} update: skipping directory " - fi - - # CVS/Root overrides $CVSROOT - if $remote; then - CVSROOT_save=${CVSROOT} - CVSROOT=:fork:${TESTDIR}/root-moved; export CVSROOT - dotest_fail reposmv-3r "${testcvs} update" \ -"Cannot access ${TESTDIR}/root1/CVSROOT -No such file or directory" - CVSROOT=${CVSROOT_save}; export CVSROOT - else - CVSROOT_save=${CVSROOT} - CVSROOT=${TESTDIR}/root-moved; export CVSROOT - dotest reposmv-3 "${testcvs} update" \ -"${DOTSTAR} -${PROG} update: ignoring CVS/Root because it specifies a non-existent repository ${TESTDIR}/root1 -${PROG} update: Updating \. -${DOTSTAR}" - CVSROOT=${CVSROOT_save}; export CVSROOT - fi - - if $remote; then - CVSROOT_save=${CVSROOT} - CVSROOT=:fork:${TESTDIR}/root-none; export CVSROOT - dotest_fail reposmv-4 "${testcvs} update" \ -"Cannot access ${TESTDIR}/root1/CVSROOT -No such file or directory" - CVSROOT=${CVSROOT_save}; export CVSROOT - else - # CVS/Root doesn't seem to quite completely override $CVSROOT - # Bug? Not necessarily a big deal if it only affects error - # messages. - CVSROOT_save=${CVSROOT} - CVSROOT=${TESTDIR}/root-none; export CVSROOT - dotest_fail reposmv-4 "${testcvs} update" \ -"${PROG} update: in directory \.: -${PROG} update: ignoring CVS/Root because it specifies a non-existent repository ${TESTDIR}/root1 -${PROG} \[update aborted\]: ${TESTDIR}/root-none/CVSROOT: No such file or directory" - CVSROOT=${CVSROOT_save}; export CVSROOT - fi - - # -d overrides CVS/Root - # - # Oddly enough, with CVS 1.10 I think this didn't work for - # local (that is, it would appear that CVS/Root would not - # get used, but would produce an error if it didn't exist). - dotest reposmv-5 "${testcvs} -d ${CVSROOT_MOVED} update" \ -"${PROG} update: Updating \." - - # TODO: could also test various other things, like what if the - # user removes CVS/Root (which is legit). Or another set of - # tests would be if both repositories exist but we want to make - # sure that CVS is using the correct one. - - cd ../.. - rm -r imp-dir 1 - rm -rf root1 root2 - unset CVSROOT1 - ;; - - pserver) - # Test basic pserver functionality. - if $remote; then - # First set SystemAuth=no. Not really necessary, I don't - # think, but somehow it seems like the clean thing for - # the testsuite. - mkdir 1; cd 1 - dotest pserver-1 "${testcvs} -Q co CVSROOT" "" - cd CVSROOT - echo "SystemAuth=no" >config - dotest pserver-2 "${testcvs} -q ci -m config-it" \ -"Checking in config; -${CVSROOT_DIRNAME}/CVSROOT/config,v <-- config -new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* -done -${PROG} commit: Rebuilding administrative file database" - cat >${CVSROOT_DIRNAME}/CVSROOT/passwd <garbageseg - echo "BEGIN AUTH REQUEST" >garbageinput - i=0 - while test $i -lt 64; do - cat >garbageseg2 - i=`expr $i + 1` - done - i=0 - while test $i -lt 64; do - cat >garbageinput - i=`expr $i + 1` - done - dotest_fail pserver-auth-no-dos \ -"${testcvs} --allow-root=${CVSROOT_DIRNAME} pserver" \ -"${PROG} \\[pserver aborted\\]: Maximum line length exceeded during authentication\." ${CVSROOT_DIRNAME}/CVSROOT/readers <${CVSROOT_DIRNAME}/CVSROOT/writers <config - dotest pserver-cleanup-1 "${testcvs} -q ci -m config-it" \ -"Checking in config; -${CVSROOT_DIRNAME}/CVSROOT/config,v <-- config -new revision: 1\.[0-9]*; previous revision: 1\.[0-9]* -done -${PROG} commit: Rebuilding administrative file database" - cd ../.. - rm -r 1 - rm ${CVSROOT_DIRNAME}/CVSROOT/passwd ${CVSROOT_DIRNAME}/CVSROOT/writers - fi # skip the whole thing for local - ;; - - server) - # Some tests of the server (independent of the client). - if $remote; then - dotest server-1 "${testcvs} server" \ -"E Protocol error: Root request missing -error " <gzipped.dat - # Note that the CVS client sends "-b 1.1.1", and this - # test doesn't. But the server also defaults to that. - cat <session.dat -Root ${TESTDIR}/crerepos -UseUnchanged -gzip-file-contents 3 -Argument -m -Argument msg -Argumentx -Argument dir1 -Argument tag1 -Argument tag2 -Directory . -${TESTDIR}/crerepos -Modified file1 -u=rw,g=r,o=r -z25 -EOF - cat gzipped.dat >>session.dat - echo import >>session.dat - dotest server-4 "${testcvs} server" \ -"M N dir1/file1 -M -M No conflicts created by this import -M -ok" ${TESTDIR}/serveme </dev/null -EOF - # Cygwin. Pthffffffffft! - if test -n "$remotehost"; then - $CVS_RSH $remotehost "chmod +x ${TESTDIR}/serveme" - else - chmod +x ${TESTDIR}/serveme - fi - save_CVS_SERVER=$CVS_SERVER - CVS_SERVER=${TESTDIR}/serveme; export CVS_SERVER - mkdir 1; cd 1 - dotest_fail client-1 "${testcvs} -q co first-dir" \ -"${PROG} \[checkout aborted\]: This server does not support the global -q option${DOTSTAR}" - dotest client-2 "${testcvs} co first-dir" "special message" - - cat >${TESTDIR}/serveme </dev/null -EOF - cd first-dir - mkdir ${TESTDIR}/bogus - # The ${DOTSTAR} is to match a potential "broken pipe" if the - # client exits before the server script sends everything - dotest_fail client-3 "${testcvs} update" "merge-it -${PROG} \[update aborted\]: protocol error: Copy-file tried to specify director${DOTSTAR}" - cat >${TESTDIR}/serveme </dev/null -EOF - dotest client-4 "${testcvs} update" "merge-it" - dotest client-5 "cat .#file1.1.1" "xyz" - dotest client-6 "cat CVS/Entries" "/file1/1.2/[A-Za-z0-9 :]*// -D" - dotest client-7 "cat file1" "abc" - - cat >${TESTDIR}/serveme <${TESTDIR}/client.tmp -EOF - chmod u=rw,go= file1 - # By specifying the time zone in local time, we don't - # know exactly how that will translate to GMT. - dotest client-8 "${testcvs} update -D 99-10-04" "OK, whatever" - # String 2 below is Cygwin again - ptoooey. - dotest client-9 "cat ${TESTDIR}/client.tmp" \ -"Root ${CVSROOT_DIRNAME} -Valid-responses [-a-zA-Z ]* -valid-requests -Argument -D -Argument [34] Oct 1999 [0-9][0-9]:00:00 -0000 -Argument -- -Directory \. -${CVSROOT_DIRNAME}/first-dir -Entry /file1/1\.2/// -Modified file1 -u=rw,g=,o= -4 -abc -update" \ -"Root ${CVSROOT_DIRNAME} -Valid-responses [-a-zA-Z ]* -valid-requests -Argument -D -Argument [34] Oct 1999 [0-9][0-9]:00:00 -0000 -Argument -- -Directory \. -${CVSROOT_DIRNAME}/first-dir -Entry /file1/1\.2/// -Modified file1 -u=rw,g=r,o=r -4 -abc -update" - - # The following test tests what was a potential client update in - # CVS versions 1.11.14 and CVS versions 1.12.6 and earlier. This - # exploit would allow a trojan server to create arbitrary files, - # anywhere the user had write permissions, even outside of the - # user's sandbox. - cat >$HOME/.bashrc <$TESTDIR/serveme </dev/null -EOF - - # If I don't run the following sleep between the above cat and - # the following calls to dotest, sometimes the serveme file isn't - # completely written yet by the time CVS tries to execute it, - # causing the shell to intermittantly report syntax errors (usually - # early EOF). There's probably a new race condition here, but this - # works. - # - # Incidentally, I can reproduce this behavior with Linux 2.4.20 and - # Bash 2.05 or Bash 2.05b. - sleep 1 - dotest_fail client-10 "$testcvs update" \ -"$PROG update: Server attempted to update a file via an invalid pathname: -$PROG \[update aborted\]: \`$HOME/.bashrc'\." - - # A second try at a client exploit. This one never actually - # failed in the past, but I thought it wouldn't hurt to add a test. - cat >$TESTDIR/serveme </dev/null -EOF - sleep 1 - dotest_fail client-11 "$testcvs update" \ -"$PROG \[update aborted\]: patch original file \./\.bashrc does not exist" - - # A third try at a client exploit. This one did used to fail like - # client-10. - cat >$TESTDIR/serveme </dev/null -EOF - sleep 1 - dotest_fail client-12 "$testcvs update" \ -"$PROG update: Server attempted to update a file via an invalid pathname: -$PROG \[update aborted\]: \`\.\./\.\./home/.bashrc'\." - - # Try the same exploit using the Created response. - cat >$TESTDIR/serveme </dev/null -EOF - sleep 1 - dotest_fail client-13 "$testcvs update" \ -"$PROG update: Server attempted to update a file via an invalid pathname: -$PROG \[update aborted\]: \`$HOME/.bashrc'\." - - # Now try using the Update-existing response - cat >$TESTDIR/serveme </dev/null -EOF - sleep 1 - dotest_fail client-14 "$testcvs update" \ -"$PROG update: Server attempted to update a file via an invalid pathname: -$PROG \[update aborted\]: \`\.\./\.\./home/.bashrc'\." - - # Try the same exploit using the Merged response. - cat >$TESTDIR/serveme </dev/null -EOF - sleep 1 - dotest_fail client-15 "$testcvs update" \ -"$PROG update: Server attempted to update a file via an invalid pathname: -$PROG \[update aborted\]: \`$HOME/.bashrc'\." - - # Now try using the Updated response - cat >$TESTDIR/serveme </dev/null -EOF - sleep 1 - dotest_fail client-16 "$testcvs update" \ -"$PROG update: Server attempted to update a file via an invalid pathname: -$PROG \[update aborted\]: \`\.\./\.\./home/.bashrc'\." - - # Try the same exploit using the Copy-file response. - # As far as I know, Copy-file was never exploitable either. - cat >$TESTDIR/serveme </dev/null -EOF - sleep 1 - dotest_fail client-18 "$testcvs update" \ -"$PROG \[update aborted\]: protocol error: Copy-file tried to specify directory" - - # And verify that none of the exploits was successful. - dotest client-19 "cat $HOME/.bashrc" \ -"#!$TESTSHELL -# This is where login scripts would usually be -# stored\." - - if $keep; then - echo Keeping ${TESTDIR} and exiting due to --keep - exit 0 - fi - - cd ../.. - rm -r 1 - rmdir ${TESTDIR}/bogus - rm $TESTDIR/serveme $HOME/.bashrc - CVS_SERVER=${save_CVS_SERVER}; export CVS_SERVER - fi # skip the whole thing for local - ;; - - - - client2) - # Test how the client handles error messages from the server. - if $remote; then - cat >$TESTDIR/serveme </dev/null -EOF - # Cygwin. Pthffffffffft! - if test -n "$remotehost"; then - $CVS_RSH $remotehost "chmod +x $TESTDIR/serveme" - else - chmod +x $TESTDIR/serveme - fi - save_CVS_SERVER=$CVS_SERVER - CVS_SERVER=$TESTDIR/serveme; export CVS_SERVER - mkdir client2; cd client2 - dotest_fail client2-1 "$testcvs co first-dir" \ -"Root somewhere/over/the/rainbow must be an absolute pathname" - - cat >$TESTDIR/serveme </dev/null -EOF - # Cygwin. Pthffffffffft! - if test -n "$remotehost"; then - $CVS_RSH $remotehost "chmod +x $TESTDIR/serveme" - else - chmod +x $TESTDIR/serveme - fi - dotest_fail client2-2 "$testcvs co first-dir" \ -"Root somewhere/over/the/rainbow must be an absolute pathname -$PROG checkout: warning: unrecognized response \`' from cvs server" - - if $keep; then - echo Keeping $TESTDIR and exiting due to --keep - exit 0 - fi - - cd .. - rm -r client2 - rm $TESTDIR/serveme - CVS_SERVER=$save_CVS_SERVER; export CVS_SERVER - fi # skip the whole thing for local - ;; - - - - dottedroot) - # Check that a CVSROOT with a "." in the name will work. - CVSROOT_save=${CVSROOT} - CVSROOT_DIRNAME_save=${CVSROOT_DIRNAME} - CVSROOT_DIRNAME=${TESTDIR}/cvs.root - CVSROOT=`newroot ${CVSROOT_DIRNAME}` - - dotest dottedroot-init-1 "$testcvs -d$CVSROOT_DIRNAME init" - mkdir dir1 - mkdir dir1/dir2 - echo version1 >dir1/dir2/file1 - cd dir1 - dotest dottedroot-1 "${testcvs} import -m '' module1 AUTHOR INITIAL" \ -"${PROG} [a-z]*: Importing ${CVSROOT_DIRNAME}/module1/dir2 -N module1/dir2/file1 - -No conflicts created by this import" - cd .. - - # This is the test that used to cause an assertion failure - # in recurse.c:do_recursion(). - dotest dottedroot-2 "${testcvs} co -rINITIAL module1" \ -"${PROG} [a-z]*: Updating module1 -${PROG} [a-z]*: Updating module1/dir2 -U module1/dir2/file1" - - # This also triggered the assertion failure above prior to 1.11.23. - dotest dottedroot-3 \ -"$testcvs -q co -prINITIAL module1/./dir2/file1" \ -'version1' - - if $keep; then - echo Keeping $TESTDIR and exiting due to --keep - exit 0 - fi - - rm -rf ${CVSROOT_DIRNAME} - rm -r dir1 module1 - CVSROOT_DIRNAME=${CVSROOT_DIRNAME_save} - CVSROOT=${CVSROOT_save} - ;; - - fork) - # Test that the server defaults to the correct executable in :fork: - # mode. See the note in the TODO at the end of this file about this. - # - # This test and client should be left after all other references to - # CVS_SERVER are removed from this script. - # - # The client series of tests already tests that CVS_SERVER is - # working, but that test might be better here. - if $remote; then - mkdir fork; cd fork - save_CVS_SERVER=$CVS_SERVER - unset CVS_SERVER - # So looking through $PATH for cvs won't work... - echo "echo junk" >cvs - chmod a+x cvs - save_PATH=$PATH; PATH=.:$PATH - dotest fork-1 "$testcvs -d:fork:$CVSROOT_DIRNAME version" \ -'Client: \(.*\) -Server: \1' - CVS_SERVER=${save_CVS_SERVER}; export CVS_SERVER - unset save_CVS_SERVER - PATH=$save_PATH; unset save_PATH - cd .. - - if $keep; then - echo Keeping ${TESTDIR} and exiting due to --keep - exit 0 - fi - fi - ;; - - commit-add-missing) - # Make sure that a commit fails when a `cvs add'ed file has - # been removed from the working directory. - - mkdir 1; cd 1 - module=c-a-m - echo > unused-file - dotest commit-add-missing-1 \ - "$testcvs -Q import -m. $module X Y" '' - - file=F - # Check it out and tag it. - dotest commit-add-missing-2 "$testcvs -Q co $module" '' - cd $module - dotest commit-add-missing-3 "$testcvs -Q tag -b B" '' - echo v1 > $file - dotest commit-add-missing-4 "$testcvs -Q add $file" '' - rm -f $file - dotest_fail commit-add-missing-5 "$testcvs -Q ci -m. $file" \ -"${PROG} commit: Up-to-date check failed for .$file' -${PROG} \[commit aborted\]: correct above errors first!" - - cd ../.. - rm -rf 1 - rm -rf ${CVSROOT_DIRNAME}/$module - ;; - - add-restricted) - # Verify that `sdir/CVS' may not be explicitly added. - mkdir add-restricted; cd add-restricted - - mkdir import; cd import - : > junk - dotest add-restricted-init-1 \ -"$testcvs -Q import -m. add-restricted X Y" - cd .. - - dotest add-restricted-init-2 "$testcvs -Q co add-restricted" - cd add-restricted - - # errmsg2-3 tests the specific message here. - dotest_fail add-restricted-1 "$testcvs -Q add CVS" - - mkdir sdir - dotest add-restricted-2 "$testcvs -Q add sdir" - dotest_fail add-restricted-3 "$testcvs add sdir/CVS" \ -"$PROG add: cannot add special file \`sdir/CVS'; skipping" - - if $keep; then - echo Keeping $TESTDIR and exiting due to --keep - exit 0 - fi - cd ../.. - rm -rf add-restricted $CVSROOT_DIRNAME/add-restricted - ;; - - - - commit-d) - # Check that top-level commits work when CVS/Root - # is overridden by cvs -d. - - mkdir -p 1/subdir; cd 1 - touch file1 subdir/file2 - dotest commit-d-1 "$testcvs -Q import -m. c-d-c X Y" "" - dotest commit-d-2 "$testcvs -Q co c-d-c" "" - cd c-d-c - echo change >>file1; echo another change >>subdir/file2 - # Changing working root, then override with -d - echo nosuchhost:/cvs > CVS/Root - dotest commit-d-3 "$testcvs -Q -d $CVSROOT commit -m." \ -"Checking in file1; -${CVSROOT_DIRNAME}/c-d-c/file1,v <-- file1 -new revision: 1.2; previous revision: 1.1 -done -Checking in subdir/file2; -${CVSROOT_DIRNAME}/c-d-c/subdir/file2,v <-- file2 -new revision: 1.2; previous revision: 1.1 -done" - cd ../.. - rm -rf 1 cvsroot/c-d-c - ;; - - *) - echo $what is not the name of a test -- ignored - ;; - esac - - # Sanity check sanity.sh. :) - # - # Test our exit directory so that tests that exit in an incorrect directory - # are noticed during single test runs. - # - # FIXME? - # Sparc Solaris 9 is dereferencing paths here as if /bin/pwd were - # called when /tmp is a symlink. This might be a new problem with this - # test, but since this was recently tested I think it more likely to be - # A Solaris issue. - if test "x$TESTDIR" != "x`pwd`"; then - fail "cleanup: PWD != TESTDIR (\``pwd`' != \`$TESTDIR')" - fi - - # Reset val-tags to a pristine state. - rm -f $CVSROOT_DIRNAME/CVSROOT/val-tags - - verify_tmp_empty "post $what" - -done # The big loop - -# Set up summary data for output. -skippedoutput= -warningsoutput= -extendedinfo= -if test $skipped -ne 0; then - skippedoutput="$skipped test group" - if test $skipped -ne 1; then - skippedoutput="${skippedoutput}s" - fi - skippedoutput="$skippedoutput skipped" -fi -if test $warnings -ne 0; then - warningsoutput="$warnings test" - if test $warnings -ne 1; then - warningsoutput="${warningsoutput}s" - fi - warningsoutput="$warningsoutput passed with warnings" -fi -if test -n "$skippedoutput" || test -n "$warningsoutput"; then - extendedinfo=" (" - if test -n "$skippedoutput"; then - extendedinfo="$extendedinfo$skippedoutput" - fi - if test -n "$skippedoutput" && test -n "$warningsoutput"; then - extendedinfo="$extendedinfo and " - fi - if test -n "$warningsoutput"; then - extendedinfo="$extendedinfo$warningsoutput" - fi - extendedinfo="$extendedinfo)" -fi - -echo "OK, all $passed tests passed$extendedinfo." - -# TODO: -# * Test `cvs update -d foo' (where foo does not exist). -# * Test `cvs update foo bar' (where foo and bar are both from the -# same directory in the repository). Suppose one is a branch--make -# sure that both directories get updated with the respective correct -# thing. -# * `cvs update ../foo'. Also ../../foo ./../foo foo/../../bar /foo/bar -# foo/.././../bar foo/../bar etc. -# * Test all flags in modules file. -# Test that ciprog gets run both on checkin in that directory, or a -# higher-level checkin which recurses into it. -# * Test operations on a directory that contains other directories but has -# no files of its own. -# * -t global option -# * cvs rm followed by cvs add or vice versa (with no checkin in between). -# * cvs rm twice (should be a nice error message). -# * -P option to checkout--(a) refrains from checking out new empty dirs, -# (b) prunes empty dirs already there. -# * Test that cvs -d `hostname`:${TESTDIR}/non/existent co foo -# gives an appropriate error (e.g. -# Cannot access ${TESTDIR}/non-existent/CVSROOT -# No such file or directory). -# (like basica-9, but for remote). -# * Test ability to send notifications in response to watches. (currently -# hard to test because CVS doesn't send notifications if username is the -# same). -# * Test the contents of adm files other than Root and Repository. -# Entries seems the next most important thing. -# * Test the following compatibility issues: -# - The filler fields in "D" entries in CVS/Entries get preserved -# (per cvs.texinfo). -# - Unrecognized entry types in CVS/Entries get ignored (looks like -# this needs to be documented in cvs.texinfo, but is not) -# - Test that unrecognized files in CVS directories (e.g. CVS/Foobar) -# are ignored (per cvs.texinfo). -# - Test 'cvs history' with symlinks in the path to the working directory. -# - Remove most of the CVS_SERVER stuff after a reasonable amount of time. -# The "fork" & "client" series of tests should be left. 4/2/00, CVS -# 1.11.0.1 was altered so that it would default to program_name (set from -# argv[0]) rather than "cvs", but I'd like this script to work on legacy -# versions of CVS for awhile. -# - Testsuite doesn't work with usernames over eight characters in length. -# Fix it. -# End of TODO list. - -# Exit if keep set -if $keep; then - echo "Keeping ${TESTDIR} and exiting due to -k (keep) option." - exit 0 -fi - -# Remove the test directory, but first change out of it. -cd `dirname ${TESTDIR}` -rm -rf ${TESTDIR} - -# end of sanity.sh diff --git a/contrib/cvs/src/scramble.c b/contrib/cvs/src/scramble.c deleted file mode 100644 index 487cbf4..0000000 --- a/contrib/cvs/src/scramble.c +++ /dev/null @@ -1,245 +0,0 @@ -/* - * Trivially encode strings to protect them from innocent eyes (i.e., - * inadvertent password compromises, like a network administrator - * who's watching packets for legitimate reasons and accidentally sees - * the password protocol go by). - * - * This is NOT secure encryption. - * - * It would be tempting to encode the password according to username - * and repository, so that the same password would encode to a - * different string when used with different usernames and/or - * repositories. However, then users would not be able to cut and - * paste passwords around. They're not supposed to anyway, but we all - * know they will, and there's no reason to make it harder for them if - * we're not trying to provide real security anyway. - */ - -/* Set this to test as a standalone program. */ -/* #define DIAGNOSTIC */ - -#ifndef DIAGNOSTIC -#include "cvs.h" -#else /* ! DIAGNOSTIC */ -/* cvs.h won't define this for us */ -#define AUTH_CLIENT_SUPPORT -#define xmalloc malloc -/* Use "gcc -fwritable-strings". */ -#include -#include -#include -#endif /* ! DIAGNOSTIC */ - -#if defined(AUTH_CLIENT_SUPPORT) || defined(AUTH_SERVER_SUPPORT) - -/* Map characters to each other randomly and symmetrically, A <--> B. - * - * We divide the ASCII character set into 3 domains: control chars (0 - * thru 31), printing chars (32 through 126), and "meta"-chars (127 - * through 255). The control chars map _to_ themselves, the printing - * chars map _among_ themselves, and the meta chars map _among_ - * themselves. Why is this thus? - * - * No character in any of these domains maps to a character in another - * domain, because I'm not sure what characters are legal in - * passwords, or what tools people are likely to use to cut and paste - * them. It seems prudent not to introduce control or meta chars, - * unless the user introduced them first. And having the control - * chars all map to themselves insures that newline and - * carriage-return are safely handled. - */ - -static unsigned char -shifts[] = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, - 114,120, 53, 79, 96,109, 72,108, 70, 64, 76, 67,116, 74, 68, 87, - 111, 52, 75,119, 49, 34, 82, 81, 95, 65,112, 86,118,110,122,105, - 41, 57, 83, 43, 46,102, 40, 89, 38,103, 45, 50, 42,123, 91, 35, - 125, 55, 54, 66,124,126, 59, 47, 92, 71,115, 78, 88,107,106, 56, - 36,121,117,104,101,100, 69, 73, 99, 63, 94, 93, 39, 37, 61, 48, - 58,113, 32, 90, 44, 98, 60, 51, 33, 97, 62, 77, 84, 80, 85,223, - 225,216,187,166,229,189,222,188,141,249,148,200,184,136,248,190, - 199,170,181,204,138,232,218,183,255,234,220,247,213,203,226,193, - 174,172,228,252,217,201,131,230,197,211,145,238,161,179,160,212, - 207,221,254,173,202,146,224,151,140,196,205,130,135,133,143,246, - 192,159,244,239,185,168,215,144,139,165,180,157,147,186,214,176, - 227,231,219,169,175,156,206,198,129,164,150,210,154,177,134,127, - 182,128,158,208,162,132,167,209,149,241,153,251,237,236,171,195, - 243,233,253,240,194,250,191,155,142,137,245,235,163,242,178,152 }; - - -/* SCRAMBLE and DESCRAMBLE work like this: - * - * scramble(STR) returns SCRM, a scrambled copy of STR. SCRM[0] is a - * single letter indicating the scrambling method. As of this - * writing, the only legal method is 'A', but check the code for more - * up-to-date information. The copy will have been allocated with - * xmalloc(). - * - * descramble(SCRM) returns STR, again in its own xmalloc'd space. - * descramble() uses SCRM[0] to determine which method of unscrambling - * to use. If it does not recognize the method, it dies with error. - */ - -/* Return a xmalloc'd, scrambled version of STR. */ -char * -scramble (str) - char *str; -{ - int i; - char *s; - - /* +2 to hold the 'A' prefix that indicates which version of - scrambling this is (the first, obviously, since we only do one - kind of scrambling so far), and then the '\0' of course. */ - s = (char *) xmalloc (strlen (str) + 2); - - /* Scramble (TM) version prefix. */ - s[0] = 'A'; - strcpy (s + 1, str); - - for (i = 1; s[i]; i++) - s[i] = shifts[(unsigned char)(s[i])]; - - return s; -} - -/* Decode the string in place. */ -char * -descramble (str) - char *str; -{ - char *s; - int i; - - /* For now we can only handle one kind of scrambling. In the future - there may be other kinds, and this `if' will become a `switch'. */ - if (str[0] != 'A') -#ifndef DIAGNOSTIC - error (1, 0, "descramble: unknown scrambling method"); -#else /* DIAGNOSTIC */ - { - fprintf (stderr, "descramble: unknown scrambling method\n", str); - fflush (stderr); - exit (EXIT_FAILURE); - } -#endif /* DIAGNOSTIC */ - - /* Method `A' is symmetrical, so scramble again to decrypt. */ - s = scramble (str + 1); - - /* Shift the whole string one char to the left, pushing the unwanted - 'A' off the left end. Safe, because s is null-terminated. */ - for (i = 0; s[i]; i++) - s[i] = s[i + 1]; - - return s; -} - -#endif /* (AUTH_CLIENT_SUPPORT || AUTH_SERVER_SUPPORT) from top of file */ - -#ifdef DIAGNOSTIC -int -main () -{ - int i; - char *e, *m, biggie[256]; - - char *cleartexts[5]; - cleartexts[0] = "first"; - cleartexts[1] = "the second"; - cleartexts[2] = "this is the third"; - cleartexts[3] = "$#% !!\\3"; - cleartexts[4] = biggie; - - /* Set up the most important test string: */ - /* Can't have a real ASCII zero in the string, because we want to - use printf, so we substitute the character zero. */ - biggie[0] = '0'; - /* The rest of the string gets straight ascending ASCII. */ - for (i = 1; i < 256; i++) - biggie[i] = i; - - /* Test all the strings. */ - for (i = 0; i < 5; i++) - { - printf ("clear%d: %s\n", i, cleartexts[i]); - e = scramble (cleartexts[i]); - printf ("scram%d: %s\n", i, e); - m = descramble (e); - free (e); - printf ("clear%d: %s\n\n", i, m); - free (m); - } - - fflush (stdout); - return 0; -} -#endif /* DIAGNOSTIC */ - -/* - * ;;; The Emacs Lisp that did the dirty work ;;; - * (progn - * - * ;; Helper func. - * (defun random-elt (lst) - * (let* ((len (length lst)) - * (rnd (random len))) - * (nth rnd lst))) - * - * ;; A list of all characters under 127, each appearing once. - * (setq non-meta-chars - * (let ((i 0) - * (l nil)) - * (while (< i 127) - * (setq l (cons i l) - * i (1+ i))) - * l)) - * - * ;; A list of all characters 127 and above, each appearing once. - * (setq meta-chars - * (let ((i 127) - * (l nil)) - * (while (< i 256) - * (setq l (cons i l) - * i (1+ i))) - * l)) - * - * ;; A vector that will hold the chars in a random order. - * (setq scrambled-chars (make-vector 256 0)) - * - * ;; These characters should map to themselves. - * (let ((i 0)) - * (while (< i 32) - * (aset scrambled-chars i i) - * (setq non-meta-chars (delete i non-meta-chars) - * i (1+ i)))) - * - * ;; Assign random (but unique) values, within the non-meta chars. - * (let ((i 32)) - * (while (< i 127) - * (let ((ch (random-elt non-meta-chars))) - * (if (= 0 (aref scrambled-chars i)) - * (progn - * (aset scrambled-chars i ch) - * (aset scrambled-chars ch i) - * (setq non-meta-chars (delete ch non-meta-chars) - * non-meta-chars (delete i non-meta-chars)))) - * (setq i (1+ i))))) - * - * ;; Assign random (but unique) values, within the non-meta chars. - * (let ((i 127)) - * (while (< i 256) - * (let ((ch (random-elt meta-chars))) - * (if (= 0 (aref scrambled-chars i)) - * (progn - * (aset scrambled-chars i ch) - * (aset scrambled-chars ch i) - * (setq meta-chars (delete ch meta-chars) - * meta-chars (delete i meta-chars)))) - * (setq i (1+ i))))) - * - * ;; Now use the `scrambled-chars' vector to get your C array. - * ) - */ diff --git a/contrib/cvs/src/server.c b/contrib/cvs/src/server.c deleted file mode 100644 index cace89d..0000000 --- a/contrib/cvs/src/server.c +++ /dev/null @@ -1,6760 +0,0 @@ -/* This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. */ - -/* - * $FreeBSD$ - */ - -#include -#include "cvs.h" -#include "watch.h" -#include "edit.h" -#include "fileattr.h" -#include "getline.h" -#include "buffer.h" - -int server_active = 0; - -#if defined(SERVER_SUPPORT) || defined(CLIENT_SUPPORT) -# ifdef HAVE_GSSAPI -/* This stuff isn't included solely with SERVER_SUPPORT since some of these - * functions (encryption & the like) get compiled with or without server - * support. - * - * FIXME - They should be in a different file. - */ -# include -# include "xgssapi.h" -/* We use Kerberos 5 routines to map the GSSAPI credential to a user - name. */ -# include - -/* We need this to wrap data. */ -static gss_ctx_id_t gcontext; - -static void gserver_authenticate_connection PROTO((void)); - -/* Whether we are already wrapping GSSAPI communication. */ -static int cvs_gssapi_wrapping; - -# ifdef ENCRYPTION -/* Whether to encrypt GSSAPI communication. We use a global variable - like this because we use the same buffer type (gssapi_wrap) to - handle both authentication and encryption, and we don't want - multiple instances of that buffer in the communication stream. */ -int cvs_gssapi_encrypt; -# endif -# endif /* HAVE_GSSAPI */ -#endif /* defined(SERVER_SUPPORT) || defined(CLIENT_SUPPORT) */ - -#ifdef SERVER_SUPPORT - -#ifdef HAVE_WINSOCK_H -#include -#endif - -#if defined (AUTH_SERVER_SUPPORT) || defined (HAVE_KERBEROS) || defined (HAVE_GSSAPI) -#include -#endif - -#ifdef HAVE_SYSLOG_H -# include -# ifndef LOG_DAEMON /* for ancient syslogs */ -# define LOG_DAEMON 0 -# endif -#endif - -#ifdef HAVE_KERBEROS -# include -# include -# ifndef HAVE_KRB_GET_ERR_TEXT -# define krb_get_err_text(status) krb_err_txt[status] -# endif - -/* Information we need if we are going to use Kerberos encryption. */ -static C_Block kblock; -static Key_schedule sched; - -#endif - -/* for select */ -#include "xselect.h" - -#ifndef O_NONBLOCK -#define O_NONBLOCK O_NDELAY -#endif - -/* EWOULDBLOCK is not defined by POSIX, but some BSD systems will - return it, rather than EAGAIN, for nonblocking writes. */ -#ifdef EWOULDBLOCK -#define blocking_error(err) ((err) == EWOULDBLOCK || (err) == EAGAIN) -#else -#define blocking_error(err) ((err) == EAGAIN) -#endif - -/* For initgroups(). */ -#if HAVE_INITGROUPS -#include -#endif /* HAVE_INITGROUPS */ - -# ifdef AUTH_SERVER_SUPPORT - -# ifdef HAVE_GETSPNAM -# include -# endif - -/* The cvs username sent by the client, which might or might not be - the same as the system username the server eventually switches to - run as. CVS_Username gets set iff password authentication is - successful. */ -char *CVS_Username = NULL; - -/* Used to check that same repos is transmitted in pserver auth and in - later CVS protocol. Exported because root.c also uses. */ -static char *Pserver_Repos = NULL; - -/* Should we check for system usernames/passwords? Can be changed by - CVSROOT/config. */ -int system_auth = 1; - -# endif /* AUTH_SERVER_SUPPORT */ - - -/* While processing requests, this buffer accumulates data to be sent to - the client, and then once we are in do_cvs_command, we use it - for all the data to be sent. */ -static struct buffer *buf_to_net; - -/* This buffer is used to read input from the client. */ -static struct buffer *buf_from_net; - -/* - * This is where we stash stuff we are going to use. Format string - * which expects a single directory within it, starting with a slash. - */ -static char *server_temp_dir; - -/* This is the original value of server_temp_dir, before any possible - changes inserted by serve_max_dotdot. */ -static char *orig_server_temp_dir; - -/* Nonzero if we should keep the temp directory around after we exit. */ -static int dont_delete_temp; - -static void server_write_entries PROTO((void)); - -/* All server communication goes through buffer structures. Most of - the buffers are built on top of a file descriptor. This structure - is used as the closure field in a buffer. */ - -struct fd_buffer -{ - /* The file descriptor. */ - int fd; - /* Nonzero if the file descriptor is in blocking mode. */ - int blocking; -}; - -static struct buffer *fd_buffer_initialize - PROTO ((int, int, void (*) (struct buffer *))); -static int fd_buffer_input PROTO((void *, char *, int, int, int *)); -static int fd_buffer_output PROTO((void *, const char *, int, int *)); -static int fd_buffer_flush PROTO((void *)); -static int fd_buffer_block PROTO((void *, int)); -static int fd_buffer_shutdown PROTO((struct buffer *)); - -/* Initialize a buffer built on a file descriptor. FD is the file - descriptor. INPUT is nonzero if this is for input, zero if this is - for output. MEMORY is the function to call when a memory error - occurs. */ - -static struct buffer * -fd_buffer_initialize (fd, input, memory) - int fd; - int input; - void (*memory) PROTO((struct buffer *)); -{ - struct fd_buffer *n; - - n = (struct fd_buffer *) xmalloc (sizeof *n); - n->fd = fd; - n->blocking = 1; - return buf_initialize (input ? fd_buffer_input : NULL, - input ? NULL : fd_buffer_output, - input ? NULL : fd_buffer_flush, - fd_buffer_block, - fd_buffer_shutdown, - memory, - n); -} - -/* The buffer input function for a buffer built on a file descriptor. */ - -static int -fd_buffer_input (closure, data, need, size, got) - void *closure; - char *data; - int need; - int size; - int *got; -{ - struct fd_buffer *fd = (struct fd_buffer *) closure; - int nbytes; - - if (! fd->blocking) - nbytes = read (fd->fd, data, size); - else - { - /* This case is not efficient. Fortunately, I don't think it - ever actually happens. */ - nbytes = read (fd->fd, data, need == 0 ? 1 : need); - } - - if (nbytes > 0) - { - *got = nbytes; - return 0; - } - - *got = 0; - - if (nbytes == 0) - { - /* End of file. This assumes that we are using POSIX or BSD - style nonblocking I/O. On System V we will get a zero - return if there is no data, even when not at EOF. */ - return -1; - } - - /* Some error occurred. */ - - if (blocking_error (errno)) - { - /* Everything's fine, we just didn't get any data. */ - return 0; - } - - return errno; -} - -/* The buffer output function for a buffer built on a file descriptor. */ - -static int -fd_buffer_output (closure, data, have, wrote) - void *closure; - const char *data; - int have; - int *wrote; -{ - struct fd_buffer *fd = (struct fd_buffer *) closure; - - *wrote = 0; - - while (have > 0) - { - int nbytes; - - nbytes = write (fd->fd, data, have); - - if (nbytes <= 0) - { - if (! fd->blocking - && (nbytes == 0 || blocking_error (errno))) - { - /* A nonblocking write failed to write any data. Just - return. */ - return 0; - } - - /* Some sort of error occurred. */ - - if (nbytes == 0) - return EIO; - - return errno; - } - - *wrote += nbytes; - data += nbytes; - have -= nbytes; - } - - return 0; -} - -/* The buffer flush function for a buffer built on a file descriptor. */ - -/*ARGSUSED*/ -static int -fd_buffer_flush (closure) - void *closure; -{ - /* Nothing to do. File descriptors are always flushed. */ - return 0; -} - -/* The buffer block function for a buffer built on a file descriptor. */ - -static int -fd_buffer_block (closure, block) - void *closure; - int block; -{ - struct fd_buffer *fd = (struct fd_buffer *) closure; - int flags; - - flags = fcntl (fd->fd, F_GETFL, 0); - if (flags < 0) - return errno; - - if (block) - flags &= ~O_NONBLOCK; - else - flags |= O_NONBLOCK; - - if (fcntl (fd->fd, F_SETFL, flags) < 0) - return errno; - - fd->blocking = block; - - return 0; -} - -/* The buffer shutdown function for a buffer built on a file descriptor. */ - -static int -fd_buffer_shutdown (buf) - struct buffer *buf; -{ - free (buf->closure); - buf->closure = NULL; - return 0; -} - -/* Populate all of the directories between BASE_DIR and its relative - subdirectory DIR with CVSADM directories. Return 0 for success or - errno value. */ -static int create_adm_p PROTO((char *, char *)); - -static int -create_adm_p (base_dir, dir) - char *base_dir; - char *dir; -{ - char *dir_where_cvsadm_lives, *dir_to_register, *p, *tmp; - int retval, done; - FILE *f; - - if (strcmp (dir, ".") == 0) - return 0; /* nothing to do */ - - /* Allocate some space for our directory-munging string. */ - p = xmalloc (strlen (dir) + 1); - if (p == NULL) - return ENOMEM; - - dir_where_cvsadm_lives = xmalloc (strlen (base_dir) + strlen (dir) + 100); - if (dir_where_cvsadm_lives == NULL) - { - free (p); - return ENOMEM; - } - - /* Allocate some space for the temporary string in which we will - construct filenames. */ - tmp = xmalloc (strlen (base_dir) + strlen (dir) + 100); - if (tmp == NULL) - { - free (p); - free (dir_where_cvsadm_lives); - return ENOMEM; - } - - - /* We make several passes through this loop. On the first pass, - we simply create the CVSADM directory in the deepest directory. - For each subsequent pass, we try to remove the last path - element from DIR, create the CVSADM directory in the remaining - pathname, and register the subdirectory in the newly created - CVSADM directory. */ - - retval = done = 0; - - strcpy (p, dir); - strcpy (dir_where_cvsadm_lives, base_dir); - strcat (dir_where_cvsadm_lives, "/"); - strcat (dir_where_cvsadm_lives, p); - dir_to_register = NULL; - - while (1) - { - /* Create CVSADM. */ - (void) sprintf (tmp, "%s/%s", dir_where_cvsadm_lives, CVSADM); - if ((CVS_MKDIR (tmp, 0777) < 0) && (errno != EEXIST)) - { - retval = errno; - goto finish; - } - - /* Create CVSADM_REP. */ - (void) sprintf (tmp, "%s/%s", dir_where_cvsadm_lives, CVSADM_REP); - if (! isfile (tmp)) - { - /* Use Emptydir as the placeholder until the client sends - us the real value. This code is similar to checkout.c - (emptydir_name), but the code below returns errors - differently. */ - - char *empty; - empty = xmalloc (strlen (current_parsed_root->directory) - + sizeof (CVSROOTADM) - + sizeof (CVSNULLREPOS) - + 3); - if (! empty) - { - retval = ENOMEM; - goto finish; - } - - /* Create the directory name. */ - (void) sprintf (empty, "%s/%s/%s", current_parsed_root->directory, - CVSROOTADM, CVSNULLREPOS); - - /* Create the directory if it doesn't exist. */ - if (! isfile (empty)) - { - mode_t omask; - omask = umask (cvsumask); - if (CVS_MKDIR (empty, 0777) < 0) - { - retval = errno; - free (empty); - goto finish; - } - (void) umask (omask); - } - - f = CVS_FOPEN (tmp, "w"); - if (f == NULL) - { - retval = errno; - free (empty); - goto finish; - } - /* Write the directory name to CVSADM_REP. */ - if (fprintf (f, "%s\n", empty) < 0) - { - retval = errno; - fclose (f); - free (empty); - goto finish; - } - if (fclose (f) == EOF) - { - retval = errno; - free (empty); - goto finish; - } - - /* Clean up after ourselves. */ - free (empty); - } - - /* Create CVSADM_ENT. We open in append mode because we - don't want to clobber an existing Entries file. */ - (void) sprintf (tmp, "%s/%s", dir_where_cvsadm_lives, CVSADM_ENT); - f = CVS_FOPEN (tmp, "a"); - if (f == NULL) - { - retval = errno; - goto finish; - } - if (fclose (f) == EOF) - { - retval = errno; - goto finish; - } - - if (dir_to_register != NULL) - { - /* FIXME: Yes, this results in duplicate entries in the - Entries.Log file, but it doesn't currently matter. We - might need to change this later on to make sure that we - only write one entry. */ - - Subdir_Register ((List *) NULL, dir_where_cvsadm_lives, - dir_to_register); - } - - if (done) - break; - - dir_to_register = strrchr (p, '/'); - if (dir_to_register == NULL) - { - dir_to_register = p; - strcpy (dir_where_cvsadm_lives, base_dir); - done = 1; - } - else - { - *dir_to_register = '\0'; - dir_to_register++; - strcpy (dir_where_cvsadm_lives, base_dir); - strcat (dir_where_cvsadm_lives, "/"); - strcat (dir_where_cvsadm_lives, p); - } - } - - finish: - free (tmp); - free (dir_where_cvsadm_lives); - free (p); - return retval; -} - -/* - * Make directory DIR, including all intermediate directories if necessary. - * Returns 0 for success or errno code. - */ -static int mkdir_p PROTO((char *)); - -static int -mkdir_p (dir) - char *dir; -{ - char *p; - char *q = xmalloc (strlen (dir) + 1); - int retval; - - if (q == NULL) - return ENOMEM; - - retval = 0; - - /* - * Skip over leading slash if present. We won't bother to try to - * make '/'. - */ - p = dir + 1; - while (1) - { - while (*p != '/' && *p != '\0') - ++p; - if (*p == '/') - { - strncpy (q, dir, p - dir); - q[p - dir] = '\0'; - if (q[p - dir - 1] != '/' && CVS_MKDIR (q, 0777) < 0) - { - int saved_errno = errno; - - if (saved_errno != EEXIST - && ((saved_errno != EACCES && saved_errno != EROFS) - || !isdir (q))) - { - retval = saved_errno; - goto done; - } - } - ++p; - } - else - { - if (CVS_MKDIR (dir, 0777) < 0) - retval = errno; - goto done; - } - } - done: - free (q); - return retval; -} - -/* - * Print the error response for error code STATUS. The caller is - * reponsible for making sure we get back to the command loop without - * any further output occuring. - * Must be called only in contexts where it is OK to send output. - */ -static void -print_error (status) - int status; -{ - char *msg; - char tmpstr[80]; - - buf_output0 (buf_to_net, "error "); - msg = strerror (status); - if (msg == NULL) - { - sprintf (tmpstr, "unknown error %d", status); - msg = tmpstr; - } - buf_output0 (buf_to_net, msg); - buf_append_char (buf_to_net, '\n'); - - buf_flush (buf_to_net, 0); -} - -static int pending_error; -/* - * Malloc'd text for pending error. Each line must start with "E ". The - * last line should not end with a newline. - */ -static char *pending_error_text; - -/* If an error is pending, print it and return 1. If not, return 0. - Must be called only in contexts where it is OK to send output. */ -static int -print_pending_error () -{ - if (pending_error_text) - { - buf_output0 (buf_to_net, pending_error_text); - buf_append_char (buf_to_net, '\n'); - if (pending_error) - print_error (pending_error); - else - buf_output0 (buf_to_net, "error \n"); - - buf_flush (buf_to_net, 0); - - pending_error = 0; - free (pending_error_text); - pending_error_text = NULL; - return 1; - } - else if (pending_error) - { - print_error (pending_error); - pending_error = 0; - return 1; - } - else - return 0; -} - -/* Is an error pending? */ -#define error_pending() (pending_error || pending_error_text) - -static int alloc_pending PROTO ((size_t size)); - -/* Allocate SIZE bytes for pending_error_text and return nonzero - if we could do it. */ -static int -alloc_pending (size) - size_t size; -{ - if (error_pending ()) - /* Probably alloc_pending callers will have already checked for - this case. But we might as well handle it if they don't, I - guess. */ - return 0; - pending_error_text = xmalloc (size); - if (pending_error_text == NULL) - { - pending_error = ENOMEM; - return 0; - } - return 1; -} - -static void serve_is_modified PROTO ((char *)); - -static int supported_response PROTO ((char *)); - -static int -supported_response (name) - char *name; -{ - struct response *rs; - - for (rs = responses; rs->name != NULL; ++rs) - if (strcmp (rs->name, name) == 0) - return rs->status == rs_supported; - error (1, 0, "internal error: testing support for unknown response?"); - /* NOTREACHED */ - return 0; -} - -static void -serve_valid_responses (arg) - char *arg; -{ - char *p = arg; - char *q; - struct response *rs; - do - { - q = strchr (p, ' '); - if (q != NULL) - *q++ = '\0'; - for (rs = responses; rs->name != NULL; ++rs) - { - if (strcmp (rs->name, p) == 0) - break; - } - if (rs->name == NULL) - /* - * It is a response we have never heard of (and thus never - * will want to use). So don't worry about it. - */ - ; - else - rs->status = rs_supported; - p = q; - } while (q != NULL); - for (rs = responses; rs->name != NULL; ++rs) - { - if (rs->status == rs_essential) - { - buf_output0 (buf_to_net, "E response `"); - buf_output0 (buf_to_net, rs->name); - buf_output0 (buf_to_net, "' not supported by client\nerror \n"); - - /* FIXME: This call to buf_flush could conceivably - cause deadlock, as noted in server_cleanup. */ - buf_flush (buf_to_net, 1); - - error_exit (); - } - else if (rs->status == rs_optional) - rs->status = rs_not_supported; - } -} - -static void -serve_root (arg) - char *arg; -{ - char *env; - char *path; - - if (error_pending()) return; - - if (!isabsolute (arg)) - { - if (alloc_pending (80 + strlen (arg))) - sprintf (pending_error_text, - "E Root %s must be an absolute pathname", arg); - return; - } - - /* Sending "Root" twice is illegal. - - The other way to handle a duplicate Root requests would be as a - request to clear out all state and start over as if it was a - new connection. Doing this would cause interoperability - headaches, so it should be a different request, if there is - any reason why such a feature is needed. */ - if (current_parsed_root != NULL) - { - if (alloc_pending (80 + strlen (arg))) - sprintf (pending_error_text, - "E Protocol error: Duplicate Root request, for %s", arg); - return; - } - - /* We need to check :ext: server here, :pserver: checks happen below. */ - if (root_allow_used() && !root_allow_ok (arg) -# ifdef AUTH_SERVER_SUPPORT - && Pserver_Repos == NULL -# endif - ) - { - if (alloc_pending (80 + strlen (arg))) - sprintf (pending_error_text, - "E Bad root %s", arg); - return; - } - -#ifdef AUTH_SERVER_SUPPORT - if (Pserver_Repos != NULL) - { - if (strcmp (Pserver_Repos, arg) != 0) - { - if (alloc_pending (80 + strlen (Pserver_Repos) + strlen (arg))) - /* The explicitness is to aid people who are writing clients. - I don't see how this information could help an - attacker. */ - sprintf (pending_error_text, "\ -E Protocol error: Root says \"%s\" but pserver says \"%s\"", - arg, Pserver_Repos); - return; - } - } -#endif - - current_parsed_root = local_cvsroot (arg); - - /* For pserver, this will already have happened, and the call will do - nothing. But for rsh, we need to do it now. */ - parse_config (current_parsed_root->directory); - - /* Now is a good time to read CVSROOT/options too. */ - parseopts(current_parsed_root->directory); - - path = xmalloc (strlen (current_parsed_root->directory) - + sizeof (CVSROOTADM) - + 2); - if (path == NULL) - { - pending_error = ENOMEM; - return; - } - (void) sprintf (path, "%s/%s", current_parsed_root->directory, CVSROOTADM); - if (!isaccessible (path, R_OK | X_OK)) - { - int save_errno = errno; - if (alloc_pending (80 + strlen (path))) - sprintf (pending_error_text, "E Cannot access %s", path); - pending_error = save_errno; - } - free (path); - -#ifdef HAVE_PUTENV - env = xmalloc (strlen (CVSROOT_ENV) + strlen (current_parsed_root->directory) + 2); - if (env == NULL) - { - pending_error = ENOMEM; - return; - } - (void) sprintf (env, "%s=%s", CVSROOT_ENV, current_parsed_root->directory); - (void) putenv (env); - /* do not free env, as putenv has control of it */ -#endif -} - -static int max_dotdot_limit = 0; - -/* Is this pathname OK to recurse into when we are running as the server? - If not, call error() with a fatal error. */ -void -server_pathname_check (path) - char *path; -{ - /* An absolute pathname is almost surely a path on the *client* machine, - and is unlikely to do us any good here. It also is probably capable - of being a security hole in the anonymous readonly case. */ - if (isabsolute (path)) - /* Giving an error is actually kind of a cop-out, in the sense - that it would be nice for "cvs co -d /foo/bar/baz" to work. - A quick fix in the server would be requiring Max-dotdot of - at least one if pathnames are absolute, and then putting - /abs/foo/bar/baz in the temp dir beside the /d/d/d stuff. - A cleaner fix in the server might be to decouple the - pathnames we pass back to the client from pathnames in our - temp directory (this would also probably remove the need - for Max-dotdot). A fix in the client would have the client - turn it into "cd /foo/bar; cvs co -d baz" (more or less). - This probably has some problems with pathnames which appear - in messages. */ - error (1, 0, "absolute pathname `%s' illegal for server", path); - if (pathname_levels (path) > max_dotdot_limit) - { - /* Similar to the isabsolute case in security implications. */ - error (0, 0, "protocol error: `%s' contains more leading ..", path); - error (1, 0, "than the %d which Max-dotdot specified", - max_dotdot_limit); - } -} - -static int outside_root PROTO ((char *)); - -/* Is file or directory REPOS an absolute pathname within the - current_parsed_root->directory? If yes, return 0. If no, set pending_error - and return 1. */ -static int -outside_root (repos) - char *repos; -{ - size_t repos_len = strlen (repos); - size_t root_len = strlen (current_parsed_root->directory); - - /* isabsolute (repos) should always be true, but - this is a good security precaution regardless. -DRP - */ - if (!isabsolute (repos)) - { - if (alloc_pending (repos_len + 80)) - sprintf (pending_error_text, "\ -E protocol error: %s is not absolute", repos); - return 1; - } - - if (repos_len < root_len - || strncmp (current_parsed_root->directory, repos, root_len) != 0) - { - not_within: - if (alloc_pending (strlen (current_parsed_root->directory) - + strlen (repos) - + 80)) - sprintf (pending_error_text, "\ -E protocol error: directory '%s' not within root '%s'", - repos, current_parsed_root->directory); - return 1; - } - if (repos_len > root_len) - { - if (repos[root_len] != '/') - goto not_within; - if (pathname_levels (repos + root_len + 1) > 0) - goto not_within; - } - return 0; -} - -static int outside_dir PROTO ((char *)); - -/* Is file or directory FILE outside the current directory (that is, does - it contain '/')? If no, return 0. If yes, set pending_error - and return 1. */ -static int -outside_dir (file) - char *file; -{ - if (strchr (file, '/') != NULL) - { - if (alloc_pending (strlen (file) - + 80)) - sprintf (pending_error_text, "\ -E protocol error: directory '%s' not within current directory", - file); - return 1; - } - return 0; -} - -/* - * Add as many directories to the temp directory as the client tells us it - * will use "..", so we never try to access something outside the temp - * directory via "..". - */ -static void -serve_max_dotdot (arg) - char *arg; -{ - int lim = atoi (arg); - int i; - char *p; - - if (lim < 0 || lim > 10000) - return; - p = xmalloc (strlen (server_temp_dir) + 2 * lim + 10); - if (p == NULL) - { - pending_error = ENOMEM; - return; - } - strcpy (p, server_temp_dir); - for (i = 0; i < lim; ++i) - strcat (p, "/d"); - if (server_temp_dir != orig_server_temp_dir) - free (server_temp_dir); - server_temp_dir = p; - max_dotdot_limit = lim; -} - -static char *dir_name; - -static void -dirswitch (dir, repos) - char *dir; - char *repos; -{ - int status; - FILE *f; - size_t dir_len; - - server_write_entries (); - - if (error_pending()) return; - - /* Check for bad directory name. - - FIXME: could/should unify these checks with server_pathname_check - except they need to report errors differently. */ - if (isabsolute (dir)) - { - if (alloc_pending (80 + strlen (dir))) - sprintf (pending_error_text, - "E absolute pathname `%s' illegal for server", dir); - return; - } - if (pathname_levels (dir) > max_dotdot_limit) - { - if (alloc_pending (80 + strlen (dir))) - sprintf (pending_error_text, - "E protocol error: `%s' has too many ..", dir); - return; - } - - dir_len = strlen (dir); - - /* Check for a trailing '/'. This is not ISDIRSEP because \ in the - protocol is an ordinary character, not a directory separator (of - course, it is perhaps unwise to use it in directory names, but that - is another issue). */ - if (dir_len > 0 - && dir[dir_len - 1] == '/') - { - if (alloc_pending (80 + dir_len)) - sprintf (pending_error_text, - "E protocol error: invalid directory syntax in %s", dir); - return; - } - - if (dir_name != NULL) - free (dir_name); - - dir_name = xmalloc (strlen (server_temp_dir) + dir_len + 40); - if (dir_name == NULL) - { - pending_error = ENOMEM; - return; - } - - strcpy (dir_name, server_temp_dir); - strcat (dir_name, "/"); - strcat (dir_name, dir); - - status = mkdir_p (dir_name); - if (status != 0 - && status != EEXIST) - { - if (alloc_pending (80 + strlen (dir_name))) - sprintf (pending_error_text, "E cannot mkdir %s", dir_name); - pending_error = status; - return; - } - - /* We need to create adm directories in all path elements because - we want the server to descend them, even if the client hasn't - sent the appropriate "Argument xxx" command to match the - already-sent "Directory xxx" command. See recurse.c - (start_recursion) for a big discussion of this. */ - - status = create_adm_p (server_temp_dir, dir); - if (status != 0) - { - if (alloc_pending (80 + strlen (dir_name))) - sprintf (pending_error_text, "E cannot create_adm_p %s", dir_name); - pending_error = status; - return; - } - - if ( CVS_CHDIR (dir_name) < 0) - { - int save_errno = errno; - if (alloc_pending (80 + strlen (dir_name))) - sprintf (pending_error_text, "E cannot change to %s", dir_name); - pending_error = save_errno; - return; - } - /* - * This is pretty much like calling Create_Admin, but Create_Admin doesn't - * report errors in the right way for us. - */ - if ((CVS_MKDIR (CVSADM, 0777) < 0) && (errno != EEXIST)) - { - int save_errno = errno; - if (alloc_pending (80 + strlen (dir_name) + strlen (CVSADM))) - sprintf (pending_error_text, - "E cannot mkdir %s/%s", dir_name, CVSADM); - pending_error = save_errno; - return; - } - - /* The following will overwrite the contents of CVSADM_REP. This - is the correct behavior -- mkdir_p may have written a - placeholder value to this file and we need to insert the - correct value. */ - - f = CVS_FOPEN (CVSADM_REP, "w"); - if (f == NULL) - { - int save_errno = errno; - if (alloc_pending (80 + strlen (dir_name) + strlen (CVSADM_REP))) - sprintf (pending_error_text, - "E cannot open %s/%s", dir_name, CVSADM_REP); - pending_error = save_errno; - return; - } - if (fprintf (f, "%s", repos) < 0) - { - int save_errno = errno; - if (alloc_pending (80 + strlen (dir_name) + strlen (CVSADM_REP))) - sprintf (pending_error_text, - "E error writing %s/%s", dir_name, CVSADM_REP); - pending_error = save_errno; - fclose (f); - return; - } - /* Non-remote CVS handles a module representing the entire tree - (e.g., an entry like ``world -a .'') by putting /. at the end - of the Repository file, so we do the same. */ - if (strcmp (dir, ".") == 0 - && current_parsed_root != NULL - && current_parsed_root->directory != NULL - && strcmp (current_parsed_root->directory, repos) == 0) - { - if (fprintf (f, "/.") < 0) - { - int save_errno = errno; - if (alloc_pending (80 + strlen (dir_name) + strlen (CVSADM_REP))) - sprintf (pending_error_text, - "E error writing %s/%s", dir_name, CVSADM_REP); - pending_error = save_errno; - fclose (f); - return; - } - } - if (fprintf (f, "\n") < 0) - { - int save_errno = errno; - if (alloc_pending (80 + strlen (dir_name) + strlen (CVSADM_REP))) - sprintf (pending_error_text, - "E error writing %s/%s", dir_name, CVSADM_REP); - pending_error = save_errno; - fclose (f); - return; - } - if (fclose (f) == EOF) - { - int save_errno = errno; - if (alloc_pending (80 + strlen (dir_name) + strlen (CVSADM_REP))) - sprintf (pending_error_text, - "E error closing %s/%s", dir_name, CVSADM_REP); - pending_error = save_errno; - return; - } - /* We open in append mode because we don't want to clobber an - existing Entries file. */ - f = CVS_FOPEN (CVSADM_ENT, "a"); - if (f == NULL) - { - int save_errno = errno; - if (alloc_pending (80 + strlen (CVSADM_ENT))) - sprintf (pending_error_text, "E cannot open %s", CVSADM_ENT); - pending_error = save_errno; - return; - } - if (fclose (f) == EOF) - { - int save_errno = errno; - if (alloc_pending (80 + strlen (CVSADM_ENT))) - sprintf (pending_error_text, "E cannot close %s", CVSADM_ENT); - pending_error = save_errno; - return; - } -} - -static void -serve_repository (arg) - char *arg; -{ - if (alloc_pending (80)) - strcpy (pending_error_text, - "E Repository request is obsolete; aborted"); - return; -} - -static void -serve_directory (arg) - char *arg; -{ - int status; - char *repos; - - status = buf_read_line (buf_from_net, &repos, (int *) NULL); - if (status == 0) - { - if (!outside_root (repos)) - dirswitch (arg, repos); - free (repos); - } - else if (status == -2) - { - pending_error = ENOMEM; - } - else - { - pending_error_text = xmalloc (80 + strlen (arg)); - if (pending_error_text == NULL) - { - pending_error = ENOMEM; - } - else if (status == -1) - { - sprintf (pending_error_text, - "E end of file reading mode for %s", arg); - } - else - { - sprintf (pending_error_text, - "E error reading mode for %s", arg); - pending_error = status; - } - } -} - -static void -serve_static_directory (arg) - char *arg; -{ - FILE *f; - - if (error_pending ()) return; - - f = CVS_FOPEN (CVSADM_ENTSTAT, "w+"); - if (f == NULL) - { - int save_errno = errno; - if (alloc_pending (80 + strlen (CVSADM_ENTSTAT))) - sprintf (pending_error_text, "E cannot open %s", CVSADM_ENTSTAT); - pending_error = save_errno; - return; - } - if (fclose (f) == EOF) - { - int save_errno = errno; - if (alloc_pending (80 + strlen (CVSADM_ENTSTAT))) - sprintf (pending_error_text, "E cannot close %s", CVSADM_ENTSTAT); - pending_error = save_errno; - return; - } -} - -static void -serve_sticky (arg) - char *arg; -{ - FILE *f; - - if (error_pending ()) return; - - f = CVS_FOPEN (CVSADM_TAG, "w+"); - if (f == NULL) - { - int save_errno = errno; - if (alloc_pending (80 + strlen (CVSADM_TAG))) - sprintf (pending_error_text, "E cannot open %s", CVSADM_TAG); - pending_error = save_errno; - return; - } - if (fprintf (f, "%s\n", arg) < 0) - { - int save_errno = errno; - if (alloc_pending (80 + strlen (CVSADM_TAG))) - sprintf (pending_error_text, "E cannot write to %s", CVSADM_TAG); - pending_error = save_errno; - (void) fclose (f); - return; - } - if (fclose (f) == EOF) - { - int save_errno = errno; - if (alloc_pending (80 + strlen (CVSADM_TAG))) - sprintf (pending_error_text, "E cannot close %s", CVSADM_TAG); - pending_error = save_errno; - return; - } -} - -/* - * Read SIZE bytes from buf_from_net, write them to FILE. - * - * Currently this isn't really used for receiving parts of a file -- - * the file is still sent over in one chunk. But if/when we get - * spiffy in-process gzip support working, perhaps the compressed - * pieces could be sent over as they're ready, if the network is fast - * enough. Or something. - */ -static void -receive_partial_file (size, file) - int size; - int file; -{ - while (size > 0) - { - int status, nread; - char *data; - - status = buf_read_data (buf_from_net, size, &data, &nread); - if (status != 0) - { - if (status == -2) - pending_error = ENOMEM; - else - { - pending_error_text = xmalloc (80); - if (pending_error_text == NULL) - pending_error = ENOMEM; - else if (status == -1) - { - sprintf (pending_error_text, - "E premature end of file from client"); - pending_error = 0; - } - else - { - sprintf (pending_error_text, - "E error reading from client"); - pending_error = status; - } - } - return; - } - - size -= nread; - - while (nread > 0) - { - int nwrote; - - nwrote = write (file, data, nread); - if (nwrote < 0) - { - int save_errno = errno; - if (alloc_pending (40)) - strcpy (pending_error_text, "E unable to write"); - pending_error = save_errno; - - /* Read and discard the file data. */ - while (size > 0) - { - int status, nread; - char *data; - - status = buf_read_data (buf_from_net, size, &data, &nread); - if (status != 0) - return; - size -= nread; - } - - return; - } - nread -= nwrote; - data += nwrote; - } - } -} - -/* Receive SIZE bytes, write to filename FILE. */ -static void -receive_file (size, file, gzipped) - int size; - char *file; - int gzipped; -{ - int fd; - char *arg = file; - - /* Write the file. */ - fd = CVS_OPEN (arg, O_WRONLY | O_CREAT | O_TRUNC, 0600); - if (fd < 0) - { - int save_errno = errno; - if (alloc_pending (40 + strlen (arg))) - sprintf (pending_error_text, "E cannot open %s", arg); - pending_error = save_errno; - return; - } - - if (gzipped) - { - /* Using gunzip_and_write isn't really a high-performance - approach, because it keeps the whole thing in memory - (contiguous memory, worse yet). But it seems easier to - code than the alternative (and less vulnerable to subtle - bugs). Given that this feature is mainly for - compatibility, that is the better tradeoff. */ - - int toread = size; - char *filebuf; - char *p; - - filebuf = xmalloc (size); - p = filebuf; - /* If NULL, we still want to read the data and discard it. */ - - while (toread > 0) - { - int status, nread; - char *data; - - status = buf_read_data (buf_from_net, toread, &data, &nread); - if (status != 0) - { - if (status == -2) - pending_error = ENOMEM; - else - { - pending_error_text = xmalloc (80); - if (pending_error_text == NULL) - pending_error = ENOMEM; - else if (status == -1) - { - sprintf (pending_error_text, - "E premature end of file from client"); - pending_error = 0; - } - else - { - sprintf (pending_error_text, - "E error reading from client"); - pending_error = status; - } - } - return; - } - - toread -= nread; - - if (filebuf != NULL) - { - memcpy (p, data, nread); - p += nread; - } - } - if (filebuf == NULL) - { - pending_error = ENOMEM; - goto out; - } - - if (gunzip_and_write (fd, file, (unsigned char *) filebuf, size)) - { - if (alloc_pending (80)) - sprintf (pending_error_text, - "E aborting due to compression error"); - } - free (filebuf); - } - else - receive_partial_file (size, fd); - - if (pending_error_text) - { - char *p = xrealloc (pending_error_text, - strlen (pending_error_text) + strlen (arg) + 30); - if (p) - { - pending_error_text = p; - sprintf (p + strlen (p), ", file %s", arg); - } - /* else original string is supposed to be unchanged */ - } - - out: - if (close (fd) < 0 && !error_pending ()) - { - int save_errno = errno; - if (alloc_pending (40 + strlen (arg))) - sprintf (pending_error_text, "E cannot close %s", arg); - pending_error = save_errno; - return; - } -} - -/* Kopt for the next file sent in Modified or Is-modified. */ -static char *kopt; - -/* Timestamp (Checkin-time) for next file sent in Modified or - Is-modified. */ -static int checkin_time_valid; -static time_t checkin_time; - -static void serve_modified PROTO ((char *)); - -static void -serve_modified (arg) - char *arg; -{ - int size, status; - char *size_text; - char *mode_text; - - int gzipped = 0; - - /* - * This used to return immediately if error_pending () was true. - * However, that fails, because it causes each line of the file to - * be echoed back to the client as an unrecognized command. The - * client isn't reading from the socket, so eventually both - * processes block trying to write to the other. Now, we try to - * read the file if we can. - */ - - status = buf_read_line (buf_from_net, &mode_text, (int *) NULL); - if (status != 0) - { - if (status == -2) - pending_error = ENOMEM; - else - { - pending_error_text = xmalloc (80 + strlen (arg)); - if (pending_error_text == NULL) - pending_error = ENOMEM; - else - { - if (status == -1) - sprintf (pending_error_text, - "E end of file reading mode for %s", arg); - else - { - sprintf (pending_error_text, - "E error reading mode for %s", arg); - pending_error = status; - } - } - } - return; - } - - status = buf_read_line (buf_from_net, &size_text, (int *) NULL); - if (status != 0) - { - if (status == -2) - pending_error = ENOMEM; - else - { - pending_error_text = xmalloc (80 + strlen (arg)); - if (pending_error_text == NULL) - pending_error = ENOMEM; - else - { - if (status == -1) - sprintf (pending_error_text, - "E end of file reading size for %s", arg); - else - { - sprintf (pending_error_text, - "E error reading size for %s", arg); - pending_error = status; - } - } - } - free (mode_text); - return; - } - if (size_text[0] == 'z') - { - gzipped = 1; - size = atoi (size_text + 1); - } - else - size = atoi (size_text); - free (size_text); - - if (error_pending ()) - { - /* Now that we know the size, read and discard the file data. */ - while (size > 0) - { - int status, nread; - char *data; - - status = buf_read_data (buf_from_net, size, &data, &nread); - if (status != 0) - return; - size -= nread; - } - free (mode_text); - return; - } - - if (outside_dir (arg)) - { - free (mode_text); - return; - } - - if (size >= 0) - { - receive_file (size, arg, gzipped); - if (error_pending ()) - { - free (mode_text); - return; - } - } - - if (checkin_time_valid) - { - struct utimbuf t; - - memset (&t, 0, sizeof (t)); - t.modtime = t.actime = checkin_time; - if (utime (arg, &t) < 0) - { - int save_errno = errno; - if (alloc_pending (80 + strlen (arg))) - sprintf (pending_error_text, "E cannot utime %s", arg); - pending_error = save_errno; - free (mode_text); - return; - } - checkin_time_valid = 0; - } - - { - int status = change_mode (arg, mode_text, 0); - free (mode_text); - if (status) - { - if (alloc_pending (40 + strlen (arg))) - sprintf (pending_error_text, - "E cannot change mode for %s", arg); - pending_error = status; - return; - } - } - - /* Make sure that the Entries indicate the right kopt. We probably - could do this even in the non-kopt case and, I think, save a stat() - call in time_stamp_server. But for conservatism I'm leaving the - non-kopt case alone. */ - if (kopt != NULL) - serve_is_modified (arg); -} - - -static void -serve_enable_unchanged (arg) - char *arg; -{ -} - -struct an_entry { - struct an_entry *next; - char *entry; -}; - -static struct an_entry *entries; - -static void serve_unchanged PROTO ((char *)); - -static void -serve_unchanged (arg) - char *arg; -{ - struct an_entry *p; - char *name; - char *cp; - char *timefield; - - if (error_pending ()) return; - - if (outside_dir (arg)) - return; - - /* Rewrite entries file to have `=' in timestamp field. */ - for (p = entries; p != NULL; p = p->next) - { - name = p->entry + 1; - cp = strchr (name, '/'); - if (cp != NULL - && strlen (arg) == cp - name - && strncmp (arg, name, cp - name) == 0) - { - if (!(timefield = strchr (cp + 1, '/')) || *++timefield == '\0') - { - /* We didn't find the record separator or it is followed by - * the end of the string, so just exit. - */ - if (alloc_pending (80)) - sprintf (pending_error_text, - "E Malformed Entry encountered."); - return; - } - /* If the time field is not currently empty, then one of - * serve_modified, serve_is_modified, & serve_unchanged were - * already called for this file. We would like to ignore the - * reinvocation silently or, better yet, exit with an error - * message, but we just avoid the copy-forward and overwrite the - * value from the last invocation instead. See the comment below - * for more. - */ - if (*timefield == '/') - { - /* Copy forward one character. Space was allocated for this - * already in serve_entry(). */ - cp = timefield + strlen (timefield); - cp[1] = '\0'; - while (cp > timefield) - { - *cp = cp[-1]; - --cp; - } - } - /* If *TIMEFIELD wasn't "/", we assume that it was because of - * multiple calls to Is-Modified & Unchanged by the client and - * just overwrite the value from the last call. Technically, we - * should probably either ignore calls after the first or send the - * client an error, since the client/server protocol specification - * specifies that only one call to either Is-Modified or Unchanged - * is allowed, but broken versions of WinCVS & TortoiseCVS rely on - * this behavior. - */ - if (*timefield != '+') - /* Skip this for entries with conflict markers. */ - *timefield = '='; - break; - } - } -} - -static void -serve_is_modified (arg) - char *arg; -{ - struct an_entry *p; - char *name; - char *cp; - char *timefield; - /* Have we found this file in "entries" yet. */ - int found; - - if (error_pending ()) return; - - if (outside_dir (arg)) - return; - - /* Rewrite entries file to have `M' in timestamp field. */ - found = 0; - for (p = entries; p != NULL; p = p->next) - { - name = p->entry + 1; - cp = strchr (name, '/'); - if (cp != NULL - && strlen (arg) == cp - name - && strncmp (arg, name, cp - name) == 0) - { - if (!(timefield = strchr (cp + 1, '/')) || *++timefield == '\0') - { - /* We didn't find the record separator or it is followed by - * the end of the string, so just exit. - */ - if (alloc_pending (80)) - sprintf (pending_error_text, - "E Malformed Entry encountered."); - return; - } - /* If the time field is not currently empty, then one of - * serve_modified, serve_is_modified, & serve_unchanged were - * already called for this file. We would like to ignore the - * reinvocation silently or, better yet, exit with an error - * message, but we just avoid the copy-forward and overwrite the - * value from the last invocation instead. See the comment below - * for more. - */ - if (*timefield == '/') - { - /* Copy forward one character. Space was allocated for this - * already in serve_entry(). */ - cp = timefield + strlen (timefield); - cp[1] = '\0'; - while (cp > timefield) - { - *cp = cp[-1]; - --cp; - } - } - /* If *TIMEFIELD wasn't "/", we assume that it was because of - * multiple calls to Is-Modified & Unchanged by the client and - * just overwrite the value from the last call. Technically, we - * should probably either ignore calls after the first or send the - * client an error, since the client/server protocol specification - * specifies that only one call to either Is-Modified or Unchanged - * is allowed, but broken versions of WinCVS & TortoiseCVS rely on - * this behavior. - */ - if (*timefield != '+') - /* Skip this for entries with conflict markers. */ - *timefield = 'M'; - - if (kopt != NULL) - { - if (alloc_pending (strlen (name) + 80)) - sprintf (pending_error_text, - "E protocol error: both Kopt and Entry for %s", - arg); - free (kopt); - kopt = NULL; - return; - } - found = 1; - break; - } - } - if (!found) - { - /* We got Is-modified but no Entry. Add a dummy entry. - The "D" timestamp is what makes it a dummy. */ - p = (struct an_entry *) xmalloc (sizeof (struct an_entry)); - if (p == NULL) - { - pending_error = ENOMEM; - return; - } - p->entry = xmalloc (strlen (arg) + 80); - if (p->entry == NULL) - { - pending_error = ENOMEM; - free (p); - return; - } - strcpy (p->entry, "/"); - strcat (p->entry, arg); - strcat (p->entry, "//D/"); - if (kopt != NULL) - { - strcat (p->entry, kopt); - free (kopt); - kopt = NULL; - } - strcat (p->entry, "/"); - p->next = entries; - entries = p; - } -} - -static void serve_entry PROTO ((char *)); - -static void -serve_entry (arg) - char *arg; -{ - struct an_entry *p; - char *cp; - int i = 0; - if (error_pending()) return; - - /* Verify that the entry is well-formed. This can avoid problems later. - * At the moment we only check that the Entry contains five slashes in - * approximately the correct locations since some of the code makes - * assumptions about this. - */ - cp = arg; - if (*cp == 'D') cp++; - while (i++ < 5) - { - if (!cp || *cp != '/') - { - if (alloc_pending (80)) - sprintf (pending_error_text, - "E protocol error: Malformed Entry"); - return; - } - cp = strchr (cp + 1, '/'); - } - - p = xmalloc (sizeof (struct an_entry)); - if (p == NULL) - { - pending_error = ENOMEM; - return; - } - /* Leave space for serve_unchanged to write '=' if it wants. */ - cp = xmalloc (strlen (arg) + 2); - if (cp == NULL) - { - free (p); - pending_error = ENOMEM; - return; - } - strcpy (cp, arg); - p->next = entries; - p->entry = cp; - entries = p; -} - -static void serve_kopt PROTO ((char *)); - -static void -serve_kopt (arg) - char *arg; -{ - if (error_pending ()) - return; - - if (kopt != NULL) - { - if (alloc_pending (80 + strlen (arg))) - sprintf (pending_error_text, - "E protocol error: duplicate Kopt request: %s", arg); - return; - } - - /* Do some sanity checks. In particular, that it is not too long. - This lets the rest of the code not worry so much about buffer - overrun attacks. Probably should call RCS_check_kflag here, - but that would mean changing RCS_check_kflag to handle errors - other than via exit(), fprintf(), and such. */ - if (strlen (arg) > 10) - { - if (alloc_pending (80 + strlen (arg))) - sprintf (pending_error_text, - "E protocol error: invalid Kopt request: %s", arg); - return; - } - - kopt = xmalloc (strlen (arg) + 1); - if (kopt == NULL) - { - pending_error = ENOMEM; - return; - } - strcpy (kopt, arg); -} - -static void serve_checkin_time PROTO ((char *)); - -static void -serve_checkin_time (arg) - char *arg; -{ - if (error_pending ()) - return; - - if (checkin_time_valid) - { - if (alloc_pending (80 + strlen (arg))) - sprintf (pending_error_text, - "E protocol error: duplicate Checkin-time request: %s", - arg); - return; - } - - checkin_time = get_date (arg, NULL); - if (checkin_time == (time_t)-1) - { - if (alloc_pending (80 + strlen (arg))) - sprintf (pending_error_text, "E cannot parse date %s", arg); - return; - } - checkin_time_valid = 1; -} - -static void -server_write_entries () -{ - FILE *f; - struct an_entry *p; - struct an_entry *q; - - if (entries == NULL) - return; - - f = NULL; - /* Note that we free all the entries regardless of errors. */ - if (!error_pending ()) - { - /* We open in append mode because we don't want to clobber an - existing Entries file. If we are checking out a module - which explicitly lists more than one file in a particular - directory, then we will wind up calling - server_write_entries for each such file. */ - f = CVS_FOPEN (CVSADM_ENT, "a"); - if (f == NULL) - { - int save_errno = errno; - if (alloc_pending (80 + strlen (CVSADM_ENT))) - sprintf (pending_error_text, "E cannot open %s", CVSADM_ENT); - pending_error = save_errno; - } - } - for (p = entries; p != NULL;) - { - if (!error_pending ()) - { - if (fprintf (f, "%s\n", p->entry) < 0) - { - int save_errno = errno; - if (alloc_pending (80 + strlen(CVSADM_ENT))) - sprintf (pending_error_text, - "E cannot write to %s", CVSADM_ENT); - pending_error = save_errno; - } - } - free (p->entry); - q = p->next; - free (p); - p = q; - } - entries = NULL; - if (f != NULL && fclose (f) == EOF && !error_pending ()) - { - int save_errno = errno; - if (alloc_pending (80 + strlen (CVSADM_ENT))) - sprintf (pending_error_text, "E cannot close %s", CVSADM_ENT); - pending_error = save_errno; - } -} - -struct notify_note { - /* Directory in which this notification happens. xmalloc'd*/ - char *dir; - - /* xmalloc'd. */ - char *filename; - - /* The following three all in one xmalloc'd block, pointed to by TYPE. - Each '\0' terminated. */ - /* "E" or "U". */ - char *type; - /* time+host+dir */ - char *val; - char *watches; - - struct notify_note *next; -}; - -static struct notify_note *notify_list; -/* Used while building list, to point to the last node that already exists. */ -static struct notify_note *last_node; - -static void serve_notify PROTO ((char *)); - -static void -serve_notify (arg) - char *arg; -{ - struct notify_note *new = NULL; - char *data = NULL; - int status; - - if (error_pending ()) return; - - if (outside_dir (arg)) - return; - - if (dir_name == NULL) - goto error; - - new = (struct notify_note *) xmalloc (sizeof (struct notify_note)); - if (new == NULL) - { - pending_error = ENOMEM; - return; - } - new->dir = xmalloc (strlen (dir_name) + 1); - new->filename = xmalloc (strlen (arg) + 1); - if (new->dir == NULL || new->filename == NULL) - { - pending_error = ENOMEM; - if (new->dir != NULL) - free (new->dir); - free (new); - return; - } - strcpy (new->dir, dir_name); - strcpy (new->filename, arg); - - status = buf_read_line (buf_from_net, &data, (int *) NULL); - if (status != 0) - { - if (status == -2) - pending_error = ENOMEM; - else - { - pending_error_text = xmalloc (80 + strlen (arg)); - if (pending_error_text == NULL) - pending_error = ENOMEM; - else - { - if (status == -1) - sprintf (pending_error_text, - "E end of file reading notification for %s", arg); - else - { - sprintf (pending_error_text, - "E error reading notification for %s", arg); - pending_error = status; - } - } - } - free (new->filename); - free (new->dir); - free (new); - } - else - { - char *cp; - - if (!data[0]) - goto error; - - if (strchr (data, '+')) - goto error; - - new->type = data; - if (data[1] != '\t') - goto error; - data[1] = '\0'; - cp = data + 2; - new->val = cp; - cp = strchr (cp, '\t'); - if (cp == NULL) - goto error; - *cp++ = '+'; - cp = strchr (cp, '\t'); - if (cp == NULL) - goto error; - *cp++ = '+'; - cp = strchr (cp, '\t'); - if (cp == NULL) - goto error; - *cp++ = '\0'; - new->watches = cp; - /* If there is another tab, ignore everything after it, - for future expansion. */ - cp = strchr (cp, '\t'); - if (cp != NULL) - { - *cp = '\0'; - } - - new->next = NULL; - - if (last_node == NULL) - { - notify_list = new; - } - else - last_node->next = new; - last_node = new; - } - return; - error: - pending_error = 0; - if (alloc_pending (80)) - strcpy (pending_error_text, - "E Protocol error; misformed Notify request"); - if (data != NULL) - free (data); - if (new != NULL) - { - free (new->filename); - free (new->dir); - free (new); - } - return; -} - -/* Process all the Notify requests that we have stored up. Returns 0 - if successful, if not prints error message (via error()) and - returns negative value. */ -static int -server_notify () -{ - struct notify_note *p; - char *repos; - - while (notify_list != NULL) - { - if ( CVS_CHDIR (notify_list->dir) < 0) - { - error (0, errno, "cannot change to %s", notify_list->dir); - return -1; - } - repos = Name_Repository (NULL, NULL); - - lock_dir_for_write (repos); - - fileattr_startdir (repos); - - notify_do (*notify_list->type, notify_list->filename, getcaller(), - notify_list->val, notify_list->watches, repos); - - buf_output0 (buf_to_net, "Notified "); - { - char *dir = notify_list->dir + strlen (server_temp_dir) + 1; - if (dir[0] == '\0') - buf_append_char (buf_to_net, '.'); - else - buf_output0 (buf_to_net, dir); - buf_append_char (buf_to_net, '/'); - buf_append_char (buf_to_net, '\n'); - } - buf_output0 (buf_to_net, repos); - buf_append_char (buf_to_net, '/'); - buf_output0 (buf_to_net, notify_list->filename); - buf_append_char (buf_to_net, '\n'); - free (repos); - - p = notify_list->next; - free (notify_list->filename); - free (notify_list->dir); - free (notify_list->type); - free (notify_list); - notify_list = p; - - fileattr_write (); - fileattr_free (); - - Lock_Cleanup (); - } - - last_node = NULL; - - /* The code used to call fflush (stdout) here, but that is no - longer necessary. The data is now buffered in buf_to_net, - which will be flushed by the caller, do_cvs_command. */ - - return 0; -} - -static int argument_count; -static char **argument_vector; -static int argument_vector_size; - -static void -serve_argument (arg) - char *arg; -{ - char *p; - - if (error_pending()) return; - - if (argument_count >= 10000) - { - if (alloc_pending (80)) - sprintf (pending_error_text, - "E Protocol error: too many arguments"); - return; - } - - if (argument_vector_size <= argument_count) - { - argument_vector_size *= 2; - argument_vector = - (char **) xrealloc ((char *)argument_vector, - argument_vector_size * sizeof (char *)); - if (argument_vector == NULL) - { - pending_error = ENOMEM; - return; - } - } - p = xmalloc (strlen (arg) + 1); - if (p == NULL) - { - pending_error = ENOMEM; - return; - } - strcpy (p, arg); - argument_vector[argument_count++] = p; -} - -static void -serve_argumentx (arg) - char *arg; -{ - char *p; - - if (error_pending()) return; - - if (argument_count <= 1) - { - if (alloc_pending (80)) - sprintf (pending_error_text, - "E Protocol error: called argumentx without prior call to argument"); - return; - } - - p = argument_vector[argument_count - 1]; - p = xrealloc (p, strlen (p) + 1 + strlen (arg) + 1); - if (p == NULL) - { - pending_error = ENOMEM; - return; - } - strcat (p, "\n"); - strcat (p, arg); - argument_vector[argument_count - 1] = p; -} - -static void -serve_global_option (arg) - char *arg; -{ - if (arg[0] != '-' || arg[1] == '\0' || arg[2] != '\0') - { - error_return: - if (alloc_pending (strlen (arg) + 80)) - sprintf (pending_error_text, - "E Protocol error: bad global option %s", - arg); - return; - } - switch (arg[1]) - { - case 'l': - error(0, 0, "WARNING: global `-l' option ignored."); - break; - case 'n': - noexec = 1; - logoff = 1; - break; - case 'q': - quiet = 1; - break; - case 'r': - cvswrite = 0; - break; - case 'Q': - really_quiet = 1; - break; - case 't': - trace = 1; - break; - default: - goto error_return; - } -} - -static void -serve_set (arg) - char *arg; -{ - /* FIXME: This sends errors immediately (I think); they should be - put into pending_error. */ - variable_set (arg); -} - -#ifdef ENCRYPTION - -#ifdef HAVE_KERBEROS - -static void -serve_kerberos_encrypt (arg) - char *arg; -{ - /* All future communication with the client will be encrypted. */ - - buf_to_net = krb_encrypt_buffer_initialize (buf_to_net, 0, sched, - kblock, - buf_to_net->memory_error); - buf_from_net = krb_encrypt_buffer_initialize (buf_from_net, 1, sched, - kblock, - buf_from_net->memory_error); -} - -#endif /* HAVE_KERBEROS */ - -#ifdef HAVE_GSSAPI - -static void -serve_gssapi_encrypt (arg) - char *arg; -{ - if (cvs_gssapi_wrapping) - { - /* We're already using a gssapi_wrap buffer for stream - authentication. Flush everything we've output so far, and - turn on encryption for future data. On the input side, we - should only have unwrapped as far as the Gssapi-encrypt - command, so future unwrapping will become encrypted. */ - buf_flush (buf_to_net, 1); - cvs_gssapi_encrypt = 1; - return; - } - - /* All future communication with the client will be encrypted. */ - - cvs_gssapi_encrypt = 1; - - buf_to_net = cvs_gssapi_wrap_buffer_initialize (buf_to_net, 0, - gcontext, - buf_to_net->memory_error); - buf_from_net = cvs_gssapi_wrap_buffer_initialize (buf_from_net, 1, - gcontext, - buf_from_net->memory_error); - - cvs_gssapi_wrapping = 1; -} - -#endif /* HAVE_GSSAPI */ - -#endif /* ENCRYPTION */ - -#ifdef HAVE_GSSAPI - -static void -serve_gssapi_authenticate (arg) - char *arg; -{ - if (cvs_gssapi_wrapping) - { - /* We're already using a gssapi_wrap buffer for encryption. - That includes authentication, so we don't have to do - anything further. */ - return; - } - - buf_to_net = cvs_gssapi_wrap_buffer_initialize (buf_to_net, 0, - gcontext, - buf_to_net->memory_error); - buf_from_net = cvs_gssapi_wrap_buffer_initialize (buf_from_net, 1, - gcontext, - buf_from_net->memory_error); - - cvs_gssapi_wrapping = 1; -} - -#endif /* HAVE_GSSAPI */ - - - -#ifdef SERVER_FLOWCONTROL -/* The maximum we'll queue to the remote client before blocking. */ -# ifndef SERVER_HI_WATER -# define SERVER_HI_WATER (2 * 1024 * 1024) -# endif /* SERVER_HI_WATER */ -/* When the buffer drops to this, we restart the child */ -# ifndef SERVER_LO_WATER -# define SERVER_LO_WATER (1 * 1024 * 1024) -# endif /* SERVER_LO_WATER */ -#endif /* SERVER_FLOWCONTROL */ - - - -static void serve_questionable PROTO((char *)); - -static void -serve_questionable (arg) - char *arg; -{ - static int initted; - - if (!initted) - { - /* Pick up ignores from CVSROOTADM_IGNORE, $HOME/.cvsignore on server, - and CVSIGNORE on server. */ - ign_setup (); - initted = 1; - } - - if (dir_name == NULL) - { - buf_output0 (buf_to_net, "E Protocol error: 'Directory' missing"); - return; - } - - if (outside_dir (arg)) - return; - - if (!ign_name (arg)) - { - char *update_dir; - - buf_output (buf_to_net, "M ? ", 4); - update_dir = dir_name + strlen (server_temp_dir) + 1; - if (!(update_dir[0] == '.' && update_dir[1] == '\0')) - { - buf_output0 (buf_to_net, update_dir); - buf_output (buf_to_net, "/", 1); - } - buf_output0 (buf_to_net, arg); - buf_output (buf_to_net, "\n", 1); - } -} - - - -static struct buffer *protocol; - -/* This is the output which we are saving up to send to the server, in the - child process. We will push it through, via the `protocol' buffer, when - we have a complete line. */ -static struct buffer *saved_output; -/* Likewise, but stuff which will go to stderr. */ -static struct buffer *saved_outerr; - -static void -protocol_memory_error (buf) - struct buffer *buf; -{ - error (1, ENOMEM, "Virtual memory exhausted"); -} - -/* - * Process IDs of the subprocess, or negative if that subprocess - * does not exist. - */ -static pid_t command_pid; - -static void -outbuf_memory_error (buf) - struct buffer *buf; -{ - static const char msg[] = "E Fatal server error\n\ -error ENOMEM Virtual memory exhausted.\n"; - if (command_pid > 0) - kill (command_pid, SIGTERM); - - /* - * We have arranged things so that printing this now either will - * be legal, or the "E fatal error" line will get glommed onto the - * end of an existing "E" or "M" response. - */ - - /* If this gives an error, not much we could do. syslog() it? */ - write (STDOUT_FILENO, msg, sizeof (msg) - 1); -#ifdef HAVE_SYSLOG_H - syslog (LOG_DAEMON | LOG_ERR, "virtual memory exhausted"); -#endif - error_exit (); -} - -static void -input_memory_error (buf) - struct buffer *buf; -{ - outbuf_memory_error (buf); -} - - - -/* If command is legal, return 1. - * Else if command is illegal and croak_on_illegal is set, then die. - * Else just return 0 to indicate that command is illegal. - */ -static int -check_command_legal_p (cmd_name) - char *cmd_name; -{ - /* Right now, only pserver notices illegal commands -- namely, - * write attempts by a read-only user. Therefore, if CVS_Username - * is not set, this just returns 1, because CVS_Username unset - * means pserver is not active. - */ -#ifdef AUTH_SERVER_SUPPORT - if (CVS_Username == NULL) - return 1; - - if (lookup_command_attribute (cmd_name) & CVS_CMD_MODIFIES_REPOSITORY) - { - /* This command has the potential to modify the repository, so - * we check if the user have permission to do that. - * - * (Only relevant for remote users -- local users can do - * whatever normal Unix file permissions allow them to do.) - * - * The decision method: - * - * If $CVSROOT/CVSADMROOT_READERS exists and user is listed - * in it, then read-only access for user. - * - * Or if $CVSROOT/CVSADMROOT_WRITERS exists and user NOT - * listed in it, then also read-only access for user. - * - * Else read-write access for user. - */ - - char *linebuf = NULL; - int num_red = 0; - size_t linebuf_len = 0; - char *fname; - size_t flen; - FILE *fp; - int found_it = 0; - - /* else */ - flen = strlen (current_parsed_root->directory) - + strlen (CVSROOTADM) - + strlen (CVSROOTADM_READERS) - + 3; - - fname = xmalloc (flen); - (void) sprintf (fname, "%s/%s/%s", current_parsed_root->directory, - CVSROOTADM, CVSROOTADM_READERS); - - fp = fopen (fname, "r"); - - if (fp == NULL) - { - if (!existence_error (errno)) - { - /* Need to deny access, so that attackers can't fool - us with some sort of denial of service attack. */ - error (0, errno, "cannot open %s", fname); - free (fname); - return 0; - } - } - else /* successfully opened readers file */ - { - while ((num_red = getline (&linebuf, &linebuf_len, fp)) >= 0) - { - /* Hmmm, is it worth importing my own readline - library into CVS? It takes care of chopping - leading and trailing whitespace, "#" comments, and - newlines automatically when so requested. Would - save some code here... -kff */ - - /* Chop newline by hand, for strcmp()'s sake. */ - if (num_red > 0 && linebuf[num_red - 1] == '\n') - linebuf[num_red - 1] = '\0'; - - if (strcmp (linebuf, CVS_Username) == 0) - goto handle_illegal; - } - if (num_red < 0 && !feof (fp)) - error (0, errno, "cannot read %s", fname); - - /* If not listed specifically as a reader, then this user - has write access by default unless writers are also - specified in a file . */ - if (fclose (fp) < 0) - error (0, errno, "cannot close %s", fname); - } - free (fname); - - /* Now check the writers file. */ - - flen = strlen (current_parsed_root->directory) - + strlen (CVSROOTADM) - + strlen (CVSROOTADM_WRITERS) - + 3; - - fname = xmalloc (flen); - (void) sprintf (fname, "%s/%s/%s", current_parsed_root->directory, - CVSROOTADM, CVSROOTADM_WRITERS); - - fp = fopen (fname, "r"); - - if (fp == NULL) - { - if (linebuf) - free (linebuf); - if (existence_error (errno)) - { - /* Writers file does not exist, so everyone is a writer, - by default. */ - free (fname); - return 1; - } - else - { - /* Need to deny access, so that attackers can't fool - us with some sort of denial of service attack. */ - error (0, errno, "cannot read %s", fname); - free (fname); - return 0; - } - } - - found_it = 0; - while ((num_red = getline (&linebuf, &linebuf_len, fp)) >= 0) - { - /* Chop newline by hand, for strcmp()'s sake. */ - if (num_red > 0 && linebuf[num_red - 1] == '\n') - linebuf[num_red - 1] = '\0'; - - if (strcmp (linebuf, CVS_Username) == 0) - { - found_it = 1; - break; - } - } - if (num_red < 0 && !feof (fp)) - error (0, errno, "cannot read %s", fname); - - if (found_it) - { - if (fclose (fp) < 0) - error (0, errno, "cannot close %s", fname); - if (linebuf) - free (linebuf); - free (fname); - return 1; - } - else /* writers file exists, but this user not listed in it */ - { - handle_illegal: - if (fclose (fp) < 0) - error (0, errno, "cannot close %s", fname); - if (linebuf) - free (linebuf); - free (fname); - return 0; - } - } -#endif /* AUTH_SERVER_SUPPORT */ - - /* If ever reach end of this function, command must be legal. */ - return 1; -} - - - -/* Execute COMMAND in a subprocess with the approriate funky things done. */ - -static struct fd_set_wrapper { fd_set fds; } command_fds_to_drain; -#ifdef SUNOS_KLUDGE -static int max_command_fd; -#endif - -#ifdef SERVER_FLOWCONTROL -static int flowcontrol_pipe[2]; -#endif /* SERVER_FLOWCONTROL */ - - - -/* - * Set buffer FD to non-blocking I/O. Returns 0 for success or errno - * code. - */ -int -set_nonblock_fd (fd) - int fd; -{ - int flags; - - flags = fcntl (fd, F_GETFL, 0); - if (flags < 0) - return errno; - if (fcntl (fd, F_SETFL, flags | O_NONBLOCK) < 0) - return errno; - return 0; -} - - - -/* - * Set buffer FD to blocking I/O. Returns 0 for success or errno code. - */ -int -set_block_fd (fd) - int fd; -{ - int flags; - - flags = fcntl (fd, F_GETFL, 0); - if (flags < 0) - return errno; - if (fcntl (fd, F_SETFL, flags & ~O_NONBLOCK) < 0) - return errno; - return 0; -} - - - -static void -do_cvs_command (cmd_name, command) - char *cmd_name; - int (*command) PROTO((int argc, char **argv)); -{ - /* - * The following file descriptors are set to -1 if that file is not - * currently open. - */ - - /* Data on these pipes is a series of '\n'-terminated lines. */ - int stdout_pipe[2]; - int stderr_pipe[2]; - - /* - * Data on this pipe is a series of counted (see buf_send_counted) - * packets. Each packet must be processed atomically (i.e. not - * interleaved with data from stdout_pipe or stderr_pipe). - */ - int protocol_pipe[2]; - - int dev_null_fd = -1; - - int errs = 0; - - command_pid = -1; - stdout_pipe[0] = -1; - stdout_pipe[1] = -1; - stderr_pipe[0] = -1; - stderr_pipe[1] = -1; - protocol_pipe[0] = -1; - protocol_pipe[1] = -1; - - server_write_entries (); - - if (print_pending_error ()) - goto free_args_and_return; - - /* Global `cvs_cmd_name' is probably "server" right now -- only - serve_export() sets it to anything else. So we will use local - parameter `cmd_name' to determine if this command is legal for - this user. */ - if (!check_command_legal_p (cmd_name)) - { - buf_output0 (buf_to_net, "E "); - buf_output0 (buf_to_net, program_name); - buf_output0 (buf_to_net, " [server aborted]: \""); - buf_output0 (buf_to_net, cmd_name); - buf_output0 (buf_to_net, "\" requires write access to the repository\n\ -error \n"); - goto free_args_and_return; - } - cvs_cmd_name = cmd_name; - - (void) server_notify (); - - /* - * We use a child process which actually does the operation. This - * is so we can intercept its standard output. Even if all of CVS - * were written to go to some special routine instead of writing - * to stdout or stderr, we would still need to do the same thing - * for the RCS commands. - */ - - if (pipe (stdout_pipe) < 0) - { - buf_output0 (buf_to_net, "E pipe failed\n"); - print_error (errno); - goto error_exit; - } - if (pipe (stderr_pipe) < 0) - { - buf_output0 (buf_to_net, "E pipe failed\n"); - print_error (errno); - goto error_exit; - } - if (pipe (protocol_pipe) < 0) - { - buf_output0 (buf_to_net, "E pipe failed\n"); - print_error (errno); - goto error_exit; - } -#ifdef SERVER_FLOWCONTROL - if (pipe (flowcontrol_pipe) < 0) - { - buf_output0 (buf_to_net, "E pipe failed\n"); - print_error (errno); - goto error_exit; - } - set_nonblock_fd (flowcontrol_pipe[0]); - set_nonblock_fd (flowcontrol_pipe[1]); -#endif /* SERVER_FLOWCONTROL */ - - dev_null_fd = CVS_OPEN (DEVNULL, O_RDONLY); - if (dev_null_fd < 0) - { - buf_output0 (buf_to_net, "E open /dev/null failed\n"); - print_error (errno); - goto error_exit; - } - - /* We shouldn't have any partial lines from cvs_output and - cvs_outerr, but we handle them here in case there is a bug. */ - /* FIXME: appending a newline, rather than using "MT" as we - do in the child process, is probably not really a very good - way to "handle" them. */ - if (! buf_empty_p (saved_output)) - { - buf_append_char (saved_output, '\n'); - buf_copy_lines (buf_to_net, saved_output, 'M'); - } - if (! buf_empty_p (saved_outerr)) - { - buf_append_char (saved_outerr, '\n'); - buf_copy_lines (buf_to_net, saved_outerr, 'E'); - } - - /* Flush out any pending data. */ - buf_flush (buf_to_net, 1); - - /* Don't use vfork; we're not going to exec(). */ - command_pid = fork (); - if (command_pid < 0) - { - buf_output0 (buf_to_net, "E fork failed\n"); - print_error (errno); - goto error_exit; - } - if (command_pid == 0) - { - int exitstatus; - - /* Since we're in the child, and the parent is going to take - care of packaging up our error messages, we can clear this - flag. */ - error_use_protocol = 0; - - protocol = fd_buffer_initialize (protocol_pipe[1], 0, - protocol_memory_error); - - /* At this point we should no longer be using buf_to_net and - buf_from_net. Instead, everything should go through - protocol. */ - if (buf_to_net != NULL) - { - buf_free (buf_to_net); - buf_to_net = NULL; - } - if (buf_from_net != NULL) - { - buf_free (buf_from_net); - buf_from_net = NULL; - } - - /* These were originally set up to use outbuf_memory_error. - Since we're now in the child, we should use the simpler - protocol_memory_error function. */ - saved_output->memory_error = protocol_memory_error; - saved_outerr->memory_error = protocol_memory_error; - - if (dup2 (dev_null_fd, STDIN_FILENO) < 0) - error (1, errno, "can't set up pipes"); - if (dup2 (stdout_pipe[1], STDOUT_FILENO) < 0) - error (1, errno, "can't set up pipes"); - if (dup2 (stderr_pipe[1], STDERR_FILENO) < 0) - error (1, errno, "can't set up pipes"); - close (dev_null_fd); - close (stdout_pipe[0]); - close (stdout_pipe[1]); - close (stderr_pipe[0]); - close (stderr_pipe[1]); - close (protocol_pipe[0]); - close_on_exec (protocol_pipe[1]); -#ifdef SERVER_FLOWCONTROL - close_on_exec (flowcontrol_pipe[0]); - close (flowcontrol_pipe[1]); -#endif /* SERVER_FLOWCONTROL */ - - /* - * Set this in .bashrc if you want to give yourself time to attach - * to the subprocess with a debugger. - */ - if (getenv ("CVS_SERVER_SLEEP")) - { - int secs = atoi (getenv ("CVS_SERVER_SLEEP")); - sleep (secs); - } - - exitstatus = (*command) (argument_count, argument_vector); - - /* Output any partial lines. If the client doesn't support - "MT", we go ahead and just tack on a newline since the - protocol doesn't support anything better. */ - if (! buf_empty_p (saved_output)) - { - buf_output0 (protocol, supported_response ("MT") ? "MT text " : "M "); - buf_append_buffer (protocol, saved_output); - buf_output (protocol, "\n", 1); - buf_send_counted (protocol); - } - /* For now we just discard partial lines on stderr. I suspect - that CVS can't write such lines unless there is a bug. */ - - buf_free (protocol); - - /* Close the pipes explicitly in order to send an EOF to the parent, - * then wait for the parent to close the flow control pipe. This - * avoids a race condition where a child which dumped more than the - * high water mark into the pipes could complete its job and exit, - * leaving the parent process to attempt to write a stop byte to the - * closed flow control pipe, which earned the parent a SIGPIPE, which - * it normally only expects on the network pipe and that causes it to - * exit with an error message, rather than the SIGCHILD that it knows - * how to handle correctly. - */ - /* Let exit() close STDIN - it's from /dev/null anyhow. */ - fclose (stderr); - fclose (stdout); - close (protocol_pipe[1]); -#ifdef SERVER_FLOWCONTROL - { - char junk; - set_block_fd (flowcontrol_pipe[0]); - while (read (flowcontrol_pipe[0], &junk, 1) > 0); - } - /* FIXME: No point in printing an error message with error(), - * as STDERR is already closed, but perhaps this could be syslogged? - */ -#endif - - rcs_cleanup (); - Lock_Cleanup (); - /* Don't call server_cleanup - the parent will handle that. */ -#ifdef SYSTEM_CLEANUP - /* Hook for OS-specific behavior, for example socket subsystems on - NT and OS2 or dealing with windows and arguments on Mac. */ - SYSTEM_CLEANUP (); -#endif - exit (exitstatus); - } - - /* OK, sit around getting all the input from the child. */ - { - struct buffer *stdoutbuf = NULL; - struct buffer *stderrbuf = NULL; - struct buffer *protocol_inbuf = NULL; - int err_exit = 0; - /* Number of file descriptors to check in select (). */ - int num_to_check; - int count_needed = 1; -#ifdef SERVER_FLOWCONTROL - int have_flowcontrolled = 0; -#endif /* SERVER_FLOWCONTROL */ - - FD_ZERO (&command_fds_to_drain.fds); - num_to_check = stdout_pipe[0]; - FD_SET (stdout_pipe[0], &command_fds_to_drain.fds); - if (stderr_pipe[0] > num_to_check) - num_to_check = stderr_pipe[0]; - FD_SET (stderr_pipe[0], &command_fds_to_drain.fds); - if (protocol_pipe[0] > num_to_check) - num_to_check = protocol_pipe[0]; - FD_SET (protocol_pipe[0], &command_fds_to_drain.fds); - if (STDOUT_FILENO > num_to_check) - num_to_check = STDOUT_FILENO; -#ifdef SUNOS_KLUDGE - max_command_fd = num_to_check; -#endif - /* - * File descriptors are numbered from 0, so num_to_check needs to - * be one larger than the largest descriptor. - */ - ++num_to_check; - if (num_to_check > FD_SETSIZE) - { - buf_output0 (buf_to_net, - "E internal error: FD_SETSIZE not big enough.\n\ -error \n"); - goto error_exit; - } - - stdoutbuf = fd_buffer_initialize (stdout_pipe[0], 1, - input_memory_error); - - stderrbuf = fd_buffer_initialize (stderr_pipe[0], 1, - input_memory_error); - - protocol_inbuf = fd_buffer_initialize (protocol_pipe[0], 1, - input_memory_error); - - set_nonblock (buf_to_net); - set_nonblock (stdoutbuf); - set_nonblock (stderrbuf); - set_nonblock (protocol_inbuf); - - if (close (stdout_pipe[1]) < 0) - { - buf_output0 (buf_to_net, "E close failed\n"); - print_error (errno); - err_exit = 1; - goto child_finish; - } - stdout_pipe[1] = -1; - - if (close (stderr_pipe[1]) < 0) - { - buf_output0 (buf_to_net, "E close failed\n"); - print_error (errno); - err_exit = 1; - goto child_finish; - } - stderr_pipe[1] = -1; - - if (close (protocol_pipe[1]) < 0) - { - buf_output0 (buf_to_net, "E close failed\n"); - print_error (errno); - err_exit = 1; - goto child_finish; - } - protocol_pipe[1] = -1; - -#ifdef SERVER_FLOWCONTROL - if (close (flowcontrol_pipe[0]) < 0) - { - buf_output0 (buf_to_net, "E close failed\n"); - print_error (errno); - err_exit = 1; - goto child_finish; - } - flowcontrol_pipe[0] = -1; -#endif /* SERVER_FLOWCONTROL */ - - if (close (dev_null_fd) < 0) - { - buf_output0 (buf_to_net, "E close failed\n"); - print_error (errno); - dev_null_fd = -1; /* Do not try to close it again. */ - err_exit = 1; - goto child_finish; - } - dev_null_fd = -1; - - while (stdout_pipe[0] >= 0 - || stderr_pipe[0] >= 0 - || protocol_pipe[0] >= 0 - || count_needed <= 0) - { - fd_set readfds; - fd_set writefds; - int numfds; - struct timeval *timeout_ptr; - struct timeval timeout; -#ifdef SERVER_FLOWCONTROL - int bufmemsize; - - /* - * See if we are swamping the remote client and filling our VM. - * Tell child to hold off if we do. - */ - bufmemsize = buf_count_mem (buf_to_net); - if (!have_flowcontrolled && (bufmemsize > SERVER_HI_WATER)) - { - if (write(flowcontrol_pipe[1], "S", 1) == 1) - have_flowcontrolled = 1; - } - else if (have_flowcontrolled && (bufmemsize < SERVER_LO_WATER)) - { - if (write(flowcontrol_pipe[1], "G", 1) == 1) - have_flowcontrolled = 0; - } -#endif /* SERVER_FLOWCONTROL */ - - FD_ZERO (&readfds); - FD_ZERO (&writefds); - - if (count_needed <= 0) - { - /* there is data pending which was read from the protocol pipe - * so don't block if we don't find any data - */ - timeout.tv_sec = 0; - timeout.tv_usec = 0; - timeout_ptr = &timeout; - } - else - { - /* block indefinately */ - timeout_ptr = NULL; - } - - if (! buf_empty_p (buf_to_net)) - FD_SET (STDOUT_FILENO, &writefds); - - if (stdout_pipe[0] >= 0) - { - FD_SET (stdout_pipe[0], &readfds); - } - if (stderr_pipe[0] >= 0) - { - FD_SET (stderr_pipe[0], &readfds); - } - if (protocol_pipe[0] >= 0) - { - FD_SET (protocol_pipe[0], &readfds); - } - - /* This process of selecting on the three pipes means that - we might not get output in the same order in which it - was written, thus producing the well-known - "out-of-order" bug. If the child process uses - cvs_output and cvs_outerr, it will send everything on - the protocol_pipe and avoid this problem, so the - solution is to use cvs_output and cvs_outerr in the - child process. */ - do { - /* This used to select on exceptions too, but as far - as I know there was never any reason to do that and - SCO doesn't let you select on exceptions on pipes. */ - numfds = select (num_to_check, &readfds, &writefds, - (fd_set *)0, timeout_ptr); - if (numfds < 0 - && errno != EINTR) - { - buf_output0 (buf_to_net, "E select failed\n"); - print_error (errno); - err_exit = 1; - goto child_finish; - } - } while (numfds < 0); - - if (numfds == 0) - { - FD_ZERO (&readfds); - FD_ZERO (&writefds); - } - - if (FD_ISSET (STDOUT_FILENO, &writefds)) - { - /* What should we do with errors? syslog() them? */ - buf_send_output (buf_to_net); - } - - if (protocol_pipe[0] >= 0 - && (FD_ISSET (protocol_pipe[0], &readfds))) - { - int status; - int count_read; - - status = buf_input_data (protocol_inbuf, &count_read); - - if (status == -1) - { - close (protocol_pipe[0]); - protocol_pipe[0] = -1; - } - else if (status > 0) - { - buf_output0 (buf_to_net, "E buf_input_data failed\n"); - print_error (status); - err_exit = 1; - goto child_finish; - } - - /* - * We only call buf_copy_counted if we have read - * enough bytes to make it worthwhile. This saves us - * from continually recounting the amount of data we - * have. - */ - count_needed -= count_read; - } - /* this is still part of the protocol pipe procedure, but it is - * outside the above conditional so that unprocessed data can be - * left in the buffer and stderr/stdout can be read when a flush - * signal is received and control can return here without passing - * through the select code and maybe blocking - */ - while (count_needed <= 0) - { - int special = 0; - - count_needed = buf_copy_counted (buf_to_net, - protocol_inbuf, - &special); - - /* What should we do with errors? syslog() them? */ - buf_send_output (buf_to_net); - - /* If SPECIAL got set to <0, it means that the child - * wants us to flush the pipe & maybe stderr or stdout. - * - * After that we break to read stderr & stdout again before - * going back to the protocol pipe - * - * Upon breaking, count_needed = 0, so the next pass will only - * perform a non-blocking select before returning here to finish - * processing data we already read from the protocol buffer - */ - if (special == -1) - { - cvs_flushout(); - break; - } - if (special == -2) - { - /* If the client supports the 'F' command, we send it. */ - if (supported_response ("F")) - { - buf_append_char (buf_to_net, 'F'); - buf_append_char (buf_to_net, '\n'); - } - cvs_flusherr (); - break; - } - } - - if (stdout_pipe[0] >= 0 - && (FD_ISSET (stdout_pipe[0], &readfds))) - { - int status; - - status = buf_input_data (stdoutbuf, (int *) NULL); - - buf_copy_lines (buf_to_net, stdoutbuf, 'M'); - - if (status == -1) - { - close (stdout_pipe[0]); - stdout_pipe[0] = -1; - } - else if (status > 0) - { - buf_output0 (buf_to_net, "E buf_input_data failed\n"); - print_error (status); - err_exit = 1; - goto child_finish; - } - - /* What should we do with errors? syslog() them? */ - buf_send_output (buf_to_net); - } - - if (stderr_pipe[0] >= 0 - && (FD_ISSET (stderr_pipe[0], &readfds))) - { - int status; - - status = buf_input_data (stderrbuf, (int *) NULL); - - buf_copy_lines (buf_to_net, stderrbuf, 'E'); - - if (status == -1) - { - close (stderr_pipe[0]); - stderr_pipe[0] = -1; - } - else if (status > 0) - { - buf_output0 (buf_to_net, "E buf_input_data failed\n"); - print_error (status); - err_exit = 1; - goto child_finish; - } - - /* What should we do with errors? syslog() them? */ - buf_send_output (buf_to_net); - } - } - - /* - * OK, we've gotten EOF on all the pipes. If there is - * anything left on stdoutbuf or stderrbuf (this could only - * happen if there was no trailing newline), send it over. - */ - if (! buf_empty_p (stdoutbuf)) - { - buf_append_char (stdoutbuf, '\n'); - buf_copy_lines (buf_to_net, stdoutbuf, 'M'); - } - if (! buf_empty_p (stderrbuf)) - { - buf_append_char (stderrbuf, '\n'); - buf_copy_lines (buf_to_net, stderrbuf, 'E'); - } - if (! buf_empty_p (protocol_inbuf)) - buf_output0 (buf_to_net, - "E Protocol error: uncounted data discarded\n"); - -#ifdef SERVER_FLOWCONTROL - close (flowcontrol_pipe[1]); - flowcontrol_pipe[1] = -1; -#endif /* SERVER_FLOWCONTROL */ - - errs = 0; - - while (command_pid > 0) - { - int status; - pid_t waited_pid; - waited_pid = waitpid (command_pid, &status, 0); - if (waited_pid < 0) - { - /* - * Intentionally ignoring EINTR. Other errors - * "can't happen". - */ - continue; - } - - if (WIFEXITED (status)) - errs += WEXITSTATUS (status); - else - { - int sig = WTERMSIG (status); - char buf[50]; - /* - * This is really evil, because signals might be numbered - * differently on the two systems. We should be using - * signal names (either of the "Terminated" or the "SIGTERM" - * variety). But cvs doesn't currently use libiberty...we - * could roll our own.... FIXME. - */ - buf_output0 (buf_to_net, "E Terminated with fatal signal "); - sprintf (buf, "%d\n", sig); - buf_output0 (buf_to_net, buf); - - /* Test for a core dump. */ - if (WCOREDUMP (status)) - { - buf_output0 (buf_to_net, "E Core dumped; preserving "); - buf_output0 (buf_to_net, orig_server_temp_dir); - buf_output0 (buf_to_net, " on server.\n\ -E CVS locks may need cleaning up.\n"); - dont_delete_temp = 1; - } - ++errs; - } - if (waited_pid == command_pid) - command_pid = -1; - } - - child_finish: - /* - * OK, we've waited for the child. By now all CVS locks are free - * and it's OK to block on the network. - */ - set_block (buf_to_net); - buf_flush (buf_to_net, 1); - if (protocol_inbuf) - { - buf_shutdown (protocol_inbuf); - buf_free (protocol_inbuf); - protocol_inbuf = NULL; - } - if (stderrbuf) - { - buf_shutdown (stderrbuf); - buf_free (stderrbuf); - stderrbuf = NULL; - } - if (stdoutbuf) - { - buf_shutdown (stdoutbuf); - buf_free (stdoutbuf); - stdoutbuf = NULL; - } - if (err_exit) - goto error_exit; - } - - if (errs) - /* We will have printed an error message already. */ - buf_output0 (buf_to_net, "error \n"); - else - buf_output0 (buf_to_net, "ok\n"); - goto free_args_and_return; - - error_exit: - if (command_pid > 0) - kill (command_pid, SIGTERM); - - while (command_pid > 0) - { - pid_t waited_pid; - waited_pid = waitpid (command_pid, (int *) 0, 0); - if (waited_pid < 0 && errno == EINTR) - continue; - if (waited_pid == command_pid) - command_pid = -1; - } - - if (dev_null_fd >= 0) - close (dev_null_fd); - close (protocol_pipe[0]); - close (protocol_pipe[1]); - close (stderr_pipe[0]); - close (stderr_pipe[1]); - close (stdout_pipe[0]); - close (stdout_pipe[1]); -#ifdef SERVER_FLOWCONTROL - close (flowcontrol_pipe[0]); - close (flowcontrol_pipe[1]); -#endif /* SERVER_FLOWCONTROL */ - - free_args_and_return: - /* Now free the arguments. */ - { - /* argument_vector[0] is a dummy argument, we don't mess with it. */ - char **cp; - for (cp = argument_vector + 1; - cp < argument_vector + argument_count; - ++cp) - free (*cp); - - argument_count = 1; - } - - /* Flush out any data not yet sent. */ - set_block (buf_to_net); - buf_flush (buf_to_net, 1); - - return; -} - -#ifdef SERVER_FLOWCONTROL -/* - * Called by the child at convenient points in the server's execution for - * the server child to block.. ie: when it has no locks active. - */ -void -server_pause_check() -{ - int paused = 0; - char buf[1]; - - while (read (flowcontrol_pipe[0], buf, 1) == 1) - { - if (*buf == 'S') /* Stop */ - paused = 1; - else if (*buf == 'G') /* Go */ - paused = 0; - else - return; /* ??? */ - } - while (paused) { - int numfds, numtocheck; - fd_set fds; - - FD_ZERO (&fds); - FD_SET (flowcontrol_pipe[0], &fds); - numtocheck = flowcontrol_pipe[0] + 1; - - do { - numfds = select (numtocheck, &fds, (fd_set *)0, - (fd_set *)0, (struct timeval *)NULL); - if (numfds < 0 - && errno != EINTR) - { - buf_output0 (buf_to_net, "E select failed\n"); - print_error (errno); - return; - } - } while (numfds < 0); - - if (FD_ISSET (flowcontrol_pipe[0], &fds)) - { - int got; - - while ((got = read (flowcontrol_pipe[0], buf, 1)) == 1) - { - if (*buf == 'S') /* Stop */ - paused = 1; - else if (*buf == 'G') /* Go */ - paused = 0; - else - return; /* ??? */ - } - - /* This assumes that we are using BSD or POSIX nonblocking - I/O. System V nonblocking I/O returns zero if there is - nothing to read. */ - if (got == 0) - error (1, 0, "flow control EOF"); - if (got < 0 && ! blocking_error (errno)) - { - error (1, errno, "flow control read failed"); - } - } - } -} -#endif /* SERVER_FLOWCONTROL */ - -/* This variable commented in server.h. */ -char *server_dir = NULL; - - - -static void output_dir PROTO((const char *, const char *)); - -static void -output_dir (update_dir, repository) - const char *update_dir; - const char *repository; -{ - if (server_dir != NULL) - { - buf_output0 (protocol, server_dir); - buf_output0 (protocol, "/"); - } - if (update_dir[0] == '\0') - buf_output0 (protocol, "."); - else - buf_output0 (protocol, update_dir); - buf_output0 (protocol, "/\n"); - buf_output0 (protocol, repository); - buf_output0 (protocol, "/"); -} - - - -/* - * Entries line that we are squirreling away to send to the client when - * we are ready. - */ -static char *entries_line; - -/* - * File which has been Scratch_File'd, we are squirreling away that fact - * to inform the client when we are ready. - */ -static char *scratched_file; - -/* - * The scratched_file will need to be removed as well as having its entry - * removed. - */ -static int kill_scratched_file; - - - -void -server_register (name, version, timestamp, options, tag, date, conflict) - const char *name; - const char *version; - const char *timestamp; - const char *options; - const char *tag; - const char *date; - const char *conflict; -{ - int len; - - if (options == NULL) - options = ""; - - if (trace) - { - (void) fprintf (stderr, - "%s-> server_register(%s, %s, %s, %s, %s, %s, %s)\n", - CLIENT_SERVER_STR, - name, version, timestamp ? timestamp : "", options, - tag ? tag : "", date ? date : "", - conflict ? conflict : ""); - } - - if (entries_line != NULL) - { - /* - * If CVS decides to Register it more than once (which happens - * on "cvs update foo/foo.c" where foo and foo.c are already - * checked out), use the last of the entries lines Register'd. - */ - free (entries_line); - } - - /* - * I have reports of Scratch_Entry and Register both happening, in - * two different cases. Using the last one which happens is almost - * surely correct; I haven't tracked down why they both happen (or - * even verified that they are for the same file). - */ - if (scratched_file != NULL) - { - free (scratched_file); - scratched_file = NULL; - } - - len = (strlen (name) + strlen (version) + strlen (options) + 80); - if (tag) - len += strlen (tag); - if (date) - len += strlen (date); - - entries_line = xmalloc (len); - sprintf (entries_line, "/%s/%s/", name, version); - if (conflict != NULL) - { - strcat (entries_line, "+="); - } - strcat (entries_line, "/"); - strcat (entries_line, options); - strcat (entries_line, "/"); - if (tag != NULL) - { - strcat (entries_line, "T"); - strcat (entries_line, tag); - } - else if (date != NULL) - { - strcat (entries_line, "D"); - strcat (entries_line, date); - } -} - - - -void -server_scratch (fname) - const char *fname; -{ - /* - * I have reports of Scratch_Entry and Register both happening, in - * two different cases. Using the last one which happens is almost - * surely correct; I haven't tracked down why they both happen (or - * even verified that they are for the same file). - * - * Don't know if this is what whoever wrote the above comment was - * talking about, but this can happen in the case where a join - * removes a file - the call to Register puts the '-vers' into the - * Entries file after the file is removed - */ - if (entries_line != NULL) - { - free (entries_line); - entries_line = NULL; - } - - if (scratched_file != NULL) - { - buf_output0 (protocol, - "E CVS server internal error: duplicate Scratch_Entry\n"); - buf_send_counted (protocol); - return; - } - scratched_file = xstrdup (fname); - kill_scratched_file = 1; -} - -void -server_scratch_entry_only () -{ - kill_scratched_file = 0; -} - -/* Print a new entries line, from a previous server_register. */ -static void -new_entries_line () -{ - if (entries_line) - { - buf_output0 (protocol, entries_line); - buf_output (protocol, "\n", 1); - } - else - /* Return the error message as the Entries line. */ - buf_output0 (protocol, - "CVS server internal error: Register missing\n"); - free (entries_line); - entries_line = NULL; -} - - -static void -serve_ci (arg) - char *arg; -{ - do_cvs_command ("commit", commit); -} - -static void -checked_in_response (file, update_dir, repository) - char *file; - char *update_dir; - char *repository; -{ - if (supported_response ("Mode")) - { - struct stat sb; - char *mode_string; - - if ( CVS_STAT (file, &sb) < 0) - { - /* Not clear to me why the file would fail to exist, but it - was happening somewhere in the testsuite. */ - if (!existence_error (errno)) - error (0, errno, "cannot stat %s", file); - } - else - { - buf_output0 (protocol, "Mode "); - mode_string = mode_to_string (sb.st_mode); - buf_output0 (protocol, mode_string); - buf_output0 (protocol, "\n"); - free (mode_string); - } - } - - buf_output0 (protocol, "Checked-in "); - output_dir (update_dir, repository); - buf_output0 (protocol, file); - buf_output (protocol, "\n", 1); - new_entries_line (); -} - -void -server_checked_in (file, update_dir, repository) - const char *file; - const char *update_dir; - const char *repository; -{ - assert (file); - assert (update_dir); - assert (repository); - - if (noexec) - return; - if (scratched_file != NULL && entries_line == NULL) - { - /* - * This happens if we are now doing a "cvs remove" after a previous - * "cvs add" (without a "cvs ci" in between). - */ - buf_output0 (protocol, "Remove-entry "); - output_dir (update_dir, repository); - buf_output0 (protocol, file); - buf_output (protocol, "\n", 1); - free (scratched_file); - scratched_file = NULL; - } - else - { - checked_in_response (file, update_dir, repository); - } - buf_send_counted (protocol); -} - -void -server_update_entries (file, update_dir, repository, updated) - const char *file; - const char *update_dir; - const char *repository; - enum server_updated_arg4 updated; -{ - if (noexec) - return; - if (updated == SERVER_UPDATED) - checked_in_response (file, update_dir, repository); - else - { - if (!supported_response ("New-entry")) - return; - buf_output0 (protocol, "New-entry "); - output_dir (update_dir, repository); - buf_output0 (protocol, file); - buf_output (protocol, "\n", 1); - new_entries_line (); - } - - buf_send_counted (protocol); -} - -static void -serve_update (arg) - char *arg; -{ - do_cvs_command ("update", update); -} - -static void -serve_diff (arg) - char *arg; -{ - do_cvs_command ("diff", diff); -} - -static void -serve_log (arg) - char *arg; -{ - do_cvs_command ("log", cvslog); -} - -static void -serve_rlog (arg) - char *arg; -{ - do_cvs_command ("rlog", cvslog); -} - -static void -serve_add (arg) - char *arg; -{ - do_cvs_command ("add", add); -} - -static void -serve_remove (arg) - char *arg; -{ - do_cvs_command ("remove", cvsremove); -} - -static void -serve_status (arg) - char *arg; -{ - do_cvs_command ("status", cvsstatus); -} - -static void -serve_rdiff (arg) - char *arg; -{ - do_cvs_command ("rdiff", patch); -} - -static void -serve_tag (arg) - char *arg; -{ - do_cvs_command ("tag", cvstag); -} - -static void -serve_rtag (arg) - char *arg; -{ - do_cvs_command ("rtag", cvstag); -} - -static void -serve_import (arg) - char *arg; -{ - do_cvs_command ("import", import); -} - -static void -serve_admin (arg) - char *arg; -{ - do_cvs_command ("admin", admin); -} - -static void -serve_history (arg) - char *arg; -{ - do_cvs_command ("history", history); -} - -static void -serve_release (arg) - char *arg; -{ - do_cvs_command ("release", release); -} - -static void serve_watch_on PROTO ((char *)); - -static void -serve_watch_on (arg) - char *arg; -{ - do_cvs_command ("watch", watch_on); -} - -static void serve_watch_off PROTO ((char *)); - -static void -serve_watch_off (arg) - char *arg; -{ - do_cvs_command ("watch", watch_off); -} - -static void serve_watch_add PROTO ((char *)); - -static void -serve_watch_add (arg) - char *arg; -{ - do_cvs_command ("watch", watch_add); -} - -static void serve_watch_remove PROTO ((char *)); - -static void -serve_watch_remove (arg) - char *arg; -{ - do_cvs_command ("watch", watch_remove); -} - -static void serve_watchers PROTO ((char *)); - -static void -serve_watchers (arg) - char *arg; -{ - do_cvs_command ("watchers", watchers); -} - -static void serve_editors PROTO ((char *)); - -static void -serve_editors (arg) - char *arg; -{ - do_cvs_command ("editors", editors); -} - -static void serve_noop PROTO ((char *)); - -static void -serve_noop (arg) - char *arg; -{ - - server_write_entries (); - if (!print_pending_error ()) - { - (void) server_notify (); - buf_output0 (buf_to_net, "ok\n"); - } - buf_flush (buf_to_net, 1); -} - -static void serve_version PROTO ((char *)); - -static void -serve_version (arg) - char *arg; -{ - do_cvs_command ("version", version); -} - -static void serve_init PROTO ((char *)); - -static void -serve_init (arg) - char *arg; -{ - if (alloc_pending (80 + strlen (arg))) - sprintf (pending_error_text, "E init may not be run remotely"); - - if (print_pending_error ()) - return; -} - -static void serve_annotate PROTO ((char *)); - -static void -serve_annotate (arg) - char *arg; -{ - do_cvs_command ("annotate", annotate); -} - -static void serve_rannotate PROTO ((char *)); - -static void -serve_rannotate (arg) - char *arg; -{ - do_cvs_command ("rannotate", annotate); -} - -static void -serve_co (arg) - char *arg; -{ - char *tempdir; - int status; - - if (print_pending_error ()) - return; - - if (!isdir (CVSADM)) - { - /* - * The client has not sent a "Repository" line. Check out - * into a pristine directory. - */ - tempdir = xmalloc (strlen (server_temp_dir) + 80); - if (tempdir == NULL) - { - buf_output0 (buf_to_net, "E Out of memory\n"); - return; - } - strcpy (tempdir, server_temp_dir); - strcat (tempdir, "/checkout-dir"); - status = mkdir_p (tempdir); - if (status != 0 && status != EEXIST) - { - buf_output0 (buf_to_net, "E Cannot create "); - buf_output0 (buf_to_net, tempdir); - buf_append_char (buf_to_net, '\n'); - print_error (errno); - free (tempdir); - return; - } - - if ( CVS_CHDIR (tempdir) < 0) - { - buf_output0 (buf_to_net, "E Cannot change to directory "); - buf_output0 (buf_to_net, tempdir); - buf_append_char (buf_to_net, '\n'); - print_error (errno); - free (tempdir); - return; - } - free (tempdir); - } - - /* Compensate for server_export()'s setting of cvs_cmd_name. - * - * [It probably doesn't matter if do_cvs_command() gets "export" - * or "checkout", but we ought to be accurate where possible.] - */ - do_cvs_command ((strcmp (cvs_cmd_name, "export") == 0) ? - "export" : "checkout", - checkout); -} - -static void -serve_export (arg) - char *arg; -{ - /* Tell checkout() to behave like export not checkout. */ - cvs_cmd_name = "export"; - serve_co (arg); -} - - - -void -server_copy_file (file, update_dir, repository, newfile) - const char *file; - const char *update_dir; - const char *repository; - const char *newfile; -{ - /* At least for now, our practice is to have the server enforce - noexec for the repository and the client enforce it for the - working directory. This might want more thought, and/or - documentation in cvsclient.texi (other responses do it - differently). */ - - if (!supported_response ("Copy-file")) - return; - buf_output0 (protocol, "Copy-file "); - output_dir (update_dir, repository); - buf_output0 (protocol, file); - buf_output0 (protocol, "\n"); - buf_output0 (protocol, newfile); - buf_output0 (protocol, "\n"); -} - -/* See server.h for description. */ - -void -server_modtime (finfo, vers_ts) - struct file_info *finfo; - Vers_TS *vers_ts; -{ - char date[MAXDATELEN]; - char outdate[MAXDATELEN]; - - assert (vers_ts->vn_rcs != NULL); - - if (!supported_response ("Mod-time")) - return; - - if (RCS_getrevtime (finfo->rcs, vers_ts->vn_rcs, date, 0) == (time_t) -1) - /* FIXME? should we be printing some kind of warning? For one - thing I'm not 100% sure whether this happens in non-error - circumstances. */ - return; - date_to_internet (outdate, date); - buf_output0 (protocol, "Mod-time "); - buf_output0 (protocol, outdate); - buf_output0 (protocol, "\n"); -} - -/* See server.h for description. */ - -#if defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__) -/* Need to prototype because mode_t might be smaller than int. */ -void -server_updated ( - struct file_info *finfo, - Vers_TS *vers, - enum server_updated_arg4 updated, - mode_t mode, - unsigned char *checksum, - struct buffer *filebuf) -#else -void -server_updated (finfo, vers, updated, mode, checksum, filebuf) - struct file_info *finfo; - Vers_TS *vers; - enum server_updated_arg4 updated; - mode_t mode; - unsigned char *checksum; - struct buffer *filebuf; -#endif -{ - if (noexec) - { - /* Hmm, maybe if we did the same thing for entries_file, we - could get rid of the kludges in server_register and - server_scratch which refrain from warning if both - Scratch_Entry and Register get called. Maybe. */ - if (scratched_file) - { - free (scratched_file); - scratched_file = NULL; - } - buf_send_counted (protocol); - return; - } - - if (entries_line != NULL && scratched_file == NULL) - { - FILE *f; - struct buffer_data *list, *last; - unsigned long size; - char size_text[80]; - - /* The contents of the file will be in one of filebuf, - list/last, or here. */ - unsigned char *file; - size_t file_allocated; - size_t file_used; - - if (filebuf != NULL) - { - size = buf_length (filebuf); - if (mode == (mode_t) -1) - error (1, 0, "\ -CVS server internal error: no mode in server_updated"); - } - else - { - struct stat sb; - - if ( CVS_STAT (finfo->file, &sb) < 0) - { - if (existence_error (errno)) - { - /* If we have a sticky tag for a branch on which - the file is dead, and cvs update the directory, - it gets a T_CHECKOUT but no file. So in this - case just forget the whole thing. */ - free (entries_line); - entries_line = NULL; - goto done; - } - error (1, errno, "reading %s", finfo->fullname); - } - size = sb.st_size; - if (mode == (mode_t) -1) - { - /* FIXME: When we check out files the umask of the - server (set in .bashrc if rsh is in use) affects - what mode we send, and it shouldn't. */ - mode = sb.st_mode; - } - } - - if (checksum != NULL) - { - static int checksum_supported = -1; - - if (checksum_supported == -1) - { - checksum_supported = supported_response ("Checksum"); - } - - if (checksum_supported) - { - int i; - char buf[3]; - - buf_output0 (protocol, "Checksum "); - for (i = 0; i < 16; i++) - { - sprintf (buf, "%02x", (unsigned int) checksum[i]); - buf_output0 (protocol, buf); - } - buf_append_char (protocol, '\n'); - } - } - - if (updated == SERVER_UPDATED) - { - Node *node; - - if (!(supported_response ("Created") - && supported_response ("Update-existing"))) - buf_output0 (protocol, "Updated "); - else - { - assert (vers != NULL); - if (vers->ts_user == NULL) - buf_output0 (protocol, "Created "); - else - buf_output0 (protocol, "Update-existing "); - } - - /* Now munge the entries to say that the file is unmodified, - in case we end up processing it again (e.g. modules3-6 - in the testsuite). */ - node = findnode_fn (finfo->entries, finfo->file); - assert (node != NULL); - if (node != NULL) - { - Entnode *entnode = node->data; - free (entnode->timestamp); - entnode->timestamp = xstrdup ("="); - } - } - else if (updated == SERVER_MERGED) - buf_output0 (protocol, "Merged "); - else if (updated == SERVER_PATCHED) - buf_output0 (protocol, "Patched "); - else if (updated == SERVER_RCS_DIFF) - buf_output0 (protocol, "Rcs-diff "); - else - abort (); - output_dir (finfo->update_dir, finfo->repository); - buf_output0 (protocol, finfo->file); - buf_output (protocol, "\n", 1); - - new_entries_line (); - - { - char *mode_string; - - mode_string = mode_to_string (mode); - buf_output0 (protocol, mode_string); - buf_output0 (protocol, "\n"); - free (mode_string); - } - - list = last = NULL; - - file = NULL; - file_allocated = 0; - file_used = 0; - - if (size > 0) - { - /* Throughout this section we use binary mode to read the - file we are sending. The client handles any line ending - translation if necessary. */ - - if (file_gzip_level - /* - * For really tiny files, the gzip process startup - * time will outweigh the compression savings. This - * might be computable somehow; using 100 here is just - * a first approximation. - */ - && size > 100) - { - /* Basing this routine on read_and_gzip is not a - high-performance approach. But it seems easier - to code than the alternative (and less - vulnerable to subtle bugs). Given that this feature - is mainly for compatibility, that is the better - tradeoff. */ - - int fd; - - /* Callers must avoid passing us a buffer if - file_gzip_level is set. We could handle this case, - but it's not worth it since this case never arises - with a current client and server. */ - if (filebuf != NULL) - error (1, 0, "\ -CVS server internal error: unhandled case in server_updated"); - - fd = CVS_OPEN (finfo->file, O_RDONLY | OPEN_BINARY, 0); - if (fd < 0) - error (1, errno, "reading %s", finfo->fullname); - if (read_and_gzip (fd, finfo->fullname, &file, - &file_allocated, &file_used, - file_gzip_level)) - error (1, 0, "aborting due to compression error"); - size = file_used; - if (close (fd) < 0) - error (1, errno, "reading %s", finfo->fullname); - /* Prepending length with "z" is flag for using gzip here. */ - buf_output0 (protocol, "z"); - } - else if (filebuf == NULL) - { - long status; - - f = CVS_FOPEN (finfo->file, "rb"); - if (f == NULL) - error (1, errno, "reading %s", finfo->fullname); - status = buf_read_file (f, size, &list, &last); - if (status == -2) - (*protocol->memory_error) (protocol); - else if (status != 0) - error (1, ferror (f) ? errno : 0, "reading %s", - finfo->fullname); - if (fclose (f) == EOF) - error (1, errno, "reading %s", finfo->fullname); - } - } - - sprintf (size_text, "%lu\n", size); - buf_output0 (protocol, size_text); - - if (file != NULL) - { - buf_output (protocol, (char *) file, file_used); - free (file); - file = NULL; - } - else if (filebuf == NULL) - buf_append_data (protocol, list, last); - else - { - buf_append_buffer (protocol, filebuf); - } - /* Note we only send a newline here if the file ended with one. */ - - /* - * Avoid using up too much disk space for temporary files. - * A file which does not exist indicates that the file is up-to-date, - * which is now the case. If this is SERVER_MERGED, the file is - * not up-to-date, and we indicate that by leaving the file there. - * I'm thinking of cases like "cvs update foo/foo.c foo". - */ - if ((updated == SERVER_UPDATED - || updated == SERVER_PATCHED - || updated == SERVER_RCS_DIFF) - && filebuf == NULL - /* But if we are joining, we'll need the file when we call - join_file. */ - && !joining ()) - { - if (CVS_UNLINK (finfo->file) < 0) - error (0, errno, "cannot remove temp file for %s", - finfo->fullname); - } - } - else if (scratched_file != NULL && entries_line == NULL) - { - if (strcmp (scratched_file, finfo->file) != 0) - error (1, 0, - "CVS server internal error: `%s' vs. `%s' scratched", - scratched_file, - finfo->file); - free (scratched_file); - scratched_file = NULL; - - if (kill_scratched_file) - buf_output0 (protocol, "Removed "); - else - buf_output0 (protocol, "Remove-entry "); - output_dir (finfo->update_dir, finfo->repository); - buf_output0 (protocol, finfo->file); - buf_output (protocol, "\n", 1); - /* keep the vers structure up to date in case we do a join - * - if there isn't a file, it can't very well have a version number, can it? - * - * we do it here on the assumption that since we just told the client - * to remove the file/entry, it will, and we want to remember that. - * If it fails, that's the client's problem, not ours - */ - if (vers && vers->vn_user != NULL) - { - free (vers->vn_user); - vers->vn_user = NULL; - } - if (vers && vers->ts_user != NULL) - { - free (vers->ts_user); - vers->ts_user = NULL; - } - } - else if (scratched_file == NULL && entries_line == NULL) - { - /* - * This can happen with death support if we were processing - * a dead file in a checkout. - */ - } - else - error (1, 0, - "CVS server internal error: Register *and* Scratch_Entry.\n"); - buf_send_counted (protocol); - done:; -} - -/* Return whether we should send patches in RCS format. */ - -int -server_use_rcs_diff () -{ - return supported_response ("Rcs-diff"); -} - - - -void -server_set_entstat (update_dir, repository) - const char *update_dir; - const char *repository; -{ - static int set_static_supported = -1; - if (set_static_supported == -1) - set_static_supported = supported_response ("Set-static-directory"); - if (!set_static_supported) return; - - buf_output0 (protocol, "Set-static-directory "); - output_dir (update_dir, repository); - buf_output0 (protocol, "\n"); - buf_send_counted (protocol); -} - - - -void -server_clear_entstat (update_dir, repository) - const char *update_dir; - const char *repository; -{ - static int clear_static_supported = -1; - if (clear_static_supported == -1) - clear_static_supported = supported_response ("Clear-static-directory"); - if (!clear_static_supported) return; - - if (noexec) - return; - - buf_output0 (protocol, "Clear-static-directory "); - output_dir (update_dir, repository); - buf_output0 (protocol, "\n"); - buf_send_counted (protocol); -} - - - -void -server_set_sticky (update_dir, repository, tag, date, nonbranch) - const char *update_dir; - const char *repository; - const char *tag; - const char *date; - int nonbranch; -{ - static int set_sticky_supported = -1; - - assert (update_dir != NULL); - - if (set_sticky_supported == -1) - set_sticky_supported = supported_response ("Set-sticky"); - if (!set_sticky_supported) return; - - if (noexec) - return; - - if (tag == NULL && date == NULL) - { - buf_output0 (protocol, "Clear-sticky "); - output_dir (update_dir, repository); - buf_output0 (protocol, "\n"); - } - else - { - buf_output0 (protocol, "Set-sticky "); - output_dir (update_dir, repository); - buf_output0 (protocol, "\n"); - if (tag != NULL) - { - if (nonbranch) - buf_output0 (protocol, "N"); - else - buf_output0 (protocol, "T"); - buf_output0 (protocol, tag); - } - else - { - buf_output0 (protocol, "D"); - buf_output0 (protocol, date); - } - buf_output0 (protocol, "\n"); - } - buf_send_counted (protocol); -} - -struct template_proc_data -{ - const char *update_dir; - const char *repository; -}; - -/* Here as a static until we get around to fixing Parse_Info to pass along - a void * for it. */ -static struct template_proc_data *tpd; - -static int -template_proc PROTO((const char *repository, const char *template)); - -static int -template_proc (repository, template) - const char *repository; - const char *template; -{ - FILE *fp; - char buf[1024]; - size_t n; - struct stat sb; - struct template_proc_data *data = tpd; - - if (!supported_response ("Template")) - /* Might want to warn the user that the rcsinfo feature won't work. */ - return 0; - buf_output0 (protocol, "Template "); - output_dir (data->update_dir, data->repository); - buf_output0 (protocol, "\n"); - - fp = CVS_FOPEN (template, "rb"); - if (fp == NULL) - { - error (0, errno, "Couldn't open rcsinfo template file %s", template); - return 1; - } - if (fstat (fileno (fp), &sb) < 0) - { - error (0, errno, "cannot stat rcsinfo template file %s", template); - return 1; - } - sprintf (buf, "%ld\n", (long) sb.st_size); - buf_output0 (protocol, buf); - while (!feof (fp)) - { - n = fread (buf, 1, sizeof buf, fp); - buf_output (protocol, buf, n); - if (ferror (fp)) - { - error (0, errno, "cannot read rcsinfo template file %s", template); - (void) fclose (fp); - return 1; - } - } - buf_send_counted (protocol); - if (fclose (fp) < 0) - error (0, errno, "cannot close rcsinfo template file %s", template); - return 0; -} - - - -void -server_template (update_dir, repository) - const char *update_dir; - const char *repository; -{ - struct template_proc_data data; - data.update_dir = update_dir; - data.repository = repository; - tpd = &data; - (void) Parse_Info (CVSROOTADM_RCSINFO, repository, template_proc, 1); -} - - - -static void -serve_gzip_contents (arg) - char *arg; -{ - int level; - level = atoi (arg); - if (level == 0) - level = 6; - file_gzip_level = level; -} - -static void -serve_gzip_stream (arg) - char *arg; -{ - int level; - level = atoi (arg); - if (level == 0) - level = 6; - - /* All further communication with the client will be compressed. */ - - buf_to_net = compress_buffer_initialize (buf_to_net, 0, level, - buf_to_net->memory_error); - buf_from_net = compress_buffer_initialize (buf_from_net, 1, level, - buf_from_net->memory_error); -} - -/* Tell the client about RCS options set in CVSROOT/cvswrappers. */ -static void -serve_wrapper_sendme_rcs_options (arg) - char *arg; -{ - /* Actually, this is kind of sdrawkcab-ssa: the client wants - * verbatim lines from a cvswrappers file, but the server has - * already parsed the cvswrappers file into the wrap_list struct. - * Therefore, the server loops over wrap_list, unparsing each - * entry before sending it. - */ - char *wrapper_line = NULL; - - wrap_setup (); - - for (wrap_unparse_rcs_options (&wrapper_line, 1); - wrapper_line; - wrap_unparse_rcs_options (&wrapper_line, 0)) - { - buf_output0 (buf_to_net, "Wrapper-rcsOption "); - buf_output0 (buf_to_net, wrapper_line); - buf_output0 (buf_to_net, "\012");; - free (wrapper_line); - } - - buf_output0 (buf_to_net, "ok\012"); - - /* The client is waiting for us, so we better send the data now. */ - buf_flush (buf_to_net, 1); -} - - -static void -serve_ignore (arg) - char *arg; -{ - /* - * Just ignore this command. This is used to support the - * update-patches command, which is not a real command, but a signal - * to the client that update will accept the -u argument. - */ -} - -static int -expand_proc (argc, argv, where, mwhere, mfile, shorten, - local_specified, omodule, msg) - int argc; - char **argv; - char *where; - char *mwhere; - char *mfile; - int shorten; - int local_specified; - char *omodule; - char *msg; -{ - int i; - char *dir = argv[0]; - - /* If mwhere has been specified, the thing we're expanding is a - module -- just return its name so the client will ask for the - right thing later. If it is an alias or a real directory, - mwhere will not be set, so send out the appropriate - expansion. */ - - if (mwhere != NULL) - { - buf_output0 (buf_to_net, "Module-expansion "); - if (server_dir != NULL) - { - buf_output0 (buf_to_net, server_dir); - buf_output0 (buf_to_net, "/"); - } - buf_output0 (buf_to_net, mwhere); - if (mfile != NULL) - { - buf_append_char (buf_to_net, '/'); - buf_output0 (buf_to_net, mfile); - } - buf_append_char (buf_to_net, '\n'); - } - else - { - /* We may not need to do this anymore -- check the definition - of aliases before removing */ - if (argc == 1) - { - buf_output0 (buf_to_net, "Module-expansion "); - if (server_dir != NULL) - { - buf_output0 (buf_to_net, server_dir); - buf_output0 (buf_to_net, "/"); - } - buf_output0 (buf_to_net, dir); - buf_append_char (buf_to_net, '\n'); - } - else - { - for (i = 1; i < argc; ++i) - { - buf_output0 (buf_to_net, "Module-expansion "); - if (server_dir != NULL) - { - buf_output0 (buf_to_net, server_dir); - buf_output0 (buf_to_net, "/"); - } - buf_output0 (buf_to_net, dir); - buf_append_char (buf_to_net, '/'); - buf_output0 (buf_to_net, argv[i]); - buf_append_char (buf_to_net, '\n'); - } - } - } - return 0; -} - -static void -serve_expand_modules (arg) - char *arg; -{ - int i; - int err; - DBM *db; - err = 0; - - db = open_module (); - for (i = 1; i < argument_count; i++) - err += do_module (db, argument_vector[i], - CHECKOUT, "Updating", expand_proc, - NULL, 0, 0, 0, 0, - (char *) NULL); - close_module (db); - { - /* argument_vector[0] is a dummy argument, we don't mess with it. */ - char **cp; - for (cp = argument_vector + 1; - cp < argument_vector + argument_count; - ++cp) - free (*cp); - - argument_count = 1; - } - if (err) - /* We will have printed an error message already. */ - buf_output0 (buf_to_net, "error \n"); - else - buf_output0 (buf_to_net, "ok\n"); - - /* The client is waiting for the module expansions, so we must - send the output now. */ - buf_flush (buf_to_net, 1); -} - - - -static void serve_valid_requests PROTO((char *arg)); - -#endif /* SERVER_SUPPORT */ -#if defined(SERVER_SUPPORT) || defined(CLIENT_SUPPORT) - -/* - * Parts of this table are shared with the client code, - * but the client doesn't need to know about the handler - * functions. - */ - -struct request requests[] = -{ -#ifdef SERVER_SUPPORT -#define REQ_LINE(n, f, s) {n, f, s} -#else -#define REQ_LINE(n, f, s) {n, s} -#endif - - REQ_LINE("Root", serve_root, RQ_ESSENTIAL | RQ_ROOTLESS), - REQ_LINE("Valid-responses", serve_valid_responses, - RQ_ESSENTIAL | RQ_ROOTLESS), - REQ_LINE("valid-requests", serve_valid_requests, - RQ_ESSENTIAL | RQ_ROOTLESS), - REQ_LINE("Repository", serve_repository, 0), - REQ_LINE("Directory", serve_directory, RQ_ESSENTIAL), - REQ_LINE("Max-dotdot", serve_max_dotdot, 0), - REQ_LINE("Static-directory", serve_static_directory, 0), - REQ_LINE("Sticky", serve_sticky, 0), - REQ_LINE("Entry", serve_entry, RQ_ESSENTIAL), - REQ_LINE("Kopt", serve_kopt, 0), - REQ_LINE("Checkin-time", serve_checkin_time, 0), - REQ_LINE("Modified", serve_modified, RQ_ESSENTIAL), - REQ_LINE("Is-modified", serve_is_modified, 0), - REQ_LINE("Empty-conflicts", serve_noop, 0), - - /* The client must send this request to interoperate with CVS 1.5 - through 1.9 servers. The server must support it (although it can - be and is a noop) to interoperate with CVS 1.5 to 1.9 clients. */ - REQ_LINE("UseUnchanged", serve_enable_unchanged, RQ_ENABLEME | RQ_ROOTLESS), - - REQ_LINE("Unchanged", serve_unchanged, RQ_ESSENTIAL), - REQ_LINE("Notify", serve_notify, 0), - REQ_LINE("Questionable", serve_questionable, 0), - REQ_LINE("Argument", serve_argument, RQ_ESSENTIAL), - REQ_LINE("Argumentx", serve_argumentx, RQ_ESSENTIAL), - REQ_LINE("Global_option", serve_global_option, RQ_ROOTLESS), - REQ_LINE("Gzip-stream", serve_gzip_stream, 0), - REQ_LINE("wrapper-sendme-rcsOptions", - serve_wrapper_sendme_rcs_options, - 0), - REQ_LINE("Set", serve_set, RQ_ROOTLESS), -#ifdef ENCRYPTION -# ifdef HAVE_KERBEROS - REQ_LINE("Kerberos-encrypt", serve_kerberos_encrypt, 0), -# endif -# ifdef HAVE_GSSAPI - REQ_LINE("Gssapi-encrypt", serve_gssapi_encrypt, 0), -# endif -#endif -#ifdef HAVE_GSSAPI - REQ_LINE("Gssapi-authenticate", serve_gssapi_authenticate, 0), -#endif - REQ_LINE("expand-modules", serve_expand_modules, 0), - REQ_LINE("ci", serve_ci, RQ_ESSENTIAL), - REQ_LINE("co", serve_co, RQ_ESSENTIAL), - REQ_LINE("update", serve_update, RQ_ESSENTIAL), - REQ_LINE("diff", serve_diff, 0), - REQ_LINE("log", serve_log, 0), - REQ_LINE("rlog", serve_rlog, 0), - REQ_LINE("add", serve_add, 0), - REQ_LINE("remove", serve_remove, 0), - REQ_LINE("update-patches", serve_ignore, 0), - REQ_LINE("gzip-file-contents", serve_gzip_contents, 0), - REQ_LINE("status", serve_status, 0), - REQ_LINE("rdiff", serve_rdiff, 0), - REQ_LINE("tag", serve_tag, 0), - REQ_LINE("rtag", serve_rtag, 0), - REQ_LINE("import", serve_import, 0), - REQ_LINE("admin", serve_admin, 0), - REQ_LINE("export", serve_export, 0), - REQ_LINE("history", serve_history, 0), - REQ_LINE("release", serve_release, 0), - REQ_LINE("watch-on", serve_watch_on, 0), - REQ_LINE("watch-off", serve_watch_off, 0), - REQ_LINE("watch-add", serve_watch_add, 0), - REQ_LINE("watch-remove", serve_watch_remove, 0), - REQ_LINE("watchers", serve_watchers, 0), - REQ_LINE("editors", serve_editors, 0), - REQ_LINE("init", serve_init, RQ_ROOTLESS), - REQ_LINE("annotate", serve_annotate, 0), - REQ_LINE("rannotate", serve_rannotate, 0), - REQ_LINE("noop", serve_noop, RQ_ROOTLESS), - REQ_LINE("version", serve_version, RQ_ROOTLESS), - REQ_LINE(NULL, NULL, 0) - -#undef REQ_LINE -}; - -#endif /* SERVER_SUPPORT or CLIENT_SUPPORT */ -#ifdef SERVER_SUPPORT - -static void -serve_valid_requests (arg) - char *arg; -{ - struct request *rq; - if (print_pending_error ()) - return; - buf_output0 (buf_to_net, "Valid-requests"); - for (rq = requests; rq->name != NULL; rq++) - { - if (rq->func != NULL) - { - buf_append_char (buf_to_net, ' '); - buf_output0 (buf_to_net, rq->name); - } - } - buf_output0 (buf_to_net, "\nok\n"); - - /* The client is waiting for the list of valid requests, so we - must send the output now. */ - buf_flush (buf_to_net, 1); -} - -#ifdef SUNOS_KLUDGE -/* - * Delete temporary files. SIG is the signal making this happen, or - * 0 if not called as a result of a signal. - */ -static int command_pid_is_dead; -static void wait_sig (sig) - int sig; -{ - int status; - pid_t r = wait (&status); - if (r == command_pid) - command_pid_is_dead++; -} -#endif /* SUNOS_KLUDGE */ - -void -server_cleanup (sig) - int sig; -{ - /* Do "rm -rf" on the temp directory. */ - int status; - int save_noexec; - - if (buf_to_net != NULL) - { - /* Since we're done, go ahead and put BUF_TO_NET back into blocking - * mode and send any pending output. In the usual case there won't - * won't be any, but there might be if an error occured. - */ - - set_block (buf_to_net); - buf_flush (buf_to_net, 1); - - /* Next we shut down BUF_FROM_NET. That will pick up the checksum - * generated when the client shuts down its buffer. Then, after we - * have generated any final output, we shut down BUF_TO_NET. - */ - - if (buf_from_net != NULL) - { - status = buf_shutdown (buf_from_net); - if (status != 0) - error (0, status, "shutting down buffer from client"); - buf_free (buf_from_net); - buf_from_net = NULL; - } - - if (dont_delete_temp) - { - (void) buf_flush (buf_to_net, 1); - (void) buf_shutdown (buf_to_net); - buf_free (buf_to_net); - buf_to_net = NULL; - error_use_protocol = 0; - return; - } - } - else if (dont_delete_temp) - return; - - /* What a bogus kludge. This disgusting code makes all kinds of - assumptions about SunOS, and is only for a bug in that system. - So only enable it on Suns. */ -#ifdef SUNOS_KLUDGE - if (command_pid > 0) - { - /* To avoid crashes on SunOS due to bugs in SunOS tmpfs - triggered by the use of rename() in RCS, wait for the - subprocess to die. Unfortunately, this means draining output - while waiting for it to unblock the signal we sent it. Yuck! */ - int status; - pid_t r; - - signal (SIGCHLD, wait_sig); - if (sig) - /* Perhaps SIGTERM would be more correct. But the child - process will delay the SIGINT delivery until its own - children have exited. */ - kill (command_pid, SIGINT); - /* The caller may also have sent a signal to command_pid, so - always try waiting. First, though, check and see if it's still - there.... */ - do_waitpid: - r = waitpid (command_pid, &status, WNOHANG); - if (r == 0) - ; - else if (r == command_pid) - command_pid_is_dead++; - else if (r == -1) - switch (errno) - { - case ECHILD: - command_pid_is_dead++; - break; - case EINTR: - goto do_waitpid; - } - else - /* waitpid should always return one of the above values */ - abort (); - while (!command_pid_is_dead) - { - struct timeval timeout; - struct fd_set_wrapper readfds; - char buf[100]; - int i; - - /* Use a non-zero timeout to avoid eating up CPU cycles. */ - timeout.tv_sec = 2; - timeout.tv_usec = 0; - readfds = command_fds_to_drain; - switch (select (max_command_fd + 1, &readfds.fds, - (fd_set *)0, (fd_set *)0, - &timeout)) - { - case -1: - if (errno != EINTR) - abort (); - case 0: - /* timeout */ - break; - case 1: - for (i = 0; i <= max_command_fd; i++) - { - if (!FD_ISSET (i, &readfds.fds)) - continue; - /* this fd is non-blocking */ - while (read (i, buf, sizeof (buf)) >= 1) - ; - } - break; - default: - abort (); - } - } - } -#endif /* SUNOS_KLUDGE */ - - CVS_CHDIR (Tmpdir); - /* Temporarily clear noexec, so that we clean up our temp directory - regardless of it (this could more cleanly be handled by moving - the noexec check to all the unlink_file_dir callers from - unlink_file_dir itself). */ - save_noexec = noexec; - noexec = 0; - /* FIXME? Would be nice to not ignore errors. But what should we do? - We could try to do this before we shut down the network connection, - and try to notify the client (but the client might not be waiting - for responses). We could try something like syslog() or our own - log file. */ - unlink_file_dir (orig_server_temp_dir); - noexec = save_noexec; - - if (buf_to_net != NULL) - { - (void) buf_flush (buf_to_net, 1); - (void) buf_shutdown (buf_to_net); - buf_free (buf_to_net); - buf_to_net = NULL; - error_use_protocol = 0; - } -} - -int -server (argc, argv) - int argc; - char **argv; -{ - char *error_prog_name; /* Used in error messages */ - - if (argc == -1) - { - static const char *const msg[] = - { - "Usage: %s %s\n", - " Normally invoked by a cvs client on a remote machine.\n", - NULL - }; - usage (msg); - } - /* Ignore argc and argv. They might be from .cvsrc. */ - - buf_to_net = fd_buffer_initialize (STDOUT_FILENO, 0, - outbuf_memory_error); - buf_from_net = stdio_buffer_initialize (stdin, 0, 1, outbuf_memory_error); - - saved_output = buf_nonio_initialize (outbuf_memory_error); - saved_outerr = buf_nonio_initialize (outbuf_memory_error); - - /* Since we're in the server parent process, error should use the - protocol to report error messages. */ - error_use_protocol = 1; - - /* OK, now figure out where we stash our temporary files. */ - { - char *p; - - /* The code which wants to chdir into server_temp_dir is not set - up to deal with it being a relative path. So give an error - for that case. */ - if (!isabsolute (Tmpdir)) - { - if (alloc_pending (80 + strlen (Tmpdir))) - sprintf (pending_error_text, - "E Value of %s for TMPDIR is not absolute", Tmpdir); - - /* FIXME: we would like this error to be persistent, that - is, not cleared by print_pending_error. The current client - will exit as soon as it gets an error, but the protocol spec - does not require a client to do so. */ - } - else - { - int status; - int i = 0; - - server_temp_dir = xmalloc (strlen (Tmpdir) + 80); - if (server_temp_dir == NULL) - { - /* - * Strictly speaking, we're not supposed to output anything - * now. But we're about to exit(), give it a try. - */ - printf ("E Fatal server error, aborting.\n\ -error ENOMEM Virtual memory exhausted.\n"); - - error_exit (); - } - strcpy (server_temp_dir, Tmpdir); - - /* Remove a trailing slash from TMPDIR if present. */ - p = server_temp_dir + strlen (server_temp_dir) - 1; - if (*p == '/') - *p = '\0'; - - /* - * I wanted to use cvs-serv/PID, but then you have to worry about - * the permissions on the cvs-serv directory being right. So - * use cvs-servPID. - */ - strcat (server_temp_dir, "/cvs-serv"); - - p = server_temp_dir + strlen (server_temp_dir); - sprintf (p, "%ld", (long) getpid ()); - - orig_server_temp_dir = server_temp_dir; - - /* Create the temporary directory, and set the mode to - 700, to discourage random people from tampering with - it. */ - while ((status = mkdir_p (server_temp_dir)) == EEXIST) - { - static const char suffix[] = "abcdefghijklmnopqrstuvwxyz"; - - if (i >= sizeof suffix - 1) break; - if (i == 0) p = server_temp_dir + strlen (server_temp_dir); - p[0] = suffix[i++]; - p[1] = '\0'; - } - if (status != 0) - { - if (alloc_pending (80 + strlen (server_temp_dir))) - sprintf (pending_error_text, - "E can't create temporary directory %s", - server_temp_dir); - pending_error = status; - } -#ifndef CHMOD_BROKEN - else if (chmod (server_temp_dir, S_IRWXU) < 0) - { - int save_errno = errno; - if (alloc_pending (80 + strlen (server_temp_dir))) - sprintf (pending_error_text, -"E cannot change permissions on temporary directory %s", - server_temp_dir); - pending_error = save_errno; - } -#endif - else if (CVS_CHDIR (server_temp_dir) < 0) - { - int save_errno = errno; - if (alloc_pending (80 + strlen (server_temp_dir))) - sprintf (pending_error_text, -"E cannot change to temporary directory %s", - server_temp_dir); - pending_error = save_errno; - } - } - } - - /* Now initialize our argument vector (for arguments from the client). */ - - /* Small for testing. */ - argument_vector_size = 1; - argument_vector = xmalloc (argument_vector_size * sizeof (char *)); - argument_count = 1; - /* This gets printed if the client supports an option which the - server doesn't, causing the server to print a usage message. - FIXME: just a nit, I suppose, but the usage message the server - prints isn't literally true--it suggests "cvs server" followed - by options which are for a particular command. Might be nice to - say something like "client apparently supports an option not supported - by this server" or something like that instead of usage message. */ - error_prog_name = xmalloc (strlen (program_name) + 8); - sprintf(error_prog_name, "%s server", program_name); - argument_vector[0] = error_prog_name; - - while (1) - { - char *cmd, *orig_cmd; - struct request *rq; - int status; - - status = buf_read_line (buf_from_net, &cmd, NULL); - if (status == -2) - { - buf_output0 (buf_to_net, "E Fatal server error, aborting.\n\ -error ENOMEM Virtual memory exhausted.\n"); - break; - } - if (status != 0) - break; - - orig_cmd = cmd; - for (rq = requests; rq->name != NULL; ++rq) - if (strncmp (cmd, rq->name, strlen (rq->name)) == 0) - { - int len = strlen (rq->name); - if (cmd[len] == '\0') - cmd += len; - else if (cmd[len] == ' ') - cmd += len + 1; - else - /* - * The first len characters match, but it's a different - * command. e.g. the command is "cooperate" but we matched - * "co". - */ - continue; - - if (!(rq->flags & RQ_ROOTLESS) - && current_parsed_root == NULL) - { - /* For commands which change the way in which data - is sent and received, for example Gzip-stream, - this does the wrong thing. Since the client - assumes that everything is being compressed, - unconditionally, there is no way to give this - error to the client without turning on - compression. The obvious fix would be to make - Gzip-stream RQ_ROOTLESS (with the corresponding - change to the spec), and that might be a good - idea but then again I can see some settings in - CVSROOT about what compression level to allow. - I suppose a more baroque answer would be to - turn on compression (say, at level 1), just - enough to give the "Root request missing" - error. For now we just lose. */ - if (alloc_pending (80)) - sprintf (pending_error_text, - "E Protocol error: Root request missing"); - } - else - (*rq->func) (cmd); - break; - } - if (rq->name == NULL) - { - if (!print_pending_error ()) - { - buf_output0 (buf_to_net, "error unrecognized request `"); - buf_output0 (buf_to_net, cmd); - buf_append_char (buf_to_net, '\''); - buf_append_char (buf_to_net, '\n'); - } - } - free (orig_cmd); - } - free (error_prog_name); - - /* We expect the client is done talking to us at this point. If there is - * any data in the buffer or on the network pipe, then something we didn't - * prepare for is happening. - */ - if (!buf_empty (buf_from_net)) - { - /* Try to send the error message to the client, but also syslog it, in - * case the client isn't listening anymore. - */ -#ifdef HAVE_SYSLOG_H - /* FIXME: Can the IP address of the connecting client be retrieved - * and printed here? - */ - syslog (LOG_DAEMON | LOG_ERR, "Dying gasps received from client."); -#endif - error (0, 0, "Dying gasps received from client."); - } - - /* This command will actually close the network buffers. */ - server_cleanup (0); - return 0; -} - - - -#if defined (HAVE_KERBEROS) || defined (AUTH_SERVER_SUPPORT) || defined (HAVE_GSSAPI) -static void switch_to_user PROTO((const char *, const char *)); - -static void -switch_to_user (cvs_username, username) - const char *cvs_username; /* Only used for error messages. */ - const char *username; -{ - struct passwd *pw; - - pw = getpwnam (username); - if (pw == NULL) - { - /* check_password contains a similar check, so this usually won't be - reached unless the CVS user is mapped to an invalid system user. */ - - printf ("E Fatal error, aborting.\n\ -error 0 %s: no such system user\n", username); - /* Don't worry about server_cleanup; server_active isn't set yet. */ - error_exit (); - } - - if (pw->pw_uid == 0) - { -#ifdef HAVE_SYSLOG_H - /* FIXME: Can the IP address of the connecting client be retrieved - * and printed here? - */ - syslog (LOG_DAEMON | LOG_ALERT, - "attempt to root from account: %s", cvs_username - ); -#endif - printf("error 0: root not allowed\n"); - error_exit (); - } - -#if HAVE_INITGROUPS - if (initgroups (pw->pw_name, pw->pw_gid) < 0 -# ifdef EPERM - /* At least on the system I tried, initgroups() only works as root. - But we do still want to report ENOMEM and whatever other - errors initgroups() might dish up. */ - && errno != EPERM -# endif - ) - { - /* This could be a warning, but I'm not sure I see the point - in doing that instead of an error given that it would happen - on every connection. We could log it somewhere and not tell - the user. But at least for now make it an error. */ - printf ("error 0 initgroups failed: %s\n", strerror (errno)); - /* Don't worry about server_cleanup; server_active isn't set yet. */ - error_exit (); - } -#endif /* HAVE_INITGROUPS */ - -#ifdef SETXID_SUPPORT - /* honor the setgid bit iff set*/ - if (getgid() != getegid()) - { - if (setgid (getegid ()) < 0) - { - /* See comments at setuid call below for more discussion. */ - printf ("error 0 setgid failed: %s\n", strerror (errno)); - /* Don't worry about server_cleanup; - server_active isn't set yet. */ - error_exit (); - } - } - else -#endif - { - if (setgid (pw->pw_gid) < 0) - { - /* See comments at setuid call below for more discussion. */ - printf ("error 0 setgid failed: %s\n", strerror (errno)); -#ifdef HAVE_SYSLOG_H - syslog (LOG_DAEMON | LOG_ERR, - "setgid to %d failed (%m): real %d/%d, effective %d/%d ", - pw->pw_gid, getuid(), getgid(), geteuid(), getegid()); -#endif - /* Don't worry about server_cleanup; - server_active isn't set yet. */ - error_exit (); - } - } - - if (setuid (pw->pw_uid) < 0) - { - /* Note that this means that if run as a non-root user, - CVSROOT/passwd must contain the user we are running as - (e.g. "joe:FsEfVcu:cvs" if run as "cvs" user). This seems - cleaner than ignoring the error like CVS 1.10 and older but - it does mean that some people might need to update their - CVSROOT/passwd file. */ - printf ("error 0 setuid failed: %s\n", strerror (errno)); -#ifdef HAVE_SYSLOG_H - syslog (LOG_DAEMON | LOG_ERR, - "setuid to %d failed (%m): real %d/%d, effective %d/%d ", - pw->pw_uid, getuid(), getgid(), geteuid(), getegid()); -#endif - /* Don't worry about server_cleanup; server_active isn't set yet. */ - error_exit (); - } - - /* We don't want our umask to change file modes. The modes should - be set by the modes used in the repository, and by the umask of - the client. */ - umask (0); - -#ifdef AUTH_SERVER_SUPPORT - /* Make sure our CVS_Username has been set. */ - if (CVS_Username == NULL) - CVS_Username = xstrdup (username); -#endif - -#if HAVE_PUTENV - /* Set LOGNAME, USER and CVS_USER in the environment, in case they - are already set to something else. */ - { - char *env; - - env = xmalloc (sizeof "LOGNAME=" + strlen (username)); - (void) sprintf (env, "LOGNAME=%s", username); - (void) putenv (env); - - env = xmalloc (sizeof "USER=" + strlen (username)); - (void) sprintf (env, "USER=%s", username); - (void) putenv (env); - -#ifdef AUTH_SERVER_SUPPORT - env = xmalloc (sizeof "CVS_USER=" + strlen (CVS_Username)); - (void) sprintf (env, "CVS_USER=%s", CVS_Username); - (void) putenv (env); -#endif - } -#endif /* HAVE_PUTENV */ -} -#endif - -#ifdef AUTH_SERVER_SUPPORT - -extern char *crypt PROTO((const char *, const char *)); - - -/* - * 0 means no entry found for this user. - * 1 means entry found and password matches (or found password is empty) - * 2 means entry found, but password does not match. - * - * If 1, host_user_ptr will be set to point at the system - * username (i.e., the "real" identity, which may or may not be the - * CVS username) of this user; caller may free this. Global - * CVS_Username will point at an allocated copy of cvs username (i.e., - * the username argument below). - * kff todo: FIXME: last sentence is not true, it applies to caller. - */ -static int -check_repository_password (username, password, repository, host_user_ptr) - char *username, *password, *repository, **host_user_ptr; -{ - int retval = 0; - FILE *fp; - char *filename; - char *linebuf = NULL; - size_t linebuf_len; - int found_it = 0; - int namelen; - - /* We don't use current_parsed_root->directory because it hasn't been - * set yet -- our `repository' argument came from the authentication - * protocol, not the regular CVS protocol. - */ - - filename = xmalloc (strlen (repository) - + 1 - + strlen (CVSROOTADM) - + 1 - + strlen (CVSROOTADM_PASSWD) - + 1); - - (void) sprintf (filename, "%s/%s/%s", repository, - CVSROOTADM, CVSROOTADM_PASSWD); - - fp = CVS_FOPEN (filename, "r"); - if (fp == NULL) - { - if (!existence_error (errno)) - error (0, errno, "cannot open %s", filename); - free (filename); - return 0; - } - - /* Look for a relevant line -- one with this user's name. */ - namelen = strlen (username); - while (getline (&linebuf, &linebuf_len, fp) >= 0) - { - if ((strncmp (linebuf, username, namelen) == 0) - && (linebuf[namelen] == ':')) - { - found_it = 1; - break; - } - } - if (ferror (fp)) - error (0, errno, "cannot read %s", filename); - if (fclose (fp) < 0) - error (0, errno, "cannot close %s", filename); - - /* If found_it, then linebuf contains the information we need. */ - if (found_it) - { - char *found_password, *host_user_tmp; - char *non_cvsuser_portion; - - /* We need to make sure lines such as - * - * "username::sysuser\n" - * "username:\n" - * "username: \n" - * - * all result in a found_password of NULL, but we also need to - * make sure that - * - * "username: :sysuser\n" - * "username: :sysuser\n" - * - * continues to result in an impossible password. That way, - * an admin would be on safe ground by going in and tacking a - * space onto the front of a password to disable the account - * (a technique some people use to close accounts - * temporarily). - */ - - /* Make `non_cvsuser_portion' contain everything after the CVS - username, but null out any final newline. */ - non_cvsuser_portion = linebuf + namelen; - strtok (non_cvsuser_portion, "\n"); - - /* If there's a colon now, we just want to inch past it. */ - if (strchr (non_cvsuser_portion, ':') == non_cvsuser_portion) - non_cvsuser_portion++; - - /* Okay, after this conditional chain, found_password and - host_user_tmp will have useful values: */ - - if ((non_cvsuser_portion == NULL) - || (strlen (non_cvsuser_portion) == 0) - || ((strspn (non_cvsuser_portion, " \t")) - == strlen (non_cvsuser_portion))) - { - found_password = NULL; - host_user_tmp = NULL; - } - else if (strncmp (non_cvsuser_portion, ":", 1) == 0) - { - found_password = NULL; - host_user_tmp = non_cvsuser_portion + 1; - if (strlen (host_user_tmp) == 0) - host_user_tmp = NULL; - } - else - { - found_password = strtok (non_cvsuser_portion, ":"); - host_user_tmp = strtok (NULL, ":"); - } - - /* Of course, maybe there was no system user portion... */ - if (host_user_tmp == NULL) - host_user_tmp = username; - - /* Verify blank passwords directly, otherwise use crypt(). */ - if ((found_password == NULL) - || ((strcmp (found_password, crypt (password, found_password)) - == 0))) - { - /* Give host_user_ptr permanent storage. */ - *host_user_ptr = xstrdup (host_user_tmp); - retval = 1; - } - else - { -#ifdef LOG_AUTHPRIV - syslog (LOG_AUTHPRIV | LOG_NOTICE, - "password mismatch for %s in %s: %s vs. %s", username, - repository, crypt(password, found_password), found_password); -#endif - *host_user_ptr = NULL; - retval = 2; - } - } - else /* Didn't find this user, so deny access. */ - { - *host_user_ptr = NULL; - retval = 0; - } - - free (filename); - if (linebuf) - free (linebuf); - - return retval; -} - - - -/* Return a hosting username if password matches, else NULL. */ -static char * -check_password (username, password, repository) - char *username, *password, *repository; -{ - int rc; - char *host_user = NULL; - char *found_passwd = NULL; - struct passwd *pw; - - /* First we see if this user has a password in the CVS-specific - password file. If so, that's enough to authenticate with. If - not, we'll check /etc/passwd. */ - - if (require_real_user) - rc = 0; /* "not found" */ - else - rc = check_repository_password (username, password, repository, - &host_user); - - if (rc == 2) - return NULL; - - if (rc == 1) - { - /* host_user already set by reference, so just return. */ - goto handle_return; - } - - assert (rc == 0); - - if (!system_auth) - { - /* Note that the message _does_ distinguish between the case in - which we check for a system password and the case in which - we do not. It is a real pain to track down why it isn't - letting you in if it won't say why, and I am not convinced - that the potential information disclosure to an attacker - outweighs this. */ - printf ("error 0 no such user %s in CVSROOT/passwd\n", username); - - error_exit (); - } - - /* No cvs password found, so try /etc/passwd. */ - -#ifdef HAVE_GETSPNAM - { - struct spwd *spw; - - spw = getspnam (username); - if (spw != NULL) - { - found_passwd = spw->sp_pwdp; - } - } -#endif - - if (found_passwd == NULL && (pw = getpwnam (username)) != NULL) - { - found_passwd = pw->pw_passwd; - } - - if (found_passwd == NULL) - { - printf ("E Fatal error, aborting.\n\ -error 0 %s: no such user\n", username); - - error_exit (); - } - - /* Allow for dain bramaged HPUX passwd aging - * - Basically, HPUX adds a comma and some data - * about whether the passwd has expired or not - * on the end of the passwd field. - * - This code replaces the ',' with '\0'. - * - * FIXME - our workaround is brain damaged too. I'm - * guessing that HPUX WANTED other systems to think the - * password was wrong so logins would fail if the - * system didn't handle expired passwds and the passwd - * might be expired. I think the way to go here - * is with PAM. - */ - strtok (found_passwd, ","); - - if (*found_passwd) - { - /* user exists and has a password */ - if (strcmp (found_passwd, crypt (password, found_passwd)) == 0) - { - host_user = xstrdup (username); - } - else - { - host_user = NULL; -#ifdef LOG_AUTHPRIV - syslog (LOG_AUTHPRIV | LOG_NOTICE, - "password mismatch for %s: %s vs. %s", username, - crypt(password, found_passwd), found_passwd); -#endif - } - goto handle_return; - } - - if (password && *password) - { - /* user exists and has no system password, but we got - one as parameter */ - host_user = xstrdup (username); - goto handle_return; - } - - /* user exists but has no password at all */ - host_user = NULL; -#ifdef LOG_AUTHPRIV - syslog (LOG_AUTHPRIV | LOG_NOTICE, - "login refused for %s: user has no password", username); -#endif - -handle_return: - if (host_user) - { - /* Set CVS_Username here, in allocated space. - It might or might not be the same as host_user. */ - CVS_Username = xmalloc (strlen (username) + 1); - strcpy (CVS_Username, username); - } - - return host_user; -} - -#endif /* AUTH_SERVER_SUPPORT */ - -#if defined (AUTH_SERVER_SUPPORT) || defined (HAVE_GSSAPI) - -/* Read username and password from client (i.e., stdin). - If correct, then switch to run as that user and send an ACK to the - client via stdout, else send NACK and die. */ -void -pserver_authenticate_connection () -{ - char *tmp = NULL; - size_t tmp_allocated = 0; -#ifdef AUTH_SERVER_SUPPORT - char *repository = NULL; - size_t repository_allocated = 0; - char *username = NULL; - size_t username_allocated = 0; - char *password = NULL; - size_t password_allocated = 0; - - char *host_user; - char *descrambled_password; -#endif /* AUTH_SERVER_SUPPORT */ - int verify_and_exit = 0; - - /* The Authentication Protocol. Client sends: - * - * BEGIN AUTH REQUEST\n - * \n - * \n - * \n - * END AUTH REQUEST\n - * - * Server uses above information to authenticate, then sends - * - * I LOVE YOU\n - * - * if it grants access, else - * - * I HATE YOU\n - * - * if it denies access (and it exits if denying). - * - * When the client is "cvs login", the user does not desire actual - * repository access, but would like to confirm the password with - * the server. In this case, the start and stop strings are - * - * BEGIN VERIFICATION REQUEST\n - * - * and - * - * END VERIFICATION REQUEST\n - * - * On a verification request, the server's responses are the same - * (with the obvious semantics), but it exits immediately after - * sending the response in both cases. - * - * Why is the repository sent? Well, note that the actual - * client/server protocol can't start up until authentication is - * successful. But in order to perform authentication, the server - * needs to look up the password in the special CVS passwd file, - * before trying /etc/passwd. So the client transmits the - * repository as part of the "authentication protocol". The - * repository will be redundantly retransmitted later, but that's no - * big deal. - */ - -#ifdef SO_KEEPALIVE - /* Set SO_KEEPALIVE on the socket, so that we don't hang forever - if the client dies while we are waiting for input. */ - { - int on = 1; - - if (setsockopt (STDIN_FILENO, SOL_SOCKET, SO_KEEPALIVE, - (char *) &on, sizeof on) < 0) - { -#ifdef HAVE_SYSLOG_H - syslog (LOG_DAEMON | LOG_ERR, "error setting KEEPALIVE: %m"); -#endif - } - } -#endif - - /* Make sure the protocol starts off on the right foot... */ - if (getline_safe (&tmp, &tmp_allocated, stdin, PATH_MAX) < 0) - { -#ifdef HAVE_SYSLOG_H - syslog (LOG_DAEMON | LOG_NOTICE, "bad auth protocol start: EOF"); -#endif - error (1, 0, "bad auth protocol start: EOF"); - } - - if (strcmp (tmp, "BEGIN VERIFICATION REQUEST\n") == 0) - verify_and_exit = 1; - else if (strcmp (tmp, "BEGIN AUTH REQUEST\n") == 0) - ; - else if (strcmp (tmp, "BEGIN GSSAPI REQUEST\n") == 0) - { -#ifdef HAVE_GSSAPI - free (tmp); - gserver_authenticate_connection (); - return; -#else - error (1, 0, "GSSAPI authentication not supported by this server"); -#endif - } - else - error (1, 0, "bad auth protocol start: %s", tmp); - -#ifndef AUTH_SERVER_SUPPORT - - error (1, 0, "Password authentication not supported by this server"); - -#else /* AUTH_SERVER_SUPPORT */ - - /* Get the three important pieces of information in order. */ - /* See above comment about error handling. */ - getline_safe (&repository, &repository_allocated, stdin, PATH_MAX); - getline_safe (&username, &username_allocated, stdin, PATH_MAX); - getline_safe (&password, &password_allocated, stdin, PATH_MAX); - - /* Make them pure. - * - * We check that none of the lines were truncated by getnline in order - * to be sure that we don't accidentally allow a blind DOS attack to - * authenticate, however slim the odds of that might be. - */ - if (!strip_trailing_newlines (repository) - || !strip_trailing_newlines (username) - || !strip_trailing_newlines (password)) - error (1, 0, "Maximum line length exceeded during authentication."); - - /* ... and make sure the protocol ends on the right foot. */ - /* See above comment about error handling. */ - getline_safe (&tmp, &tmp_allocated, stdin, PATH_MAX); - if (strcmp (tmp, - verify_and_exit ? - "END VERIFICATION REQUEST\n" : "END AUTH REQUEST\n") - != 0) - { - error (1, 0, "bad auth protocol end: %s", tmp); - } - if (!root_allow_ok (repository)) - { - printf ("error 0 %s: no such repository\n", repository); -#ifdef HAVE_SYSLOG_H - syslog (LOG_DAEMON | LOG_NOTICE, "login refused for %s", repository); -#endif - goto i_hate_you; - } - - /* OK, now parse the config file, so we can use it to control how - to check passwords. If there was an error parsing the config - file, parse_config already printed an error. We keep going. - Why? Because if we didn't, then there would be no way to check - in a new CVSROOT/config file to fix the broken one! */ - parse_config (repository); - - /* We need the real cleartext before we hash it. */ - descrambled_password = descramble (password); - host_user = check_password (username, descrambled_password, repository); - if (host_user == NULL) - { -#ifdef HAVE_SYSLOG_H - syslog (LOG_DAEMON | LOG_NOTICE, "login failure (for %s)", repository); -#endif - memset (descrambled_password, 0, strlen (descrambled_password)); - free (descrambled_password); - i_hate_you: - printf ("I HATE YOU\n"); - fflush (stdout); - - /* Don't worry about server_cleanup, server_active isn't set - yet. */ - error_exit (); - } - memset (descrambled_password, 0, strlen (descrambled_password)); - free (descrambled_password); - - /* Don't go any farther if we're just responding to "cvs login". */ - if (verify_and_exit) - { - printf ("I LOVE YOU\n"); - fflush (stdout); - - /* It's okay to skip rcs_cleanup() and Lock_Cleanup() here. */ - -#ifdef SYSTEM_CLEANUP - /* Hook for OS-specific behavior, for example socket subsystems on - NT and OS2 or dealing with windows and arguments on Mac. */ - SYSTEM_CLEANUP (); -#endif - - exit (0); - } - - /* Set Pserver_Repos so that we can check later that the same - repository is sent in later client/server protocol. */ - Pserver_Repos = xmalloc (strlen (repository) + 1); - strcpy (Pserver_Repos, repository); - - /* Switch to run as this user. */ - switch_to_user (username, host_user); - free (host_user); - free (tmp); - free (repository); - free (username); - free (password); - - printf ("I LOVE YOU\n"); - fflush (stdout); -#endif /* AUTH_SERVER_SUPPORT */ -} - -#endif /* AUTH_SERVER_SUPPORT || HAVE_GSSAPI */ - - -#ifdef HAVE_KERBEROS -void -kserver_authenticate_connection () -{ - int status; - char instance[INST_SZ]; - struct sockaddr_in peer; - struct sockaddr_in laddr; - int len; - KTEXT_ST ticket; - AUTH_DAT auth; - char version[KRB_SENDAUTH_VLEN]; - char user[ANAME_SZ]; - - strcpy (instance, "*"); - len = sizeof peer; - if (getpeername (STDIN_FILENO, (struct sockaddr *) &peer, &len) < 0 - || getsockname (STDIN_FILENO, (struct sockaddr *) &laddr, - &len) < 0) - { - printf ("E Fatal error, aborting.\n\ -error %s getpeername or getsockname failed\n", strerror (errno)); - - error_exit (); - } - -#ifdef SO_KEEPALIVE - /* Set SO_KEEPALIVE on the socket, so that we don't hang forever - if the client dies while we are waiting for input. */ - { - int on = 1; - - if (setsockopt (STDIN_FILENO, SOL_SOCKET, SO_KEEPALIVE, - (char *) &on, sizeof on) < 0) - { -#ifdef HAVE_SYSLOG_H - syslog (LOG_DAEMON | LOG_ERR, "error setting KEEPALIVE: %m"); -#endif - } - } -#endif - - status = krb_recvauth (KOPT_DO_MUTUAL, STDIN_FILENO, &ticket, "rcmd", - instance, &peer, &laddr, &auth, "", sched, - version); - if (status != KSUCCESS) - { - printf ("E Fatal error, aborting.\n\ -error 0 kerberos: %s\n", krb_get_err_text(status)); - - error_exit (); - } - - memcpy (kblock, auth.session, sizeof (C_Block)); - - /* Get the local name. */ - status = krb_kntoln (&auth, user); - if (status != KSUCCESS) - { - printf ("E Fatal error, aborting.\n\ -error 0 kerberos: can't get local name: %s\n", krb_get_err_text(status)); - - error_exit (); - } - - /* Switch to run as this user. */ - switch_to_user ("Kerberos 4", user); -} -#endif /* HAVE_KERBEROS */ - -#ifdef HAVE_GSSAPI - -#ifndef MAXHOSTNAMELEN -#define MAXHOSTNAMELEN (256) -#endif - -/* Authenticate a GSSAPI connection. This is called from - pserver_authenticate_connection, and it handles success and failure - the same way. */ - -static void -gserver_authenticate_connection () -{ - char hostname[MAXHOSTNAMELEN]; - struct hostent *hp; - gss_buffer_desc tok_in, tok_out; - char buf[1024]; - char *credbuf; - size_t credbuflen; - OM_uint32 stat_min, ret; - gss_name_t server_name, client_name; - gss_cred_id_t server_creds; - int nbytes; - gss_OID mechid; - - gethostname (hostname, sizeof hostname); - hp = gethostbyname (hostname); - if (hp == NULL) - error (1, 0, "can't get canonical hostname"); - - sprintf (buf, "cvs@%s", hp->h_name); - tok_in.value = buf; - tok_in.length = strlen (buf); - - if (gss_import_name (&stat_min, &tok_in, GSS_C_NT_HOSTBASED_SERVICE, - &server_name) != GSS_S_COMPLETE) - error (1, 0, "could not import GSSAPI service name %s", buf); - - /* Acquire the server credential to verify the client's - authentication. */ - if (gss_acquire_cred (&stat_min, server_name, 0, GSS_C_NULL_OID_SET, - GSS_C_ACCEPT, &server_creds, - NULL, NULL) != GSS_S_COMPLETE) - error (1, 0, "could not acquire GSSAPI server credentials"); - - gss_release_name (&stat_min, &server_name); - - /* The client will send us a two byte length followed by that many - bytes. */ - if (fread (buf, 1, 2, stdin) != 2) - error (1, errno, "read of length failed"); - - nbytes = ((buf[0] & 0xff) << 8) | (buf[1] & 0xff); - if (nbytes <= sizeof buf) - { - credbuf = buf; - credbuflen = sizeof buf; - } - else - { - credbuflen = nbytes; - credbuf = xmalloc (credbuflen); - } - - if (fread (credbuf, 1, nbytes, stdin) != nbytes) - error (1, errno, "read of data failed"); - - gcontext = GSS_C_NO_CONTEXT; - tok_in.length = nbytes; - tok_in.value = credbuf; - - if (gss_accept_sec_context (&stat_min, - &gcontext, /* context_handle */ - server_creds, /* verifier_cred_handle */ - &tok_in, /* input_token */ - NULL, /* channel bindings */ - &client_name, /* src_name */ - &mechid, /* mech_type */ - &tok_out, /* output_token */ - &ret, - NULL, /* ignore time_rec */ - NULL) /* ignore del_cred_handle */ - != GSS_S_COMPLETE) - { - error (1, 0, "could not verify credentials"); - } - - /* FIXME: Use Kerberos v5 specific code to authenticate to a user. - We could instead use an authentication to access mapping. */ - { - krb5_context kc; - krb5_principal p; - gss_buffer_desc desc; - - krb5_init_context (&kc); - if (gss_display_name (&stat_min, client_name, &desc, - &mechid) != GSS_S_COMPLETE - || krb5_parse_name (kc, ((gss_buffer_t) &desc)->value, &p) != 0 - || krb5_aname_to_localname (kc, p, sizeof buf, buf) != 0 - || krb5_kuserok (kc, p, buf) != TRUE) - { - error (1, 0, "access denied"); - } - krb5_free_principal (kc, p); - krb5_free_context (kc); - } - - if (tok_out.length != 0) - { - char cbuf[2]; - - cbuf[0] = (tok_out.length >> 8) & 0xff; - cbuf[1] = tok_out.length & 0xff; - if (fwrite (cbuf, 1, 2, stdout) != 2 - || (fwrite (tok_out.value, 1, tok_out.length, stdout) - != tok_out.length)) - error (1, errno, "fwrite failed"); - } - - switch_to_user ("GSSAPI", buf); - - if (credbuf != buf) - free (credbuf); - - printf ("I LOVE YOU\n"); - fflush (stdout); -} - -#endif /* HAVE_GSSAPI */ - -#endif /* SERVER_SUPPORT */ - -#if defined (CLIENT_SUPPORT) || defined (SERVER_SUPPORT) - -/* This global variable is non-zero if the user requests encryption on - the command line. */ -int cvsencrypt; - -/* This global variable is non-zero if the users requests stream - authentication on the command line. */ -int cvsauthenticate; - -#ifdef HAVE_GSSAPI - -/* An buffer interface using GSSAPI. This is built on top of a - packetizing buffer. */ - -/* This structure is the closure field of the GSSAPI translation - routines. */ - -struct cvs_gssapi_wrap_data -{ - /* The GSSAPI context. */ - gss_ctx_id_t gcontext; -}; - -static int cvs_gssapi_wrap_input PROTO((void *, const char *, char *, int)); -static int cvs_gssapi_wrap_output PROTO((void *, const char *, char *, int, - int *)); - -/* Create a GSSAPI wrapping buffer. We use a packetizing buffer with - GSSAPI wrapping routines. */ - -struct buffer * -cvs_gssapi_wrap_buffer_initialize (buf, input, gcontext, memory) - struct buffer *buf; - int input; - gss_ctx_id_t gcontext; - void (*memory) PROTO((struct buffer *)); -{ - struct cvs_gssapi_wrap_data *gd; - - gd = (struct cvs_gssapi_wrap_data *) xmalloc (sizeof *gd); - gd->gcontext = gcontext; - - return (packetizing_buffer_initialize - (buf, - input ? cvs_gssapi_wrap_input : NULL, - input ? NULL : cvs_gssapi_wrap_output, - gd, - memory)); -} - -/* Unwrap data using GSSAPI. */ - -static int -cvs_gssapi_wrap_input (fnclosure, input, output, size) - void *fnclosure; - const char *input; - char *output; - int size; -{ - struct cvs_gssapi_wrap_data *gd = - (struct cvs_gssapi_wrap_data *) fnclosure; - gss_buffer_desc inbuf, outbuf; - OM_uint32 stat_min; - int conf; - - inbuf.value = (void *) input; - inbuf.length = size; - - if (gss_unwrap (&stat_min, gd->gcontext, &inbuf, &outbuf, &conf, NULL) - != GSS_S_COMPLETE) - { - error (1, 0, "gss_unwrap failed"); - } - - if (outbuf.length > size) - abort (); - - memcpy (output, outbuf.value, outbuf.length); - - /* The real packet size is stored in the data, so we don't need to - remember outbuf.length. */ - - gss_release_buffer (&stat_min, &outbuf); - - return 0; -} - -/* Wrap data using GSSAPI. */ - -static int -cvs_gssapi_wrap_output (fnclosure, input, output, size, translated) - void *fnclosure; - const char *input; - char *output; - int size; - int *translated; -{ - struct cvs_gssapi_wrap_data *gd = - (struct cvs_gssapi_wrap_data *) fnclosure; - gss_buffer_desc inbuf, outbuf; - OM_uint32 stat_min; - int conf_req, conf; - - inbuf.value = (void *) input; - inbuf.length = size; - -#ifdef ENCRYPTION - conf_req = cvs_gssapi_encrypt; -#else - conf_req = 0; -#endif - - if (gss_wrap (&stat_min, gd->gcontext, conf_req, GSS_C_QOP_DEFAULT, - &inbuf, &conf, &outbuf) != GSS_S_COMPLETE) - error (1, 0, "gss_wrap failed"); - - /* The packetizing buffer only permits us to add 100 bytes. - FIXME: I don't know what, if anything, is guaranteed by GSSAPI. - This may need to be increased for a different GSSAPI - implementation, or we may need a different algorithm. */ - if (outbuf.length > size + 100) - abort (); - - memcpy (output, outbuf.value, outbuf.length); - - *translated = outbuf.length; - - gss_release_buffer (&stat_min, &outbuf); - - return 0; -} - -#endif /* HAVE_GSSAPI */ - -#ifdef ENCRYPTION - -#ifdef HAVE_KERBEROS - -/* An encryption interface using Kerberos. This is built on top of a - packetizing buffer. */ - -/* This structure is the closure field of the Kerberos translation - routines. */ - -struct krb_encrypt_data -{ - /* The Kerberos key schedule. */ - Key_schedule sched; - /* The Kerberos DES block. */ - C_Block block; -}; - -static int krb_encrypt_input PROTO((void *, const char *, char *, int)); -static int krb_encrypt_output PROTO((void *, const char *, char *, int, - int *)); - -/* Create a Kerberos encryption buffer. We use a packetizing buffer - with Kerberos encryption translation routines. */ - -struct buffer * -krb_encrypt_buffer_initialize (buf, input, sched, block, memory) - struct buffer *buf; - int input; - Key_schedule sched; - C_Block block; - void (*memory) PROTO((struct buffer *)); -{ - struct krb_encrypt_data *kd; - - kd = (struct krb_encrypt_data *) xmalloc (sizeof *kd); - memcpy (kd->sched, sched, sizeof (Key_schedule)); - memcpy (kd->block, block, sizeof (C_Block)); - - return packetizing_buffer_initialize (buf, - input ? krb_encrypt_input : NULL, - input ? NULL : krb_encrypt_output, - kd, - memory); -} - -/* Decrypt Kerberos data. */ - -static int -krb_encrypt_input (fnclosure, input, output, size) - void *fnclosure; - const char *input; - char *output; - int size; -{ - struct krb_encrypt_data *kd = (struct krb_encrypt_data *) fnclosure; - int tcount; - - des_cbc_encrypt ((C_Block *) input, (C_Block *) output, - size, kd->sched, &kd->block, 0); - - /* SIZE is the size of the buffer, which is set by the encryption - routine. The packetizing buffer will arrange for the first two - bytes in the decrypted buffer to be the real (unaligned) - length. As a safety check, make sure that the length in the - buffer corresponds to SIZE. Note that the length in the buffer - is just the length of the data. We must add 2 to account for - the buffer count itself. */ - tcount = ((output[0] & 0xff) << 8) + (output[1] & 0xff); - if (((tcount + 2 + 7) & ~7) != size) - error (1, 0, "Decryption failure"); - - return 0; -} - -/* Encrypt Kerberos data. */ - -static int -krb_encrypt_output (fnclosure, input, output, size, translated) - void *fnclosure; - const char *input; - char *output; - int size; - int *translated; -{ - struct krb_encrypt_data *kd = (struct krb_encrypt_data *) fnclosure; - int aligned; - - /* For security against a known plaintext attack, we should - initialize any padding bytes to random values. Instead, we - just pick up whatever is on the stack, which is at least better - than using zero. */ - - /* Align SIZE to an 8 byte boundary. Note that SIZE includes the - two byte buffer count at the start of INPUT which was added by - the packetizing buffer. */ - aligned = (size + 7) & ~7; - - /* We use des_cbc_encrypt rather than krb_mk_priv because the - latter sticks a timestamp in the block, and krb_rd_priv expects - that timestamp to be within five minutes of the current time. - Given the way the CVS server buffers up data, that can easily - fail over a long network connection. We trust krb_recvauth to - guard against a replay attack. */ - - des_cbc_encrypt ((C_Block *) input, (C_Block *) output, aligned, - kd->sched, &kd->block, 1); - - *translated = aligned; - - return 0; -} - -#endif /* HAVE_KERBEROS */ -#endif /* ENCRYPTION */ -#endif /* defined (CLIENT_SUPPORT) || defined (SERVER_SUPPORT) */ - -/* Output LEN bytes at STR. If LEN is zero, then output up to (not including) - the first '\0' byte. */ - -void -cvs_output (str, len) - const char *str; - size_t len; -{ - if (len == 0) - len = strlen (str); -#ifdef SERVER_SUPPORT - if (error_use_protocol && buf_to_net != NULL) - { - buf_output (saved_output, str, len); - buf_copy_lines (buf_to_net, saved_output, 'M'); - } - else if (server_active && protocol != NULL) - { - buf_output (saved_output, str, len); - buf_copy_lines (protocol, saved_output, 'M'); - buf_send_counted (protocol); - } - else -#endif - { - size_t written; - size_t to_write = len; - const char *p = str; - - /* Local users that do 'cvs status 2>&1' on a local repository - may see the informational messages out-of-order with the - status messages unless we use the fflush (stderr) here. */ - fflush (stderr); - - while (to_write > 0) - { - written = fwrite (p, 1, to_write, stdout); - if (written == 0) - break; - p += written; - to_write -= written; - } - } -} - -/* Output LEN bytes at STR in binary mode. If LEN is zero, then - output zero bytes. */ - -void -cvs_output_binary (str, len) - char *str; - size_t len; -{ -#ifdef SERVER_SUPPORT - if (error_use_protocol || server_active) - { - struct buffer *buf; - char size_text[40]; - - if (error_use_protocol) - buf = buf_to_net; - else - buf = protocol; - - if (!supported_response ("Mbinary")) - { - error (0, 0, "\ -this client does not support writing binary files to stdout"); - return; - } - - buf_output0 (buf, "Mbinary\012"); - sprintf (size_text, "%lu\012", (unsigned long) len); - buf_output0 (buf, size_text); - - /* Not sure what would be involved in using buf_append_data here - without stepping on the toes of our caller (which is responsible - for the memory allocation of STR). */ - buf_output (buf, str, len); - - if (!error_use_protocol) - buf_send_counted (protocol); - } - else -#endif - { - size_t written; - size_t to_write = len; - const char *p = str; -#ifdef USE_SETMODE_STDOUT - int oldmode; -#endif - - /* Local users that do 'cvs status 2>&1' on a local repository - may see the informational messages out-of-order with the - status messages unless we use the fflush (stderr) here. */ - fflush (stderr); - -#ifdef USE_SETMODE_STDOUT - /* It is possible that this should be the same ifdef as - USE_SETMODE_BINARY but at least for the moment we keep them - separate. Mostly this is just laziness and/or a question - of what has been tested where. Also there might be an - issue of setmode vs. _setmode. */ - /* The Windows doc says to call setmode only right after startup. - I assume that what they are talking about can also be helped - by flushing the stream before changing the mode. */ - fflush (stdout); - oldmode = _setmode (_fileno (stdout), OPEN_BINARY); - if (oldmode < 0) - error (0, errno, "failed to setmode on stdout"); -#endif - - while (to_write > 0) - { - written = fwrite (p, 1, to_write, stdout); - if (written == 0) - break; - p += written; - to_write -= written; - } -#ifdef USE_SETMODE_STDOUT - fflush (stdout); - if (_setmode (_fileno (stdout), oldmode) != OPEN_BINARY) - error (0, errno, "failed to setmode on stdout"); -#endif - } -} - - - -/* Like CVS_OUTPUT but output is for stderr not stdout. */ -void -cvs_outerr (str, len) - const char *str; - size_t len; -{ - if (len == 0) - len = strlen (str); -#ifdef SERVER_SUPPORT - if (error_use_protocol) - { - buf_output (saved_outerr, str, len); - buf_copy_lines (buf_to_net, saved_outerr, 'E'); - } - else if (server_active) - { - buf_output (saved_outerr, str, len); - buf_copy_lines (protocol, saved_outerr, 'E'); - buf_send_counted (protocol); - } - else -#endif - { - size_t written; - size_t to_write = len; - const char *p = str; - - /* Make sure that output appears in order if stdout and stderr - point to the same place. For the server case this is taken - care of by the fact that saved_outerr always holds less - than a line. */ - fflush (stdout); - - while (to_write > 0) - { - written = fwrite (p, 1, to_write, stderr); - if (written == 0) - break; - p += written; - to_write -= written; - } - } -} - - - -/* Flush stderr. stderr is normally flushed automatically, of course, - but this function is used to flush information from the server back - to the client. */ -void -cvs_flusherr () -{ -#ifdef SERVER_SUPPORT - if (error_use_protocol) - { - /* skip the actual stderr flush in this case since the parent process - * on the server should only be writing to stdout anyhow - */ - /* Flush what we can to the network, but don't block. */ - buf_flush (buf_to_net, 0); - } - else if (server_active) - { - /* make sure stderr is flushed before we send the flush count on the - * protocol pipe - */ - fflush (stderr); - /* Send a special count to tell the parent to flush. */ - buf_send_special_count (protocol, -2); - } - else -#endif - fflush (stderr); -} - - - -/* Make it possible for the user to see what has been written to - stdout (it is up to the implementation to decide exactly how far it - should go to ensure this). */ -void -cvs_flushout () -{ -#ifdef SERVER_SUPPORT - if (error_use_protocol) - { - /* Flush what we can to the network, but don't block. */ - buf_flush (buf_to_net, 0); - } - else if (server_active) - { - /* Just do nothing. This is because the code which - cvs_flushout replaces, setting stdout to line buffering in - main.c, didn't get called in the server child process. But - in the future it is quite plausible that we'll want to make - this case work analogously to cvs_flusherr. - - FIXME - DRP - I tried to implement this and triggered the following - error: "Protocol error: uncounted data discarded". I don't need - this feature right now, so I'm not going to bother with it yet. - */ - buf_send_special_count (protocol, -1); - } - else -#endif - fflush (stdout); -} - -/* Output TEXT, tagging it according to TAG. There are lots more - details about what TAG means in cvsclient.texi but for the simple - case (e.g. non-client/server), TAG is just "newline" to output a - newline (in which case TEXT must be NULL), and any other tag to - output normal text. - - Note that there is no way to output either \0 or \n as part of TEXT. */ - -void -cvs_output_tagged (tag, text) - const char *tag; - const char *text; -{ - if (text != NULL && strchr (text, '\n') != NULL) - /* Uh oh. The protocol has no way to cope with this. For now - we dump core, although that really isn't such a nice - response given that this probably can be caused by newlines - in filenames and other causes other than bugs in CVS. Note - that we don't want to turn this into "MT newline" because - this case is a newline within a tagged item, not a newline - as extraneous sugar for the user. */ - assert (0); - - /* Start and end tags don't take any text, per cvsclient.texi. */ - if (tag[0] == '+' || tag[0] == '-') - assert (text == NULL); - -#ifdef SERVER_SUPPORT - if (server_active && supported_response ("MT")) - { - struct buffer *buf; - - if (error_use_protocol) - buf = buf_to_net; - else - buf = protocol; - - buf_output0 (buf, "MT "); - buf_output0 (buf, tag); - if (text != NULL) - { - buf_output (buf, " ", 1); - buf_output0 (buf, text); - } - buf_output (buf, "\n", 1); - - if (!error_use_protocol) - buf_send_counted (protocol); - } - else -#endif - { - if (strcmp (tag, "newline") == 0) - cvs_output ("\n", 1); - else if (text != NULL) - cvs_output (text, 0); - } -} diff --git a/contrib/cvs/src/server.h b/contrib/cvs/src/server.h deleted file mode 100644 index 4c32386..0000000 --- a/contrib/cvs/src/server.h +++ /dev/null @@ -1,202 +0,0 @@ -/* - * Copyright (C) 1986-2005 The Free Software Foundation, Inc. - * - * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot , - * and others. - * - * You may distribute under the terms of the GNU General Public License as - * specified in the README file that comes with the CVS kit. - * - * - * - * This file contains the interface between the server and the rest of CVS. - */ - -/* Miscellaneous stuff which isn't actually particularly server-specific. */ -#ifndef STDIN_FILENO -#define STDIN_FILENO 0 -#define STDOUT_FILENO 1 -#define STDERR_FILENO 2 -#endif - - -/* - * Nonzero if we are using the server. Used by various places to call - * server-specific functions. - */ -extern int server_active; - -/* - * Expand to `S', ` ', or the empty string. Used in `%s-> ...' trace printfs. - */ -#ifdef SERVER_SUPPORT -# define CLIENT_SERVER_STR ((server_active) ? "S" : " ") -#else -# define CLIENT_SERVER_STR "" -#endif - -#ifdef SERVER_SUPPORT - -/* Server functions exported to the rest of CVS. */ - -/* Run the server. */ -extern int server PROTO((int argc, char **argv)); - -/* kserver user authentication. */ -# ifdef HAVE_KERBEROS -extern void kserver_authenticate_connection PROTO ((void)); -# endif - -/* pserver user authentication. */ -# if defined (AUTH_SERVER_SUPPORT) || defined (HAVE_GSSAPI) -extern void pserver_authenticate_connection PROTO ((void)); -# endif - -/* See server.c for description. */ -extern void server_pathname_check PROTO ((char *)); - -/* We have a new Entries line for a file. TAG or DATE can be NULL. */ -extern void server_register - PROTO((const char *name, const char *version, const char *timestamp, - const char *options, const char *tag, const char *date, - const char *conflict)); - -/* Set the modification time of the next file sent. This must be - followed by a call to server_updated on the same file. */ -extern void server_modtime PROTO ((struct file_info *finfo, - Vers_TS *vers_ts)); - -/* - * We want to nuke the Entries line for a file, and (unless - * server_scratch_entry_only is subsequently called) the file itself. - */ -extern void server_scratch PROTO((const char *name)); - -/* - * The file which just had server_scratch called on it needs to have only - * the Entries line removed, not the file itself. - */ -extern void server_scratch_entry_only PROTO((void)); - -/* - * We just successfully checked in FILE (which is just the bare - * filename, with no directory). REPOSITORY is the directory for the - * repository. - */ -extern void server_checked_in - PROTO((const char *file, const char *update_dir, const char *repository)); - -extern void server_copy_file - PROTO((const char *file, const char *update_dir, const char *repository, - const char *newfile)); - -/* Send the appropriate responses for a file described by FINFO and - VERS. This is called after server_register or server_scratch. In - the latter case the file is to be removed (and VERS can be NULL). - In the former case, VERS must be non-NULL, and UPDATED indicates - whether the file is now up to date (SERVER_UPDATED, yes, - SERVER_MERGED, no, SERVER_PATCHED, yes, but file is a diff from - user version to repository version, SERVER_RCS_DIFF, yes, like - SERVER_PATCHED but with an RCS style diff). MODE is the mode the - file should get, or (mode_t) -1 if this should be obtained from the - file itself. CHECKSUM is the MD5 checksum of the file, or NULL if - this need not be sent. If FILEBUF is not NULL, it holds the - contents of the file, in which case the file itself may not exist. - If FILEBUF is not NULL, server_updated will free it. */ -enum server_updated_arg4 -{ - SERVER_UPDATED, - SERVER_MERGED, - SERVER_PATCHED, - SERVER_RCS_DIFF -}; -#ifdef __STDC__ -struct buffer; -#endif - -extern void server_updated - PROTO((struct file_info *finfo, Vers_TS *vers, - enum server_updated_arg4 updated, mode_t mode, - unsigned char *checksum, struct buffer *filebuf)); - -/* Whether we should send RCS format patches. */ -extern int server_use_rcs_diff PROTO((void)); - -/* Set the Entries.Static flag. */ -extern void server_set_entstat PROTO((const char *update_dir, - const char *repository)); -/* Clear it. */ -extern void server_clear_entstat PROTO((const char *update_dir, - const char *repository)); - -/* Set or clear a per-directory sticky tag or date. */ -extern void server_set_sticky PROTO((const char *update_dir, - const char *repository, const char *tag, - const char *date, int nonbranch)); -/* Send Template response. */ -extern void server_template PROTO ((const char *, const char *)); - -extern void server_update_entries - PROTO((const char *file, const char *update_dir, const char *repository, - enum server_updated_arg4 updated)); - -/* Pointer to a malloc'd string which is the directory which - the server should prepend to the pathnames which it sends - to the client. */ -extern char *server_dir; - -extern void server_cleanup PROTO((int sig)); - -#ifdef SERVER_FLOWCONTROL -/* Pause if it's convenient to avoid memory blowout */ -extern void server_pause_check PROTO((void)); -#endif /* SERVER_FLOWCONTROL */ - -#ifdef AUTH_SERVER_SUPPORT -extern char *CVS_Username; -extern int system_auth; -#endif /* AUTH_SERVER_SUPPORT */ - -#endif /* SERVER_SUPPORT */ - -/* Stuff shared with the client. */ -struct request -{ - /* Name of the request. */ - char *name; - -#ifdef SERVER_SUPPORT - /* - * Function to carry out the request. ARGS is the text of the command - * after name and, if present, a single space, have been stripped off. - */ - void (*func) PROTO((char *args)); -#endif - - /* One or more of the RQ_* flags described below. */ - int flags; - - /* If set, failure to implement this request can imply a fatal - error. This should be set only for commands which were in the - original version of the protocol; it should not be set for new - commands. */ -#define RQ_ESSENTIAL 1 - - /* Set by the client if the server we are talking to supports it. */ -#define RQ_SUPPORTED 2 - - /* If set, and client and server both support the request, the - client should tell the server by making the request. */ -#define RQ_ENABLEME 4 - - /* The server may accept this request before "Root". */ -#define RQ_ROOTLESS 8 -}; - -/* Table of requests ending with an entry with a NULL name. */ -extern struct request requests[]; - -/* Gzip library, see zlib.c. */ -extern int gunzip_and_write PROTO ((int, char *, unsigned char *, size_t)); -extern int read_and_gzip PROTO ((int, const char *, unsigned char **, size_t *, - size_t *, int)); diff --git a/contrib/cvs/src/stack.c b/contrib/cvs/src/stack.c deleted file mode 100644 index 22a1088..0000000 --- a/contrib/cvs/src/stack.c +++ /dev/null @@ -1,188 +0,0 @@ -/* - * Copyright (C) 2004-2005 The Free Software Foundation, Inc. - * - * Portions Copyright (C) 2004-2005 Derek Price, Ximbiot , - * and others. - * - * You may distribute under the terms of the GNU General Public License as - * specified in the README file that comes with the CVS source distribution. - * - * This module uses the hash.c module to implement a stack. - */ - -#include "cvs.h" -#include - - - -static void -do_push (stack, elem, isstring) - List *stack; - void *elem; - int isstring; -{ - Node *p = getnode(); - - if (isstring) - p->key = elem; - else - p->data = elem; - - addnode(stack, p); -} - - - -void -push (stack, elem) - List *stack; - void *elem; -{ - do_push (stack, elem, 0); -} - - - -void -push_string (stack, elem) - List *stack; - char *elem; -{ - do_push (stack, elem, 1); -} - - - -static void * -do_pop (stack, isstring) - List *stack; - int isstring; -{ - void *elem; - - if (isempty (stack)) return NULL; - - if (isstring) - { - elem = stack->list->prev->key; - stack->list->prev->key = NULL; - } - else - { - elem = stack->list->prev->data; - stack->list->prev->data = NULL; - } - - delnode (stack->list->prev); - return elem; -} - - - -void * -pop (stack) - List *stack; -{ - return do_pop (stack, 0); -} - - - -char * -pop_string (stack) - List *stack; -{ - return do_pop (stack, 1); -} - - - -static void -do_unshift (stack, elem, isstring) - List *stack; - void *elem; - int isstring; -{ - Node *p = getnode(); - - if (isstring) - p->key = elem; - else - p->data = elem; - - addnode_at_front(stack, p); -} - - - -void -unshift (stack, elem) - List *stack; - void *elem; -{ - do_unshift (stack, elem, 0); -} - - - -void -unshift_string (stack, elem) - List *stack; - char *elem; -{ - do_unshift (stack, elem, 1); -} - - - -static void * -do_shift (stack, isstring) - List *stack; - int isstring; -{ - void *elem; - - if (isempty (stack)) return NULL; - - if (isstring) - { - elem = stack->list->next->key; - stack->list->next->key = NULL; - } - else - { - elem = stack->list->next->data; - stack->list->next->data = NULL; - } - delnode (stack->list->next); - return elem; -} - - - -void * -shift (stack) - List *stack; -{ - return do_shift (stack, 0); -} - - - -char * -shift_string (stack) - List *stack; -{ - return do_shift (stack, 1); -} - - - -int -isempty (stack) - List *stack; -{ - if (stack->list == stack->list->next) - return 1; - return 0; -} diff --git a/contrib/cvs/src/stack.h b/contrib/cvs/src/stack.h deleted file mode 100644 index 822010b..0000000 --- a/contrib/cvs/src/stack.h +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright (c) 2004-2005 The Free Software Foundation, - * Derek Price, and Ximbiot . - * - * You may distribute under the terms of the GNU General Public License as - * specified in the README file that comes with the CVS source distribution. - */ - -void push PROTO((List *_stack, void *_elem)); -void *pop PROTO((List *_stack)); -void unshift PROTO((List *_stack, void *_elem)); -void *shift PROTO((List *_stack)); -void push_string PROTO((List *_stack, char *_elem)); -char *pop_string PROTO((List *_stack)); -void unshift_string PROTO((List *_stack, char *_elem)); -char *shift_string PROTO((List *_stack)); -int isempty PROTO((List *_stack)); diff --git a/contrib/cvs/src/status.c b/contrib/cvs/src/status.c deleted file mode 100644 index 7a828ae..0000000 --- a/contrib/cvs/src/status.c +++ /dev/null @@ -1,357 +0,0 @@ -/* - * Copyright (C) 1986-2005 The Free Software Foundation, Inc. - * - * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot , - * and others. - * - * Portions Copyright (C) 1992, Brian Berliner and Jeff Polk - * Portions Copyright (C) 1989-1992, Brian Berliner - * - * You may distribute under the terms of the GNU General Public License as - * specified in the README file that comes with the CVS source distribution. - * - * Status Information - */ - -#include "cvs.h" - -static Dtype status_dirproc PROTO ((void *callerdat, const char *dir, - const char *repos, const char *update_dir, - List *entries)); -static int status_fileproc PROTO ((void *callerdat, struct file_info *finfo)); -static int tag_list_proc PROTO((Node * p, void *closure)); - -static int local = 0; -static int long_format = 0; -static RCSNode *xrcsnode; - -static const char *const status_usage[] = -{ - "Usage: %s %s [-vlR] [files...]\n", - "\t-v\tVerbose format; includes tag information for the file\n", - "\t-l\tProcess this directory only (not recursive).\n", - "\t-R\tProcess directories recursively.\n", - "(Specify the --help global option for a list of other help options)\n", - NULL -}; - -int -cvsstatus (argc, argv) - int argc; - char **argv; -{ - int c; - int err = 0; - - if (argc == -1) - usage (status_usage); - - optind = 0; - while ((c = getopt (argc, argv, "+vlR")) != -1) - { - switch (c) - { - case 'v': - long_format = 1; - break; - case 'l': - local = 1; - break; - case 'R': - local = 0; - break; - case '?': - default: - usage (status_usage); - break; - } - } - argc -= optind; - argv += optind; - - wrap_setup (); - -#ifdef CLIENT_SUPPORT - if (current_parsed_root->isremote) - { - start_server (); - - ign_setup (); - - if (long_format) - send_arg("-v"); - if (local) - send_arg("-l"); - send_arg ("--"); - - /* For a while, we tried setting SEND_NO_CONTENTS here so this - could be a fast operation. That prevents the - server from updating our timestamp if the timestamp is - changed but the file is unmodified. Worse, it is user-visible - (shows "locally modified" instead of "up to date" if - timestamp is changed but file is not). And there is no good - workaround (you might not want to run "cvs update"; "cvs -n - update" doesn't update CVS/Entries; "cvs diff --brief" or - something perhaps could be made to work but somehow that - seems nonintuitive to me even if so). Given that timestamps - seem to have the potential to get munged for any number of - reasons, it seems better to not rely too much on them. */ - - send_files (argc, argv, local, 0, 0); - - send_file_names (argc, argv, SEND_EXPAND_WILD); - - send_to_server ("status\012", 0); - err = get_responses_and_close (); - - return err; - } -#endif - - /* start the recursion processor */ - err = start_recursion (status_fileproc, (FILESDONEPROC) NULL, - status_dirproc, (DIRLEAVEPROC) NULL, NULL, - argc, argv, local, - W_LOCAL, 0, CVS_LOCK_READ, (char *) NULL, 1, - (char *) NULL); - - return (err); -} - -/* - * display the status of a file - */ -/* ARGSUSED */ -static int -status_fileproc (callerdat, finfo) - void *callerdat; - struct file_info *finfo; -{ - Ctype status; - char *sstat; - Vers_TS *vers; - - status = Classify_File (finfo, (char *) NULL, (char *) NULL, (char *) NULL, - 1, 0, &vers, 0); - sstat = "Classify Error"; - switch (status) - { - case T_UNKNOWN: - sstat = "Unknown"; - break; - case T_CHECKOUT: - sstat = "Needs Checkout"; - break; - case T_PATCH: - sstat = "Needs Patch"; - break; - case T_CONFLICT: - sstat = "Unresolved Conflict"; - break; - case T_ADDED: - sstat = "Locally Added"; - break; - case T_REMOVED: - sstat = "Locally Removed"; - break; - case T_MODIFIED: - if (file_has_markers (finfo)) - sstat = "File had conflicts on merge"; - else - /* Note that we do not re Register() the file when we spot - * a resolved conflict like update_fileproc() does on the - * premise that status should not alter the sandbox. - */ - sstat = "Locally Modified"; - break; - case T_REMOVE_ENTRY: - sstat = "Entry Invalid"; - break; - case T_UPTODATE: - sstat = "Up-to-date"; - break; - case T_NEEDS_MERGE: - sstat = "Needs Merge"; - break; - case T_TITLE: - /* I don't think this case can occur here. Just print - "Classify Error". */ - break; - } - - cvs_output ("\ -===================================================================\n", 0); - if (vers->ts_user == NULL) - { - cvs_output ("File: no file ", 0); - cvs_output (finfo->file, 0); - cvs_output ("\t\tStatus: ", 0); - cvs_output (sstat, 0); - cvs_output ("\n\n", 0); - } - else - { - char *buf; - buf = xmalloc (strlen (finfo->file) + strlen (sstat) + 80); - sprintf (buf, "File: %-17s\tStatus: %s\n\n", finfo->file, sstat); - cvs_output (buf, 0); - free (buf); - } - - if (vers->vn_user == NULL) - { - cvs_output (" Working revision:\tNo entry for ", 0); - cvs_output (finfo->file, 0); - cvs_output ("\n", 0); - } - else if (vers->vn_user[0] == '0' && vers->vn_user[1] == '\0') - cvs_output (" Working revision:\tNew file!\n", 0); - else - { - cvs_output (" Working revision:\t", 0); - cvs_output (vers->vn_user, 0); - if (!server_active) - { - cvs_output ("\t", 0); - cvs_output (vers->ts_rcs, 0); - } - cvs_output ("\n", 0); - } - - if (vers->vn_rcs == NULL) - cvs_output (" Repository revision:\tNo revision control file\n", 0); - else - { - cvs_output (" Repository revision:\t", 0); - cvs_output (vers->vn_rcs, 0); - cvs_output ("\t", 0); - cvs_output (vers->srcfile->path, 0); - cvs_output ("\n", 0); - } - - if (vers->entdata) - { - Entnode *edata; - - edata = vers->entdata; - if (edata->tag) - { - if (vers->vn_rcs == NULL) - { - cvs_output (" Sticky Tag:\t\t", 0); - cvs_output (edata->tag, 0); - cvs_output (" - MISSING from RCS file!\n", 0); - } - else - { - if (isdigit ((unsigned char) edata->tag[0])) - { - cvs_output (" Sticky Tag:\t\t", 0); - cvs_output (edata->tag, 0); - cvs_output ("\n", 0); - } - else - { - char *branch = NULL; - - if (RCS_nodeisbranch (finfo->rcs, edata->tag)) - branch = RCS_whatbranch(finfo->rcs, edata->tag); - - cvs_output (" Sticky Tag:\t\t", 0); - cvs_output (edata->tag, 0); - cvs_output (" (", 0); - cvs_output (branch ? "branch" : "revision", 0); - cvs_output (": ", 0); - cvs_output (branch ? branch : vers->vn_rcs, 0); - cvs_output (")\n", 0); - - if (branch) - free (branch); - } - } - } - else if (!really_quiet) - cvs_output (" Sticky Tag:\t\t(none)\n", 0); - - if (edata->date) - { - cvs_output (" Sticky Date:\t\t", 0); - cvs_output (edata->date, 0); - cvs_output ("\n", 0); - } - else if (!really_quiet) - cvs_output (" Sticky Date:\t\t(none)\n", 0); - - if (edata->options && edata->options[0]) - { - cvs_output (" Sticky Options:\t", 0); - cvs_output (edata->options, 0); - cvs_output ("\n", 0); - } - else if (!really_quiet) - cvs_output (" Sticky Options:\t(none)\n", 0); - } - - if (long_format && vers->srcfile) - { - List *symbols = RCS_symbols(vers->srcfile); - - cvs_output ("\n Existing Tags:\n", 0); - if (symbols) - { - xrcsnode = finfo->rcs; - (void) walklist (symbols, tag_list_proc, NULL); - } - else - cvs_output ("\tNo Tags Exist\n", 0); - } - - cvs_output ("\n", 0); - freevers_ts (&vers); - return (0); -} - -/* - * Print a warm fuzzy message - */ -/* ARGSUSED */ -static Dtype -status_dirproc (callerdat, dir, repos, update_dir, entries) - void *callerdat; - const char *dir; - const char *repos; - const char *update_dir; - List *entries; -{ - if (!quiet) - error (0, 0, "Examining %s", update_dir); - return (R_PROCESS); -} - -/* - * Print out a tag and its type - */ -static int -tag_list_proc (p, closure) - Node *p; - void *closure; -{ - char *branch = NULL; - char *buf; - - if (RCS_nodeisbranch (xrcsnode, p->key)) - branch = RCS_whatbranch(xrcsnode, p->key) ; - - buf = xmalloc (80 + strlen (p->key) - + (branch ? strlen (branch) : strlen (p->data))); - sprintf (buf, "\t%-25s\t(%s: %s)\n", p->key, - branch ? "branch" : "revision", - branch ? branch : (char *)p->data); - cvs_output (buf, 0); - free (buf); - - if (branch) - free (branch); - - return (0); -} diff --git a/contrib/cvs/src/subr.c b/contrib/cvs/src/subr.c deleted file mode 100644 index faa988a..0000000 --- a/contrib/cvs/src/subr.c +++ /dev/null @@ -1,968 +0,0 @@ -/* - * Copyright (C) 1986-2005 The Free Software Foundation, Inc. - * - * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot , - * and others. - * - * Portions Copyright (C) 1992, Brian Berliner and Jeff Polk - * Portions Copyright (C) 1989-1992, Brian Berliner - * - * You may distribute under the terms of the GNU General Public License as - * specified in the README file that comes with the CVS source distribution. - * - * Various useful functions for the CVS support code. - */ - -#include -#include "cvs.h" -#include "getline.h" - -#ifdef HAVE_NANOSLEEP -# include "xtime.h" -#else /* HAVE_NANOSLEEP */ -# if !defined HAVE_USLEEP && defined HAVE_SELECT - /* use select as a workaround */ -# include "xselect.h" -# endif /* !defined HAVE_USLEEP && defined HAVE_SELECT */ -#endif /* !HAVE_NANOSLEEP */ - -extern char *getlogin (); - -/* - * malloc some data and die if it fails - */ -void * -xmalloc (bytes) - size_t bytes; -{ - char *cp; - - /* Parts of CVS try to xmalloc zero bytes and then free it. Some - systems have a malloc which returns NULL for zero byte - allocations but a free which can't handle NULL, so compensate. */ - if (bytes == 0) - bytes = 1; - - cp = malloc (bytes); - if (cp == NULL) - { - char buf[80]; - sprintf (buf, "out of memory; can not allocate %lu bytes", - (unsigned long) bytes); - error (1, 0, buf); - } - return (cp); -} - -/* - * realloc data and die if it fails [I've always wanted to have "realloc" do - * a "malloc" if the argument is NULL, but you can't depend on it. Here, I - * can *force* it.] - */ -void * -xrealloc (ptr, bytes) - void *ptr; - size_t bytes; -{ - char *cp; - - if (!ptr) - cp = malloc (bytes); - else - cp = realloc (ptr, bytes); - - if (cp == NULL) - { - char buf[80]; - sprintf (buf, "out of memory; can not reallocate %lu bytes", - (unsigned long) bytes); - error (1, 0, buf); - } - return (cp); -} - -/* Two constants which tune expand_string. Having MIN_INCR as large - as 1024 might waste a bit of memory, but it shouldn't be too bad - (CVS used to allocate arrays of, say, 3000, PATH_MAX (8192, often), - or other such sizes). Probably anything which is going to allocate - memory which is likely to get as big as MAX_INCR shouldn't be doing - it in one block which must be contiguous, but since getrcskey does - so, we might as well limit the wasted memory to MAX_INCR or so - bytes. - - MIN_INCR and MAX_INCR should both be powers of two and we generally - try to keep our allocations to powers of two for the most part. - Most malloc implementations these days tend to like that. */ - -#define MIN_INCR 1024 -#define MAX_INCR (2*1024*1024) - -/* *STRPTR is a pointer returned from malloc (or NULL), pointing to *N - characters of space. Reallocate it so that points to at least - NEWSIZE bytes of space. Gives a fatal error if out of memory; - if it returns it was successful. */ -void -expand_string (strptr, n, newsize) - char **strptr; - size_t *n; - size_t newsize; -{ - if (*n < newsize) - { - while (*n < newsize) - { - if (*n < MIN_INCR) - *n = MIN_INCR; - else if (*n >= MAX_INCR) - *n += MAX_INCR; - else - { - *n *= 2; - if (*n > MAX_INCR) - *n = MAX_INCR; - } - } - *strptr = xrealloc (*strptr, *n); - } -} - -/* *STR is a pointer to a malloc'd string. *LENP is its allocated - length. Add SRC to the end of it, reallocating if necessary. */ -void -xrealloc_and_strcat (str, lenp, src) - char **str; - size_t *lenp; - const char *src; -{ - - expand_string (str, lenp, strlen (*str) + strlen (src) + 1); - strcat (*str, src); -} - -/* - * Duplicate a string, calling xmalloc to allocate some dynamic space - */ -char * -xstrdup (str) - const char *str; -{ - char *s; - - if (str == NULL) - return ((char *) NULL); - s = xmalloc (strlen (str) + 1); - (void) strcpy (s, str); - return (s); -} - - - -/* Remove trailing newlines from STRING, destructively. - * - * RETURNS - * - * True if any newlines were removed, false otherwise. - */ -int -strip_trailing_newlines (str) - char *str; -{ - size_t index, origlen; - index = origlen = strlen (str); - - while (index > 0 && str[index-1] == '\n') - str[--index] = '\0'; - - return index != origlen; -} - - - -/* Return the number of levels that PATH ascends above where it starts. - * For example: - * - * "../../foo" -> 2 - * "foo/../../bar" -> 1 - */ -int -pathname_levels (p) - const char *p; -{ - int level; - int max_level; - - if (p == NULL) return 0; - - max_level = 0; - level = 0; - do - { - /* Now look for pathname level-ups. */ - if (p[0] == '.' && p[1] == '.' && (p[2] == '\0' || ISDIRSEP (p[2]))) - { - --level; - if (-level > max_level) - max_level = -level; - } - else if (p[0] == '\0' || ISDIRSEP (p[0]) || - (p[0] == '.' && (p[1] == '\0' || ISDIRSEP (p[1])))) - ; - else - ++level; - - /* q = strchr (p, '/'); but sub ISDIRSEP() for '/': */ - while (*p != '\0' && !ISDIRSEP (*p)) p++; - if (*p != '\0') p++; - } while (*p != '\0'); - return max_level; -} - - - -/* Free a vector, where (*ARGV)[0], (*ARGV)[1], ... (*ARGV)[*PARGC - 1] - are malloc'd and so is *ARGV itself. Such a vector is allocated by - line2argv or expand_wild, for example. */ -void -free_names (pargc, argv) - int *pargc; - char **argv; -{ - register int i; - - for (i = 0; i < *pargc; i++) - { /* only do through *pargc */ - free (argv[i]); - } - free (argv); - *pargc = 0; /* and set it to zero when done */ -} - -/* Convert LINE into arguments separated by SEPCHARS. Set *ARGC - to the number of arguments found, and (*ARGV)[0] to the first argument, - (*ARGV)[1] to the second, etc. *ARGV is malloc'd and so are each of - (*ARGV)[0], (*ARGV)[1], ... Use free_names() to return the memory - allocated here back to the free pool. */ -void -line2argv (pargc, argv, line, sepchars) - int *pargc; - char ***argv; - char *line; - char *sepchars; -{ - char *cp; - /* Could make a case for size_t or some other unsigned type, but - we'll stick with int to avoid signed/unsigned warnings when - comparing with *pargc. */ - int argv_allocated; - - /* Small for testing. */ - argv_allocated = 1; - *argv = (char **) xmalloc (argv_allocated * sizeof (**argv)); - - *pargc = 0; - for (cp = strtok (line, sepchars); cp; cp = strtok ((char *) NULL, sepchars)) - { - if (*pargc == argv_allocated) - { - argv_allocated *= 2; - *argv = xrealloc (*argv, argv_allocated * sizeof (**argv)); - } - (*argv)[*pargc] = xstrdup (cp); - (*pargc)++; - } -} - -/* - * Returns the number of dots ('.') found in an RCS revision number - */ -int -numdots (s) - const char *s; -{ - int dots = 0; - - for (; *s; s++) - { - if (*s == '.') - dots++; - } - return (dots); -} - -/* Compare revision numbers REV1 and REV2 by consecutive fields. - Return negative, zero, or positive in the manner of strcmp. The - two revision numbers must have the same number of fields, or else - compare_revnums will return an inaccurate result. */ -int -compare_revnums (rev1, rev2) - const char *rev1; - const char *rev2; -{ - const char *sp, *tp; - char *snext, *tnext; - int result = 0; - - sp = rev1; - tp = rev2; - while (result == 0) - { - result = strtoul (sp, &snext, 10) - strtoul (tp, &tnext, 10); - if (*snext == '\0' || *tnext == '\0') - break; - sp = snext + 1; - tp = tnext + 1; - } - - return result; -} - -/* Increment a revision number. Working on the string is a bit awkward, - but it avoid problems with integer overflow should the revision numbers - get really big. */ -char * -increment_revnum (rev) - const char *rev; -{ - char *newrev, *p; - size_t len = strlen (rev); - - newrev = xmalloc (len + 2); - memcpy (newrev, rev, len + 1); - for (p = newrev + len; p != newrev; ) - { - --p; - if (!isdigit(*p)) - { - ++p; - break; - } - if (*p != '9') - { - ++*p; - return newrev; - } - *p = '0'; - } - /* The number was all 9s, so change the first character to 1 and add - a 0 to the end. */ - *p = '1'; - p = newrev + len; - *p++ = '0'; - *p = '\0'; - return newrev; -} - -/* Return the username by which the caller should be identified in - CVS, in contexts such as the author field of RCS files, various - logs, etc. */ -char * -getcaller () -{ -#ifndef SYSTEM_GETCALLER - static char *cache; - struct passwd *pw; - uid_t uid; -#endif - - /* If there is a CVS username, return it. */ -#ifdef AUTH_SERVER_SUPPORT - if (CVS_Username != NULL) - return CVS_Username; -#endif - -#ifdef SYSTEM_GETCALLER - return SYSTEM_GETCALLER (); -#else - /* Get the caller's login from his uid. If the real uid is "root" - try LOGNAME USER or getlogin(). If getlogin() and getpwuid() - both fail, return the uid as a string. */ - - if (cache != NULL) - return cache; - - uid = getuid (); - if (uid == (uid_t) 0) - { - char *name; - - /* super-user; try getlogin() to distinguish */ - if (((name = getlogin ()) || (name = getenv("LOGNAME")) || - (name = getenv("USER"))) && *name) - { - cache = xstrdup (name); - return cache; - } - } - if ((pw = (struct passwd *) getpwuid (uid)) == NULL) - { - char uidname[20]; - - (void) sprintf (uidname, "uid%lu", (unsigned long) uid); - cache = xstrdup (uidname); - return cache; - } - cache = xstrdup (pw->pw_name); - return cache; -#endif -} - -#ifdef lint -#ifndef __GNUC__ -/* ARGSUSED */ -time_t -get_date (date, now) - char *date; - struct timeb *now; -{ - time_t foo = 0; - - return (foo); -} -#endif -#endif - - - -/* Given some revision, REV, return the first prior revision that exists in the - * RCS file, RCS. - * - * ASSUMPTIONS - * REV exists. - * - * INPUTS - * RCS The RCS node pointer. - * REV An existing revision in the RCS file referred to by RCS. - * - * RETURNS - * The first prior revision that exists in the RCS file, or NULL if no prior - * revision exists. The caller is responsible for disposing of this string. - * - * NOTES - * This function currently neglects the case where we are on the trunk with - * rev = X.1, where X != 1. If rev = X.Y, where X != 1 and Y > 1, then this - * function should work fine, as revision X.1 must exist, due to RCS rules. - */ -char * -previous_rev (rcs, rev) - RCSNode *rcs; - const char *rev; -{ - char *p; - char *tmp = xstrdup (rev); - long r1; - char *retval; - - /* Our retval can have no more digits and dots than our input revision. */ - retval = xmalloc (strlen (rev) + 1); - p = strrchr (tmp, '.'); - *p = '\0'; - r1 = strtol (p+1, NULL, 10); - do { - if (--r1 == 0) - { - /* If r1 == 0, then we must be on a branch and our parent must - * exist, or we must be on the trunk with a REV like X.1. - * We are neglecting the X.1 with X != 1 case by assuming that - * there is no previous revision when we discover we were on - * the trunk. - */ - p = strrchr (tmp, '.'); - if (p == NULL) - /* We are on the trunk. */ - retval = NULL; - else - { - *p = '\0'; - sprintf (retval, "%s", tmp); - } - break; - } - sprintf (retval, "%s.%ld", tmp, r1); - } while (!RCS_exist_rev (rcs, retval)); - - free (tmp); - return retval; -} - - - -/* Given two revisions, find their greatest common ancestor. If the - two input revisions exist, then rcs guarantees that the gca will - exist. */ - -char * -gca (rev1, rev2) - const char *rev1; - const char *rev2; -{ - int dots; - char *gca, *g; - const char *p1, *p2; - int r1, r2; - char *retval; - - if (rev1 == NULL || rev2 == NULL) - { - error (0, 0, "sanity failure in gca"); - abort(); - } - - /* The greatest common ancestor will have no more dots, and numbers - of digits for each component no greater than the arguments. Therefore - this string will be big enough. */ - g = gca = xmalloc (strlen (rev1) + strlen (rev2) + 100); - - /* walk the strings, reading the common parts. */ - p1 = rev1; - p2 = rev2; - do - { - r1 = strtol (p1, (char **) &p1, 10); - r2 = strtol (p2, (char **) &p2, 10); - - /* use the lowest. */ - (void) sprintf (g, "%d.", r1 < r2 ? r1 : r2); - g += strlen (g); - if (*p1 == '.') ++p1; - else break; - if (*p2 == '.') ++p2; - else break; - } while (r1 == r2); - - /* erase that last dot. */ - *--g = '\0'; - - /* numbers differ, or we ran out of strings. we're done with the - common parts. */ - - dots = numdots (gca); - if (dots == 0) - { - /* revisions differ in trunk major number. */ - - if (r2 < r1) p1 = p2; - if (*p1 == '\0') - { - /* we only got one number. this is strange. */ - error (0, 0, "bad revisions %s or %s", rev1, rev2); - abort(); - } - else - { - /* we have a minor number. use it. */ - *g++ = '.'; - while (*p1 != '.' && *p1 != '\0') - *g++ = *p1++; - *g = '\0'; - } - } - else if ((dots & 1) == 0) - { - /* if we have an even number of dots, then we have a branch. - remove the last number in order to make it a revision. */ - - g = strrchr (gca, '.'); - *g = '\0'; - } - - retval = xstrdup (gca); - free (gca); - return retval; -} - -/* Give fatal error if REV is numeric and ARGC,ARGV imply we are - planning to operate on more than one file. The current directory - should be the working directory. Note that callers assume that we - will only be checking the first character of REV; it need not have - '\0' at the end of the tag name and other niceties. Right now this - is only called from admin.c, but if people like the concept it probably - should also be called from diff -r, update -r, get -r, and log -r. */ - -void -check_numeric (rev, argc, argv) - const char *rev; - int argc; - char **argv; -{ - if (rev == NULL || !isdigit ((unsigned char) *rev)) - return; - - /* Note that the check for whether we are processing more than one - file is (basically) syntactic; that is, we don't behave differently - depending on whether a directory happens to contain only a single - file or whether it contains more than one. I strongly suspect this - is the least confusing behavior. */ - if (argc != 1 - || (!wrap_name_has (argv[0], WRAP_TOCVS) && isdir (argv[0]))) - { - error (0, 0, "while processing more than one file:"); - error (1, 0, "attempt to specify a numeric revision"); - } -} - -/* - * Sanity checks and any required fix-up on message passed to RCS via '-m'. - * RCS 5.7 requires that a non-total-whitespace, non-null message be provided - * with '-m'. Returns a newly allocated, non-empty buffer with whitespace - * stripped from end of lines and end of buffer. - * - * TODO: We no longer use RCS to manage repository files, so maybe this - * nonsense about non-empty log fields can be dropped. - */ -char * -make_message_rcslegal (message) - const char *message; -{ - char *dst, *dp; - const char *mp; - - if (message == NULL) message = ""; - - /* Strip whitespace from end of lines and end of string. */ - dp = dst = (char *) xmalloc (strlen (message) + 1); - for (mp = message; *mp != '\0'; ++mp) - { - if (*mp == '\n') - { - /* At end-of-line; backtrack to last non-space. */ - while (dp > dst && (dp[-1] == ' ' || dp[-1] == '\t')) - --dp; - } - *dp++ = *mp; - } - - /* Backtrack to last non-space at end of string, and truncate. */ - while (dp > dst && isspace ((unsigned char) dp[-1])) - --dp; - *dp = '\0'; - - /* After all that, if there was no non-space in the string, - substitute a non-empty message. */ - if (*dst == '\0') - { - free (dst); - dst = xstrdup ("*** empty log message ***"); - } - - return dst; -} - - - -/* Does the file FINFO contain conflict markers? The whole concept - of looking at the contents of the file to figure out whether there are - unresolved conflicts is kind of bogus (people do want to manage files - which contain those patterns not as conflict markers), but for now it - is what we do. */ -int -file_has_markers (finfo) - const struct file_info *finfo; -{ - FILE *fp; - char *line = NULL; - size_t line_allocated = 0; - int result; - - result = 0; - fp = CVS_FOPEN (finfo->file, "r"); - if (fp == NULL) - error (1, errno, "cannot open %s", finfo->fullname); - while (getline (&line, &line_allocated, fp) > 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; - } - } - if (ferror (fp)) - error (0, errno, "cannot read %s", finfo->fullname); -out: - if (fclose (fp) < 0) - error (0, errno, "cannot close %s", finfo->fullname); - if (line != NULL) - free (line); - return result; -} - -/* Read the entire contents of the file NAME into *BUF. - If NAME is NULL, read from stdin. *BUF - is a pointer returned from malloc (or NULL), pointing to *BUFSIZE - bytes of space. The actual size is returned in *LEN. On error, - give a fatal error. The name of the file to use in error messages - (typically will include a directory if we have changed directory) - is FULLNAME. MODE is "r" for text or "rb" for binary. */ - -void -get_file (name, fullname, mode, buf, bufsize, len) - const char *name; - const char *fullname; - const char *mode; - char **buf; - size_t *bufsize; - size_t *len; -{ - struct stat s; - size_t nread; - char *tobuf; - FILE *e; - size_t filesize; - - if (name == NULL) - { - e = stdin; - filesize = 100; /* force allocation of minimum buffer */ - } - else - { - /* Although it would be cleaner in some ways to just read - until end of file, reallocating the buffer, this function - does get called on files in the working directory which can - be of arbitrary size, so I think we better do all that - extra allocation. */ - - if (CVS_STAT (name, &s) < 0) - error (1, errno, "can't stat %s", fullname); - - /* Convert from signed to unsigned. */ - filesize = s.st_size; - - e = open_file (name, mode); - } - - if (*buf == NULL || *bufsize <= filesize) - { - *bufsize = filesize + 1; - *buf = xrealloc (*buf, *bufsize); - } - - tobuf = *buf; - nread = 0; - while (1) - { - size_t got; - - got = fread (tobuf, 1, *bufsize - (tobuf - *buf), e); - if (ferror (e)) - error (1, errno, "can't read %s", fullname); - nread += got; - tobuf += got; - - if (feof (e)) - break; - - /* Allocate more space if needed. */ - if (tobuf == *buf + *bufsize) - { - int c; - long off; - - c = getc (e); - if (c == EOF) - break; - off = tobuf - *buf; - expand_string (buf, bufsize, *bufsize + 100); - tobuf = *buf + off; - *tobuf++ = c; - ++nread; - } - } - - if (e != stdin && fclose (e) < 0) - error (0, errno, "cannot close %s", fullname); - - *len = nread; - - /* Force *BUF to be large enough to hold a null terminator. */ - if (nread == *bufsize) - expand_string (buf, bufsize, *bufsize + 1); - (*buf)[nread] = '\0'; -} - - -/* Follow a chain of symbolic links to its destination. FILENAME - should be a handle to a malloc'd block of memory which contains the - beginning of the chain. This routine will replace the contents of - FILENAME with the destination (a real file). */ - -void -resolve_symlink (filename) - char **filename; -{ - if (filename == NULL || *filename == NULL) - return; - - while (islink (*filename)) - { -#ifdef HAVE_READLINK - /* The clean thing to do is probably to have each filesubr.c - implement this (with an error if not supported by the - platform, in which case islink would presumably return 0). - But that would require editing each filesubr.c and so the - expedient hack seems to be looking at HAVE_READLINK. */ - char *newname = xreadlink (*filename); - - if (isabsolute (newname)) - { - free (*filename); - *filename = newname; - } - else - { - const char *oldname = last_component (*filename); - int dirlen = oldname - *filename; - char *fullnewname = xmalloc (dirlen + strlen (newname) + 1); - strncpy (fullnewname, *filename, dirlen); - strcpy (fullnewname + dirlen, newname); - free (newname); - free (*filename); - *filename = fullnewname; - } -#else - error (1, 0, "internal error: islink doesn't like readlink"); -#endif - } -} - -/* - * Rename a file to an appropriate backup name based on BAKPREFIX. - * If suffix non-null, then "." 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; -} - -/* - * Copy a string into a buffer escaping any shell metacharacters. The - * buffer should be at least twice as long as the string. - * - * Returns a pointer to the terminating NUL byte in buffer. - */ - -char * -shell_escape(buf, str) - char *buf; - const char *str; -{ - static const char meta[] = "$`\\\""; - const char *p; - - for (;;) - { - p = strpbrk(str, meta); - if (!p) p = str + strlen(str); - if (p > str) - { - memcpy(buf, str, p - str); - buf += p - str; - } - if (!*p) break; - *buf++ = '\\'; - *buf++ = *p++; - str = p; - } - *buf = '\0'; - return buf; -} - - - -/* - * We can only travel forwards in time, not backwards. :) - */ -void -sleep_past (desttime) - time_t desttime; -{ - time_t t; - long s; - long us; - - while (time (&t) <= desttime) - { -#ifdef HAVE_GETTIMEOFDAY - struct timeval tv; - gettimeofday (&tv, NULL); - if (tv.tv_sec > desttime) - break; - s = desttime - tv.tv_sec; - if (tv.tv_usec > 0) - us = 1000000 - tv.tv_usec; - else - { - s++; - us = 0; - } -#else - /* default to 20 ms increments */ - s = desttime - t; - us = 20000; -#endif - -#if defined(HAVE_NANOSLEEP) - { - struct timespec ts; - ts.tv_sec = s; - ts.tv_nsec = us * 1000; - (void)nanosleep (&ts, NULL); - } -#elif defined(HAVE_USLEEP) - if (s > 0) - (void)sleep (s); - else - (void)usleep (us); -#elif defined(HAVE_SELECT) - { - /* use select instead of sleep since it is a fairly portable way of - * sleeping for ms. - */ - struct timeval tv; - tv.tv_sec = s; - tv.tv_usec = us; - (void)select (0, (fd_set *)NULL, (fd_set *)NULL, (fd_set *)NULL, - &tv); - } -#else - if (us > 0) s++; - (void)sleep(s); -#endif - } -} - - - -/* Return non-zero iff FILENAME is absolute. - Trivial under Unix, but more complicated under other systems. */ -int -isabsolute (filename) - const char *filename; -{ - return ISABSOLUTE (filename); -} diff --git a/contrib/cvs/src/tag.c b/contrib/cvs/src/tag.c deleted file mode 100644 index 43451ce..0000000 --- a/contrib/cvs/src/tag.c +++ /dev/null @@ -1,1465 +0,0 @@ -/* - * Copyright (C) 1986-2005 The Free Software Foundation, Inc. - * - * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot , - * and others. - * - * Portions Copyright (C) 1992, Brian Berliner and Jeff Polk - * Portions Copyright (C) 1989-1992, Brian Berliner - * - * You may distribute under the terms of the GNU General Public License as - * specified in the README file that comes with the CVS source distribution. - * - * Tag and Rtag - * - * Add or delete a symbolic name to an RCS file, or a collection of RCS files. - * Tag uses the checked out revision in the current directory, rtag uses - * the modules database, if necessary. - * - * $FreeBSD$ - */ - -#include "cvs.h" -#include "savecwd.h" - -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 check_fileproc PROTO ((void *callerdat, struct file_info *finfo)); -static int check_filesdoneproc PROTO ((void *callerdat, int err, - const char *repos, - const char *update_dir, - List *entries)); -static int pretag_proc PROTO((const char *repository, const char *filter)); -static void masterlist_delproc PROTO((Node *p)); -static void tag_delproc PROTO((Node *p)); -static int pretag_list_proc PROTO((Node *p, void *closure)); - -static Dtype tag_dirproc PROTO ((void *callerdat, const char *dir, - const char *repos, const char *update_dir, - List *entries)); -static int rtag_fileproc PROTO ((void *callerdat, struct file_info *finfo)); -static int rtag_delete PROTO((RCSNode *rcsfile)); -static int tag_fileproc PROTO ((void *callerdat, struct file_info *finfo)); - -static char *numtag; /* specific revision to tag */ -static int numtag_validated = 0; -static char *date = NULL; -static char *symtag; /* tag to add or delete */ -static int delete_flag; /* adding a tag by default */ -static int branch_mode; /* make an automagic "branch" tag */ -static int disturb_branch_tags = 0; /* allow -F,-d to disturb branch tags */ -static int force_tag_match = 1; /* force tag to match by default */ -static int force_tag_move; /* don't force tag to move by default */ -static int check_uptodate; /* no uptodate-check by default */ -static int attic_too; /* remove tag from Attic files */ -static int is_rtag; - -struct tag_info -{ - Ctype status; - char *rev; - char *tag; - char *options; -}; - -struct master_lists -{ - List *tlist; -}; - -static List *mtlist; -static List *tlist; - -static const char rtag_opts[] = "+aBbdFflnQqRr:D:"; -static const char *const rtag_usage[] = -{ - "Usage: %s %s [-abdFflnR] [-r rev|-D date] tag modules...\n", - "\t-a\tClear tag from removed files that would not otherwise be tagged.\n", - "\t-b\tMake the tag a \"branch\" tag, allowing concurrent development.\n", - "\t-B\tAllows -F and -d to disturb branch tags. Use with extreme care.\n", - "\t-d\tDelete the given tag.\n", - "\t-F\tMove tag if it already exists.\n", - "\t-f\tForce a head revision match if tag/date not found.\n", - "\t-l\tLocal directory only, not recursive.\n", - "\t-n\tNo execution of 'tag program'.\n", - "\t-R\tProcess directories recursively.\n", - "\t-r rev\tExisting revision/tag.\n", - "\t-D\tExisting date.\n", - "(Specify the --help global option for a list of other help options)\n", - NULL -}; - -static const char tag_opts[] = "+BbcdFflQqRr:D:"; -static const char *const tag_usage[] = -{ - "Usage: %s %s [-bcdFflR] [-r rev|-D date] tag [files...]\n", - "\t-b\tMake the tag a \"branch\" tag, allowing concurrent development.\n", - "\t-B\tAllows -F and -d to disturb branch tags. Use with extreme care.\n", - "\t-c\tCheck that working files are unmodified.\n", - "\t-d\tDelete the given tag.\n", - "\t-F\tMove tag if it already exists.\n", - "\t-f\tForce a head revision match if tag/date not found.\n", - "\t-l\tLocal directory only, not recursive.\n", - "\t-R\tProcess directories recursively.\n", - "\t-r rev\tExisting revision/tag.\n", - "\t-D\tExisting date.\n", - "(Specify the --help global option for a list of other help options)\n", - NULL -}; - -int -cvstag (argc, argv) - int argc; - char **argv; -{ - int local = 0; /* recursive by default */ - int c; - int err = 0; - int run_module_prog = 1; - - is_rtag = (strcmp (cvs_cmd_name, "rtag") == 0); - - if (argc == -1) - usage (is_rtag ? rtag_usage : tag_usage); - - optind = 0; - while ((c = getopt (argc, argv, is_rtag ? rtag_opts : tag_opts)) != -1) - { - switch (c) - { - case 'a': - attic_too = 1; - break; - case 'b': - branch_mode = 1; - break; - case 'B': - disturb_branch_tags = 1; - break; - case 'c': - check_uptodate = 1; - break; - case 'd': - delete_flag = 1; - break; - case 'F': - force_tag_move = 1; - break; - case 'f': - force_tag_match = 0; - break; - case 'l': - local = 1; - break; - case 'n': - run_module_prog = 0; - break; - case 'Q': - case 'q': - /* The CVS 1.5 client sends these options (in addition to - Global_option requests), so we must ignore them. */ - if (!server_active) - error (1, 0, - "-q or -Q must be specified before \"%s\"", - cvs_cmd_name); - break; - case 'R': - local = 0; - break; - case 'r': - numtag = optarg; - break; - case 'D': - if (date) - free (date); - date = Make_Date (optarg); - break; - case '?': - default: - usage (is_rtag ? rtag_usage : tag_usage); - break; - } - } - argc -= optind; - argv += optind; - - if (argc < (is_rtag ? 2 : 1)) - usage (is_rtag ? rtag_usage : tag_usage); - symtag = argv[0]; - argc--; - argv++; - - if (date && numtag) - error (1, 0, "-r and -D options are mutually exclusive"); - if (delete_flag && branch_mode) - error (0, 0, "warning: -b ignored with -d options"); - RCS_check_tag (symtag); - -#ifdef CLIENT_SUPPORT - if (current_parsed_root->isremote) - { - /* We're the client side. Fire up the remote server. */ - start_server (); - - ign_setup (); - - if (attic_too) - send_arg("-a"); - if (branch_mode) - send_arg("-b"); - if (disturb_branch_tags) - send_arg("-B"); - if (check_uptodate) - send_arg("-c"); - if (delete_flag) - send_arg("-d"); - if (force_tag_move) - send_arg("-F"); - if (!force_tag_match) - send_arg ("-f"); - if (local) - send_arg("-l"); - if (!run_module_prog) - send_arg("-n"); - - if (numtag) - option_with_arg ("-r", numtag); - if (date) - client_senddate (date); - - send_arg ("--"); - - send_arg (symtag); - - if (is_rtag) - { - int i; - for (i = 0; i < argc; ++i) - send_arg (argv[i]); - send_to_server ("rtag\012", 0); - } - else - { - send_files (argc, argv, local, 0, - - /* I think the -c case is like "cvs status", in - which we really better be correct rather than - being fast; it is just too confusing otherwise. */ - check_uptodate ? 0 : SEND_NO_CONTENTS); - send_file_names (argc, argv, SEND_EXPAND_WILD); - send_to_server ("tag\012", 0); - } - - return get_responses_and_close (); - } -#endif - - if (is_rtag) - { - DBM *db; - int i; - db = open_module (); - for (i = 0; i < argc; i++) - { - /* XXX last arg should be repository, but doesn't make sense here */ - history_write ('T', (delete_flag ? "D" : (numtag ? numtag : - (date ? date : "A"))), symtag, argv[i], ""); - err += do_module (db, argv[i], TAG, - delete_flag ? "Untagging" : "Tagging", - rtag_proc, (char *) NULL, 0, local, run_module_prog, - 0, symtag); - } - close_module (db); - } - else - { - err = rtag_proc (argc + 1, argv - 1, NULL, NULL, NULL, 0, local, NULL, - NULL); - } - - return (err); -} - -/* - * callback proc for doing the real work of tagging - */ -/* ARGSUSED */ -static int -rtag_proc (argc, argv, xwhere, mwhere, mfile, shorten, local_specified, - mname, msg) - int argc; - char **argv; - char *xwhere; - char *mwhere; - char *mfile; - int shorten; - int local_specified; - char *mname; - char *msg; -{ - /* Begin section which is identical to patch_proc--should this - be abstracted out somehow? */ - char *myargv[2]; - int err = 0; - int which; - char *repository; - char *where; - - if (is_rtag) - { - repository = xmalloc (strlen (current_parsed_root->directory) + strlen (argv[0]) - + (mfile == NULL ? 0 : strlen (mfile) + 1) + 2); - (void) sprintf (repository, "%s/%s", current_parsed_root->directory, argv[0]); - where = xmalloc (strlen (argv[0]) + (mfile == NULL ? 0 : strlen (mfile) + 1) - + 1); - (void) strcpy (where, argv[0]); - - /* if mfile isn't null, we need to set up to do only part of the module */ - if (mfile != NULL) - { - char *cp; - char *path; - - /* if the portion of the module is a path, put the dir part on repos */ - if ((cp = strrchr (mfile, '/')) != NULL) - { - *cp = '\0'; - (void) strcat (repository, "/"); - (void) strcat (repository, mfile); - (void) strcat (where, "/"); - (void) strcat (where, mfile); - mfile = cp + 1; - } - - /* take care of the rest */ - path = xmalloc (strlen (repository) + strlen (mfile) + 5); - (void) sprintf (path, "%s/%s", repository, mfile); - if (isdir (path)) - { - /* directory means repository gets the dir tacked on */ - (void) strcpy (repository, path); - (void) strcat (where, "/"); - (void) strcat (where, mfile); - } - else - { - myargv[0] = argv[0]; - myargv[1] = mfile; - argc = 2; - argv = myargv; - } - free (path); - } - - /* cd to the starting repository */ - if ( CVS_CHDIR (repository) < 0) - { - error (0, errno, "cannot chdir to %s", repository); - free (repository); - free (where); - return (1); - } - /* End section which is identical to patch_proc. */ - - if (delete_flag || force_tag_move || attic_too || numtag) - which = W_REPOS | W_ATTIC; - else - which = W_REPOS; - } - else - { - where = NULL; - which = W_LOCAL; - repository = ""; - } - - if (numtag != NULL && !numtag_validated) - { - tag_check_valid (numtag, argc - 1, argv + 1, local_specified, 0, repository); - numtag_validated = 1; - } - - /* check to make sure they are authorized to tag all the - specified files in the repository */ - - mtlist = getlist(); - err = start_recursion (check_fileproc, check_filesdoneproc, - (DIRENTPROC) NULL, (DIRLEAVEPROC) NULL, NULL, - argc - 1, argv + 1, local_specified, which, 0, - CVS_LOCK_READ, where, 1, repository); - - if (err) - { - error (1, 0, "correct the above errors first!"); - } - - /* It would be nice to provide consistency with respect to - commits; however CVS lacks the infrastructure to do that (see - Concurrency in cvs.texinfo and comment in do_recursion). */ - - /* start the recursion processor */ - err = start_recursion (is_rtag ? rtag_fileproc : tag_fileproc, - (FILESDONEPROC) NULL, tag_dirproc, - (DIRLEAVEPROC) NULL, NULL, argc - 1, argv + 1, - local_specified, which, 0, CVS_LOCK_WRITE, where, 1, - repository); - if ( which & W_REPOS ) free ( repository ); - dellist (&mtlist); - if (where != NULL) - free (where); - return (err); -} - -/* check file that is to be tagged */ -/* All we do here is add it to our list */ - -static int -check_fileproc (callerdat, finfo) - void *callerdat; - struct file_info *finfo; -{ - const char *xdir; - Node *p; - Vers_TS *vers; - - if (check_uptodate) - { - switch (Classify_File (finfo, (char *) NULL, (char *) NULL, - (char *) NULL, 1, 0, &vers, 0)) - { - case T_UPTODATE: - case T_CHECKOUT: - case T_PATCH: - case T_REMOVE_ENTRY: - break; - case T_UNKNOWN: - case T_CONFLICT: - case T_NEEDS_MERGE: - case T_MODIFIED: - case T_ADDED: - case T_REMOVED: - default: - 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 = "."; - else - xdir = finfo->update_dir; - if ((p = findnode (mtlist, xdir)) != NULL) - { - tlist = ((struct master_lists *) p->data)->tlist; - } - else - { - struct master_lists *ml; - - tlist = getlist (); - p = getnode (); - p->key = xstrdup (xdir); - p->type = UPDATE; - ml = (struct master_lists *) - xmalloc (sizeof (struct master_lists)); - ml->tlist = tlist; - p->data = ml; - p->delproc = masterlist_delproc; - (void) addnode (mtlist, p); - } - /* do tlist */ - p = getnode (); - p->key = xstrdup (finfo->file); - p->type = UPDATE; - p->delproc = tag_delproc; - if (vers->srcfile == NULL) - { - if (!really_quiet) - error (0, 0, "nothing known about %s", finfo->file); - freevers_ts (&vers); - freenode (p); - return (1); - } - - /* Here we duplicate the calculation in tag_fileproc about which - version we are going to tag. There probably are some subtle races - (e.g. numtag is "foo" which gets moved between here and - tag_fileproc). */ - if (!is_rtag && numtag == NULL && date == NULL) - p->data = xstrdup (vers->vn_user); - else - p->data = RCS_getversion (vers->srcfile, numtag, date, - force_tag_match, NULL); - - if (p->data != NULL) - { - int addit = 1; - char *oversion; - - oversion = RCS_getversion (vers->srcfile, symtag, (char *) NULL, 1, - (int *) NULL); - if (oversion == NULL) - { - if (delete_flag) - { - /* Deleting a tag which did not exist is a noop and - should not be logged. */ - addit = 0; - } - } - else if (delete_flag) - { - free (p->data); - p->data = xstrdup (oversion); - } - else if (strcmp(oversion, p->data) == 0) - { - addit = 0; - } - else if (!force_tag_move) - { - addit = 0; - } - if (oversion != NULL) - { - free(oversion); - } - if (!addit) - { - free(p->data); - p->data = NULL; - } - } - freevers_ts (&vers); - (void) addnode (tlist, p); - return (0); -} - -static int -check_filesdoneproc (callerdat, err, repos, update_dir, entries) - void *callerdat; - int err; - const char *repos; - const char *update_dir; - List *entries; -{ - int n; - Node *p; - - p = findnode(mtlist, update_dir); - if (p != NULL) - { - tlist = ((struct master_lists *) p->data)->tlist; - } - else - { - tlist = (List *) NULL; - } - if ((tlist == NULL) || (tlist->list->next == tlist->list)) - { - return (err); - } - if ((n = Parse_Info(CVSROOTADM_TAGINFO, repos, pretag_proc, 1)) > 0) - { - error (0, 0, "Pre-tag check failed"); - err += n; - } - return (err); -} - -static int -pretag_proc (repository, filter) - const char *repository; - const char *filter; -{ - if (filter[0] == '/') - { - char *s, *cp; - - s = xstrdup(filter); - for (cp=s; *cp; cp++) - { - if (isspace ((unsigned char) *cp)) - { - *cp = '\0'; - break; - } - } - if (!isfile(s)) - { - error (0, errno, "cannot find pre-tag filter '%s'", s); - free(s); - return (1); - } - free(s); - } - run_setup (filter); - run_arg (symtag); - run_arg (delete_flag ? "del" : force_tag_move ? "mov" : "add"); - run_arg (repository); - walklist(tlist, pretag_list_proc, NULL); - return (run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL)); -} - -static void -masterlist_delproc(p) - Node *p; -{ - struct master_lists *ml = p->data; - - dellist(&ml->tlist); - free(ml); - return; -} - -static void -tag_delproc(p) - Node *p; -{ - if (p->data != NULL) - { - free(p->data); - p->data = NULL; - } - return; -} - -static int -pretag_list_proc(p, closure) - Node *p; - void *closure; -{ - if (p->data != NULL) - { - run_arg(p->key); - run_arg(p->data); - } - return (0); -} - - -/* - * Called to rtag a particular file, as appropriate with the options that were - * set above. - */ -/* ARGSUSED */ -static int -rtag_fileproc (callerdat, finfo) - void *callerdat; - struct file_info *finfo; -{ - RCSNode *rcsfile; - char *version, *rev; - int retcode = 0; - - /* find the parsed RCS data */ - if ((rcsfile = finfo->rcs) == NULL) - return (1); - - /* - * For tagging an RCS file which is a symbolic link, you'd best be - * running with RCS 5.6, since it knows how to handle symbolic links - * correctly without breaking your link! - */ - - if (delete_flag) - return (rtag_delete (rcsfile)); - - /* - * If we get here, we are adding a tag. But, if -a was specified, we - * need to check to see if a -r or -D option was specified. If neither - * was specified and the file is in the Attic, remove the tag. - */ - if (attic_too && (!numtag && !date)) - { - if ((rcsfile->flags & VALID) && (rcsfile->flags & INATTIC)) - return (rtag_delete (rcsfile)); - } - - version = RCS_getversion (rcsfile, numtag, date, force_tag_match, - (int *) NULL); - if (version == NULL) - { - /* If -a specified, clean up any old tags */ - if (attic_too) - (void) rtag_delete (rcsfile); - - if (!quiet && !force_tag_match) - { - error (0, 0, "cannot find tag `%s' in `%s'", - numtag ? numtag : "head", rcsfile->path); - return (1); - } - return (0); - } - if (numtag - && isdigit ((unsigned char) *numtag) - && strcmp (numtag, version) != 0) - { - - /* - * We didn't find a match for the numeric tag that was specified, but - * that's OK. just pass the numeric tag on to rcs, to be tagged as - * specified. Could get here if one tried to tag "1.1.1" and there - * was a 1.1.1 branch with some head revision. In this case, we want - * the tag to reference "1.1.1" and not the revision at the head of - * the branch. Use a symbolic tag for that. - */ - rev = branch_mode ? RCS_magicrev (rcsfile, version) : numtag; - retcode = RCS_settag(rcsfile, symtag, numtag); - if (retcode == 0) - RCS_rewrite (rcsfile, NULL, NULL); - } - else - { - char *oversion; - - /* - * As an enhancement for the case where a tag is being re-applied to - * a large body of a module, make one extra call to RCS_getversion to - * see if the tag is already set in the RCS file. If so, check to - * see if it needs to be moved. If not, do nothing. This will - * likely save a lot of time when simply moving the tag to the - * "current" head revisions of a module -- which I have found to be a - * typical tagging operation. - */ - rev = branch_mode ? RCS_magicrev (rcsfile, version) : version; - oversion = RCS_getversion (rcsfile, symtag, (char *) NULL, 1, - (int *) NULL); - if (oversion != NULL) - { - int isbranch = RCS_nodeisbranch (finfo->rcs, symtag); - - /* - * if versions the same and neither old or new are branches don't - * have to do anything - */ - if (strcmp (version, oversion) == 0 && !branch_mode && !isbranch) - { - free (oversion); - free (version); - return (0); - } - - if (!force_tag_move) - { - /* we're NOT going to move the tag */ - (void) printf ("W %s", finfo->fullname); - - (void) printf (" : %s already exists on %s %s", - symtag, isbranch ? "branch" : "version", - oversion); - (void) printf (" : NOT MOVING tag to %s %s\n", - branch_mode ? "branch" : "version", rev); - free (oversion); - free (version); - if (branch_mode) free(rev); - return (0); - } - else /* force_tag_move is set and... */ - if ((isbranch && !disturb_branch_tags) || - (!isbranch && disturb_branch_tags)) - { - error(0,0, "%s: Not moving %s tag `%s' from %s to %s%s.", - finfo->fullname, - isbranch ? "branch" : "non-branch", - symtag, oversion, rev, - isbranch ? "" : " due to `-B' option"); - if (branch_mode) free(rev); - free (oversion); - free (version); - return (0); - } - free (oversion); - } - retcode = RCS_settag(rcsfile, symtag, rev); - if (retcode == 0) - RCS_rewrite (rcsfile, NULL, NULL); - } - - if (retcode != 0) - { - error (1, retcode == -1 ? errno : 0, - "failed to set tag `%s' to revision `%s' in `%s'", - symtag, rev, rcsfile->path); - if (branch_mode) - free (rev); - free (version); - return (1); - } - if (branch_mode) - free (rev); - free (version); - return (0); -} - -/* - * If -d is specified, "force_tag_match" is set, so that this call to - * RCS_getversion() will return a NULL version string if the symbolic - * tag does not exist in the RCS file. - * - * If the -r flag was used, numtag is set, and we only delete the - * symtag from files that have numtag. - * - * This is done here because it's MUCH faster than just blindly calling - * "rcs" to remove the tag... trust me. - */ -static int -rtag_delete (rcsfile) - RCSNode *rcsfile; -{ - char *version; - int retcode, isbranch; - - if (numtag) - { - version = RCS_getversion (rcsfile, numtag, (char *) NULL, 1, - (int *) NULL); - if (version == NULL) - return (0); - free (version); - } - - version = RCS_getversion (rcsfile, symtag, (char *) NULL, 1, - (int *) NULL); - if (version == NULL) - return (0); - free (version); - - - isbranch = RCS_nodeisbranch (rcsfile, symtag); - if ((isbranch && !disturb_branch_tags) || - (!isbranch && disturb_branch_tags)) - { - if (!quiet) - error(0, 0, - "Not removing %s tag `%s' from `%s'%s.", - isbranch ? "branch" : "non-branch", - symtag, rcsfile->path, - isbranch ? "" : " due to `-B' option"); - return (1); - } - - if ((retcode = RCS_deltag(rcsfile, symtag)) != 0) - { - if (!quiet) - error (0, retcode == -1 ? errno : 0, - "failed to remove tag `%s' from `%s'", symtag, - rcsfile->path); - return (1); - } - RCS_rewrite (rcsfile, NULL, NULL); - return (0); -} - - -/* - * Called to tag a particular file (the currently checked out version is - * tagged with the specified tag - or the specified tag is deleted). - */ -/* ARGSUSED */ -static int -tag_fileproc (callerdat, finfo) - void *callerdat; - struct file_info *finfo; -{ - char *version, *oversion; - char *nversion = NULL; - char *rev; - Vers_TS *vers; - int retcode = 0; - int retval = 0; - - vers = Version_TS (finfo, NULL, NULL, NULL, 0, 0); - - if ((numtag != NULL) || (date != NULL)) - { - nversion = RCS_getversion(vers->srcfile, - numtag, - date, - force_tag_match, - (int *) NULL); - if (nversion == NULL) - goto free_vars_and_return; - } - if (delete_flag) - { - - int isbranch; - /* - * If -d is specified, "force_tag_match" is set, so that this call to - * RCS_getversion() will return a NULL version string if the symbolic - * tag does not exist in the RCS file. - * - * This is done here because it's MUCH faster than just blindly calling - * "rcs" to remove the tag... trust me. - */ - - version = RCS_getversion (vers->srcfile, symtag, (char *) NULL, 1, - (int *) NULL); - if (version == NULL || vers->srcfile == NULL) - goto free_vars_and_return; - - free (version); - - isbranch = RCS_nodeisbranch (finfo->rcs, symtag); - if ((isbranch && !disturb_branch_tags) || - (!isbranch && disturb_branch_tags)) - { - if (!quiet) - error(0, 0, - "Not removing %s tag `%s' from `%s'%s.", - isbranch ? "branch" : "non-branch", - symtag, vers->srcfile->path, - isbranch ? "" : " due to `-B' option"); - retval = 1; - goto free_vars_and_return; - } - - if ((retcode = RCS_deltag(vers->srcfile, symtag)) != 0) - { - if (!quiet) - error (0, retcode == -1 ? errno : 0, - "failed to remove tag %s from %s", symtag, - vers->srcfile->path); - retval = 1; - goto free_vars_and_return; - } - RCS_rewrite (vers->srcfile, NULL, NULL); - - /* warm fuzzies */ - if (!really_quiet) - { - cvs_output ("D ", 2); - cvs_output (finfo->fullname, 0); - cvs_output ("\n", 1); - } - - goto free_vars_and_return; - } - - /* - * If we are adding a tag, we need to know which version we have checked - * out and we'll tag that version. - */ - if (nversion == NULL) - { - version = vers->vn_user; - } - else - { - version = nversion; - } - if (version == NULL) - { - goto free_vars_and_return; - } - else if (strcmp (version, "0") == 0) - { - if (!quiet) - error (0, 0, "couldn't tag added but un-commited file `%s'", finfo->file); - goto free_vars_and_return; - } - else if (version[0] == '-') - { - if (!quiet) - error (0, 0, "skipping removed but un-commited file `%s'", finfo->file); - goto free_vars_and_return; - } - else if (vers->srcfile == NULL) - { - if (!quiet) - error (0, 0, "cannot find revision control file for `%s'", finfo->file); - goto free_vars_and_return; - } - - /* - * As an enhancement for the case where a tag is being re-applied to a - * large number of files, make one extra call to RCS_getversion to see - * if the tag is already set in the RCS file. If so, check to see if it - * needs to be moved. If not, do nothing. This will likely save a lot of - * time when simply moving the tag to the "current" head revisions of a - * module -- which I have found to be a typical tagging operation. - */ - rev = branch_mode ? RCS_magicrev (vers->srcfile, version) : version; - oversion = RCS_getversion (vers->srcfile, symtag, (char *) NULL, 1, - (int *) NULL); - if (oversion != NULL) - { - int isbranch = RCS_nodeisbranch (finfo->rcs, symtag); - - /* - * if versions the same and neither old or new are branches don't have - * to do anything - */ - if (strcmp (version, oversion) == 0 && !branch_mode && !isbranch) - { - free (oversion); - if (branch_mode) - free (rev); - goto free_vars_and_return; - } - - if (!force_tag_move) - { - /* we're NOT going to move the tag */ - cvs_output ("W ", 2); - cvs_output (finfo->fullname, 0); - cvs_output (" : ", 0); - cvs_output (symtag, 0); - cvs_output (" already exists on ", 0); - cvs_output (isbranch ? "branch" : "version", 0); - cvs_output (" ", 0); - cvs_output (oversion, 0); - cvs_output (" : NOT MOVING tag to ", 0); - cvs_output (branch_mode ? "branch" : "version", 0); - cvs_output (" ", 0); - cvs_output (rev, 0); - cvs_output ("\n", 1); - free (oversion); - if (branch_mode) - free (rev); - goto free_vars_and_return; - } - else /* force_tag_move == 1 and... */ - if ((isbranch && !disturb_branch_tags) || - (!isbranch && disturb_branch_tags)) - { - error(0,0, "%s: Not moving %s tag `%s' from %s to %s%s.", - finfo->fullname, - isbranch ? "branch" : "non-branch", - symtag, oversion, rev, - isbranch ? "" : " due to `-B' option"); - free (oversion); - if (branch_mode) - free (rev); - goto free_vars_and_return; - } - free (oversion); - } - - if ((retcode = RCS_settag(vers->srcfile, symtag, rev)) != 0) - { - 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); - retval = 1; - goto free_vars_and_return; - } - if (branch_mode) - free (rev); - RCS_rewrite (vers->srcfile, NULL, NULL); - - /* more warm fuzzies */ - if (!really_quiet) - { - cvs_output ("T ", 2); - cvs_output (finfo->fullname, 0); - cvs_output ("\n", 1); - } - - free_vars_and_return: - if (nversion != NULL) - free (nversion); - freevers_ts (&vers); - return (retval); -} - -/* - * Print a warm fuzzy message - */ -/* ARGSUSED */ -static Dtype -tag_dirproc (callerdat, dir, repos, update_dir, entries) - void *callerdat; - const char *dir; - const char *repos; - const char *update_dir; - List *entries; -{ - - if (ignore_directory (update_dir)) - { - /* print the warm fuzzy message */ - if (!quiet) - error (0, 0, "Ignoring %s", update_dir); - return R_SKIP_ALL; - } - - if (!quiet) - error (0, 0, "%s %s", delete_flag ? "Untagging" : "Tagging", update_dir); - return (R_PROCESS); -} - -/* Code relating to the val-tags file. Note that this file has no way - of knowing when a tag has been deleted. The problem is that there - is no way of knowing whether a tag still exists somewhere, when we - delete it some places. Using per-directory val-tags files (in - CVSREP) might be better, but that might slow down the process of - verifying that a tag is correct (maybe not, for the likely cases, - if carefully done), and/or be harder to implement correctly. */ - -struct val_args { - char *name; - int found; -}; - -static int val_fileproc PROTO ((void *callerdat, struct file_info *finfo)); - -static int -val_fileproc (callerdat, finfo) - void *callerdat; - struct file_info *finfo; -{ - RCSNode *rcsdata; - struct val_args *args = (struct val_args *)callerdat; - char *tag; - - if ((rcsdata = finfo->rcs) == NULL) - /* Not sure this can happen, after all we passed only - W_REPOS | W_ATTIC. */ - return 0; - - tag = RCS_gettag (rcsdata, args->name, 1, (int *) NULL); - if (tag != NULL) - { - /* FIXME: should find out a way to stop the search at this point. */ - args->found = 1; - free (tag); - } - return 0; -} - - - -/* This routine determines whether a tag appears in CVSROOT/val-tags. - * - * The val-tags file will be open read-only when IDB is NULL. Since writes to - * val-tags always append to it, the lack of locking is okay. The worst case - * race condition might misinterpret a partially written "foobar" matched, for - * instance, a request for "f", "foo", of "foob". Such a mismatch would be - * caught harmlessly later. - * - * Before CVS adds a tag to val-tags, it will lock val-tags for write and - * verify that the tag is still not present to avoid adding it twice. - * - * NOTES - * This function expects its parent to handle any necessary locking of the - * val-tags file. - * - * INPUTS - * idb When this value is NULL, the val-tags file is opened in - * in read-only mode. When present, the val-tags file is opened - * in read-write mode and the DBM handle is stored in *IDB. - * name The tag to search for. - * - * OUTPUTS - * *idb The val-tags file opened for read/write, or NULL if it couldn't - * be opened. - * - * ERRORS - * Exits with an error message if the val-tags file cannot be opened for - * read (failure to open val-tags read/write is harmless - see below). - * - * RETURNS - * true 1. If NAME exists in val-tags. - * 2. If IDB is non-NULL and val-tags cannot be opened for write. - * This allows callers to ignore the harmless inability to - * update the val-tags cache. - * false If the file could be opened and the tag is not present. - */ -static int is_in_val_tags PROTO((DBM **idb, const char *name)); -static int -is_in_val_tags (idb, name) - DBM **idb; - const char *name; -{ - DBM *db = NULL; - char *valtags_filename; - datum mytag; - int status; - - /* Casting out const should be safe here - input datums are not - * written to by the myndbm functions. - */ - mytag.dptr = (char *)name; - mytag.dsize = strlen (name); - - valtags_filename = xmalloc (strlen (current_parsed_root->directory) - + sizeof CVSROOTADM - + sizeof CVSROOTADM_VALTAGS + 3); - sprintf (valtags_filename, "%s/%s/%s", current_parsed_root->directory, - CVSROOTADM, CVSROOTADM_VALTAGS); - - if (idb) - { - db = dbm_open (valtags_filename, O_RDWR, 0666); - if (!db) - { - mode_t omask; - - if (!existence_error (errno)) - { - error (0, errno, "warning: cannot open %s read/write", - valtags_filename); - *idb = NULL; - return 1; - } - - omask = umask (cvsumask); - db = dbm_open (valtags_filename, O_RDWR | O_CREAT | O_TRUNC, 0666); - umask (omask); - if (!db) - { - error (0, errno, "warning: cannot create %s", - valtags_filename); - *idb = NULL; - return 1; - } - - *idb = db; - return 0; - } - - *idb = db; - } - else - { - db = dbm_open (valtags_filename, O_RDONLY, 0444); - if (!db && !existence_error (errno)) - error (1, errno, "cannot read %s", valtags_filename); - } - - /* If the file merely fails to exist, we just keep going and create - it later if need be. */ - - status = 0; - if (db) - { - datum val; - - val = dbm_fetch (db, mytag); - if (val.dptr != NULL) - /* Found. The tag is valid. */ - status = 1; - - /* FIXME: should check errors somehow (add dbm_error to myndbm.c?). */ - - if (!idb) dbm_close (db); - } - - free (valtags_filename); - return status; -} - - - -/* Add a tag to the CVSROOT/val-tags cache. Establishes a write lock and - * reverifies that the tag does not exist before adding it. - */ -static void add_to_val_tags PROTO((const char *name)); -static void -add_to_val_tags (name) - const char *name; -{ - DBM *db; - datum mytag; - datum value; - - if (noexec) return; - - val_tags_lock (current_parsed_root->directory); - - /* Check for presence again since we have a lock now. */ - if (is_in_val_tags (&db, name)) - { - clear_val_tags_lock (); - if (db) - dbm_close (db); - return; - } - - /* Casting out const should be safe here - input datums are not - * written to by the myndbm functions. - */ - mytag.dptr = (char *)name; - mytag.dsize = strlen (name); - value.dptr = "y"; - value.dsize = 1; - - if (dbm_store (db, mytag, value, DBM_REPLACE) < 0) - error (0, errno, "failed to store %s into val-tags", name); - dbm_close (db); - - clear_val_tags_lock (); -} - - - -static Dtype val_direntproc PROTO ((void *, const char *, const char *, - const char *, List *)); - -static Dtype -val_direntproc (callerdat, dir, repository, update_dir, entries) - void *callerdat; - const char *dir; - const char *repository; - const char *update_dir; - List *entries; -{ - /* This is not quite right--it doesn't get right the case of "cvs - update -d -r foobar" where foobar is a tag which exists only in - files in a directory which does not exist yet, but which is - about to be created. */ - if (isdir (dir)) - return R_PROCESS; - return R_SKIP_ALL; -} - -/* Check to see whether NAME is a valid tag. If so, return. If not - print an error message and exit. ARGC, ARGV, LOCAL, and AFLAG specify - which files we will be operating on. - - REPOSITORY is the repository if we need to cd into it, or NULL if - we are already there, or "" if we should do a W_LOCAL recursion. - Sorry for three cases, but the "" case is needed in case the - working directories come from diverse parts of the repository, the - NULL case avoids an unneccesary chdir, and the non-NULL, non-"" - case is needed for checkout, where we don't want to chdir if the - tag is found in CVSROOTADM_VALTAGS, but there is not (yet) any - local directory. */ -void -tag_check_valid (name, argc, argv, local, aflag, repository) - char *name; - int argc; - char **argv; - int local; - int aflag; - char *repository; -{ - struct val_args the_val_args; - struct saved_cwd cwd; - int which; - - /* Numeric tags require only a syntactic check. */ - if (isdigit ((unsigned char) name[0])) - { - char *p; - for (p = name; *p != '\0'; ++p) - { - if (!(isdigit ((unsigned char) *p) || *p == '.')) - error (1, 0, "\ -Numeric tag %s contains characters other than digits and '.'", name); - } - return; - } - - /* Special tags are always valid. */ - if (strcmp (name, TAG_BASE) == 0 - || strcmp (name, TAG_HEAD) == 0) - return; - - if (readonlyfs) - return; - - /* Verify that the tag is valid syntactically. Some later code once made - * assumptions about this. - */ - RCS_check_tag (name); - - if (is_in_val_tags (NULL, name)) return; - - /* We didn't find the tag in val-tags, so look through all the RCS files - to see whether it exists there. Yes, this is expensive, but there - is no other way to cope with a tag which might have been created - by an old version of CVS, from before val-tags was invented. - - Since we need this code anyway, we also use it to create - entries in val-tags in general (that is, the val-tags entry - will get created the first time the tag is used, not when the - tag is created). */ - - the_val_args.name = name; - the_val_args.found = 0; - - which = W_REPOS | W_ATTIC; - - if (repository != NULL) - { - if (repository[0] == '\0') - which |= W_LOCAL; - else - { - if (save_cwd (&cwd)) - error_exit (); - if (CVS_CHDIR (repository) < 0) - error (1, errno, "cannot change to %s directory", repository); - } - } - - start_recursion (val_fileproc, (FILESDONEPROC) NULL, - val_direntproc, (DIRLEAVEPROC) NULL, - (void *)&the_val_args, - argc, argv, local, which, aflag, - CVS_LOCK_READ, NULL, 1, repository); - if (repository != NULL && repository[0] != '\0') - { - if (restore_cwd (&cwd, NULL)) - error_exit (); - free_cwd (&cwd); - } - - if (!the_val_args.found) - error (1, 0, "no such tag %s", name); - else - /* The tags is valid but not mentioned in val-tags. Add it. */ - add_to_val_tags (name); -} - - - -/* - * Check whether a join tag is valid. This is just like - * tag_check_valid, but we must stop before the colon if there is one. - */ - -void -tag_check_valid_join (join_tag, argc, argv, local, aflag, repository) - char *join_tag; - int argc; - char **argv; - int local; - int aflag; - char *repository; -{ - char *c, *s; - - c = xstrdup (join_tag); - s = strchr (c, ':'); - if (s != NULL) - { - if (isdigit ((unsigned char) join_tag[0])) - error (1, 0, - "Numeric join tag %s may not contain a date specifier", - join_tag); - - *s = '\0'; - /* hmmm... I think it makes sense to allow -j:, but - * for now this fixes a bug where CVS just spins and spins (I - * think in the RCS code) looking for a zero length tag. - */ - if (!*c) - error (1, 0, - "argument to join may not contain a date specifier without a tag"); - } - - tag_check_valid (c, argc, argv, local, aflag, repository); - - free (c); -} diff --git a/contrib/cvs/src/update.c b/contrib/cvs/src/update.c deleted file mode 100644 index f2c8087..0000000 --- a/contrib/cvs/src/update.c +++ /dev/null @@ -1,3049 +0,0 @@ -/* - * Copyright (C) 1986-2005 The Free Software Foundation, Inc. - * - * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot , - * and others. - * - * Portions Copyright (C) 1992, Brian Berliner and Jeff Polk - * Portions Copyright (C) 1989-1992, Brian Berliner - * - * You may distribute under the terms of the GNU General Public License as - * specified in the README file that comes with the CVS source distribution. - * - * "update" updates the version in the present directory with respect to the RCS - * repository. The present version must have been created by "checkout". The - * user can keep up-to-date by calling "update" whenever he feels like it. - * - * The present version can be committed by "commit", but this keeps the version - * in tact. - * - * Arguments following the options are taken to be file names to be updated, - * rather than updating the entire directory. - * - * Modified or non-existent RCS files are checked out and reported as U - * - * - * Modified user files are reported as M . If both the RCS file and - * the user file have been modified, the user file is replaced by the result - * of rcsmerge, and a backup file is written for the user in .#file.version. - * If this throws up irreconcilable differences, the file is reported as C - * , and as M otherwise. - * - * Files added but not yet committed are reported as A . Files - * removed but not yet committed are reported as R . - * - * If the current directory contains subdirectories that hold concurrent - * versions, these are updated too. If the -d option was specified, new - * directories added to the repository are automatically created and updated - * as well. - * - * $FreeBSD$ - */ - -#include "cvs.h" -#include -#include "savecwd.h" -#ifdef SERVER_SUPPORT -# include "md5.h" -#endif -#include "watch.h" -#include "fileattr.h" -#include "edit.h" -#include "getline.h" -#include "buffer.h" -#include "hardlink.h" - -static int checkout_file PROTO ((struct file_info *finfo, Vers_TS *vers_ts, - int adding, int merging, int update_server)); -#ifdef SERVER_SUPPORT -static void checkout_to_buffer PROTO ((void *, const char *, size_t)); -static int patch_file PROTO ((struct file_info *finfo, - Vers_TS *vers_ts, - int *docheckout, struct stat *file_info, - unsigned char *checksum)); -static void patch_file_write PROTO ((void *, const char *, size_t)); -#endif /* SERVER_SUPPORT */ -static int merge_file PROTO ((struct file_info *finfo, Vers_TS *vers)); -static int scratch_file PROTO((struct file_info *finfo, Vers_TS *vers)); -static Dtype update_dirent_proc PROTO ((void *callerdat, const char *dir, - const char *repository, - const char *update_dir, - List *entries)); -static int update_dirleave_proc PROTO ((void *callerdat, const char *dir, - int err, const char *update_dir, - List *entries)); -static int update_fileproc PROTO ((void *callerdat, struct file_info *)); -static int update_filesdone_proc PROTO ((void *callerdat, int err, - const char *repository, - const char *update_dir, - List *entries)); -#ifdef PRESERVE_PERMISSIONS_SUPPORT -static int get_linkinfo_proc PROTO ((void *callerdat, struct file_info *)); -#endif -static void join_file PROTO ((struct file_info *finfo, Vers_TS *vers_ts)); - -static char *options = NULL; -static char *tag = NULL; -static char *date = NULL; -/* This is a bit of a kludge. We call WriteTag at the beginning - before we know whether nonbranch is set or not. And then at the - end, once we have the right value for nonbranch, we call WriteTag - again. I don't know whether the first call is necessary or not. - rewrite_tag is nonzero if we are going to have to make that second - call. */ -static int rewrite_tag; -static int nonbranch; - -/* If we set the tag or date for a subdirectory, we use this to undo - the setting. See update_dirent_proc. */ -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 pull_template = 0; -static int update_build_dirs = 0; -static int update_prune_dirs = 0; -static int pipeout = 0; -#ifdef SERVER_SUPPORT -static int patches = 0; -static int rcs_diff_patches = 0; -#endif -static List *ignlist = (List *) NULL; -static time_t last_register_time; -static const char *const update_usage[] = -{ - "Usage: %s %s [-APCdflRp] [-k kopt] [-r rev] [-D date] [-j rev]\n", - " [-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", - "\t-R\tProcess directories recursively.\n", - "\t-p\tSend updates to standard output (avoids stickiness).\n", - "\t-k kopt\tUse RCS kopt -k option on checkout. (is sticky)\n", - "\t-r rev\tUpdate using specified revision/tag (is sticky).\n", - "\t-D date\tSet date to update from (is sticky).\n", - "\t-j rev\tMerge in changes made between current revision and rev.\n", - "\t-I ign\tMore files to ignore (! to reset).\n", - "\t-W spec\tWrappers specification line.\n", - "\t-T\tCreate CVS/Template.\n", - "(Specify the --help global option for a list of other help options)\n", - NULL -}; - -/* - * update is the argv,argc based front end for arg parsing - */ -int -update (argc, argv) - int argc; - char **argv; -{ - int c, err; - int local = 0; /* recursive by default */ - int which; /* where to look for files and dirs */ - int xpull_template = 0; - - if (argc == -1) - usage (update_usage); - - ign_setup (); - wrap_setup (); - - /* parse the args */ - optind = 0; - while ((c = getopt (argc, argv, "+ApCPflRQTqduk: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; - case 'W': - wrap_add (optarg, 0); - break; - case 'k': - if (options) - free (options); - options = RCS_check_kflag (optarg); - break; - case 'l': - local = 1; - break; - case 'R': - local = 0; - break; - case 'Q': - case 'q': - /* The CVS 1.5 client sends these options (in addition to - Global_option requests), so we must ignore them. */ - if (!server_active) - error (1, 0, - "-q or -Q must be specified before \"%s\"", - cvs_cmd_name); - break; - case 'T': - xpull_template = 1; - break; - case 'd': - update_build_dirs = 1; - break; - case 'f': - force_tag_match = 0; - break; - case 'r': - tag = optarg; - break; - case 'D': - if (date) free (date); - date = Make_Date (optarg); - break; - case 'P': - update_prune_dirs = 1; - break; - case 'p': - pipeout = 1; - noexec = 1; /* so no locks will be created */ - break; - case 'j': - if (join_rev2) - error (1, 0, "only two -j options can be specified"); - if (join_rev1) - join_rev2 = optarg; - else - join_rev1 = optarg; - break; - case 'u': -#ifdef SERVER_SUPPORT - if (server_active) - { - patches = 1; - rcs_diff_patches = server_use_rcs_diff (); - } - else -#endif - usage (update_usage); - break; - case '?': - default: - usage (update_usage); - break; - } - } - argc -= optind; - argv += optind; - -#ifdef CLIENT_SUPPORT - if (current_parsed_root->isremote) - { - int pass; - - /* The first pass does the regular update. If we receive at least - one patch which failed, we do a second pass and just fetch - those files whose patches failed. */ - pass = 1; - do - { - int status; - - start_server (); - - if (local) - send_arg("-l"); - if (update_build_dirs) - send_arg("-d"); - if (pipeout) - send_arg("-p"); - if (!force_tag_match) - 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; - option_with_arg ("-r", tag); - if (options && options[0] != '\0') - send_arg (options); - if (date) - client_senddate (date); - if (join_rev1) - option_with_arg ("-j", join_rev1); - if (join_rev2) - option_with_arg ("-j", join_rev2); - wrap_send (); - - if (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"); - - send_arg ("--"); - - 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, flags); - send_file_names (argc, argv, SEND_EXPAND_WILD); - } - else - { - int i; - - (void) printf ("%s client: refetching unpatchable files\n", - program_name); - - if (toplevel_wd != NULL - && CVS_CHDIR (toplevel_wd) < 0) - { - error (1, errno, "could not chdir to %s", toplevel_wd); - } - - send_arg ("--"); - - for (i = 0; i < failed_patches_count; i++) - if (unlink_file (failed_patches[i]) < 0 - && !existence_error (errno)) - error (0, errno, "cannot remove %s", - failed_patches[i]); - 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); - } - - send_to_server ("update\012", 0); - - status = get_responses_and_close (); - - /* If there are any conflicts, the server will return a - non-zero exit status. If any patches failed, we still - want to run the update again. We use a pass count to - avoid an endless loop. */ - - /* Notes: (1) assuming that status != 0 implies a - potential conflict is the best we can cleanly do given - the current protocol. I suppose that trying to - re-fetch in cases where there was a more serious error - is probably more or less harmless, but it isn't really - ideal. (2) it would be nice to have a testsuite case for the - conflict-and-patch-failed case. */ - - if (status != 0 - && (failed_patches_count == 0 || pass > 1)) - { - if (failed_patches_count > 0) - free_names (&failed_patches_count, failed_patches); - return status; - } - - ++pass; - } while (failed_patches_count > 0); - - return 0; - } -#endif - - if (tag != NULL) - tag_check_valid (tag, argc, argv, local, aflag, ""); - if (join_rev1 != NULL) - tag_check_valid_join (join_rev1, argc, argv, local, aflag, ""); - if (join_rev2 != NULL) - tag_check_valid_join (join_rev2, argc, argv, local, aflag, ""); - - /* - * If we are updating the entire directory (for real) and building dirs - * as we go, we make sure there is no static entries file and write the - * tag file as appropriate - */ - if (argc <= 0 && !pipeout) - { - if (update_build_dirs) - { - if (unlink_file (CVSADM_ENTSTAT) < 0 && ! existence_error (errno)) - error (1, errno, "cannot remove file %s", CVSADM_ENTSTAT); -#ifdef SERVER_SUPPORT - if (server_active) - { - 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) - { - char *repos = Name_Repository (NULL, NULL); - WriteTag ((char *) NULL, tag, date, 0, ".", repos); - free (repos); - rewrite_tag = 1; - nonbranch = 0; - } - } - - /* look for files/dirs locally and in the repository */ - which = W_LOCAL | W_REPOS; - - /* look in the attic too if a tag or date is specified */ - if (tag != NULL || date != NULL || joining()) - which |= W_ATTIC; - - /* call the command line interface */ - err = do_update (argc, argv, options, tag, date, force_tag_match, - local, update_build_dirs, aflag, update_prune_dirs, - pipeout, which, join_rev1, join_rev2, (char *) NULL, - xpull_template, (char *) NULL); - - /* free the space Make_Date allocated if necessary */ - if (date != NULL) - free (date); - - return err; -} - - - -/* - * Command line interface to update (used by checkout) - */ -int -do_update (argc, argv, xoptions, xtag, xdate, xforce, local, xbuild, xaflag, - xprune, xpipeout, which, xjoin_rev1, xjoin_rev2, preload_update_dir, - xpull_template, repository) - int argc; - char **argv; - char *xoptions; - char *xtag; - char *xdate; - int xforce; - int local; - int xbuild; - int xaflag; - int xprune; - int xpipeout; - int which; - char *xjoin_rev1; - char *xjoin_rev2; - char *preload_update_dir; - int xpull_template; - char *repository; -{ - int err = 0; - char *cp; - - /* fill in the statics */ - options = xoptions; - tag = xtag; - date = xdate; - force_tag_match = xforce; - update_build_dirs = xbuild; - aflag = xaflag; - update_prune_dirs = xprune; - pipeout = xpipeout; - pull_template = xpull_template; - - /* setup the join support */ - join_rev1 = xjoin_rev1; - join_rev2 = xjoin_rev2; - if (join_rev1 && (cp = strchr (join_rev1, ':')) != NULL) - { - *cp++ = '\0'; - date_rev1 = Make_Date (cp); - } - else - date_rev1 = (char *) NULL; - if (join_rev2 && (cp = strchr (join_rev2, ':')) != NULL) - { - *cp++ = '\0'; - date_rev2 = Make_Date (cp); - } - else - date_rev2 = (char *) NULL; - -#ifdef PRESERVE_PERMISSIONS_SUPPORT - if (preserve_perms) - { - /* We need to do an extra recursion, bleah. It's to make sure - that we know as much as possible about file linkage. */ - hardlist = getlist(); - working_dir = xgetwd(); /* save top-level working dir */ - - /* FIXME-twp: the arguments to start_recursion make me dizzy. This - function call was copied from the update_fileproc call that - follows it; someone should make sure that I did it right. */ - err = start_recursion (get_linkinfo_proc, (FILESDONEPROC) NULL, - (DIRENTPROC) NULL, (DIRLEAVEPROC) NULL, NULL, - argc, argv, local, which, aflag, CVS_LOCK_READ, - preload_update_dir, 1, (char *) NULL); - if (err) - return err; - - /* FIXME-twp: at this point we should walk the hardlist - and update the `links' field of each hardlink_info struct - to list the files that are linked on dist. That would make - it easier & more efficient to compare the disk linkage with - the repository linkage (a simple strcmp). */ - } -#endif - - /* call the recursion processor */ - err = start_recursion (update_fileproc, update_filesdone_proc, - update_dirent_proc, update_dirleave_proc, NULL, - argc, argv, local, which, aflag, CVS_LOCK_READ, - preload_update_dir, 1, repository); - - /* see if we need to sleep before returning to avoid time-stamp races */ - if (!server_active && last_register_time) - { - sleep_past (last_register_time); - } - - return err; -} - -#ifdef PRESERVE_PERMISSIONS_SUPPORT -/* - * The get_linkinfo_proc callback adds each file to the hardlist - * (see hardlink.c). - */ - -static int -get_linkinfo_proc (callerdat, finfo) - void *callerdat; - struct file_info *finfo; -{ - char *fullpath; - Node *linkp; - struct hardlink_info *hlinfo; - - /* Get the full pathname of the current file. */ - fullpath = xmalloc (strlen(working_dir) + - strlen(finfo->fullname) + 2); - sprintf (fullpath, "%s/%s", working_dir, finfo->fullname); - - /* To permit recursing into subdirectories, files - are keyed on the full pathname and not on the basename. */ - linkp = lookup_file_by_inode (fullpath); - if (linkp == NULL) - { - /* The file isn't on disk; we are probably restoring - a file that was removed. */ - return 0; - } - - /* Create a new, empty hardlink_info node. */ - hlinfo = (struct hardlink_info *) - xmalloc (sizeof (struct hardlink_info)); - - hlinfo->status = (Ctype) 0; /* is this dumb? */ - hlinfo->checked_out = 0; - - linkp->data = hlinfo; - - return 0; -} -#endif - - - -/* - * This is the callback proc for update. It is called for each file in each - * directory by the recursion code. The current directory is the local - * instantiation. file is the file name we are to operate on. update_dir is - * set to the path relative to where we started (for pretty printing). - * repository is the repository. entries and srcfiles are the pre-parsed - * entries and source control files. - * - * This routine decides what needs to be done for each file and does the - * appropriate magic for checkout - */ -static int -update_fileproc (callerdat, finfo) - void *callerdat; - struct file_info *finfo; -{ - int retval; - Ctype status; - Vers_TS *vers; - - status = Classify_File (finfo, tag, date, options, force_tag_match, - aflag, &vers, pipeout); - - /* Keep track of whether TAG is a branch tag. - Note that if it is a branch tag in some files and a nonbranch tag - in others, treat it as a nonbranch tag. It is possible that case - should elicit a warning or an error. */ - if (rewrite_tag - && tag != NULL - && finfo->rcs != NULL) - { - char *rev = RCS_getversion (finfo->rcs, tag, date, 1, NULL); - if (rev != NULL - && !RCS_nodeisbranch (finfo->rcs, tag)) - nonbranch = 1; - if (rev != NULL) - free (rev); - } - - if (pipeout) - { - /* - * We just return success without doing anything if any of the really - * funky cases occur - * - * If there is still a valid RCS file, do a regular checkout type - * operation - */ - switch (status) - { - case T_UNKNOWN: /* unknown file was explicitly asked - * about */ - case T_REMOVE_ENTRY: /* needs to be un-registered */ - case T_ADDED: /* added but not committed */ - retval = 0; - break; - case T_CONFLICT: /* old punt-type errors */ - retval = 1; - break; - case T_UPTODATE: /* file was already up-to-date */ - case T_NEEDS_MERGE: /* needs merging */ - case T_MODIFIED: /* locally modified */ - case T_REMOVED: /* removed but not committed */ - case T_CHECKOUT: /* needs checkout */ - case T_PATCH: /* needs patch */ - retval = checkout_file (finfo, vers, 0, 0, 0); - break; - - default: /* can't ever happen :-) */ - error (0, 0, - "unknown file status %d for file %s", status, finfo->file); - retval = 0; - break; - } - } - else - { - switch (status) - { - case T_UNKNOWN: /* unknown file was explicitly asked - * about */ - case T_UPTODATE: /* file was already up-to-date */ - retval = 0; - break; - case T_CONFLICT: /* old punt-type errors */ - retval = 1; - write_letter (finfo, 'C'); - break; - case T_NEEDS_MERGE: /* needs merging */ - if (! toss_local_changes) - { - retval = merge_file (finfo, vers); - break; - } - /* else FALL THROUGH */ - case T_MODIFIED: /* locally modified */ - retval = 0; - if (toss_local_changes) - { - char *bakname; - bakname = backup_file (finfo->file, vers->vn_user); - /* This behavior is sufficiently unexpected to - justify overinformativeness, I think. */ - if (!really_quiet && !server_active) - (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) - { - if (file_has_markers (finfo)) - { - 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'); - } - break; - case T_PATCH: /* needs patch */ -#ifdef SERVER_SUPPORT - if (patches) - { - int docheckout; - struct stat file_info; - unsigned char checksum[16]; - - retval = patch_file (finfo, - vers, &docheckout, - &file_info, checksum); - if (! docheckout) - { - if (server_active && retval == 0) - server_updated (finfo, vers, - (rcs_diff_patches - ? SERVER_RCS_DIFF - : SERVER_PATCHED), - file_info.st_mode, checksum, - (struct buffer *) NULL); - break; - } - } -#endif - /* If we're not running as a server, just check the - file out. It's simpler and faster than producing - and applying patches. */ - /* Fall through. */ - case T_CHECKOUT: /* needs checkout */ - retval = checkout_file (finfo, vers, 0, 0, 1); - break; - case T_ADDED: /* added but not committed */ - write_letter (finfo, 'A'); - retval = 0; - break; - case T_REMOVED: /* removed but not committed */ - write_letter (finfo, 'R'); - retval = 0; - break; - case T_REMOVE_ENTRY: /* needs to be un-registered */ - retval = scratch_file (finfo, vers); - break; - default: /* can't ever happen :-) */ - error (0, 0, - "unknown file status %d for file %s", status, finfo->file); - retval = 0; - break; - } - } - - /* only try to join if things have gone well thus far */ - if (retval == 0 && join_rev1) - join_file (finfo, vers); - - /* if this directory has an ignore list, add this file to it */ - if (ignlist && (status != T_UNKNOWN || vers->ts_user == NULL)) - { - Node *p; - - p = getnode (); - p->type = FILES; - p->key = xstrdup (finfo->file); - if (addnode (ignlist, p) != 0) - freenode (p); - } - - freevers_ts (&vers); - return retval; -} - - - -static void update_ignproc PROTO ((const char *, const char *)); - -static void -update_ignproc (file, dir) - const char *file; - const char *dir; -{ - struct file_info finfo; - char *tmp; - - memset (&finfo, 0, sizeof (finfo)); - finfo.file = file; - finfo.update_dir = dir; - if (dir[0] == '\0') - tmp = xstrdup (file); - else - { - tmp = xmalloc (strlen (file) + strlen (dir) + 10); - strcpy (tmp, dir); - strcat (tmp, "/"); - strcat (tmp, file); - } - - finfo.fullname = tmp; - write_letter (&finfo, '?'); - free (tmp); -} - - - -/* ARGSUSED */ -static int -update_filesdone_proc (callerdat, err, repository, update_dir, entries) - void *callerdat; - int err; - const char *repository; - const char *update_dir; - List *entries; -{ - if (rewrite_tag) - { - WriteTag (NULL, tag, date, nonbranch, update_dir, repository); - rewrite_tag = 0; - } - - /* if this directory has an ignore list, process it then free it */ - if (ignlist) - { - ignore_files (ignlist, entries, update_dir, update_ignproc); - dellist (&ignlist); - } - - /* Clean up CVS admin dirs if we are export */ - if (strcmp (cvs_cmd_name, "export") == 0) - { - /* I'm not sure the existence_error is actually possible (except - in cases where we really should print a message), but since - this code used to ignore all errors, I'll play it safe. */ - if (unlink_file_dir (CVSADM) < 0 && !existence_error (errno)) - error (0, errno, "cannot remove %s directory", CVSADM); - } - else if (!server_active && !pipeout) - { - /* If there is no CVS/Root file, add one */ - if (!isfile (CVSADM_ROOT)) - Create_Root ((char *) NULL, current_parsed_root->original); - } - - return err; -} - - - -/* - * update_dirent_proc () is called back by the recursion processor before a - * sub-directory is processed for update. In this case, update_dirent proc - * will probably create the directory unless -d isn't specified and this is a - * new directory. A return code of 0 indicates the directory should be - * processed by the recursion code. A return of non-zero indicates the - * recursion code should skip this directory. - */ -static Dtype -update_dirent_proc (callerdat, dir, repository, update_dir, entries) - void *callerdat; - const char *dir; - const char *repository; - const char *update_dir; - List *entries; -{ - if (ignore_directory (update_dir)) - { - /* print the warm fuzzy message */ - if (!quiet) - error (0, 0, "Ignoring %s", update_dir); - return R_SKIP_ALL; - } - - if (!isdir (dir)) - { - /* if we aren't building dirs, blow it off */ - if (!update_build_dirs) - return R_SKIP_ALL; - - /* Various CVS administrators are in the habit of removing - the repository directory for things they don't want any - more. I've even been known to do it myself (on rare - occasions). Not the usual recommended practice, but we - want to try to come up with some kind of - reasonable/documented/sensible behavior. Generally - the behavior is to just skip over that directory (see - dirs test in sanity.sh; the case which reaches here - is when update -d is specified, and the working directory - is gone but the subdirectory is still mentioned in - CVS/Entries). */ - /* In the remote case, the client should refrain from - sending us the directory in the first place. So we - want to continue to give an error, so clients make - sure to do this. */ - if (!server_active && !isdir (repository)) - return R_SKIP_ALL; - - if (noexec) - { - /* ignore the missing dir if -n is specified */ - error (0, 0, "New directory `%s' -- ignored", update_dir); - return R_SKIP_ALL; - } - else - { - /* otherwise, create the dir and appropriate adm files */ - - /* If no tag or date were specified on the command line, - and we're not using -A, we want the subdirectory to use - the tag and date, if any, of the current directory. - That way, update -d will work correctly when working on - a branch. - - We use TAG_UPDATE_DIR to undo the tag setting in - update_dirleave_proc. If we did not do this, we would - not correctly handle a working directory with multiple - tags (and maybe we should prohibit such working - directories, but they work now and we shouldn't make - them stop working without more thought). */ - if ((tag == NULL && date == NULL) && ! aflag) - { - ParseTag (&tag, &date, &nonbranch); - if (tag != NULL || date != NULL) - tag_update_dir = xstrdup (update_dir); - } - - make_directory (dir); - Create_Admin (dir, update_dir, repository, tag, date, - /* This is a guess. We will rewrite it later - via WriteTag. */ - 0, - 0, - pull_template); - rewrite_tag = 1; - nonbranch = 0; - Subdir_Register (entries, (char *) NULL, dir); - } - } - /* Do we need to check noexec here? */ - else if (!pipeout) - { - char *cvsadmdir; - - /* The directory exists. Check to see if it has a CVS - subdirectory. */ - - cvsadmdir = xmalloc (strlen (dir) + 80); - strcpy (cvsadmdir, dir); - strcat (cvsadmdir, "/"); - strcat (cvsadmdir, CVSADM); - - if (!isdir (cvsadmdir)) - { - /* We cannot successfully recurse into a directory without a CVS - subdirectory. Generally we will have already printed - "? foo". */ - free (cvsadmdir); - return R_SKIP_ALL; - } - free (cvsadmdir); - } - - /* - * If we are building dirs and not going to stdout, we make sure there is - * no static entries file and write the tag file as appropriate - */ - if (!pipeout) - { - if (update_build_dirs) - { - char *tmp; - - tmp = xmalloc (strlen (dir) + sizeof (CVSADM_ENTSTAT) + 10); - (void) sprintf (tmp, "%s/%s", dir, CVSADM_ENTSTAT); - if (unlink_file (tmp) < 0 && ! existence_error (errno)) - error (1, errno, "cannot remove file %s", tmp); -#ifdef SERVER_SUPPORT - if (server_active) - server_clear_entstat (update_dir, repository); -#endif - free (tmp); - } - - /* keep the CVS/Tag file current with the specified arguments */ - if (aflag || tag || date) - { - WriteTag (dir, tag, date, 0, update_dir, repository); - rewrite_tag = 1; - nonbranch = 0; - } - - /* keep the CVS/Template file current */ - if (pull_template) - { - WriteTemplate (dir, update_dir); - } - - /* initialize the ignore list for this directory */ - ignlist = getlist (); - } - - /* print the warm fuzzy message */ - if (!quiet) - error (0, 0, "Updating %s", update_dir); - - return R_PROCESS; -} - - - -/* - * update_dirleave_proc () is called back by the recursion code upon leaving - * a directory. It will prune empty directories if needed and will execute - * any appropriate update programs. - */ -/* ARGSUSED */ -static int -update_dirleave_proc (callerdat, dir, err, update_dir, entries) - void *callerdat; - const char *dir; - int err; - const char *update_dir; - List *entries; -{ - /* 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 - date were both originally NULL in this case. */ - if (tag_update_dir != NULL && strcmp (update_dir, tag_update_dir) == 0) - { - if (tag != NULL) - { - free (tag); - tag = NULL; - } - if (date != NULL) - { - free (date); - date = NULL; - } - nonbranch = 0; - free (tag_update_dir); - tag_update_dir = NULL; - } - - if (strchr (dir, '/') == NULL) - { - /* FIXME: chdir ("..") loses with symlinks. */ - /* Prune empty dirs on the way out - if necessary */ - (void) CVS_CHDIR (".."); - if (update_prune_dirs && isemptydir (dir, 0)) - { - /* I'm not sure the existence_error is actually possible (except - in cases where we really should print a message), but since - this code used to ignore all errors, I'll play it safe. */ - if (unlink_file_dir (dir) < 0 && !existence_error (errno)) - error (0, errno, "cannot remove %s directory", dir); - Subdir_Deregister (entries, (char *) NULL, dir); - } - } - - return err; -} - - - -static int isremoved PROTO ((Node *, void *)); - -/* Returns 1 if the file indicated by node has been removed. */ -static int -isremoved (node, closure) - Node *node; - void *closure; -{ - Entnode *entdata = node->data; - - /* If the first character of the version is a '-', the file has been - removed. */ - return (entdata->version && entdata->version[0] == '-') ? 1 : 0; -} - - - -/* Returns 1 if the argument directory is completely empty, other than the - existence of the CVS directory entry. Zero otherwise. If MIGHT_NOT_EXIST - and the directory doesn't exist, then just return 0. */ -int -isemptydir (dir, might_not_exist) - const char *dir; - int might_not_exist; -{ - DIR *dirp; - struct dirent *dp; - - if ((dirp = CVS_OPENDIR (dir)) == NULL) - { - if (might_not_exist && existence_error (errno)) - return 0; - error (0, errno, "cannot open directory %s for empty check", dir); - return 0; - } - errno = 0; - while ((dp = CVS_READDIR (dirp)) != NULL) - { - if (strcmp (dp->d_name, ".") != 0 - && strcmp (dp->d_name, "..") != 0) - { - if (strcmp (dp->d_name, CVSADM) != 0) - { - /* An entry other than the CVS directory. The directory - is certainly not empty. */ - (void) CVS_CLOSEDIR (dirp); - return 0; - } - else - { - /* The CVS directory entry. We don't have to worry about - this unless the Entries file indicates that files have - been removed, but not committed, in this directory. - (Removing the directory would prevent people from - comitting the fact that they removed the files!) */ - List *l; - int files_removed; - struct saved_cwd cwd; - - if (save_cwd (&cwd)) - error_exit (); - - if (CVS_CHDIR (dir) < 0) - error (1, errno, "cannot change directory to %s", dir); - l = Entries_Open (0, NULL); - files_removed = walklist (l, isremoved, 0); - Entries_Close (l); - - if (restore_cwd (&cwd, NULL)) - error_exit (); - free_cwd (&cwd); - - if (files_removed != 0) - { - /* There are files that have been removed, but not - committed! Do not consider the directory empty. */ - (void) CVS_CLOSEDIR (dirp); - return 0; - } - } - } - errno = 0; - } - if (errno != 0) - { - error (0, errno, "cannot read directory %s", dir); - (void) CVS_CLOSEDIR (dirp); - return 0; - } - (void) CVS_CLOSEDIR (dirp); - return 1; -} - - - -/* - * scratch the Entries file entry associated with a file - */ -static int -scratch_file (finfo, vers) - struct file_info *finfo; - Vers_TS *vers; -{ - history_write ('W', finfo->update_dir, "", finfo->file, finfo->repository); - Scratch_Entry (finfo->entries, finfo->file); -#ifdef SERVER_SUPPORT - if (server_active) - { - if (vers->ts_user == NULL) - server_scratch_entry_only (); - server_updated (finfo, vers, - SERVER_UPDATED, (mode_t) -1, - (unsigned char *) NULL, - (struct buffer *) NULL); - } -#endif - if (unlink_file (finfo->file) < 0 && ! existence_error (errno)) - error (0, errno, "unable to remove %s", finfo->fullname); - else if (!server_active) - { - /* skip this step when the server is running since - * server_updated should have handled it */ - /* keep the vers structure up to date in case we do a join - * - if there isn't a file, it can't very well have a version number, can it? - */ - if (vers->vn_user != NULL) - { - free (vers->vn_user); - vers->vn_user = NULL; - } - if (vers->ts_user != NULL) - { - free (vers->ts_user); - vers->ts_user = NULL; - } - } - return 0; -} - - - -/* - * Check out a file. - */ -static int -checkout_file (finfo, vers_ts, adding, merging, update_server) - struct file_info *finfo; - Vers_TS *vers_ts; - int adding; - int merging; - int update_server; -{ - char *backup; - int set_time, retval = 0; - int status; - int file_is_dead; - struct buffer *revbuf; - - backup = NULL; - revbuf = NULL; - - /* Don't screw with backup files if we're going to stdout, or if - we are the server. */ - if (!pipeout && !server_active) - { - backup = xmalloc (strlen (finfo->file) - + sizeof (CVSADM) - + sizeof (CVSPREFIX) - + 10); - (void) sprintf (backup, "%s/%s%s", CVSADM, CVSPREFIX, finfo->file); - if (isfile (finfo->file)) - rename_file (finfo->file, backup); - else - { - /* If -f/-t wrappers are being used to wrap up a directory, - then backup might be a directory instead of just a file. */ - if (unlink_file_dir (backup) < 0) - { - /* Not sure if the existence_error check is needed here. */ - if (!existence_error (errno)) - /* FIXME: should include update_dir in message. */ - error (0, errno, "error removing %s", backup); - } - free (backup); - backup = NULL; - } - } - - file_is_dead = RCS_isdead (vers_ts->srcfile, vers_ts->vn_rcs); - - if (!file_is_dead) - { - /* - * if we are checking out to stdout, print a nice message to - * stderr, and add the -p flag to the command */ - if (pipeout) - { - if (!quiet) - { - cvs_outerr ("\ -===================================================================\n\ -Checking out ", 0); - cvs_outerr (finfo->fullname, 0); - cvs_outerr ("\n\ -RCS: ", 0); - cvs_outerr (vers_ts->srcfile->path, 0); - cvs_outerr ("\n\ -VERS: ", 0); - cvs_outerr (vers_ts->vn_rcs, 0); - cvs_outerr ("\n***************\n", 0); - } - } - -#ifdef SERVER_SUPPORT - if (update_server - && server_active - && ! pipeout - && ! file_gzip_level - && ! joining () - && ! wrap_name_has (finfo->file, WRAP_FROMCVS)) - { - revbuf = buf_nonio_initialize ((BUFMEMERRPROC) NULL); - status = RCS_checkout (vers_ts->srcfile, (char *) NULL, - vers_ts->vn_rcs, vers_ts->tag, - vers_ts->options, RUN_TTY, - checkout_to_buffer, revbuf); - } - else -#endif - status = RCS_checkout (vers_ts->srcfile, - pipeout ? NULL : finfo->file, - vers_ts->vn_rcs, vers_ts->tag, - vers_ts->options, RUN_TTY, - (RCSCHECKOUTPROC) NULL, (void *) NULL); - } - if (file_is_dead || status == 0) - { - mode_t mode; - - mode = (mode_t) -1; - - if (!pipeout) - { - Vers_TS *xvers_ts; - - if (revbuf != NULL && !noexec) - { - struct stat sb; - - /* FIXME: We should have RCS_checkout return the mode. - That would also fix the kludge with noexec, above, which - is here only because noexec doesn't write srcfile->path - for us to stat. */ - if (stat (vers_ts->srcfile->path, &sb) < 0) - { -#if defined (SERVER_SUPPORT) || defined (CLIENT_SUPPORT) - buf_free (revbuf); -#endif /* defined (SERVER_SUPPORT) || defined (CLIENT_SUPPORT) */ - error (1, errno, "cannot stat %s", - vers_ts->srcfile->path); - } - mode = sb.st_mode &~ (S_IWRITE | S_IWGRP | S_IWOTH); - } - - if (cvswrite - && !file_is_dead - && !fileattr_get (finfo->file, "_watched")) - { - if (revbuf == NULL) - xchmod (finfo->file, 1); - else - { - /* We know that we are the server here, so - although xchmod checks umask, we don't bother. */ - mode |= (((mode & S_IRUSR) ? S_IWUSR : 0) - | ((mode & S_IRGRP) ? S_IWGRP : 0) - | ((mode & S_IROTH) ? S_IWOTH : 0)); - } - } - - { - /* A newly checked out file is never under the spell - of "cvs edit". If we think we were editing it - from a previous life, clean up. Would be better to - check for same the working directory instead of - same user, but that is hairy. */ - - struct addremove_args args; - - editor_set (finfo->file, getcaller (), NULL); - - memset (&args, 0, sizeof args); - args.remove_temp = 1; - watch_modify_watchers (finfo->file, &args); - } - - /* set the time from the RCS file iff it was unknown before */ - set_time = - (!noexec - && (vers_ts->vn_user == NULL || - strncmp (vers_ts->ts_rcs, "Initial", 7) == 0) - && !file_is_dead); - - wrap_fromcvs_process_file (finfo->file); - - xvers_ts = Version_TS (finfo, options, tag, date, - force_tag_match, set_time); - if (strcmp (xvers_ts->options, "-V4") == 0) - xvers_ts->options[0] = '\0'; - - if (revbuf != NULL) - { - /* If we stored the file data into a buffer, then we - didn't create a file at all, so xvers_ts->ts_user - is wrong. The correct value is to have it be the - same as xvers_ts->ts_rcs, meaning that the working - file is unchanged from the RCS file. - - FIXME: We should tell Version_TS not to waste time - statting the nonexistent file. - - FIXME: Actually, I don't think the ts_user value - matters at all here. The only use I know of is - that it is printed in a trace message by - Server_Register. */ - - if (xvers_ts->ts_user != NULL) - free (xvers_ts->ts_user); - xvers_ts->ts_user = xstrdup (xvers_ts->ts_rcs); - } - - (void) time (&last_register_time); - - if (file_is_dead) - { - if (xvers_ts->vn_user != NULL) - { - error (0, 0, - "warning: %s is not (any longer) pertinent", - finfo->fullname); - } - Scratch_Entry (finfo->entries, finfo->file); -#ifdef SERVER_SUPPORT - if (server_active && xvers_ts->ts_user == NULL) - server_scratch_entry_only (); -#endif - /* FIXME: Rather than always unlink'ing, and ignoring the - existence_error, we should do the unlink only if - vers_ts->ts_user is non-NULL. Then there would be no - need to ignore an existence_error (for example, if the - user removes the file while we are running). */ - if (unlink_file (finfo->file) < 0 && ! existence_error (errno)) - { - error (0, errno, "cannot remove %s", finfo->fullname); - } - } - else - Register (finfo->entries, finfo->file, - adding ? "0" : xvers_ts->vn_rcs, - xvers_ts->ts_user, xvers_ts->options, - xvers_ts->tag, xvers_ts->date, - (char *)0); /* Clear conflict flag on fresh checkout */ - - /* fix up the vers structure, in case it is used by join */ - if (join_rev1) - { - /* FIXME: It seems like we should be preserving ts_user - * & ts_rcs here, but setting them causes problems in - * join_file(). - */ - if (vers_ts->vn_user != NULL) - free (vers_ts->vn_user); - if (vers_ts->vn_rcs != NULL) - free (vers_ts->vn_rcs); - vers_ts->vn_user = xstrdup (xvers_ts->vn_rcs); - vers_ts->vn_rcs = xstrdup (xvers_ts->vn_rcs); - } - - /* If this is really Update and not Checkout, recode history */ - if (strcmp (cvs_cmd_name, "update") == 0) - history_write ('U', finfo->update_dir, xvers_ts->vn_rcs, finfo->file, - finfo->repository); - - freevers_ts (&xvers_ts); - - if (!really_quiet && !file_is_dead) - { - write_letter (finfo, 'U'); - } - } - -#ifdef SERVER_SUPPORT - if (update_server && server_active) - server_updated (finfo, vers_ts, - merging ? SERVER_MERGED : SERVER_UPDATED, - mode, (unsigned char *) NULL, revbuf); -#endif - } - else - { - if (backup != NULL) - { - rename_file (backup, finfo->file); - free (backup); - backup = NULL; - } - - error (0, 0, "could not check out %s", finfo->fullname); - - retval = status; - } - - if (backup != NULL) - { - /* If -f/-t wrappers are being used to wrap up a directory, - then backup might be a directory instead of just a file. */ - if (unlink_file_dir (backup) < 0) - { - /* Not sure if the existence_error check is needed here. */ - if (!existence_error (errno)) - /* FIXME: should include update_dir in message. */ - error (0, errno, "error removing %s", backup); - } - free (backup); - } - -#if defined (SERVER_SUPPORT) || defined (CLIENT_SUPPORT) - if (revbuf != NULL) - buf_free (revbuf); -#endif /* defined (SERVER_SUPPORT) || defined (CLIENT_SUPPORT) */ - return retval; -} - - - -#ifdef SERVER_SUPPORT - -/* This function is used to write data from a file being checked out - into a buffer. */ - -static void -checkout_to_buffer (callerdat, data, len) - void *callerdat; - const char *data; - size_t len; -{ - struct buffer *buf = (struct buffer *) callerdat; - - buf_output (buf, data, len); -} - -#endif /* SERVER_SUPPORT */ - -#ifdef SERVER_SUPPORT - -/* This structure is used to pass information between patch_file and - patch_file_write. */ - -struct patch_file_data -{ - /* File name, for error messages. */ - const char *filename; - /* File to which to write. */ - FILE *fp; - /* Whether to compute the MD5 checksum. */ - int compute_checksum; - /* Data structure for computing the MD5 checksum. */ - struct cvs_MD5Context context; - /* Set if the file has a final newline. */ - int final_nl; -}; - -/* Patch a file. Runs diff. This is only done when running as the - * server. The hope is that the diff will be smaller than the file - * itself. - */ -static int -patch_file (finfo, vers_ts, docheckout, file_info, checksum) - struct file_info *finfo; - Vers_TS *vers_ts; - int *docheckout; - struct stat *file_info; - unsigned char *checksum; -{ - char *backup; - char *file1; - char *file2; - int retval = 0; - int retcode = 0; - int fail; - FILE *e; - struct patch_file_data data; - - *docheckout = 0; - - if (noexec || pipeout || joining ()) - { - *docheckout = 1; - return 0; - } - - /* If this file has been marked as being binary, then never send a - patch. */ - if (strcmp (vers_ts->options, "-kb") == 0) - { - *docheckout = 1; - return 0; - } - - /* First check that the first revision exists. If it has been nuked - by cvs admin -o, then just fall back to checking out entire - revisions. In some sense maybe we don't have to do this; after - all cvs.texinfo says "Make sure that no-one has checked out a - copy of the revision you outdate" but then again, that advice - doesn't really make complete sense, because "cvs admin" operates - on a working directory and so _someone_ will almost always have - _some_ revision checked out. */ - { - char *rev; - - rev = RCS_gettag (finfo->rcs, vers_ts->vn_user, 1, NULL); - if (rev == NULL) - { - *docheckout = 1; - return 0; - } - else - free (rev); - } - - /* If the revision is dead, let checkout_file handle it rather - than duplicating the processing here. */ - if (RCS_isdead (vers_ts->srcfile, vers_ts->vn_rcs)) - { - *docheckout = 1; - return 0; - } - - backup = xmalloc (strlen (finfo->file) - + sizeof (CVSADM) - + sizeof (CVSPREFIX) - + 10); - (void) sprintf (backup, "%s/%s%s", CVSADM, CVSPREFIX, finfo->file); - if (isfile (finfo->file)) - rename_file (finfo->file, backup); - else - { - if (unlink_file (backup) < 0 - && !existence_error (errno)) - error (0, errno, "cannot remove %s", backup); - } - - file1 = xmalloc (strlen (finfo->file) - + sizeof (CVSADM) - + sizeof (CVSPREFIX) - + 10); - (void) sprintf (file1, "%s/%s%s-1", CVSADM, CVSPREFIX, finfo->file); - file2 = xmalloc (strlen (finfo->file) - + sizeof (CVSADM) - + sizeof (CVSPREFIX) - + 10); - (void) sprintf (file2, "%s/%s%s-2", CVSADM, CVSPREFIX, finfo->file); - - fail = 0; - - /* We need to check out both revisions first, to see if either one - has a trailing newline. Because of this, we don't use rcsdiff, - but just use diff. */ - - e = CVS_FOPEN (file1, "w"); - if (e == NULL) - error (1, errno, "cannot open %s", file1); - - data.filename = file1; - data.fp = e; - data.final_nl = 0; - data.compute_checksum = 0; - - /* Duplicating the client working file, so use the original sticky options. - */ - retcode = RCS_checkout (vers_ts->srcfile, (char *) NULL, - vers_ts->vn_user, vers_ts->entdata->tag, - vers_ts->entdata->options, RUN_TTY, - patch_file_write, (void *) &data); - - if (fclose (e) < 0) - error (1, errno, "cannot close %s", file1); - - if (retcode != 0 || ! data.final_nl) - fail = 1; - - if (! fail) - { - e = CVS_FOPEN (file2, "w"); - if (e == NULL) - error (1, errno, "cannot open %s", file2); - - data.filename = file2; - data.fp = e; - data.final_nl = 0; - data.compute_checksum = 1; - cvs_MD5Init (&data.context); - - retcode = RCS_checkout (vers_ts->srcfile, (char *) NULL, - vers_ts->vn_rcs, vers_ts->tag, - vers_ts->options, RUN_TTY, - patch_file_write, (void *) &data); - - if (fclose (e) < 0) - error (1, errno, "cannot close %s", file2); - - if (retcode != 0 || ! data.final_nl) - fail = 1; - else - cvs_MD5Final (checksum, &data.context); - } - - retcode = 0; - if (! fail) - { - int dargc = 0; - size_t darg_allocated = 0; - char **dargv = NULL; - - /* If the client does not support the Rcs-diff command, we - send a context diff, and the client must invoke patch. - That approach was problematical for various reasons. The - new approach only requires running diff in the server; the - client can handle everything without invoking an external - program. */ - if (!rcs_diff_patches) - /* We use -c, not -u, because that is what CVS has - traditionally used. Kind of a moot point, now that - Rcs-diff is preferred, so there is no point in making - the compatibility issues worse. */ - run_add_arg_p (&dargc, &darg_allocated, &dargv, "-c"); - else - /* Now that diff is librarified, we could be passing -a if - we wanted to. However, it is unclear to me whether we - would want to. Does diff -a, in any significant - percentage of cases, produce patches which are smaller - than the files it is patching? I guess maybe text - files with character sets which diff regards as - 'binary'. Conversely, do they tend to be much larger - in the bad cases? This needs some more - thought/investigation, I suspect. */ - run_add_arg_p (&dargc, &darg_allocated, &dargv, "-n"); - retcode = diff_exec (file1, file2, NULL, NULL, dargc, dargv, - finfo->file); - run_arg_free_p (dargc, dargv); - free (dargv); - - /* A retcode of 0 means no differences. 1 means some differences. */ - if (retcode != 0 - && retcode != 1) - { - fail = 1; - } - } - - if (! fail) - { - struct stat file2_info; - - /* Check to make sure the patch is really shorter */ - if (CVS_STAT (file2, &file2_info) < 0) - error (1, errno, "could not stat %s", file2); - if (CVS_STAT (finfo->file, file_info) < 0) - error (1, errno, "could not stat %s", finfo->file); - if (file2_info.st_size <= file_info->st_size) - fail = 1; - } - - if (! fail) - { -# define BINARY "Binary" - char buf[sizeof BINARY]; - unsigned int c; - - /* Check the diff output to make sure patch will be handle it. */ - e = CVS_FOPEN (finfo->file, "r"); - if (e == NULL) - error (1, errno, "could not open diff output file %s", - finfo->fullname); - c = fread (buf, 1, sizeof BINARY - 1, e); - buf[c] = '\0'; - if (strcmp (buf, BINARY) == 0) - { - /* These are binary files. We could use diff -a, but - patch can't handle that. */ - fail = 1; - } - fclose (e); - } - - if (! fail) - { - Vers_TS *xvers_ts; - - /* Stat the original RCS file, and then adjust it the way - that RCS_checkout would. FIXME: This is an abstraction - violation. */ - if (CVS_STAT (vers_ts->srcfile->path, file_info) < 0) - error (1, errno, "could not stat %s", vers_ts->srcfile->path); - if (chmod (finfo->file, - file_info->st_mode & ~(S_IWRITE | S_IWGRP | S_IWOTH)) - < 0) - error (0, errno, "cannot change mode of file %s", finfo->file); - if (cvswrite - && !fileattr_get (finfo->file, "_watched")) - xchmod (finfo->file, 1); - - /* This stuff is just copied blindly from checkout_file. I - don't really know what it does. */ - xvers_ts = Version_TS (finfo, options, tag, date, - force_tag_match, 0); - if (strcmp (xvers_ts->options, "-V4") == 0) - xvers_ts->options[0] = '\0'; - - Register (finfo->entries, finfo->file, xvers_ts->vn_rcs, - xvers_ts->ts_user, xvers_ts->options, - xvers_ts->tag, xvers_ts->date, NULL); - - if (CVS_STAT (finfo->file, file_info) < 0) - error (1, errno, "could not stat %s", finfo->file); - - /* If this is really Update and not Checkout, record history. */ - if (strcmp (cvs_cmd_name, "update") == 0) - history_write ('P', finfo->update_dir, xvers_ts->vn_rcs, - finfo->file, finfo->repository); - - freevers_ts (&xvers_ts); - - if (!really_quiet) - { - write_letter (finfo, 'P'); - } - } - else - { - int old_errno = errno; /* save errno value over the rename */ - - if (isfile (backup)) - rename_file (backup, finfo->file); - - if (retcode != 0 && retcode != 1) - error (retcode == -1 ? 1 : 0, retcode == -1 ? old_errno : 0, - "could not diff %s", finfo->fullname); - - *docheckout = 1; - retval = retcode; - } - - if (unlink_file (backup) < 0 - && !existence_error (errno)) - error (0, errno, "cannot remove %s", backup); - if (unlink_file (file1) < 0 - && !existence_error (errno)) - error (0, errno, "cannot remove %s", file1); - if (unlink_file (file2) < 0 - && !existence_error (errno)) - error (0, errno, "cannot remove %s", file2); - - free (backup); - free (file1); - free (file2); - return retval; -} - - - -/* Write data to a file. Record whether the last byte written was a - newline. Optionally compute a checksum. This is called by - patch_file via RCS_checkout. */ - -static void -patch_file_write (callerdat, buffer, len) - void *callerdat; - const char *buffer; - size_t len; -{ - struct patch_file_data *data = (struct patch_file_data *) callerdat; - - if (fwrite (buffer, 1, len, data->fp) != len) - error (1, errno, "cannot write %s", data->filename); - - data->final_nl = (buffer[len - 1] == '\n'); - - if (data->compute_checksum) - cvs_MD5Update (&data->context, (unsigned char *) buffer, len); -} - -#endif /* SERVER_SUPPORT */ - -/* - * Several of the types we process only print a bit of information consisting - * of a single letter and the name. - */ -void -write_letter (finfo, letter) - struct file_info *finfo; - int letter; -{ - if (!really_quiet) - { - char *tag = NULL; - /* Big enough for "+updated" or any of its ilk. */ - char buf[80]; - - switch (letter) - { - case 'U': - tag = "updated"; - break; - default: - /* We don't yet support tagged output except for "U". */ - break; - } - - if (tag != NULL) - { - sprintf (buf, "+%s", tag); - cvs_output_tagged (buf, NULL); - } - buf[0] = letter; - buf[1] = ' '; - buf[2] = '\0'; - cvs_output_tagged ("text", buf); - cvs_output_tagged ("fname", finfo->fullname); - cvs_output_tagged ("newline", NULL); - if (tag != NULL) - { - sprintf (buf, "-%s", tag); - cvs_output_tagged (buf, NULL); - } - } - return; -} - - - -/* Reregister a file after a merge. */ -static void -RegisterMerge PROTO((struct file_info *finfo, Vers_TS *vers, - const char *backup, int has_conflicts)); -static void -RegisterMerge (finfo, vers, backup, has_conflicts) - struct file_info *finfo; - Vers_TS *vers; - const char *backup; - int has_conflicts; -{ - /* This file is the result of a merge, which means that it has - been modified. We use a special timestamp string which will - not compare equal to any actual timestamp. */ - char *cp = NULL; - - if (has_conflicts) - { - time (&last_register_time); - cp = time_stamp (finfo->file); - } - 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); - -#ifdef SERVER_SUPPORT - /* Send the new contents of the file before the message. If we - wanted to be totally correct, we would have the client write - the message only after the file has safely been written. */ - if (server_active) - { - server_copy_file (finfo->file, finfo->update_dir, finfo->repository, - backup); - server_updated (finfo, vers, SERVER_MERGED, (mode_t) -1, NULL, NULL); - } -#endif -} - - - -/* - * Do all the magic associated with a file which needs to be merged - */ -static int -merge_file (finfo, vers) - struct file_info *finfo; - Vers_TS *vers; -{ - char *backup; - int status; - int retcode = 0; - int retval; - - assert (vers->vn_user); - - /* - * The users currently modified file is moved to a backup file name - * ".#filename.version", so that it will stay around for a few days - * before being automatically removed by some cron daemon. The "version" - * is the version of the file that the user was most up-to-date with - * before the merge. - */ - backup = xmalloc (strlen (finfo->file) - + strlen (vers->vn_user) - + sizeof (BAKPREFIX) - + 10); - (void) sprintf (backup, "%s%s.%s", BAKPREFIX, finfo->file, vers->vn_user); - - if (unlink_file (backup) && !existence_error (errno)) - error (0, errno, "unable to remove %s", backup); - copy_file (finfo->file, backup); - xchmod (finfo->file, 1); - - if (strcmp (vers->options, "-kb") == 0 - || wrap_merge_is_copy (finfo->file) - || special_file_mismatch (finfo, NULL, vers->vn_rcs)) - { - /* For binary files, a merge is always a conflict. Same for - files whose permissions or linkage do not match. We give the - user the two files, and let them resolve it. It is possible - that we should require a "touch foo" or similar step before - we allow a checkin. */ - - /* TODO: it may not always be necessary to regard a permission - mismatch as a conflict. The working file and the RCS file - have a common ancestor `A'; if the working file's permissions - match A's, then it's probably safe to overwrite them with the - RCS permissions. Only if the working file, the RCS file, and - A all disagree should this be considered a conflict. But more - thought needs to go into this, and in the meantime it is safe - to treat any such mismatch as an automatic conflict. -twp */ - - retcode = RCS_checkout (finfo->rcs, finfo->file, - vers->vn_rcs, vers->tag, - vers->options, NULL, NULL, NULL); - if (retcode) - { - error (0, 0, "failed to check out `%s' file", finfo->fullname); - error (0, 0, "restoring `%s' from backup file `%s'", - finfo->fullname, backup); - rename_file (backup, finfo->file); - retval = 1; - goto out; - } - xchmod (finfo->file, 1); - - RegisterMerge (finfo, vers, backup, 1); - - /* Is there a better term than "nonmergeable file"? What we - really mean is, not something that CVS cannot or does not - want to merge (there might be an external manual or - automatic merge process). */ - error (0, 0, "nonmergeable file needs merge"); - error (0, 0, "revision %s from repository is now in %s", - vers->vn_rcs, finfo->fullname); - error (0, 0, "file from working directory is now in %s", backup); - write_letter (finfo, 'C'); - - history_write ('C', finfo->update_dir, vers->vn_rcs, finfo->file, - finfo->repository); - retval = 0; - goto out; - } - - status = RCS_merge (finfo->rcs, vers->srcfile->path, finfo->file, - vers->options, vers->vn_user, vers->vn_rcs); - if (status != 0 && status != 1) - { - error (0, status == -1 ? errno : 0, - "could not merge revision %s of %s", vers->vn_user, finfo->fullname); - error (status == -1 ? 1 : 0, 0, "restoring %s from backup file %s", - finfo->fullname, backup); - rename_file (backup, finfo->file); - retval = 1; - goto out; - } - - if (strcmp (vers->options, "-V4") == 0) - vers->options[0] = '\0'; - - /* fix up the vers structure, in case it is used by join */ - if (join_rev1) - { - /* FIXME: Throwing away the original revision info is almost - certainly wrong -- what if join_rev1 is "BASE"? */ - if (vers->vn_user != NULL) - free (vers->vn_user); - vers->vn_user = xstrdup (vers->vn_rcs); - } - - RegisterMerge (finfo, vers, backup, status); - - /* FIXME: the noexec case is broken. RCS_merge could be doing the - xcmp on the temporary files without much hassle, I think. */ - if (!noexec && !xcmp (backup, finfo->file)) - { - cvs_output (finfo->fullname, 0); - cvs_output (" already contains the differences between ", 0); - cvs_output (vers->vn_user, 0); - cvs_output (" and ", 0); - cvs_output (vers->vn_rcs, 0); - cvs_output ("\n", 1); - - history_write ('G', finfo->update_dir, vers->vn_rcs, finfo->file, - finfo->repository); - retval = 0; - goto out; - } - - if (status == 1) - { - error (0, 0, "conflicts found in %s", finfo->fullname); - - write_letter (finfo, 'C'); - - history_write ('C', finfo->update_dir, vers->vn_rcs, finfo->file, - finfo->repository); - - } - else if (retcode == -1) - { - error (1, errno, "fork failed while examining update of %s", - finfo->fullname); - } - else - { - write_letter (finfo, 'M'); - history_write ('G', finfo->update_dir, vers->vn_rcs, finfo->file, - finfo->repository); - } - retval = 0; - out: - free (backup); - return retval; -} - - - -/* - * Do all the magic associated with a file which needs to be joined - * (reached via the -j option to checkout or update). - * - * INPUTS - * finfo File information about the destination file. - * vers The Vers_TS structure for finfo. - * - * GLOBALS - * join_rev1 From the command line. - * join_rev2 From the command line. - * server_active Natch. - * - * ASSUMPTIONS - * 1. Is not called in client mode. - */ -static void -join_file (finfo, vers) - struct file_info *finfo; - Vers_TS *vers; -{ - char *backup; - char *t_options; - int status; - - char *rev1; - char *rev2; - char *jrev1; - char *jrev2; - char *jdate1; - char *jdate2; - - if (trace) - fprintf (stderr, "%s-> join_file(%s, %s%s%s%s, %s, %s)\n", - CLIENT_SERVER_STR, - finfo->file, - vers->tag ? vers->tag : "", - vers->tag ? " (" : "", - vers->vn_rcs ? vers->vn_rcs : "", - vers->tag ? ")" : "", - join_rev1 ? join_rev1 : "", - join_rev2 ? join_rev2 : ""); - - jrev1 = join_rev1; - jrev2 = join_rev2; - jdate1 = date_rev1; - jdate2 = date_rev2; - - /* Determine if we need to do anything at all. */ - if (vers->srcfile == NULL || - vers->srcfile->path == NULL) - { - return; - } - - /* If only one join revision is specified, it becomes the second - revision. */ - if (jrev2 == NULL) - { - jrev2 = jrev1; - jrev1 = NULL; - jdate2 = jdate1; - jdate1 = NULL; - } - - /* FIXME: Need to handle "BASE" for jrev1 and/or jrev2. Note caveat - below about vn_user. */ - - /* Convert the second revision, walking branches and dates. */ - rev2 = RCS_getversion (vers->srcfile, jrev2, jdate2, 1, (int *) NULL); - - /* If this is a merge of two revisions, get the first revision. - If only one join tag was specified, then the first revision is - the greatest common ancestor of the second revision and the - working file. */ - if (jrev1 != NULL) - rev1 = RCS_getversion (vers->srcfile, jrev1, jdate1, 1, (int *) NULL); - else - { - /* Note that we use vn_rcs here, since vn_user may contain a - special string such as "-nn". */ - if (vers->vn_rcs == NULL) - rev1 = NULL; - else if (rev2 == NULL) - { - /* This means that the file never existed on the branch. - It does not mean that the file was removed on the - branch: that case is represented by a dead rev2. If - the file never existed on the branch, then we have - nothing to merge, so we just return. */ - return; - } - else - rev1 = gca (vers->vn_rcs, rev2); - } - - /* Handle a nonexistent or dead merge target. */ - if (rev2 == NULL || RCS_isdead (vers->srcfile, rev2)) - { - char *mrev; - short conflict = 0; - - if (rev2 != NULL) - free (rev2); - - /* If the first revision doesn't exist either, then there is - no change between the two revisions, so we don't do - anything. */ - if (rev1 == NULL || RCS_isdead (vers->srcfile, rev1)) - { - if (rev1 != NULL) - free (rev1); - return; - } - - /* If we are merging two revisions, then the file was removed - between the first revision and the second one. In this - case we want to mark the file for removal. - - If we are merging one revision, then the file has been - removed between the greatest common ancestor and the merge - revision. From the perspective of the branch on to which - we ar emerging, which may be the trunk, either 1) the file - does not currently exist on the target, or 2) the file has - not been modified on the target branch since the greatest - common ancestor, or 3) the file has been modified on the - target branch since the greatest common ancestor. In case - 1 there is nothing to do. In case 2 we mark the file for - removal. In case 3 we have a conflict. - - Note that the handling is slightly different depending upon - whether one or two join targets were specified. If two - join targets were specified, we don't check whether the - file was modified since a given point. My reasoning is - that if you ask for an explicit merge between two tags, - then you want to merge in whatever was changed between - those two tags. If a file was removed between the two - tags, then you want it to be removed. However, if you ask - for a merge of a branch, then you want to merge in all - changes which were made on the branch. If a file was - removed on the branch, that is a change to the file. If - the file was also changed on the main line, then that is - also a change. These two changes--the file removal and the - modification--must be merged. This is a conflict. */ - - /* If the user file is dead, or does not exist, or has been - marked for removal, then there is nothing to do. */ - if (vers->vn_user == NULL - || vers->vn_user[0] == '-' - || RCS_isdead (vers->srcfile, vers->vn_user)) - { - free (rev1); - return; - } - - /* If the user file has been marked for addition, or has been - locally modified, then we have a conflict which we can not - resolve. No_Difference will already have been called in - this case, so comparing the timestamps is sufficient to - determine whether the file is locally modified. */ - if (/* may have changed on destination branch */ - /* file added locally */ - !strcmp (vers->vn_user, "0") - || /* destination branch modified in repository */ - strcmp (rev1, vers->vn_user) - || /* locally modified */ - vers->ts_user && strcmp (vers->ts_user, vers->ts_rcs)) - { - /* The removal should happen if either the file has never changed - * on the destination or the file has changed to be identical to - * the first join revision. - * - * ------R-----------D - * | - * \----J1---J2-----S - * - * So: - * - * J2 is dead. - * D is destination. - * R is source branch root/GCA. - * if J1 == D removal should happen - * if D == R removal should happen - * otherwise, fail. - * - * (In the source, J2 = REV2, D = user file (potentially VN_USER), - * R = GCA computed below) - */ - char *gca_rev1 = gca (rev1, vers->vn_user); -#ifdef SERVER_SUPPORT - if (server_active && !isreadable (finfo->file)) - { - int retcode; - /* The file is up to date. Need to check out the current - * contents. - */ - /* FIXME - see the FIXME comment above the call to RCS_checkout - * in the patch_file function. - */ - retcode = RCS_checkout (vers->srcfile, finfo->file, - vers->vn_user, vers->tag, - NULL, RUN_TTY, NULL, NULL); - if (retcode) - error (1, 0, - "failed to check out %s file", finfo->fullname); - } -#endif - if (/* genuinely changed on destination branch */ - RCS_cmp_file (vers->srcfile, gca_rev1, NULL, - NULL, vers->options, finfo->file) - && /* genuinely different from REV1 */ - RCS_cmp_file (vers->srcfile, rev1, NULL, - NULL, vers->options, finfo->file)) - conflict = 1; - } - - free (rev1); - - if (conflict) - { - char *cp; - - if (jdate2) - error (0, 0, - "file %s has been removed in revision %s as of %s, but the destination is incompatibly modified", - finfo->fullname, jrev2, jdate2); - else - error (0, 0, - "file %s has been removed in revision %s, but the destination is incompatibly modified", - finfo->fullname, jrev2); - - /* Register the conflict with the client. */ - - /* FIXME: vers->ts_user should always be set here but sometimes - * isn't, namely when checkout_file() has just created the file, - * but simply setting it in checkout_file() appears to cause other - * problems. - */ - if (isfile (finfo->file)) - cp = time_stamp (finfo->file); - else - cp = xstrdup (vers->ts_user); - - Register (finfo->entries, finfo->file, vers->vn_user, - "Result of merge", vers->options, vers->tag, vers->date, - cp); - write_letter (finfo, 'C'); - free (cp); - -#ifdef SERVER_SUPPORT - /* Abuse server_checked_in() to send the updated entry without - * needing to update the file. - */ - if (server_active) - server_checked_in (finfo->file, finfo->update_dir, - finfo->repository); -#endif - - return; - } - - /* The user file exists and has not been modified. Mark it - for removal. FIXME: If we are doing a checkout, this has - the effect of first checking out the file, and then - removing it. It would be better to just register the - removal. - - The same goes for a removal then an add. e.g. - cvs up -rbr -jbr2 could remove and readd the same file - */ - /* save the rev since server_updated might invalidate it */ - mrev = xmalloc (strlen (vers->vn_user) + 2); - sprintf (mrev, "-%s", vers->vn_user); -#ifdef SERVER_SUPPORT - if (server_active) - { - server_scratch (finfo->file); - server_updated (finfo, vers, SERVER_UPDATED, (mode_t) -1, - (unsigned char *) NULL, (struct buffer *) NULL); - } -#endif - Register (finfo->entries, finfo->file, mrev, vers->ts_rcs, - vers->options, vers->tag, vers->date, vers->ts_conflict); - free (mrev); - /* We need to check existence_error here because if we are - running as the server, and the file is up to date in the - working directory, the client will not have sent us a copy. */ - if (unlink_file (finfo->file) < 0 && ! existence_error (errno)) - error (0, errno, "cannot remove file %s", finfo->fullname); -#ifdef SERVER_SUPPORT - if (server_active) - server_checked_in (finfo->file, finfo->update_dir, - finfo->repository); -#endif - if (! really_quiet) - error (0, 0, "scheduling %s for removal", finfo->fullname); - - return; - } - - /* If the two merge revisions are the same, then there is nothing - * to do. This needs to be checked before the rev2 == up-to-date base - * revision check tha comes next. Otherwise, rev1 can == rev2 and get an - * "already contains the changes between and " message. - */ - if (rev1 && strcmp (rev1, rev2) == 0) - { - free (rev1); - free (rev2); - return; - } - - /* If we know that the user file is up-to-date, then it becomes an - * optimization to skip the merge when rev2 is the same as the base - * revision. i.e. we know that diff3(file2,file1,file2) will produce - * file2. - */ - if (vers->vn_user != NULL && vers->ts_user != NULL - && strcmp (vers->ts_user, vers->ts_rcs) == 0 - && strcmp (rev2, vers->vn_user) == 0) - { - if (!really_quiet) - { - cvs_output (finfo->fullname, 0); - cvs_output (" already contains the differences between ", 0); - cvs_output (rev1 ? rev1 : "creation", 0); - cvs_output (" and ", 0); - cvs_output (rev2, 0); - cvs_output ("\n", 1); - } - - if (rev1 != NULL) - free (rev1); - free (rev2); - - return; - } - - /* If rev1 is dead or does not exist, then the file was added - between rev1 and rev2. */ - if (rev1 == NULL || RCS_isdead (vers->srcfile, rev1)) - { - if (rev1 != NULL) - free (rev1); - free (rev2); - - /* If the file does not exist in the working directory, then - we can just check out the new revision and mark it for - addition. */ - if (vers->vn_user == NULL) - { - char *saved_options = options; - Vers_TS *xvers; - - 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); - options = saved_options; - - freevers_ts (&xvers); - - return; - } - - /* The file currently exists in the working directory, so we - have a conflict which we can not resolve. Note that this - is true even if the file is marked for addition or removal. */ - - if (jdate2 != NULL) - error (0, 0, - "file %s exists, but has been added in revision %s as of %s", - finfo->fullname, jrev2, jdate2); - else - error (0, 0, - "file %s exists, but has been added in revision %s", - finfo->fullname, jrev2); - - return; - } - - /* If there is no working file, then we can't do the merge. */ - if (vers->vn_user == NULL || vers->vn_user[0] == '-') - { - free (rev1); - free (rev2); - - if (jdate2 != NULL) - error (0, 0, - "file %s does not exist, but is present in revision %s as of %s", - finfo->fullname, jrev2, jdate2); - else - error (0, 0, - "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? */ - - return; - } - -#ifdef SERVER_SUPPORT - if (server_active && !isreadable (finfo->file)) - { - int retcode; - /* The file is up to date. Need to check out the current contents. */ - /* FIXME - see the FIXME comment above the call to RCS_checkout in the - * patch_file function. - */ - retcode = RCS_checkout (vers->srcfile, finfo->file, - vers->vn_user, vers->tag, - (char *) NULL, RUN_TTY, - (RCSCHECKOUTPROC) NULL, (void *) NULL); - if (retcode != 0) - error (1, 0, - "failed to check out %s file", finfo->fullname); - } -#endif - - /* - * The users currently modified file is moved to a backup file name - * ".#filename.version", so that it will stay around for a few days - * before being automatically removed by some cron daemon. The "version" - * is the version of the file that the user was most up-to-date with - * before the merge. - */ - backup = xmalloc (strlen (finfo->file) - + strlen (vers->vn_user) - + sizeof (BAKPREFIX) - + 10); - (void) sprintf (backup, "%s%s.%s", BAKPREFIX, finfo->file, vers->vn_user); - - if (unlink_file (backup) < 0 - && !existence_error (errno)) - error (0, errno, "cannot remove %s", backup); - copy_file (finfo->file, backup); - xchmod (finfo->file, 1); - - t_options = vers->options; -#if 0 - 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 - revision, then we can just RCS_checkout the target (no merging - as such). In the text file case, this is probably quite - similar to the RCS_merge, but in the binary file case, - RCS_merge gives all kinds of trouble. */ - if (vers->vn_user != NULL - && strcmp (rev1, vers->vn_user) == 0 - /* See comments above about how No_Difference has already been - called. */ - && vers->ts_user != NULL - && strcmp (vers->ts_user, vers->ts_rcs) == 0 - - /* Avoid this in the text file case. See below for why. - */ - && (strcmp (t_options, "-kb") == 0 - || wrap_merge_is_copy (finfo->file))) - { - /* FIXME: Verify my comment below: - * - * RCS_merge does nothing with keywords. It merges the changes between - * two revisions without expanding the keywords (it might expand in - * -kk mode before computing the diff between rev1 and rev2 - I'm not - * sure). In other words, the keyword lines in the current work file - * get left alone. - * - * Therfore, checking out the destination revision (rev2) is probably - * incorrect in the text case since we should see the keywords that were - * substituted into the original file at the time it was checked out - * and not the keywords from rev2. - * - * Also, it is safe to pass in NULL for nametag since we know no - * substitution is happening during the binary mode checkout. - */ - if (RCS_checkout ( finfo->rcs, finfo->file, rev2, (char *)NULL, t_options, - RUN_TTY, (RCSCHECKOUTPROC)0, NULL) != 0 ) - status = 2; - else - status = 0; - - /* OK, this is really stupid. RCS_checkout carefully removes - write permissions, and we carefully put them back. But - until someone gets around to fixing it, that seems like the - easiest way to get what would seem to be the right mode. - I don't check CVSWRITE or _watched; I haven't thought about - that in great detail, but it seems like a watched file should - be checked out (writable) after a merge. */ - xchmod (finfo->file, 1); - - /* Traditionally, the text file case prints a whole bunch of - scary looking and verbose output which fails to tell the user - what is really going on (it gives them rev1 and rev2 but doesn't - indicate in any way that rev1 == vn_user). I think just a - simple "U foo" is good here; it seems analogous to the case in - which the file was added on the branch in terms of what to - print. */ - write_letter (finfo, 'U'); - } - else if (strcmp (t_options, "-kb") == 0 - || wrap_merge_is_copy (finfo->file) - || special_file_mismatch (finfo, rev1, rev2)) - { - /* We are dealing with binary files, or files with a - permission/linkage mismatch (this second case only occurs when - PRESERVE_PERMISSIONS_SUPPORT is enabled), and real merging would - need to take place. This is a conflict. We give the user - the two files, and let them resolve it. It is possible - that we should require a "touch foo" or similar step before - we allow a checkin. */ - if (RCS_checkout ( finfo->rcs, finfo->file, rev2, (char *)NULL, - t_options, RUN_TTY, (RCSCHECKOUTPROC)0, NULL) != 0) - status = 2; - else - status = 0; - - /* OK, this is really stupid. RCS_checkout carefully removes - write permissions, and we carefully put them back. But - until someone gets around to fixing it, that seems like the - easiest way to get what would seem to be the right mode. - I don't check CVSWRITE or _watched; I haven't thought about - that in great detail, but it seems like a watched file should - be checked out (writable) after a merge. */ - xchmod (finfo->file, 1); - - /* Hmm. We don't give them REV1 anywhere. I guess most people - probably don't have a 3-way merge tool for the file type in - question, and might just get confused if we tried to either - provide them with a copy of the file from REV1, or even just - told them what REV1 is so they can get it themself, but it - might be worth thinking about. */ - /* See comment in merge_file about the "nonmergeable file" - terminology. */ - error (0, 0, "nonmergeable file needs merge"); - error (0, 0, "revision %s from repository is now in %s", - rev2, finfo->fullname); - error (0, 0, "file from working directory is now in %s", backup); - write_letter (finfo, 'C'); - } - else - status = RCS_merge (finfo->rcs, vers->srcfile->path, finfo->file, - t_options, rev1, rev2); - - if (status != 0) - { - if (status != 1) - { - error (0, status == -1 ? errno : 0, - "could not merge revision %s of %s", rev2, finfo->fullname); - error (status == -1 ? 1 : 0, 0, "restoring %s from backup file %s", - finfo->fullname, backup); - rename_file (backup, finfo->file); - } - } - else /* status == 0 */ - { - /* FIXME: the noexec case is broken. RCS_merge could be doing the - xcmp on the temporary files without much hassle, I think. */ - if (!noexec && !xcmp (backup, finfo->file)) - { - if (!really_quiet) - { - cvs_output (finfo->fullname, 0); - cvs_output (" already contains the differences between ", 0); - cvs_output (rev1, 0); - cvs_output (" and ", 0); - cvs_output (rev2, 0); - cvs_output ("\n", 1); - } - - /* and skip the registering and sending the new file since it - * hasn't been updated. - */ - goto out; - } - } - - /* The file has changed, but if we just checked it out it may - still have the same timestamp it did when it was first - registered above in checkout_file. We register it again with a - dummy timestamp to make sure that later runs of CVS will - recognize that it has changed. - - We don't actually need to register again if we called - RCS_checkout above, and we aren't running as the server. - However, that is not the normal case, and calling Register - again won't cost much in that case. */ - RegisterMerge (finfo, vers, backup, status); - -out: - free (rev1); - free (rev2); - free (backup); -} - - - -/* - * Report whether revisions REV1 and REV2 of FINFO agree on: - * . file ownership - * . permissions - * . major and minor device numbers - * . symbolic links - * . hard links - * - * If either REV1 or REV2 is NULL, the working copy is used instead. - * - * Return 1 if the files differ on these data. - */ - -int -special_file_mismatch (finfo, rev1, rev2) - struct file_info *finfo; - char *rev1; - char *rev2; -{ -#ifdef PRESERVE_PERMISSIONS_SUPPORT - struct stat sb; - RCSVers *vp; - Node *n; - uid_t rev1_uid, rev2_uid; - gid_t rev1_gid, rev2_gid; - mode_t rev1_mode, rev2_mode; - unsigned long dev_long; - dev_t rev1_dev, rev2_dev; - char *rev1_symlink = NULL; - char *rev2_symlink = NULL; - List *rev1_hardlinks = NULL; - List *rev2_hardlinks = NULL; - int check_uids, check_gids, check_modes; - int result; - - /* If we don't care about special file info, then - don't report a mismatch in any case. */ - if (!preserve_perms) - return 0; - - /* When special_file_mismatch is called from No_Difference, the - RCS file has been only partially parsed. We must read the - delta tree in order to compare special file info recorded in - the delta nodes. (I think this is safe. -twp) */ - if (finfo->rcs->flags & PARTIAL) - RCS_reparsercsfile (finfo->rcs, NULL, NULL); - - check_uids = check_gids = check_modes = 1; - - /* Obtain file information for REV1. If this is null, then stat - finfo->file and use that info. */ - /* If a revision does not know anything about its status, - then presumably it doesn't matter, and indicates no conflict. */ - - if (rev1 == NULL) - { - if (islink (finfo->file)) - rev1_symlink = xreadlink (finfo->file); - else - { -# ifdef HAVE_STRUCT_STAT_ST_RDEV - if (CVS_LSTAT (finfo->file, &sb) < 0) - error (1, errno, "could not get file information for %s", - finfo->file); - rev1_uid = sb.st_uid; - rev1_gid = sb.st_gid; - 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); - } - else - { - n = findnode (finfo->rcs->versions, rev1); - vp = n->data; - - n = findnode (vp->other_delta, "symlink"); - if (n != NULL) - rev1_symlink = xstrdup (n->data); - else - { - n = findnode (vp->other_delta, "owner"); - if (n == NULL) - check_uids = 0; /* don't care */ - else - rev1_uid = strtoul (n->data, NULL, 10); - - n = findnode (vp->other_delta, "group"); - if (n == NULL) - check_gids = 0; /* don't care */ - else - rev1_gid = strtoul (n->data, NULL, 10); - - n = findnode (vp->other_delta, "permissions"); - if (n == NULL) - check_modes = 0; /* don't care */ - else - rev1_mode = strtoul (n->data, NULL, 8); - - n = findnode (vp->other_delta, "special"); - if (n == NULL) - rev1_mode |= S_IFREG; - else - { - /* If the size of `ftype' changes, fix the sscanf call also */ - char ftype[16]; - if (sscanf (n->data, "%15s %lu", ftype, - &dev_long) < 2) - error (1, 0, "%s:%s has bad `special' newphrase %s", - finfo->file, rev1, (char *)n->data); - rev1_dev = dev_long; - if (strcmp (ftype, "character") == 0) - rev1_mode |= S_IFCHR; - else if (strcmp (ftype, "block") == 0) - rev1_mode |= S_IFBLK; - else - error (0, 0, "%s:%s unknown file type `%s'", - finfo->file, rev1, ftype); - } - - rev1_hardlinks = vp->hardlinks; - if (rev1_hardlinks == NULL) - rev1_hardlinks = getlist(); - } - } - - /* Obtain file information for REV2. */ - if (rev2 == NULL) - { - if (islink (finfo->file)) - rev2_symlink = xreadlink (finfo->file); - else - { -# ifdef HAVE_STRUCT_STAT_ST_RDEV - if (CVS_LSTAT (finfo->file, &sb) < 0) - error (1, errno, "could not get file information for %s", - finfo->file); - rev2_uid = sb.st_uid; - rev2_gid = sb.st_gid; - 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); - } - else - { - n = findnode (finfo->rcs->versions, rev2); - vp = n->data; - - n = findnode (vp->other_delta, "symlink"); - if (n != NULL) - rev2_symlink = xstrdup (n->data); - else - { - n = findnode (vp->other_delta, "owner"); - if (n == NULL) - check_uids = 0; /* don't care */ - else - rev2_uid = strtoul (n->data, NULL, 10); - - n = findnode (vp->other_delta, "group"); - if (n == NULL) - check_gids = 0; /* don't care */ - else - rev2_gid = strtoul (n->data, NULL, 10); - - n = findnode (vp->other_delta, "permissions"); - if (n == NULL) - check_modes = 0; /* don't care */ - else - rev2_mode = strtoul (n->data, NULL, 8); - - n = findnode (vp->other_delta, "special"); - if (n == NULL) - rev2_mode |= S_IFREG; - else - { - /* If the size of `ftype' changes, fix the sscanf call also */ - char ftype[16]; - if (sscanf (n->data, "%15s %lu", ftype, - &dev_long) < 2) - error (1, 0, "%s:%s has bad `special' newphrase %s", - finfo->file, rev2, (char *)n->data); - rev2_dev = dev_long; - if (strcmp (ftype, "character") == 0) - rev2_mode |= S_IFCHR; - else if (strcmp (ftype, "block") == 0) - rev2_mode |= S_IFBLK; - else - error (0, 0, "%s:%s unknown file type `%s'", - finfo->file, rev2, ftype); - } - - rev2_hardlinks = vp->hardlinks; - if (rev2_hardlinks == NULL) - rev2_hardlinks = getlist(); - } - } - - /* Check the user/group ownerships and file permissions, printing - an error for each mismatch found. Return 0 if all characteristics - matched, and 1 otherwise. */ - - result = 0; - - /* Compare symlinks first, since symlinks are simpler (don't have - any other characteristics). */ - if (rev1_symlink != NULL && rev2_symlink == NULL) - { - error (0, 0, "%s is a symbolic link", - (rev1 == NULL ? "working file" : rev1)); - result = 1; - } - else if (rev1_symlink == NULL && rev2_symlink != NULL) - { - error (0, 0, "%s is a symbolic link", - (rev2 == NULL ? "working file" : rev2)); - result = 1; - } - else if (rev1_symlink != NULL) - result = (strcmp (rev1_symlink, rev2_symlink) == 0); - else - { - /* Compare user ownership. */ - if (check_uids && rev1_uid != rev2_uid) - { - error (0, 0, "%s: owner mismatch between %s and %s", - finfo->file, - (rev1 == NULL ? "working file" : rev1), - (rev2 == NULL ? "working file" : rev2)); - result = 1; - } - - /* Compare group ownership. */ - if (check_gids && rev1_gid != rev2_gid) - { - error (0, 0, "%s: group mismatch between %s and %s", - finfo->file, - (rev1 == NULL ? "working file" : rev1), - (rev2 == NULL ? "working file" : rev2)); - result = 1; - } - - /* Compare permissions. */ - if (check_modes && - (rev1_mode & 07777) != (rev2_mode & 07777)) - { - error (0, 0, "%s: permission mismatch between %s and %s", - finfo->file, - (rev1 == NULL ? "working file" : rev1), - (rev2 == NULL ? "working file" : rev2)); - result = 1; - } - - /* Compare device file characteristics. */ - if ((rev1_mode & S_IFMT) != (rev2_mode & S_IFMT)) - { - error (0, 0, "%s: %s and %s are different file types", - finfo->file, - (rev1 == NULL ? "working file" : rev1), - (rev2 == NULL ? "working file" : rev2)); - result = 1; - } - else if (S_ISBLK (rev1_mode)) - { - if (rev1_dev != rev2_dev) - { - error (0, 0, "%s: device numbers of %s and %s do not match", - finfo->file, - (rev1 == NULL ? "working file" : rev1), - (rev2 == NULL ? "working file" : rev2)); - result = 1; - } - } - - /* Compare hard links. */ - if (compare_linkage_lists (rev1_hardlinks, rev2_hardlinks) == 0) - { - error (0, 0, "%s: hard linkage of %s and %s do not match", - finfo->file, - (rev1 == NULL ? "working file" : rev1), - (rev2 == NULL ? "working file" : rev2)); - result = 1; - } - } - - if (rev1_symlink != NULL) - free (rev1_symlink); - if (rev2_symlink != NULL) - free (rev2_symlink); - if (rev1_hardlinks != NULL) - dellist (&rev1_hardlinks); - if (rev2_hardlinks != NULL) - dellist (&rev2_hardlinks); - - return result; -#else - return 0; -#endif -} - - - -int -joining () -{ - return join_rev1 != NULL; -} diff --git a/contrib/cvs/src/update.h b/contrib/cvs/src/update.h deleted file mode 100644 index c886b4c..0000000 --- a/contrib/cvs/src/update.h +++ /dev/null @@ -1,23 +0,0 @@ -/* Declarations for update.c. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. */ - -/* - * $FreeBSD$ - */ - -int do_update PROTO((int argc, char *argv[], char *xoptions, char *xtag, - char *xdate, int xforce, int local, int xbuild, - int xaflag, int xprune, int xpipeout, int which, - char *xjoin_rev1, char *xjoin_rev2, char *preload_update_dir, - int xpull_template, char *repository)); -int joining PROTO((void)); -extern int isemptydir PROTO ((const char *dir, int might_not_exist)); diff --git a/contrib/cvs/src/vers_ts.c b/contrib/cvs/src/vers_ts.c deleted file mode 100644 index 1bf880a..0000000 --- a/contrib/cvs/src/vers_ts.c +++ /dev/null @@ -1,429 +0,0 @@ -/* - * Copyright (C) 1986-2005 The Free Software Foundation, Inc. - * - * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot , - * and others. - * - * Portions Copyright (C) 1992, Brian Berliner and Jeff Polk - * Portions Copyright (C) 1989-1992, Brian Berliner - * - * You may distribute under the terms of the GNU General Public License as - * specified in the README file that comes with the CVS source distribution. - */ - -#include "cvs.h" - -#ifdef SERVER_SUPPORT -static void time_stamp_server PROTO((const char *, Vers_TS *, Entnode *)); -#endif - - - -/* Fill in and return a Vers_TS structure for the file FINFO. TAG and - DATE are from the command line. */ - -Vers_TS * -Version_TS (finfo, options, tag, date, force_tag_match, set_time) - struct file_info *finfo; - - /* Keyword expansion options, I think generally from the command - line. Can be either NULL or "" to indicate none are specified - here. */ - char *options; - char *tag; - char *date; - int force_tag_match; - int set_time; -{ - Node *p; - RCSNode *rcsdata; - Vers_TS *vers_ts; - struct stickydirtag *sdtp; - Entnode *entdata; - char *rcsexpand = NULL; - -#ifdef UTIME_EXPECTS_WRITABLE - int change_it_back = 0; -#endif - - /* get a new Vers_TS struct */ - vers_ts = (Vers_TS *) xmalloc (sizeof (Vers_TS)); - memset ((char *) vers_ts, 0, sizeof (*vers_ts)); - - /* - * look up the entries file entry and fill in the version and timestamp - * if entries is NULL, there is no entries file so don't bother trying to - * look it up (used by checkout -P) - */ - if (finfo->entries == NULL) - { - sdtp = NULL; - p = NULL; - } - else - { - p = findnode_fn (finfo->entries, finfo->file); - sdtp = finfo->entries->list->data; /* list-private */ - } - - entdata = NULL; - if (p != NULL) - { - entdata = p->data; - - if (entdata->type == ENT_SUBDIR) - { - /* According to cvs.texinfo, the various fields in the Entries - file for a directory (other than the name) do not have a - defined meaning. We need to pass them along without getting - confused based on what is in them. Therefore we make sure - not to set vn_user and the like from Entries, add.c and - perhaps other code will expect these fields to be NULL for - a directory. */ - vers_ts->entdata = entdata; - } - else -#ifdef SERVER_SUPPORT - /* An entries line with "D" in the timestamp indicates that the - client sent Is-modified without sending Entry. So we want to - use the entries line for the sole purpose of telling - time_stamp_server what is up; we don't want the rest of CVS - to think there is an entries line. */ - if (strcmp (entdata->timestamp, "D") != 0) -#endif - { - vers_ts->vn_user = xstrdup (entdata->version); - vers_ts->ts_rcs = xstrdup (entdata->timestamp); - vers_ts->ts_conflict = xstrdup (entdata->conflict); - if (!(tag || date) && !(sdtp && sdtp->aflag)) - { - 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 == '\0') - { - if (!(sdtp && sdtp->aflag)) - vers_ts->options = xstrdup (entdata->options); - } - } - - /* Always look up the RCS keyword mode when we have an RCS archive. It - * will either be needed as a default or to avoid allowing the -k options - * specified on the command line from overriding binary mode (-kb). - */ - if (finfo->rcs != NULL) - rcsexpand = RCS_getexpand (finfo->rcs); - - /* - * -k options specified on the command line override (and overwrite) - * options stored in the entries file and default options from the RCS - * archive, except for binary mode (-kb). - */ - if (options && *options != '\0') - { - if (vers_ts->options != NULL) - free (vers_ts->options); - if (rcsexpand != NULL && strcmp (rcsexpand, "b") == 0) - vers_ts->options = xstrdup ("-kb"); - else - vers_ts->options = xstrdup (options); - } - else if ((!vers_ts->options || *vers_ts->options == '\0') - && rcsexpand != NULL) - { - /* If no keyword expansion was specified on command line, - use whatever was in the rcs file (if there is one). This - is how we, if we are the server, tell the client whether - a file is binary. */ - 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); - } - if (!vers_ts->options) - vers_ts->options = xstrdup (""); - - /* - * if tags were specified on the command line, they override what is in - * the Entries file - */ - if (tag || date) - { - vers_ts->tag = xstrdup (tag); - vers_ts->date = xstrdup (date); - } - else if (!vers_ts->entdata && (sdtp && sdtp->aflag == 0)) - { - if (!vers_ts->tag) - { - vers_ts->tag = xstrdup (sdtp->tag); - vers_ts->nonbranch = sdtp->nonbranch; - } - if (!vers_ts->date) - vers_ts->date = xstrdup (sdtp->date); - } - - /* Now look up the info on the source controlled file */ - if (finfo->rcs != NULL) - { - rcsdata = finfo->rcs; - rcsdata->refcount++; - } - else if (finfo->repository != NULL) - rcsdata = RCS_parse (finfo->file, finfo->repository); - else - rcsdata = NULL; - - if (rcsdata != NULL) - { - /* squirrel away the rcsdata pointer for others */ - vers_ts->srcfile = rcsdata; - - if (vers_ts->tag && strcmp (vers_ts->tag, TAG_BASE) == 0) - { - vers_ts->vn_rcs = xstrdup (vers_ts->vn_user); - vers_ts->vn_tag = xstrdup (vers_ts->vn_user); - } - else - { - int simple; - - vers_ts->vn_rcs = RCS_getversion (rcsdata, vers_ts->tag, - vers_ts->date, force_tag_match, - &simple); - if (vers_ts->vn_rcs == NULL) - vers_ts->vn_tag = NULL; - else if (simple) - vers_ts->vn_tag = xstrdup (vers_ts->tag); - else - vers_ts->vn_tag = xstrdup (vers_ts->vn_rcs); - } - - /* - * If the source control file exists and has the requested revision, - * get the Date the revision was checked in. If "user" exists, set - * its mtime. - */ - if (set_time && vers_ts->vn_rcs != NULL) - { -#ifdef SERVER_SUPPORT - if (server_active) - server_modtime (finfo, vers_ts); - else -#endif - { - struct utimbuf t; - - memset (&t, 0, sizeof (t)); - t.modtime = RCS_getrevtime (rcsdata, vers_ts->vn_rcs, 0, 0); - if (t.modtime != (time_t) -1) - { - (void) time (&t.actime); - -#ifdef UTIME_EXPECTS_WRITABLE - if (!iswritable (finfo->file)) - { - xchmod (finfo->file, 1); - change_it_back = 1; - } -#endif /* UTIME_EXPECTS_WRITABLE */ - - /* This used to need to ignore existence_errors - (for cases like where update.c now clears - set_time if noexec, but didn't used to). I - think maybe now it doesn't (server_modtime does - not like those kinds of cases). */ - (void) utime (finfo->file, &t); - -#ifdef UTIME_EXPECTS_WRITABLE - if (change_it_back) - { - xchmod (finfo->file, 0); - change_it_back = 0; - } -#endif /* UTIME_EXPECTS_WRITABLE */ - } - } - } - } - - /* get user file time-stamp in ts_user */ - if (finfo->entries != (List *) NULL) - { -#ifdef SERVER_SUPPORT - if (server_active) - time_stamp_server (finfo->file, vers_ts, entdata); - else -#endif - vers_ts->ts_user = time_stamp (finfo->file); - } - - return (vers_ts); -} - -#ifdef SERVER_SUPPORT - -/* Set VERS_TS->TS_USER to time stamp for FILE. */ - -/* Separate these out to keep the logic below clearer. */ -#define mark_lost(V) ((V)->ts_user = 0) -#define mark_unchanged(V) ((V)->ts_user = xstrdup ((V)->ts_rcs)) - -static void -time_stamp_server (file, vers_ts, entdata) - const char *file; - Vers_TS *vers_ts; - Entnode *entdata; -{ - struct stat sb; - char *cp; - - if (CVS_LSTAT (file, &sb) < 0) - { - if (! existence_error (errno)) - error (1, errno, "cannot stat temp file"); - - /* Missing file means lost or unmodified; check entries - file to see which. - - XXX FIXME - If there's no entries file line, we - wouldn't be getting the file at all, so consider it - lost. I don't know that that's right, but it's not - clear to me that either choice is. Besides, would we - have an RCS string in that case anyways? */ - if (entdata == NULL) - mark_lost (vers_ts); - else if (entdata->timestamp - && entdata->timestamp[0] == '=') - mark_unchanged (vers_ts); - else if (entdata->conflict - && entdata->conflict[0] == '=') - { - /* These just need matching content. Might as well minimize it. */ - vers_ts->ts_user = xstrdup (""); - vers_ts->ts_conflict = xstrdup (""); - } - else if (entdata->timestamp - && (entdata->timestamp[0] == 'M' - || entdata->timestamp[0] == 'D') - && entdata->timestamp[1] == '\0') - vers_ts->ts_user = xstrdup ("Is-modified"); - else - mark_lost (vers_ts); - } - else if (sb.st_mtime == 0) - { - /* We shouldn't reach this case any more! */ - abort (); - } - else - { - struct tm *tm_p; - - vers_ts->ts_user = xmalloc (25); - /* We want to use the same timestamp format as is stored in the - st_mtime. For unix (and NT I think) this *must* be universal - time (UT), so that files don't appear to be modified merely - because the timezone has changed. For VMS, or hopefully other - systems where gmtime returns NULL, the modification time is - stored in local time, and therefore it is not possible to cause - st_mtime to be out of sync by changing the timezone. */ - tm_p = gmtime (&sb.st_mtime); - cp = tm_p ? asctime (tm_p) : ctime (&sb.st_mtime); - cp[24] = 0; - /* Fix non-standard format. */ - if (cp[8] == '0') cp[8] = ' '; - (void) strcpy (vers_ts->ts_user, cp); - } -} - -#endif /* SERVER_SUPPORT */ -/* - * Gets the time-stamp for the file "file" and returns it in space it - * allocates - */ -char * -time_stamp (file) - const char *file; -{ - struct stat sb; - char *cp; - char *ts = NULL; - time_t mtime = 0L; - - if (!CVS_LSTAT (file, &sb)) - { - mtime = sb.st_mtime; - } - else if (! existence_error (errno)) - error (0, errno, "cannot lstat %s", file); - - /* If it's a symlink, return whichever is the newest mtime of - the link and its target, for safety. - */ - if (!CVS_STAT (file, &sb)) - { - if (mtime < sb.st_mtime) - mtime = sb.st_mtime; - } - else if (! existence_error (errno)) - error (0, errno, "cannot stat %s", file); - - if (mtime) - { - struct tm *tm_p; - ts = xmalloc (25); - /* We want to use the same timestamp format as is stored in the - st_mtime. For unix (and NT I think) this *must* be universal - time (UT), so that files don't appear to be modified merely - because the timezone has changed. For VMS, or hopefully other - systems where gmtime returns NULL, the modification time is - stored in local time, and therefore it is not possible to cause - st_mtime to be out of sync by changing the timezone. */ - tm_p = gmtime (&sb.st_mtime); - cp = tm_p ? asctime (tm_p) : ctime (&sb.st_mtime); - cp[24] = 0; - /* Fix non-standard format. */ - if (cp[8] == '0') cp[8] = ' '; - (void) strcpy (ts, cp); - } - - return (ts); -} - -/* - * free up a Vers_TS struct - */ -void -freevers_ts (versp) - Vers_TS **versp; -{ - if ((*versp)->srcfile) - freercsnode (&((*versp)->srcfile)); - if ((*versp)->vn_user) - free ((*versp)->vn_user); - if ((*versp)->vn_rcs) - free ((*versp)->vn_rcs); - if ((*versp)->vn_tag) - free ((*versp)->vn_tag); - if ((*versp)->ts_user) - free ((*versp)->ts_user); - if ((*versp)->ts_rcs) - free ((*versp)->ts_rcs); - if ((*versp)->options) - free ((*versp)->options); - if ((*versp)->tag) - free ((*versp)->tag); - if ((*versp)->date) - free ((*versp)->date); - if ((*versp)->ts_conflict) - free ((*versp)->ts_conflict); - free ((char *) *versp); - *versp = (Vers_TS *) NULL; -} diff --git a/contrib/cvs/src/version.c b/contrib/cvs/src/version.c deleted file mode 100644 index 09f99f4..0000000 --- a/contrib/cvs/src/version.c +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (C) 1986-2005 The Free Software Foundation, Inc. - * - * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot , - * and others. - * - * Portions Copyright (C) 1994 david d `zoo' zuhn - * Portions Copyright (C) 1992, Brian Berliner and Jeff Polk - * Portions Copyright (C) 1989-1992, Brian Berliner - * - * You may distribute under the terms of the GNU General Public License as - * specified in the README file that comes with this CVS source distribution. - * - * version.c - the CVS version number - */ - -#include "cvs.h" - -#ifdef CLIENT_SUPPORT -#ifdef SERVER_SUPPORT -char *config_string = " (client/server)\n"; -#else -char *config_string = " (client)\n"; -#endif -#else -#ifdef SERVER_SUPPORT -char *config_string = " (server)\n"; -#else -char *config_string = "\n"; -#endif -#endif - - - -static const char *const version_usage[] = -{ - "Usage: %s %s\n", - NULL -}; - - - -/* - * Output a version string for the client and server. - * - * This function will output the simple version number (for the '--version' - * option) or the version numbers of the client and server (using the 'version' - * command). - */ -int -version (argc, argv) - int argc; - char **argv; -{ - int err = 0; - - if (argc == -1) - usage (version_usage); - - if (current_parsed_root && current_parsed_root->isremote) - (void) fputs ("Client: ", stdout); - - /* 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 (PACKAGE_STRING, stdout); - (void) fputs (config_string, stdout); - -#ifdef CLIENT_SUPPORT - if (current_parsed_root && current_parsed_root->isremote) - { - (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; -} - diff --git a/contrib/cvs/src/watch.c b/contrib/cvs/src/watch.c deleted file mode 100644 index 0ef987c..0000000 --- a/contrib/cvs/src/watch.c +++ /dev/null @@ -1,522 +0,0 @@ -/* Implementation for "cvs watch add", "cvs watchers", and related commands - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. */ - -#include "cvs.h" -#include "edit.h" -#include "fileattr.h" -#include "watch.h" - -const char *const watch_usage[] = -{ - "Usage: %s %s {on|off|add|remove} [-lR] [-a ]... []...\n", - "on/off: Turn on/off read-only checkouts of files.\n", - "add/remove: Add or remove notification on actions.\n", - "-l (on/off/add/remove): Local directory only, not recursive.\n", - "-R (on/off/add/remove): Process directories recursively (default).\n", - "-a (add/remove): Specify what actions, one of: `edit', `unedit',\n", - " `commit', `all', or `none' (defaults to `all').\n", - "(Specify the --help global option for a list of other help options.)\n", - NULL -}; - -static struct addremove_args the_args; - -void -watch_modify_watchers (file, what) - const char *file; - struct addremove_args *what; -{ - char *curattr = fileattr_get0 (file, "_watchers"); - char *p; - char *pend; - char *nextp; - char *who; - int who_len; - char *mycurattr; - char *mynewattr; - size_t mynewattr_size; - - int add_edit_pending; - int add_unedit_pending; - int add_commit_pending; - int remove_edit_pending; - int remove_unedit_pending; - int remove_commit_pending; - int add_tedit_pending; - int add_tunedit_pending; - int add_tcommit_pending; - - who = getcaller (); - who_len = strlen (who); - - /* Look for current watcher types for this user. */ - mycurattr = NULL; - if (curattr != NULL) - { - p = curattr; - while (1) { - if (strncmp (who, p, who_len) == 0 - && p[who_len] == '>') - { - /* Found this user. */ - mycurattr = p + who_len + 1; - } - p = strchr (p, ','); - if (p == NULL) - break; - ++p; - } - } - if (mycurattr != NULL) - { - mycurattr = xstrdup (mycurattr); - p = strchr (mycurattr, ','); - if (p != NULL) - *p = '\0'; - } - - /* Now copy mycurattr to mynewattr, making the requisite modifications. - Note that we add a dummy '+' to the start of mynewattr, to reduce - special cases (but then we strip it off when we are done). */ - - mynewattr_size = sizeof "+edit+unedit+commit+tedit+tunedit+tcommit"; - if (mycurattr != NULL) - mynewattr_size += strlen (mycurattr); - mynewattr = xmalloc (mynewattr_size); - mynewattr[0] = '\0'; - - add_edit_pending = what->adding && what->edit; - add_unedit_pending = what->adding && what->unedit; - add_commit_pending = what->adding && what->commit; - remove_edit_pending = !what->adding && what->edit; - remove_unedit_pending = !what->adding && what->unedit; - remove_commit_pending = !what->adding && what->commit; - add_tedit_pending = what->add_tedit; - add_tunedit_pending = what->add_tunedit; - add_tcommit_pending = what->add_tcommit; - - /* Copy over existing watch types, except those to be removed. */ - p = mycurattr; - while (p != NULL) - { - pend = strchr (p, '+'); - if (pend == NULL) - { - pend = p + strlen (p); - nextp = NULL; - } - else - nextp = pend + 1; - - /* Process this item. */ - if (pend - p == 4 && strncmp ("edit", p, 4) == 0) - { - if (!remove_edit_pending) - strcat (mynewattr, "+edit"); - add_edit_pending = 0; - } - else if (pend - p == 6 && strncmp ("unedit", p, 6) == 0) - { - if (!remove_unedit_pending) - strcat (mynewattr, "+unedit"); - add_unedit_pending = 0; - } - else if (pend - p == 6 && strncmp ("commit", p, 6) == 0) - { - if (!remove_commit_pending) - strcat (mynewattr, "+commit"); - add_commit_pending = 0; - } - else if (pend - p == 5 && strncmp ("tedit", p, 5) == 0) - { - if (!what->remove_temp) - strcat (mynewattr, "+tedit"); - add_tedit_pending = 0; - } - else if (pend - p == 7 && strncmp ("tunedit", p, 7) == 0) - { - if (!what->remove_temp) - strcat (mynewattr, "+tunedit"); - add_tunedit_pending = 0; - } - else if (pend - p == 7 && strncmp ("tcommit", p, 7) == 0) - { - if (!what->remove_temp) - strcat (mynewattr, "+tcommit"); - add_tcommit_pending = 0; - } - else - { - char *mp; - - /* Copy over any unrecognized watch types, for future - expansion. */ - mp = mynewattr + strlen (mynewattr); - *mp++ = '+'; - strncpy (mp, p, pend - p); - *(mp + (pend - p)) = '\0'; - } - - /* Set up for next item. */ - p = nextp; - } - - /* Add in new watch types. */ - if (add_edit_pending) - strcat (mynewattr, "+edit"); - if (add_unedit_pending) - strcat (mynewattr, "+unedit"); - if (add_commit_pending) - strcat (mynewattr, "+commit"); - if (add_tedit_pending) - strcat (mynewattr, "+tedit"); - if (add_tunedit_pending) - strcat (mynewattr, "+tunedit"); - if (add_tcommit_pending) - strcat (mynewattr, "+tcommit"); - - { - char *curattr_new; - - curattr_new = - fileattr_modify (curattr, - who, - mynewattr[0] == '\0' ? NULL : mynewattr + 1, - '>', - ','); - /* If the attribute is unchanged, don't rewrite the attribute file. */ - if (!((curattr_new == NULL && curattr == NULL) - || (curattr_new != NULL - && curattr != NULL - && strcmp (curattr_new, curattr) == 0))) - fileattr_set (file, - "_watchers", - curattr_new); - if (curattr_new != NULL) - free (curattr_new); - } - - if (curattr != NULL) - free (curattr); - if (mycurattr != NULL) - free (mycurattr); - if (mynewattr != NULL) - free (mynewattr); -} - -static int addremove_fileproc PROTO ((void *callerdat, - struct file_info *finfo)); - -static int -addremove_fileproc (callerdat, finfo) - void *callerdat; - struct file_info *finfo; -{ - watch_modify_watchers (finfo->file, &the_args); - return 0; -} - - - -static int addremove_filesdoneproc PROTO ((void *, int, const char *, - const char *, List *)); - -static int -addremove_filesdoneproc (callerdat, err, repository, update_dir, entries) - void *callerdat; - int err; - const char *repository; - const char *update_dir; - List *entries; -{ - if (the_args.setting_default) - watch_modify_watchers (NULL, &the_args); - return err; -} - -static int watch_addremove PROTO ((int argc, char **argv)); - -static int -watch_addremove (argc, argv) - int argc; - char **argv; -{ - int c; - int local = 0; - int err; - int a_omitted; - - a_omitted = 1; - the_args.commit = 0; - the_args.edit = 0; - the_args.unedit = 0; - optind = 0; - while ((c = getopt (argc, argv, "+lRa:")) != -1) - { - switch (c) - { - case 'l': - local = 1; - break; - case 'R': - local = 0; - break; - case 'a': - a_omitted = 0; - if (strcmp (optarg, "edit") == 0) - the_args.edit = 1; - else if (strcmp (optarg, "unedit") == 0) - the_args.unedit = 1; - else if (strcmp (optarg, "commit") == 0) - the_args.commit = 1; - else if (strcmp (optarg, "all") == 0) - { - the_args.edit = 1; - the_args.unedit = 1; - the_args.commit = 1; - } - else if (strcmp (optarg, "none") == 0) - { - the_args.edit = 0; - the_args.unedit = 0; - the_args.commit = 0; - } - else - usage (watch_usage); - break; - case '?': - default: - usage (watch_usage); - break; - } - } - argc -= optind; - argv += optind; - - if (a_omitted) - { - the_args.edit = 1; - the_args.unedit = 1; - the_args.commit = 1; - } - -#ifdef CLIENT_SUPPORT - if (current_parsed_root->isremote) - { - start_server (); - ign_setup (); - - if (local) - send_arg ("-l"); - /* FIXME: copes poorly with "all" if server is extended to have - new watch types and client is still running an old version. */ - if (the_args.edit) - option_with_arg ("-a", "edit"); - if (the_args.unedit) - option_with_arg ("-a", "unedit"); - if (the_args.commit) - option_with_arg ("-a", "commit"); - if (!the_args.edit && !the_args.unedit && !the_args.commit) - option_with_arg ("-a", "none"); - send_arg ("--"); - send_files (argc, argv, local, 0, SEND_NO_CONTENTS); - send_file_names (argc, argv, SEND_EXPAND_WILD); - send_to_server (the_args.adding ? - "watch-add\012" : "watch-remove\012", - 0); - return get_responses_and_close (); - } -#endif /* CLIENT_SUPPORT */ - - the_args.setting_default = (argc <= 0); - - lock_tree_for_write (argc, argv, local, W_LOCAL, 0); - - err = start_recursion (addremove_fileproc, addremove_filesdoneproc, - (DIRENTPROC) NULL, (DIRLEAVEPROC) NULL, NULL, - argc, argv, local, W_LOCAL, 0, CVS_LOCK_NONE, - (char *) NULL, 1, (char *) NULL); - - Lock_Cleanup (); - return err; -} - -int -watch_add (argc, argv) - int argc; - char **argv; -{ - the_args.adding = 1; - return watch_addremove (argc, argv); -} - -int -watch_remove (argc, argv) - int argc; - char **argv; -{ - the_args.adding = 0; - return watch_addremove (argc, argv); -} - -int -watch (argc, argv) - int argc; - char **argv; -{ - if (argc <= 1) - usage (watch_usage); - if (strcmp (argv[1], "on") == 0) - { - --argc; - ++argv; - return watch_on (argc, argv); - } - else if (strcmp (argv[1], "off") == 0) - { - --argc; - ++argv; - return watch_off (argc, argv); - } - else if (strcmp (argv[1], "add") == 0) - { - --argc; - ++argv; - return watch_add (argc, argv); - } - else if (strcmp (argv[1], "remove") == 0) - { - --argc; - ++argv; - return watch_remove (argc, argv); - } - else - usage (watch_usage); - return 0; -} - -static const char *const watchers_usage[] = -{ - "Usage: %s %s [-lR] []...\n", - "-l\tProcess this directory only (not recursive).\n", - "-R\tProcess directories recursively (default).\n", - "(Specify the --help global option for a list of other help options.)\n", - NULL -}; - -static int watchers_fileproc PROTO ((void *callerdat, - struct file_info *finfo)); - -static int -watchers_fileproc (callerdat, finfo) - void *callerdat; - struct file_info *finfo; -{ - char *them; - char *p; - - them = fileattr_get0 (finfo->file, "_watchers"); - if (them == NULL) - return 0; - - cvs_output (finfo->fullname, 0); - - p = them; - while (1) - { - cvs_output ("\t", 1); - while (*p != '>' && *p != '\0') - cvs_output (p++, 1); - if (*p == '\0') - { - /* Only happens if attribute is misformed. */ - cvs_output ("\n", 1); - break; - } - ++p; - cvs_output ("\t", 1); - while (1) - { - while (*p != '+' && *p != ',' && *p != '\0') - cvs_output (p++, 1); - if (*p == '\0') - { - cvs_output ("\n", 1); - goto out; - } - if (*p == ',') - { - ++p; - break; - } - ++p; - cvs_output ("\t", 1); - } - cvs_output ("\n", 1); - } - out:; - free (them); - return 0; -} - -int -watchers (argc, argv) - int argc; - char **argv; -{ - int local = 0; - int c; - - if (argc == -1) - usage (watchers_usage); - - optind = 0; - while ((c = getopt (argc, argv, "+lR")) != -1) - { - switch (c) - { - case 'l': - local = 1; - break; - case 'R': - local = 0; - break; - case '?': - default: - usage (watchers_usage); - break; - } - } - argc -= optind; - argv += optind; - -#ifdef CLIENT_SUPPORT - if (current_parsed_root->isremote) - { - start_server (); - ign_setup (); - - if (local) - send_arg ("-l"); - send_arg ("--"); - send_files (argc, argv, local, 0, SEND_NO_CONTENTS); - send_file_names (argc, argv, SEND_EXPAND_WILD); - send_to_server ("watchers\012", 0); - return get_responses_and_close (); - } -#endif /* CLIENT_SUPPORT */ - - return start_recursion (watchers_fileproc, (FILESDONEPROC) NULL, - (DIRENTPROC) NULL, (DIRLEAVEPROC) NULL, NULL, - argc, argv, local, W_LOCAL, 0, CVS_LOCK_READ, - (char *) NULL, 1, (char *) NULL); -} diff --git a/contrib/cvs/src/watch.h b/contrib/cvs/src/watch.h deleted file mode 100644 index 0394635..0000000 --- a/contrib/cvs/src/watch.h +++ /dev/null @@ -1,52 +0,0 @@ -/* Interface to "cvs watch add", "cvs watchers", and related features - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. */ - -extern const char *const watch_usage[]; - -/* Flags to pass between the various functions making up the - add/remove code. All in a single structure in case there is some - need to make the code reentrant some day. */ - -struct addremove_args { - /* A flag for each watcher type. */ - int edit; - int unedit; - int commit; - - /* Are we adding or removing (non-temporary) edit,unedit,and/or commit - watches? */ - int adding; - - /* Should we add a temporary edit watch? */ - int add_tedit; - /* Should we add a temporary unedit watch? */ - int add_tunedit; - /* Should we add a temporary commit watch? */ - int add_tcommit; - - /* Should we remove all temporary watches? */ - int remove_temp; - - /* Should we set the default? This is here for passing among various - routines in watch.c (a good place for it if there is ever any reason - to make the stuff reentrant), not for watch_modify_watchers. */ - int setting_default; -}; - -/* Modify the watchers for FILE. *WHAT tells what to do to them. - If FILE is NULL, modify default args (WHAT->SETTING_DEFAULT is - not used). */ -extern void watch_modify_watchers PROTO ((const char *file, - struct addremove_args *what)); - -extern int watch_add PROTO ((int argc, char **argv)); -extern int watch_remove PROTO ((int argc, char **argv)); diff --git a/contrib/cvs/src/wrapper.c b/contrib/cvs/src/wrapper.c deleted file mode 100644 index 512e96c..0000000 --- a/contrib/cvs/src/wrapper.c +++ /dev/null @@ -1,623 +0,0 @@ -/* This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. */ - -#include "cvs.h" -#include "getline.h" - -/* - Original Author: athan@morgan.com 2/1/94 - Modified By: vdemarco@bou.shl.com - - This package was written to support the NEXTSTEP concept of - "wrappers." These are essentially directories that are to be - treated as "files." This package allows such wrappers to be - "processed" on the way in and out of CVS. The intended use is to - wrap up a wrapper into a single tar, such that that tar can be - treated as a single binary file in CVS. To solve the problem - effectively, it was also necessary to be able to prevent rcsmerge - application at appropriate times. - - ------------------ - Format of wrapper file ($CVSROOT/CVSROOT/cvswrappers or .cvswrappers) - - wildcard [option value][option value]... - - where option is one of - -m update methodology value: MERGE or COPY - -k default -k rcs option to use on import or add - - and value is a single-quote delimited value. - - E.g: - *.nib -f 'gunzipuntar' -t 'targzip' -m 'COPY' -*/ - - -typedef struct { - char *wildCard; - char *tocvsFilter; - char *fromcvsFilter; - char *rcsOption; - WrapMergeMethod mergeMethod; -} WrapperEntry; - -static WrapperEntry **wrap_list=NULL; -static WrapperEntry **wrap_saved_list=NULL; - -static int wrap_size=0; -static int wrap_count=0; -static int wrap_tempcount=0; - -/* FIXME: the relationship between wrap_count, wrap_tempcount, - * wrap_saved_count, and wrap_saved_tempcount is not entirely clear; - * it is certainly suspicious that wrap_saved_count is never set to a - * value other than zero! If the variable isn't being used, it should - * be removed. And in general, we should describe how temporary - * vs. permanent wrappers are implemented, and then make sure the - * implementation is actually doing that. - * - * Right now things seem to be working, but that's no guarantee there - * isn't a bug lurking somewhere in the murk. - */ - -static int wrap_saved_count=0; - -static int wrap_saved_tempcount=0; - -#define WRAPPER_GROW 8 - -void wrap_add_entry PROTO((WrapperEntry *e,int temp)); -void wrap_kill PROTO((void)); -void wrap_kill_temp PROTO((void)); -void wrap_free_entry PROTO((WrapperEntry *e)); -void wrap_free_entry_internal PROTO((WrapperEntry *e)); -void wrap_restore_saved PROTO((void)); - -void wrap_setup() -{ - /* FIXME-reentrancy: if we do a multithreaded server, will need to - move this to a per-connection data structure, or better yet - think about a cleaner solution. */ - static int wrap_setup_already_done = 0; - char *homedir; - - if (wrap_setup_already_done != 0) - return; - else - wrap_setup_already_done = 1; - - if (!current_parsed_root->isremote) - { - char *file; - - file = xmalloc (strlen (current_parsed_root->directory) - + sizeof (CVSROOTADM) - + sizeof (CVSROOTADM_WRAPPER) - + 3); - /* Then add entries found in repository, if it exists. */ - (void) sprintf (file, "%s/%s/%s", current_parsed_root->directory, CVSROOTADM, - CVSROOTADM_WRAPPER); - if (isfile (file)) - { - wrap_add_file(file,0); - } - free (file); - } - - /* Then add entries found in home dir, (if user has one) and file - exists. */ - homedir = get_homedir (); - /* If we can't find a home directory, ignore ~/.cvswrappers. This may - make tracking down problems a bit of a pain, but on the other - hand it might be obnoxious to complain when CVS will function - just fine without .cvswrappers (and many users won't even know what - .cvswrappers is). */ - if (homedir != NULL) - { - char *file = strcat_filename_onto_homedir (homedir, CVSDOTWRAPPER); - if (isfile (file)) - { - wrap_add_file (file, 0); - } - free (file); - } - - /* FIXME: calling wrap_add() below implies that the CVSWRAPPERS - * environment variable contains exactly one "wrapper" -- a line - * of the form - * - * FILENAME_PATTERN FLAG OPTS [ FLAG OPTS ...] - * - * This may disagree with the documentation, which states: - * - * `$CVSWRAPPERS' - * A whitespace-separated list of file name patterns that CVS - * should treat as wrappers. *Note Wrappers::. - * - * Does this mean the environment variable can hold multiple - * wrappers lines? If so, a single call to wrap_add() is - * insufficient. - */ - - /* Then add entries found in CVSWRAPPERS environment variable. */ - wrap_add (getenv (WRAPPER_ENV), 0); -} - -#ifdef CLIENT_SUPPORT -/* Send -W arguments for the wrappers to the server. The command must - be one that accepts them (e.g. update, import). */ -void -wrap_send () -{ - int i; - - for (i = 0; i < wrap_count + wrap_tempcount; ++i) - { - if (wrap_list[i]->tocvsFilter != NULL - || wrap_list[i]->fromcvsFilter != NULL) - /* For greater studliness we would print the offending option - and (more importantly) where we found it. */ - error (0, 0, "\ --t and -f wrapper options are not supported remotely; ignored"); - if (wrap_list[i]->mergeMethod == WRAP_COPY) - /* For greater studliness we would print the offending option - and (more importantly) where we found it. */ - error (0, 0, "\ --m wrapper option is not supported remotely; ignored"); - send_to_server ("Argument -W\012Argument ", 0); - send_to_server (wrap_list[i]->wildCard, 0); - send_to_server (" -k '", 0); - if (wrap_list[i]->rcsOption != NULL) - send_to_server (wrap_list[i]->rcsOption, 0); - else - send_to_server ("kv", 0); - send_to_server ("'\012", 0); - } -} -#endif /* CLIENT_SUPPORT */ - -#if defined(SERVER_SUPPORT) || defined(CLIENT_SUPPORT) -/* Output wrapper entries in the format of cvswrappers lines. - * - * This is useful when one side of a client/server connection wants to - * send its wrappers to the other; since the receiving side would like - * to use wrap_add() to incorporate the wrapper, it's best if the - * entry arrives in this format. - * - * The entries are stored in `line', which is allocated here. Caller - * can free() it. - * - * If first_call_p is nonzero, then start afresh. */ -void -wrap_unparse_rcs_options (line, first_call_p) - char **line; - int first_call_p; -{ - /* FIXME-reentrancy: we should design a reentrant interface, like - a callback which gets handed each wrapper (a multithreaded - server being the most concrete reason for this, but the - non-reentrant interface is fairly unnecessary/ugly). */ - static int i; - - if (first_call_p) - i = 0; - - if (i >= wrap_count + wrap_tempcount) { - *line = NULL; - return; - } - - *line = xmalloc (strlen (wrap_list[i]->wildCard) - + strlen ("\t") - + strlen (" -k '") - + (wrap_list[i]->rcsOption != NULL ? - strlen (wrap_list[i]->rcsOption) : 2) - + strlen ("'") - + 1); /* leave room for '\0' */ - - strcpy (*line, wrap_list[i]->wildCard); - strcat (*line, " -k '"); - if (wrap_list[i]->rcsOption != NULL) - strcat (*line, wrap_list[i]->rcsOption); - else - strcat (*line, "kv"); - strcat (*line, "'"); - - ++i; -} -#endif /* SERVER_SUPPORT || CLIENT_SUPPORT */ - -/* - * Remove fmt str specifier other than %% or %s. And allow - * only max_s %s specifiers - */ -void -wrap_clean_fmt_str(char *fmt, int max_s) -{ - while (*fmt) { - if (fmt[0] == '%' && fmt[1]) - { - if (fmt[1] == '%') - fmt++; - else - if (fmt[1] == 's' && max_s > 0) - { - max_s--; - fmt++; - } else - *fmt = ' '; - } - fmt++; - } -} - -/* - * Open a file and read lines, feeding each line to a line parser. Arrange - * for keeping a temporary list of wrappers at the end, if the "temp" - * argument is set. - */ -void -wrap_add_file (file, temp) - const char *file; - int temp; -{ - FILE *fp; - char *line = NULL; - size_t line_allocated = 0; - - wrap_restore_saved (); - wrap_kill_temp (); - - /* Load the file. */ - fp = CVS_FOPEN (file, "r"); - if (fp == NULL) - { - if (!existence_error (errno)) - error (0, errno, "cannot open %s", file); - return; - } - while (getline (&line, &line_allocated, fp) >= 0) - wrap_add (line, temp); - if (line) - free (line); - if (ferror (fp)) - error (0, errno, "cannot read %s", file); - if (fclose (fp) == EOF) - error (0, errno, "cannot close %s", file); -} - -void -wrap_kill() -{ - wrap_kill_temp(); - while(wrap_count) - wrap_free_entry(wrap_list[--wrap_count]); -} - -void -wrap_kill_temp() -{ - WrapperEntry **temps=wrap_list+wrap_count; - - while(wrap_tempcount) - wrap_free_entry(temps[--wrap_tempcount]); -} - -void -wrap_free_entry(e) - WrapperEntry *e; -{ - wrap_free_entry_internal(e); - free(e); -} - -void -wrap_free_entry_internal(e) - WrapperEntry *e; -{ - free (e->wildCard); - if (e->tocvsFilter) - free (e->tocvsFilter); - if (e->fromcvsFilter) - free (e->fromcvsFilter); - if (e->rcsOption) - free (e->rcsOption); -} - -void -wrap_restore_saved() -{ - if(!wrap_saved_list) - return; - - wrap_kill(); - - free(wrap_list); - - wrap_list=wrap_saved_list; - wrap_count=wrap_saved_count; - wrap_tempcount=wrap_saved_tempcount; - - wrap_saved_list=NULL; - wrap_saved_count=0; - wrap_saved_tempcount=0; -} - -void -wrap_add (line, isTemp) - char *line; - int isTemp; -{ - char *temp; - char ctemp; - WrapperEntry e; - char opt; - - if (!line || line[0] == '#') - return; - - memset (&e, 0, sizeof(e)); - - /* Search for the wild card */ - while (*line && isspace ((unsigned char) *line)) - ++line; - for (temp = line; - *line && !isspace ((unsigned char) *line); - ++line) - ; - if(temp==line) - return; - - ctemp=*line; - *line='\0'; - - e.wildCard=xstrdup(temp); - *line=ctemp; - - while(*line){ - /* Search for the option */ - while(*line && *line!='-') - ++line; - if(!*line) - break; - ++line; - if(!*line) - break; - opt=*line; - - /* Search for the filter commandline */ - for(++line;*line && *line!='\'';++line); - if(!*line) - break; - - for(temp=++line;*line && (*line!='\'' || line[-1]=='\\');++line) - ; - - /* This used to "break;" (ignore the option) if there was a - single character between the single quotes (I'm guessing - that was accidental). Now it "break;"s if there are no - characters. I'm not sure either behavior is particularly - necessary--the current options might not require '' - arguments, but surely some future option legitimately - might. Also I'm not sure that ignoring the option is a - swift way to handle syntax errors in general. */ - if (line==temp) - break; - - ctemp=*line; - *line='\0'; - switch(opt){ - case 'f': - /* Before this is reenabled, need to address the problem in - commit.c (see - http://ximbiot.com/cvs/cvshome/docs/infowrapper.html). */ - error (1, 0, - "-t/-f wrappers not supported by this version of CVS"); - - if(e.fromcvsFilter) - free(e.fromcvsFilter); - /* FIXME: error message should say where the bad value - came from. */ - e.fromcvsFilter=expand_path (temp, "", 0); - if (!e.fromcvsFilter) - error (1, 0, "Correct above errors first"); - break; - case 't': - /* Before this is reenabled, need to address the problem in - commit.c (see - http://ximbiot.com/cvs/cvshome/docs/infowrapper.html). */ - error (1, 0, - "-t/-f wrappers not supported by this version of CVS"); - - if(e.tocvsFilter) - free(e.tocvsFilter); - /* FIXME: error message should say where the bad value - came from. */ - e.tocvsFilter=expand_path (temp, "", 0); - if (!e.tocvsFilter) - error (1, 0, "Correct above errors first"); - break; - case 'm': - if(*temp=='C' || *temp=='c') - e.mergeMethod=WRAP_COPY; - else - e.mergeMethod=WRAP_MERGE; - break; - case 'k': - if (e.rcsOption) - free (e.rcsOption); - e.rcsOption = strcmp (temp, "kv") ? xstrdup (temp) : NULL; - break; - default: - break; - } - *line=ctemp; - if(!*line)break; - ++line; - } - - wrap_add_entry(&e, isTemp); -} - -void -wrap_add_entry(e, temp) - WrapperEntry *e; - int temp; -{ - int x; - if(wrap_count+wrap_tempcount>=wrap_size){ - wrap_size += WRAPPER_GROW; - wrap_list = (WrapperEntry **) xrealloc ((char *) wrap_list, - wrap_size * - sizeof (WrapperEntry *)); - } - - if(!temp && wrap_tempcount){ - for(x=wrap_count+wrap_tempcount-1;x>=wrap_count;--x) - wrap_list[x+1]=wrap_list[x]; - } - - x=(temp ? wrap_count+(wrap_tempcount++):(wrap_count++)); - wrap_list[x]=(WrapperEntry *)xmalloc(sizeof(WrapperEntry)); - *wrap_list[x]=*e; -} - -/* Return 1 if the given filename is a wrapper filename */ -int -wrap_name_has (name,has) - const char *name; - WrapMergeHas has; -{ - int x,count=wrap_count+wrap_tempcount; - char *temp; - - for(x=0;xwildCard, name, 0) == 0){ - switch(has){ - case WRAP_TOCVS: - temp=wrap_list[x]->tocvsFilter; - break; - case WRAP_FROMCVS: - temp=wrap_list[x]->fromcvsFilter; - break; - case WRAP_RCSOPTION: - temp = wrap_list[x]->rcsOption; - break; - default: - abort (); - } - if(temp==NULL) - return (0); - else - return (1); - } - return (0); -} - -static WrapperEntry *wrap_matching_entry PROTO ((const char *)); - -static WrapperEntry * -wrap_matching_entry (name) - const char *name; -{ - int x,count=wrap_count+wrap_tempcount; - - for(x=0;xwildCard, name, 0) == 0) - return wrap_list[x]; - return (WrapperEntry *)NULL; -} - -/* Return the RCS options for FILENAME in a newly malloc'd string. If - ASFLAG, then include "-k" at the beginning (e.g. "-kb"), otherwise - just give the option itself (e.g. "b"). */ -char * -wrap_rcsoption (filename, asflag) - const char *filename; - int asflag; -{ - WrapperEntry *e = wrap_matching_entry (filename); - char *buf; - - if (e == NULL || e->rcsOption == NULL || (*e->rcsOption == '\0')) - return NULL; - - buf = xmalloc (strlen (e->rcsOption) + 3); - if (asflag) - { - strcpy (buf, "-k"); - strcat (buf, e->rcsOption); - } - else - { - strcpy (buf, e->rcsOption); - } - return buf; -} - -char * -wrap_tocvs_process_file(fileName) - const char *fileName; -{ - WrapperEntry *e=wrap_matching_entry(fileName); - static char *buf = NULL; - char *args; - - if(e==NULL || e->tocvsFilter==NULL) - return NULL; - - if (buf != NULL) - free (buf); - buf = cvs_temp_name (); - - args = xmalloc (strlen (e->tocvsFilter) - + strlen (fileName) - + strlen (buf)); - - wrap_clean_fmt_str(e->tocvsFilter, 2); - sprintf (args, e->tocvsFilter, fileName, buf); - run_setup (args); - run_exec(RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL|RUN_REALLY ); - free (args); - - return buf; -} - -int -wrap_merge_is_copy (fileName) - const char *fileName; -{ - WrapperEntry *e=wrap_matching_entry(fileName); - if(e==NULL || e->mergeMethod==WRAP_MERGE) - return 0; - - return 1; -} - -void -wrap_fromcvs_process_file(fileName) - const char *fileName; -{ - char *args; - WrapperEntry *e=wrap_matching_entry(fileName); - - if(e==NULL || e->fromcvsFilter==NULL) - return; - - args = xmalloc (strlen (e->fromcvsFilter) - + strlen (fileName)); - - wrap_clean_fmt_str(e->fromcvsFilter, 1); - sprintf (args, e->fromcvsFilter, fileName); - run_setup (args); - run_exec(RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL ); - free (args); - return; -} diff --git a/contrib/cvs/src/zlib.c b/contrib/cvs/src/zlib.c deleted file mode 100644 index 46ed0e6..0000000 --- a/contrib/cvs/src/zlib.c +++ /dev/null @@ -1,760 +0,0 @@ -/* zlib.c --- interface to the zlib compression library - Ian Lance Taylor - - This file is part of GNU CVS. - - GNU CVS is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. */ - -/* The routines in this file are the interface between the CVS - client/server support and the zlib compression library. */ - -#include -#include "cvs.h" -#include "buffer.h" - -#if defined (SERVER_SUPPORT) || defined (CLIENT_SUPPORT) - -#include "zlib.h" - -/* OS/2 doesn't have EIO. FIXME: this whole notion of turning - a different error into EIO strikes me as pretty dubious. */ -#if !defined (EIO) -#define EIO EBADPOS -#endif - -/* The compression interface is built upon the buffer data structure. - We provide a buffer type which compresses or decompresses the data - which passes through it. An input buffer decompresses the data - read from an underlying buffer, and an output buffer compresses the - data before writing it to an underlying buffer. */ - -/* This structure is the closure field of the buffer. */ - -struct compress_buffer -{ - /* The underlying buffer. */ - struct buffer *buf; - /* The compression information. */ - z_stream zstr; -}; - -static void compress_error PROTO((int, int, z_stream *, const char *)); -static int compress_buffer_input PROTO((void *, char *, int, int, int *)); -static int compress_buffer_output PROTO((void *, const char *, int, int *)); -static int compress_buffer_flush PROTO((void *)); -static int compress_buffer_block PROTO((void *, int)); -static int compress_buffer_shutdown_input PROTO((struct buffer *)); -static int compress_buffer_shutdown_output PROTO((struct buffer *)); - -/* Report an error from one of the zlib functions. */ - -static void -compress_error (status, zstatus, zstr, msg) - int status; - int zstatus; - z_stream *zstr; - const char *msg; -{ - int hold_errno; - const char *zmsg; - char buf[100]; - - hold_errno = errno; - - zmsg = zstr->msg; - if (zmsg == NULL) - { - sprintf (buf, "error %d", zstatus); - zmsg = buf; - } - - error (status, - zstatus == Z_ERRNO ? hold_errno : 0, - "%s: %s", msg, zmsg); -} - -/* Create a compression buffer. */ - -struct buffer * -compress_buffer_initialize (buf, input, level, memory) - struct buffer *buf; - int input; - int level; - void (*memory) PROTO((struct buffer *)); -{ - struct compress_buffer *n; - int zstatus; - - n = (struct compress_buffer *) xmalloc (sizeof *n); - memset (n, 0, sizeof *n); - - n->buf = buf; - - if (input) - zstatus = inflateInit (&n->zstr); - else - zstatus = deflateInit (&n->zstr, level); - if (zstatus != Z_OK) - compress_error (1, zstatus, &n->zstr, "compression initialization"); - - /* There may already be data buffered on BUF. For an output - buffer, this is OK, because these routines will just use the - buffer routines to append data to the (uncompressed) data - already on BUF. An input buffer expects to handle a single - buffer_data of buffered input to be uncompressed, so that is OK - provided there is only one buffer. At present that is all - there ever will be; if this changes, compress_buffer_input must - be modified to handle multiple input buffers. */ - assert (! input || buf->data == NULL || buf->data->next == NULL); - - return buf_initialize (input ? compress_buffer_input : NULL, - input ? NULL : compress_buffer_output, - input ? NULL : compress_buffer_flush, - compress_buffer_block, - (input - ? compress_buffer_shutdown_input - : compress_buffer_shutdown_output), - memory, - n); -} - -/* Input data from a compression buffer. */ - -static int -compress_buffer_input (closure, data, need, size, got) - void *closure; - char *data; - int need; - int size; - int *got; -{ - struct compress_buffer *cb = (struct compress_buffer *) closure; - struct buffer_data *bd; - - if (cb->buf->input == NULL) - abort (); - - /* We use a single buffer_data structure to buffer up data which - the z_stream structure won't use yet. We can safely store this - on cb->buf->data, because we never call the buffer routines on - cb->buf; we only call the buffer input routine, since that - gives us the semantics we want. As noted in - compress_buffer_initialize, the buffer_data structure may - already exist, and hold data which was already read and - buffered before the decompression began. */ - bd = cb->buf->data; - if (bd == NULL) - { - bd = ((struct buffer_data *) xmalloc (sizeof (struct buffer_data))); - if (bd == NULL) - return -2; - bd->text = (char *) xmalloc (BUFFER_DATA_SIZE); - if (bd->text == NULL) - { - free (bd); - return -2; - } - bd->bufp = bd->text; - bd->size = 0; - cb->buf->data = bd; - } - - cb->zstr.avail_out = size; - cb->zstr.next_out = (Bytef *) data; - - while (1) - { - int zstatus, sofar, status, nread; - - /* First try to inflate any data we already have buffered up. - This is useful even if we don't have any buffered data, - because there may be data buffered inside the z_stream - structure. */ - - cb->zstr.avail_in = bd->size; - cb->zstr.next_in = (Bytef *) bd->bufp; - - do - { - zstatus = inflate (&cb->zstr, Z_NO_FLUSH); - if (zstatus == Z_STREAM_END) - break; - if (zstatus != Z_OK && zstatus != Z_BUF_ERROR) - { - compress_error (0, zstatus, &cb->zstr, "inflate"); - return EIO; - } - } while (cb->zstr.avail_in > 0 - && cb->zstr.avail_out > 0); - - bd->size = cb->zstr.avail_in; - bd->bufp = (char *) cb->zstr.next_in; - - if (zstatus == Z_STREAM_END) - return -1; - - /* If we have obtained NEED bytes, then return, unless NEED is - zero and we haven't obtained anything at all. If NEED is - zero, we will keep reading from the underlying buffer until - we either can't read anything, or we have managed to - inflate at least one byte. */ - sofar = size - cb->zstr.avail_out; - if (sofar > 0 && sofar >= need) - break; - - /* All our buffered data should have been processed at this - point. */ - assert (bd->size == 0); - - /* This will work well in the server, because this call will - do an unblocked read and fetch all the available data. In - the client, this will read a single byte from the stdio - stream, which will cause us to call inflate once per byte. - It would be more efficient if we could make a call which - would fetch all the available bytes, and at least one byte. */ - - status = (*cb->buf->input) (cb->buf->closure, bd->text, - need > 0 ? 1 : 0, - BUFFER_DATA_SIZE, &nread); - if (status != 0) - return status; - - /* If we didn't read anything, then presumably the buffer is - in nonblocking mode, and we should just get out now with - whatever we've inflated. */ - if (nread == 0) - { - assert (need == 0); - break; - } - - bd->bufp = bd->text; - bd->size = nread; - } - - *got = size - cb->zstr.avail_out; - - return 0; -} - -/* Output data to a compression buffer. */ - -static int -compress_buffer_output (closure, data, have, wrote) - void *closure; - const char *data; - int have; - int *wrote; -{ - struct compress_buffer *cb = (struct compress_buffer *) closure; - - cb->zstr.avail_in = have; - cb->zstr.next_in = (unsigned char *) data; - - while (cb->zstr.avail_in > 0) - { - char buffer[BUFFER_DATA_SIZE]; - int zstatus; - - cb->zstr.avail_out = BUFFER_DATA_SIZE; - cb->zstr.next_out = (unsigned char *) buffer; - - zstatus = deflate (&cb->zstr, Z_NO_FLUSH); - if (zstatus != Z_OK) - { - compress_error (0, zstatus, &cb->zstr, "deflate"); - return EIO; - } - - if (cb->zstr.avail_out != BUFFER_DATA_SIZE) - buf_output (cb->buf, buffer, - BUFFER_DATA_SIZE - cb->zstr.avail_out); - } - - *wrote = have; - - /* We will only be here because buf_send_output was called on the - compression buffer. That means that we should now call - buf_send_output on the underlying buffer. */ - return buf_send_output (cb->buf); -} - -/* Flush a compression buffer. */ - -static int -compress_buffer_flush (closure) - void *closure; -{ - struct compress_buffer *cb = (struct compress_buffer *) closure; - - cb->zstr.avail_in = 0; - cb->zstr.next_in = NULL; - - while (1) - { - char buffer[BUFFER_DATA_SIZE]; - int zstatus; - - cb->zstr.avail_out = BUFFER_DATA_SIZE; - cb->zstr.next_out = (unsigned char *) buffer; - - zstatus = deflate (&cb->zstr, Z_SYNC_FLUSH); - - /* The deflate function will return Z_BUF_ERROR if it can't do - anything, which in this case means that all data has been - flushed. */ - if (zstatus == Z_BUF_ERROR) - break; - - if (zstatus != Z_OK) - { - compress_error (0, zstatus, &cb->zstr, "deflate flush"); - return EIO; - } - - if (cb->zstr.avail_out != BUFFER_DATA_SIZE) - buf_output (cb->buf, buffer, - BUFFER_DATA_SIZE - cb->zstr.avail_out); - - /* If the deflate function did not fill the output buffer, - then all data has been flushed. */ - if (cb->zstr.avail_out > 0) - break; - } - - /* Now flush the underlying buffer. Note that if the original - call to buf_flush passed 1 for the BLOCK argument, then the - buffer will already have been set into blocking mode, so we - should always pass 0 here. */ - return buf_flush (cb->buf, 0); -} - -/* The block routine for a compression buffer. */ - -static int -compress_buffer_block (closure, block) - void *closure; - int block; -{ - struct compress_buffer *cb = (struct compress_buffer *) closure; - - if (block) - return set_block (cb->buf); - else - return set_nonblock (cb->buf); -} - -/* Shut down an input buffer. */ - -static int -compress_buffer_shutdown_input (buf) - struct buffer *buf; -{ - struct compress_buffer *cb = (struct compress_buffer *) buf->closure; - int zstatus; - - /* Don't make any attempt to pick up trailing data since we are shutting - * down. If the client doesn't know we are shutting down, we might not - * see the EOF we are expecting. - */ - - zstatus = inflateEnd (&cb->zstr); - if (zstatus != Z_OK) - { - compress_error (0, zstatus, &cb->zstr, "inflateEnd"); - return EIO; - } - - return buf_shutdown (cb->buf); -} - -/* Shut down an output buffer. */ - -static int -compress_buffer_shutdown_output (buf) - struct buffer *buf; -{ - struct compress_buffer *cb = (struct compress_buffer *) buf->closure; - int zstatus, status; - - do - { - char buffer[BUFFER_DATA_SIZE]; - - cb->zstr.avail_out = BUFFER_DATA_SIZE; - cb->zstr.next_out = (unsigned char *) buffer; - - zstatus = deflate (&cb->zstr, Z_FINISH); - if (zstatus != Z_OK && zstatus != Z_STREAM_END) - { - compress_error (0, zstatus, &cb->zstr, "deflate finish"); - return EIO; - } - - if (cb->zstr.avail_out != BUFFER_DATA_SIZE) - buf_output (cb->buf, buffer, - BUFFER_DATA_SIZE - cb->zstr.avail_out); - } while (zstatus != Z_STREAM_END); - - zstatus = deflateEnd (&cb->zstr); - if (zstatus != Z_OK) - { - compress_error (0, zstatus, &cb->zstr, "deflateEnd"); - return EIO; - } - - status = buf_flush (cb->buf, 1); - if (status != 0) - return status; - - return buf_shutdown (cb->buf); -} - - - -/* Here is our librarified gzip implementation. It is very minimal - but attempts to be RFC1952 compliant. */ - -/* GZIP ID byte values */ -#define GZIP_ID1 31 -#define GZIP_ID2 139 - -/* Compression methods */ -#define GZIP_CDEFLATE 8 - -/* Flags */ -#define GZIP_FTEXT 1 -#define GZIP_FHCRC 2 -#define GZIP_FEXTRA 4 -#define GZIP_FNAME 8 -#define GZIP_FCOMMENT 16 - -/* BUF should contain SIZE bytes of gzipped data (RFC1952/RFC1951). - We are to uncompress the data and write the result to the file - descriptor FD. If something goes wrong, give a nonfatal error message - mentioning FULLNAME as the name of the file for FD. Return 1 if - it is an error we can't recover from. */ - -int -gunzip_and_write (fd, fullname, buf, size) - int fd; - char *fullname; - unsigned char *buf; - size_t size; -{ - size_t pos; - z_stream zstr; - int zstatus; - unsigned char outbuf[32768]; - unsigned long crc; - - if (size < 10) - { - error (0, 0, "gzipped data too small - lacks complete header"); - return 1; - } - if (buf[0] != GZIP_ID1 || buf[1] != GZIP_ID2) - { - error (0, 0, "gzipped data does not start with gzip identification"); - return 1; - } - if (buf[2] != GZIP_CDEFLATE) - { - error (0, 0, "only the deflate compression method is supported"); - return 1; - } - - /* Skip over the fixed header, and then skip any of the variable-length - fields. As we skip each field, we keep pos <= size. The checks - on positions and lengths are really checks for malformed or - incomplete gzip data. */ - pos = 10; - if (buf[3] & GZIP_FEXTRA) - { - if (pos + 2 >= size) - { - error (0, 0, "%s lacks proper gzip XLEN field", fullname); - return 1; - } - pos += buf[pos] + (buf[pos + 1] << 8) + 2; - if (pos > size) - { - error (0, 0, "%s lacks proper gzip \"extra field\"", fullname); - return 1; - } - - } - if (buf[3] & GZIP_FNAME) - { - unsigned char *p = memchr(buf + pos, '\0', size - pos); - if (p == NULL) - { - error (0, 0, "%s has bad gzip filename field", fullname); - return 1; - } - pos = p - buf + 1; - } - if (buf[3] & GZIP_FCOMMENT) - { - unsigned char *p = memchr(buf + pos, '\0', size - pos); - if (p == NULL) - { - error (0, 0, "%s has bad gzip comment field", fullname); - return 1; - } - pos = p - buf + 1; - } - if (buf[3] & GZIP_FHCRC) - { - pos += 2; - if (pos > size) - { - error (0, 0, "%s has bad gzip CRC16 field", fullname); - return 1; - } - } - - /* There could be no data to decompress - check and short circuit. */ - if (pos >= size) - { - error (0, 0, "gzip data incomplete for %s (no data)", fullname); - return 1; - } - - memset (&zstr, 0, sizeof zstr); - /* Passing a negative argument tells zlib not to look for a zlib - (RFC1950) header. This is an undocumented feature; I suppose if - we wanted to be anal we could synthesize a header instead, - but why bother? */ - zstatus = inflateInit2 (&zstr, -15); - - if (zstatus != Z_OK) - compress_error (1, zstatus, &zstr, fullname); - - /* I don't see why we should have to include the 8 byte trailer in - avail_in. But I see that zlib/gzio.c does, and it seemed to fix - a fairly rare bug in which we'd get a Z_BUF_ERROR for no obvious - reason. */ - zstr.avail_in = size - pos; - zstr.next_in = buf + pos; - - crc = crc32 (0, NULL, 0); - - do - { - zstr.avail_out = sizeof (outbuf); - zstr.next_out = outbuf; - zstatus = inflate (&zstr, Z_NO_FLUSH); - if (zstatus != Z_STREAM_END && zstatus != Z_OK) - { - compress_error (0, zstatus, &zstr, fullname); - return 1; - } - if (write (fd, outbuf, sizeof (outbuf) - zstr.avail_out) < 0) - { - error (0, errno, "writing decompressed file %s", fullname); - return 1; - } - crc = crc32 (crc, outbuf, sizeof (outbuf) - zstr.avail_out); - } while (zstatus != Z_STREAM_END); - zstatus = inflateEnd (&zstr); - if (zstatus != Z_OK) - compress_error (0, zstatus, &zstr, fullname); - - /* Check that there is still 8 trailer bytes remaining (CRC32 - and ISIZE). Check total decomp. data, plus header len (pos) - against input buffer total size. */ - pos += zstr.total_in; - if (size - pos != 8) - { - error (0, 0, "gzip data incomplete for %s (no trailer)", fullname); - return 1; - } - - if (crc != ((unsigned long)buf[pos] - + ((unsigned long)buf[pos + 1] << 8) - + ((unsigned long)buf[pos + 2] << 16) - + ((unsigned long)buf[pos + 3] << 24))) - { - error (0, 0, "CRC error uncompressing %s", fullname); - return 1; - } - - if (zstr.total_out != ((unsigned long)buf[pos + 4] - + ((unsigned long)buf[pos + 5] << 8) - + ((unsigned long)buf[pos + 6] << 16) - + ((unsigned long)buf[pos + 7] << 24))) - { - error (0, 0, "invalid length uncompressing %s", fullname); - return 1; - } - - return 0; -} - -/* Read all of FD and put the gzipped data (RFC1952/RFC1951) into *BUF, - replacing previous contents of *BUF. *BUF is xmalloc'd and *SIZE is - its allocated size. Put the actual number of bytes of data in - *LEN. If something goes wrong, give a nonfatal error mentioning - FULLNAME as the name of the file for FD, and return 1 if we can't - recover from it). LEVEL is the compression level (1-9). */ - -int -read_and_gzip (fd, fullname, buf, size, len, level) - int fd; - const char *fullname; - unsigned char **buf; - size_t *size; - size_t *len; - int level; -{ - z_stream zstr; - int zstatus; - unsigned char inbuf[8192]; - int nread; - unsigned long crc; - - if (*size < 1024) - { - unsigned char *newbuf; - - *size = 1024; - newbuf = xrealloc (*buf, *size); - if (newbuf == NULL) - { - error (0, 0, "out of memory"); - return 1; - } - *buf = newbuf; - } - (*buf)[0] = GZIP_ID1; - (*buf)[1] = GZIP_ID2; - (*buf)[2] = GZIP_CDEFLATE; - (*buf)[3] = 0; - (*buf)[4] = (*buf)[5] = (*buf)[6] = (*buf)[7] = 0; - /* Could set this based on level, but why bother? */ - (*buf)[8] = 0; - (*buf)[9] = 255; - - memset (&zstr, 0, sizeof zstr); - zstatus = deflateInit2 (&zstr, level, Z_DEFLATED, -15, 8, - Z_DEFAULT_STRATEGY); - crc = crc32 (0, NULL, 0); - if (zstatus != Z_OK) - { - compress_error (0, zstatus, &zstr, fullname); - return 1; - } - - /* Adjust for 10-byte output header (filled in above) */ - zstr.total_out = 10; - zstr.avail_out = *size - 10; - zstr.next_out = *buf + 10; - - while (1) - { - int finish = 0; - - nread = read (fd, inbuf, sizeof inbuf); - if (nread < 0) - { - error (0, errno, "cannot read %s", fullname); - return 1; - } - else if (nread == 0) - /* End of file. */ - finish = 1; - crc = crc32 (crc, inbuf, nread); - zstr.next_in = inbuf; - zstr.avail_in = nread; - - do - { - /* I don't see this documented anywhere, but deflate seems - to tend to dump core sometimes if we pass it Z_FINISH and - a small (e.g. 2147 byte) avail_out. So we insist on at - least 4096 bytes (that is what zlib/gzio.c uses). */ - - if (zstr.avail_out < 4096) - { - unsigned char *newbuf; - - assert(zstr.avail_out + zstr.total_out == *size); - assert(zstr.next_out == *buf + zstr.total_out); - *size *= 2; - newbuf = xrealloc (*buf, *size); - if (newbuf == NULL) - { - error (0, 0, "out of memory"); - return 1; - } - *buf = newbuf; - zstr.next_out = *buf + zstr.total_out; - zstr.avail_out = *size - zstr.total_out; - assert(zstr.avail_out + zstr.total_out == *size); - assert(zstr.next_out == *buf + zstr.total_out); - } - - zstatus = deflate (&zstr, finish ? Z_FINISH : 0); - if (zstatus == Z_STREAM_END) - goto done; - else if (zstatus != Z_OK) - compress_error (0, zstatus, &zstr, fullname); - } while (zstr.avail_out == 0); - } - done: - /* Need to add the CRC information (8 bytes) - to the end of the gzip'd output. - Ensure there is enough space in the output buffer - to do so. */ - if (zstr.avail_out < 8) - { - unsigned char *newbuf; - - assert(zstr.avail_out + zstr.total_out == *size); - assert(zstr.next_out == *buf + zstr.total_out); - *size += 8 - zstr.avail_out; - newbuf = realloc (*buf, *size); - if (newbuf == NULL) - { - error (0, 0, "out of memory"); - return 1; - } - *buf = newbuf; - zstr.next_out = *buf + zstr.total_out; - zstr.avail_out = *size - zstr.total_out; - assert(zstr.avail_out + zstr.total_out == *size); - assert(zstr.next_out == *buf + zstr.total_out); - } - *zstr.next_out++ = (unsigned char)(crc & 0xff); - *zstr.next_out++ = (unsigned char)((crc >> 8) & 0xff); - *zstr.next_out++ = (unsigned char)((crc >> 16) & 0xff); - *zstr.next_out++ = (unsigned char)((crc >> 24) & 0xff); - - *zstr.next_out++ = (unsigned char)(zstr.total_in & 0xff); - *zstr.next_out++ = (unsigned char)((zstr.total_in >> 8) & 0xff); - *zstr.next_out++ = (unsigned char)((zstr.total_in >> 16) & 0xff); - *zstr.next_out++ = (unsigned char)((zstr.total_in >> 24) & 0xff); - - zstr.total_out += 8; - zstr.avail_out -= 8; - assert(zstr.avail_out + zstr.total_out == *size); - assert(zstr.next_out == *buf + zstr.total_out); - - *len = zstr.total_out; - - zstatus = deflateEnd (&zstr); - if (zstatus != Z_OK) - compress_error (0, zstatus, &zstr, fullname); - - return 0; -} -#endif /* defined (SERVER_SUPPORT) || defined (CLIENT_SUPPORT) */ diff --git a/contrib/cvs/tools/ChangeLog b/contrib/cvs/tools/ChangeLog deleted file mode 100644 index 89d715d..0000000 --- a/contrib/cvs/tools/ChangeLog +++ /dev/null @@ -1,107 +0,0 @@ -2005-09-01 Derek Price - - * README: Correct grammar. - - * README: Update links. - -2005-01-31 Derek Price - - * Makefile.am: Update copyright notices. - -2003-05-21 Derek Price - - * Makefile.in: Regenerate with Automake version 1.7.5. - -2003-04-10 Larry Jones - - * Makefile.in: Regenerated. - -2003-03-24 Derek Price - - * Makefile.am: Update copyright notice. - - * Makefile.in: Regenerated. - -2003-02-25 Derek Price - - * Makefile.in: Regenerated. - -2002-09-24 Derek Price - - * Makefile.in: Regenerated using Automake 1.6.3. - -2002-09-24 Derek Price - - * Makefile.in: Regenerated. - -2002-04-30 Derek Price - - * Makefile.in: Regenerated with automake 1.6. - -2002-04-17 Derek Price - - * README: Replace cyclic.com with cvshome.org. - -2001-09-04 Derek Price - - * Makefile.in: Regenerated with automake 1.5. - -2001-08-06 Derek Price - - * Makefile.in: Regenerated. - -2001-07-04 Derek Price - - * Makefile.in: Regenerated with new Automake release candidate 1.4h. - -2001-06-28 Derek Price - - * Makefile.in: Regenerated with new version of Automake. - -2001-04-25 Derek Price - - * Makefile.in: Regenerated using AM 1.4e as of today at 18:10 -0400. - -2001-03-14 Derek Price - - * Makefile.in: Regenerated - -2000-12-22 Derek Price - - * Makefile.in: Regenerated - -2000-12-21 Derek Price - - * Makefile.am: New file needed by Automake - * Makefile.in: Regenerated - -1998-09-09 Jim Kingdon - - * README: Update now that pcl-cvs is no longer here. - * pcl-cvs: Remove this subdirectory and all its contents. - * Makefile.in: Remove references to pcl-cvs directory. - -Sat Feb 21 22:02:12 1998 Ian Lance Taylor - - * Makefile.in (clean): Change "/bin/rm" to "rm". - -Wed Jan 8 14:50:47 1997 Jim Kingdon - - * Makefile.in: Remove CVSid; we decided to get rid - of these some time ago. - -Thu Jan 2 13:30:56 1997 Jim Kingdon - - * Makefile.in: Remove "675" paragraph; see ../ChangeLog for rationale. - -Fri Aug 16 16:05:56 1996 Norbert Kiesel - - * Makefile.in (installdirs): new (empty) target - -Sun Apr 14 11:07:43 1996 Karl Fogel - - * .cvsignore: new file. - - * Makefile.in (subdir): `tools', not `contrib'. - - * Added ChangeLog (this file), and subdir `pcl-cvs'. diff --git a/contrib/cvs/tools/Makefile.am b/contrib/cvs/tools/Makefile.am deleted file mode 100644 index 2a26eb0..0000000 --- a/contrib/cvs/tools/Makefile.am +++ /dev/null @@ -1,24 +0,0 @@ -## Process this file with automake to produce Makefile.in -# Makefile for GNU CVS auxiliary tools. -# -# Copyright (C) 1986-2005 The Free Software Foundation, Inc. -# -# Portions Copyright (C) 1998-2005 Derek Price, Ximbiot , -# and others. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -EXTRA_DIST = \ - README .cvsignore - -# for backwards compatibility with the old makefiles -realclean: maintainer-clean -.PHONY: realclean diff --git a/contrib/cvs/tools/Makefile.in b/contrib/cvs/tools/Makefile.in deleted file mode 100644 index c996c99..0000000 --- a/contrib/cvs/tools/Makefile.in +++ /dev/null @@ -1,334 +0,0 @@ -# Makefile.in generated by automake 1.10 from Makefile.am. -# @configure_input@ - -# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006 Free Software Foundation, Inc. -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ - -# Makefile for GNU CVS auxiliary tools. -# -# Copyright (C) 1986-2005 The Free Software Foundation, Inc. -# -# Portions Copyright (C) 1998-2005 Derek Price, Ximbiot , -# and others. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -VPATH = @srcdir@ -pkgdatadir = $(datadir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -subdir = tools -DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ - ChangeLog -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ - $(top_srcdir)/configure.in -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs -CONFIG_HEADER = $(top_builddir)/config.h -CONFIG_CLEAN_FILES = -SOURCES = -DIST_SOURCES = -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -ACLOCAL = @ACLOCAL@ -AMTAR = @AMTAR@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -CC = @CC@ -CCDEPMODE = @CCDEPMODE@ -CFLAGS = @CFLAGS@ -CPP = @CPP@ -CPPFLAGS = @CPPFLAGS@ -CSH = @CSH@ -CYGPATH_W = @CYGPATH_W@ -DEFS = @DEFS@ -DEPDIR = @DEPDIR@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EDITOR = @EDITOR@ -EGREP = @EGREP@ -EXEEXT = @EXEEXT@ -GREP = @GREP@ -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -KRB4 = @KRB4@ -LDFLAGS = @LDFLAGS@ -LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ -LN_S = @LN_S@ -LTLIBOBJS = @LTLIBOBJS@ -MAINT = @MAINT@ -MAKEINFO = @MAKEINFO@ -MKDIR_P = @MKDIR_P@ -MKTEMP = @MKTEMP@ -OBJEXT = @OBJEXT@ -PACKAGE = @PACKAGE@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ -PACKAGE_NAME = @PACKAGE_NAME@ -PACKAGE_STRING = @PACKAGE_STRING@ -PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -PERL = @PERL@ -PR = @PR@ -PS2PDF = @PS2PDF@ -RANLIB = @RANLIB@ -ROFF = @ROFF@ -SENDMAIL = @SENDMAIL@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -STRIP = @STRIP@ -TEXI2DVI = @TEXI2DVI@ -VERSION = @VERSION@ -YACC = @YACC@ -YFLAGS = @YFLAGS@ -abs_builddir = @abs_builddir@ -abs_srcdir = @abs_srcdir@ -abs_top_builddir = @abs_top_builddir@ -abs_top_srcdir = @abs_top_srcdir@ -ac_ct_CC = @ac_ct_CC@ -ac_prefix_program = @ac_prefix_program@ -am__include = @am__include@ -am__leading_dot = @am__leading_dot@ -am__quote = @am__quote@ -am__tar = @am__tar@ -am__untar = @am__untar@ -bindir = @bindir@ -build_alias = @build_alias@ -builddir = @builddir@ -datadir = @datadir@ -datarootdir = @datarootdir@ -docdir = @docdir@ -dvidir = @dvidir@ -exec_prefix = @exec_prefix@ -host_alias = @host_alias@ -htmldir = @htmldir@ -includedir = @includedir@ -includeopt = @includeopt@ -infodir = @infodir@ -install_sh = @install_sh@ -libdir = @libdir@ -libexecdir = @libexecdir@ -localedir = @localedir@ -localstatedir = @localstatedir@ -mandir = @mandir@ -mkdir_p = @mkdir_p@ -oldincludedir = @oldincludedir@ -pdfdir = @pdfdir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -psdir = @psdir@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -srcdir = @srcdir@ -sysconfdir = @sysconfdir@ -target_alias = @target_alias@ -top_builddir = @top_builddir@ -top_srcdir = @top_srcdir@ -with_default_rsh = @with_default_rsh@ -with_default_ssh = @with_default_ssh@ -EXTRA_DIST = \ - README .cvsignore - -all: all-am - -.SUFFIXES: -$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ - && exit 0; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu tools/Makefile'; \ - cd $(top_srcdir) && \ - $(AUTOMAKE) --gnu tools/Makefile -.PRECIOUS: Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - @case '$?' in \ - *config.status*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ - *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ - esac; - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh - -$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -tags: TAGS -TAGS: - -ctags: CTAGS -CTAGS: - - -distdir: $(DISTFILES) - @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - list='$(DISTFILES)'; \ - dist_files=`for file in $$list; do echo $$file; done | \ - sed -e "s|^$$srcdirstrip/||;t" \ - -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ - case $$dist_files in \ - */*) $(MKDIR_P) `echo "$$dist_files" | \ - sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ - sort -u` ;; \ - esac; \ - for file in $$dist_files; do \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - if test -d $$d/$$file; then \ - dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ - fi; \ - cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ - else \ - test -f $(distdir)/$$file \ - || cp -p $$d/$$file $(distdir)/$$file \ - || exit 1; \ - fi; \ - done -check-am: all-am -check: check-am -all-am: Makefile -installdirs: -install: install-am -install-exec: install-exec-am -install-data: install-data-am -uninstall: uninstall-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-am -install-strip: - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - `test -z '$(STRIP)' || \ - echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install -mostlyclean-generic: - -clean-generic: - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." -clean: clean-am - -clean-am: clean-generic mostlyclean-am - -distclean: distclean-am - -rm -f Makefile -distclean-am: clean-am distclean-generic - -dvi: dvi-am - -dvi-am: - -html: html-am - -info: info-am - -info-am: - -install-data-am: - -install-dvi: install-dvi-am - -install-exec-am: - -install-html: install-html-am - -install-info: install-info-am - -install-man: - -install-pdf: install-pdf-am - -install-ps: install-ps-am - -installcheck-am: - -maintainer-clean: maintainer-clean-am - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-am - -mostlyclean-am: mostlyclean-generic - -pdf: pdf-am - -pdf-am: - -ps: ps-am - -ps-am: - -uninstall-am: - -.MAKE: install-am install-strip - -.PHONY: all all-am check check-am clean clean-generic distclean \ - distclean-generic distdir dvi dvi-am html html-am info info-am \ - install install-am install-data install-data-am install-dvi \ - install-dvi-am install-exec install-exec-am install-html \ - install-html-am install-info install-info-am install-man \ - install-pdf install-pdf-am install-ps install-ps-am \ - install-strip installcheck installcheck-am installdirs \ - maintainer-clean maintainer-clean-generic mostlyclean \ - mostlyclean-generic pdf pdf-am ps ps-am uninstall uninstall-am - - -# for backwards compatibility with the old makefiles -realclean: maintainer-clean -.PHONY: realclean -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/contrib/cvs/tools/README b/contrib/cvs/tools/README deleted file mode 100644 index 9593c96..0000000 --- a/contrib/cvs/tools/README +++ /dev/null @@ -1,10 +0,0 @@ -This subdirectory formerly contained tools that can be used with CVS. -In particular, it used to contain a copy of pcl-cvs version 1.x. -Pcl-cvs is an Emacs interface to CVS. - -If you are looking for pcl-cvs, we'd suggest pcl-cvs version 2.x, at: - ftp://ftp.weird.com/pub/local/ - -The following CVS site has a page about pcl-cvs: - http://ximbiot.com -It also has much information about CVS tools more generally. diff --git a/etc/inetd.conf b/etc/inetd.conf index 8b8e604..77b4eda 100644 --- a/etc/inetd.conf +++ b/etc/inetd.conf @@ -58,8 +58,8 @@ # --allow-root path correctly or you open a trivial to exploit but # deadly security hole. # -#cvspserver stream tcp nowait root /usr/bin/cvs cvs --allow-root=/your/cvsroot/here pserver -#cvspserver stream tcp nowait root /usr/bin/cvs cvs --allow-root=/your/cvsroot/here kserver +#cvspserver stream tcp nowait root /usr/local/bin/cvs cvs --allow-root=/your/cvsroot/here pserver +#cvspserver stream tcp nowait root /usr/local/bin/cvs cvs --allow-root=/your/cvsroot/here kserver # # RPC based services (you MUST have rpcbind running to use these) # diff --git a/etc/mtree/BSD.usr.dist b/etc/mtree/BSD.usr.dist index 0064d10..02d2286 100644 --- a/etc/mtree/BSD.usr.dist +++ b/etc/mtree/BSD.usr.dist @@ -148,8 +148,6 @@ .. 27.nfsrfc .. - 28.cvs - .. .. smm 01.setup @@ -223,10 +221,6 @@ .. csh .. - cvs - contrib - .. - .. cvsup .. diskless diff --git a/gnu/usr.bin/Makefile b/gnu/usr.bin/Makefile index 386c957..cfb9a21 100644 --- a/gnu/usr.bin/Makefile +++ b/gnu/usr.bin/Makefile @@ -4,7 +4,6 @@ SUBDIR= ${_binutils} \ ${_cc} \ - ${_cvs} \ dialog \ diff \ diff3 \ @@ -26,10 +25,6 @@ _groff= groff .endif .endif -.if ${MK_CVS} != "no" -_cvs= cvs -.endif - .if ${MK_GPL_DTC} != "no" _dtc= dtc .endif diff --git a/gnu/usr.bin/cvs/Makefile b/gnu/usr.bin/cvs/Makefile deleted file mode 100644 index dc41a73..0000000 --- a/gnu/usr.bin/cvs/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -# $FreeBSD$ - -SUBDIR = lib libdiff cvs contrib cvsbug doc - -.include diff --git a/gnu/usr.bin/cvs/Makefile.inc b/gnu/usr.bin/cvs/Makefile.inc deleted file mode 100644 index 4acfa0b..0000000 --- a/gnu/usr.bin/cvs/Makefile.inc +++ /dev/null @@ -1,17 +0,0 @@ -# $FreeBSD$ - -.if !defined(CVSDIR) - -CVSDIR= $(.CURDIR)/../../../../contrib/cvs - -LIBCVSDIR= ${.OBJDIR}/../lib -LIBCVS= ${LIBCVSDIR}/libcvs.a - -LIBDIFFDIR= ${.OBJDIR}/../libdiff -LIBDIFF= ${LIBDIFFDIR}/libdiff.a - -.if exists(${.CURDIR}/../../Makefile.inc) -.include "${.CURDIR}/../../Makefile.inc" -.endif - -.endif diff --git a/gnu/usr.bin/cvs/contrib/Makefile b/gnu/usr.bin/cvs/contrib/Makefile deleted file mode 100644 index 2ac3618..0000000 --- a/gnu/usr.bin/cvs/contrib/Makefile +++ /dev/null @@ -1,35 +0,0 @@ -# $FreeBSD$ - -.include "../Makefile.inc" - -.PATH: ${CVSDIR}/contrib -.PATH: ${CVSDIR}/man - -SCRIPTS= clmerge cln_hist commit_prep cvs2vendor cvs_acls cvscheck \ - log log_accum mfpipe rcs-to-cvs rcs2log rcslock sccs2rcs \ - easy-import - -FILES= README cvscheck.man cvshelp.man descend.man intro.doc - -EXAMPDIR= ${SHAREDIR}/examples/cvs -FILESDIR= ${EXAMPDIR}/contrib -SCRIPTSDIR= ${FILESDIR} -PERLPATH= /usr/bin/perl -CLEANFILES+= $(SCRIPTS) - -.SUFFIXES: .sh .pl .in - -# Prevent Makefile.in from overwriting Makefile through the suffix rules. -Makefile: - @: - -.sh: - cp -f ${.IMPSRC} ${.TARGET} - -.pl: - sed -e 's,xPERL_PATHx,$(PERLPATH),' ${.IMPSRC} > ${.TARGET} - -.in: - sed -e 's,@CSH@,/bin/csh,' -e 's,@PERL@,$(PERLPATH),' ${.IMPSRC} > ${.TARGET} - -.include diff --git a/gnu/usr.bin/cvs/contrib/easy-import.pl b/gnu/usr.bin/cvs/contrib/easy-import.pl deleted file mode 100644 index d266957..0000000 --- a/gnu/usr.bin/cvs/contrib/easy-import.pl +++ /dev/null @@ -1,403 +0,0 @@ -#! xPERL_PATHx -# -# Support for importing a source collection into CVS. -# Tries to prevent the user from the most common pitfalls (like creating -# new top-level repositories or second-level areas accidentally), and -# cares to do some of the `dirty' work like maintaining the modules -# database accordingly. -# -# Written by Jörg Wunsch, 95/03/07, and placed in the public domain. -# -# $FreeBSD$ - -require "complete.pl"; -require "getopts.pl"; - - -sub scan_opts -{ - local($status); - - $status = &Getopts("nv"); - - $dont_do_it = "-n" if $opt_n; - if($opt_v) { - print STDERR '$FreeBSD$' . "\n"; # 'emacs kludge - exit 0; - } - die "usage: $0 [-v] [-n] [moduledir]\n" . - " -n: don't do any commit, show only\n" . - " -v: show program version\n" - unless $status && $#ARGV <= 0; - - if($#ARGV == 0) { - $moduledir = $ARGV[0]; - shift; - } -} - -sub lsdir -{ - # find all subdirectories under @_ - # ignore all CVS entries, dot entries, and non-directories - - local($base) = @_; - local(@ls, @rv, $fname); - - opendir(DIR, $base) || die "Cannot find dir $base.\n"; - - @ls = readdir(DIR); - closedir(DIR); - - @rv = (); - - foreach $fname (@ls) { - next if $fname =~ /^CVS/ || $fname eq "Attic" - || $fname =~ /^\./ || ! -d "$base/$fname"; - @rv = (@rv, $fname); - } - - return sort(@rv); -} - - -sub contains -{ - # look if the first parameter is contained in the list following it - local($item, @list) = @_; - local($found, $i); - - $found = 0; - foreach $i (@list) { - return 1 if $i eq $item; - } - return 0; -} - - - -sub term_init -{ - # first, get some terminal attributes - - # try bold mode first - $so = `tput md`; $se = `tput me`; - - # if no bold mode available, use standout mode - if ($so eq "") { - $so = `tput so`; $se = `tput se`; - } - - # try if we can underscore - $us = `tput us`; $ue = `tput ue`; - # if we don't have it available, or same as bold/standout, disable it - if ($us eq "" || $us eq $so) { - $us = $ue = ""; - } - - # look how many columns we've got - if($ENV{'COLUMNS'} ne "") { - $columns = $ENV{'COLUMNS'}; - } elsif(-t STDIN) { # if we operate on a terminal... - local($word, $tmp); - - open(STTY, "stty -a|"); - $_ = ; # try getting the tty win structure value - close(STTY); - chop; - $columns = 0; - foreach $word (split) { - $columns = $tmp if $word eq "columns;"; # the number preceding - $tmp = $word; - } - } else { - $columns = 80; - } - # sanity - $columns = 80 unless $columns >= 5; -} - - -sub list -{ - # pretty-print a list - # imports: global variable $columns - local(@items) = @_; - local($longest,$i,$item,$cols,$width); - - # find the longest item - $longest = 0; - foreach $item (@items) { - $i = length($item); - $longest = $i if $longest < $i; - } - $width = $longest + 1; - $cols = int($columns / $width); - - $i = 0; - foreach $item (@items) { - print $item; - if(++$i == $cols) { - $i = 0; print "\n"; - } else { - print ' ' x ($width - length($item)); - } - } - print "\n" unless $i == 0; -} - -sub cvs_init -{ - # get the CVS repository(s) - - die "You need to have the \$CVSROOT variable set.\n" - unless $ENV{'CVSROOT'} ne ""; - - # get the list of available repositories - $cvsroot = $ENV{'CVSROOT'}; - $cvsroot = (split(/:/, $cvsroot, 2))[1] if $cvsroot =~ /:/; - @reps = &lsdir($cvsroot); -} - - -sub lsmodules -{ - # list all known CVS modules - local(%rv, $mname, $mpath, $_); - - %rv = (); - - open(CVS, "cvs co -c|"); - while($_ = ) { - chop; - ($mname,$mpath) = split; - next if $mname eq ""; - $rv{$mname} = $mpath; - } - close(CVS); - - return %rv; -} - - -sub checktag -{ - # check a given string for tag rules - local($s, $name) = @_; - local($regexp); - - if($name eq "vendor") { $regexp = '^[A-Z][A-Z0-9_]*$'; } - elsif($name eq "release") { $regexp = '^[a-z][a-z0-9_]*$'; } - else { - print STDERR "Internal error: unknown tag name $name\n"; - exit(2); - } - - if($s !~ /$regexp/) { - print "\a${us}Valid $name tags must match the regexp " . - "$regexp.${ue}\n"; - return 0; - } - if($s =~ /^RELENG/) { - print "\a${us}Tags must not start with the word \"RELENG\".${ue}\n"; - return 0; - } - - return 1; -} - - -&scan_opts; -&term_init; -&cvs_init; - -if(! $moduledir) { - @dirs = &lsdir("."); - print "${so}Import from which directory?${se}\n"; - @dirs = (@dirs, "."); - &list(@dirs); - $moduledir = &Complete("Which? [.]: ", @dirs); - $moduledir = "." unless $moduledir ne ""; -} - -chdir $moduledir || die "Cannot chdir to $moduledir\n"; - -print "${so}Available repositories:${se}\n"; -&list(@reps); - -# the following kludge prevents the Complete package from starting -# over with the string just selected; Complete should better provide -# some reinitialize method -$Complete'return = ""; $Complete'r = 0; - -$selected = - &Complete("Enter repository (=complete, ^D=show): ", - @reps); - -die "\aYou cannot create new repositories with this script.\n" - unless &contains($selected, @reps); - -$rep = $selected; - -print "\n${so}Selected repository:${se} ${us}$rep${ue}\n"; - - -@areas = &lsdir("$cvsroot/$rep"); - -print "${so}Existent areas in this repository:${se}\n"; -&list(@areas); - -$Complete'return = ""; $Complete'r = 0; - -$selected = - &Complete("Enter area name (=complete, ^D=show): ", - @areas); - -print "\a${us}Warning: this will create a new area.${ue}\n" - unless &contains($selected, @areas); - -$area = "$rep/$selected"; - -print "\n${so}[Working on:${se} ${us}$area${ue}${so}]${se}\n"; - -%cvsmods = &lsmodules(); - -for(;;) { - $| = 1; - print "${so}Gimme the module name:${se} "; - $| = 0; - $modname = <>; - chop $modname; - if ($modname eq "") { - print "\a${us}You cannot use an empty module name.${ue}\n"; - next; - } - last if !$cvsmods{$modname}; - print "\a${us}This module name does already exist; do you intend to\n" . - "perform a vendor-branch import to the existing sources?${ue}: "; - $rep = <>; - if ($rep =~ /\s*[yY]/) { - ($area,$modpath) = split(/\//,$cvsmods{$modname},2); - $branchimport = 1; - last; - } - print "${us}Choose another name.${ue}\n"; -} - - -if(!$branchimport) { - for(;;) { - $| = 1; - print "${so}Enter the module path:${se} $area/"; - $| = 0; - $modpath = <>; - chop $modpath; - if ($modpath eq "") { - print "\a${us}You cannot use an empty module path.${ue}\n"; - next; - } - last if ! -d "$cvsroot/$area/$modpath"; - print "\a${us}This module path does already exist; " . - "choose another one.${ue}\n"; - } - - - @newdirs = (); - $dir1 = "$cvsroot/$area"; - $dir2 = "$area"; - - @newdirs = (@newdirs, "$dir2") if ! -d $dir1; - - foreach $ele (split(/\//, $modpath)) { - $dir1 = "$dir1/$ele"; - $dir2 = "$dir2/$ele"; - @newdirs = (@newdirs, "$dir2") if ! -d $dir1; - } - - print "${so}You're going to create the following new directories:${se}\n"; - - &list(@newdirs); -} - -for(;;) { - $| = 1; - print "${so}Enter a \`vendor\' tag (e. g. the authors ID):${se} "; - $| = 0; - $vtag = <>; - chop $vtag; - last if &checktag($vtag, "vendor"); -} - -for(;;) { - $| = 1; - print "${so}Enter a \`release\' tag (e. g. the version #):${se} "; - $| = 0; - $rtag = <>; - chop $rtag; - last if &checktag($rtag, "release"); -} - - -$| = 1; -print "${so}This is your last chance to interrupt, " . - "hit to go on:${se} "; -$| = 0; -<>; - -if (!$branchimport) { - $mod = ""; - foreach $tmp (sort(keys(%cvsmods))) { - if($tmp gt $modname) { - $mod = $tmp; - last; - } - } - if($mod eq "") { - # we are going to append our module - $cmd = "\$\na\n"; - } else { - # we can insert it - $cmd = "/^${mod}[ \t]/\ni\n"; - } - - print "${so}Checking out the modules database...${se}\n"; - system("cvs co modules") && die "${us}failed.\n${ue}"; - - print "${so}Inserting new module...${se}\n"; - open(ED, "|ed modules/modules") || die "${us}Cannot start ed${ue}\n"; - print(ED "${cmd}${modname} " . ' ' x (15 - length($modname)) . - "$area/${modpath}\n.\nw\nq\n"); - close(ED); - - print "${so}Commiting new modules database...${se}\n"; - system("cvs $dont_do_it commit -m \" " . - "${modname} --> $area/${modpath}\" modules") - && die "Commit failed\n"; - - # we always release "modules" to prevent duplicate - system("cvs -Q release -d modules"); -} - -print "${so}Importing source. Enter a commit message in the editor.${se}\n"; - -system("cvs $dont_do_it import $area/$modpath $vtag $rtag"); - -print "${so}You are done now. Go to a different directory, perform a${se}\n". - "${us}cvs co ${modname}${ue} ${so}command, and see if your new module" . - " builds ok.${se}\n"; - -print "\nPlease don't forget to edit the parent Makefile to add what you\n". - "just imported.\n"; - -if($dont_do_it) { -print < -.include "${.CURDIR}/../Makefile.inc" - -.PATH: ${CVSDIR}/src -.PATH: ${CVSDIR}/lib -.PATH: ${CVSDIR}/man -.PATH: ${CVSDIR} - -PROG= cvs -MAN= cvs.1 cvs.5 - -SRCS= add.c admin.c annotate.c buffer.c \ - checkin.c checkout.c classify.c client.c \ - commit.c create_adm.c cvsrc.c diff.c edit.c entries.c error.c \ - expand_path.c fileattr.c filesubr.c find_names.c \ - hardlink.c hash.c history.c \ - ignore.c import.c lock.c log.c login.c logmsg.c main.c mkmodules.c \ - modules.c myndbm.c no_diff.c parseinfo.c patch.c prepend_args.c \ - rcs.c rcscmds.c \ - recurse.c release.c remove.c repos.c root.c run.c scramble.c \ - server.c stack.c status.c subr.c \ - tag.c update.c vers_ts.c version.c watch.c \ - wrapper.c zlib.c - -# gnu must be before lib to pick correct regex.h -CFLAGS+= -I${.CURDIR} -I../lib -DHAVE_CONFIG_H -I${CVSDIR}/src \ - -I${DESTDIR}/usr/include/gnu \ - -I${CVSDIR}/lib -I${CVSDIR}/diff -I. - -DPADD= ${LIBCVS} ${LIBDIFF} ${LIBGNUREGEX} ${LIBMD} ${LIBCRYPT} ${LIBZ} -LDADD= ${LIBCVS} ${LIBDIFF} -lgnuregex -lmd -lcrypt -lz - -.if ${MK_KERBEROS_SUPPORT} != "no" -CFLAGS+= -DHAVE_GSSAPI -DENCRYPTION -LDADD+= -lgssapi -lkrb5 -lhx509 -lasn1 -lcrypto -lroken -lcrypt -lcom_err -DPADD+= ${LIBGSSAPI} ${LIBKRB5} ${LIBHX509} ${LIBASN1} ${LIBCRYPTO} ${LIBROKEN} -DPADD+= ${LIBCRYPT} ${LIBCOM_ERR} -.endif - -# -# Regression test support -# -CLEANDIRS+=cvs-sanity -.ifmake regress -USERID!=id -u -regress: - mkdir -p ${.OBJDIR}/cvs-sanity/tmp ${.OBJDIR}/cvs-sanity/work -.if ${USERID} == "0" - chown -R nobody ${.OBJDIR}/cvs-sanity - (TESTDIR=`sh -c 'cd ${.OBJDIR}/cvs-sanity/tmp && /bin/pwd'`;\ - export TESTDIR;\ - cd ${.OBJDIR}/cvs-sanity/work;\ - su -m nobody -c "sh ${CVSDIR}/src/sanity.sh ${.OBJDIR}/cvs") -.else - (TESTDIR=`sh -c 'cd ${.OBJDIR}/cvs-sanity/tmp && /bin/pwd'`;\ - export TESTDIR;\ - cd ${.OBJDIR}/cvs-sanity/work;\ - sh ${CVSDIR}/src/sanity.sh ${.OBJDIR}/cvs) -.endif -.endif - -.include diff --git a/gnu/usr.bin/cvs/cvs/prepend_args.c b/gnu/usr.bin/cvs/cvs/prepend_args.c deleted file mode 100644 index 12322ce..0000000 --- a/gnu/usr.bin/cvs/cvs/prepend_args.c +++ /dev/null @@ -1,86 +0,0 @@ -/* prepend_args.c - utilility programs for manpiulating argv[] - Copyright (C) 1999 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. */ - -/* $FreeBSD$ */ - - -#ifdef HAVE_CONFIG_H -# include -#endif -#include "cvs.h" -#include "prepend_args.h" - - -/* Find the white-space-separated options specified by OPTIONS, and - using BUF to store copies of these options, set ARGV[0], ARGV[1], - etc. to the option copies. Return the number N of options found. - Do not set ARGV[N] to NULL. If ARGV is NULL, do not store ARGV[0] - etc. Backslash can be used to escape whitespace (and backslashes). */ -static int -prepend_args (options, buf, argv) - char const *options; - char *buf; - char **argv; -{ - char const *o = options; - char *b = buf; - int n = 0; - - for (;;) - { - while (isspace ((unsigned char) *o)) - o++; - if (!*o) - return n; - if (argv) - argv[n] = b; - n++; - - do - if ((*b++ = *o++) == '\\' && *o) - b[-1] = *o++; - while (*o && ! isspace ((unsigned char) *o)); - - *b++ = '\0'; - } -} - -/* Prepend the whitespace-separated options in OPTIONS to the argument - vector of a main program with argument count *PARGC and argument - vector *PARGV. */ -void -prepend_default_options (options, pargc, pargv) - char const *options; - int *pargc; - char ***pargv; -{ - if (options) - { - char *buf = xmalloc (strlen (options) + 1); - int prepended = prepend_args (options, buf, (char **) NULL); - int argc = *pargc; - char * const *argv = *pargv; - char **pp = (char **) xmalloc ((prepended + argc + 1) * sizeof *pp); - *pargc = prepended + argc; - *pargv = pp; - *pp++ = *argv++; - pp += prepend_args (options, buf, pp); - while ((*pp++ = *argv++)) - continue; - } -} diff --git a/gnu/usr.bin/cvs/cvs/prepend_args.h b/gnu/usr.bin/cvs/cvs/prepend_args.h deleted file mode 100644 index 6708442..0000000 --- a/gnu/usr.bin/cvs/cvs/prepend_args.h +++ /dev/null @@ -1,26 +0,0 @@ -/* prepend_args.h - utilility programs for manpiulating argv[] - Copyright (C) 1999 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. */ - -/* $FreeBSD$ */ - -/* This code, taken from GNU Grep, originally used the "PARAM" macro, as the - current GNU coding standards requires. Older GNU code used the "PROTO" - macro, before the GNU coding standards replaced it. We use the older - form here to keep from having to include another file in cvs/src/main.c. */ - -void prepend_default_options PROTO ((char const *, int *, char ***)); diff --git a/gnu/usr.bin/cvs/cvsbug/Makefile b/gnu/usr.bin/cvs/cvsbug/Makefile deleted file mode 100644 index ad07f39..0000000 --- a/gnu/usr.bin/cvs/cvsbug/Makefile +++ /dev/null @@ -1,25 +0,0 @@ -# $FreeBSD$ - -.include "${.CURDIR}/../Makefile.inc" - -.PATH: ${CVSDIR}/src -.PATH: ${CVSDIR}/man -.PATH: ${CVSDIR} - -SCRIPTS= cvsbug -MAN= cvsbug.8 - -CLEANFILES+= cvsbug - -cvsbug: cvsbug.in - version=`sed < ${CVSDIR}/configure \ - -e '/^[ ]*VERSION=/!d' -e 's/.*=["'\'']\{0,1\}\([^"'\'']*\)["'\'']\{0,1\}/\1/' -e q`; \ - sed -e "s,@VERSION@,$${version}-FreeBSD,g" \ - -e "s,@MKTEMP@,/usr/bin/mktemp,g" \ - -e "s,@PACKAGE_BUGREPORT@,bug-cvs@gnu.org,g" \ - -e "s,@SENDMAIL@,/usr/sbin/sendmail,g" \ - -e "s,@MKTEMP_FUNCTION@,," \ - -e "s,@MKTEMP_SH_FUNCTION@,," \ - ${.ALLSRC} > ${.TARGET} - -.include diff --git a/gnu/usr.bin/cvs/doc/Makefile b/gnu/usr.bin/cvs/doc/Makefile deleted file mode 100644 index ade0e8b..0000000 --- a/gnu/usr.bin/cvs/doc/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -# $FreeBSD$ - -.include "${.CURDIR}/../Makefile.inc" - -SRCDIR= ${CVSDIR}/doc - -INFO= cvs cvsclient -INFOSECTION= "Programming & development tools." -INFOENTRY_cvs= "* CVS: (cvs). CVS Reference Manual." -INFOENTRY_cvsclient= "* CVS-CLIENT: (cvsclient). CVS client/server Reference Manual." - -.include diff --git a/gnu/usr.bin/cvs/lib/Makefile b/gnu/usr.bin/cvs/lib/Makefile deleted file mode 100644 index 54a727d..0000000 --- a/gnu/usr.bin/cvs/lib/Makefile +++ /dev/null @@ -1,37 +0,0 @@ -# $FreeBSD$ - -.include "${.CURDIR}/../Makefile.inc" - -.PATH: ${CVSDIR}/src -.PATH: ${CVSDIR}/lib -.PATH: ${CVSDIR}/man - -LIB= cvs -INTERNALLIB= - -# gnu must be before lib to pick correct regex.h -CFLAGS+= -I. -I${CVSDIR}/src -I${DESTDIR}/usr/include/gnu \ - -I${CVSDIR}/lib -CFLAGS+= -DHAVE_CONFIG_H -YFLAGS= -CLEANFILES+= config.h - -CVS_UMASK_DFLT?= 002 -CVS_ADMIN_GROUP?= cvsadmin -CVS_TMPDIR_DFLT?= /tmp - -SRCS= config.h argmatch.c getdate.y getline.c \ - getopt.c getopt1.c savecwd.c \ - sighandle.c stripslash.c \ - xgetwd.c yesno.c - -config.h: config.h.proto ${CVSDIR}/configure - version=`sed < ${CVSDIR}/configure \ - -e '/^[ ]*VERSION=/!d' -e 's/.*=["'\'']\{0,1\}\([^"'\'']*\)["'\'']\{0,1\}/\1/' -e q`; \ - sed -e "s,@VERSION@,$${version}-20080310-FreeBSD,g" \ - -e "s,@UMASK_DFLT@,${CVS_UMASK_DFLT},g" \ - -e "s,@TMPDIR_DFLT@,${CVS_TMPDIR_DFLT},g" \ - -e "s,@CVS_ADMIN_GROUP@,${CVS_ADMIN_GROUP},g" \ - ${.ALLSRC:M*config.h.proto} > ${.TARGET} - -.include diff --git a/gnu/usr.bin/cvs/lib/config.h.proto b/gnu/usr.bin/cvs/lib/config.h.proto deleted file mode 100644 index 30a4f00..0000000 --- a/gnu/usr.bin/cvs/lib/config.h.proto +++ /dev/null @@ -1,532 +0,0 @@ -/* $FreeBSD$ */ - -/* config.h. Generated from config.h.in by configure. */ -/* config.h.in. Generated from configure.in by autoheader. */ - -/* Enable AUTH_CLIENT_SUPPORT to enable pserver as a remote access method in - the CVS client (default) */ -#define AUTH_CLIENT_SUPPORT 1 - -/* Define if you want to use the password authenticated server. */ -#define AUTH_SERVER_SUPPORT 1 - -/* Define if you want CVS to be able to be a remote repository client. */ -#define CLIENT_SUPPORT 1 - -/* Define to 1 if the `closedir' function returns void instead of `int'. */ -/* #undef CLOSEDIR_VOID */ - -/* The CVS admin command is restricted to the members of the group - CVS_ADMIN_GROUP. If this group does not exist, all users are allowed to run - CVS admin. To disable the CVS admin command for all users, create an empty - CVS_ADMIN_GROUP by running configure with the --with-cvs-admin-group= - option. To disable access control for CVS admin, run configure with the - --without-cvs-admin-group option in order to comment out the define below. - */ -#define CVS_ADMIN_GROUP "@CVS_ADMIN_GROUP@" - -/* When committing a permanent change, CVS and RCS make a log entry of who - committed the change. If you are committing the change logged in as "root" - (not under "su" or other root-priv giving program), CVS/RCS cannot - determine who is actually making the change. As such, by default, CVS - prohibits changes committed by users logged in as "root". You can disable - checking by passing the "--enable-rootcommit" option to configure or by - commenting out the lines below. */ -#define CVS_BADROOT 1 - -/* The default editor to use, if one does not specify the "-e" option to cvs, - or does not have an EDITOR environment variable. If this is not set to an - absolute path to an executable, use the shell to find where the editor - actually is. This allows sites with /usr/bin/vi or /usr/ucb/vi to work - equally well (assuming that their PATH is reasonable). */ -#ifndef EDITOR_DFLT -#define EDITOR_DFLT "vi" -#endif - -/* Define to enable encryption support. */ -/* #undef ENCRYPTION */ - -/* Define if this executable will be running on case insensitive file systems. - In the client case, this means that it will request that the server pretend - to be case insensitive if it isn't already. */ -/* #undef FILENAMES_CASE_INSENSITIVE */ - -/* When committing or importing files, you must enter a log message. Normally, - you can do this either via the -m flag on the command line, the -F flag on - the command line, or an editor will be started for you. If you like to use - logging templates (the rcsinfo file within the $CVSROOT/CVSROOT directory), - you might want to force people to use the editor even if they specify a - message with -m or -F. Enabling FORCE_USE_EDITOR will cause the -m or -F - message to be appended to the temp file when the editor is started. */ -/* #undef FORCE_USE_EDITOR */ - -/* Define to an alternative value if GSS_C_NT_HOSTBASED_SERVICE isn't defined - in the gssapi.h header file. MIT Kerberos 1.2.1 requires this. Only - relevant when using GSSAPI. */ -/* #undef GSS_C_NT_HOSTBASED_SERVICE */ - -/* Define if you have the connect function. */ -#define HAVE_CONNECT 1 - -/* Define if you have the crypt function. */ -#define HAVE_CRYPT 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_DIRECT_H */ - -/* Define to 1 if you have the header file, and it defines `DIR'. - */ -#define HAVE_DIRENT_H 1 - -/* Define to 1 if you have the `dup2' function. */ -#define HAVE_DUP2 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_ERRNO_H 1 - -/* Define to 1 if you have the `fchdir' function. */ -#define HAVE_FCHDIR 1 - -/* Define to 1 if you have the `fchmod' function. */ -#define HAVE_FCHMOD 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_FCNTL_H 1 - -/* Define to 1 if your system has a working POSIX `fnmatch' function. */ -#define HAVE_FNMATCH 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_FNMATCH_H 1 - -/* Define to 1 if you have the `fork' function. */ -#define HAVE_FORK 1 - -/* Define to 1 if you have the `fsync' function. */ -#define HAVE_FSYNC 1 - -/* Define to 1 if you have the `ftime' function. */ -/* #undef HAVE_FTIME */ - -/* Define to 1 if you have the `ftruncate' function. */ -#define HAVE_FTRUNCATE 1 - -/* Define to 1 if you have the `geteuid' function. */ -#define HAVE_GETEUID 1 - -/* Define to 1 if you have the `getgroups' function. */ -#define HAVE_GETGROUPS 1 - -/* Define to 1 if you have the `gethostname' function. */ -#define HAVE_GETHOSTNAME 1 - -/* Define to 1 if you have the `getopt' function. */ -#define HAVE_GETOPT 1 - -/* Define to 1 if you have the `getpagesize' function. */ -#define HAVE_GETPAGESIZE 1 - -/* Define to 1 if you have the `getpassphrase' function. */ -/* #undef HAVE_GETPASSPHRASE */ - -/* Define to 1 if you have the `getpassphrase' function. */ -/* #undef HAVE_GETPASSPHRASE */ - -/* Define if you have the getspnam function. */ -/* #undef HAVE_GETSPNAM */ - -/* Define to 1 if you have the `gettimeofday' function. */ -#define HAVE_GETTIMEOFDAY 1 - -/* Define if you have GSSAPI with Kerberos version 5 available. */ -/* #undef HAVE_GSSAPI */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_GSSAPI_GSSAPI_GENERIC_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_GSSAPI_GSSAPI_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_GSSAPI_H */ - -/* Define to 1 if you have the `initgroups' function. */ -#define HAVE_INITGROUPS 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_INTTYPES_H 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_IO_H */ - -/* Define if you have MIT Kerberos version 4 available. */ -/* #undef HAVE_KERBEROS */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_KRB5_H */ - -/* Define to 1 if you have the `krb_get_err_text' function. */ -/* #undef HAVE_KRB_GET_ERR_TEXT */ - -/* Define to 1 if you have the `krb' library (-lkrb). */ -/* #undef HAVE_LIBKRB */ - -/* Define to 1 if you have the `krb4' library (-lkrb4). */ -/* #undef HAVE_LIBKRB4 */ - -/* Define to 1 if you have the `nsl' library (-lnsl). */ -/* #undef HAVE_LIBNSL */ - -/* Define to 1 if you have the header file. */ -#define HAVE_LIMITS_H 1 - -/* Define to 1 if you have the `login' function. */ -/* #undef HAVE_LOGIN */ - -/* Define to 1 if you have the `logout' function. */ -/* #undef HAVE_LOGOUT */ - -/* Define to 1 if you support file names longer than 14 characters. */ -#define HAVE_LONG_FILE_NAMES 1 - -/* Define if you have memchr (always for CVS). */ -#define HAVE_MEMCHR 1 - -/* Define to 1 if you have the `memmove' function. */ -#define HAVE_MEMMOVE 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_MEMORY_H 1 - -/* Define to 1 if you have the `mkdir' function. */ -#define HAVE_MKDIR 1 - -/* Define to 1 if you have the `mknod' function. */ -#define HAVE_MKNOD 1 - -/* Define to 1 if you have the `mkstemp' function. */ -#define HAVE_MKSTEMP 1 - -/* Define to 1 if you have the `mktemp' function. */ -#define HAVE_MKTEMP 1 - -/* Define to 1 if you have a working `mmap' system call. */ -#define HAVE_MMAP 1 - -/* Define to 1 if you have the `nanosleep' function. */ -#define HAVE_NANOSLEEP 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_NDBM_H 1 - -/* Define to 1 if you have the header file, and it defines `DIR'. */ -/* #undef HAVE_NDIR_H */ - -/* Define to 1 if you have the `putenv' function. */ -#define HAVE_PUTENV 1 - -/* Define to 1 if you have the `readlink' function. */ -#define HAVE_READLINK 1 - -/* Define to 1 if you have the `regcomp' function. */ -#define HAVE_REGCOMP 1 - -/* Define to 1 if you have the `regerror' function. */ -#define HAVE_REGERROR 1 - -/* Define to 1 if you have the `regexec' function. */ -#define HAVE_REGEXEC 1 - -/* Define to 1 if you have the `regfree' function. */ -#define HAVE_REGFREE 1 - -/* Define to 1 if you have the `rename' function. */ -#define HAVE_RENAME 1 - -/* Define to 1 if you have the `select' function. */ -/* #undef HAVE_SELECT */ - -/* Define if the diff library should use setmode for binary files. */ -/* #undef HAVE_SETMODE */ - -/* Define to 1 if you have the `sigaction' function. */ -#define HAVE_SIGACTION 1 - -/* Define to 1 if you have the `sigblock' function. */ -#define HAVE_SIGBLOCK 1 - -/* Define to 1 if you have the `sigprocmask' function. */ -#define HAVE_SIGPROCMASK 1 - -/* Define to 1 if you have the `sigsetmask' function. */ -#define HAVE_SIGSETMASK 1 - -/* Define to 1 if you have the `sigvec' function. */ -#define HAVE_SIGVEC 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STDINT_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STDLIB_H 1 - -/* Define if you have strchr (always for CVS). */ -#define HAVE_STRCHR 1 - -/* Define to 1 if you have the `strerror' function. */ -#define HAVE_STRERROR 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STRINGS_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STRING_H 1 - -/* Define to 1 if you have the `strstr' function. */ -#define HAVE_STRSTR 1 - -/* Define to 1 if you have the `strtoul' function. */ -#define HAVE_STRTOUL 1 - -/* Define to 1 if `st_blksize' is member of `struct stat'. */ -#define HAVE_STRUCT_STAT_ST_BLKSIZE 1 - -/* Define to 1 if `st_rdev' is member of `struct stat'. */ -#define HAVE_STRUCT_STAT_ST_RDEV 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYSLOG_H 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_SYS_BSDTYPES_H */ - -/* Define to 1 if you have the header file, and it defines `DIR'. - */ -/* #undef HAVE_SYS_DIR_H */ - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_FILE_H 1 - -/* Define to 1 if you have the header file, and it defines `DIR'. - */ -/* #undef HAVE_SYS_NDIR_H */ - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_PARAM_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_RESOURCE_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_SELECT_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_STAT_H 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_SYS_TIMEB_H */ - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_TIME_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_TYPES_H 1 - -/* Define to 1 if you have that is POSIX.1 compatible. */ -#define HAVE_SYS_WAIT_H 1 - -/* Define to 1 if you have the `tempnam' function. */ -#define HAVE_TEMPNAM 1 - -/* Define to 1 if you have the `timezone' function. */ -#define HAVE_TIMEZONE 1 - -/* Define to 1 if you have the `tzset' function. */ -#define HAVE_TZSET 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_UNISTD_H 1 - -/* Define to 1 if you have the `usleep' function. */ -/* #undef HAVE_USLEEP */ - -/* Define to 1 if you have the header file. */ -#define HAVE_UTIME_H 1 - -/* Define to 1 if `utime(file, NULL)' sets file's timestamp to the present. */ -#define HAVE_UTIME_NULL 1 - -/* Define to 1 if you have the `valloc' function. */ -#define HAVE_VALLOC 1 - -/* Define to 1 if you have the `vfork' function. */ -#define HAVE_VFORK 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_VFORK_H */ - -/* Define to 1 if you have the `vprintf' function. */ -#define HAVE_VPRINTF 1 - -/* Define to 1 if you have the `wait3' function. */ -#define HAVE_WAIT3 1 - -/* Define to 1 if you have the `waitpid' function. */ -#define HAVE_WAITPID 1 - -/* Define to 1 if `fork' works. */ -#define HAVE_WORKING_FORK 1 - -/* Define to 1 if `vfork' works. */ -#define HAVE_WORKING_VFORK 1 - -/* By default, CVS stores its modules and other such items in flat text files - (MY_NDBM enables this). Turning off MY_NDBM causes CVS to look for a - system-supplied ndbm database library and use it instead. That may speed - things up, but the default setting generally works fine too. */ -#define MY_NDBM 1 - -/* Define to 1 if your C compiler doesn't accept -c and -o together. */ -/* #undef NO_MINUS_C_MINUS_O */ - -/* Define to the address where bug reports for this package should be sent. */ -#define PACKAGE_BUGREPORT "bug-cvs@nongnu.org" - -/* Define to the full name of this package. */ -#define PACKAGE_NAME "Concurrent Versions System (CVS)" - -/* Define to the full name and version of this package. */ -#define PACKAGE_STRING "Concurrent Versions System (CVS) @VERSION@" - -/* Define to the one symbol short name of this package. */ -#define PACKAGE_TARNAME "cvs" - -/* Define to the version of this package. */ -#define PACKAGE_VERSION "@VERSION@" - -/* Path to the pr utility */ -#define PR_PROGRAM "/usr/bin/pr" - -/* Define to force lib/regex.c to use malloc instead of alloca. */ -#define REGEX_MALLOC 1 - -/* Define as the return type of signal handlers (`int' or `void'). */ -#define RETSIGTYPE void - -/* The default remote shell to use, if one does not specify the CVS_RSH - environment variable. */ -/* FreeBSD.org default is to use ssh. */ -#define RSH_DFLT "ssh" - -/* If you are working with a large remote repository and a 'cvs checkout' is - swamping your network and memory, define these to enable flow control. You - will end up with even less probability of a consistent checkout (see - Concurrency in cvs.texinfo), but CVS doesn't try to guarantee that anyway. - The master server process will monitor how far it is getting behind, if it - reaches the high water mark, it will signal the child process to stop - generating data when convenient (ie: no locks are held, currently at the - beginning of a new directory). Once the buffer has drained sufficiently to - reach the low water mark, it will be signalled to start again. */ -#define SERVER_FLOWCONTROL 1 - -/* The high water mark in bytes for server flow control. Required if - SERVER_FLOWCONTROL is defined, and useless otherwise. */ -#define SERVER_HI_WATER (2 * 1024 * 1024) - -/* The low water mark in bytes for server flow control. Required if - SERVER_FLOWCONTROL is defined, and useless otherwise. */ -#define SERVER_LO_WATER (1 * 1024 * 1024) - -/* Define if you want CVS to be able to serve repositories to remote clients. - */ -#define SERVER_SUPPORT 1 - -/* Define as the maximum value of type 'size_t', if the system doesn't define - it. */ -/* #undef SIZE_MAX */ - -/* The default remote shell to use, if one does not specify the CVS_SSH - environment variable. */ -#define SSH_DFLT "ssh" - -/* Define to 1 if the `S_IS*' macros in do not work properly. */ -/* #undef STAT_MACROS_BROKEN */ - -/* Define to 1 if you have the ANSI C header files. */ -#define STDC_HEADERS 1 - -/* Define to 1 if you can safely include both and . */ -#define TIME_WITH_SYS_TIME 1 - -/* Directory used for storing temporary files, if not overridden by - environment variables or the -T global option. There should be little need - to change this (-T is a better mechanism if you need to use a different - directory for temporary files). */ -#define TMPDIR_DFLT "@TMPDIR_DFLT@" - -/* The default umask to use when creating or otherwise setting file or - directory permissions in the repository. Must be a value in the range of 0 - through 0777. For example, a value of 002 allows group rwx access and world - rx access; a value of 007 allows group rwx access but no world access. This - value is overridden by the value of the CVSUMASK environment variable, - which is interpreted as an octal number. */ -#define UMASK_DFLT @UMASK_DFLT@ - -/* Define if setmode is required when writing binary data to stdout. */ -/* #undef USE_SETMODE_STDOUT */ - -/* Define if utime requires write access to the file (true on Windows, but not - Unix). */ -/* #undef UTIME_EXPECTS_WRITABLE */ - -/* Define to 1 if on AIX 3. - System headers sometimes define this. - We just want to avoid a redefinition error message. */ -#ifndef _ALL_SOURCE -/* # undef _ALL_SOURCE */ -#endif - -/* Define to 1 if on MINIX. */ -/* #undef _MINIX */ - -/* Define to 2 if the system does not provide POSIX.1 features except with - this defined. */ -/* #undef _POSIX_1_SOURCE */ - -/* Define to 1 if you need to in order for `stat' and other things to work. */ -/* #undef _POSIX_SOURCE */ - -/* Define to force lib/regex.c to define re_comp et al. */ -#define _REGEX_RE_COMP 1 - -/* Define to empty if `const' does not conform to ANSI C. */ -/* #undef const */ - -/* We want to always use the GNULIB version of getpass which we have in lib, - so define getpass to something that won't conflict with any existing system - declarations. */ -/* #define getpass cvs_getpass */ - -/* Define to `int' if doesn't define. */ -/* #undef gid_t */ - -/* Define to `__inline__' or `__inline' if that's what the C compiler - calls it, or to nothing if 'inline' is not supported under any name. */ -#ifndef __cplusplus -/* #undef inline */ -#endif - -/* Define to `int' if does not define. */ -/* #undef mode_t */ - -/* Define to `int' if does not define. */ -/* #undef pid_t */ - -/* Define to `unsigned int' if does not define. */ -/* #undef size_t */ - -/* Define to `int' if doesn't define. */ -/* #undef uid_t */ - -/* Define as `fork' if `vfork' does not work. */ -/* #undef vfork */ diff --git a/gnu/usr.bin/cvs/libdiff/Makefile b/gnu/usr.bin/cvs/libdiff/Makefile deleted file mode 100644 index 7fd67a4..0000000 --- a/gnu/usr.bin/cvs/libdiff/Makefile +++ /dev/null @@ -1,17 +0,0 @@ -# $FreeBSD$ - -.include "${.CURDIR}/../Makefile.inc" - -.PATH: ${CVSDIR}/diff - -LIB= diff -INTERNALLIB= - -# gnu must be before lib to pick correct regex.h -CFLAGS+= -I../lib -I${DESTDIR}/usr/include/gnu \ - -I${CVSDIR}/lib -DHAVE_CONFIG_H - -SRCS = diff.c diff3.c analyze.c cmpbuf.c cmpbuf.h io.c context.c ed.c \ - normal.c ifdef.c util.c dir.c version.c diff.h side.c - -.include diff --git a/share/doc/psd/28.cvs/Makefile b/share/doc/psd/28.cvs/Makefile deleted file mode 100644 index a624732..0000000 --- a/share/doc/psd/28.cvs/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -# $FreeBSD$ - -VOLUME= psd/28.cvs -SRCS= cvs-paper.ms -MACROS= -ms -USE_PIC= -USE_TBL= -SRCDIR= ${.CURDIR}/../../../../contrib/cvs/doc - -.include diff --git a/share/doc/psd/Makefile b/share/doc/psd/Makefile index d50f05b..243ba99 100644 --- a/share/doc/psd/Makefile +++ b/share/doc/psd/Makefile @@ -35,7 +35,6 @@ SUBDIR+=22.rpcgen \ 24.xdr \ 25.xdrrfc \ 26.rpcrfc \ - 27.nfsrpc \ - 28.cvs + 27.nfsrpc .include diff --git a/share/mk/bsd.own.mk b/share/mk/bsd.own.mk index a9eee61..8fd5664 100644 --- a/share/mk/bsd.own.mk +++ b/share/mk/bsd.own.mk @@ -272,7 +272,6 @@ __DEFAULT_YES_OPTIONS = \ CROSS_COMPILER \ CRYPT \ CTM \ - CVS \ CXX \ DICT \ DYNAMICROOT \ diff --git a/tools/build/mk/OptionalObsoleteFiles.inc b/tools/build/mk/OptionalObsoleteFiles.inc index b4c47a4..b319324 100644 --- a/tools/build/mk/OptionalObsoleteFiles.inc +++ b/tools/build/mk/OptionalObsoleteFiles.inc @@ -889,35 +889,6 @@ OLD_FILES+=usr/share/man/man1/ctm_smail.1.gz OLD_FILES+=usr/share/man/man5/ctm.5.gz .endif -.if ${MK_CVS} == no -OLD_FILES+=usr/bin/cvs -OLD_FILES+=usr/bin/cvsbug -OLD_FILES+=usr/share/examples/cvs/contrib/README -OLD_FILES+=usr/share/examples/cvs/contrib/clmerge -OLD_FILES+=usr/share/examples/cvs/contrib/cln_hist -OLD_FILES+=usr/share/examples/cvs/contrib/commit_prep -OLD_FILES+=usr/share/examples/cvs/contrib/cvs2vendor -OLD_FILES+=usr/share/examples/cvs/contrib/cvs_acls -OLD_FILES+=usr/share/examples/cvs/contrib/cvscheck -OLD_FILES+=usr/share/examples/cvs/contrib/cvscheck.man -OLD_FILES+=usr/share/examples/cvs/contrib/cvshelp.man -OLD_FILES+=usr/share/examples/cvs/contrib/descend.man -OLD_FILES+=usr/share/examples/cvs/contrib/easy-import -OLD_FILES+=usr/share/examples/cvs/contrib/intro.doc -OLD_FILES+=usr/share/examples/cvs/contrib/log -OLD_FILES+=usr/share/examples/cvs/contrib/log_accum -OLD_FILES+=usr/share/examples/cvs/contrib/mfpipe -OLD_FILES+=usr/share/examples/cvs/contrib/rcs-to-cvs -OLD_FILES+=usr/share/examples/cvs/contrib/rcs2log -OLD_FILES+=usr/share/examples/cvs/contrib/rcslock -OLD_FILES+=usr/share/examples/cvs/contrib/sccs2rcs -OLD_FILES+=usr/share/info/cvs.info.gz -OLD_FILES+=usr/share/info/cvsclient.info.gz -OLD_FILES+=usr/share/man/man1/cvs.1.gz -OLD_FILES+=usr/share/man/man5/cvs.5.gz -OLD_FILES+=usr/share/man/man8/cvsbug.8.gz -.endif - # devd(8) and gperf(1) not listed here on purpose .if ${MK_CXX} == no OLD_FILES+=usr/bin/CC diff --git a/tools/build/options/WITHOUT_KERBEROS_SUPPORT b/tools/build/options/WITHOUT_KERBEROS_SUPPORT index a724fbf..e8dd495 100644 --- a/tools/build/options/WITHOUT_KERBEROS_SUPPORT +++ b/tools/build/options/WITHOUT_KERBEROS_SUPPORT @@ -1,6 +1,5 @@ .\" $FreeBSD$ Set to build some programs without Kerberos support, like -.Xr cvs 1 , .Xr ssh 1 , .Xr telnet 1 , .Xr sshd 8 , diff --git a/tools/tools/nanobsd/gateworks/common b/tools/tools/nanobsd/gateworks/common index c23a2bf..182bfbd 100644 --- a/tools/tools/nanobsd/gateworks/common +++ b/tools/tools/nanobsd/gateworks/common @@ -113,7 +113,6 @@ WITHOUT_BSNMP=true WITHOUT_CALENDAR=true WITHOUT_CDDL=true WITHOUT_CTM=true -WITHOUT_CVS=true WITHOUT_DICT=true WITHOUT_EXAMPLES=true WITHOUT_FLOPPY=true -- cgit v1.1