summaryrefslogtreecommitdiffstats
path: root/contrib/cvs
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/cvs')
-rw-r--r--contrib/cvs/FREEBSD-upgrade66
-rw-r--r--contrib/cvs/README.VMS159
-rw-r--r--contrib/cvs/contrib/log.pl2
-rw-r--r--contrib/cvs/contrib/sccs2rcs.csh2
-rw-r--r--contrib/cvs/diff/diagmeet.note71
-rw-r--r--contrib/cvs/doc/DIFFUTILS-2.7-BUG263
-rw-r--r--contrib/cvs/lib/getwd.c33
-rw-r--r--contrib/cvs/lib/strdup.c39
-rw-r--r--contrib/cvs/lib/strippath.c80
-rw-r--r--contrib/cvs/man/cvs.158
-rw-r--r--contrib/cvs/man/cvsbug.82
-rw-r--r--contrib/cvs/src/NOTES60
-rw-r--r--contrib/cvs/src/README-rm-add31
-rw-r--r--contrib/cvs/src/commit.c287
-rw-r--r--contrib/cvs/src/cvs.h39
-rw-r--r--contrib/cvs/src/diff.c36
-rw-r--r--contrib/cvs/src/filesubr.c57
-rw-r--r--contrib/cvs/src/import.c126
-rw-r--r--contrib/cvs/src/lock.c190
-rw-r--r--contrib/cvs/src/login.c30
-rw-r--r--contrib/cvs/src/logmsg.c73
-rw-r--r--contrib/cvs/src/main.c570
-rw-r--r--contrib/cvs/src/mkmodules.c149
-rw-r--r--contrib/cvs/src/prepend_args.c86
-rw-r--r--contrib/cvs/src/prepend_args.h26
-rw-r--r--contrib/cvs/src/rcs.c587
-rw-r--r--contrib/cvs/src/rcs.h5
-rw-r--r--contrib/cvs/src/rcscmds.c3
-rw-r--r--contrib/cvs/src/recurse.c347
-rw-r--r--contrib/cvs/src/server.c879
-rw-r--r--contrib/cvs/src/update.c122
-rw-r--r--contrib/cvs/tools/pcl-cvs/ChangeLog.woods383
-rw-r--r--contrib/cvs/tools/pcl-cvs/ToDo44
33 files changed, 1449 insertions, 3456 deletions
diff --git a/contrib/cvs/FREEBSD-upgrade b/contrib/cvs/FREEBSD-upgrade
new file mode 100644
index 0000000..9138048
--- /dev/null
+++ b/contrib/cvs/FREEBSD-upgrade
@@ -0,0 +1,66 @@
+$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;
+
+The following generated files were deleted:
+doc/*.ps
+doc/*.info*
+doc/*.aux*
+doc/CVSvn.texi
+lib/getdate.c
+tools/pcl-cvs/*.ps
+tools/pcl-cvs/*.aux
+tools/pcl-cvs/texinfo.tex
+cvsnt.*
+cvs.spec
+build.com
+src/build_src.com
+lib/build_lib.com
+diff/build_diff.com
+README.VMS
+
+The following non-freebsd-specific directories were deleted:
+macintosh
+os2
+emx
+windows-NT
+vms
+contrib/elib (this has a .tar.Z in it)
+zlib
+
+CVS has RCS Id, Name and Header tags. It needs to be imported with -ko.
+
+It is imported from it's top level directory something like this:
+ cvs -n import -ko src/contrib/cvs CYCLIC v<version>
+
+The -n option is "dont 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 -ko src/contrib/cvs CYCLIC v1_8_1
+
+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: <devel-cvs@cyclic.com>. Local changes
+that are suitable for public consumption should be submitted for inclusion
+in future releases.
+
+peter@freebsd.org - 20 Aug 1996
+
+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.
+ - if pserver username is "anoncvs", implicitly use a password of "anoncvs".
+ - CVSROOT/options file
+ - Variable keyword expansion controls including custom keywords.
+ - $ CVSHeader$ keyword - like Header, but with $CVSROOT stripped off.
diff --git a/contrib/cvs/README.VMS b/contrib/cvs/README.VMS
deleted file mode 100644
index b32ed8f..0000000
--- a/contrib/cvs/README.VMS
+++ /dev/null
@@ -1,159 +0,0 @@
- CVS port to VMS
-
-DISCLAIMER: This port must be considered experimental. Although
-previous versions have been in use at one large site since about
-October, 1995, and the port is believed to be quite usable, various
-VMS-specific quirks are known and the port cannot be considered as
-mature as the ports to, say, Windows NT or unix. As always, future
-progress of this port will depend on volunteer and customer interest.
-
-This port is of the CVS client only. Or in other words, the port
-implements the full set of CVS commands, but cannot access
-repositories located on the local machine. The repository must live
-on another machine (a Unix box) which runs a complete port of CVS.
-
-Most (all?) work to date has been done on OpenVMS/AXP 6.2. Other VMS
-variants might work too.
-
-You will also need GNU patch installed on your system. Here's a list
-of ftp servers which have VMS GNU resources, taken from
-
- ftp://prep.ai.mit.edu/pub/gnu/vms.README
-
- mvb.saic.com
- wuarchive.wustl.edu
- ftp.wku.edu
- ftp.spc.edu
- ftp.stacken.kth.se
-
-Please send bug reports to bug-cvs@prep.ai.mit.edu.
-
-As of CVS 1.5.something, this port passed most of the tests in
-[.src]sanity.sh. I say "most" because some tests to not apply to the
-CVS client. The tests were run by hand because the VMS POSIX shell
-was incapable of running the script. The tests that sanity.sh
-provides are not conclusive but at least provides some assurance that
-the client is usable.
-
-To compile, you will need DEC C (CC), DEC UCX, and of course DCL
-installed on your machine. Just type "@build" in the top level
-directory. This will build the sources in each subdirectory, and link
-the executable [.src]cvs.exe
-
-Copy the executable to an appropriate directory, and define the symbol "CVS"
-in a .COM file which everyone running CVS will need to run. Here's an example
-of what needs to be done.
-
-$ CVS :== $YOUR_DEVICE:[YOUR.DIRECTORY.CVS]CVS.EXE
-
-Accessing a remote repository can happen in several ways.
-
-1. pserver
-2. rsh - privileged (default)
-3. rsh - unprivileged (on VMS side)
-
-Here's how to do each of the above:
-
--------------------------------------------------------------------------------
-1. pserver. This is the preferred way. It works just as it is
-documented in the CVS manual (see the README file in the CVS
-distribution for more information on the manual).
-
--------------------------------------------------------------------------------
-2. Using CVS internal rsh support (privileged)
-
-VMS's RSH is unusable for CVS's purposes (that is, the one in UCX.
-Don't know about Multinet). However, there is code within CVS to
-emulate RSH for purposes of contacting a CVS server "in the usual way"
-via rshd. Unfortunately, this requires the VMS CVS client to be
-installed with OPER privilege, by your system administrator.
-
-RSH uses privileged ports and trusted software/hosts to determine
-which user on the client side is trying to connect. Part of this
-security is due to the fact that on VMS or UNIX, a non privileged
-process is not permitted to bind a socket to a privileged port.
-
-If rshd receives a connection on a non-privileged port, the connection is
-immediately aborted. Only connections arriving from a privileged port will
-be authenticated and served. The CVS client will therefore need privileges
-under VMS to produce such a connection.
-
-*** Please note that no careful examination has been done of the security
- implications of installing CVS with the OPER privilege. If some hole
- exists, then by doing so, you will enable users who are already on
- your system to gain unauthorized privileges ***
-
--------------------------------------------------------------------------------
-3. Using CVS internal rsh support (non-privileged)
-
-There is a workaround, but this is one case where I think the cure is worse
-than the disease. If you patch an rshd to not care that the RSH originating
-port is "non-privileged", the CVS VMS client will allow you to define the
-logical CVS_RCMD_PORT to the port number where this patched rshd will be
-listening. I leave the talk of patching rshd to the gentle reader and his/her
-friendly system administrator.
-
-If I put an entry in my /etc/services file:
-
-cvs_rcmd 4381/tcp cvs_rcmd
-
-And add a line to /etc/inetd.conf, then restart inetd via "kill -1"
-
-cvs_rcmd stream tcp nowait root /usr/sbin/tcpd /usr/local/sbin/cvs_rcmd
-
-On the VMS side, you will have to do this:
-
-$ define CVS_RCMD_PORT 4381
-
-Then run CVS in the "usual way".
-
-Note that the patched rshd will need to be invoked via inetd as root, so it can
-authenticate and _become_ the intended user, the same as the regular rshd.
-
-***Please note that you will be installing a security hole by doing this.***
-
-Please also note that this security hole is no larger than allowing a
-Macintosh, PC (OS/2, NT, etc.) to have it's hostname in any .rhosts file,
-as any user can create a privileged socket without authentication, under these
-environments. In fact, existing ports of CVS to these environment use this
-to their advantage.
-
--------------------------------------------------------------------------------
-Wildcard expansion is not yet implemented (i.e. CVS COMMIT *.c won't
-work.) I think that expand_wild should be calling lib$findfile
-(util.c in gzip is said to provide an example), but noone has gotten
-around to implementing this.
-
-Log messages must be entered on the command line using -m or -F. You
-can use -e or define the logical EDITOR to cause CVS to try other
-editors (TPU.EXE or any other editor which wants DCL command parsing
-will not work) if you want to test what's available on your system. I
-haven't tested this, but if you install vi or emacs, chances are it
-will probably work. Just make sure the .EXE files are in a directory
-listed in VAXC$PATH (is this a typo for DCL$PATH? Also, will a
-logical name work?). If someone gets around to implementing it, we
-should probably be using the callable editors (e.g. TPU$TPU), although
-of course we also need interface(s) which are not locked into any
-particular editors.
-
-----------------------------------------
-
-Notes regarding compiling on VAX/VMS 6.2 (not Alpha) (These are items
-which hopefully will have cleaner solutions in the future, but here is
-how to get around them for now):
-
-* Need to compile lib/getdate.c with vaxc instead of decc to avoid a
-compiler bugcheck. Therefore one must add SYS$LIBRARY:VAXCRTL/LIBRARY
-to the link.
-
-* In src/ignore.c, change lstat to stat. In vms/filesubr.c, change
-"#ifdef S_ISLNK" to "#if 0".
-
-* Ignore the warnings in vms/vmsmunch.c; the system include file
-declares something as an int when it should be void *. Not *our*
-fault!
-
-Credits:
-
-Initial VMS port by Benjamin J. Lee <benjamin@cyclic.com>, Cyclic
-Software, October 1, 1995 (Update March 1, 1996).
diff --git a/contrib/cvs/contrib/log.pl b/contrib/cvs/contrib/log.pl
index 3a8ad99..89eba48 100644
--- a/contrib/cvs/contrib/log.pl
+++ b/contrib/cvs/contrib/log.pl
@@ -91,7 +91,7 @@ $mailcmd = "| Mail -s 'CVS update: $modulepath'";
@days = (Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday);
($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime;
-$year += 1900;
+$year+=1900;
# get a login name for the guy doing the commit....
#
diff --git a/contrib/cvs/contrib/sccs2rcs.csh b/contrib/cvs/contrib/sccs2rcs.csh
index a1dea01..8243890 100644
--- a/contrib/cvs/contrib/sccs2rcs.csh
+++ b/contrib/cvs/contrib/sccs2rcs.csh
@@ -177,7 +177,7 @@ foreach sfile (SCCS/s.*)
if ($status != 0) goto ERROR
# get file into current dir and get stats
- set date = `sccs prs -r$rev $file | grep "^D " | awk '{printf("19%s %s", $3, $4); exit}'`
+ set date = `sccs prs -r$rev $file | grep "^D " | awk '{y=$3; if($3 < 100) {y+=1900};printf("%s %s", y, $4);exit;}'`
set author = `sccs prs -r$rev $file | grep "^D " | awk '{print $5; exit}'`
echo ""
echo "==> file $file, rev=$rev, date=$date, author=$author"
diff --git a/contrib/cvs/diff/diagmeet.note b/contrib/cvs/diff/diagmeet.note
deleted file mode 100644
index 8f7242c..0000000
--- a/contrib/cvs/diff/diagmeet.note
+++ /dev/null
@@ -1,71 +0,0 @@
-Here is a comparison matrix which shows a case in which
-it is possible for the forward and backward scan in `diag'
-to meet along a nonzero length of diagonal simultaneous
-(so that bdiag[d] and fdiag[d] are not equal)
-even though there is no snake on that diagonal at the meeting point.
-
-
- 85 1 1 1 159 1 1 17
- 1 2 3 4
-60
- 1 2
-1
- 2 2 3 4
-71
- 3 3 4 5
-85
- 4 3 4 5
-17
- 5 4 5
-1
- 6 4 5 6
-183
- 7 5 6 7
-10
- 8 6 7
-1
- 9 6 7 8
-12
- 7 8 9 10
-13
- 10 8 9 10
-14
- 10 9 10
-17
- 10 10
-1
- 10 9 10
-1
- 8 10 10 10
-183
- 8 7 9 9 9
-10
- 7 6 8 9 8 8
-1
- 6 5 7 7
-1
- 5 6 6
-1
- 5 5 5
-50
- 5 4 4 4
-1
- 4 3 3
-85
- 5 4 3 2 2
-1
- 2 1
-17
- 5 4 3 2 1 1
-1
- 1 0
- 85 1 1 1 159 1 1 17
-
-
-
-
-
-
-
-
-
diff --git a/contrib/cvs/doc/DIFFUTILS-2.7-BUG b/contrib/cvs/doc/DIFFUTILS-2.7-BUG
deleted file mode 100644
index f258ee7..0000000
--- a/contrib/cvs/doc/DIFFUTILS-2.7-BUG
+++ /dev/null
@@ -1,263 +0,0 @@
-The enclosed two messages describe a bug in GNU diff 2.6 and 2.7 which
-may cause CVS to perform an erroneous merge. You may wish to use GNU
-diff 2.5 or apply the patch supplied by Loren James Rittle below. It
-would be nice to add this to the CVS testsuite, but I haven't done so
-because probably a lot of people who would like to run the testsuite
-are using the buggy diff.
-
-From: friedman@splode.com (Noah Friedman)
-To: bug-gnu-utils@prep.ai.mit.edu
-Cc: info-cvs@prep.ai.mit.edu
-Subject: diffutils 2.7 -- diff3 merge bug
-Date: Tue, 29 Oct 96 17:02:54 CST
-
-I believe a change first introduced in GNU diff 2.6 causes diff3 sometimes
-to produce incorrect merges.
-
-Since this is a not a bug in CVS itself but can cause commits to CVS
-repositories to be incorrect, am warning info-cvs@prep.ai.mit.edu as
-well as reporting the bug to bug-gnu-utils@prep.ai.mit.edu.
-
-I am including a simple test case as well as some sample outputs from
-different versions of `diff' and `diff3' in the enclosed shar archive.
-In addition, the file DESCRIPTION in that archive describes the problem
-more fully.
-
-If anyone has any advice for how to fix or to work around this bug, I would
-appreciate it. Using diff 2.5 seems like the most immediately obvious
-solution, but I don't know if it will introduce other problems.
-I do not understand the algorithms used by GNU diff well enough to suggest
-any patches.
-
-Unshar and enjoy. ;-)
-
-begin 666 merge-testcase.shar.gz
-M'XL(",&,=C("`VUE<F=E+71E<W1C87-E+G-H87(`[5Q[;]M&$O_[^"FF;E#9
-M@41)?C!GYX&V;MPS<$F+V+FZP.&:%;F26)-<E;NTHC[NL]_,+%^29;USUP-L
-M&)9$[CQW]C?#W;$^_ZS="Y.V'CJ?P_4PU("_`O101A&(U!^&=Q+V1ZD*,E\&
-MT)O`MV_?XVV19B:,-!R[W0.72!7(CR85O@$SE-`/(ZFAGZH8/Q)'RZD)6B"_
-M$`<IT"J6<''Y]]=-2&6L[B2RD7<RG2!%,H">[*M4,K</A8X-B,)$@N@IXH6W
-M$C"3$0[00^;40%60RQL12%`)=$]/O5:WTSH\A:YW=G(,YU?79,*+?AK*(!;)
-MEWH4J4"ZOHI?D157*DM]"4&82M^H=`)CH>%#.]-I.U*^B-HZ]=N#)&L'8;_/
-M#FC',AW(EI':^$++7('7'T-MR`CKAW&(SGR:*/,4K0+4/1VGH3&H?9;@?131
-M\AOD>#V2?MA'W2P;G@_R-?@J,2),]!E>C60R,$.(47&P/XF(R7DM_LE?9MXN
-M^T%R_#DZ]:"5CO-?F+:M7;QI3=!-VE(\ZQRM0A'CM%D"[_1X%0(5!3*U%,<G
-MAPLHWHA;25[FL8?=PV<+QG[S^NK\W>7WUY??O<U9=Q;92Y-\Z)Y87>I&>R>K
-MD)'-=:I5A'ESA!T_6X'LOK"3%52LYH?N!ZM,:2%P'FFW>[1HJJ[>OWGSU;L?
-M,;2-ROPAM$0,W<,C_#TY/3V%)T]<>_U5.Y!W[23#17/XZHNN$_:!>,!GT.K7
-M";[XPE['JP7M<P8%!WC5_,277O)?1T9:3E\_PX_2'ZK\!1H_?/7N[>7;;\\`
-M5RI"DD8$H#5LPAC?BWBD78!SE>@09P@&TO`*%TG0*#CLX0HU(HKH.L'D/S^P
-MI$83$46;-.QE!C$T3/CF!08MO$<,"4THM>NZ>X4^_=!)XQE;"P,9%U[6?Q:O
-MTNFQ+^N^#*`Q`UZE]ZP_/D(+_%0*MK/"Q!DB'![?XMU[W,B.0AP:TUBH9Z.<
-MS9N])]T]^.PEOFGY>W-4TK?A:$0J+39\GU`!1(0&!!-,3C@#^J!1Q$'%+D];
-M*S`T./2`[-4XBPW=_M=-N]V`%R^@<?6WK][]]/J[BP:\6L%.I]V&KS-C5.+^
-M+.Z$<^.,A'\K!A)2C"85NV(TBD(?_:Z2YW@WC$<J-<5-2CON4[H^RGHX#/Q(
-M8`JQ#)W?G!N`]E.XI$A,3"A0/.9S>Q<3$28.C.H!QN!^IPF=`XI?^%6F"N\%
-M>),^#F4X&!J7.,%3^%%E$&<X,9C_L"1(,'XQ8D44(A5ZS`Q50-D<2X213*-)
-M[3;G[MQ0RZQ-+[G:N4K[!W2-U4;'9L@#+Y%U?.$G$YI(GJM(I?`2^-7M1>BM
-MY_E]7%BB%\G@^OZX02HFS^ML+C")XEUZ<0/9%UED^!++`_C#^<,I)A(G^4D%
-M%1:I.H>GW9-##U/D"E,,X`\Q0T/'\Y:/__WW,B(M[&"1T%\2C7V!X<W0PWKZ
-M*DO,R[T/8Q]:/KQ8)O(#@0TO-T[Y\A?8>U+QV;,:%:BVD-59'D\B`DUSCOR:
-MX&=I*M&S?*7.F#!A5?RBE/80?"W"$Z+;)9RP'CM$$\MO2S`IC'S$DI6Q!#VU
-M#$YHR&J(4C);"BHWN1>Q<KB322@3?,#`<A[K@8SR*>!3#H2EA[FDJ+LX]UP/
-MET^@X6,3)DWKWF;=OP"O?\G".Q'1JC,J)Z*?OE*H7B+'E9.>3]]VR<NP/\7:
-MLBU&SG-UB(*0A%XF]B4GI;<Y>6TV^"FP$`U+)*Z&Q,\6(7&Y/E8#8CM\/1SF
-M=;PI#+/`"H6YYMX,A8G3+`@CNQV!,#^.;(+"3+A+&+::[!"'<X9;`G%IYR,2
-M_TFKND<`_D0`O+`4KM;%:@B<CU\/@NT2WA2#K<@*A'EK:C,09E:S*(S\MD/A
-M8F]K#?PM2':`O*7T[3&W8K49VM:M<KZYO+@XPB5%.U%'_"G_@"N=Z<Z<F[^T
-MGNSSN`-HO>:8G4[;,Q$TL[-YPWNO:'(ZR&*</,T8@8[32#E68/"&Q*MCB>$9
-M2"-38LJ[X[CX9.K+$7D!N;".#6U1%@.9/C-L(.",I/65F9*$ZW*$R,];P*3$
-MQ.X>WXET@J)&,@F(!@&`R,)DE!G>9'8=8EW?/20O6">@#P2T6D.,SE]5TJ(M
-M=/VRV\%+B_V`L9)F$KW!K*L=QII_Y[/N3K&>=GB=\S*(\;K=.1`S%0P+P:4:
-MN1*LE%&Z)J"48BHHX3WKM:"D8#(+(LAI.Q"I;7JO@2,UJAU`25V'[=%DBMMF
-M@#)CGF-/6J2AJ+!G-KCHL#Q*\TJ+S2=*&`]YT=.Z9KU(O_QX3#MAXJN4]DEI
-M^Q@+$4W#$\ATL2-<GAO!H>OA3%-=(%.L'E@!7V0:N?@JCD.DQ?KK_!]7R&JD
-M=$B;T9*O]6C=YW*:H!5<`BZ81)FP/R$YYQ,?ZP3G2O7-6-A`)ZQ`);&DBD$0
-M;E'-IZ&7#5J#)&NQ1E^.4)`K0A=ENS+(L+ASD+/)]ZVG>*`6?,JGHDB-<06*
-M9$">"7'Q8I4K42IO<S/:H:%-A[`-ZU["2#2CSP4ELWC[^H<KL(N.(5:8:J\<
-M"<Z*DG'/==WO16J04M"$6/\V2Z<BQJK,$!JB'VG_7G[$X,'1)$2+&"-.6T[V
-M7-&%]SI#4)X0X/*19P_?Z!@OR;2)GC%\/LE[_U-#(L+^U-TCQ9PWDUIDU".F
-M\@[-B/9E(M)0Y=9\90W.S_1X`!V%^G2@1U$PE/XM>@KMH8Q""6<DU8@P_@8X
-M+_7#%(5B4:TQ#P0RDC9(^UGBD],XP11!Q'%E)\C.&C$I0VI2\M02]0D*ID3-
-MZ8B4&*'?*8H$^G5(]59=#@:(C$<<K<3*BJU)I4.3K\D2R=%MHQ'O<FQ@`/(Q
-MKEWA$"C)DV=5I"/A/.KD7:@R'4U:UMB@4B$_8I[1OU%))UY7J@BW/@.KKT9E
-M`%:NL)K<DS"DA2(1Z%@ISAVT-*[+4^ZI1-><2:G-F<Q'9]UHC^;'!)R,6;6)
-MI56D3`/V$OG:S,Q],=Y!AEQ-W,EH4E<.'CCHXW!.\J<>GR=%0`%==B[L0V7?
-M(9EFF$H)=R@3'8(FE.T`/*B.:2=N$:'H&>?^22B;,>=<==HK/`)#-TMNZ8X(
-M$%AI*5C4I<=2F>(BCLO0P34TQVQOKMEV]G-0K`";1U2F.?=,\W+3[!HH)#S-
-M@X"`5N!LJ0$&:K[2PK3P`'"VEBFM)`I)AQZ_N:XCV/9MF-]*:R'F%YJ3/#ZM
-M$V1,_0)<81;^H6'&R2>EK"T)12LF%+EF+*E-8JH:XV":BDM&>RN1P:S@A\H_
-ML"Z$G2HL2`MGLNNI@R1Q"'G4.&'M65H!Q[$PB&^ZOF1Y3"ZO5-A94>$RQ5C5
-M[:(GSJ1C/BWH9G2F`,K"D?5H,\]6ER@O"N6==&*LORS2QP@(.NSE*:F,.4-)
-MTU+Q-#)O*S!@_?B>4]W#B,+E6#C.75[M'I[.J79G*Y6%!>_4X)5JWGHMM6;9
-M6Q=65;ZV!6.MTK?&:+;Z)6[;E;_SP&;U,G@.]0[*X7DZ;5\6S^6Z67G\@-G.
-MC>M6K4\M',&?-GR\=`X[S:-.T#UU7@#^;K5'1^3K;]+E5`_NTDW?7[A-9X>V
-M^763C3JB^\URJ;;J[,=E8I=OU7F=><CRT"0O1)BY1"LAS;SP7!-QY@FO/7-W
-MUCW)GL/OWN-WQ]L-_M1JH/7AIR+>(?K4--H=^-29;H<]TS:O`SU+MY^<KM?L
-M_M7GO_DB6WPX7(U9>C(QPV[1Z02U7;Z")0<B^8"E<NN,%@E]!-T_!>C.1/=*
-MF%NG60MR:XMR0\2MB:Z=EYQL"KBUO>39,Y.3G>"MMU6]YWV2>L_[)/6>M[MZ
-MSUM:[WF/]=[_!?1T.P]"C[=)O>=M7.]YV]=[WH[K/>^_4.]YV]1[WJ>H][Q/
-M4>]Y.ZOWO&7UGK=EO7=X^C^O]^SB?02_3<'O?U(O;X>UZY=YWJ9EGK=UF><]
-M4.8=/]L09Q>4><<[VM:;W>%?_]EZAL,.'[!G==O=4_8]SML]:L]QP6,WXY^]
-MKWR5,O!PP1/HO$E?Z3'T'N%:SZ*SH;OA`^FL$O6R\&3#I](9GO=+PY/=E(;;
-M8I;WR3#+^V28Y>T6L[Q'S'K\7YC'5NP5@-[;%.B]K8#>VPW0>PN`?OW_F7F`
-MY\[_>R;_1_<U@#VGV`&0%[*W!^Z2TV9`73/)N;E(57P&<[YV`_;?*C&$B_S.
-M@7.MSA;W)3KG_ADNFKYJ^7?W;UYEO9^E;\ZF6G>>T09!U;(I28#S3HZB28O$
-MS5'+^08!_@RN,]F$PU/XSC?\92+\-2)'9]UC:'6\3@?VSZ^N#YP+'S7Z=UL:
-MOQUCD+>1NZ[V+O"QE1R8MP-JN_IIYP*?9LOV$VI+LDUZMK\+@:/HL<J_+J!H
-M=,F;1'-SRAY%QZ8*(IEM:N)6F:LPX3:CX@M>J$52D!^(/W69AD;+J,^-CSXF
-M(]NL-]V)ZBSN1$4T&HN4^QD?FAYJPBR:3XE96C;`DR;$<86.U)B$1EE@TX/&
-M+![)6AMFK;^5VRJUX`&V.]1^)XU3]D^536T$9!^XD913R0?;N%\T86&BBA1%
-M/W\92_YE-B[U'XD@"*F>:%8=4/66&J87IOPFG4!J/PU[>0-4WD[KQ(2D_2RR
-MS7N7U&DY48GDUD-\BT+NJ$F,LN-0C<E/_?`C=0_CN[%*;Y$]I40[O=Q3>8G7
-MLRAPL.+!R:%J!2<8,^-[;;_+P79VX8*6,07CK:TI8D6A%\<R(`JL.52/&R\=
-MK:+,6DGQ<0F!2AH&;A-4!D$M-+:7K0S:O$<N-P_CCR@XY%!+=+@IFAE%-,!@
-M,D-4(M/5UPNQ?CR),E'98,C?%I0-,)2-0_X8V28R<M;[Q$X)M9@E/ZL)VOB\
-M=;`\8YX<S<F8=<A:F"'+@2MEQ`)(U\R`A9`JX]GO5UDKY>5,9E,<<5J2XS!E
--&.@X_P&I*Y$W($H``"'+
-`
-end
-
-Date: Wed, 30 Oct 96 14:54:13 CST
-From: Loren James Rittle <rittle@comm.mot.com>
-To: friedman@splode.com
-Cc: bug-gnu-utils@prep.ai.mit.edu, info-cvs@prep.ai.mit.edu
-Subject: Re: diffutils 2.7 -- diff3 merge bug
-
-Noah,
-
-I have seen the problem you discuss in your e-mail, however I fail to
-see how this situation is as critical as might be implied since it can
-never arise without at least some user involvement (an update that
-caused a merge is never automatically followed by a commit --- the
-user has a chance to inspect the merged file). However, I will agree
-that I don't always look very closely at non-conflicted merges before
-checking them back in.
-
-You didn't give the exact CVS commands used to create a lossage,
-but I added the following to your Makefile, to help me see the problem
-in a CVS usage context:
-
-t-older: testcase-older
- cp testcase-older t-older
-
-t-yours: testcase-yours
- cp testcase-yours t-yours
-
-t-mine: testcase-mine
- cp testcase-mine t-mine
-
-# Assume cvs-1.9
-cvs-test: t-older t-yours t-mine
- rm -rf /tmp/cvs-test-root x x2
- cvs -d /tmp/cvs-test-root init
- mkdir x
- cp t-older x/testcase
- cd x; cvs -d /tmp/cvs-test-root import -m '' x X X1
- rm -rf x
- cvs -d /tmp/cvs-test-root co x
- cvs -d /tmp/cvs-test-root co -d x2 x
- cp t-yours x/testcase
- cp t-mine x2/testcase
- cd x; cvs ci -m ''
- -cd x2; cvs ci -m ''
- cd x2; cvs update
- cat x2/testcase # at this point, user may commit blindly
-
-It looks like whomever added shift_boundaries() in analyze.c, which
-seems to be the source of the diff3 induced mischief, already provided
-a means to disable the boundary shifting optimization (at least with
-a recompile).
-
-Here is the patch I applied to diff to disable this (currently)
-overaggressive optimization:
-
-[ rittle@supra ]; diff -c analyze.c-old analyze.c
-*** analyze.c-old Wed Oct 30 14:10:27 1996
---- analyze.c Wed Oct 30 13:48:57 1996
-***************
-*** 616,622 ****
- but usually it is cleaner to consider the following identical line
- to be the "change". */
-
-! int inhibit;
-
- static void
- shift_boundaries (filevec)
---- 616,622 ----
- but usually it is cleaner to consider the following identical line
- to be the "change". */
-
-! int inhibit = 1;
-
- static void
- shift_boundaries (filevec)
-
-Now, diff-2.7 with the above patch produces:
-
-[ rittle@supra ]; make diff-mine-yours 'DIFF=/usr/src/diffutils-2.7/diff'
-/usr/src/diffutils-2.7/diff -a --horizon-lines=11 -- testcase-mine testcase-yours; true
-16,18c16,18
-< // _titleColor = Color.black;
-< // _disabledTitleColor = Color.gray;
-< // _titleFont = Font.defaultFont ();
----
-> _titleColor = Color.black;
-> _disabledTitleColor = Color.gray;
-> _titleFont = Font.defaultFont ();
-20,30d19
-<
-< /* 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);
-< }
-
-Whereas, stock diff-2.7 produces:
-
-[ rittle@supra ]; make diff-mine-yours
-diff -a --horizon-lines=11 -- testcase-mine testcase-yours; true
-16,29c16,18
-< // _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);
----
-> _titleColor = Color.black;
-> _disabledTitleColor = Color.gray;
-> _titleFont = Font.defaultFont ();
-
-A better solution might be to disable the boundary shifting code
-unless explicitly turned on via command line argument. That way
-programs, like diff3, expecting unoptimized diff regions will work
-correctly, yet users can get smaller diffs, if desired. The problem
-is that diff3 doesn't properly track changes once they have been
-optimized.
-
-BTW, I never did like the look of the `optimized diff regions', so I
-consider this a good change for other reasons... :-)
-
-Enjoy!
-
-Regards,
-Loren
---
-Loren J. Rittle (rittle@comm.mot.com) PGP KeyIDs: 1024/B98B3249 2048/ADCE34A5
-Systems Technology Research (IL02/2240) FP1024:6810D8AB3029874DD7065BC52067EAFD
-Motorola, Inc. FP2048:FDC0292446937F2A240BC07D42763672
-(847) 576-7794 Call for verification of fingerprints.
diff --git a/contrib/cvs/lib/getwd.c b/contrib/cvs/lib/getwd.c
deleted file mode 100644
index 5707dcb..0000000
--- a/contrib/cvs/lib/getwd.c
+++ /dev/null
@@ -1,33 +0,0 @@
-/* getwd.c -- get current working directory pathname
- 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. */
-
-/* Some systems which include both getwd() and getcwd() have an implementation
- of getwd() which is much faster than getcwd(). As a result, we use the
- system's getwd() if it is available */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "system.h"
-
-/* Get the current working directory into PATHNAME */
-
-char *
-getwd (pathname)
- char *pathname;
-{
- char *getcwd();
-
- return (getcwd(pathname, PATH_MAX));
-}
diff --git a/contrib/cvs/lib/strdup.c b/contrib/cvs/lib/strdup.c
deleted file mode 100644
index c81969d..0000000
--- a/contrib/cvs/lib/strdup.c
+++ /dev/null
@@ -1,39 +0,0 @@
-/* strdup.c -- return a newly allocated copy of 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
-
-#ifdef STDC_HEADERS
-#include <string.h>
-#include <stdlib.h>
-#else
-char *malloc ();
-char *strcpy ();
-#endif
-
-/* Return a newly allocated copy of STR,
- or 0 if out of memory. */
-
-char *
-strdup (str)
- char *str;
-{
- char *newstr;
-
- newstr = (char *) malloc (strlen (str) + 1);
- if (newstr)
- strcpy (newstr, str);
- return newstr;
-}
diff --git a/contrib/cvs/lib/strippath.c b/contrib/cvs/lib/strippath.c
deleted file mode 100644
index 39687f9..0000000
--- a/contrib/cvs/lib/strippath.c
+++ /dev/null
@@ -1,80 +0,0 @@
-/* strippath.c -- remove unnecessary components from a path specifier
- 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.
-
- 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. */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#if STDC_HEADERS || HAVE_STRING_H
-#include <string.h>
-/* An ANSI string.h and pre-ANSI memory.h might conflict. */
-#if !STDC_HEADERS && HAVE_MEMORY_H
-#include <memory.h>
-#endif /* not STDC_HEADERS and HAVE_MEMORY_H */
-#else /* not STDC_HJEADERS and not HAVE_STRING_H */
-#include <strings.h>
-/* memory.h and strings.h conflict on some systems. */
-#endif /* not STDC_HEADERS and not HAVE_STRING_H */
-
-#include <stdio.h>
-
-#if __STDC__
-static void remove_component(char *beginc, char *endc);
-void strip_trailing_slashes(char *path);
-#else
-static void remove_component();
-void strip_trailing_slashes();
-#endif /* __STDC__ */
-
-/* Remove unnecessary components from PATH. */
-
-void
-strip_path (path)
- char *path;
-{
- int stripped = 0;
- char *cp, *slash;
-
- for (cp = path; (slash = strchr(cp, '/')) != NULL; cp = slash)
- {
- *slash = '\0';
- if ((!*cp && (cp != path || stripped)) ||
- strcmp(cp, ".") == 0 || strcmp(cp, "/") == 0)
- {
- stripped = 1;
- remove_component(cp, slash);
- slash = cp;
- }
- else
- {
- *slash++ = '/';
- }
- }
- strip_trailing_slashes(path);
-}
-
-/* Remove the component delimited by BEGINC and ENDC from the path */
-
-static void
-remove_component (beginc, endc)
- char *beginc;
- char *endc;
-{
- for (endc++; *endc; endc++)
- *beginc++ = *endc;
- *beginc = '\0';
-}
diff --git a/contrib/cvs/man/cvs.1 b/contrib/cvs/man/cvs.1
index 8cbe2be..fe9e30a 100644
--- a/contrib/cvs/man/cvs.1
+++ b/contrib/cvs/man/cvs.1
@@ -1,3 +1,4 @@
+.\" $FreeBSD$
.de Id
.ds Rv \\$3
.ds Dt \\$4
@@ -229,6 +230,16 @@ 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 .
@@ -239,6 +250,25 @@ 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
@@ -291,6 +321,15 @@ 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
@@ -1994,7 +2033,7 @@ A read lock.
.TP
#cvs.wfl.\fIpid\fP
A write lock.
-.SH "ENVIRONMENT VARIABLES"
+.SH "ENVIRONMENT"
.TP
.SM CVSROOT
Should contain the full pathname to the root of the
@@ -2009,9 +2048,7 @@ 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; use
-.` "cvs \-v"
-to display all compiled-in paths.
+if your \fBcvs\fP binary has the right path compiled in.
.TP
.SM CVSREAD
If this is set,
@@ -2022,6 +2059,13 @@ 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
@@ -2047,6 +2091,12 @@ 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
diff --git a/contrib/cvs/man/cvsbug.8 b/contrib/cvs/man/cvsbug.8
index 63574d4..fc1bf07 100644
--- a/contrib/cvs/man/cvsbug.8
+++ b/contrib/cvs/man/cvsbug.8
@@ -180,7 +180,7 @@ describe only
with each problem report.
.IP \(bu 3m
For follow-up mail, use the same subject line as the one in the automatic
-acknowledgent. It consists of category, PR number and the original synopsis
+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
diff --git a/contrib/cvs/src/NOTES b/contrib/cvs/src/NOTES
deleted file mode 100644
index 646ebdf..0000000
--- a/contrib/cvs/src/NOTES
+++ /dev/null
@@ -1,60 +0,0 @@
-wishlist - Tue Nov 2 15:22:58 PST 1993
-
-* bcopy -> memcpy & friends.
- ** done 12/18/93
-
-* remove static buffers.
-* replace list & node cache with recursive obstacks, (xmalloc,
- getnode, getlist)
-* check all io functions for error return codes. also check all
- system calls.
-* error check mkdir.
-
----
-Old notes...
-
-* All sizing limits are gone. The rest of these items were incidental
- in that effort.
-
-* login name from history was duplicated. taught existing routine to
- cache and use that instead. Also add routines to cache uid, pid,
- etc.
-
-* ign strings were never freed. Now they are.
-
-* there was a printf("... %s ...", cp) vs *cp bug in history.c. Now
- fixed.
-
-* The environment variables TMPDIR, HOME, and LOGNAME were not
- honored. Now they are.
-
-* extra line inserted by do_editor() is gone. Then obviated. Editor
- is now called exactly once per checkin.
-
-* revised editor behaviour. Never use /dev/tty. If the editor
- session fails, we haven't yet done anything. Therefor the user can
- safely rerun cvs and we should just fail. Also use the editor for
- initial log messages on added files. Also omit the confirmation
- when adding directories. Adding directories will require an
- explicit "commit" step soon. Make it possible to prevent null login
- messages using #define REQUIRE_LOG_MESSAGES
-
-* prototypes for all callbacks.
-
-* all callbacks get ref pointers.
-
-* do_recursion/start_recursion now use recusion_frame's rather than a
- list of a lot of pointers and global variables.
-
-* corrected types on status_dirproc().
-
-* CONFIRM_DIRECTORY_ADDS
-
-* re_comp was innappropriate in a few places. I've eliminated it.
-
-* FORCE_MESSAGE_ON_ADD
-
-* So I built a regression test. Let's call it a sanity check to be
- less ambitious. It exposed that cvs is difficult to call from
- scripts.
-
diff --git a/contrib/cvs/src/README-rm-add b/contrib/cvs/src/README-rm-add
deleted file mode 100644
index 87fd7c6..0000000
--- a/contrib/cvs/src/README-rm-add
+++ /dev/null
@@ -1,31 +0,0 @@
-WHAT THE "DEATH SUPPORT" FEATURES DO:
-
-(Some of the death support stuff is documented in the main manual, but
-this file is for stuff which noone has gotten around to adding to the
-main manual yet).
-
-CVS with death support can record when a file is active, or alive, and
-when it is removed, or dead. With this facility you can record the
-history of a file, including the fact that at some point in its life
-the file was removed and then later added.
-
-Files can now be added or removed in a branch and later merged
-into the trunk.
-
- cvs update -A
- touch a b c
- cvs add a b c ; cvs ci -m "added" a b c
- cvs tag -b branchtag
- cvs update -r branchtag
- touch d ; cvs add d
- rm a ; cvs rm a
- cvs ci -m "added d, removed a"
- cvs update -A
- cvs update -jbranchtag
-
-Added and removed files may also be merged between branches.
-
-Files removed in the trunk may be merged into branches.
-
-Files added on the trunk are a special case. They cannot be merged
-into a branch. Instead, simply branch the file by hand.
diff --git a/contrib/cvs/src/commit.c b/contrib/cvs/src/commit.c
index c4cbd24..6b674e1 100644
--- a/contrib/cvs/src/commit.c
+++ b/contrib/cvs/src/commit.c
@@ -12,6 +12,7 @@
*
* The call is: cvs commit [options] files...
*
+ * $FreeBSD$
*/
#include <assert.h>
@@ -49,6 +50,7 @@ static int precommit_list_proc PROTO((Node * p, void *closure));
static int precommit_proc PROTO((char *repository, char *filter));
static int remove_file PROTO ((struct file_info *finfo, char *tag,
char *message));
+static void fix_rcs_modes PROTO((char *rcs, char *user));
static void fixaddfile PROTO((char *file, char *repository));
static void fixbranch PROTO((RCSNode *, char *branch));
static void unlockrcs PROTO((RCSNode *rcs));
@@ -340,11 +342,10 @@ commit (argc, argv)
readonly user stuff (CVSROOT/readers, &c). That is, why should
root be able to "cvs init", "cvs import", &c, but not "cvs ci"? */
if (geteuid () == (uid_t) 0
-# ifdef CLIENT_SUPPORT
- /* Who we are on the client side doesn't affect logging. */
+#ifdef CLIENT_SUPPORT
&& !client_active
-# endif
- )
+#endif
+ )
{
struct passwd *pw;
@@ -410,7 +411,7 @@ commit (argc, argv)
argv += optind;
/* numeric specified revision means we ignore sticky tags... */
- if (saved_tag && isdigit ((unsigned char) *saved_tag))
+ if (saved_tag && isdigit (*saved_tag))
{
aflag = 1;
/* strip trailing dots */
@@ -509,7 +510,7 @@ commit (argc, argv)
/* Run the user-defined script to verify/check information in
*the log message
*/
- do_verify (saved_message, (char *)NULL);
+ do_verify (&saved_message, (char *)NULL);
/* We always send some sort of message, even if empty. */
/* FIXME: is that true? There seems to be some code in do_editor
@@ -565,6 +566,13 @@ commit (argc, argv)
send_arg("-n");
option_with_arg ("-r", saved_tag);
+ /* Sending only the names of the files which were modified, added,
+ or removed means that the server will only do an up-to-date
+ 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);
+
/* 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
@@ -577,13 +585,6 @@ commit (argc, argv)
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);
-
send_to_server ("ci\012", 0);
err = get_responses_and_close ();
if (err != 0 && use_editor && saved_message != NULL)
@@ -676,10 +677,9 @@ commit (argc, argv)
{
time_t now;
- for (;;)
+ (void) time (&now);
+ if (now == last_register_time)
{
- (void) time (&now);
- if (now != last_register_time) break;
sleep (1); /* to avoid time-stamp races */
}
}
@@ -708,7 +708,7 @@ classify_file_internal (finfo, vers)
noexec = quiet = really_quiet = 1;
/* handle specified numeric revision specially */
- if (saved_tag && isdigit ((unsigned char) *saved_tag))
+ if (saved_tag && isdigit (*saved_tag))
{
/* If the tag is for the trunk, make sure we're at the head */
if (numdots (saved_tag) < 2)
@@ -792,19 +792,6 @@ check_fileproc (callerdat, finfo)
struct commit_info *ci;
struct logfile_info *li;
- size_t cvsroot_len = strlen (CVSroot_directory);
-
- if (strncmp (finfo->repository, CVSroot_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);
/*
@@ -843,7 +830,7 @@ check_fileproc (callerdat, finfo)
* 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 (!saved_tag || !isdigit (*saved_tag))
{
if (vers->date)
{
@@ -915,9 +902,7 @@ warning: file `%s' seems to still contain conflict indicators",
}
}
- if (status == T_REMOVED
- && vers->tag
- && isdigit ((unsigned char) *vers->tag))
+ if (status == T_REMOVED && vers->tag && isdigit (*vers->tag))
{
/* Remove also tries to forbid this, but we should check
here. I'm only _sure_ about somewhat obscure cases
@@ -956,7 +941,7 @@ warning: file `%s' seems to still contain conflict indicators",
}
free (rcs);
}
- if (vers->tag && isdigit ((unsigned char) *vers->tag) &&
+ if (vers->tag && isdigit (*vers->tag) &&
numdots (vers->tag) > 1)
{
error (0, 0,
@@ -1016,7 +1001,7 @@ warning: file `%s' seems to still contain conflict indicators",
ci = (struct commit_info *) xmalloc (sizeof (struct commit_info));
ci->status = status;
if (vers->tag)
- if (isdigit ((unsigned char) *vers->tag))
+ if (isdigit (*vers->tag))
ci->rev = xstrdup (vers->tag);
else
ci->rev = RCS_whatbranch (finfo->rcs, vers->tag);
@@ -1135,7 +1120,7 @@ precommit_proc (repository, filter)
s = xstrdup (filter);
for (cp = s; *cp; cp++)
- if (isspace ((unsigned char) *cp))
+ if (isspace (*cp))
{
*cp = '\0';
break;
@@ -1248,7 +1233,7 @@ commit_fileproc (callerdat, finfo)
if (use_editor)
do_editor (finfo->update_dir, &saved_message,
finfo->repository, ulist);
- do_verify (saved_message, finfo->repository);
+ do_verify (&saved_message, finfo->repository);
}
p = findnode (cilist, finfo->file);
@@ -1282,11 +1267,7 @@ commit_fileproc (callerdat, finfo)
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 (ci->tag)
{
if (finfo->rcs == NULL)
error (1, 0, "internal error: no parsed RCS file");
@@ -1559,7 +1540,7 @@ commit_direntproc (callerdat, dir, repos, update_dir, entries)
got_message = 1;
if (use_editor)
do_editor (update_dir, &saved_message, real_repos, ulist);
- do_verify (saved_message, real_repos);
+ do_verify (&saved_message, real_repos);
free (real_repos);
return (R_PROCESS);
}
@@ -1620,16 +1601,16 @@ findmaxrev (p, closure)
* 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;
{
+ mode_t omask;
int retcode;
+ char *tmp;
int branch;
int lockflag;
@@ -1719,6 +1700,16 @@ remove_file (finfo, tag, message)
RCS_rewrite (finfo->rcs, NULL, NULL);
}
+#ifdef SERVER_SUPPORT
+ if (server_active) {
+ /* If this is the server, there will be a file sitting in the
+ temp directory which is the kludgy way in which server.c
+ tells time_stamp that the file is no longer around. Remove
+ it so we can create temp files with that name (ignore errors). */
+ unlink_file (finfo->file);
+ }
+#endif
+
/* 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,
@@ -1755,9 +1746,34 @@ remove_file (finfo, tag, message)
if (rev != NULL)
free (rev);
- old_path = xstrdup (finfo->rcs->path);
+ old_path = finfo->rcs->path;
if (!branch)
- RCS_setattic (finfo->rcs, 1);
+ {
+ /* this was the head; really move it into the Attic */
+ tmp = xmalloc(strlen(finfo->repository) +
+ sizeof('/') +
+ sizeof(CVSATTIC) +
+ sizeof('/') +
+ strlen(finfo->file) +
+ sizeof(RCSEXT) + 1);
+ (void) sprintf (tmp, "%s/%s", finfo->repository, CVSATTIC);
+ omask = umask (cvsumask);
+ (void) CVS_MKDIR (tmp, 0777);
+ (void) umask (omask);
+ (void) sprintf (tmp, "%s/%s/%s%s", finfo->repository, CVSATTIC,
+ finfo->file, RCSEXT);
+
+ if (strcmp (finfo->rcs->path, tmp) != 0
+ && CVS_RENAME (finfo->rcs->path, tmp) == -1
+ && (isreadable (finfo->rcs->path) || !isreadable (tmp)))
+ {
+ free(tmp);
+ return (1);
+ }
+ /* The old value of finfo->rcs->path is in old_path, and is
+ freed below. */
+ finfo->rcs->path = tmp;
+ }
/* Print message that file was removed. */
cvs_output (old_path, 0);
@@ -1768,7 +1784,8 @@ remove_file (finfo, tag, message)
cvs_output ("\ndone\n", 0);
free(prev_rev);
- free (old_path);
+ if (old_path != finfo->rcs->path)
+ free (old_path);
Scratch_Entry (finfo->entries, finfo->file);
return (0);
@@ -1794,9 +1811,7 @@ finaladd (finfo, rev, tag, options)
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);
+ (void) unlink_file (tmp);
free (tmp);
}
else
@@ -1840,10 +1855,7 @@ fixaddfile (file, repository)
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);
- }
+ (void) unlink_file (rcs);
else
freercsnode (&rcsfile);
really_quiet = save_really_quiet;
@@ -1890,20 +1902,8 @@ checkaddfile (file, repository, tag, options, rcsnode)
int newfile = 0;
RCSNode *rcsfile = NULL;
int retval;
- int adding_on_branch;
-
- /* 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 (adding_on_branch)
+ if (tag)
{
rcs = xmalloc (strlen (repository) + strlen (file)
+ sizeof (RCSEXT) + sizeof (CVSATTIC) + 10);
@@ -1926,7 +1926,6 @@ checkaddfile (file, repository, tag, options, rcsnode)
{
/* file has existed in the past. Prepare to resurrect. */
char *rev;
- char *oldexpand;
if ((rcsfile = *rcsnode) == NULL)
{
@@ -1935,38 +1934,41 @@ checkaddfile (file, repository, tag, options, rcsnode)
goto out;
}
- oldexpand = RCS_getexpand (rcsfile);
- if ((oldexpand != NULL
- && options != NULL
- && strcmp (options + 2, oldexpand) != 0)
- || (oldexpand == NULL && options != NULL))
+ if (tag == 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 (rcsfile, options + 2);
- }
+ char *oldfile;
- if (!adding_on_branch)
- {
- /* We are adding on the trunk, so move the file out of the
- Attic. */
- if (!(rcsfile->flags & INATTIC))
+ /* we are adding on the trunk, so move the file out of the
+ Attic. */
+ oldfile = xstrdup (rcs);
+ sprintf (rcs, "%s/%s%s", repository, file, RCSEXT);
+
+ if (strcmp (oldfile, rcs) == 0)
{
error (0, 0, "internal error: confused about attic for %s",
- rcsfile->path);
+ oldfile);
+ out1:
+ free (oldfile);
retval = 1;
goto out;
}
-
- sprintf (rcs, "%s/%s%s", repository, file, RCSEXT);
-
- if (RCS_setattic (rcsfile, 0))
+ if (CVS_RENAME (oldfile, rcs) != 0)
{
- retval = 1;
- goto out;
+ error (0, errno, "failed to move `%s' out of the attic",
+ oldfile);
+ goto out1;
}
+ if (isreadable (oldfile)
+ || !isreadable (rcs))
+ {
+ error (0, 0, "\
+internal error: `%s' didn't move out of the attic",
+ oldfile);
+ goto out1;
+ }
+ free (oldfile);
+ free (rcsfile->path);
+ rcsfile->path = xstrdup (rcs);
}
rev = RCS_getversion (rcsfile, tag, NULL, 1, (int *) NULL);
@@ -2019,7 +2021,7 @@ checkaddfile (file, repository, tag, options, rcsnode)
}
/* Set RCS keyword expansion options. */
- if (options != NULL)
+ if (options && options[0] == '-' && options[1] == 'k')
opt = options + 2;
else
opt = NULL;
@@ -2048,7 +2050,7 @@ checkaddfile (file, repository, tag, options, rcsnode)
/* when adding a file for the first time, and using a tag, we need
to create a dead revision on the trunk. */
- if (adding_on_branch && newfile)
+ if (tag && newfile)
{
char *tmp;
FILE *fp;
@@ -2110,7 +2112,7 @@ checkaddfile (file, repository, tag, options, rcsnode)
}
}
- if (adding_on_branch)
+ if (tag != NULL)
{
/* when adding with a tag, we need to stub a branch, if it
doesn't already exist. */
@@ -2137,6 +2139,8 @@ checkaddfile (file, repository, tag, options, rcsnode)
char *head;
char *magicrev;
+ fixbranch(rcsfile, sbranch);
+
head = RCS_getversion (rcsfile, NULL, NULL, 0, (int *) NULL);
magicrev = RCS_magicrev (rcsfile, head);
@@ -2174,22 +2178,13 @@ checkaddfile (file, repository, tag, options, rcsnode)
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. */
+ /* I don't think fix_rcs_modes is needed any more. In the
+ add_rcs_file case, the algorithms used by add_rcs_file and
+ fix_rcs_modes are the same, so there is no need to go through
+ it all twice. In the other cases, I think we want to just
+ preserve the mode that the file had before we started. That is
+ a behavior change, but I would think a desirable one. */
+ fix_rcs_modes (rcs, file);
retval = 0;
@@ -2223,8 +2218,7 @@ lock_RCS (user, rcs, rev, repository)
* 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))
+ if (rev == NULL || (rev && isdigit (*rev) && numdots (rev) < 2))
{
branch = xstrdup (rcs->branch);
if (branch != NULL)
@@ -2281,6 +2275,69 @@ lock_RCS (user, rcs, rev, repository)
return (1);
}
+/* Called when "add"ing files to the RCS respository. It doesn't seem to
+ be possible to get RCS to use the right mode, so we change it after
+ the fact. TODO: now that RCS has been librarified, we have the power
+ to change this. */
+
+static void
+fix_rcs_modes (rcs, user)
+ char *rcs;
+ char *user;
+{
+ struct stat sb;
+ mode_t rcs_mode;
+
+#ifdef PRESERVE_PERMISSIONS_SUPPORT
+ /* Do ye nothing to the modes on a symbolic link. */
+ if (preserve_perms && islink (user))
+ return;
+#endif
+
+ if (CVS_STAT (user, &sb) < 0)
+ {
+ /* FIXME: Should be ->fullname. */
+ error (0, errno, "warning: cannot stat %s", user);
+ return;
+ }
+
+ /* Now we compute the new mode.
+
+ TODO: decide whether this whole thing can/should be skipped
+ when `preserve_perms' is set. Almost certainly so. -twp
+
+ The algorithm that we use is:
+
+ Write permission is always off (this is what RCS and CVS have always
+ done).
+
+ If S_IRUSR is on (user read), then the read permission of
+ the RCS file will be on. It would seem that if this is off,
+ then other users can't do "cvs update" and such, so perhaps this
+ should be hardcoded to being on (it is a strange case, though--the
+ case in which a user file doesn't have user read permission on).
+
+ If S_IXUSR is on (user execute), then set execute permission
+ on the RCS file. This allows other users who check out the file
+ to get the right setting for whether a shell script (for example)
+ has the executable bit set.
+
+ The result of that calculation is modified by CVSUMASK. The
+ reason, of course, that the read and execute settings take the
+ user bit and copy it to all three bits (user, group, other), is
+ that it should be CVSUMASK, not the umask of individual users,
+ which is the sole determiner of modes in the repository. */
+
+ rcs_mode = 0;
+ if (sb.st_mode & S_IRUSR)
+ rcs_mode |= S_IRUSR | S_IRGRP | S_IROTH;
+ if (sb.st_mode & S_IXUSR)
+ rcs_mode |= S_IXUSR | S_IXGRP | S_IXOTH;
+ rcs_mode &= ~cvsumask;
+ if (chmod (rcs, rcs_mode) < 0)
+ error (0, errno, "warning: cannot change mode of %s", rcs);
+}
+
/*
* free an UPDATE node's data
*/
diff --git a/contrib/cvs/src/cvs.h b/contrib/cvs/src/cvs.h
index 8a1501c..9e0b057 100644
--- a/contrib/cvs/src/cvs.h
+++ b/contrib/cvs/src/cvs.h
@@ -187,6 +187,7 @@ extern int errno;
#define CVSROOTADM_WRITERS "writers"
#define CVSROOTADM_PASSWD "passwd"
#define CVSROOTADM_CONFIG "config"
+#define CVSROOTADM_OPTIONS "options"
#define CVSNULLREPOS "Emptydir" /* an empty directory */
@@ -256,6 +257,8 @@ extern int errno;
#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 TMPDIR_DFLT Set by options.h */
@@ -363,20 +366,16 @@ extern int really_quiet, quiet;
extern int use_editor;
extern int cvswrite;
extern mode_t cvsumask;
+extern char *RCS_citag;
/* Access method specified in CVSroot. */
typedef enum {
local_method, server_method, pserver_method, kserver_method, gserver_method,
- ext_method, fork_method
+ ext_method
} CVSmethod;
extern char *method_names[]; /* change this in root.c if you change
the enum above */
-/* 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;
-
extern char *CVSroot_original; /* the active, complete CVSroot string */
extern int client_active; /* nonzero if we are doing remote access */
extern CVSmethod CVSroot_method; /* one of the enum values above */
@@ -384,24 +383,21 @@ extern char *CVSroot_username; /* the username or NULL if method == local */
extern char *CVSroot_hostname; /* the hostname or NULL if method == local */
extern char *CVSroot_directory; /* the directory name */
-/* 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 char *current_root;
-
extern char *emptydir_name PROTO ((void));
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;
-#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
+#ifdef AUTH_SERVER_SUPPORT
+extern char *Pserver_Repos; /* used to check that same repos is
+ transmitted in pserver auth and in
+ CVS protocol. */
+#endif /* AUTH_SERVER_SUPPORT */
extern char hostname[];
@@ -442,7 +438,6 @@ 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 *, char *));
char *Name_Repository PROTO((char *dir, char *update_dir));
char *Short_Repository PROTO((char *repository));
@@ -461,7 +456,7 @@ extern void check_numeric PROTO ((const char *, int, char **));
char *getcaller PROTO((void));
char *time_stamp PROTO((char *file));
-void *xmalloc PROTO((size_t bytes));
+char *xmalloc PROTO((size_t bytes));
void *xrealloc PROTO((void *ptr, size_t bytes));
void expand_string PROTO ((char **, size_t *, size_t));
char *xstrdup PROTO((const char *str));
@@ -486,6 +481,7 @@ char *xreadlink PROTO((const char *link));
char *last_component PROTO((char *path));
char *get_homedir PROTO ((void));
char *cvs_temp_name PROTO ((void));
+void parseopts PROTO ((const char *root));
int numdots PROTO((const char *s));
char *increment_revnum PROTO ((const char *));
@@ -513,9 +509,6 @@ void lock_tree_for_write PROTO ((int argc, char **argv, int local, int aflag));
/* See lock.c for description. */
extern void lock_dir_for_write PROTO ((char *));
-
-/* LockDir setting from CVSROOT/config. */
-extern char *lock_dir;
void Scratch_Entry PROTO((List * list, char *fname));
void ParseTag PROTO((char **tagp, char **datep, int *nonbranchp));
@@ -575,7 +568,7 @@ void Update_Logfile PROTO((char *repository, char *xmessage, FILE * xlogfp,
void do_editor PROTO((char *dir, char **messagep,
char *repository, List * changes));
-void do_verify PROTO((char *message, char *repository));
+void do_verify PROTO((char **messagep, char *repository));
typedef int (*CALLBACKPROC) PROTO((int *pargc, char *argv[], char *where,
char *mwhere, char *mfile, int shorten, int local_specified,
@@ -642,7 +635,6 @@ char *make_message_rcslegal PROTO((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 void resolve_symlink PROTO ((char **filename));
/* flags for run_exec(), the fast system() for CVS */
#define RUN_NORMAL 0x0000 /* no special behaviour */
@@ -663,6 +655,7 @@ int run_exec PROTO((const char *stin, const char *stout, const char *sterr,
FILE *run_popen PROTO((const char *, const char *));
int piped_child PROTO((char **, int *, int *));
void close_on_exec PROTO((int));
+int filter_stream_through_program PROTO((int, int, char **, pid_t *));
pid_t waitpid PROTO((pid_t, int *, int));
diff --git a/contrib/cvs/src/diff.c b/contrib/cvs/src/diff.c
index e98938d..d5e3a7c 100644
--- a/contrib/cvs/src/diff.c
+++ b/contrib/cvs/src/diff.c
@@ -40,13 +40,7 @@ static enum diff_file diff_file_nodiff PROTO ((struct file_info *finfo,
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 *use_rev1, *use_rev2;
static int have_rev1_label, have_rev2_label;
@@ -230,19 +224,15 @@ diff (argc, argv)
* 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). */
+ /* For server, need to be able to do this command more than once
+ (according to the protocol spec, even if the current client
+ doesn't use it). */
if (opts == NULL)
{
opts_allocated = 1;
opts = xmalloc (opts_allocated);
}
opts[0] = '\0';
- diff_rev1 = NULL;
- diff_rev2 = NULL;
- diff_date1 = NULL;
- diff_date2 = NULL;
optind = 0;
while ((c = getopt_long (argc, argv,
@@ -277,7 +267,7 @@ diff (argc, argv)
break;
case 131:
/* --ifdef. */
- strcat_and_allocate (&opts, &opts_allocated, " --ifdef=");
+ strcat_and_allocate (&opts, &opts_allocated, " -D");
strcat_and_allocate (&opts, &opts_allocated, optarg);
break;
case 129: case 130: case 132: case 133: case 134:
@@ -363,18 +353,17 @@ diff (argc, argv)
if (diff_date2)
client_senddate (diff_date2);
+ send_file_names (argc, argv, SEND_EXPAND_WILD);
+
/* 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 ();
free (options);
- options = NULL;
return (err);
}
#endif
@@ -397,13 +386,6 @@ diff (argc, argv)
/* clean up */
free (options);
- options = NULL;
-
- if (diff_date1 != NULL)
- free (diff_date1);
- if (diff_date2 != NULL)
- free (diff_date2);
-
return (err);
}
@@ -457,7 +439,8 @@ diff_fileproc (callerdat, finfo)
(vers->vn_rcs == NULL
? NULL
: RCS_branch_head (vers->srcfile, vers->vn_rcs));
- exists = head != NULL;
+ exists = (head != NULL
+ && !RCS_isdead (vers->srcfile, head));
if (head != NULL)
free (head);
}
@@ -467,7 +450,8 @@ diff_fileproc (callerdat, finfo)
xvers = Version_TS (finfo, NULL, diff_rev1, diff_date1,
1, 0);
- exists = xvers->vn_rcs != NULL;
+ exists = (xvers->vn_rcs != NULL
+ && !RCS_isdead (xvers->srcfile, xvers->vn_rcs));
freevers_ts (&xvers);
}
if (exists)
diff --git a/contrib/cvs/src/filesubr.c b/contrib/cvs/src/filesubr.c
index f3da62a..91af048 100644
--- a/contrib/cvs/src/filesubr.c
+++ b/contrib/cvs/src/filesubr.c
@@ -34,8 +34,12 @@ copy_file (from, to)
int fdin, fdout;
if (trace)
- (void) fprintf (stderr, "%s-> copy(%s,%s)\n",
- CLIENT_SERVER_STR, from, to);
+#ifdef SERVER_SUPPORT
+ (void) fprintf (stderr, "%c-> copy(%s,%s)\n",
+ (server_active) ? 'S' : ' ', from, to);
+#else
+ (void) fprintf (stderr, "-> copy(%s,%s)\n", from, to);
+#endif
if (noexec)
return;
@@ -373,9 +377,14 @@ xchmod (fname, writable)
}
if (trace)
- (void) fprintf (stderr, "%s-> chmod(%s,%o)\n",
- CLIENT_SERVER_STR, fname,
+#ifdef SERVER_SUPPORT
+ (void) fprintf (stderr, "%c-> chmod(%s,%o)\n",
+ (server_active) ? 'S' : ' ', fname,
(unsigned int) mode);
+#else
+ (void) fprintf (stderr, "-> chmod(%s,%o)\n", fname,
+ (unsigned int) mode);
+#endif
if (noexec)
return;
@@ -392,8 +401,12 @@ rename_file (from, to)
const char *to;
{
if (trace)
- (void) fprintf (stderr, "%s-> rename(%s,%s)\n",
- CLIENT_SERVER_STR, from, to);
+#ifdef SERVER_SUPPORT
+ (void) fprintf (stderr, "%c-> rename(%s,%s)\n",
+ (server_active) ? 'S' : ' ', from, to);
+#else
+ (void) fprintf (stderr, "-> rename(%s,%s)\n", from, to);
+#endif
if (noexec)
return;
@@ -409,8 +422,12 @@ unlink_file (f)
const char *f;
{
if (trace)
- (void) fprintf (stderr, "%s-> unlink(%s)\n",
- CLIENT_SERVER_STR, f);
+#ifdef SERVER_SUPPORT
+ (void) fprintf (stderr, "%c-> unlink(%s)\n",
+ (server_active) ? 'S' : ' ', f);
+#else
+ (void) fprintf (stderr, "-> unlink(%s)\n", f);
+#endif
if (noexec)
return (0);
@@ -489,7 +506,6 @@ deep_remove_dir (path)
*/
return -1;
- errno = 0;
while ((dp = readdir (dirp)) != NULL)
{
char *buf;
@@ -523,15 +539,6 @@ deep_remove_dir (path)
}
}
free (buf);
-
- errno = 0;
- }
- if (errno != 0)
- {
- int save_errno = errno;
- closedir (dirp);
- errno = save_errno;
- return -1;
}
closedir (dirp);
return rmdir (path);
@@ -741,8 +748,8 @@ xreadlink (link)
{
char *file = NULL;
char *tfile;
- int buflen = 128;
- int link_name_len;
+ int buflen = BUFSIZ;
+ int linklen;
if (!islink (link))
return NULL;
@@ -753,15 +760,15 @@ xreadlink (link)
do
{
file = xrealloc (file, buflen);
- link_name_len = readlink (link, file, buflen - 1);
+ errno = 0;
+ linklen = readlink (link, file, buflen - 1);
buflen *= 2;
}
- while (link_name_len < 0 && errno == ENAMETOOLONG);
+ while (linklen == -1 && errno == ENAMETOOLONG);
- if (link_name_len < 0)
+ if (linklen == -1)
error (1, errno, "cannot readlink %s", link);
-
- file[link_name_len] = '\0';
+ file[linklen] = '\0';
tfile = xstrdup (file);
free (file);
diff --git a/contrib/cvs/src/import.c b/contrib/cvs/src/import.c
index 57ff619..cc84258 100644
--- a/contrib/cvs/src/import.c
+++ b/contrib/cvs/src/import.c
@@ -94,17 +94,6 @@ import (argc, argv)
command_name);
break;
case 'd':
-#ifdef SERVER_SUPPORT
- 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");
- }
-#endif
use_file_modtime = 1;
break;
case 'b':
@@ -143,20 +132,6 @@ import (argc, argv)
if (argc < 3)
usage (import_usage);
-#ifdef SERVER_SUPPORT
- /* 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;
-#endif
-
for (i = 1; i < argc; i++) /* check the tags for validity */
{
int j;
@@ -168,8 +143,7 @@ import (argc, argv)
}
/* XXX - this should be a module, not just a pathname */
- if (! isabsolute (argv[0])
- && pathname_levels (argv[0]) == 0)
+ if (! isabsolute (argv[0]))
{
if (CVSroot_directory == NULL)
{
@@ -184,11 +158,9 @@ import (argc, argv)
}
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]);
+ repository = xmalloc (strlen (argv[0]) + 5);
+ (void) strcpy (repository, argv[0]);
+ repos_len = 0;
}
/*
@@ -198,7 +170,7 @@ import (argc, argv)
* must only have two dots in it (like "1.1.1").
*/
for (cp = vbranch; *cp != '\0'; cp++)
- if (!isdigit ((unsigned char) *cp) && *cp != '.')
+ if (!isdigit (*cp) && *cp != '.')
error (1, 0, "%s is not a numeric branch", vbranch);
if (numdots (vbranch) != 2)
error (1, 0, "Only branches with two dots are supported: %s", vbranch);
@@ -220,7 +192,7 @@ import (argc, argv)
do_editor ((char *) NULL, &message, repository,
(List *) NULL);
}
- do_verify (message, repository);
+ do_verify (&message, repository);
msglen = message == NULL ? 0 : strlen (message);
if (msglen == 0 || message[msglen - 1] != '\n')
{
@@ -240,6 +212,9 @@ import (argc, argv)
{
int err;
+ if (use_file_modtime)
+ send_arg("-d");
+
if (vbranch[0] != '\0')
option_with_arg ("-b", vbranch);
if (message)
@@ -300,52 +275,29 @@ import (argc, argv)
{
if (!really_quiet)
{
- char buf[20];
- char *buf2;
-
- 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");
- buf2 = xmalloc (strlen (argv[1]) + 20);
- sprintf (buf2, "%s:yesterday", argv[1]);
- cvs_output_tagged ("mergetag1", buf2);
- free (buf2);
- cvs_output_tagged ("text", " -j");
- cvs_output_tagged ("mergetag2", argv[1]);
- 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);
+ char buf[80];
+ sprintf (buf, "\n%d conflicts created by this import.\n",
+ 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);
+ cvs_output (" checkout -j", 0);
+ cvs_output (argv[1], 0);
+ cvs_output (":yesterday -j", 0);
+ cvs_output (argv[1], 0);
+ cvs_output (" ", 1);
+ cvs_output (argv[0], 0);
+ cvs_output ("\n\n", 0);
}
- /* 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]);
+ (void) fprintf (logfp, "\t%s checkout -j%s:yesterday -j%s %s\n\n",
+ program_name, argv[1], argv[1], argv[0]);
}
else
{
@@ -388,9 +340,9 @@ import (argc, argv)
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). */
+/*
+ * process all the files in ".", then descend into other directories.
+ */
static int
import_descend (message, vtag, targc, targv)
char *message;
@@ -409,27 +361,25 @@ import_descend (message, vtag, targc, targv)
if ((dirp = CVS_OPENDIR (".")) == NULL)
{
- error (0, errno, "cannot open directory");
err++;
}
else
{
- errno = 0;
while ((dp = readdir (dirp)) != NULL)
{
if (strcmp (dp->d_name, ".") == 0 || strcmp (dp->d_name, "..") == 0)
- goto one_more_time_boys;
+ continue;
#ifdef SERVER_SUPPORT
/* 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;
+ continue;
#endif
if (ign_name (dp->d_name))
{
add_log ('I', dp->d_name);
- goto one_more_time_boys;
+ continue;
}
if (
@@ -468,20 +418,12 @@ import_descend (message, vtag, targc, targv)
vtag, targc, targv,
repository,
keyword_opt != NULL &&
- keyword_opt[0] == 'b',
- use_file_modtime);
+ keyword_opt[0] == 'b');
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) closedir (dirp);
}
@@ -932,7 +874,7 @@ get_comment (user)
*/
(void) strcpy (suffix_path, cp);
for (cp = suffix_path; *cp; cp++)
- if (isupper ((unsigned char) *cp))
+ if (isupper (*cp))
*cp = tolower (*cp);
suffix = suffix_path;
}
diff --git a/contrib/cvs/src/lock.c b/contrib/cvs/src/lock.c
index 3776b2c..1f2ccad 100644
--- a/contrib/cvs/src/lock.c
+++ b/contrib/cvs/src/lock.c
@@ -73,7 +73,6 @@
unneeded complication although it presumably would be faster). */
#include "cvs.h"
-#include <assert.h>
struct lock {
/* This is the directory in which we may have a lock named by the
@@ -135,161 +134,12 @@ static List *lock_tree_list;
static char *locked_dir;
static List *locked_list;
-/* LockDir from CVSROOT/config. */
-char *lock_dir;
-
-static char *lock_name PROTO ((char *repository, 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)
- char *repository;
- char *name;
-{
- char *retval;
- char *p;
- char *q;
- char *short_repos;
- mode_t save_umask;
- 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 (CVSroot_directory != NULL);
- assert (strncmp (repository, CVSroot_directory,
- strlen (CVSroot_directory)) == 0);
- short_repos = repository + strlen (CVSroot_directory);
- assert (*short_repos++ == '/');
-
- 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 (in_lock_cleanup)
- return;
- in_lock_cleanup = 1;
-
remove_locks ();
dellist (&lock_tree_list);
@@ -301,7 +151,6 @@ Lock_Cleanup ()
locked_dir = NULL;
locked_list = NULL;
}
- in_lock_cleanup = 0;
}
/*
@@ -350,7 +199,8 @@ lock_simple_remove (lock)
existence_error here. */
if (readlock != NULL)
{
- tmp = lock_name (lock->repository, readlock);
+ tmp = xmalloc (strlen (lock->repository) + strlen (readlock) + 10);
+ (void) sprintf (tmp, "%s/%s", lock->repository, readlock);
if ( CVS_UNLINK (tmp) < 0 && ! existence_error (errno))
error (0, errno, "failed to remove lock %s", tmp);
free (tmp);
@@ -362,7 +212,8 @@ lock_simple_remove (lock)
existence_error here. */
if (writelock != NULL)
{
- tmp = lock_name (lock->repository, writelock);
+ tmp = xmalloc (strlen (lock->repository) + strlen (writelock) + 10);
+ (void) sprintf (tmp, "%s/%s", lock->repository, writelock);
if ( CVS_UNLINK (tmp) < 0 && ! existence_error (errno))
error (0, errno, "failed to remove lock %s", tmp);
free (tmp);
@@ -370,7 +221,8 @@ lock_simple_remove (lock)
if (lock->have_lckdir)
{
- tmp = lock_name (lock->repository, CVSLCK);
+ tmp = xmalloc (strlen (lock->repository) + sizeof (CVSLCK) + 10);
+ (void) sprintf (tmp, "%s/%s", lock->repository, CVSLCK);
SIG_beginCrSect ();
if (CVS_RMDIR (tmp) < 0)
error (0, errno, "failed to remove lock dir %s", tmp);
@@ -391,7 +243,7 @@ Reader_Lock (xrepository)
FILE *fp;
char *tmp;
- if (noexec)
+ if (noexec || readonlyfs)
return (0);
/* we only do one directory at a time for read locks! */
@@ -431,7 +283,8 @@ Reader_Lock (xrepository)
}
/* write a read-lock */
- tmp = lock_name (xrepository, readlock);
+ tmp = xmalloc (strlen (xrepository) + strlen (readlock) + 10);
+ (void) sprintf (tmp, "%s/%s", xrepository, readlock);
if ((fp = CVS_FOPEN (tmp, "w+")) == NULL || fclose (fp) == EOF)
{
error (0, errno, "cannot create read lock in repository `%s'",
@@ -466,6 +319,11 @@ Writer_Lock (list)
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)
{
@@ -579,7 +437,8 @@ write_lock (lock)
}
/* write the write-lock file */
- tmp = lock_name (lock->repository, writelock);
+ tmp = xmalloc (strlen (lock->repository) + strlen (writelock) + 10);
+ (void) sprintf (tmp, "%s/%s", lock->repository, writelock);
if ((fp = CVS_FOPEN (tmp, "w+")) == NULL || fclose (fp) == EOF)
{
int xerrno = errno;
@@ -723,7 +582,8 @@ set_lock (lock, will_wait)
if (masterlock != NULL)
free (masterlock);
- masterlock = lock_name (lock->repository, CVSLCK);
+ masterlock = xmalloc (strlen (lock->repository) + sizeof (CVSLCK) + 10);
+ (void) sprintf (masterlock, "%s/%s", lock->repository, CVSLCK);
/*
* Note that it is up to the callers of set_lock() to arrange for signal
@@ -820,17 +680,13 @@ lock_wait (repos)
char *repos;
{
time_t now;
- char *msg;
(void) time (&now);
- msg = xmalloc (100 + strlen (lockers_name) + strlen (repos));
- sprintf (msg, "[%8.8s] waiting for %s's lock in %s", ctime (&now) + 11,
- lockers_name, repos);
- error (0, 0, "%s", msg);
+ error (0, 0, "[%8.8s] waiting for %s's lock in %s", ctime (&now) + 11,
+ lockers_name, repos);
/* Call cvs_flusherr to ensure that the user sees this message as
soon as possible. */
cvs_flusherr ();
- free (msg);
(void) sleep (CVSLCKSLEEP);
}
@@ -842,16 +698,12 @@ lock_obtained (repos)
char *repos;
{
time_t now;
- char *msg;
(void) time (&now);
- msg = xmalloc (100 + strlen (repos));
- sprintf (msg, "[%8.8s] obtained lock in %s", ctime (&now) + 11, repos);
- error (0, 0, "%s", msg);
+ error (0, 0, "[%8.8s] obtained lock in %s", ctime (&now) + 11, repos);
/* Call cvs_flusherr to ensure that the user sees this message as
soon as possible. */
cvs_flusherr ();
- free (msg);
}
static int lock_filesdoneproc PROTO ((void *callerdat, int err,
diff --git a/contrib/cvs/src/login.c b/contrib/cvs/src/login.c
index 46707e2..0a74f37 100644
--- a/contrib/cvs/src/login.c
+++ b/contrib/cvs/src/login.c
@@ -48,14 +48,7 @@ construct_cvspass_filename ()
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");
+ error (1, errno, "could not find out home directory");
return (char *) NULL;
}
@@ -253,8 +246,7 @@ login (argc, argv)
/* FIXME: rename_file would make more sense (e.g. almost
always faster). */
copy_file (tmp_name, passfile);
- if (unlink_file (tmp_name) < 0)
- error (0, errno, "cannot remove %s", tmp_name);
+ unlink_file (tmp_name);
chmod (passfile, 0600);
free (tmp_name);
@@ -301,6 +293,9 @@ get_cvs_password ()
FILE *fp;
char *passfile;
int line_length;
+ int anoncvs;
+
+ anoncvs = (strcmp(CVSroot_username, "anoncvs") == 0);
/* If someone (i.e., login()) is calling connect_to_pserver() out of
context, then assume they have supplied the correct, scrambled
@@ -341,6 +336,10 @@ get_cvs_password ()
fp = CVS_FOPEN (passfile, "r");
if (fp == NULL)
{
+ if (anoncvs) {
+ free (passfile);
+ return strdup("Ay=0=h<Z"); /* scrambled "anoncvs" */
+ }
error (0, errno, "could not open %s", passfile);
free (passfile);
error (1, 0, "use \"cvs login\" to log in first");
@@ -362,6 +361,7 @@ get_cvs_password ()
error (0, errno, "cannot read %s", passfile);
if (fclose (fp) < 0)
error (0, errno, "cannot close %s", passfile);
+ free (passfile);
if (found_it)
{
@@ -381,6 +381,8 @@ get_cvs_password ()
{
if (linebuf)
free (linebuf);
+ if (anoncvs)
+ return strdup("Ay=0=h<Z"); /* scrambled "anoncvs" */
error (0, 0, "cannot find password");
error (1, 0, "use \"cvs login\" to log in first");
}
@@ -445,8 +447,6 @@ logout (argc, argv)
*/
passfile = construct_cvspass_filename ();
- /* FIXME: This should not be in /tmp; that is almost surely a security
- hole. Probably should just keep it in memory. */
tmp_name = cvs_temp_name ();
if ((tmp_fp = CVS_FOPEN (tmp_name, "w")) == NULL)
{
@@ -486,16 +486,14 @@ logout (argc, argv)
if (! found)
{
printf ("Entry not found for %s\n", CVSroot_original);
- if (unlink_file (tmp_name) < 0)
- error (0, errno, "cannot remove %s", tmp_name);
+ unlink_file (tmp_name);
}
else
{
/* FIXME: rename_file would make more sense (e.g. almost
always faster). */
copy_file (tmp_name, passfile);
- if (unlink_file (tmp_name) < 0)
- error (0, errno, "cannot remove %s", tmp_name);
+ unlink_file (tmp_name);
chmod (passfile, 0600);
}
return 0;
diff --git a/contrib/cvs/src/logmsg.c b/contrib/cvs/src/logmsg.c
index 6d45ca3..6807937 100644
--- a/contrib/cvs/src/logmsg.c
+++ b/contrib/cvs/src/logmsg.c
@@ -385,14 +385,20 @@ do_editor (dir, messagep, repository, changes)
independant of the running of an editor for getting a message.
*/
void
-do_verify (message, repository)
- char *message;
+do_verify (messagep, repository)
+ char **messagep;
char *repository;
{
FILE *fp;
char *fname;
int retcode = 0;
+ char *line;
+ int line_length;
+ size_t line_chars_allocated;
+ char *p;
+ struct stat stbuf;
+
#ifdef CLIENT_SUPPORT
if (client_active)
/* The verification will happen on the server. */
@@ -406,7 +412,7 @@ do_verify (message, repository)
/* If there's no message, then we have nothing to verify. Can this
case happen? And if so why would we print a message? */
- if (message == NULL)
+ if (*messagep == NULL)
{
cvs_output ("No message to verify\n", 0);
return;
@@ -422,9 +428,9 @@ do_verify (message, repository)
error (1, errno, "cannot create temporary file %s", fname);
else
{
- fprintf (fp, "%s", message);
- if ((message)[0] == '\0' ||
- (message)[strlen (message) - 1] != '\n')
+ fprintf (fp, "%s", *messagep);
+ if ((*messagep)[0] == '\0' ||
+ (*messagep)[strlen (*messagep) - 1] != '\n')
(void) fprintf (fp, "%s", "\n");
if (fclose (fp) == EOF)
error (1, errno, "%s", fname);
@@ -446,18 +452,65 @@ do_verify (message, repository)
{
/* Since following error() exits, delete the temp file
now. */
- if (unlink_file (fname) < 0)
- error (0, errno, "cannot remove %s", fname);
+ unlink_file (fname);
error (1, retcode == -1 ? errno : 0,
"Message verification failed");
}
}
+ /* put the entire message back into the *messagep variable */
+
+ fp = open_file (fname, "r");
+ if (fp == NULL)
+ {
+ error (1, errno, "cannot open temporary file %s", fname);
+ return;
+ }
+
+ if (*messagep)
+ free (*messagep);
+
+ if ( CVS_STAT (fname, &stbuf) != 0)
+ error (1, errno, "cannot find size of temp file %s", fname);
+
+ if (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 (stbuf.st_size + 1);
+ *messagep[0] = '\0';
+ }
+
+ line = NULL;
+ line_chars_allocated = 0;
+
+ if (*messagep)
+ {
+ p = *messagep;
+ 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;
+ (void) strcpy (p, line);
+ p += line_length;
+ }
+ }
+ 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);
+ unlink_file (fname);
free (fname);
}
}
diff --git a/contrib/cvs/src/main.c b/contrib/cvs/src/main.c
index e211db6..6792245 100644
--- a/contrib/cvs/src/main.c
+++ b/contrib/cvs/src/main.c
@@ -12,8 +12,10 @@
*
*/
-#include <assert.h>
+/* $FreeBSD$ */
+
#include "cvs.h"
+#include "prepend_args.h"
#ifdef HAVE_WINSOCK_H
#include <winsock.h>
@@ -41,6 +43,8 @@ int really_quiet = 0;
int quiet = 0;
int trace = 0;
int noexec = 0;
+int readonlyfs = 0;
+int require_real_user = 0;
int logoff = 0;
/* Set if we should be writing CVSADM directories at top level. At
@@ -58,16 +62,6 @@ char *CurDir;
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;
-
-/* We step through the above values. This variable is set to reflect
- the currently active value. */
-char *current_root = NULL;
-
-
static const struct cmd
{
char *fullname; /* Full name of the function (e.g. "commit") */
@@ -220,17 +214,19 @@ static const char *const cmd_usage[] =
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",
" -l Turn history logging off.\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",
+ " -b bindir Find RCS programs in 'bindir'.\n",
" -T tmpdir Use 'tmpdir' for temporary files.\n",
" -e editor Use 'editor' for editing log information.\n",
" -d CVS_root Overrides $CVSROOT as the root of the CVS tree.\n",
@@ -247,21 +243,6 @@ static const char *const opt_usage[] =
NULL
};
-
-static int
-set_root_directory (p, ignored)
- Node *p;
- void *ignored;
-{
- if (current_root == NULL && p->data == NULL)
- {
- current_root = p->key;
- return 1;
- }
- return 0;
-}
-
-
static const char * const*
cmd_synonyms ()
{
@@ -337,6 +318,7 @@ lookup_command_attribute (cmd_name)
(strcmp (cmd_name, "diff") != 0) &&
(strcmp (cmd_name, "rdiff") != 0) &&
(strcmp (cmd_name, "update") != 0) &&
+ (strcmp (cmd_name, "history") != 0) &&
(strcmp (cmd_name, "editors") != 0) &&
(strcmp (cmd_name, "export") != 0) &&
(strcmp (cmd_name, "history") != 0) &&
@@ -431,6 +413,7 @@ main (argc, argv)
/* `getopt_long' stores the option index here, but right now we
don't use it. */
int option_index = 0;
+ int need_to_create_root = 0;
#ifdef SYSTEM_INITIALIZE
/* Hook for OS-specific behavior, for example socket subsystems on
@@ -480,6 +463,12 @@ main (argc, argv)
}
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. */
@@ -509,7 +498,7 @@ main (argc, argv)
opterr = 1;
while ((c = getopt_long
- (argc, argv, "+Qqrwtnlvb:T:e:d:Hfz:s:xa", long_options, &option_index))
+ (argc, argv, "+QqgrwtnRlvb:T:e:d:Hfz:s:xaU", long_options, &option_index))
!= EOF)
{
switch (c)
@@ -542,9 +531,20 @@ main (argc, argv)
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;
case 'l': /* Fall through */
@@ -586,9 +586,6 @@ Copyright (c) 1989-1998 Brian Berliner, david d `zoo' zuhn, \n\
free_Editor = 1;
break;
case 'd':
- if (CVSroot_cmdline != NULL)
- free (CVSroot_cmdline);
- CVSroot_cmdline = xstrdup (optarg);
CVSroot = xstrdup (optarg);
free_CVSroot = 1;
cvs_update_env = 1; /* need to update environment */
@@ -631,6 +628,11 @@ Copyright (c) 1989-1998 Brian Berliner, david d `zoo' zuhn, \n\
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);
@@ -671,10 +673,7 @@ Copyright (c) 1989-1998 Brian Berliner, david d `zoo' zuhn, \n\
}
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,
@@ -731,79 +730,10 @@ Copyright (c) 1989-1998 Brian Berliner, david d `zoo' zuhn, \n\
#ifdef SERVER_SUPPORT
server_active = strcmp (command_name, "server") == 0;
-#endif
-
- /* This is only used for writing into the history file. For
- remote connections, it might be nice to have hostname
- and/or remote path, on the other hand I'm not sure whether
- it is worth the trouble. */
-
-#ifdef SERVER_SUPPORT
- if (server_active)
- CurDir = xstrdup ("<remote>");
- else
-#endif
- {
- CurDir = xgetwd ();
- if (CurDir == NULL)
- error (1, errno, "cannot get working directory");
- }
-
- if (Tmpdir == NULL || Tmpdir[0] == '\0')
- 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 */
- }
-#endif
-
-#ifndef DONT_USE_SIGNALS
- /* make sure we clean up on error */
-#ifdef SIGHUP
- (void) SIG_register (SIGHUP, main_cleanup);
- (void) SIG_register (SIGHUP, Lock_Cleanup);
-#endif
-#ifdef SIGINT
- (void) SIG_register (SIGINT, main_cleanup);
- (void) SIG_register (SIGINT, Lock_Cleanup);
-#endif
-#ifdef SIGQUIT
- (void) SIG_register (SIGQUIT, main_cleanup);
- (void) SIG_register (SIGQUIT, Lock_Cleanup);
-#endif
-#ifdef SIGPIPE
- (void) SIG_register (SIGPIPE, main_cleanup);
- (void) SIG_register (SIGPIPE, Lock_Cleanup);
-#endif
-#ifdef SIGTERM
- (void) SIG_register (SIGTERM, main_cleanup);
- (void) SIG_register (SIGTERM, Lock_Cleanup);
-#endif
-#endif /* !DONT_USE_SIGNALS */
-
- 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, command_name);
-#ifdef SERVER_SUPPORT
/* 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. */
+ in server mode, since the client will send the repository
+ directory after the connection is made. */
if (!server_active)
#endif
@@ -820,15 +750,11 @@ Copyright (c) 1989-1998 Brian Berliner, david d `zoo' zuhn, \n\
specify a different repository than the one we are
importing to. */
- if ((lookup_command_attribute (command_name)
- & CVS_CMD_IGNORE_ADMROOT)
-
- /* -d overrides CVS/Root, so don't give an error if the
- latter points to a nonexistent repository. */
- && CVSroot_cmdline == NULL)
- {
+ if (lookup_command_attribute (command_name)
+ & CVS_CMD_IGNORE_ADMROOT)
+ {
CVSADM_Root = Name_Root((char *) NULL, (char *) NULL);
- }
+ }
if (CVSADM_Root != NULL)
{
@@ -837,11 +763,39 @@ Copyright (c) 1989-1998 Brian Berliner, david d `zoo' zuhn, \n\
CVSroot = CVSADM_Root;
cvs_update_env = 1; /* need to update environment */
}
+ /* Let -d override CVS/Root file. The user might want
+ to change the access method, use a different server
+ (if there are two server machines which share the
+ repository using a networked file system), etc. */
+ else if (
+#ifdef CLIENT_SUPPORT
+ !getenv ("CVS_IGNORE_REMOTE_ROOT") &&
+#endif
+ strcmp (CVSroot, CVSADM_Root) != 0)
+ {
+ /* Once we have verified that this root is usable,
+ we will want to write it into CVS/Root.
+
+ Don't do it for the "login" command, however.
+ Consider: if the user executes "cvs login" with
+ the working directory inside an already checked
+ out module, we'd incorrectly change the
+ CVS/Root file to reflect the CVSROOT of the
+ "cvs login" command. Ahh, the things one
+ discovers. */
+
+ if (lookup_command_attribute (command_name)
+ & CVS_CMD_USES_WORK_DIR)
+ {
+ need_to_create_root = 1;
+ }
+
+ }
}
/* 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. */
+ CVS/Root file, and the environment variable. Do the
+ last sanity checks on the variable. */
if (! CVSroot)
{
@@ -863,180 +817,181 @@ Copyright (c) 1989-1998 Brian Berliner, david d `zoo' zuhn, \n\
error (1, 0,
"CVS/Root file (if any).");
}
- }
-
- /* 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 ();
+ /* 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. */
- /* Prime it. */
- if (CVSroot != NULL)
- {
- Node *n;
- n = getnode ();
- n->type = UNKNOWN;
- n->key = xstrdup (CVSroot);
- n->data = NULL;
-
- if (addnode (root_directories, n))
- error (1, 0, "cannot add initial CVSROOT %s", n->key);
- }
+ if (parse_cvsroot (CVSroot))
+ error (1, 0, "Bad CVSROOT.");
- assert (current_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 (
-#ifdef SERVER_SUPPORT
- server_active ||
-#endif
- walklist (root_directories, set_root_directory, NULL)
- )
- {
-#ifdef SERVER_SUPPORT
- /* 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. */
+ /*
+ * Check to see if we can write into the history file. If not,
+ * we assume that we can't work in the repository.
+ * BUT, only if the history file exists.
+ */
- if (!server_active)
-#endif
+ if (!client_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 (parse_cvsroot (current_root))
- error (1, 0, "Bad CVSROOT.");
-
- if (trace)
- error (0, 0, "notice: main loop with CVSROOT=%s",
- current_root);
-
- /*
- * Check to see if we can write into the history file. If not,
- * we assume that we can't work in the repository.
- * BUT, only if the history file exists.
- */
-
- if (!client_active)
+ char *path;
+ int save_errno;
+
+ path = xmalloc (strlen (CVSroot_directory)
+ + sizeof (CVSROOTADM)
+ + 20
+ + sizeof (CVSROOTADM_HISTORY));
+ (void) sprintf (path, "%s/%s", CVSroot_directory, CVSROOTADM);
+ if (!isaccessible (path, R_OK | X_OK))
{
- char *path;
- int save_errno;
-
- path = xmalloc (strlen (CVSroot_directory)
- + sizeof (CVSROOTADM)
- + 20
- + sizeof (CVSROOTADM_HISTORY));
- (void) sprintf (path, "%s/%s", CVSroot_directory, CVSROOTADM);
- if (!isaccessible (path, R_OK | X_OK))
- {
- save_errno = errno;
- /* If this is "cvs init", the root need not exist yet. */
- if (strcmp (command_name, "init") != 0)
- {
- error (1, save_errno, "%s", path);
- }
- }
- (void) strcat (path, "/");
- (void) strcat (path, CVSROOTADM_HISTORY);
- if (isfile (path) && !isaccessible (path, R_OK | W_OK))
+ save_errno = errno;
+ /* If this is "cvs init", the root need not exist yet. */
+ if (strcmp (command_name, "init") != 0)
{
- save_errno = errno;
- error (0, 0, "Sorry, you don't have read/write access to the history file");
error (1, save_errno, "%s", path);
}
- free (path);
}
-
-#ifdef HAVE_PUTENV
- /* Update the CVSROOT environment variable if necessary. */
- /* FIXME (njc): should we always set this with the CVSROOT from the command line? */
- if (cvs_update_env)
+ (void) strcat (path, "/");
+ (void) strcat (path, CVSROOTADM_HISTORY);
+ if (readonlyfs == 0 && isfile (path) && !isaccessible (path, R_OK | W_OK))
{
- char *env;
- env = xmalloc (strlen (CVSROOT_ENV) + strlen (CVSroot)
- + 1 + 1);
- (void) sprintf (env, "%s=%s", CVSROOT_ENV, CVSroot);
- (void) putenv (env);
- /* do not free env, as putenv has control of it */
+ save_errno = errno;
+ error (0, 0, "Sorry, you don't have read/write access to the history file");
+ error (1, save_errno, "%s", path);
}
-#endif
+ free (path);
}
+
+#ifdef HAVE_PUTENV
+ /* Update the CVSROOT environment variable if necessary. */
+
+ if (cvs_update_env)
+ {
+ char *env;
+ env = xmalloc (strlen (CVSROOT_ENV) + strlen (CVSroot)
+ + 1 + 1);
+ (void) sprintf (env, "%s=%s", CVSROOT_ENV, CVSroot);
+ (void) putenv (env);
+ /* do not free env, as putenv has control of it */
+ }
+#endif
+ }
- /* 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 (1
+ /* 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. */
+
#ifdef SERVER_SUPPORT
- && !server_active
+ if (server_active)
+ CurDir = xstrdup ("<remote>");
+ else
#endif
-#ifdef CLIENT_SUPPORT
- && !client_active
+ {
+ CurDir = xgetwd ();
+ if (CurDir == NULL)
+ error (1, errno, "cannot get working directory");
+ }
+
+ if (Tmpdir == NULL || Tmpdir[0] == '\0')
+ 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
- )
- {
- /* 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 (CVSroot_directory);
- }
-#ifdef CLIENT_SUPPORT
- if (client_active)
- {
- /* 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 ();
- }
+#ifndef DONT_USE_SIGNALS
+ /* make sure we clean up on error */
+#ifdef SIGHUP
+ (void) SIG_register (SIGHUP, main_cleanup);
+ (void) SIG_register (SIGHUP, Lock_Cleanup);
#endif
+#ifdef SIGINT
+ (void) SIG_register (SIGINT, main_cleanup);
+ (void) SIG_register (SIGINT, Lock_Cleanup);
+#endif
+#ifdef SIGQUIT
+ (void) SIG_register (SIGQUIT, main_cleanup);
+ (void) SIG_register (SIGQUIT, Lock_Cleanup);
+#endif
+#ifdef SIGPIPE
+ (void) SIG_register (SIGPIPE, main_cleanup);
+ (void) SIG_register (SIGPIPE, Lock_Cleanup);
+#endif
+#ifdef SIGTERM
+ (void) SIG_register (SIGTERM, main_cleanup);
+ (void) SIG_register (SIGTERM, Lock_Cleanup);
+#endif
+#endif /* !DONT_USE_SIGNALS */
- err = (*(cm->func)) (argc, argv);
-
- /* Mark this root directory as done. When the server is
- active, current_root will be NULL -- don't try and
- remove it from the list. */
+ gethostname(hostname, sizeof (hostname));
- if (current_root != NULL)
- {
- Node *n = findnode (root_directories, current_root);
- assert (n != NULL);
- n->data = (void *) 1;
- current_root = NULL;
- }
-
-#if 0
- /* This will not work yet, since it tries to free (void *) 1. */
- dellist (&root_directories);
-#endif
+#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, command_name);
+
+ /* 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 (1
#ifdef SERVER_SUPPORT
- if (server_active)
- break;
+ && !server_active
#endif
- } /* end of loop for cvsroot values */
-
+#ifdef CLIENT_SUPPORT
+ && !client_active
+#endif
+ )
+ {
+ /* 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 (CVSroot_directory);
+
+ /* Now is a convenient time to read CVSROOT/options */
+ parseopts(CVSroot_directory);
+ }
} /* end of stuff that gets done if the user DOESN'T ask for help */
+ err = (*(cm->func)) (argc, argv);
+
+ if (need_to_create_root)
+ {
+ /* Update the CVS/Root file. We might want to do this in
+ all directories that we recurse into, but currently we
+ don't. Note that if there is an error writing the file,
+ we give an error/warning. This is so if users try to rewrite
+ CVS/Root with the -d option (a documented feature), they will
+ either succeed, or be told why it didn't work. */
+ Create_Root (NULL, CVSroot);
+ }
+
Lock_Cleanup ();
free (program_path);
- if (CVSroot_cmdline != NULL)
- free (CVSroot_cmdline);
if (free_CVSroot)
free (CVSroot);
if (free_Editor)
@@ -1103,43 +1058,6 @@ date_from_time_t (unixtime)
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;
- char *source;
-{
- int year, month, day, hour, minute, second;
-
- /* 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"};
-
- if (sscanf (source, SDATEFORM,
- &year, &month, &day, &hour, &minute, &second)
- != 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);
-
- /* Always send a four digit year. */
- if (year < 100)
- year += 1900;
-
- sprintf (dest, "%d %s %d %02d:%02d:%02d -0000", day,
- month < 1 || month > 12 ? "???" : month_names[month - 1],
- year, hour, minute, second);
-}
-
void
usage (cpp)
register const char *const *cpp;
@@ -1149,3 +1067,61 @@ usage (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 (!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
index 4244258..e716222 100644
--- a/contrib/cvs/src/mkmodules.c
+++ b/contrib/cvs/src/mkmodules.c
@@ -353,7 +353,7 @@ static const struct admin_file filelist[] = {
{CVSROOTADM_CONFIG,
"a %s file configures various behaviors",
config_contents},
- {NULL, NULL, NULL}
+ {NULL, NULL}
};
/* Rebuild the checked out administrative files in directory DIR. */
@@ -397,6 +397,11 @@ mkmodules (dir)
rename_rcsfile (temp, CVSROOTADM_MODULES);
break;
+ case -1: /* fork failed */
+ (void) unlink_file (temp);
+ error (1, errno, "cannot check out %s", CVSROOTADM_MODULES);
+ /* NOTREACHED */
+
default:
error (0, 0,
"'cvs checkout' is less functional without a %s file",
@@ -404,9 +409,7 @@ mkmodules (dir)
break;
} /* switch on checkout_file() */
- if (unlink_file (temp) < 0
- && !existence_error (errno))
- error (0, errno, "cannot remove %s", temp);
+ (void) unlink_file (temp);
free (temp);
/* Checkout the files that need it in CVSROOT dir */
@@ -427,9 +430,7 @@ mkmodules (dir)
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);
+ (void) unlink_file (temp);
free (temp);
}
@@ -452,13 +453,11 @@ mkmodules (dir)
*last = '\0'; /* strip the newline */
/* Skip leading white space. */
- for (fname = line;
- *fname && isspace ((unsigned char) *fname);
- fname++)
+ for (fname = line; *fname && isspace(*fname); fname++)
;
/* Find end of filename. */
- for (cp = fname; *cp && !isspace ((unsigned char) *cp); cp++)
+ for (cp = fname; *cp && !isspace(*cp); cp++)
;
*cp = '\0';
@@ -469,16 +468,11 @@ mkmodules (dir)
}
else
{
- for (cp++;
- cp < last && *last && isspace ((unsigned char) *last);
- cp++)
+ for (cp++; cp < last && *last && isspace(*last); cp++)
;
if (cp < last && *cp)
error (0, 0, cp, fname);
}
- if (unlink_file (temp) < 0
- && !existence_error (errno))
- error (0, errno, "cannot remove %s", temp);
free (temp);
}
if (line)
@@ -528,10 +522,6 @@ make_tempfile ()
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;
@@ -557,8 +547,6 @@ checkout_file (file, 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);
}
@@ -619,7 +607,7 @@ write_dbmfile (temp)
if (value[0] == '#')
continue; /* comment line */
vp = value;
- while (*vp && isspace ((unsigned char) *vp))
+ while (*vp && isspace (*vp))
vp++;
if (*vp == '\0')
continue; /* empty line */
@@ -630,11 +618,11 @@ write_dbmfile (temp)
if (!cont)
{
key.dptr = vp;
- while (*vp && !isspace ((unsigned char) *vp))
+ while (*vp && !isspace (*vp))
vp++;
key.dsize = vp - key.dptr;
*vp++ = '\0'; /* NULL terminate the key */
- while (*vp && isspace ((unsigned char) *vp))
+ while (*vp && isspace (*vp))
vp++; /* skip whitespace to value */
if (*vp == '\0')
{
@@ -651,28 +639,17 @@ write_dbmfile (temp)
}
}
dbm_close (db);
- if (fclose (fp) < 0)
- error (0, errno, "cannot close %s", temp);
+ (void) fclose (fp);
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);
+ (void) unlink_file (dotdir);
+ (void) unlink_file (dotpag);
+ (void) unlink_file (dotdb);
error (1, 0, "DBM creation failed; correct above errors");
}
}
@@ -681,18 +658,10 @@ 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);
@@ -710,59 +679,18 @@ rename_dbmfile (temp)
/* 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;
+ (void) unlink_file (bakdir); /* rm .#modules.dir .#modules.pag */
+ (void) unlink_file (bakpag);
+ (void) unlink_file (bakdb);
+ (void) CVS_RENAME (dotdir, bakdir); /* mv modules.dir .#modules.dir */
+ (void) CVS_RENAME (dotpag, bakpag); /* mv modules.pag .#modules.pag */
+ (void) CVS_RENAME (dotdb, bakdb); /* mv modules.db .#modules.db */
+ (void) CVS_RENAME (newdir, dotdir); /* mv "temp".dir modules.dir */
+ (void) CVS_RENAME (newpag, dotpag); /* mv "temp".pag modules.pag */
+ (void) CVS_RENAME (newdb, dotdb); /* mv "temp".db modules.db */
/* 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 */
@@ -780,31 +708,16 @@ rename_rcsfile (temp, real)
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);
+ (void) CVS_STAT (rcs, &statbuf);
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);
-
+ (void) unlink_file (bak); /* rm .#loginfo */
+ (void) CVS_RENAME (real, bak); /* mv loginfo .#loginfo */
+ (void) CVS_RENAME (temp, real); /* mv "temp" loginfo */
free (bak);
}
diff --git a/contrib/cvs/src/prepend_args.c b/contrib/cvs/src/prepend_args.c
new file mode 100644
index 0000000..12322ce
--- /dev/null
+++ b/contrib/cvs/src/prepend_args.c
@@ -0,0 +1,86 @@
+/* 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 <config.h>
+#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/contrib/cvs/src/prepend_args.h b/contrib/cvs/src/prepend_args.h
new file mode 100644
index 0000000..6708442
--- /dev/null
+++ b/contrib/cvs/src/prepend_args.h
@@ -0,0 +1,26 @@
+/* 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/contrib/cvs/src/rcs.c b/contrib/cvs/src/rcs.c
index 64524b1..d5a17a2 100644
--- a/contrib/cvs/src/rcs.c
+++ b/contrib/cvs/src/rcs.c
@@ -124,6 +124,8 @@ static char *rcs_lockfilename PROTO ((char *));
evaluates its arguments multiple times. */
#define STREQ(a, b) ((a)[0] == (b)[0] && strcmp ((a), (b)) == 0)
+static char * getfullCVSname PROTO ((char *, char **));
+
/*
* We don't want to use isspace() from the C library because:
*
@@ -153,26 +155,6 @@ static const char spacetab[] = {
#define whitespace(c) (spacetab[(unsigned char)c] != 0)
-static char *rcs_lockfile;
-
-/* 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
@@ -384,9 +366,7 @@ RCS_parsercsfile_i (fp, rcsfile)
break;
}
- for (cp = key;
- (isdigit ((unsigned char) *cp) || *cp == '.') && *cp != '\0';
- cp++)
+ for (cp = key; (isdigit (*cp) || *cp == '.') && *cp != '\0'; cp++)
/* do nothing */ ;
if (*cp == '\0')
break;
@@ -520,9 +500,7 @@ RCS_reparsercsfile (rdata, pfp, rcsbufp)
* 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++)
+ for (cp = key; (isdigit (*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
@@ -607,98 +585,6 @@ RCS_reparsercsfile (rdata, pfp, rcsbufp)
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;
- 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
@@ -787,8 +673,7 @@ warning: duplicate key `%s' in version `%s' of RCS file `%s'",
op = *cp++;
if (op != 'a' && op != 'd')
- error (1, 0, "\
-unrecognized operation '\\x%x' in %s",
+ error (1, 0, "unrecognized operation '%c' in %s",
op, rcs->path);
(void) strtoul (cp, (char **) &cp, 10);
if (*cp++ != ' ')
@@ -1596,8 +1481,7 @@ rcsbuf_getstring (rcsbuf, strp)
/* PTR should now point to the start of a string. */
if (c != '@')
- error (1, 0, "expected @-string at '\\x%x' in %s",
- c, rcsbuf->filename);
+ error (1, 0, "expected @-string at `%c' in %s", c, rcsbuf->filename);
/* Optimize the common case of a value composed of a single
'@' string. */
@@ -1854,7 +1738,7 @@ rcsbuf_getword (rcsbuf, wordp)
printing character that is not a special.' This test ought
to do the trick. */
c = *ptr;
- if (isprint ((unsigned char) c) &&
+ if (isprint (c) &&
c != ';' && c != '$' && c != ',' && c != '@' && c != ':')
{
++ptr;
@@ -1922,10 +1806,9 @@ rcsbuf_getrevnum (rcsbuf, revp)
++ptr;
}
- if (! isdigit ((unsigned char) c) && c != '.')
+ if (! isdigit (c) && c != '.')
error (1, 0,
- "\
-unexpected '\\x%x' reading revision number in RCS file %s",
+ "unexpected `%c' reading revision number in RCS file %s",
c, rcsbuf->filename);
*revp = ptr;
@@ -1945,11 +1828,10 @@ unexpected '\\x%x' reading revision number in RCS file %s",
c = *ptr;
}
- while (isdigit ((unsigned char) c) || c == '.');
+ while (isdigit (c) || c == '.');
if (! whitespace (c))
- error (1, 0, "\
-unexpected '\\x%x' reading revision number in RCS file %s",
+ error (1, 0, "unexpected `%c' reading revision number in RCS file %s",
c, rcsbuf->filename);
*ptr = '\0';
@@ -2457,7 +2339,7 @@ RCS_getversion (rcs, tag, date, force_tag_match, simple_tag)
}
/* Work out the branch. */
- if (! isdigit ((unsigned char) tag[0]))
+ if (! isdigit (tag[0]))
branch = RCS_whatbranch (rcs, tag);
else
branch = xstrdup (tag);
@@ -2522,16 +2404,6 @@ RCS_tag2rev (rcs, 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.
*
@@ -2555,7 +2427,7 @@ RCS_tag2rev (rcs, 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))
+ if (tag && (strcmp (tag, TAG_HEAD) == 0))
return (RCS_head (rcs));
/* If valid tag let translate_symtag say yea or nay. */
@@ -2608,7 +2480,7 @@ RCS_gettag (rcs, symtag, force_tag_match, simple_tag)
#endif
return (RCS_head (rcs));
- if (!isdigit ((unsigned char) tag[0]))
+ if (!isdigit (tag[0]))
{
char *version;
@@ -2748,13 +2620,25 @@ RCS_magicrev (rcs, rev)
char *rev;
{
int rev_num;
- char *xrev, *test_branch;
+ 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; ; rev_num += 2)
+ for ( ; ; rev_num += 2)
{
/* see if the physical branch exists */
(void) sprintf (xrev, "%s.%d", rev, rev_num);
@@ -2805,7 +2689,7 @@ RCS_isbranch (rcs, rev)
const char *rev;
{
/* numeric revisions are easy -- even number of dots is a branch */
- if (isdigit ((unsigned char) *rev))
+ if (isdigit (*rev))
return ((numdots (rev) & 1) == 0);
/* assume a revision if you can't find the RCS info */
@@ -2832,7 +2716,7 @@ RCS_nodeisbranch (rcs, rev)
assert (rcs != NULL);
/* numeric revisions are easy -- even number of dots is a branch */
- if (isdigit ((unsigned char) *rev))
+ if (isdigit (*rev))
return ((numdots (rev) & 1) == 0);
version = translate_symtag (rcs, rev);
@@ -3059,7 +2943,7 @@ RCS_branch_head (rcs, rev)
if (RCS_nodeisbranch (rcs, rev))
return RCS_getbranch (rcs, rev, 1);
- if (isdigit ((unsigned char) *rev))
+ if (isdigit (*rev))
num = xstrdup (rev);
else
{
@@ -3231,23 +3115,8 @@ RCS_getdate (rcs, date, force_tag_match)
*/
/* 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)
- {
- vers = (RCSVers *) p->data;
- if (RCS_datecmp (vers->date, date) != 0)
- return xstrdup ("1.1");
- }
- }
+ if (cur_rev != NULL && ! STREQ (cur_rev, "1.1"))
+ return (xstrdup (cur_rev));
/* look on the vendor branch */
retval = RCS_getdatebranch (rcs, date, CVSBRANCH);
@@ -3599,11 +3468,11 @@ RCS_check_tag (tag)
* characters cannot be non-visible graphic characters, and must not be
* in the set of "invalid" RCS identifier characters.
*/
- if (isalpha ((unsigned char) *tag))
+ if (isalpha (*tag))
{
for (cp = tag; *cp; cp++)
{
- if (!isgraph ((unsigned char) *cp))
+ if (!isgraph (*cp))
error (1, 0, "tag `%s' has non-visible graphic characters",
tag);
if (strchr (invalid, *cp))
@@ -3630,7 +3499,7 @@ RCS_valid_rev (rev)
{
char last, c;
last = *rev++;
- if (!isdigit ((unsigned char) last))
+ if (!isdigit (last))
return 0;
while ((c = *rev++)) /* Extra parens placate -Wall gcc option */
{
@@ -3641,10 +3510,10 @@ RCS_valid_rev (rev)
continue;
}
last = c;
- if (!isdigit ((unsigned char) c))
+ if (!isdigit (c))
return 0;
}
- if (!isdigit ((unsigned char) last))
+ if (!isdigit (last))
return 0;
return 1;
}
@@ -3680,52 +3549,40 @@ 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;
- 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 const struct rcs_keyword keywords[] =
+static struct rcs_keyword keywords[] =
{
- { KEYWORD_INIT ("Author") },
- { KEYWORD_INIT ("Date") },
- { KEYWORD_INIT ("Header") },
- { KEYWORD_INIT ("Id") },
- { KEYWORD_INIT ("Locker") },
- { KEYWORD_INIT ("Log") },
- { KEYWORD_INIT ("Name") },
- { KEYWORD_INIT ("RCSfile") },
- { KEYWORD_INIT ("Revision") },
- { KEYWORD_INIT ("Source") },
- { KEYWORD_INIT ("State") },
- { NULL, 0 }
+ { 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,
@@ -3734,8 +3591,10 @@ enum keyword
KEYWORD_RCSFILE,
KEYWORD_REVISION,
KEYWORD_SOURCE,
- KEYWORD_STATE
+ 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. */
@@ -3901,7 +3760,7 @@ expand_keywords (rcs, ver, name, log, loglen, expand, buf, len, retbuf, retlen)
/* Look for the first non alphabetic character after the '$'. */
send = srch + srch_len;
for (s = srch; s < send; s++)
- if (! isalpha ((unsigned char) *s))
+ if (! isalpha (*s))
break;
/* If the first non alphabetic character is not '$' or ':',
@@ -3913,7 +3772,8 @@ expand_keywords (rcs, ver, name, log, loglen, expand, buf, len, retbuf, retlen)
slen = s - srch;
for (keyword = keywords; keyword->string != NULL; keyword++)
{
- if (keyword->len == slen
+ if (keyword->expandit
+ && keyword->len == slen
&& strncmp (keyword->string, srch, slen) == 0)
{
break;
@@ -3960,15 +3820,25 @@ expand_keywords (rcs, ver, name, log, loglen, expand, buf, len, retbuf, retlen)
free_value = 1;
break;
+ case KEYWORD_CVSHEADER:
case KEYWORD_HEADER:
case KEYWORD_ID:
+ case KEYWORD_LOCALID:
{
char *path;
int free_path;
char *date;
+ char *old_path;
- if (kw == KEYWORD_HEADER)
+ 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);
@@ -3988,6 +3858,8 @@ expand_keywords (rcs, ver, name, log, loglen, expand, buf, len, retbuf, retlen)
locker != NULL ? locker : "");
if (free_path)
free (path);
+ if (old_path)
+ free (old_path);
free (date);
free_value = 1;
}
@@ -4004,7 +3876,7 @@ expand_keywords (rcs, ver, name, log, loglen, expand, buf, len, retbuf, retlen)
break;
case KEYWORD_NAME:
- if (name != NULL && ! isdigit ((unsigned char) *name))
+ if (name != NULL && ! isdigit (*name))
value = (char *) name;
else
value = NULL;
@@ -4347,7 +4219,7 @@ RCS_checkout (rcs, workfile, rev, nametag, options, sout, pfn, callerdat)
: (sout != RUN_TTY ? sout : "(stdout)"))));
}
- assert (rev == NULL || isdigit ((unsigned char) *rev));
+ assert (rev == NULL || isdigit (*rev));
if (noexec && workfile != NULL)
return 0;
@@ -4595,9 +4467,9 @@ RCS_checkout (rcs, workfile, rev, nametag, options, sout, pfn, callerdat)
error (1, 0, "%s:%s has bad `special' newphrase %s",
workfile, vers->version, info->data);
devnum = devnum_long;
- if (STREQ (devtype, "character"))
+ if (strcmp (devtype, "character") == 0)
special_file = S_IFCHR;
- else if (STREQ (devtype, "block"))
+ else if (strcmp (devtype, "block") == 0)
special_file = S_IFBLK;
else
error (0, 0, "%s is a special file of unsupported type `%s'",
@@ -5158,9 +5030,6 @@ RCS_checkin (rcs, workfile, message, rev, flags)
struct tm *ftm;
time_t modtime;
int adding_branch = 0;
-#ifdef PRESERVE_PERMISSIONS_SUPPORT
- struct stat sb;
-#endif
commitpt = NULL;
@@ -5181,11 +5050,40 @@ RCS_checkin (rcs, workfile, message, rev, flags)
allocated_workfile = 1;
}
- /* 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));
+ /* Is the backend file a symbolic link? Follow it and replace the
+ filename with the destination of the link. */
+
+ while (islink (rcs->path))
+ {
+ char *newname;
+#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. */
+ newname = xreadlink (rcs->path);
+#else
+ error (1, 0, "internal error: islink doesn't like readlink");
+#endif
+
+ if (isabsolute (newname))
+ {
+ free (rcs->path);
+ rcs->path = newname;
+ }
+ else
+ {
+ char *oldname = last_component (rcs->path);
+ int dirlen = oldname - rcs->path;
+ char *fullnewname = xmalloc (dirlen + strlen (newname) + 1);
+ strncpy (fullnewname, rcs->path, dirlen);
+ strcpy (fullnewname + dirlen, newname);
+ free (newname);
+ free (rcs->path);
+ rcs->path = fullnewname;
+ }
+ }
checkin_quiet = flags & RCS_FLAGS_QUIET;
if (!checkin_quiet)
@@ -5231,6 +5129,7 @@ RCS_checkin (rcs, workfile, message, rev, flags)
if (preserve_perms)
{
Node *np;
+ struct stat sb;
char buf[64]; /* static buffer should be safe: see usage. -twp */
delta->other_delta = getlist();
@@ -5329,12 +5228,6 @@ RCS_checkin (rcs, workfile, message, rev, flags)
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);
@@ -5417,7 +5310,7 @@ RCS_checkin (rcs, workfile, message, rev, flags)
char *branch, *tip, *newrev, *p;
int dots, isrevnum;
- assert (isdigit ((unsigned char) *rev));
+ assert (isdigit(*rev));
newrev = xstrdup (rev);
dots = numdots (newrev);
@@ -5572,12 +5465,6 @@ RCS_checkin (rcs, workfile, message, rev, flags)
/* 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);
@@ -6652,23 +6539,8 @@ RCS_delete_revs (rcs, tag1, tag2, inclusive)
char *diffbuf;
size_t bufsize, len;
-#if defined (__CYGWIN32__) || defined (_WIN32)
- /* 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
-
afterfile = cvs_temp_name();
- status = RCS_checkout (rcs, NULL, after, NULL, "-ko", afterfile,
+ status = RCS_checkout (rcs, NULL, after, NULL, NULL, afterfile,
(RCSCHECKOUTPROC)0, NULL);
if (status > 0)
goto delrev_done;
@@ -6696,13 +6568,13 @@ RCS_delete_revs (rcs, tag1, tag2, inclusive)
else
{
beforefile = cvs_temp_name();
- status = RCS_checkout (rcs, NULL, before, NULL, "-ko", beforefile,
+ status = RCS_checkout (rcs, NULL, before, NULL, NULL, beforefile,
(RCSCHECKOUTPROC)0, NULL);
if (status > 0)
goto delrev_done;
outfile = cvs_temp_name();
- status = diff_exec (beforefile, afterfile, "-an", outfile);
+ status = diff_exec (beforefile, afterfile, "-n", outfile);
if (status == 2)
{
@@ -7152,7 +7024,7 @@ apply_rcs_changes (lines, diffbuf, difflen, name, addvers, delvers)
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;
+ enum {ADD, DELETE} type;
unsigned long pos;
unsigned long nlines;
const char *new_lines;
@@ -7169,8 +7041,7 @@ apply_rcs_changes (lines, diffbuf, difflen, name, addvers, delvers)
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);
+ error (1, 0, "unrecognized operation '%c' in %s", op, name);
df = (struct deltafrag *) xmalloc (sizeof (struct deltafrag));
df->next = dfhead;
dfhead = df;
@@ -7192,7 +7063,7 @@ apply_rcs_changes (lines, diffbuf, difflen, name, addvers, delvers)
{
unsigned int i;
- df->type = FRAG_ADD;
+ df->type = 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
@@ -7222,7 +7093,7 @@ apply_rcs_changes (lines, diffbuf, difflen, name, addvers, delvers)
--df->pos;
assert (op == 'd');
- df->type = FRAG_DELETE;
+ df->type = DELETE;
}
}
@@ -7232,12 +7103,12 @@ apply_rcs_changes (lines, diffbuf, difflen, name, addvers, delvers)
switch (df->type)
{
- case FRAG_ADD:
+ case ADD:
if (! linevector_add (lines, df->new_lines, df->len, addvers,
df->pos))
return 0;
break;
- case FRAG_DELETE:
+ case DELETE:
if (df->pos > lines->nlines
|| df->pos + df->nlines > lines->nlines)
return 0;
@@ -7696,9 +7567,7 @@ getdelta (rcsbuf, rcsfile, keyp, valp)
/* 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++)
+ for (cp = key; (isdigit (*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
@@ -7882,9 +7751,7 @@ unable to parse %s; `state' not in the expected place", rcsfile);
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++)
+ for (cp = key; (isdigit (*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
@@ -8466,30 +8333,6 @@ count_delta_actions (np, ignore)
return 0;
}
-/*
- * Clean up temporary files
- */
-static 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)
- {
- if (unlink_file (rcs_lockfile) < 0
- && !existence_error (errno))
- error (0, errno, "cannot remove %s", rcs_lockfile);
- }
- rcs_lockfile = NULL;
-}
-
/* 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,'.
@@ -8514,6 +8357,10 @@ rcs_cleanup ()
processes from stomping all over each other's laundry. Hence,
they are `internal' locking functions.
+ Note that we don't clean up the ,foo, file on ^C. We probably should.
+ I'm not completely sure whether RCS does or not (I looked at the code
+ a little, and didn't find it).
+
If there is an error, give a fatal error; if we return we always
return a non-NULL value. */
@@ -8521,35 +8368,13 @@ static FILE *
rcs_internal_lockfile (rcsfile)
char *rcsfile;
{
+ char *lockfile;
int fd;
struct stat rstat;
FILE *fp;
- static int first_call = 1;
-
- if (first_call)
- {
- first_call = 0;
- /* clean up if we get a signal */
-#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);
- rcs_lockfile = rcs_lockfilename (rcsfile);
+ 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,
@@ -8575,13 +8400,12 @@ rcs_internal_lockfile (rcsfile)
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. */
- fd = open (rcs_lockfile,
- OPEN_BINARY | O_WRONLY | O_CREAT | O_EXCL | O_TRUNC,
+ fd = open (lockfile, OPEN_BINARY | O_WRONLY | O_CREAT | O_EXCL | O_TRUNC,
S_IRUSR | S_IRGRP | S_IROTH);
if (fd < 0)
{
- error (1, errno, "could not open lock file `%s'", rcs_lockfile);
+ error (1, errno, "could not open lock file `%s'", lockfile);
}
/* Force the file permissions, and return a stream object. */
@@ -8589,11 +8413,13 @@ rcs_internal_lockfile (rcsfile)
this in the non-HAVE_FCHMOD case. */
#ifdef HAVE_FCHMOD
if (fchmod (fd, rstat.st_mode) < 0)
- error (1, errno, "cannot change mode for %s", rcs_lockfile);
+ error (1, errno, "cannot change mode for %s", lockfile);
#endif
fp = fdopen (fd, FOPEN_BINARY_WRITE);
if (fp == NULL)
- error (1, errno, "cannot fdopen %s", rcs_lockfile);
+ error (1, errno, "cannot fdopen %s", lockfile);
+
+ free (lockfile);
return fp;
}
@@ -8603,7 +8429,10 @@ rcs_internal_unlockfile (fp, rcsfile)
FILE *fp;
char *rcsfile;
{
- assert (rcs_lockfile != NULL);
+ char *lockfile;
+
+ /* Get the lock file name: `,file,' for RCS file `file,v'. */
+ lockfile = rcs_lockfilename (rcsfile);
/* Abort if we could not write everything successfully to LOCKFILE.
This is not a great error-handling mechanism, but should prevent
@@ -8616,21 +8445,12 @@ rcs_internal_unlockfile (fp, rcsfile)
fragile even if it happens to sometimes be true. The real
solution is to check each call to fprintf rather than waiting
until the end like this. */
- error (1, 0, "error writing to lock file %s", rcs_lockfile);
+ error (1, 0, "error writing to lock file %s", lockfile);
if (fclose (fp) == EOF)
- error (1, errno, "error closing lock file %s", rcs_lockfile);
+ error (1, errno, "error closing lock file %s", lockfile);
- 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);
- }
+ rename_file (lockfile, rcsfile);
+ free (lockfile);
}
static char *
@@ -8673,9 +8493,6 @@ RCS_rewrite (rcs, newdtext, insertpt)
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);
@@ -8754,8 +8571,8 @@ annotate_fileproc (callerdat, finfo)
cvs_outerr (finfo->fullname, 0);
cvs_outerr ("\n***************\n", 0);
- RCS_deltas (finfo->rcs, fp, rcsbufp, version, RCS_ANNOTATE, NULL,
- NULL, NULL, NULL);
+ RCS_deltas (finfo->rcs, fp, rcsbufp, version, RCS_ANNOTATE, (char **) NULL,
+ (size_t) NULL, (char **) NULL, (size_t *) NULL);
free (version);
return 0;
}
@@ -8828,8 +8645,8 @@ annotate (argc, argv)
option_with_arg ("-r", tag);
if (date)
client_senddate (date);
- send_files (argc, argv, local, 0, SEND_NO_CONTENTS);
send_file_names (argc, argv, SEND_EXPAND_WILD);
+ send_files (argc, argv, local, 0, SEND_NO_CONTENTS);
send_to_server ("annotate\012", 0);
return get_responses_and_close ();
}
@@ -8865,7 +8682,7 @@ make_file_label (path, rev, rcs)
char *file;
file = last_component (path);
- label = (char *) xmalloc (strlen (path)
+ label = (char *) xmalloc (strlen (file)
+ (rev == NULL ? 0 : strlen (rev))
+ 50);
@@ -8874,7 +8691,7 @@ make_file_label (path, rev, rcs)
char *date;
RCS_getrevtime (rcs, rev, datebuf, 0);
date = printable_date (datebuf);
- (void) sprintf (label, "-L%s\t%s\t%s", path, date, rev);
+ (void) sprintf (label, "-L%s\t%s\t%s", file, date, rev);
free (date);
}
else
@@ -8891,8 +8708,110 @@ make_file_label (path, rev, rcs)
wm->tm_year + 1900, wm->tm_mon + 1,
wm->tm_mday, wm->tm_hour,
wm->tm_min, wm->tm_sec);
- (void) sprintf (label, "-L%s\t%s", path, datebuf);
+ (void) sprintf (label, "-L%s\t%s", file, 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 (CVSroot_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(CVSroot_directory);
+ if (!strncmp(*pathstore, CVSroot_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
index 0a28161..dc0c7be 100644
--- a/contrib/cvs/src/rcs.h
+++ b/contrib/cvs/src/rcs.h
@@ -184,7 +184,6 @@ RCSNode *RCS_parse PROTO((const char *file, const char *repos));
RCSNode *RCS_parsercsfile PROTO((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, char *date, int force_tag_match));
@@ -212,7 +211,6 @@ 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 *, char *));
int RCS_checkout PROTO ((RCSNode *, char *, char *, char *, char *, char *,
RCSCHECKOUTPROC, void *));
int RCS_checkin PROTO ((RCSNode *rcs, char *workfile, char *message,
@@ -230,6 +228,9 @@ char *RCS_getaccess PROTO ((RCSNode *));
void RCS_rewrite PROTO ((RCSNode *, Deltatext *, char *));
int rcs_change_text PROTO ((const char *, char *, size_t, const 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 ((char *, char *, RCSNode *));
extern int preserve_perms;
diff --git a/contrib/cvs/src/rcscmds.c b/contrib/cvs/src/rcscmds.c
index ab94e40..f889233 100644
--- a/contrib/cvs/src/rcscmds.c
+++ b/contrib/cvs/src/rcscmds.c
@@ -147,8 +147,7 @@ call_diff_write_output (text, len)
const char *text;
size_t len;
{
- if (len > 0)
- cvs_output (text, len);
+ cvs_output (text, len);
}
/* Call back function for the diff library to flush the output file.
diff --git a/contrib/cvs/src/recurse.c b/contrib/cvs/src/recurse.c
index e93afbf..d88bf2b 100644
--- a/contrib/cvs/src/recurse.c
+++ b/contrib/cvs/src/recurse.c
@@ -13,6 +13,9 @@
#include "fileattr.h"
#include "edit.h"
+#ifdef CLIENT_SUPPORT
+static int do_argument_proc PROTO((Node * p, void *closure));
+#endif
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));
@@ -58,6 +61,23 @@ struct frame_and_entries {
List *entries;
};
+#ifdef CLIENT_SUPPORT
+/* This is a callback to send "Argument" commands to the server in the
+ case we've done a "cvs update" or "cvs commit" in a top-level
+ directory where there is no CVSADM directory. */
+
+static int
+do_argument_proc (p, closure)
+ Node *p;
+ void *closure;
+{
+ char *dir = p->key;
+ send_to_server ("Argument ", 0);
+ send_to_server (dir, 0);
+ send_to_server ("\012", 1);
+ return 0;
+}
+#endif
/* Start a recursive command.
@@ -107,9 +127,6 @@ start_recursion (fileproc, filesdoneproc, direntproc, dirleaveproc, callerdat,
int dosrcs;
{
int i, err = 0;
-#ifdef CLIENT_SUPPORT
- List *args_to_send_when_finished = NULL;
-#endif
List *files_by_dir = NULL;
struct recursion_frame frame;
@@ -152,29 +169,6 @@ start_recursion (fileproc, filesdoneproc, direntproc, dirleaveproc, callerdat,
if (argc == 0)
{
- int just_subdirs = (which & W_LOCAL) && !isdir (CVSADM);
-
-#ifdef CLIENT_SUPPORT
- if (!just_subdirs
- && CVSroot_cmdline == NULL
- && client_active)
- {
- char *root = Name_Root (NULL, update_dir);
- if (root && strcmp (root, current_root) != 0)
- /* 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;
- }
-#endif
/*
* There were no arguments, so we'll probably just recurse. The
@@ -183,7 +177,7 @@ start_recursion (fileproc, filesdoneproc, direntproc, dirleaveproc, callerdat,
* 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)
+ if ((which & W_LOCAL) && !isdir (CVSADM))
{
dirlist = Find_Directories ((char *) NULL, W_LOCAL, (List *) NULL);
/* If there are no sub-directories, there is a certain logic in
@@ -210,21 +204,17 @@ start_recursion (fileproc, filesdoneproc, direntproc, dirleaveproc, callerdat,
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);
+ generalizes to other commands. */
+
+ err += walklist (dirlist, do_argument_proc, NULL);
}
#endif
}
else
addlist (&dirlist, ".");
- goto do_the_work;
+ err += do_recursion (&frame);
+ goto out;
}
@@ -345,146 +335,14 @@ start_recursion (fileproc, filesdoneproc, direntproc, dirleaveproc, callerdat,
/* 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);
+ out:
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_root. 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_root.
-
- */
-
- /* 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);
}
@@ -501,7 +359,6 @@ do_recursion (frame)
char *srepository;
List *entries = NULL;
int should_readlock;
- int process_this_directory = 1;
/* do nothing if told */
if (frame->flags == R_SKIP_ALL)
@@ -553,57 +410,6 @@ do_recursion (frame)
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 (
- /* 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. */
- CVSroot_cmdline == NULL
-
-#ifdef SERVER_SUPPORT
- && ! server_active
-#endif
- )
- {
- char *this_root = Name_Root ((char *) NULL, update_dir);
- if (this_root != NULL)
- {
- if (findnode (root_directories, this_root) == NULL)
- {
- /* Add it to our list. */
-
- Node *n = getnode ();
- n->type = UNKNOWN;
- n->key = xstrdup (this_root);
-
- if (addnode (root_directories, n))
- error (1, 0, "cannot add new CVSROOT %s", this_root);
-
- }
-
- process_this_directory = (strcmp (current_root, this_root) == 0);
-
- free (this_root);
- }
- }
-
/*
* Fill in repository with the current repository
*/
@@ -662,26 +468,12 @@ do_recursion (frame)
repository = Name_Repository ((char *) NULL, update_dir);
/* 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;
- }
- }
+ filelist = Find_Names (repository, lwhich, frame->aflag, &entries);
}
/* find sub-directories if we will recurse */
if (frame->flags != R_SKIP_DIRS)
- dirlist = Find_Directories (
- process_this_directory ? repository : NULL,
- frame->which, entries);
+ dirlist = Find_Directories (repository, frame->which, entries);
}
else
{
@@ -695,7 +487,7 @@ do_recursion (frame)
}
/* process the files (if any) */
- if (process_this_directory && filelist != NULL && frame->fileproc)
+ if (filelist != NULL && frame->fileproc)
{
struct file_info finfo_struct;
struct frame_and_file frfile;
@@ -733,12 +525,11 @@ do_recursion (frame)
}
/* call-back files done proc (if any) */
- if (process_this_directory && dodoneproc && frame->filesdoneproc != NULL)
+ if (dodoneproc && frame->filesdoneproc != NULL)
err = frame->filesdoneproc (frame->callerdat, err, repository,
update_dir[0] ? update_dir : ".",
entries);
- skip_directory:
fileattr_write ();
fileattr_free ();
@@ -798,24 +589,7 @@ do_file_proc (p, closure)
strcat (finfo->fullname, 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", finfo->fullname);
- free (finfo->fullname);
- cvs_flushout ();
- return 0;
- }
- }
else
finfo->rcs = (RCSNode *) NULL;
ret = frfile->frame->fileproc (frfile->frame->callerdat, finfo);
@@ -851,7 +625,6 @@ do_dir_proc (p, closure)
int err = 0;
struct saved_cwd cwd;
char *saved_update_dir;
- int process_this_directory = 1;
if (fncmp (dir, CVSADM) == 0)
{
@@ -987,62 +760,12 @@ but CVS uses %s for its own purposes; skipping %s directory",
free (cvsadmdir);
}
- /* Only process this directory if the root matches. This nearly
- duplicates code in do_recursion. */
-
- if (
- /* 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. */
- CVSroot_cmdline == NULL
-
-#ifdef SERVER_SUPPORT
- && ! server_active
-#endif
- )
- {
- char *this_root = Name_Root (dir, update_dir);
- if (this_root != NULL)
- {
- if (findnode (root_directories, this_root) == NULL)
- {
- /* Add it to our list. */
-
- Node *n = getnode ();
- n->type = UNKNOWN;
- n->key = xstrdup (this_root);
-
- if (addnode (root_directories, n))
- error (1, 0, "cannot add new CVSROOT %s", this_root);
-
- }
-
- process_this_directory = (strcmp (current_root, this_root) == 0);
- free (this_root);
- }
- }
-
/* 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;
- }
+ dir_return = frame->direntproc (frame->callerdat, dir, newrepos,
+ update_dir, frent->entries);
else
{
/* Generic behavior. I don't see a reason to make the caller specify
@@ -1088,7 +811,7 @@ but CVS uses %s for its own purposes; skipping %s directory",
(void) strcpy (update_dir, ".");
/* call-back dir leave proc (if any) */
- if (process_this_directory && frame->dirleaveproc != NULL)
+ if (frame->dirleaveproc != NULL)
err = frame->dirleaveproc (frame->callerdat, dir, err, update_dir,
frent->entries);
diff --git a/contrib/cvs/src/server.c b/contrib/cvs/src/server.c
index 669cad7..4c18fc9 100644
--- a/contrib/cvs/src/server.c
+++ b/contrib/cvs/src/server.c
@@ -133,7 +133,7 @@ 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;
+char *Pserver_Repos = NULL;
/* Should we check for system usernames/passwords? Can be changed by
CVSROOT/config. */
@@ -341,182 +341,6 @@ fd_buffer_block (closure, block)
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 = malloc (strlen (dir) + 1);
- if (p == NULL)
- return ENOMEM;
-
- dir_where_cvsadm_lives = malloc (strlen (base_dir) + strlen (dir) + 100);
- if (dir_where_cvsadm_lives == NULL)
- return ENOMEM;
-
- /* Allocate some space for the temporary string in which we will
- construct filenames. */
- tmp = malloc (strlen (base_dir) + strlen (dir) + 100);
- if (tmp == NULL)
- 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 = malloc (strlen (CVSroot_directory)
- + sizeof (CVSROOTADM)
- + sizeof (CVSNULLREPOS)
- + 10);
- if (! empty)
- {
- retval = ENOMEM;
- goto finish;
- }
-
- /* Create the directory name. */
- (void) sprintf (empty, "%s/%s/%s", CVSroot_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.
@@ -739,7 +563,6 @@ serve_root (arg)
char *env;
char *path;
int save_errno;
- char *arg_dup;
if (error_pending()) return;
@@ -751,7 +574,9 @@ serve_root (arg)
return;
}
- /* Sending "Root" twice is illegal.
+ /* Sending "Root" twice is illegal. It would also be nice to
+ check for the other case, in which there is no Root request
+ prior to a request which requires one.
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
@@ -766,43 +591,19 @@ serve_root (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);
- }
- }
-#endif
- arg_dup = malloc (strlen (arg) + 1);
- if (arg_dup == NULL)
- {
- pending_error = ENOMEM;
- return;
- }
- strcpy (arg_dup, arg);
- set_local_cvsroot (arg_dup);
+ set_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 (CVSroot_directory);
- path = malloc (strlen (CVSroot_directory)
- + sizeof (CVSROOTADM)
- + sizeof (CVSROOTADM_HISTORY)
- + 10);
- if (path == NULL)
- {
- pending_error = ENOMEM;
- return;
- }
+ /* Now is a good time to read CVSROOT/options too. */
+ parseopts(CVSroot_directory);
+
+ path = xmalloc (strlen (CVSroot_directory)
+ + sizeof (CVSROOTADM)
+ + sizeof (CVSROOTADM_HISTORY)
+ + 10);
(void) sprintf (path, "%s/%s", CVSroot_directory, CVSROOTADM);
if (!isaccessible (path, R_OK | X_OK))
{
@@ -814,7 +615,7 @@ E Protocol error: Root says \"%s\" but pserver says \"%s\"",
}
(void) strcat (path, "/");
(void) strcat (path, CVSROOTADM_HISTORY);
- if (isfile (path) && !isaccessible (path, R_OK | W_OK))
+ if (readonlyfs == 0 && isfile (path) && !isaccessible (path, R_OK | W_OK))
{
save_errno = errno;
pending_error_text = malloc (80 + strlen (path));
@@ -872,73 +673,6 @@ server_pathname_check (path)
}
}
-static int outside_root PROTO ((char *));
-
-/* Is file or directory REPOS an absolute pathname within the
- CVSroot_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 (CVSroot_directory);
-
- /* I think isabsolute (repos) should always be true, and that
- any RELATIVE_REPOS stuff should only be in CVS/Repository
- files, not the protocol (for compatibility), but I'm putting
- in the isabsolute check just in case. */
- 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 (CVSroot_directory, repos, root_len) != 0)
- {
- not_within:
- if (alloc_pending (strlen (CVSroot_directory)
- + strlen (repos)
- + 80))
- sprintf (pending_error_text, "\
-E protocol error: directory '%s' not within root '%s'",
- repos, CVSroot_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
@@ -978,31 +712,13 @@ dirswitch (dir, repos)
{
int status;
FILE *f;
+ char *b;
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;
- }
-
if (dir_name != NULL)
free (dir_name);
@@ -1032,7 +748,7 @@ dirswitch (dir, repos)
strcat (dir_name, "/");
strcat (dir_name, dir);
- status = mkdir_p (dir_name);
+ status = mkdir_p (dir_name);
if (status != 0
&& status != EEXIST)
{
@@ -1042,20 +758,16 @@ dirswitch (dir, repos)
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)
- {
- pending_error = status;
- if (alloc_pending (80 + strlen (dir_name)))
- sprintf (pending_error_text, "E cannot create_adm_p %s", dir_name);
- return;
- }
+ /* Note that this call to Subdir_Register will be a noop if the parent
+ directory does not yet exist (for example, if the client sends
+ "Directory foo" followed by "Directory .", then the subdirectory does
+ not get registered, but if the client sends "Directory ." followed
+ by "Directory foo", then the subdirectory does get registered.
+ This seems pretty fishy, but maybe it is the way it needs to work. */
+ b = strrchr (dir_name, '/');
+ *b = '\0';
+ Subdir_Register ((List *) NULL, dir_name, b + 1);
+ *b = '/';
if ( CVS_CHDIR (dir_name) < 0)
{
@@ -1068,17 +780,14 @@ dirswitch (dir, repos)
* 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))
+ if (CVS_MKDIR (CVSADM, 0777) < 0)
{
+ if (errno == EEXIST)
+ /* Don't create the files again. */
+ return;
pending_error = 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)
{
@@ -1158,8 +867,24 @@ serve_directory (arg)
status = buf_read_line (buf_from_net, &repos, (int *) NULL);
if (status == 0)
{
- if (outside_root (repos))
+ /* I think isabsolute (repos) should always be true, and that
+ any RELATIVE_REPOS stuff should only be in CVS/Repository
+ files, not the protocol (for compatibility), but I'm putting
+ in the in isabsolute check just in case. */
+ if (isabsolute (repos)
+ && strncmp (CVSroot_directory,
+ repos,
+ strlen (CVSroot_directory)) != 0)
+ {
+ if (alloc_pending (strlen (CVSroot_directory)
+ + strlen (repos)
+ + 80))
+ sprintf (pending_error_text, "\
+E protocol error: directory '%s' not within root '%s'",
+ repos, CVSroot_directory);
return;
+ }
+
dirswitch (arg, repos);
free (repos);
}
@@ -1333,6 +1058,8 @@ receive_file (size, file, gzipped)
{
int fd;
char *arg = file;
+ pid_t gzip_pid = 0;
+ int gzip_status;
/* Write the file. */
fd = CVS_OPEN (arg, O_WRONLY | O_CREAT | O_TRUNC, 0600);
@@ -1345,78 +1072,15 @@ receive_file (size, file, gzipped)
return;
}
+ /*
+ * FIXME: This doesn't do anything reasonable with gunzip's stderr, which
+ * means that if gunzip writes to stderr, it will cause all manner of
+ * protocol violations.
+ */
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 = malloc (size);
- p = filebuf;
- /* If NULL, we still want to read the data and discard it. */
+ fd = filter_through_gunzip (fd, 0, &gzip_pid);
- 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 = malloc (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, filebuf, size))
- {
- if (alloc_pending (80))
- sprintf (pending_error_text,
- "E aborting due to compression error");
- }
- free (filebuf);
- }
- else
- receive_partial_file (size, fd);
+ receive_partial_file (size, fd);
if (pending_error_text)
{
@@ -1430,25 +1094,30 @@ receive_file (size, file, gzipped)
/* else original string is supposed to be unchanged */
}
- out:
if (close (fd) < 0 && !error_pending ())
{
pending_error_text = malloc (40 + strlen (arg));
if (pending_error_text)
sprintf (pending_error_text, "E cannot close %s", arg);
pending_error = errno;
+ if (gzip_pid)
+ waitpid (gzip_pid, (int *) 0, 0);
return;
}
+
+ if (gzip_pid)
+ {
+ if (waitpid (gzip_pid, &gzip_status, 0) != gzip_pid)
+ error (1, errno, "waiting for gunzip process %ld",
+ (long) gzip_pid);
+ else if (gzip_status != 0)
+ error (1, 0, "gunzip exited %d", gzip_status);
+ }
}
/* 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
@@ -1546,31 +1215,12 @@ serve_modified (arg)
return;
}
- if (outside_dir (arg))
- return;
-
if (size >= 0)
{
receive_file (size, arg, gzipped);
if (error_pending ()) return;
}
- if (checkin_time_valid)
- {
- struct utimbuf t;
-
- memset (&t, 0, sizeof (t));
- t.modtime = t.actime = checkin_time;
- if (utime (arg, &t) < 0)
- {
- pending_error = errno;
- if (alloc_pending (80 + strlen (arg)))
- sprintf (pending_error_text, "E cannot utime %s", arg);
- return;
- }
- checkin_time_valid = 0;
- }
-
{
int status = change_mode (arg, mode_text, 0);
free (mode_text);
@@ -1621,9 +1271,6 @@ serve_unchanged (arg)
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)
{
@@ -1664,9 +1311,6 @@ serve_is_modified (arg)
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)
@@ -1802,34 +1446,6 @@ serve_kopt (arg)
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 ()
{
@@ -1917,9 +1533,6 @@ serve_notify (arg)
if (error_pending ()) return;
- if (outside_dir (arg))
- return;
-
new = (struct notify_note *) malloc (sizeof (struct notify_note));
if (new == NULL)
{
@@ -1971,9 +1584,6 @@ serve_notify (arg)
{
char *cp;
- if (strchr (data, '+'))
- goto error;
-
new->type = data;
if (data[1] != '\t')
goto error;
@@ -2013,7 +1623,7 @@ serve_notify (arg)
}
return;
error:
- pending_error_text = malloc (80);
+ pending_error_text = malloc (40);
if (pending_error_text)
strcpy (pending_error_text,
"E Protocol error; misformed Notify request");
@@ -2074,8 +1684,6 @@ server_notify ()
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. */
@@ -2321,9 +1929,6 @@ serve_questionable (arg)
return;
}
- if (outside_dir (arg))
- return;
-
if (!ign_name (arg))
{
char *update_dir;
@@ -3277,8 +2882,8 @@ server_register (name, version, timestamp, options, tag, date, conflict)
if (trace)
{
(void) fprintf (stderr,
- "%s-> server_register(%s, %s, %s, %s, %s, %s, %s)\n",
- CLIENT_SERVER_STR,
+ "%c-> server_register(%s, %s, %s, %s, %s, %s, %s)\n",
+ (server_active) ? 'S' : ' ', /* silly */
name, version, timestamp ? timestamp : "", options,
tag ? tag : "", date ? date : "",
conflict ? conflict : "");
@@ -3744,12 +3349,6 @@ server_copy_file (file, update_dir, repository, newfile)
char *repository;
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 ");
@@ -3768,21 +3367,33 @@ server_modtime (finfo, vers_ts)
Vers_TS *vers_ts;
{
char date[MAXDATELEN];
- char outdate[MAXDATELEN];
+ int year, month, day, hour, minute, second;
+ /* Note that these strings are specified in 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"};
assert (vers_ts->vn_rcs != NULL);
if (!supported_response ("Mod-time"))
return;
+ /* The only hard part about this routine is converting the date
+ formats. In terms of functionality it all boils down to the
+ call to RCS_getrevtime. */
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);
+
+ sscanf (date, SDATEFORM, &year, &month, &day, &hour, &minute, &second);
+ sprintf (date, "%d %s %d %d:%d:%d -0000", day,
+ month < 1 || month > 12 ? "???" : month_names[month - 1],
+ year, hour, minute, second);
buf_output0 (protocol, "Mod-time ");
- buf_output0 (protocol, outdate);
+ buf_output0 (protocol, date);
buf_output0 (protocol, "\n");
}
@@ -3830,12 +3441,6 @@ server_updated (finfo, vers, updated, mode, checksum, filebuf)
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);
@@ -3944,11 +3549,6 @@ CVS server internal error: no mode in server_updated");
}
list = last = NULL;
-
- file = NULL;
- file_allocated = 0;
- file_used = 0;
-
if (size > 0)
{
/* Throughout this section we use binary mode to read the
@@ -3964,14 +3564,8 @@ CVS server internal error: no mode in server_updated");
*/
&& 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;
+ int status, fd, gzip_status;
+ pid_t gzip_pid;
/* Callers must avoid passing us a buffer if
file_gzip_level is set. We could handle this case,
@@ -3984,13 +3578,22 @@ 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)
+ fd = filter_through_gzip (fd, 1, file_gzip_level, &gzip_pid);
+ f = fdopen (fd, "rb");
+ status = buf_read_file_to_eof (f, &list, &last);
+ size = buf_chain_length (list);
+ if (status == -2)
+ (*protocol->memory_error) (protocol);
+ 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);
+ if (waitpid (gzip_pid, &gzip_status, 0) == -1)
+ error (1, errno, "waiting for gzip process %ld",
+ (long) gzip_pid);
+ else if (gzip_status != 0)
+ error (1, 0, "gzip exited %d", gzip_status);
/* Prepending length with "z" is flag for using gzip here. */
buf_output0 (protocol, "z");
}
@@ -4015,13 +3618,7 @@ CVS server internal error: unhandled case in server_updated");
sprintf (size_text, "%lu\n", size);
buf_output0 (protocol, size_text);
- if (file != NULL)
- {
- buf_output (protocol, file, file_used);
- free (file);
- file = NULL;
- }
- else if (filebuf == NULL)
+ if (filebuf == NULL)
buf_append_data (protocol, list, last);
else
{
@@ -4044,11 +3641,7 @@ CVS server internal error: unhandled case in server_updated");
/* 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);
- }
+ CVS_UNLINK (finfo->file);
}
else if (scratched_file != NULL && entries_line == NULL)
{
@@ -4543,81 +4136,78 @@ struct request requests[] =
#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("Checkin-prog", serve_checkin_prog, 0),
- REQ_LINE("Update-prog", serve_update_prog, 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("Root", serve_root, rq_essential),
+ REQ_LINE("Valid-responses", serve_valid_responses, rq_essential),
+ REQ_LINE("valid-requests", serve_valid_requests, rq_essential),
+ REQ_LINE("Repository", serve_repository, rq_optional),
+ REQ_LINE("Directory", serve_directory, rq_essential),
+ REQ_LINE("Max-dotdot", serve_max_dotdot, rq_optional),
+ REQ_LINE("Static-directory", serve_static_directory, rq_optional),
+ REQ_LINE("Sticky", serve_sticky, rq_optional),
+ REQ_LINE("Checkin-prog", serve_checkin_prog, rq_optional),
+ REQ_LINE("Update-prog", serve_update_prog, rq_optional),
+ REQ_LINE("Entry", serve_entry, rq_essential),
+ REQ_LINE("Kopt", serve_kopt, rq_optional),
+ REQ_LINE("Modified", serve_modified, rq_essential),
+ REQ_LINE("Is-modified", serve_is_modified, rq_optional),
/* 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("Case", serve_case, 0),
- REQ_LINE("Argument", serve_argument, RQ_ESSENTIAL),
- REQ_LINE("Argumentx", serve_argumentx, RQ_ESSENTIAL),
- REQ_LINE("Global_option", serve_global_option, 0),
- REQ_LINE("Gzip-stream", serve_gzip_stream, 0),
+ REQ_LINE("UseUnchanged", serve_enable_unchanged, rq_enableme),
+
+ REQ_LINE("Unchanged", serve_unchanged, rq_essential),
+ REQ_LINE("Notify", serve_notify, rq_optional),
+ REQ_LINE("Questionable", serve_questionable, rq_optional),
+ REQ_LINE("Case", serve_case, rq_optional),
+ REQ_LINE("Argument", serve_argument, rq_essential),
+ REQ_LINE("Argumentx", serve_argumentx, rq_essential),
+ REQ_LINE("Global_option", serve_global_option, rq_optional),
+ REQ_LINE("Gzip-stream", serve_gzip_stream, rq_optional),
REQ_LINE("wrapper-sendme-rcsOptions",
serve_wrapper_sendme_rcs_options,
- 0),
- REQ_LINE("Set", serve_set, RQ_ROOTLESS),
+ rq_optional),
+ REQ_LINE("Set", serve_set, rq_optional),
#ifdef ENCRYPTION
# ifdef HAVE_KERBEROS
- REQ_LINE("Kerberos-encrypt", serve_kerberos_encrypt, 0),
+ REQ_LINE("Kerberos-encrypt", serve_kerberos_encrypt, rq_optional),
# endif
# ifdef HAVE_GSSAPI
- REQ_LINE("Gssapi-encrypt", serve_gssapi_encrypt, 0),
+ REQ_LINE("Gssapi-encrypt", serve_gssapi_encrypt, rq_optional),
# endif
#endif
#ifdef HAVE_GSSAPI
- REQ_LINE("Gssapi-authenticate", serve_gssapi_authenticate, 0),
+ REQ_LINE("Gssapi-authenticate", serve_gssapi_authenticate, rq_optional),
#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("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("noop", serve_noop, 0),
- REQ_LINE(NULL, NULL, 0)
+ REQ_LINE("expand-modules", serve_expand_modules, rq_optional),
+ 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, rq_optional),
+ REQ_LINE("log", serve_log, rq_optional),
+ REQ_LINE("add", serve_add, rq_optional),
+ REQ_LINE("remove", serve_remove, rq_optional),
+ REQ_LINE("update-patches", serve_ignore, rq_optional),
+ REQ_LINE("gzip-file-contents", serve_gzip_contents, rq_optional),
+ REQ_LINE("status", serve_status, rq_optional),
+ REQ_LINE("rdiff", serve_rdiff, rq_optional),
+ REQ_LINE("tag", serve_tag, rq_optional),
+ REQ_LINE("rtag", serve_rtag, rq_optional),
+ REQ_LINE("import", serve_import, rq_optional),
+ REQ_LINE("admin", serve_admin, rq_optional),
+ REQ_LINE("export", serve_export, rq_optional),
+ REQ_LINE("history", serve_history, rq_optional),
+ REQ_LINE("release", serve_release, rq_optional),
+ REQ_LINE("watch-on", serve_watch_on, rq_optional),
+ REQ_LINE("watch-off", serve_watch_off, rq_optional),
+ REQ_LINE("watch-add", serve_watch_add, rq_optional),
+ REQ_LINE("watch-remove", serve_watch_remove, rq_optional),
+ REQ_LINE("watchers", serve_watchers, rq_optional),
+ REQ_LINE("editors", serve_editors, rq_optional),
+ REQ_LINE("init", serve_init, rq_optional),
+ REQ_LINE("annotate", serve_annotate, rq_optional),
+ REQ_LINE("noop", serve_noop, rq_optional),
+ REQ_LINE(NULL, NULL, rq_optional)
#undef REQ_LINE
};
@@ -5015,31 +4605,7 @@ error ENOMEM Virtual memory exhausted.\n");
* "co".
*/
continue;
-
- if (!(rq->flags & RQ_ROOTLESS)
- && CVSroot_directory == 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);
+ (*rq->func) (cmd);
break;
}
if (rq->name == NULL)
@@ -5071,74 +4637,48 @@ switch_to_user (username)
pw = getpwnam (username);
if (pw == NULL)
{
- /* Normally this won't be reached; check_password contains
- a similar check. */
-
printf ("E Fatal error, aborting.\n\
error 0 %s: no such user\n", username);
- /* Don't worry about server_cleanup; server_active isn't set yet. */
- error_exit ();
+ /* I'm doing this manually rather than via error_exit ()
+ because I'm not sure whether we want to call server_cleanup.
+ Needs more investigation.... */
+
+#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);
}
+ /* FIXME? We don't check for errors from initgroups, setuid, &c.
+ I think this mainly would come up if someone is trying to run
+ the server as a non-root user. I think we should be checking for
+ errors and aborting (as with the error above from getpwnam) if
+ there is an error (presumably EPERM). That means that pserver
+ should continue to work right if all of the "system usernames"
+ in CVSROOT/passwd match the user which the server is being run
+ as (in inetd.conf), but fail otherwise. */
+
#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 ();
- }
+ initgroups (pw->pw_name, pw->pw_gid);
#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 setuid failed: %s\n", strerror (errno));
- /* Don't worry about server_cleanup;
- server_active isn't set yet. */
- error_exit ();
- }
+ setgid (getegid ());
}
else
-#endif
+#else
{
- if (setgid (pw->pw_gid) < 0)
- {
- /* See comments at setuid call below for more discussion. */
- printf ("error 0 setuid failed: %s\n", strerror (errno));
- /* Don't worry about server_cleanup;
- server_active isn't set yet. */
- error_exit ();
- }
+ setgid (pw->pw_gid);
}
+#endif
- 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));
- /* Don't worry about server_cleanup; server_active isn't set yet. */
- error_exit ();
- }
-
+ setuid (pw->pw_uid);
/* 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. */
@@ -5232,15 +4772,18 @@ check_repository_password (username, password, repository, host_user_ptr)
/* If found_it != 0, then linebuf contains the information we need. */
if (found_it)
{
- char *found_password, *host_user_tmp;
+ char *found_password, *host_user_tmp = NULL;
+ char *linebufp = linebuf;
- strtok (linebuf, ":");
- found_password = strtok (NULL, ": \n");
- host_user_tmp = strtok (NULL, ": \n");
+ strsep (&linebufp, ":");
+ found_password = strsep (&linebufp, ": \n");
+ if (found_password)
+ host_user_tmp = strsep (&linebufp, ": \n");
if (host_user_tmp == NULL)
host_user_tmp = username;
- if (strcmp (found_password, crypt (password, found_password)) == 0)
+ if (found_password == NULL || *found_password == '\0' ||
+ strcmp (found_password, crypt (password, found_password)) == 0)
{
/* Give host_user_ptr permanent storage. */
*host_user_ptr = xstrdup (host_user_tmp);
@@ -5278,7 +4821,10 @@ check_password (username, password, repository)
password file. If so, that's enough to authenticate with. If
not, we'll check /etc/passwd. */
- rc = check_repository_password (username, password, repository,
+ if (require_real_user)
+ rc = 0; /* "not found" */
+ else
+ rc = check_repository_password (username, password, repository,
&host_user);
if (rc == 2)
@@ -5543,23 +5089,32 @@ pserver_authenticate_connection ()
host_user = check_password (username, descrambled_password, repository);
memset (descrambled_password, 0, strlen (descrambled_password));
free (descrambled_password);
- if (host_user == NULL)
+ if (host_user)
+ {
+ printf ("I LOVE YOU\n");
+ fflush (stdout);
+ }
+ else
{
i_hate_you:
printf ("I HATE YOU\n");
fflush (stdout);
+ /* I'm doing this manually rather than via error_exit ()
+ because I'm not sure whether we want to call server_cleanup.
+ Needs more investigation.... */
+
+#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
- /* Don't worry about server_cleanup, server_active isn't set
- yet. */
- error_exit ();
+ exit (EXIT_FAILURE);
}
/* Don't go any farther if we're just responding to "cvs login". */
if (verify_and_exit)
{
- printf ("I LOVE YOU\n");
- fflush (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. */
@@ -5581,8 +5136,6 @@ pserver_authenticate_connection ()
free (username);
free (password);
- printf ("I LOVE YOU\n");
- fflush (stdout);
#endif /* AUTH_SERVER_SUPPORT */
}
diff --git a/contrib/cvs/src/update.c b/contrib/cvs/src/update.c
index 4a24d15..dd64ab7 100644
--- a/contrib/cvs/src/update.c
+++ b/contrib/cvs/src/update.c
@@ -1,32 +1,32 @@
/*
* Copyright (c) 1992, Brian Berliner and Jeff Polk
* Copyright (c) 1989-1992, Brian Berliner
- *
+ *
* You may distribute under the terms of the GNU General Public License as
* specified in the README file that comes with the CVS source distribution.
- *
+ *
* "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
* <user_file>
- *
+ *
* Modified user files are reported as M <user_file>. 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
* <user_file>, and as M <user_file> otherwise.
- *
+ *
* Files added but not yet committed are reported as A <user_file>. Files
* removed but not yet committed are reported as R <user_file>.
- *
+ *
* 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
@@ -284,11 +284,11 @@ update (argc, argv)
if (failed_patches == NULL)
{
+ send_file_names (argc, argv, SEND_EXPAND_WILD);
/* If noexec, probably could be setting SEND_NO_CONTENTS.
Same caveats as for "cvs status" apply. */
send_files (argc, argv, local, aflag,
update_build_dirs ? SEND_BUILD_DIRS : 0);
- send_file_names (argc, argv, SEND_EXPAND_WILD);
}
else
{
@@ -304,13 +304,10 @@ update (argc, argv)
}
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]);
+ (void) unlink_file (failed_patches[i]);
+ send_file_names (failed_patches_count, failed_patches, 0);
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);
}
failed_patches = NULL;
@@ -489,12 +486,9 @@ do_update (argc, argv, xoptions, xtag, xdate, xforce, local, xbuild, xaflag,
{
time_t now;
- for (;;)
- {
- (void) time (&now);
- if (now != last_register_time) break;
+ (void) time (&now);
+ if (now == last_register_time)
sleep (1); /* to avoid time-stamp races */
- }
}
return (err);
@@ -577,7 +571,7 @@ update_fileproc (callerdat, finfo)
&& tag != NULL
&& finfo->rcs != NULL)
{
- char *rev = RCS_getversion (finfo->rcs, tag, NULL, 1, NULL);
+ char *rev = RCS_getversion (finfo->rcs, tag, date, 1, NULL);
if (rev != NULL
&& !RCS_nodeisbranch (finfo->rcs, tag))
nonbranch = 1;
@@ -637,7 +631,15 @@ update_fileproc (callerdat, finfo)
write_letter (finfo, 'C');
break;
case T_NEEDS_MERGE: /* needs merging */
- retval = merge_file (finfo, vers);
+ if (noexec)
+ {
+ retval = 1;
+ write_letter (finfo, 'C');
+ }
+ else
+ {
+ retval = merge_file (finfo, vers);
+ }
break;
case T_MODIFIED: /* locally modified */
retval = 0;
@@ -872,28 +874,6 @@ update_dirent_proc (callerdat, dir, repository, update_dir, entries)
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). */
- if (1
-#ifdef SERVER_SUPPORT
- /* 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. */
- && !server_active
-#endif
- && !isdir (repository))
- return R_SKIP_ALL;
-
if (noexec)
{
/* ignore the missing dir if -n is specified */
@@ -1305,14 +1285,11 @@ VERS: ", 0);
{
Vers_TS *xvers_ts;
- if (revbuf != NULL && !noexec)
+ if (revbuf != NULL)
{
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. */
+ /* FIXME: We should have RCS_checkout return the mode. */
if (stat (vers_ts->srcfile->path, &sb) < 0)
error (1, errno, "cannot stat %s",
vers_ts->srcfile->path);
@@ -1512,7 +1489,7 @@ struct patch_file_data
/* Whether to compute the MD5 checksum. */
int compute_checksum;
/* Data structure for computing the MD5 checksum. */
- struct cvs_MD5Context context;
+ struct MD5Context context;
/* Set if the file has a final newline. */
int final_nl;
};
@@ -1591,11 +1568,7 @@ patch_file (finfo, vers_ts, docheckout, file_info, checksum)
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);
- }
+ (void) unlink_file (backup);
file1 = xmalloc (strlen (finfo->file)
+ sizeof (CVSADM)
@@ -1644,10 +1617,10 @@ patch_file (finfo, vers_ts, docheckout, file_info, checksum)
data.fp = e;
data.final_nl = 0;
data.compute_checksum = 1;
- cvs_MD5Init (&data.context);
+ MD5Init (&data.context);
retcode = RCS_checkout (vers_ts->srcfile, (char *) NULL,
- vers_ts->vn_rcs, vers_ts->vn_tag,
+ vers_ts->vn_rcs, (char *) NULL,
vers_ts->options, RUN_TTY,
patch_file_write, (void *) &data);
@@ -1657,7 +1630,7 @@ patch_file (finfo, vers_ts, docheckout, file_info, checksum)
if (retcode != 0 || ! data.final_nl)
fail = 1;
else
- cvs_MD5Final (checksum, &data.context);
+ MD5Final (checksum, &data.context);
}
retcode = 0;
@@ -1782,15 +1755,9 @@ patch_file (finfo, vers_ts, docheckout, file_info, checksum)
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);
+ (void) unlink_file (backup);
+ (void) unlink_file (file1);
+ (void) unlink_file (file2);
free (backup);
free (file1);
@@ -1816,7 +1783,7 @@ patch_file_write (callerdat, buffer, len)
data->final_nl = (buffer[len - 1] == '\n');
if (data->compute_checksum)
- cvs_MD5Update (&data->context, (unsigned char *) buffer, len);
+ MD5Update (&data->context, (unsigned char *) buffer, len);
}
#endif /* SERVER_SUPPORT */
@@ -1892,8 +1859,7 @@ merge_file (finfo, vers)
+ 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);
+ (void) unlink_file (backup);
copy_file (finfo->file, backup);
xchmod (finfo->file, 1);
@@ -1996,17 +1962,10 @@ merge_file (finfo, vers)
}
#endif
- /* 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);
-
+ printf ("%s already contains the differences between %s and %s\n",
+ finfo->fullname, vers->vn_user, vers->vn_rcs);
history_write ('G', finfo->update_dir, vers->vn_rcs, finfo->file,
finfo->repository);
retval = 0;
@@ -2015,7 +1974,8 @@ merge_file (finfo, vers)
if (status == 1)
{
- error (0, 0, "conflicts found in %s", finfo->fullname);
+ if (!noexec)
+ error (0, 0, "conflicts found in %s", finfo->fullname);
write_letter (finfo, 'C');
@@ -2366,9 +2326,7 @@ join_file (finfo, vers)
+ 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);
+ (void) unlink_file (backup);
copy_file (finfo->file, backup);
xchmod (finfo->file, 1);
diff --git a/contrib/cvs/tools/pcl-cvs/ChangeLog.woods b/contrib/cvs/tools/pcl-cvs/ChangeLog.woods
deleted file mode 100644
index 827c3f2..0000000
--- a/contrib/cvs/tools/pcl-cvs/ChangeLog.woods
+++ /dev/null
@@ -1,383 +0,0 @@
-Thu Jan 4 13:19:20 1996 Greg A. Woods <woods@most.weird.com>
-
- * pcl-cvs.el:
- - from Cyclic CVS version:
-
- Sat Dec 30 15:01:45 1995 Karl Fogel <kfogel@floss.cyclic.com>
-
- * pcl-cvs.el (cvs-changelog-ours-p): check that
- `add-log-full-name' and `add-log-mailing-address' are non-nil, in
- addition to checking that they are boundp.
-
-Fri Dec 22 17:52:17 1995 Greg A. Woods <woods@most.weird.com>
-
- * pcl-cvs.el:
- - (cvs-parse-stdout): make the "connection timed out" an error
-
- - from Cyclic CVS version:
-
- Thu Dec 21 16:45:48 1995 Karl Fogel <kfogel@occs.cs.oberlin.edu>
-
- * pcl-cvs.el (cvs-parse-stderr): ignore kerberos connection
- failure, since CVS will automatically try rsh next. I think this
- is okay because if a person needs to know that kerberos failed,
- then chances are the rsh failed too, and *that* error message will
- clue them in that something's afoot.
-
-Thu Dec 21 21:13:10 1995 Greg A. Woods <woods@most.weird.com>
-
- * pcl-cvs.el:
- - (cvs-parse-stdout): handle "Permission denied" (which will
- often precede the "premature EOF from server" message....)
-
- - from Cyclic CVS version:
-
- Wed Nov 22 11:01:50 1995 Joshua Cowan <jcowan@hermit.reslife.okstate.edu>
-
- * pcl-cvs.el (cvs-changelog-ours-p): use `user-full-name' if
- `add-log-full-name' unbound, as not every uses the stuff in
- add-log.el. Same with `add-log-mailing-address'.
- (cvs-changelog-entries): change to `change-log-mode' unless
- already in it.
-
- * ToDo:
- - more new ideas....
-
-Mon Nov 27 23:19:50 1995 Greg A. Woods <woods@most.weird.com>
-
- * pcl-cvs.el:
- - add more support for recognizing unknown directories
- - add initial support for properly supporting directories with cvs-mode-add
-
-Tue Nov 21 16:51:45 1995 Greg A. Woods <woods@most.weird.com>
-
- * pcl-cvs.el:
- - fix up the debug mail message buffer formatting
- - include bugs@most.weird.com on debug message list (i.e. my gnats)
- (cvs-parse-stderr): fix up handling of some transient errors, such as
- network server errors
-
-Mon Nov 20 19:13:34 1995 Greg A. Woods <woods@most.weird.com>
-
- * Makefile:
- - minor tweaks on version numbers, etc.
- - added '-n -q' to emacs arguments...
-
- * pcl-cvs.texinfo:
- - mention new pcl-cvs release properly
- - mention new CVS release
- - fix grammar & layout style here and there...
- - move GPL to the bottom and into an included file (should ref another
- info document)
- - add Ediff documentation, fix up Emerge docs.
- - updated Contributors section
- - add note about 'Patched' state (FIXME: more remote docs needed!!!!)
- - added some documentation for cvs-mode-changelog-commit
- - added a few more index entries, etc.
-
- * pcl-cvs.el:
- - update comments and documentation, fix grammar, etc.
- - mention new CVS release
- - re-sort cvs-mode-map setup, document key-map convention
- - re-write (cvs-mode-ediff), adding (cvs-old-ediff-interface)
- - fix (cvs-retrieve-revision-to-tmpfile) to handle empty revision arg.
-
- * ToDo:
- - lots of new ideas
- - give up on 'C-u' for cvs-mode-*
- - minor prioritisation
-
-Thu Nov 16 20:38:58 1995 Greg A. Woods <woods@most.weird.com>
-
- * pcl-cvs.el (cvs-mode-emerge):
- fix the quit-hook setup for ediff-*
- (cvs-mode-ediff): new, based on cvs-mode-emerge
-
- * pcl-cvs.el (cvs-mode-emerge):
- cleanups and use emerge-hooks, and protect from
- multiple invocations (idea from Loren James Rittle <rittle@comm.mot.com>)
-
- * pcl-cvs.el (cvs-diff-program):
- document problems with vendor versions
-
- * pcl-cvs.el, ToDo:
- - add minimal "cvs tag" and "cvs rtag" support
- (cvs-mod): clean up the documentation
- (cvs-mode-map): clean up a bit too
- (cvs-mode-log), (cvs-mode-status): clean up implementation
-
-Wed Nov 15 18:39:22 1995 Greg A. Woods <woods@most.weird.com>
-
- * pcl-cvs.el, ToDo:
- (cvs-parse-stderr) - handle some more error messages from CVS
-
- * pcl-cvs.el:
- Various tweaks and fixes after diffing with CVS-1.6.1 version:
- - spelling/typos
- - minor re-indentation
- - missed one check for PATCHED
- - more documentation and comment fixups
-
- * pcl-cvs.el:
- From: Loren James Rittle <rittle@comm.mot.com>
- To: info-cvs@prep.ai.mit.edu
- Subject: Change to allow pcl-cvs to use ediff instead of emerge
- Date: Mon, 6 Nov 95 17:17:31 CST
-
- 2) ensures the user wants to `update' in cases where a possible conflict
- currectly exists;
-
- * pcl-cvs.el:
- Message-Id: <9511062119.AA29213@supra.comm.mot.com>
- From: Loren James Rittle <rittle@comm.mot.com>
- To: info-cvs@prep.ai.mit.edu
- Subject: Change to allow pcl-cvs to use more hidden buffer names
- Date: Mon, 6 Nov 95 15:19:57 CST
-
-
- PCL-CVS uses hidden buffers in some places. This patch makes more
- PCL-CVS buffers hidden.
-
- Loren
-
-Tue Nov 14 20:56:41 1995 Greg A. Woods <woods@most.weird.com>
-
- * pcl-cvs.el (cvs-do-removal):
- don't fail if the file is missing or a directory
- (cvs-mode-add-change-log-entry-other-window): get the
- change-log-filename and entry name right
-
- * pcl-cvs.el, ChangeLog:
- * pcl-cvs.el (local-path, local-gnu-path): added documentation
- string
- (cvs-rmdir-program): use the proper default and leave it alone
-
- * pcl-cvs.el:
- - from ccvs official sources:
- revision 1.12
- pcl-cvs.el 1995/05/19 01:59:26 jimb
- Automatically guess CVS log entries from ChangeLog contents.
- * pcl-cvs.el (cvs-mode-changelog-commit): New command.
- (cvs-changelog-full-paragraphs): New variable.
- (cvs-changelog-name, cvs-narrow-changelog,
- cvs-changelog-paragraph, cvs-changelog-subparagraph,
- cvs-changelog-entry, cvs-changelog-ours-p, cvs-relative-path,
- cvs-changelog-entries, cvs-changelog-insert-entries, cvs-union,
- cvs-insert-changelog-entries, cvs-edit-delete-common-indentation): New functions.
- (cvs-mode-map): Bind 'C' to cvs-mode-changelog-commit.
- (cvs-mode): Mention cvs-mode-changelog-commit in docstring.
-
- * ChangeLog:
- - from ccvs official sources:
- revision 1.12
- ChangeLog 1995/05/19 01:59:26 jimb
- Automatically guess CVS log entries from ChangeLog contents.
- * pcl-cvs.el (cvs-mode-changelog-commit): New command.
- (cvs-changelog-full-paragraphs): New variable.
- (cvs-changelog-name, cvs-narrow-changelog,
- cvs-changelog-paragraph, cvs-changelog-subparagraph,
- cvs-changelog-entry, cvs-changelog-ours-p, cvs-relative-path,
- cvs-changelog-entries, cvs-changelog-insert-entries, cvs-union,
- cvs-insert-changelog-entries, cvs-edit-delete-common-indentation): New functions.
- (cvs-mode-map): Bind 'C' to cvs-mode-changelog-commit.
- (cvs-mode): Mention cvs-mode-changelog-commit in docstring.
-
- * pcl-cvs.el:
- - slight variant of this change ccvs official sources
- revision 1.10
- pcl-cvs.el 1995/05/03 18:56:20 jimb
- (cvs-parse-stderr): Handle colons after both "rcsmerge" and "warning".
-
- * pcl-cvs.el:
- - from ccvs official sources
- revision 1.9
- pcl-cvs.el 1995/04/26 02:36:15 jimb
- (cvs-parse-stderr): Recognize "conflicts" as well as "overlaps" before
- "during merge."
- - also fixed a few other minor inconsitencies in that region...
-
- * pcl-cvs.el:
- - from ccvs official sources
- revision 1.5
- pcl-cvs.el 1995/01/31 23:31:39 jimb
- (cvs-cvsroot-required): New variable.
- (cvs-do-update): If cvs-cvsroot-required is not set, don't complain if
- CVSROOT and cvs-cvsroot are both unset.
-
- * pcl-cvs.el:
- - use 'identity instead of '(lambda (foo) foo)
- - fix a botch in cvs-make-list
- - check cvs-status-flags and cvs-log-flags are lists before using them
-
-Mon Nov 13 23:49:25 1995 Greg A. Woods <woods@most.weird.com>
-
- * pcl-cvs.el:
- - fixed up version strings
- - minor changes to cvs-*-flags defaults
- - added functions parse-string and cvs-make-list
- - modified various parsers to handle "cvs server:" messages
- - added support for "P" flag (PATCHED)
- - fixed use of "-Q" for "cvs status"
- - use cvs-make-list when reading new values for cvs-*-flags
-
- * Makefile:
- - fix the info install rules...
-
- * ToDo:
- - more things to look into...
-
-Sun Mar 12 20:40:05 1995 Greg A. Woods <woods@most.weird.com>
-
- * pcl-cvs.el:
- - minor twiggle to old RCS Id's to match format
-
- * Makefile:
- - fix up RCS Id's
- - add clobber to "clean" targets
- - separate installation of *.el's and default off
- - fix INSTALL_DATA
-
- * pcl-cvs.el:
- - minor twiggles to automatically localise and to note this is a local version
-
- * ToDo:
- - first cut
-
- * .cvsignore:
- - first time in -- default generated targets
-
-Tue Nov 22 20:49:39 1994 Greg A. Woods <woods@most.weird.com>
-
- * pcl-cvs.el:
- - adjust RCS keywords
- - reset shell to just /bin/sh
-
-Fri Nov 4 21:14:55 1994 Greg A. Woods <woods@most.weird.com>
-
- * pcl-cvs.el:
- - fix directory for new CVS-1.4
- - add '-v' to cvs-status-flags
-
-Mon Dec 6 19:06:18 1993 Greg A. Woods <woods@most.weird.com>
-
- * pcl-cvs.el:
- - I don't quite know how that happened, but we had a variable and
- function with the same name, and an un-defined variable....
-
- * pcl-cvs.el:
- - re-format a few things....
- - replace numerous duplicate lambda expressions with a new common
- function: cvs-quote-multiword-string
-
-Fri Nov 26 20:54:25 1993 Greg A. Woods <woods@most.weird.com>
-
- * pcl-cvs.el:
- - oops! was changing the directory string we were comparing against!
-
- * pcl-cvs.el:
- - oops -- missing an end-sexp....
-
- * pcl-cvs.el:
- - in theory this fixes up all the local directory vs.
- default-directory problems
-
- * pcl-cvs.el:
- - ensure multi-word args are quoted in messages
- - enhance naming of diff buffers
-
-Fri Nov 12 18:43:09 1993 Greg A. Woods <woods@most.weird.com>
-
- * pcl-cvs.el:
- - update comment about "Conflict"...
- - fiddle with rcs-ident stuff
-
-Thu Nov 4 01:15:53 1993 Greg A. Woods <woods@most.weird.com>
-
- * pcl-cvs.el:
- - set default cvs-status-flags to '("-Q)
- - use cvs-bakprefix where intended
- - add functions and keymaps for setting cvs-*-flags.
- - re-pretty-print some stuff
-
-Wed Nov 3 23:11:15 1993 Greg A. Woods <woods@most.weird.com>
-
- * pcl-cvs.el:
- - use cvs-kill-buffer-visiting in cvs-mode-diff-vendor for cleanup.
- - fix last minibuffer message in cvs-mode-diff-vendor.
-
- * pcl-cvs.el:
- - OOPS! put (list ...) back where we need evaluation.
- - default to use of CVS/Root always for cvs-update, if it exits.
-
- * pcl-cvs.el:
- - oops -- minor bug with usage of mapconcat
- - changed (list ...) to '(...)
-
- * pcl-cvs.texinfo:
- - minor updates of filenames and versions.
- - added myself as a contributor
-
- * pcl-cvs.el:
- - re-justified multitueds of comments, and fixed minor bits too.
- - added support for CVS/Root file to supplement use of $CVSROOT and/or
- cvs-cvsroot.
- - added cvs-mode-map binding for cvs-change-cvsroot
- - added optional message-fmt argument to cvs-execute-list (prints
- message showing progress in minibuffer).
- - modified cvs-mode-diff-cvs to put results in
- cvs-fileinfo->cvs-diff-buffer.
- - modified cvs-mode-diff-backup to put results in
- cvs-fileinfo->backup-diff-buffer.
- - modified cvs-mode-diff-vendor to put results in
- cvs-fileinfo->vendor-diff-buffer.
- - modified cvs-mode-diff-* to use cvs-diff-flags.
- - added cvs-*-diffable.
- - fixed various minibuffer progress messages.
-
-Thu Oct 28 23:10:38 1993 Greg A. Woods <woods@most.weird.com>
-
- * pcl-cvs.el:
- - many minor improvements,
- - several bug fixes,
- - added some support for vendor branch merging,
-
-Tue Oct 26 18:26:33 1993 Greg A. Woods <woods@most.weird.com>
-
- * Makefile:
- - fixes, localisations, etc.
-
-Fri Oct 22 21:19:15 1993 Greg A. Woods <woods@most.weird.com>
-
- * pcl-cvs.el, Makefile:
- - localisations....
-
- * pcl-cvs.el:
- pick the 1.05 version over local edits....
-
-Thu Oct 21 21:40:26 1993 Greg A. Woods <woods@most.weird.com>
-
- * texinfo.tex, pcl-cvs.texinfo, pcl-cvs.el, pcl-cvs-startup.el, pcl-cvs-lucid.el, compile-all.el, README, NEWS, Makefile, INSTALL, ChangeLog:
- pcl-cvs version 1.05 distribution
-
-Tue Jun 1 16:25:35 1993 Greg A. Woods <woods@most.weird.com>
-
- * pcl-cvs.el:
- add a newline to the cvs-mode-add description
-
-Fri May 28 14:13:41 1993 Greg A. Woods <woods@most.weird.com>
-
- * pcl-cvs.el:
- add cvs-commit-buffer-require-final-newline to allow forcing a newline
- onto the commit buffer
-
-Fri May 14 22:35:01 1993 Greg A. Woods <woods@most.weird.com>
-
- * pcl-cvs.el:
- localizations....
-
- * ChangeLog, INSTALL, Makefile, NEWS, README, compile-all.el, pcl-cvs.el, pcl-cvs-lucid.el, pcl-cvs-startup.el, pcl-cvs.texinfo, texinfo.tex:
- pcl-cvs version 1.04 distribution
-
- * ChangeLog, INSTALL, Makefile, NEWS, README, compile-all.el, pcl-cvs.el, pcl-cvs-lucid.el, pcl-cvs-startup.el, pcl-cvs.texinfo, texinfo.tex:
- Initial revision
-
diff --git a/contrib/cvs/tools/pcl-cvs/ToDo b/contrib/cvs/tools/pcl-cvs/ToDo
deleted file mode 100644
index 8e317f8..0000000
--- a/contrib/cvs/tools/pcl-cvs/ToDo
+++ /dev/null
@@ -1,44 +0,0 @@
-- documentation.... (esp. ChangeLog support)
-
-- IMPORTANT: make cvs-mode-tag run in the background
-
-- fix 'cvs-mode-add' to "cvs update" in the added directory
-
-- write 'cvs-mode-import'
-
-- write 'cvs-mode-handle-new-vendor-version'
-
- - checks out module
- - does "cvs -n tag LAST_VENDOR" to find old files into *cvs*
-
-- add 'cvs-set-cvs-flags' for top level cvs command flags
-
-- add '\M-a' to do arbitrary 'cvs admin' commands
-
-- add 'cvs patch' support (with completion on tag names and hooks to
-help generate ChangeLog files with rcs2log, etc.)
-
-- add 'cvs export' support (with completion on tag names and hooks to
-help generate full releases)
-
-- add 'cvs-mode-version' to call 'cvs -v' [on ^C-cv ?] (really???)
-
-- re-write rcs2log in e-lisp.
-
-- add support for parsing 'modules' file ("cvs co -c")
-
-- enhance 'cvs-mode-rtag'
-
-- fix 'cvs-examine'
-
-- write 'cvs-mode-checkout' and 'cvs-mode-checkout-other-window'
-
-- write 'cvs-mode-release'
-
-- add an update mode that keeps all files
-
- - this will require all commands to work only on non-up-to-date
- files
-
---
-#ident "@(#)cvs/contrib/pcl-cvs:$Name: $Id: ToDo,v 1.1 1996/04/14 15:17:57 kfogel Exp $"
OpenPOWER on IntegriCloud