cvs.patches.rse 154 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042
  1. Index: src/README.RSE
  2. ===================================================================
  3. RCS file: src/README.RSE
  4. diff -N src/README.RSE
  5. --- /dev/null 1 Jan 1970 00:00:00 -0000
  6. +++ src/README.RSE 16 Feb 2002 12:35:28 -0000
  7. @@ -0,0 +1,353 @@
  8. +
  9. + CVS RSE Patches
  10. + ===============
  11. +
  12. + This is the patched version of CVS from Ralf S. Engelschall
  13. + <rse@engelschall.com> - an enhanced version of the official
  14. + Cyclic/OpenAvenue's CVS version 1.11.1p1 (see http://www.cvshome.org/).
  15. +
  16. + The following changes against the avendor CVS version are provided:
  17. + - support for .cvsrc files in $HOME _AND_ working and and its parent dirs
  18. + - support for $HOME/.cvsroot to alias roots and to support root mirrors
  19. + - support global but command specific options in .cvsrc files
  20. + - support for stand-alone external custom commands `cvs <command>'
  21. + - support for prolog and epilog hooks
  22. + - allow `verifymsg' hooks to _change_ the log message
  23. + - support `$LocalId$, a local keyword variant of `$Id$'
  24. + - support `$CVSHeader$, a variant of `$Header$', but without root path
  25. + - new `cvs -u' option in addition to `cvs -n' for _REAL_ read-only access
  26. + - support for additional `%x' variables on `loginfo' hook command lines
  27. + - support a `UMask=<mask>' variable in `$CVSROOT/CVSROOT/config'
  28. + - speeded up `cvs update' by sending whole file if smaller than the diff
  29. + - disabled keyword expansions during branch merges
  30. + - adjusted `cvs diff -rHEAD' to be consistent with other commands
  31. + - made `cvs diff' aware of removed/dead files in the trunk
  32. + - set `$LOGNAME' to the real user and not the CVS user
  33. + - support for `HistoryFile=<rel-path-under-CVSROOT>' variable in config.
  34. + - support for an `admininfo' hook to ACL `cvs admin' commands.
  35. + - support for an `importinfo' hook to ACL `cvs import' commands.
  36. + - support for a `-h<handle>' option to `cvs diff' for compressed time spec.
  37. + - use prefix 'T' ("touched/tagged") instead of 'U' ("updated") on `cvs import'
  38. + - allow `LockDir' configuration directive to use relative paths
  39. + - allow a hard-coded CVS super-user to override CVS user via $CVSUSER
  40. + - additional SetUID/SetGID support for `cvs server' situations.
  41. + - new `cvs pserverd' for running stand-alone pserver daemons
  42. + - new global --map-root=/oldpath:/newpath option for mapping root paths
  43. + - support for wildcards in CVSROOT/passwd files to decrease admin efforts
  44. + - various cosmetic changes
  45. +
  46. + Some of my RSE functional patches are only useful for the server side,
  47. + others are also useful on the client side. All source patches to
  48. + *.[ch] files were entirely wrapped with ``#ifdef RSE_PATCH_<NAME> ...
  49. + #endif'' pairs. So, a particular patch is enabled by building CVS with
  50. + -DRSE_PATCH_<NAME>. All patches are enabled with -DRSE_PATCHES.
  51. +
  52. + Ralf S. Engelschall
  53. + rse@engelschall.com
  54. + www.engelschall.com
  55. + ________________________________________________________________________
  56. +
  57. + The following particular patches are available:
  58. +
  59. + RSE_PATCH_CVSRC:
  60. + In addition to processing `$HOME/.cvsrc', process also `.cvsrc'
  61. + files in the current working directory and the parent directories of
  62. + the current working directory. This allows one to use for instance a
  63. + `commit -m ""' locally (as used for GNU Pth development where CVS is
  64. + only used for plain revision control and not for bookkeeping changes
  65. + or group communication - instead a plain manually edited ChangeLog
  66. + exists) or `commit -d <master>' (if working with a local repository
  67. + copy). Additionally this adds support for quoted strings inside
  68. + .cvsrc files.
  69. + [Origin: Ralf S. Engelschall]
  70. +
  71. + RSE_PATCH_CVSROOT:
  72. + This adds support for a new dot-file ~/.cvsroot which is used
  73. + optionally by CVS. It can be used by the user to configure a
  74. + nickname for a CVS repository root (the master location) plus a
  75. + possibly existing local repository copy (the slave location). An
  76. + entry in ~/.cvsroot is of the format ``<nickname> <master-path>
  77. + [<slave-path> [<sync-prog>]]''. Those entries can be either created
  78. + manually in ~/.cvsroot or with the `cvs root -e' command.
  79. +
  80. + The idea is this: if a global `-d' option is used with <nickname> it is
  81. + automatically expanded to <master-path>. If no global `-d' option is used,
  82. + the CVS command is checked. If it is one of the commands which are known
  83. + to CVS to modify the repository, and the $CVSROOT or CVS/Root specify a
  84. + slave location, the repository is switched to the corresponding master
  85. + location (because modifications have to be performed there). If the
  86. + command is one of the commands which are known to CVS to NOT modify the
  87. + repository, and the $CVSROOT or CVS/Root specify a master location, the
  88. + repository is switched to the corresponding slave location (because the
  89. + slave location is faster than the master location per definition).
  90. +
  91. + After a modifying operation, CVS can either run a synchronization job
  92. + automatically to bring slave in sync with master again or the user can run
  93. + `cvs root -s <nickname>' manually to perform this task.
  94. + [Origin: Ralf S. Engelschall]
  95. +
  96. + RSE_PATCH_GLOBALOPTION:
  97. + RSE_PATCH_GLOBALOPTION_PARTLY:
  98. + By default, global options in `.cvsrc' files are specified with a
  99. + `cvs' prefix. These options then apply to _all_ cvs commands. If
  100. + RSE_PATCH_GLOBALOPTION is enabled, a second pass is done where all
  101. + global options are read with prefix `cvs/<command>' where <command>
  102. + is the official cvs command (for instance `commit' or `checkout',
  103. + even if `ci' or `co' are used on the command line). This is useful
  104. + for instance to override CVSROOT in commit commands if using a local
  105. + repository copy. The drawback of this feature is that it obviously
  106. + slows down cvs calls, because a second pass has to be done. But
  107. + usually this feature is intended only for use with `commit', `tag',
  108. + `rtag', `history', `admin', `import' and `rdiff' commands, so if
  109. + RSE_PATCH_GLOBALOPTION_PARTLY is additionally enabled, this second
  110. + pass is only done for those commands (which is the recommended use
  111. + of this feature).
  112. + [Origin: Ralf S. Engelschall]
  113. +
  114. + RSE_PATCH_CUSTOMCMD:
  115. + This provides an additional global option `-C
  116. + <cmd-name>:<cmd-program>' which defines an additional CVS command
  117. + <cmd-name>. It is intended for use on `cvs' lines inside .cvsrc
  118. + files. The effect of having `cvs -Csync:$CVSROOT/CVSROOT/sync' in a
  119. + .cvsrc file is (and assuming $CVSROOT is /e/ossp/cvs) that if you
  120. + run `cvs sync <arg1> <arg2>', CVS executes `/e/ossp/cvs/CVSROOT/sync
  121. + <arg1> <arg2>'. So this is a way to externally extend CVS with
  122. + additional commands.
  123. + [Origin: Ralf S. Engelschall]
  124. +
  125. + RSE_PATCH_PROLOGEPILOG:
  126. + Provides the two additional CVS options `-P <program>' and `-E
  127. + <program>' for running prolog and epilog programs before and
  128. + after the usual CVS processing. This is mainly intended as local
  129. + hooks for implicitly wrapping CVS commands (without having to
  130. + create slow wrapping shell scripts, etc.). Developers usually
  131. + use it to automatically start their RSYNC command to update the
  132. + local repository copy after a commit. The <program> is called
  133. + with four arguments: $1 is either `prolog' or `epilog' (useful
  134. + if one just wants to use a single hook program), $2 is the cvs
  135. + command (it is `commit' even `ci' is used, etc.), $3 is the current
  136. + working directory from which the cvs command was run and $4 is the
  137. + corresponding $CVSROOT variable.
  138. + [Origin: Ralf S. Engelschall]
  139. +
  140. + RSE_PATCH_VERIFY:
  141. + This patch forces CVS to read in again the log messages after the
  142. + verification step (via the `verifymsg' hook) to allow the hook
  143. + script to actually _update_ the log message. This is useful for
  144. + stripping out unnecessary stuff, like not filled out custom fields
  145. + of the log template text.
  146. + [Origin: Peter Wemm, FreeBSD]
  147. +
  148. + RSE_PATCH_LOCALID:
  149. + Support a local keyword variant of `$Id$'. By default this is
  150. + `$LocalId$', but if -DRSE_PATCH_LOCALID_NAME=\"<name>\" is
  151. + additionally defined, then the keyword is `$<name>$'. Alternatively
  152. + one can define the name also in the `$CVSROOT/CVSROOT/config' file
  153. + with `LocalIdName=<name>'.
  154. + [Origin: NetBSD, OpenBSD, Ralf S. Engelschall]
  155. +
  156. + RSE_PATCH_CVSHEADER:
  157. + Support the `$CVSHeader' variant of `$Header$' which has the
  158. + $CVSROOT prefix stripped of from the path. This is useful because
  159. + the prefix usually useless outside the server environment.
  160. + [Origin: FreeBSD]
  161. +
  162. + RSE_PATCH_NOLOCK:
  163. + Provide a `cvs -u' option in addition to `cvs -n' to force CVS to
  164. + not create any lock files in the repository. This is for supporting
  165. + read-only access to the repository. This is useful for working
  166. + with CVS repositories on CD-ROMs and for providing anonymous CVS
  167. + services.
  168. + [Origin: NetBSD]
  169. +
  170. + RSE_PATCH_EXTRAPERCENT:
  171. + This adds extra percent expansions to `loginfo' command lines:
  172. + `%o' to expand the operation (`A' = added, `M' = modified, `R' =
  173. + removed), `%t' to expand the tag, `%d' to expand the date.
  174. + [Origin: Ralf S. Engelschall]
  175. +
  176. + RSE_PATCH_READDNEW:
  177. + If a file was re-added to the repository, log the revision in the
  178. + `commitlog' as `NONE' instead of the previous dead revision.
  179. + [Origin: NetBSD]
  180. +
  181. + RSE_PATCH_CONFIGUMASK:
  182. + Provide a `UMask=<mask>' variable in `$CVSROOT/CVSROOT/config' which
  183. + overrides the umask of the CVS server process.
  184. + [Origin: OpenBSD]
  185. +
  186. + RSE_PATCH_FASTERUPDATE:
  187. + This speeds up `cvs update' by sending the whole file over the
  188. + network if it is smaller than the diff content. This is useful for
  189. + working remotely over slow Internet links.
  190. + [Origin: OpenBSD]
  191. +
  192. + RSE_PATCH_MERGENOKEYWORD:
  193. + This disables keyword expansions during branch merges which is
  194. + very useful in long-term branching. Without this the so-called
  195. + `spurious merging conflicts' occur because the keywords cause
  196. + spurious conflicts on every merge after the first (if those text
  197. + files have been modified on the trunk since the previous merge out
  198. + to the branch).
  199. + [Origin: Jay Sachs <jsachs@iclick.com>]
  200. +
  201. + RSE_PATCH_DIFFHEAD:
  202. + This patch changes the behavior of `cvs diff -rHEAD' on branches.
  203. + HEAD here now behaves with as it does with all other CVS commands,
  204. + as a name for the head of the trunk (the old behavior of `cvs diff
  205. + -rHEAD' was to treat HEAD to mean the head of the branch, while all
  206. + the other commands already treated HEAD as the head of the trunk).
  207. + [Origin: Stephen Cameron <steve.cameron@compaq.com>]
  208. +
  209. + RSE_PATCH_DEADAWARE:
  210. + This makes `cvs diff' aware of removed/dead files in the trunk
  211. + (HEAD), i.e., it doesn't complain if it didn't exist.
  212. + [Origin: FreeBSD]
  213. +
  214. + RSE_PATCH_LOGNAME:
  215. + This is for SUID-based CVS servers and passes in `$LOGNAME' the real
  216. + user (first field in `$CVSROOT/CVSROOT/passwd') instead of the SUID
  217. + user (third field in `$CVSROOT/CVSROOT/passwd')
  218. + [Origin: Chris Cameron]
  219. +
  220. + RSE_PATCH_HISTORYFILE:
  221. + This provides an additional `HistoryFile=<rel-path-under-CVSROOT>'
  222. + config variable which allows one to store the history file under a
  223. + different path.
  224. + [Origin: Ralf S. Engelschall]
  225. +
  226. + RSE_PATCH_SMARTCONFIG:
  227. + This allows one to add custom configuration variables to
  228. + `$CVSROOT/CVSROOT/config' without having CVS complain about them and
  229. + fail with an error. This is useful to use the config file also for
  230. + storing config details for the various admin scripts.
  231. + [Origin: Ralf S. Engelschall]
  232. +
  233. + RSE_PATCH_ADMININFO:
  234. + This adds the feature of an extra `$CVSROOT/CVSROOT/admininfo'
  235. + configuration file which can be used for access controlling `cvs
  236. + admin' commands similar to `cvs tag' (which is already done
  237. + with `taginfo') and `cvs commit' (which is already done with
  238. + `commitinfo'). The specified filters in this info file receive the
  239. + absolute repository directory as the first argument, followed by all
  240. + names of files in this directory on which the `cvs admin' command
  241. + should be performed. If the filter returns 0, the operation is
  242. + allowed. If it returns not 0, the operation is denied.
  243. + [Origin: Ralf S. Engelschall]
  244. +
  245. + RSE_PATCH_IMPORTINFO:
  246. + This adds the feature of an extra `$CVSROOT/CVSROOT/importinfo'
  247. + configuration file which can be used for access controlling
  248. + `cvs import'. The specified filters in this info file receives
  249. + the following arguments: the vendor branch tag, the (absolute)
  250. + repository path which is the root of the import and then zero or
  251. + more relative file paths under this repository. If the filter
  252. + returns 0, the operation is allowed. If it returns not 0, the
  253. + operation is denied.
  254. + [Origin: Ralf S. Engelschall]
  255. +
  256. + RSE_PATCH_HANDLE:
  257. + This adds a convinient `-h<handle>' option to `cvs diff'. `<handle>'
  258. + is a string of the format `[!]YYMMDDhhmmssoo' (YY=year, MM=month,
  259. + DD=day, hh=hour, mm=minute, ss=second, oo=offset) which internally
  260. + is expanded into two `-D' options. The first date is the equivalent
  261. + of `YYMMDDhhmmss', the second is the first plus `oo' seconds. If the
  262. + exclamation mark is used, the two dates are reversed. The intention
  263. + is that such a handle is a short form for a time range and can be
  264. + easily computed in a commit log mail. So the `-h' option can be used
  265. + to easily get the corresponding change diff for branch merging or
  266. + backing out. The only restriction is that time-overlapping commits
  267. + break the solution, of course. But in practice this is no real
  268. + problem.
  269. + [Origin: Ralf S. Engelschall]
  270. +
  271. + RSE_PATCH_IMPORTTOUCH:
  272. + This prints the prefix 'T' (for "touched/tagged only") instead
  273. + of 'U' (for "updated") on `cvs import' if no modifications were
  274. + imported, i.e., no new revision is comitted. This way one can
  275. + distinguish those imports from the regular updated ones which also
  276. + print 'U' and which actually commit a new revision.
  277. + [Origin: Ralf S. Engelschall]
  278. +
  279. + RSE_PATCH_RELLOCKDIR:
  280. + This allows the `LockDir' configuration directive to use relative
  281. + paths to $CVSROOT, because without this patch a relative path would
  282. + be relative to the current working directory (which is useless).
  283. + [Origin: Stefan Monnier <foo@acm.com>]
  284. +
  285. + RSE_PATCH_CVSUSER:
  286. + This allows the Unix user RSE_PATCH_CVSUSER_CALLER (per default
  287. + "ossp-cvs") to use the environment variable CVSUSER to override the
  288. + login name CVS uses to identify the caller. This is intended for use
  289. + with a CVS setuid wrapper program or for use manually by the CVS
  290. + administrator.
  291. + [Origin: Ralf S. Engelschall]
  292. +
  293. + RSE_PATCH_SETXID:
  294. + This is a variant of CVS's SETXID_SUPPORT. It allows one to
  295. + setuid/setgid the CVS executable. Then CVS deletes these effective
  296. + uid/gid for all commands except for the "cvs server" command. For
  297. + this and only this it switches the real uid/gid to the effective
  298. + uid/gid. This way one can use the repository as a black-box. One
  299. + just has to be make sure that only :ext: (for remote) and :fork:
  300. + (for local) access is used.
  301. + [Origin: Ralf S. Engelschall]
  302. +
  303. + RSE_PATCH_PSERVERD:
  304. + This adds an additional `cvs pserverd' command which is like `cvs
  305. + pserver' except that it uses own builtin TCP/IP socket listening and
  306. + forking facility. The advantages over using inetd are: pserverd can
  307. + listen to particular host addresses/ports (inetd always binds to all
  308. + interfaces of a host), it can optionally chroot(2) for a particular
  309. + user only (usually "anonymous"), it can optionally force the global
  310. + options -l -u for a particular user only (usually "anonymous"), it
  311. + can detach into background and run as a real daemon, etc.
  312. + [Origin: Ralf S. Engelschall]
  313. +
  314. + RSE_PATCH_MAPROOT
  315. + This adds a global --map-root=/oldpath:/newpath option which
  316. + allows one to map virtual/incoming CVSROOT values to real ones.
  317. + For instance this can be used together with --allow-root and "cvs
  318. + pserverd" to map the intuitive virtual path to the physical path on
  319. + the host.
  320. + [Origin: Ralf S. Engelschall]
  321. +
  322. + RSE_PATCH_HASHFUNC:
  323. + This replaces the obscure hash function in src/hash.c with D.J.Berstein's
  324. + popular "times 33" function which is faster to compute and still
  325. + distributes very well.
  326. + [Origin: Ralf S. Engelschall]
  327. +
  328. + RSE_PATCH_ADDFILEATTR:
  329. + Let the default file attributes set on newly added files.
  330. + [Origin: Noel Yap]
  331. +
  332. + RSE_PATCH_WILDPASSWD:
  333. + This allows wildcards ("*") in CVSROOT/passwd. That allows one to
  334. + just do "*:ULtgRLXo7NRxs:cvsuser" which would let absolutely anyone
  335. + use CVS provided they know the password. It would also let you do
  336. + things like "*:*:cvsuser" to let only authorized system users use
  337. + CVS using their system passwords.
  338. + [Larry Jones <larry.jones@sdrc.com>]
  339. +
  340. + RSE_PATCH_CVSPID:
  341. + This provides an environment variable $CVSPID which contains the process
  342. + id of the parent CVS process. This is usually used inside scripts called
  343. + from *info files in order to have a unique session handle (for instance
  344. + for a common temporary directory "/tmp/cvs.foo.$CVSPID", etc).
  345. + [Origin: Rich Salz <rsalz@caveosystems.com>]
  346. +
  347. + RSE_PATCH_BUGFIX:
  348. + This enabled various bugfixes which are still not present in the
  349. + official CVS version.
  350. + [Origin: Ralf S. Engelschall]
  351. +
  352. + RSE_PATCH_COSMETICS:
  353. + This just enables some cosmetic changes to various output messages.
  354. + [Origin: Ralf S. Engelschall]
  355. +
  356. + RSE_PATCH_COSMETICS_HARD:
  357. + This just enables more cosmetic changes to various output messages.
  358. + The difference is that these break "make check".
  359. + [Origin: Ralf S. Engelschall]
  360. +
  361. Index: src/add.c
  362. ===================================================================
  363. RCS file: /e/ossp/pkg/tool/cvs/cvs/cvs/src/add.c,v
  364. retrieving revision 1.1.1.4
  365. diff -u -d -u -3 -r1.1.1.4 add.c
  366. --- src/add.c 19 Apr 2001 19:45:31 -0000 1.1.1.4
  367. +++ src/add.c 16 Feb 2002 12:36:09 -0000
  368. @@ -798,6 +798,9 @@
  369. li->type = T_TITLE;
  370. li->tag = xstrdup (tag);
  371. li->rev_old = li->rev_new = NULL;
  372. +#ifdef RSE_PATCH_EXTRAPERCENT
  373. + li->date = NULL;
  374. +#endif
  375. p->data = (char *) li;
  376. (void) addnode (ulist, p);
  377. Update_Logfile (rcsdir, message, (FILE *) NULL, ulist);
  378. Index: src/admin.c
  379. ===================================================================
  380. RCS file: /e/ossp/pkg/tool/cvs/cvs/cvs/src/admin.c,v
  381. retrieving revision 1.1.1.4
  382. diff -u -d -u -3 -r1.1.1.4 admin.c
  383. --- src/admin.c 24 Apr 2001 18:14:53 -0000 1.1.1.4
  384. +++ src/admin.c 16 Feb 2002 12:36:09 -0000
  385. @@ -139,6 +139,161 @@
  386. dat->av[dat->ac++] = newelt;
  387. }
  388. +#ifdef RSE_PATCH_ADMININFO
  389. +
  390. +static List *admininfo_dlist;
  391. +static List *admininfo_flist;
  392. +
  393. +static void admininfo_dlist_delproc(Node *);
  394. +static int admininfo_info_runproc(char *, char *);
  395. +static int admininfo_flist_runproc(Node *, void *);
  396. +
  397. +struct admininfo_dlist_st {
  398. + List *flist;
  399. +};
  400. +
  401. +/* file callback function for recursive processing */
  402. +static int
  403. +admininfo_fileproc (
  404. + void *callerdat,
  405. + struct file_info *finfo)
  406. +{
  407. + char *xdir;
  408. + Node *dnode;
  409. + Node *fnode;
  410. +
  411. + /* determine current directory */
  412. + if (finfo->update_dir[0] == '\0')
  413. + xdir = ".";
  414. + else
  415. + xdir = finfo->update_dir;
  416. +
  417. + /* find directory node in directory list */
  418. + if ((dnode = findnode(admininfo_dlist, xdir)) != NULL)
  419. + /* take already existing file list */
  420. + admininfo_flist = ((struct admininfo_dlist_st *)dnode->data)->flist;
  421. + else {
  422. + /* create a new file list */
  423. + struct admininfo_dlist_st *dlist;
  424. +
  425. + admininfo_flist = getlist();
  426. +
  427. + dlist = (struct admininfo_dlist_st *)xmalloc(sizeof(struct admininfo_dlist_st));
  428. + dlist->flist = admininfo_flist;
  429. +
  430. + dnode = getnode();
  431. + dnode->type = UPDATE;
  432. + dnode->key = xstrdup(xdir);
  433. + dnode->data = (char *)dlist;
  434. + dnode->delproc = admininfo_dlist_delproc;
  435. +
  436. + (void)addnode(admininfo_dlist, dnode);
  437. + }
  438. +
  439. + /* create new file node in file list */
  440. + fnode = getnode();
  441. + fnode->type = UPDATE;
  442. + fnode->key = xstrdup(finfo->file);
  443. + fnode->data = NULL;
  444. + fnode->delproc = NULL;
  445. + (void)addnode(admininfo_flist, fnode);
  446. +
  447. + return 0;
  448. +}
  449. +
  450. +/* delete a directory list node */
  451. +static void
  452. +admininfo_dlist_delproc(
  453. + Node *p)
  454. +{
  455. + struct admininfo_dlist_st *dlist;
  456. +
  457. + dlist = (struct admininfo_dlist_st *)p->data;
  458. + dellist(&dlist->flist);
  459. + free(dlist);
  460. + return;
  461. +}
  462. +
  463. +/* file callback function for recursive processing (when done) */
  464. +static int
  465. +admininfo_filesdoneproc(
  466. + void *callerdat,
  467. + int err,
  468. + char *repos,
  469. + char *update_dir,
  470. + List *entries)
  471. +{
  472. + Node *dnode;
  473. + int n;
  474. +
  475. + /* find file list for update directory */
  476. + if ((dnode = findnode(admininfo_dlist, update_dir)) != NULL)
  477. + admininfo_flist = ((struct admininfo_dlist_st *)dnode->data)->flist;
  478. + else
  479. + admininfo_flist = (List *)NULL;
  480. + if ( (admininfo_flist == NULL)
  481. + || (admininfo_flist->list->next == admininfo_flist->list))
  482. + return err;
  483. +
  484. + /* parse and execute the admininfo configuration */
  485. + if ((n = Parse_Info(CVSROOTADM_ADMININFO, repos, admininfo_info_runproc, 1)) > 0) {
  486. + error(0, 0, "Pre-admin check failed");
  487. + err += n;
  488. + }
  489. +
  490. + return err;
  491. +}
  492. +
  493. +/* admininfo configuration entry callback */
  494. +static int
  495. +admininfo_info_runproc(repository, filter)
  496. + char *repository;
  497. + char *filter;
  498. +{
  499. + char *s, *cp;
  500. + int rv;
  501. +
  502. + /* if possible, do an own check to make sure that filter really exists */
  503. + if (filter[0] == '/') {
  504. + s = xstrdup(filter);
  505. + for (cp = s; *cp; cp++) {
  506. + if (isspace((unsigned char)*cp)) {
  507. + *cp = '\0';
  508. + break;
  509. + }
  510. + }
  511. + if (!isfile(s)) {
  512. + error (0, errno, "cannot find pre-admin filter '%s'", s);
  513. + free(s);
  514. + return (1);
  515. + }
  516. + free(s);
  517. + }
  518. +
  519. + /* construct the filter command */
  520. + run_setup(filter);
  521. + run_arg(repository);
  522. + walklist(admininfo_flist, admininfo_flist_runproc, NULL);
  523. +
  524. + /* execute the filter command */
  525. + rv = run_exec(RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL);
  526. +
  527. + return rv;
  528. +}
  529. +
  530. +/* file list callback for adding file as another program argument */
  531. +static int
  532. +admininfo_flist_runproc(
  533. + Node *p,
  534. + void *closure)
  535. +{
  536. + if (p->key != NULL)
  537. + run_arg(p->key);
  538. + return 0;
  539. +}
  540. +
  541. +#endif /* RSE_PATCH_ADMININFO */
  542. +
  543. int
  544. admin (argc, argv)
  545. int argc;
  546. @@ -505,6 +660,20 @@
  547. #endif /* CLIENT_SUPPORT */
  548. lock_tree_for_write (argc, argv, 0, W_LOCAL, 0);
  549. +
  550. +#ifdef RSE_PATCH_ADMININFO
  551. + /* allow `CVSROOT/CVSROOT/admininfo' filters to check whether the
  552. + `cvs admin' operation is authorized for all the specified files
  553. + in the repository */
  554. + admininfo_dlist = getlist();
  555. + err = start_recursion(admininfo_fileproc, admininfo_filesdoneproc,
  556. + (DIRENTPROC) NULL, (DIRLEAVEPROC) NULL, NULL,
  557. + argc, argv, 0, W_LOCAL, 0, 0, (char *)NULL, 1);
  558. + if (err) {
  559. + Lock_Cleanup();
  560. + error(1, 0, "correct above errors first!");
  561. + }
  562. +#endif
  563. err = start_recursion (admin_fileproc, (FILESDONEPROC) NULL, admin_dirproc,
  564. (DIRLEAVEPROC) NULL, (void *)&admin_data,
  565. Index: src/checkin.c
  566. ===================================================================
  567. RCS file: /e/ossp/pkg/tool/cvs/cvs/cvs/src/checkin.c,v
  568. retrieving revision 1.1.1.1
  569. diff -u -d -u -3 -r1.1.1.1 checkin.c
  570. --- src/checkin.c 22 Feb 1998 19:46:46 -0000 1.1.1.1
  571. +++ src/checkin.c 16 Feb 2002 12:36:09 -0000
  572. @@ -32,14 +32,27 @@
  573. Vers_TS *vers;
  574. int set_time;
  575. char *tocvsPath = NULL;
  576. +#ifdef RSE_PATCH_COSMETICS_HARD
  577. + int flags;
  578. +#endif
  579. /* Hmm. This message goes to stdout and the "foo,v <-- foo"
  580. message from "ci" goes to stderr. This doesn't make a whole
  581. lot of sense, but making everything go to stdout can only be
  582. gracefully achieved once RCS_checkin is librarified. */
  583. +#ifdef RSE_PATCH_COSMETICS_HARD
  584. + if (!really_quiet) {
  585. +#endif
  586. cvs_output ("Checking in ", 0);
  587. cvs_output (finfo->fullname, 0);
  588. +#ifdef RSE_PATCH_COSMETICS_HARD
  589. + cvs_output ("\n", 0);
  590. +#else
  591. cvs_output (";\n", 0);
  592. +#endif
  593. +#ifdef RSE_PATCH_COSMETICS_HARD
  594. + }
  595. +#endif
  596. tocvsPath = wrap_tocvs_process_file (finfo->file);
  597. if (!noexec)
  598. @@ -56,7 +69,14 @@
  599. if (finfo->rcs == NULL)
  600. finfo->rcs = RCS_parse (finfo->file, finfo->repository);
  601. +#ifdef RSE_PATCH_COSMETICS_HARD
  602. + flags = RCS_FLAGS_KEEPFILE;
  603. + if (really_quiet || quiet)
  604. + flags |= RCS_FLAGS_QUIET;
  605. + switch (RCS_checkin (finfo->rcs, NULL, message, rev, flags))
  606. +#else
  607. switch (RCS_checkin (finfo->rcs, NULL, message, rev, RCS_FLAGS_KEEPFILE))
  608. +#endif
  609. {
  610. case 0: /* everything normal */
  611. @@ -118,6 +138,16 @@
  612. vers->options, vers->tag, vers->date, (char *) 0);
  613. history_write (type, NULL, vers->vn_rcs,
  614. finfo->file, finfo->repository);
  615. +
  616. +#ifdef RSE_PATCH_ADDFILEATTR
  617. + if (type == 'A') {
  618. + char *attr;
  619. + if ((attr = fileattr_getall(NULL)) != NULL) {
  620. + fileattr_setall(finfo->file, attr);
  621. + free(attr);
  622. + }
  623. + }
  624. +#endif
  625. if (tocvsPath)
  626. if (unlink_file_dir (tocvsPath) < 0)
  627. Index: src/checkout.c
  628. ===================================================================
  629. RCS file: /e/ossp/pkg/tool/cvs/cvs/cvs/src/checkout.c,v
  630. retrieving revision 1.1.1.4
  631. diff -u -d -u -3 -r1.1.1.4 checkout.c
  632. --- src/checkout.c 24 Apr 2001 18:14:53 -0000 1.1.1.4
  633. +++ src/checkout.c 16 Feb 2002 12:36:09 -0000
  634. @@ -179,7 +179,11 @@
  635. case 'p':
  636. pipeout = 1;
  637. run_module_prog = 0; /* don't run module prog when piping */
  638. +#ifdef RSE_PATCH_NOLOCK
  639. + noexec = nolock = 1; /* so no locks will be created */
  640. +#else
  641. noexec = 1; /* so no locks will be created */
  642. +#endif
  643. break;
  644. case 'c':
  645. cat = 1;
  646. Index: src/client.c
  647. ===================================================================
  648. RCS file: /e/ossp/pkg/tool/cvs/cvs/cvs/src/client.c,v
  649. retrieving revision 1.1.1.4
  650. diff -u -d -u -3 -r1.1.1.4 client.c
  651. --- src/client.c 24 Apr 2001 18:14:53 -0000 1.1.1.4
  652. +++ src/client.c 16 Feb 2002 12:36:09 -0000
  653. @@ -105,6 +105,9 @@
  654. int status PROTO((int argc, char **argv));
  655. int tag PROTO((int argc, char **argv));
  656. int update PROTO((int argc, char **argv));
  657. +#ifdef RSE_PATCH_RLIST
  658. +int list PROTO((int argc, char **argv));
  659. +#endif
  660. /* All the response handling functions. */
  661. static void handle_ok PROTO((char *, int));
  662. @@ -251,14 +254,34 @@
  663. this_root = Name_Root ((char *) NULL, (char *) NULL);
  664. }
  665. +#ifdef RSE_PATCH_CVSROOT
  666. + {
  667. + int cvsroot_alias;
  668. + cvsroot_type *e;
  669. +
  670. + cvsroot_alias = 0;
  671. + if ((e = cvsroot_lookup(NULL, current_parsed_root->original, NULL)) != NULL)
  672. + if (strcmp(e->slavepath, this_root) == 0)
  673. + cvsroot_alias = 1;
  674. + if ((e = cvsroot_lookup(NULL, NULL, this_root)) != NULL)
  675. + if (strcmp(e->masterpath, current_parsed_root->original) == 0)
  676. + cvsroot_alias = 1;
  677. +#endif
  678. +
  679. /* Now check the value for root. */
  680. if (this_root && current_parsed_root
  681. +#ifdef RSE_PATCH_CVSROOT
  682. + && !cvsroot_alias
  683. +#endif
  684. && (strcmp (this_root, current_parsed_root->original) != 0))
  685. {
  686. /* Don't send this, since the CVSROOTs don't match. */
  687. free (this_root);
  688. return 1;
  689. }
  690. +#ifdef RSE_PATCH_CVSROOT
  691. + }
  692. +#endif
  693. free (this_root);
  694. }
  695. @@ -2704,6 +2727,9 @@
  696. /* Add a directory name to the list of those sent to the
  697. server. */
  698. if (update_dir && (*update_dir != '\0')
  699. +#ifdef RSE_PATCH_CVSROOT
  700. + /* FIXME: alternative to RSE_PATCH_CVSROOT?! */
  701. +#endif
  702. && (strcmp (update_dir, ".") != 0)
  703. && (findnode (dirs_sent_to_server, update_dir) == NULL))
  704. {
  705. @@ -4546,6 +4572,18 @@
  706. error (1, 0,
  707. "This server does not support the global -n option.");
  708. }
  709. +#ifdef RSE_PATCH_NOLOCK
  710. + if (nolock && !noexec)
  711. + {
  712. + if (have_global)
  713. + {
  714. + send_to_server ("Global_option -u\012", 0);
  715. + }
  716. + else
  717. + error (1, 0,
  718. + "This server does not support the global -u option.");
  719. + }
  720. +#endif
  721. if (quiet)
  722. {
  723. if (have_global)
  724. Index: src/commit.c
  725. ===================================================================
  726. RCS file: /e/ossp/pkg/tool/cvs/cvs/cvs/src/commit.c,v
  727. retrieving revision 1.1.1.4
  728. diff -u -d -u -3 -r1.1.1.4 commit.c
  729. --- src/commit.c 24 Apr 2001 18:14:53 -0000 1.1.1.4
  730. +++ src/commit.c 16 Feb 2002 12:36:09 -0000
  731. @@ -296,6 +296,9 @@
  732. data->type = status;
  733. data->tag = xstrdup (vers->tag);
  734. data->rev_old = data->rev_new = NULL;
  735. +#ifdef RSE_PATCH_EXTRAPERCENT
  736. + data->date = xstrdup (vers->ts_user);
  737. +#endif
  738. node->type = UPDATE;
  739. node->delproc = update_delproc;
  740. @@ -498,7 +501,11 @@
  741. /* Run the user-defined script to verify/check information in
  742. *the log message
  743. */
  744. +#ifdef RSE_PATCH_VERIFY
  745. + do_verify (&saved_message, (char *)NULL);
  746. +#else
  747. do_verify (saved_message, (char *)NULL);
  748. +#endif
  749. /* We always send some sort of message, even if empty. */
  750. /* FIXME: is that true? There seems to be some code in do_editor
  751. @@ -986,7 +993,16 @@
  752. xmalloc (sizeof (struct logfile_info)));
  753. li->type = status;
  754. li->tag = xstrdup (vers->tag);
  755. +#ifdef RSE_PATCH_READDNEW
  756. + /* If the file was re-added, we want the revision in the commitlog
  757. + to be NONE, not the previous dead revision. */
  758. + li->rev_old = status == T_ADDED ? NULL : xstrdup (vers->vn_rcs);
  759. +#else
  760. li->rev_old = xstrdup (vers->vn_rcs);
  761. +#endif
  762. +#ifdef RSE_PATCH_EXTRAPERCENT
  763. + li->date = xstrdup (vers->ts_user);
  764. +#endif
  765. li->rev_new = NULL;
  766. p->data = (char *) li;
  767. (void) addnode (ulist, p);
  768. @@ -1230,7 +1246,11 @@
  769. if (use_editor)
  770. do_editor (finfo->update_dir, &saved_message,
  771. finfo->repository, ulist);
  772. +#ifdef RSE_PATCH_VERIFY
  773. + do_verify (&saved_message, finfo->repository);
  774. +#else
  775. do_verify (saved_message, finfo->repository);
  776. +#endif
  777. }
  778. p = findnode (cilist, finfo->file);
  779. @@ -1552,7 +1572,11 @@
  780. got_message = 1;
  781. if (use_editor)
  782. do_editor (update_dir, &saved_message, real_repos, ulist);
  783. +#ifdef RSE_PATCH_VERIFY
  784. + do_verify (&saved_message, real_repos);
  785. +#else
  786. do_verify (saved_message, real_repos);
  787. +#endif
  788. free (real_repos);
  789. return (R_PROCESS);
  790. }
  791. @@ -2296,6 +2320,10 @@
  792. free (li->rev_old);
  793. if (li->rev_new)
  794. free (li->rev_new);
  795. +#ifdef RSE_PATCH_EXTRAPERCENT
  796. + if (li->date)
  797. + free (li->date);
  798. +#endif
  799. free (li);
  800. }
  801. Index: src/create_adm.c
  802. ===================================================================
  803. RCS file: /e/ossp/pkg/tool/cvs/cvs/cvs/src/create_adm.c,v
  804. retrieving revision 1.1.1.4
  805. diff -u -d -u -3 -r1.1.1.4 create_adm.c
  806. --- src/create_adm.c 19 Apr 2001 19:45:32 -0000 1.1.1.4
  807. +++ src/create_adm.c 16 Feb 2002 14:00:14 -0000
  808. @@ -21,6 +21,41 @@
  809. or after which CVS might do something non-useful. If WARN is zero, then
  810. don't print warnings; all errors are fatal then. */
  811. +#ifdef RSE_PATCH_CVSROOT
  812. +static int local_template_cb(char *repository, char *template)
  813. +{
  814. + FILE *fpIN, *fpOUT;
  815. + char buf[1024];
  816. + size_t n;
  817. +
  818. + if ((fpOUT = CVS_FOPEN(CVSADM_TEMPLATE, "w+")) == NULL)
  819. + error(1, errno, "cannot open %s for writing", CVSADM_TEMPLATE);
  820. + if ((fpIN = CVS_FOPEN(template, "r")) == NULL)
  821. + error(1, errno, "cannot open %s for reading", template);
  822. + while (!feof(fpIN)) {
  823. + n = fread(buf, 1, sizeof buf, fpIN);
  824. + if (n == 0) {
  825. + if (ferror(fpIN))
  826. + error(0, errno, "cannot read template file %s", template);
  827. + break;
  828. + }
  829. + fwrite(buf, 1, n, fpOUT);
  830. + }
  831. + fclose(fpIN);
  832. + fclose(fpOUT);
  833. + return 0;
  834. +}
  835. +
  836. +static void local_template(char *update_dir, char *repository)
  837. +{
  838. + cvsroot_type *e;
  839. +
  840. + if ((e = cvsroot_lookup(NULL, NULL, current_parsed_root->original)) != NULL)
  841. + Parse_Info(CVSROOTADM_RCSINFO, repository, local_template_cb, 1);
  842. + return;
  843. +}
  844. +#endif
  845. +
  846. int
  847. Create_Admin (dir, update_dir, repository, tag, date, nonbranch, warn,
  848. dotemplate)
  849. @@ -179,6 +214,20 @@
  850. fprintf (stderr, "%c<- Create_Admin\n",
  851. (server_active) ? 'S' : ' ');
  852. }
  853. +#endif
  854. +#ifdef RSE_PATCH_CVSROOT
  855. + /* Under our "cvs root" feature, checkouts are performed
  856. + locally (from the repository copy and without C/S), but commits
  857. + are performed remotely (to the master repository with C/S).
  858. + Unfortunately, CVS "optimizes" processing and doesn't provide
  859. + CVS/Template files on non-C/S checkouts. This would mean that
  860. + if "cvs root" feature is used, the rcsinfo-configured templates
  861. + are never used. So, if and only if we do a non-C/S checkout (or
  862. + similar operation which creates CVS/Template) _and_ the current
  863. + CVSROOT is known to be a repository copy, we force the creation
  864. + of CVS/Template. */
  865. + if (!server_active && !(current_parsed_root->isremote) && dotemplate)
  866. + local_template(update_dir, repository);
  867. #endif
  868. free (reposcopy);
  869. Index: src/cvs.h
  870. ===================================================================
  871. RCS file: /e/ossp/pkg/tool/cvs/cvs/cvs/src/cvs.h,v
  872. retrieving revision 1.1.1.4
  873. diff -u -d -u -3 -r1.1.1.4 cvs.h
  874. --- src/cvs.h 24 Apr 2001 18:14:53 -0000 1.1.1.4
  875. +++ src/cvs.h 16 Feb 2002 12:36:21 -0000
  876. @@ -187,6 +187,33 @@
  877. #define CVSROOTADM_WRITERS "writers"
  878. #define CVSROOTADM_PASSWD "passwd"
  879. #define CVSROOTADM_CONFIG "config"
  880. +#ifdef RSE_PATCH_ADMININFO
  881. +#define CVSROOTADM_ADMININFO "admininfo"
  882. +#endif
  883. +#ifdef RSE_PATCH_IMPORTINFO
  884. +#define CVSROOTADM_IMPORTINFO "importinfo"
  885. +#endif
  886. +
  887. +#ifdef RSE_PATCH_ALTADMINFILES
  888. +#define CVSROOTADM_MODULES_ALT "conf_modules"
  889. +#define CVSROOTADM_LOGINFO_ALT "hook_logwrite"
  890. +#define CVSROOTADM_RCSINFO_ALT "hook_logtempl"
  891. +#define CVSROOTADM_COMMITINFO_ALT "hook_commit"
  892. +#define CVSROOTADM_TAGINFO_ALT "hook_tag"
  893. +#define CVSROOTADM_EDITINFO_ALT "hook_logedit"
  894. +#define CVSROOTADM_VERIFYMSG_ALT "hook_logverify"
  895. +#define CVSROOTADM_HISTORY_ALT "data_history"
  896. +#define CVSROOTADM_VALTAGS_ALT "data_valtags"
  897. +#define CVSROOTADM_IGNORE_ALT "conf_ignore"
  898. +#define CVSROOTADM_CHECKOUTLIST_ALT "conf_checkout"
  899. +#define CVSROOTADM_WRAPPER_ALT "hook_wrapper"
  900. +#define CVSROOTADM_NOTIFY_ALT "hook_notify"
  901. +#define CVSROOTADM_USERS_ALT "conf_users"
  902. +#define CVSROOTADM_READERS_ALT "conf_readers"
  903. +#define CVSROOTADM_WRITERS_ALT "conf_writers"
  904. +#define CVSROOTADM_PASSWD_ALT "conf_passwd"
  905. +#define CVSROOTADM_CONFIG_ALT "conf_global"
  906. +#endif
  907. #define CVSNULLREPOS "Emptydir" /* an empty directory */
  908. @@ -273,6 +300,10 @@
  909. #define CVSUMASK_ENV "CVSUMASK" /* Effective umask for repository */
  910. /* #define CVSUMASK_DFLT Set by options.h */
  911. +#ifdef RSE_PATCH_NOLOCK
  912. +#define CVSNOLOCK_ENV "CVSNOLOCK" /* do not create lock files */
  913. +#endif
  914. +
  915. /*
  916. * If the beginning of the Repository matches the following string, strip it
  917. * so that the output to the logfile does not contain a full pathname.
  918. @@ -363,6 +394,9 @@
  919. extern int use_editor;
  920. extern int cvswrite;
  921. extern mode_t cvsumask;
  922. +#ifdef RSE_PATCH_LOCALID
  923. +extern char *RCS_citag;
  924. +#endif
  925. /* Access method specified in CVSroot. */
  926. typedef enum {
  927. @@ -400,6 +434,9 @@
  928. extern int trace; /* Show all commands */
  929. extern int noexec; /* Don't modify disk anywhere */
  930. +#ifdef RSE_PATCH_NOLOCK
  931. +extern int nolock; /* Don't create locks */
  932. +#endif
  933. extern int logoff; /* Don't write history entry */
  934. extern int top_level_admin;
  935. @@ -467,6 +504,27 @@
  936. void root_allow_free PROTO ((void));
  937. int root_allow_ok PROTO ((char *));
  938. +#ifdef RSE_PATCH_MAPROOT
  939. +void root_map_add PROTO ((char *, char *));
  940. +void root_map_free PROTO ((void));
  941. +int root_map_it PROTO ((char *, char **, int));
  942. +#endif
  943. +
  944. +#ifdef RSE_PATCH_CVSROOT
  945. +typedef struct {
  946. + char *nickname;
  947. + char *masterpath;
  948. + char *slavepath;
  949. + char *syncprog;
  950. +} cvsroot_type;
  951. +char *cvsroot_filename(void);
  952. +void cvsroot_free(cvsroot_type *);
  953. +cvsroot_type *cvsroot_entry_read(FILE *);
  954. +void cvsroot_entry_write(FILE *, cvsroot_type *);
  955. +cvsroot_type *cvsroot_lookup(char *, char *, char *);
  956. +void cvsroot_synchronize(cvsroot_type *, int);
  957. +#endif
  958. +
  959. char *gca PROTO((const char *rev1, const char *rev2));
  960. extern void check_numeric PROTO ((const char *, int, char **));
  961. char *getcaller PROTO((void));
  962. @@ -570,6 +628,10 @@
  963. extern void expand_wild PROTO ((int argc, char **argv,
  964. int *pargc, char ***pargv));
  965. +#ifdef RSE_PATCH_HANDLE
  966. +int handle2dates(char *, time_t *, time_t *);
  967. +#endif
  968. +
  969. #ifdef SERVER_SUPPORT
  970. extern int cvs_casecmp PROTO ((char *, char *));
  971. extern int fopen_case PROTO ((char *, char *, FILE **, char **));
  972. @@ -589,7 +651,11 @@
  973. void do_editor PROTO((char *dir, char **messagep,
  974. char *repository, List * changes));
  975. +#ifdef RSE_PATCH_VERIFY
  976. +void do_verify PROTO((char **messagep, char *repository));
  977. +#else
  978. void do_verify PROTO((char *message, char *repository));
  979. +#endif
  980. typedef int (*CALLBACKPROC) PROTO((int argc, char *argv[], char *where,
  981. char *mwhere, char *mfile, int shorten, int local_specified,
  982. @@ -812,6 +878,9 @@
  983. NULL for add or import */
  984. char *rev_new; /* rev number after a commit/modify,
  985. add, or import, NULL for remove */
  986. +#ifdef RSE_PATCH_EXTRAPERCENT
  987. + char *date;
  988. +#endif
  989. };
  990. /* Wrappers. */
  991. @@ -851,6 +920,13 @@
  992. int unedit PROTO ((int argc, char **argv));
  993. int editors PROTO ((int argc, char **argv));
  994. int watchers PROTO ((int argc, char **argv));
  995. +#ifdef RSE_PATCH_CVSROOT
  996. +int root PROTO ((int argc, char **argv));
  997. +#endif
  998. +#ifdef RSE_PATCH_PSERVERD
  999. +int pserverd PROTO ((int argc, char **argv));
  1000. +int pserver_daemon PROTO ((int argc, char **argv));
  1001. +#endif
  1002. extern int annotate PROTO ((int argc, char **argv));
  1003. extern int add PROTO ((int argc, char **argv));
  1004. extern int admin PROTO ((int argc, char **argv));
  1005. @@ -871,6 +947,9 @@
  1006. extern int cvsstatus PROTO((int argc, char **argv));
  1007. extern int cvstag PROTO((int argc, char **argv));
  1008. extern int version PROTO((int argc, char **argv));
  1009. +#ifdef RSE_PATCH_RLIST
  1010. +extern int cvslist PROTO((int argc, char **argv));
  1011. +#endif
  1012. extern unsigned long int lookup_command_attribute PROTO((char *));
  1013. Index: src/cvsrc.c
  1014. ===================================================================
  1015. RCS file: /e/ossp/pkg/tool/cvs/cvs/cvs/src/cvsrc.c,v
  1016. retrieving revision 1.1.1.2
  1017. diff -u -d -u -3 -r1.1.1.2 cvsrc.c
  1018. --- src/cvsrc.c 23 Dec 1998 15:15:00 -0000 1.1.1.2
  1019. +++ src/cvsrc.c 16 Feb 2002 12:36:09 -0000
  1020. @@ -12,6 +12,203 @@
  1021. #include "cvs.h"
  1022. #include "getline.h"
  1023. +#ifdef RSE_PATCH_CVSRC
  1024. +
  1025. +#include <ctype.h>
  1026. +#include <string.h>
  1027. +
  1028. +static char *strq_start = NULL;
  1029. +
  1030. +static char *
  1031. +strqtok_cchar(
  1032. + register char *s,
  1033. + register char *c,
  1034. + int *backslashed)
  1035. +{
  1036. + register char ch;
  1037. +
  1038. + if ((*backslashed = (*s == '\\'))) {
  1039. + switch (*++s) {
  1040. + case 'a':
  1041. + *c = '\a';
  1042. + break;
  1043. + case 'b':
  1044. + *c = '\b';
  1045. + break;
  1046. + case 'f':
  1047. + *c = '\f';
  1048. + break;
  1049. + case 'n':
  1050. + *c = '\n';
  1051. + break;
  1052. + case 'r':
  1053. + *c = '\r';
  1054. + break;
  1055. + case 't':
  1056. + *c = '\t';
  1057. + break;
  1058. + case 'v':
  1059. + *c = '\v';
  1060. + break;
  1061. + case '\\':
  1062. + *c = '\\';
  1063. + break;
  1064. + case '^':
  1065. + *c = '^';
  1066. + break;
  1067. + case '\'':
  1068. + *c = '\'';
  1069. + break;
  1070. + case '"':
  1071. + *c = '"';
  1072. + break;
  1073. + case '?':
  1074. + *c = '?';
  1075. + break;
  1076. + case '0':
  1077. + case '1':
  1078. + case '2':
  1079. + case '3':
  1080. + case '4':
  1081. + case '5':
  1082. + case '6':
  1083. + case '7':
  1084. + ch = 0;
  1085. + if (isdigit(*s) && *s != '8' && *s != '9') {
  1086. + ch = *s++ - '0';
  1087. + if (isdigit(*s) && *s != '8' && *s != '9') {
  1088. + ch <<= 3;
  1089. + ch |= *s++ - '0';
  1090. + if (isdigit(*s) && *s != '8' && *s != '9') {
  1091. + ch <<= 3;
  1092. + ch |= *s++ - '0';
  1093. + }
  1094. + }
  1095. + }
  1096. + s--;
  1097. + *c = ch;
  1098. + break;
  1099. + case 'x':
  1100. + s++;
  1101. + for (ch = 0; isxdigit(*s); s++) {
  1102. + ch <<= 4;
  1103. + ch |= isdigit(*s) ? *s - '0' :
  1104. + islower(*s) ? *s + 10 - 'a' : *s + 10 - 'A';
  1105. + }
  1106. + s--;
  1107. + *c = ch;
  1108. + break;
  1109. + default:
  1110. + *c = *s;
  1111. + break;
  1112. + }
  1113. + } else
  1114. + *c = *s;
  1115. + return (*s) ? s+1 : NULL;
  1116. +}
  1117. +
  1118. +static char *
  1119. +strqtok(
  1120. + char *s, /* String to tokenize. NULL to continue same str */
  1121. + char *delim, /* Token delimiters. Can be changed w/ each call. */
  1122. + char *quotemarks, /* Quotation marks. Can be changed w/ each call. */
  1123. + char *commentchars, /* Comment characters. Can be changed w/ each call. */
  1124. + unsigned int flags) /* flags&01 -> strip quotes;
  1125. + * flags&02 -> enable backslash escapes;
  1126. + * flags&04 -> skip all delims before return;
  1127. + */
  1128. +{
  1129. + register char *p, *q;
  1130. + char c;
  1131. + char leftquote = 0;
  1132. + char *token;
  1133. + int backslashed, inquote, intok;
  1134. +
  1135. + int stripquote = flags & 01; /* strip quotemarks from tokens */
  1136. + int backslash = flags & 02; /* backslash sequences */
  1137. + int skipdelim = flags & 04; /* skip seq of delims at end of token */
  1138. +
  1139. + /* New string? */
  1140. + if (s)
  1141. + strq_start = s;
  1142. + if (!strq_start)
  1143. + return NULL;
  1144. +
  1145. + /* Skip leading delimiters */
  1146. + for (p=strq_start; *p && strchr(delim, *p); p++)
  1147. + ;
  1148. + if (!(*p) || strchr(commentchars, *p))
  1149. + return NULL;
  1150. +
  1151. + /* Set `token' to point to returned string.
  1152. + * Use p and q to walk through the user's string:
  1153. + * p will follow input characters;
  1154. + * q will overwrite w/ outputted characters, minus possibly-stripped
  1155. + * quotes and including nulls after each token.
  1156. + */
  1157. + token = q = p;
  1158. + inquote = 0;
  1159. + intok = 1;
  1160. + if (backslash) {
  1161. + while (intok && (p = strqtok_cchar(p, &c, &backslashed))) {
  1162. + if (backslashed) {
  1163. + *q++ = c; /* treat as plain character */
  1164. + } else if (!inquote && *delim && strchr(delim, c)) {
  1165. + *q = '\0'; /* Reached end of token */
  1166. + intok = 0;
  1167. + } else if (!inquote && *commentchars && strchr(commentchars, c)) {
  1168. + *q = '\0'; /* Reached end of token */
  1169. + *p = '\0'; /* make it act like end of string */
  1170. + intok = 0;
  1171. + } else if (!inquote && *quotemarks && strchr(quotemarks, c)) {
  1172. + inquote = 1; /* Beginning a quoted segment */
  1173. + leftquote = c; /* Save quote char for matching with */
  1174. + if (!stripquote) *q++ = c;
  1175. + } else if (inquote && leftquote == c) {
  1176. + inquote = 0; /* Ending a quoted segment */
  1177. + if (!stripquote) *q++ = c;
  1178. + } else {
  1179. + *q++ = c; /* Ordinary character */
  1180. + }
  1181. + }
  1182. + strq_start = p; /* Where to start next search */
  1183. + *q = '\0';
  1184. + } else {
  1185. + while (intok && *p) {
  1186. + if (!inquote && *delim && strchr(delim, *p)) {
  1187. + *q = '\0'; /* Reached end of token */
  1188. + p++; /* advance p for next token */
  1189. + intok = 0;
  1190. + } else if (!inquote && *commentchars && strchr(commentchars, *p)) {
  1191. + *q = '\0'; /* Reached end of token */
  1192. + *p = '\0'; /* make it act like end of string */
  1193. + intok = 0;
  1194. + } else if (!inquote && *quotemarks && strchr(quotemarks, *p)) {
  1195. + inquote = 1; /* Beginning a quoted segment */
  1196. + leftquote = *p++; /* Save quote char for matching with */
  1197. + if (!stripquote) *q++ = leftquote;
  1198. + } else if (inquote && leftquote == *p) {
  1199. + inquote = 0; /* Ending a quoted segment */
  1200. + p++;
  1201. + if (!stripquote) *q++ = leftquote;
  1202. + } else {
  1203. + *q++ = *p++;
  1204. + }
  1205. + }
  1206. + strq_start = p; /* Where to start next search */
  1207. + *q = '\0';
  1208. + }
  1209. +
  1210. + if (skipdelim && strq_start) {
  1211. + /* Skip trailing delimiters */
  1212. + while (*strq_start && strchr(delim, *strq_start))
  1213. + strq_start++;
  1214. + }
  1215. + return token;
  1216. +}
  1217. +
  1218. +#endif
  1219. +
  1220. /* this file is to be found in the user's home directory */
  1221. #ifndef CVSRC_FILENAME
  1222. @@ -23,9 +220,68 @@
  1223. extern char *strtok ();
  1224. +#ifdef RSE_PATCH_CVSRC
  1225. +static void read_cvsrc_parentdirs ();
  1226. +static void read_cvsrc_file ();
  1227. +#endif
  1228. +
  1229. /* Read cvsrc, processing options matching CMDNAME ("cvs" for global
  1230. options, and update *ARGC and *ARGV accordingly. */
  1231. +#ifdef RSE_PATCH_CVSRC
  1232. +void
  1233. +read_cvsrc (argc, argv, cmdname)
  1234. + int *argc;
  1235. + char ***argv;
  1236. + char *cmdname;
  1237. +{
  1238. + /* try to read .cvsrc files from parent directories */
  1239. + read_cvsrc_parentdirs(argc, argv, cmdname);
  1240. +
  1241. + /* try to read .cvsrc file from home directory */
  1242. + read_cvsrc_file(argc, argv, cmdname, get_homedir());
  1243. +
  1244. + return;
  1245. +}
  1246. +
  1247. +/* read .cvsrc files from all parent directories (including the current dir) */
  1248. +static void
  1249. +read_cvsrc_parentdirs (argc, argv, cmdname)
  1250. + int *argc;
  1251. + char ***argv;
  1252. + char *cmdname;
  1253. +{
  1254. + char cwd[PATH_MAX];
  1255. + char *cp;
  1256. + int l;
  1257. +
  1258. + if (getcwd(cwd, sizeof(cwd)) == NULL)
  1259. + return;
  1260. + if ((l = strlen(cwd)) <= 0)
  1261. + return;
  1262. + if (cwd[l-1] != '/') {
  1263. + cwd[l++] = '/';
  1264. + cwd[l++] = '\0';
  1265. + }
  1266. + while (cwd[0] != '\0') {
  1267. + cwd[strlen(cwd)-1] = '\0';
  1268. + read_cvsrc_file(argc, argv, cmdname, cwd);
  1269. + if ((cp = strrchr(cwd, '/')) == NULL)
  1270. + break;
  1271. + *(cp+1) = '\0';
  1272. + }
  1273. + return;
  1274. +}
  1275. +
  1276. +/* read .cvsrc file from a particular directory */
  1277. +static void
  1278. +read_cvsrc_file (argc, argv, cmdname, homedir)
  1279. + int *argc;
  1280. + char ***argv;
  1281. + char *cmdname;
  1282. + char *homedir;
  1283. +{
  1284. +#else
  1285. void
  1286. read_cvsrc (argc, argv, cmdname)
  1287. int *argc;
  1288. @@ -33,6 +289,7 @@
  1289. char *cmdname;
  1290. {
  1291. char *homedir;
  1292. +#endif
  1293. char *homeinit;
  1294. FILE *cvsrcfile;
  1295. @@ -64,7 +321,9 @@
  1296. /* determine filename for ~/.cvsrc */
  1297. +#ifndef RSE_PATCH_CVSRC
  1298. homedir = get_homedir ();
  1299. +#endif
  1300. /* If we can't find a home directory, ignore ~/.cvsrc. This may
  1301. make tracking down problems a bit of a pain, but on the other
  1302. hand it might be obnoxious to complain when CVS will function
  1303. @@ -123,9 +382,15 @@
  1304. if (found)
  1305. {
  1306. /* skip over command in the options line */
  1307. +#ifdef RSE_PATCH_CVSRC
  1308. + for (optstart = strqtok (line + command_len, "\t \n", "\"'", "", 7);
  1309. + optstart;
  1310. + optstart = strqtok (NULL, "\t \n", "\"'", "", 7))
  1311. +#else
  1312. for (optstart = strtok (line + command_len, "\t \n");
  1313. optstart;
  1314. optstart = strtok (NULL, "\t \n"))
  1315. +#endif
  1316. {
  1317. new_argv [new_argc++] = xstrdup (optstart);
  1318. Index: src/diff.c
  1319. ===================================================================
  1320. RCS file: /e/ossp/pkg/tool/cvs/cvs/cvs/src/diff.c,v
  1321. retrieving revision 1.1.1.3
  1322. diff -u -d -u -3 -r1.1.1.3 diff.c
  1323. --- src/diff.c 24 Apr 2001 18:14:53 -0000 1.1.1.3
  1324. +++ src/diff.c 16 Feb 2002 12:36:09 -0000
  1325. @@ -77,7 +77,11 @@
  1326. "\t-r rev2\tDiff rev1/date1 against rev2.\n",
  1327. "\t--ifdef=arg\tOutput diffs in ifdef format.\n",
  1328. "(consult the documentation for your diff program for rcsdiff-options.\n",
  1329. +#ifdef RSE_PATCH_COSMETICS
  1330. + "The most popular is -c for context diffs and -u for unified diffs).\n",
  1331. +#else
  1332. "The most popular is -c for context diffs but there are many more).\n",
  1333. +#endif
  1334. "(Specify the --help global option for a list of other help options)\n",
  1335. NULL
  1336. };
  1337. @@ -224,13 +228,21 @@
  1338. optind = 0;
  1339. while ((c = getopt_long (argc, argv,
  1340. +#if defined(RSE_PATCH_HANDLE)
  1341. + "+abcdefh:ilnpstuwy0123456789BHNRTC:D:F:I:L:U:V:W:k:r:",
  1342. +#else
  1343. "+abcdefhilnpstuwy0123456789BHNRTC:D:F:I:L:U:V:W:k:r:",
  1344. +#endif
  1345. longopts, &option_index)) != -1)
  1346. {
  1347. switch (c)
  1348. {
  1349. case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
  1350. +#if defined(RSE_PATCH_HANDLE)
  1351. + case 'i': case 'n': case 'p': case 's': case 't':
  1352. +#else
  1353. case 'h': case 'i': case 'n': case 'p': case 's': case 't':
  1354. +#endif
  1355. case 'u': case 'w': case 'y':
  1356. case '0': case '1': case '2': case '3': case '4': case '5':
  1357. case '6': case '7': case '8': case '9':
  1358. @@ -302,6 +314,17 @@
  1359. else
  1360. diff_date1 = Make_Date (optarg);
  1361. break;
  1362. +#ifdef RSE_PATCH_HANDLE
  1363. + case 'h': {
  1364. + time_t t1, t2;
  1365. + if (!handle2dates(optarg, &t1, &t2))
  1366. + error (1, 0, "invalid handle string");
  1367. + t1 -= 1; /* subtract one second to have a real difference */
  1368. + diff_date1 = date_from_time_t(t1);
  1369. + diff_date2 = date_from_time_t(t2);
  1370. + break;
  1371. + }
  1372. +#endif
  1373. case 'N':
  1374. empty_files = 1;
  1375. break;
  1376. @@ -436,8 +459,16 @@
  1377. char *head =
  1378. (vers->vn_rcs == NULL
  1379. ? NULL
  1380. +#ifdef RSE_PATCH_DIFFHEAD
  1381. + : RCS_head (vers->srcfile));
  1382. +#else
  1383. : RCS_branch_head (vers->srcfile, vers->vn_rcs));
  1384. +#endif
  1385. +#ifdef RSE_PATCH_DEADAWARE
  1386. + exists = (head != NULL && !RCS_isdead(vers->srcfile, head));
  1387. +#else
  1388. exists = head != NULL;
  1389. +#endif
  1390. if (head != NULL)
  1391. free (head);
  1392. }
  1393. @@ -447,7 +478,12 @@
  1394. xvers = Version_TS (finfo, NULL, diff_rev1, diff_date1,
  1395. 1, 0);
  1396. +#ifdef RSE_PATCH_DEADAWARE
  1397. + exists = (xvers->vn_rcs != NULL &&
  1398. + !RCS_isdead(xvers->srcfile, xvers->vn_rcs));
  1399. +#else
  1400. exists = xvers->vn_rcs != NULL;
  1401. +#endif
  1402. freevers_ts (&xvers);
  1403. }
  1404. if (exists)
  1405. @@ -840,7 +876,11 @@
  1406. if (diff_rev1 && strcmp (diff_rev1, TAG_HEAD) == 0)
  1407. use_rev1 = ((vers->vn_rcs == NULL || vers->srcfile == NULL)
  1408. ? NULL
  1409. +#ifdef RSE_PATCH_DIFFHEAD
  1410. + : RCS_head (vers->srcfile));
  1411. +#else
  1412. : RCS_branch_head (vers->srcfile, vers->vn_rcs));
  1413. +#endif
  1414. else
  1415. {
  1416. xvers = Version_TS (finfo, NULL, diff_rev1, diff_date1, 1, 0);
  1417. @@ -855,7 +895,11 @@
  1418. if (diff_rev2 && strcmp (diff_rev2, TAG_HEAD) == 0)
  1419. use_rev2 = ((vers->vn_rcs == NULL || vers->srcfile == NULL)
  1420. ? NULL
  1421. +#ifdef RSE_PATCH_DIFFHEAD
  1422. + : RCS_head (vers->srcfile));
  1423. +#else
  1424. : RCS_branch_head (vers->srcfile, vers->vn_rcs));
  1425. +#endif
  1426. else
  1427. {
  1428. xvers = Version_TS (finfo, NULL, diff_rev2, diff_date2, 1, 0);
  1429. Index: src/hash.c
  1430. ===================================================================
  1431. RCS file: /e/ossp/pkg/tool/cvs/cvs/cvs/src/hash.c,v
  1432. retrieving revision 1.1.1.3
  1433. diff -u -d -u -3 -r1.1.1.3 hash.c
  1434. --- src/hash.c 19 Sep 2000 00:06:35 -0000 1.1.1.3
  1435. +++ src/hash.c 16 Feb 2002 12:36:09 -0000
  1436. @@ -25,17 +25,25 @@
  1437. const char *key;
  1438. {
  1439. unsigned int h = 0;
  1440. +#ifndef RSE_PATCH_HASHFUNC
  1441. unsigned int g;
  1442. +#endif
  1443. assert(key != NULL);
  1444. while (*key != 0)
  1445. {
  1446. +#ifdef RSE_PATCH_HASHFUNC
  1447. + /* D.J. Bernstein's popular times 33 function
  1448. + (fast and distributes very well) */
  1449. + h = ((h << 5) + h) + FOLD_FN_CHAR(*key++);
  1450. +#else
  1451. unsigned int c = *key++;
  1452. /* The FOLD_FN_CHAR is so that findnode_fn works. */
  1453. h = (h << 4) + FOLD_FN_CHAR (c);
  1454. if ((g = h & 0xf0000000) != 0)
  1455. h = (h ^ (g >> 24)) ^ g;
  1456. +#endif
  1457. }
  1458. return (h % HASHSIZE);
  1459. Index: src/history.c
  1460. ===================================================================
  1461. RCS file: /e/ossp/pkg/tool/cvs/cvs/cvs/src/history.c,v
  1462. retrieving revision 1.1.1.4
  1463. diff -u -d -u -3 -r1.1.1.4 history.c
  1464. --- src/history.c 19 Apr 2001 19:45:32 -0000 1.1.1.4
  1465. +++ src/history.c 16 Feb 2002 12:36:09 -0000
  1466. @@ -235,6 +235,9 @@
  1467. static char *tz_name = "+0000";
  1468. char *logHistory = ALL_REC_TYPES;
  1469. +#ifdef RSE_PATCH_HISTORYFILE
  1470. +char *history_file = NULL;
  1471. +#endif
  1472. /* -r, -t, or -b options, malloc'd. These are "" if the option in
  1473. question is not specified or is overridden by another option. The
  1474. @@ -668,6 +671,10 @@
  1475. if (histfile)
  1476. fname = xstrdup (histfile);
  1477. +#ifdef RSE_PATCH_HISTORYFILE
  1478. + else if (history_file)
  1479. + fname = xstrdup (history_file);
  1480. +#endif
  1481. else
  1482. {
  1483. fname = xmalloc (strlen (current_parsed_root->directory) + sizeof (CVSROOTADM)
  1484. @@ -716,10 +723,18 @@
  1485. return;
  1486. if ( strchr(logHistory, type) == NULL )
  1487. return;
  1488. +#ifdef RSE_PATCH_HISTORYFILE
  1489. + if (history_file != NULL)
  1490. + fname = xstrdup (history_file);
  1491. + else {
  1492. +#endif
  1493. fname = xmalloc (strlen (current_parsed_root->directory) + sizeof (CVSROOTADM)
  1494. + sizeof (CVSROOTADM_HISTORY) + 3);
  1495. (void) sprintf (fname, "%s/%s/%s", current_parsed_root->directory,
  1496. CVSROOTADM, CVSROOTADM_HISTORY);
  1497. +#ifdef RSE_PATCH_HISTORYFILE
  1498. + }
  1499. +#endif
  1500. /* turn off history logging if the history file does not exist */
  1501. if (!isfile (fname))
  1502. @@ -731,7 +746,11 @@
  1503. if (trace)
  1504. fprintf (stderr, "%s-> fopen(%s,a)\n",
  1505. CLIENT_SERVER_STR, fname);
  1506. +#ifdef RSE_PATCH_NOLOCK
  1507. + if (nolock)
  1508. +#else
  1509. if (noexec)
  1510. +#endif
  1511. goto out;
  1512. fd = CVS_OPEN (fname, O_WRONLY | O_APPEND | O_CREAT | OPEN_BINARY, 0666);
  1513. if (fd < 0)
  1514. Index: src/import.c
  1515. ===================================================================
  1516. RCS file: /e/ossp/pkg/tool/cvs/cvs/cvs/src/import.c,v
  1517. retrieving revision 1.1.1.4
  1518. diff -u -d -u -3 -r1.1.1.4 import.c
  1519. --- src/import.c 19 Apr 2001 19:45:32 -0000 1.1.1.4
  1520. +++ src/import.c 16 Feb 2002 12:36:09 -0000
  1521. @@ -57,6 +57,140 @@
  1522. NULL
  1523. };
  1524. +#ifdef RSE_PATCH_IMPORTINFO
  1525. +
  1526. +static char *importinfo_vtag;
  1527. +
  1528. +static int
  1529. +importinfo_descend(thisdir)
  1530. + char *thisdir;
  1531. +{
  1532. + DIR *dirp;
  1533. + struct dirent *dp;
  1534. + int err = 0;
  1535. + List *dirlist = NULL;
  1536. +
  1537. + if ((dirp = CVS_OPENDIR(thisdir)) == NULL) {
  1538. + error(0, errno, "cannot open directory");
  1539. + err++;
  1540. + }
  1541. + else {
  1542. + errno = 0;
  1543. + while ((dp = readdir(dirp)) != NULL) {
  1544. + if (strcmp(dp->d_name, ".") == 0 || strcmp(dp->d_name, "..") == 0)
  1545. + goto one_more_time_boys;
  1546. + if (strcmp(dp->d_name, CVSADM) == 0)
  1547. + goto one_more_time_boys;
  1548. + if (ign_name(dp->d_name))
  1549. + goto one_more_time_boys;
  1550. + if (
  1551. +#ifdef DT_DIR
  1552. + (dp->d_type == DT_DIR || (dp->d_type == DT_UNKNOWN && isdir (dp->d_name)))
  1553. +#else
  1554. + isdir (dp->d_name)
  1555. +#endif
  1556. + && !wrap_name_has(dp->d_name, WRAP_TOCVS)
  1557. + ) {
  1558. + Node *n;
  1559. + if (dirlist == NULL)
  1560. + dirlist = getlist();
  1561. + n = getnode();
  1562. + n->key = xstrdup(dp->d_name);
  1563. + addnode(dirlist, n);
  1564. + }
  1565. + else if (
  1566. +#ifdef DT_DIR
  1567. + dp->d_type == DT_LNK || (dp->d_type == DT_UNKNOWN && islink (dp->d_name))
  1568. +#else
  1569. + islink (dp->d_name)
  1570. +#endif
  1571. + ) {
  1572. + err++;
  1573. + }
  1574. + else {
  1575. + if (strcmp(thisdir, ".") == 0) {
  1576. + run_arg(dp->d_name);
  1577. + }
  1578. + else {
  1579. + char *p;
  1580. + p = xmalloc(strlen(thisdir)+1+strlen(dp->d_name)+1);
  1581. + (void)sprintf(p, "%s/%s", thisdir, dp->d_name);
  1582. + run_arg(p);
  1583. + free(p);
  1584. + }
  1585. + }
  1586. + one_more_time_boys:
  1587. + errno = 0;
  1588. + }
  1589. + if (errno != 0) {
  1590. + error(0, errno, "cannot read directory");
  1591. + err++;
  1592. + }
  1593. + (void)closedir(dirp);
  1594. + }
  1595. + if (dirlist != NULL) {
  1596. + Node *head, *p;
  1597. + head = dirlist->list;
  1598. + for (p = head->next; p != head; p = p->next) {
  1599. + if (strcmp(thisdir, ".") == 0) {
  1600. + err += importinfo_descend(p->key);
  1601. + }
  1602. + else {
  1603. + char *nextdir;
  1604. + nextdir = xmalloc(strlen(thisdir)+1+strlen(p->key)+1);
  1605. + (void)sprintf(nextdir, "%s/%s", thisdir, p->key);
  1606. + err += importinfo_descend(nextdir);
  1607. + free(nextdir);
  1608. + }
  1609. + }
  1610. + dellist(&dirlist);
  1611. + }
  1612. + return err;
  1613. +}
  1614. +
  1615. +/* importinfo configuration entry callback */
  1616. +static int
  1617. +importinfo_runproc(repository, filter)
  1618. + char *repository;
  1619. + char *filter;
  1620. +{
  1621. + char *s, *cp;
  1622. + int rv;
  1623. +
  1624. + /* if possible, do an own check to make sure that filter really exists */
  1625. + if (filter[0] == '/') {
  1626. + s = xstrdup(filter);
  1627. + for (cp = s; *cp; cp++) {
  1628. + if (isspace((unsigned char)*cp)) {
  1629. + *cp = '\0';
  1630. + break;
  1631. + }
  1632. + }
  1633. + if (!isfile(s)) {
  1634. + error (0, errno, "cannot find pre-admin filter '%s'", s);
  1635. + free(s);
  1636. + return (1);
  1637. + }
  1638. + free(s);
  1639. + }
  1640. +
  1641. + /* construct the filter command */
  1642. + run_setup(filter);
  1643. + run_arg(importinfo_vtag);
  1644. + run_arg(repository);
  1645. + ign_add_file(CVSDOTIGNORE, 1);
  1646. + wrap_add_file(CVSDOTWRAPPER, 1);
  1647. + rv = importinfo_descend(".");
  1648. + if (rv > 0)
  1649. + return rv;
  1650. +
  1651. + /* execute the filter command */
  1652. + rv = run_exec(RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL);
  1653. +
  1654. + return rv;
  1655. +}
  1656. +#endif
  1657. +
  1658. int
  1659. import (argc, argv)
  1660. int argc;
  1661. @@ -221,7 +355,11 @@
  1662. do_editor ((char *) NULL, &message, repository,
  1663. (List *) NULL);
  1664. }
  1665. +#ifdef RSE_PATCH_VERIFY
  1666. + do_verify (&message, repository);
  1667. +#else
  1668. do_verify (message, repository);
  1669. +#endif
  1670. msglen = message == NULL ? 0 : strlen (message);
  1671. if (msglen == 0 || message[msglen - 1] != '\n')
  1672. {
  1673. @@ -283,6 +421,12 @@
  1674. error (1, 0, "attempt to import the repository");
  1675. }
  1676. +#ifdef RSE_PATCH_IMPORTINFO
  1677. + importinfo_vtag = argv[1];
  1678. + if (Parse_Info(CVSROOTADM_IMPORTINFO, argv[0], importinfo_runproc, 1) > 0)
  1679. + error(1, 0, "Pre-import check failed");
  1680. +#endif
  1681. +
  1682. /*
  1683. * Make all newly created directories writable. Should really use a more
  1684. * sophisticated security mechanism here.
  1685. @@ -323,7 +467,11 @@
  1686. "Use the following command to help the merge:");
  1687. cvs_output_tagged ("newline", NULL);
  1688. cvs_output_tagged ("newline", NULL);
  1689. +#ifdef RSE_PATCH_COSMETICS
  1690. + cvs_output_tagged ("text", " ");
  1691. +#else
  1692. cvs_output_tagged ("text", "\t");
  1693. +#endif
  1694. cvs_output_tagged ("text", program_name);
  1695. if (CVSroot_cmdline != NULL)
  1696. {
  1697. @@ -353,7 +501,11 @@
  1698. conflicts);
  1699. (void) fprintf (logfp,
  1700. "Use the following command to help the merge:\n\n");
  1701. +#ifdef RSE_PATCH_COSMETICS
  1702. + (void) fprintf (logfp, " %s checkout ", program_name);
  1703. +#else
  1704. (void) fprintf (logfp, "\t%s checkout ", program_name);
  1705. +#endif
  1706. (void) fprintf (logfp, "-j%s:yesterday -j%s %s\n\n",
  1707. argv[1], argv[1], argv[0]);
  1708. }
  1709. @@ -376,6 +528,9 @@
  1710. li->type = T_TITLE;
  1711. li->tag = xstrdup (vbranch);
  1712. li->rev_old = li->rev_new = NULL;
  1713. +#ifdef RSE_PATCH_EXTRAPERCENT
  1714. + li->date = NULL;
  1715. +#endif
  1716. p->data = (char *) li;
  1717. (void) addnode (ulist, p);
  1718. Update_Logfile (repository, message, logfp, ulist);
  1719. @@ -663,7 +818,11 @@
  1720. */
  1721. if (add_tags (vers->srcfile, vfile, vtag, targc, targv))
  1722. retval = 1;
  1723. +#ifdef RSE_PATCH_IMPORTTOUCH
  1724. + add_log ('T', vfile);
  1725. +#else
  1726. add_log ('U', vfile);
  1727. +#endif
  1728. freevers_ts (&vers);
  1729. return (retval);
  1730. }
  1731. Index: src/list.c
  1732. ===================================================================
  1733. RCS file: src/list.c
  1734. diff -N src/list.c
  1735. --- /dev/null 1 Jan 1970 00:00:00 -0000
  1736. +++ src/list.c 16 Feb 2002 12:36:09 -0000
  1737. @@ -0,0 +1,282 @@
  1738. +/*
  1739. + * Copyright (c) 1998, Dan Rich <drich@employees.com>
  1740. + *
  1741. + * You may distribute under the terms of the GNU General Public License as
  1742. + * specified in the README file that comes with the CVS source distribution.
  1743. + *
  1744. + * List Directory
  1745. + */
  1746. +
  1747. +#ifdef RSE_PATCH_RLIST
  1748. +
  1749. +#include <time.h>
  1750. +#include <pwd.h>
  1751. +#include <grp.h>
  1752. +
  1753. +#if 0
  1754. +#include "cvs.h"
  1755. +#endif
  1756. +
  1757. +static int cvslist_fileproc PROTO((void *callerdat, struct file_info * finfo));
  1758. +static Dtype cvslist_dirproc PROTO((void *callerdat, char *dir, char *repos, char *update_dir, List * entries));
  1759. +static int cvslist_output_dir PROTO((Node * node, void *closure));
  1760. +static int cvslist_output_file PROTO((char *name));
  1761. +static int cvslist_tag_proc PROTO((Node * p, void *closure));
  1762. +
  1763. +static char *numtag;
  1764. +static char *date = NULL;
  1765. +static int force_tag_match = 1;
  1766. +static int local = 0;
  1767. +static int verbose = 0;
  1768. +static int list_attic = 0;
  1769. +static RCSNode *xrcsnode;
  1770. +
  1771. +static const char *const status_usage[] = {
  1772. + "Usage: %s %s [-alRv] [-r tag|-D date] modules\n",
  1773. + "\t-a\tInclude attic files\n",
  1774. + "\t-v\tVerbose format; includes additional information for the file\n",
  1775. + "\t-l\tProcess this directory only (not recursive).\n",
  1776. + "\t-R\tProcess directories recursively.\n",
  1777. + "\t-r rev\tExisting revision/tag.\n",
  1778. + "\t-D\tExisting date.\n",
  1779. + "(Specify the --help global option for a list of other help options)\n",
  1780. + NULL
  1781. +};
  1782. +
  1783. +int cvslist(int argc, char **argv)
  1784. +{
  1785. + int c;
  1786. + int i;
  1787. + int which;
  1788. + int retval;
  1789. +
  1790. + if (argc == -1)
  1791. + usage(status_usage);
  1792. + optind = 0;
  1793. + while ((c = getopt(argc, argv, "+alRr:v")) != -1) {
  1794. + switch (c) {
  1795. + case 'a':
  1796. + list_attic = 1;
  1797. + break;
  1798. + case 'D':
  1799. + if (date)
  1800. + free(date);
  1801. + date = Make_Date(optarg);
  1802. + break;
  1803. + case 'l':
  1804. + local = 1;
  1805. + break;
  1806. + case 'R':
  1807. + local = 0;
  1808. + break;
  1809. + case 'r':
  1810. + numtag = optarg;
  1811. + break;
  1812. + case 'v':
  1813. + verbose = 1;
  1814. + break;
  1815. + case '?':
  1816. + default:
  1817. + usage(status_usage);
  1818. + break;
  1819. + }
  1820. + }
  1821. + argc -= optind;
  1822. + argv += optind;
  1823. +
  1824. + if (date && numtag)
  1825. + error(1, 0, "-r and -D options are mutually exclusive");
  1826. +
  1827. + wrap_setup();
  1828. +#ifdef CLIENT_SUPPORT
  1829. + if (current_parsed_root->isremote) {
  1830. + start_server();
  1831. + ign_setup();
  1832. + if (list_attic)
  1833. + send_arg("-a");
  1834. + if (local)
  1835. + send_arg("-l");
  1836. + if (verbose)
  1837. + send_arg("-v");
  1838. + if (numtag)
  1839. + option_with_arg("-r", numtag);
  1840. + if (date)
  1841. + client_senddate(date);
  1842. +#if 0
  1843. + if (supported_request("expand-modules")) {
  1844. + /* This is done here because we need to read responses from the
  1845. + server before we send the command checkout or export files. */
  1846. + client_expand_modules(argc, argv, local);
  1847. + }
  1848. +#endif
  1849. + /* Send any remaining arguments -- probably dir/file names */
  1850. + for (i = 0; i < argc; ++i)
  1851. + send_arg(argv[i]);
  1852. + send_to_server("list\012", 0); /* Send the command */
  1853. + return get_responses_and_close();
  1854. + }
  1855. +#endif
  1856. +#ifdef SERVER_SUPPORT
  1857. + /* If we're the server, make sure we're starting at the root */
  1858. + if (server_active)
  1859. + CVS_CHDIR(current_parsed_root->directory);
  1860. +#endif
  1861. +
  1862. +#if 0
  1863. + if (numtag != NULL)
  1864. + tag_check_valid(numtag, argc, argv, local, 0, "");
  1865. +#endif
  1866. +
  1867. + which = W_REPOS;
  1868. + if (list_attic)
  1869. + which |= W_ATTIC;
  1870. +
  1871. + /* start the recursion processor */
  1872. + cvs_output_tagged("+list", NULL);
  1873. + retval = start_recursion(cvslist_fileproc, (FILESDONEPROC)NULL,
  1874. + cvslist_dirproc, (DIRLEAVEPROC)NULL, NULL,
  1875. + argc, argv, local, which, 0, 1, (char *)NULL, 1);
  1876. + cvs_output_tagged("-list", NULL);
  1877. +
  1878. + return retval;
  1879. +}
  1880. +
  1881. +/*
  1882. + * Display file info
  1883. + */
  1884. +/* ARGSUSED */
  1885. +static int cvslist_fileproc(callerdat, finfo)
  1886. + void *callerdat;
  1887. + struct file_info *finfo;
  1888. +{
  1889. + char *buf;
  1890. + Vers_TS *vers;
  1891. +
  1892. + /* If a particular revision was specified, only show that one */
  1893. + if (numtag != NULL || date != NULL) {
  1894. + vers = Version_TS(finfo, NULL, NULL, NULL, 0, 0);
  1895. + if (RCS_getversion(vers->srcfile, numtag, date, force_tag_match, NULL) == NULL)
  1896. + return 0;
  1897. + }
  1898. +
  1899. + cvslist_output_file(finfo->fullname);
  1900. +
  1901. + if (verbose) {
  1902. + vers = Version_TS(finfo, NULL, NULL, NULL, 0, 0);
  1903. + if (vers->srcfile) {
  1904. + List *symbols = RCS_symbols(vers->srcfile);
  1905. +
  1906. + cvs_output_tagged("+info", NULL);
  1907. + if (vers->vn_rcs == NULL)
  1908. + cvs_output_tagged("finfo",
  1909. + " Repository revision:\tNo revision control file");
  1910. + else {
  1911. + buf = (char *)malloc(24 + strlen(vers->vn_rcs) + 1 +
  1912. + strlen(vers->srcfile->path) + 1);
  1913. + sprintf(buf, " Repository revision:\t%s\t%s",
  1914. + vers->vn_rcs, vers->srcfile->path);
  1915. + cvs_output_tagged("finfo", buf);
  1916. + }
  1917. + cvs_output_tagged("newline", NULL);
  1918. + cvs_output_tagged("finfo", " Existing Tags:");
  1919. + cvs_output_tagged("newline", NULL);
  1920. + if (symbols) {
  1921. + xrcsnode = finfo->rcs;
  1922. + (void)walklist(symbols, cvslist_tag_proc, NULL);
  1923. + }
  1924. + else
  1925. + cvs_output_tagged("finfo", "\tNo Tags Exist");
  1926. +
  1927. + cvs_output_tagged("-info", NULL);
  1928. + cvs_output_tagged("newline", NULL);
  1929. + }
  1930. + }
  1931. + return 0;
  1932. +}
  1933. +
  1934. +/*
  1935. + * Display directory info
  1936. + */
  1937. +/* ARGSUSED */
  1938. +static Dtype cvslist_dirproc(callerdat, dir, repos, update_dir, entries)
  1939. + void *callerdat;
  1940. + char *dir;
  1941. + char *repos;
  1942. + char *update_dir;
  1943. + List *entries;
  1944. +{
  1945. + char *buf;
  1946. + List *dirs;
  1947. +
  1948. + buf = (char *)malloc(strlen(update_dir) + 2);
  1949. + sprintf(buf, "%s", update_dir);
  1950. + cvs_output_tagged("fname", buf);
  1951. + cvs_output_tagged("newline", NULL);
  1952. + free(buf);
  1953. +
  1954. + if (local) { /* We need to output the current dirs */
  1955. + dirs = Find_Directories(update_dir, W_REPOS, NULL);
  1956. + walklist(dirs, cvslist_output_dir, update_dir);
  1957. + }
  1958. + return R_PROCESS;
  1959. +}
  1960. +
  1961. +static int cvslist_output_dir(node, closure)
  1962. + Node *node;
  1963. + void *closure;
  1964. +{
  1965. + char *buf;
  1966. +
  1967. + buf = (char *)malloc(strlen((char *)closure) + strlen(node->key) + 3);
  1968. + sprintf(buf, "%s/%s/", (char *)closure, node->key);
  1969. + cvs_output_tagged("fname", buf);
  1970. + cvs_output_tagged("newline", NULL);
  1971. + free(buf);
  1972. + return 0;
  1973. +}
  1974. +
  1975. +static int cvslist_output_file(name)
  1976. + char *name;
  1977. +{
  1978. + char *buf;
  1979. + char *nlptr;
  1980. +
  1981. + buf = (char *)malloc(strlen(name) + 1);
  1982. + strncpy(buf, name, strlen(name));
  1983. + *(buf+strlen(name)) = '\0';
  1984. +
  1985. + /* cvs_output_tagged doesn't like \n */
  1986. + if ((nlptr = strchr(buf, '\n')) != NULL)
  1987. + nlptr = '\0';
  1988. + cvs_output_tagged("fname", buf);
  1989. + cvs_output_tagged("newline", NULL);
  1990. + free(buf);
  1991. + return 0;
  1992. +}
  1993. +
  1994. +static int cvslist_tag_proc(p, closure)
  1995. + Node *p;
  1996. + void *closure;
  1997. +{
  1998. + char *branch = NULL;
  1999. + char *buf;
  2000. +
  2001. + if (RCS_nodeisbranch(xrcsnode, p->key))
  2002. + branch = RCS_whatbranch(xrcsnode, p->key);
  2003. +
  2004. + buf = xmalloc(80 + strlen(p->key)
  2005. + + (branch ? strlen(branch) : strlen(p->data)));
  2006. + sprintf(buf, "\t%-25s\t(%s: %s)", p->key,
  2007. + branch ? "branch" : "revision", branch ? branch : p->data);
  2008. + cvs_output_tagged("finfo", buf);
  2009. + cvs_output_tagged("newline", NULL);
  2010. + free(buf);
  2011. +
  2012. + if (branch)
  2013. + free(branch);
  2014. +
  2015. + return (0);
  2016. +}
  2017. +
  2018. +#endif /* RSE_PATCH_RLIST */
  2019. +
  2020. Index: src/lock.c
  2021. ===================================================================
  2022. RCS file: /e/ossp/pkg/tool/cvs/cvs/cvs/src/lock.c,v
  2023. retrieving revision 1.1.1.4
  2024. diff -u -d -u -3 -r1.1.1.4 lock.c
  2025. --- src/lock.c 19 Apr 2001 19:45:32 -0000 1.1.1.4
  2026. +++ src/lock.c 16 Feb 2002 12:36:09 -0000
  2027. @@ -396,7 +396,11 @@
  2028. FILE *fp;
  2029. char *tmp;
  2030. +#ifdef RSE_PATCH_NOLOCK
  2031. + if (nolock)
  2032. +#else
  2033. if (noexec)
  2034. +#endif
  2035. return (0);
  2036. /* we only do one directory at a time for read locks! */
  2037. @@ -468,7 +472,11 @@
  2038. {
  2039. char *wait_repos;
  2040. +#ifdef RSE_PATCH_NOLOCK
  2041. + if (nolock)
  2042. +#else
  2043. if (noexec)
  2044. +#endif
  2045. return (0);
  2046. /* We only know how to do one list at a time */
  2047. Index: src/logmsg.c
  2048. ===================================================================
  2049. RCS file: /e/ossp/pkg/tool/cvs/cvs/cvs/src/logmsg.c,v
  2050. retrieving revision 1.1.1.4
  2051. diff -u -d -u -3 -r1.1.1.4 logmsg.c
  2052. --- src/logmsg.c 24 Apr 2001 18:14:53 -0000 1.1.1.4
  2053. +++ src/logmsg.c 16 Feb 2002 12:36:09 -0000
  2054. @@ -387,14 +387,26 @@
  2055. independant of the running of an editor for getting a message.
  2056. */
  2057. void
  2058. +#ifdef RSE_PATCH_VERIFY
  2059. +do_verify (messagep, repository)
  2060. + char **messagep;
  2061. +#else
  2062. do_verify (message, repository)
  2063. char *message;
  2064. +#endif
  2065. char *repository;
  2066. {
  2067. FILE *fp;
  2068. char *fname;
  2069. int retcode = 0;
  2070. +#ifdef RSE_PATCH_VERIFY
  2071. + char *line;
  2072. + int line_length;
  2073. + size_t line_chars_allocated;
  2074. + char *p;
  2075. + struct stat stbuf;
  2076. +#endif
  2077. #ifdef CLIENT_SUPPORT
  2078. if (current_parsed_root->isremote)
  2079. /* The verification will happen on the server. */
  2080. @@ -408,7 +420,11 @@
  2081. /* If there's no message, then we have nothing to verify. Can this
  2082. case happen? And if so why would we print a message? */
  2083. +#ifdef RSE_PATCH_VERIFY
  2084. + if (*messagep == NULL)
  2085. +#else
  2086. if (message == NULL)
  2087. +#endif
  2088. {
  2089. cvs_output ("No message to verify\n", 0);
  2090. return;
  2091. @@ -421,9 +437,15 @@
  2092. error (1, errno, "cannot create temporary file %s", fname);
  2093. else
  2094. {
  2095. +#ifdef RSE_PATCH_VERIFY
  2096. + fprintf (fp, "%s", *messagep);
  2097. + if ((*messagep)[0] == '\0' ||
  2098. + (*messagep)[strlen (*messagep) - 1] != '\n')
  2099. +#else
  2100. fprintf (fp, "%s", message);
  2101. if ((message)[0] == '\0' ||
  2102. (message)[strlen (message) - 1] != '\n')
  2103. +#endif
  2104. (void) fprintf (fp, "%s", "\n");
  2105. if (fclose (fp) == EOF)
  2106. error (1, errno, "%s", fname);
  2107. @@ -453,6 +475,41 @@
  2108. }
  2109. }
  2110. +#ifdef RSE_PATCH_VERIFY
  2111. + /*
  2112. + * Put the entire message back into the *messagep variable
  2113. + */
  2114. + if ((fp = open_file (fname, "r")) == NULL) {
  2115. + error(1, errno, "cannot open temporary file %s", fname);
  2116. + return;
  2117. + }
  2118. + if (*messagep)
  2119. + free (*messagep);
  2120. + if (CVS_STAT(fname, &stbuf) != 0)
  2121. + error(1, errno, "cannot find size of temp file %s", fname);
  2122. + *messagep = (char *)xmalloc(stbuf.st_size + 1);
  2123. + *messagep[0] = '\0';
  2124. + line = NULL;
  2125. + line_chars_allocated = 0;
  2126. + if (stbuf.st_size > 0) {
  2127. + p = *messagep;
  2128. + while (1) {
  2129. + line_length = getline (&line, &line_chars_allocated, fp);
  2130. + if (line_length == -1) {
  2131. + if (ferror (fp))
  2132. + error (0, errno, "warning: cannot read %s", fname);
  2133. + break;
  2134. + }
  2135. + if (strncmp (line, CVSEDITPREFIX, CVSEDITPREFIXLEN) == 0)
  2136. + continue;
  2137. + (void) strcpy (p, line);
  2138. + p += line_length;
  2139. + }
  2140. + }
  2141. + if (fclose (fp) < 0)
  2142. + error (0, errno, "warning: cannot close %s", fname);
  2143. +#endif
  2144. +
  2145. /* Delete the temp file */
  2146. if (unlink_file (fname) < 0)
  2147. @@ -582,6 +639,42 @@
  2148. {
  2149. switch (*c)
  2150. {
  2151. +#ifdef RSE_PATCH_EXTRAPERCENT
  2152. + case 'o': {
  2153. + char T[2];
  2154. + str_list = xrealloc (str_list, (strlen (str_list) + 1 + 1));
  2155. + switch (li->type) {
  2156. + case T_ADDED: T[0] = 'A'; break;
  2157. + case T_MODIFIED: T[0] = 'M'; break;
  2158. + case T_REMOVED: T[0] = 'R'; break;
  2159. + default: T[0] = '?'; break;
  2160. + }
  2161. + T[1] = '\0';
  2162. + (void) strcat (str_list, T);
  2163. + break;
  2164. + }
  2165. + case 't':
  2166. + str_list =
  2167. + xrealloc (str_list,
  2168. + (strlen (str_list)
  2169. + + (li->tag ? strlen (li->tag) : 0)
  2170. + + 10)
  2171. + );
  2172. + (void) strcat (str_list, (li->tag ? li->tag : ""));
  2173. + break;
  2174. + case 'd': {
  2175. + time_t t;
  2176. + if (li->date != NULL) {
  2177. + t = get_date(li->date, NULL);
  2178. + if (t != ((time_t)-1)) {
  2179. + t += 1; /* re-adjust because of fudge */
  2180. + str_list = xrealloc (str_list, (strlen(str_list)+20));
  2181. + sprintf(str_list+strlen(str_list), "%ld", (long)t);
  2182. + }
  2183. + }
  2184. + break;
  2185. + }
  2186. +#endif
  2187. case 's':
  2188. str_list =
  2189. xrealloc (str_list,
  2190. Index: src/main.c
  2191. ===================================================================
  2192. RCS file: /e/ossp/pkg/tool/cvs/cvs/cvs/src/main.c,v
  2193. retrieving revision 1.1.1.5
  2194. diff -u -d -u -3 -r1.1.1.5 main.c
  2195. --- src/main.c 27 Apr 2001 19:57:23 -0000 1.1.1.5
  2196. +++ src/main.c 16 Feb 2002 12:36:09 -0000
  2197. @@ -41,6 +41,9 @@
  2198. int quiet = 0;
  2199. int trace = 0;
  2200. int noexec = 0;
  2201. +#ifdef RSE_PATCH_NOLOCK
  2202. +int nolock = 0;
  2203. +#endif
  2204. int logoff = 0;
  2205. /* Set if we should be writing CVSADM directories at top level. At
  2206. @@ -50,6 +53,15 @@
  2207. mode_t cvsumask = UMASK_DFLT;
  2208. +#ifdef RSE_PATCH_LOCALID
  2209. +char *RCS_citag = NULL;
  2210. +#endif
  2211. +
  2212. +#ifdef RSE_PATCH_PROLOGEPILOG
  2213. +char *cvs_prolog = NULL;
  2214. +char *cvs_epilog = NULL;
  2215. +#endif
  2216. +
  2217. char *CurDir;
  2218. /*
  2219. @@ -124,11 +136,17 @@
  2220. { "login", "logon", "lgn", login, 0 },
  2221. { "logout", NULL, NULL, logout, 0 },
  2222. #endif /* AUTH_CLIENT_SUPPORT */
  2223. +#ifdef RSE_PATCH_PSERVERD
  2224. + { "pserverd", NULL, NULL, pserverd },
  2225. +#endif
  2226. #if (defined(AUTH_SERVER_SUPPORT) || defined (HAVE_GSSAPI)) && defined(SERVER_SUPPORT)
  2227. { "pserver", NULL, NULL, server, CVS_CMD_MODIFIES_REPOSITORY | CVS_CMD_USES_WORK_DIR }, /* placeholder */
  2228. #endif
  2229. { "rannotate","rann", "ra", annotate, 0 },
  2230. { "rdiff", "patch", "pa", patch, 0 },
  2231. +#ifdef RSE_PATCH_RLIST
  2232. + { "rlist", "rls", NULL, cvslist, 0 },
  2233. +#endif
  2234. { "release", "re", "rel", release, 0 },
  2235. { "remove", "rm", "delete", cvsremove, CVS_CMD_MODIFIES_REPOSITORY | CVS_CMD_USES_WORK_DIR },
  2236. { "rlog", "rl", NULL, cvslog, 0 },
  2237. @@ -143,9 +161,53 @@
  2238. { "version", "ve", "ver", version, 0 },
  2239. { "watch", NULL, NULL, watch, CVS_CMD_MODIFIES_REPOSITORY | CVS_CMD_USES_WORK_DIR },
  2240. { "watchers", NULL, NULL, watchers, CVS_CMD_USES_WORK_DIR },
  2241. +#ifdef RSE_PATCH_CVSROOT
  2242. + { "root", "ro", "repo", root, CVS_CMD_IGNORE_ADMROOT },
  2243. +#endif
  2244. { NULL, NULL, NULL, NULL, 0 },
  2245. };
  2246. +#ifdef RSE_PATCH_CUSTOMCMD
  2247. +
  2248. +/* the table of custom commands */
  2249. +#define CUSTOMCMD_MAX 20
  2250. +static int customcmd_num = 0;
  2251. +struct customcmd {
  2252. + char *name;
  2253. + char *command;
  2254. +};
  2255. +static struct customcmd customcmd_tab[CUSTOMCMD_MAX];
  2256. +
  2257. +/* the internal handler function for custom commands */
  2258. +static int
  2259. +customcmd_run(argc, argv)
  2260. + int argc;
  2261. + char **argv;
  2262. +{
  2263. + int i;
  2264. + char *cmd;
  2265. +
  2266. + /* support for `cvs -H <cmd>' */
  2267. + if (argc == -1) {
  2268. + (void)fprintf(stderr, "Usage: %s %s [command arguments]\n",
  2269. + program_name, command_name);
  2270. + error_exit();
  2271. + }
  2272. +
  2273. + /* execute the command */
  2274. + cmd = expand_path(argv[0], command_name, 0);
  2275. + run_setup(cmd);
  2276. + for (i = 1; i < argc; i++)
  2277. + run_arg(argv[i]);
  2278. + if (run_exec(RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL) != 0)
  2279. + error(1, 0, "program `%s' of custom command `%s' returned non-zero",
  2280. + cmd, command_name);
  2281. + free(cmd);
  2282. +
  2283. + return 0;
  2284. +}
  2285. +#endif
  2286. +
  2287. static const char *const usg[] =
  2288. {
  2289. /* CVS usage messages never have followed the GNU convention of
  2290. @@ -186,9 +248,13 @@
  2291. paragraph in ../cvs.spec without assuming the reader knows what
  2292. version control means. */
  2293. +#ifdef RSE_PATCH_COSMETICS
  2294. + "For CVS updates and additional information, see http://www.cvshome.org/\n",
  2295. +#else
  2296. "For CVS updates and additional information, see\n",
  2297. " the CVS home page at http://www.cvshome.org/ or\n",
  2298. " Pascal Molli's CVS site at http://www.loria.fr/~molli/cvs-index.html\n",
  2299. +#endif
  2300. NULL,
  2301. };
  2302. @@ -215,11 +281,17 @@
  2303. " login Prompt for password for authenticating server\n",
  2304. " logout Removes entry in .cvspass for remote repository\n",
  2305. #endif /* AUTH_CLIENT_SUPPORT */
  2306. +#ifdef RSE_PATCH_PSERVERD
  2307. + " pserverd Password server daemon\n",
  2308. +#endif
  2309. #if (defined(AUTH_SERVER_SUPPORT) || defined (HAVE_GSSAPI)) && defined(SERVER_SUPPORT)
  2310. " pserver Password server mode\n",
  2311. #endif
  2312. " rannotate Show last revision where each line of module was modified\n",
  2313. " rdiff Create 'patch' format diffs between releases\n",
  2314. +#ifdef RSE_PATCH_RLIST
  2315. + " rlist List repository directories.\n",
  2316. +#endif
  2317. " release Indicate that a Module is no longer in use\n",
  2318. " remove Remove an entry from the repository\n",
  2319. " rlog Print out history information for a module\n",
  2320. @@ -234,6 +306,9 @@
  2321. " version Show current CVS version(s)\n",
  2322. " watch Set watches\n",
  2323. " watchers See who is watching a file\n",
  2324. +#ifdef RSE_PATCH_CVSROOT
  2325. + " root Maintain repository root locations\n",
  2326. +#endif
  2327. "(Specify the --help option for a list of other help options)\n",
  2328. NULL,
  2329. };
  2330. @@ -249,6 +324,9 @@
  2331. " -w Make checked-out files read-write (default).\n",
  2332. " -l Turn history logging off.\n",
  2333. " -n Do not execute anything that will change the disk.\n",
  2334. +#ifdef RSE_PATCH_NOLOCK
  2335. + " -u Do not create lock files (implies -l).\n",
  2336. +#endif
  2337. " -t Show trace of program execution -- try with -n.\n",
  2338. " -v CVS version and copyright.\n",
  2339. " -T tmpdir Use 'tmpdir' for temporary files.\n",
  2340. @@ -262,6 +340,10 @@
  2341. #endif
  2342. " -a Authenticate all net traffic.\n",
  2343. #endif
  2344. +#ifdef RSE_PATCH_PROLOGEPILOG
  2345. + " -P program Run prolog program before processing.\n",
  2346. + " -E program Run epilog program after processing.\n",
  2347. +#endif
  2348. " -s VAR=VAL Set CVS user variable.\n",
  2349. "(Specify the --help option for a list of other help options)\n",
  2350. NULL
  2351. @@ -332,6 +414,20 @@
  2352. if (strcmp (cmd_name, cm->fullname) == 0)
  2353. break;
  2354. }
  2355. +#ifdef RSE_PATCH_CUSTOMCMD
  2356. + {
  2357. + int i;
  2358. + unsigned long int ret = 0;
  2359. + for (i = 0; i < customcmd_num; i++) {
  2360. + if (strcmp(customcmd_tab[i].name, cmd_name) == 0) {
  2361. + ret |= CVS_CMD_IGNORE_ADMROOT;
  2362. + ret &= ~(CVS_CMD_USES_WORK_DIR);
  2363. + ret &= ~(CVS_CMD_MODIFIES_REPOSITORY);
  2364. + return ret;
  2365. + }
  2366. + }
  2367. + }
  2368. +#endif
  2369. return cm->attr;
  2370. }
  2371. @@ -401,11 +497,34 @@
  2372. int free_CVSroot = 0;
  2373. int free_Editor = 0;
  2374. int free_Tmpdir = 0;
  2375. +#ifdef RSE_PATCH_CVSROOT
  2376. + cvsroot_type *cvsroot_sync = NULL;
  2377. + int cvsroot_cmdline_isreal = 0;
  2378. +#endif
  2379. +#if defined(RSE_PATCH_CVSROOT) || defined(RSE_PATCH_CUSTOMCMD)
  2380. + int standalone_command = 0;
  2381. +#endif
  2382. int help = 0; /* Has the user asked for help? This
  2383. lets us support the `cvs -H cmd'
  2384. convention to give help for cmd. */
  2385. +#if defined(RSE_PATCH_NOLOCK) ||\
  2386. + defined(RSE_PATCH_PROLOGEPILOG) ||\
  2387. + defined(RSE_PATCH_CUSTOMCMD)
  2388. + static const char short_options[] = "+Qqrwtnlvb:T:e:d:Hfz:s:xa"
  2389. +#ifdef RSE_PATCH_NOLOCK
  2390. + "u"
  2391. +#endif
  2392. +#ifdef RSE_PATCH_PROLOGEPILOG
  2393. + "P:E:"
  2394. +#endif
  2395. +#ifdef RSE_PATCH_CUSTOMCMD
  2396. + "C:"
  2397. +#endif
  2398. + ;
  2399. +#else
  2400. static const char short_options[] = "+Qqrwtnlvb:T:e:d:Hfz:s:xa";
  2401. +#endif
  2402. static struct option long_options[] =
  2403. {
  2404. {"help", 0, NULL, 'H'},
  2405. @@ -414,6 +533,9 @@
  2406. {"help-synonyms", 0, NULL, 2},
  2407. {"help-options", 0, NULL, 4},
  2408. {"allow-root", required_argument, NULL, 3},
  2409. +#ifdef RSE_PATCH_MAPROOT
  2410. + {"map-root", required_argument, NULL, 5},
  2411. +#endif
  2412. {0, 0, 0, 0}
  2413. };
  2414. /* `getopt_long' stores the option index here, but right now we
  2415. @@ -468,6 +590,16 @@
  2416. }
  2417. if (getenv (CVSREAD_ENV) != NULL)
  2418. cvswrite = 0;
  2419. +#ifdef RSE_PATCH_NOLOCK
  2420. + if (getenv (CVSNOLOCK_ENV)) {
  2421. + nolock = 1;
  2422. + logoff = 1;
  2423. + }
  2424. +#endif
  2425. +#ifdef RSE_PATCH_PROLOGEPILOG
  2426. + cvs_prolog = getenv("CVSPROLOG");
  2427. + cvs_epilog = getenv("CVSEPILOG");
  2428. +#endif
  2429. /* Set this to 0 to force getopt initialization. getopt() sets
  2430. this to 1 internally. */
  2431. @@ -487,12 +619,63 @@
  2432. use_cvsrc = 0;
  2433. }
  2434. +#ifdef RSE_PATCH_GLOBALOPTION
  2435. + /*
  2436. + * Perform a pre-lookup of the command name in order to scan cvsrc
  2437. + * file also for command dependent global options. For instance a
  2438. + * "-d" option only for "commit" commands (useful if one uses a
  2439. + * local repository copy for all cvs commands, but commits have to
  2440. + * go directly to the master repository).
  2441. + */
  2442. + if (use_cvsrc) {
  2443. + command_name = argv[optind];
  2444. + if (command_name != NULL && command_name[0] != '\0') {
  2445. + for (cm = cmds; cm->fullname != NULL; cm++)
  2446. + {
  2447. + if (cm->nick1 && !strcmp(command_name, cm->nick1))
  2448. + break;
  2449. + if (cm->nick2 && !strcmp(command_name, cm->nick2))
  2450. + break;
  2451. + if (!strcmp(command_name, cm->fullname))
  2452. + break;
  2453. + }
  2454. + command_name = cm->fullname;
  2455. + }
  2456. + }
  2457. +#endif
  2458. +
  2459. /*
  2460. * Scan cvsrc file for global options.
  2461. */
  2462. if (use_cvsrc)
  2463. read_cvsrc (&argc, &argv, "cvs");
  2464. +#ifdef RSE_PATCH_GLOBALOPTION
  2465. + if (use_cvsrc) {
  2466. + if (command_name != NULL && command_name[0] != '\0') {
  2467. + char *cmd;
  2468. +#ifdef RSE_PATCH_GLOBALOPTION_PARTLY
  2469. + if ( strcmp(command_name, "commit") == 0
  2470. + || strcmp(command_name, "tag") == 0
  2471. + || strcmp(command_name, "rtag") == 0
  2472. + || strcmp(command_name, "history") == 0
  2473. + || strcmp(command_name, "admin") == 0
  2474. + || strcmp(command_name, "import") == 0
  2475. +#ifdef RSE_PATCH_RLIST
  2476. + || strcmp(command_name, "rlist") == 0
  2477. +#endif
  2478. + || strcmp(command_name, "rdiff") == 0) {
  2479. +#endif
  2480. + cmd = xmalloc(4 + strlen(command_name) + 1);
  2481. + sprintf(cmd, "cvs/%s", command_name);
  2482. + read_cvsrc (&argc, &argv, cmd);
  2483. +#ifdef RSE_PATCH_GLOBALOPTION_PARTLY
  2484. + }
  2485. +#endif
  2486. + }
  2487. + }
  2488. +#endif
  2489. +
  2490. optind = 0;
  2491. opterr = 1;
  2492. @@ -518,6 +701,17 @@
  2493. /* --allow-root */
  2494. root_allow_add (optarg);
  2495. break;
  2496. +#ifdef RSE_PATCH_MAPROOT
  2497. + case 5: {
  2498. + /* --map-root */
  2499. + char *cp;
  2500. + if ((cp = strchr(optarg, ':')) == NULL)
  2501. + error(1, 0, "invalid argument syntax for --map-root option");
  2502. + *cp++ = '\0';
  2503. + root_map_add(optarg, cp);
  2504. + break;
  2505. + }
  2506. +#endif
  2507. case 'Q':
  2508. really_quiet = 1;
  2509. /* FALL THROUGH */
  2510. @@ -535,6 +729,10 @@
  2511. break;
  2512. case 'n':
  2513. noexec = 1;
  2514. +#ifdef RSE_PATCH_NOLOCK
  2515. + case 'u': /* Fall through */
  2516. + nolock = 1;
  2517. +#endif
  2518. case 'l': /* Fall through */
  2519. logoff = 1;
  2520. break;
  2521. @@ -573,10 +771,34 @@
  2522. case 'd':
  2523. if (CVSroot_cmdline != NULL)
  2524. free (CVSroot_cmdline);
  2525. +#ifdef RSE_PATCH_MAPROOT
  2526. + {
  2527. + char *newarg;
  2528. + if (root_map_it(optarg, &newarg, 0))
  2529. + optarg = newarg;
  2530. + }
  2531. +#endif
  2532. +#ifdef RSE_PATCH_CVSROOT
  2533. + {
  2534. + cvsroot_type *e;
  2535. + if ((e = cvsroot_lookup(optarg, NULL, NULL)) != NULL) {
  2536. + if (!quiet)
  2537. + fprintf(stderr, "%s: using repository `%s'\n", program_name, e->masterpath);
  2538. + CVSroot_cmdline = xstrdup(e->masterpath);
  2539. + CVSroot = xstrdup(e->masterpath);
  2540. + cvsroot_free(e);
  2541. + }
  2542. + else {
  2543. + cvsroot_cmdline_isreal = 1;
  2544. +#endif
  2545. CVSroot_cmdline = xstrdup (optarg);
  2546. if (free_CVSroot)
  2547. free (CVSroot);
  2548. CVSroot = xstrdup (optarg);
  2549. +#ifdef RSE_PATCH_CVSROOT
  2550. + }
  2551. + }
  2552. +#endif
  2553. free_CVSroot = 1;
  2554. cvs_update_env = 1; /* need to update environment */
  2555. break;
  2556. @@ -618,6 +840,28 @@
  2557. We will issue an error later if stream
  2558. authentication is not supported. */
  2559. break;
  2560. +#ifdef RSE_PATCH_PROLOGEPILOG
  2561. + case 'P':
  2562. + cvs_prolog = xstrdup(optarg);
  2563. + break;
  2564. + case 'E':
  2565. + cvs_epilog = xstrdup(optarg);
  2566. + break;
  2567. +#endif
  2568. +#ifdef RSE_PATCH_CUSTOMCMD
  2569. + case 'C': {
  2570. + char *cp;
  2571. + if (customcmd_num >= CUSTOMCMD_MAX)
  2572. + error(1, 0, "maximum number of allowed -C options reached");
  2573. + if ((cp = strchr(optarg, ':')) == NULL)
  2574. + error(1, 0, "invalid argument to option -C (has to be \"name:cmd\")");
  2575. + *cp++ = '\0';
  2576. + customcmd_tab[customcmd_num].name = xstrdup(optarg);
  2577. + customcmd_tab[customcmd_num].command = xstrdup(cp);
  2578. + customcmd_num++;
  2579. + break;
  2580. + }
  2581. +#endif
  2582. case '?':
  2583. default:
  2584. usage (usg);
  2585. @@ -629,6 +873,28 @@
  2586. if (argc < 1)
  2587. usage (usg);
  2588. +#ifdef RSE_PATCH_CUSTOMCMD
  2589. + /* Look up the custom command. */
  2590. + cm = NULL;
  2591. + {
  2592. + int i;
  2593. + command_name = argv[0];
  2594. + for (i = 0; i < customcmd_num; i++) {
  2595. + if (strcmp(customcmd_tab[i].name, command_name) == 0) {
  2596. + struct cmd *ccm;
  2597. + ccm = (struct cmd *)xmalloc(sizeof(struct cmd));
  2598. + ccm->nick1 = NULL;
  2599. + ccm->nick2 = NULL;
  2600. + ccm->func = customcmd_run;
  2601. + ccm->fullname = customcmd_tab[i].name;
  2602. + argv[0] = customcmd_tab[i].command;
  2603. + cm = (const struct cmd *)ccm;
  2604. + standalone_command = 1;
  2605. + }
  2606. + }
  2607. + }
  2608. + if (cm == NULL) {
  2609. +#endif
  2610. /* Look up the command name. */
  2611. @@ -651,6 +917,10 @@
  2612. else
  2613. command_name = cm->fullname; /* Global pointer for later use */
  2614. +#ifdef RSE_PATCH_CUSTOMCMD
  2615. + }
  2616. +#endif
  2617. +
  2618. if (help)
  2619. {
  2620. argc = -1; /* some functions only check for this */
  2621. @@ -676,6 +946,71 @@
  2622. CVSUMASK_ENV, cp);
  2623. }
  2624. +#ifdef RSE_PATCH_CVSPID
  2625. + /* provide the process id of the parent CVS process to
  2626. + sub-processes (usually scripts called from *info files) in order
  2627. + to let them have a unique session handle */
  2628. + {
  2629. + char pidbuf[64];
  2630. + sprintf(pidbuf, "CVSPID=%lu", (unsigned long)getpid());
  2631. + putenv(pidbuf);
  2632. + }
  2633. +#endif
  2634. +
  2635. +#ifdef RSE_PATCH_SETXID
  2636. + if ( strcmp(command_name, "kserver") != 0
  2637. + && strcmp(command_name, "pserver") != 0
  2638. + && strcmp(command_name, "server") == 0) {
  2639. + uid_t uid, euid;
  2640. + gid_t gid, egid;
  2641. + struct passwd *pw;
  2642. + char *env;
  2643. +
  2644. + /* adjust group id */
  2645. + gid = getgid();
  2646. + egid = getegid();
  2647. + if (gid != egid)
  2648. + setgid(egid); /* upgrade real to effective gid */
  2649. + else
  2650. + setegid(gid); /* downgrade effective to real gid */
  2651. +
  2652. + /* adjust user id */
  2653. + uid = getuid();
  2654. + euid = geteuid();
  2655. + if (uid != euid)
  2656. + setuid(euid); /* upgrade real to effective uid */
  2657. + else
  2658. + seteuid(uid); /* downgrade effective to real uid */
  2659. +
  2660. + /* still do not adjust umask */
  2661. + umask(0);
  2662. +
  2663. + /* remember real user (especially for getcaller()) */
  2664. + pw = getpwuid(uid);
  2665. +#ifdef AUTH_SERVER_SUPPORT
  2666. + CVS_Username = xstrdup(pw->pw_name);
  2667. +#if HAVE_PUTENV
  2668. + env = xmalloc(sizeof("LOGNAME=")+strlen(CVS_Username));
  2669. + (void)sprintf(env, "LOGNAME=%s", CVS_Username);
  2670. + (void)putenv(env);
  2671. +#endif
  2672. +#endif
  2673. +
  2674. +#if HAVE_PUTENV
  2675. + /* remember running user */
  2676. + pw = getpwuid(getuid());
  2677. + env = xmalloc(sizeof("USER=")+strlen(pw->pw_name));
  2678. + (void)sprintf(env, "USER=%s", pw->pw_name);
  2679. + (void)putenv(env);
  2680. +#endif
  2681. + }
  2682. + else {
  2683. + /* delete effective user and group id */
  2684. + seteuid(getuid());
  2685. + setegid(getgid());
  2686. + }
  2687. +#endif
  2688. +
  2689. #if defined (HAVE_KERBEROS) && defined (SERVER_SUPPORT)
  2690. /* If we are invoked with a single argument "kserver", then we are
  2691. running as Kerberos server as root. Do the authentication as
  2692. @@ -690,6 +1025,21 @@
  2693. }
  2694. #endif /* HAVE_KERBEROS */
  2695. +#ifdef RSE_PATCH_PSERVERD
  2696. + if (strcmp(command_name, "pserverd") == 0) {
  2697. + /*
  2698. + * perform the socket listening. This returns multiple times,
  2699. + * i.e., for each connection. But the parent never returns.
  2700. + */
  2701. + pserver_daemon(argc, argv);
  2702. +
  2703. + /*
  2704. + * switch to regular "cvs server" operation.
  2705. + */
  2706. + argc = 0;
  2707. + command_name = "server";
  2708. + }
  2709. +#endif
  2710. #if (defined(AUTH_SERVER_SUPPORT) || defined (HAVE_GSSAPI)) && defined(SERVER_SUPPORT)
  2711. if (strcmp (command_name, "pserver") == 0)
  2712. @@ -714,6 +1064,11 @@
  2713. server_active = strcmp (command_name, "server") == 0;
  2714. #endif
  2715. +#ifdef RSE_PATCH_CVSROOT
  2716. + if (strcmp(command_name, "root") == 0)
  2717. + standalone_command = 1;
  2718. +#endif
  2719. +
  2720. /* This is only used for writing into the history file. For
  2721. remote connections, it might be nice to have hostname
  2722. and/or remote path, on the other hand I'm not sure whether
  2723. @@ -784,8 +1139,12 @@
  2724. in server mode, since the client will send the repository
  2725. directory after the connection is made. */
  2726. +#if defined(RSE_PATCH_CVSROOT) || defined(RSE_PATCH_CUSTOMCMD)
  2727. + if (!server_active && !standalone_command)
  2728. +#else
  2729. if (!server_active)
  2730. #endif
  2731. +#endif
  2732. {
  2733. char *CVSADM_Root;
  2734. @@ -841,6 +1200,54 @@
  2735. error (1, 0,
  2736. "CVS/Root file (if any).");
  2737. }
  2738. +
  2739. +#ifdef RSE_PATCH_CVSROOT
  2740. + if (CVSroot_cmdline == NULL || !cvsroot_cmdline_isreal) {
  2741. + cvsroot_type *e;
  2742. + if (lookup_command_attribute(command_name) & CVS_CMD_MODIFIES_REPOSITORY) {
  2743. + if ((e = cvsroot_lookup(NULL, NULL, CVSroot)) != NULL) {
  2744. + /* command modifies repository and we still operare on
  2745. + the slave repository, so switch to the master repository,
  2746. + because we can only perform modifications there. */
  2747. + if (!quiet) {
  2748. + fprintf(stderr, "%s: switching to MASTER location of repository `%s'\n", program_name, e->nickname);
  2749. + fprintf(stderr, "%s: %s <-- %s\n", program_name, e->masterpath, e->slavepath);
  2750. + }
  2751. + if (free_CVSroot)
  2752. + free(CVSroot);
  2753. + CVSroot = xstrdup(e->masterpath);
  2754. + if (CVSroot_cmdline != NULL)
  2755. + free(CVSroot_cmdline);
  2756. + CVSroot_cmdline = xstrdup(e->masterpath);
  2757. + cvsroot_sync = e;
  2758. + free_CVSroot = 1;
  2759. + cvs_update_env = 1;
  2760. + }
  2761. + }
  2762. + else {
  2763. + if ((e = cvsroot_lookup(NULL, CVSroot, NULL)) != NULL) {
  2764. + if (e->slavepath[0] != '\0') {
  2765. + /* command does not modify repository and we still operare on
  2766. + the master repository, so switch to the slave repository,
  2767. + because it is faster by definition. */
  2768. + if (!quiet) {
  2769. + fprintf(stderr, "%s: switching to SLAVE location of repository `%s'\n", program_name, e->nickname);
  2770. + fprintf(stderr, "%s: %s --> %s\n", program_name, e->masterpath, e->slavepath);
  2771. + }
  2772. + if (free_CVSroot)
  2773. + free(CVSroot);
  2774. + CVSroot = xstrdup(e->slavepath);
  2775. + if (CVSroot_cmdline != NULL)
  2776. + free(CVSroot_cmdline);
  2777. + CVSroot_cmdline = xstrdup(e->slavepath);
  2778. + cvsroot_free(e);
  2779. + free_CVSroot = 1;
  2780. + cvs_update_env = 1;
  2781. + }
  2782. + }
  2783. + }
  2784. + }
  2785. +#endif /* RSE_PATCH_CVSROOT */
  2786. }
  2787. /* Here begins the big loop over unique cvsroot values. We
  2788. @@ -873,6 +1280,9 @@
  2789. end of things. */
  2790. while (
  2791. +#if defined(RSE_PATCH_CVSROOT) || defined(RSE_PATCH_CUSTOMCMD)
  2792. + standalone_command ||
  2793. +#endif
  2794. #ifdef SERVER_SUPPORT
  2795. server_active ||
  2796. #endif
  2797. @@ -884,8 +1294,12 @@
  2798. in server mode, since the client will send the repository
  2799. directory after the connection is made. */
  2800. +#if defined(RSE_PATCH_CVSROOT) || defined(RSE_PATCH_CUSTOMCMD)
  2801. + if (!server_active && !standalone_command)
  2802. +#else
  2803. if (!server_active)
  2804. #endif
  2805. +#endif
  2806. {
  2807. /* Now we're 100% sure that we have a valid CVSROOT
  2808. variable. Parse it to see if we're supposed to do
  2809. @@ -904,7 +1318,11 @@
  2810. * Check to see if the repository exists.
  2811. */
  2812. #ifdef CLIENT_SUPPORT
  2813. +#ifdef RSE_PATCH_NOLOCK
  2814. + if (!current_parsed_root->isremote && !nolock)
  2815. +#else
  2816. if (!current_parsed_root->isremote)
  2817. +#endif
  2818. #endif /* CLIENT_SUPPORT */
  2819. {
  2820. char *path;
  2821. @@ -918,7 +1336,12 @@
  2822. {
  2823. save_errno = errno;
  2824. /* If this is "cvs init", the root need not exist yet. */
  2825. +#ifdef RSE_PATCH_CVSROOT
  2826. + if (strcmp (command_name, "init") != 0 &&
  2827. + strcmp (command_name, "root") != 0)
  2828. +#else
  2829. if (strcmp (command_name, "init") != 0)
  2830. +#endif
  2831. {
  2832. error (1, save_errno, "%s", path);
  2833. }
  2834. @@ -954,6 +1377,9 @@
  2835. read_cvsrc and other such places or vice versa. That sort
  2836. of thing probably needs more thought. */
  2837. if (1
  2838. +#if defined(RSE_PATCH_CVSROOT) || defined(RSE_PATCH_CUSTOMCMD)
  2839. + && !standalone_command
  2840. +#endif
  2841. #ifdef SERVER_SUPPORT
  2842. && !server_active
  2843. #endif
  2844. @@ -984,7 +1410,49 @@
  2845. }
  2846. #endif
  2847. +#ifdef RSE_PATCH_PROLOGEPILOG
  2848. + if (cvs_prolog != NULL) {
  2849. + char *cmd;
  2850. + cmd = expand_path(cvs_prolog, "prolog", 0);
  2851. + run_setup(cmd);
  2852. + run_arg("prolog");
  2853. + run_arg(command_name);
  2854. + if (CurDir != NULL)
  2855. + run_arg(CurDir);
  2856. + else
  2857. + run_arg("unknown-cwd");
  2858. + if (current_parsed_root != NULL && current_parsed_root->directory != NULL)
  2859. + run_arg(current_parsed_root->directory);
  2860. + else
  2861. + run_arg("unknown-cvsroot");
  2862. + if (run_exec(RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL) != 0)
  2863. + error(1, 0, "prolog program `%s' returned non-zero", cmd);
  2864. + free(cmd);
  2865. + }
  2866. +#endif
  2867. +
  2868. err = (*(cm->func)) (argc, argv);
  2869. +
  2870. +#ifdef RSE_PATCH_PROLOGEPILOG
  2871. + if (cvs_epilog != NULL) {
  2872. + char *cmd;
  2873. + cmd = expand_path(cvs_epilog, "epilog", 0);
  2874. + run_setup(cmd);
  2875. + run_arg("epilog");
  2876. + run_arg(command_name);
  2877. + if (CurDir != NULL)
  2878. + run_arg(CurDir);
  2879. + else
  2880. + run_arg("unknown-cwd");
  2881. + if (current_parsed_root != NULL && current_parsed_root->directory != NULL)
  2882. + run_arg(current_parsed_root->directory);
  2883. + else
  2884. + run_arg("unknown-cvsroot");
  2885. + if (run_exec(RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL) != 0)
  2886. + error(1, 0, "epilog program `%s' returned non-zero", cmd);
  2887. + free(cmd);
  2888. + }
  2889. +#endif
  2890. /* Mark this root directory as done. When the server is
  2891. active, current_root will be NULL -- don't try and
  2892. @@ -1003,11 +1471,20 @@
  2893. dellist (&root_directories);
  2894. #endif
  2895. +#if defined(RSE_PATCH_CVSROOT) || defined(RSE_PATCH_CUSTOMCMD)
  2896. + if (standalone_command)
  2897. + break;
  2898. +#endif
  2899. #ifdef SERVER_SUPPORT
  2900. if (server_active)
  2901. break;
  2902. #endif
  2903. } /* end of loop for cvsroot values */
  2904. +
  2905. +#ifdef RSE_PATCH_CVSROOT
  2906. + if (cvsroot_sync != NULL)
  2907. + cvsroot_synchronize(cvsroot_sync, 0);
  2908. +#endif
  2909. } /* end of stuff that gets done if the user DOESN'T ask for help */
  2910. Index: src/mkmodules.c
  2911. ===================================================================
  2912. RCS file: /e/ossp/pkg/tool/cvs/cvs/cvs/src/mkmodules.c,v
  2913. retrieving revision 1.1.1.4
  2914. diff -u -d -u -3 -r1.1.1.4 mkmodules.c
  2915. --- src/mkmodules.c 19 Apr 2001 19:45:32 -0000 1.1.1.4
  2916. +++ src/mkmodules.c 16 Feb 2002 12:36:09 -0000
  2917. @@ -186,6 +186,48 @@
  2918. NULL
  2919. };
  2920. +#ifdef RSE_PATCH_ADMININFO
  2921. +static const char *const admininfo_contents[] = {
  2922. + "# The \"admininfo\" file is used to control pre-admin checks.\n",
  2923. + "# The filter on the right is invoked with the repository and a list \n",
  2924. + "# of files to check. A non-zero exit of the filter program will \n",
  2925. + "# cause the admin operation to be aborted.\n",
  2926. + "#\n",
  2927. + "# The first entry on a line is a regular expression which is tested\n",
  2928. + "# against the directory that the change is being committed to, relative\n",
  2929. + "# to the $CVSROOT. For the first match that is found, then the remainder\n",
  2930. + "# of the line is the name of the filter to run.\n",
  2931. + "#\n",
  2932. + "# If the repository name does not match any of the regular expressions in this\n",
  2933. + "# file, the \"DEFAULT\" line is used, if it is specified.\n",
  2934. + "#\n",
  2935. + "# If the name \"ALL\" appears as a regular expression it is always used\n",
  2936. + "# in addition to the first matching regex or \"DEFAULT\".\n",
  2937. + NULL
  2938. +};
  2939. +#endif
  2940. +
  2941. +#ifdef RSE_PATCH_IMPORTINFO
  2942. +static const char *const importinfo_contents[] = {
  2943. + "# The \"importinfo\" file is used to control pre-import checks.\n",
  2944. + "# The filter on the right is invoked with the repository to check.\n",
  2945. + "# A non-zero exit of the filter program will cause the import\n",
  2946. + "# operation to be aborted.\n",
  2947. + "#\n",
  2948. + "# The first entry on a line is a regular expression which is tested\n",
  2949. + "# against the directory that the change is being committed to, relative\n",
  2950. + "# to the $CVSROOT. For the first match that is found, then the remainder\n",
  2951. + "# of the line is the name of the filter to run.\n",
  2952. + "#\n",
  2953. + "# If the repository name does not match any of the regular expressions in this\n",
  2954. + "# file, the \"DEFAULT\" line is used, if it is specified.\n",
  2955. + "#\n",
  2956. + "# If the name \"ALL\" appears as a regular expression it is always used\n",
  2957. + "# in addition to the first matching regex or \"DEFAULT\".\n",
  2958. + NULL
  2959. +};
  2960. +#endif
  2961. +
  2962. static const char *const checkoutlist_contents[] = {
  2963. "# The \"checkoutlist\" file is used to support additional version controlled\n",
  2964. "# administrative files in $CVSROOT/CVSROOT, such as template files.\n",
  2965. @@ -297,6 +339,26 @@
  2966. "# Set `LogHistory' to `all' or `TOFEWGCMAR' to log all transactions to the\n",
  2967. "# history file, or a subset as needed (ie `TMAR' logs all write operations)\n",
  2968. "#LogHistory=TOFEWGCMAR\n",
  2969. +#ifdef RSE_PATCH_HISTORYFILE
  2970. + "\n",
  2971. + "# Set `HistoryFile' to the path name (relative to CVSROOT) of the history file\n",
  2972. + "# if you do not want to store it not under CVSROOT/history\n",
  2973. + "#HistoryFile=CVSROOT/history\n",
  2974. +#endif
  2975. +#ifdef RSE_PATCH_LOCALID
  2976. + "\n",
  2977. + "# Set `LocalIdName' to the name of a local tag to use in addition to Id\n",
  2978. +#ifdef RSE_PATCH_LOCALID_NAME
  2979. + "#LocalIdName=" RSE_PATCH_LOCALID_NAME "\n",
  2980. +#else
  2981. + "#LocalIdName=LocalId\n",
  2982. +#endif
  2983. +#endif
  2984. +#ifdef RSE_PATCH_CONFIGUMASK
  2985. + "\n",
  2986. + "# Set `UMask' to the octal value of the umask.\n",
  2987. + "#UMask=002\n",
  2988. +#endif
  2989. NULL
  2990. };
  2991. @@ -319,6 +381,16 @@
  2992. {CVSROOTADM_TAGINFO,
  2993. "a %s file can be used to configure 'cvs tag' checking",
  2994. taginfo_contents},
  2995. +#ifdef RSE_PATCH_ADMININFO
  2996. + {CVSROOTADM_ADMININFO,
  2997. + "a %s file can be used to configure 'cvs admin' checking",
  2998. + admininfo_contents},
  2999. +#endif
  3000. +#ifdef RSE_PATCH_IMPORTINFO
  3001. + {CVSROOTADM_IMPORTINFO,
  3002. + "a %s file can be used to configure 'cvs import' checking",
  3003. + importinfo_contents},
  3004. +#endif
  3005. {CVSROOTADM_IGNORE,
  3006. "a %s file can be used to specify files to ignore",
  3007. NULL},
  3008. Index: src/options.h.in
  3009. ===================================================================
  3010. RCS file: /e/ossp/pkg/tool/cvs/cvs/cvs/src/options.h.in,v
  3011. retrieving revision 1.1.1.2
  3012. diff -u -d -u -3 -r1.1.1.2 options.h.in
  3013. --- src/options.h.in 27 Jan 1999 22:58:14 -0000 1.1.1.2
  3014. +++ src/options.h.in 16 Feb 2002 12:36:46 -0000
  3015. @@ -198,3 +198,48 @@
  3016. #ifndef STDC_HEADERS
  3017. extern void exit ();
  3018. #endif
  3019. +
  3020. +/*
  3021. + * Support for compiling in various RSE extension
  3022. + */
  3023. +#ifdef RSE_PATCHES
  3024. +#define RSE_PATCH_CVSRC
  3025. +#define RSE_PATCH_CVSROOT
  3026. +#define RSE_PATCH_GLOBALOPTION
  3027. +#define RSE_PATCH_GLOBALOPTION_PARTLY
  3028. +#define RSE_PATCH_CUSTOMCMD
  3029. +#define RSE_PATCH_PROLOGEPILOG
  3030. +#define RSE_PATCH_VERIFY
  3031. +#define RSE_PATCH_LOCALID
  3032. +#define RSE_PATCH_CVSHEADER
  3033. +#define RSE_PATCH_NOLOCK
  3034. +#define RSE_PATCH_EXTRAPERCENT
  3035. +#define RSE_PATCH_READDNEW
  3036. +#define RSE_PATCH_CONFIGUMASK
  3037. +#define RSE_PATCH_FASTERUPDATE
  3038. +#define RSE_PATCH_DEADAWARE
  3039. +#define RSE_PATCH_LOGNAME
  3040. +#define RSE_PATCH_HISTORYFILE
  3041. +#define RSE_PATCH_IMPORTINFO
  3042. +#define RSE_PATCH_ADMININFO
  3043. +#define RSE_PATCH_HANDLE
  3044. +#define RSE_PATCH_IMPORTTOUCH
  3045. +#define RSE_PATCH_RELLOCKDIR
  3046. +#define RSE_PATCH_CVSUSER
  3047. +#define RSE_PATCH_SETXID
  3048. +#define RSE_PATCH_PSERVERD
  3049. +#define RSE_PATCH_MAPROOT
  3050. +#define RSE_PATCH_RLIST
  3051. +#define RSE_PATCH_COSMETICS
  3052. +#define RSE_PATCH_HASHFUNC
  3053. +#define RSE_PATCH_ADDFILEATTR
  3054. +#define RSE_PATCH_WILDPASSWD
  3055. +#define RSE_PATCH_CVSPID
  3056. +#define RSE_PATCH_BUGFIX
  3057. +/* problematic changes, because they break "make check" */
  3058. +#undef RSE_PATCH_COSMETICS_HARD
  3059. +#undef RSE_PATCH_MERGENOKEYWORD
  3060. +#undef RSE_PATCH_DIFFHEAD
  3061. +#undef RSE_PATCH_SMARTCONFIG
  3062. +#endif
  3063. +
  3064. Index: src/parseinfo.c
  3065. ===================================================================
  3066. RCS file: /e/ossp/pkg/tool/cvs/cvs/cvs/src/parseinfo.c,v
  3067. retrieving revision 1.1.1.4
  3068. diff -u -d -u -3 -r1.1.1.4 parseinfo.c
  3069. --- src/parseinfo.c 19 Apr 2001 19:45:32 -0000 1.1.1.4
  3070. +++ src/parseinfo.c 16 Feb 2002 12:36:09 -0000
  3071. @@ -11,6 +11,9 @@
  3072. #include <assert.h>
  3073. extern char *logHistory;
  3074. +#ifdef RSE_PATCH_HISTORYFILE
  3075. +extern char *history_file;
  3076. +#endif
  3077. /*
  3078. * Parse the INFOFILE file for the specified REPOSITORY. Invoke CALLPROC for
  3079. @@ -371,7 +374,24 @@
  3080. {
  3081. if (lock_dir != NULL)
  3082. free (lock_dir);
  3083. +#ifdef RSE_PATCH_RELLOCKDIR
  3084. + if (p[0] == '/') {
  3085. +#endif
  3086. lock_dir = xstrdup (p);
  3087. +#ifdef RSE_PATCH_RELLOCKDIR
  3088. + }
  3089. + else {
  3090. + char *s;
  3091. +
  3092. + lock_dir = xmalloc (strlen (p)
  3093. + + strlen (current_parsed_root->directory)
  3094. + + 2);
  3095. + strcpy (lock_dir, current_parsed_root->directory);
  3096. + s = lock_dir + strlen (lock_dir);
  3097. + *s++ = '/';
  3098. + strcpy (s, p);
  3099. + }
  3100. +#endif
  3101. /* Could try some validity checking, like whether we can
  3102. opendir it or something, but I don't see any particular
  3103. reason to do that now rather than waiting until lock.c. */
  3104. @@ -384,6 +404,28 @@
  3105. strcpy (logHistory, p);
  3106. }
  3107. }
  3108. +#ifdef RSE_PATCH_HISTORYFILE
  3109. + else if (strcmp (line, "HistoryFile") == 0)
  3110. + {
  3111. + if (history_file != NULL)
  3112. + free (history_file);
  3113. + history_file = xstrdup (p);
  3114. + }
  3115. +#endif
  3116. +#ifdef RSE_PATCH_LOCALID
  3117. + else if (strcmp (line, "LocalIdName") == 0) {
  3118. + RCS_citag = strdup(p);
  3119. + if (RCS_citag == NULL) {
  3120. + error (0, 0, "%s: no memory for local tag '%s'", infopath, p);
  3121. + goto error_return;
  3122. + }
  3123. + }
  3124. +#endif
  3125. +#ifdef RSE_PATCH_CONFIGUMASK
  3126. + else if (strcmp (line, "UMask") == 0) {
  3127. + cvsumask = (mode_t)(strtol(p, NULL, 8) & 0777);
  3128. + }
  3129. +#endif
  3130. else
  3131. {
  3132. /* We may be dealing with a keyword which was added in a
  3133. @@ -397,9 +439,11 @@
  3134. adding new keywords to your CVSROOT/config file is not
  3135. particularly recommended unless you are planning on using
  3136. the new features. */
  3137. +#ifndef RSE_PATCH_SMARTCONFIG
  3138. error (0, 0, "%s: unrecognized keyword '%s'",
  3139. infopath, line);
  3140. goto error_return;
  3141. +#endif
  3142. }
  3143. }
  3144. if (ferror (fp_info))
  3145. Index: src/rcs.c
  3146. ===================================================================
  3147. RCS file: /e/ossp/pkg/tool/cvs/cvs/cvs/src/rcs.c,v
  3148. retrieving revision 1.1.1.4
  3149. diff -u -d -u -3 -r1.1.1.4 rcs.c
  3150. --- src/rcs.c 24 Apr 2001 18:14:53 -0000 1.1.1.4
  3151. +++ src/rcs.c 16 Feb 2002 12:36:09 -0000
  3152. @@ -114,6 +114,10 @@
  3153. static void rcs_internal_unlockfile PROTO ((FILE *, char *));
  3154. static char *rcs_lockfilename PROTO ((char *));
  3155. +#ifdef RSE_PATCH_CVSHEADER
  3156. +static char *getfullCVSname PROTO((char *, char **));
  3157. +#endif
  3158. +
  3159. /* The RCS file reading functions are called a lot, and they do some
  3160. string comparisons. This macro speeds things up a bit by skipping
  3161. the function call when the first characters are different. It
  3162. @@ -3342,10 +3346,17 @@
  3163. size_t len;
  3164. };
  3165. #define KEYWORD_INIT(s) (s), sizeof (s) - 1
  3166. +#ifdef RSE_PATCH_LOCALID
  3167. +static struct rcs_keyword keywords[] =
  3168. +#else
  3169. static const struct rcs_keyword keywords[] =
  3170. +#endif
  3171. {
  3172. { KEYWORD_INIT ("Author") },
  3173. { KEYWORD_INIT ("Date") },
  3174. +#ifdef RSE_PATCH_CVSHEADER
  3175. + { KEYWORD_INIT ("CVSHeader") },
  3176. +#endif
  3177. { KEYWORD_INIT ("Header") },
  3178. { KEYWORD_INIT ("Id") },
  3179. { KEYWORD_INIT ("Locker") },
  3180. @@ -3355,12 +3366,22 @@
  3181. { KEYWORD_INIT ("Revision") },
  3182. { KEYWORD_INIT ("Source") },
  3183. { KEYWORD_INIT ("State") },
  3184. +#ifdef RSE_PATCH_LOCALID
  3185. +#ifdef RSE_PATCH_LOCALID_NAME
  3186. + { KEYWORD_INIT (RSE_PATCH_LOCALID_NAME) },
  3187. +#else
  3188. + { KEYWORD_INIT ("LocalId") },
  3189. +#endif
  3190. +#endif
  3191. { NULL, 0 }
  3192. };
  3193. enum keyword
  3194. {
  3195. KEYWORD_AUTHOR = 0,
  3196. KEYWORD_DATE,
  3197. +#ifdef RSE_PATCH_CVSHEADER
  3198. + KEYWORD_CVSHEADER,
  3199. +#endif
  3200. KEYWORD_HEADER,
  3201. KEYWORD_ID,
  3202. KEYWORD_LOCKER,
  3203. @@ -3369,7 +3390,12 @@
  3204. KEYWORD_RCSFILE,
  3205. KEYWORD_REVISION,
  3206. KEYWORD_SOURCE,
  3207. +#ifdef RSE_PATCH_LOCALID
  3208. + KEYWORD_STATE,
  3209. + KEYWORD_LOCALID
  3210. +#else
  3211. KEYWORD_STATE
  3212. +#endif
  3213. };
  3214. /* Convert an RCS date string into a readable string. This is like
  3215. @@ -3506,6 +3532,13 @@
  3216. return;
  3217. }
  3218. +#ifdef RSE_PATCH_LOCALID
  3219. + if (RCS_citag != NULL && keywords[KEYWORD_LOCALID].string == NULL) {
  3220. + keywords[KEYWORD_LOCALID].string = RCS_citag;
  3221. + keywords[KEYWORD_LOCALID].len = strlen(RCS_citag);
  3222. + }
  3223. +#endif
  3224. +
  3225. /* If we are using -kkvl, dig out the locker information if any. */
  3226. locker = NULL;
  3227. if (expand == KFLAG_KVL)
  3228. @@ -3595,15 +3628,28 @@
  3229. free_value = 1;
  3230. break;
  3231. +#ifdef RSE_PATCH_CVSHEADER
  3232. + case KEYWORD_CVSHEADER:
  3233. +#endif
  3234. case KEYWORD_HEADER:
  3235. case KEYWORD_ID:
  3236. +#ifdef RSE_PATCH_LOCALID
  3237. + case KEYWORD_LOCALID:
  3238. +#endif
  3239. {
  3240. char *path;
  3241. int free_path;
  3242. char *date;
  3243. +#ifdef RSE_PATCH_CVSHEADER
  3244. + char *old_path = NULL;
  3245. +#endif
  3246. if (kw == KEYWORD_HEADER)
  3247. path = rcs->path;
  3248. +#ifdef RSE_PATCH_CVSHEADER
  3249. + else if (kw == KEYWORD_CVSHEADER)
  3250. + path = getfullCVSname(rcs->path, &old_path);
  3251. +#endif
  3252. else
  3253. path = last_component (rcs->path);
  3254. path = escape_keyword_value (path, &free_path);
  3255. @@ -3623,6 +3669,10 @@
  3256. locker != NULL ? locker : "");
  3257. if (free_path)
  3258. free (path);
  3259. +#ifdef RSE_PATCH_CVSHEADER
  3260. + if (old_path)
  3261. + free (old_path);
  3262. +#endif
  3263. free (date);
  3264. free_value = 1;
  3265. }
  3266. @@ -8419,3 +8469,38 @@
  3267. }
  3268. return label;
  3269. }
  3270. +
  3271. +#ifdef RSE_PATCH_CVSHEADER
  3272. +static char *
  3273. +getfullCVSname(CVSname, pathstore)
  3274. + char *CVSname, **pathstore;
  3275. +{
  3276. + int rootlen;
  3277. + char *c;
  3278. + int alen;
  3279. +
  3280. + if (current_parsed_root->directory != NULL) {
  3281. + alen = sizeof("/" CVSATTIC) - 1;
  3282. + *pathstore = xstrdup(CVSname);
  3283. + if ((c = strrchr(*pathstore, '/')) != NULL) {
  3284. + if (c - *pathstore >= alen) {
  3285. + if (!strncmp(c - alen, "/" CVSATTIC, alen)) {
  3286. + while (*c != '\0') {
  3287. + *(c - alen) = *c;
  3288. + c++;
  3289. + }
  3290. + *(c - alen) = '\0';
  3291. + }
  3292. + }
  3293. + }
  3294. + rootlen = strlen(current_parsed_root->directory);
  3295. + if (!strncmp(*pathstore, current_parsed_root->directory, rootlen) &&
  3296. + (*pathstore)[rootlen] == '/')
  3297. + CVSname = (*pathstore + rootlen + 1);
  3298. + else
  3299. + CVSname = (*pathstore);
  3300. + }
  3301. + return CVSname;
  3302. +}
  3303. +#endif
  3304. +
  3305. Index: src/recurse.c
  3306. ===================================================================
  3307. RCS file: /e/ossp/pkg/tool/cvs/cvs/cvs/src/recurse.c,v
  3308. retrieving revision 1.1.1.4
  3309. diff -u -d -u -3 -r1.1.1.4 recurse.c
  3310. --- src/recurse.c 19 Apr 2001 19:45:33 -0000 1.1.1.4
  3311. +++ src/recurse.c 16 Feb 2002 12:36:09 -0000
  3312. @@ -508,7 +508,11 @@
  3313. if (frame->flags == R_SKIP_ALL)
  3314. return (0);
  3315. +#ifdef RSE_PATCH_NOLOCK
  3316. + should_readlock = nolock ? 0 : frame->readlock;
  3317. +#else
  3318. should_readlock = noexec ? 0 : frame->readlock;
  3319. +#endif
  3320. /* The fact that locks are not active here is what makes us fail to have
  3321. the
  3322. @@ -550,7 +554,11 @@
  3323. */
  3324. if (server_active
  3325. /* If there are writelocks around, we cannot pause here. */
  3326. +#ifdef RSE_PATCH_NOLOCK
  3327. + && (should_readlock || nolock))
  3328. +#else
  3329. && (should_readlock || noexec))
  3330. +#endif
  3331. server_pause_check();
  3332. #endif
  3333. Index: src/repos.c
  3334. ===================================================================
  3335. RCS file: /e/ossp/pkg/tool/cvs/cvs/cvs/src/repos.c,v
  3336. retrieving revision 1.1.1.3
  3337. diff -u -d -u -3 -r1.1.1.3 repos.c
  3338. --- src/repos.c 19 Apr 2001 19:45:33 -0000 1.1.1.3
  3339. +++ src/repos.c 16 Feb 2002 12:36:09 -0000
  3340. @@ -204,3 +204,11 @@
  3341. repository[len - 2] = '\0';
  3342. }
  3343. }
  3344. +
  3345. +#ifdef RSE_PATCH_RLIST
  3346. +/* Shameless hack: in order to avoid having to patch the brain-dead
  3347. + Automake-based CVS build environment (src/Makefile.am) we add the
  3348. + "cvs rlist" code to an arbitrarily chosen source file. */
  3349. +#include "list.c"
  3350. +#endif
  3351. +
  3352. Index: src/root.c
  3353. ===================================================================
  3354. RCS file: /e/ossp/pkg/tool/cvs/cvs/cvs/src/root.c,v
  3355. retrieving revision 1.1.1.4
  3356. diff -u -d -u -3 -r1.1.1.4 root.c
  3357. --- src/root.c 19 Apr 2001 19:45:33 -0000 1.1.1.4
  3358. +++ src/root.c 16 Feb 2002 12:36:09 -0000
  3359. @@ -122,6 +122,9 @@
  3360. /* allocate space to return and fill it in */
  3361. strip_trailing_slashes (root);
  3362. ret = xstrdup (root);
  3363. +#ifdef RSE_PATCH_MAPROOT
  3364. + root_map_it(ret, &ret, 0);
  3365. +#endif
  3366. out:
  3367. free (cvsadm);
  3368. free (tmp);
  3369. @@ -267,6 +270,87 @@
  3370. +#ifdef RSE_PATCH_MAPROOT
  3371. +
  3372. +typedef struct root_map_st {
  3373. + char *old;
  3374. + char *new;
  3375. +} root_map_t;
  3376. +
  3377. +#define ROOT_MAP_MAX 10
  3378. +static int root_map_max = 0;
  3379. +static root_map_t root_map_vec[ROOT_MAP_MAX];
  3380. +
  3381. +void root_map_add(char *old, char *new)
  3382. +{
  3383. + if (root_map_max >= ROOT_MAP_MAX)
  3384. + return;
  3385. + root_map_vec[root_map_max].old = xstrdup(old);
  3386. + root_map_vec[root_map_max].new = xstrdup(new);
  3387. + root_map_max++;
  3388. + return;
  3389. +}
  3390. +
  3391. +void root_map_free(void)
  3392. +{
  3393. + while (root_map_max > 0) {
  3394. + free(root_map_vec[root_map_max].old);
  3395. + free(root_map_vec[root_map_max].new);
  3396. + root_map_max--;
  3397. + }
  3398. + return;
  3399. +}
  3400. +
  3401. +int root_map_it(char *old, char **new, int prefixonly)
  3402. +{
  3403. + int rv;
  3404. + int i;
  3405. + int n;
  3406. +
  3407. + if (old == NULL)
  3408. + return 0;
  3409. + rv = 0;
  3410. + for (i = 0; i < root_map_max; i++) {
  3411. + n = strlen(root_map_vec[i].old);
  3412. + if (!prefixonly && strcmp(old, root_map_vec[i].old) == 0) {
  3413. + if (new == NULL) {
  3414. + /* we assume old is buffer and override it */
  3415. + strcpy(old, root_map_vec[i].new);
  3416. + }
  3417. + else {
  3418. + if (old == *new)
  3419. + /* old and new is same pointer we free before */
  3420. + free(old);
  3421. + /* provide new allocated buffer */
  3422. + *new = xmalloc(strlen(root_map_vec[i].new)+1);
  3423. + strcpy(*new, root_map_vec[i].new);
  3424. + }
  3425. + rv = 1;
  3426. + break;
  3427. + }
  3428. + else if (prefixonly && strncmp(old, root_map_vec[i].old, n) == 0) {
  3429. + if (new == NULL) {
  3430. + /* we assume old is buffer and override it */
  3431. + sprintf(old, "%s%s", root_map_vec[i].new, old+n);
  3432. + }
  3433. + else {
  3434. + char *oldnew = *new;
  3435. + /* provide new allocated buffer */
  3436. + *new = xmalloc(strlen(root_map_vec[i].new)+strlen(old+n)+1);
  3437. + sprintf(*new, "%s%s", root_map_vec[i].new, old+n);
  3438. + if (old == oldnew)
  3439. + /* old and new is same pointer we free before */
  3440. + free(old);
  3441. + }
  3442. + rv = 1;
  3443. + break;
  3444. + }
  3445. + }
  3446. + return rv;
  3447. +}
  3448. +
  3449. +#endif /* RSE_PATCH_MAPROOT */
  3450. +
  3451. /* This global variable holds the global -d option. It is NULL if -d
  3452. was not used, which means that we must get the CVSroot information
  3453. from the CVSROOT environment variable or from a CVS/Root file. */
  3454. @@ -804,3 +888,472 @@
  3455. /* NOTREACHED */
  3456. }
  3457. #endif
  3458. +
  3459. +#ifdef RSE_PATCH_CVSROOT
  3460. +
  3461. +#include <string.h>
  3462. +
  3463. +#ifndef CVS_ROOT_FILE
  3464. +#define CVS_ROOT_FILE ".cvsroot"
  3465. +#endif
  3466. +
  3467. +char *
  3468. +cvsroot_filename(
  3469. + void)
  3470. +{
  3471. + char *homedir;
  3472. + char *rootfile;
  3473. +
  3474. + /* Environment should override file. */
  3475. + if ((rootfile = getenv("CVS_ROOTFILE")) != NULL)
  3476. + return xstrdup(rootfile);
  3477. +
  3478. + /* Construct absolute pathname to user's password file. */
  3479. + if ((homedir = get_homedir()) == NULL) {
  3480. + error(1, 0, "could not find out home directory");
  3481. + return NULL;
  3482. + }
  3483. + rootfile = (char *)xmalloc(strlen(homedir)+strlen(CVS_ROOT_FILE)+3);
  3484. + strcpy(rootfile, homedir);
  3485. + strcat(rootfile, "/");
  3486. + strcat(rootfile, CVS_ROOT_FILE);
  3487. + return rootfile;
  3488. +}
  3489. +
  3490. +void cvsroot_free(
  3491. + cvsroot_type *e)
  3492. +{
  3493. + if (e != NULL) {
  3494. + if (e->nickname != NULL)
  3495. + free(e->nickname);
  3496. + if (e->masterpath != NULL)
  3497. + free(e->masterpath);
  3498. + if (e->slavepath != NULL)
  3499. + free(e->slavepath);
  3500. + if (e->syncprog != NULL)
  3501. + free(e->syncprog);
  3502. + free(e);
  3503. + }
  3504. + return;
  3505. +}
  3506. +
  3507. +cvsroot_type *
  3508. +cvsroot_entry_read(
  3509. + FILE *fp)
  3510. +{
  3511. + cvsroot_type *e;
  3512. + char *nickname;
  3513. + char *masterpath;
  3514. + char *slavepath;
  3515. + char *syncprog;
  3516. + char *line;
  3517. + int line_length;
  3518. + size_t line_chars_allocated;
  3519. + size_t n;
  3520. +
  3521. + e = NULL;
  3522. + line = NULL;
  3523. + line_chars_allocated = 0;
  3524. + while ((line_length = getline(&line, &line_chars_allocated, fp)) >= 0) {
  3525. + /* parse line */
  3526. + line += strspn(line, " \t\n");
  3527. + if (line[0] == '#')
  3528. + continue;
  3529. + nickname = line;
  3530. + if ((n = strcspn(line, " \t\n")) == 0)
  3531. + return NULL;
  3532. + line += n;
  3533. + *line++ = '\0';
  3534. + line += strspn(line, " \t");
  3535. + masterpath = line;
  3536. + if ((n = strcspn(line, " \t\n")) == 0)
  3537. + return NULL;
  3538. + line += n;
  3539. + *line++ = '\0';
  3540. + line += strspn(line, " \t\n");
  3541. + slavepath = "";
  3542. + syncprog = "";
  3543. + if (line[0] != '\0') {
  3544. + slavepath = line;
  3545. + n = strcspn(line, " \t\n");
  3546. + line += n;
  3547. + *line++ = '\0';
  3548. + if (line[0] != '\0') {
  3549. + syncprog = line;
  3550. + n = strcspn(line, " \t\n");
  3551. + line += n;
  3552. + *line++ = '\0';
  3553. + }
  3554. + }
  3555. + e = (cvsroot_type *)xmalloc(sizeof(cvsroot_type));
  3556. + e->nickname = xstrdup(nickname);
  3557. + e->masterpath = xstrdup(masterpath);
  3558. + e->slavepath = xstrdup(slavepath);
  3559. + e->syncprog = xstrdup(syncprog);
  3560. + break;
  3561. + }
  3562. + return e;
  3563. +}
  3564. +
  3565. +void
  3566. +cvsroot_entry_write(
  3567. + FILE *fp,
  3568. + cvsroot_type *e)
  3569. +{
  3570. + if (fp != NULL && e != NULL) {
  3571. + fprintf(fp, "%s %s",
  3572. + e->nickname, e->masterpath);
  3573. + if (e->slavepath[0] != '\0')
  3574. + fprintf(fp, " %s", e->slavepath);
  3575. + if (e->syncprog[0] != '\0')
  3576. + fprintf(fp, " %s", e->syncprog);
  3577. + fprintf(fp, "\n");
  3578. + }
  3579. + return;
  3580. +}
  3581. +
  3582. +cvsroot_type *
  3583. +cvsroot_lookup(
  3584. + char *by_nickname,
  3585. + char *by_masterpath,
  3586. + char *by_slavepath)
  3587. +{
  3588. + char *rootfile;
  3589. + cvsroot_type *e = NULL;
  3590. + FILE *fp;
  3591. +
  3592. + if ((rootfile = cvsroot_filename()) == NULL)
  3593. + return NULL;
  3594. + if ((fp = fopen(rootfile, "r")) == NULL) {
  3595. + free(rootfile);
  3596. + return NULL;
  3597. + }
  3598. + while ((e = cvsroot_entry_read(fp)) != NULL) {
  3599. + if ( (by_nickname != NULL && strcmp(e->nickname, by_nickname) == 0)
  3600. + || (by_masterpath != NULL && strcmp(e->masterpath, by_masterpath) == 0)
  3601. + || (by_slavepath != NULL && strcmp(e->slavepath, by_slavepath) == 0))
  3602. + break;
  3603. + cvsroot_free(e);
  3604. + }
  3605. + fclose(fp);
  3606. + free(rootfile);
  3607. + return e;
  3608. +}
  3609. +
  3610. +void
  3611. +cvsroot_synchronize(
  3612. + cvsroot_type *e,
  3613. + int force)
  3614. +{
  3615. + char *cmd;
  3616. + char *arg;
  3617. + char *rsh;
  3618. + int smart;
  3619. + char *syncprog;
  3620. +
  3621. + smart = 0;
  3622. + syncprog = e->syncprog;
  3623. + if (syncprog[0] == '-') {
  3624. + smart++;
  3625. + syncprog++;
  3626. + }
  3627. + if (smart && !force) {
  3628. + if (!really_quiet) {
  3629. + if (strcasecmp(syncprog, "manual") == 0) {
  3630. + fprintf(stderr, "%s: synchronize SLAVE with MASTER of repository `%s', please!\n", program_name, e->nickname);
  3631. + }
  3632. + else {
  3633. + fprintf(stderr, "%s: synchronize SLAVE with MASTER of repository `%s'\n", program_name, e->nickname);
  3634. + fprintf(stderr, "%s: by running the command `%s root -s %s', please.\n", program_name, program_name, e->nickname);
  3635. + }
  3636. + }
  3637. + return;
  3638. + }
  3639. +
  3640. + if (strcasecmp(syncprog, "manual") == 0) {
  3641. + if (!really_quiet) {
  3642. + fprintf(stderr, "%s: synchronizing SLAVE with MASTER of repository `%s'\n", program_name, e->nickname);
  3643. + fprintf(stderr, "%s: has to be performed manually by you!\n", program_name);
  3644. + }
  3645. + }
  3646. + else if (strcasecmp(syncprog, "rsync") == 0 ||
  3647. + strncasecmp(syncprog, "rsync:", 6) == 0) {
  3648. + if (!really_quiet) {
  3649. + fprintf(stderr, "%s: synchronizing SLAVE with MASTER of repository `%s':\n", program_name, e->nickname);
  3650. + fprintf(stderr, "%s: %s --> %s (rsync)\n", program_name, e->masterpath, e->slavepath);
  3651. + }
  3652. + run_setup("rsync");
  3653. + if (!quiet)
  3654. + run_arg("-v");
  3655. + if ((rsh = getenv("CVS_RSH")) != NULL) {
  3656. + arg = xmalloc(strlen(rsh)+7);
  3657. + strcpy(arg, "--rsh=");
  3658. + strcat(arg, rsh);
  3659. + run_arg(arg);
  3660. + free(arg);
  3661. + }
  3662. + run_arg("-rlpt");
  3663. + run_arg("--delete");
  3664. + if (strncasecmp(syncprog, "rsync:", 6) == 0) {
  3665. + char *list = xstrdup(syncprog+6);
  3666. + for (arg = strtok(list, ","); arg != NULL; arg = strtok(NULL, ",")) {
  3667. + if (arg[0] == '!') {
  3668. + run_arg("--exclude");
  3669. + run_arg(arg+1);
  3670. + }
  3671. + else {
  3672. + run_arg("--include");
  3673. + run_arg(arg);
  3674. + }
  3675. + }
  3676. + free(list);
  3677. + }
  3678. + arg = xmalloc(strlen(e->masterpath)+2);
  3679. + strcpy(arg, e->masterpath);
  3680. + strcat(arg, "/");
  3681. + run_arg(arg);
  3682. + free(arg);
  3683. + arg = xmalloc(strlen(e->slavepath)+2);
  3684. + strcpy(arg, e->slavepath);
  3685. + strcat(arg, "/");
  3686. + run_arg(arg);
  3687. + free(arg);
  3688. + if (trace) {
  3689. + cvs_output(program_name, 0);
  3690. + cvs_output(" ", 1);
  3691. + cvs_output(command_name, 0);
  3692. + cvs_output(": Executing ", 0);
  3693. + run_print(stdout);
  3694. + cvs_output("\n", 0);
  3695. + }
  3696. + if (run_exec(RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL) != 0)
  3697. + error(1, 0, "synchronization program `rsync' returned non-zero");
  3698. + }
  3699. + else {
  3700. + if (!really_quiet) {
  3701. + fprintf(stderr, "%s: synchronizing SLAVE with MASTER of repository `%s':\n", program_name, e->nickname);
  3702. + fprintf(stderr, "%s: %s --> %s (%s)\n", program_name, e->masterpath, e->slavepath, e->syncprog);
  3703. + }
  3704. + cmd = expand_path(syncprog, "sync", 0);
  3705. + run_setup(cmd);
  3706. + run_arg(e->nickname);
  3707. + run_arg(e->masterpath);
  3708. + run_arg(e->slavepath);
  3709. + if (trace) {
  3710. + cvs_output(program_name, 0);
  3711. + cvs_output(" ", 1);
  3712. + cvs_output(command_name, 0);
  3713. + cvs_output(": Executing ", 0);
  3714. + run_print(stdout);
  3715. + cvs_output("\n", 0);
  3716. + }
  3717. + if (run_exec(RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL) != 0)
  3718. + error(1, 0, "synchronization program `%s' returned non-zero", cmd);
  3719. + free(cmd);
  3720. + }
  3721. +}
  3722. +
  3723. +static const char *const root_usage[] = {
  3724. + "Usage: %s %s [-v] -e|-E|-l|s [arg ...]\n",
  3725. + "Options:\n",
  3726. + " -v Verbose mode.\n",
  3727. + " -e Edit entry from ~/.cvsroot in batch mode.\n",
  3728. + " -E Edit entry from ~/.cvsroot in visual mode.\n",
  3729. + " -l List entries from ~/.cvsroot.\n",
  3730. + " -s Synchronize entries from ~/.cvsroot.\n",
  3731. + "Synopsis:\n",
  3732. + " Add/Modify an entry:\n",
  3733. + " cvs root -e nickname masterpath [slavepath [syncprog]]\n",
  3734. + " Delete an entry:\n",
  3735. + " cvs root -e nickname\n",
  3736. + " List all or some particular entries:\n",
  3737. + " cvs [-Q] [-q] root [-v] -l [nickname ...]\n",
  3738. + " Synchronize all or some particular entries:\n",
  3739. + " cvs [-Q] [-q] root -s [nickname ...]\n",
  3740. + "(Specify the --help global option for a list of other help options)\n",
  3741. + NULL
  3742. +};
  3743. +
  3744. +int
  3745. +root(
  3746. + int argc,
  3747. + char **argv)
  3748. +{
  3749. + enum {
  3750. + ROOT_MODE_UNKNOWN,
  3751. + ROOT_MODE_EDIT_CMDLINE,
  3752. + ROOT_MODE_EDIT_VISUAL,
  3753. + ROOT_MODE_LIST,
  3754. + ROOT_MODE_SYNC
  3755. + };
  3756. + int mode = ROOT_MODE_UNKNOWN;
  3757. + char *rootfile;
  3758. + char *rootfilebak = NULL;
  3759. + FILE *fp;
  3760. + FILE *fpbak = NULL;
  3761. + int option;
  3762. + cvsroot_type *e;
  3763. + cvsroot_type E;
  3764. + int doit;
  3765. + int i;
  3766. + int rc;
  3767. + int verbose = 0;
  3768. + int found = 0;
  3769. + int oldexists;
  3770. +
  3771. + if (argc == -1)
  3772. + usage(root_usage);
  3773. + optind = 0;
  3774. + while ((option = getopt(argc, argv, "veEsl")) != EOF) {
  3775. + switch ((char)option) {
  3776. + case 'v':
  3777. + verbose = 1;
  3778. + break;
  3779. + case 'e':
  3780. + mode = ROOT_MODE_EDIT_CMDLINE;
  3781. + break;
  3782. + case 'E':
  3783. + mode = ROOT_MODE_EDIT_VISUAL;
  3784. + break;
  3785. + case 'l':
  3786. + mode = ROOT_MODE_LIST;
  3787. + break;
  3788. + case 's':
  3789. + mode = ROOT_MODE_SYNC;
  3790. + break;
  3791. + case '?':
  3792. + default:
  3793. + usage(root_usage);
  3794. + break;
  3795. + }
  3796. + }
  3797. + argc -= optind;
  3798. + argv += optind;
  3799. + if (mode == ROOT_MODE_UNKNOWN)
  3800. + error(1, 0, "exactly one of the -e, -E, -l or -s options have to given");
  3801. +
  3802. + if (mode == ROOT_MODE_EDIT_CMDLINE) {
  3803. + if (argc < 1 || argc > 4)
  3804. + error(1, 0, "option -e requires 1-4 arguments");
  3805. + E.nickname = argv[0];
  3806. + if (argc >= 2)
  3807. + E.masterpath = argv[1];
  3808. + else
  3809. + E.masterpath = "";
  3810. + if (argc >= 3)
  3811. + E.slavepath = argv[2];
  3812. + else
  3813. + E.slavepath = "";
  3814. + if (argc == 4)
  3815. + E.syncprog = argv[3];
  3816. + else
  3817. + E.syncprog = "";
  3818. + if ((rootfile = cvsroot_filename()) == NULL)
  3819. + return 0;
  3820. + oldexists = 0;
  3821. + if (isfile(rootfile)) {
  3822. + oldexists = 1;
  3823. + rootfilebak = xmalloc(strlen(rootfile)+5);
  3824. + strcpy(rootfilebak, rootfile);
  3825. + strcat(rootfilebak, ".bak");
  3826. + rename(rootfile, rootfilebak);
  3827. + if ((fpbak = fopen(rootfilebak, "r")) == NULL) {
  3828. + free(rootfile);
  3829. + free(rootfilebak);
  3830. + return 0;
  3831. + }
  3832. + }
  3833. + if ((fp = fopen(rootfile, "w")) == NULL) {
  3834. + fclose(fpbak);
  3835. + free(rootfile);
  3836. + free(rootfilebak);
  3837. + return 0;
  3838. + }
  3839. + if (oldexists) {
  3840. + found = 0;
  3841. + while ((e = cvsroot_entry_read(fpbak)) != NULL) {
  3842. + if (strcmp(e->nickname, E.nickname) == 0) {
  3843. + cvsroot_free(e);
  3844. + found = 1;
  3845. + break;
  3846. + }
  3847. + cvsroot_entry_write(fp, e);
  3848. + cvsroot_free(e);
  3849. + }
  3850. + }
  3851. + if (argc > 1)
  3852. + cvsroot_entry_write(fp, &E);
  3853. + if (oldexists) {
  3854. + if (found) {
  3855. + while ((e = cvsroot_entry_read(fpbak)) != NULL) {
  3856. + cvsroot_entry_write(fp, e);
  3857. + cvsroot_free(e);
  3858. + }
  3859. + }
  3860. + fclose(fpbak);
  3861. + }
  3862. + fclose(fp);
  3863. + }
  3864. + else if (mode == ROOT_MODE_EDIT_VISUAL) {
  3865. + if (argc != 0)
  3866. + error(1, 0, "option -E requires no arguments");
  3867. + if ((rootfile = cvsroot_filename()) == NULL)
  3868. + return 0;
  3869. + run_setup(Editor);
  3870. + run_arg(rootfile);
  3871. + if ((rc = run_exec(RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL|RUN_SIGIGNORE)) != 0)
  3872. + error (1, rc == -1 ? errno : 0, "warning: editor session failed");
  3873. + }
  3874. + else if (mode == ROOT_MODE_LIST || mode == ROOT_MODE_SYNC) {
  3875. + if ((rootfile = cvsroot_filename()) == NULL)
  3876. + return 0;
  3877. + if ((fp = fopen(rootfile, "r")) == NULL) {
  3878. + free(rootfile);
  3879. + return 0;
  3880. + }
  3881. + while ((e = cvsroot_entry_read(fp)) != NULL) {
  3882. + doit = 0;
  3883. + if (argc == 0)
  3884. + doit = 1;
  3885. + else {
  3886. + for (i = 0; i < argc; i++) {
  3887. + if (strcmp(argv[i], e->nickname) == 0) {
  3888. + doit = 1;
  3889. + break;
  3890. + }
  3891. + }
  3892. + }
  3893. + if (doit) {
  3894. + if (mode == ROOT_MODE_LIST) {
  3895. + if (verbose)
  3896. + fprintf(stdout, "Repository `%s':\n"
  3897. + " Master Path: %s\n"
  3898. + " Slave Path: %s\n"
  3899. + " Synchronize: %s\n",
  3900. + e->nickname, e->masterpath,
  3901. + e->slavepath, e->syncprog);
  3902. + else
  3903. + fprintf(stdout, "%s %s %s %s\n",
  3904. + e->nickname, e->masterpath,
  3905. + e->slavepath, e->syncprog);
  3906. + }
  3907. + else if (mode == ROOT_MODE_SYNC) {
  3908. + if (e->slavepath[0] == '\0' || e->syncprog[0] == '\0') {
  3909. + if (argc > 0)
  3910. + error(1, 0, "repository `%s' has no slave path or sync program defined", e->nickname);
  3911. + }
  3912. + else
  3913. + cvsroot_synchronize(e, 1);
  3914. + }
  3915. + }
  3916. + cvsroot_free(e);
  3917. + }
  3918. + fclose(fp);
  3919. + free(rootfile);
  3920. + }
  3921. + return 0;
  3922. +}
  3923. +
  3924. +
  3925. +#endif /* RSE_PATCH_CVSROOT */
  3926. +
  3927. Index: src/sanity.sh
  3928. ===================================================================
  3929. RCS file: /e/ossp/pkg/tool/cvs/cvs/cvs/src/sanity.sh,v
  3930. retrieving revision 1.1.1.4
  3931. diff -u -d -u -3 -r1.1.1.4 sanity.sh
  3932. --- src/sanity.sh 25 Apr 2001 22:30:56 -0000 1.1.1.4
  3933. +++ src/sanity.sh 16 Feb 2002 12:36:35 -0000
  3934. @@ -104,6 +104,7 @@
  3935. # "debugger"
  3936. #set -x
  3937. +echo '[THIS PROCEDURE TAKES APPROX. 25min ON A PII/400MHz, SO BE PATIENT!]'
  3938. echo 'This test should produce no other output than this line, and a final "OK".'
  3939. # Regexp to match what CVS will call itself in output that it prints.
  3940. @@ -8517,11 +8518,13 @@
  3941. ############################################################
  3942. # Check out the whole repository
  3943. mkdir 1; cd 1
  3944. - dotest modules-1 "${testcvs} -q co ." 'U CVSROOT/checkoutlist
  3945. + dotest modules-1 "${testcvs} -q co ." 'U CVSROOT/admininfo
  3946. +U CVSROOT/checkoutlist
  3947. U CVSROOT/commitinfo
  3948. U CVSROOT/config
  3949. U CVSROOT/cvswrappers
  3950. U CVSROOT/editinfo
  3951. +U CVSROOT/importinfo
  3952. U CVSROOT/loginfo
  3953. U CVSROOT/modules
  3954. U CVSROOT/notify
  3955. @@ -8541,11 +8544,13 @@
  3956. ############################################################
  3957. # Check out CVSROOT
  3958. mkdir 1; cd 1
  3959. - dotest modules-2 "${testcvs} -q co CVSROOT" 'U CVSROOT/checkoutlist
  3960. + dotest modules-2 "${testcvs} -q co CVSROOT" 'U CVSROOT/admininfo
  3961. +U CVSROOT/checkoutlist
  3962. U CVSROOT/commitinfo
  3963. U CVSROOT/config
  3964. U CVSROOT/cvswrappers
  3965. U CVSROOT/editinfo
  3966. +U CVSROOT/importinfo
  3967. U CVSROOT/loginfo
  3968. U CVSROOT/modules
  3969. U CVSROOT/notify
  3970. @@ -8568,11 +8573,13 @@
  3971. mkdir 1; cd 1
  3972. dotest modules-3 "${testcvs} -q co somedir" ''
  3973. cd somedir
  3974. - dotest modules-3d "${testcvs} -q co CVSROOT" 'U CVSROOT/checkoutlist
  3975. + dotest modules-3d "${testcvs} -q co CVSROOT" 'U CVSROOT/admininfo
  3976. +U CVSROOT/checkoutlist
  3977. U CVSROOT/commitinfo
  3978. U CVSROOT/config
  3979. U CVSROOT/cvswrappers
  3980. U CVSROOT/editinfo
  3981. +U CVSROOT/importinfo
  3982. U CVSROOT/loginfo
  3983. U CVSROOT/modules
  3984. U CVSROOT/notify
  3985. @@ -18230,7 +18237,7 @@
  3986. add a line on trunk after trunktag"
  3987. # But diff thinks that HEAD is "br1". Case (b) from cvs.texinfo.
  3988. # Probably people are relying on it.
  3989. - dotest head-br1-diff "${testcvs} -q diff -c -r HEAD -r br1" ""
  3990. + #RSE# dotest head-br1-diff "${testcvs} -q diff -c -r HEAD -r br1" ""
  3991. # With a nonbranch sticky tag on a branch,
  3992. # HEAD is the head of the trunk
  3993. Index: src/server.c
  3994. ===================================================================
  3995. RCS file: /e/ossp/pkg/tool/cvs/cvs/cvs/src/server.c,v
  3996. retrieving revision 1.1.1.4
  3997. diff -u -d -u -3 -r1.1.1.4 server.c
  3998. --- src/server.c 19 Apr 2001 19:34:04 -0000 1.1.1.4
  3999. +++ src/server.c 16 Feb 2002 12:36:09 -0000
  4000. @@ -117,6 +117,13 @@
  4001. # endif /* AUTH_SERVER_SUPPORT */
  4002. +#ifdef RSE_PATCH_PSERVERD
  4003. +#include <sys/ioctl.h>
  4004. +#include <netinet/in.h>
  4005. +#include <arpa/inet.h>
  4006. +#include <netdb.h>
  4007. +#endif
  4008. +
  4009. /* While processing requests, this buffer accumulates data to be sent to
  4010. the client, and then once we are in do_cvs_command, we use it
  4011. @@ -734,6 +741,13 @@
  4012. if (error_pending()) return;
  4013. +#ifdef RSE_PATCH_MAPROOT
  4014. + {
  4015. + char *argnew;
  4016. + if (root_map_it(arg, &argnew, 0))
  4017. + arg = argnew;
  4018. + }
  4019. +#endif
  4020. if (!isabsolute (arg))
  4021. {
  4022. if (alloc_pending (80 + strlen (arg)))
  4023. @@ -1155,6 +1169,9 @@
  4024. char *repos;
  4025. status = buf_read_line (buf_from_net, &repos, (int *) NULL);
  4026. +#ifdef RSE_PATCH_MAPROOT
  4027. + root_map_it(repos, &repos, 1);
  4028. +#endif
  4029. if (status == 0)
  4030. {
  4031. if (!outside_root (repos))
  4032. @@ -2181,6 +2198,11 @@
  4033. case 'n':
  4034. noexec = 1;
  4035. break;
  4036. +#ifdef RSE_PATCH_NOLOCK
  4037. + case 'u':
  4038. + nolock = 1;
  4039. + break;
  4040. +#endif
  4041. case 'q':
  4042. quiet = 1;
  4043. break;
  4044. @@ -3916,6 +3938,17 @@
  4045. }
  4046. /* See server.h for description. */
  4047. +#ifdef RSE_PATCH_RLIST
  4048. +static void serve_list PROTO ((char *));
  4049. +static void
  4050. +serve_list (arg)
  4051. + char *arg;
  4052. +{
  4053. + if (print_pending_error())
  4054. + return;
  4055. + do_cvs_command("rlist", cvslist);
  4056. +}
  4057. +#endif
  4058. void
  4059. server_modtime (finfo, vers_ts)
  4060. @@ -4770,6 +4803,9 @@
  4061. REQ_LINE("expand-modules", serve_expand_modules, 0),
  4062. REQ_LINE("ci", serve_ci, RQ_ESSENTIAL),
  4063. REQ_LINE("co", serve_co, RQ_ESSENTIAL),
  4064. +#ifdef RSE_PATCH_RLIST
  4065. + REQ_LINE("rlist", serve_list, 0),
  4066. +#endif
  4067. REQ_LINE("update", serve_update, RQ_ESSENTIAL),
  4068. REQ_LINE("diff", serve_diff, 0),
  4069. REQ_LINE("log", serve_log, 0),
  4070. @@ -5351,8 +5387,13 @@
  4071. {
  4072. char *env, *cvs_user;
  4073. +#if defined(RSE_PATCH_LOGNAME) && defined(AUTH_SERVER_SUPPORT)
  4074. + env = xmalloc (sizeof "LOGNAME=" + strlen (CVS_Username));
  4075. + (void) sprintf (env, "LOGNAME=%s", CVS_Username);
  4076. +#else
  4077. env = xmalloc (sizeof "LOGNAME=" + strlen (username));
  4078. (void) sprintf (env, "LOGNAME=%s", username);
  4079. +#endif
  4080. (void) putenv (env);
  4081. env = xmalloc (sizeof "USER=" + strlen (username));
  4082. @@ -5430,6 +5471,13 @@
  4083. found_it = 1;
  4084. break;
  4085. }
  4086. +#ifdef RSE_PATCH_WILDPASSWD
  4087. + if (strncmp(linebuf, "*:", 2) == 0) {
  4088. + found_it = 1;
  4089. + namelen = 1;
  4090. + break;
  4091. + }
  4092. +#endif
  4093. }
  4094. if (ferror (fp))
  4095. error (0, errno, "cannot read %s", filename);
  4096. @@ -5473,10 +5521,14 @@
  4097. /* Okay, after this conditional chain, found_password and
  4098. host_user_tmp will have useful values: */
  4099. +#ifdef RSE_PATCH_WILDPASSWD
  4100. + if (non_cvsuser_portion[strspn(non_cvsuser_portion, " \t")] == '\0')
  4101. +#else
  4102. if ((non_cvsuser_portion == NULL)
  4103. || (strlen (non_cvsuser_portion) == 0)
  4104. || ((strspn (non_cvsuser_portion, " \t"))
  4105. == strlen (non_cvsuser_portion)))
  4106. +#endif
  4107. {
  4108. found_password = NULL;
  4109. host_user_tmp = NULL;
  4110. @@ -5507,6 +5559,14 @@
  4111. *host_user_ptr = xstrdup (host_user_tmp);
  4112. retval = 1;
  4113. }
  4114. +#ifdef RSE_PATCH_WILDPASSWD
  4115. + else if (strcmp(found_password, "*") == 0)
  4116. + {
  4117. + /* Give host_user_ptr permanent storage. */
  4118. + *host_user_ptr = xstrdup(host_user_tmp);
  4119. + retval = -1;
  4120. + }
  4121. +#endif
  4122. else
  4123. {
  4124. *host_user_ptr = NULL;
  4125. @@ -5552,7 +5612,11 @@
  4126. /* host_user already set by reference, so just return. */
  4127. goto handle_return;
  4128. }
  4129. +#ifdef RSE_PATCH_WILDPASSWD
  4130. + else if (rc == -1 || system_auth)
  4131. +#else
  4132. else if (rc == 0 && system_auth)
  4133. +#endif
  4134. {
  4135. /* No cvs password found, so try /etc/passwd. */
  4136. @@ -5594,15 +5658,30 @@
  4137. if (*found_passwd)
  4138. {
  4139. /* user exists and has a password */
  4140. +#ifdef RSE_PATCH_WILDPASSWD
  4141. + if (strcmp (found_passwd, crypt (password, found_passwd)) != 0) {
  4142. + if (host_user != NULL) {
  4143. + free (host_user);
  4144. + host_user = NULL;
  4145. + }
  4146. + }
  4147. + else if (host_user == NULL) {
  4148. + host_user = xstrdup (username);
  4149. + }
  4150. +#else
  4151. host_user = ((! strcmp (found_passwd,
  4152. crypt (password, found_passwd)))
  4153. ? xstrdup (username) : NULL);
  4154. +#endif
  4155. goto handle_return;
  4156. }
  4157. else if (password && *password)
  4158. {
  4159. /* user exists and has no system password, but we got
  4160. one as parameter */
  4161. +#ifdef RSE_PATCH_WILDPASSWD
  4162. + if (host_user == NULL)
  4163. +#endif
  4164. host_user = xstrdup (username);
  4165. goto handle_return;
  4166. }
  4167. @@ -5613,7 +5692,11 @@
  4168. goto handle_return;
  4169. }
  4170. }
  4171. +#ifdef RSE_PATCH_WILDPASSWD
  4172. + else
  4173. +#else
  4174. else if (rc == 0)
  4175. +#endif
  4176. {
  4177. /* Note that the message _does_ distinguish between the case in
  4178. which we check for a system password and the case in which
  4179. @@ -5634,6 +5717,7 @@
  4180. #endif
  4181. exit (EXIT_FAILURE);
  4182. }
  4183. +#ifndef RSE_PATCH_WILDPASSWD
  4184. else
  4185. {
  4186. /* Something strange happened. We don't know what it was, but
  4187. @@ -5641,6 +5725,7 @@
  4188. host_user = NULL;
  4189. goto handle_return;
  4190. }
  4191. +#endif
  4192. handle_return:
  4193. if (host_user)
  4194. @@ -5778,6 +5863,10 @@
  4195. strip_trailing_newlines (username);
  4196. strip_trailing_newlines (password);
  4197. +#ifdef RSE_PATCH_MAPROOT
  4198. + root_map_it(repository, &repository, 0);
  4199. +#endif
  4200. +
  4201. /* ... and make sure the protocol ends on the right foot. */
  4202. /* See above comment about error handling. */
  4203. getline_safe (&tmp, &tmp_allocated, stdin, PATH_MAX);
  4204. @@ -6611,3 +6700,520 @@
  4205. cvs_output (text, 0);
  4206. }
  4207. }
  4208. +
  4209. +#ifdef RSE_PATCH_PSERVERD
  4210. +
  4211. +/* ========================================================================= */
  4212. +
  4213. +#if !defined(SIGCHLD) && defined(SIGCLD)
  4214. +#define SIGCHLD SIGCLD
  4215. +#endif
  4216. +
  4217. +static void pserver_handshake(void);
  4218. +
  4219. +/*
  4220. + * Main procedure stub. This is called in two contexts: first under "cvs
  4221. + * -H pserverd" where we just display the usage; second inside the CVS
  4222. + * main loop where we have to act as the regular "cvs server".
  4223. + */
  4224. +
  4225. +static const char *const pserverd_usage[] = {
  4226. + "Usage: %s %s [-v] [-d] [-l addr[:port]] [-p pidfile] [-A user] [-R user:repos:chroot]\n",
  4227. + "\t-v\tVerbose mode.\n",
  4228. + "\t-d\tDetach into background and run as a daemon.\n",
  4229. + "\t-l\tListen to a particular address/port.\n",
  4230. + "\t-p\tWrite the daemon's PID to a file.\n",
  4231. + "\t-A\tForce global -l -n -u options for a particular user.\n",
  4232. + "\t-R\tPerform a chroot(2) for a user/repository pair.\n",
  4233. + "(Specify the --help global option for a list of other help options)\n",
  4234. + NULL
  4235. +};
  4236. +
  4237. +int
  4238. +pserverd(
  4239. + int argc,
  4240. + char **argv)
  4241. +{
  4242. + if (argc == -1)
  4243. + usage(pserverd_usage);
  4244. + return server(argc, argv);
  4245. +}
  4246. +
  4247. +/*
  4248. + * The pserver daemon. This listens on a particular TCP/IP socket for
  4249. + * connections. If one occurs, it forks and returns to the caller inside
  4250. + * the child process. The parent process runs forever.
  4251. + */
  4252. +
  4253. +static struct {
  4254. + char *user;
  4255. + char *repos;
  4256. + char *chroot;
  4257. +} pserver_chroot;
  4258. +
  4259. +static char *pserverd_anonymous_user = NULL;
  4260. +static int pserverd_verbose = 0;
  4261. +
  4262. +static int
  4263. +tcp_setinaddr(
  4264. + struct sockaddr_in *addr,
  4265. + const char *host,
  4266. + const char *service,
  4267. + const char *protocol)
  4268. +{
  4269. + struct hostent *hp;
  4270. + char *end;
  4271. + long portno;
  4272. + struct servent *serv;
  4273. +
  4274. + memset(addr, 0, sizeof *addr);
  4275. + addr->sin_family = AF_INET;
  4276. +
  4277. + /* set host part of address */
  4278. + if (host == NULL)
  4279. + addr->sin_addr.s_addr = INADDR_ANY;
  4280. + else {
  4281. + addr->sin_addr.s_addr = inet_addr(host);
  4282. + if (addr->sin_addr.s_addr == (unsigned long) -1) {
  4283. + if ((hp = gethostbyname(host)) == NULL)
  4284. + return -1;
  4285. + memcpy(&addr->sin_addr, hp->h_addr, hp->h_length);
  4286. + addr->sin_family = hp->h_addrtype;
  4287. + }
  4288. + }
  4289. +
  4290. + /* set port part of address */
  4291. + if (service == NULL)
  4292. + addr->sin_port = htons(0);
  4293. + else {
  4294. + portno = strtol(service, &end, 10);
  4295. + if (portno > 0 && portno <= 65535 && end != service && *end == '\0')
  4296. + addr->sin_port = htons(portno);
  4297. + else {
  4298. + if ((serv = getservbyname(service, protocol)) == NULL)
  4299. + return -1;
  4300. + addr->sin_port = serv->s_port;
  4301. + }
  4302. + }
  4303. + return 0;
  4304. +}
  4305. +
  4306. +static int
  4307. +tcp_listen(
  4308. + const char *host,
  4309. + const char *port)
  4310. +{
  4311. + int s;
  4312. + struct protoent *proto;
  4313. + struct sockaddr_in server;
  4314. + int yes = 1;
  4315. +
  4316. + if (tcp_setinaddr(&server, host, port, "tcp") < 0)
  4317. + return -1;
  4318. + if ((proto = getprotobyname("tcp")) == NULL)
  4319. + return -1;
  4320. + if ((s = socket(PF_INET, SOCK_STREAM, proto->p_proto)) < 0)
  4321. + return -1;
  4322. + setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&yes, sizeof(yes));
  4323. + if (bind(s, (struct sockaddr *)&server, sizeof(server)) < 0) {
  4324. + close(s);
  4325. + return -1;
  4326. + }
  4327. + if (listen(s, 256) < 0) {
  4328. + close(s);
  4329. + return -1;
  4330. + }
  4331. + return s;
  4332. +}
  4333. +
  4334. +static int
  4335. +proc_daemon(
  4336. + int nochdir,
  4337. + int noclose)
  4338. +{
  4339. + int fd;
  4340. + int rc;
  4341. +
  4342. + /*
  4343. + * Ignore tty related signals
  4344. + */
  4345. +#ifdef SIGTTOU
  4346. + signal(SIGTTOU, SIG_IGN);
  4347. +#endif
  4348. +#ifdef SIGTTIN
  4349. + signal(SIGTTIN, SIG_IGN);
  4350. +#endif
  4351. +#ifdef SIGTSTP
  4352. + signal(SIGTSTP, SIG_IGN);
  4353. +#endif
  4354. +
  4355. + /*
  4356. + * fork so the parent can exit, this returns control to the command line
  4357. + * or shell invoking your program. This step is required so that the new
  4358. + * process is guaranteed not to be a process group leader (The next step,
  4359. + * setsid, would fail if you're a process group leader).
  4360. + */
  4361. + rc = fork();
  4362. + switch (rc) {
  4363. + case -1: return -1;
  4364. + case 0: break;
  4365. + default: _exit(0); /* exit original process */
  4366. + }
  4367. +
  4368. + /*
  4369. + * setsid to become a process group and session group leader. Since a
  4370. + * controlling terminal is associated with a session, and this new session
  4371. + * has not yet acquired a controlling terminal our process now has no
  4372. + * controlling terminal, which is a Good Thing for daemons.
  4373. + */
  4374. +#ifdef HAVE_SETSID
  4375. + if (setsid() == -1)
  4376. + return -1;
  4377. +#else
  4378. + if (setpgid(0, getpid()) == -1)
  4379. + return -1;
  4380. +#ifndef _PATH_TTY
  4381. +#define _PATH_TTY "/dev/tty"
  4382. +#endif
  4383. + if ((fd = open(_PATH_TTY, O_RDWR)) == -1)
  4384. + return -1;
  4385. + ioctl(fd, TIOCNOTTY, NULL);
  4386. + close(fd);
  4387. +#endif
  4388. +
  4389. + /*
  4390. + * fork again so the parent, (the session group leader), can exit. This
  4391. + * means that we, as a non-session group leader, can never regain a
  4392. + * controlling terminal.
  4393. + */
  4394. + rc = fork();
  4395. + switch (rc) {
  4396. + case -1: return -1;
  4397. + case 0: break;
  4398. + default: _exit(0); /* exit original process */
  4399. + }
  4400. +
  4401. + /*
  4402. + * chdir("/") to ensure that our process doesn't keep any directory in
  4403. + * use. Failure to do this could make it so that an administrator couldn't
  4404. + * unmount a filesystem, because it was our current directory.
  4405. + * [Equivalently, we could change to any directory containing files
  4406. + * important to the daemon's operation.]
  4407. + */
  4408. + if (!nochdir)
  4409. + chdir("/");
  4410. +
  4411. + /*
  4412. + * give us complete control over the permissions of anything we write. We
  4413. + * don't know what umask we may have inherited. [This step is optional]
  4414. + */
  4415. + umask(0);
  4416. +
  4417. + /*
  4418. + * close fds 0, 1, and 2. This releases the standard in, out, and error we
  4419. + * inherited from our parent process. We have no way of knowing where
  4420. + * these fds might have been redirected to.
  4421. + */
  4422. + if (!noclose && (fd = open("/dev/null", O_RDWR, 0)) != -1) {
  4423. + dup2(fd, STDIN_FILENO);
  4424. + dup2(fd, STDOUT_FILENO);
  4425. + dup2(fd, STDERR_FILENO);
  4426. + if (fd > 2)
  4427. + close(fd);
  4428. + }
  4429. + return 0;
  4430. +}
  4431. +
  4432. +static void
  4433. +pserver_daemon_reapchild(
  4434. + int signo)
  4435. +{
  4436. + pid_t child;
  4437. + int status;
  4438. + char buf[128];
  4439. +
  4440. + while ((child = waitpid(-1, &status, WNOHANG)) > (pid_t)0) {
  4441. + if (pserverd_verbose) {
  4442. + sprintf(buf, "cvs pserverd[%ld]: child process (pid %ld): terminated.\n",
  4443. + (long)getpid(), (long)child);
  4444. + write(STDOUT_FILENO, buf, strlen(buf));
  4445. + }
  4446. + }
  4447. + signal(signo, &pserver_daemon_reapchild);
  4448. + return;
  4449. +}
  4450. +
  4451. +int
  4452. +pserver_daemon(
  4453. + int argc,
  4454. + char **argv)
  4455. +{
  4456. + int sd;
  4457. + pid_t child;
  4458. + int option;
  4459. + char *host = NULL;
  4460. + char *port = "2401";
  4461. + char *listen = NULL;
  4462. + struct sockaddr_in them;
  4463. + int detach = 0;
  4464. + char *pidfile = NULL;
  4465. + FILE *fp;
  4466. + char *cp;
  4467. + int len;
  4468. + int ns;
  4469. +
  4470. + /* make sure we are running with root priviledges, because
  4471. + we need it later for chroot, switch_to_user, etc. */
  4472. + if (geteuid() != 0)
  4473. + error(1, 0, "root priviledges required for pserver operation");
  4474. +
  4475. + /* process "cvs pserverd" command options */
  4476. + optind = 0;
  4477. + while ((option = getopt(argc, argv, "vl:dp:A:R:")) != EOF) {
  4478. + switch ((char) option) {
  4479. + case 'v':
  4480. + pserverd_verbose = 1;
  4481. + break;
  4482. + case 'l':
  4483. + listen = xstrdup(optarg);
  4484. + break;
  4485. + case 'd':
  4486. + detach = 1;
  4487. + pserverd_verbose = 0;
  4488. + break;
  4489. + case 'p':
  4490. + pidfile = xstrdup(optarg);
  4491. + break;
  4492. + case 'A':
  4493. + pserverd_anonymous_user = xstrdup(optarg);
  4494. + break;
  4495. + case 'R':
  4496. + cp = xstrdup(optarg);
  4497. + pserver_chroot.user = cp;
  4498. + if ((cp = strchr(cp, ':')) == NULL)
  4499. + error(1, 0, "invalid -R option argument");
  4500. + *cp++ = '\0';
  4501. + pserver_chroot.repos = cp;
  4502. + if ((cp = strchr(cp, ':')) == NULL)
  4503. + error(1, 0, "invalid -R option argument");
  4504. + *cp++ = '\0';
  4505. + pserver_chroot.chroot = cp;
  4506. + break;
  4507. + case '?':
  4508. + default:
  4509. + usage(pserverd_usage);
  4510. + break;
  4511. + }
  4512. + }
  4513. + argc -= optind;
  4514. + argv += optind;
  4515. + if (argc < 0)
  4516. + usage(pserverd_usage);
  4517. +
  4518. + /* optionally go into the background as a real daemon */
  4519. + if (detach)
  4520. + proc_daemon(0, 0);
  4521. +
  4522. + /* optionally write out the pid */
  4523. + if (pidfile != NULL) {
  4524. + if ((fp = fopen(pidfile, "w")) == NULL)
  4525. + error(1, 0, "unable to write pid to file %s: %s",
  4526. + pidfile, strerror(errno));
  4527. + fprintf(fp, "%ld\n", (long)getpid());
  4528. + fclose(fp);
  4529. + }
  4530. +
  4531. + /* listen on the TCP/IP socket */
  4532. + if (listen != NULL) {
  4533. + if ((port = strrchr(listen, ':')) != NULL)
  4534. + *(port++) = '\0';
  4535. + if (strcasecmp(listen, "*") == 0 || strcmp(listen, "0.0.0.0") == 0)
  4536. + host = NULL;
  4537. + else
  4538. + host = listen;
  4539. + }
  4540. + if ((sd = tcp_listen(host, port)) < 0)
  4541. + error(1, 0, "unable to listen (%s:%s): %s",
  4542. + host != NULL ? host : "*", port, strerror(errno));
  4543. +
  4544. + /* make sure we reap the childs */
  4545. + signal(SIGCHLD, &pserver_daemon_reapchild);
  4546. +
  4547. + /* daemon loop */
  4548. + for (;;) {
  4549. + len = sizeof(them);
  4550. + ns = accept(sd, (struct sockaddr *)&them, &len);
  4551. + if (ns < 0) {
  4552. + if (errno == EINTR)
  4553. + continue;
  4554. + error(1, 0, "accept(2) failed: %s", strerror(errno));
  4555. + }
  4556. + switch (child = fork()) {
  4557. + case -1:
  4558. + error(1, 0, "unable to fork(2): %s", strerror(errno));
  4559. + break;
  4560. + case 0:
  4561. + /* child */
  4562. + close(sd);
  4563. + signal(SIGCHLD, SIG_DFL);
  4564. +
  4565. + /* connect stdin/stdout to socket */
  4566. + dup2(ns, STDIN_FILENO);
  4567. + dup2(ns, STDOUT_FILENO);
  4568. +
  4569. + /*
  4570. + * perform "cvs pserver" authentication handshake.
  4571. + */
  4572. + pserver_handshake();
  4573. +
  4574. + /*
  4575. + * just return to caller, i.e., the main() procedure
  4576. + * which in turn will dispatch into "cvs server" code
  4577. + * for us...
  4578. + */
  4579. + return 0;
  4580. + break;
  4581. + default:
  4582. + /* parent */
  4583. + if (pserverd_verbose)
  4584. + fprintf(stderr, "cvs pserverd[%ld]: child process (pid %ld): started.\n",
  4585. + (long)getpid(), (long)child);
  4586. + close(ns);
  4587. + break;
  4588. + }
  4589. + }
  4590. + exit(0);
  4591. + return 0;
  4592. +}
  4593. +
  4594. +static void
  4595. +pserver_handshake(
  4596. + void)
  4597. +{
  4598. + char *tmp = NULL;
  4599. + size_t tmp_allocated = 0;
  4600. + char *repository = NULL;
  4601. + size_t repository_allocated = 0;
  4602. + char *username = NULL;
  4603. + size_t username_allocated = 0;
  4604. + char *password = NULL;
  4605. + size_t password_allocated = 0;
  4606. + char *host_user = NULL;
  4607. + char *descrambled_password;
  4608. + int verify_and_exit = 0;
  4609. + char *chrootdir = NULL;
  4610. + int on;
  4611. +
  4612. +#ifdef SO_KEEPALIVE
  4613. + /* Set SO_KEEPALIVE on the socket, so that we don't hang forever
  4614. + if the client dies while we are waiting for input. */
  4615. + on = 1;
  4616. + (void)setsockopt(STDIN_FILENO, SOL_SOCKET, SO_KEEPALIVE,
  4617. + (char *)&on, sizeof(on));
  4618. +#endif
  4619. +
  4620. + /* Make sure the protocol starts off on the right foot... */
  4621. + getline(&tmp, &tmp_allocated, stdin);
  4622. +
  4623. + if (strcmp (tmp, "BEGIN VERIFICATION REQUEST\n") == 0)
  4624. + verify_and_exit = 1;
  4625. + else if (strcmp (tmp, "BEGIN AUTH REQUEST\n") == 0)
  4626. + ;
  4627. + else
  4628. + error (1, 0, "bad auth protocol start: %s", tmp);
  4629. +
  4630. + /* Get the three important pieces of information in order. */
  4631. + getline(&repository, &repository_allocated, stdin);
  4632. + getline(&username, &username_allocated, stdin);
  4633. + getline(&password, &password_allocated, stdin);
  4634. +
  4635. + /* Make them pure. */
  4636. + strip_trailing_newlines(repository);
  4637. + strip_trailing_newlines(username);
  4638. + strip_trailing_newlines(password);
  4639. +
  4640. +#ifdef RSE_PATCH_MAPROOT
  4641. + root_map_it(repository, &repository, 0);
  4642. +#endif
  4643. +
  4644. + /* ... and make sure the protocol ends on the right foot. */
  4645. + getline(&tmp, &tmp_allocated, stdin);
  4646. + if (strcmp (tmp, verify_and_exit ?
  4647. + "END VERIFICATION REQUEST\n" : "END AUTH REQUEST\n") != 0)
  4648. + error (1, 0, "bad auth protocol end: %s", tmp);
  4649. +
  4650. + if (!root_allow_ok(repository))
  4651. + goto i_hate_you;
  4652. + parse_config(repository);
  4653. +
  4654. + /* We need the real cleartext before we hash it. */
  4655. + descrambled_password = descramble(password);
  4656. + host_user = check_password(username, descrambled_password, repository);
  4657. + memset(descrambled_password, 0, strlen(descrambled_password));
  4658. + free(descrambled_password);
  4659. +
  4660. + if (host_user == NULL) {
  4661. + i_hate_you:
  4662. + printf("I HATE YOU\n");
  4663. + fflush(stdout);
  4664. + if (pserverd_verbose)
  4665. + fprintf(stderr, "cvs pserverd[%ld]: status=FAILED user=%s root=%s\n",
  4666. + (long)getpid(), username, repository);
  4667. + error_exit();
  4668. + }
  4669. +
  4670. + /* Don't go any farther if we're just responding to "cvs login". */
  4671. + if (verify_and_exit) {
  4672. + printf("I LOVE YOU\n");
  4673. + fflush(stdout);
  4674. + if (pserverd_verbose)
  4675. + fprintf(stderr, "cvs pserverd[%ld]: status=OK user=%s root=%s (huser=%s)\n",
  4676. + (long)getpid(), username, repository, host_user);
  4677. + exit(0);
  4678. + }
  4679. +
  4680. + /* Set Pserver_Repos so that we can check later that the same
  4681. + repository is sent in later client/server protocol. */
  4682. + Pserver_Repos = xmalloc(strlen(repository)+1);
  4683. + strcpy(Pserver_Repos, repository);
  4684. +
  4685. + /* Optionally perform a chroot */
  4686. + if (pserver_chroot.user != NULL) {
  4687. + if ( strcmp(username, pserver_chroot.user) == 0
  4688. + && ( strcmp(repository, pserver_chroot.repos) == 0
  4689. + || strcmp(pserver_chroot.repos, "*") == 0 )) {
  4690. + chrootdir = pserver_chroot.chroot;
  4691. + if (chdir(chrootdir) == -1)
  4692. + error(1, 0, "failed to chdir(2) to %s: %s", chrootdir, strerror(errno));
  4693. + if (chroot(chrootdir) == -1)
  4694. + error(1, 0, "failed to chroot(2) to %s: %s", chrootdir, strerror(errno));
  4695. + }
  4696. + }
  4697. +
  4698. + /* Additionally switch to read-only mode for anonymous user */
  4699. + if (pserverd_anonymous_user != NULL) {
  4700. + if (strcmp(username, pserverd_anonymous_user) == 0) {
  4701. +#ifdef RSE_PATCH_NOLOCK
  4702. + nolock = 1;
  4703. +#endif
  4704. + logoff = 1;
  4705. + }
  4706. + }
  4707. +
  4708. + /* Switch to run as this user. */
  4709. + switch_to_user(host_user);
  4710. + free(tmp);
  4711. + free(repository);
  4712. + free(username);
  4713. + free(password);
  4714. +
  4715. + printf("I LOVE YOU\n");
  4716. + fflush(stdout);
  4717. + if (pserverd_verbose)
  4718. + fprintf(stderr, "cvs pserverd[%ld]: status=OK user=%s root=%s (huser=%s hroot=%s)\n",
  4719. + (long)getpid(), username, repository, host_user, chrootdir != NULL ? chrootdir : "/");
  4720. + return;
  4721. +}
  4722. +
  4723. +#endif /* RSE_PATCH_PSERVERD */
  4724. +
  4725. Index: src/subr.c
  4726. ===================================================================
  4727. RCS file: /e/ossp/pkg/tool/cvs/cvs/cvs/src/subr.c,v
  4728. retrieving revision 1.1.1.4
  4729. diff -u -d -u -3 -r1.1.1.4 subr.c
  4730. --- src/subr.c 19 Apr 2001 19:34:04 -0000 1.1.1.4
  4731. +++ src/subr.c 16 Feb 2002 13:49:47 -0000
  4732. @@ -336,6 +336,22 @@
  4733. uid_t uid;
  4734. #endif
  4735. +#ifdef RSE_PATCH_CVSUSER
  4736. +#ifndef RSE_PATCH_CVSUSER_CALLER
  4737. +#define RSE_PATCH_CVSUSER_CALLER "cvs"
  4738. +#endif
  4739. + uid = getuid();
  4740. + if ((pw = (struct passwd *)getpwnam(RSE_PATCH_CVSUSER_CALLER)) != NULL) {
  4741. + if (pw->pw_uid == uid) {
  4742. + char *name;
  4743. + if ((name = getenv("CVSUSER")) != NULL) {
  4744. + cache = xstrdup(name);
  4745. + return cache;
  4746. + }
  4747. + }
  4748. + }
  4749. +#endif
  4750. +
  4751. /* If there is a CVS username, return it. */
  4752. #ifdef AUTH_SERVER_SUPPORT
  4753. if (CVS_Username != NULL)
  4754. @@ -797,6 +813,73 @@
  4755. return backup_name;
  4756. }
  4757. +
  4758. +#ifdef RSE_PATCH_HANDLE
  4759. +/* handle: 2000041317203601
  4760. + date1: 2000/04/13 17:20:36
  4761. + date2: 2000/04/13 17:20:37 */
  4762. +int handle2dates(char *handle, time_t *t1, time_t *t2)
  4763. +{
  4764. + int Y,M,D,h,m,s,o;
  4765. + char buf[17];
  4766. + time_t t;
  4767. + struct tm tm;
  4768. + int rev = 0;
  4769. + int i;
  4770. +
  4771. + /* check for correct handle format */
  4772. + if (handle == NULL)
  4773. + return 0;
  4774. + if (handle[0] == '!') {
  4775. + handle++;
  4776. + rev = 1;
  4777. + }
  4778. + if (strlen(handle) != 16)
  4779. + return 0;
  4780. + for (i = 0; i < 16; i++)
  4781. + if (!isdigit(handle[i]))
  4782. + return 0;
  4783. +
  4784. + /* parse out handle parts */
  4785. + strcpy(buf, handle);
  4786. + o = atoi(buf+14);
  4787. + buf[14] = '\0';
  4788. + s = atoi(buf+12);
  4789. + buf[12] = '\0';
  4790. + m = atoi(buf+10);
  4791. + buf[10] = '\0';
  4792. + h = atoi(buf+8);
  4793. + buf[8] = '\0';
  4794. + D = atoi(buf+6);
  4795. + buf[6] = '\0';
  4796. + M = atoi(buf+4);
  4797. + buf[4] = '\0';
  4798. + Y = atoi(buf);
  4799. +
  4800. + /* assemble parts into a time value */
  4801. + memset(&tm, 0, sizeof tm);
  4802. + tm.tm_sec = s;
  4803. + tm.tm_min = m;
  4804. + tm.tm_hour = h;
  4805. + tm.tm_mday = D;
  4806. + tm.tm_mon = M - 1;
  4807. + tm.tm_year = Y - 1900;
  4808. + t = mktime(&tm);
  4809. + if (t == -1)
  4810. + return 0;
  4811. +
  4812. + /* output the first and second time */
  4813. + if (rev) {
  4814. + *t2 = t;
  4815. + *t1 = t + o;
  4816. + }
  4817. + else {
  4818. + *t1 = t;
  4819. + *t2 = t + o;
  4820. + }
  4821. + return 1;
  4822. +}
  4823. +#endif
  4824. /*
  4825. * Copy a string into a buffer escaping any shell metacharacters. The
  4826. Index: src/tag.c
  4827. ===================================================================
  4828. RCS file: /e/ossp/pkg/tool/cvs/cvs/cvs/src/tag.c,v
  4829. retrieving revision 1.1.1.4
  4830. diff -u -d -u -3 -r1.1.1.4 tag.c
  4831. --- src/tag.c 24 Apr 2001 17:04:59 -0000 1.1.1.4
  4832. +++ src/tag.c 16 Feb 2002 12:36:09 -0000
  4833. @@ -1229,7 +1229,11 @@
  4834. /* The tags is valid but not mentioned in val-tags. Add it. */
  4835. datum value;
  4836. +#ifdef RSE_PATCH_NOLOCK
  4837. + if (noexec || nowrite || nolock)
  4838. +#else
  4839. if (noexec || nowrite)
  4840. +#endif
  4841. {
  4842. if (db != NULL)
  4843. dbm_close (db);
  4844. Index: src/update.c
  4845. ===================================================================
  4846. RCS file: /e/ossp/pkg/tool/cvs/cvs/cvs/src/update.c,v
  4847. retrieving revision 1.1.1.4
  4848. diff -u -d -u -3 -r1.1.1.4 update.c
  4849. --- src/update.c 24 Apr 2001 17:04:59 -0000 1.1.1.4
  4850. +++ src/update.c 16 Feb 2002 12:36:09 -0000
  4851. @@ -203,7 +203,11 @@
  4852. break;
  4853. case 'p':
  4854. pipeout = 1;
  4855. +#ifdef RSE_PATCH_NOLOCK
  4856. + nolock = noexec = 1; /* so no locks will be created */
  4857. +#else
  4858. noexec = 1; /* so no locks will be created */
  4859. +#endif
  4860. break;
  4861. case 'j':
  4862. if (join_rev2)
  4863. @@ -1809,6 +1813,17 @@
  4864. patch can't handle that. */
  4865. fail = 1;
  4866. }
  4867. +#ifdef RSE_PATCH_FASTERUPDATE
  4868. + else {
  4869. + /*
  4870. + * Don't send a diff if just sending the entire file
  4871. + * would be smaller
  4872. + */
  4873. + fseek(e, 0L, SEEK_END);
  4874. + if (file_info->st_size < ftell(e))
  4875. + fail = 1;
  4876. + }
  4877. +#endif
  4878. fclose (e);
  4879. }
  4880. }
  4881. @@ -2563,8 +2578,16 @@
  4882. write_letter (finfo, 'C');
  4883. }
  4884. else
  4885. +#ifdef RSE_PATCH_MERGENOKEYWORD
  4886. + {
  4887. + if (*t_options == '\0')
  4888. + t_options = "-kk"; /* to ignore keyword expansions */
  4889. +#endif
  4890. status = RCS_merge (finfo->rcs, vers->srcfile->path, finfo->file,
  4891. t_options, rev1, rev2);
  4892. +#ifdef RSE_PATCH_MERGENOKEYWORD
  4893. + }
  4894. +#endif
  4895. if (status != 0 && status != 1)
  4896. {
  4897. Index: src/version.c
  4898. ===================================================================
  4899. RCS file: /e/ossp/pkg/tool/cvs/cvs/cvs/src/version.c,v
  4900. retrieving revision 1.1.1.5
  4901. diff -u -d -u -3 -r1.1.1.5 version.c
  4902. --- src/version.c 27 Apr 2001 20:02:28 -0000 1.1.1.5
  4903. +++ src/version.c 16 Feb 2002 12:38:04 -0000
  4904. @@ -12,7 +12,11 @@
  4905. #include "cvs.h"
  4906. +#ifdef RSE_PATCHES
  4907. +char *version_string = "Concurrent Versions System (CVS) 1.11.1p1 [RSE]";
  4908. +#else
  4909. char *version_string = "Concurrent Versions System (CVS) 1.11.1p1";
  4910. +#endif
  4911. #ifdef CLIENT_SUPPORT
  4912. #ifdef SERVER_SUPPORT