12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042 |
- Index: src/README.RSE
- ===================================================================
- RCS file: src/README.RSE
- diff -N src/README.RSE
- --- /dev/null 1 Jan 1970 00:00:00 -0000
- +++ src/README.RSE 16 Feb 2002 12:35:28 -0000
- @@ -0,0 +1,353 @@
- +
- + CVS RSE Patches
- + ===============
- +
- + This is the patched version of CVS from Ralf S. Engelschall
- + <rse@engelschall.com> - an enhanced version of the official
- + Cyclic/OpenAvenue's CVS version 1.11.1p1 (see http://www.cvshome.org/).
- +
- + The following changes against the avendor CVS version are provided:
- + - support for .cvsrc files in $HOME _AND_ working and and its parent dirs
- + - support for $HOME/.cvsroot to alias roots and to support root mirrors
- + - support global but command specific options in .cvsrc files
- + - support for stand-alone external custom commands `cvs <command>'
- + - support for prolog and epilog hooks
- + - allow `verifymsg' hooks to _change_ the log message
- + - support `$LocalId$, a local keyword variant of `$Id$'
- + - support `$CVSHeader$, a variant of `$Header$', but without root path
- + - new `cvs -u' option in addition to `cvs -n' for _REAL_ read-only access
- + - support for additional `%x' variables on `loginfo' hook command lines
- + - support a `UMask=<mask>' variable in `$CVSROOT/CVSROOT/config'
- + - speeded up `cvs update' by sending whole file if smaller than the diff
- + - disabled keyword expansions during branch merges
- + - adjusted `cvs diff -rHEAD' to be consistent with other commands
- + - made `cvs diff' aware of removed/dead files in the trunk
- + - set `$LOGNAME' to the real user and not the CVS user
- + - support for `HistoryFile=<rel-path-under-CVSROOT>' variable in config.
- + - support for an `admininfo' hook to ACL `cvs admin' commands.
- + - support for an `importinfo' hook to ACL `cvs import' commands.
- + - support for a `-h<handle>' option to `cvs diff' for compressed time spec.
- + - use prefix 'T' ("touched/tagged") instead of 'U' ("updated") on `cvs import'
- + - allow `LockDir' configuration directive to use relative paths
- + - allow a hard-coded CVS super-user to override CVS user via $CVSUSER
- + - additional SetUID/SetGID support for `cvs server' situations.
- + - new `cvs pserverd' for running stand-alone pserver daemons
- + - new global --map-root=/oldpath:/newpath option for mapping root paths
- + - support for wildcards in CVSROOT/passwd files to decrease admin efforts
- + - various cosmetic changes
- +
- + Some of my RSE functional patches are only useful for the server side,
- + others are also useful on the client side. All source patches to
- + *.[ch] files were entirely wrapped with ``#ifdef RSE_PATCH_<NAME> ...
- + #endif'' pairs. So, a particular patch is enabled by building CVS with
- + -DRSE_PATCH_<NAME>. All patches are enabled with -DRSE_PATCHES.
- +
- + Ralf S. Engelschall
- + rse@engelschall.com
- + www.engelschall.com
- + ________________________________________________________________________
- +
- + The following particular patches are available:
- +
- + RSE_PATCH_CVSRC:
- + In addition to processing `$HOME/.cvsrc', process also `.cvsrc'
- + files in the current working directory and the parent directories of
- + the current working directory. This allows one to use for instance a
- + `commit -m ""' locally (as used for GNU Pth development where CVS is
- + only used for plain revision control and not for bookkeeping changes
- + or group communication - instead a plain manually edited ChangeLog
- + exists) or `commit -d <master>' (if working with a local repository
- + copy). Additionally this adds support for quoted strings inside
- + .cvsrc files.
- + [Origin: Ralf S. Engelschall]
- +
- + RSE_PATCH_CVSROOT:
- + This adds support for a new dot-file ~/.cvsroot which is used
- + optionally by CVS. It can be used by the user to configure a
- + nickname for a CVS repository root (the master location) plus a
- + possibly existing local repository copy (the slave location). An
- + entry in ~/.cvsroot is of the format ``<nickname> <master-path>
- + [<slave-path> [<sync-prog>]]''. Those entries can be either created
- + manually in ~/.cvsroot or with the `cvs root -e' command.
- +
- + The idea is this: if a global `-d' option is used with <nickname> it is
- + automatically expanded to <master-path>. If no global `-d' option is used,
- + the CVS command is checked. If it is one of the commands which are known
- + to CVS to modify the repository, and the $CVSROOT or CVS/Root specify a
- + slave location, the repository is switched to the corresponding master
- + location (because modifications have to be performed there). If the
- + command is one of the commands which are known to CVS to NOT modify the
- + repository, and the $CVSROOT or CVS/Root specify a master location, the
- + repository is switched to the corresponding slave location (because the
- + slave location is faster than the master location per definition).
- +
- + After a modifying operation, CVS can either run a synchronization job
- + automatically to bring slave in sync with master again or the user can run
- + `cvs root -s <nickname>' manually to perform this task.
- + [Origin: Ralf S. Engelschall]
- +
- + RSE_PATCH_GLOBALOPTION:
- + RSE_PATCH_GLOBALOPTION_PARTLY:
- + By default, global options in `.cvsrc' files are specified with a
- + `cvs' prefix. These options then apply to _all_ cvs commands. If
- + RSE_PATCH_GLOBALOPTION is enabled, a second pass is done where all
- + global options are read with prefix `cvs/<command>' where <command>
- + is the official cvs command (for instance `commit' or `checkout',
- + even if `ci' or `co' are used on the command line). This is useful
- + for instance to override CVSROOT in commit commands if using a local
- + repository copy. The drawback of this feature is that it obviously
- + slows down cvs calls, because a second pass has to be done. But
- + usually this feature is intended only for use with `commit', `tag',
- + `rtag', `history', `admin', `import' and `rdiff' commands, so if
- + RSE_PATCH_GLOBALOPTION_PARTLY is additionally enabled, this second
- + pass is only done for those commands (which is the recommended use
- + of this feature).
- + [Origin: Ralf S. Engelschall]
- +
- + RSE_PATCH_CUSTOMCMD:
- + This provides an additional global option `-C
- + <cmd-name>:<cmd-program>' which defines an additional CVS command
- + <cmd-name>. It is intended for use on `cvs' lines inside .cvsrc
- + files. The effect of having `cvs -Csync:$CVSROOT/CVSROOT/sync' in a
- + .cvsrc file is (and assuming $CVSROOT is /e/ossp/cvs) that if you
- + run `cvs sync <arg1> <arg2>', CVS executes `/e/ossp/cvs/CVSROOT/sync
- + <arg1> <arg2>'. So this is a way to externally extend CVS with
- + additional commands.
- + [Origin: Ralf S. Engelschall]
- +
- + RSE_PATCH_PROLOGEPILOG:
- + Provides the two additional CVS options `-P <program>' and `-E
- + <program>' for running prolog and epilog programs before and
- + after the usual CVS processing. This is mainly intended as local
- + hooks for implicitly wrapping CVS commands (without having to
- + create slow wrapping shell scripts, etc.). Developers usually
- + use it to automatically start their RSYNC command to update the
- + local repository copy after a commit. The <program> is called
- + with four arguments: $1 is either `prolog' or `epilog' (useful
- + if one just wants to use a single hook program), $2 is the cvs
- + command (it is `commit' even `ci' is used, etc.), $3 is the current
- + working directory from which the cvs command was run and $4 is the
- + corresponding $CVSROOT variable.
- + [Origin: Ralf S. Engelschall]
- +
- + RSE_PATCH_VERIFY:
- + This patch forces CVS to read in again the log messages after the
- + verification step (via the `verifymsg' hook) to allow the hook
- + script to actually _update_ the log message. This is useful for
- + stripping out unnecessary stuff, like not filled out custom fields
- + of the log template text.
- + [Origin: Peter Wemm, FreeBSD]
- +
- + RSE_PATCH_LOCALID:
- + Support a local keyword variant of `$Id$'. By default this is
- + `$LocalId$', but if -DRSE_PATCH_LOCALID_NAME=\"<name>\" is
- + additionally defined, then the keyword is `$<name>$'. Alternatively
- + one can define the name also in the `$CVSROOT/CVSROOT/config' file
- + with `LocalIdName=<name>'.
- + [Origin: NetBSD, OpenBSD, Ralf S. Engelschall]
- +
- + RSE_PATCH_CVSHEADER:
- + Support the `$CVSHeader' variant of `$Header$' which has the
- + $CVSROOT prefix stripped of from the path. This is useful because
- + the prefix usually useless outside the server environment.
- + [Origin: FreeBSD]
- +
- + RSE_PATCH_NOLOCK:
- + Provide a `cvs -u' option in addition to `cvs -n' to force CVS to
- + not create any lock files in the repository. This is for supporting
- + read-only access to the repository. This is useful for working
- + with CVS repositories on CD-ROMs and for providing anonymous CVS
- + services.
- + [Origin: NetBSD]
- +
- + RSE_PATCH_EXTRAPERCENT:
- + This adds extra percent expansions to `loginfo' command lines:
- + `%o' to expand the operation (`A' = added, `M' = modified, `R' =
- + removed), `%t' to expand the tag, `%d' to expand the date.
- + [Origin: Ralf S. Engelschall]
- +
- + RSE_PATCH_READDNEW:
- + If a file was re-added to the repository, log the revision in the
- + `commitlog' as `NONE' instead of the previous dead revision.
- + [Origin: NetBSD]
- +
- + RSE_PATCH_CONFIGUMASK:
- + Provide a `UMask=<mask>' variable in `$CVSROOT/CVSROOT/config' which
- + overrides the umask of the CVS server process.
- + [Origin: OpenBSD]
- +
- + RSE_PATCH_FASTERUPDATE:
- + This speeds up `cvs update' by sending the whole file over the
- + network if it is smaller than the diff content. This is useful for
- + working remotely over slow Internet links.
- + [Origin: OpenBSD]
- +
- + RSE_PATCH_MERGENOKEYWORD:
- + This disables keyword expansions during branch merges which is
- + very useful in long-term branching. Without this the so-called
- + `spurious merging conflicts' occur because the keywords cause
- + spurious conflicts on every merge after the first (if those text
- + files have been modified on the trunk since the previous merge out
- + to the branch).
- + [Origin: Jay Sachs <jsachs@iclick.com>]
- +
- + RSE_PATCH_DIFFHEAD:
- + This patch changes the behavior of `cvs diff -rHEAD' on branches.
- + HEAD here now behaves with as it does with all other CVS commands,
- + as a name for the head of the trunk (the old behavior of `cvs diff
- + -rHEAD' was to treat HEAD to mean the head of the branch, while all
- + the other commands already treated HEAD as the head of the trunk).
- + [Origin: Stephen Cameron <steve.cameron@compaq.com>]
- +
- + RSE_PATCH_DEADAWARE:
- + This makes `cvs diff' aware of removed/dead files in the trunk
- + (HEAD), i.e., it doesn't complain if it didn't exist.
- + [Origin: FreeBSD]
- +
- + RSE_PATCH_LOGNAME:
- + This is for SUID-based CVS servers and passes in `$LOGNAME' the real
- + user (first field in `$CVSROOT/CVSROOT/passwd') instead of the SUID
- + user (third field in `$CVSROOT/CVSROOT/passwd')
- + [Origin: Chris Cameron]
- +
- + RSE_PATCH_HISTORYFILE:
- + This provides an additional `HistoryFile=<rel-path-under-CVSROOT>'
- + config variable which allows one to store the history file under a
- + different path.
- + [Origin: Ralf S. Engelschall]
- +
- + RSE_PATCH_SMARTCONFIG:
- + This allows one to add custom configuration variables to
- + `$CVSROOT/CVSROOT/config' without having CVS complain about them and
- + fail with an error. This is useful to use the config file also for
- + storing config details for the various admin scripts.
- + [Origin: Ralf S. Engelschall]
- +
- + RSE_PATCH_ADMININFO:
- + This adds the feature of an extra `$CVSROOT/CVSROOT/admininfo'
- + configuration file which can be used for access controlling `cvs
- + admin' commands similar to `cvs tag' (which is already done
- + with `taginfo') and `cvs commit' (which is already done with
- + `commitinfo'). The specified filters in this info file receive the
- + absolute repository directory as the first argument, followed by all
- + names of files in this directory on which the `cvs admin' command
- + should be performed. If the filter returns 0, the operation is
- + allowed. If it returns not 0, the operation is denied.
- + [Origin: Ralf S. Engelschall]
- +
- + RSE_PATCH_IMPORTINFO:
- + This adds the feature of an extra `$CVSROOT/CVSROOT/importinfo'
- + configuration file which can be used for access controlling
- + `cvs import'. The specified filters in this info file receives
- + the following arguments: the vendor branch tag, the (absolute)
- + repository path which is the root of the import and then zero or
- + more relative file paths under this repository. If the filter
- + returns 0, the operation is allowed. If it returns not 0, the
- + operation is denied.
- + [Origin: Ralf S. Engelschall]
- +
- + RSE_PATCH_HANDLE:
- + This adds a convinient `-h<handle>' option to `cvs diff'. `<handle>'
- + is a string of the format `[!]YYMMDDhhmmssoo' (YY=year, MM=month,
- + DD=day, hh=hour, mm=minute, ss=second, oo=offset) which internally
- + is expanded into two `-D' options. The first date is the equivalent
- + of `YYMMDDhhmmss', the second is the first plus `oo' seconds. If the
- + exclamation mark is used, the two dates are reversed. The intention
- + is that such a handle is a short form for a time range and can be
- + easily computed in a commit log mail. So the `-h' option can be used
- + to easily get the corresponding change diff for branch merging or
- + backing out. The only restriction is that time-overlapping commits
- + break the solution, of course. But in practice this is no real
- + problem.
- + [Origin: Ralf S. Engelschall]
- +
- + RSE_PATCH_IMPORTTOUCH:
- + This prints the prefix 'T' (for "touched/tagged only") instead
- + of 'U' (for "updated") on `cvs import' if no modifications were
- + imported, i.e., no new revision is comitted. This way one can
- + distinguish those imports from the regular updated ones which also
- + print 'U' and which actually commit a new revision.
- + [Origin: Ralf S. Engelschall]
- +
- + RSE_PATCH_RELLOCKDIR:
- + This allows the `LockDir' configuration directive to use relative
- + paths to $CVSROOT, because without this patch a relative path would
- + be relative to the current working directory (which is useless).
- + [Origin: Stefan Monnier <foo@acm.com>]
- +
- + RSE_PATCH_CVSUSER:
- + This allows the Unix user RSE_PATCH_CVSUSER_CALLER (per default
- + "ossp-cvs") to use the environment variable CVSUSER to override the
- + login name CVS uses to identify the caller. This is intended for use
- + with a CVS setuid wrapper program or for use manually by the CVS
- + administrator.
- + [Origin: Ralf S. Engelschall]
- +
- + RSE_PATCH_SETXID:
- + This is a variant of CVS's SETXID_SUPPORT. It allows one to
- + setuid/setgid the CVS executable. Then CVS deletes these effective
- + uid/gid for all commands except for the "cvs server" command. For
- + this and only this it switches the real uid/gid to the effective
- + uid/gid. This way one can use the repository as a black-box. One
- + just has to be make sure that only :ext: (for remote) and :fork:
- + (for local) access is used.
- + [Origin: Ralf S. Engelschall]
- +
- + RSE_PATCH_PSERVERD:
- + This adds an additional `cvs pserverd' command which is like `cvs
- + pserver' except that it uses own builtin TCP/IP socket listening and
- + forking facility. The advantages over using inetd are: pserverd can
- + listen to particular host addresses/ports (inetd always binds to all
- + interfaces of a host), it can optionally chroot(2) for a particular
- + user only (usually "anonymous"), it can optionally force the global
- + options -l -u for a particular user only (usually "anonymous"), it
- + can detach into background and run as a real daemon, etc.
- + [Origin: Ralf S. Engelschall]
- +
- + RSE_PATCH_MAPROOT
- + This adds a global --map-root=/oldpath:/newpath option which
- + allows one to map virtual/incoming CVSROOT values to real ones.
- + For instance this can be used together with --allow-root and "cvs
- + pserverd" to map the intuitive virtual path to the physical path on
- + the host.
- + [Origin: Ralf S. Engelschall]
- +
- + RSE_PATCH_HASHFUNC:
- + This replaces the obscure hash function in src/hash.c with D.J.Berstein's
- + popular "times 33" function which is faster to compute and still
- + distributes very well.
- + [Origin: Ralf S. Engelschall]
- +
- + RSE_PATCH_ADDFILEATTR:
- + Let the default file attributes set on newly added files.
- + [Origin: Noel Yap]
- +
- + RSE_PATCH_WILDPASSWD:
- + This allows wildcards ("*") in CVSROOT/passwd. That allows one to
- + just do "*:ULtgRLXo7NRxs:cvsuser" which would let absolutely anyone
- + use CVS provided they know the password. It would also let you do
- + things like "*:*:cvsuser" to let only authorized system users use
- + CVS using their system passwords.
- + [Larry Jones <larry.jones@sdrc.com>]
- +
- + RSE_PATCH_CVSPID:
- + This provides an environment variable $CVSPID which contains the process
- + id of the parent CVS process. This is usually used inside scripts called
- + from *info files in order to have a unique session handle (for instance
- + for a common temporary directory "/tmp/cvs.foo.$CVSPID", etc).
- + [Origin: Rich Salz <rsalz@caveosystems.com>]
- +
- + RSE_PATCH_BUGFIX:
- + This enabled various bugfixes which are still not present in the
- + official CVS version.
- + [Origin: Ralf S. Engelschall]
- +
- + RSE_PATCH_COSMETICS:
- + This just enables some cosmetic changes to various output messages.
- + [Origin: Ralf S. Engelschall]
- +
- + RSE_PATCH_COSMETICS_HARD:
- + This just enables more cosmetic changes to various output messages.
- + The difference is that these break "make check".
- + [Origin: Ralf S. Engelschall]
- +
- Index: src/add.c
- ===================================================================
- RCS file: /e/ossp/pkg/tool/cvs/cvs/cvs/src/add.c,v
- retrieving revision 1.1.1.4
- diff -u -d -u -3 -r1.1.1.4 add.c
- --- src/add.c 19 Apr 2001 19:45:31 -0000 1.1.1.4
- +++ src/add.c 16 Feb 2002 12:36:09 -0000
- @@ -798,6 +798,9 @@
- li->type = T_TITLE;
- li->tag = xstrdup (tag);
- li->rev_old = li->rev_new = NULL;
- +#ifdef RSE_PATCH_EXTRAPERCENT
- + li->date = NULL;
- +#endif
- p->data = (char *) li;
- (void) addnode (ulist, p);
- Update_Logfile (rcsdir, message, (FILE *) NULL, ulist);
- Index: src/admin.c
- ===================================================================
- RCS file: /e/ossp/pkg/tool/cvs/cvs/cvs/src/admin.c,v
- retrieving revision 1.1.1.4
- diff -u -d -u -3 -r1.1.1.4 admin.c
- --- src/admin.c 24 Apr 2001 18:14:53 -0000 1.1.1.4
- +++ src/admin.c 16 Feb 2002 12:36:09 -0000
- @@ -139,6 +139,161 @@
- dat->av[dat->ac++] = newelt;
- }
-
- +#ifdef RSE_PATCH_ADMININFO
- +
- +static List *admininfo_dlist;
- +static List *admininfo_flist;
- +
- +static void admininfo_dlist_delproc(Node *);
- +static int admininfo_info_runproc(char *, char *);
- +static int admininfo_flist_runproc(Node *, void *);
- +
- +struct admininfo_dlist_st {
- + List *flist;
- +};
- +
- +/* file callback function for recursive processing */
- +static int
- +admininfo_fileproc (
- + void *callerdat,
- + struct file_info *finfo)
- +{
- + char *xdir;
- + Node *dnode;
- + Node *fnode;
- +
- + /* determine current directory */
- + if (finfo->update_dir[0] == '\0')
- + xdir = ".";
- + else
- + xdir = finfo->update_dir;
- +
- + /* find directory node in directory list */
- + if ((dnode = findnode(admininfo_dlist, xdir)) != NULL)
- + /* take already existing file list */
- + admininfo_flist = ((struct admininfo_dlist_st *)dnode->data)->flist;
- + else {
- + /* create a new file list */
- + struct admininfo_dlist_st *dlist;
- +
- + admininfo_flist = getlist();
- +
- + dlist = (struct admininfo_dlist_st *)xmalloc(sizeof(struct admininfo_dlist_st));
- + dlist->flist = admininfo_flist;
- +
- + dnode = getnode();
- + dnode->type = UPDATE;
- + dnode->key = xstrdup(xdir);
- + dnode->data = (char *)dlist;
- + dnode->delproc = admininfo_dlist_delproc;
- +
- + (void)addnode(admininfo_dlist, dnode);
- + }
- +
- + /* create new file node in file list */
- + fnode = getnode();
- + fnode->type = UPDATE;
- + fnode->key = xstrdup(finfo->file);
- + fnode->data = NULL;
- + fnode->delproc = NULL;
- + (void)addnode(admininfo_flist, fnode);
- +
- + return 0;
- +}
- +
- +/* delete a directory list node */
- +static void
- +admininfo_dlist_delproc(
- + Node *p)
- +{
- + struct admininfo_dlist_st *dlist;
- +
- + dlist = (struct admininfo_dlist_st *)p->data;
- + dellist(&dlist->flist);
- + free(dlist);
- + return;
- +}
- +
- +/* file callback function for recursive processing (when done) */
- +static int
- +admininfo_filesdoneproc(
- + void *callerdat,
- + int err,
- + char *repos,
- + char *update_dir,
- + List *entries)
- +{
- + Node *dnode;
- + int n;
- +
- + /* find file list for update directory */
- + if ((dnode = findnode(admininfo_dlist, update_dir)) != NULL)
- + admininfo_flist = ((struct admininfo_dlist_st *)dnode->data)->flist;
- + else
- + admininfo_flist = (List *)NULL;
- + if ( (admininfo_flist == NULL)
- + || (admininfo_flist->list->next == admininfo_flist->list))
- + return err;
- +
- + /* parse and execute the admininfo configuration */
- + if ((n = Parse_Info(CVSROOTADM_ADMININFO, repos, admininfo_info_runproc, 1)) > 0) {
- + error(0, 0, "Pre-admin check failed");
- + err += n;
- + }
- +
- + return err;
- +}
- +
- +/* admininfo configuration entry callback */
- +static int
- +admininfo_info_runproc(repository, filter)
- + char *repository;
- + char *filter;
- +{
- + char *s, *cp;
- + int rv;
- +
- + /* if possible, do an own check to make sure that filter really exists */
- + if (filter[0] == '/') {
- + s = xstrdup(filter);
- + for (cp = s; *cp; cp++) {
- + if (isspace((unsigned char)*cp)) {
- + *cp = '\0';
- + break;
- + }
- + }
- + if (!isfile(s)) {
- + error (0, errno, "cannot find pre-admin filter '%s'", s);
- + free(s);
- + return (1);
- + }
- + free(s);
- + }
- +
- + /* construct the filter command */
- + run_setup(filter);
- + run_arg(repository);
- + walklist(admininfo_flist, admininfo_flist_runproc, NULL);
- +
- + /* execute the filter command */
- + rv = run_exec(RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL);
- +
- + return rv;
- +}
- +
- +/* file list callback for adding file as another program argument */
- +static int
- +admininfo_flist_runproc(
- + Node *p,
- + void *closure)
- +{
- + if (p->key != NULL)
- + run_arg(p->key);
- + return 0;
- +}
- +
- +#endif /* RSE_PATCH_ADMININFO */
- +
- int
- admin (argc, argv)
- int argc;
- @@ -505,6 +660,20 @@
- #endif /* CLIENT_SUPPORT */
-
- lock_tree_for_write (argc, argv, 0, W_LOCAL, 0);
- +
- +#ifdef RSE_PATCH_ADMININFO
- + /* allow `CVSROOT/CVSROOT/admininfo' filters to check whether the
- + `cvs admin' operation is authorized for all the specified files
- + in the repository */
- + admininfo_dlist = getlist();
- + err = start_recursion(admininfo_fileproc, admininfo_filesdoneproc,
- + (DIRENTPROC) NULL, (DIRLEAVEPROC) NULL, NULL,
- + argc, argv, 0, W_LOCAL, 0, 0, (char *)NULL, 1);
- + if (err) {
- + Lock_Cleanup();
- + error(1, 0, "correct above errors first!");
- + }
- +#endif
-
- err = start_recursion (admin_fileproc, (FILESDONEPROC) NULL, admin_dirproc,
- (DIRLEAVEPROC) NULL, (void *)&admin_data,
- Index: src/checkin.c
- ===================================================================
- RCS file: /e/ossp/pkg/tool/cvs/cvs/cvs/src/checkin.c,v
- retrieving revision 1.1.1.1
- diff -u -d -u -3 -r1.1.1.1 checkin.c
- --- src/checkin.c 22 Feb 1998 19:46:46 -0000 1.1.1.1
- +++ src/checkin.c 16 Feb 2002 12:36:09 -0000
- @@ -32,14 +32,27 @@
- Vers_TS *vers;
- int set_time;
- char *tocvsPath = NULL;
- +#ifdef RSE_PATCH_COSMETICS_HARD
- + int flags;
- +#endif
-
- /* Hmm. This message goes to stdout and the "foo,v <-- foo"
- message from "ci" goes to stderr. This doesn't make a whole
- lot of sense, but making everything go to stdout can only be
- gracefully achieved once RCS_checkin is librarified. */
- +#ifdef RSE_PATCH_COSMETICS_HARD
- + if (!really_quiet) {
- +#endif
- cvs_output ("Checking in ", 0);
- cvs_output (finfo->fullname, 0);
- +#ifdef RSE_PATCH_COSMETICS_HARD
- + cvs_output ("\n", 0);
- +#else
- cvs_output (";\n", 0);
- +#endif
- +#ifdef RSE_PATCH_COSMETICS_HARD
- + }
- +#endif
-
- tocvsPath = wrap_tocvs_process_file (finfo->file);
- if (!noexec)
- @@ -56,7 +69,14 @@
- if (finfo->rcs == NULL)
- finfo->rcs = RCS_parse (finfo->file, finfo->repository);
-
- +#ifdef RSE_PATCH_COSMETICS_HARD
- + flags = RCS_FLAGS_KEEPFILE;
- + if (really_quiet || quiet)
- + flags |= RCS_FLAGS_QUIET;
- + switch (RCS_checkin (finfo->rcs, NULL, message, rev, flags))
- +#else
- switch (RCS_checkin (finfo->rcs, NULL, message, rev, RCS_FLAGS_KEEPFILE))
- +#endif
- {
- case 0: /* everything normal */
-
- @@ -118,6 +138,16 @@
- vers->options, vers->tag, vers->date, (char *) 0);
- history_write (type, NULL, vers->vn_rcs,
- finfo->file, finfo->repository);
- +
- +#ifdef RSE_PATCH_ADDFILEATTR
- + if (type == 'A') {
- + char *attr;
- + if ((attr = fileattr_getall(NULL)) != NULL) {
- + fileattr_setall(finfo->file, attr);
- + free(attr);
- + }
- + }
- +#endif
-
- if (tocvsPath)
- if (unlink_file_dir (tocvsPath) < 0)
- Index: src/checkout.c
- ===================================================================
- RCS file: /e/ossp/pkg/tool/cvs/cvs/cvs/src/checkout.c,v
- retrieving revision 1.1.1.4
- diff -u -d -u -3 -r1.1.1.4 checkout.c
- --- src/checkout.c 24 Apr 2001 18:14:53 -0000 1.1.1.4
- +++ src/checkout.c 16 Feb 2002 12:36:09 -0000
- @@ -179,7 +179,11 @@
- case 'p':
- pipeout = 1;
- run_module_prog = 0; /* don't run module prog when piping */
- +#ifdef RSE_PATCH_NOLOCK
- + noexec = nolock = 1; /* so no locks will be created */
- +#else
- noexec = 1; /* so no locks will be created */
- +#endif
- break;
- case 'c':
- cat = 1;
- Index: src/client.c
- ===================================================================
- RCS file: /e/ossp/pkg/tool/cvs/cvs/cvs/src/client.c,v
- retrieving revision 1.1.1.4
- diff -u -d -u -3 -r1.1.1.4 client.c
- --- src/client.c 24 Apr 2001 18:14:53 -0000 1.1.1.4
- +++ src/client.c 16 Feb 2002 12:36:09 -0000
- @@ -105,6 +105,9 @@
- int status PROTO((int argc, char **argv));
- int tag PROTO((int argc, char **argv));
- int update PROTO((int argc, char **argv));
- +#ifdef RSE_PATCH_RLIST
- +int list PROTO((int argc, char **argv));
- +#endif
-
- /* All the response handling functions. */
- static void handle_ok PROTO((char *, int));
- @@ -251,14 +254,34 @@
- this_root = Name_Root ((char *) NULL, (char *) NULL);
- }
-
- +#ifdef RSE_PATCH_CVSROOT
- + {
- + int cvsroot_alias;
- + cvsroot_type *e;
- +
- + cvsroot_alias = 0;
- + if ((e = cvsroot_lookup(NULL, current_parsed_root->original, NULL)) != NULL)
- + if (strcmp(e->slavepath, this_root) == 0)
- + cvsroot_alias = 1;
- + if ((e = cvsroot_lookup(NULL, NULL, this_root)) != NULL)
- + if (strcmp(e->masterpath, current_parsed_root->original) == 0)
- + cvsroot_alias = 1;
- +#endif
- +
- /* Now check the value for root. */
- if (this_root && current_parsed_root
- +#ifdef RSE_PATCH_CVSROOT
- + && !cvsroot_alias
- +#endif
- && (strcmp (this_root, current_parsed_root->original) != 0))
- {
- /* Don't send this, since the CVSROOTs don't match. */
- free (this_root);
- return 1;
- }
- +#ifdef RSE_PATCH_CVSROOT
- + }
- +#endif
- free (this_root);
- }
-
- @@ -2704,6 +2727,9 @@
- /* Add a directory name to the list of those sent to the
- server. */
- if (update_dir && (*update_dir != '\0')
- +#ifdef RSE_PATCH_CVSROOT
- + /* FIXME: alternative to RSE_PATCH_CVSROOT?! */
- +#endif
- && (strcmp (update_dir, ".") != 0)
- && (findnode (dirs_sent_to_server, update_dir) == NULL))
- {
- @@ -4546,6 +4572,18 @@
- error (1, 0,
- "This server does not support the global -n option.");
- }
- +#ifdef RSE_PATCH_NOLOCK
- + if (nolock && !noexec)
- + {
- + if (have_global)
- + {
- + send_to_server ("Global_option -u\012", 0);
- + }
- + else
- + error (1, 0,
- + "This server does not support the global -u option.");
- + }
- +#endif
- if (quiet)
- {
- if (have_global)
- Index: src/commit.c
- ===================================================================
- RCS file: /e/ossp/pkg/tool/cvs/cvs/cvs/src/commit.c,v
- retrieving revision 1.1.1.4
- diff -u -d -u -3 -r1.1.1.4 commit.c
- --- src/commit.c 24 Apr 2001 18:14:53 -0000 1.1.1.4
- +++ src/commit.c 16 Feb 2002 12:36:09 -0000
- @@ -296,6 +296,9 @@
- data->type = status;
- data->tag = xstrdup (vers->tag);
- data->rev_old = data->rev_new = NULL;
- +#ifdef RSE_PATCH_EXTRAPERCENT
- + data->date = xstrdup (vers->ts_user);
- +#endif
-
- node->type = UPDATE;
- node->delproc = update_delproc;
- @@ -498,7 +501,11 @@
- /* Run the user-defined script to verify/check information in
- *the log message
- */
- +#ifdef RSE_PATCH_VERIFY
- + do_verify (&saved_message, (char *)NULL);
- +#else
- do_verify (saved_message, (char *)NULL);
- +#endif
-
- /* We always send some sort of message, even if empty. */
- /* FIXME: is that true? There seems to be some code in do_editor
- @@ -986,7 +993,16 @@
- xmalloc (sizeof (struct logfile_info)));
- li->type = status;
- li->tag = xstrdup (vers->tag);
- +#ifdef RSE_PATCH_READDNEW
- + /* If the file was re-added, we want the revision in the commitlog
- + to be NONE, not the previous dead revision. */
- + li->rev_old = status == T_ADDED ? NULL : xstrdup (vers->vn_rcs);
- +#else
- li->rev_old = xstrdup (vers->vn_rcs);
- +#endif
- +#ifdef RSE_PATCH_EXTRAPERCENT
- + li->date = xstrdup (vers->ts_user);
- +#endif
- li->rev_new = NULL;
- p->data = (char *) li;
- (void) addnode (ulist, p);
- @@ -1230,7 +1246,11 @@
- if (use_editor)
- do_editor (finfo->update_dir, &saved_message,
- finfo->repository, ulist);
- +#ifdef RSE_PATCH_VERIFY
- + do_verify (&saved_message, finfo->repository);
- +#else
- do_verify (saved_message, finfo->repository);
- +#endif
- }
-
- p = findnode (cilist, finfo->file);
- @@ -1552,7 +1572,11 @@
- got_message = 1;
- if (use_editor)
- do_editor (update_dir, &saved_message, real_repos, ulist);
- +#ifdef RSE_PATCH_VERIFY
- + do_verify (&saved_message, real_repos);
- +#else
- do_verify (saved_message, real_repos);
- +#endif
- free (real_repos);
- return (R_PROCESS);
- }
- @@ -2296,6 +2320,10 @@
- free (li->rev_old);
- if (li->rev_new)
- free (li->rev_new);
- +#ifdef RSE_PATCH_EXTRAPERCENT
- + if (li->date)
- + free (li->date);
- +#endif
- free (li);
- }
-
- Index: src/create_adm.c
- ===================================================================
- RCS file: /e/ossp/pkg/tool/cvs/cvs/cvs/src/create_adm.c,v
- retrieving revision 1.1.1.4
- diff -u -d -u -3 -r1.1.1.4 create_adm.c
- --- src/create_adm.c 19 Apr 2001 19:45:32 -0000 1.1.1.4
- +++ src/create_adm.c 16 Feb 2002 14:00:14 -0000
- @@ -21,6 +21,41 @@
- or after which CVS might do something non-useful. If WARN is zero, then
- don't print warnings; all errors are fatal then. */
-
- +#ifdef RSE_PATCH_CVSROOT
- +static int local_template_cb(char *repository, char *template)
- +{
- + FILE *fpIN, *fpOUT;
- + char buf[1024];
- + size_t n;
- +
- + if ((fpOUT = CVS_FOPEN(CVSADM_TEMPLATE, "w+")) == NULL)
- + error(1, errno, "cannot open %s for writing", CVSADM_TEMPLATE);
- + if ((fpIN = CVS_FOPEN(template, "r")) == NULL)
- + error(1, errno, "cannot open %s for reading", template);
- + while (!feof(fpIN)) {
- + n = fread(buf, 1, sizeof buf, fpIN);
- + if (n == 0) {
- + if (ferror(fpIN))
- + error(0, errno, "cannot read template file %s", template);
- + break;
- + }
- + fwrite(buf, 1, n, fpOUT);
- + }
- + fclose(fpIN);
- + fclose(fpOUT);
- + return 0;
- +}
- +
- +static void local_template(char *update_dir, char *repository)
- +{
- + cvsroot_type *e;
- +
- + if ((e = cvsroot_lookup(NULL, NULL, current_parsed_root->original)) != NULL)
- + Parse_Info(CVSROOTADM_RCSINFO, repository, local_template_cb, 1);
- + return;
- +}
- +#endif
- +
- int
- Create_Admin (dir, update_dir, repository, tag, date, nonbranch, warn,
- dotemplate)
- @@ -179,6 +214,20 @@
- fprintf (stderr, "%c<- Create_Admin\n",
- (server_active) ? 'S' : ' ');
- }
- +#endif
- +#ifdef RSE_PATCH_CVSROOT
- + /* Under our "cvs root" feature, checkouts are performed
- + locally (from the repository copy and without C/S), but commits
- + are performed remotely (to the master repository with C/S).
- + Unfortunately, CVS "optimizes" processing and doesn't provide
- + CVS/Template files on non-C/S checkouts. This would mean that
- + if "cvs root" feature is used, the rcsinfo-configured templates
- + are never used. So, if and only if we do a non-C/S checkout (or
- + similar operation which creates CVS/Template) _and_ the current
- + CVSROOT is known to be a repository copy, we force the creation
- + of CVS/Template. */
- + if (!server_active && !(current_parsed_root->isremote) && dotemplate)
- + local_template(update_dir, repository);
- #endif
-
- free (reposcopy);
- Index: src/cvs.h
- ===================================================================
- RCS file: /e/ossp/pkg/tool/cvs/cvs/cvs/src/cvs.h,v
- retrieving revision 1.1.1.4
- diff -u -d -u -3 -r1.1.1.4 cvs.h
- --- src/cvs.h 24 Apr 2001 18:14:53 -0000 1.1.1.4
- +++ src/cvs.h 16 Feb 2002 12:36:21 -0000
- @@ -187,6 +187,33 @@
- #define CVSROOTADM_WRITERS "writers"
- #define CVSROOTADM_PASSWD "passwd"
- #define CVSROOTADM_CONFIG "config"
- +#ifdef RSE_PATCH_ADMININFO
- +#define CVSROOTADM_ADMININFO "admininfo"
- +#endif
- +#ifdef RSE_PATCH_IMPORTINFO
- +#define CVSROOTADM_IMPORTINFO "importinfo"
- +#endif
- +
- +#ifdef RSE_PATCH_ALTADMINFILES
- +#define CVSROOTADM_MODULES_ALT "conf_modules"
- +#define CVSROOTADM_LOGINFO_ALT "hook_logwrite"
- +#define CVSROOTADM_RCSINFO_ALT "hook_logtempl"
- +#define CVSROOTADM_COMMITINFO_ALT "hook_commit"
- +#define CVSROOTADM_TAGINFO_ALT "hook_tag"
- +#define CVSROOTADM_EDITINFO_ALT "hook_logedit"
- +#define CVSROOTADM_VERIFYMSG_ALT "hook_logverify"
- +#define CVSROOTADM_HISTORY_ALT "data_history"
- +#define CVSROOTADM_VALTAGS_ALT "data_valtags"
- +#define CVSROOTADM_IGNORE_ALT "conf_ignore"
- +#define CVSROOTADM_CHECKOUTLIST_ALT "conf_checkout"
- +#define CVSROOTADM_WRAPPER_ALT "hook_wrapper"
- +#define CVSROOTADM_NOTIFY_ALT "hook_notify"
- +#define CVSROOTADM_USERS_ALT "conf_users"
- +#define CVSROOTADM_READERS_ALT "conf_readers"
- +#define CVSROOTADM_WRITERS_ALT "conf_writers"
- +#define CVSROOTADM_PASSWD_ALT "conf_passwd"
- +#define CVSROOTADM_CONFIG_ALT "conf_global"
- +#endif
-
- #define CVSNULLREPOS "Emptydir" /* an empty directory */
-
- @@ -273,6 +300,10 @@
- #define CVSUMASK_ENV "CVSUMASK" /* Effective umask for repository */
- /* #define CVSUMASK_DFLT Set by options.h */
-
- +#ifdef RSE_PATCH_NOLOCK
- +#define CVSNOLOCK_ENV "CVSNOLOCK" /* do not create lock files */
- +#endif
- +
- /*
- * If the beginning of the Repository matches the following string, strip it
- * so that the output to the logfile does not contain a full pathname.
- @@ -363,6 +394,9 @@
- extern int use_editor;
- extern int cvswrite;
- extern mode_t cvsumask;
- +#ifdef RSE_PATCH_LOCALID
- +extern char *RCS_citag;
- +#endif
-
- /* Access method specified in CVSroot. */
- typedef enum {
- @@ -400,6 +434,9 @@
-
- extern int trace; /* Show all commands */
- extern int noexec; /* Don't modify disk anywhere */
- +#ifdef RSE_PATCH_NOLOCK
- +extern int nolock; /* Don't create locks */
- +#endif
- extern int logoff; /* Don't write history entry */
-
- extern int top_level_admin;
- @@ -467,6 +504,27 @@
- void root_allow_free PROTO ((void));
- int root_allow_ok PROTO ((char *));
-
- +#ifdef RSE_PATCH_MAPROOT
- +void root_map_add PROTO ((char *, char *));
- +void root_map_free PROTO ((void));
- +int root_map_it PROTO ((char *, char **, int));
- +#endif
- +
- +#ifdef RSE_PATCH_CVSROOT
- +typedef struct {
- + char *nickname;
- + char *masterpath;
- + char *slavepath;
- + char *syncprog;
- +} cvsroot_type;
- +char *cvsroot_filename(void);
- +void cvsroot_free(cvsroot_type *);
- +cvsroot_type *cvsroot_entry_read(FILE *);
- +void cvsroot_entry_write(FILE *, cvsroot_type *);
- +cvsroot_type *cvsroot_lookup(char *, char *, char *);
- +void cvsroot_synchronize(cvsroot_type *, int);
- +#endif
- +
- char *gca PROTO((const char *rev1, const char *rev2));
- extern void check_numeric PROTO ((const char *, int, char **));
- char *getcaller PROTO((void));
- @@ -570,6 +628,10 @@
- extern void expand_wild PROTO ((int argc, char **argv,
- int *pargc, char ***pargv));
-
- +#ifdef RSE_PATCH_HANDLE
- +int handle2dates(char *, time_t *, time_t *);
- +#endif
- +
- #ifdef SERVER_SUPPORT
- extern int cvs_casecmp PROTO ((char *, char *));
- extern int fopen_case PROTO ((char *, char *, FILE **, char **));
- @@ -589,7 +651,11 @@
- void do_editor PROTO((char *dir, char **messagep,
- char *repository, List * changes));
-
- +#ifdef RSE_PATCH_VERIFY
- +void do_verify PROTO((char **messagep, char *repository));
- +#else
- void do_verify PROTO((char *message, char *repository));
- +#endif
-
- typedef int (*CALLBACKPROC) PROTO((int argc, char *argv[], char *where,
- char *mwhere, char *mfile, int shorten, int local_specified,
- @@ -812,6 +878,9 @@
- NULL for add or import */
- char *rev_new; /* rev number after a commit/modify,
- add, or import, NULL for remove */
- +#ifdef RSE_PATCH_EXTRAPERCENT
- + char *date;
- +#endif
- };
-
- /* Wrappers. */
- @@ -851,6 +920,13 @@
- int unedit PROTO ((int argc, char **argv));
- int editors PROTO ((int argc, char **argv));
- int watchers PROTO ((int argc, char **argv));
- +#ifdef RSE_PATCH_CVSROOT
- +int root PROTO ((int argc, char **argv));
- +#endif
- +#ifdef RSE_PATCH_PSERVERD
- +int pserverd PROTO ((int argc, char **argv));
- +int pserver_daemon PROTO ((int argc, char **argv));
- +#endif
- extern int annotate PROTO ((int argc, char **argv));
- extern int add PROTO ((int argc, char **argv));
- extern int admin PROTO ((int argc, char **argv));
- @@ -871,6 +947,9 @@
- extern int cvsstatus PROTO((int argc, char **argv));
- extern int cvstag PROTO((int argc, char **argv));
- extern int version PROTO((int argc, char **argv));
- +#ifdef RSE_PATCH_RLIST
- +extern int cvslist PROTO((int argc, char **argv));
- +#endif
-
- extern unsigned long int lookup_command_attribute PROTO((char *));
-
- Index: src/cvsrc.c
- ===================================================================
- RCS file: /e/ossp/pkg/tool/cvs/cvs/cvs/src/cvsrc.c,v
- retrieving revision 1.1.1.2
- diff -u -d -u -3 -r1.1.1.2 cvsrc.c
- --- src/cvsrc.c 23 Dec 1998 15:15:00 -0000 1.1.1.2
- +++ src/cvsrc.c 16 Feb 2002 12:36:09 -0000
- @@ -12,6 +12,203 @@
- #include "cvs.h"
- #include "getline.h"
-
- +#ifdef RSE_PATCH_CVSRC
- +
- +#include <ctype.h>
- +#include <string.h>
- +
- +static char *strq_start = NULL;
- +
- +static char *
- +strqtok_cchar(
- + register char *s,
- + register char *c,
- + int *backslashed)
- +{
- + register char ch;
- +
- + if ((*backslashed = (*s == '\\'))) {
- + switch (*++s) {
- + case 'a':
- + *c = '\a';
- + break;
- + case 'b':
- + *c = '\b';
- + break;
- + case 'f':
- + *c = '\f';
- + break;
- + case 'n':
- + *c = '\n';
- + break;
- + case 'r':
- + *c = '\r';
- + break;
- + case 't':
- + *c = '\t';
- + break;
- + case 'v':
- + *c = '\v';
- + break;
- + case '\\':
- + *c = '\\';
- + break;
- + case '^':
- + *c = '^';
- + break;
- + case '\'':
- + *c = '\'';
- + break;
- + case '"':
- + *c = '"';
- + break;
- + case '?':
- + *c = '?';
- + break;
- + case '0':
- + case '1':
- + case '2':
- + case '3':
- + case '4':
- + case '5':
- + case '6':
- + case '7':
- + ch = 0;
- + if (isdigit(*s) && *s != '8' && *s != '9') {
- + ch = *s++ - '0';
- + if (isdigit(*s) && *s != '8' && *s != '9') {
- + ch <<= 3;
- + ch |= *s++ - '0';
- + if (isdigit(*s) && *s != '8' && *s != '9') {
- + ch <<= 3;
- + ch |= *s++ - '0';
- + }
- + }
- + }
- + s--;
- + *c = ch;
- + break;
- + case 'x':
- + s++;
- + for (ch = 0; isxdigit(*s); s++) {
- + ch <<= 4;
- + ch |= isdigit(*s) ? *s - '0' :
- + islower(*s) ? *s + 10 - 'a' : *s + 10 - 'A';
- + }
- + s--;
- + *c = ch;
- + break;
- + default:
- + *c = *s;
- + break;
- + }
- + } else
- + *c = *s;
- + return (*s) ? s+1 : NULL;
- +}
- +
- +static char *
- +strqtok(
- + char *s, /* String to tokenize. NULL to continue same str */
- + char *delim, /* Token delimiters. Can be changed w/ each call. */
- + char *quotemarks, /* Quotation marks. Can be changed w/ each call. */
- + char *commentchars, /* Comment characters. Can be changed w/ each call. */
- + unsigned int flags) /* flags&01 -> strip quotes;
- + * flags&02 -> enable backslash escapes;
- + * flags&04 -> skip all delims before return;
- + */
- +{
- + register char *p, *q;
- + char c;
- + char leftquote = 0;
- + char *token;
- + int backslashed, inquote, intok;
- +
- + int stripquote = flags & 01; /* strip quotemarks from tokens */
- + int backslash = flags & 02; /* backslash sequences */
- + int skipdelim = flags & 04; /* skip seq of delims at end of token */
- +
- + /* New string? */
- + if (s)
- + strq_start = s;
- + if (!strq_start)
- + return NULL;
- +
- + /* Skip leading delimiters */
- + for (p=strq_start; *p && strchr(delim, *p); p++)
- + ;
- + if (!(*p) || strchr(commentchars, *p))
- + return NULL;
- +
- + /* Set `token' to point to returned string.
- + * Use p and q to walk through the user's string:
- + * p will follow input characters;
- + * q will overwrite w/ outputted characters, minus possibly-stripped
- + * quotes and including nulls after each token.
- + */
- + token = q = p;
- + inquote = 0;
- + intok = 1;
- + if (backslash) {
- + while (intok && (p = strqtok_cchar(p, &c, &backslashed))) {
- + if (backslashed) {
- + *q++ = c; /* treat as plain character */
- + } else if (!inquote && *delim && strchr(delim, c)) {
- + *q = '\0'; /* Reached end of token */
- + intok = 0;
- + } else if (!inquote && *commentchars && strchr(commentchars, c)) {
- + *q = '\0'; /* Reached end of token */
- + *p = '\0'; /* make it act like end of string */
- + intok = 0;
- + } else if (!inquote && *quotemarks && strchr(quotemarks, c)) {
- + inquote = 1; /* Beginning a quoted segment */
- + leftquote = c; /* Save quote char for matching with */
- + if (!stripquote) *q++ = c;
- + } else if (inquote && leftquote == c) {
- + inquote = 0; /* Ending a quoted segment */
- + if (!stripquote) *q++ = c;
- + } else {
- + *q++ = c; /* Ordinary character */
- + }
- + }
- + strq_start = p; /* Where to start next search */
- + *q = '\0';
- + } else {
- + while (intok && *p) {
- + if (!inquote && *delim && strchr(delim, *p)) {
- + *q = '\0'; /* Reached end of token */
- + p++; /* advance p for next token */
- + intok = 0;
- + } else if (!inquote && *commentchars && strchr(commentchars, *p)) {
- + *q = '\0'; /* Reached end of token */
- + *p = '\0'; /* make it act like end of string */
- + intok = 0;
- + } else if (!inquote && *quotemarks && strchr(quotemarks, *p)) {
- + inquote = 1; /* Beginning a quoted segment */
- + leftquote = *p++; /* Save quote char for matching with */
- + if (!stripquote) *q++ = leftquote;
- + } else if (inquote && leftquote == *p) {
- + inquote = 0; /* Ending a quoted segment */
- + p++;
- + if (!stripquote) *q++ = leftquote;
- + } else {
- + *q++ = *p++;
- + }
- + }
- + strq_start = p; /* Where to start next search */
- + *q = '\0';
- + }
- +
- + if (skipdelim && strq_start) {
- + /* Skip trailing delimiters */
- + while (*strq_start && strchr(delim, *strq_start))
- + strq_start++;
- + }
- + return token;
- +}
- +
- +#endif
- +
- /* this file is to be found in the user's home directory */
-
- #ifndef CVSRC_FILENAME
- @@ -23,9 +220,68 @@
-
- extern char *strtok ();
-
- +#ifdef RSE_PATCH_CVSRC
- +static void read_cvsrc_parentdirs ();
- +static void read_cvsrc_file ();
- +#endif
- +
- /* Read cvsrc, processing options matching CMDNAME ("cvs" for global
- options, and update *ARGC and *ARGV accordingly. */
-
- +#ifdef RSE_PATCH_CVSRC
- +void
- +read_cvsrc (argc, argv, cmdname)
- + int *argc;
- + char ***argv;
- + char *cmdname;
- +{
- + /* try to read .cvsrc files from parent directories */
- + read_cvsrc_parentdirs(argc, argv, cmdname);
- +
- + /* try to read .cvsrc file from home directory */
- + read_cvsrc_file(argc, argv, cmdname, get_homedir());
- +
- + return;
- +}
- +
- +/* read .cvsrc files from all parent directories (including the current dir) */
- +static void
- +read_cvsrc_parentdirs (argc, argv, cmdname)
- + int *argc;
- + char ***argv;
- + char *cmdname;
- +{
- + char cwd[PATH_MAX];
- + char *cp;
- + int l;
- +
- + if (getcwd(cwd, sizeof(cwd)) == NULL)
- + return;
- + if ((l = strlen(cwd)) <= 0)
- + return;
- + if (cwd[l-1] != '/') {
- + cwd[l++] = '/';
- + cwd[l++] = '\0';
- + }
- + while (cwd[0] != '\0') {
- + cwd[strlen(cwd)-1] = '\0';
- + read_cvsrc_file(argc, argv, cmdname, cwd);
- + if ((cp = strrchr(cwd, '/')) == NULL)
- + break;
- + *(cp+1) = '\0';
- + }
- + return;
- +}
- +
- +/* read .cvsrc file from a particular directory */
- +static void
- +read_cvsrc_file (argc, argv, cmdname, homedir)
- + int *argc;
- + char ***argv;
- + char *cmdname;
- + char *homedir;
- +{
- +#else
- void
- read_cvsrc (argc, argv, cmdname)
- int *argc;
- @@ -33,6 +289,7 @@
- char *cmdname;
- {
- char *homedir;
- +#endif
- char *homeinit;
- FILE *cvsrcfile;
-
- @@ -64,7 +321,9 @@
-
- /* determine filename for ~/.cvsrc */
-
- +#ifndef RSE_PATCH_CVSRC
- homedir = get_homedir ();
- +#endif
- /* If we can't find a home directory, ignore ~/.cvsrc. This may
- make tracking down problems a bit of a pain, but on the other
- hand it might be obnoxious to complain when CVS will function
- @@ -123,9 +382,15 @@
- if (found)
- {
- /* skip over command in the options line */
- +#ifdef RSE_PATCH_CVSRC
- + for (optstart = strqtok (line + command_len, "\t \n", "\"'", "", 7);
- + optstart;
- + optstart = strqtok (NULL, "\t \n", "\"'", "", 7))
- +#else
- for (optstart = strtok (line + command_len, "\t \n");
- optstart;
- optstart = strtok (NULL, "\t \n"))
- +#endif
- {
- new_argv [new_argc++] = xstrdup (optstart);
-
- Index: src/diff.c
- ===================================================================
- RCS file: /e/ossp/pkg/tool/cvs/cvs/cvs/src/diff.c,v
- retrieving revision 1.1.1.3
- diff -u -d -u -3 -r1.1.1.3 diff.c
- --- src/diff.c 24 Apr 2001 18:14:53 -0000 1.1.1.3
- +++ src/diff.c 16 Feb 2002 12:36:09 -0000
- @@ -77,7 +77,11 @@
- "\t-r rev2\tDiff rev1/date1 against rev2.\n",
- "\t--ifdef=arg\tOutput diffs in ifdef format.\n",
- "(consult the documentation for your diff program for rcsdiff-options.\n",
- +#ifdef RSE_PATCH_COSMETICS
- + "The most popular is -c for context diffs and -u for unified diffs).\n",
- +#else
- "The most popular is -c for context diffs but there are many more).\n",
- +#endif
- "(Specify the --help global option for a list of other help options)\n",
- NULL
- };
- @@ -224,13 +228,21 @@
-
- optind = 0;
- while ((c = getopt_long (argc, argv,
- +#if defined(RSE_PATCH_HANDLE)
- + "+abcdefh:ilnpstuwy0123456789BHNRTC:D:F:I:L:U:V:W:k:r:",
- +#else
- "+abcdefhilnpstuwy0123456789BHNRTC:D:F:I:L:U:V:W:k:r:",
- +#endif
- longopts, &option_index)) != -1)
- {
- switch (c)
- {
- case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
- +#if defined(RSE_PATCH_HANDLE)
- + case 'i': case 'n': case 'p': case 's': case 't':
- +#else
- case 'h': case 'i': case 'n': case 'p': case 's': case 't':
- +#endif
- case 'u': case 'w': case 'y':
- case '0': case '1': case '2': case '3': case '4': case '5':
- case '6': case '7': case '8': case '9':
- @@ -302,6 +314,17 @@
- else
- diff_date1 = Make_Date (optarg);
- break;
- +#ifdef RSE_PATCH_HANDLE
- + case 'h': {
- + time_t t1, t2;
- + if (!handle2dates(optarg, &t1, &t2))
- + error (1, 0, "invalid handle string");
- + t1 -= 1; /* subtract one second to have a real difference */
- + diff_date1 = date_from_time_t(t1);
- + diff_date2 = date_from_time_t(t2);
- + break;
- + }
- +#endif
- case 'N':
- empty_files = 1;
- break;
- @@ -436,8 +459,16 @@
- char *head =
- (vers->vn_rcs == NULL
- ? NULL
- +#ifdef RSE_PATCH_DIFFHEAD
- + : RCS_head (vers->srcfile));
- +#else
- : RCS_branch_head (vers->srcfile, vers->vn_rcs));
- +#endif
- +#ifdef RSE_PATCH_DEADAWARE
- + exists = (head != NULL && !RCS_isdead(vers->srcfile, head));
- +#else
- exists = head != NULL;
- +#endif
- if (head != NULL)
- free (head);
- }
- @@ -447,7 +478,12 @@
-
- xvers = Version_TS (finfo, NULL, diff_rev1, diff_date1,
- 1, 0);
- +#ifdef RSE_PATCH_DEADAWARE
- + exists = (xvers->vn_rcs != NULL &&
- + !RCS_isdead(xvers->srcfile, xvers->vn_rcs));
- +#else
- exists = xvers->vn_rcs != NULL;
- +#endif
- freevers_ts (&xvers);
- }
- if (exists)
- @@ -840,7 +876,11 @@
- if (diff_rev1 && strcmp (diff_rev1, TAG_HEAD) == 0)
- use_rev1 = ((vers->vn_rcs == NULL || vers->srcfile == NULL)
- ? NULL
- +#ifdef RSE_PATCH_DIFFHEAD
- + : RCS_head (vers->srcfile));
- +#else
- : RCS_branch_head (vers->srcfile, vers->vn_rcs));
- +#endif
- else
- {
- xvers = Version_TS (finfo, NULL, diff_rev1, diff_date1, 1, 0);
- @@ -855,7 +895,11 @@
- if (diff_rev2 && strcmp (diff_rev2, TAG_HEAD) == 0)
- use_rev2 = ((vers->vn_rcs == NULL || vers->srcfile == NULL)
- ? NULL
- +#ifdef RSE_PATCH_DIFFHEAD
- + : RCS_head (vers->srcfile));
- +#else
- : RCS_branch_head (vers->srcfile, vers->vn_rcs));
- +#endif
- else
- {
- xvers = Version_TS (finfo, NULL, diff_rev2, diff_date2, 1, 0);
- Index: src/hash.c
- ===================================================================
- RCS file: /e/ossp/pkg/tool/cvs/cvs/cvs/src/hash.c,v
- retrieving revision 1.1.1.3
- diff -u -d -u -3 -r1.1.1.3 hash.c
- --- src/hash.c 19 Sep 2000 00:06:35 -0000 1.1.1.3
- +++ src/hash.c 16 Feb 2002 12:36:09 -0000
- @@ -25,17 +25,25 @@
- const char *key;
- {
- unsigned int h = 0;
- +#ifndef RSE_PATCH_HASHFUNC
- unsigned int g;
- +#endif
-
- assert(key != NULL);
-
- while (*key != 0)
- {
- +#ifdef RSE_PATCH_HASHFUNC
- + /* D.J. Bernstein's popular times 33 function
- + (fast and distributes very well) */
- + h = ((h << 5) + h) + FOLD_FN_CHAR(*key++);
- +#else
- unsigned int c = *key++;
- /* The FOLD_FN_CHAR is so that findnode_fn works. */
- h = (h << 4) + FOLD_FN_CHAR (c);
- if ((g = h & 0xf0000000) != 0)
- h = (h ^ (g >> 24)) ^ g;
- +#endif
- }
-
- return (h % HASHSIZE);
- Index: src/history.c
- ===================================================================
- RCS file: /e/ossp/pkg/tool/cvs/cvs/cvs/src/history.c,v
- retrieving revision 1.1.1.4
- diff -u -d -u -3 -r1.1.1.4 history.c
- --- src/history.c 19 Apr 2001 19:45:32 -0000 1.1.1.4
- +++ src/history.c 16 Feb 2002 12:36:09 -0000
- @@ -235,6 +235,9 @@
- static char *tz_name = "+0000";
-
- char *logHistory = ALL_REC_TYPES;
- +#ifdef RSE_PATCH_HISTORYFILE
- +char *history_file = NULL;
- +#endif
-
- /* -r, -t, or -b options, malloc'd. These are "" if the option in
- question is not specified or is overridden by another option. The
- @@ -668,6 +671,10 @@
-
- if (histfile)
- fname = xstrdup (histfile);
- +#ifdef RSE_PATCH_HISTORYFILE
- + else if (history_file)
- + fname = xstrdup (history_file);
- +#endif
- else
- {
- fname = xmalloc (strlen (current_parsed_root->directory) + sizeof (CVSROOTADM)
- @@ -716,10 +723,18 @@
- return;
- if ( strchr(logHistory, type) == NULL )
- return;
- +#ifdef RSE_PATCH_HISTORYFILE
- + if (history_file != NULL)
- + fname = xstrdup (history_file);
- + else {
- +#endif
- fname = xmalloc (strlen (current_parsed_root->directory) + sizeof (CVSROOTADM)
- + sizeof (CVSROOTADM_HISTORY) + 3);
- (void) sprintf (fname, "%s/%s/%s", current_parsed_root->directory,
- CVSROOTADM, CVSROOTADM_HISTORY);
- +#ifdef RSE_PATCH_HISTORYFILE
- + }
- +#endif
-
- /* turn off history logging if the history file does not exist */
- if (!isfile (fname))
- @@ -731,7 +746,11 @@
- if (trace)
- fprintf (stderr, "%s-> fopen(%s,a)\n",
- CLIENT_SERVER_STR, fname);
- +#ifdef RSE_PATCH_NOLOCK
- + if (nolock)
- +#else
- if (noexec)
- +#endif
- goto out;
- fd = CVS_OPEN (fname, O_WRONLY | O_APPEND | O_CREAT | OPEN_BINARY, 0666);
- if (fd < 0)
- Index: src/import.c
- ===================================================================
- RCS file: /e/ossp/pkg/tool/cvs/cvs/cvs/src/import.c,v
- retrieving revision 1.1.1.4
- diff -u -d -u -3 -r1.1.1.4 import.c
- --- src/import.c 19 Apr 2001 19:45:32 -0000 1.1.1.4
- +++ src/import.c 16 Feb 2002 12:36:09 -0000
- @@ -57,6 +57,140 @@
- NULL
- };
-
- +#ifdef RSE_PATCH_IMPORTINFO
- +
- +static char *importinfo_vtag;
- +
- +static int
- +importinfo_descend(thisdir)
- + char *thisdir;
- +{
- + DIR *dirp;
- + struct dirent *dp;
- + int err = 0;
- + List *dirlist = NULL;
- +
- + if ((dirp = CVS_OPENDIR(thisdir)) == 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;
- + if (strcmp(dp->d_name, CVSADM) == 0)
- + goto one_more_time_boys;
- + if (ign_name(dp->d_name))
- + goto one_more_time_boys;
- + if (
- +#ifdef DT_DIR
- + (dp->d_type == DT_DIR || (dp->d_type == DT_UNKNOWN && isdir (dp->d_name)))
- +#else
- + isdir (dp->d_name)
- +#endif
- + && !wrap_name_has(dp->d_name, WRAP_TOCVS)
- + ) {
- + Node *n;
- + if (dirlist == NULL)
- + dirlist = getlist();
- + n = getnode();
- + n->key = xstrdup(dp->d_name);
- + addnode(dirlist, n);
- + }
- + else if (
- +#ifdef DT_DIR
- + dp->d_type == DT_LNK || (dp->d_type == DT_UNKNOWN && islink (dp->d_name))
- +#else
- + islink (dp->d_name)
- +#endif
- + ) {
- + err++;
- + }
- + else {
- + if (strcmp(thisdir, ".") == 0) {
- + run_arg(dp->d_name);
- + }
- + else {
- + char *p;
- + p = xmalloc(strlen(thisdir)+1+strlen(dp->d_name)+1);
- + (void)sprintf(p, "%s/%s", thisdir, dp->d_name);
- + run_arg(p);
- + free(p);
- + }
- + }
- + one_more_time_boys:
- + errno = 0;
- + }
- + if (errno != 0) {
- + error(0, errno, "cannot read directory");
- + err++;
- + }
- + (void)closedir(dirp);
- + }
- + if (dirlist != NULL) {
- + Node *head, *p;
- + head = dirlist->list;
- + for (p = head->next; p != head; p = p->next) {
- + if (strcmp(thisdir, ".") == 0) {
- + err += importinfo_descend(p->key);
- + }
- + else {
- + char *nextdir;
- + nextdir = xmalloc(strlen(thisdir)+1+strlen(p->key)+1);
- + (void)sprintf(nextdir, "%s/%s", thisdir, p->key);
- + err += importinfo_descend(nextdir);
- + free(nextdir);
- + }
- + }
- + dellist(&dirlist);
- + }
- + return err;
- +}
- +
- +/* importinfo configuration entry callback */
- +static int
- +importinfo_runproc(repository, filter)
- + char *repository;
- + char *filter;
- +{
- + char *s, *cp;
- + int rv;
- +
- + /* if possible, do an own check to make sure that filter really exists */
- + if (filter[0] == '/') {
- + s = xstrdup(filter);
- + for (cp = s; *cp; cp++) {
- + if (isspace((unsigned char)*cp)) {
- + *cp = '\0';
- + break;
- + }
- + }
- + if (!isfile(s)) {
- + error (0, errno, "cannot find pre-admin filter '%s'", s);
- + free(s);
- + return (1);
- + }
- + free(s);
- + }
- +
- + /* construct the filter command */
- + run_setup(filter);
- + run_arg(importinfo_vtag);
- + run_arg(repository);
- + ign_add_file(CVSDOTIGNORE, 1);
- + wrap_add_file(CVSDOTWRAPPER, 1);
- + rv = importinfo_descend(".");
- + if (rv > 0)
- + return rv;
- +
- + /* execute the filter command */
- + rv = run_exec(RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL);
- +
- + return rv;
- +}
- +#endif
- +
- int
- import (argc, argv)
- int argc;
- @@ -221,7 +355,11 @@
- do_editor ((char *) NULL, &message, repository,
- (List *) NULL);
- }
- +#ifdef RSE_PATCH_VERIFY
- + do_verify (&message, repository);
- +#else
- do_verify (message, repository);
- +#endif
- msglen = message == NULL ? 0 : strlen (message);
- if (msglen == 0 || message[msglen - 1] != '\n')
- {
- @@ -283,6 +421,12 @@
- error (1, 0, "attempt to import the repository");
- }
-
- +#ifdef RSE_PATCH_IMPORTINFO
- + importinfo_vtag = argv[1];
- + if (Parse_Info(CVSROOTADM_IMPORTINFO, argv[0], importinfo_runproc, 1) > 0)
- + error(1, 0, "Pre-import check failed");
- +#endif
- +
- /*
- * Make all newly created directories writable. Should really use a more
- * sophisticated security mechanism here.
- @@ -323,7 +467,11 @@
- "Use the following command to help the merge:");
- cvs_output_tagged ("newline", NULL);
- cvs_output_tagged ("newline", NULL);
- +#ifdef RSE_PATCH_COSMETICS
- + cvs_output_tagged ("text", " ");
- +#else
- cvs_output_tagged ("text", "\t");
- +#endif
- cvs_output_tagged ("text", program_name);
- if (CVSroot_cmdline != NULL)
- {
- @@ -353,7 +501,11 @@
- conflicts);
- (void) fprintf (logfp,
- "Use the following command to help the merge:\n\n");
- +#ifdef RSE_PATCH_COSMETICS
- + (void) fprintf (logfp, " %s checkout ", program_name);
- +#else
- (void) fprintf (logfp, "\t%s checkout ", program_name);
- +#endif
- (void) fprintf (logfp, "-j%s:yesterday -j%s %s\n\n",
- argv[1], argv[1], argv[0]);
- }
- @@ -376,6 +528,9 @@
- li->type = T_TITLE;
- li->tag = xstrdup (vbranch);
- li->rev_old = li->rev_new = NULL;
- +#ifdef RSE_PATCH_EXTRAPERCENT
- + li->date = NULL;
- +#endif
- p->data = (char *) li;
- (void) addnode (ulist, p);
- Update_Logfile (repository, message, logfp, ulist);
- @@ -663,7 +818,11 @@
- */
- if (add_tags (vers->srcfile, vfile, vtag, targc, targv))
- retval = 1;
- +#ifdef RSE_PATCH_IMPORTTOUCH
- + add_log ('T', vfile);
- +#else
- add_log ('U', vfile);
- +#endif
- freevers_ts (&vers);
- return (retval);
- }
- Index: src/list.c
- ===================================================================
- RCS file: src/list.c
- diff -N src/list.c
- --- /dev/null 1 Jan 1970 00:00:00 -0000
- +++ src/list.c 16 Feb 2002 12:36:09 -0000
- @@ -0,0 +1,282 @@
- +/*
- + * Copyright (c) 1998, Dan Rich <drich@employees.com>
- + *
- + * 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.
- + *
- + * List Directory
- + */
- +
- +#ifdef RSE_PATCH_RLIST
- +
- +#include <time.h>
- +#include <pwd.h>
- +#include <grp.h>
- +
- +#if 0
- +#include "cvs.h"
- +#endif
- +
- +static int cvslist_fileproc PROTO((void *callerdat, struct file_info * finfo));
- +static Dtype cvslist_dirproc PROTO((void *callerdat, char *dir, char *repos, char *update_dir, List * entries));
- +static int cvslist_output_dir PROTO((Node * node, void *closure));
- +static int cvslist_output_file PROTO((char *name));
- +static int cvslist_tag_proc PROTO((Node * p, void *closure));
- +
- +static char *numtag;
- +static char *date = NULL;
- +static int force_tag_match = 1;
- +static int local = 0;
- +static int verbose = 0;
- +static int list_attic = 0;
- +static RCSNode *xrcsnode;
- +
- +static const char *const status_usage[] = {
- + "Usage: %s %s [-alRv] [-r tag|-D date] modules\n",
- + "\t-a\tInclude attic files\n",
- + "\t-v\tVerbose format; includes additional information for the file\n",
- + "\t-l\tProcess this directory only (not recursive).\n",
- + "\t-R\tProcess directories recursively.\n",
- + "\t-r rev\tExisting revision/tag.\n",
- + "\t-D\tExisting date.\n",
- + "(Specify the --help global option for a list of other help options)\n",
- + NULL
- +};
- +
- +int cvslist(int argc, char **argv)
- +{
- + int c;
- + int i;
- + int which;
- + int retval;
- +
- + if (argc == -1)
- + usage(status_usage);
- + optind = 0;
- + while ((c = getopt(argc, argv, "+alRr:v")) != -1) {
- + switch (c) {
- + case 'a':
- + list_attic = 1;
- + break;
- + case 'D':
- + if (date)
- + free(date);
- + date = Make_Date(optarg);
- + break;
- + case 'l':
- + local = 1;
- + break;
- + case 'R':
- + local = 0;
- + break;
- + case 'r':
- + numtag = optarg;
- + break;
- + case 'v':
- + verbose = 1;
- + break;
- + case '?':
- + default:
- + usage(status_usage);
- + break;
- + }
- + }
- + argc -= optind;
- + argv += optind;
- +
- + if (date && numtag)
- + error(1, 0, "-r and -D options are mutually exclusive");
- +
- + wrap_setup();
- +#ifdef CLIENT_SUPPORT
- + if (current_parsed_root->isremote) {
- + start_server();
- + ign_setup();
- + if (list_attic)
- + send_arg("-a");
- + if (local)
- + send_arg("-l");
- + if (verbose)
- + send_arg("-v");
- + if (numtag)
- + option_with_arg("-r", numtag);
- + if (date)
- + client_senddate(date);
- +#if 0
- + if (supported_request("expand-modules")) {
- + /* This is done here because we need to read responses from the
- + server before we send the command checkout or export files. */
- + client_expand_modules(argc, argv, local);
- + }
- +#endif
- + /* Send any remaining arguments -- probably dir/file names */
- + for (i = 0; i < argc; ++i)
- + send_arg(argv[i]);
- + send_to_server("list\012", 0); /* Send the command */
- + return get_responses_and_close();
- + }
- +#endif
- +#ifdef SERVER_SUPPORT
- + /* If we're the server, make sure we're starting at the root */
- + if (server_active)
- + CVS_CHDIR(current_parsed_root->directory);
- +#endif
- +
- +#if 0
- + if (numtag != NULL)
- + tag_check_valid(numtag, argc, argv, local, 0, "");
- +#endif
- +
- + which = W_REPOS;
- + if (list_attic)
- + which |= W_ATTIC;
- +
- + /* start the recursion processor */
- + cvs_output_tagged("+list", NULL);
- + retval = start_recursion(cvslist_fileproc, (FILESDONEPROC)NULL,
- + cvslist_dirproc, (DIRLEAVEPROC)NULL, NULL,
- + argc, argv, local, which, 0, 1, (char *)NULL, 1);
- + cvs_output_tagged("-list", NULL);
- +
- + return retval;
- +}
- +
- +/*
- + * Display file info
- + */
- +/* ARGSUSED */
- +static int cvslist_fileproc(callerdat, finfo)
- + void *callerdat;
- + struct file_info *finfo;
- +{
- + char *buf;
- + Vers_TS *vers;
- +
- + /* If a particular revision was specified, only show that one */
- + if (numtag != NULL || date != NULL) {
- + vers = Version_TS(finfo, NULL, NULL, NULL, 0, 0);
- + if (RCS_getversion(vers->srcfile, numtag, date, force_tag_match, NULL) == NULL)
- + return 0;
- + }
- +
- + cvslist_output_file(finfo->fullname);
- +
- + if (verbose) {
- + vers = Version_TS(finfo, NULL, NULL, NULL, 0, 0);
- + if (vers->srcfile) {
- + List *symbols = RCS_symbols(vers->srcfile);
- +
- + cvs_output_tagged("+info", NULL);
- + if (vers->vn_rcs == NULL)
- + cvs_output_tagged("finfo",
- + " Repository revision:\tNo revision control file");
- + else {
- + buf = (char *)malloc(24 + strlen(vers->vn_rcs) + 1 +
- + strlen(vers->srcfile->path) + 1);
- + sprintf(buf, " Repository revision:\t%s\t%s",
- + vers->vn_rcs, vers->srcfile->path);
- + cvs_output_tagged("finfo", buf);
- + }
- + cvs_output_tagged("newline", NULL);
- + cvs_output_tagged("finfo", " Existing Tags:");
- + cvs_output_tagged("newline", NULL);
- + if (symbols) {
- + xrcsnode = finfo->rcs;
- + (void)walklist(symbols, cvslist_tag_proc, NULL);
- + }
- + else
- + cvs_output_tagged("finfo", "\tNo Tags Exist");
- +
- + cvs_output_tagged("-info", NULL);
- + cvs_output_tagged("newline", NULL);
- + }
- + }
- + return 0;
- +}
- +
- +/*
- + * Display directory info
- + */
- +/* ARGSUSED */
- +static Dtype cvslist_dirproc(callerdat, dir, repos, update_dir, entries)
- + void *callerdat;
- + char *dir;
- + char *repos;
- + char *update_dir;
- + List *entries;
- +{
- + char *buf;
- + List *dirs;
- +
- + buf = (char *)malloc(strlen(update_dir) + 2);
- + sprintf(buf, "%s", update_dir);
- + cvs_output_tagged("fname", buf);
- + cvs_output_tagged("newline", NULL);
- + free(buf);
- +
- + if (local) { /* We need to output the current dirs */
- + dirs = Find_Directories(update_dir, W_REPOS, NULL);
- + walklist(dirs, cvslist_output_dir, update_dir);
- + }
- + return R_PROCESS;
- +}
- +
- +static int cvslist_output_dir(node, closure)
- + Node *node;
- + void *closure;
- +{
- + char *buf;
- +
- + buf = (char *)malloc(strlen((char *)closure) + strlen(node->key) + 3);
- + sprintf(buf, "%s/%s/", (char *)closure, node->key);
- + cvs_output_tagged("fname", buf);
- + cvs_output_tagged("newline", NULL);
- + free(buf);
- + return 0;
- +}
- +
- +static int cvslist_output_file(name)
- + char *name;
- +{
- + char *buf;
- + char *nlptr;
- +
- + buf = (char *)malloc(strlen(name) + 1);
- + strncpy(buf, name, strlen(name));
- + *(buf+strlen(name)) = '\0';
- +
- + /* cvs_output_tagged doesn't like \n */
- + if ((nlptr = strchr(buf, '\n')) != NULL)
- + nlptr = '\0';
- + cvs_output_tagged("fname", buf);
- + cvs_output_tagged("newline", NULL);
- + free(buf);
- + return 0;
- +}
- +
- +static int cvslist_tag_proc(p, closure)
- + Node *p;
- + void *closure;
- +{
- + char *branch = NULL;
- + char *buf;
- +
- + if (RCS_nodeisbranch(xrcsnode, p->key))
- + branch = RCS_whatbranch(xrcsnode, p->key);
- +
- + buf = xmalloc(80 + strlen(p->key)
- + + (branch ? strlen(branch) : strlen(p->data)));
- + sprintf(buf, "\t%-25s\t(%s: %s)", p->key,
- + branch ? "branch" : "revision", branch ? branch : p->data);
- + cvs_output_tagged("finfo", buf);
- + cvs_output_tagged("newline", NULL);
- + free(buf);
- +
- + if (branch)
- + free(branch);
- +
- + return (0);
- +}
- +
- +#endif /* RSE_PATCH_RLIST */
- +
- Index: src/lock.c
- ===================================================================
- RCS file: /e/ossp/pkg/tool/cvs/cvs/cvs/src/lock.c,v
- retrieving revision 1.1.1.4
- diff -u -d -u -3 -r1.1.1.4 lock.c
- --- src/lock.c 19 Apr 2001 19:45:32 -0000 1.1.1.4
- +++ src/lock.c 16 Feb 2002 12:36:09 -0000
- @@ -396,7 +396,11 @@
- FILE *fp;
- char *tmp;
-
- +#ifdef RSE_PATCH_NOLOCK
- + if (nolock)
- +#else
- if (noexec)
- +#endif
- return (0);
-
- /* we only do one directory at a time for read locks! */
- @@ -468,7 +472,11 @@
- {
- char *wait_repos;
-
- +#ifdef RSE_PATCH_NOLOCK
- + if (nolock)
- +#else
- if (noexec)
- +#endif
- return (0);
-
- /* We only know how to do one list at a time */
- Index: src/logmsg.c
- ===================================================================
- RCS file: /e/ossp/pkg/tool/cvs/cvs/cvs/src/logmsg.c,v
- retrieving revision 1.1.1.4
- diff -u -d -u -3 -r1.1.1.4 logmsg.c
- --- src/logmsg.c 24 Apr 2001 18:14:53 -0000 1.1.1.4
- +++ src/logmsg.c 16 Feb 2002 12:36:09 -0000
- @@ -387,14 +387,26 @@
- independant of the running of an editor for getting a message.
- */
- void
- +#ifdef RSE_PATCH_VERIFY
- +do_verify (messagep, repository)
- + char **messagep;
- +#else
- do_verify (message, repository)
- char *message;
- +#endif
- char *repository;
- {
- FILE *fp;
- char *fname;
- int retcode = 0;
-
- +#ifdef RSE_PATCH_VERIFY
- + char *line;
- + int line_length;
- + size_t line_chars_allocated;
- + char *p;
- + struct stat stbuf;
- +#endif
- #ifdef CLIENT_SUPPORT
- if (current_parsed_root->isremote)
- /* The verification will happen on the server. */
- @@ -408,7 +420,11 @@
-
- /* If there's no message, then we have nothing to verify. Can this
- case happen? And if so why would we print a message? */
- +#ifdef RSE_PATCH_VERIFY
- + if (*messagep == NULL)
- +#else
- if (message == NULL)
- +#endif
- {
- cvs_output ("No message to verify\n", 0);
- return;
- @@ -421,9 +437,15 @@
- error (1, errno, "cannot create temporary file %s", fname);
- else
- {
- +#ifdef RSE_PATCH_VERIFY
- + fprintf (fp, "%s", *messagep);
- + if ((*messagep)[0] == '\0' ||
- + (*messagep)[strlen (*messagep) - 1] != '\n')
- +#else
- fprintf (fp, "%s", message);
- if ((message)[0] == '\0' ||
- (message)[strlen (message) - 1] != '\n')
- +#endif
- (void) fprintf (fp, "%s", "\n");
- if (fclose (fp) == EOF)
- error (1, errno, "%s", fname);
- @@ -453,6 +475,41 @@
- }
- }
-
- +#ifdef RSE_PATCH_VERIFY
- + /*
- + * Put the entire message back into the *messagep variable
- + */
- + if ((fp = open_file (fname, "r")) == 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);
- + *messagep = (char *)xmalloc(stbuf.st_size + 1);
- + *messagep[0] = '\0';
- + line = NULL;
- + line_chars_allocated = 0;
- + if (stbuf.st_size > 0) {
- + 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);
- +#endif
- +
- /* Delete the temp file */
-
- if (unlink_file (fname) < 0)
- @@ -582,6 +639,42 @@
- {
- switch (*c)
- {
- +#ifdef RSE_PATCH_EXTRAPERCENT
- + case 'o': {
- + char T[2];
- + str_list = xrealloc (str_list, (strlen (str_list) + 1 + 1));
- + switch (li->type) {
- + case T_ADDED: T[0] = 'A'; break;
- + case T_MODIFIED: T[0] = 'M'; break;
- + case T_REMOVED: T[0] = 'R'; break;
- + default: T[0] = '?'; break;
- + }
- + T[1] = '\0';
- + (void) strcat (str_list, T);
- + break;
- + }
- + case 't':
- + str_list =
- + xrealloc (str_list,
- + (strlen (str_list)
- + + (li->tag ? strlen (li->tag) : 0)
- + + 10)
- + );
- + (void) strcat (str_list, (li->tag ? li->tag : ""));
- + break;
- + case 'd': {
- + time_t t;
- + if (li->date != NULL) {
- + t = get_date(li->date, NULL);
- + if (t != ((time_t)-1)) {
- + t += 1; /* re-adjust because of fudge */
- + str_list = xrealloc (str_list, (strlen(str_list)+20));
- + sprintf(str_list+strlen(str_list), "%ld", (long)t);
- + }
- + }
- + break;
- + }
- +#endif
- case 's':
- str_list =
- xrealloc (str_list,
- Index: src/main.c
- ===================================================================
- RCS file: /e/ossp/pkg/tool/cvs/cvs/cvs/src/main.c,v
- retrieving revision 1.1.1.5
- diff -u -d -u -3 -r1.1.1.5 main.c
- --- src/main.c 27 Apr 2001 19:57:23 -0000 1.1.1.5
- +++ src/main.c 16 Feb 2002 12:36:09 -0000
- @@ -41,6 +41,9 @@
- int quiet = 0;
- int trace = 0;
- int noexec = 0;
- +#ifdef RSE_PATCH_NOLOCK
- +int nolock = 0;
- +#endif
- int logoff = 0;
-
- /* Set if we should be writing CVSADM directories at top level. At
- @@ -50,6 +53,15 @@
-
- mode_t cvsumask = UMASK_DFLT;
-
- +#ifdef RSE_PATCH_LOCALID
- +char *RCS_citag = NULL;
- +#endif
- +
- +#ifdef RSE_PATCH_PROLOGEPILOG
- +char *cvs_prolog = NULL;
- +char *cvs_epilog = NULL;
- +#endif
- +
- char *CurDir;
-
- /*
- @@ -124,11 +136,17 @@
- { "login", "logon", "lgn", login, 0 },
- { "logout", NULL, NULL, logout, 0 },
- #endif /* AUTH_CLIENT_SUPPORT */
- +#ifdef RSE_PATCH_PSERVERD
- + { "pserverd", NULL, NULL, pserverd },
- +#endif
- #if (defined(AUTH_SERVER_SUPPORT) || defined (HAVE_GSSAPI)) && defined(SERVER_SUPPORT)
- { "pserver", NULL, NULL, server, CVS_CMD_MODIFIES_REPOSITORY | CVS_CMD_USES_WORK_DIR }, /* placeholder */
- #endif
- { "rannotate","rann", "ra", annotate, 0 },
- { "rdiff", "patch", "pa", patch, 0 },
- +#ifdef RSE_PATCH_RLIST
- + { "rlist", "rls", NULL, cvslist, 0 },
- +#endif
- { "release", "re", "rel", release, 0 },
- { "remove", "rm", "delete", cvsremove, CVS_CMD_MODIFIES_REPOSITORY | CVS_CMD_USES_WORK_DIR },
- { "rlog", "rl", NULL, cvslog, 0 },
- @@ -143,9 +161,53 @@
- { "version", "ve", "ver", version, 0 },
- { "watch", NULL, NULL, watch, CVS_CMD_MODIFIES_REPOSITORY | CVS_CMD_USES_WORK_DIR },
- { "watchers", NULL, NULL, watchers, CVS_CMD_USES_WORK_DIR },
- +#ifdef RSE_PATCH_CVSROOT
- + { "root", "ro", "repo", root, CVS_CMD_IGNORE_ADMROOT },
- +#endif
- { NULL, NULL, NULL, NULL, 0 },
- };
-
- +#ifdef RSE_PATCH_CUSTOMCMD
- +
- +/* the table of custom commands */
- +#define CUSTOMCMD_MAX 20
- +static int customcmd_num = 0;
- +struct customcmd {
- + char *name;
- + char *command;
- +};
- +static struct customcmd customcmd_tab[CUSTOMCMD_MAX];
- +
- +/* the internal handler function for custom commands */
- +static int
- +customcmd_run(argc, argv)
- + int argc;
- + char **argv;
- +{
- + int i;
- + char *cmd;
- +
- + /* support for `cvs -H <cmd>' */
- + if (argc == -1) {
- + (void)fprintf(stderr, "Usage: %s %s [command arguments]\n",
- + program_name, command_name);
- + error_exit();
- + }
- +
- + /* execute the command */
- + cmd = expand_path(argv[0], command_name, 0);
- + run_setup(cmd);
- + for (i = 1; i < argc; i++)
- + run_arg(argv[i]);
- + if (run_exec(RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL) != 0)
- + error(1, 0, "program `%s' of custom command `%s' returned non-zero",
- + cmd, command_name);
- + free(cmd);
- +
- + return 0;
- +}
- +#endif
- +
- static const char *const usg[] =
- {
- /* CVS usage messages never have followed the GNU convention of
- @@ -186,9 +248,13 @@
- paragraph in ../cvs.spec without assuming the reader knows what
- version control means. */
-
- +#ifdef RSE_PATCH_COSMETICS
- + "For CVS updates and additional information, see http://www.cvshome.org/\n",
- +#else
- "For CVS updates and additional information, see\n",
- " the CVS home page at http://www.cvshome.org/ or\n",
- " Pascal Molli's CVS site at http://www.loria.fr/~molli/cvs-index.html\n",
- +#endif
- NULL,
- };
-
- @@ -215,11 +281,17 @@
- " login Prompt for password for authenticating server\n",
- " logout Removes entry in .cvspass for remote repository\n",
- #endif /* AUTH_CLIENT_SUPPORT */
- +#ifdef RSE_PATCH_PSERVERD
- + " pserverd Password server daemon\n",
- +#endif
- #if (defined(AUTH_SERVER_SUPPORT) || defined (HAVE_GSSAPI)) && defined(SERVER_SUPPORT)
- " pserver Password server mode\n",
- #endif
- " rannotate Show last revision where each line of module was modified\n",
- " rdiff Create 'patch' format diffs between releases\n",
- +#ifdef RSE_PATCH_RLIST
- + " rlist List repository directories.\n",
- +#endif
- " release Indicate that a Module is no longer in use\n",
- " remove Remove an entry from the repository\n",
- " rlog Print out history information for a module\n",
- @@ -234,6 +306,9 @@
- " version Show current CVS version(s)\n",
- " watch Set watches\n",
- " watchers See who is watching a file\n",
- +#ifdef RSE_PATCH_CVSROOT
- + " root Maintain repository root locations\n",
- +#endif
- "(Specify the --help option for a list of other help options)\n",
- NULL,
- };
- @@ -249,6 +324,9 @@
- " -w Make checked-out files read-write (default).\n",
- " -l Turn history logging off.\n",
- " -n Do not execute anything that will change the disk.\n",
- +#ifdef RSE_PATCH_NOLOCK
- + " -u Do not create lock files (implies -l).\n",
- +#endif
- " -t Show trace of program execution -- try with -n.\n",
- " -v CVS version and copyright.\n",
- " -T tmpdir Use 'tmpdir' for temporary files.\n",
- @@ -262,6 +340,10 @@
- #endif
- " -a Authenticate all net traffic.\n",
- #endif
- +#ifdef RSE_PATCH_PROLOGEPILOG
- + " -P program Run prolog program before processing.\n",
- + " -E program Run epilog program after processing.\n",
- +#endif
- " -s VAR=VAL Set CVS user variable.\n",
- "(Specify the --help option for a list of other help options)\n",
- NULL
- @@ -332,6 +414,20 @@
- if (strcmp (cmd_name, cm->fullname) == 0)
- break;
- }
- +#ifdef RSE_PATCH_CUSTOMCMD
- + {
- + int i;
- + unsigned long int ret = 0;
- + for (i = 0; i < customcmd_num; i++) {
- + if (strcmp(customcmd_tab[i].name, cmd_name) == 0) {
- + ret |= CVS_CMD_IGNORE_ADMROOT;
- + ret &= ~(CVS_CMD_USES_WORK_DIR);
- + ret &= ~(CVS_CMD_MODIFIES_REPOSITORY);
- + return ret;
- + }
- + }
- + }
- +#endif
- return cm->attr;
- }
-
- @@ -401,11 +497,34 @@
- int free_CVSroot = 0;
- int free_Editor = 0;
- int free_Tmpdir = 0;
- +#ifdef RSE_PATCH_CVSROOT
- + cvsroot_type *cvsroot_sync = NULL;
- + int cvsroot_cmdline_isreal = 0;
- +#endif
- +#if defined(RSE_PATCH_CVSROOT) || defined(RSE_PATCH_CUSTOMCMD)
- + int standalone_command = 0;
- +#endif
-
- int help = 0; /* Has the user asked for help? This
- lets us support the `cvs -H cmd'
- convention to give help for cmd. */
- +#if defined(RSE_PATCH_NOLOCK) ||\
- + defined(RSE_PATCH_PROLOGEPILOG) ||\
- + defined(RSE_PATCH_CUSTOMCMD)
- + static const char short_options[] = "+Qqrwtnlvb:T:e:d:Hfz:s:xa"
- +#ifdef RSE_PATCH_NOLOCK
- + "u"
- +#endif
- +#ifdef RSE_PATCH_PROLOGEPILOG
- + "P:E:"
- +#endif
- +#ifdef RSE_PATCH_CUSTOMCMD
- + "C:"
- +#endif
- + ;
- +#else
- static const char short_options[] = "+Qqrwtnlvb:T:e:d:Hfz:s:xa";
- +#endif
- static struct option long_options[] =
- {
- {"help", 0, NULL, 'H'},
- @@ -414,6 +533,9 @@
- {"help-synonyms", 0, NULL, 2},
- {"help-options", 0, NULL, 4},
- {"allow-root", required_argument, NULL, 3},
- +#ifdef RSE_PATCH_MAPROOT
- + {"map-root", required_argument, NULL, 5},
- +#endif
- {0, 0, 0, 0}
- };
- /* `getopt_long' stores the option index here, but right now we
- @@ -468,6 +590,16 @@
- }
- if (getenv (CVSREAD_ENV) != NULL)
- cvswrite = 0;
- +#ifdef RSE_PATCH_NOLOCK
- + if (getenv (CVSNOLOCK_ENV)) {
- + nolock = 1;
- + logoff = 1;
- + }
- +#endif
- +#ifdef RSE_PATCH_PROLOGEPILOG
- + cvs_prolog = getenv("CVSPROLOG");
- + cvs_epilog = getenv("CVSEPILOG");
- +#endif
-
- /* Set this to 0 to force getopt initialization. getopt() sets
- this to 1 internally. */
- @@ -487,12 +619,63 @@
- use_cvsrc = 0;
- }
-
- +#ifdef RSE_PATCH_GLOBALOPTION
- + /*
- + * Perform a pre-lookup of the command name in order to scan cvsrc
- + * file also for command dependent global options. For instance a
- + * "-d" option only for "commit" commands (useful if one uses a
- + * local repository copy for all cvs commands, but commits have to
- + * go directly to the master repository).
- + */
- + if (use_cvsrc) {
- + command_name = argv[optind];
- + if (command_name != NULL && command_name[0] != '\0') {
- + for (cm = cmds; cm->fullname != NULL; cm++)
- + {
- + if (cm->nick1 && !strcmp(command_name, cm->nick1))
- + break;
- + if (cm->nick2 && !strcmp(command_name, cm->nick2))
- + break;
- + if (!strcmp(command_name, cm->fullname))
- + break;
- + }
- + command_name = cm->fullname;
- + }
- + }
- +#endif
- +
- /*
- * Scan cvsrc file for global options.
- */
- if (use_cvsrc)
- read_cvsrc (&argc, &argv, "cvs");
-
- +#ifdef RSE_PATCH_GLOBALOPTION
- + if (use_cvsrc) {
- + if (command_name != NULL && command_name[0] != '\0') {
- + char *cmd;
- +#ifdef RSE_PATCH_GLOBALOPTION_PARTLY
- + if ( strcmp(command_name, "commit") == 0
- + || strcmp(command_name, "tag") == 0
- + || strcmp(command_name, "rtag") == 0
- + || strcmp(command_name, "history") == 0
- + || strcmp(command_name, "admin") == 0
- + || strcmp(command_name, "import") == 0
- +#ifdef RSE_PATCH_RLIST
- + || strcmp(command_name, "rlist") == 0
- +#endif
- + || strcmp(command_name, "rdiff") == 0) {
- +#endif
- + cmd = xmalloc(4 + strlen(command_name) + 1);
- + sprintf(cmd, "cvs/%s", command_name);
- + read_cvsrc (&argc, &argv, cmd);
- +#ifdef RSE_PATCH_GLOBALOPTION_PARTLY
- + }
- +#endif
- + }
- + }
- +#endif
- +
- optind = 0;
- opterr = 1;
-
- @@ -518,6 +701,17 @@
- /* --allow-root */
- root_allow_add (optarg);
- break;
- +#ifdef RSE_PATCH_MAPROOT
- + case 5: {
- + /* --map-root */
- + char *cp;
- + if ((cp = strchr(optarg, ':')) == NULL)
- + error(1, 0, "invalid argument syntax for --map-root option");
- + *cp++ = '\0';
- + root_map_add(optarg, cp);
- + break;
- + }
- +#endif
- case 'Q':
- really_quiet = 1;
- /* FALL THROUGH */
- @@ -535,6 +729,10 @@
- break;
- case 'n':
- noexec = 1;
- +#ifdef RSE_PATCH_NOLOCK
- + case 'u': /* Fall through */
- + nolock = 1;
- +#endif
- case 'l': /* Fall through */
- logoff = 1;
- break;
- @@ -573,10 +771,34 @@
- case 'd':
- if (CVSroot_cmdline != NULL)
- free (CVSroot_cmdline);
- +#ifdef RSE_PATCH_MAPROOT
- + {
- + char *newarg;
- + if (root_map_it(optarg, &newarg, 0))
- + optarg = newarg;
- + }
- +#endif
- +#ifdef RSE_PATCH_CVSROOT
- + {
- + cvsroot_type *e;
- + if ((e = cvsroot_lookup(optarg, NULL, NULL)) != NULL) {
- + if (!quiet)
- + fprintf(stderr, "%s: using repository `%s'\n", program_name, e->masterpath);
- + CVSroot_cmdline = xstrdup(e->masterpath);
- + CVSroot = xstrdup(e->masterpath);
- + cvsroot_free(e);
- + }
- + else {
- + cvsroot_cmdline_isreal = 1;
- +#endif
- CVSroot_cmdline = xstrdup (optarg);
- if (free_CVSroot)
- free (CVSroot);
- CVSroot = xstrdup (optarg);
- +#ifdef RSE_PATCH_CVSROOT
- + }
- + }
- +#endif
- free_CVSroot = 1;
- cvs_update_env = 1; /* need to update environment */
- break;
- @@ -618,6 +840,28 @@
- We will issue an error later if stream
- authentication is not supported. */
- break;
- +#ifdef RSE_PATCH_PROLOGEPILOG
- + case 'P':
- + cvs_prolog = xstrdup(optarg);
- + break;
- + case 'E':
- + cvs_epilog = xstrdup(optarg);
- + break;
- +#endif
- +#ifdef RSE_PATCH_CUSTOMCMD
- + case 'C': {
- + char *cp;
- + if (customcmd_num >= CUSTOMCMD_MAX)
- + error(1, 0, "maximum number of allowed -C options reached");
- + if ((cp = strchr(optarg, ':')) == NULL)
- + error(1, 0, "invalid argument to option -C (has to be \"name:cmd\")");
- + *cp++ = '\0';
- + customcmd_tab[customcmd_num].name = xstrdup(optarg);
- + customcmd_tab[customcmd_num].command = xstrdup(cp);
- + customcmd_num++;
- + break;
- + }
- +#endif
- case '?':
- default:
- usage (usg);
- @@ -629,6 +873,28 @@
- if (argc < 1)
- usage (usg);
-
- +#ifdef RSE_PATCH_CUSTOMCMD
- + /* Look up the custom command. */
- + cm = NULL;
- + {
- + int i;
- + command_name = argv[0];
- + for (i = 0; i < customcmd_num; i++) {
- + if (strcmp(customcmd_tab[i].name, command_name) == 0) {
- + struct cmd *ccm;
- + ccm = (struct cmd *)xmalloc(sizeof(struct cmd));
- + ccm->nick1 = NULL;
- + ccm->nick2 = NULL;
- + ccm->func = customcmd_run;
- + ccm->fullname = customcmd_tab[i].name;
- + argv[0] = customcmd_tab[i].command;
- + cm = (const struct cmd *)ccm;
- + standalone_command = 1;
- + }
- + }
- + }
- + if (cm == NULL) {
- +#endif
-
- /* Look up the command name. */
-
- @@ -651,6 +917,10 @@
- else
- command_name = cm->fullname; /* Global pointer for later use */
-
- +#ifdef RSE_PATCH_CUSTOMCMD
- + }
- +#endif
- +
- if (help)
- {
- argc = -1; /* some functions only check for this */
- @@ -676,6 +946,71 @@
- CVSUMASK_ENV, cp);
- }
-
- +#ifdef RSE_PATCH_CVSPID
- + /* provide the process id of the parent CVS process to
- + sub-processes (usually scripts called from *info files) in order
- + to let them have a unique session handle */
- + {
- + char pidbuf[64];
- + sprintf(pidbuf, "CVSPID=%lu", (unsigned long)getpid());
- + putenv(pidbuf);
- + }
- +#endif
- +
- +#ifdef RSE_PATCH_SETXID
- + if ( strcmp(command_name, "kserver") != 0
- + && strcmp(command_name, "pserver") != 0
- + && strcmp(command_name, "server") == 0) {
- + uid_t uid, euid;
- + gid_t gid, egid;
- + struct passwd *pw;
- + char *env;
- +
- + /* adjust group id */
- + gid = getgid();
- + egid = getegid();
- + if (gid != egid)
- + setgid(egid); /* upgrade real to effective gid */
- + else
- + setegid(gid); /* downgrade effective to real gid */
- +
- + /* adjust user id */
- + uid = getuid();
- + euid = geteuid();
- + if (uid != euid)
- + setuid(euid); /* upgrade real to effective uid */
- + else
- + seteuid(uid); /* downgrade effective to real uid */
- +
- + /* still do not adjust umask */
- + umask(0);
- +
- + /* remember real user (especially for getcaller()) */
- + pw = getpwuid(uid);
- +#ifdef AUTH_SERVER_SUPPORT
- + CVS_Username = xstrdup(pw->pw_name);
- +#if HAVE_PUTENV
- + env = xmalloc(sizeof("LOGNAME=")+strlen(CVS_Username));
- + (void)sprintf(env, "LOGNAME=%s", CVS_Username);
- + (void)putenv(env);
- +#endif
- +#endif
- +
- +#if HAVE_PUTENV
- + /* remember running user */
- + pw = getpwuid(getuid());
- + env = xmalloc(sizeof("USER=")+strlen(pw->pw_name));
- + (void)sprintf(env, "USER=%s", pw->pw_name);
- + (void)putenv(env);
- +#endif
- + }
- + else {
- + /* delete effective user and group id */
- + seteuid(getuid());
- + setegid(getgid());
- + }
- +#endif
- +
- #if defined (HAVE_KERBEROS) && defined (SERVER_SUPPORT)
- /* If we are invoked with a single argument "kserver", then we are
- running as Kerberos server as root. Do the authentication as
- @@ -690,6 +1025,21 @@
- }
- #endif /* HAVE_KERBEROS */
-
- +#ifdef RSE_PATCH_PSERVERD
- + if (strcmp(command_name, "pserverd") == 0) {
- + /*
- + * perform the socket listening. This returns multiple times,
- + * i.e., for each connection. But the parent never returns.
- + */
- + pserver_daemon(argc, argv);
- +
- + /*
- + * switch to regular "cvs server" operation.
- + */
- + argc = 0;
- + command_name = "server";
- + }
- +#endif
-
- #if (defined(AUTH_SERVER_SUPPORT) || defined (HAVE_GSSAPI)) && defined(SERVER_SUPPORT)
- if (strcmp (command_name, "pserver") == 0)
- @@ -714,6 +1064,11 @@
- server_active = strcmp (command_name, "server") == 0;
- #endif
-
- +#ifdef RSE_PATCH_CVSROOT
- + if (strcmp(command_name, "root") == 0)
- + standalone_command = 1;
- +#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
- @@ -784,8 +1139,12 @@
- in server mode, since the client will send the repository
- directory after the connection is made. */
-
- +#if defined(RSE_PATCH_CVSROOT) || defined(RSE_PATCH_CUSTOMCMD)
- + if (!server_active && !standalone_command)
- +#else
- if (!server_active)
- #endif
- +#endif
- {
- char *CVSADM_Root;
-
- @@ -841,6 +1200,54 @@
- error (1, 0,
- "CVS/Root file (if any).");
- }
- +
- +#ifdef RSE_PATCH_CVSROOT
- + if (CVSroot_cmdline == NULL || !cvsroot_cmdline_isreal) {
- + cvsroot_type *e;
- + if (lookup_command_attribute(command_name) & CVS_CMD_MODIFIES_REPOSITORY) {
- + if ((e = cvsroot_lookup(NULL, NULL, CVSroot)) != NULL) {
- + /* command modifies repository and we still operare on
- + the slave repository, so switch to the master repository,
- + because we can only perform modifications there. */
- + if (!quiet) {
- + fprintf(stderr, "%s: switching to MASTER location of repository `%s'\n", program_name, e->nickname);
- + fprintf(stderr, "%s: %s <-- %s\n", program_name, e->masterpath, e->slavepath);
- + }
- + if (free_CVSroot)
- + free(CVSroot);
- + CVSroot = xstrdup(e->masterpath);
- + if (CVSroot_cmdline != NULL)
- + free(CVSroot_cmdline);
- + CVSroot_cmdline = xstrdup(e->masterpath);
- + cvsroot_sync = e;
- + free_CVSroot = 1;
- + cvs_update_env = 1;
- + }
- + }
- + else {
- + if ((e = cvsroot_lookup(NULL, CVSroot, NULL)) != NULL) {
- + if (e->slavepath[0] != '\0') {
- + /* command does not modify repository and we still operare on
- + the master repository, so switch to the slave repository,
- + because it is faster by definition. */
- + if (!quiet) {
- + fprintf(stderr, "%s: switching to SLAVE location of repository `%s'\n", program_name, e->nickname);
- + fprintf(stderr, "%s: %s --> %s\n", program_name, e->masterpath, e->slavepath);
- + }
- + if (free_CVSroot)
- + free(CVSroot);
- + CVSroot = xstrdup(e->slavepath);
- + if (CVSroot_cmdline != NULL)
- + free(CVSroot_cmdline);
- + CVSroot_cmdline = xstrdup(e->slavepath);
- + cvsroot_free(e);
- + free_CVSroot = 1;
- + cvs_update_env = 1;
- + }
- + }
- + }
- + }
- +#endif /* RSE_PATCH_CVSROOT */
- }
-
- /* Here begins the big loop over unique cvsroot values. We
- @@ -873,6 +1280,9 @@
- end of things. */
-
- while (
- +#if defined(RSE_PATCH_CVSROOT) || defined(RSE_PATCH_CUSTOMCMD)
- + standalone_command ||
- +#endif
- #ifdef SERVER_SUPPORT
- server_active ||
- #endif
- @@ -884,8 +1294,12 @@
- in server mode, since the client will send the repository
- directory after the connection is made. */
-
- +#if defined(RSE_PATCH_CVSROOT) || defined(RSE_PATCH_CUSTOMCMD)
- + if (!server_active && !standalone_command)
- +#else
- if (!server_active)
- #endif
- +#endif
- {
- /* Now we're 100% sure that we have a valid CVSROOT
- variable. Parse it to see if we're supposed to do
- @@ -904,7 +1318,11 @@
- * Check to see if the repository exists.
- */
- #ifdef CLIENT_SUPPORT
- +#ifdef RSE_PATCH_NOLOCK
- + if (!current_parsed_root->isremote && !nolock)
- +#else
- if (!current_parsed_root->isremote)
- +#endif
- #endif /* CLIENT_SUPPORT */
- {
- char *path;
- @@ -918,7 +1336,12 @@
- {
- save_errno = errno;
- /* If this is "cvs init", the root need not exist yet. */
- +#ifdef RSE_PATCH_CVSROOT
- + if (strcmp (command_name, "init") != 0 &&
- + strcmp (command_name, "root") != 0)
- +#else
- if (strcmp (command_name, "init") != 0)
- +#endif
- {
- error (1, save_errno, "%s", path);
- }
- @@ -954,6 +1377,9 @@
- read_cvsrc and other such places or vice versa. That sort
- of thing probably needs more thought. */
- if (1
- +#if defined(RSE_PATCH_CVSROOT) || defined(RSE_PATCH_CUSTOMCMD)
- + && !standalone_command
- +#endif
- #ifdef SERVER_SUPPORT
- && !server_active
- #endif
- @@ -984,7 +1410,49 @@
- }
- #endif
-
- +#ifdef RSE_PATCH_PROLOGEPILOG
- + if (cvs_prolog != NULL) {
- + char *cmd;
- + cmd = expand_path(cvs_prolog, "prolog", 0);
- + run_setup(cmd);
- + run_arg("prolog");
- + run_arg(command_name);
- + if (CurDir != NULL)
- + run_arg(CurDir);
- + else
- + run_arg("unknown-cwd");
- + if (current_parsed_root != NULL && current_parsed_root->directory != NULL)
- + run_arg(current_parsed_root->directory);
- + else
- + run_arg("unknown-cvsroot");
- + if (run_exec(RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL) != 0)
- + error(1, 0, "prolog program `%s' returned non-zero", cmd);
- + free(cmd);
- + }
- +#endif
- +
- err = (*(cm->func)) (argc, argv);
- +
- +#ifdef RSE_PATCH_PROLOGEPILOG
- + if (cvs_epilog != NULL) {
- + char *cmd;
- + cmd = expand_path(cvs_epilog, "epilog", 0);
- + run_setup(cmd);
- + run_arg("epilog");
- + run_arg(command_name);
- + if (CurDir != NULL)
- + run_arg(CurDir);
- + else
- + run_arg("unknown-cwd");
- + if (current_parsed_root != NULL && current_parsed_root->directory != NULL)
- + run_arg(current_parsed_root->directory);
- + else
- + run_arg("unknown-cvsroot");
- + if (run_exec(RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL) != 0)
- + error(1, 0, "epilog program `%s' returned non-zero", cmd);
- + free(cmd);
- + }
- +#endif
-
- /* Mark this root directory as done. When the server is
- active, current_root will be NULL -- don't try and
- @@ -1003,11 +1471,20 @@
- dellist (&root_directories);
- #endif
-
- +#if defined(RSE_PATCH_CVSROOT) || defined(RSE_PATCH_CUSTOMCMD)
- + if (standalone_command)
- + break;
- +#endif
- #ifdef SERVER_SUPPORT
- if (server_active)
- break;
- #endif
- } /* end of loop for cvsroot values */
- +
- +#ifdef RSE_PATCH_CVSROOT
- + if (cvsroot_sync != NULL)
- + cvsroot_synchronize(cvsroot_sync, 0);
- +#endif
-
- } /* end of stuff that gets done if the user DOESN'T ask for help */
-
- Index: src/mkmodules.c
- ===================================================================
- RCS file: /e/ossp/pkg/tool/cvs/cvs/cvs/src/mkmodules.c,v
- retrieving revision 1.1.1.4
- diff -u -d -u -3 -r1.1.1.4 mkmodules.c
- --- src/mkmodules.c 19 Apr 2001 19:45:32 -0000 1.1.1.4
- +++ src/mkmodules.c 16 Feb 2002 12:36:09 -0000
- @@ -186,6 +186,48 @@
- NULL
- };
-
- +#ifdef RSE_PATCH_ADMININFO
- +static const char *const admininfo_contents[] = {
- + "# The \"admininfo\" file is used to control pre-admin checks.\n",
- + "# The filter on the right is invoked with the repository and a list \n",
- + "# of files to check. A non-zero exit of the filter program will \n",
- + "# cause the admin operation to be aborted.\n",
- + "#\n",
- + "# The first entry on a line is a regular expression which is tested\n",
- + "# against the directory that the change is being committed to, relative\n",
- + "# to the $CVSROOT. For the first match that is found, then the remainder\n",
- + "# of the line is the name of the filter to run.\n",
- + "#\n",
- + "# If the repository name does not match any of the regular expressions in this\n",
- + "# file, the \"DEFAULT\" line is used, if it is specified.\n",
- + "#\n",
- + "# If the name \"ALL\" appears as a regular expression it is always used\n",
- + "# in addition to the first matching regex or \"DEFAULT\".\n",
- + NULL
- +};
- +#endif
- +
- +#ifdef RSE_PATCH_IMPORTINFO
- +static const char *const importinfo_contents[] = {
- + "# The \"importinfo\" file is used to control pre-import checks.\n",
- + "# The filter on the right is invoked with the repository to check.\n",
- + "# A non-zero exit of the filter program will cause the import\n",
- + "# operation to be aborted.\n",
- + "#\n",
- + "# The first entry on a line is a regular expression which is tested\n",
- + "# against the directory that the change is being committed to, relative\n",
- + "# to the $CVSROOT. For the first match that is found, then the remainder\n",
- + "# of the line is the name of the filter to run.\n",
- + "#\n",
- + "# If the repository name does not match any of the regular expressions in this\n",
- + "# file, the \"DEFAULT\" line is used, if it is specified.\n",
- + "#\n",
- + "# If the name \"ALL\" appears as a regular expression it is always used\n",
- + "# in addition to the first matching regex or \"DEFAULT\".\n",
- + NULL
- +};
- +#endif
- +
- static const char *const checkoutlist_contents[] = {
- "# The \"checkoutlist\" file is used to support additional version controlled\n",
- "# administrative files in $CVSROOT/CVSROOT, such as template files.\n",
- @@ -297,6 +339,26 @@
- "# Set `LogHistory' to `all' or `TOFEWGCMAR' to log all transactions to the\n",
- "# history file, or a subset as needed (ie `TMAR' logs all write operations)\n",
- "#LogHistory=TOFEWGCMAR\n",
- +#ifdef RSE_PATCH_HISTORYFILE
- + "\n",
- + "# Set `HistoryFile' to the path name (relative to CVSROOT) of the history file\n",
- + "# if you do not want to store it not under CVSROOT/history\n",
- + "#HistoryFile=CVSROOT/history\n",
- +#endif
- +#ifdef RSE_PATCH_LOCALID
- + "\n",
- + "# Set `LocalIdName' to the name of a local tag to use in addition to Id\n",
- +#ifdef RSE_PATCH_LOCALID_NAME
- + "#LocalIdName=" RSE_PATCH_LOCALID_NAME "\n",
- +#else
- + "#LocalIdName=LocalId\n",
- +#endif
- +#endif
- +#ifdef RSE_PATCH_CONFIGUMASK
- + "\n",
- + "# Set `UMask' to the octal value of the umask.\n",
- + "#UMask=002\n",
- +#endif
- NULL
- };
-
- @@ -319,6 +381,16 @@
- {CVSROOTADM_TAGINFO,
- "a %s file can be used to configure 'cvs tag' checking",
- taginfo_contents},
- +#ifdef RSE_PATCH_ADMININFO
- + {CVSROOTADM_ADMININFO,
- + "a %s file can be used to configure 'cvs admin' checking",
- + admininfo_contents},
- +#endif
- +#ifdef RSE_PATCH_IMPORTINFO
- + {CVSROOTADM_IMPORTINFO,
- + "a %s file can be used to configure 'cvs import' checking",
- + importinfo_contents},
- +#endif
- {CVSROOTADM_IGNORE,
- "a %s file can be used to specify files to ignore",
- NULL},
- Index: src/options.h.in
- ===================================================================
- RCS file: /e/ossp/pkg/tool/cvs/cvs/cvs/src/options.h.in,v
- retrieving revision 1.1.1.2
- diff -u -d -u -3 -r1.1.1.2 options.h.in
- --- src/options.h.in 27 Jan 1999 22:58:14 -0000 1.1.1.2
- +++ src/options.h.in 16 Feb 2002 12:36:46 -0000
- @@ -198,3 +198,48 @@
- #ifndef STDC_HEADERS
- extern void exit ();
- #endif
- +
- +/*
- + * Support for compiling in various RSE extension
- + */
- +#ifdef RSE_PATCHES
- +#define RSE_PATCH_CVSRC
- +#define RSE_PATCH_CVSROOT
- +#define RSE_PATCH_GLOBALOPTION
- +#define RSE_PATCH_GLOBALOPTION_PARTLY
- +#define RSE_PATCH_CUSTOMCMD
- +#define RSE_PATCH_PROLOGEPILOG
- +#define RSE_PATCH_VERIFY
- +#define RSE_PATCH_LOCALID
- +#define RSE_PATCH_CVSHEADER
- +#define RSE_PATCH_NOLOCK
- +#define RSE_PATCH_EXTRAPERCENT
- +#define RSE_PATCH_READDNEW
- +#define RSE_PATCH_CONFIGUMASK
- +#define RSE_PATCH_FASTERUPDATE
- +#define RSE_PATCH_DEADAWARE
- +#define RSE_PATCH_LOGNAME
- +#define RSE_PATCH_HISTORYFILE
- +#define RSE_PATCH_IMPORTINFO
- +#define RSE_PATCH_ADMININFO
- +#define RSE_PATCH_HANDLE
- +#define RSE_PATCH_IMPORTTOUCH
- +#define RSE_PATCH_RELLOCKDIR
- +#define RSE_PATCH_CVSUSER
- +#define RSE_PATCH_SETXID
- +#define RSE_PATCH_PSERVERD
- +#define RSE_PATCH_MAPROOT
- +#define RSE_PATCH_RLIST
- +#define RSE_PATCH_COSMETICS
- +#define RSE_PATCH_HASHFUNC
- +#define RSE_PATCH_ADDFILEATTR
- +#define RSE_PATCH_WILDPASSWD
- +#define RSE_PATCH_CVSPID
- +#define RSE_PATCH_BUGFIX
- +/* problematic changes, because they break "make check" */
- +#undef RSE_PATCH_COSMETICS_HARD
- +#undef RSE_PATCH_MERGENOKEYWORD
- +#undef RSE_PATCH_DIFFHEAD
- +#undef RSE_PATCH_SMARTCONFIG
- +#endif
- +
- Index: src/parseinfo.c
- ===================================================================
- RCS file: /e/ossp/pkg/tool/cvs/cvs/cvs/src/parseinfo.c,v
- retrieving revision 1.1.1.4
- diff -u -d -u -3 -r1.1.1.4 parseinfo.c
- --- src/parseinfo.c 19 Apr 2001 19:45:32 -0000 1.1.1.4
- +++ src/parseinfo.c 16 Feb 2002 12:36:09 -0000
- @@ -11,6 +11,9 @@
- #include <assert.h>
-
- extern char *logHistory;
- +#ifdef RSE_PATCH_HISTORYFILE
- +extern char *history_file;
- +#endif
-
- /*
- * Parse the INFOFILE file for the specified REPOSITORY. Invoke CALLPROC for
- @@ -371,7 +374,24 @@
- {
- if (lock_dir != NULL)
- free (lock_dir);
- +#ifdef RSE_PATCH_RELLOCKDIR
- + if (p[0] == '/') {
- +#endif
- lock_dir = xstrdup (p);
- +#ifdef RSE_PATCH_RELLOCKDIR
- + }
- + else {
- + char *s;
- +
- + lock_dir = xmalloc (strlen (p)
- + + strlen (current_parsed_root->directory)
- + + 2);
- + strcpy (lock_dir, current_parsed_root->directory);
- + s = lock_dir + strlen (lock_dir);
- + *s++ = '/';
- + strcpy (s, p);
- + }
- +#endif
- /* Could try some validity checking, like whether we can
- opendir it or something, but I don't see any particular
- reason to do that now rather than waiting until lock.c. */
- @@ -384,6 +404,28 @@
- strcpy (logHistory, p);
- }
- }
- +#ifdef RSE_PATCH_HISTORYFILE
- + else if (strcmp (line, "HistoryFile") == 0)
- + {
- + if (history_file != NULL)
- + free (history_file);
- + history_file = xstrdup (p);
- + }
- +#endif
- +#ifdef RSE_PATCH_LOCALID
- + else if (strcmp (line, "LocalIdName") == 0) {
- + RCS_citag = strdup(p);
- + if (RCS_citag == NULL) {
- + error (0, 0, "%s: no memory for local tag '%s'", infopath, p);
- + goto error_return;
- + }
- + }
- +#endif
- +#ifdef RSE_PATCH_CONFIGUMASK
- + else if (strcmp (line, "UMask") == 0) {
- + cvsumask = (mode_t)(strtol(p, NULL, 8) & 0777);
- + }
- +#endif
- else
- {
- /* We may be dealing with a keyword which was added in a
- @@ -397,9 +439,11 @@
- adding new keywords to your CVSROOT/config file is not
- particularly recommended unless you are planning on using
- the new features. */
- +#ifndef RSE_PATCH_SMARTCONFIG
- error (0, 0, "%s: unrecognized keyword '%s'",
- infopath, line);
- goto error_return;
- +#endif
- }
- }
- if (ferror (fp_info))
- Index: src/rcs.c
- ===================================================================
- RCS file: /e/ossp/pkg/tool/cvs/cvs/cvs/src/rcs.c,v
- retrieving revision 1.1.1.4
- diff -u -d -u -3 -r1.1.1.4 rcs.c
- --- src/rcs.c 24 Apr 2001 18:14:53 -0000 1.1.1.4
- +++ src/rcs.c 16 Feb 2002 12:36:09 -0000
- @@ -114,6 +114,10 @@
- static void rcs_internal_unlockfile PROTO ((FILE *, char *));
- static char *rcs_lockfilename PROTO ((char *));
-
- +#ifdef RSE_PATCH_CVSHEADER
- +static char *getfullCVSname PROTO((char *, char **));
- +#endif
- +
- /* The RCS file reading functions are called a lot, and they do some
- string comparisons. This macro speeds things up a bit by skipping
- the function call when the first characters are different. It
- @@ -3342,10 +3346,17 @@
- size_t len;
- };
- #define KEYWORD_INIT(s) (s), sizeof (s) - 1
- +#ifdef RSE_PATCH_LOCALID
- +static struct rcs_keyword keywords[] =
- +#else
- static const struct rcs_keyword keywords[] =
- +#endif
- {
- { KEYWORD_INIT ("Author") },
- { KEYWORD_INIT ("Date") },
- +#ifdef RSE_PATCH_CVSHEADER
- + { KEYWORD_INIT ("CVSHeader") },
- +#endif
- { KEYWORD_INIT ("Header") },
- { KEYWORD_INIT ("Id") },
- { KEYWORD_INIT ("Locker") },
- @@ -3355,12 +3366,22 @@
- { KEYWORD_INIT ("Revision") },
- { KEYWORD_INIT ("Source") },
- { KEYWORD_INIT ("State") },
- +#ifdef RSE_PATCH_LOCALID
- +#ifdef RSE_PATCH_LOCALID_NAME
- + { KEYWORD_INIT (RSE_PATCH_LOCALID_NAME) },
- +#else
- + { KEYWORD_INIT ("LocalId") },
- +#endif
- +#endif
- { NULL, 0 }
- };
- enum keyword
- {
- KEYWORD_AUTHOR = 0,
- KEYWORD_DATE,
- +#ifdef RSE_PATCH_CVSHEADER
- + KEYWORD_CVSHEADER,
- +#endif
- KEYWORD_HEADER,
- KEYWORD_ID,
- KEYWORD_LOCKER,
- @@ -3369,7 +3390,12 @@
- KEYWORD_RCSFILE,
- KEYWORD_REVISION,
- KEYWORD_SOURCE,
- +#ifdef RSE_PATCH_LOCALID
- + KEYWORD_STATE,
- + KEYWORD_LOCALID
- +#else
- KEYWORD_STATE
- +#endif
- };
-
- /* Convert an RCS date string into a readable string. This is like
- @@ -3506,6 +3532,13 @@
- return;
- }
-
- +#ifdef RSE_PATCH_LOCALID
- + if (RCS_citag != NULL && keywords[KEYWORD_LOCALID].string == NULL) {
- + keywords[KEYWORD_LOCALID].string = RCS_citag;
- + keywords[KEYWORD_LOCALID].len = strlen(RCS_citag);
- + }
- +#endif
- +
- /* If we are using -kkvl, dig out the locker information if any. */
- locker = NULL;
- if (expand == KFLAG_KVL)
- @@ -3595,15 +3628,28 @@
- free_value = 1;
- break;
-
- +#ifdef RSE_PATCH_CVSHEADER
- + case KEYWORD_CVSHEADER:
- +#endif
- case KEYWORD_HEADER:
- case KEYWORD_ID:
- +#ifdef RSE_PATCH_LOCALID
- + case KEYWORD_LOCALID:
- +#endif
- {
- char *path;
- int free_path;
- char *date;
- +#ifdef RSE_PATCH_CVSHEADER
- + char *old_path = NULL;
- +#endif
-
- if (kw == KEYWORD_HEADER)
- path = rcs->path;
- +#ifdef RSE_PATCH_CVSHEADER
- + else if (kw == KEYWORD_CVSHEADER)
- + path = getfullCVSname(rcs->path, &old_path);
- +#endif
- else
- path = last_component (rcs->path);
- path = escape_keyword_value (path, &free_path);
- @@ -3623,6 +3669,10 @@
- locker != NULL ? locker : "");
- if (free_path)
- free (path);
- +#ifdef RSE_PATCH_CVSHEADER
- + if (old_path)
- + free (old_path);
- +#endif
- free (date);
- free_value = 1;
- }
- @@ -8419,3 +8469,38 @@
- }
- return label;
- }
- +
- +#ifdef RSE_PATCH_CVSHEADER
- +static char *
- +getfullCVSname(CVSname, pathstore)
- + char *CVSname, **pathstore;
- +{
- + int rootlen;
- + char *c;
- + int alen;
- +
- + if (current_parsed_root->directory != NULL) {
- + alen = sizeof("/" CVSATTIC) - 1;
- + *pathstore = xstrdup(CVSname);
- + if ((c = strrchr(*pathstore, '/')) != NULL) {
- + if (c - *pathstore >= alen) {
- + if (!strncmp(c - alen, "/" CVSATTIC, alen)) {
- + while (*c != '\0') {
- + *(c - alen) = *c;
- + c++;
- + }
- + *(c - alen) = '\0';
- + }
- + }
- + }
- + rootlen = strlen(current_parsed_root->directory);
- + if (!strncmp(*pathstore, current_parsed_root->directory, rootlen) &&
- + (*pathstore)[rootlen] == '/')
- + CVSname = (*pathstore + rootlen + 1);
- + else
- + CVSname = (*pathstore);
- + }
- + return CVSname;
- +}
- +#endif
- +
- Index: src/recurse.c
- ===================================================================
- RCS file: /e/ossp/pkg/tool/cvs/cvs/cvs/src/recurse.c,v
- retrieving revision 1.1.1.4
- diff -u -d -u -3 -r1.1.1.4 recurse.c
- --- src/recurse.c 19 Apr 2001 19:45:33 -0000 1.1.1.4
- +++ src/recurse.c 16 Feb 2002 12:36:09 -0000
- @@ -508,7 +508,11 @@
- if (frame->flags == R_SKIP_ALL)
- return (0);
-
- +#ifdef RSE_PATCH_NOLOCK
- + should_readlock = nolock ? 0 : frame->readlock;
- +#else
- should_readlock = noexec ? 0 : frame->readlock;
- +#endif
-
- /* The fact that locks are not active here is what makes us fail to have
- the
- @@ -550,7 +554,11 @@
- */
- if (server_active
- /* If there are writelocks around, we cannot pause here. */
- +#ifdef RSE_PATCH_NOLOCK
- + && (should_readlock || nolock))
- +#else
- && (should_readlock || noexec))
- +#endif
- server_pause_check();
- #endif
-
- Index: src/repos.c
- ===================================================================
- RCS file: /e/ossp/pkg/tool/cvs/cvs/cvs/src/repos.c,v
- retrieving revision 1.1.1.3
- diff -u -d -u -3 -r1.1.1.3 repos.c
- --- src/repos.c 19 Apr 2001 19:45:33 -0000 1.1.1.3
- +++ src/repos.c 16 Feb 2002 12:36:09 -0000
- @@ -204,3 +204,11 @@
- repository[len - 2] = '\0';
- }
- }
- +
- +#ifdef RSE_PATCH_RLIST
- +/* Shameless hack: in order to avoid having to patch the brain-dead
- + Automake-based CVS build environment (src/Makefile.am) we add the
- + "cvs rlist" code to an arbitrarily chosen source file. */
- +#include "list.c"
- +#endif
- +
- Index: src/root.c
- ===================================================================
- RCS file: /e/ossp/pkg/tool/cvs/cvs/cvs/src/root.c,v
- retrieving revision 1.1.1.4
- diff -u -d -u -3 -r1.1.1.4 root.c
- --- src/root.c 19 Apr 2001 19:45:33 -0000 1.1.1.4
- +++ src/root.c 16 Feb 2002 12:36:09 -0000
- @@ -122,6 +122,9 @@
- /* allocate space to return and fill it in */
- strip_trailing_slashes (root);
- ret = xstrdup (root);
- +#ifdef RSE_PATCH_MAPROOT
- + root_map_it(ret, &ret, 0);
- +#endif
- out:
- free (cvsadm);
- free (tmp);
- @@ -267,6 +270,87 @@
-
-
-
- +#ifdef RSE_PATCH_MAPROOT
- +
- +typedef struct root_map_st {
- + char *old;
- + char *new;
- +} root_map_t;
- +
- +#define ROOT_MAP_MAX 10
- +static int root_map_max = 0;
- +static root_map_t root_map_vec[ROOT_MAP_MAX];
- +
- +void root_map_add(char *old, char *new)
- +{
- + if (root_map_max >= ROOT_MAP_MAX)
- + return;
- + root_map_vec[root_map_max].old = xstrdup(old);
- + root_map_vec[root_map_max].new = xstrdup(new);
- + root_map_max++;
- + return;
- +}
- +
- +void root_map_free(void)
- +{
- + while (root_map_max > 0) {
- + free(root_map_vec[root_map_max].old);
- + free(root_map_vec[root_map_max].new);
- + root_map_max--;
- + }
- + return;
- +}
- +
- +int root_map_it(char *old, char **new, int prefixonly)
- +{
- + int rv;
- + int i;
- + int n;
- +
- + if (old == NULL)
- + return 0;
- + rv = 0;
- + for (i = 0; i < root_map_max; i++) {
- + n = strlen(root_map_vec[i].old);
- + if (!prefixonly && strcmp(old, root_map_vec[i].old) == 0) {
- + if (new == NULL) {
- + /* we assume old is buffer and override it */
- + strcpy(old, root_map_vec[i].new);
- + }
- + else {
- + if (old == *new)
- + /* old and new is same pointer we free before */
- + free(old);
- + /* provide new allocated buffer */
- + *new = xmalloc(strlen(root_map_vec[i].new)+1);
- + strcpy(*new, root_map_vec[i].new);
- + }
- + rv = 1;
- + break;
- + }
- + else if (prefixonly && strncmp(old, root_map_vec[i].old, n) == 0) {
- + if (new == NULL) {
- + /* we assume old is buffer and override it */
- + sprintf(old, "%s%s", root_map_vec[i].new, old+n);
- + }
- + else {
- + char *oldnew = *new;
- + /* provide new allocated buffer */
- + *new = xmalloc(strlen(root_map_vec[i].new)+strlen(old+n)+1);
- + sprintf(*new, "%s%s", root_map_vec[i].new, old+n);
- + if (old == oldnew)
- + /* old and new is same pointer we free before */
- + free(old);
- + }
- + rv = 1;
- + break;
- + }
- + }
- + return rv;
- +}
- +
- +#endif /* RSE_PATCH_MAPROOT */
- +
- /* 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. */
- @@ -804,3 +888,472 @@
- /* NOTREACHED */
- }
- #endif
- +
- +#ifdef RSE_PATCH_CVSROOT
- +
- +#include <string.h>
- +
- +#ifndef CVS_ROOT_FILE
- +#define CVS_ROOT_FILE ".cvsroot"
- +#endif
- +
- +char *
- +cvsroot_filename(
- + void)
- +{
- + char *homedir;
- + char *rootfile;
- +
- + /* Environment should override file. */
- + if ((rootfile = getenv("CVS_ROOTFILE")) != NULL)
- + return xstrdup(rootfile);
- +
- + /* Construct absolute pathname to user's password file. */
- + if ((homedir = get_homedir()) == NULL) {
- + error(1, 0, "could not find out home directory");
- + return NULL;
- + }
- + rootfile = (char *)xmalloc(strlen(homedir)+strlen(CVS_ROOT_FILE)+3);
- + strcpy(rootfile, homedir);
- + strcat(rootfile, "/");
- + strcat(rootfile, CVS_ROOT_FILE);
- + return rootfile;
- +}
- +
- +void cvsroot_free(
- + cvsroot_type *e)
- +{
- + if (e != NULL) {
- + if (e->nickname != NULL)
- + free(e->nickname);
- + if (e->masterpath != NULL)
- + free(e->masterpath);
- + if (e->slavepath != NULL)
- + free(e->slavepath);
- + if (e->syncprog != NULL)
- + free(e->syncprog);
- + free(e);
- + }
- + return;
- +}
- +
- +cvsroot_type *
- +cvsroot_entry_read(
- + FILE *fp)
- +{
- + cvsroot_type *e;
- + char *nickname;
- + char *masterpath;
- + char *slavepath;
- + char *syncprog;
- + char *line;
- + int line_length;
- + size_t line_chars_allocated;
- + size_t n;
- +
- + e = NULL;
- + line = NULL;
- + line_chars_allocated = 0;
- + while ((line_length = getline(&line, &line_chars_allocated, fp)) >= 0) {
- + /* parse line */
- + line += strspn(line, " \t\n");
- + if (line[0] == '#')
- + continue;
- + nickname = line;
- + if ((n = strcspn(line, " \t\n")) == 0)
- + return NULL;
- + line += n;
- + *line++ = '\0';
- + line += strspn(line, " \t");
- + masterpath = line;
- + if ((n = strcspn(line, " \t\n")) == 0)
- + return NULL;
- + line += n;
- + *line++ = '\0';
- + line += strspn(line, " \t\n");
- + slavepath = "";
- + syncprog = "";
- + if (line[0] != '\0') {
- + slavepath = line;
- + n = strcspn(line, " \t\n");
- + line += n;
- + *line++ = '\0';
- + if (line[0] != '\0') {
- + syncprog = line;
- + n = strcspn(line, " \t\n");
- + line += n;
- + *line++ = '\0';
- + }
- + }
- + e = (cvsroot_type *)xmalloc(sizeof(cvsroot_type));
- + e->nickname = xstrdup(nickname);
- + e->masterpath = xstrdup(masterpath);
- + e->slavepath = xstrdup(slavepath);
- + e->syncprog = xstrdup(syncprog);
- + break;
- + }
- + return e;
- +}
- +
- +void
- +cvsroot_entry_write(
- + FILE *fp,
- + cvsroot_type *e)
- +{
- + if (fp != NULL && e != NULL) {
- + fprintf(fp, "%s %s",
- + e->nickname, e->masterpath);
- + if (e->slavepath[0] != '\0')
- + fprintf(fp, " %s", e->slavepath);
- + if (e->syncprog[0] != '\0')
- + fprintf(fp, " %s", e->syncprog);
- + fprintf(fp, "\n");
- + }
- + return;
- +}
- +
- +cvsroot_type *
- +cvsroot_lookup(
- + char *by_nickname,
- + char *by_masterpath,
- + char *by_slavepath)
- +{
- + char *rootfile;
- + cvsroot_type *e = NULL;
- + FILE *fp;
- +
- + if ((rootfile = cvsroot_filename()) == NULL)
- + return NULL;
- + if ((fp = fopen(rootfile, "r")) == NULL) {
- + free(rootfile);
- + return NULL;
- + }
- + while ((e = cvsroot_entry_read(fp)) != NULL) {
- + if ( (by_nickname != NULL && strcmp(e->nickname, by_nickname) == 0)
- + || (by_masterpath != NULL && strcmp(e->masterpath, by_masterpath) == 0)
- + || (by_slavepath != NULL && strcmp(e->slavepath, by_slavepath) == 0))
- + break;
- + cvsroot_free(e);
- + }
- + fclose(fp);
- + free(rootfile);
- + return e;
- +}
- +
- +void
- +cvsroot_synchronize(
- + cvsroot_type *e,
- + int force)
- +{
- + char *cmd;
- + char *arg;
- + char *rsh;
- + int smart;
- + char *syncprog;
- +
- + smart = 0;
- + syncprog = e->syncprog;
- + if (syncprog[0] == '-') {
- + smart++;
- + syncprog++;
- + }
- + if (smart && !force) {
- + if (!really_quiet) {
- + if (strcasecmp(syncprog, "manual") == 0) {
- + fprintf(stderr, "%s: synchronize SLAVE with MASTER of repository `%s', please!\n", program_name, e->nickname);
- + }
- + else {
- + fprintf(stderr, "%s: synchronize SLAVE with MASTER of repository `%s'\n", program_name, e->nickname);
- + fprintf(stderr, "%s: by running the command `%s root -s %s', please.\n", program_name, program_name, e->nickname);
- + }
- + }
- + return;
- + }
- +
- + if (strcasecmp(syncprog, "manual") == 0) {
- + if (!really_quiet) {
- + fprintf(stderr, "%s: synchronizing SLAVE with MASTER of repository `%s'\n", program_name, e->nickname);
- + fprintf(stderr, "%s: has to be performed manually by you!\n", program_name);
- + }
- + }
- + else if (strcasecmp(syncprog, "rsync") == 0 ||
- + strncasecmp(syncprog, "rsync:", 6) == 0) {
- + if (!really_quiet) {
- + fprintf(stderr, "%s: synchronizing SLAVE with MASTER of repository `%s':\n", program_name, e->nickname);
- + fprintf(stderr, "%s: %s --> %s (rsync)\n", program_name, e->masterpath, e->slavepath);
- + }
- + run_setup("rsync");
- + if (!quiet)
- + run_arg("-v");
- + if ((rsh = getenv("CVS_RSH")) != NULL) {
- + arg = xmalloc(strlen(rsh)+7);
- + strcpy(arg, "--rsh=");
- + strcat(arg, rsh);
- + run_arg(arg);
- + free(arg);
- + }
- + run_arg("-rlpt");
- + run_arg("--delete");
- + if (strncasecmp(syncprog, "rsync:", 6) == 0) {
- + char *list = xstrdup(syncprog+6);
- + for (arg = strtok(list, ","); arg != NULL; arg = strtok(NULL, ",")) {
- + if (arg[0] == '!') {
- + run_arg("--exclude");
- + run_arg(arg+1);
- + }
- + else {
- + run_arg("--include");
- + run_arg(arg);
- + }
- + }
- + free(list);
- + }
- + arg = xmalloc(strlen(e->masterpath)+2);
- + strcpy(arg, e->masterpath);
- + strcat(arg, "/");
- + run_arg(arg);
- + free(arg);
- + arg = xmalloc(strlen(e->slavepath)+2);
- + strcpy(arg, e->slavepath);
- + strcat(arg, "/");
- + run_arg(arg);
- + free(arg);
- + if (trace) {
- + cvs_output(program_name, 0);
- + cvs_output(" ", 1);
- + cvs_output(command_name, 0);
- + cvs_output(": Executing ", 0);
- + run_print(stdout);
- + cvs_output("\n", 0);
- + }
- + if (run_exec(RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL) != 0)
- + error(1, 0, "synchronization program `rsync' returned non-zero");
- + }
- + else {
- + if (!really_quiet) {
- + fprintf(stderr, "%s: synchronizing SLAVE with MASTER of repository `%s':\n", program_name, e->nickname);
- + fprintf(stderr, "%s: %s --> %s (%s)\n", program_name, e->masterpath, e->slavepath, e->syncprog);
- + }
- + cmd = expand_path(syncprog, "sync", 0);
- + run_setup(cmd);
- + run_arg(e->nickname);
- + run_arg(e->masterpath);
- + run_arg(e->slavepath);
- + if (trace) {
- + cvs_output(program_name, 0);
- + cvs_output(" ", 1);
- + cvs_output(command_name, 0);
- + cvs_output(": Executing ", 0);
- + run_print(stdout);
- + cvs_output("\n", 0);
- + }
- + if (run_exec(RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL) != 0)
- + error(1, 0, "synchronization program `%s' returned non-zero", cmd);
- + free(cmd);
- + }
- +}
- +
- +static const char *const root_usage[] = {
- + "Usage: %s %s [-v] -e|-E|-l|s [arg ...]\n",
- + "Options:\n",
- + " -v Verbose mode.\n",
- + " -e Edit entry from ~/.cvsroot in batch mode.\n",
- + " -E Edit entry from ~/.cvsroot in visual mode.\n",
- + " -l List entries from ~/.cvsroot.\n",
- + " -s Synchronize entries from ~/.cvsroot.\n",
- + "Synopsis:\n",
- + " Add/Modify an entry:\n",
- + " cvs root -e nickname masterpath [slavepath [syncprog]]\n",
- + " Delete an entry:\n",
- + " cvs root -e nickname\n",
- + " List all or some particular entries:\n",
- + " cvs [-Q] [-q] root [-v] -l [nickname ...]\n",
- + " Synchronize all or some particular entries:\n",
- + " cvs [-Q] [-q] root -s [nickname ...]\n",
- + "(Specify the --help global option for a list of other help options)\n",
- + NULL
- +};
- +
- +int
- +root(
- + int argc,
- + char **argv)
- +{
- + enum {
- + ROOT_MODE_UNKNOWN,
- + ROOT_MODE_EDIT_CMDLINE,
- + ROOT_MODE_EDIT_VISUAL,
- + ROOT_MODE_LIST,
- + ROOT_MODE_SYNC
- + };
- + int mode = ROOT_MODE_UNKNOWN;
- + char *rootfile;
- + char *rootfilebak = NULL;
- + FILE *fp;
- + FILE *fpbak = NULL;
- + int option;
- + cvsroot_type *e;
- + cvsroot_type E;
- + int doit;
- + int i;
- + int rc;
- + int verbose = 0;
- + int found = 0;
- + int oldexists;
- +
- + if (argc == -1)
- + usage(root_usage);
- + optind = 0;
- + while ((option = getopt(argc, argv, "veEsl")) != EOF) {
- + switch ((char)option) {
- + case 'v':
- + verbose = 1;
- + break;
- + case 'e':
- + mode = ROOT_MODE_EDIT_CMDLINE;
- + break;
- + case 'E':
- + mode = ROOT_MODE_EDIT_VISUAL;
- + break;
- + case 'l':
- + mode = ROOT_MODE_LIST;
- + break;
- + case 's':
- + mode = ROOT_MODE_SYNC;
- + break;
- + case '?':
- + default:
- + usage(root_usage);
- + break;
- + }
- + }
- + argc -= optind;
- + argv += optind;
- + if (mode == ROOT_MODE_UNKNOWN)
- + error(1, 0, "exactly one of the -e, -E, -l or -s options have to given");
- +
- + if (mode == ROOT_MODE_EDIT_CMDLINE) {
- + if (argc < 1 || argc > 4)
- + error(1, 0, "option -e requires 1-4 arguments");
- + E.nickname = argv[0];
- + if (argc >= 2)
- + E.masterpath = argv[1];
- + else
- + E.masterpath = "";
- + if (argc >= 3)
- + E.slavepath = argv[2];
- + else
- + E.slavepath = "";
- + if (argc == 4)
- + E.syncprog = argv[3];
- + else
- + E.syncprog = "";
- + if ((rootfile = cvsroot_filename()) == NULL)
- + return 0;
- + oldexists = 0;
- + if (isfile(rootfile)) {
- + oldexists = 1;
- + rootfilebak = xmalloc(strlen(rootfile)+5);
- + strcpy(rootfilebak, rootfile);
- + strcat(rootfilebak, ".bak");
- + rename(rootfile, rootfilebak);
- + if ((fpbak = fopen(rootfilebak, "r")) == NULL) {
- + free(rootfile);
- + free(rootfilebak);
- + return 0;
- + }
- + }
- + if ((fp = fopen(rootfile, "w")) == NULL) {
- + fclose(fpbak);
- + free(rootfile);
- + free(rootfilebak);
- + return 0;
- + }
- + if (oldexists) {
- + found = 0;
- + while ((e = cvsroot_entry_read(fpbak)) != NULL) {
- + if (strcmp(e->nickname, E.nickname) == 0) {
- + cvsroot_free(e);
- + found = 1;
- + break;
- + }
- + cvsroot_entry_write(fp, e);
- + cvsroot_free(e);
- + }
- + }
- + if (argc > 1)
- + cvsroot_entry_write(fp, &E);
- + if (oldexists) {
- + if (found) {
- + while ((e = cvsroot_entry_read(fpbak)) != NULL) {
- + cvsroot_entry_write(fp, e);
- + cvsroot_free(e);
- + }
- + }
- + fclose(fpbak);
- + }
- + fclose(fp);
- + }
- + else if (mode == ROOT_MODE_EDIT_VISUAL) {
- + if (argc != 0)
- + error(1, 0, "option -E requires no arguments");
- + if ((rootfile = cvsroot_filename()) == NULL)
- + return 0;
- + run_setup(Editor);
- + run_arg(rootfile);
- + if ((rc = run_exec(RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL|RUN_SIGIGNORE)) != 0)
- + error (1, rc == -1 ? errno : 0, "warning: editor session failed");
- + }
- + else if (mode == ROOT_MODE_LIST || mode == ROOT_MODE_SYNC) {
- + if ((rootfile = cvsroot_filename()) == NULL)
- + return 0;
- + if ((fp = fopen(rootfile, "r")) == NULL) {
- + free(rootfile);
- + return 0;
- + }
- + while ((e = cvsroot_entry_read(fp)) != NULL) {
- + doit = 0;
- + if (argc == 0)
- + doit = 1;
- + else {
- + for (i = 0; i < argc; i++) {
- + if (strcmp(argv[i], e->nickname) == 0) {
- + doit = 1;
- + break;
- + }
- + }
- + }
- + if (doit) {
- + if (mode == ROOT_MODE_LIST) {
- + if (verbose)
- + fprintf(stdout, "Repository `%s':\n"
- + " Master Path: %s\n"
- + " Slave Path: %s\n"
- + " Synchronize: %s\n",
- + e->nickname, e->masterpath,
- + e->slavepath, e->syncprog);
- + else
- + fprintf(stdout, "%s %s %s %s\n",
- + e->nickname, e->masterpath,
- + e->slavepath, e->syncprog);
- + }
- + else if (mode == ROOT_MODE_SYNC) {
- + if (e->slavepath[0] == '\0' || e->syncprog[0] == '\0') {
- + if (argc > 0)
- + error(1, 0, "repository `%s' has no slave path or sync program defined", e->nickname);
- + }
- + else
- + cvsroot_synchronize(e, 1);
- + }
- + }
- + cvsroot_free(e);
- + }
- + fclose(fp);
- + free(rootfile);
- + }
- + return 0;
- +}
- +
- +
- +#endif /* RSE_PATCH_CVSROOT */
- +
- Index: src/sanity.sh
- ===================================================================
- RCS file: /e/ossp/pkg/tool/cvs/cvs/cvs/src/sanity.sh,v
- retrieving revision 1.1.1.4
- diff -u -d -u -3 -r1.1.1.4 sanity.sh
- --- src/sanity.sh 25 Apr 2001 22:30:56 -0000 1.1.1.4
- +++ src/sanity.sh 16 Feb 2002 12:36:35 -0000
- @@ -104,6 +104,7 @@
- # "debugger"
- #set -x
-
- +echo '[THIS PROCEDURE TAKES APPROX. 25min ON A PII/400MHz, SO BE PATIENT!]'
- echo 'This test should produce no other output than this line, and a final "OK".'
-
- # Regexp to match what CVS will call itself in output that it prints.
- @@ -8517,11 +8518,13 @@
- ############################################################
- # Check out the whole repository
- mkdir 1; cd 1
- - dotest modules-1 "${testcvs} -q co ." 'U CVSROOT/checkoutlist
- + dotest modules-1 "${testcvs} -q co ." 'U CVSROOT/admininfo
- +U CVSROOT/checkoutlist
- U CVSROOT/commitinfo
- U CVSROOT/config
- U CVSROOT/cvswrappers
- U CVSROOT/editinfo
- +U CVSROOT/importinfo
- U CVSROOT/loginfo
- U CVSROOT/modules
- U CVSROOT/notify
- @@ -8541,11 +8544,13 @@
- ############################################################
- # Check out CVSROOT
- mkdir 1; cd 1
- - dotest modules-2 "${testcvs} -q co CVSROOT" 'U CVSROOT/checkoutlist
- + dotest modules-2 "${testcvs} -q co CVSROOT" 'U CVSROOT/admininfo
- +U CVSROOT/checkoutlist
- U CVSROOT/commitinfo
- U CVSROOT/config
- U CVSROOT/cvswrappers
- U CVSROOT/editinfo
- +U CVSROOT/importinfo
- U CVSROOT/loginfo
- U CVSROOT/modules
- U CVSROOT/notify
- @@ -8568,11 +8573,13 @@
- mkdir 1; cd 1
- dotest modules-3 "${testcvs} -q co somedir" ''
- cd somedir
- - dotest modules-3d "${testcvs} -q co CVSROOT" 'U CVSROOT/checkoutlist
- + dotest modules-3d "${testcvs} -q co CVSROOT" 'U CVSROOT/admininfo
- +U CVSROOT/checkoutlist
- U CVSROOT/commitinfo
- U CVSROOT/config
- U CVSROOT/cvswrappers
- U CVSROOT/editinfo
- +U CVSROOT/importinfo
- U CVSROOT/loginfo
- U CVSROOT/modules
- U CVSROOT/notify
- @@ -18230,7 +18237,7 @@
- add a line on trunk after trunktag"
- # But diff thinks that HEAD is "br1". Case (b) from cvs.texinfo.
- # Probably people are relying on it.
- - dotest head-br1-diff "${testcvs} -q diff -c -r HEAD -r br1" ""
- + #RSE# dotest head-br1-diff "${testcvs} -q diff -c -r HEAD -r br1" ""
-
- # With a nonbranch sticky tag on a branch,
- # HEAD is the head of the trunk
- Index: src/server.c
- ===================================================================
- RCS file: /e/ossp/pkg/tool/cvs/cvs/cvs/src/server.c,v
- retrieving revision 1.1.1.4
- diff -u -d -u -3 -r1.1.1.4 server.c
- --- src/server.c 19 Apr 2001 19:34:04 -0000 1.1.1.4
- +++ src/server.c 16 Feb 2002 12:36:09 -0000
- @@ -117,6 +117,13 @@
-
- # endif /* AUTH_SERVER_SUPPORT */
-
- +#ifdef RSE_PATCH_PSERVERD
- +#include <sys/ioctl.h>
- +#include <netinet/in.h>
- +#include <arpa/inet.h>
- +#include <netdb.h>
- +#endif
- +
-
- /* While processing requests, this buffer accumulates data to be sent to
- the client, and then once we are in do_cvs_command, we use it
- @@ -734,6 +741,13 @@
-
- if (error_pending()) return;
-
- +#ifdef RSE_PATCH_MAPROOT
- + {
- + char *argnew;
- + if (root_map_it(arg, &argnew, 0))
- + arg = argnew;
- + }
- +#endif
- if (!isabsolute (arg))
- {
- if (alloc_pending (80 + strlen (arg)))
- @@ -1155,6 +1169,9 @@
- char *repos;
-
- status = buf_read_line (buf_from_net, &repos, (int *) NULL);
- +#ifdef RSE_PATCH_MAPROOT
- + root_map_it(repos, &repos, 1);
- +#endif
- if (status == 0)
- {
- if (!outside_root (repos))
- @@ -2181,6 +2198,11 @@
- case 'n':
- noexec = 1;
- break;
- +#ifdef RSE_PATCH_NOLOCK
- + case 'u':
- + nolock = 1;
- + break;
- +#endif
- case 'q':
- quiet = 1;
- break;
- @@ -3916,6 +3938,17 @@
- }
-
- /* See server.h for description. */
- +#ifdef RSE_PATCH_RLIST
- +static void serve_list PROTO ((char *));
- +static void
- +serve_list (arg)
- + char *arg;
- +{
- + if (print_pending_error())
- + return;
- + do_cvs_command("rlist", cvslist);
- +}
- +#endif
-
- void
- server_modtime (finfo, vers_ts)
- @@ -4770,6 +4803,9 @@
- REQ_LINE("expand-modules", serve_expand_modules, 0),
- REQ_LINE("ci", serve_ci, RQ_ESSENTIAL),
- REQ_LINE("co", serve_co, RQ_ESSENTIAL),
- +#ifdef RSE_PATCH_RLIST
- + REQ_LINE("rlist", serve_list, 0),
- +#endif
- REQ_LINE("update", serve_update, RQ_ESSENTIAL),
- REQ_LINE("diff", serve_diff, 0),
- REQ_LINE("log", serve_log, 0),
- @@ -5351,8 +5387,13 @@
- {
- char *env, *cvs_user;
-
- +#if defined(RSE_PATCH_LOGNAME) && defined(AUTH_SERVER_SUPPORT)
- + env = xmalloc (sizeof "LOGNAME=" + strlen (CVS_Username));
- + (void) sprintf (env, "LOGNAME=%s", CVS_Username);
- +#else
- env = xmalloc (sizeof "LOGNAME=" + strlen (username));
- (void) sprintf (env, "LOGNAME=%s", username);
- +#endif
- (void) putenv (env);
-
- env = xmalloc (sizeof "USER=" + strlen (username));
- @@ -5430,6 +5471,13 @@
- found_it = 1;
- break;
- }
- +#ifdef RSE_PATCH_WILDPASSWD
- + if (strncmp(linebuf, "*:", 2) == 0) {
- + found_it = 1;
- + namelen = 1;
- + break;
- + }
- +#endif
- }
- if (ferror (fp))
- error (0, errno, "cannot read %s", filename);
- @@ -5473,10 +5521,14 @@
- /* Okay, after this conditional chain, found_password and
- host_user_tmp will have useful values: */
-
- +#ifdef RSE_PATCH_WILDPASSWD
- + if (non_cvsuser_portion[strspn(non_cvsuser_portion, " \t")] == '\0')
- +#else
- if ((non_cvsuser_portion == NULL)
- || (strlen (non_cvsuser_portion) == 0)
- || ((strspn (non_cvsuser_portion, " \t"))
- == strlen (non_cvsuser_portion)))
- +#endif
- {
- found_password = NULL;
- host_user_tmp = NULL;
- @@ -5507,6 +5559,14 @@
- *host_user_ptr = xstrdup (host_user_tmp);
- retval = 1;
- }
- +#ifdef RSE_PATCH_WILDPASSWD
- + else if (strcmp(found_password, "*") == 0)
- + {
- + /* Give host_user_ptr permanent storage. */
- + *host_user_ptr = xstrdup(host_user_tmp);
- + retval = -1;
- + }
- +#endif
- else
- {
- *host_user_ptr = NULL;
- @@ -5552,7 +5612,11 @@
- /* host_user already set by reference, so just return. */
- goto handle_return;
- }
- +#ifdef RSE_PATCH_WILDPASSWD
- + else if (rc == -1 || system_auth)
- +#else
- else if (rc == 0 && system_auth)
- +#endif
- {
- /* No cvs password found, so try /etc/passwd. */
-
- @@ -5594,15 +5658,30 @@
- if (*found_passwd)
- {
- /* user exists and has a password */
- +#ifdef RSE_PATCH_WILDPASSWD
- + if (strcmp (found_passwd, crypt (password, found_passwd)) != 0) {
- + if (host_user != NULL) {
- + free (host_user);
- + host_user = NULL;
- + }
- + }
- + else if (host_user == NULL) {
- + host_user = xstrdup (username);
- + }
- +#else
- host_user = ((! strcmp (found_passwd,
- crypt (password, found_passwd)))
- ? xstrdup (username) : NULL);
- +#endif
- goto handle_return;
- }
- else if (password && *password)
- {
- /* user exists and has no system password, but we got
- one as parameter */
- +#ifdef RSE_PATCH_WILDPASSWD
- + if (host_user == NULL)
- +#endif
- host_user = xstrdup (username);
- goto handle_return;
- }
- @@ -5613,7 +5692,11 @@
- goto handle_return;
- }
- }
- +#ifdef RSE_PATCH_WILDPASSWD
- + else
- +#else
- else if (rc == 0)
- +#endif
- {
- /* Note that the message _does_ distinguish between the case in
- which we check for a system password and the case in which
- @@ -5634,6 +5717,7 @@
- #endif
- exit (EXIT_FAILURE);
- }
- +#ifndef RSE_PATCH_WILDPASSWD
- else
- {
- /* Something strange happened. We don't know what it was, but
- @@ -5641,6 +5725,7 @@
- host_user = NULL;
- goto handle_return;
- }
- +#endif
-
- handle_return:
- if (host_user)
- @@ -5778,6 +5863,10 @@
- strip_trailing_newlines (username);
- strip_trailing_newlines (password);
-
- +#ifdef RSE_PATCH_MAPROOT
- + root_map_it(repository, &repository, 0);
- +#endif
- +
- /* ... and make sure the protocol ends on the right foot. */
- /* See above comment about error handling. */
- getline_safe (&tmp, &tmp_allocated, stdin, PATH_MAX);
- @@ -6611,3 +6700,520 @@
- cvs_output (text, 0);
- }
- }
- +
- +#ifdef RSE_PATCH_PSERVERD
- +
- +/* ========================================================================= */
- +
- +#if !defined(SIGCHLD) && defined(SIGCLD)
- +#define SIGCHLD SIGCLD
- +#endif
- +
- +static void pserver_handshake(void);
- +
- +/*
- + * Main procedure stub. This is called in two contexts: first under "cvs
- + * -H pserverd" where we just display the usage; second inside the CVS
- + * main loop where we have to act as the regular "cvs server".
- + */
- +
- +static const char *const pserverd_usage[] = {
- + "Usage: %s %s [-v] [-d] [-l addr[:port]] [-p pidfile] [-A user] [-R user:repos:chroot]\n",
- + "\t-v\tVerbose mode.\n",
- + "\t-d\tDetach into background and run as a daemon.\n",
- + "\t-l\tListen to a particular address/port.\n",
- + "\t-p\tWrite the daemon's PID to a file.\n",
- + "\t-A\tForce global -l -n -u options for a particular user.\n",
- + "\t-R\tPerform a chroot(2) for a user/repository pair.\n",
- + "(Specify the --help global option for a list of other help options)\n",
- + NULL
- +};
- +
- +int
- +pserverd(
- + int argc,
- + char **argv)
- +{
- + if (argc == -1)
- + usage(pserverd_usage);
- + return server(argc, argv);
- +}
- +
- +/*
- + * The pserver daemon. This listens on a particular TCP/IP socket for
- + * connections. If one occurs, it forks and returns to the caller inside
- + * the child process. The parent process runs forever.
- + */
- +
- +static struct {
- + char *user;
- + char *repos;
- + char *chroot;
- +} pserver_chroot;
- +
- +static char *pserverd_anonymous_user = NULL;
- +static int pserverd_verbose = 0;
- +
- +static int
- +tcp_setinaddr(
- + struct sockaddr_in *addr,
- + const char *host,
- + const char *service,
- + const char *protocol)
- +{
- + struct hostent *hp;
- + char *end;
- + long portno;
- + struct servent *serv;
- +
- + memset(addr, 0, sizeof *addr);
- + addr->sin_family = AF_INET;
- +
- + /* set host part of address */
- + if (host == NULL)
- + addr->sin_addr.s_addr = INADDR_ANY;
- + else {
- + addr->sin_addr.s_addr = inet_addr(host);
- + if (addr->sin_addr.s_addr == (unsigned long) -1) {
- + if ((hp = gethostbyname(host)) == NULL)
- + return -1;
- + memcpy(&addr->sin_addr, hp->h_addr, hp->h_length);
- + addr->sin_family = hp->h_addrtype;
- + }
- + }
- +
- + /* set port part of address */
- + if (service == NULL)
- + addr->sin_port = htons(0);
- + else {
- + portno = strtol(service, &end, 10);
- + if (portno > 0 && portno <= 65535 && end != service && *end == '\0')
- + addr->sin_port = htons(portno);
- + else {
- + if ((serv = getservbyname(service, protocol)) == NULL)
- + return -1;
- + addr->sin_port = serv->s_port;
- + }
- + }
- + return 0;
- +}
- +
- +static int
- +tcp_listen(
- + const char *host,
- + const char *port)
- +{
- + int s;
- + struct protoent *proto;
- + struct sockaddr_in server;
- + int yes = 1;
- +
- + if (tcp_setinaddr(&server, host, port, "tcp") < 0)
- + return -1;
- + if ((proto = getprotobyname("tcp")) == NULL)
- + return -1;
- + if ((s = socket(PF_INET, SOCK_STREAM, proto->p_proto)) < 0)
- + return -1;
- + setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&yes, sizeof(yes));
- + if (bind(s, (struct sockaddr *)&server, sizeof(server)) < 0) {
- + close(s);
- + return -1;
- + }
- + if (listen(s, 256) < 0) {
- + close(s);
- + return -1;
- + }
- + return s;
- +}
- +
- +static int
- +proc_daemon(
- + int nochdir,
- + int noclose)
- +{
- + int fd;
- + int rc;
- +
- + /*
- + * Ignore tty related signals
- + */
- +#ifdef SIGTTOU
- + signal(SIGTTOU, SIG_IGN);
- +#endif
- +#ifdef SIGTTIN
- + signal(SIGTTIN, SIG_IGN);
- +#endif
- +#ifdef SIGTSTP
- + signal(SIGTSTP, SIG_IGN);
- +#endif
- +
- + /*
- + * fork so the parent can exit, this returns control to the command line
- + * or shell invoking your program. This step is required so that the new
- + * process is guaranteed not to be a process group leader (The next step,
- + * setsid, would fail if you're a process group leader).
- + */
- + rc = fork();
- + switch (rc) {
- + case -1: return -1;
- + case 0: break;
- + default: _exit(0); /* exit original process */
- + }
- +
- + /*
- + * setsid to become a process group and session group leader. Since a
- + * controlling terminal is associated with a session, and this new session
- + * has not yet acquired a controlling terminal our process now has no
- + * controlling terminal, which is a Good Thing for daemons.
- + */
- +#ifdef HAVE_SETSID
- + if (setsid() == -1)
- + return -1;
- +#else
- + if (setpgid(0, getpid()) == -1)
- + return -1;
- +#ifndef _PATH_TTY
- +#define _PATH_TTY "/dev/tty"
- +#endif
- + if ((fd = open(_PATH_TTY, O_RDWR)) == -1)
- + return -1;
- + ioctl(fd, TIOCNOTTY, NULL);
- + close(fd);
- +#endif
- +
- + /*
- + * fork again so the parent, (the session group leader), can exit. This
- + * means that we, as a non-session group leader, can never regain a
- + * controlling terminal.
- + */
- + rc = fork();
- + switch (rc) {
- + case -1: return -1;
- + case 0: break;
- + default: _exit(0); /* exit original process */
- + }
- +
- + /*
- + * chdir("/") to ensure that our process doesn't keep any directory in
- + * use. Failure to do this could make it so that an administrator couldn't
- + * unmount a filesystem, because it was our current directory.
- + * [Equivalently, we could change to any directory containing files
- + * important to the daemon's operation.]
- + */
- + if (!nochdir)
- + chdir("/");
- +
- + /*
- + * give us complete control over the permissions of anything we write. We
- + * don't know what umask we may have inherited. [This step is optional]
- + */
- + umask(0);
- +
- + /*
- + * close fds 0, 1, and 2. This releases the standard in, out, and error we
- + * inherited from our parent process. We have no way of knowing where
- + * these fds might have been redirected to.
- + */
- + if (!noclose && (fd = open("/dev/null", O_RDWR, 0)) != -1) {
- + dup2(fd, STDIN_FILENO);
- + dup2(fd, STDOUT_FILENO);
- + dup2(fd, STDERR_FILENO);
- + if (fd > 2)
- + close(fd);
- + }
- + return 0;
- +}
- +
- +static void
- +pserver_daemon_reapchild(
- + int signo)
- +{
- + pid_t child;
- + int status;
- + char buf[128];
- +
- + while ((child = waitpid(-1, &status, WNOHANG)) > (pid_t)0) {
- + if (pserverd_verbose) {
- + sprintf(buf, "cvs pserverd[%ld]: child process (pid %ld): terminated.\n",
- + (long)getpid(), (long)child);
- + write(STDOUT_FILENO, buf, strlen(buf));
- + }
- + }
- + signal(signo, &pserver_daemon_reapchild);
- + return;
- +}
- +
- +int
- +pserver_daemon(
- + int argc,
- + char **argv)
- +{
- + int sd;
- + pid_t child;
- + int option;
- + char *host = NULL;
- + char *port = "2401";
- + char *listen = NULL;
- + struct sockaddr_in them;
- + int detach = 0;
- + char *pidfile = NULL;
- + FILE *fp;
- + char *cp;
- + int len;
- + int ns;
- +
- + /* make sure we are running with root priviledges, because
- + we need it later for chroot, switch_to_user, etc. */
- + if (geteuid() != 0)
- + error(1, 0, "root priviledges required for pserver operation");
- +
- + /* process "cvs pserverd" command options */
- + optind = 0;
- + while ((option = getopt(argc, argv, "vl:dp:A:R:")) != EOF) {
- + switch ((char) option) {
- + case 'v':
- + pserverd_verbose = 1;
- + break;
- + case 'l':
- + listen = xstrdup(optarg);
- + break;
- + case 'd':
- + detach = 1;
- + pserverd_verbose = 0;
- + break;
- + case 'p':
- + pidfile = xstrdup(optarg);
- + break;
- + case 'A':
- + pserverd_anonymous_user = xstrdup(optarg);
- + break;
- + case 'R':
- + cp = xstrdup(optarg);
- + pserver_chroot.user = cp;
- + if ((cp = strchr(cp, ':')) == NULL)
- + error(1, 0, "invalid -R option argument");
- + *cp++ = '\0';
- + pserver_chroot.repos = cp;
- + if ((cp = strchr(cp, ':')) == NULL)
- + error(1, 0, "invalid -R option argument");
- + *cp++ = '\0';
- + pserver_chroot.chroot = cp;
- + break;
- + case '?':
- + default:
- + usage(pserverd_usage);
- + break;
- + }
- + }
- + argc -= optind;
- + argv += optind;
- + if (argc < 0)
- + usage(pserverd_usage);
- +
- + /* optionally go into the background as a real daemon */
- + if (detach)
- + proc_daemon(0, 0);
- +
- + /* optionally write out the pid */
- + if (pidfile != NULL) {
- + if ((fp = fopen(pidfile, "w")) == NULL)
- + error(1, 0, "unable to write pid to file %s: %s",
- + pidfile, strerror(errno));
- + fprintf(fp, "%ld\n", (long)getpid());
- + fclose(fp);
- + }
- +
- + /* listen on the TCP/IP socket */
- + if (listen != NULL) {
- + if ((port = strrchr(listen, ':')) != NULL)
- + *(port++) = '\0';
- + if (strcasecmp(listen, "*") == 0 || strcmp(listen, "0.0.0.0") == 0)
- + host = NULL;
- + else
- + host = listen;
- + }
- + if ((sd = tcp_listen(host, port)) < 0)
- + error(1, 0, "unable to listen (%s:%s): %s",
- + host != NULL ? host : "*", port, strerror(errno));
- +
- + /* make sure we reap the childs */
- + signal(SIGCHLD, &pserver_daemon_reapchild);
- +
- + /* daemon loop */
- + for (;;) {
- + len = sizeof(them);
- + ns = accept(sd, (struct sockaddr *)&them, &len);
- + if (ns < 0) {
- + if (errno == EINTR)
- + continue;
- + error(1, 0, "accept(2) failed: %s", strerror(errno));
- + }
- + switch (child = fork()) {
- + case -1:
- + error(1, 0, "unable to fork(2): %s", strerror(errno));
- + break;
- + case 0:
- + /* child */
- + close(sd);
- + signal(SIGCHLD, SIG_DFL);
- +
- + /* connect stdin/stdout to socket */
- + dup2(ns, STDIN_FILENO);
- + dup2(ns, STDOUT_FILENO);
- +
- + /*
- + * perform "cvs pserver" authentication handshake.
- + */
- + pserver_handshake();
- +
- + /*
- + * just return to caller, i.e., the main() procedure
- + * which in turn will dispatch into "cvs server" code
- + * for us...
- + */
- + return 0;
- + break;
- + default:
- + /* parent */
- + if (pserverd_verbose)
- + fprintf(stderr, "cvs pserverd[%ld]: child process (pid %ld): started.\n",
- + (long)getpid(), (long)child);
- + close(ns);
- + break;
- + }
- + }
- + exit(0);
- + return 0;
- +}
- +
- +static void
- +pserver_handshake(
- + void)
- +{
- + char *tmp = NULL;
- + size_t tmp_allocated = 0;
- + char *repository = NULL;
- + size_t repository_allocated = 0;
- + char *username = NULL;
- + size_t username_allocated = 0;
- + char *password = NULL;
- + size_t password_allocated = 0;
- + char *host_user = NULL;
- + char *descrambled_password;
- + int verify_and_exit = 0;
- + char *chrootdir = NULL;
- + int on;
- +
- +#ifdef SO_KEEPALIVE
- + /* Set SO_KEEPALIVE on the socket, so that we don't hang forever
- + if the client dies while we are waiting for input. */
- + on = 1;
- + (void)setsockopt(STDIN_FILENO, SOL_SOCKET, SO_KEEPALIVE,
- + (char *)&on, sizeof(on));
- +#endif
- +
- + /* Make sure the protocol starts off on the right foot... */
- + getline(&tmp, &tmp_allocated, stdin);
- +
- + if (strcmp (tmp, "BEGIN VERIFICATION REQUEST\n") == 0)
- + verify_and_exit = 1;
- + else if (strcmp (tmp, "BEGIN AUTH REQUEST\n") == 0)
- + ;
- + else
- + error (1, 0, "bad auth protocol start: %s", tmp);
- +
- + /* Get the three important pieces of information in order. */
- + getline(&repository, &repository_allocated, stdin);
- + getline(&username, &username_allocated, stdin);
- + getline(&password, &password_allocated, stdin);
- +
- + /* Make them pure. */
- + strip_trailing_newlines(repository);
- + strip_trailing_newlines(username);
- + strip_trailing_newlines(password);
- +
- +#ifdef RSE_PATCH_MAPROOT
- + root_map_it(repository, &repository, 0);
- +#endif
- +
- + /* ... and make sure the protocol ends on the right foot. */
- + getline(&tmp, &tmp_allocated, stdin);
- + if (strcmp (tmp, verify_and_exit ?
- + "END VERIFICATION REQUEST\n" : "END AUTH REQUEST\n") != 0)
- + error (1, 0, "bad auth protocol end: %s", tmp);
- +
- + if (!root_allow_ok(repository))
- + goto i_hate_you;
- + parse_config(repository);
- +
- + /* We need the real cleartext before we hash it. */
- + descrambled_password = descramble(password);
- + host_user = check_password(username, descrambled_password, repository);
- + memset(descrambled_password, 0, strlen(descrambled_password));
- + free(descrambled_password);
- +
- + if (host_user == NULL) {
- + i_hate_you:
- + printf("I HATE YOU\n");
- + fflush(stdout);
- + if (pserverd_verbose)
- + fprintf(stderr, "cvs pserverd[%ld]: status=FAILED user=%s root=%s\n",
- + (long)getpid(), username, repository);
- + error_exit();
- + }
- +
- + /* Don't go any farther if we're just responding to "cvs login". */
- + if (verify_and_exit) {
- + printf("I LOVE YOU\n");
- + fflush(stdout);
- + if (pserverd_verbose)
- + fprintf(stderr, "cvs pserverd[%ld]: status=OK user=%s root=%s (huser=%s)\n",
- + (long)getpid(), username, repository, host_user);
- + exit(0);
- + }
- +
- + /* Set Pserver_Repos so that we can check later that the same
- + repository is sent in later client/server protocol. */
- + Pserver_Repos = xmalloc(strlen(repository)+1);
- + strcpy(Pserver_Repos, repository);
- +
- + /* Optionally perform a chroot */
- + if (pserver_chroot.user != NULL) {
- + if ( strcmp(username, pserver_chroot.user) == 0
- + && ( strcmp(repository, pserver_chroot.repos) == 0
- + || strcmp(pserver_chroot.repos, "*") == 0 )) {
- + chrootdir = pserver_chroot.chroot;
- + if (chdir(chrootdir) == -1)
- + error(1, 0, "failed to chdir(2) to %s: %s", chrootdir, strerror(errno));
- + if (chroot(chrootdir) == -1)
- + error(1, 0, "failed to chroot(2) to %s: %s", chrootdir, strerror(errno));
- + }
- + }
- +
- + /* Additionally switch to read-only mode for anonymous user */
- + if (pserverd_anonymous_user != NULL) {
- + if (strcmp(username, pserverd_anonymous_user) == 0) {
- +#ifdef RSE_PATCH_NOLOCK
- + nolock = 1;
- +#endif
- + logoff = 1;
- + }
- + }
- +
- + /* Switch to run as this user. */
- + switch_to_user(host_user);
- + free(tmp);
- + free(repository);
- + free(username);
- + free(password);
- +
- + printf("I LOVE YOU\n");
- + fflush(stdout);
- + if (pserverd_verbose)
- + fprintf(stderr, "cvs pserverd[%ld]: status=OK user=%s root=%s (huser=%s hroot=%s)\n",
- + (long)getpid(), username, repository, host_user, chrootdir != NULL ? chrootdir : "/");
- + return;
- +}
- +
- +#endif /* RSE_PATCH_PSERVERD */
- +
- Index: src/subr.c
- ===================================================================
- RCS file: /e/ossp/pkg/tool/cvs/cvs/cvs/src/subr.c,v
- retrieving revision 1.1.1.4
- diff -u -d -u -3 -r1.1.1.4 subr.c
- --- src/subr.c 19 Apr 2001 19:34:04 -0000 1.1.1.4
- +++ src/subr.c 16 Feb 2002 13:49:47 -0000
- @@ -336,6 +336,22 @@
- uid_t uid;
- #endif
-
- +#ifdef RSE_PATCH_CVSUSER
- +#ifndef RSE_PATCH_CVSUSER_CALLER
- +#define RSE_PATCH_CVSUSER_CALLER "cvs"
- +#endif
- + uid = getuid();
- + if ((pw = (struct passwd *)getpwnam(RSE_PATCH_CVSUSER_CALLER)) != NULL) {
- + if (pw->pw_uid == uid) {
- + char *name;
- + if ((name = getenv("CVSUSER")) != NULL) {
- + cache = xstrdup(name);
- + return cache;
- + }
- + }
- + }
- +#endif
- +
- /* If there is a CVS username, return it. */
- #ifdef AUTH_SERVER_SUPPORT
- if (CVS_Username != NULL)
- @@ -797,6 +813,73 @@
-
- return backup_name;
- }
- +
- +#ifdef RSE_PATCH_HANDLE
- +/* handle: 2000041317203601
- + date1: 2000/04/13 17:20:36
- + date2: 2000/04/13 17:20:37 */
- +int handle2dates(char *handle, time_t *t1, time_t *t2)
- +{
- + int Y,M,D,h,m,s,o;
- + char buf[17];
- + time_t t;
- + struct tm tm;
- + int rev = 0;
- + int i;
- +
- + /* check for correct handle format */
- + if (handle == NULL)
- + return 0;
- + if (handle[0] == '!') {
- + handle++;
- + rev = 1;
- + }
- + if (strlen(handle) != 16)
- + return 0;
- + for (i = 0; i < 16; i++)
- + if (!isdigit(handle[i]))
- + return 0;
- +
- + /* parse out handle parts */
- + strcpy(buf, handle);
- + o = atoi(buf+14);
- + buf[14] = '\0';
- + s = atoi(buf+12);
- + buf[12] = '\0';
- + m = atoi(buf+10);
- + buf[10] = '\0';
- + h = atoi(buf+8);
- + buf[8] = '\0';
- + D = atoi(buf+6);
- + buf[6] = '\0';
- + M = atoi(buf+4);
- + buf[4] = '\0';
- + Y = atoi(buf);
- +
- + /* assemble parts into a time value */
- + memset(&tm, 0, sizeof tm);
- + tm.tm_sec = s;
- + tm.tm_min = m;
- + tm.tm_hour = h;
- + tm.tm_mday = D;
- + tm.tm_mon = M - 1;
- + tm.tm_year = Y - 1900;
- + t = mktime(&tm);
- + if (t == -1)
- + return 0;
- +
- + /* output the first and second time */
- + if (rev) {
- + *t2 = t;
- + *t1 = t + o;
- + }
- + else {
- + *t1 = t;
- + *t2 = t + o;
- + }
- + return 1;
- +}
- +#endif
-
- /*
- * Copy a string into a buffer escaping any shell metacharacters. The
- Index: src/tag.c
- ===================================================================
- RCS file: /e/ossp/pkg/tool/cvs/cvs/cvs/src/tag.c,v
- retrieving revision 1.1.1.4
- diff -u -d -u -3 -r1.1.1.4 tag.c
- --- src/tag.c 24 Apr 2001 17:04:59 -0000 1.1.1.4
- +++ src/tag.c 16 Feb 2002 12:36:09 -0000
- @@ -1229,7 +1229,11 @@
- /* The tags is valid but not mentioned in val-tags. Add it. */
- datum value;
-
- +#ifdef RSE_PATCH_NOLOCK
- + if (noexec || nowrite || nolock)
- +#else
- if (noexec || nowrite)
- +#endif
- {
- if (db != NULL)
- dbm_close (db);
- Index: src/update.c
- ===================================================================
- RCS file: /e/ossp/pkg/tool/cvs/cvs/cvs/src/update.c,v
- retrieving revision 1.1.1.4
- diff -u -d -u -3 -r1.1.1.4 update.c
- --- src/update.c 24 Apr 2001 17:04:59 -0000 1.1.1.4
- +++ src/update.c 16 Feb 2002 12:36:09 -0000
- @@ -203,7 +203,11 @@
- break;
- case 'p':
- pipeout = 1;
- +#ifdef RSE_PATCH_NOLOCK
- + nolock = noexec = 1; /* so no locks will be created */
- +#else
- noexec = 1; /* so no locks will be created */
- +#endif
- break;
- case 'j':
- if (join_rev2)
- @@ -1809,6 +1813,17 @@
- patch can't handle that. */
- fail = 1;
- }
- +#ifdef RSE_PATCH_FASTERUPDATE
- + else {
- + /*
- + * Don't send a diff if just sending the entire file
- + * would be smaller
- + */
- + fseek(e, 0L, SEEK_END);
- + if (file_info->st_size < ftell(e))
- + fail = 1;
- + }
- +#endif
- fclose (e);
- }
- }
- @@ -2563,8 +2578,16 @@
- write_letter (finfo, 'C');
- }
- else
- +#ifdef RSE_PATCH_MERGENOKEYWORD
- + {
- + if (*t_options == '\0')
- + t_options = "-kk"; /* to ignore keyword expansions */
- +#endif
- status = RCS_merge (finfo->rcs, vers->srcfile->path, finfo->file,
- t_options, rev1, rev2);
- +#ifdef RSE_PATCH_MERGENOKEYWORD
- + }
- +#endif
-
- if (status != 0 && status != 1)
- {
- Index: src/version.c
- ===================================================================
- RCS file: /e/ossp/pkg/tool/cvs/cvs/cvs/src/version.c,v
- retrieving revision 1.1.1.5
- diff -u -d -u -3 -r1.1.1.5 version.c
- --- src/version.c 27 Apr 2001 20:02:28 -0000 1.1.1.5
- +++ src/version.c 16 Feb 2002 12:38:04 -0000
- @@ -12,7 +12,11 @@
-
- #include "cvs.h"
-
- +#ifdef RSE_PATCHES
- +char *version_string = "Concurrent Versions System (CVS) 1.11.1p1 [RSE]";
- +#else
- char *version_string = "Concurrent Versions System (CVS) 1.11.1p1";
- +#endif
-
- #ifdef CLIENT_SUPPORT
- #ifdef SERVER_SUPPORT
|