| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392 |
- Index: src/README.RSE
- ===================================================================
- RCS file: src/README.RSE
- diff -N src/README.RSE
- --- /dev/null 1 Jan 1970 00:00:00 -0000
- +++ src/README.RSE 27 Oct 2003 19:19:10 -0000
- @@ -0,0 +1,310 @@
- +
- + CVS RSE Patches
- + ===============
- +
- + This is the patched version of CVS from Ralf S. Engelschall
- + <rse@engelschall.com> - an enhanced version of the official CVS
- + version 1.12.1 (see http://www.cvshome.org/).
- +
- + The following changes against the vendor CVS version are provided:
- + - new `cvs pserverd' for running stand-alone pserver daemons
- + - support for an `admininfo' hook to ACL `cvs admin' commands.
- + - support for an `importinfo' hook to ACL `cvs import' commands.
- + - support for a `-h<handle>' option to `cvs diff' for compressed time spec.
- + - allow a hard-coded CVS super-user to override the CVS user via $CVSUSER
- + - support for .cvsrc files in both $HOME and working and its parent dirs
- + - support for $HOME/.cvsroot to alias CVSROOTs and to support root mirrors
- + - support global but command specific options in .cvsrc files
- + - support for stand-alone external custom commands `cvs <command>'
- + - support for prolog and epilog command line hooks
- + - support for additional `%x' variables on `loginfo' hook command lines
- + - support a `UMask=<mask>' variable in `$CVSROOT/CVSROOT/config'
- + - speeded up `cvs update' by sending whole file if smaller than the diff
- + - disabled keyword expansions during branch merges
- + - adjusted `cvs diff -rHEAD' to be consistent with other commands
- + - allow `-j revision:date' for `cvs diff'
- + - set `$LOGNAME' to the real user and not the CVS user
- + - support for `HistoryFile=<rel-path-under-CVSROOT>' variable in config.
- + - use prefix 'T' ("touched/tagged") instead of 'U' ("updated") on `cvs import'
- + - allow `LockDir' configuration directive to use relative paths
- + - additional SetUID/SetGID support for `cvs server' situations.
- + - new global --map-root=/oldpath:/newpath option for mapping root paths
- + - various cosmetic changes
- +
- + Some of my RSE functional patches are only useful for the server side,
- + others are also useful on the client side. All source patches to
- + *.[ch] files were entirely wrapped with ``#ifdef RSE_PATCH_<NAME> ...
- + #endif'' pairs. So, a particular patch is enabled by building CVS with
- + -DRSE_PATCH_<NAME>. All patches are enabled with -DRSE_PATCHES.
- +
- + Ralf S. Engelschall
- + rse@engelschall.com
- + www.engelschall.com
- + ________________________________________________________________________
- +
- + The following particular patches are available:
- +
- + RSE_PATCH_CVSRC:
- + In addition to processing `$HOME/.cvsrc', process also `.cvsrc'
- + files in the current working directory and the parent directories of
- + the current working directory. This allows one to use for instance a
- + `commit -m ""' locally (as used for GNU Pth development where CVS is
- + only used for plain revision control and not for bookkeeping changes
- + or group communication - instead a plain manually edited ChangeLog
- + exists) or `commit -d <master>' (if working with a local repository
- + copy). Additionally this adds support for quoted strings inside
- + .cvsrc files.
- + [Origin: Ralf S. Engelschall]
- +
- + RSE_PATCH_CVSROOT:
- + This adds support for a new dot-file ~/.cvsroot which is used
- + optionally by CVS. It can be used by the user to configure a
- + nickname for a CVS repository root (the master location) plus a
- + possibly existing local repository copy (the slave location). An
- + entry in ~/.cvsroot is of the format ``<nickname> <master-path>
- + [<slave-path> [<sync-prog>]]''. Those entries can be either created
- + manually in ~/.cvsroot or with the `cvs root -e' command.
- +
- + The idea is this: if a global `-d' option is used with <nickname> it is
- + automatically expanded to <master-path>. If no global `-d' option is used,
- + the CVS command is checked. If it is one of the commands which are known
- + to CVS to modify the repository, and the $CVSROOT or CVS/Root specify a
- + slave location, the repository is switched to the corresponding master
- + location (because modifications have to be performed there). If the
- + command is one of the commands which are known to CVS to NOT modify the
- + repository, and the $CVSROOT or CVS/Root specify a master location, the
- + repository is switched to the corresponding slave location (because the
- + slave location is faster than the master location per definition).
- +
- + After a modifying operation, CVS can either run a synchronization job
- + automatically to bring slave in sync with master again or the user can run
- + `cvs root -s <nickname>' manually to perform this task.
- + [Origin: Ralf S. Engelschall]
- +
- + RSE_PATCH_GLOBALOPTION:
- + RSE_PATCH_GLOBALOPTION_PARTLY:
- + By default, global options in `.cvsrc' files are specified with a
- + `cvs' prefix. These options then apply to _all_ cvs commands. If
- + RSE_PATCH_GLOBALOPTION is enabled, a second pass is done where all
- + global options are read with prefix `cvs/<command>' where <command>
- + is the official cvs command (for instance `commit' or `checkout',
- + even if `ci' or `co' are used on the command line). This is useful
- + for instance to override CVSROOT in commit commands if using a local
- + repository copy. The drawback of this feature is that it obviously
- + slows down cvs calls, because a second pass has to be done. But
- + usually this feature is intended only for use with `commit', `tag',
- + `rtag', `history', `admin', `import' and `rdiff' commands, so if
- + RSE_PATCH_GLOBALOPTION_PARTLY is additionally enabled, this second
- + pass is only done for those commands (which is the recommended use
- + of this feature).
- + [Origin: Ralf S. Engelschall]
- +
- + RSE_PATCH_CUSTOMCMD:
- + This provides an additional global option `-C
- + <cmd-name>:<cmd-program>' which defines an additional CVS command
- + <cmd-name>. It is intended for use on `cvs' lines inside .cvsrc
- + files. The effect of having `cvs -Csync:$CVSROOT/CVSROOT/sync' in a
- + .cvsrc file is (and assuming $CVSROOT is /e/ossp/cvs) that if you
- + run `cvs sync <arg1> <arg2>', CVS executes `/e/ossp/cvs/CVSROOT/sync
- + <arg1> <arg2>'. So this is a way to externally extend CVS with
- + additional commands.
- + [Origin: Ralf S. Engelschall]
- +
- + RSE_PATCH_PROLOGEPILOG:
- + Provides the two additional CVS options `-P <program>' and `-E
- + <program>' for running prolog and epilog programs before and
- + after the usual CVS processing. This is mainly intended as local
- + hooks for implicitly wrapping CVS commands (without having to
- + create slow wrapping shell scripts, etc.). Developers usually
- + use it to automatically start their RSYNC command to update the
- + local repository copy after a commit. The <program> is called
- + with four arguments: $1 is either `prolog' or `epilog' (useful
- + if one just wants to use a single hook program), $2 is the cvs
- + command (it is `commit' even `ci' is used, etc.), $3 is the current
- + working directory from which the cvs command was run and $4 is the
- + corresponding $CVSROOT variable.
- + [Origin: Ralf S. Engelschall]
- +
- + RSE_PATCH_EXTRAPERCENT:
- + This adds extra percent expansions to `loginfo' command lines:
- + `%o' to expand the operation (`A' = added, `M' = modified, `R' =
- + removed), `%t' to expand the tag, `%d' to expand the date.
- + [Origin: Ralf S. Engelschall]
- +
- + RSE_PATCH_READDNEW:
- + If a file was re-added to the repository, log the revision in the
- + `commitlog' as `NONE' instead of the previous dead revision.
- + [Origin: NetBSD]
- +
- + RSE_PATCH_CONFIGUMASK:
- + Provide a `UMask=<mask>' variable in `$CVSROOT/CVSROOT/config' which
- + overrides the umask of the CVS server process.
- + [Origin: OpenBSD]
- +
- + RSE_PATCH_FASTERUPDATE:
- + This speeds up `cvs update' by sending the whole file over the
- + network if it is smaller than the diff content. This is useful for
- + working remotely over slow Internet links.
- + [Origin: OpenBSD]
- +
- + RSE_PATCH_MERGENOKEYWORD:
- + This disables keyword expansions during branch merges which is
- + very useful in long-term branching. Without this the so-called
- + `spurious merging conflicts' occur because the keywords cause
- + spurious conflicts on every merge after the first (if those text
- + files have been modified on the trunk since the previous merge out
- + to the branch).
- + [Origin: Jay Sachs <jsachs@iclick.com>]
- +
- + RSE_PATCH_DIFFHEAD:
- + This patch changes the behavior of `cvs diff -rHEAD' on branches.
- + HEAD here now behaves with as it does with all other CVS commands,
- + as a name for the head of the trunk (the old behavior of `cvs diff
- + -rHEAD' was to treat HEAD to mean the head of the branch, while all
- + the other commands already treated HEAD as the head of the trunk).
- + [Origin: Stephen Cameron <steve.cameron@compaq.com>]
- +
- + RSE_PATCH_DIFFJ:
- + This patch adds `-j revision:date' to `cvs diff' in order to provide
- + the ability to see date-based differences on branch, too.
- + [Origin: Matt Dillon]
- +
- + RSE_PATCH_LOGNAME:
- + This is for SUID-based CVS servers and passes in `$LOGNAME' the real
- + user (first field in `$CVSROOT/CVSROOT/passwd') instead of the SUID
- + user (third field in `$CVSROOT/CVSROOT/passwd')
- + [Origin: Chris Cameron]
- +
- + RSE_PATCH_HISTORYFILE:
- + This provides an additional `HistoryFile=<rel-path-under-CVSROOT>'
- + config variable which allows one to store the history file under a
- + different path.
- + [Origin: Ralf S. Engelschall]
- +
- + RSE_PATCH_SMARTCONFIG:
- + This allows one to add custom configuration variables to
- + `$CVSROOT/CVSROOT/config' without having CVS complain about them and
- + fail with an error. This is useful to use the config file also for
- + storing config details for the various admin scripts.
- + [Origin: Ralf S. Engelschall]
- +
- + RSE_PATCH_ADMININFO:
- + This adds the feature of an extra `$CVSROOT/CVSROOT/admininfo'
- + configuration file which can be used for access controlling `cvs
- + admin' commands similar to `cvs tag' (which is already done
- + with `taginfo') and `cvs commit' (which is already done with
- + `commitinfo'). The specified filters in this info file receive the
- + absolute repository directory as the first argument, followed by all
- + names of files in this directory on which the `cvs admin' command
- + should be performed. If the filter returns 0, the operation is
- + allowed. If it returns not 0, the operation is denied.
- + [Origin: Ralf S. Engelschall]
- +
- + RSE_PATCH_IMPORTINFO:
- + This adds the feature of an extra `$CVSROOT/CVSROOT/importinfo'
- + configuration file which can be used for access controlling
- + `cvs import'. The specified filters in this info file receives
- + the following arguments: the vendor branch tag, the (absolute)
- + repository path which is the root of the import and then zero or
- + more relative file paths under this repository. If the filter
- + returns 0, the operation is allowed. If it returns not 0, the
- + operation is denied.
- + [Origin: Ralf S. Engelschall]
- +
- + RSE_PATCH_HANDLE:
- + This adds a convinient `-h<handle>' option to `cvs diff'. `<handle>'
- + is a string of the format `[!]YYMMDDhhmmssoo' (YY=year, MM=month,
- + DD=day, hh=hour, mm=minute, ss=second, oo=offset) which internally
- + is expanded into two `-D' options. The first date is the equivalent
- + of `YYMMDDhhmmss', the second is the first plus `oo' seconds. If the
- + exclamation mark is used, the two dates are reversed. The intention
- + is that such a handle is a short form for a time range and can be
- + easily computed in a commit log mail. So the `-h' option can be used
- + to easily get the corresponding change diff for branch merging or
- + backing out. The only restriction is that time-overlapping commits
- + break the solution, of course. But in practice this is no real
- + problem.
- + [Origin: Ralf S. Engelschall]
- +
- + RSE_PATCH_IMPORTTOUCH:
- + This prints the prefix 'T' (for "touched/tagged only") instead
- + of 'U' (for "updated") on `cvs import' if no modifications were
- + imported, i.e., no new revision is comitted. This way one can
- + distinguish those imports from the regular updated ones which also
- + print 'U' and which actually commit a new revision.
- + [Origin: Ralf S. Engelschall]
- +
- + RSE_PATCH_RELLOCKDIR:
- + This allows the `LockDir' configuration directive to use relative
- + paths to $CVSROOT, because without this patch a relative path would
- + be relative to the current working directory (which is useless).
- + [Origin: Stefan Monnier <foo@acm.com>]
- +
- + RSE_PATCH_CVSUSER:
- + This allows the Unix user RSE_PATCH_CVSUSER_CALLER (per default
- + "ossp-cvs") to use the environment variable CVSUSER to override the
- + login name CVS uses to identify the caller. This is intended for use
- + with a CVS setuid wrapper program or for use manually by the CVS
- + administrator.
- + [Origin: Ralf S. Engelschall]
- +
- + RSE_PATCH_SETXID:
- + This is a variant of CVS's SETXID_SUPPORT. It allows one to
- + setuid/setgid the CVS executable. Then CVS deletes these effective
- + uid/gid for all commands except for the "cvs server" command. For
- + this and only this it switches the real uid/gid to the effective
- + uid/gid. This way one can use the repository as a black-box. One
- + just has to be make sure that only :ext: (for remote) and :fork:
- + (for local) access is used.
- + [Origin: Ralf S. Engelschall]
- +
- + RSE_PATCH_PSERVERD:
- + This adds an additional `cvs pserverd' command which is like `cvs
- + pserver' except that it uses own builtin TCP/IP socket listening and
- + forking facility. The advantages over using inetd are: pserverd can
- + listen to particular host addresses/ports (inetd always binds to all
- + interfaces of a host), it can optionally chroot(2) for a particular
- + user only (usually "anonymous"), it can optionally force the global
- + options -l -u for a particular user only (usually "anonymous"), it
- + can detach into background and run as a real daemon, etc.
- + [Origin: Ralf S. Engelschall]
- +
- + RSE_PATCH_MAPROOT
- + This adds a global --map-root=/oldpath:/newpath option which
- + allows one to map virtual/incoming CVSROOT values to real ones.
- + For instance this can be used together with --allow-root and "cvs
- + pserverd" to map the intuitive virtual path to the physical path on
- + the host.
- + [Origin: Ralf S. Engelschall]
- +
- + RSE_PATCH_HASHFUNC:
- + This replaces the obscure hash function in src/hash.c with D.J.Berstein's
- + popular "times 33" function which is faster to compute and still
- + distributes very well.
- + [Origin: Ralf S. Engelschall]
- +
- + RSE_PATCH_ADDFILEATTR:
- + Let the default file attributes set on newly added files.
- + [Origin: Noel Yap]
- +
- + RSE_PATCH_CVSPID:
- + This provides an environment variable $CVSPID which contains the process
- + id of the parent CVS process. This is usually used inside scripts called
- + from *info files in order to have a unique session handle (for instance
- + for a common temporary directory "/tmp/cvs.foo.$CVSPID", etc).
- + [Origin: Rich Salz <rsalz@caveosystems.com>]
- +
- + RSE_PATCH_BUGFIX:
- + This enabled various bugfixes which are still not present in the
- + official CVS version.
- + [Origin: Ralf S. Engelschall]
- +
- + RSE_PATCH_COSMETICS:
- + This just enables some cosmetic changes to various output messages.
- + [Origin: Ralf S. Engelschall]
- +
- + RSE_PATCH_COSMETICS_HARD:
- + This just enables more cosmetic changes to various output messages.
- + The difference is that these break "make check".
- + [Origin: Ralf S. Engelschall]
- +
- Index: src/add.c
- ===================================================================
- RCS file: /e/ossp/pkg/tool/cvs/cvs/cvs/src/add.c,v
- retrieving revision 1.1.1.9
- diff -u -d -r1.1.1.9 add.c
- --- src/add.c 25 Nov 2003 20:51:25 -0000 1.1.1.9
- +++ src/add.c 5 Dec 2003 20:22:14 -0000
- @@ -740,6 +740,9 @@
- li->type = T_TITLE;
- li->tag = xstrdup (tag);
- li->rev_old = li->rev_new = NULL;
- +#ifdef RSE_PATCH_EXTRAPERCENT
- + li->date = NULL;
- +#endif
- p->data = (char *) li;
- (void) addnode (ulist, p);
- Update_Logfile (rcsdir, message, (FILE *) NULL, ulist);
- Index: src/admin.c
- ===================================================================
- RCS file: /e/ossp/pkg/tool/cvs/cvs/cvs/src/admin.c,v
- retrieving revision 1.1.1.11
- diff -u -d -r1.1.1.11 admin.c
- --- src/admin.c 9 Dec 2003 19:38:36 -0000 1.1.1.11
- +++ src/admin.c 11 Dec 2003 21:04:09 -0000
- @@ -137,6 +137,160 @@
- dat->av[dat->ac++] = newelt;
- }
-
- +#ifdef RSE_PATCH_ADMININFO
- +
- +static List *admininfo_dlist;
- +static List *admininfo_flist;
- +
- +static void admininfo_dlist_delproc (Node *);
- +static int admininfo_info_runproc (char *, char *, void *);
- +static int admininfo_flist_runproc (Node *, void *);
- +
- +struct admininfo_dlist_st {
- + List *flist;
- +};
- +
- +/* file callback function for recursive processing */
- +static int
- +admininfo_fileproc (void *callerdat, struct file_info *finfo)
- +{
- + char *xdir;
- + Node *dnode;
- + Node *fnode;
- +
- + /* determine current directory */
- + if (finfo->update_dir[0] == '\0')
- + xdir = ".";
- + else
- + xdir = finfo->update_dir;
- +
- + /* find directory node in directory list */
- + if ((dnode = findnode(admininfo_dlist, xdir)) != NULL)
- + /* take already existing file list */
- + admininfo_flist = ((struct admininfo_dlist_st *)dnode->data)->flist;
- + else
- + {
- + /* create a new file list */
- + struct admininfo_dlist_st *dlist;
- +
- + admininfo_flist = getlist ();
- +
- + dlist = (struct admininfo_dlist_st *) xmalloc (sizeof(struct admininfo_dlist_st));
- + dlist->flist = admininfo_flist;
- +
- + dnode = getnode ();
- + dnode->type = UPDATE;
- + dnode->key = xstrdup (xdir);
- + dnode->data = (char *)dlist;
- + dnode->delproc = admininfo_dlist_delproc;
- +
- + (void) addnode (admininfo_dlist, dnode);
- + }
- +
- + /* create new file node in file list */
- + fnode = getnode ();
- + fnode->type = UPDATE;
- + fnode->key = xstrdup (finfo->file);
- + fnode->data = NULL;
- + fnode->delproc = NULL;
- + (void) addnode (admininfo_flist, fnode);
- +
- + return 0;
- +}
- +
- +/* delete a directory list node */
- +static void
- +admininfo_dlist_delproc(Node *p)
- +{
- + struct admininfo_dlist_st *dlist;
- +
- + dlist = (struct admininfo_dlist_st *)p->data;
- + dellist (&dlist->flist);
- + free (dlist);
- + return;
- +}
- +
- +/* file callback function for recursive processing (when done) */
- +static int
- +admininfo_filesdoneproc(
- + void *callerdat,
- + int err,
- + char *repos,
- + char *update_dir,
- + List *entries)
- +{
- + Node *dnode;
- + int n;
- +
- + /* find file list for update directory */
- + if ((dnode = findnode(admininfo_dlist, update_dir)) != NULL)
- + admininfo_flist = ((struct admininfo_dlist_st *)dnode->data)->flist;
- + else
- + admininfo_flist = (List *)NULL;
- + if ( (admininfo_flist == NULL)
- + || (admininfo_flist->list->next == admininfo_flist->list))
- + return err;
- +
- + /* parse and execute the admininfo configuration */
- + if ((n = Parse_Info(CVSROOTADM_ADMININFO, repos, admininfo_info_runproc, PIOPT_ALL, NULL)) > 0) {
- + error(0, 0, "Pre-admin check failed");
- + err += n;
- + }
- +
- + return err;
- +}
- +
- +/* admininfo configuration entry callback */
- +static int
- +admininfo_info_runproc(repository, filter, closure)
- + char *repository;
- + char *filter;
- + void *closure;
- +{
- + char *s, *cp;
- + int rv;
- +
- + /* if possible, do an own check to make sure that filter really exists */
- + if (filter[0] == '/') {
- + s = xstrdup(filter);
- + for (cp = s; *cp; cp++) {
- + if (isspace((unsigned char)*cp)) {
- + *cp = '\0';
- + break;
- + }
- + }
- + if (!isfile(s)) {
- + error (0, errno, "cannot find pre-admin filter '%s'", s);
- + free(s);
- + return (1);
- + }
- + free(s);
- + }
- +
- + /* construct the filter command */
- + run_setup(filter);
- + run_arg(repository);
- + walklist(admininfo_flist, admininfo_flist_runproc, NULL);
- +
- + /* execute the filter command */
- + rv = run_exec(RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL);
- +
- + return rv;
- +}
- +
- +/* file list callback for adding file as another program argument */
- +static int
- +admininfo_flist_runproc(
- + Node *p,
- + void *closure)
- +{
- + if (p->key != NULL)
- + run_arg(p->key);
- + return 0;
- +}
- +
- +#endif /* RSE_PATCH_ADMININFO */
- +
- int
- admin (int argc, char **argv)
- {
- @@ -513,6 +667,20 @@
-
- lock_tree_promotably (argc, argv, 0, W_LOCAL, 0);
-
- +#ifdef RSE_PATCH_ADMININFO
- + /* allow `CVSROOT/CVSROOT/admininfo' filters to check whether the
- + `cvs admin' operation is authorized for all the specified files
- + in the repository */
- + admininfo_dlist = getlist();
- + err = start_recursion(admininfo_fileproc, admininfo_filesdoneproc,
- + (DIRENTPROC) NULL, (DIRLEAVEPROC) NULL, NULL,
- + argc, argv, 0, W_LOCAL, 0, 0, (char *)NULL, 1, (char *)NULL);
- + if (err) {
- + Lock_Cleanup();
- + error(1, 0, "correct above errors first!");
- + }
- +#endif
- +
- err = start_recursion
- (admin_fileproc, NULL, admin_dirproc,
- NULL, &admin_data,
- Index: src/buffer.c
- ===================================================================
- RCS file: /e/ossp/pkg/tool/cvs/cvs/cvs/src/buffer.c,v
- retrieving revision 1.1.1.6
- diff -u -d -r1.1.1.6 buffer.c
- --- src/buffer.c 4 Oct 2003 15:46:32 -0000 1.1.1.6
- +++ src/buffer.c 27 Oct 2003 19:07:22 -0000
- @@ -1318,7 +1318,7 @@
- int closefp = 1;
-
- /* Must be a pipe or a socket. What could go wrong? */
- - assert (fstat ( fileno (bc->fp), &s ) != -1);
- + assert (fstat ( fileno (bc->fp), &s ) != -1); /* RSE XXX */
-
- /* Flush the buffer if we can */
- if (buf->flush)
- Index: src/checkin.c
- ===================================================================
- RCS file: /e/ossp/pkg/tool/cvs/cvs/cvs/src/checkin.c,v
- retrieving revision 1.1.1.3
- diff -u -d -r1.1.1.3 checkin.c
- --- src/checkin.c 19 Aug 2003 12:20:47 -0000 1.1.1.3
- +++ src/checkin.c 27 Oct 2003 19:07:22 -0000
- @@ -26,14 +26,27 @@
- Vers_TS *vers;
- int set_time;
- char *tocvsPath = NULL;
- +#ifdef RSE_PATCH_COSMETICS_HARD
- + int flags;
- +#endif
-
- /* Hmm. This message goes to stdout and the "foo,v <-- foo"
- message from "ci" goes to stderr. This doesn't make a whole
- lot of sense, but making everything go to stdout can only be
- gracefully achieved once RCS_checkin is librarified. */
- +#ifdef RSE_PATCH_COSMETICS_HARD
- + if (!really_quiet) {
- +#endif
- cvs_output ("Checking in ", 0);
- cvs_output (finfo->fullname, 0);
- +#ifdef RSE_PATCH_COSMETICS_HARD
- + cvs_output ("\n", 0);
- +#else
- cvs_output (";\n", 0);
- +#endif
- +#ifdef RSE_PATCH_COSMETICS_HARD
- + }
- +#endif
-
- tocvsPath = wrap_tocvs_process_file (finfo->file);
- if (!noexec)
- @@ -54,11 +67,22 @@
- */
- assert ( finfo->rcs != NULL );
-
- +#ifdef RSE_PATCH_COSMETICS_HARD
- + flags = RCS_FLAGS_KEEPFILE;
- + if (really_quiet || quiet)
- + flags |= RCS_FLAGS_QUIET;
- + switch ( RCS_checkin ( finfo->rcs,
- + finfo->file,
- + message,
- + rev,
- + flags ) )
- +#else
- switch ( RCS_checkin ( finfo->rcs,
- finfo->file,
- message,
- rev,
- RCS_FLAGS_KEEPFILE ) )
- +#endif
- {
- case 0: /* everything normal */
-
- @@ -122,6 +146,16 @@
- history_write (type, NULL, vers->vn_rcs,
- finfo->file, finfo->repository);
-
- +#ifdef RSE_PATCH_ADDFILEATTR
- + if (type == 'A') {
- + char *attr;
- + if ((attr = fileattr_getall(NULL)) != NULL) {
- + fileattr_setall(finfo->file, attr);
- + free(attr);
- + }
- + }
- +#endif
- +
- if (tocvsPath)
- if (unlink_file_dir (tocvsPath) < 0)
- error (0, errno, "cannot remove %s", tocvsPath);
- Index: src/client.c
- ===================================================================
- RCS file: /e/ossp/pkg/tool/cvs/cvs/cvs/src/client.c,v
- retrieving revision 1.1.1.12
- diff -u -d -r1.1.1.12 client.c
- --- src/client.c 25 Nov 2003 20:51:59 -0000 1.1.1.12
- +++ src/client.c 5 Dec 2003 20:22:14 -0000
- @@ -53,6 +53,9 @@
- int status (int argc, char **argv);
- int tag (int argc, char **argv);
- int update (int argc, char **argv);
- +#ifdef RSE_PATCH_RLIST
- +int list (int argc, char **argv);
- +#endif
-
- /* All the response handling functions. */
- static void handle_ok (char *, int);
- @@ -196,14 +199,34 @@
- : Name_Root ((char *) NULL, (char *) NULL));
- }
-
- +#ifdef RSE_PATCH_CVSROOT
- + {
- + int cvsroot_alias;
- + cvsroot_type *e;
- +
- + cvsroot_alias = 0;
- + if ((e = cvsroot_lookup(NULL, current_parsed_root->original, NULL)) != NULL)
- + if (strcmp(e->slavepath, this_root) == 0)
- + cvsroot_alias = 1;
- + if ((e = cvsroot_lookup(NULL, NULL, this_root)) != NULL)
- + if (strcmp(e->masterpath, current_parsed_root->original) == 0)
- + cvsroot_alias = 1;
- +#endif
- +
- /* Now check the value for root. */
- if (this_root && current_parsed_root
- +#ifdef RSE_PATCH_CVSROOT
- + && !cvsroot_alias
- +#endif
- && (strcmp (this_root, current_parsed_root->original) != 0))
- {
- /* Don't send this, since the CVSROOTs don't match. */
- free (this_root);
- return 1;
- }
- +#ifdef RSE_PATCH_CVSROOT
- + }
- +#endif
- free (this_root);
- }
-
- @@ -2152,6 +2175,9 @@
- /* Add a directory name to the list of those sent to the
- server. */
- if (update_dir && (*update_dir != '\0')
- +#ifdef RSE_PATCH_CVSROOT
- + /* FIXME: alternative to RSE_PATCH_CVSROOT?! */
- +#endif
- && (strcmp (update_dir, ".") != 0)
- && (findnode (dirs_sent_to_server, update_dir) == NULL))
- {
- Index: src/commit.c
- ===================================================================
- RCS file: /e/ossp/pkg/tool/cvs/cvs/cvs/src/commit.c,v
- retrieving revision 1.1.1.13
- diff -u -d -r1.1.1.13 commit.c
- --- src/commit.c 9 Dec 2003 19:38:58 -0000 1.1.1.13
- +++ src/commit.c 11 Dec 2003 21:04:10 -0000
- @@ -291,6 +291,9 @@
- data->type = status;
- data->tag = xstrdup (vers->tag);
- data->rev_old = data->rev_new = NULL;
- +#ifdef RSE_PATCH_EXTRAPERCENT
- + data->date = xstrdup (vers->ts_user);
- +#endif
-
- node->type = UPDATE;
- node->delproc = update_delproc;
- @@ -967,7 +970,16 @@
- xmalloc (sizeof (struct logfile_info)));
- li->type = status;
- li->tag = xstrdup (vers->tag);
- +#ifdef RSE_PATCH_READDNEW
- + /* If the file was re-added, we want the revision in the commitlog
- + to be NONE, not the previous dead revision. */
- + li->rev_old = status == T_ADDED ? NULL : xstrdup (vers->vn_rcs);
- +#else
- li->rev_old = xstrdup (vers->vn_rcs);
- +#endif
- +#ifdef RSE_PATCH_EXTRAPERCENT
- + li->date = xstrdup (vers->ts_user);
- +#endif
- li->rev_new = NULL;
- p->data = (char *) li;
- (void) addnode (ulist, p);
- @@ -2187,6 +2199,10 @@
- free (li->rev_old);
- if (li->rev_new)
- free (li->rev_new);
- +#ifdef RSE_PATCH_EXTRAPERCENT
- + if (li->date)
- + free (li->date);
- +#endif
- free (li);
- }
-
- Index: src/create_adm.c
- ===================================================================
- RCS file: /e/ossp/pkg/tool/cvs/cvs/cvs/src/create_adm.c,v
- retrieving revision 1.1.1.7
- diff -u -d -r1.1.1.7 create_adm.c
- --- src/create_adm.c 23 Jul 2003 20:40:07 -0000 1.1.1.7
- +++ src/create_adm.c 27 Oct 2003 19:26:55 -0000
- @@ -21,6 +21,41 @@
- or after which CVS might do something non-useful. If WARN is zero, then
- don't print warnings; all errors are fatal then. */
-
- +#ifdef RSE_PATCH_CVSROOT
- +static int local_template_cb(char *repository, char *template, void *closure)
- +{
- + FILE *fpIN, *fpOUT;
- + char buf[1024];
- + size_t n;
- +
- + if ((fpOUT = CVS_FOPEN(CVSADM_TEMPLATE, "w+")) == NULL)
- + error(1, errno, "cannot open %s for writing", CVSADM_TEMPLATE);
- + if ((fpIN = CVS_FOPEN(template, "r")) == NULL)
- + error(1, errno, "cannot open %s for reading", template);
- + while (!feof(fpIN)) {
- + n = fread(buf, 1, sizeof buf, fpIN);
- + if (n == 0) {
- + if (ferror(fpIN))
- + error(0, errno, "cannot read template file %s", template);
- + break;
- + }
- + fwrite(buf, 1, n, fpOUT);
- + }
- + fclose(fpIN);
- + fclose(fpOUT);
- + return 0;
- +}
- +
- +static void local_template(char *update_dir, char *repository)
- +{
- + cvsroot_type *e;
- +
- + if ((e = cvsroot_lookup(NULL, NULL, current_parsed_root->original)) != NULL)
- + Parse_Info(CVSROOTADM_RCSINFO, repository, local_template_cb, PIOPT_ALL, NULL);
- + return;
- +}
- +#endif
- +
- int
- Create_Admin (char *dir, char *update_dir, char *repository, char *tag, char *date, int nonbranch, int warn, int dotemplate)
- {
- @@ -150,6 +185,20 @@
- /* Create a new CVS/Tag file */
- WriteTag (dir, tag, date, nonbranch, update_dir, repository);
-
- +#ifdef RSE_PATCH_CVSROOT
- + /* Under our "cvs root" feature, checkouts are performed
- + locally (from the repository copy and without C/S), but commits
- + are performed remotely (to the master repository with C/S).
- + Unfortunately, CVS "optimizes" processing and doesn't provide
- + CVS/Template files on non-C/S checkouts. This would mean that
- + if "cvs root" feature is used, the rcsinfo-configured templates
- + are never used. So, if and only if we do a non-C/S checkout (or
- + similar operation which creates CVS/Template) _and_ the current
- + CVSROOT is known to be a repository copy, we force the creation
- + of CVS/Template. */
- + if (!server_active && !(current_parsed_root->isremote) && dotemplate)
- + local_template(update_dir, repository);
- +#endif
- TRACE ( 1, "Create_Admin" );
-
- free (reposcopy);
- Index: src/cvs.h
- ===================================================================
- RCS file: /e/ossp/pkg/tool/cvs/cvs/cvs/src/cvs.h,v
- retrieving revision 1.1.1.12
- diff -u -d -r1.1.1.12 cvs.h
- --- src/cvs.h 8 Dec 2003 19:43:00 -0000 1.1.1.12
- +++ src/cvs.h 11 Dec 2003 21:04:10 -0000
- @@ -7,6 +7,45 @@
- */
-
- /*
- + * Support for compiling in various RSE extension
- + */
- +#ifdef RSE_PATCHES
- +#define RSE_PATCH_CVSRC
- +#define RSE_PATCH_CVSROOT
- +#define RSE_PATCH_GLOBALOPTION
- +#define RSE_PATCH_GLOBALOPTION_PARTLY
- +#define RSE_PATCH_CUSTOMCMD
- +#define RSE_PATCH_PROLOGEPILOG
- +#define RSE_PATCH_EXTRAPERCENT
- +#define RSE_PATCH_READDNEW
- +#define RSE_PATCH_CONFIGUMASK
- +#define RSE_PATCH_FASTERUPDATE
- +#define RSE_PATCH_LOGNAME
- +#define RSE_PATCH_HISTORYFILE
- +#define RSE_PATCH_IMPORTINFO
- +#define RSE_PATCH_ADMININFO
- +#define RSE_PATCH_HANDLE
- +#define RSE_PATCH_IMPORTTOUCH
- +#define RSE_PATCH_RELLOCKDIR
- +#define RSE_PATCH_CVSUSER
- +#define RSE_PATCH_SETXID
- +#define RSE_PATCH_PSERVERD
- +#define RSE_PATCH_MAPROOT
- +#define RSE_PATCH_RLIST
- +#define RSE_PATCH_COSMETICS
- +#define RSE_PATCH_HASHFUNC
- +#define RSE_PATCH_ADDFILEATTR
- +#define RSE_PATCH_CVSPID
- +#define RSE_PATCH_BUGFIX
- +#define RSE_PATCH_DIFFJ
- +/* problematic changes, because they break "make check" */
- +#undef RSE_PATCH_COSMETICS_HARD
- +#undef RSE_PATCH_MERGENOKEYWORD
- +#undef RSE_PATCH_DIFFHEAD
- +#undef RSE_PATCH_SMARTCONFIG
- +#endif
- +
- +/*
- * basic information used in all source files
- *
- */
- @@ -166,6 +205,33 @@
- #define CVSROOTADM_WRITERS "writers"
- #define CVSROOTADM_PASSWD "passwd"
- #define CVSROOTADM_CONFIG "config"
- +#ifdef RSE_PATCH_ADMININFO
- +#define CVSROOTADM_ADMININFO "admininfo"
- +#endif
- +#ifdef RSE_PATCH_IMPORTINFO
- +#define CVSROOTADM_IMPORTINFO "importinfo"
- +#endif
- +
- +#ifdef RSE_PATCH_ALTADMINFILES
- +#define CVSROOTADM_MODULES_ALT "conf_modules"
- +#define CVSROOTADM_LOGINFO_ALT "hook_logwrite"
- +#define CVSROOTADM_RCSINFO_ALT "hook_logtempl"
- +#define CVSROOTADM_COMMITINFO_ALT "hook_commit"
- +#define CVSROOTADM_TAGINFO_ALT "hook_tag"
- +#define CVSROOTADM_EDITINFO_ALT "hook_logedit"
- +#define CVSROOTADM_VERIFYMSG_ALT "hook_logverify"
- +#define CVSROOTADM_HISTORY_ALT "data_history"
- +#define CVSROOTADM_VALTAGS_ALT "data_valtags"
- +#define CVSROOTADM_IGNORE_ALT "conf_ignore"
- +#define CVSROOTADM_CHECKOUTLIST_ALT "conf_checkout"
- +#define CVSROOTADM_WRAPPER_ALT "hook_wrapper"
- +#define CVSROOTADM_NOTIFY_ALT "hook_notify"
- +#define CVSROOTADM_USERS_ALT "conf_users"
- +#define CVSROOTADM_READERS_ALT "conf_readers"
- +#define CVSROOTADM_WRITERS_ALT "conf_writers"
- +#define CVSROOTADM_PASSWD_ALT "conf_passwd"
- +#define CVSROOTADM_CONFIG_ALT "conf_global"
- +#endif
-
- #define CVSNULLREPOS "Emptydir" /* an empty directory */
-
- @@ -442,6 +508,27 @@
- void root_allow_free (void);
- int root_allow_ok (char *);
-
- +#ifdef RSE_PATCH_MAPROOT
- +void root_map_add (char *, char *);
- +void root_map_free (void);
- +int root_map_it (char *, char **, int);
- +#endif
- +
- +#ifdef RSE_PATCH_CVSROOT
- +typedef struct {
- + char *nickname;
- + char *masterpath;
- + char *slavepath;
- + char *syncprog;
- +} cvsroot_type;
- +char *cvsroot_filename(void);
- +void cvsroot_free(cvsroot_type *);
- +cvsroot_type *cvsroot_entry_read(FILE *);
- +void cvsroot_entry_write(FILE *, cvsroot_type *);
- +cvsroot_type *cvsroot_lookup(char *, char *, char *);
- +void cvsroot_synchronize(cvsroot_type *, int);
- +#endif
- +
- char *gca (const char *rev1, const char *rev2);
- void check_numeric (const char *, int, char **);
- char *getcaller (void);
- @@ -559,6 +646,10 @@
- void expand_wild (int argc, char **argv,
- int *pargc, char ***pargv);
-
- +#ifdef RSE_PATCH_HANDLE
- +int handle2dates(char *, time_t *, time_t *);
- +#endif
- +
- #ifdef SERVER_SUPPORT
- int cvs_casecmp (const char *, const char *);
- int fopen_case (char *, char *, FILE **, char **);
- @@ -806,6 +897,9 @@
- NULL for add or import */
- char *rev_new; /* rev number after a commit/modify,
- add, or import, NULL for remove */
- +#ifdef RSE_PATCH_EXTRAPERCENT
- + char *date;
- +#endif
- };
-
- /* Wrappers. */
- @@ -845,6 +939,13 @@
- int unedit (int argc, char **argv);
- int editors (int argc, char **argv);
- int watchers (int argc, char **argv);
- +#ifdef RSE_PATCH_CVSROOT
- +int root (int argc, char **argv);
- +#endif
- +#ifdef RSE_PATCH_PSERVERD
- +int pserverd (int argc, char **argv);
- +int pserver_daemon (int argc, char **argv);
- +#endif
- int annotate (int argc, char **argv);
- int add (int argc, char **argv);
- int admin (int argc, char **argv);
- @@ -874,6 +975,9 @@
- int cvsstatus (int argc, char **argv);
- int cvstag (int argc, char **argv);
- int version (int argc, char **argv);
- +#ifdef RSE_PATCH_RLIST
- +extern int cvslist (int argc, char **argv);
- +#endif
-
- unsigned long int lookup_command_attribute (char *);
-
- Index: src/cvsrc.c
- ===================================================================
- RCS file: /e/ossp/pkg/tool/cvs/cvs/cvs/src/cvsrc.c,v
- retrieving revision 1.1.1.4
- diff -u -d -r1.1.1.4 cvsrc.c
- --- src/cvsrc.c 23 Jul 2003 20:40:07 -0000 1.1.1.4
- +++ src/cvsrc.c 27 Oct 2003 19:07:23 -0000
- @@ -12,6 +12,203 @@
- #include "cvs.h"
- #include "getline.h"
-
- +#ifdef RSE_PATCH_CVSRC
- +
- +#include <ctype.h>
- +#include <string.h>
- +
- +static char *strq_start = NULL;
- +
- +static char *
- +strqtok_cchar(
- + register char *s,
- + register char *c,
- + int *backslashed)
- +{
- + register char ch;
- +
- + if ((*backslashed = (*s == '\\'))) {
- + switch (*++s) {
- + case 'a':
- + *c = '\a';
- + break;
- + case 'b':
- + *c = '\b';
- + break;
- + case 'f':
- + *c = '\f';
- + break;
- + case 'n':
- + *c = '\n';
- + break;
- + case 'r':
- + *c = '\r';
- + break;
- + case 't':
- + *c = '\t';
- + break;
- + case 'v':
- + *c = '\v';
- + break;
- + case '\\':
- + *c = '\\';
- + break;
- + case '^':
- + *c = '^';
- + break;
- + case '\'':
- + *c = '\'';
- + break;
- + case '"':
- + *c = '"';
- + break;
- + case '?':
- + *c = '?';
- + break;
- + case '0':
- + case '1':
- + case '2':
- + case '3':
- + case '4':
- + case '5':
- + case '6':
- + case '7':
- + ch = 0;
- + if (isdigit(*s) && *s != '8' && *s != '9') {
- + ch = *s++ - '0';
- + if (isdigit(*s) && *s != '8' && *s != '9') {
- + ch <<= 3;
- + ch |= *s++ - '0';
- + if (isdigit(*s) && *s != '8' && *s != '9') {
- + ch <<= 3;
- + ch |= *s++ - '0';
- + }
- + }
- + }
- + s--;
- + *c = ch;
- + break;
- + case 'x':
- + s++;
- + for (ch = 0; isxdigit(*s); s++) {
- + ch <<= 4;
- + ch |= isdigit(*s) ? *s - '0' :
- + islower(*s) ? *s + 10 - 'a' : *s + 10 - 'A';
- + }
- + s--;
- + *c = ch;
- + break;
- + default:
- + *c = *s;
- + break;
- + }
- + } else
- + *c = *s;
- + return (*s) ? s+1 : NULL;
- +}
- +
- +static char *
- +strqtok(
- + char *s, /* String to tokenize. NULL to continue same str */
- + char *delim, /* Token delimiters. Can be changed w/ each call. */
- + char *quotemarks, /* Quotation marks. Can be changed w/ each call. */
- + char *commentchars, /* Comment characters. Can be changed w/ each call. */
- + unsigned int flags) /* flags&01 -> strip quotes;
- + * flags&02 -> enable backslash escapes;
- + * flags&04 -> skip all delims before return;
- + */
- +{
- + register char *p, *q;
- + char c;
- + char leftquote = 0;
- + char *token;
- + int backslashed, inquote, intok;
- +
- + int stripquote = flags & 01; /* strip quotemarks from tokens */
- + int backslash = flags & 02; /* backslash sequences */
- + int skipdelim = flags & 04; /* skip seq of delims at end of token */
- +
- + /* New string? */
- + if (s)
- + strq_start = s;
- + if (!strq_start)
- + return NULL;
- +
- + /* Skip leading delimiters */
- + for (p=strq_start; *p && strchr(delim, *p); p++)
- + ;
- + if (!(*p) || strchr(commentchars, *p))
- + return NULL;
- +
- + /* Set `token' to point to returned string.
- + * Use p and q to walk through the user's string:
- + * p will follow input characters;
- + * q will overwrite w/ outputted characters, minus possibly-stripped
- + * quotes and including nulls after each token.
- + */
- + token = q = p;
- + inquote = 0;
- + intok = 1;
- + if (backslash) {
- + while (intok && (p = strqtok_cchar(p, &c, &backslashed))) {
- + if (backslashed) {
- + *q++ = c; /* treat as plain character */
- + } else if (!inquote && *delim && strchr(delim, c)) {
- + *q = '\0'; /* Reached end of token */
- + intok = 0;
- + } else if (!inquote && *commentchars && strchr(commentchars, c)) {
- + *q = '\0'; /* Reached end of token */
- + *p = '\0'; /* make it act like end of string */
- + intok = 0;
- + } else if (!inquote && *quotemarks && strchr(quotemarks, c)) {
- + inquote = 1; /* Beginning a quoted segment */
- + leftquote = c; /* Save quote char for matching with */
- + if (!stripquote) *q++ = c;
- + } else if (inquote && leftquote == c) {
- + inquote = 0; /* Ending a quoted segment */
- + if (!stripquote) *q++ = c;
- + } else {
- + *q++ = c; /* Ordinary character */
- + }
- + }
- + strq_start = p; /* Where to start next search */
- + *q = '\0';
- + } else {
- + while (intok && *p) {
- + if (!inquote && *delim && strchr(delim, *p)) {
- + *q = '\0'; /* Reached end of token */
- + p++; /* advance p for next token */
- + intok = 0;
- + } else if (!inquote && *commentchars && strchr(commentchars, *p)) {
- + *q = '\0'; /* Reached end of token */
- + *p = '\0'; /* make it act like end of string */
- + intok = 0;
- + } else if (!inquote && *quotemarks && strchr(quotemarks, *p)) {
- + inquote = 1; /* Beginning a quoted segment */
- + leftquote = *p++; /* Save quote char for matching with */
- + if (!stripquote) *q++ = leftquote;
- + } else if (inquote && leftquote == *p) {
- + inquote = 0; /* Ending a quoted segment */
- + p++;
- + if (!stripquote) *q++ = leftquote;
- + } else {
- + *q++ = *p++;
- + }
- + }
- + strq_start = p; /* Where to start next search */
- + *q = '\0';
- + }
- +
- + if (skipdelim && strq_start) {
- + /* Skip trailing delimiters */
- + while (*strq_start && strchr(delim, *strq_start))
- + strq_start++;
- + }
- + return token;
- +}
- +
- +#endif
- +
- /* this file is to be found in the user's home directory */
-
- #ifndef CVSRC_FILENAME
- @@ -23,13 +220,73 @@
-
- extern char *strtok (char *, const char *);
-
- +#ifdef RSE_PATCH_CVSRC
- +static void read_cvsrc_parentdirs ();
- +static void read_cvsrc_file ();
- +#endif
- +
- /* Read cvsrc, processing options matching CMDNAME ("cvs" for global
- options, and update *ARGC and *ARGV accordingly. */
-
- +#ifdef RSE_PATCH_CVSRC
- +void
- +read_cvsrc (argc, argv, cmdname)
- + int *argc;
- + char ***argv;
- + char *cmdname;
- +{
- + /* try to read .cvsrc files from parent directories */
- + read_cvsrc_parentdirs(argc, argv, cmdname);
- +
- + /* try to read .cvsrc file from home directory */
- + read_cvsrc_file(argc, argv, cmdname, get_homedir());
- +
- + return;
- +}
- +
- +/* read .cvsrc files from all parent directories (including the current dir) */
- +static void
- +read_cvsrc_parentdirs (argc, argv, cmdname)
- + int *argc;
- + char ***argv;
- + char *cmdname;
- +{
- + char cwd[PATH_MAX];
- + char *cp;
- + int l;
- +
- + if (getcwd(cwd, sizeof(cwd)) == NULL)
- + return;
- + if ((l = strlen(cwd)) <= 0)
- + return;
- + if (cwd[l-1] != '/') {
- + cwd[l++] = '/';
- + cwd[l++] = '\0';
- + }
- + while (cwd[0] != '\0') {
- + cwd[strlen(cwd)-1] = '\0';
- + read_cvsrc_file(argc, argv, cmdname, cwd);
- + if ((cp = strrchr(cwd, '/')) == NULL)
- + break;
- + *(cp+1) = '\0';
- + }
- + return;
- +}
- +
- +/* read .cvsrc file from a particular directory */
- +static void
- +read_cvsrc_file (argc, argv, cmdname, homedir)
- + int *argc;
- + char ***argv;
- + char *cmdname;
- + char *homedir;
- +{
- +#else
- void
- read_cvsrc (int *argc, char ***argv, char *cmdname)
- {
- char *homedir;
- +#endif
- char *homeinit;
- FILE *cvsrcfile;
-
- @@ -61,7 +318,9 @@
-
- /* determine filename for ~/.cvsrc */
-
- +#ifndef RSE_PATCH_CVSRC
- homedir = get_homedir ();
- +#endif
- /* If we can't find a home directory, ignore ~/.cvsrc. This may
- make tracking down problems a bit of a pain, but on the other
- hand it might be obnoxious to complain when CVS will function
- @@ -117,9 +376,15 @@
- if (found)
- {
- /* skip over command in the options line */
- +#ifdef RSE_PATCH_CVSRC
- + for (optstart = strqtok (line + command_len, "\t \n", "\"'", "", 7);
- + optstart;
- + optstart = strqtok (NULL, "\t \n", "\"'", "", 7))
- +#else
- for (optstart = strtok (line + command_len, "\t \n");
- optstart;
- optstart = strtok (NULL, "\t \n"))
- +#endif
- {
- new_argv [new_argc++] = xstrdup (optstart);
-
- Index: src/diff.c
- ===================================================================
- RCS file: /e/ossp/pkg/tool/cvs/cvs/cvs/src/diff.c,v
- retrieving revision 1.1.1.10
- diff -u -d -r1.1.1.10 diff.c
- --- src/diff.c 25 Nov 2003 16:11:47 -0000 1.1.1.10
- +++ src/diff.c 5 Dec 2003 20:26:45 -0000
- @@ -51,6 +51,10 @@
- static char *diff_date1, *diff_date2;
- static char *use_rev1, *use_rev2;
- static int have_rev1_label, have_rev2_label;
- +#if defined(RSE_PATCH_DIFFJ)
- +/* Command line dates and revisions, from -j option. Malloc'd. */
- +static char *diff_join1, *diff_join2;
- +#endif
-
- /* Revision of the user file, if it is unchanged from something in the
- repository and we want to use that fact. */
- @@ -267,6 +271,10 @@
- diff_rev2 = NULL;
- diff_date1 = NULL;
- diff_date2 = NULL;
- +#if defined(RSE_PATCH_DIFFJ)
- + diff_join1 = NULL; /* used for client/server only */
- + diff_join2 = NULL; /* used for client/server only */
- +#endif
-
- optind = 0;
- /* FIXME: This should really be allocating an argv to be passed to diff
- @@ -277,7 +285,14 @@
- * to diff.
- */
- while ((c = getopt_long (argc, argv,
- +#if defined(RSE_PATCH_DIFFJ)
- + "j:"
- +#endif
- +#if defined(RSE_PATCH_HANDLE)
- + "+abcdefh:ilnpstuwy0123456789BHNRTC:D:F:I:L:U:W:k:r:",
- +#else
- "+abcdefhilnpstuwy0123456789BHNRTC:D:F:I:L:U:W:k:r:",
- +#endif
- longopts, &option_index)) != -1)
- {
- switch (c)
- @@ -286,7 +301,11 @@
- xrealloc_and_strcat (&opts, &opts_allocated, " --side-by-side");
- break;
- case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
- +#if defined(RSE_PATCH_HANDLE)
- + case 'i': case 'n': case 'p': case 's': case 't':
- +#else
- case 'h': case 'i': case 'n': case 'p': case 's': case 't':
- +#endif
- case 'u': case 'w':
- case '0': case '1': case '2': case '3': case '4': case '5':
- case '6': case '7': case '8': case '9':
- @@ -358,6 +377,39 @@
- else
- diff_date1 = Make_Date (optarg);
- break;
- +#if defined(RSE_PATCH_DIFFJ)
- + case 'j':
- + {
- + char *ptr;
- + char *cpy = strdup(optarg);
- + if ((ptr = strchr(optarg, ':')) != NULL)
- + *ptr++ = '\0';
- + if (diff_rev2 != NULL || diff_date2 != NULL)
- + error (1, 0,
- + "no more than two revisions/dates can be specified");
- + if (diff_rev1 != NULL || diff_date1 != NULL) {
- + diff_join2 = cpy;
- + diff_rev2 = optarg;
- + diff_date2 = (ptr != NULL ? Make_Date(ptr) : NULL);
- + } else {
- + diff_join1 = cpy;
- + diff_rev1 = optarg;
- + diff_date1 = (ptr != NULL ? Make_Date(ptr) : NULL);
- + }
- + }
- + break;
- +#endif
- +#if defined(RSE_PATCH_HANDLE)
- + case 'h': {
- + time_t t1, t2;
- + if (!handle2dates(optarg, &t1, &t2))
- + error (1, 0, "invalid handle string");
- + t1 -= 1; /* subtract one second to have a real difference */
- + diff_date1 = date_from_time_t(t1);
- + diff_date2 = date_from_time_t(t2);
- + break;
- + }
- +#endif
- case 'N':
- empty_files = 1;
- break;
- @@ -388,14 +440,32 @@
- send_option_string (opts);
- if (options[0] != '\0')
- send_arg (options);
- +#if defined(RSE_PATCH_DIFFJ)
- + if (diff_join1)
- + option_with_arg ("-j", diff_join1);
- + else if (diff_rev1)
- + option_with_arg ("-r", diff_rev1);
- + else if (diff_date1)
- + client_senddate (diff_date1);
- +#else
- if (diff_rev1)
- option_with_arg ("-r", diff_rev1);
- if (diff_date1)
- client_senddate (diff_date1);
- +#endif
- +#if defined(RSE_PATCH_DIFFJ)
- + if (diff_join2)
- + option_with_arg ("-j", diff_join2);
- + else if (diff_rev2)
- + option_with_arg ("-r", diff_rev2);
- + else if (diff_date2)
- + client_senddate (diff_date2);
- +#else
- if (diff_rev2)
- option_with_arg ("-r", diff_rev2);
- if (diff_date2)
- client_senddate (diff_date2);
- +#endif
- send_arg ("--");
-
- /* Send the current files unless diffing two revs from the archive */
- @@ -435,6 +505,12 @@
- free (options);
- options = NULL;
-
- +#if defined(RSE_PATCH_DIFFJ)
- + if (diff_join1 != NULL)
- + free (diff_join1);
- + if (diff_join2 != NULL)
- + free (diff_join2);
- +#endif
- if (diff_date1 != NULL)
- free (diff_date1);
- if (diff_date2 != NULL)
- @@ -488,7 +564,11 @@
- char *head =
- (vers->vn_rcs == NULL
- ? NULL
- +#ifdef RSE_PATCH_DIFFHEAD
- + : RCS_head (vers->srcfile));
- +#else
- : RCS_branch_head (vers->srcfile, vers->vn_rcs));
- +#endif
- exists = head != NULL && !RCS_isdead(vers->srcfile, head);
- if (head != NULL)
- free (head);
- @@ -822,7 +902,11 @@
- if (diff_rev1 && strcmp (diff_rev1, TAG_HEAD) == 0)
- {
- if (vers->vn_rcs != NULL && vers->srcfile != NULL)
- +#ifdef RSE_PATCH_DIFFHEAD
- + use_rev1 = RCS_head (vers->srcfile);
- +#else
- use_rev1 = RCS_branch_head (vers->srcfile, vers->vn_rcs);
- +#endif
- }
- else
- {
- @@ -838,7 +922,11 @@
- if (diff_rev2 && strcmp (diff_rev2, TAG_HEAD) == 0)
- {
- if (vers->vn_rcs != NULL && vers->srcfile != NULL)
- +#ifdef RSE_PATCH_DIFFHEAD
- + use_rev2 = RCS_head (vers->srcfile);
- +#else
- use_rev2 = RCS_branch_head (vers->srcfile, vers->vn_rcs);
- +#endif
- }
- else
- {
- Index: src/hash.c
- ===================================================================
- RCS file: /e/ossp/pkg/tool/cvs/cvs/cvs/src/hash.c,v
- retrieving revision 1.1.1.5
- diff -u -d -r1.1.1.5 hash.c
- --- src/hash.c 4 Oct 2003 14:36:03 -0000 1.1.1.5
- +++ src/hash.c 27 Oct 2003 19:07:23 -0000
- @@ -23,17 +23,25 @@
- hashp (const char *key)
- {
- unsigned int h = 0;
- +#ifndef RSE_PATCH_HASHFUNC
- unsigned int g;
- +#endif
-
- assert(key != NULL);
-
- while (*key != 0)
- {
- +#ifdef RSE_PATCH_HASHFUNC
- + /* D.J. Bernstein's popular times 33 function
- + (fast and distributes very well) */
- + h = ((h << 5) + h) + FOLD_FN_CHAR(*key++);
- +#else
- unsigned int c = *key++;
- /* The FOLD_FN_CHAR is so that findnode_fn works. */
- h = (h << 4) + FOLD_FN_CHAR (c);
- if ((g = h & 0xf0000000) != 0)
- h = (h ^ (g >> 24)) ^ g;
- +#endif
- }
-
- return (h % HASHSIZE);
- Index: src/history.c
- ===================================================================
- RCS file: /e/ossp/pkg/tool/cvs/cvs/cvs/src/history.c,v
- retrieving revision 1.1.1.9
- diff -u -d -r1.1.1.9 history.c
- --- src/history.c 8 Oct 2003 21:37:21 -0000 1.1.1.9
- +++ src/history.c 27 Oct 2003 19:10:23 -0000
- @@ -237,6 +237,9 @@
- static char *tz_name = "+0000";
-
- char *logHistory = ALL_HISTORY_REC_TYPES;
- +#ifdef RSE_PATCH_HISTORYFILE
- +char *history_file = NULL;
- +#endif
-
- /* -r, -t, or -b options, malloc'd. These are "" if the option in
- question is not specified or is overridden by another option. The
- @@ -668,6 +671,10 @@
-
- if (histfile)
- fname = xstrdup (histfile);
- +#ifdef RSE_PATCH_HISTORYFILE
- + else if (history_file)
- + fname = xstrdup (history_file);
- +#endif
- else
- {
- fname = xmalloc (strlen (current_parsed_root->directory) + sizeof (CVSROOTADM)
- @@ -713,10 +720,18 @@
- return;
- if ( strchr(logHistory, type) == NULL )
- return;
- +#ifdef RSE_PATCH_HISTORYFILE
- + if (history_file != NULL)
- + fname = xstrdup (history_file);
- + else {
- +#endif
- fname = xmalloc (strlen (current_parsed_root->directory) + sizeof (CVSROOTADM)
- + sizeof (CVSROOTADM_HISTORY) + 3);
- (void) sprintf (fname, "%s/%s/%s", current_parsed_root->directory,
- CVSROOTADM, CVSROOTADM_HISTORY);
- +#ifdef RSE_PATCH_HISTORYFILE
- + }
- +#endif
-
- /* turn off history logging if the history file does not exist */
- /* FIXME: This should check for write permissions instead. This way,
- Index: src/import.c
- ===================================================================
- RCS file: /e/ossp/pkg/tool/cvs/cvs/cvs/src/import.c,v
- retrieving revision 1.1.1.7
- diff -u -d -r1.1.1.7 import.c
- --- src/import.c 4 Oct 2003 21:11:55 -0000 1.1.1.7
- +++ src/import.c 27 Oct 2003 19:27:36 -0000
- @@ -56,6 +56,141 @@
- NULL
- };
-
- +#ifdef RSE_PATCH_IMPORTINFO
- +
- +static char *importinfo_vtag;
- +
- +static int
- +importinfo_descend(thisdir)
- + char *thisdir;
- +{
- + DIR *dirp;
- + struct dirent *dp;
- + int err = 0;
- + List *dirlist = NULL;
- +
- + if ((dirp = CVS_OPENDIR(thisdir)) == NULL) {
- + error(0, errno, "cannot open directory");
- + err++;
- + }
- + else {
- + errno = 0;
- + while ((dp = readdir(dirp)) != NULL) {
- + if (strcmp(dp->d_name, ".") == 0 || strcmp(dp->d_name, "..") == 0)
- + goto one_more_time_boys;
- + if (strcmp(dp->d_name, CVSADM) == 0)
- + goto one_more_time_boys;
- + if (ign_name(dp->d_name))
- + goto one_more_time_boys;
- + if (
- +#ifdef DT_DIR
- + (dp->d_type == DT_DIR || (dp->d_type == DT_UNKNOWN && isdir (dp->d_name)))
- +#else
- + isdir (dp->d_name)
- +#endif
- + && !wrap_name_has(dp->d_name, WRAP_TOCVS)
- + ) {
- + Node *n;
- + if (dirlist == NULL)
- + dirlist = getlist();
- + n = getnode();
- + n->key = xstrdup(dp->d_name);
- + addnode(dirlist, n);
- + }
- + else if (
- +#ifdef DT_DIR
- + dp->d_type == DT_LNK || (dp->d_type == DT_UNKNOWN && islink (dp->d_name))
- +#else
- + islink (dp->d_name)
- +#endif
- + ) {
- + err++;
- + }
- + else {
- + if (strcmp(thisdir, ".") == 0) {
- + run_arg(dp->d_name);
- + }
- + else {
- + char *p;
- + p = xmalloc(strlen(thisdir)+1+strlen(dp->d_name)+1);
- + (void)sprintf(p, "%s/%s", thisdir, dp->d_name);
- + run_arg(p);
- + free(p);
- + }
- + }
- + one_more_time_boys:
- + errno = 0;
- + }
- + if (errno != 0) {
- + error(0, errno, "cannot read directory");
- + err++;
- + }
- + (void)closedir(dirp);
- + }
- + if (dirlist != NULL) {
- + Node *head, *p;
- + head = dirlist->list;
- + for (p = head->next; p != head; p = p->next) {
- + if (strcmp(thisdir, ".") == 0) {
- + err += importinfo_descend(p->key);
- + }
- + else {
- + char *nextdir;
- + nextdir = xmalloc(strlen(thisdir)+1+strlen(p->key)+1);
- + (void)sprintf(nextdir, "%s/%s", thisdir, p->key);
- + err += importinfo_descend(nextdir);
- + free(nextdir);
- + }
- + }
- + dellist(&dirlist);
- + }
- + return err;
- +}
- +
- +/* importinfo configuration entry callback */
- +static int
- +importinfo_runproc(repository, filter, closure)
- + char *repository;
- + char *filter;
- + void *closure;
- +{
- + char *s, *cp;
- + int rv;
- +
- + /* if possible, do an own check to make sure that filter really exists */
- + if (filter[0] == '/') {
- + s = xstrdup(filter);
- + for (cp = s; *cp; cp++) {
- + if (isspace((unsigned char)*cp)) {
- + *cp = '\0';
- + break;
- + }
- + }
- + if (!isfile(s)) {
- + error (0, errno, "cannot find pre-admin filter '%s'", s);
- + free(s);
- + return (1);
- + }
- + free(s);
- + }
- +
- + /* construct the filter command */
- + run_setup(filter);
- + run_arg(importinfo_vtag);
- + run_arg(repository);
- + ign_add_file(CVSDOTIGNORE, 1);
- + wrap_add_file(CVSDOTWRAPPER, 1);
- + rv = importinfo_descend(".");
- + if (rv > 0)
- + return rv;
- +
- + /* execute the filter command */
- + rv = run_exec(RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL);
- +
- + return rv;
- +}
- +#endif
- +
- int
- import (int argc, char **argv)
- {
- @@ -287,6 +422,12 @@
- error (1, 0, "attempt to import the repository");
- }
-
- +#ifdef RSE_PATCH_IMPORTINFO
- + importinfo_vtag = argv[1];
- + if (Parse_Info(CVSROOTADM_IMPORTINFO, argv[0], importinfo_runproc, PIOPT_ALL, NULL) > 0)
- + error(1, 0, "Pre-import check failed");
- +#endif
- +
- /*
- * Make all newly created directories writable. Should really use a more
- * sophisticated security mechanism here.
- @@ -326,7 +467,11 @@
- "Use the following command to help the merge:");
- cvs_output_tagged ("newline", NULL);
- cvs_output_tagged ("newline", NULL);
- +#ifdef RSE_PATCH_COSMETICS
- + cvs_output_tagged ("text", " ");
- +#else
- cvs_output_tagged ("text", "\t");
- +#endif
- cvs_output_tagged ("text", program_name);
- if (CVSroot_cmdline != NULL)
- {
- @@ -353,7 +498,11 @@
- conflicts);
- (void) fprintf (logfp,
- "Use the following command to help the merge:\n\n");
- +#ifdef RSE_PATCH_COSMETICS
- + (void) fprintf (logfp, " %s checkout ", program_name);
- +#else
- (void) fprintf (logfp, "\t%s checkout ", program_name);
- +#endif
- (void) fprintf (logfp, "-j%s:yesterday -j%s %s\n\n",
- argv[1], argv[1], argv[0]);
- }
- @@ -376,6 +525,9 @@
- li->type = T_TITLE;
- li->tag = xstrdup (vbranch);
- li->rev_old = li->rev_new = NULL;
- +#ifdef RSE_PATCH_EXTRAPERCENT
- + li->date = NULL;
- +#endif
- p->data = (char *) li;
- (void) addnode (ulist, p);
- Update_Logfile (repository, message, logfp, ulist);
- @@ -652,7 +804,11 @@
- */
- if (add_tags (vers->srcfile, vfile, vtag, targc, targv))
- retval = 1;
- +#ifdef RSE_PATCH_IMPORTTOUCH
- + add_log ('T', vfile);
- +#else
- add_log ('U', vfile);
- +#endif
- freevers_ts (&vers);
- return (retval);
- }
- Index: src/list.c
- ===================================================================
- RCS file: src/list.c
- diff -N src/list.c
- --- /dev/null 1 Jan 1970 00:00:00 -0000
- +++ src/list.c 27 Oct 2003 19:28:25 -0000
- @@ -0,0 +1,282 @@
- +/*
- + * Copyright (c) 1998, Dan Rich <drich@employees.com>
- + *
- + * You may distribute under the terms of the GNU General Public License as
- + * specified in the README file that comes with the CVS source distribution.
- + *
- + * List Directory
- + */
- +
- +#ifdef RSE_PATCH_RLIST
- +
- +#include <time.h>
- +#include <pwd.h>
- +#include <grp.h>
- +
- +#if 0
- +#include "cvs.h"
- +#endif
- +
- +static int cvslist_fileproc (void *callerdat, struct file_info * finfo);
- +static Dtype cvslist_dirproc (void *callerdat, char *dir, char *repos, char *update_dir, List * entries);
- +static int cvslist_output_dir (Node * node, void *closure);
- +static int cvslist_output_file (char *name);
- +static int cvslist_tag_proc (Node * p, void *closure);
- +
- +static char *numtag;
- +static char *date = NULL;
- +static int force_tag_match = 1;
- +static int local = 0;
- +static int verbose = 0;
- +static int list_attic = 0;
- +static RCSNode *xrcsnode;
- +
- +static const char *const status_usage[] = {
- + "Usage: %s %s [-alRv] [-r tag|-D date] modules\n",
- + "\t-a\tInclude attic files\n",
- + "\t-v\tVerbose format; includes additional information for the file\n",
- + "\t-l\tProcess this directory only (not recursive).\n",
- + "\t-R\tProcess directories recursively.\n",
- + "\t-r rev\tExisting revision/tag.\n",
- + "\t-D\tExisting date.\n",
- + "(Specify the --help global option for a list of other help options)\n",
- + NULL
- +};
- +
- +int cvslist(int argc, char **argv)
- +{
- + int c;
- + int i;
- + int which;
- + int retval;
- +
- + if (argc == -1)
- + usage(status_usage);
- + optind = 0;
- + while ((c = getopt(argc, argv, "+alRr:v")) != -1) {
- + switch (c) {
- + case 'a':
- + list_attic = 1;
- + break;
- + case 'D':
- + if (date)
- + free(date);
- + date = Make_Date(optarg);
- + break;
- + case 'l':
- + local = 1;
- + break;
- + case 'R':
- + local = 0;
- + break;
- + case 'r':
- + numtag = optarg;
- + break;
- + case 'v':
- + verbose = 1;
- + break;
- + case '?':
- + default:
- + usage(status_usage);
- + break;
- + }
- + }
- + argc -= optind;
- + argv += optind;
- +
- + if (date && numtag)
- + error(1, 0, "-r and -D options are mutually exclusive");
- +
- + wrap_setup();
- +#ifdef CLIENT_SUPPORT
- + if (current_parsed_root->isremote) {
- + start_server();
- + ign_setup();
- + if (list_attic)
- + send_arg("-a");
- + if (local)
- + send_arg("-l");
- + if (verbose)
- + send_arg("-v");
- + if (numtag)
- + option_with_arg("-r", numtag);
- + if (date)
- + client_senddate(date);
- +#if 0
- + if (supported_request("expand-modules")) {
- + /* This is done here because we need to read responses from the
- + server before we send the command checkout or export files. */
- + client_expand_modules(argc, argv, local);
- + }
- +#endif
- + /* Send any remaining arguments -- probably dir/file names */
- + for (i = 0; i < argc; ++i)
- + send_arg(argv[i]);
- + send_to_server("list\012", 0); /* Send the command */
- + return get_responses_and_close();
- + }
- +#endif
- +#ifdef SERVER_SUPPORT
- + /* If we're the server, make sure we're starting at the root */
- + if (server_active)
- + CVS_CHDIR(current_parsed_root->directory);
- +#endif
- +
- +#if 0
- + if (numtag != NULL)
- + tag_check_valid(numtag, argc, argv, local, 0, "");
- +#endif
- +
- + which = W_REPOS;
- + if (list_attic)
- + which |= W_ATTIC;
- +
- + /* start the recursion processor */
- + cvs_output_tagged("+list", NULL);
- + retval = start_recursion(cvslist_fileproc, (FILESDONEPROC)NULL,
- + cvslist_dirproc, (DIRLEAVEPROC)NULL, NULL,
- + argc, argv, local, which, 0, 1, (char *)NULL, 1, (char *)NULL);
- + cvs_output_tagged("-list", NULL);
- +
- + return retval;
- +}
- +
- +/*
- + * Display file info
- + */
- +/* ARGSUSED */
- +static int cvslist_fileproc(callerdat, finfo)
- + void *callerdat;
- + struct file_info *finfo;
- +{
- + char *buf;
- + Vers_TS *vers;
- +
- + /* If a particular revision was specified, only show that one */
- + if (numtag != NULL || date != NULL) {
- + vers = Version_TS(finfo, NULL, NULL, NULL, 0, 0);
- + if (RCS_getversion(vers->srcfile, numtag, date, force_tag_match, NULL) == NULL)
- + return 0;
- + }
- +
- + cvslist_output_file(finfo->fullname);
- +
- + if (verbose) {
- + vers = Version_TS(finfo, NULL, NULL, NULL, 0, 0);
- + if (vers->srcfile) {
- + List *symbols = RCS_symbols(vers->srcfile);
- +
- + cvs_output_tagged("+info", NULL);
- + if (vers->vn_rcs == NULL)
- + cvs_output_tagged("finfo",
- + " Repository revision:\tNo revision control file");
- + else {
- + buf = (char *)malloc(24 + strlen(vers->vn_rcs) + 1 +
- + strlen(vers->srcfile->path) + 1);
- + sprintf(buf, " Repository revision:\t%s\t%s",
- + vers->vn_rcs, vers->srcfile->path);
- + cvs_output_tagged("finfo", buf);
- + }
- + cvs_output_tagged("newline", NULL);
- + cvs_output_tagged("finfo", " Existing Tags:");
- + cvs_output_tagged("newline", NULL);
- + if (symbols) {
- + xrcsnode = finfo->rcs;
- + (void)walklist(symbols, cvslist_tag_proc, NULL);
- + }
- + else
- + cvs_output_tagged("finfo", "\tNo Tags Exist");
- +
- + cvs_output_tagged("-info", NULL);
- + cvs_output_tagged("newline", NULL);
- + }
- + }
- + return 0;
- +}
- +
- +/*
- + * Display directory info
- + */
- +/* ARGSUSED */
- +static Dtype cvslist_dirproc(callerdat, dir, repos, update_dir, entries)
- + void *callerdat;
- + char *dir;
- + char *repos;
- + char *update_dir;
- + List *entries;
- +{
- + char *buf;
- + List *dirs;
- +
- + buf = (char *)malloc(strlen(update_dir) + 2);
- + sprintf(buf, "%s", update_dir);
- + cvs_output_tagged("fname", buf);
- + cvs_output_tagged("newline", NULL);
- + free(buf);
- +
- + if (local) { /* We need to output the current dirs */
- + dirs = Find_Directories(update_dir, W_REPOS, NULL);
- + walklist(dirs, cvslist_output_dir, update_dir);
- + }
- + return R_PROCESS;
- +}
- +
- +static int cvslist_output_dir(node, closure)
- + Node *node;
- + void *closure;
- +{
- + char *buf;
- +
- + buf = (char *)malloc(strlen((char *)closure) + strlen(node->key) + 3);
- + sprintf(buf, "%s/%s/", (char *)closure, node->key);
- + cvs_output_tagged("fname", buf);
- + cvs_output_tagged("newline", NULL);
- + free(buf);
- + return 0;
- +}
- +
- +static int cvslist_output_file(name)
- + char *name;
- +{
- + char *buf;
- + char *nlptr;
- +
- + buf = (char *)malloc(strlen(name) + 1);
- + strncpy(buf, name, strlen(name));
- + *(buf+strlen(name)) = '\0';
- +
- + /* cvs_output_tagged doesn't like \n */
- + if ((nlptr = strchr(buf, '\n')) != NULL)
- + nlptr = '\0';
- + cvs_output_tagged("fname", buf);
- + cvs_output_tagged("newline", NULL);
- + free(buf);
- + return 0;
- +}
- +
- +static int cvslist_tag_proc(p, closure)
- + Node *p;
- + void *closure;
- +{
- + char *branch = NULL;
- + char *buf;
- +
- + if (RCS_nodeisbranch(xrcsnode, p->key))
- + branch = RCS_whatbranch(xrcsnode, p->key);
- +
- + buf = xmalloc(80 + strlen(p->key)
- + + (branch ? strlen(branch) : strlen(p->data)));
- + sprintf(buf, "\t%-25s\t(%s: %s)", p->key,
- + branch ? "branch" : "revision", branch ? branch : p->data);
- + cvs_output_tagged("finfo", buf);
- + cvs_output_tagged("newline", NULL);
- + free(buf);
- +
- + if (branch)
- + free(branch);
- +
- + return (0);
- +}
- +
- +#endif /* RSE_PATCH_RLIST */
- +
- Index: src/logmsg.c
- ===================================================================
- RCS file: /e/ossp/pkg/tool/cvs/cvs/cvs/src/logmsg.c,v
- retrieving revision 1.1.1.8
- diff -u -d -r1.1.1.8 logmsg.c
- --- src/logmsg.c 29 Aug 2003 17:02:18 -0000 1.1.1.8
- +++ src/logmsg.c 27 Oct 2003 19:07:24 -0000
- @@ -646,6 +646,42 @@
- {
- switch (*c)
- {
- +#ifdef RSE_PATCH_EXTRAPERCENT
- + case 'o': {
- + char T[2];
- + str_list = xrealloc (str_list, (strlen (str_list) + 1 + 1));
- + switch (li->type) {
- + case T_ADDED: T[0] = 'A'; break;
- + case T_MODIFIED: T[0] = 'M'; break;
- + case T_REMOVED: T[0] = 'R'; break;
- + default: T[0] = '?'; break;
- + }
- + T[1] = '\0';
- + (void) strcat (str_list, T);
- + break;
- + }
- + case 't':
- + str_list =
- + xrealloc (str_list,
- + (strlen (str_list)
- + + (li->tag ? strlen (li->tag) : 0)
- + + 10)
- + );
- + (void) strcat (str_list, (li->tag ? li->tag : ""));
- + break;
- + case 'd': {
- + time_t t;
- + if (li->date != NULL) {
- + t = get_date(li->date, NULL);
- + if (t != ((time_t)-1)) {
- + t += 1; /* re-adjust because of fudge */
- + str_list = xrealloc (str_list, (strlen(str_list)+20));
- + sprintf(str_list+strlen(str_list), "%ld", (long)t);
- + }
- + }
- + break;
- + }
- +#endif
- case 's':
- str_list =
- xrealloc (str_list,
- Index: src/main.c
- ===================================================================
- RCS file: /e/ossp/pkg/tool/cvs/cvs/cvs/src/main.c,v
- retrieving revision 1.1.1.11
- diff -u -d -r1.1.1.11 main.c
- --- src/main.c 25 Nov 2003 16:11:47 -0000 1.1.1.11
- +++ src/main.c 5 Dec 2003 20:22:15 -0000
- @@ -51,6 +51,11 @@
-
- mode_t cvsumask = UMASK_DFLT;
-
- +#ifdef RSE_PATCH_PROLOGEPILOG
- +char *cvs_prolog = NULL;
- +char *cvs_epilog = NULL;
- +#endif
- +
- char *CurDir;
-
- /*
- @@ -125,11 +130,17 @@
- { "login", "logon", "lgn", login, 0 },
- { "logout", NULL, NULL, logout, 0 },
- #endif /* AUTH_CLIENT_SUPPORT */
- +#ifdef RSE_PATCH_PSERVERD
- + { "pserverd", NULL, NULL, pserverd },
- +#endif
- #if (defined(AUTH_SERVER_SUPPORT) || defined (HAVE_GSSAPI)) && defined(SERVER_SUPPORT)
- { "pserver", NULL, NULL, server, CVS_CMD_MODIFIES_REPOSITORY | CVS_CMD_USES_WORK_DIR }, /* placeholder */
- #endif
- { "rannotate","rann", "ra", annotate, 0 },
- { "rdiff", "patch", "pa", patch, 0 },
- +#ifdef RSE_PATCH_RLIST
- + { "rlist", "rls", NULL, cvslist, 0 },
- +#endif
- { "release", "re", "rel", release, 0 },
- { "remove", "rm", "delete", cvsremove, CVS_CMD_MODIFIES_REPOSITORY | CVS_CMD_USES_WORK_DIR },
- { "rlog", "rl", NULL, cvslog, 0 },
- @@ -144,9 +155,53 @@
- { "version", "ve", "ver", version, 0 },
- { "watch", NULL, NULL, watch, CVS_CMD_MODIFIES_REPOSITORY | CVS_CMD_USES_WORK_DIR },
- { "watchers", NULL, NULL, watchers, CVS_CMD_USES_WORK_DIR },
- +#ifdef RSE_PATCH_CVSROOT
- + { "root", "ro", "repo", root, CVS_CMD_IGNORE_ADMROOT },
- +#endif
- { NULL, NULL, NULL, NULL, 0 },
- };
-
- +#ifdef RSE_PATCH_CUSTOMCMD
- +
- +/* the table of custom commands */
- +#define CUSTOMCMD_MAX 20
- +static int customcmd_num = 0;
- +struct customcmd {
- + char *name;
- + char *command;
- +};
- +static struct customcmd customcmd_tab[CUSTOMCMD_MAX];
- +
- +/* the internal handler function for custom commands */
- +static int
- +customcmd_run(argc, argv)
- + int argc;
- + char **argv;
- +{
- + int i;
- + char *cmd;
- +
- + /* support for `cvs -H <cmd>' */
- + if (argc == -1) {
- + (void)fprintf(stderr, "Usage: %s %s [command arguments]\n",
- + program_name, command_name);
- + exit (EXIT_FAILURE);
- + }
- +
- + /* execute the command */
- + cmd = expand_path(argv[0], command_name, 0);
- + run_setup(cmd);
- + for (i = 1; i < argc; i++)
- + run_arg(argv[i]);
- + if (run_exec(RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL) != 0)
- + error(1, 0, "program `%s' of custom command `%s' returned non-zero",
- + cmd, command_name);
- + free(cmd);
- +
- + return 0;
- +}
- +#endif
- +
- static const char *const usg[] =
- {
- /* CVS usage messages never have followed the GNU convention of
- @@ -187,9 +242,13 @@
- paragraph in ../cvs.spec without assuming the reader knows what
- version control means. */
-
- +#ifdef RSE_PATCH_COSMETICS
- + "For CVS updates and additional information, see http://www.cvshome.org/\n",
- +#else
- "For CVS updates and additional information, see\n",
- " the CVS home page at http://www.cvshome.org/ or\n",
- " Pascal Molli's CVS site at http://www.loria.fr/~molli/cvs-index.html\n",
- +#endif
- NULL,
- };
-
- @@ -216,11 +275,17 @@
- " login Prompt for password for authenticating server\n",
- " logout Removes entry in .cvspass for remote repository\n",
- #endif /* AUTH_CLIENT_SUPPORT */
- +#ifdef RSE_PATCH_PSERVERD
- + " pserverd Password server daemon\n",
- +#endif
- #if (defined(AUTH_SERVER_SUPPORT) || defined (HAVE_GSSAPI)) && defined(SERVER_SUPPORT)
- " pserver Password server mode\n",
- #endif
- " rannotate Show last revision where each line of module was modified\n",
- " rdiff Create 'patch' format diffs between releases\n",
- +#ifdef RSE_PATCH_RLIST
- + " rlist List repository directories.\n",
- +#endif
- " release Indicate that a Module is no longer in use\n",
- " remove Remove an entry from the repository\n",
- " rlog Print out history information for a module\n",
- @@ -235,6 +300,9 @@
- " version Show current CVS version(s)\n",
- " watch Set watches\n",
- " watchers See who is watching a file\n",
- +#ifdef RSE_PATCH_CVSROOT
- + " root Maintain repository root locations\n",
- +#endif
- "(Specify the --help option for a list of other help options)\n",
- NULL,
- };
- @@ -264,6 +332,10 @@
- #endif
- " -a Authenticate all net traffic.\n",
- #endif
- +#ifdef RSE_PATCH_PROLOGEPILOG
- + " -P program Run prolog program before processing.\n",
- + " -E program Run epilog program after processing.\n",
- +#endif
- " -s VAR=VAL Set CVS user variable.\n",
- "(Specify the --help option for a list of other help options)\n",
- NULL
- @@ -331,6 +403,20 @@
- if (strcmp (cmd_name, cm->fullname) == 0)
- break;
- }
- +#ifdef RSE_PATCH_CUSTOMCMD
- + {
- + int i;
- + unsigned long int ret = 0;
- + for (i = 0; i < customcmd_num; i++) {
- + if (strcmp(customcmd_tab[i].name, cmd_name) == 0) {
- + ret |= CVS_CMD_IGNORE_ADMROOT;
- + ret &= ~(CVS_CMD_USES_WORK_DIR);
- + ret &= ~(CVS_CMD_MODIFIES_REPOSITORY);
- + return ret;
- + }
- + }
- + }
- +#endif
- if (!cm->fullname)
- error (1, 0, "unknown command: %s", cmd_name);
- return cm->attr;
- @@ -419,11 +505,30 @@
- int free_CVSroot = 0;
- int free_Editor = 0;
- int free_Tmpdir = 0;
- +#ifdef RSE_PATCH_CVSROOT
- + cvsroot_type *cvsroot_sync = NULL;
- + int cvsroot_cmdline_isreal = 0;
- +#endif
- +#if defined(RSE_PATCH_CVSROOT) || defined(RSE_PATCH_CUSTOMCMD)
- + int standalone_command = 0;
- +#endif
-
- int help = 0; /* Has the user asked for help? This
- lets us support the `cvs -H cmd'
- convention to give help for cmd. */
- +#if defined(RSE_PATCH_PROLOGEPILOG) ||\
- + defined(RSE_PATCH_CUSTOMCMD)
- + static const char short_options[] = "+QqrwtnRvb:T:e:d:Hfz:s:xa"
- +#ifdef RSE_PATCH_PROLOGEPILOG
- + "P:E:"
- +#endif
- +#ifdef RSE_PATCH_CUSTOMCMD
- + "C:"
- +#endif
- + ;
- +#else
- static const char short_options[] = "+QqrwtnRvb:T:e:d:Hfz:s:xa";
- +#endif
- static struct option long_options[] =
- {
- {"help", 0, NULL, 'H'},
- @@ -432,6 +537,9 @@
- {"help-synonyms", 0, NULL, 2},
- {"help-options", 0, NULL, 4},
- {"allow-root", required_argument, NULL, 3},
- +#ifdef RSE_PATCH_MAPROOT
- + {"map-root", required_argument, NULL, 5},
- +#endif
- {0, 0, 0, 0}
- };
- /* `getopt_long' stores the option index here, but right now we
- @@ -496,6 +604,10 @@
- readonlyfs = 1;
- logoff = 1;
- }
- +#ifdef RSE_PATCH_PROLOGEPILOG
- + cvs_prolog = getenv("CVSPROLOG");
- + cvs_epilog = getenv("CVSEPILOG");
- +#endif
-
- /* Set this to 0 to force getopt initialization. getopt() sets
- this to 1 internally. */
- @@ -515,12 +627,63 @@
- use_cvsrc = 0;
- }
-
- +#ifdef RSE_PATCH_GLOBALOPTION
- + /*
- + * Perform a pre-lookup of the command name in order to scan cvsrc
- + * file also for command dependent global options. For instance a
- + * "-d" option only for "commit" commands (useful if one uses a
- + * local repository copy for all cvs commands, but commits have to
- + * go directly to the master repository).
- + */
- + if (use_cvsrc) {
- + command_name = argv[optind];
- + if (command_name != NULL && command_name[0] != '\0') {
- + for (cm = cmds; cm->fullname != NULL; cm++)
- + {
- + if (cm->nick1 && !strcmp(command_name, cm->nick1))
- + break;
- + if (cm->nick2 && !strcmp(command_name, cm->nick2))
- + break;
- + if (!strcmp(command_name, cm->fullname))
- + break;
- + }
- + command_name = cm->fullname;
- + }
- + }
- +#endif
- +
- /*
- * Scan cvsrc file for global options.
- */
- if (use_cvsrc)
- read_cvsrc (&argc, &argv, "cvs");
-
- +#ifdef RSE_PATCH_GLOBALOPTION
- + if (use_cvsrc) {
- + if (command_name != NULL && command_name[0] != '\0') {
- + char *cmd;
- +#ifdef RSE_PATCH_GLOBALOPTION_PARTLY
- + if ( strcmp(command_name, "commit") == 0
- + || strcmp(command_name, "tag") == 0
- + || strcmp(command_name, "rtag") == 0
- + || strcmp(command_name, "history") == 0
- + || strcmp(command_name, "admin") == 0
- + || strcmp(command_name, "import") == 0
- +#ifdef RSE_PATCH_RLIST
- + || strcmp(command_name, "rlist") == 0
- +#endif
- + || strcmp(command_name, "rdiff") == 0) {
- +#endif
- + cmd = xmalloc(4 + strlen(command_name) + 1);
- + sprintf(cmd, "cvs/%s", command_name);
- + read_cvsrc (&argc, &argv, cmd);
- +#ifdef RSE_PATCH_GLOBALOPTION_PARTLY
- + }
- +#endif
- + }
- + }
- +#endif
- +
- optind = 0;
- opterr = 1;
-
- @@ -546,6 +709,17 @@
- /* --allow-root */
- root_allow_add (optarg);
- break;
- +#ifdef RSE_PATCH_MAPROOT
- + case 5: {
- + /* --map-root */
- + char *cp;
- + if ((cp = strchr(optarg, ':')) == NULL)
- + error(1, 0, "invalid argument syntax for --map-root option");
- + *cp++ = '\0';
- + root_map_add(optarg, cp);
- + break;
- + }
- +#endif
- case 'Q':
- really_quiet = 1;
- /* FALL THROUGH */
- @@ -605,10 +779,34 @@
- case 'd':
- if (CVSroot_cmdline != NULL)
- free (CVSroot_cmdline);
- +#ifdef RSE_PATCH_MAPROOT
- + {
- + char *newarg;
- + if (root_map_it(optarg, &newarg, 0))
- + optarg = newarg;
- + }
- +#endif
- +#ifdef RSE_PATCH_CVSROOT
- + {
- + cvsroot_type *e;
- + if ((e = cvsroot_lookup(optarg, NULL, NULL)) != NULL) {
- + if (!quiet)
- + fprintf(stderr, "%s: using repository `%s'\n", program_name, e->masterpath);
- + CVSroot_cmdline = xstrdup(e->masterpath);
- + CVSroot = xstrdup(e->masterpath);
- + cvsroot_free(e);
- + }
- + else {
- + cvsroot_cmdline_isreal = 1;
- +#endif
- CVSroot_cmdline = xstrdup (optarg);
- if (free_CVSroot)
- {
- free (CVSroot);
- +#ifdef RSE_PATCH_CVSROOT
- + }
- + }
- +#endif
- free_CVSroot = 0;
- }
- CVSroot = CVSroot_cmdline;
- @@ -657,6 +855,28 @@
- We will issue an error later if stream
- authentication is not supported. */
- break;
- +#ifdef RSE_PATCH_PROLOGEPILOG
- + case 'P':
- + cvs_prolog = xstrdup(optarg);
- + break;
- + case 'E':
- + cvs_epilog = xstrdup(optarg);
- + break;
- +#endif
- +#ifdef RSE_PATCH_CUSTOMCMD
- + case 'C': {
- + char *cp;
- + if (customcmd_num >= CUSTOMCMD_MAX)
- + error(1, 0, "maximum number of allowed -C options reached");
- + if ((cp = strchr(optarg, ':')) == NULL)
- + error(1, 0, "invalid argument to option -C (has to be \"name:cmd\")");
- + *cp++ = '\0';
- + customcmd_tab[customcmd_num].name = xstrdup(optarg);
- + customcmd_tab[customcmd_num].command = xstrdup(cp);
- + customcmd_num++;
- + break;
- + }
- +#endif
- case '?':
- default:
- usage (usg);
- @@ -674,6 +894,28 @@
- Using this option to access a repository which some users write to may\n\
- cause intermittent sandbox corruption.");
- }
- +#ifdef RSE_PATCH_CUSTOMCMD
- + /* Look up the custom command. */
- + cm = NULL;
- + {
- + int i;
- + command_name = argv[0];
- + for (i = 0; i < customcmd_num; i++) {
- + if (strcmp(customcmd_tab[i].name, command_name) == 0) {
- + struct cmd *ccm;
- + ccm = (struct cmd *)xmalloc(sizeof(struct cmd));
- + ccm->nick1 = NULL;
- + ccm->nick2 = NULL;
- + ccm->func = customcmd_run;
- + ccm->fullname = customcmd_tab[i].name;
- + argv[0] = customcmd_tab[i].command;
- + cm = (const struct cmd *)ccm;
- + standalone_command = 1;
- + }
- + }
- + }
- + if (cm == NULL) {
- +#endif
-
- /* Look up the command name. */
-
- @@ -696,6 +938,10 @@
- else
- command_name = cm->fullname; /* Global pointer for later use */
-
- +#ifdef RSE_PATCH_CUSTOMCMD
- + }
- +#endif
- +
- if (help)
- {
- argc = -1; /* some functions only check for this */
- @@ -723,6 +969,71 @@
- CVSUMASK_ENV, cp);
- }
-
- +#ifdef RSE_PATCH_CVSPID
- + /* provide the process id of the parent CVS process to
- + sub-processes (usually scripts called from *info files) in order
- + to let them have a unique session handle */
- + {
- + char pidbuf[64];
- + sprintf(pidbuf, "CVSPID=%lu", (unsigned long)getpid());
- + putenv(pidbuf);
- + }
- +#endif
- +
- +#ifdef RSE_PATCH_SETXID
- + if ( strcmp(command_name, "kserver") != 0
- + && strcmp(command_name, "pserver") != 0
- + && strcmp(command_name, "server") == 0) {
- + uid_t uid, euid;
- + gid_t gid, egid;
- + struct passwd *pw;
- + char *env;
- +
- + /* adjust group id */
- + gid = getgid();
- + egid = getegid();
- + if (gid != egid)
- + setgid(egid); /* upgrade real to effective gid */
- + else
- + setegid(gid); /* downgrade effective to real gid */
- +
- + /* adjust user id */
- + uid = getuid();
- + euid = geteuid();
- + if (uid != euid)
- + setuid(euid); /* upgrade real to effective uid */
- + else
- + seteuid(uid); /* downgrade effective to real uid */
- +
- + /* still do not adjust umask */
- + umask(0);
- +
- + /* remember real user (especially for getcaller()) */
- + pw = getpwuid(uid);
- +#ifdef AUTH_SERVER_SUPPORT
- + CVS_Username = xstrdup(pw->pw_name);
- +#if HAVE_PUTENV
- + env = xmalloc(sizeof("LOGNAME=")+strlen(CVS_Username));
- + (void)sprintf(env, "LOGNAME=%s", CVS_Username);
- + (void)putenv(env);
- +#endif
- +#endif
- +
- +#if HAVE_PUTENV
- + /* remember running user */
- + pw = getpwuid(getuid());
- + env = xmalloc(sizeof("USER=")+strlen(pw->pw_name));
- + (void)sprintf(env, "USER=%s", pw->pw_name);
- + (void)putenv(env);
- +#endif
- + }
- + else {
- + /* delete effective user and group id */
- + seteuid(getuid());
- + setegid(getgid());
- + }
- +#endif
- +
- #ifdef SERVER_SUPPORT
-
- # ifdef HAVE_KERBEROS
- @@ -739,6 +1050,21 @@
- }
- # endif /* HAVE_KERBEROS */
-
- +#ifdef RSE_PATCH_PSERVERD
- + if (strcmp(command_name, "pserverd") == 0) {
- + /*
- + * perform the socket listening. This returns multiple times,
- + * i.e., for each connection. But the parent never returns.
- + */
- + pserver_daemon(argc, argv);
- +
- + /*
- + * switch to regular "cvs server" operation.
- + */
- + argc = 0;
- + command_name = "server";
- + }
- +#endif
-
- # if defined (AUTH_SERVER_SUPPORT) || defined (HAVE_GSSAPI)
- if (strcmp (command_name, "pserver") == 0)
- @@ -763,6 +1089,10 @@
-
- #endif /* SERVER_SUPPORT */
-
- +#ifdef RSE_PATCH_CVSROOT
- + if (strcmp(command_name, "root") == 0)
- + standalone_command = 1;
- +#endif
-
- #ifdef SERVER_SUPPORT
- if (server_active)
- @@ -825,8 +1155,12 @@
- in server mode, since the client will send the repository
- directory after the connection is made. */
-
- +#if defined(RSE_PATCH_CVSROOT) || defined(RSE_PATCH_CUSTOMCMD)
- + if (!server_active && !standalone_command)
- +#else
- if (!server_active)
- #endif
- +#endif
- {
- char *CVSADM_Root;
-
- @@ -882,6 +1216,54 @@
- error (1, 0,
- "CVS/Root file (if any).");
- }
- +
- +#ifdef RSE_PATCH_CVSROOT
- + if (CVSroot_cmdline == NULL || !cvsroot_cmdline_isreal) {
- + cvsroot_type *e;
- + if (lookup_command_attribute(command_name) & CVS_CMD_MODIFIES_REPOSITORY) {
- + if ((e = cvsroot_lookup(NULL, NULL, CVSroot)) != NULL) {
- + /* command modifies repository and we still operare on
- + the slave repository, so switch to the master repository,
- + because we can only perform modifications there. */
- + if (!quiet) {
- + fprintf(stderr, "%s: switching to MASTER location of repository `%s'\n", program_name, e->nickname);
- + fprintf(stderr, "%s: %s <-- %s\n", program_name, e->masterpath, e->slavepath);
- + }
- + if (free_CVSroot)
- + free(CVSroot);
- + CVSroot = xstrdup(e->masterpath);
- + if (CVSroot_cmdline != NULL)
- + free(CVSroot_cmdline);
- + CVSroot_cmdline = xstrdup(e->masterpath);
- + cvsroot_sync = e;
- + free_CVSroot = 1;
- + cvs_update_env = 1;
- + }
- + }
- + else {
- + if ((e = cvsroot_lookup(NULL, CVSroot, NULL)) != NULL) {
- + if (e->slavepath[0] != '\0') {
- + /* command does not modify repository and we still operare on
- + the master repository, so switch to the slave repository,
- + because it is faster by definition. */
- + if (!quiet) {
- + fprintf(stderr, "%s: switching to SLAVE location of repository `%s'\n", program_name, e->nickname);
- + fprintf(stderr, "%s: %s --> %s\n", program_name, e->masterpath, e->slavepath);
- + }
- + if (free_CVSroot)
- + free(CVSroot);
- + CVSroot = xstrdup(e->slavepath);
- + if (CVSroot_cmdline != NULL)
- + free(CVSroot_cmdline);
- + CVSroot_cmdline = xstrdup(e->slavepath);
- + cvsroot_free(e);
- + free_CVSroot = 1;
- + cvs_update_env = 1;
- + }
- + }
- + }
- + }
- +#endif /* RSE_PATCH_CVSROOT */
- }
-
- /* Here begins the big loop over unique cvsroot values. We
- @@ -914,6 +1296,9 @@
- end of things. */
-
- while (
- +#if defined(RSE_PATCH_CVSROOT) || defined(RSE_PATCH_CUSTOMCMD)
- + standalone_command ||
- +#endif
- #ifdef SERVER_SUPPORT
- server_active ||
- #endif
- @@ -925,8 +1310,12 @@
- in server mode, since the client will send the repository
- directory after the connection is made. */
-
- +#if defined(RSE_PATCH_CVSROOT) || defined(RSE_PATCH_CUSTOMCMD)
- + if (!server_active && !standalone_command)
- +#else
- if (!server_active)
- #endif
- +#endif
- {
- /* Now we're 100% sure that we have a valid CVSROOT
- variable. Parse it to see if we're supposed to do
- @@ -959,7 +1348,12 @@
- {
- save_errno = errno;
- /* If this is "cvs init", the root need not exist yet. */
- +#ifdef RSE_PATCH_CVSROOT
- + if (strcmp (command_name, "init") != 0 &&
- + strcmp (command_name, "root") != 0)
- +#else
- if (strcmp (command_name, "init") != 0)
- +#endif
- {
- error (1, save_errno, "%s", path);
- }
- @@ -995,6 +1389,9 @@
- read_cvsrc and other such places or vice versa. That sort
- of thing probably needs more thought. */
- if (1
- +#if defined(RSE_PATCH_CVSROOT) || defined(RSE_PATCH_CUSTOMCMD)
- + && !standalone_command
- +#endif
- #ifdef SERVER_SUPPORT
- && !server_active
- #endif
- @@ -1025,7 +1422,31 @@
- }
- #endif
-
- +#ifdef RSE_PATCH_PROLOGEPILOG
- + if (cvs_prolog != NULL) {
- + char *cmd;
- + cmd = expand_path(cvs_prolog, "prolog", 0);
- + run_setup(cmd);
- + run_arg("prolog");
- + run_arg(command_name);
- + if (CurDir != NULL)
- + run_arg(CurDir);
- + else
- + run_arg("unknown-cwd");
- + if (current_parsed_root != NULL && current_parsed_root->directory != NULL)
- + run_arg(current_parsed_root->directory);
- + else
- + run_arg("unknown-cvsroot");
- + if (run_exec(RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL) != 0)
- + error(1, 0, "prolog program `%s' returned non-zero", cmd);
- + free(cmd);
- + }
- +#endif
- +
- if (
- +#if defined(RSE_PATCH_CVSROOT) || defined(RSE_PATCH_CUSTOMCMD)
- + !standalone_command && (
- +#endif
- #ifdef SERVER_SUPPORT
- /* Don't worry about lock_cleanup_setup when the server is
- * active since we can only go through this loop once in that
- @@ -1034,6 +1455,9 @@
- server_active ||
- #endif
- !current_parsed_root->isremote && !lock_cleanup_setup)
- +#if defined(RSE_PATCH_CVSROOT) || defined(RSE_PATCH_CUSTOMCMD)
- + )
- +#endif
- {
- /* Set up to clean up any locks we might create on exit. */
- cleanup_register (Lock_Cleanup);
- @@ -1042,6 +1466,27 @@
-
- /* Call our worker function. */
- err = (*(cm->func)) (argc, argv);
- +
- +#ifdef RSE_PATCH_PROLOGEPILOG
- + if (cvs_epilog != NULL) {
- + char *cmd;
- + cmd = expand_path(cvs_epilog, "epilog", 0);
- + run_setup(cmd);
- + run_arg("epilog");
- + run_arg(command_name);
- + if (CurDir != NULL)
- + run_arg(CurDir);
- + else
- + run_arg("unknown-cwd");
- + if (current_parsed_root != NULL && current_parsed_root->directory != NULL)
- + run_arg(current_parsed_root->directory);
- + else
- + run_arg("unknown-cvsroot");
- + if (run_exec(RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL) != 0)
- + error(1, 0, "epilog program `%s' returned non-zero", cmd);
- + free(cmd);
- + }
- +#endif
-
- /* Mark this root directory as done. When the server is
- active, current_root will be NULL -- don't try and
- @@ -1060,12 +1505,21 @@
- dellist (&root_directories);
- #endif
-
- +#if defined(RSE_PATCH_CVSROOT) || defined(RSE_PATCH_CUSTOMCMD)
- + if (standalone_command)
- + break;
- +#endif
- #ifdef SERVER_SUPPORT
- if (server_active)
- break;
- #endif
- } /* end of loop for cvsroot values */
-
- +#ifdef RSE_PATCH_CVSROOT
- + if (cvsroot_sync != NULL)
- + cvsroot_synchronize(cvsroot_sync, 0);
- +#endif
- +
- } /* end of stuff that gets done if the user DOESN'T ask for help */
-
- if (free_CVSroot)
- Index: src/mkmodules.c
- ===================================================================
- RCS file: /e/ossp/pkg/tool/cvs/cvs/cvs/src/mkmodules.c,v
- retrieving revision 1.1.1.7
- diff -u -d -r1.1.1.7 mkmodules.c
- --- src/mkmodules.c 8 Oct 2003 21:37:21 -0000 1.1.1.7
- +++ src/mkmodules.c 27 Oct 2003 19:20:05 -0000
- @@ -164,6 +164,48 @@
- NULL
- };
-
- +#ifdef RSE_PATCH_ADMININFO
- +static const char *const admininfo_contents[] = {
- + "# The \"admininfo\" file is used to control pre-admin checks.\n",
- + "# The filter on the right is invoked with the repository and a list \n",
- + "# of files to check. A non-zero exit of the filter program will \n",
- + "# cause the admin operation to be aborted.\n",
- + "#\n",
- + "# The first entry on a line is a regular expression which is tested\n",
- + "# against the directory that the change is being committed to, relative\n",
- + "# to the $CVSROOT. For the first match that is found, then the remainder\n",
- + "# of the line is the name of the filter to run.\n",
- + "#\n",
- + "# If the repository name does not match any of the regular expressions in this\n",
- + "# file, the \"DEFAULT\" line is used, if it is specified.\n",
- + "#\n",
- + "# If the name \"ALL\" appears as a regular expression it is always used\n",
- + "# in addition to the first matching regex or \"DEFAULT\".\n",
- + NULL
- +};
- +#endif
- +
- +#ifdef RSE_PATCH_IMPORTINFO
- +static const char *const importinfo_contents[] = {
- + "# The \"importinfo\" file is used to control pre-import checks.\n",
- + "# The filter on the right is invoked with the repository to check.\n",
- + "# A non-zero exit of the filter program will cause the import\n",
- + "# operation to be aborted.\n",
- + "#\n",
- + "# The first entry on a line is a regular expression which is tested\n",
- + "# against the directory that the change is being committed to, relative\n",
- + "# to the $CVSROOT. For the first match that is found, then the remainder\n",
- + "# of the line is the name of the filter to run.\n",
- + "#\n",
- + "# If the repository name does not match any of the regular expressions in this\n",
- + "# file, the \"DEFAULT\" line is used, if it is specified.\n",
- + "#\n",
- + "# If the name \"ALL\" appears as a regular expression it is always used\n",
- + "# in addition to the first matching regex or \"DEFAULT\".\n",
- + NULL
- +};
- +#endif
- +
- static const char *const checkoutlist_contents[] = {
- "# The \"checkoutlist\" file is used to support additional version controlled\n",
- "# administrative files in $CVSROOT/CVSROOT, such as template files.\n",
- @@ -285,6 +327,17 @@
- "# repositories. Set it to `never' (the previous CVS behavior) to prevent\n",
- "# verifymsg scripts from changing the log message.\n",
- "#RereadLogAfterVerify=always\n",
- +#ifdef RSE_PATCH_HISTORYFILE
- + "\n",
- + "# Set `HistoryFile' to the path name (relative to CVSROOT) of the history file\n",
- + "# if you do not want to store it not under CVSROOT/history\n",
- + "#HistoryFile=CVSROOT/history\n",
- +#endif
- +#ifdef RSE_PATCH_CONFIGUMASK
- + "\n",
- + "# Set `UMask' to the octal value of the umask.\n",
- + "#UMask=002\n",
- +#endif
- "\n",
- "# Set `UserAdminOptions' to the list of `cvs admin' commands (options)\n",
- "# that users not in the `cvsadmin' group are allowed to run. This\n",
- @@ -314,6 +367,16 @@
- {CVSROOTADM_TAGINFO,
- "a %s file can be used to configure 'cvs tag' checking",
- taginfo_contents},
- +#ifdef RSE_PATCH_ADMININFO
- + {CVSROOTADM_ADMININFO,
- + "a %s file can be used to configure 'cvs admin' checking",
- + admininfo_contents},
- +#endif
- +#ifdef RSE_PATCH_IMPORTINFO
- + {CVSROOTADM_IMPORTINFO,
- + "a %s file can be used to configure 'cvs import' checking",
- + importinfo_contents},
- +#endif
- {CVSROOTADM_IGNORE,
- "a %s file can be used to specify files to ignore",
- NULL},
- Index: src/parseinfo.c
- ===================================================================
- RCS file: /e/ossp/pkg/tool/cvs/cvs/cvs/src/parseinfo.c,v
- retrieving revision 1.1.1.9
- diff -u -d -r1.1.1.9 parseinfo.c
- --- src/parseinfo.c 19 Aug 2003 12:20:48 -0000 1.1.1.9
- +++ src/parseinfo.c 27 Oct 2003 19:19:25 -0000
- @@ -10,6 +10,9 @@
- #include "getline.h"
-
- extern char *logHistory;
- +#ifdef RSE_PATCH_HISTORYFILE
- +extern char *history_file;
- +#endif
-
- /*
- * Parse the INFOFILE file for the specified REPOSITORY. Invoke CALLPROC for
- @@ -380,7 +383,24 @@
- {
- if (lock_dir != NULL)
- free (lock_dir);
- +#ifdef RSE_PATCH_RELLOCKDIR
- + if (p[0] == '/') {
- +#endif
- lock_dir = xstrdup (p);
- +#ifdef RSE_PATCH_RELLOCKDIR
- + }
- + else {
- + char *s;
- +
- + lock_dir = xmalloc (strlen (p)
- + + strlen (current_parsed_root->directory)
- + + 2);
- + strcpy (lock_dir, current_parsed_root->directory);
- + s = lock_dir + strlen (lock_dir);
- + *s++ = '/';
- + strcpy (s, p);
- + }
- +#endif
- /* Could try some validity checking, like whether we can
- opendir it or something, but I don't see any particular
- reason to do that now rather than waiting until lock.c. */
- @@ -402,6 +422,19 @@
- else if (strcmp (p, "stat") == 0)
- RereadLogAfterVerify = LOGMSG_REREAD_STAT;
- }
- +#ifdef RSE_PATCH_HISTORYFILE
- + else if (strcmp (line, "HistoryFile") == 0)
- + {
- + if (history_file != NULL)
- + free (history_file);
- + history_file = xstrdup (p);
- + }
- +#endif
- +#ifdef RSE_PATCH_CONFIGUMASK
- + else if (strcmp (line, "UMask") == 0) {
- + cvsumask = (mode_t)(strtol(p, NULL, 8) & 0777);
- + }
- +#endif
- else if (strcmp (line, "UserAdminOptions") == 0)
- {
- UserAdminOptions = xmalloc(strlen(p) + 1);
- @@ -420,9 +453,11 @@
- adding new keywords to your CVSROOT/config file is not
- particularly recommended unless you are planning on using
- the new features. */
- +#ifndef RSE_PATCH_SMARTCONFIG
- error (0, 0, "%s: unrecognized keyword '%s'",
- infopath, line);
- goto error_return;
- +#endif
- }
- }
- if (ferror (fp_info))
- Index: src/repos.c
- ===================================================================
- RCS file: /e/ossp/pkg/tool/cvs/cvs/cvs/src/repos.c,v
- retrieving revision 1.1.1.7
- diff -u -d -r1.1.1.7 repos.c
- --- src/repos.c 11 Nov 2003 00:55:54 -0000 1.1.1.7
- +++ src/repos.c 5 Dec 2003 20:22:15 -0000
- @@ -193,3 +193,11 @@
- repository[len - 2] = '\0';
- }
- }
- +
- +#ifdef RSE_PATCH_RLIST
- +/* Shameless hack: in order to avoid having to patch the brain-dead
- + Automake-based CVS build environment (src/Makefile.am) we add the
- + "cvs rlist" code to an arbitrarily chosen source file. */
- +#include "list.c"
- +#endif
- +
- Index: src/root.c
- ===================================================================
- RCS file: /e/ossp/pkg/tool/cvs/cvs/cvs/src/root.c,v
- retrieving revision 1.1.1.10
- diff -u -d -r1.1.1.10 root.c
- --- src/root.c 25 Nov 2003 16:11:50 -0000 1.1.1.10
- +++ src/root.c 5 Dec 2003 20:22:15 -0000
- @@ -125,6 +125,9 @@
- /* allocate space to return and fill it in */
- strip_trailing_slashes (root);
- ret = xstrdup (root);
- +#ifdef RSE_PATCH_MAPROOT
- + root_map_it(ret, &ret, 0);
- +#endif
- out:
- free (cvsadm);
- free (tmp);
- @@ -253,7 +256,86 @@
- return 0;
- }
-
- +#ifdef RSE_PATCH_MAPROOT
- +
- +typedef struct root_map_st {
- + char *old;
- + char *new;
- +} root_map_t;
- +
- +#define ROOT_MAP_MAX 10
- +static int root_map_max = 0;
- +static root_map_t root_map_vec[ROOT_MAP_MAX];
- +
- +void root_map_add(char *old, char *new)
- +{
- + if (root_map_max >= ROOT_MAP_MAX)
- + return;
- + root_map_vec[root_map_max].old = xstrdup(old);
- + root_map_vec[root_map_max].new = xstrdup(new);
- + root_map_max++;
- + return;
- +}
- +
- +void root_map_free(void)
- +{
- + while (root_map_max > 0) {
- + free(root_map_vec[root_map_max].old);
- + free(root_map_vec[root_map_max].new);
- + root_map_max--;
- + }
- + return;
- +}
- +
- +int root_map_it(char *old, char **new, int prefixonly)
- +{
- + int rv;
- + int i;
- + int n;
- +
- + if (old == NULL)
- + return 0;
- + rv = 0;
- + for (i = 0; i < root_map_max; i++) {
- + n = strlen(root_map_vec[i].old);
- + if (!prefixonly && strcmp(old, root_map_vec[i].old) == 0) {
- + if (new == NULL) {
- + /* we assume old is buffer and override it */
- + strcpy(old, root_map_vec[i].new);
- + }
- + else {
- + if (old == *new)
- + /* old and new is same pointer we free before */
- + free(old);
- + /* provide new allocated buffer */
- + *new = xmalloc(strlen(root_map_vec[i].new)+1);
- + strcpy(*new, root_map_vec[i].new);
- + }
- + rv = 1;
- + break;
- + }
- + else if (prefixonly && strncmp(old, root_map_vec[i].old, n) == 0) {
- + if (new == NULL) {
- + /* we assume old is buffer and override it */
- + sprintf(old, "%s%s", root_map_vec[i].new, old+n);
- + }
- + else {
- + char *oldnew = *new;
- + /* provide new allocated buffer */
- + *new = xmalloc(strlen(root_map_vec[i].new)+strlen(old+n)+1);
- + sprintf(*new, "%s%s", root_map_vec[i].new, old+n);
- + if (old == oldnew)
- + /* old and new is same pointer we free before */
- + free(old);
- + }
- + rv = 1;
- + break;
- + }
- + }
- + return rv;
- +}
-
- +#endif /* RSE_PATCH_MAPROOT */
-
- /* This global variable holds the global -d option. It is NULL if -d
- was not used, which means that we must get the CVSroot information
- @@ -814,5 +896,473 @@
- /* NOTREACHED */
- }
- #endif
- +
- +#ifdef RSE_PATCH_CVSROOT
- +
- +#include <string.h>
- +
- +#ifndef CVS_ROOT_FILE
- +#define CVS_ROOT_FILE ".cvsroot"
- +#endif
- +
- +char *
- +cvsroot_filename(
- + void)
- +{
- + char *homedir;
- + char *rootfile;
- +
- + /* Environment should override file. */
- + if ((rootfile = getenv("CVS_ROOTFILE")) != NULL)
- + return xstrdup(rootfile);
- +
- + /* Construct absolute pathname to user's password file. */
- + if ((homedir = get_homedir()) == NULL) {
- + error(1, 0, "could not find out home directory");
- + return NULL;
- + }
- + rootfile = (char *)xmalloc(strlen(homedir)+strlen(CVS_ROOT_FILE)+3);
- + strcpy(rootfile, homedir);
- + strcat(rootfile, "/");
- + strcat(rootfile, CVS_ROOT_FILE);
- + return rootfile;
- +}
- +
- +void cvsroot_free(
- + cvsroot_type *e)
- +{
- + if (e != NULL) {
- + if (e->nickname != NULL)
- + free(e->nickname);
- + if (e->masterpath != NULL)
- + free(e->masterpath);
- + if (e->slavepath != NULL)
- + free(e->slavepath);
- + if (e->syncprog != NULL)
- + free(e->syncprog);
- + free(e);
- + }
- + return;
- +}
- +
- +cvsroot_type *
- +cvsroot_entry_read(
- + FILE *fp)
- +{
- + cvsroot_type *e;
- + char *nickname;
- + char *masterpath;
- + char *slavepath;
- + char *syncprog;
- + char *line;
- + int line_length;
- + size_t line_chars_allocated;
- + size_t n;
- +
- + e = NULL;
- + line = NULL;
- + line_chars_allocated = 0;
- + while ((line_length = getline(&line, &line_chars_allocated, fp)) >= 0) {
- + /* parse line */
- + line += strspn(line, " \t\n");
- + if (line[0] == '#')
- + continue;
- + nickname = line;
- + if ((n = strcspn(line, " \t\n")) == 0)
- + return NULL;
- + line += n;
- + *line++ = '\0';
- + line += strspn(line, " \t");
- + masterpath = line;
- + if ((n = strcspn(line, " \t\n")) == 0)
- + return NULL;
- + line += n;
- + *line++ = '\0';
- + line += strspn(line, " \t\n");
- + slavepath = "";
- + syncprog = "";
- + if (line[0] != '\0') {
- + slavepath = line;
- + n = strcspn(line, " \t\n");
- + line += n;
- + *line++ = '\0';
- + if (line[0] != '\0') {
- + syncprog = line;
- + n = strcspn(line, " \t\n");
- + line += n;
- + *line++ = '\0';
- + }
- + }
- + e = (cvsroot_type *)xmalloc(sizeof(cvsroot_type));
- + e->nickname = xstrdup(nickname);
- + e->masterpath = xstrdup(masterpath);
- + e->slavepath = xstrdup(slavepath);
- + e->syncprog = xstrdup(syncprog);
- + break;
- + }
- + return e;
- +}
- +
- +void
- +cvsroot_entry_write(
- + FILE *fp,
- + cvsroot_type *e)
- +{
- + if (fp != NULL && e != NULL) {
- + fprintf(fp, "%s %s",
- + e->nickname, e->masterpath);
- + if (e->slavepath[0] != '\0')
- + fprintf(fp, " %s", e->slavepath);
- + if (e->syncprog[0] != '\0')
- + fprintf(fp, " %s", e->syncprog);
- + fprintf(fp, "\n");
- + }
- + return;
- +}
- +
- +cvsroot_type *
- +cvsroot_lookup(
- + char *by_nickname,
- + char *by_masterpath,
- + char *by_slavepath)
- +{
- + char *rootfile;
- + cvsroot_type *e = NULL;
- + FILE *fp;
- +
- + if ((rootfile = cvsroot_filename()) == NULL)
- + return NULL;
- + if ((fp = fopen(rootfile, "r")) == NULL) {
- + free(rootfile);
- + return NULL;
- + }
- + while ((e = cvsroot_entry_read(fp)) != NULL) {
- + if ( (by_nickname != NULL && strcmp(e->nickname, by_nickname) == 0)
- + || (by_masterpath != NULL && strcmp(e->masterpath, by_masterpath) == 0)
- + || (by_slavepath != NULL && strcmp(e->slavepath, by_slavepath) == 0))
- + break;
- + cvsroot_free(e);
- + }
- + fclose(fp);
- + free(rootfile);
- + return e;
- +}
- +
- +void
- +cvsroot_synchronize(
- + cvsroot_type *e,
- + int force)
- +{
- + char *cmd;
- + char *arg;
- + char *rsh;
- + int smart;
- + char *syncprog;
- +
- + smart = 0;
- + syncprog = e->syncprog;
- + if (syncprog[0] == '-') {
- + smart++;
- + syncprog++;
- + }
- + if (smart && !force) {
- + if (!really_quiet) {
- + if (strcasecmp(syncprog, "manual") == 0) {
- + fprintf(stderr, "%s: synchronize SLAVE with MASTER of repository `%s', please!\n", program_name, e->nickname);
- + }
- + else {
- + fprintf(stderr, "%s: synchronize SLAVE with MASTER of repository `%s'\n", program_name, e->nickname);
- + fprintf(stderr, "%s: by running the command `%s root -s %s', please.\n", program_name, program_name, e->nickname);
- + }
- + }
- + return;
- + }
- +
- + if (strcasecmp(syncprog, "manual") == 0) {
- + if (!really_quiet) {
- + fprintf(stderr, "%s: synchronizing SLAVE with MASTER of repository `%s'\n", program_name, e->nickname);
- + fprintf(stderr, "%s: has to be performed manually by you!\n", program_name);
- + }
- + }
- + else if (strcasecmp(syncprog, "rsync") == 0 ||
- + strncasecmp(syncprog, "rsync:", 6) == 0) {
- + if (!really_quiet) {
- + fprintf(stderr, "%s: synchronizing SLAVE with MASTER of repository `%s':\n", program_name, e->nickname);
- + fprintf(stderr, "%s: %s --> %s (rsync)\n", program_name, e->masterpath, e->slavepath);
- + }
- + run_setup("rsync");
- + if (!quiet)
- + run_arg("-v");
- + if ((rsh = getenv("CVS_RSH")) != NULL) {
- + arg = xmalloc(strlen(rsh)+7);
- + strcpy(arg, "--rsh=");
- + strcat(arg, rsh);
- + run_arg(arg);
- + free(arg);
- + }
- + run_arg("-rlpt");
- + run_arg("--delete");
- + if (strncasecmp(syncprog, "rsync:", 6) == 0) {
- + char *list = xstrdup(syncprog+6);
- + for (arg = strtok(list, ","); arg != NULL; arg = strtok(NULL, ",")) {
- + if (arg[0] == '!') {
- + run_arg("--exclude");
- + run_arg(arg+1);
- + }
- + else {
- + run_arg("--include");
- + run_arg(arg);
- + }
- + }
- + free(list);
- + }
- + arg = xmalloc(strlen(e->masterpath)+2);
- + strcpy(arg, e->masterpath);
- + strcat(arg, "/");
- + run_arg(arg);
- + free(arg);
- + arg = xmalloc(strlen(e->slavepath)+2);
- + strcpy(arg, e->slavepath);
- + strcat(arg, "/");
- + run_arg(arg);
- + free(arg);
- + if (trace) {
- + cvs_output(program_name, 0);
- + cvs_output(" ", 1);
- + cvs_output(command_name, 0);
- + cvs_output(": Executing ", 0);
- + run_print(stdout);
- + cvs_output("\n", 0);
- + }
- + if (run_exec(RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL) != 0)
- + error(1, 0, "synchronization program `rsync' returned non-zero");
- + }
- + else {
- + if (!really_quiet) {
- + fprintf(stderr, "%s: synchronizing SLAVE with MASTER of repository `%s':\n", program_name, e->nickname);
- + fprintf(stderr, "%s: %s --> %s (%s)\n", program_name, e->masterpath, e->slavepath, e->syncprog);
- + }
- + cmd = expand_path(syncprog, "sync", 0);
- + run_setup(cmd);
- + run_arg(e->nickname);
- + run_arg(e->masterpath);
- + run_arg(e->slavepath);
- + if (trace) {
- + cvs_output(program_name, 0);
- + cvs_output(" ", 1);
- + cvs_output(command_name, 0);
- + cvs_output(": Executing ", 0);
- + run_print(stdout);
- + cvs_output("\n", 0);
- + }
- + if (run_exec(RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL) != 0)
- + error(1, 0, "synchronization program `%s' returned non-zero", cmd);
- + free(cmd);
- + }
- +}
- +
- +static const char *const root_usage[] = {
- + "Usage: %s %s [-v] -e|-E|-l|s [arg ...]\n",
- + "Options:\n",
- + " -v Verbose mode.\n",
- + " -e Edit entry from ~/.cvsroot in batch mode.\n",
- + " -E Edit entry from ~/.cvsroot in visual mode.\n",
- + " -l List entries from ~/.cvsroot.\n",
- + " -s Synchronize entries from ~/.cvsroot.\n",
- + "Synopsis:\n",
- + " Add/Modify an entry:\n",
- + " cvs root -e nickname masterpath [slavepath [syncprog]]\n",
- + " Delete an entry:\n",
- + " cvs root -e nickname\n",
- + " List all or some particular entries:\n",
- + " cvs [-Q] [-q] root [-v] -l [nickname ...]\n",
- + " Synchronize all or some particular entries:\n",
- + " cvs [-Q] [-q] root -s [nickname ...]\n",
- + "(Specify the --help global option for a list of other help options)\n",
- + NULL
- +};
- +
- +int
- +root(
- + int argc,
- + char **argv)
- +{
- + enum {
- + ROOT_MODE_UNKNOWN,
- + ROOT_MODE_EDIT_CMDLINE,
- + ROOT_MODE_EDIT_VISUAL,
- + ROOT_MODE_LIST,
- + ROOT_MODE_SYNC
- + };
- + int mode = ROOT_MODE_UNKNOWN;
- + char *rootfile;
- + char *rootfilebak = NULL;
- + FILE *fp;
- + FILE *fpbak = NULL;
- + int option;
- + cvsroot_type *e;
- + cvsroot_type E;
- + int doit;
- + int i;
- + int rc;
- + int verbose = 0;
- + int found = 0;
- + int oldexists;
- +
- + if (argc == -1)
- + usage(root_usage);
- + optind = 0;
- + while ((option = getopt(argc, argv, "veEsl")) != EOF) {
- + switch ((char)option) {
- + case 'v':
- + verbose = 1;
- + break;
- + case 'e':
- + mode = ROOT_MODE_EDIT_CMDLINE;
- + break;
- + case 'E':
- + mode = ROOT_MODE_EDIT_VISUAL;
- + break;
- + case 'l':
- + mode = ROOT_MODE_LIST;
- + break;
- + case 's':
- + mode = ROOT_MODE_SYNC;
- + break;
- + case '?':
- + default:
- + usage(root_usage);
- + break;
- + }
- + }
- + argc -= optind;
- + argv += optind;
- + if (mode == ROOT_MODE_UNKNOWN)
- + error(1, 0, "exactly one of the -e, -E, -l or -s options have to given");
- +
- + if (mode == ROOT_MODE_EDIT_CMDLINE) {
- + if (argc < 1 || argc > 4)
- + error(1, 0, "option -e requires 1-4 arguments");
- + E.nickname = argv[0];
- + if (argc >= 2)
- + E.masterpath = argv[1];
- + else
- + E.masterpath = "";
- + if (argc >= 3)
- + E.slavepath = argv[2];
- + else
- + E.slavepath = "";
- + if (argc == 4)
- + E.syncprog = argv[3];
- + else
- + E.syncprog = "";
- + if ((rootfile = cvsroot_filename()) == NULL)
- + return 0;
- + oldexists = 0;
- + if (isfile(rootfile)) {
- + oldexists = 1;
- + rootfilebak = xmalloc(strlen(rootfile)+5);
- + strcpy(rootfilebak, rootfile);
- + strcat(rootfilebak, ".bak");
- + rename(rootfile, rootfilebak);
- + if ((fpbak = fopen(rootfilebak, "r")) == NULL) {
- + free(rootfile);
- + free(rootfilebak);
- + return 0;
- + }
- + }
- + if ((fp = fopen(rootfile, "w")) == NULL) {
- + fclose(fpbak);
- + free(rootfile);
- + free(rootfilebak);
- + return 0;
- + }
- + if (oldexists) {
- + found = 0;
- + while ((e = cvsroot_entry_read(fpbak)) != NULL) {
- + if (strcmp(e->nickname, E.nickname) == 0) {
- + cvsroot_free(e);
- + found = 1;
- + break;
- + }
- + cvsroot_entry_write(fp, e);
- + cvsroot_free(e);
- + }
- + }
- + if (argc > 1)
- + cvsroot_entry_write(fp, &E);
- + if (oldexists) {
- + if (found) {
- + while ((e = cvsroot_entry_read(fpbak)) != NULL) {
- + cvsroot_entry_write(fp, e);
- + cvsroot_free(e);
- + }
- + }
- + fclose(fpbak);
- + }
- + fclose(fp);
- + }
- + else if (mode == ROOT_MODE_EDIT_VISUAL) {
- + if (argc != 0)
- + error(1, 0, "option -E requires no arguments");
- + if ((rootfile = cvsroot_filename()) == NULL)
- + return 0;
- + run_setup(Editor);
- + run_arg(rootfile);
- + if ((rc = run_exec(RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL|RUN_SIGIGNORE)) != 0)
- + error (1, rc == -1 ? errno : 0, "warning: editor session failed");
- + }
- + else if (mode == ROOT_MODE_LIST || mode == ROOT_MODE_SYNC) {
- + if ((rootfile = cvsroot_filename()) == NULL)
- + return 0;
- + if ((fp = fopen(rootfile, "r")) == NULL) {
- + free(rootfile);
- + return 0;
- + }
- + while ((e = cvsroot_entry_read(fp)) != NULL) {
- + doit = 0;
- + if (argc == 0)
- + doit = 1;
- + else {
- + for (i = 0; i < argc; i++) {
- + if (strcmp(argv[i], e->nickname) == 0) {
- + doit = 1;
- + break;
- + }
- + }
- + }
- + if (doit) {
- + if (mode == ROOT_MODE_LIST) {
- + if (verbose)
- + fprintf(stdout, "Repository `%s':\n"
- + " Master Path: %s\n"
- + " Slave Path: %s\n"
- + " Synchronize: %s\n",
- + e->nickname, e->masterpath,
- + e->slavepath, e->syncprog);
- + else
- + fprintf(stdout, "%s %s %s %s\n",
- + e->nickname, e->masterpath,
- + e->slavepath, e->syncprog);
- + }
- + else if (mode == ROOT_MODE_SYNC) {
- + if (e->slavepath[0] == '\0' || e->syncprog[0] == '\0') {
- + if (argc > 0)
- + error(1, 0, "repository `%s' has no slave path or sync program defined", e->nickname);
- + }
- + else
- + cvsroot_synchronize(e, 1);
- + }
- + }
- + cvsroot_free(e);
- + }
- + fclose(fp);
- + free(rootfile);
- + }
- + return 0;
- +}
- +
- +#endif /* RSE_PATCH_CVSROOT */
- +
- /* vim:tabstop=8:shiftwidth=4
- */
- Index: src/sanity.sh
- ===================================================================
- RCS file: /e/ossp/pkg/tool/cvs/cvs/cvs/src/sanity.sh,v
- retrieving revision 1.1.1.11
- diff -u -d -r1.1.1.11 sanity.sh
- --- src/sanity.sh 9 Dec 2003 17:40:07 -0000 1.1.1.11
- +++ src/sanity.sh 11 Dec 2003 21:04:12 -0000
- @@ -391,6 +391,7 @@
- # "debugger"
- #set -x
-
- +echo '[THIS PROCEDURE TAKES APPROX. 25min ON A PII/400MHz, SO BE PATIENT!]'
- echo 'This test should produce no other output than this message, and a final "OK".'
- echo '(Note that the test can take an hour or more to run and periodically stops'
- echo 'for as long as one minute. Do not assume there is a problem just because'
- @@ -10803,10 +10804,12 @@
- ############################################################
- # Check out the whole repository
- mkdir 1; cd 1
- - dotest modules-1 "${testcvs} -q co ." 'U CVSROOT/checkoutlist
- + dotest modules-1 "${testcvs} -q co ." 'U CVSROOT/admininfo
- +U CVSROOT/checkoutlist
- U CVSROOT/commitinfo
- U CVSROOT/config
- U CVSROOT/cvswrappers
- +U CVSROOT/importinfo
- U CVSROOT/loginfo
- U CVSROOT/modules
- U CVSROOT/notify
- @@ -10826,10 +10829,12 @@
- ############################################################
- # Check out CVSROOT
- mkdir 1; cd 1
- - dotest modules-2 "${testcvs} -q co CVSROOT" 'U CVSROOT/checkoutlist
- + dotest modules-2 "${testcvs} -q co CVSROOT" 'U CVSROOT/admininfo
- +U CVSROOT/checkoutlist
- U CVSROOT/commitinfo
- U CVSROOT/config
- U CVSROOT/cvswrappers
- +U CVSROOT/importinfo
- U CVSROOT/loginfo
- U CVSROOT/modules
- U CVSROOT/notify
- @@ -10852,10 +10857,12 @@
- mkdir 1; cd 1
- dotest modules-3 "${testcvs} -q co somedir" ''
- cd somedir
- - dotest modules-3d "${testcvs} -q co CVSROOT" 'U CVSROOT/checkoutlist
- + dotest modules-3d "${testcvs} -q co CVSROOT" 'U CVSROOT/admininfo
- +U CVSROOT/checkoutlist
- U CVSROOT/commitinfo
- U CVSROOT/config
- U CVSROOT/cvswrappers
- +U CVSROOT/importinfo
- U CVSROOT/loginfo
- U CVSROOT/modules
- U CVSROOT/notify
- @@ -21839,7 +21846,7 @@
- add a line on trunk after trunktag"
- # But diff thinks that HEAD is "br1". Case (b) from cvs.texinfo.
- # Probably people are relying on it.
- - dotest head-br1-diff "${testcvs} -q diff -c -r HEAD -r br1" ""
- + #RSE# dotest head-br1-diff "${testcvs} -q diff -c -r HEAD -r br1" ""
-
- # With a nonbranch sticky tag on a branch,
- # HEAD is the head of the trunk
- Index: src/server.c
- ===================================================================
- RCS file: /e/ossp/pkg/tool/cvs/cvs/cvs/src/server.c,v
- retrieving revision 1.1.1.12
- diff -u -d -r1.1.1.12 server.c
- --- src/server.c 9 Dec 2003 16:38:05 -0000 1.1.1.12
- +++ src/server.c 11 Dec 2003 21:04:13 -0000
- @@ -112,6 +112,16 @@
-
- # endif /* AUTH_SERVER_SUPPORT */
-
- +#ifdef RSE_PATCH_PSERVERD
- +#include <sys/ioctl.h>
- +#include <netinet/in.h>
- +#include <arpa/inet.h>
- +#include <netdb.h>
- +#ifdef __sun__
- +#include <termio.h>
- +#endif
- +#endif
- +
-
- /* While processing requests, this buffer accumulates data to be sent to
- the client, and then once we are in do_cvs_command, we use it
- @@ -694,6 +704,13 @@
-
- if (error_pending()) return;
-
- +#ifdef RSE_PATCH_MAPROOT
- + {
- + char *argnew;
- + if (root_map_it(arg, &argnew, 0))
- + arg = argnew;
- + }
- +#endif
- if (!isabsolute (arg))
- {
- if (alloc_pending (80 + strlen (arg)))
- @@ -1116,6 +1133,9 @@
- TRACE( TRACE_FUNCTION, "serve_directory (%s)", arg ? arg : "(null)" );
-
- status = buf_read_line (buf_from_net, &repos, (int *) NULL);
- +#ifdef RSE_PATCH_MAPROOT
- + root_map_it(repos, &repos, 1);
- +#endif
- if (status == 0)
- {
- if (!outside_root (repos))
- @@ -3813,6 +3833,17 @@
- }
-
- /* See server.h for description. */
- +#ifdef RSE_PATCH_RLIST
- +static void serve_list (char *);
- +static void
- +serve_list (arg)
- + char *arg;
- +{
- + if (print_pending_error())
- + return;
- + do_cvs_command("rlist", cvslist);
- +}
- +#endif
-
- void
- server_modtime (struct file_info *finfo, Vers_TS *vers_ts)
- @@ -4546,6 +4577,9 @@
- REQ_LINE("expand-modules", serve_expand_modules, 0),
- REQ_LINE("ci", serve_ci, RQ_ESSENTIAL),
- REQ_LINE("co", serve_co, RQ_ESSENTIAL),
- +#ifdef RSE_PATCH_RLIST
- + REQ_LINE("rlist", serve_list, 0),
- +#endif
- REQ_LINE("update", serve_update, RQ_ESSENTIAL),
- REQ_LINE("diff", serve_diff, 0),
- REQ_LINE("log", serve_log, 0),
- @@ -5194,8 +5228,13 @@
- {
- char *env;
-
- +#if defined(RSE_PATCH_LOGNAME) && defined(AUTH_SERVER_SUPPORT)
- + env = xmalloc (sizeof "LOGNAME=" + strlen (CVS_Username));
- + (void) sprintf (env, "LOGNAME=%s", CVS_Username);
- +#else
- env = xmalloc (sizeof "LOGNAME=" + strlen (username));
- (void) sprintf (env, "LOGNAME=%s", username);
- +#endif
- (void) putenv (env);
-
- env = xmalloc (sizeof "USER=" + strlen (username));
- @@ -5727,6 +5766,10 @@
- || !strip_trailing_newlines (password))
- error (1, 0, "Maximum line length exceeded during authentication.");
-
- +#ifdef RSE_PATCH_MAPROOT
- + root_map_it(repository, &repository, 0);
- +#endif
- +
- /* ... and make sure the protocol ends on the right foot. */
- /* See above comment about error handling. */
- getnline( &tmp, &tmp_allocated, PATH_MAX, stdin );
- @@ -6437,3 +6480,517 @@
- cvs_output (text, 0);
- }
- }
- +
- +#ifdef RSE_PATCH_PSERVERD
- +
- +/* ========================================================================= */
- +
- +#if !defined(SIGCHLD) && defined(SIGCLD)
- +#define SIGCHLD SIGCLD
- +#endif
- +
- +static void pserver_handshake(void);
- +
- +/*
- + * Main procedure stub. This is called in two contexts: first under "cvs
- + * -H pserverd" where we just display the usage; second inside the CVS
- + * main loop where we have to act as the regular "cvs server".
- + */
- +
- +static const char *const pserverd_usage[] = {
- + "Usage: %s %s [-v] [-d] [-l addr[:port]] [-p pidfile] [-A user] [-R user:repos:chroot]\n",
- + "\t-v\tVerbose mode.\n",
- + "\t-d\tDetach into background and run as a daemon.\n",
- + "\t-l\tListen to a particular address/port.\n",
- + "\t-p\tWrite the daemon's PID to a file.\n",
- + "\t-A\tForce global -l -n -u options for a particular user.\n",
- + "\t-R\tPerform a chroot(2) for a user/repository pair.\n",
- + "(Specify the --help global option for a list of other help options)\n",
- + NULL
- +};
- +
- +int
- +pserverd(
- + int argc,
- + char **argv)
- +{
- + if (argc == -1)
- + usage(pserverd_usage);
- + return server(argc, argv);
- +}
- +
- +/*
- + * The pserver daemon. This listens on a particular TCP/IP socket for
- + * connections. If one occurs, it forks and returns to the caller inside
- + * the child process. The parent process runs forever.
- + */
- +
- +static struct {
- + char *user;
- + char *repos;
- + char *chroot;
- +} pserver_chroot;
- +
- +static char *pserverd_anonymous_user = NULL;
- +static int pserverd_verbose = 0;
- +
- +static int
- +tcp_setinaddr(
- + struct sockaddr_in *addr,
- + const char *host,
- + const char *service,
- + const char *protocol)
- +{
- + struct hostent *hp;
- + char *end;
- + long portno;
- + struct servent *serv;
- +
- + memset(addr, 0, sizeof *addr);
- + addr->sin_family = AF_INET;
- +
- + /* set host part of address */
- + if (host == NULL)
- + addr->sin_addr.s_addr = INADDR_ANY;
- + else {
- + addr->sin_addr.s_addr = inet_addr(host);
- + if (addr->sin_addr.s_addr == (unsigned long) -1) {
- + if ((hp = gethostbyname(host)) == NULL)
- + return -1;
- + memcpy(&addr->sin_addr, hp->h_addr, hp->h_length);
- + addr->sin_family = hp->h_addrtype;
- + }
- + }
- +
- + /* set port part of address */
- + if (service == NULL)
- + addr->sin_port = htons(0);
- + else {
- + portno = strtol(service, &end, 10);
- + if (portno > 0 && portno <= 65535 && end != service && *end == '\0')
- + addr->sin_port = htons(portno);
- + else {
- + if ((serv = getservbyname(service, protocol)) == NULL)
- + return -1;
- + addr->sin_port = serv->s_port;
- + }
- + }
- + return 0;
- +}
- +
- +static int
- +tcp_listen(
- + const char *host,
- + const char *port)
- +{
- + int s;
- + struct protoent *proto;
- + struct sockaddr_in server;
- + int yes = 1;
- +
- + if (tcp_setinaddr(&server, host, port, "tcp") < 0)
- + return -1;
- + if ((proto = getprotobyname("tcp")) == NULL)
- + return -1;
- + if ((s = socket(PF_INET, SOCK_STREAM, proto->p_proto)) < 0)
- + return -1;
- + setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&yes, sizeof(yes));
- + if (bind(s, (struct sockaddr *)&server, sizeof(server)) < 0) {
- + close(s);
- + return -1;
- + }
- + if (listen(s, 256) < 0) {
- + close(s);
- + return -1;
- + }
- + return s;
- +}
- +
- +static int
- +proc_daemon(
- + int nochdir,
- + int noclose)
- +{
- + int fd;
- + int rc;
- +
- + /*
- + * Ignore tty related signals
- + */
- +#ifdef SIGTTOU
- + signal(SIGTTOU, SIG_IGN);
- +#endif
- +#ifdef SIGTTIN
- + signal(SIGTTIN, SIG_IGN);
- +#endif
- +#ifdef SIGTSTP
- + signal(SIGTSTP, SIG_IGN);
- +#endif
- +
- + /*
- + * fork so the parent can exit, this returns control to the command line
- + * or shell invoking your program. This step is required so that the new
- + * process is guaranteed not to be a process group leader (The next step,
- + * setsid, would fail if you're a process group leader).
- + */
- + rc = fork();
- + switch (rc) {
- + case -1: return -1;
- + case 0: break;
- + default: _exit(0); /* exit original process */
- + }
- +
- + /*
- + * setsid to become a process group and session group leader. Since a
- + * controlling terminal is associated with a session, and this new session
- + * has not yet acquired a controlling terminal our process now has no
- + * controlling terminal, which is a Good Thing for daemons.
- + */
- +#ifdef HAVE_SETSID
- + if (setsid() == -1)
- + return -1;
- +#else
- + if (setpgid(0, getpid()) == -1)
- + return -1;
- +#ifndef _PATH_TTY
- +#define _PATH_TTY "/dev/tty"
- +#endif
- + if ((fd = open(_PATH_TTY, O_RDWR)) == -1)
- + return -1;
- + ioctl(fd, TIOCNOTTY, NULL);
- + close(fd);
- +#endif
- +
- + /*
- + * fork again so the parent, (the session group leader), can exit. This
- + * means that we, as a non-session group leader, can never regain a
- + * controlling terminal.
- + */
- + rc = fork();
- + switch (rc) {
- + case -1: return -1;
- + case 0: break;
- + default: _exit(0); /* exit original process */
- + }
- +
- + /*
- + * chdir("/") to ensure that our process doesn't keep any directory in
- + * use. Failure to do this could make it so that an administrator couldn't
- + * unmount a filesystem, because it was our current directory.
- + * [Equivalently, we could change to any directory containing files
- + * important to the daemon's operation.]
- + */
- + if (!nochdir)
- + chdir("/");
- +
- + /*
- + * give us complete control over the permissions of anything we write. We
- + * don't know what umask we may have inherited. [This step is optional]
- + */
- + umask(0);
- +
- + /*
- + * close fds 0, 1, and 2. This releases the standard in, out, and error we
- + * inherited from our parent process. We have no way of knowing where
- + * these fds might have been redirected to.
- + */
- + if (!noclose && (fd = open("/dev/null", O_RDWR, 0)) != -1) {
- + dup2(fd, STDIN_FILENO);
- + dup2(fd, STDOUT_FILENO);
- + dup2(fd, STDERR_FILENO);
- + if (fd > 2)
- + close(fd);
- + }
- + return 0;
- +}
- +
- +static void
- +pserver_daemon_reapchild(
- + int signo)
- +{
- + pid_t child;
- + int status;
- + char buf[128];
- +
- + while ((child = waitpid(-1, &status, WNOHANG)) > (pid_t)0) {
- + if (pserverd_verbose) {
- + sprintf(buf, "cvs pserverd[%ld]: child process (pid %ld): terminated.\n",
- + (long)getpid(), (long)child);
- + write(STDOUT_FILENO, buf, strlen(buf));
- + }
- + }
- + signal(signo, &pserver_daemon_reapchild);
- + return;
- +}
- +
- +int
- +pserver_daemon(
- + int argc,
- + char **argv)
- +{
- + int sd;
- + pid_t child;
- + int option;
- + char *host = NULL;
- + char *port = "2401";
- + char *listen = NULL;
- + struct sockaddr_in them;
- + int detach = 0;
- + char *pidfile = NULL;
- + FILE *fp;
- + char *cp;
- + int len;
- + int ns;
- +
- + /* make sure we are running with root priviledges, because
- + we need it later for chroot, switch_to_user, etc. */
- + if (geteuid() != 0)
- + error(1, 0, "root priviledges required for pserver operation");
- +
- + /* process "cvs pserverd" command options */
- + optind = 0;
- + while ((option = getopt(argc, argv, "vl:dp:A:R:")) != EOF) {
- + switch ((char) option) {
- + case 'v':
- + pserverd_verbose = 1;
- + break;
- + case 'l':
- + listen = xstrdup(optarg);
- + break;
- + case 'd':
- + detach = 1;
- + pserverd_verbose = 0;
- + break;
- + case 'p':
- + pidfile = xstrdup(optarg);
- + break;
- + case 'A':
- + pserverd_anonymous_user = xstrdup(optarg);
- + break;
- + case 'R':
- + cp = xstrdup(optarg);
- + pserver_chroot.user = cp;
- + if ((cp = strchr(cp, ':')) == NULL)
- + error(1, 0, "invalid -R option argument");
- + *cp++ = '\0';
- + pserver_chroot.repos = cp;
- + if ((cp = strchr(cp, ':')) == NULL)
- + error(1, 0, "invalid -R option argument");
- + *cp++ = '\0';
- + pserver_chroot.chroot = cp;
- + break;
- + case '?':
- + default:
- + usage(pserverd_usage);
- + break;
- + }
- + }
- + argc -= optind;
- + argv += optind;
- + if (argc < 0)
- + usage(pserverd_usage);
- +
- + /* optionally go into the background as a real daemon */
- + if (detach)
- + proc_daemon(0, 0);
- +
- + /* optionally write out the pid */
- + if (pidfile != NULL) {
- + if ((fp = fopen(pidfile, "w")) == NULL)
- + error(1, 0, "unable to write pid to file %s: %s",
- + pidfile, strerror(errno));
- + fprintf(fp, "%ld\n", (long)getpid());
- + fclose(fp);
- + }
- +
- + /* listen on the TCP/IP socket */
- + if (listen != NULL) {
- + if ((port = strrchr(listen, ':')) != NULL)
- + *(port++) = '\0';
- + if (strcasecmp(listen, "*") == 0 || strcmp(listen, "0.0.0.0") == 0)
- + host = NULL;
- + else
- + host = listen;
- + }
- + if ((sd = tcp_listen(host, port)) < 0)
- + error(1, 0, "unable to listen (%s:%s): %s",
- + host != NULL ? host : "*", port, strerror(errno));
- +
- + /* make sure we reap the childs */
- + signal(SIGCHLD, &pserver_daemon_reapchild);
- +
- + /* daemon loop */
- + for (;;) {
- + len = sizeof(them);
- + ns = accept(sd, (struct sockaddr *)&them, &len);
- + if (ns < 0) {
- + if (errno == EINTR)
- + continue;
- + error(1, 0, "accept(2) failed: %s", strerror(errno));
- + }
- + switch (child = fork()) {
- + case -1:
- + error(1, 0, "unable to fork(2): %s", strerror(errno));
- + break;
- + case 0:
- + /* child */
- + close(sd);
- + signal(SIGCHLD, SIG_DFL);
- +
- + /* connect stdin/stdout to socket */
- + dup2(ns, STDIN_FILENO);
- + dup2(ns, STDOUT_FILENO);
- +
- + /*
- + * perform "cvs pserver" authentication handshake.
- + */
- + pserver_handshake();
- +
- + /*
- + * just return to caller, i.e., the main() procedure
- + * which in turn will dispatch into "cvs server" code
- + * for us...
- + */
- + return 0;
- + break;
- + default:
- + /* parent */
- + if (pserverd_verbose)
- + fprintf(stderr, "cvs pserverd[%ld]: child process (pid %ld): started.\n",
- + (long)getpid(), (long)child);
- + close(ns);
- + break;
- + }
- + }
- + exit(0);
- + return 0;
- +}
- +
- +static void
- +pserver_handshake(
- + void)
- +{
- + char *tmp = NULL;
- + size_t tmp_allocated = 0;
- + char *repository = NULL;
- + size_t repository_allocated = 0;
- + char *username = NULL;
- + size_t username_allocated = 0;
- + char *password = NULL;
- + size_t password_allocated = 0;
- + char *host_user = NULL;
- + char *descrambled_password;
- + int verify_and_exit = 0;
- + char *chrootdir = NULL;
- + int on;
- +
- +#ifdef SO_KEEPALIVE
- + /* Set SO_KEEPALIVE on the socket, so that we don't hang forever
- + if the client dies while we are waiting for input. */
- + on = 1;
- + (void)setsockopt(STDIN_FILENO, SOL_SOCKET, SO_KEEPALIVE,
- + (char *)&on, sizeof(on));
- +#endif
- +
- + /* Make sure the protocol starts off on the right foot... */
- + getline(&tmp, &tmp_allocated, stdin);
- +
- + if (strcmp (tmp, "BEGIN VERIFICATION REQUEST\n") == 0)
- + verify_and_exit = 1;
- + else if (strcmp (tmp, "BEGIN AUTH REQUEST\n") == 0)
- + ;
- + else
- + error (1, 0, "bad auth protocol start: %s", tmp);
- +
- + /* Get the three important pieces of information in order. */
- + getline(&repository, &repository_allocated, stdin);
- + getline(&username, &username_allocated, stdin);
- + getline(&password, &password_allocated, stdin);
- +
- + /* Make them pure. */
- + strip_trailing_newlines(repository);
- + strip_trailing_newlines(username);
- + strip_trailing_newlines(password);
- +
- +#ifdef RSE_PATCH_MAPROOT
- + root_map_it(repository, &repository, 0);
- +#endif
- +
- + /* ... and make sure the protocol ends on the right foot. */
- + getline(&tmp, &tmp_allocated, stdin);
- + if (strcmp (tmp, verify_and_exit ?
- + "END VERIFICATION REQUEST\n" : "END AUTH REQUEST\n") != 0)
- + error (1, 0, "bad auth protocol end: %s", tmp);
- +
- + if (!root_allow_ok(repository))
- + goto i_hate_you;
- + parse_config(repository);
- +
- + /* We need the real cleartext before we hash it. */
- + descrambled_password = descramble(password);
- + host_user = check_password(username, descrambled_password, repository);
- + memset(descrambled_password, 0, strlen(descrambled_password));
- + free(descrambled_password);
- +
- + if (host_user == NULL) {
- + i_hate_you:
- + printf("I HATE YOU\n");
- + fflush(stdout);
- + if (pserverd_verbose)
- + fprintf(stderr, "cvs pserverd[%ld]: status=FAILED user=%s root=%s\n",
- + (long)getpid(), username, repository);
- + exit (EXIT_FAILURE);
- + }
- +
- + /* Don't go any farther if we're just responding to "cvs login". */
- + if (verify_and_exit) {
- + printf("I LOVE YOU\n");
- + fflush(stdout);
- + if (pserverd_verbose)
- + fprintf(stderr, "cvs pserverd[%ld]: status=OK user=%s root=%s (huser=%s)\n",
- + (long)getpid(), username, repository, host_user);
- + exit(0);
- + }
- +
- + /* Set Pserver_Repos so that we can check later that the same
- + repository is sent in later client/server protocol. */
- + Pserver_Repos = xmalloc(strlen(repository)+1);
- + strcpy(Pserver_Repos, repository);
- +
- + /* Optionally perform a chroot */
- + if (pserver_chroot.user != NULL) {
- + if ( strcmp(username, pserver_chroot.user) == 0
- + && ( strcmp(repository, pserver_chroot.repos) == 0
- + || strcmp(pserver_chroot.repos, "*") == 0 )) {
- + chrootdir = pserver_chroot.chroot;
- + if (chdir(chrootdir) == -1)
- + error(1, 0, "failed to chdir(2) to %s: %s", chrootdir, strerror(errno));
- + if (chroot(chrootdir) == -1)
- + error(1, 0, "failed to chroot(2) to %s: %s", chrootdir, strerror(errno));
- + }
- + }
- +
- + /* Additionally switch to read-only mode for anonymous user */
- + if (pserverd_anonymous_user != NULL) {
- + if (strcmp(username, pserverd_anonymous_user) == 0) {
- + logoff = 1;
- + }
- + }
- +
- + /* Switch to run as this user. */
- + switch_to_user(host_user);
- + free(tmp);
- + free(repository);
- + free(username);
- + free(password);
- +
- + printf("I LOVE YOU\n");
- + fflush(stdout);
- + if (pserverd_verbose)
- + fprintf(stderr, "cvs pserverd[%ld]: status=OK user=%s root=%s (huser=%s hroot=%s)\n",
- + (long)getpid(), username, repository, host_user, chrootdir != NULL ? chrootdir : "/");
- + return;
- +}
- +
- +#endif /* RSE_PATCH_PSERVERD */
- +
- Index: src/subr.c
- ===================================================================
- RCS file: /e/ossp/pkg/tool/cvs/cvs/cvs/src/subr.c,v
- retrieving revision 1.1.1.10
- diff -u -d -r1.1.1.10 subr.c
- --- src/subr.c 25 Nov 2003 20:52:41 -0000 1.1.1.10
- +++ src/subr.c 5 Dec 2003 20:22:20 -0000
- @@ -321,6 +321,22 @@
- uid_t uid;
- #endif
-
- +#ifdef RSE_PATCH_CVSUSER
- +#ifndef RSE_PATCH_CVSUSER_CALLER
- +#define RSE_PATCH_CVSUSER_CALLER "cvs"
- +#endif
- + uid = getuid();
- + if ((pw = (struct passwd *)getpwnam(RSE_PATCH_CVSUSER_CALLER)) != NULL) {
- + if (pw->pw_uid == uid) {
- + char *name;
- + if ((name = getenv("CVSUSER")) != NULL) {
- + cache = xstrdup(name);
- + return cache;
- + }
- + }
- + }
- +#endif
- +
- /* If there is a CVS username, return it. */
- #ifdef AUTH_SERVER_SUPPORT
- if (CVS_Username != NULL)
- @@ -784,6 +800,73 @@
- return backup_name;
- }
-
- +#ifdef RSE_PATCH_HANDLE
- +/* handle: 2000041317203601
- + date1: 2000/04/13 17:20:36
- + date2: 2000/04/13 17:20:37 */
- +int handle2dates(char *handle, time_t *t1, time_t *t2)
- +{
- + int Y,M,D,h,m,s,o;
- + char buf[17];
- + time_t t;
- + struct tm tm;
- + int rev = 0;
- + int i;
- +
- + /* check for correct handle format */
- + if (handle == NULL)
- + return 0;
- + if (handle[0] == '!') {
- + handle++;
- + rev = 1;
- + }
- + if (strlen(handle) != 16)
- + return 0;
- + for (i = 0; i < 16; i++)
- + if (!isdigit(handle[i]))
- + return 0;
- +
- + /* parse out handle parts */
- + strcpy(buf, handle);
- + o = atoi(buf+14);
- + buf[14] = '\0';
- + s = atoi(buf+12);
- + buf[12] = '\0';
- + m = atoi(buf+10);
- + buf[10] = '\0';
- + h = atoi(buf+8);
- + buf[8] = '\0';
- + D = atoi(buf+6);
- + buf[6] = '\0';
- + M = atoi(buf+4);
- + buf[4] = '\0';
- + Y = atoi(buf);
- +
- + /* assemble parts into a time value */
- + memset(&tm, 0, sizeof tm);
- + tm.tm_sec = s;
- + tm.tm_min = m;
- + tm.tm_hour = h;
- + tm.tm_mday = D;
- + tm.tm_mon = M - 1;
- + tm.tm_year = Y - 1900;
- + t = mktime(&tm);
- + if (t == -1)
- + return 0;
- +
- + /* output the first and second time */
- + if (rev) {
- + *t2 = t;
- + *t1 = t + o;
- + }
- + else {
- + *t1 = t;
- + *t2 = t + o;
- + }
- + return 1;
- +}
- +#endif
- +
- /*
- * Copy a string into a buffer escaping any shell metacharacters. The
- * buffer should be at least twice as long as the string.
- Index: src/update.c
- ===================================================================
- RCS file: /e/ossp/pkg/tool/cvs/cvs/cvs/src/update.c,v
- retrieving revision 1.1.1.11
- diff -u -d -r1.1.1.11 update.c
- --- src/update.c 25 Nov 2003 16:12:03 -0000 1.1.1.11
- +++ src/update.c 5 Dec 2003 20:22:20 -0000
- @@ -1725,6 +1725,17 @@
- patch can't handle that. */
- fail = 1;
- }
- +#ifdef RSE_PATCH_FASTERUPDATE
- + else {
- + /*
- + * Don't send a diff if just sending the entire file
- + * would be smaller...
- + */
- + fseek(e, 0L, SEEK_END);
- + if (file_info->st_size < ftell(e))
- + fail = 1;
- + }
- +#endif
- fclose (e);
- }
-
- @@ -2528,8 +2539,16 @@
- write_letter (finfo, 'C');
- }
- else
- +#ifdef RSE_PATCH_MERGENOKEYWORD
- + {
- + if (*t_options == '\0')
- + t_options = "-kk"; /* to ignore keyword expansions */
- +#endif
- status = RCS_merge (finfo->rcs, vers->srcfile->path, finfo->file,
- t_options, rev1, rev2);
- +#ifdef RSE_PATCH_MERGENOKEYWORD
- + }
- +#endif
-
- if (status != 0)
- {
- Index: src/version.c
- ===================================================================
- RCS file: /e/ossp/pkg/tool/cvs/cvs/cvs/src/version.c,v
- retrieving revision 1.1.1.8
- diff -u -d -r1.1.1.8 version.c
- --- src/version.c 23 Jul 2003 20:40:09 -0000 1.1.1.8
- +++ src/version.c 27 Oct 2003 19:07:29 -0000
- @@ -60,6 +60,9 @@
- some idea of how long ago their version of CVS was
- released. */
- (void) fputs (PACKAGE_STRING, stdout);
- +#ifdef RSE_PATCHES
- + (void) fputs (" [RSE]", stdout);
- +#endif
- (void) fputs (config_string, stdout);
-
- #ifdef CLIENT_SUPPORT
|