ckuus6.c 423 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568756975707571757275737574757575767577757875797580758175827583758475857586758775887589759075917592759375947595759675977598759976007601760276037604760576067607760876097610761176127613761476157616761776187619762076217622762376247625762676277628762976307631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700770177027703770477057706770777087709771077117712771377147715771677177718771977207721772277237724772577267727772877297730773177327733773477357736773777387739774077417742774377447745774677477748774977507751775277537754775577567757775877597760776177627763776477657766776777687769777077717772777377747775777677777778777977807781778277837784778577867787778877897790779177927793779477957796779777987799780078017802780378047805780678077808780978107811781278137814781578167817781878197820782178227823782478257826782778287829783078317832783378347835783678377838783978407841784278437844784578467847784878497850785178527853785478557856785778587859786078617862786378647865786678677868786978707871787278737874787578767877787878797880788178827883788478857886788778887889789078917892789378947895789678977898789979007901790279037904790579067907790879097910791179127913791479157916791779187919792079217922792379247925792679277928792979307931793279337934793579367937793879397940794179427943794479457946794779487949795079517952795379547955795679577958795979607961796279637964796579667967796879697970797179727973797479757976797779787979798079817982798379847985798679877988798979907991799279937994799579967997799879998000800180028003800480058006800780088009801080118012801380148015801680178018801980208021802280238024802580268027802880298030803180328033803480358036803780388039804080418042804380448045804680478048804980508051805280538054805580568057805880598060806180628063806480658066806780688069807080718072807380748075807680778078807980808081808280838084808580868087808880898090809180928093809480958096809780988099810081018102810381048105810681078108810981108111811281138114811581168117811881198120812181228123812481258126812781288129813081318132813381348135813681378138813981408141814281438144814581468147814881498150815181528153815481558156815781588159816081618162816381648165816681678168816981708171817281738174817581768177817881798180818181828183818481858186818781888189819081918192819381948195819681978198819982008201820282038204820582068207820882098210821182128213821482158216821782188219822082218222822382248225822682278228822982308231823282338234823582368237823882398240824182428243824482458246824782488249825082518252825382548255825682578258825982608261826282638264826582668267826882698270827182728273827482758276827782788279828082818282828382848285828682878288828982908291829282938294829582968297829882998300830183028303830483058306830783088309831083118312831383148315831683178318831983208321832283238324832583268327832883298330833183328333833483358336833783388339834083418342834383448345834683478348834983508351835283538354835583568357835883598360836183628363836483658366836783688369837083718372837383748375837683778378837983808381838283838384838583868387838883898390839183928393839483958396839783988399840084018402840384048405840684078408840984108411841284138414841584168417841884198420842184228423842484258426842784288429843084318432843384348435843684378438843984408441844284438444844584468447844884498450845184528453845484558456845784588459846084618462846384648465846684678468846984708471847284738474847584768477847884798480848184828483848484858486848784888489849084918492849384948495849684978498849985008501850285038504850585068507850885098510851185128513851485158516851785188519852085218522852385248525852685278528852985308531853285338534853585368537853885398540854185428543854485458546854785488549855085518552855385548555855685578558855985608561856285638564856585668567856885698570857185728573857485758576857785788579858085818582858385848585858685878588858985908591859285938594859585968597859885998600860186028603860486058606860786088609861086118612861386148615861686178618861986208621862286238624862586268627862886298630863186328633863486358636863786388639864086418642864386448645864686478648864986508651865286538654865586568657865886598660866186628663866486658666866786688669867086718672867386748675867686778678867986808681868286838684868586868687868886898690869186928693869486958696869786988699870087018702870387048705870687078708870987108711871287138714871587168717871887198720872187228723872487258726872787288729873087318732873387348735873687378738873987408741874287438744874587468747874887498750875187528753875487558756875787588759876087618762876387648765876687678768876987708771877287738774877587768777877887798780878187828783878487858786878787888789879087918792879387948795879687978798879988008801880288038804880588068807880888098810881188128813881488158816881788188819882088218822882388248825882688278828882988308831883288338834883588368837883888398840884188428843884488458846884788488849885088518852885388548855885688578858885988608861886288638864886588668867886888698870887188728873887488758876887788788879888088818882888388848885888688878888888988908891889288938894889588968897889888998900890189028903890489058906890789088909891089118912891389148915891689178918891989208921892289238924892589268927892889298930893189328933893489358936893789388939894089418942894389448945894689478948894989508951895289538954895589568957895889598960896189628963896489658966896789688969897089718972897389748975897689778978897989808981898289838984898589868987898889898990899189928993899489958996899789988999900090019002900390049005900690079008900990109011901290139014901590169017901890199020902190229023902490259026902790289029903090319032903390349035903690379038903990409041904290439044904590469047904890499050905190529053905490559056905790589059906090619062906390649065906690679068906990709071907290739074907590769077907890799080908190829083908490859086908790889089909090919092909390949095909690979098909991009101910291039104910591069107910891099110911191129113911491159116911791189119912091219122912391249125912691279128912991309131913291339134913591369137913891399140914191429143914491459146914791489149915091519152915391549155915691579158915991609161916291639164916591669167916891699170917191729173917491759176917791789179918091819182918391849185918691879188918991909191919291939194919591969197919891999200920192029203920492059206920792089209921092119212921392149215921692179218921992209221922292239224922592269227922892299230923192329233923492359236923792389239924092419242924392449245924692479248924992509251925292539254925592569257925892599260926192629263926492659266926792689269927092719272927392749275927692779278927992809281928292839284928592869287928892899290929192929293929492959296929792989299930093019302930393049305930693079308930993109311931293139314931593169317931893199320932193229323932493259326932793289329933093319332933393349335933693379338933993409341934293439344934593469347934893499350935193529353935493559356935793589359936093619362936393649365936693679368936993709371937293739374937593769377937893799380938193829383938493859386938793889389939093919392939393949395939693979398939994009401940294039404940594069407940894099410941194129413941494159416941794189419942094219422942394249425942694279428942994309431943294339434943594369437943894399440944194429443944494459446944794489449945094519452945394549455945694579458945994609461946294639464946594669467946894699470947194729473947494759476947794789479948094819482948394849485948694879488948994909491949294939494949594969497949894999500950195029503950495059506950795089509951095119512951395149515951695179518951995209521952295239524952595269527952895299530953195329533953495359536953795389539954095419542954395449545954695479548954995509551955295539554955595569557955895599560956195629563956495659566956795689569957095719572957395749575957695779578957995809581958295839584958595869587958895899590959195929593959495959596959795989599960096019602960396049605960696079608960996109611961296139614961596169617961896199620962196229623962496259626962796289629963096319632963396349635963696379638963996409641964296439644964596469647964896499650965196529653965496559656965796589659966096619662966396649665966696679668966996709671967296739674967596769677967896799680968196829683968496859686968796889689969096919692969396949695969696979698969997009701970297039704970597069707970897099710971197129713971497159716971797189719972097219722972397249725972697279728972997309731973297339734973597369737973897399740974197429743974497459746974797489749975097519752975397549755975697579758975997609761976297639764976597669767976897699770977197729773977497759776977797789779978097819782978397849785978697879788978997909791979297939794979597969797979897999800980198029803980498059806980798089809981098119812981398149815981698179818981998209821982298239824982598269827982898299830983198329833983498359836983798389839984098419842984398449845984698479848984998509851985298539854985598569857985898599860986198629863986498659866986798689869987098719872987398749875987698779878987998809881988298839884988598869887988898899890989198929893989498959896989798989899990099019902990399049905990699079908990999109911991299139914991599169917991899199920992199229923992499259926992799289929993099319932993399349935993699379938993999409941994299439944994599469947994899499950995199529953995499559956995799589959996099619962996399649965996699679968996999709971997299739974997599769977997899799980998199829983998499859986998799889989999099919992999399949995999699979998999910000100011000210003100041000510006100071000810009100101001110012100131001410015100161001710018100191002010021100221002310024100251002610027100281002910030100311003210033100341003510036100371003810039100401004110042100431004410045100461004710048100491005010051100521005310054100551005610057100581005910060100611006210063100641006510066100671006810069100701007110072100731007410075100761007710078100791008010081100821008310084100851008610087100881008910090100911009210093100941009510096100971009810099101001010110102101031010410105101061010710108101091011010111101121011310114101151011610117101181011910120101211012210123101241012510126101271012810129101301013110132101331013410135101361013710138101391014010141101421014310144101451014610147101481014910150101511015210153101541015510156101571015810159101601016110162101631016410165101661016710168101691017010171101721017310174101751017610177101781017910180101811018210183101841018510186101871018810189101901019110192101931019410195101961019710198101991020010201102021020310204102051020610207102081020910210102111021210213102141021510216102171021810219102201022110222102231022410225102261022710228102291023010231102321023310234102351023610237102381023910240102411024210243102441024510246102471024810249102501025110252102531025410255102561025710258102591026010261102621026310264102651026610267102681026910270102711027210273102741027510276102771027810279102801028110282102831028410285102861028710288102891029010291102921029310294102951029610297102981029910300103011030210303103041030510306103071030810309103101031110312103131031410315103161031710318103191032010321103221032310324103251032610327103281032910330103311033210333103341033510336103371033810339103401034110342103431034410345103461034710348103491035010351103521035310354103551035610357103581035910360103611036210363103641036510366103671036810369103701037110372103731037410375103761037710378103791038010381103821038310384103851038610387103881038910390103911039210393103941039510396103971039810399104001040110402104031040410405104061040710408104091041010411104121041310414104151041610417104181041910420104211042210423104241042510426104271042810429104301043110432104331043410435104361043710438104391044010441104421044310444104451044610447104481044910450104511045210453104541045510456104571045810459104601046110462104631046410465104661046710468104691047010471104721047310474104751047610477104781047910480104811048210483104841048510486104871048810489104901049110492104931049410495104961049710498104991050010501105021050310504105051050610507105081050910510105111051210513105141051510516105171051810519105201052110522105231052410525105261052710528105291053010531105321053310534105351053610537105381053910540105411054210543105441054510546105471054810549105501055110552105531055410555105561055710558105591056010561105621056310564105651056610567105681056910570105711057210573105741057510576105771057810579105801058110582105831058410585105861058710588105891059010591105921059310594105951059610597105981059910600106011060210603106041060510606106071060810609106101061110612106131061410615106161061710618106191062010621106221062310624106251062610627106281062910630106311063210633106341063510636106371063810639106401064110642106431064410645106461064710648106491065010651106521065310654106551065610657106581065910660106611066210663106641066510666106671066810669106701067110672106731067410675106761067710678106791068010681106821068310684106851068610687106881068910690106911069210693106941069510696106971069810699107001070110702107031070410705107061070710708107091071010711107121071310714107151071610717107181071910720107211072210723107241072510726107271072810729107301073110732107331073410735107361073710738107391074010741107421074310744107451074610747107481074910750107511075210753107541075510756107571075810759107601076110762107631076410765107661076710768107691077010771107721077310774107751077610777107781077910780107811078210783107841078510786107871078810789107901079110792107931079410795107961079710798107991080010801108021080310804108051080610807108081080910810108111081210813108141081510816108171081810819108201082110822108231082410825108261082710828108291083010831108321083310834108351083610837108381083910840108411084210843108441084510846108471084810849108501085110852108531085410855108561085710858108591086010861108621086310864108651086610867108681086910870108711087210873108741087510876108771087810879108801088110882108831088410885108861088710888108891089010891108921089310894108951089610897108981089910900109011090210903109041090510906109071090810909109101091110912109131091410915109161091710918109191092010921109221092310924109251092610927109281092910930109311093210933109341093510936109371093810939109401094110942109431094410945109461094710948109491095010951109521095310954109551095610957109581095910960109611096210963109641096510966109671096810969109701097110972109731097410975109761097710978109791098010981109821098310984109851098610987109881098910990109911099210993109941099510996109971099810999110001100111002110031100411005110061100711008110091101011011110121101311014110151101611017110181101911020110211102211023110241102511026110271102811029110301103111032110331103411035110361103711038110391104011041110421104311044110451104611047110481104911050110511105211053110541105511056110571105811059110601106111062110631106411065110661106711068110691107011071110721107311074110751107611077110781107911080110811108211083110841108511086110871108811089110901109111092110931109411095110961109711098110991110011101111021110311104111051110611107111081110911110111111111211113111141111511116111171111811119111201112111122111231112411125111261112711128111291113011131111321113311134111351113611137111381113911140111411114211143111441114511146111471114811149111501115111152111531115411155111561115711158111591116011161111621116311164111651116611167111681116911170111711117211173111741117511176111771117811179111801118111182111831118411185111861118711188111891119011191111921119311194111951119611197111981119911200112011120211203112041120511206112071120811209112101121111212112131121411215112161121711218112191122011221112221122311224112251122611227112281122911230112311123211233112341123511236112371123811239112401124111242112431124411245112461124711248112491125011251112521125311254112551125611257112581125911260112611126211263112641126511266112671126811269112701127111272112731127411275112761127711278112791128011281112821128311284112851128611287112881128911290112911129211293112941129511296112971129811299113001130111302113031130411305113061130711308113091131011311113121131311314113151131611317113181131911320113211132211323113241132511326113271132811329113301133111332113331133411335113361133711338113391134011341113421134311344113451134611347113481134911350113511135211353113541135511356113571135811359113601136111362113631136411365113661136711368113691137011371113721137311374113751137611377113781137911380113811138211383113841138511386113871138811389113901139111392113931139411395113961139711398113991140011401114021140311404114051140611407114081140911410114111141211413114141141511416114171141811419114201142111422114231142411425114261142711428114291143011431114321143311434114351143611437114381143911440114411144211443114441144511446114471144811449114501145111452114531145411455114561145711458114591146011461114621146311464114651146611467114681146911470114711147211473114741147511476114771147811479114801148111482114831148411485114861148711488114891149011491114921149311494114951149611497114981149911500115011150211503115041150511506115071150811509115101151111512115131151411515115161151711518115191152011521115221152311524115251152611527115281152911530115311153211533115341153511536115371153811539115401154111542115431154411545115461154711548115491155011551115521155311554115551155611557115581155911560115611156211563115641156511566115671156811569115701157111572115731157411575115761157711578115791158011581115821158311584115851158611587115881158911590115911159211593115941159511596115971159811599116001160111602116031160411605116061160711608116091161011611116121161311614116151161611617116181161911620116211162211623116241162511626116271162811629116301163111632116331163411635116361163711638116391164011641116421164311644116451164611647116481164911650116511165211653116541165511656116571165811659116601166111662116631166411665116661166711668116691167011671116721167311674116751167611677116781167911680116811168211683116841168511686116871168811689116901169111692116931169411695116961169711698116991170011701117021170311704117051170611707117081170911710117111171211713117141171511716117171171811719117201172111722117231172411725117261172711728117291173011731117321173311734117351173611737117381173911740117411174211743117441174511746117471174811749117501175111752117531175411755117561175711758117591176011761117621176311764117651176611767117681176911770117711177211773117741177511776117771177811779117801178111782117831178411785117861178711788117891179011791117921179311794117951179611797117981179911800118011180211803118041180511806118071180811809118101181111812118131181411815118161181711818118191182011821118221182311824118251182611827118281182911830118311183211833118341183511836118371183811839118401184111842118431184411845118461184711848118491185011851118521185311854118551185611857118581185911860118611186211863118641186511866118671186811869118701187111872118731187411875118761187711878118791188011881118821188311884118851188611887118881188911890118911189211893118941189511896118971189811899119001190111902119031190411905119061190711908119091191011911119121191311914119151191611917119181191911920119211192211923119241192511926119271192811929119301193111932119331193411935119361193711938119391194011941119421194311944119451194611947119481194911950119511195211953119541195511956119571195811959119601196111962119631196411965119661196711968119691197011971119721197311974119751197611977119781197911980119811198211983119841198511986119871198811989119901199111992119931199411995119961199711998119991200012001120021200312004120051200612007120081200912010120111201212013120141201512016120171201812019120201202112022120231202412025120261202712028120291203012031120321203312034120351203612037120381203912040120411204212043120441204512046120471204812049120501205112052120531205412055120561205712058120591206012061120621206312064120651206612067120681206912070120711207212073120741207512076120771207812079120801208112082120831208412085120861208712088120891209012091120921209312094120951209612097120981209912100121011210212103121041210512106121071210812109121101211112112121131211412115121161211712118121191212012121121221212312124121251212612127121281212912130121311213212133121341213512136121371213812139121401214112142121431214412145121461214712148121491215012151121521215312154121551215612157121581215912160121611216212163121641216512166121671216812169121701217112172121731217412175121761217712178121791218012181121821218312184121851218612187121881218912190121911219212193121941219512196121971219812199122001220112202122031220412205122061220712208122091221012211122121221312214122151221612217122181221912220122211222212223122241222512226122271222812229122301223112232122331223412235122361223712238122391224012241122421224312244122451224612247122481224912250122511225212253122541225512256122571225812259122601226112262122631226412265122661226712268122691227012271122721227312274122751227612277122781227912280122811228212283122841228512286122871228812289122901229112292122931229412295122961229712298122991230012301123021230312304123051230612307123081230912310123111231212313123141231512316123171231812319123201232112322123231232412325123261232712328123291233012331123321233312334123351233612337123381233912340123411234212343123441234512346123471234812349123501235112352123531235412355123561235712358123591236012361123621236312364123651236612367123681236912370123711237212373123741237512376123771237812379123801238112382123831238412385123861238712388123891239012391123921239312394123951239612397123981239912400124011240212403124041240512406124071240812409124101241112412124131241412415124161241712418124191242012421124221242312424124251242612427124281242912430124311243212433124341243512436124371243812439124401244112442124431244412445124461244712448124491245012451124521245312454124551245612457124581245912460124611246212463124641246512466124671246812469124701247112472124731247412475124761247712478124791248012481124821248312484124851248612487124881248912490124911249212493124941249512496124971249812499125001250112502125031250412505125061250712508125091251012511125121251312514125151251612517125181251912520125211252212523125241252512526125271252812529125301253112532125331253412535125361253712538125391254012541125421254312544125451254612547125481254912550125511255212553125541255512556125571255812559125601256112562125631256412565125661256712568125691257012571125721257312574125751257612577125781257912580125811258212583125841258512586125871258812589125901259112592125931259412595125961259712598125991260012601126021260312604126051260612607126081260912610126111261212613126141261512616126171261812619126201262112622126231262412625126261262712628126291263012631126321263312634126351263612637126381263912640126411264212643126441264512646126471264812649126501265112652126531265412655126561265712658126591266012661126621266312664126651266612667126681266912670126711267212673126741267512676126771267812679126801268112682126831268412685126861268712688126891269012691126921269312694126951269612697126981269912700127011270212703127041270512706127071270812709127101271112712127131271412715127161271712718127191272012721127221272312724127251272612727127281272912730127311273212733127341273512736127371273812739127401274112742127431274412745127461274712748127491275012751127521275312754127551275612757127581275912760127611276212763127641276512766127671276812769127701277112772127731277412775127761277712778127791278012781127821278312784127851278612787127881278912790127911279212793127941279512796127971279812799128001280112802128031280412805128061280712808128091281012811128121281312814128151281612817128181281912820128211282212823128241282512826128271282812829128301283112832128331283412835128361283712838128391284012841128421284312844128451284612847128481284912850128511285212853128541285512856128571285812859128601286112862128631286412865128661286712868128691287012871128721287312874128751287612877128781287912880128811288212883128841288512886128871288812889128901289112892128931289412895128961289712898128991290012901129021290312904129051290612907129081290912910129111291212913129141291512916129171291812919
  1. #include "ckcsym.h"
  2. #ifndef NOICP
  3. /*
  4. Authors:
  5. Frank da Cruz <fdc@columbia.edu>,
  6. The Kermit Project, New York City
  7. Jeffrey E Altman <jaltman@secure-endpoints.com>
  8. Secure Endpoints Inc., New York City
  9. Copyright (C) 1985, 2020,
  10. Trustees of Columbia University in the City of New York.
  11. All rights reserved. See the C-Kermit COPYING.TXT file or the
  12. copyright text in the ckcmai.c module for disclaimer and permissions.
  13. Last update:
  14. Fri Sep 18 14:55:27 2020
  15. */
  16. /* Includes */
  17. #include "ckcdeb.h"
  18. #include "ckcasc.h"
  19. #include "ckcker.h"
  20. #include "ckuusr.h"
  21. #include "ckcxla.h"
  22. #include "ckcnet.h" /* Network symbols */
  23. #include <signal.h>
  24. #ifndef NOSTAT
  25. #ifdef VMS
  26. /* 2010-03-09 SMS. VAX C needs help to find "sys". It's easier not to try. */
  27. #include <stat.h>
  28. #else /* def VMS */
  29. #include <sys/stat.h>
  30. #endif /* def VMS [else] */
  31. #endif /* NOSTAT */
  32. #ifdef VMS
  33. #ifndef TCPSOCKET
  34. #include <errno.h>
  35. #endif /* TCPSOCKET */
  36. #endif /* VMS */
  37. #ifdef datageneral
  38. #define fgets(stringbuf,max,fd) dg_fgets(stringbuf,max,fd)
  39. #endif /* datageneral */
  40. #ifdef QNX6
  41. #define readblock kreadblock
  42. #endif /* QNX6 */
  43. /* External Kermit Variables, see ckmain.c for description. */
  44. extern xx_strp xxstring;
  45. extern int local, xitsta, binary, parity, escape, flow, cmd_rows, turn,
  46. turnch, duplex, ckxech, seslog, dfloc, cnflg, tlevel, pflag, msgflg, mdmtyp,
  47. zincnt, quiet, repars, techo, network, nzxopts, what, filepeek, recursive;
  48. extern int xaskmore, tt_rows, tt_cols, cmd_cols, g_matchdot, diractive,
  49. xcmdsrc, nscanfile, reliable, nolinks, cmflgs;
  50. #ifdef VMSORUNIX
  51. extern int zgfs_dir, zgfs_link;
  52. #endif /* VMSORUNIX */
  53. #ifdef CK_IFRO
  54. extern int remonly;
  55. #endif /* CK_IFRO */
  56. #ifdef OS2
  57. extern int StartedFromDialer ;
  58. extern BYTE vmode;
  59. extern int k95stdout;
  60. #ifndef NT
  61. #define INCL_NOPM
  62. #define INCL_VIO /* Needed for ckocon.h */
  63. #include <os2.h>
  64. #undef COMMENT
  65. #else
  66. #define APIRET ULONG
  67. #include <windows.h>
  68. #include <tapi.h>
  69. #include "ckntap.h"
  70. #endif /* NT */
  71. #include "ckocon.h"
  72. #include "ckodir.h" /* [jt] 2013/11/21 - for MAXPATHLEN */
  73. #endif /* OS2 */
  74. extern long vernum, speed;
  75. extern char *versio, *protv, *ckxv, *ckzv, *fnsv, *connv, *dftty, *cmdv;
  76. extern char *dialv, *loginv, *for_def[], *whil_def[], *xif_def[], *sw_def[];
  77. extern char *foz_def[];
  78. extern char *ckxsys, *ckzsys;
  79. #ifndef OS2
  80. extern char *DIRCMD;
  81. #ifndef UNIX
  82. extern char *DELCMD;
  83. #endif /* UNIX */
  84. #endif /* OS2 */
  85. extern char ttname[], filnam[];
  86. extern CHAR sstate, feol;
  87. extern char *zinptr;
  88. #ifdef UNIX
  89. extern char ** mtchs; /* zxpand() file list */
  90. #endif /* UNIX */
  91. #ifndef NOXFER
  92. extern int oopts, omode, oname, opath; /* O-Packet options */
  93. extern int stdinf, sndsrc, size, rpsiz, urpsiz, fncnv, fnrpath, displa,
  94. stdouf, isguest, pktlog, nfils, keep, maxrps, fblksiz, frecl, frecfm,
  95. atcapr, atdiso, spsizf, spsiz, spsizr, spmax, wslotr, prefixing,
  96. fncact, fnspath, nprotos, g_proto, g_urpsiz, g_spsizf,
  97. g_spsiz, g_spsizr, g_spmax, g_wslotr, g_prefixing, g_fncact, g_fncnv,
  98. g_fnspath, g_fnrpath, xfrxla, g_xfrxla;
  99. extern char *cmarg, *cmarg2;
  100. #ifndef NOMSEND /* Multiple SEND */
  101. extern char *msfiles[];
  102. #endif /* NOMSEND */
  103. extern char fspec[]; /* Most recent filespec */
  104. extern int fspeclen;
  105. #ifdef CK_TMPDIR
  106. extern int f_tmpdir; /* Directory changed temporarily */
  107. extern char savdir[]; /* For saving current directory */
  108. #endif /* CK_TMPDIR */
  109. extern struct keytab protos[]; /* File transfer protocols */
  110. extern struct ck_p ptab[NPROTOS];
  111. #endif /* NOXFER */
  112. #ifdef DCMDBUF /* Declarations from cmd package */
  113. extern char *cmdbuf, *atmbuf; /* Command buffers */
  114. #else
  115. extern char cmdbuf[], atmbuf[]; /* Command buffers */
  116. #endif /* DCMDBUF */
  117. extern int nopush;
  118. #ifndef NOSPL
  119. int askflag = 0; /* ASK-class command active */
  120. int echostars = 0; /* ASKQ should echo asterisks */
  121. extern char **a_ptr[];
  122. extern int a_dim[];
  123. extern char **m_xarg[];
  124. extern int n_xarg[];
  125. extern struct mtab *mactab;
  126. extern int nmac;
  127. extern long ck_alarm;
  128. extern char alrm_date[], alrm_time[];
  129. extern int x_ifnum;
  130. #endif /* NOSPL */
  131. extern int inserver; /* I am IKSD */
  132. extern int backgrd; /* Kermit executing in background */
  133. extern char psave[]; /* For saving & restoring prompt */
  134. extern char *tp; /* Temporary buffer */
  135. int readblock = 4096; /* READ buffer size */
  136. CHAR * readbuf = NULL; /* Pointer to read buffer */
  137. int readsize = 0; /* Number of chars actually read */
  138. int getcmd = 0; /* GET-class command was given */
  139. char chgsourcedir[MAXPATHLEN+1] = { 0,0 }; /* Source directory for CHANGE */
  140. char chgdestdir[MAXPATHLEN+1] = { 0,0 }; /* Destination directory for CHANGE */
  141. char chgbackupdir[MAXPATHLEN+1] = { 0,0 }; /* Backup directory for CHANGE */
  142. extern int zchkod, zchkid;
  143. /* C K U U S 6 -- "User Interface" for Unix Kermit (Part 6) */
  144. struct keytab deltab[] = { /* DELETE Command Options */
  145. { "/all", DEL_ALL, CM_INV },
  146. { "/after", DEL_AFT, CM_ARG },
  147. { "/ask", DEL_ASK, 0 },
  148. { "/before", DEL_BEF, CM_ARG },
  149. { "/directories", DEL_DIR, 0 },
  150. { "/dotfiles", DEL_DOT, 0 },
  151. { "/except", DEL_EXC, CM_ARG },
  152. { "/heading", DEL_HDG, 0 },
  153. { "/l", DEL_LIS, CM_INV|CM_ABR },
  154. { "/larger-than", DEL_LAR, CM_ARG },
  155. { "/list", DEL_LIS, 0 },
  156. { "/log", DEL_LIS, CM_INV },
  157. { "/noask", DEL_NAS, 0 },
  158. { "/nodotfiles", DEL_NOD, 0 },
  159. { "/noheading", DEL_NOH, 0 },
  160. { "/nol", DEL_NOL, CM_INV|CM_ABR },
  161. { "/nolist", DEL_NOL, 0 },
  162. { "/nolog", DEL_NOL, CM_INV },
  163. { "/nopage", DEL_NOP, 0 },
  164. { "/not-after", DEL_NAF, CM_ARG },
  165. { "/not-before", DEL_NBF, CM_ARG },
  166. { "/not-since", DEL_NAF, CM_INV|CM_ARG },
  167. { "/page", DEL_PAG, 0 },
  168. { "/quiet", DEL_QUI, CM_INV },
  169. { "/recursive", DEL_REC, 0 },
  170. { "/simulate", DEL_SIM, 0 },
  171. { "/since", DEL_AFT, CM_ARG|CM_INV },
  172. { "/smaller-than", DEL_SMA, CM_ARG },
  173. { "/summary", DEL_SUM, 0 },
  174. { "/tree", DEL_ALL, 0 },
  175. { "/type", DEL_TYP, CM_ARG },
  176. { "/verbose", DEL_VRB, CM_INV }
  177. };
  178. int ndeltab = sizeof(deltab)/sizeof(struct keytab);
  179. /* /QUIET-/VERBOSE (/LIST-/NOLIST) (/LOG-/NOLOG) table */
  180. struct keytab qvswtab[] = {
  181. { "/l", DEL_LIS, CM_INV|CM_ABR },
  182. { "/list", DEL_LIS, 0 },
  183. { "/log", DEL_LIS, CM_INV },
  184. { "/nol", DEL_NOL, CM_INV|CM_ABR },
  185. { "/nolist", DEL_NOL, 0 },
  186. { "/nolog", DEL_NOL, CM_INV },
  187. { "/quiet", DEL_QUI, CM_INV },
  188. { "/verbose", DEL_VRB, CM_INV }
  189. };
  190. int nqvswtab = sizeof(qvswtab)/sizeof(struct keytab);
  191. static struct keytab renamsw[] = {
  192. { "/collision", REN_OVW, CM_ARG },
  193. #ifndef NOUNICODE
  194. { "/convert", REN_XLA, CM_ARG },
  195. #endif /* NOUNICODE */
  196. { "/fixspaces", REN_SPA, CM_ARG },
  197. { "/l", DEL_LIS, CM_INV|CM_ABR },
  198. { "/list", DEL_LIS, 0 },
  199. { "/log", DEL_LIS, CM_INV },
  200. { "/lower", REN_LOW, CM_ARG },
  201. { "/nol", DEL_NOL, CM_INV|CM_ABR },
  202. { "/nolist", DEL_NOL, 0 },
  203. { "/nolog", DEL_NOL, CM_INV },
  204. { "/quiet", DEL_QUI, CM_INV },
  205. { "/replace", REN_RPL, CM_ARG },
  206. { "/simulate", DEL_SIM, 0 },
  207. { "/upper", REN_UPP, CM_ARG },
  208. { "/verbose", DEL_VRB, CM_INV }
  209. };
  210. static int nrenamsw = sizeof(renamsw)/sizeof(struct keytab);
  211. static struct keytab renamset[] = {
  212. { "collision", REN_OVW, 0 },
  213. { "list", DEL_LIS, 0 }
  214. };
  215. static int nrenamset = sizeof(renamset)/sizeof(struct keytab);
  216. /* Args for RENAME /LOWER: and /UPPER: */
  217. static struct keytab r_upper[] = {
  218. { "all", 1, 0 },
  219. { "lower", 0, 0 }
  220. };
  221. static struct keytab r_lower[] = {
  222. { "all", 1, 0 },
  223. { "upper", 0, 0 }
  224. };
  225. /* Args for RENAME /COLLISION... */
  226. #define RENX_FAIL 0
  227. #define RENX_OVWR 1
  228. #define RENX_SKIP 2
  229. static struct keytab r_collision[] = {
  230. { "fail", RENX_FAIL, 0 },
  231. { "overwrite", RENX_OVWR, 0 },
  232. { "proceed", RENX_SKIP, CM_INV },
  233. { "skip", RENX_SKIP, 0 }
  234. };
  235. static int nr_collision = sizeof(r_collision)/sizeof(struct keytab);
  236. struct keytab copytab[] = {
  237. { "/append", 998, 0 },
  238. #ifndef NOSPL
  239. { "/fromb64", 997, 0 },
  240. #endif /* NOSPL */
  241. { "/l", DEL_LIS, CM_INV|CM_ABR },
  242. { "/list", DEL_LIS, 0 },
  243. { "/log", DEL_LIS, CM_INV },
  244. { "/nol", DEL_NOL, CM_INV|CM_ABR },
  245. { "/nolist", DEL_NOL, 0 },
  246. { "/nolog", DEL_NOL, CM_INV },
  247. { "/overwrite", 994, CM_ARG },
  248. #ifndef NOXFER
  249. { "/preserve", 995, 0 },
  250. #endif /* NOXFER */
  251. { "/quiet", DEL_QUI, CM_INV },
  252. { "/swap-bytes", 999, 0 },
  253. #ifndef NOSPL
  254. { "/tob64", 996, 0 },
  255. #endif /* NOSPL */
  256. { "/verbose", DEL_VRB, CM_INV }
  257. };
  258. int ncopytab = sizeof(copytab)/sizeof(struct keytab);
  259. #define OVW_ALWAYS 0
  260. #define OVW_NEVER 1
  261. #define OVW_OLDER 2
  262. #define OVW_NEWER 3
  263. static struct keytab ovwtab[] = {
  264. { "always", OVW_ALWAYS, 0 },
  265. { "never", OVW_NEVER, 0 },
  266. { "newer", OVW_NEWER, 0 },
  267. { "older", OVW_OLDER, 0 }
  268. };
  269. static int novwtab = 4;
  270. #ifndef NOXFER
  271. static struct keytab gettab[] = { /* GET options */
  272. { "/as-name", SND_ASN, CM_ARG },
  273. { "/binary", SND_BIN, 0 },
  274. #ifdef CALIBRATE
  275. { "/calibrate", SND_CAL, CM_INV },
  276. #endif /* CALIBRATE */
  277. #ifdef PIPESEND
  278. { "/command", SND_CMD, CM_PSH },
  279. #endif /* PIPESEND */
  280. { "/delete", SND_DEL, 0 },
  281. { "/except", SND_EXC, CM_ARG },
  282. { "/filenames", SND_NAM, CM_ARG },
  283. #ifdef PIPESEND
  284. { "/filter", SND_FLT, CM_ARG|CM_PSH },
  285. #endif /* PIPESEND */
  286. #ifdef VMS
  287. { "/image", SND_IMG, 0 },
  288. { "/labeled", SND_LBL, 0 },
  289. #else
  290. { "/image", SND_BIN, CM_INV },
  291. #endif /* VMS */
  292. #ifdef CK_TMPDIR
  293. { "/move-to", SND_MOV, CM_ARG },
  294. #endif /* CK_TMPDIR */
  295. { "/pathnames", SND_PTH, CM_ARG },
  296. { "/pipes", SND_PIP, CM_ARG|CM_PSH },
  297. { "/quiet", SND_SHH, 0 },
  298. #ifdef CK_RESEND
  299. { "/recover", SND_RES, 0 },
  300. #endif /* CK_RESEND */
  301. { "/recursive", SND_REC, 0 },
  302. { "/rename-to", SND_REN, CM_ARG },
  303. #ifdef COMMENT
  304. { "/smaller-than", SND_SMA, CM_ARG },
  305. #endif /* COMMENT */
  306. { "/subdirectories", SND_REC, CM_INV },
  307. { "/text", SND_TXT, 0 },
  308. { "/transparent", SND_XPA, 0 }
  309. };
  310. #define NGETTAB sizeof(gettab)/sizeof(struct keytab)
  311. static int ngettab = NGETTAB;
  312. static struct keytab rcvtab[] = { /* RECEIVE options */
  313. { "/as-name", SND_ASN, CM_ARG },
  314. { "/binary", SND_BIN, 0 },
  315. #ifdef CALIBRATE
  316. { "/calibrate", SND_CAL, CM_INV },
  317. #endif /* CALIBRATE */
  318. #ifdef PIPESEND
  319. { "/command", SND_CMD, CM_PSH },
  320. #endif /* PIPESEND */
  321. { "/except", SND_EXC, CM_ARG },
  322. { "/filenames", SND_NAM, CM_ARG },
  323. #ifdef PIPESEND
  324. { "/filter", SND_FLT, CM_ARG|CM_PSH },
  325. #endif /* PIPESEND */
  326. #ifdef VMS
  327. { "/image", SND_IMG, 0 },
  328. { "/labeled", SND_LBL, 0 },
  329. #else
  330. { "/image", SND_BIN, CM_INV },
  331. #endif /* VMS */
  332. #ifdef CK_TMPDIR
  333. { "/move-to", SND_MOV, CM_ARG },
  334. #endif /* CK_TMPDIR */
  335. { "/pathnames", SND_PTH, CM_ARG },
  336. { "/pipes", SND_PIP, CM_ARG|CM_PSH },
  337. #ifdef CK_XYZ
  338. { "/protocol", SND_PRO, CM_ARG },
  339. #else
  340. { "/protocol", SND_PRO, CM_ARG|CM_INV },
  341. #endif /* CK_XYZ */
  342. { "/quiet", SND_SHH, 0 },
  343. { "/recursive", SND_REC, 0 },
  344. { "/rename-to", SND_REN, CM_ARG },
  345. { "/text", SND_TXT, 0 },
  346. { "/transparent", SND_XPA, 0 }
  347. };
  348. #define NRCVTAB sizeof(rcvtab)/sizeof(struct keytab)
  349. static int nrcvtab = NRCVTAB;
  350. #endif /* NOXFER */
  351. /* WAIT table */
  352. #define WAIT_FIL 997
  353. #define WAIT_MDM 998
  354. struct keytab waittab[] = {
  355. { "cd", BM_DCD, CM_INV }, /* (Carrier Detect) */
  356. { "cts", BM_CTS, CM_INV }, /* (Clear To Send) */
  357. { "dsr", BM_DSR, CM_INV }, /* (Data Set Ready) */
  358. { "file", WAIT_FIL, 0 }, /* New category selector keywords */
  359. { "modem-signals", WAIT_MDM, 0 }, /* ... */
  360. { "ri", BM_RNG, CM_INV } /* (Ring Indicator) */
  361. };
  362. int nwaittab = (sizeof(waittab) / sizeof(struct keytab));
  363. /* Modem signal table */
  364. struct keytab mstab[] = {
  365. { "cd", BM_DCD, 0 }, /* Carrier Detect */
  366. { "cts", BM_CTS, 0 }, /* Clear To Send */
  367. { "dsr", BM_DSR, 0 }, /* Data Set Ready */
  368. { "ri", BM_RNG, 0 } /* Ring Indicator */
  369. };
  370. int nms = (sizeof(mstab) / sizeof(struct keytab));
  371. #define WF_MOD 1
  372. #define WF_DEL 2
  373. #define WF_CRE 3
  374. struct keytab wfswi[] = { /* WAIT FILE switches */
  375. { "creation", WF_CRE, 0 }, /* Wait for file to be created */
  376. { "deletion", WF_DEL, 0 }, /* Wait for file to be deleted */
  377. { "modification", WF_MOD, 0 } /* Wait for file to be modified */
  378. };
  379. int nwfswi = (sizeof(wfswi) / sizeof(struct keytab));
  380. #ifndef NOSPL
  381. struct keytab asgtab[] = { /* Assignment operators for "." */
  382. { "::=", 2, 0 }, /* ASSIGN and EVALUATE */
  383. { ":=", 1, 0 }, /* ASSIGN */
  384. { "=", 0, 0 } /* DEFINE */
  385. };
  386. int nasgtab = (sizeof(asgtab) / sizeof(struct keytab));
  387. struct keytab opntab[] = {
  388. #ifndef NOPUSH
  389. { "!read", OPN_PI_R, CM_INV },
  390. { "!write", OPN_PI_W, CM_INV },
  391. #endif /* NOPUSH */
  392. { "append", OPN_FI_A, 0 },
  393. { "host", OPN_NET, 0 },
  394. #ifdef OS2
  395. { "line", OPN_SER, CM_INV },
  396. { "port", OPN_SER, 0 },
  397. #else
  398. { "line", OPN_SER, 0 },
  399. { "port", OPN_SER, CM_INV },
  400. #endif /* OS2 */
  401. { "read", OPN_FI_R, 0 },
  402. { "write", OPN_FI_W, 0 }
  403. };
  404. int nopn = (sizeof(opntab) / sizeof(struct keytab));
  405. /* IF conditions */
  406. #define XXIFCO 0 /* IF COUNT */
  407. #define XXIFER 1 /* IF ERRORLEVEL */
  408. #define XXIFEX 2 /* IF EXIST */
  409. #define XXIFFA 3 /* IF FAILURE */
  410. #define XXIFSU 4 /* IF SUCCESS */
  411. #define XXIFNO 5 /* IF NOT */
  412. #define XXIFDE 6 /* IF DEFINED */
  413. #define XXIFEQ 7 /* IF EQUAL (strings) */
  414. #define XXIFAE 8 /* IF = (numbers) */
  415. #define XXIFLT 9 /* IF < (numbers) */
  416. #define XXIFGT 10 /* IF > (numbers) */
  417. #define XXIFLL 11 /* IF Lexically Less Than (strings) */
  418. #define XXIFLG 12 /* IF Lexically Greater Than (strings) */
  419. #define XXIFEO 13 /* IF EOF (READ file) */
  420. #define XXIFBG 14 /* IF BACKGROUND */
  421. #define XXIFNU 15 /* IF NUMERIC */
  422. #define XXIFFG 16 /* IF FOREGROUND */
  423. #define XXIFDI 17 /* IF DIRECTORY */
  424. #define XXIFNE 18 /* IF NEWER */
  425. #define XXIFRO 19 /* IF REMOTE-ONLY */
  426. #define XXIFAL 20 /* IF ALARM */
  427. #define XXIFSD 21 /* IF STARTED-FROM-DIALER */
  428. #define XXIFTR 22 /* IF TRUE */
  429. #define XXIFNT 23 /* IF FALSE */
  430. #define XXIFTM 24 /* IF TERMINAL-MACRO */
  431. #define XXIFEM 25 /* IF EMULATION */
  432. #define XXIFOP 26 /* IF OPEN */
  433. #define XXIFLE 27 /* IF <= */
  434. #define XXIFGE 28 /* IF >= */
  435. #define XXIFIP 29 /* IF INPATH */
  436. #define XXIFTA 30 /* IF TAPI */
  437. #define XXIFMA 31 /* IF MATCH */
  438. #define XXIFFL 32 /* IF FLAG */
  439. #define XXIFAB 33 /* IF ABSOLUTE */
  440. #define XXIFAV 34 /* IF AVAILABLE */
  441. #define XXIFAT 35 /* IF ASKTIMEOUT */
  442. #define XXIFRD 36 /* IF READABLE */
  443. #define XXIFWR 37 /* IF WRITEABLE */
  444. #define XXIFAN 38 /* IF ... AND ... */
  445. #define XXIFOR 39 /* IF ... OR ... */
  446. #define XXIFLP 40 /* IF left parenthesis */
  447. #define XXIFRP 41 /* IF right parenthesis */
  448. #define XXIFNQ 42 /* IF != (== "NOT =") */
  449. #define XXIFQU 43 /* IF QUIET */
  450. #define XXIFCK 44 /* IF C-KERMIT */
  451. #define XXIFK9 45 /* IF K-95 */
  452. #define XXIFMS 46 /* IF MS-KERMIT */
  453. #define XXIFWI 47 /* IF WILD */
  454. #define XXIFLO 48 /* IF LOCAL */
  455. #define XXIFCM 49 /* IF COMMAND */
  456. #define XXIFFP 50 /* IF FLOAT */
  457. #define XXIFIK 51 /* IF IKS */
  458. #define XXIFKB 52 /* IF KBHIT */
  459. #define XXIFKG 53 /* IF KERBANG */
  460. #define XXIFVE 54 /* IF VERSION */
  461. #define XXIFDC 55 /* IF DECLARED */
  462. #define XXIFGU 56 /* IF GUI */
  463. #define XXIFLN 57 /* IF LINK */
  464. #define XXIFDB 58 /* IF DEBUG */
  465. #define XXIFFU 59 /* IF FUNCTION */
  466. #define XXIFNN 60 /* IF NEQ (lexically not equal) */
  467. #define XXIFLLE 61 /* IF LLE (lexically less than or equal) */
  468. #define XXIFLGE 62 /* IF LLE (lexically less than or equal) */
  469. #define XXIFTXT 63 /* IF TEXT (file) */
  470. #define XXIFBIN 64 /* IF BINARY (file) */
  471. struct keytab iftab[] = { /* IF commands */
  472. { "!", XXIFNO, 0 },
  473. { "!=", XXIFNQ, 0 },
  474. { "&&", XXIFAN, 0 },
  475. { "(", XXIFLP, 0 },
  476. { ")", XXIFRP, 0 },
  477. { "<", XXIFLT, 0 },
  478. { "<=", XXIFLE, 0 },
  479. { "=", XXIFAE, 0 },
  480. { "==", XXIFAE, CM_INV },
  481. { ">", XXIFGT, 0 },
  482. { ">=", XXIFGE, 0 },
  483. { "absolute", XXIFAB, 0 },
  484. { "alarm", XXIFAL, 0 },
  485. { "and", XXIFAN, 0 },
  486. { "asktimeout", XXIFAT, 0 },
  487. { "available", XXIFAV, 0 },
  488. { "background", XXIFBG, 0 },
  489. { "binary", XXIFBIN,0 },
  490. { "c-kermit", XXIFCK, 0 },
  491. { "command", XXIFCM, 0 },
  492. { "count", XXIFCO, 0 },
  493. { "dcl", XXIFDC, CM_INV },
  494. { "debug", XXIFDB, 0 },
  495. { "declared", XXIFDC, 0 },
  496. { "defined", XXIFDE, 0 },
  497. #ifdef CK_TMPDIR
  498. { "directory", XXIFDI, 0 },
  499. #endif /* CK_TMPDIR */
  500. { "emulation", XXIFEM, 0 },
  501. #ifdef COMMENT
  502. { "eof", XXIFEO, 0 },
  503. #endif /* COMMENT */
  504. { "equal", XXIFEQ, 0 },
  505. { "error", XXIFFA, CM_INV },
  506. { "exist", XXIFEX, 0 },
  507. { "failure", XXIFFA, 0 },
  508. { "false", XXIFNT, 0 },
  509. { "flag", XXIFFL, 0 },
  510. #ifdef CKFLOAT
  511. { "float", XXIFFP, 0 },
  512. #endif /* CKFLOAT */
  513. { "foreground", XXIFFG, 0 },
  514. { "function", XXIFFU, 0 },
  515. #ifdef OS2
  516. { "gui", XXIFGU, 0 },
  517. #else
  518. { "gui", XXIFGU, CM_INV },
  519. #endif /* OS2 */
  520. #ifdef IKSD
  521. { "iksd", XXIFIK, 0 },
  522. #else
  523. { "iksd", XXIFIK, CM_INV },
  524. #endif /* IKSD */
  525. { "integer", XXIFNU, CM_INV },
  526. { "k-95", XXIFK9, CM_INV },
  527. { "kbhit", XXIFKB, 0 },
  528. #ifdef UNIX
  529. { "kerbang", XXIFKG, 0 },
  530. #else
  531. { "kerbang", XXIFKG, CM_INV },
  532. #endif /* UNIX */
  533. { "lge", XXIFLGE,0 },
  534. { "lgt", XXIFLG, 0 },
  535. #ifdef UNIX
  536. { "link", XXIFLN, 0 },
  537. #endif /* UNIX */
  538. { "lle", XXIFLLE,0 },
  539. { "llt", XXIFLL, 0 },
  540. { "local", XXIFLO, 0 },
  541. { "match", XXIFMA, 0 },
  542. { "ms-kermit", XXIFMS, CM_INV },
  543. { "neq", XXIFNN, 0 },
  544. #ifdef ZFCDAT
  545. { "newer", XXIFNE, 0 },
  546. #endif /* ZFCDAT */
  547. { "not", XXIFNO, 0 },
  548. { "numeric", XXIFNU, 0 },
  549. /* { "ok", XXIFSU, CM_INV }, */
  550. { "open", XXIFOP, 0 },
  551. { "or", XXIFOR, 0 },
  552. { "quiet", XXIFQU, 0 },
  553. { "readable", XXIFRD, 0 },
  554. { "remote-only",XXIFRO, 0 },
  555. { "started-from-dialer",XXIFSD, CM_INV },
  556. { "success", XXIFSU, 0 },
  557. { "tapi", XXIFTA, 0 },
  558. #ifdef OS2
  559. { "terminal-macro", XXIFTM, 0 },
  560. #else
  561. { "terminal-macro", XXIFTM, CM_INV },
  562. #endif /* OS2 */
  563. { "text", XXIFTXT,0 },
  564. { "true", XXIFTR, 0 },
  565. { "version", XXIFVE, 0 },
  566. { "wild", XXIFWI, 0 },
  567. { "windows", XXIFK9, 0 },
  568. { "writeable", XXIFWR, 0 },
  569. { "||", XXIFOR, 0 },
  570. { "", 0, 0 }
  571. };
  572. int nif = (sizeof(iftab) / sizeof(struct keytab)) - 1;
  573. struct keytab iotab[] = { /* Keywords for IF OPEN */
  574. { "!read-file", ZRFILE, CM_INV },
  575. { "!write-file", ZWFILE, CM_INV },
  576. { "append-file", ZWFILE, CM_INV },
  577. { "connection", 8888, 0 },
  578. #ifdef CKLOGDIAL
  579. { "cx-log", 7777, 0 },
  580. #endif /* CKLOGDIAL */
  581. { "debug-log", ZDFILE, 0 },
  582. { "error", 9999, 0 },
  583. { "packet-log", ZPFILE, 0 },
  584. { "read-file", ZRFILE, 0 },
  585. { "screen", ZSTDIO, 0 },
  586. { "session-log", ZSFILE, 0 },
  587. { "transaction-log", ZTFILE, 0 },
  588. { "write-file", ZWFILE, 0 }
  589. };
  590. int niot = (sizeof(iotab) / sizeof(struct keytab));
  591. #endif /* NOSPL */
  592. /* Variables and prototypes */
  593. _PROTOTYP(static int doymdir,(int));
  594. _PROTOTYP(static int renameone,(char *,char *,
  595. int,int,int,int,int,int,int,int,int,int,int));
  596. #ifdef NETCONN
  597. extern int nnetdir; /* How many network directories */
  598. #endif /* NETCONN */
  599. #ifdef CK_SECURITY
  600. _PROTOTYP(int ck_krb4_is_installed,(void));
  601. _PROTOTYP(int ck_krb5_is_installed,(void));
  602. _PROTOTYP(int ck_ntlm_is_installed,(void));
  603. _PROTOTYP(int ck_srp_is_installed,(void));
  604. _PROTOTYP(int ck_ssleay_is_installed,(void));
  605. _PROTOTYP(int ck_ssh_is_installed,(void));
  606. _PROTOTYP(int ck_crypt_is_installed,(void));
  607. #else
  608. #define ck_krb4_is_installed() (0)
  609. #define ck_krb5_is_installed() (0)
  610. #define ck_ntlm_is_installed() (0)
  611. #define ck_srp_is_installed() (0)
  612. #define ck_ssleay_is_installed() (0)
  613. #define ck_ssh_is_installed() (0)
  614. #define ck_crypt_is_installed() (0)
  615. #endif /* CK_SECURITY */
  616. #define AV_KRB4 1
  617. #define AV_KRB5 2
  618. #define AV_NTLM 3
  619. #define AV_SRP 4
  620. #define AV_SSL 5
  621. #define AV_CRYPTO 6
  622. #define AV_SSH 7
  623. struct keytab availtab[] = { /* Available authentication types */
  624. { "crypto", AV_CRYPTO, CM_INV }, /* and encryption */
  625. { "encryption", AV_CRYPTO, 0 },
  626. { "k4", AV_KRB4, CM_INV },
  627. { "k5", AV_KRB5, CM_INV },
  628. { "kerberos4", AV_KRB4, 0 },
  629. { "kerberos5", AV_KRB5, 0 },
  630. { "krb4", AV_KRB4, CM_INV },
  631. { "krb5", AV_KRB5, CM_INV },
  632. { "ntlm", AV_NTLM, 0 },
  633. { "srp", AV_SRP, 0 },
  634. { "ssh", AV_SSH, 0 },
  635. { "ssl", AV_SSL, 0 },
  636. { "tls", AV_SSL, 0 },
  637. { "", 0, 0 }
  638. };
  639. int availtabn = sizeof(availtab)/sizeof(struct keytab)-1;
  640. #ifndef NODIAL
  641. _PROTOTYP(static int ddcvt, (char *, FILE *, int) );
  642. _PROTOTYP(static int dncvt, (int, int, int, int) );
  643. _PROTOTYP(char * getdname, (void) );
  644. static int partial = 0; /* For partial dial */
  645. static char *dscopy = NULL;
  646. int dialtype = -1;
  647. char *dialnum = (char *)0; /* Remember DIAL number for REDIAL */
  648. int dirline = 0; /* Dial directory line number */
  649. extern char * dialdir[]; /* Dial directory file names */
  650. extern int dialdpy; /* DIAL DISPLAY on/off */
  651. extern int ndialdir; /* How many dial directories */
  652. extern int ntollfree; /* Toll-free call info */
  653. extern int ndialpxx; /* List of PBX exchanges */
  654. extern char *dialtfc[];
  655. char * matchpxx = NULL; /* PBX exchange that matched */
  656. extern int nlocalac; /* Local area-code list */
  657. extern char * diallcac[];
  658. extern int tttapi;
  659. #ifdef CK_TAPI
  660. extern int tapiconv; /* TAPI Conversions */
  661. extern int tapipass; /* TAPI Passthrough */
  662. #endif /* CK_TAPI */
  663. extern int dialatmo;
  664. extern char * dialnpr, * dialsfx;
  665. extern char * dialixp, * dialixs, * dialmac;
  666. extern char * dialldp, * diallds, * dialtfp;
  667. extern char * dialpxi, * dialpxo, * diallac;
  668. extern char * diallcp, * diallcs, * diallcc;
  669. extern char * dialpxx[];
  670. extern int dialcnf; /* DIAL CONFIRMATION */
  671. int dialfld = 0; /* DIAL FORCE-LONG-DISTANCE */
  672. int dialsrt = 1; /* DIAL SORT ON */
  673. int dialrstr = 6; /* DIAL RESTRICTION */
  674. int dialtest = 0; /* DIAL TEST */
  675. int dialcount = 0; /* \v(dialcount) */
  676. extern int dialsta; /* Dial status */
  677. int dialrtr = -1, /* Dial retries */
  678. dialint = 10; /* Dial retry interval */
  679. extern long dialcapas; /* Modem capabilities */
  680. extern int dialcvt; /* DIAL CONVERT-DIRECTORY */
  681. #endif /* NODIAL */
  682. #ifndef NOSPL
  683. #define IFCONDLEN 256
  684. int ifc, /* IF case */
  685. not = 0, /* Flag for IF NOT */
  686. ifargs = 0; /* Count of IF condition words */
  687. char ifcond[IFCONDLEN]; /* IF condition text */
  688. char *ifcp; /* Pointer to IF condition text */
  689. extern int vareval;
  690. #ifdef DCMDBUF
  691. extern int
  692. *ifcmd, *count, *iftest, *intime,
  693. *inpcas, *takerr, *merror, *xquiet, *xvarev;
  694. #else
  695. extern int ifcmd[]; /* Last command was IF */
  696. extern int iftest[]; /* Last IF was true */
  697. extern int count[]; /* For IF COUNT, one for each cmdlvl */
  698. extern int intime[]; /* Ditto for other stackables... */
  699. extern int inpcas[];
  700. extern int takerr[];
  701. extern int merror[];
  702. extern int xquiet[];
  703. extern int xvarev[];
  704. #endif /* DCMDBUF */
  705. #else
  706. extern int takerr[];
  707. #endif /* NOSPL */
  708. #ifdef DCMDBUF
  709. extern char *line; /* Character buffer for anything */
  710. extern char *tmpbuf;
  711. #else
  712. extern char line[], tmpbuf[];
  713. #endif /* DCMDBUF */
  714. extern char *lp; /* Pointer to line buffer */
  715. int cwdf = 0; /* CWD has been done */
  716. /* Flags for ENABLE/DISABLE */
  717. extern int en_cwd, en_cpy, en_del, en_dir, en_fin,
  718. en_get, en_hos, en_ren, en_sen, en_set, en_spa, en_typ, en_who, en_bye,
  719. en_asg, en_que, en_ret, en_mai, en_pri, en_mkd, en_rmd, en_xit, en_ena;
  720. extern FILE *tfile[]; /* File pointers for TAKE command */
  721. extern char *tfnam[]; /* Names of TAKE files */
  722. extern int tfline[]; /* TAKE-file line number */
  723. extern int success; /* Command success/failure flag */
  724. extern int cmdlvl; /* Current position in command stack */
  725. #ifndef NOSPL
  726. extern int maclvl; /* Macro to execute */
  727. extern char *macx[]; /* Index of current macro */
  728. extern char *mrval[]; /* Macro return value */
  729. extern char *macp[]; /* Pointer to macro */
  730. extern int macargc[]; /* ARGC from macro invocation */
  731. #ifdef COMMENT
  732. extern char *m_line[];
  733. #endif /* COMMENT */
  734. extern char *m_arg[MACLEVEL][NARGS]; /* Stack of macro arguments */
  735. extern char *g_var[]; /* Global variables %a, %b, etc */
  736. #ifdef DCMDBUF
  737. extern struct cmdptr *cmdstk; /* The command stack itself */
  738. #else
  739. extern struct cmdptr cmdstk[]; /* The command stack itself */
  740. #endif /* DCMDBUF */
  741. #endif /* NOSPL */
  742. #define xsystem(s) zsyscmd(s)
  743. static int x, y, z = 0;
  744. static char *s, *p;
  745. #ifdef OS2
  746. _PROTOTYP( int os2settitle, (char *, int) );
  747. #endif /* OS2 */
  748. extern struct keytab yesno[], onoff[], fntab[];
  749. extern int nyesno, nfntab;
  750. #ifndef NOSPL
  751. /* Do the ASK, ASKQ, GETOK, and READ commands */
  752. int asktimedout = 0;
  753. #define ASK_PUP 1
  754. #define ASK_TMO 2
  755. #define ASK_GUI 3
  756. #define ASK_QUI 4
  757. #define ASK_DEF 5
  758. #define ASK_ECH 6
  759. #define GETC_CHK 1
  760. #define GETC_TMO 2
  761. #define GETC_QUI 3
  762. static struct keytab asktab[] = {
  763. { "/default", ASK_DEF, CM_ARG },
  764. { "/gui", ASK_GUI,
  765. #ifdef KUI
  766. 0
  767. #else /* KUI */
  768. CM_INV
  769. #endif /* KUI */
  770. },
  771. { "/popup", ASK_PUP,
  772. #ifdef OS2
  773. 0
  774. #else /* OS2 */
  775. CM_INV
  776. #endif /* OS2 */
  777. },
  778. { "/quiet", ASK_QUI, 0 },
  779. { "/timeout", ASK_TMO, CM_ARG },
  780. { "", 0, 0 }
  781. };
  782. static int nasktab = sizeof(asktab)/sizeof(struct keytab)-1;
  783. static struct keytab askqtab[] = {
  784. { "/default", ASK_DEF, CM_ARG },
  785. { "/echo", ASK_ECH, CM_ARG },
  786. { "/gui", ASK_GUI,
  787. #ifdef KUI
  788. 0
  789. #else /* KUI */
  790. CM_INV
  791. #endif /* KUI */
  792. },
  793. { "/noecho", ASK_QUI, CM_INV },
  794. { "/popup", ASK_PUP,
  795. #ifdef OS2
  796. 0
  797. #else /* OS2 */
  798. CM_INV
  799. #endif /* OS2 */
  800. },
  801. { "/quiet", ASK_QUI, 0 },
  802. { "/timeout", ASK_TMO, CM_ARG },
  803. { "", 0, 0 }
  804. };
  805. static int naskqtab = sizeof(askqtab)/sizeof(struct keytab)-1;
  806. static struct keytab getctab[] = {
  807. { "/check", GETC_CHK, 0 },
  808. { "/quiet", GETC_QUI, 0 },
  809. { "/timeout", GETC_TMO, CM_ARG },
  810. { "", 0, 0 }
  811. };
  812. static int ngetctab = sizeof(getctab)/sizeof(struct keytab)-1;
  813. int
  814. doask(cx) int cx; {
  815. extern int asktimer, timelimit;
  816. #ifdef CK_RECALL
  817. extern int on_recall;
  818. #endif /* CK_RECALL */
  819. int echochar = 0;
  820. int popupflg = 0;
  821. int guiflg = 0;
  822. int nomsg = 0;
  823. int mytimer = 0;
  824. int peek = 0;
  825. #ifdef CK_APC
  826. extern int apcactive, apcstatus;
  827. #endif /* CK_APC */
  828. char dfbuf[1024]; /* Buffer for default answer */
  829. char * dfanswer = NULL; /* Pointer to it */
  830. char vnambuf[VNAML+1]; /* Buffer for variable names */
  831. char *vnp = NULL; /* Pointer to same */
  832. dfbuf[0] = NUL;
  833. vnambuf[0] = NUL;
  834. #ifdef CK_APC
  835. if ( apcactive != APC_INACTIVE && (apcstatus & APC_NOINP) ) {
  836. return(success = 0);
  837. }
  838. #endif /* CK_APC */
  839. mytimer = asktimer; /* Inherit global ASK timer */
  840. echostars = 0; /* For ASKQ */
  841. if (cx == XXASK || cx == XXASKQ) {
  842. struct FDB sw, fl;
  843. int getval;
  844. char c;
  845. if (cx == XXASKQ) /* Don't log ASKQ response */
  846. debok = 0;
  847. cmfdbi(&sw, /* First FDB - command switches */
  848. _CMKEY, /* fcode */
  849. "Variable name or switch",
  850. "", /* default */
  851. "", /* addtl string data */
  852. ((cx == XXASK) ? nasktab : naskqtab), /* Table size */
  853. 4, /* addtl numeric data 2: 4 = cmswi */
  854. xxstring, /* Processing function */
  855. ((cx == XXASK) ? asktab : askqtab), /* Keyword table */
  856. &fl /* Pointer to next FDB */
  857. );
  858. cmfdbi(&fl, /* Anything that doesn't match */
  859. _CMFLD, /* fcode */
  860. "", /* hlpmsg */
  861. "", /* default */
  862. "", /* addtl string data */
  863. 0, /* addtl numeric data 1 */
  864. 0, /* addtl numeric data 2 */
  865. NULL,
  866. NULL,
  867. NULL
  868. );
  869. while (1) { /* Parse 0 or more switches */
  870. x = cmfdb(&sw); /* Parse something */
  871. if (x < 0)
  872. return(x);
  873. if (cmresult.fcode != _CMKEY) /* Break out if not a switch */
  874. break;
  875. c = cmgbrk();
  876. if ((getval = (c == ':' || c == '=')) && !(cmgkwflgs() & CM_ARG)) {
  877. printf("?This switch does not take an argument\n");
  878. return(-9);
  879. }
  880. if (!getval && (cmgkwflgs() & CM_ARG)) {
  881. printf("?This switch requires an argument\n");
  882. return(-9);
  883. }
  884. switch (cmresult.nresult) {
  885. case ASK_QUI:
  886. nomsg = 1;
  887. if (cx == XXASKQ)
  888. echostars = 0;
  889. break;
  890. case ASK_PUP:
  891. popupflg = 1;
  892. break;
  893. case ASK_GUI:
  894. guiflg = 1;
  895. break;
  896. case ASK_TMO: {
  897. if ((y = cmnum("seconds","1",10,&x,xxstring)) < 0)
  898. return(y);
  899. if (x < 0)
  900. x = 0;
  901. mytimer = x;
  902. break;
  903. }
  904. case ASK_ECH: {
  905. if ((y = cmfld("Character to echo","*",&s,xxstring)) < 0)
  906. return(y);
  907. echochar = *s;
  908. break;
  909. }
  910. case ASK_DEF: {
  911. if ((y = cmfld("Text to supply if reply is empty",
  912. "",&s,xxstring)) < 0)
  913. return(y);
  914. ckstrncpy(dfbuf,s,1024);
  915. dfanswer = dfbuf;
  916. break;
  917. }
  918. default: return(-2);
  919. }
  920. }
  921. /* Have variable name, make copy. */
  922. ckstrncpy(vnambuf,cmresult.sresult,VNAML);
  923. vnp = vnambuf;
  924. if (vnambuf[0] == CMDQ &&
  925. (vnambuf[1] == '%' || vnambuf[1] == '&'))
  926. vnp++;
  927. y = 0;
  928. if (*vnp == '%' || *vnp == '&') {
  929. if ((y = parsevar(vnp,&x,&z)) < 0)
  930. return(y);
  931. }
  932. } else if (cx == XXGETC) { /* GETC */
  933. struct FDB sw, fl;
  934. int getval;
  935. char c;
  936. cmfdbi(&sw, /* First FDB - command switches */
  937. _CMKEY, /* fcode */
  938. "Variable name or switch",
  939. "", /* default */
  940. "", /* addtl string data */
  941. ngetctab, /* Table size */
  942. 4, /* addtl numeric data 2: 4 = cmswi */
  943. xxstring, /* Processing function */
  944. getctab, /* Keyword table */
  945. &fl /* Pointer to next FDB */
  946. );
  947. cmfdbi(&fl, /* Anything that doesn't match */
  948. _CMFLD, /* fcode */
  949. "", /* hlpmsg */
  950. "", /* default */
  951. "", /* addtl string data */
  952. 0, /* addtl numeric data 1 */
  953. 0, /* addtl numeric data 2 */
  954. NULL,
  955. NULL,
  956. NULL
  957. );
  958. while (1 && !peek) { /* Parse 0 or more switches */
  959. x = cmfdb(&sw); /* Parse something */
  960. if (x < 0)
  961. return(x);
  962. if (cmresult.fcode != _CMKEY) /* Break out if not a switch */
  963. break;
  964. c = cmgbrk();
  965. if ((getval = (c == ':' || c == '=')) && !(cmgkwflgs() & CM_ARG)) {
  966. printf("?This switch does not take an argument\n");
  967. return(-9);
  968. }
  969. if (!getval && (cmgkwflgs() & CM_ARG)) {
  970. printf("?This switch requires an argument\n");
  971. return(-9);
  972. }
  973. switch (cmresult.nresult) {
  974. case GETC_CHK: /* GETC /CHECK */
  975. peek = 1;
  976. break;
  977. case GETC_QUI: /* GETC /QUIET */
  978. nomsg = 1;
  979. break;
  980. case GETC_TMO: { /* GETC /TIMEOUT:sec */
  981. if ((y = cmnum("seconds","1",10,&x,xxstring)) < 0)
  982. return(y);
  983. if (x < 0)
  984. x = 0;
  985. mytimer = x;
  986. break;
  987. }
  988. default: return(-2);
  989. }
  990. }
  991. if (peek) { /* GETC /CHECK */
  992. /*
  993. This was intended to mean "check how many characters are waiting to be
  994. read from standard input". Conchk() was supposed to do that but it
  995. doesn't when stdin is redirected. The best I can do is ask isatty(0)
  996. whether stdin is a terminal. If not we'll assume it's redirected stdin.
  997. Btw, even if stdin really is a terminal conchk() returns 0, even if
  998. there is typeahead. - fdc, 21 Apr 2017.
  999. */
  1000. int itsatty = -1;
  1001. if ((y = cmcfm()) < 0) /* Get confirmation */
  1002. return(y);
  1003. itsatty = isatty(0); /* Is stdin a tty? */
  1004. debug(F101,"GETC peek","",peek);
  1005. debug(F101,"GETC itsatty","",itsatty);
  1006. return(success = (itsatty > 0) ? 0 : 1);
  1007. }
  1008. /* Regular GETC... Have variable name, make copy. */
  1009. ckstrncpy(vnambuf,cmresult.sresult,VNAML);
  1010. vnp = vnambuf;
  1011. if (vnambuf[0] == CMDQ &&
  1012. (vnambuf[1] == '%' || vnambuf[1] == '&'))
  1013. vnp++;
  1014. y = 0;
  1015. if (*vnp == '%' || *vnp == '&') {
  1016. if ((y = parsevar(vnp,&x,&z)) < 0)
  1017. return(y);
  1018. }
  1019. } else if (cx != XXGOK && cx != XXRDBL && !peek) { /* Get variable name */
  1020. if ((y = cmfld("Variable name","",&s,NULL)) < 0) {
  1021. if (y == -3) {
  1022. printf("?Variable name required\n");
  1023. return(-9);
  1024. } else return(y);
  1025. }
  1026. ckstrncpy(vnambuf,s,VNAML); /* Make a copy. */
  1027. vnp = vnambuf;
  1028. if (vnambuf[0] == CMDQ &&
  1029. (vnambuf[1] == '%' || vnambuf[1] == '&'))
  1030. vnp++;
  1031. y = 0;
  1032. if (*vnp == '%' || *vnp == '&') {
  1033. if ((y = parsevar(vnp,&x,&z)) < 0)
  1034. return(y);
  1035. }
  1036. }
  1037. if (cx == XXREA || cx == XXRDBL) { /* READ or READBLOCK command */
  1038. if ((y = cmcfm()) < 0) /* Get confirmation */
  1039. return(y);
  1040. if (chkfn(ZRFILE) < 1) { /* File open? */
  1041. printf("?Read file not open\n");
  1042. return(success = 0);
  1043. }
  1044. if (!(s = (char *)readbuf)) { /* Where to read into. */
  1045. printf("?Oops, no READ buffer!\n");
  1046. return(success = 0);
  1047. }
  1048. y = zsinl(ZRFILE, s, readblock); /* Read a line. */
  1049. debug(F111,"read zsinl",s,y);
  1050. if (y < 0) { /* On EOF or other error, */
  1051. zclose(ZRFILE); /* close the file, */
  1052. delmac(vnp,0); /* delete the variable, */
  1053. return(success = 0); /* and return failure. */
  1054. } else { /* Read was OK. */
  1055. readsize = (int) strlen(s);
  1056. success = (addmac(vnp,s) < 0 ? 0 : 1); /* Define variable */
  1057. debug(F111,"read addmac",vnp,success);
  1058. return(success); /* Return success. */
  1059. }
  1060. }
  1061. /* ASK, ASKQ, GETOK */
  1062. if (cx == XXGOK) { /* GETOK can take switches */
  1063. struct FDB sw, fl;
  1064. int getval;
  1065. char c;
  1066. cmfdbi(&sw, /* First FDB - command switches */
  1067. _CMKEY, /* fcode */
  1068. "Variable name or question prompt",
  1069. "", /* default */
  1070. "", /* addtl string data */
  1071. nasktab, /* addtl numeric data 1: tbl size */
  1072. 4, /* addtl numeric data 2: 4 = cmswi */
  1073. xxstring, /* Processing function */
  1074. asktab, /* Keyword table */
  1075. &fl /* Pointer to next FDB */
  1076. );
  1077. cmfdbi(&fl, /* Anything that doesn't match */
  1078. _CMTXT, /* fcode */
  1079. "", /* hlpmsg */
  1080. "", /* default */
  1081. "", /* addtl string data */
  1082. 0, /* addtl numeric data 1 */
  1083. 0, /* addtl numeric data 2 */
  1084. NULL,
  1085. NULL,
  1086. NULL
  1087. );
  1088. while (1) { /* Parse 0 or more switches */
  1089. x = cmfdb(&sw); /* Parse something */
  1090. if (x < 0)
  1091. return(x);
  1092. if (cmresult.fcode != _CMKEY) /* Break out if not a switch */
  1093. break;
  1094. c = cmgbrk();
  1095. if ((getval = (c == ':' || c == '=')) && !(cmgkwflgs() & CM_ARG)) {
  1096. printf("?This switch does not take an argument\n");
  1097. return(-9);
  1098. }
  1099. if (!getval && (cmgkwflgs() & CM_ARG)) {
  1100. printf("?This switch requires an argument\n");
  1101. return(-9);
  1102. }
  1103. switch (cmresult.nresult) {
  1104. case ASK_PUP:
  1105. popupflg = 1;
  1106. break;
  1107. case ASK_GUI:
  1108. guiflg = 1;
  1109. break;
  1110. case ASK_TMO: {
  1111. if ((y = cmnum("seconds","1",10,&x,xxstring)) < 0)
  1112. return(y);
  1113. if (x < 0)
  1114. x = 0;
  1115. mytimer = x;
  1116. break;
  1117. }
  1118. case ASK_DEF: {
  1119. if ((y = cmfld("Text to supply if reply is empty",
  1120. "",&s,xxstring)) < 0)
  1121. return(y);
  1122. ckstrncpy(dfbuf,s,1024);
  1123. dfanswer = dfbuf;
  1124. break;
  1125. }
  1126. case ASK_QUI:
  1127. nomsg = 1;
  1128. break;
  1129. default: return(-2);
  1130. }
  1131. }
  1132. p = cmresult.sresult;
  1133. } else
  1134. if ((y = cmtxt(
  1135. "Prompt,\n\
  1136. enclose in { braces } or \" quotes \" to preserve leading and trailing\n\
  1137. spaces, precede question mark with backslash (\\).",
  1138. "",&p,xxstring)) < 0)
  1139. return(y);
  1140. if (!p) p = "";
  1141. #ifndef NOLOCAL
  1142. #ifdef OS2
  1143. if (popupflg) { /* Popup requested */
  1144. int len = -1;
  1145. ckstrncpy(tmpbuf,brstrip(p),TMPBUFSIZ);
  1146. p = tmpbuf;
  1147. if (cx == XXASK || cx == XXASKQ) {
  1148. if (cx == XXASK)
  1149. len = popup_readtext(vmode,NULL,p,line,LINBUFSIZ,mytimer);
  1150. else
  1151. len = popup_readpass(vmode,NULL,p,line,LINBUFSIZ,mytimer);
  1152. asktimedout = ( len < 0 && mytimer );
  1153. } else if (cx == XXGOK) {
  1154. printf("?Sorry, GETOK /POPUP not implemented yet\n");
  1155. timelimit = 0;
  1156. return(-9);
  1157. }
  1158. if (len >= 0) {
  1159. y = addmac(vnp,(char *)line); /* Add it to the macro table. */
  1160. } else if ( asktimedout && dfanswer ) {
  1161. y = addmac(vnp,dfanswer); /* Add it to the macro table. */
  1162. asktimedout = 0;
  1163. len = 0;
  1164. }
  1165. timelimit = 0;
  1166. return(success = ((len >= 0) && (y >= 0)) && !asktimedout);
  1167. }
  1168. #ifdef KUI
  1169. if (guiflg) { /* GUI requested */
  1170. int rc, n;
  1171. char * s1;
  1172. s1 = tmpbuf;
  1173. n = TMPBUFSIZ-1;
  1174. zzstring(brstrip(p),&s1,&n);
  1175. p = tmpbuf;
  1176. if (cx == XXASK || cx == XXASKQ) {
  1177. rc = gui_txt_dialog(NULL,p,(cx == XXASK),
  1178. line,LINBUFSIZ,dfanswer,mytimer);
  1179. asktimedout = (rc == -1 && mytimer);
  1180. if (rc == 1) {
  1181. y = addmac(vnp,(char *)line); /* Add it to the macro table. */
  1182. } else if ( asktimedout && dfanswer ) {
  1183. y = addmac(vnp,dfanswer); /* Add default to macro table. */
  1184. asktimedout = 0;
  1185. rc = 1;
  1186. }
  1187. timelimit = 0;
  1188. return(success = (rc == 1 && (y >= 0)) && !asktimedout);
  1189. } else if (cx == XXGOK) {
  1190. int x;
  1191. x = lookup(yesno,dfanswer,nyesno,NULL);
  1192. if (x != 1) x = 2;
  1193. rc = uq_ok(NULL, p, 3, NULL, x);
  1194. return(success = (rc == 1));
  1195. }
  1196. }
  1197. #endif /* KUI */
  1198. #endif /* OS2 */
  1199. #endif /* NOLOCAL */
  1200. concb((char)escape); /* Enter CBREAK mode */
  1201. cmsavp(psave,PROMPTL); /* Save old prompt */
  1202. cmsetp(brstrip(p)); /* Make new prompt */
  1203. reprompt:
  1204. if (cx == XXASKQ) { /* For ASKQ, */
  1205. cmini(0); /* no-echo mode. */
  1206. if (echochar)
  1207. echostars = echochar;
  1208. } else { /* For others, regular echoing. */
  1209. cmini(ckxech);
  1210. echostars = 0;
  1211. }
  1212. askflag = 1;
  1213. x = -1; /* This means to reparse. */
  1214. cmflgs = 0;
  1215. if (pflag)
  1216. prompt(xxstring); /* Issue prompt. */
  1217. asktimedout = 0; /* Handle timed responses. */
  1218. timelimit = mytimer;
  1219. reparse:
  1220. cmres();
  1221. if (cx == XXGOK) { /* GETOK */
  1222. #ifdef CK_RECALL
  1223. on_recall = 0;
  1224. #endif /* CK_RECALL */
  1225. askflag = 0;
  1226. /* GETOK uses keyword table */
  1227. x = cmkey(yesno,nyesno,"",dfanswer,xxstring);
  1228. if (x < 0) { /* Parse error */
  1229. if (x == -10) {
  1230. char * ds;
  1231. ds = dfanswer ? dfanswer : "No";
  1232. if (!nomsg)
  1233. printf("?Timed out, assuming \"%s\"",ds);
  1234. printf("\n");
  1235. asktimedout = 1;
  1236. x = lookup(yesno,ds,nyesno,NULL);
  1237. if (x != 1) x = 0;
  1238. goto gokdone;
  1239. } else if (x == -3) { /* No answer? */
  1240. printf("Please respond Yes or No\n"); /* Make them answer */
  1241. cmini(ckxech);
  1242. goto reprompt;
  1243. } else if (x == -1) {
  1244. goto reparse;
  1245. } else
  1246. goto reprompt;
  1247. }
  1248. if (cmcfm() < 0) /* Get confirmation */
  1249. goto reparse;
  1250. gokdone:
  1251. askflag = 0;
  1252. cmsetp(psave); /* Restore prompt */
  1253. #ifdef VMS
  1254. if (cmdlvl > 0) /* In VMS and not at top level, */
  1255. conres(); /* restore console again. */
  1256. #endif /* VMS */
  1257. timelimit = 0;
  1258. return(x); /* Return success or failure */
  1259. } else if (cx == XXGETC /* GETC */
  1260. #ifdef OS2
  1261. || cx == XXGETK /* or GETKEYCODE */
  1262. #endif /* OS2 */
  1263. ) { /* GETC */
  1264. char tmp[16];
  1265. conbin((char)escape); /* Put keyboard in raw mode */
  1266. #ifndef NOSETKEY
  1267. #ifdef OS2
  1268. if (cx == XXGETK) { /* GETKEYCODE */
  1269. extern int os2gks;
  1270. int t;
  1271. t = os2gks; /* Turn off kverb recognition */
  1272. os2gks = 0;
  1273. x = congks(timelimit); /* Read a key event, blocking */
  1274. os2gks = t; /* Put back kverb recognition */
  1275. } else /* GETC */
  1276. #endif /* OS2 */
  1277. #endif /* NOSETKEY */
  1278. {
  1279. x = coninc(timelimit); /* Read one character */
  1280. debug(F101,"GETC coninc","",x);
  1281. }
  1282. concb((char)escape); /* Put keyboard back in cbreak mode */
  1283. if (x > -1) {
  1284. if (xcmdsrc == 0)
  1285. printf("\r\n");
  1286. #ifdef OS2
  1287. if (cx == XXGETK) { /* GETKEYCODE */
  1288. sprintf(tmp,"%d",x); /* SAFE */
  1289. } else {
  1290. #endif /* OS2 */
  1291. tmp[0] = (char) (x & 0xff);
  1292. tmp[1] = NUL;
  1293. #ifdef OS2
  1294. }
  1295. #endif /* OS2 */
  1296. y = addmac(vnp,tmp); /* Add it to the macro table. */
  1297. debug(F111,"getc/getk addmac",vnp,y);
  1298. } else y = -1;
  1299. cmsetp(psave); /* Restore old prompt. */
  1300. if (x < -1) {
  1301. asktimedout = 1;
  1302. if (!quiet && !nomsg)
  1303. printf("?Timed out");
  1304. printf("\n");
  1305. }
  1306. timelimit = 0;
  1307. return(success = ((y < 0 ? 0 : 1) && (asktimedout == 0)));
  1308. } else { /* ASK or ASKQ */
  1309. #ifdef CK_RECALL
  1310. on_recall = 0; /* Don't put response in recall buf */
  1311. #endif /* CK_RECALL */
  1312. askflag = 1; /* ASK[Q] always goes to terminal */
  1313. y = cmdgquo(); /* Get current quoting */
  1314. cmdsquo(0); /* Turn off quoting */
  1315. while (x == -1) { /* Prompt till they answer */
  1316. x = cmtxt("Please respond.",dfanswer,&s,NULL);
  1317. debug(F111,"ASK cmtxt",s,x);
  1318. cmres();
  1319. }
  1320. cmdsquo(y); /* Restore previous quoting */
  1321. if (cx == XXASKQ) /* ASKQ must echo CRLF here */
  1322. printf("\r\n");
  1323. if (x == -10 && dfanswer) { /* Don't fail on timeout if */
  1324. s = dfanswer; /* a default was specified */
  1325. asktimedout = 0; /* and don't fail */
  1326. x = 0;
  1327. }
  1328. if (x < 0) { /* If cmtxt parse error, */
  1329. cmsetp(psave); /* restore original prompt */
  1330. #ifdef VMS
  1331. if (cmdlvl > 0) /* In VMS and not at top level, */
  1332. conres(); /* restore console again. */
  1333. #endif /* VMS */
  1334. if (x == -10) { /* Timed out with no response */
  1335. if (!nomsg)
  1336. printf("?Timed out");
  1337. printf("\n");
  1338. asktimedout = 1;
  1339. if (dfanswer) /* Supply default answer if any */
  1340. s = dfanswer;
  1341. success = x = 0; /* (was "x = -9;") */
  1342. }
  1343. timelimit = 0;
  1344. return(x); /* and return cmtxt's error code. */
  1345. }
  1346. if (!s || *s == NUL) { /* If user typed a bare CR, */
  1347. cmsetp(psave); /* Restore old prompt, */
  1348. delmac(vnp,0); /* delete variable if it exists, */
  1349. #ifdef VMS
  1350. if (cmdlvl > 0) /* In VMS and not at top level, */
  1351. conres(); /* restore console again. */
  1352. #endif /* VMS */
  1353. timelimit = 0;
  1354. return(success = 1); /* and return. */
  1355. }
  1356. y = addmac(vnp,s); /* Add it to the macro table. */
  1357. debug(F111,"ask addmac",vnp,y);
  1358. cmsetp(psave); /* Restore old prompt. */
  1359. #ifdef VMS
  1360. if (cmdlvl > 0) /* In VMS and not at top level, */
  1361. conres(); /* restore console again. */
  1362. #endif /* VMS */
  1363. timelimit = 0;
  1364. return(success = (y < 0 ? 0 : 1) && (asktimedout == 0));
  1365. }
  1366. }
  1367. #endif /* NOSPL */
  1368. #ifndef NOSPL
  1369. int
  1370. doincr(cx) int cx; { /* INCREMENT, DECREMENT */
  1371. char vnambuf[VNAML+1]; /* Buffer for variable names */
  1372. int eval = 0;
  1373. CK_OFF_T x;
  1374. eval = (cx == XX_DECR || cx == XX_INCR);
  1375. if ((y = cmfld("Variable name","",&s, eval ? xxstring : NULL)) < 0) {
  1376. if (y == -3) {
  1377. printf("?Variable name required\n");
  1378. return(-9);
  1379. } else return(y);
  1380. }
  1381. ckstrncpy(vnambuf,s,VNAML);
  1382. if ((y = cmnumw("by amount","1",10,&x,xxstring)) < 0)
  1383. return(y);
  1384. if ((y = cmcfm()) < 0)
  1385. return(y);
  1386. z = (cx == XX_INCR || cx == XXINC) ? 1 : 0; /* Increment or decrement? */
  1387. if (incvar(vnambuf,x,z) < 0) {
  1388. printf("?Variable %s not defined or not numeric\n",vnambuf);
  1389. return(success = 0);
  1390. }
  1391. return(success = 1);
  1392. }
  1393. /* Used by doundef() */
  1394. static int
  1395. xxundef(s,verbose,simulate) char * s; int verbose, simulate; {
  1396. int rc = 0;
  1397. if (!s) return(0);
  1398. if (*s == CMDQ && *(s+1) == '%') {
  1399. char c = *(s+2), * p = NULL;
  1400. if (c >= '0' && c <= '9') {
  1401. if (maclvl < 0)
  1402. p = g_var[c];
  1403. else
  1404. p = m_arg[maclvl][c - '0'];
  1405. } else {
  1406. if (isupper(c)) c += ('a'-'A');
  1407. if (c >= 'a' && c <= 'z')
  1408. p = g_var[c];
  1409. }
  1410. if (!p) return(-1);
  1411. }
  1412. if (verbose)
  1413. printf(" %s ",s);
  1414. if (simulate) {
  1415. printf("(SELECTED)\n");
  1416. } else if ((x = delmac(s,1)) > -1) { /* Full name required */
  1417. rc = 1;
  1418. if (verbose) printf("(OK)\n");
  1419. } else if (verbose)
  1420. printf("(FAILED)\n");
  1421. return(rc);
  1422. }
  1423. /* Do the (_)DEFINE, (_)ASSIGN, and UNDEFINE commands */
  1424. #define UND_MAT 1
  1425. #define UND_VRB 2
  1426. #define UND_EXC 3
  1427. #define UND_SIM 3
  1428. static struct keytab undefswi[] = {
  1429. { "/list", UND_VRB, 0 },
  1430. #ifdef COMMENT
  1431. { "/except", UND_EXC, CM_ARG },
  1432. #endif /* COMMENT */
  1433. { "/matching", UND_MAT, 0 },
  1434. { "/simulate", UND_SIM, 0 },
  1435. { "/verbose", UND_VRB, CM_INV }
  1436. };
  1437. static int nundefswi = sizeof(undefswi) / sizeof(struct keytab);
  1438. #define UNDEFMAX 64
  1439. static char ** undeflist = NULL;
  1440. int
  1441. doundef(cx) int cx; { /* UNDEF, _UNDEF */
  1442. int i, j, n, rc = 0, arraymsg = 0;
  1443. int domatch = 0, verbose = 0, errors = 0, simulate = 0, flag = 0;
  1444. char *vnp, vnbuf[4];
  1445. #ifdef COMMENT
  1446. char *except = NULL;
  1447. #endif /* COMMENT */
  1448. struct FDB sw, fl;
  1449. int getval;
  1450. char c;
  1451. if (!undeflist) { /* Allocate list if necessary */
  1452. undeflist = (char **)malloc(UNDEFMAX * sizeof(char *));
  1453. if (!undeflist) {
  1454. printf("?Memory allocation failure\n");
  1455. return(-9);
  1456. }
  1457. for (i = 0; i < UNDEFMAX; i++)
  1458. undeflist[i] = NULL;
  1459. }
  1460. cmfdbi(&sw, /* First FDB - command switches */
  1461. _CMKEY, /* fcode */
  1462. "Variable name or switch",
  1463. "", /* default */
  1464. "", /* addtl string data */
  1465. nundefswi, /* addtl numeric data 1: tbl size */
  1466. 4, /* addtl numeric data 2: 4 = cmswi */
  1467. xxstring, /* Processing function */
  1468. undefswi, /* Keyword table */
  1469. &fl /* Pointer to next FDB */
  1470. );
  1471. cmfdbi(&fl, /* Anything that doesn't match */
  1472. _CMFLD, /* fcode */
  1473. "", /* hlpmsg */
  1474. "", /* default */
  1475. "", /* addtl string data */
  1476. 0, /* addtl numeric data 1 */
  1477. 0, /* addtl numeric data 2 */
  1478. (cx == XXUNDEF) ? NULL : xxstring,
  1479. NULL,
  1480. NULL
  1481. );
  1482. while (1) { /* Parse 0 or more switches */
  1483. x = cmfdb(&sw); /* Parse something */
  1484. if (x < 0)
  1485. return(x);
  1486. if (cmresult.fcode != _CMKEY) /* Break out if not a switch */
  1487. break;
  1488. c = cmgbrk();
  1489. if ((getval = (c == ':' || c == '=')) && !(cmgkwflgs() & CM_ARG)) {
  1490. printf("?This switch does not take an argument\n");
  1491. return(-9);
  1492. }
  1493. switch (cmresult.nresult) {
  1494. case UND_MAT: domatch = 1; break;
  1495. case UND_SIM: simulate = 1; /* fall thru on purpose */
  1496. case UND_VRB: verbose = 1; break;
  1497. #ifdef COMMENT
  1498. case UND_EXC:
  1499. if (!getval) break;
  1500. if ((x = cmfld("Pattern","",&s,xxstring)) < 0) {
  1501. if (x == -3) {
  1502. printf("?Pattern required\n");
  1503. x = -9;
  1504. }
  1505. goto xgetx;
  1506. }
  1507. makestr(&except,cmresult.sresult);
  1508. break;
  1509. #endif /* COMMENT */
  1510. default:
  1511. return(-2);
  1512. }
  1513. }
  1514. n = 0;
  1515. makestr(&(undeflist[n++]),cmresult.sresult);
  1516. for (i = 1; i < UNDEFMAX; i++) {
  1517. x = cmfld("Macro or variable name","",&s,
  1518. ((cx == XXUNDEF) ? NULL : xxstring)
  1519. );
  1520. if (x == -3) {
  1521. if ((y = cmcfm()) < 0)
  1522. return(y);
  1523. break;
  1524. } else if (y < 0) {
  1525. return(y);
  1526. }
  1527. makestr(&(undeflist[n++]),s);
  1528. }
  1529. /* Now we have a list of n variables or patterns to undefine */
  1530. for (i = 0; i < n; i++) {
  1531. flag = 0;
  1532. if (!(vnp = undeflist[i]))
  1533. continue;
  1534. if (vnp[0] == CMDQ && (vnp[1] == '%' || vnp[1] == '&')) {
  1535. flag++;
  1536. vnp++;
  1537. }
  1538. if (!domatch) { /* Pattern match not requested */
  1539. if (flag) {
  1540. if ((y = parsevar(vnp,&x,&z)) < 0) {
  1541. vnp--;
  1542. if (verbose) printf(" %s...error\n",vnp);
  1543. continue;
  1544. }
  1545. vnp--;
  1546. }
  1547. x = xxundef(vnp,verbose,simulate);
  1548. if (x > -1) {
  1549. if (!x && !simulate) errors++;
  1550. rc += x;
  1551. }
  1552. continue;
  1553. }
  1554. /* Pattern match requested */
  1555. if (!flag) { /* It's a macro */
  1556. for (j = 0; j < nmac; j++) {
  1557. if (ckmatch(vnp,mactab[j].kwd,0,1)) {
  1558. x = xxundef(mactab[j].kwd,verbose,simulate);
  1559. if (x > -1) {
  1560. rc += x;
  1561. if (!x) errors++;
  1562. }
  1563. if (!simulate)
  1564. j--; /* Because mactab shifted up */
  1565. }
  1566. }
  1567. } else if (vnp[0] == '%') { /* It's a \%x variable */
  1568. vnbuf[0] = CMDQ;
  1569. vnbuf[1] = '%';
  1570. vnbuf[3] = NUL;
  1571. for (j = '0'; j <= 'z'; j++) { /* 0..9 a..z */
  1572. vnbuf[2] = j;
  1573. if (ckmatch(vnp,&vnbuf[1],0,1)) {
  1574. x = xxundef(vnbuf,verbose,simulate);
  1575. if (x > -1) {
  1576. if (!x) errors++;
  1577. rc += x;
  1578. }
  1579. }
  1580. if (j == '9') j = (int)'a' - 1; /* 9 -> a */
  1581. }
  1582. } else if (vnp[0] == '&') {
  1583. if (!arraymsg && !quiet) {
  1584. printf("?UNDEFINE /MATCH can't be used with arrays.\n");
  1585. printf("(Type HELP ARRAY to see other methods.)\n");
  1586. }
  1587. arraymsg++;
  1588. errors++;
  1589. }
  1590. }
  1591. if (verbose)
  1592. printf("undefined: %d, errors: %d\n",rc,errors);
  1593. for (i = 0; i < UNDEFMAX; i++) { /* Check them all */
  1594. if (undeflist[i]) { /* in case we were interrupted */
  1595. free(undeflist[i]); /* previously... */
  1596. undeflist[i] = NULL;
  1597. }
  1598. }
  1599. return(success = (errors == 0) ? 1 : 0);
  1600. }
  1601. int
  1602. dodef(cx) int cx; {
  1603. extern int xxdot;
  1604. extern char ppvnambuf[];
  1605. int doeval = 0;
  1606. char vnambuf[VNAML+1]; /* Buffer for variable names */
  1607. char *vnp; /* Pointer to same */
  1608. int k, mydot;
  1609. mydot = xxdot; /* Copy */
  1610. xxdot = 0; /* and reset */
  1611. /*
  1612. In case we got here from a command that begins like ".\%a", cmkey() has
  1613. already evaluated \%a, but we don't want that, so we retrieve the variable
  1614. name from a special pre-evaluation buffer in the command module, and we
  1615. undo the "unget word" that would be done because of the token, because if
  1616. the variable was defined, it will unget its value rather than its name.
  1617. */
  1618. s = NULL;
  1619. if (mydot && ppvnambuf[0] == '.' && ppvnambuf[1]) {
  1620. s = ppvnambuf+1;
  1621. unungw();
  1622. }
  1623. if (!s) {
  1624. if (cx == XXDFX || cx == XXASX)
  1625. /* Evaluate variable name */
  1626. y = cmfld("Macro or variable name","",&s,xxstring);
  1627. else
  1628. /* Don't evaluate the variable name */
  1629. y = cmfld("Macro or variable name","",&s,NULL);
  1630. if (y < 0) {
  1631. if (y == -3) {
  1632. printf("?Variable name required\n");
  1633. return(-9);
  1634. } else return(y);
  1635. }
  1636. }
  1637. k = strlen(s);
  1638. if (k > VNAML) {
  1639. printf("?Name too long: \"%s\"\n",s);
  1640. return(-9);
  1641. }
  1642. ckstrncpy(vnambuf,s,VNAML);
  1643. vnambuf[VNAML] = NUL;
  1644. vnp = vnambuf;
  1645. if (vnambuf[0] == CMDQ && (vnambuf[1] == '%' || vnambuf[1] == '&')) vnp++;
  1646. if (*vnp == '%' || *vnp == '&') {
  1647. if ((y = parsevar(vnp,&x,&z)) < 0) return(y);
  1648. #ifdef COMMENT
  1649. if (cx == XXUNDEF) { /* Undefine */
  1650. if ((y = cmtxt("Text to be ignored","",&s,NULL)) < 0) return(y);
  1651. delmac(vnp,0);
  1652. return(success = 1);
  1653. }
  1654. #endif /* COMMENT */
  1655. debug(F101,"dodef parsevar x","",x);
  1656. if (mydot) {
  1657. if ((doeval = cmkey(asgtab,nasgtab,"operator","=",NULL)) < 0)
  1658. return(doeval);
  1659. if (doeval > 0) /* Type of assignment */
  1660. cx = XXASS;
  1661. }
  1662. if (y == 1) { /* Simple variable */
  1663. if ((y = cmtxt("Definition of variable","",&s,NULL)) < 0)
  1664. return(y);
  1665. s = brstrip(s);
  1666. debug(F110,"xxdef var name",vnp,0);
  1667. debug(F110,"xxdef var def",s,0);
  1668. } else if (y == 2) { /* Array element */
  1669. if ((y = arraynam(vnp,&x,&z)) < 0) return(y);
  1670. if (x == 96) {
  1671. printf("?Argument vector array is read-only\n");
  1672. return(-9);
  1673. }
  1674. if (chkarray(x,z) < 0) return(-2);
  1675. if ((y = cmtxt("Definition of array element","",&s,NULL)) < 0)
  1676. return(y);
  1677. debug(F110,"xxdef array ref",vnp,0);
  1678. debug(F110,"xxdef array def",s,0);
  1679. }
  1680. } else { /* Macro */
  1681. #ifdef COMMENT
  1682. if (cx == XXUNDEF) { /* Undefine */
  1683. if ((y = cmtxt("Text to be ignored","",&s,NULL)) < 0) return(y);
  1684. delmac(vnp,0);
  1685. return(success = 1);
  1686. }
  1687. #endif /* COMMENT */
  1688. if (mydot) {
  1689. if ((doeval = cmkey(asgtab,nasgtab,"operator","=",NULL)) < 0)
  1690. return(doeval);
  1691. if (doeval > 0)
  1692. cx = XXASS;
  1693. }
  1694. if ((y = cmtxt("Definition of macro","",&s,NULL)) < 0) return(y);
  1695. #ifdef DEBUG
  1696. if (deblog) {
  1697. debug(F110,"xxdef macro name",vnp,0);
  1698. debug(F010,"xxdef macro def",s,0);
  1699. }
  1700. #endif /* DEBUG */
  1701. s = brstrip(s);
  1702. }
  1703. if (*s == NUL) { /* No arg given, undefine */
  1704. delmac(vnp,1); /* silently... */
  1705. return(success = 1); /* even if it doesn't exist... */
  1706. }
  1707. /* Defining a new macro or variable */
  1708. if (cx == XXASS || cx == XXASX) { /* ASSIGN rather than DEFINE? */
  1709. int t;
  1710. t = LINBUFSIZ-1;
  1711. lp = line; /* If so, expand its value now */
  1712. zzstring(s,&lp,&t);
  1713. s = line;
  1714. }
  1715. if (doeval == 2) { /* Arithmetic evaluation wanted too? */
  1716. ckstrncpy(line,evala(s),LINBUFSIZ);
  1717. line[LINBUFSIZ] = NUL;
  1718. }
  1719. /* debug(F111,"calling addmac",s,(int)strlen(s)); */
  1720. y = addmac(vnp,s); /* Add it to the appropriate table. */
  1721. if (y < 0) {
  1722. printf("?%s failed\n",(cx == XXASS || cx == XXASX) ?
  1723. "ASSIGN" : "DEFINE");
  1724. return(success = 0);
  1725. } else if (cx == XXASX || cx == XXDFX) /* For _ASG or _DEF, */
  1726. return(1); /* don't change success variable */
  1727. else
  1728. return(success = 1);
  1729. }
  1730. #endif /* NOSPL */
  1731. #ifndef NODIAL
  1732. /*
  1733. L U D I A L -- Lookup up dialing directory entry.
  1734. Call with string to look up and file descriptor of open dialing directory
  1735. file. On success, returns number of matches found, with numbers stored
  1736. in an array accessible via getdnum().
  1737. */
  1738. static char *dn_p[MAXDNUMS + 1]; /* Dial Number pointers */
  1739. static char *dn_p2[MAXDNUMS + 1]; /* Converted dial number pointers */
  1740. static int dn_x[MAXDNUMS + 1]; /* Type of call */
  1741. static int dncount = 0;
  1742. char * d_name = NULL; /* Dial name pointer */
  1743. char * /* Get dial directory entry name */
  1744. getdname() {
  1745. return(d_name ? d_name : "");
  1746. }
  1747. char *
  1748. getdnum(n) int n; { /* Get dial number n from directory */
  1749. if (n < 0 || n > dncount || n > MAXDNUMS)
  1750. return("");
  1751. else
  1752. return(dn_p[n]);
  1753. }
  1754. char * /* Check area code for spurious leading digit */
  1755. chk_ac(i,buf) int i; char buf[]; {
  1756. char *p;
  1757. if (!buf)
  1758. return("");
  1759. p = (char *) buf; /* Country we are calling: */
  1760. if (i == 44 || /* UK */
  1761. i == 49 || /* Germany */
  1762. i == 39 || /* Italy */
  1763. i == 31 || /* Netherlands */
  1764. i == 351 || /* Portugal */
  1765. i == 55 || /* Brazil */
  1766. i == 972 || /* Israel */
  1767. i == 41 || /* Switzerland */
  1768. i == 43 || /* Austria */
  1769. i == 42 || /* Czech Republic */
  1770. i == 36 || /* Hungary */
  1771. i == 30 || /* Greece */
  1772. i == 352 || /* Luxembourg */
  1773. i == 48 || /* Poland */
  1774. i == 27 || /* South Africa */
  1775. i == 33 || /* France (as of 1997) */
  1776. i == 358 /* Finland (ditto) */
  1777. ) {
  1778. if (buf[0] == '0')
  1779. p++;
  1780. }
  1781. return(p);
  1782. }
  1783. /* Call Is Long Distance -- Expand this to cover 10-digit local dialing etc */
  1784. /*
  1785. src = area code of caller
  1786. dest = area code of callee
  1787. Returns:
  1788. 0 if call is local
  1789. 1 if call is long distance
  1790. 2 if call is local but area code must be dialed anyway
  1791. */
  1792. static int
  1793. callisld(src, dest) char * src, * dest; {
  1794. int i;
  1795. if (dialfld) /* Force long distance? */
  1796. return(1);
  1797. if (!strcmp(src,dest)) { /* Area codes are the same */
  1798. for (i = 0; i < nlocalac; i++) /* Is AC in the lc-area-codes list? */
  1799. if (!strcmp(src,diallcac[i]))
  1800. return(2); /* Yes so must be dialed */
  1801. return(0); /* No so don't dial it. */
  1802. }
  1803. for (i = 0; i < nlocalac; i++) /* ACs not the same so look in list */
  1804. if (!strcmp(dest,diallcac[i])) /* Match */
  1805. return(2); /* So local call with area code */
  1806. return(1); /* Not local so long-distance */
  1807. }
  1808. char pdsfx[64] = { NUL, NUL };
  1809. #ifndef NOSPL
  1810. static char *
  1811. xdial(s) char *s; { /* Run dial string thru macro */
  1812. int x, m;
  1813. char * s2;
  1814. s2 = NULL;
  1815. makestr(&s2,s); /* Copy the argument */
  1816. if (!dialmac) /* Dial macro name given? */
  1817. return(NULL);
  1818. if ((x = mxlook(mactab,dialmac,nmac)) < 0) /* Is the macro defined? */
  1819. return(NULL);
  1820. m = maclvl;
  1821. x = dodo(x,s2,0); /* Set up the macro */
  1822. if (s2) free(s2);
  1823. if (x > 0) {
  1824. while (maclvl > m) /* Execute the parser */
  1825. parser(1);
  1826. return(mrval[maclvl+1]); /* Return the result */
  1827. }
  1828. return(NULL);
  1829. }
  1830. #endif /* NOSPL */
  1831. static int
  1832. dncvt(k,cx, prefix, suffix)
  1833. int k, cx, prefix, suffix; { /* Dial Number Convert */
  1834. int i, j, n, what; /* cx is top-level command index */
  1835. char *ss; /* prefix - add prefixes? */
  1836. char *p, *p2, *pxo; /* suffix - add suffixes? */
  1837. char *lac;
  1838. char *npr;
  1839. char *sfx;
  1840. /* char *psfx; */
  1841. char ccbuf[128];
  1842. int cc;
  1843. char acbuf[24];
  1844. char *acptr;
  1845. char outbuf[256];
  1846. /*
  1847. First pass for strict (punctuation-based) interpretation.
  1848. If it fails, we try the looser (length-based) one.
  1849. */
  1850. dialtype = -1;
  1851. what = 0; /* Type of call */
  1852. s = dn_p[k]; /* Number to be converted. */
  1853. debug(F111,"dncvt",s,k);
  1854. if (dn_p2[k]) {
  1855. free(dn_p2[k]);
  1856. dn_p2[k] = NULL;
  1857. }
  1858. if (!s) {
  1859. printf("Error - No phone number to convert\n");
  1860. return(-1);
  1861. }
  1862. if ((int)strlen(s) > 200) {
  1863. ckstrncpy(outbuf,s,40);
  1864. printf("?Too long: \"%s...\"\n",outbuf);
  1865. return(-1);
  1866. }
  1867. npr = (prefix && dialnpr) ? dialnpr : "";
  1868. sfx = (suffix && dialsfx) ? dialsfx : "";
  1869. /* if (partial) psfx = dialsfx ? dialsfx : ""; */
  1870. pxo = (prefix && dialpxo) ? dialpxo : "";
  1871. lac = diallac ? diallac : ""; /* Local area code */
  1872. outbuf[0] = NUL; /* Initialize conversion buffer */
  1873. ss = s; /* Remember original string */
  1874. if (*s != '+') { /* Literal number */
  1875. dn_x[k] = DN_UNK; /* Sort key is "unknown". */
  1876. ckmakmsg(outbuf,256, /* Sandwich it between */
  1877. pxo,npr,s,sfx /* DIAL PREFIX and SUFFIX */
  1878. );
  1879. #ifdef CK_TAPI
  1880. if (tttapi && /* TAPI does its own conversions */
  1881. !tapipass && /* if not in passthru mode */
  1882. tapiconv == CK_AUTO || /* and TAPI conversions are AUTO */
  1883. tapiconv == CK_ON /* OR if TAPI conversions are ON */
  1884. ) {
  1885. char * p = NULL;
  1886. dialtype = -2;
  1887. if (!cktapiConvertPhoneNumber(dn_p[k], &p))
  1888. return(-1);
  1889. makestr(&dn_p2[k], p);
  1890. if (p) free(p);
  1891. return(0);
  1892. } else
  1893. #endif /* CK_TAPI */
  1894. makestr(&dn_p2[k], outbuf); /* Not TAPI */
  1895. dialtype = what;
  1896. return(0); /* Done. */
  1897. }
  1898. i = 0; /* Portable number */
  1899. s++; /* Tiptoe past the plus sign */
  1900. ccbuf[0] = NUL; /* Do country code first */
  1901. if (!diallcc) { /* Do we know our own? */
  1902. if (cx != XXLOOK)
  1903. printf("Error - prior SET DIAL COUNTRY-CODE command required\n");
  1904. return(-1);
  1905. }
  1906. /* Parse the number */
  1907. while (1) { /* Get the country code */
  1908. while (*s == HT || *s == SP)
  1909. s++;
  1910. if (!s) /* Not in standard format */
  1911. break;
  1912. if (*s == '(') { /* Beginning of area code */
  1913. s++; /* Skip past parenthesis */
  1914. ccbuf[i] = NUL; /* End of country code */
  1915. if (!s) { /* Check for end of string */
  1916. printf("Error - phone number ends prematurely: \"%s\"\n",ss);
  1917. return(-1);
  1918. }
  1919. break;
  1920. } else { /* Collect country code */
  1921. if (isdigit(*s))
  1922. ccbuf[i++] = *s; /* copy this character */
  1923. s++;
  1924. if (!*s || i > 127) /* watch out for memory leak */
  1925. break;
  1926. }
  1927. }
  1928. cc = atoi(ccbuf); /* Numeric version of country code */
  1929. i = 0; /* Now get area code */
  1930. acbuf[0] = NUL; /* Initialize area-code buffer */
  1931. acptr = acbuf; /* and pointer. */
  1932. while (1) {
  1933. while (*s == HT || *s == SP) /* Ignore whitespace */
  1934. s++;
  1935. if (!s) /* String finished */
  1936. break;
  1937. if (*s == ')') { /* End of area code */
  1938. s++; /* Skip past parenthesis */
  1939. acbuf[i] = NUL; /* Terminate area-code buffer */
  1940. break;
  1941. } else { /* Part of area code */
  1942. if (isdigit(*s)) /* If it's a digit, */
  1943. acbuf[i++] = *s; /* copy this character */
  1944. s++; /* Point to next */
  1945. if (!*s || i > 23) /* Watch out for overflow */
  1946. break;
  1947. }
  1948. }
  1949. /*
  1950. Here we strip any leading 0 for countries that we know have
  1951. 0 as a long-distance prefix and do not have any area codes that
  1952. start with 0 (formerly also ditto for "9" in Finland...)
  1953. */
  1954. i = atoi(ccbuf);
  1955. acptr = chk_ac(i,acbuf);
  1956. while (*s == HT || *s == SP) /* Skip whitespace */
  1957. s++;
  1958. /* printf("S=[%s], ACPTR=[%s]\n",s,acptr); */
  1959. if (*s && *acptr) { /* Area code was delimited */
  1960. while (*s == '-' || *s == '.') /* Skip past gratuitious punctuation */
  1961. s++;
  1962. if (!*s) s--; /* But not to end of string */
  1963. if (strcmp(diallcc,ccbuf)) { /* Out of country? */
  1964. if (!dialixp) { /* Need intl-prefix */
  1965. if (cx != XXLOOK)
  1966. printf("Error - No international dialing prefix defined\n");
  1967. return(-1);
  1968. }
  1969. what = dn_x[k] = DN_INTL;
  1970. p = (prefix && dialixp) ? dialixp : ""; /* Intl-prefix */
  1971. p2 = (suffix && dialixs) ? dialixs : ""; /* Intl-suffix */
  1972. /* Form the final phone number */
  1973. #ifdef COMMENT
  1974. sprintf(pdsfx,"%s%s",p2,sfx); /* UNSAFE */
  1975. sprintf(outbuf,
  1976. "%s%s%s%s%s%s%s%s",
  1977. pxo,npr,p,ccbuf,acptr,s,p2,sfx
  1978. );
  1979. #else
  1980. ckmakmsg(pdsfx,64,p2,sfx,NULL,NULL);
  1981. ckmakxmsg(outbuf,256,pxo,npr,p,ccbuf,acptr,s,p2,sfx,
  1982. NULL,NULL,NULL,NULL);
  1983. #endif /* COMMENT */
  1984. } else if ((x = callisld(lac,acptr)) >= 1) { /* In-country LD */
  1985. if (!diallac && cx != XXLOOK) { /* Don't know my own area code */
  1986. if (cc == 1)
  1987. printf("WARNING - Prior SET DIAL AREA-CODE needed\n");
  1988. }
  1989. if (x == 2) { /* Local call with area code */
  1990. what = dn_x[k] = DN_LOCAL; /* Local-call */
  1991. p = (prefix && diallcp) ? diallcp : ""; /* local-prefix */
  1992. p2 = (suffix && diallcs) ? diallcs : ""; /* local-suffix */
  1993. } else {
  1994. what = dn_x[k] = DN_LONG; /* Long-distance */
  1995. for (i = 0; i < ntollfree; i++) { /* But toll-free too? */
  1996. if (!strcmp(acptr,dialtfc[i])) {
  1997. what = dn_x[k] = DN_FREE;
  1998. break;
  1999. }
  2000. }
  2001. if (what == DN_FREE) { /* Toll-free call */
  2002. p = (prefix && dialtfp) ? dialtfp :
  2003. ((prefix && dialldp) ? dialldp : "");
  2004. p2 = ""; /* no suffix */
  2005. } else { /* normal long distance */
  2006. p = (prefix && dialldp) ? dialldp : ""; /* ld-prefix */
  2007. p2 = (suffix && diallds) ? diallds : ""; /* ld-suffix */
  2008. }
  2009. }
  2010. /* Form the number to be dialed */
  2011. #ifdef COMMENT
  2012. sprintf(outbuf,"%s%s%s%s%s%s%s",
  2013. pxo,npr,p,acptr,s,p2,sfx
  2014. );
  2015. sprintf(pdsfx,"%s%s",p2,sfx);
  2016. #else
  2017. ckmakxmsg(outbuf,256,
  2018. pxo,npr,p,acptr,s,p2,sfx,
  2019. NULL,NULL,NULL,NULL,NULL);
  2020. ckmakmsg(pdsfx,64,p2,sfx,NULL,NULL);
  2021. #endif /* COMMENT */
  2022. } else { /* Same country, same area code */
  2023. what = dn_x[k] = DN_LOCAL; /* So it's a local call. */
  2024. if (!prefix || !(dialpxo || ndialpxx)) { /* Not dialing from PBX */
  2025. p = (prefix && diallcp) ? diallcp : ""; /* local-prefix */
  2026. p2 = (suffix && diallcs) ? diallcs : ""; /* local-suffix */
  2027. #ifdef COMMENT
  2028. if (x == 2)
  2029. sprintf(outbuf,"%s%s%s%s%s%s",npr,p,acptr,s,p2,sfx);
  2030. else
  2031. sprintf(outbuf,"%s%s%s%s%s",npr,p,s,p2,sfx);
  2032. sprintf(pdsfx,"%s%s",p2,sfx);
  2033. #else
  2034. if (x == 2)
  2035. ckmakxmsg(outbuf,256,
  2036. npr,p,acptr,s,p2,sfx,
  2037. NULL,NULL,NULL,NULL,NULL,NULL);
  2038. else
  2039. ckmakxmsg(outbuf,256,
  2040. npr,p,s,p2,sfx,
  2041. NULL,NULL,NULL,NULL,NULL,NULL,NULL);
  2042. ckmakmsg(pdsfx,64,p2,sfx,NULL,NULL);
  2043. #endif /* COMMENT */
  2044. } else { /* Dialing from a PBX and not TAPI */
  2045. if (ndialpxx) { /* Is it internal? */
  2046. #ifdef COMMENT
  2047. i = (int) strlen(dialpxx);
  2048. j = (int) strlen(s);
  2049. x = -1;
  2050. if (j > i)
  2051. x = ckstrcmp(dialpxx,s,i,0);
  2052. #else
  2053. int kx;
  2054. x = -1;
  2055. j = (int) strlen(s);
  2056. for (kx = 0; kx < ndialpxx; kx++) {
  2057. i = (int) strlen(dialpxx[kx]);
  2058. if (j > i)
  2059. if (!(x = ckstrcmp(dialpxx[kx],s,i,0)))
  2060. break;
  2061. }
  2062. #endif /* COMMENT */
  2063. if (!x) {
  2064. char * icp, buf[32];
  2065. makestr(&matchpxx,dialpxx[kx]);
  2066. debug(F111,"dncvt matchpxx",matchpxx,kx);
  2067. what = dn_x[kx] = DN_INTERN; /* Internal call. */
  2068. s += i;
  2069. /* Internal-call prefix */
  2070. icp = dialpxi;
  2071. #ifndef NOSPL
  2072. if (icp) {
  2073. if (*icp == '\\') {
  2074. char c, *bp;
  2075. int n;
  2076. c = *(icp+1);
  2077. if (isupper(c)) c = tolower(c);
  2078. if (c == 'v' || c == 'f') {
  2079. n = 32;
  2080. bp = buf;
  2081. zzstring(icp,&bp,&n);
  2082. icp = buf;
  2083. }
  2084. }
  2085. }
  2086. #endif /* NOSPL */
  2087. p = (prefix && icp) ? icp : "";
  2088. #ifdef COMMENT
  2089. sprintf(outbuf,"%s%s%s%s",npr,p,s,sfx);
  2090. #else
  2091. ckmakmsg(outbuf,256,npr,p,s,sfx);
  2092. #endif /* COMMENT */
  2093. } else { /* External local call */
  2094. /* local-prefix */
  2095. p = (prefix && diallcp) ? diallcp : "";
  2096. /* local-suffix */
  2097. p2 = (prefix && diallcs) ? diallcs : "";
  2098. #ifdef COMMENT
  2099. if (x == 2)
  2100. sprintf(outbuf,"%s%s%s%s%s%s%s",
  2101. dialpxo ? dialpxo : "",
  2102. npr,p,acptr,s,p2,sfx);
  2103. else
  2104. sprintf(outbuf,
  2105. "%s%s%s%s%s%s",
  2106. dialpxo ? dialpxo : "",
  2107. npr,p,s,p2,sfx
  2108. );
  2109. #else
  2110. if (x == 2)
  2111. ckmakxmsg(outbuf, 256,
  2112. dialpxo ? dialpxo : "",
  2113. npr,p,acptr,s,p2,sfx,
  2114. NULL,NULL,NULL,NULL,NULL);
  2115. else
  2116. ckmakxmsg(outbuf, 256,
  2117. dialpxo ? dialpxo : "",
  2118. npr,p,s,p2,sfx,
  2119. NULL,NULL,NULL,NULL,NULL,NULL);
  2120. #endif /* COMMENT */
  2121. }
  2122. }
  2123. }
  2124. }
  2125. } else { /* Area code was not delimited */
  2126. char xbuf[256]; /* Comparison based only on length */
  2127. char ybuf[256];
  2128. int x, j;
  2129. s = ss;
  2130. for (i = 0; i < 255; i++) {
  2131. if (!*s) break;
  2132. while (!isdigit(*s)) { /* Pay attention only to digits */
  2133. s++;
  2134. if (!*s) break;
  2135. }
  2136. xbuf[i] = *s++;
  2137. }
  2138. xbuf[i] = NUL;
  2139. x = 1; /* Assume LD */
  2140. n = 0;
  2141. if (!dialfld) { /* If LD not forced */
  2142. for (j = 0; j < nlocalac; j++) { /* check local AC list? */
  2143. ckmakmsg(ybuf,256,diallcc,diallcac[j],NULL,NULL);
  2144. n = (int) strlen(ybuf);
  2145. if (n > 0 && !ckstrcmp(xbuf,ybuf,n,0)) {
  2146. x = 2;
  2147. break;
  2148. }
  2149. }
  2150. if (x == 1) { /* Or exact match with local CC+AC? */
  2151. ckmakmsg(ybuf,256,diallcc,lac,NULL,NULL);
  2152. n = (int) strlen(ybuf);
  2153. if (n > 0 && !ckstrcmp(xbuf,ybuf,n,0))
  2154. x = 0;
  2155. }
  2156. }
  2157. if (x == 0 || x == 2) { /* Local call */
  2158. int xx,kx; /* Begin 1 Dec 2001... */
  2159. /* Account for PBX internal calls */
  2160. if (ndialpxx) {
  2161. xx = -1;
  2162. j = (int) strlen(ybuf);
  2163. for (kx = 0; kx < ndialpxx; kx++) {
  2164. i = (int) strlen(dialpxx[kx]);
  2165. if (j >= i)
  2166. if (!(xx = ckstrcmp(dialpxx[kx],&xbuf[j],i,0)))
  2167. break;
  2168. }
  2169. }
  2170. if (!xx) {
  2171. char * icp, buf[32];
  2172. makestr(&matchpxx,dialpxx[kx]);
  2173. debug(F111,"dncvt matchpxx",matchpxx,kx);
  2174. what = dn_x[kx] = DN_INTERN; /* Internal call. */
  2175. s = xbuf + j + i;
  2176. icp = dialpxi; /* Internal-call prefix */
  2177. #ifndef NOSPL
  2178. if (icp) {
  2179. if (*icp == '\\') {
  2180. char c, *bp;
  2181. int n;
  2182. c = *(icp+1);
  2183. if (isupper(c)) c = tolower(c);
  2184. if (c == 'v' || c == 'f') {
  2185. n = 32;
  2186. bp = buf;
  2187. zzstring(icp,&bp,&n);
  2188. icp = buf;
  2189. }
  2190. }
  2191. }
  2192. #endif /* NOSPL */
  2193. p = (prefix && icp) ? icp : "";
  2194. ckmakmsg(outbuf,256,npr,p,s,sfx);
  2195. /* End 1 Dec 2001... */
  2196. } else { /* Not PBX internal */
  2197. dn_x[k] = DN_LOCAL;
  2198. p = (prefix && diallcp) ? diallcp : "";
  2199. p2 = (suffix && diallcs) ? diallcs : "";
  2200. s = (char *) (xbuf + ((x == 0) ? n : (int)strlen(diallcc)));
  2201. ckmakxmsg(outbuf,256,
  2202. pxo,npr,p,s,p2,sfx,
  2203. NULL,NULL,NULL,NULL,NULL,NULL);
  2204. ckmakmsg(pdsfx,64,p2,sfx,NULL,NULL);
  2205. }
  2206. } else { /* Not local */
  2207. n = ckstrncpy(ybuf,diallcc,256);
  2208. if (n > 0 && !ckstrcmp(xbuf,ybuf,n,0)) { /* Long distance */
  2209. dn_x[k] = DN_LONG;
  2210. p = (prefix && dialldp) ? dialldp : "";
  2211. p2 = (suffix && diallds) ? diallds : "";
  2212. s = xbuf + n;
  2213. while (*s == '-' || *s == '.')
  2214. s++;
  2215. #ifdef COMMENT
  2216. sprintf(outbuf,"%s%s%s%s%s%s",pxo,npr,p,s,p2,sfx);
  2217. sprintf(pdsfx,"%s%s",p2,sfx);
  2218. #else
  2219. ckmakxmsg(outbuf,256,
  2220. pxo,npr,p,s,p2,sfx,
  2221. NULL,NULL,NULL,NULL,NULL,NULL);
  2222. ckmakmsg(pdsfx,64,p2,sfx,NULL,NULL);
  2223. #endif /* COMMENT */
  2224. } else {
  2225. dn_x[k] = DN_INTL; /* International */
  2226. if (!dialixp) {
  2227. if (cx != XXLOOK) {
  2228. printf(
  2229. "Error - No international dialing prefix defined\n"
  2230. );
  2231. return(-1);
  2232. }
  2233. }
  2234. p = (prefix && dialixp) ? dialixp : "";
  2235. p2 = (suffix && dialixs) ? dialixs : "";
  2236. #ifdef COMMENT
  2237. sprintf(outbuf,"%s%s%s%s%s%s",pxo,npr,p,xbuf,p2,sfx);
  2238. sprintf(pdsfx,"%s%s",p2,sfx);
  2239. #else
  2240. ckmakxmsg(outbuf,256,
  2241. pxo,npr,p,xbuf,p2,sfx,
  2242. NULL,NULL,NULL,NULL,NULL,NULL);
  2243. ckmakmsg(pdsfx,64,p2,sfx,NULL,NULL);
  2244. #endif /* COMMENT */
  2245. }
  2246. }
  2247. }
  2248. #ifdef CK_TAPI
  2249. if (tttapi && /* TAPI performs the conversions */
  2250. !tapipass &&
  2251. tapiconv == CK_AUTO ||
  2252. tapiconv == CK_ON
  2253. ) {
  2254. p = NULL;
  2255. dialtype = -2;
  2256. if (!cktapiConvertPhoneNumber(dn_p[k],&p))
  2257. return(-1);
  2258. makestr(&dn_p2[k], p);
  2259. if (p) free(p);
  2260. return(0);
  2261. } else {
  2262. #endif /* CK_TAPI */
  2263. makestr(&dn_p2[k], outbuf);
  2264. #ifdef CK_TAPI
  2265. }
  2266. #endif /* CK_TAPI */
  2267. dialtype = what;
  2268. return(0);
  2269. }
  2270. static int
  2271. ddcvt(s, f, n) char * s; FILE * f; int n; { /* Dial Directory Convert */
  2272. char linebuf[1024], *s2; /* Buffers and pointers */
  2273. #ifdef VMS
  2274. char * temp = NULL;
  2275. #endif /* VMS */
  2276. char *info[8]; /* Pointers to words from entry */
  2277. FILE * f2 = NULL;
  2278. int x, rc;
  2279. rc = -1;
  2280. debug(F110,"ddcvt file",s,0);
  2281. if (!s || !f) /* No filename or file */
  2282. return(-1);
  2283. if (!*s)
  2284. fclose(f);
  2285. znewn(s,&s2); /* s2 = address of static buffer */
  2286. debug(F110,"ddcvt newname",s2,0);
  2287. #ifdef VMS
  2288. /* In VMS, znewn() returns the same file name with a new version number */
  2289. makestr(&temp,s); /* Swap - otherwise the new */
  2290. s = s2; /* version has the older version */
  2291. s2 = temp; /* number... */
  2292. debug(F110,"ddcvt after swap s",s,0);
  2293. debug(F110,"ddcvt after swap s2",s2,0);
  2294. makestr(&(dialdir[n]),s); /* New file gets new version number */
  2295. debug(F110,"ddcvt after makestr s2",s2,0);
  2296. debug(F111,"ddcvt dialdir[n]",dialdir[n],n);
  2297. #else
  2298. if (zrename(s,s2) < 0) { /* Not VMS - rename old file */
  2299. perror(s2); /* to new (wierd) name. */
  2300. goto ddexit;
  2301. }
  2302. #endif /* VMS */
  2303. debug(F110,"ddcvt s2 (old)",s2,0);
  2304. if ((f = fopen(s2,"r")) == NULL) { /* Reopen old file with wierd name */
  2305. debug(F110,"ddcvt s2 open error",ck_errstr(),0);
  2306. dirline = 0; /* (or in VMS, old version) */
  2307. perror(s2);
  2308. goto ddexit;
  2309. }
  2310. debug(F110,"ddcvt fopen(s2) OK",s2,0);
  2311. debug(F110,"ddcvt s (new)",s,0);
  2312. if ((f2 = fopen(s,"w")) == NULL) { /* Create new file with old name */
  2313. debug(F110,"ddcvt s open error",ck_errstr(),0);
  2314. perror(s); /* (or in VMS, new version) */
  2315. goto ddexit;
  2316. }
  2317. debug(F110,"ddcvt fopen(s) OK",s,0);
  2318. printf("\nSaving old directory as %s.\nConverting %s...",s2,s);
  2319. fprintf(f2,"; %s - Kermit dialing directory\n", s);
  2320. fprintf(f2,"%-16s %-20s ; %5s %-6s ; %s\n",
  2321. "; Name","Number","Speed","Parity","Comment"
  2322. );
  2323. while (1) {
  2324. linebuf[0] = NUL; /* Read a line */
  2325. if (fgets(linebuf,1023,f) == NULL)
  2326. break;
  2327. debug(F110,"ddcvt linebuf",linebuf,0);
  2328. if (!linebuf[0]) { /* Empty line */
  2329. fprintf(f2,"\n");
  2330. continue;
  2331. }
  2332. x = (int) strlen(linebuf); /* Strip line terminator, */
  2333. while (x-- > 0) { /* if any. */
  2334. if (linebuf[x] <= SP)
  2335. linebuf[x] = NUL;
  2336. else
  2337. break;
  2338. }
  2339. xwords(linebuf,5,info,1); /* Parse it the old way */
  2340. for (x = 1; x < 6; x++)
  2341. if (!info[x]) info[x] = "";
  2342. fprintf(f2,"%-16s %-20s ; %5s %-6s %s\n",
  2343. info[1],info[2],info[3],info[4],info[5]
  2344. );
  2345. }
  2346. printf(" OK\n\n");
  2347. rc = 0; /* Success */
  2348. ddexit:
  2349. if (f) fclose(f);
  2350. if (f2) fclose(f2);
  2351. #ifdef VMS
  2352. if (temp) free(temp);
  2353. #endif /* VMS */
  2354. return(rc);
  2355. }
  2356. int /* s = name to look up */
  2357. #ifdef CK_ANSIC /* cx = index of command */
  2358. ludial(char *s, int cx) /* (DIAL, LOOKUP, etc) */
  2359. #else
  2360. ludial(s, cx) char *s; int cx;
  2361. #endif /* CK_ANSIC */
  2362. /* ludial */ {
  2363. int dd, n1, n2, n3, i, j, t; /* Workers */
  2364. int olddir, newdir, oldentry, newentry;
  2365. int pass = 0;
  2366. int oldflg = 0;
  2367. int ambiguous = 0; /* Flag for lookup was ambiguous */
  2368. char *info[7]; /* Pointers to words from entry */
  2369. char *pp; /* Pointer to element of array */
  2370. FILE * f;
  2371. char *line; /* File input buffer */
  2372. /* #define LUDEBUG */
  2373. #ifdef LUDEBUG
  2374. int zz = 1;
  2375. #endif /* LUDEBUG */
  2376. if (!s || ndialdir < 1) /* Validate arguments */
  2377. return(-1);
  2378. if ((n1 = (int) strlen(s)) < 1) /* Length of string to look up */
  2379. return(-1);
  2380. if (!(line = malloc(1024))) /* Allocate input buffer */
  2381. return(-1);
  2382. #ifdef LUDEBUG
  2383. if (zz) printf("LUDIAL 1 s[%s], n1=%d\n",s,n1);
  2384. #endif /* LUDEBUG */
  2385. pass = 0;
  2386. lu_again:
  2387. f = NULL; /* Dial directory file descriptor */
  2388. t = dncount = 0; /* Dial-number match count */
  2389. dd = 0; /* Directory counter */
  2390. olddir = 0;
  2391. newdir = 0;
  2392. /*
  2393. We need to recognize both old- and new-style directories.
  2394. But we can't allow old-style and new-style entries in the same
  2395. directory because there is no way to tell for sure the difference between
  2396. an old-style entry like this:
  2397. foo 5551212 9600
  2398. and a new-style literal entry like this:
  2399. foo 555 9600
  2400. I.e. is the "9600" a speed, or part of the phone number?
  2401. */
  2402. while (1) { /* We make one pass */
  2403. if (!f) { /* Directory not open */
  2404. if (dd >= ndialdir) /* No directories left? */
  2405. break; /* Done. */
  2406. debug(F111,"ludial dialdir[dd]",dialdir[dd],dd);
  2407. if ((f = fopen(dialdir[dd],"r")) == NULL) { /* Open it */
  2408. perror(dialdir[dd]); /* Can't, print message saying why */
  2409. if (line) {
  2410. free(line);
  2411. line = NULL;
  2412. }
  2413. dd++; /* Go on to next one, if any... */
  2414. continue;
  2415. }
  2416. dirline = 0; /* Directory file line number */
  2417. if (dialdpy && !pass)
  2418. printf("Opening: %s...\n",dialdir[dd]);
  2419. dd++;
  2420. if (!oldflg) olddir = 0;
  2421. newdir = 0;
  2422. }
  2423. oldentry = 0;
  2424. newentry = 0;
  2425. line[0] = NUL;
  2426. if (getnct(line,1023,f,1) < 0) { /* Read a line */
  2427. if (f) { /* f can be clobbered! */
  2428. fclose(f); /* Close the file */
  2429. f = NULL; /* Indicate next one needs opening */
  2430. oldflg = 0;
  2431. }
  2432. continue;
  2433. }
  2434. if (!line[0]) /* Empty line */
  2435. continue;
  2436. #ifdef LUDEBUG
  2437. if (zz) printf("LUDIAL 2 s[%s]\n",s);
  2438. #endif /* LUDEBUG */
  2439. /* Make a copy and parse it the old way */
  2440. /* A copy is needed because xwords() pokes NULs into the string */
  2441. if ((pp = malloc((int)strlen(line) + 1))) {
  2442. strcpy(pp,line); /* safe */
  2443. xwords(pp,5,info,0); /* Parse it the old way */
  2444. #ifdef LUDEBUG
  2445. if (zz) printf("LUDIAL 3 s[%s]\n",s);
  2446. #endif /* LUDEBUG */
  2447. if (!info[1])
  2448. continue;
  2449. if (*info[1] == ';') { /* If full-line comment, */
  2450. newdir = 1; /* (only new directories have them) */
  2451. continue; /* keep reading. */
  2452. }
  2453. if (!info[2])
  2454. continue;
  2455. if (*info[2] == '+')
  2456. newentry = 1;
  2457. if (info[4]) {
  2458. if ((*info[4] == '=') ||
  2459. !ckstrcmp(info[4],"none", 4,0) ||
  2460. !ckstrcmp(info[4],"even", 4,0) ||
  2461. !ckstrcmp(info[4],"space",5,0) ||
  2462. !ckstrcmp(info[4],"mark", 4,0) ||
  2463. !ckstrcmp(info[4],"odd", 3,0)
  2464. )
  2465. oldentry = 1;
  2466. }
  2467. }
  2468. if (pp) {
  2469. free(pp);
  2470. pp = NULL;
  2471. }
  2472. /* Check consistency */
  2473. if ((oldentry || olddir) && (newentry || newdir)) {
  2474. printf(
  2475. "\nERROR: You seem to have old- and new-format entries mixed in your\n");
  2476. printf(
  2477. "dialing directory. You'll have to edit it by hand to convert it to the\n");
  2478. #ifndef NOHELP
  2479. printf("new format. Type HELP DIAL for further information.\n\n");
  2480. #else
  2481. printf("new format.\n\n");
  2482. #endif /* NOHELP */
  2483. if (line) {
  2484. free(line);
  2485. line = NULL;
  2486. }
  2487. return(-1);
  2488. }
  2489. if (!olddir && oldentry) {
  2490. int convert = 0;
  2491. olddir = 1;
  2492. if (dialcvt == 2) { /* 2 == ASK */
  2493. sprintf(tmpbuf,
  2494. "WARNING: Old-style dialing directory detected:\n%s", line);
  2495. convert = uq_ok(tmpbuf,
  2496. "Shall I convert it for you? ",3,NULL,0);
  2497. } else
  2498. convert = dialcvt;
  2499. if (convert) {
  2500. debug(F111,"ludial calling ddcvt",dialdir[dd-1],dd);
  2501. if (ddcvt(dialdir[dd-1],f,dd-1) < 0) {
  2502. debug(F111,"ludial ddcvt failed",dialdir[dd-1],dd);
  2503. oldflg = 1;
  2504. printf(
  2505. " Sorry, can't convert.");
  2506. printf(
  2507. " Will ignore speed and parity fields, continuing...\n\n");
  2508. } else {
  2509. olddir = newdir = 0;
  2510. debug(F111,"ludial ddcvt ok",dialdir[dd-1],dd);
  2511. }
  2512. dd--;
  2513. f = NULL;
  2514. continue;
  2515. } else {
  2516. if (dialcvt == 2)
  2517. printf(
  2518. " OK, will ignore speed and parity fields, continuing...\n\n");
  2519. olddir = 1;
  2520. }
  2521. }
  2522. #ifdef LUDEBUG
  2523. if (zz) printf("LUDIAL XX s[%s], n1=%d\n",s,n1);
  2524. #endif /* LUDEBUG */
  2525. /* Now parse again for real */
  2526. if (oldentry) /* Parse it the old way */
  2527. xwords(line,5,info,0);
  2528. else /* Parse it the new way */
  2529. xwords(line,2,info,1);
  2530. #ifdef LUDEBUG
  2531. if (zz) printf("LUDIAL YY s[%s], n1=%d\n",s,n1);
  2532. if (zz) printf("%s [%s]\n",info[1],info[2]);
  2533. #endif /* LUDEBUG */
  2534. if (info[1]) { /* First word is entry name */
  2535. if ((n3 = (int) strlen(info[1])) < 1) /* Its length */
  2536. continue; /* If no first word, keep reading. */
  2537. if (n3 < n1) /* Search name is longer */
  2538. continue; /* Can't possibly match */
  2539. if (ambiguous && n3 != n1)
  2540. continue;
  2541. #ifdef LUDEBUG
  2542. if (zz) printf("MATCHING: [%s] [%s], n1=%d\n",s,info[1],n1);
  2543. #endif /* LUDEBUG */
  2544. if (ckstrcmp(s,info[1],n1,0)) /* Caseless string comparison */
  2545. continue;
  2546. #ifdef LUDEBUG
  2547. if (zz) printf("MATCH OK: [%s] [%s], n1=%d\n",s,info[1],n1);
  2548. #endif /* LUDEBUG */
  2549. if (!info[2]) /* No phone number given */
  2550. continue;
  2551. if ((n2 = (int) strlen(info[2])) < 1) /* Length of phone number */
  2552. continue; /* Ignore empty phone numbers */
  2553. /* Got one */
  2554. if (!(pp = (char *)malloc(n2 + 1))) { /* Allocate storage for it */
  2555. printf("?internal error - ludial malloc 1\n");
  2556. if (line) {
  2557. free(line);
  2558. line = NULL;
  2559. }
  2560. dncount = 0;
  2561. return(-1);
  2562. }
  2563. strcpy(pp,info[2]); /* safe */
  2564. if (dncount > MAXDNUMS) {
  2565. printf("Warning: %d matches found, %d max\n",
  2566. dncount,
  2567. MAXDNUMS
  2568. );
  2569. dncount = MAXDNUMS;
  2570. break;
  2571. }
  2572. dn_p[dncount++] = pp; /* Add pointer to array. */
  2573. if (dncount == 1) { /* First one... */
  2574. if (d_name) free(d_name);
  2575. if (!(d_name = (char *)malloc(n3 + 1))) { /* Save its name */
  2576. printf("?internal error - ludial malloc 2\n");
  2577. if (line) {
  2578. free(line);
  2579. line = NULL;
  2580. }
  2581. dncount = 0;
  2582. return(-1);
  2583. }
  2584. t = n3; /* And its length */
  2585. strcpy(d_name,info[1]); /* safe */
  2586. } else { /* Second or subsequent one */
  2587. #ifdef LUDEBUG
  2588. if (zz)
  2589. printf("d_name=[%s],info[1]=%s,t=[%d]\n",d_name,info[1],t);
  2590. #endif /* LUDEBUG */
  2591. if ((int) strlen(info[1]) == t) /* Lengths compare */
  2592. if (!ckstrcmp(d_name,info[1],t,0)) /* Caseless compare OK */
  2593. continue;
  2594. /* Name given by user matches entries with different names */
  2595. if (ambiguous) /* Been here before */
  2596. break;
  2597. ambiguous = 1; /* Now an exact match is required */
  2598. for (j = 0; j < dncount; j++) { /* Clean out previous list */
  2599. if (dn_p[j]) {
  2600. free(dn_p[j]);
  2601. dn_p[j] = NULL;
  2602. }
  2603. }
  2604. pass++; /* Second pass... */
  2605. goto lu_again; /* Do it all over again. */
  2606. }
  2607. }
  2608. }
  2609. if (line) free(line);
  2610. if (dncount == 0 && ambiguous) {
  2611. printf(" Lookup: \"%s\" - ambiguous%s\n",
  2612. s,
  2613. cx == XXLOOK ? "" : " - dialing skipped"
  2614. );
  2615. return(-2);
  2616. }
  2617. return(dncount);
  2618. }
  2619. char *
  2620. pncvt(s) char *s; { /* Phone number conversion */
  2621. char *p = NULL; /* (just a wrapper for dncvt() */
  2622. char *q = NULL;
  2623. static char pnbuf[128];
  2624. makestr(&p,dn_p[0]); /* Save these in case they are */
  2625. makestr(&q,dn_p2[0]); /* being used */
  2626. makestr(&dn_p[0],s); /* Copy the argument string to here */
  2627. dncvt(0,XXLOOK,1,1); /* Convert it */
  2628. if (!dn_p2[0]) /* Put result where can return it */
  2629. pnbuf[0] = NUL;
  2630. else
  2631. ckstrncpy(pnbuf,dn_p2[0],127);
  2632. makestr(&dn_p[0],p); /* Restore these */
  2633. makestr(&dn_p2[0],q);
  2634. makestr(&p,NULL); /* Free these */
  2635. makestr(&q,NULL);
  2636. return((char *)pnbuf);
  2637. }
  2638. int
  2639. dodial(cx) int cx; { /* DIAL or REDIAL */
  2640. int i = 0, x = 0; /* Workers */
  2641. int sparity = -1; /* For saving global parity value */
  2642. int previous = 0;
  2643. int len = 0;
  2644. int literal = 0;
  2645. int flowsave;
  2646. int lufound = 0; /* Did any lookup succeed? */
  2647. int prefix = 1;
  2648. int postfix = 1;
  2649. int wasalpha = 0;
  2650. int xredial = 0;
  2651. int braces = 0;
  2652. char *p = NULL, *s3 = NULL, * sav = NULL;
  2653. int j = 0, t = 0, n = 0;
  2654. int xretries, xlcc;
  2655. #ifdef COMMENT
  2656. debug(F101,"dodial cx","",cx);
  2657. debug(F111,"dodial diallcc",diallcc,diallcc);
  2658. #endif /* COMMENT */
  2659. xretries = dialrtr; /* If retries not set, */
  2660. if (diallcc) { /* choose default based on */
  2661. xlcc = atoi(diallcc); /* local country code. */
  2662. if (xretries < 0) {
  2663. switch (xlcc) {
  2664. case 1: xretries = 10; break; /* No restrictions in NANP */
  2665. /* Add other country codes here */
  2666. /* that are known to have no restrictions on redialing. */
  2667. default: xretries = 1;
  2668. }
  2669. }
  2670. }
  2671. if (cx == XXPDIA) { /* Shortcut... */
  2672. cx = XXDIAL;
  2673. partial = 1;
  2674. debug(F100,"PDIAL sets partial=1","",0);
  2675. postfix = 0; /* Do not add postfix */
  2676. } else {
  2677. partial = 0;
  2678. debug(F100,"DIAL sets partial=0","",0);
  2679. }
  2680. previous = dialsta; /* Status of previous call, if any */
  2681. if (previous == DIA_PART) {
  2682. prefix = 0; /* do not add prefix */
  2683. }
  2684. s = NULL; /* Initialize user's dial string */
  2685. if (cx == XXRED) { /* REDIAL or... */
  2686. if ((y = cmcfm()) < 0)
  2687. return(y);
  2688. } else if (cx == XXANSW) { /* ANSWER or ... */
  2689. if ((y = cmnum("timeout (seconds)","0",10,&x,xxstring)) < 0)
  2690. return(y);
  2691. dialatmo = x;
  2692. if ((y = cmcfm()) < 0)
  2693. return(y);
  2694. } else { /* DIAL or LOOKUP */
  2695. if (ndialdir > 0)
  2696. s3 = "Number to dial or entry from dial directory";
  2697. else
  2698. s3 = "Number to dial";
  2699. if ((x = cmtxt(s3, dialnum ? dialnum : "",&s,xxstring)) < 0)
  2700. return(x);
  2701. if (s) {
  2702. len = (int) strlen(s);
  2703. ckstrncpy(tmpbuf,s,TMPBUFSIZ); /* Save literal copy */
  2704. #ifdef COMMENT
  2705. if (len > 1) { /* Strip outer braces if given */
  2706. if (*s == '{') {
  2707. if (s[len-1] == '}') {
  2708. s[len-1] = NUL;
  2709. s++;
  2710. len -= 2;
  2711. }
  2712. }
  2713. }
  2714. #else
  2715. s = brstrip(s); /* Strip outer braces or quotes */
  2716. #endif /* COMMENT */
  2717. }
  2718. }
  2719. if (cx != XXLOOK) { /* Not LOOKUP */
  2720. #ifdef IKSD
  2721. if (inserver) {
  2722. printf("Sorry, dialing is disabled.\r\n");
  2723. return(success = 0);
  2724. }
  2725. #endif /* IKSD */
  2726. #ifdef CK_TAPI
  2727. if (tttapi && !tapipass) {
  2728. ; /* Skip the modem test if TAPI */
  2729. } else
  2730. #endif /* CK_TAPI */
  2731. if (mdmtyp < 1 && !dialtest) {
  2732. if (network
  2733. #ifdef TN_COMPORT
  2734. && !istncomport()
  2735. #endif /* TN_COMPORT */
  2736. )
  2737. printf("Please SET HOST first, and then SET MODEM TYPE\n");
  2738. else
  2739. printf("Sorry, you must SET MODEM TYPE first\n");
  2740. dialsta = DIA_NOMO;
  2741. return(success = 0);
  2742. }
  2743. if (!local && !dialtest) {
  2744. printf("Sorry, you must SET %s or SET HOST first\n",
  2745. #ifdef OS2
  2746. "PORT"
  2747. #else
  2748. "LINE"
  2749. #endif /* OS2 */
  2750. );
  2751. dialsta = DIA_NOLI;
  2752. return(success = 0);
  2753. }
  2754. if ((!network
  2755. #ifdef TN_COMPORT
  2756. || istncomport()
  2757. #endif /* TN_COMPORT */
  2758. ) && !dialtest &&
  2759. #ifdef CK_TAPI
  2760. !tttapi &&
  2761. #endif /* CK_TAPI */
  2762. (speed < 0L)
  2763. #ifdef UNIX
  2764. && (strcmp(ttname,"/dev/null"))
  2765. #else
  2766. #ifdef OSK
  2767. && (strcmp(ttname,"/nil"))
  2768. #endif /* OSK */
  2769. #endif /* UNIX */
  2770. ) {
  2771. printf("\nSorry, you must SET SPEED first\n");
  2772. dialsta = DIA_NOSP;
  2773. return(success = 0);
  2774. }
  2775. }
  2776. if (cx != XXANSW) {
  2777. for (j = 0; j < MAXDNUMS; j++) { /* Initialize dial-number list */
  2778. if (!dialnum) { /* First time dialing */
  2779. dn_p[j] = NULL; /* initialize all pointers. */
  2780. dn_p2[j] = NULL;
  2781. } else if (dn_p[j]) { /* Not the first time, */
  2782. free(dn_p[j]); /* free previous, if any, */
  2783. dn_p[j] = NULL; /* then set to NULL. */
  2784. if (dn_p2[j])
  2785. free(dn_p2[j]);
  2786. dn_p2[j] = NULL;
  2787. } else break; /* Already NULL */
  2788. }
  2789. if (len == 0)
  2790. s = NULL;
  2791. if (!s)
  2792. s = dialnum;
  2793. if (!s) {
  2794. if (cx == XXLOOK)
  2795. printf("?Lookup what?\n");
  2796. else
  2797. printf("%s\n", (cx == XXRED) ?
  2798. "?No DIAL command given yet" :
  2799. "?You must specify a number to dial"
  2800. );
  2801. return(-9);
  2802. }
  2803. /* Now we have the "raw" dial or lookup string and s is not NULL */
  2804. makestr(&dscopy,s); /* Put it in a safe place */
  2805. s = dscopy;
  2806. n = 0;
  2807. debug(F111,"dodial",s,ndialdir);
  2808. wasalpha = 0;
  2809. if (isalpha(*s)) {
  2810. wasalpha = 1;
  2811. if (ndialdir > 0) { /* Do we have a dialing directory? */
  2812. n = ludial(s,cx); /* Look up what the user typed */
  2813. if (n == 0)
  2814. printf(" Lookup: \"%s\" - not found%s\n",
  2815. s,
  2816. cx == XXLOOK ? "" : " - dialing as given\n"
  2817. );
  2818. }
  2819. debug(F101,"dodial",s,n);
  2820. if (n < 0 && cx != XXLOOK) { /* Error out if they wanted to dial */
  2821. if (n == -1) /* -2 means ludial already gave msg */
  2822. printf(" Lookup: fatal error - dialing skipped\n");
  2823. dialsta = DIA_DIR;
  2824. return(-9);
  2825. }
  2826. if (n > 0) /* A successful lookup */
  2827. lufound = 1;
  2828. } else if (*s == '=') { /* If number starts with = sign */
  2829. s++; /* strip it */
  2830. literal = 1; /* remember this */
  2831. while (*s == SP) s++; /* and then also any leading spaces */
  2832. } else if (tmpbuf[0] == '{' && tmpbuf[1] == '{') {
  2833. makelist(tmpbuf,dn_p,MAXDNUMS);
  2834. makestr(&dscopy,tmpbuf);
  2835. s = tmpbuf;
  2836. for (n = 0; n < MAXDNUMS; n++) /* (have to count how many) */
  2837. if (!dn_p[n]) break;
  2838. braces = 1;
  2839. }
  2840. if (cx == XXLOOK && !wasalpha && !braces) {
  2841. /* We've been told to lookup a number or a quoted name */
  2842. char *p;
  2843. n = 0;
  2844. p = literal ? s : pncvt(dscopy);
  2845. if (!p) p = "";
  2846. if (*p) {
  2847. printf("%s => %s\n", dscopy, p);
  2848. return(success = 1);
  2849. } else {
  2850. printf("?Bad phone number\n");
  2851. return(success = 0);
  2852. }
  2853. }
  2854. /* Save DIAL or successful LOOKUP string for future DIAL or REDIAL */
  2855. /* But don't save pieces of partial dial ... */
  2856. debug(F101,"DIAL save dialnum partial","",partial);
  2857. debug(F101,"DIAL save dialnum previous","",previous);
  2858. if ((cx == XXDIAL && partial == 0 && previous != DIA_PART) ||
  2859. (cx == XXLOOK && n > 0)) {
  2860. makestr(&dialnum,dscopy);
  2861. if (!quiet && dscopy && !dialnum)
  2862. printf("WARNING - memory allocation failure: redial number\n");
  2863. }
  2864. if (n > 0) {
  2865. if (!quiet && !backgrd && !braces /* && dialdpy */ ) {
  2866. if (!strcmp(d_name,s))
  2867. printf(" Lookup: \"%s\" - exact match\n",s);
  2868. else
  2869. printf(" Lookup: \"%s\" - uniquely matches \"%s\"\n",
  2870. s,
  2871. d_name
  2872. );
  2873. }
  2874. if ((cx == XXLOOK) ||
  2875. ((n > 1) && !quiet && !backgrd /* && dialdpy */ )) {
  2876. printf(" %d telephone number%sfound for \"%s\"%s\n",
  2877. n,
  2878. (n == 1) ? " " : "s ",
  2879. s,
  2880. (n > 0) ? ":" : "."
  2881. );
  2882. s3 = getdname();
  2883. }
  2884. for (i = 0; i < n; i++) { /* Convert */
  2885. dn_x[i] = -1;
  2886. if (dncvt(i,cx,prefix,postfix) < 0) {
  2887. if (cx != XXLOOK) {
  2888. dialsta = DIA_DIR;
  2889. return(-9);
  2890. }
  2891. }
  2892. }
  2893. if (dialsrt && n > 1) { /* Sort into optimal order */
  2894. for (i = 0; i < n-1; i++) {
  2895. for (j = i+1; j < n; j++) {
  2896. if (dn_x[j] < dn_x[i]) {
  2897. t = dn_x[j];
  2898. dn_x[j] = dn_x[i];
  2899. dn_x[i] = t;
  2900. p = dn_p[j];
  2901. dn_p[j] = dn_p[i];
  2902. dn_p[i] = p;
  2903. p = dn_p2[j];
  2904. dn_p2[j] = dn_p2[i];
  2905. dn_p2[i] = p;
  2906. }
  2907. }
  2908. }
  2909. }
  2910. if ((cx == XXLOOK) ||
  2911. ((n > 1) && !quiet && !backgrd /* && dialdpy */ )) {
  2912. int nn = n;
  2913. #ifndef NOSPL
  2914. char * p;
  2915. #endif /* NOSPL */
  2916. if (cx != XXLOOK)
  2917. if (n > 12) nn = 12;
  2918. for (i = 0; i < nn; i++) {
  2919. printf("%3d. %-12s %-20s => %-20s (%d)\n",i+1,
  2920. s3, dn_p[i],
  2921. dn_p2[i] ? dn_p2[i] : "(processing failed)",
  2922. dn_x[i]
  2923. );
  2924. }
  2925. if (cx != XXLOOK && n != nn)
  2926. printf("And %d more...\n", n - nn);
  2927. }
  2928. } else if (n == 0) { /* Not found in directory */
  2929. makestr(&(dn_p[0]),literal ? s : dscopy);
  2930. makestr(&d_name,literal ? s : dscopy);
  2931. dncount = 1;
  2932. n = 1;
  2933. if (dncvt(0,cx,prefix,postfix) < 0) { /* In case they typed a */
  2934. dialsta = DIA_DIR; /* portable-format number ... */
  2935. return(-9);
  2936. }
  2937. }
  2938. #ifndef NONET
  2939. #ifdef NETCONN
  2940. /* It's not good that the networks directory depends on NOT-NODIAL.. */
  2941. if (cx == XXLOOK && dscopy) { /* Networks here too... */
  2942. extern char *nh_p[], *nh_p2[], *n_name;
  2943. extern char *nh_px[4][MAXDNUMS+1];
  2944. n = -1;
  2945. if (nnetdir > 0) { /* Do we have a network directory? */
  2946. dirline = 0;
  2947. n = lunet(dscopy); /* Look up what the user typed */
  2948. }
  2949. if (n > -1) {
  2950. int k;
  2951. if (n > 0) /* A successful lookup */
  2952. lufound = 1;
  2953. if (cx == XXLOOK && n == 0)
  2954. printf(" Lookup: \"%s\" - not found\n",dscopy);
  2955. else
  2956. printf("%s %d network entr%s found for \"%s\"%s\n",
  2957. cx == XXLOOK ? " Lookup:" : "",
  2958. n,
  2959. (n == 1) ? "y" : "ies",
  2960. dscopy,
  2961. (n > 0) ? ":" : "."
  2962. );
  2963. for (i = 0; i < n; i++) {
  2964. printf("%3d. %-12s => %-9s %s",
  2965. i+1,n_name,nh_p2[i],nh_p[i]);
  2966. for (k = 0; k < 4; k++) {
  2967. if (nh_px[k][i]) {
  2968. printf(" %s",nh_px[k][i]);
  2969. } else
  2970. break;
  2971. }
  2972. printf("\n");
  2973. }
  2974. }
  2975. }
  2976. #endif /* NETCONN */
  2977. #endif /* NONET */
  2978. if (cx == XXLOOK)
  2979. return(success = lufound);
  2980. } /* cx != XXANSW */
  2981. #ifdef VMS
  2982. conres(); /* So Ctrl-C/Y will work */
  2983. #endif /* VMS */
  2984. /*
  2985. Some modems do not react well to parity. Also, if we are dialing through a
  2986. TCP/IP TELNET modem server, parity can be fatally misinterpreted as TELNET
  2987. negotiations.
  2988. This should work even if the user interrupts the DIAL command, because the
  2989. DIAL module has its own interrupt handler. BUT... if, for some reason, a
  2990. dialing device actually *requires* parity (e.g. CCITT V.25bis says that even
  2991. parity should be used), this might prevent successful dialing. For that
  2992. reason, we don't do this for V.25bis modems.
  2993. */
  2994. sparity = parity; /* Save current parity */
  2995. if ((dialcapas & CKD_V25) == 0) /* If not V.25bis... */
  2996. parity = 0; /* Set parity to NONE */
  2997. flowsave = flow;
  2998. /*
  2999. These modems use some kind of screwy flow control while in command mode,
  3000. and do not present CTS as they should. So if RTS/CTS is set (or even if
  3001. it isn't) disable flow control during dialing.
  3002. */
  3003. #ifndef MINIDIAL
  3004. if (mdmtyp == n_ATT1910 || mdmtyp == n_ATT1900) {
  3005. flow = FLO_NONE; /* This is not enough */
  3006. #ifdef CK_TTSETFLOW
  3007. ttsetflow(FLO_NONE); /* Really turn it off */
  3008. #endif /* CK_TTSETFLOW */
  3009. }
  3010. #endif /* MINIDIAL */
  3011. if (!network
  3012. #ifdef TN_COMPORT
  3013. || istncomport()
  3014. #endif /* TN_COMPORT */
  3015. ) {
  3016. int x;
  3017. if ((x = ttgmdm()) > -1) {
  3018. if (!x && msgflg) {
  3019. printf(
  3020. "WARNING - No modem signals detected. Is your modem turned on? If not,\n\
  3021. use Ctrl-C to interrupt dialing, turn on your modem, then %s.\n",
  3022. cx == XXANSW ?
  3023. "ANSWER again" :
  3024. "REDIAL"
  3025. );
  3026. }
  3027. if (flow == FLO_RTSC) {
  3028. if (!(x & BM_CTS)) {
  3029. if (msgflg)
  3030. printf(
  3031. "WARNING - SET FLOW RTS/CTS is in effect but modem's CTS signal is off.\n\
  3032. Disabling flow control temporarily %s...\n",
  3033. cx == XXANSW ?
  3034. "while waiting for call" :
  3035. "during dialing"
  3036. );
  3037. flow = FLO_NONE;
  3038. }
  3039. }
  3040. }
  3041. }
  3042. if (cx == XXANSW) { /* ANSWER */
  3043. success = ckdial("",0,0,1,0);
  3044. goto dialfin;
  3045. }
  3046. /* Edit 192 adds the ability to dial repeatedly. */
  3047. i = 0;
  3048. dialcount = 0;
  3049. do {
  3050. if (i > 0) printf("\nDial attempt %d of %d...\n", i+1, xretries);
  3051. dialcount = i+1;
  3052. success = 0;
  3053. /* And the ability to dial alternate numbers. */
  3054. /* Loop to dial each in a list of numbers for the same name... */
  3055. for (j = 0; j < n && !success; j++) { /* until one answers. */
  3056. s = dn_p2[j]; /* Next number in list */
  3057. if (dn_x[j] >= dialrstr) { /* Dial restriction */
  3058. printf("Restricted: %s, skipping...\n",dn_p[j]);
  3059. continue;
  3060. }
  3061. xredial = (i == 0 && j == 0) ? 0 : 1;
  3062. if (!s) s = dn_p[j];
  3063. #ifndef NOSPL
  3064. sav = s;
  3065. p = xdial(s); /* Apply DIAL macro now */
  3066. if (p) if (*p) s = p;
  3067. #endif /* NOSPL */
  3068. /* Dial confirmation */
  3069. /* NOTE: the uq_xxx() calls allow for a GUI dialog */
  3070. if (i == 0 && dialcnf) {
  3071. char msgbuf[128];
  3072. ckmakmsg(msgbuf,128,"Dialing ",s,NULL,NULL);
  3073. x = uq_ok(msgbuf,"Is this number correct? ",3,NULL,0);
  3074. if (!x) {
  3075. #ifndef COMMENT
  3076. x = uq_txt( /* Allow GUI dialog */
  3077. #ifdef OS2
  3078. " Please enter the correct number,\r\n or press Enter to skip.",
  3079. #else
  3080. " Please enter the correct number,\r\n or press Return to skip.",
  3081. #endif /* OS2 */
  3082. "Corrected phone number: ",
  3083. 1,
  3084. NULL,
  3085. atmbuf,
  3086. ATMBL,
  3087. s,
  3088. DEFAULT_UQ_TIMEOUT
  3089. );
  3090. if (x && atmbuf[0]) { /* They gave a new one */
  3091. s = atmbuf;
  3092. makestr(&(dn_p2[j]), s);
  3093. }
  3094. #else /* COMMENT */
  3095. #ifdef CK_RECALL
  3096. extern int on_recall;
  3097. #endif /* CK_RECALL */
  3098. cmsavp(psave,PROMPTL);
  3099. cmsetp(
  3100. #ifdef OS2
  3101. " Please enter the correct number,\r\n or press Enter to skip: "
  3102. #else
  3103. " Please enter the correct number,\r\n or press Return to skip: "
  3104. #endif /* OS2 */
  3105. );
  3106. cmini(ckxech);
  3107. x = -1;
  3108. if (pflag) prompt(NULL);
  3109. #ifdef CK_RECALL
  3110. on_recall = 0;
  3111. #endif /* CK_RECALL */
  3112. y = cmdgquo();
  3113. cmdsquo(0);
  3114. while (x < 0) {
  3115. x = cmtxt("Corrected phone number","",&s,NULL);
  3116. cmres();
  3117. }
  3118. if ((int) strlen(s) < 1) {
  3119. cmsetp(psave);
  3120. continue;
  3121. }
  3122. makestr(&(dn_p2[j]), s);
  3123. cmdsquo(y);
  3124. cmsetp(psave);
  3125. #endif /* COMMENT */
  3126. }
  3127. }
  3128. if (dialtest) { /* Just testing */
  3129. if (i + j == 0)
  3130. printf("\nTESTING...\n");
  3131. if (dialmac)
  3132. printf(" Number: \"%s\" => \"%s\"\n",sav,s);
  3133. else
  3134. printf(" Number: \"%s\"\n",s);
  3135. dialsta = DIA_BUSY;
  3136. success = 0;
  3137. } else {
  3138. what |= W_DIALING;
  3139. success = ckdial(s,i,j,partial ? 3 : 0, xredial); /* Dial it */
  3140. what &= ~(W_DIALING);
  3141. if (!success) {
  3142. if (dialsta < 8 || /* Break out if unrecoverable error */
  3143. dialsta == DIA_INTR ||
  3144. dialsta == DIA_ERR ||
  3145. previous == DIA_PART
  3146. )
  3147. break;
  3148. }
  3149. }
  3150. }
  3151. if (success) /* Succeeded, leave the outer loop */
  3152. break;
  3153. if (dialsta < 8 || /* Break out if unrecoverable error */
  3154. dialsta == DIA_INTR || /* Interrupted */
  3155. dialsta == DIA_NODT || /* No dialtone */
  3156. dialsta == DIA_NOAC || /* Access forbidden */
  3157. dialsta == DIA_BLCK || /* Blacklisted */
  3158. dialsta == DIA_DIR || /* Dialing directory error */
  3159. dialsta == DIA_ERR || /* Modem command error */
  3160. previous == DIA_PART)
  3161. break;
  3162. if (++i >= xretries) /* Break out if too many tries */
  3163. break;
  3164. if (!backgrd && !quiet) {
  3165. if (dialint > 5)
  3166. printf(
  3167. "\nWill redial in %d second%s- press any key to redial immediately.\n",
  3168. dialint,
  3169. dialint == 1 ? " " : "s "
  3170. );
  3171. printf("Ctrl-C to cancel...\n");
  3172. }
  3173. x = dialint; /* Redial interval */
  3174. while (x-- > 0) {
  3175. if ((y = conchk()) > 0) { /* Did they type something? */
  3176. while (y--) coninc(0); /* Yes, absorb it */
  3177. break; /* And wake up */
  3178. }
  3179. sleep(1); /* No interrupt, sleep a sec */
  3180. }
  3181. } while (!success);
  3182. dialfin:
  3183. if (cx != XXLOOK) {
  3184. if (!success)
  3185. bleep((short) BP_FAIL);
  3186. else if (!quiet)
  3187. bleep((short) BP_NOTE);
  3188. #ifdef OS2
  3189. setint(); /* Fix OS/2 interrupts */
  3190. #endif /* OS2 */
  3191. if (sparity > -1)
  3192. parity = sparity; /* Restore parity if we saved it */
  3193. flow = flowsave;
  3194. #ifdef OS2
  3195. ttres(); /* Restore DIAL device */
  3196. #endif /* OS2 */
  3197. #ifdef VMS
  3198. concb((char)escape); /* Restore console */
  3199. #endif /* VMS */
  3200. #ifdef OS2
  3201. { /* Set session title */
  3202. char * p, name[72]; /* in window list. */
  3203. char * q;
  3204. if (cx == XXANSW) {
  3205. q = "Incoming call";
  3206. } else {
  3207. if (d_name)
  3208. q = d_name;
  3209. else if (dialnum)
  3210. q = dialnum;
  3211. else if (ttname[0])
  3212. q = ttname;
  3213. else q = "";
  3214. }
  3215. p = name;
  3216. if (success) {
  3217. strncpy(name,q,48);
  3218. while (*p) { /* Uppercase it for emphasis. */
  3219. if (islower(*p))
  3220. *p = toupper(*p);
  3221. p++;
  3222. }
  3223. } else
  3224. name[0] = NUL ;
  3225. os2settitle((char *) name, TRUE);
  3226. }
  3227. #endif /* OS2 */
  3228. }
  3229. if (cx != XXLOOK) {
  3230. if (success) {
  3231. if (reliable == SET_AUTO) { /* It's not a reliable connection. */
  3232. reliable = SET_OFF;
  3233. debug(F101,"dodial reliable","",reliable);
  3234. }
  3235. } else {
  3236. #ifndef NOHINTS
  3237. extern int hints;
  3238. if (hints && !quiet && dialsta != 9) { /* 9 == User interrupted */
  3239. extern int dialmhu, dialhng, dialdpy;
  3240. extern char * dialmsg[];
  3241. printf("\n*************************\n");
  3242. printf("DIAL-class command failed.\n");
  3243. printf("Modem type: %s\n", gmdmtyp());
  3244. printf("Device: %s\n", ttname);
  3245. printf("Speed: %ld\n", speed);
  3246. printf("Dial status: %d",dialsta);
  3247. if (dialsta < 35 && dialmsg[dialsta])
  3248. printf(" [%s]",dialmsg[dialsta]);
  3249. printf("\n");
  3250. if (dialsta == DIA_TIMO ||
  3251. dialsta == DIA_NRDY ||
  3252. (dialsta > 13 && dialsta != DIA_BUSY && dialsta != DIA_NOAN)
  3253. ) {
  3254. switch (dialsta) {
  3255. case DIA_TIMO:
  3256. printf(
  3257. " . SET DIAL TIMEOUT to a greater value and try again.\n"
  3258. );
  3259. break;
  3260. case DIA_NRSP:
  3261. case DIA_NRDY:
  3262. case DIA_NOIN:
  3263. printf(
  3264. " . Is the modem turned on?\n"
  3265. );
  3266. printf(
  3267. " . Are you using the right communication port?\n"
  3268. );
  3269. break;
  3270. case DIA_NODT:
  3271. printf(
  3272. " . Is the modem connected to the telephone line?\n"
  3273. );
  3274. }
  3275. if (mdmtyp == n_GENERIC) {
  3276. printf(
  3277. " . Please choose a specific modem type with SET MODEM TYPE and try again.\n"
  3278. );
  3279. printf(
  3280. " SET MODEM TYPE ? to see the list of known modem types.\n"
  3281. );
  3282. } else {
  3283. printf(
  3284. " . Are you sure you have chosen the appropriate modem type?\n"
  3285. );
  3286. }
  3287. if (speed > 19200L) {
  3288. printf(
  3289. " . Maybe the interface speed (%ld) is too fast:\n", speed
  3290. );
  3291. printf(
  3292. " SET SPEED to a lower speed and try again.\n"
  3293. );
  3294. printf(
  3295. " SET SPEED ? to see the list of valid speeds.\n"
  3296. );
  3297. }
  3298. if (dialhng) {
  3299. if (dialmhu)
  3300. printf(
  3301. " . SET MODEM HANGUP-METHOD RS232 and try again.\n"
  3302. );
  3303. else
  3304. printf(
  3305. " . SET MODEM HANGUP-METHOD MODEM-COMMAND and try again.\n"
  3306. );
  3307. printf(
  3308. " . If that doesn't work, try again with SET DIAL HANGUP OFF.\n"
  3309. );
  3310. } else {
  3311. printf(
  3312. " . Give a HANGUP or SET DIAL HANGUP ON command and try again.\n"
  3313. );
  3314. }
  3315. if (!dialdpy)
  3316. printf(
  3317. " . Use SET DIAL DISPLAY ON to watch the dialog between Kermit and modem.\n"
  3318. );
  3319. }
  3320. #ifndef NOSHOW
  3321. printf(
  3322. " . SHOW COMMUNICATIONS, SHOW MODEM, SHOW DIAL to see current settings.\n"
  3323. );
  3324. #endif /* NOSHOW */
  3325. #ifndef NOHELP
  3326. printf(
  3327. " . HELP SET MODEM, HELP SET DIAL, and HELP DIAL for more information.\n"
  3328. );
  3329. #endif /* NOHELP */
  3330. printf("(Use SET HINTS OFF to suppress future hints.)\n");
  3331. printf("*************************\n\n");
  3332. }
  3333. #endif /* NOHINTS */
  3334. }
  3335. }
  3336. return(success);
  3337. }
  3338. #endif /* NODIAL */
  3339. /* D O T Y P E -- Type (display) a file with various options... */
  3340. #ifdef BIGBUFOK
  3341. #define TYPBUFL 16384
  3342. #else
  3343. #define TYPBUFL 256
  3344. #endif /* BIGBUFOK */
  3345. int typ_lines = 0; /* \v(ty_ln) */
  3346. int typ_mtchs = 0; /* \v(ty_lm) */
  3347. static int typ_int = 0; /* Flag if TYPE interrupted */
  3348. #ifdef UNICODE
  3349. extern int fcharset, fileorder, byteorder, ucsorder;
  3350. #define TYPXBUFL TYPBUFL+TYPBUFL+TYPBUFL+4
  3351. static char * mp = NULL;
  3352. static char * mbuf = NULL;
  3353. static long xn = 0L;
  3354. static int
  3355. #ifdef CK_ANSIC
  3356. storechar(char c)
  3357. #else
  3358. storechar(c) char c;
  3359. #endif /* CK_ANSIC */
  3360. {
  3361. if (!mp) return(-1);
  3362. if (++xn > TYPXBUFL)
  3363. return(-1);
  3364. debug(F111,"storechar xn",ckitoa((int)c),xn);
  3365. *mp++ = c;
  3366. return(0);
  3367. }
  3368. #endif /* UNICODE */
  3369. static FILE * ofp = NULL; /* For /OUTPUT: file */
  3370. static int
  3371. typeline(buf,len,outcs,ofp) char * buf; int len, outcs; FILE * ofp; {
  3372. register int i;
  3373. debug(F011,"typeline buf",buf,len);
  3374. /* debug(F101,"typeline outcs","",outcs); */
  3375. #ifdef OS2
  3376. #ifndef NOLOCAL
  3377. #ifdef UNICODE
  3378. /* In K95 only, the buffer is guaranteed to be in UCS-2 if outcs >= 0. */
  3379. /* Len is its length in bytes. There is no line terminator. */
  3380. /* outcs is the file character-set number (FC_xxx) of the target set */
  3381. /* that was requested by the user. */
  3382. if (!inserver && !k95stdout) {
  3383. extern int wherex[], wherey[];
  3384. extern unsigned char colorcmd;
  3385. VscrnWrtUCS2StrAtt( VCMD, (unsigned short *)buf, len/2,
  3386. wherey[VCMD], wherex[VCMD], &colorcmd);
  3387. printf("\r\n");
  3388. return(0);
  3389. }
  3390. #endif /* UNICODE */
  3391. #endif /* NOLOCAL */
  3392. #endif /* OS2 */
  3393. /* In Unix, VMS, etc, the line has already been converted to the desired */
  3394. /* character-set, if one was given. OR... on all platforms, including in */
  3395. /* K95, we don't know the character set. In either case we dump the line */
  3396. /* byte by byte in case it contains NULs (printf() would truncate). */
  3397. #ifdef COMMENT
  3398. for (i = 0; i < len; i++)
  3399. putchar(buf[i]);
  3400. #else
  3401. for (i = 0; i < len; i++) {
  3402. if (ofp == stdout) {
  3403. putchar(buf[i]);
  3404. } else {
  3405. putc(buf[i],ofp);
  3406. }
  3407. }
  3408. #endif /* COMMENT */
  3409. #ifdef IKSD
  3410. if (inserver) {
  3411. #ifdef UNICODE
  3412. if (outcs == FC_UCS2) {
  3413. if (ofp == stdout) {
  3414. putchar(NUL);
  3415. } else {
  3416. putc(NUL,ofp);
  3417. }
  3418. }
  3419. #endif /* UNICODE */
  3420. if (ofp == stdout) {
  3421. putchar('\r');
  3422. } else {
  3423. putc('\r',ofp);
  3424. }
  3425. }
  3426. #endif /* IKSD */
  3427. #ifdef UNICODE
  3428. if (outcs == FC_UCS2) {
  3429. if (ofp == stdout) {
  3430. putchar(NUL);
  3431. } else {
  3432. putc(NUL,ofp);
  3433. }
  3434. }
  3435. #endif /* UNICODE */
  3436. if (ofp == stdout) {
  3437. putchar('\n');
  3438. } else {
  3439. putc('\n',ofp);
  3440. }
  3441. fflush(stdout);
  3442. return(0);
  3443. }
  3444. static int /* Get translated line */
  3445. typegetline(incs, outcs, buf, n) int incs, outcs, n; char * buf; {
  3446. int x = 0, c0, c1, len = 0, count = 0, eof = 0, xlate = 0;
  3447. #ifdef UNICODE
  3448. int xxn = -1;
  3449. int yyn = -9;
  3450. xn = 0L;
  3451. #ifdef DEBUG
  3452. if (deblog && typ_lines == 0) {
  3453. debug(F101,"typegetline incs","",incs);
  3454. debug(F101,"typegetline outcs","",outcs);
  3455. debug(F101,"typegetline feol","",feol);
  3456. debug(F101,"typegetline byteorder","",byteorder);
  3457. debug(F101,"typegetline ucsorder ","",ucsorder);
  3458. debug(F111,"typegetline fileorder","1",fileorder);
  3459. }
  3460. #endif /* DEBUG */
  3461. if (incs < 0) /* Shouldn't happen */
  3462. return(-2);
  3463. if (outcs == -1) /* Can happen */
  3464. outcs = incs;
  3465. if (incs != outcs || incs == FC_UCS2) { /* See if we should translate */
  3466. xlate = 1;
  3467. if (!mbuf) { /* Allocate buffer if not allocated */
  3468. mbuf = (char *)malloc(TYPXBUFL+1); /* yet */
  3469. if (!mbuf) {
  3470. printf("WARNING: Translation buffer allocation failure.\n");
  3471. printf("Translation will be skipped...\n");
  3472. xlate = 0;
  3473. }
  3474. }
  3475. }
  3476. if (xlate) { /* Translating... */
  3477. mp = mbuf; /* Reset working buffer pointer */
  3478. /*
  3479. Here we call xgnbyte() in a loop, having it return UCS-2 bytes. In K95, we
  3480. use UCS-2 directly. Elsewhere, we feed the UCS-2 bytes into xpnbyte() to
  3481. convert them to the desired target character set. But since we are using
  3482. UCS-2, we have several sources for confusion: (1) xgnbyte() might return in
  3483. LE or BE byte order, with no explicit indication of what the order is; but
  3484. (2) xpnbyte() wants BE; but (3) Windows wants LE.
  3485. */
  3486. while (1) {
  3487. if (typ_int) /* Quit if interrupted */
  3488. return(0);
  3489. c0 = xgnbyte(FC_UCS2,incs,NULL); /* Convert to UCS-2 */
  3490. debug(F000,"typegetline c0","",c0);
  3491. if (c0 < 0) { /* EOF */
  3492. eof++;
  3493. break;
  3494. }
  3495. c1 = xgnbyte(FC_UCS2,incs,NULL); /* Convert to UCS-2 */
  3496. debug(F000,"typegetline c1","",c1);
  3497. if (c1 < 0) { /* EOF */
  3498. eof++;
  3499. break;
  3500. }
  3501. #ifdef DEBUG
  3502. if (deblog && typ_lines == 0) {
  3503. if (count == 0) /* Check fileorder after BOM */
  3504. debug(F111,"typegetline fileorder","2",fileorder);
  3505. }
  3506. #endif /* DEBUG */
  3507. #ifdef COMMENT
  3508. /* Now we have the two UCS-2 bytes. Which order are they in? */
  3509. if (fileorder > 0) { /* Little Endian */
  3510. int t; /* So swap them */
  3511. debug(F100,"typegetline swapping","",0);
  3512. t = c1;
  3513. c1 = c0;
  3514. c0 = t;
  3515. }
  3516. #endif /* COMMENT */
  3517. if (c0 == 0 && c1 == 0x0D) /* Now see if we have EOL */
  3518. yyn = xn;
  3519. if (c0 == 0 && c1 == 0x0A) /* Now see if we have EOL */
  3520. xxn = xn;
  3521. count++; /* Count byte */
  3522. /* Give the two bytes to xpnbyte() in BE order */
  3523. if ((x = xpnbyte(c0,TC_UCS2,outcs,storechar)) < 0) return(-1);
  3524. if ((x = xpnbyte(c1,TC_UCS2,outcs,storechar)) < 0) return(-1);
  3525. if (xxn > -1) { /* Have end of line? */
  3526. xn = xxn;
  3527. if (yyn == xxn - 2) /* Adjust for CRLF */
  3528. xn = yyn;
  3529. break; /* And break out of loop. */
  3530. }
  3531. }
  3532. mbuf[xn] = NUL;
  3533. if (xn > n) /* Can truncate here... */
  3534. xn = n;
  3535. memcpy(buf,mbuf,xn);
  3536. debug(F011,"typegetline xlate",buf,xn);
  3537. return((eof && (xn == 0)) ? -1 : xn);
  3538. }
  3539. #endif /* UNICODE */
  3540. #ifdef COMMENT
  3541. /* We can't use this because, stupidly, zsinl() doesn't return a length. */
  3542. /* It could be changed but then we'd have to change all ck?fio.c modules */
  3543. x = zsinl(ZIFILE,buf,n);
  3544. #else
  3545. /* So instead, we copy zsinl() to here... */
  3546. /* But note: This does not necessarily handle UCS-2 alignment properly; */
  3547. /* that's what the code in the first section of this routine is for. */
  3548. /* But it does tolerate files that contain NULs. */
  3549. {
  3550. int a;
  3551. char *s;
  3552. s = buf;
  3553. a = -1; /* Current character, none yet. */
  3554. debug(F101,"typegetline zsinl simulation","",n);
  3555. while (n--) { /* Up to given length */
  3556. #ifdef COMMENT
  3557. int old = 0;
  3558. if (feol) /* Previous character */
  3559. old = a;
  3560. #endif /* COMMENT */
  3561. if (zchin(ZIFILE,&a) < 0) { /* Read a character from the file */
  3562. debug(F101,"typegetline zchin fail","",count);
  3563. if (count == 0)
  3564. x = -1; /* EOF or other error */
  3565. break;
  3566. } else
  3567. count++;
  3568. if (feol) { /* Single-character line terminator */
  3569. if (a == feol)
  3570. break;
  3571. } else { /* CRLF line terminator */
  3572. #ifdef COMMENT
  3573. /* Debug log shows that in Windows, <CR><LF> is returned as <LF>. */
  3574. /* Apparently we're not reading the file in binary mode. */
  3575. if (a == '\015') /* CR, get next character */
  3576. continue;
  3577. if (old == '\015') { /* Previous character was CR */
  3578. if (a == '\012') { /* This one is LF, so we have a line */
  3579. break;
  3580. } else { /* Not LF, deposit CR */
  3581. *s++ = '\015';
  3582. n--;
  3583. len++;
  3584. }
  3585. }
  3586. #else
  3587. if (a == LF) {
  3588. if (s[len] == CR) { /* This probably won't happen */
  3589. s[len] = NUL;
  3590. s--;
  3591. len--;
  3592. }
  3593. break;
  3594. }
  3595. #endif /* COMMENT */
  3596. }
  3597. *s = a; /* Deposit character */
  3598. s++;
  3599. len++;
  3600. }
  3601. *s = '\0'; /* Terminate the string */
  3602. }
  3603. #endif /* COMMENT */
  3604. return(x < 0 ? -1 : len);
  3605. }
  3606. #ifndef MAC
  3607. SIGTYP
  3608. #ifdef CK_ANSIC
  3609. tytrap(int foo) /* TYPE interrupt trap */
  3610. #else
  3611. tytrap(foo) int foo;
  3612. #endif /* CK_ANSIC */
  3613. /* tytrap */ {
  3614. #ifdef __EMX__
  3615. signal(SIGINT, SIG_ACK);
  3616. #endif
  3617. debug(F100,"type tytrap SIGINT","",0);
  3618. typ_int = 1; /* (Need arg for ANSI C) */
  3619. SIGRETURN;
  3620. }
  3621. #endif /* MAC */
  3622. int
  3623. dotype(file, paging, first, head, pat, width, prefix, incs, outcs, outfile, z)
  3624. char * file, * pat, * prefix; int paging, first, head, width, incs, outcs;
  3625. char * outfile; int z;
  3626. /* dotype */ {
  3627. extern CK_OFF_T ffc;
  3628. char buf[TYPBUFL+2];
  3629. char * s = NULL;
  3630. int rc = 1, lines = 0, ucs2 = 0;
  3631. char ** tail = NULL;
  3632. int * tlen = NULL;
  3633. int tailing = 0, counting = 0;
  3634. int x, c, n, i, j, k = 0;
  3635. int number = 0, save, len, pfxlen = 0, evalpfx = 1;
  3636. #ifdef UNICODE
  3637. int ucsbom_sav;
  3638. extern int ucsbom;
  3639. #endif /* UNICODE */
  3640. #ifdef NT
  3641. int gui = 0;
  3642. #endif /* NT */
  3643. #ifndef MAC
  3644. #ifdef OS2
  3645. #ifdef NT
  3646. SIGTYP (* oldsig)(int); /* For saving old interrupt trap. */
  3647. #else /* NT */
  3648. SIGTYP (* volatile oldsig)(int);
  3649. #endif /* NT */
  3650. #else /* OS2 */
  3651. SIGTYP (* oldsig)();
  3652. #endif /* OS2 */
  3653. #endif /* MAC */
  3654. #ifdef KUI
  3655. if (outfile == (char *)1) {
  3656. gui = 1;
  3657. outfile = "";
  3658. }
  3659. #endif /* KUI */
  3660. if (!file) file = "";
  3661. if (!*file) return(-2);
  3662. if (ofp != stdout) { /* In case of previous interruption */
  3663. if (ofp) fclose(ofp);
  3664. ofp = stdout;
  3665. }
  3666. if (!outfile) outfile = "";
  3667. if (outfile[0]) {
  3668. ofp = fopen(outfile,"w"); /* Open output file */
  3669. if (!ofp) {
  3670. printf("?Can't open output file %s: %s\n",outfile,ck_errstr());
  3671. ofp = stdout;
  3672. return(-9);
  3673. }
  3674. }
  3675. number = z;
  3676. if (number && prefix) prefix = NULL;
  3677. #ifdef UNICODE
  3678. ucsbom_sav = ucsbom; /* We are not creating a file */
  3679. ucsbom = 0; /* Do not use BOM bytes */
  3680. #endif /* UNICODE */
  3681. typ_int = 0;
  3682. save = binary; /* Save file type */
  3683. debug(F101,"dotype incs","",incs);
  3684. debug(F101,"dotype outcs","",outcs);
  3685. #ifdef UNICODE
  3686. debug(F111,"dotype fileorder","A",fileorder);
  3687. #ifdef OS2
  3688. if (!inserver && !k95stdout)
  3689. outcs = FC_UCS2;
  3690. #endif /* OS2 */
  3691. if (outcs == FC_UCS2) /* Output is UCS-2? */
  3692. ucs2 = 1;
  3693. if (fileorder < 0)
  3694. fileorder = ucsorder;
  3695. debug(F111,"dotype fileorder","B",fileorder);
  3696. #endif /* UNICODE */
  3697. #ifdef CK_TTGWSIZ
  3698. #ifdef OS2
  3699. ttgcwsz();
  3700. #else /* OS2 */
  3701. /* Check whether window size changed */
  3702. if (ttgwsiz() > 0) {
  3703. if (tt_rows > 0 && tt_cols > 0) {
  3704. cmd_rows = tt_rows;
  3705. cmd_cols = tt_cols;
  3706. debug(F101,"dotype cmd_rows","",cmd_rows);
  3707. debug(F101,"dotype cmd_cols","",cmd_cols);
  3708. }
  3709. }
  3710. #endif /* OS2 */
  3711. #endif /* CK_TTGWSIZ */
  3712. if (prefix)
  3713. pfxlen = strlen(prefix);
  3714. if (paging < 0) { /* Count only, don't print */
  3715. counting = 1;
  3716. prefix = NULL;
  3717. width = 0;
  3718. paging = 0;
  3719. }
  3720. if (ucs2) /* Crude... */
  3721. width *= 2;
  3722. #ifdef OS2
  3723. if (*file) {
  3724. ckstrncpy(buf, file, TYPBUFL); /* Change / to \. */
  3725. p = buf;
  3726. while (*p) {
  3727. if (*p == '/') *p = '\\';
  3728. p++;
  3729. }
  3730. file = buf;
  3731. } else {
  3732. rc = 0;
  3733. goto xdotype;
  3734. }
  3735. #endif /* OS2 */
  3736. if (zchki(file) == -2) { /* It's a directory */
  3737. debug(F111,"dotype zchki failure",file,-2);
  3738. if (xcmdsrc == 0) {
  3739. printf("?Not a regular file: \"%s\"\n",file);
  3740. rc = -9;
  3741. } else
  3742. rc = 0;
  3743. goto xdotype;
  3744. }
  3745. if (!zopeni(ZIFILE, file)) { /* Not a directory, open it */
  3746. debug(F111,"dotype zopeni failure",file,0);
  3747. if (xcmdsrc == 0) {
  3748. printf("?Can't open file: \"%s\"\n",file);
  3749. rc = -9;
  3750. } else
  3751. rc = 0;
  3752. goto xdotype;
  3753. }
  3754. #ifndef AMIGA
  3755. #ifndef MAC
  3756. errno = 0;
  3757. oldsig = signal(SIGINT, tytrap); /* Save current interrupt trap. */
  3758. /* debug(F111,"type SIGINT trap set",ckitoa(errno),oldsig); */
  3759. #endif /* MAC */
  3760. #endif /* AMIGA */
  3761. if (paging > -1) /* More-prompting */
  3762. xaskmore = paging;
  3763. binary = 0;
  3764. if (head < 0) { /* "tail" was requested */
  3765. tailing = 1; /* Set flag */
  3766. head = 0 - head; /* Get absolute number of lines */
  3767. if (!counting) {
  3768. tail = (char **) malloc(head * sizeof(char *)); /* Allocate list */
  3769. if (!tail) {
  3770. printf("?Memory allocation failure\n");
  3771. goto xdotype;
  3772. }
  3773. tlen = (int *) malloc(head * sizeof(int));
  3774. if (!tlen) {
  3775. printf("?Memory allocation failure\n");
  3776. goto xdotype;
  3777. }
  3778. for (i = 0; i < head; i++) { /* Initialize each pointer in list. */
  3779. tail[i] = NULL;
  3780. tlen[i] = 0;
  3781. }
  3782. }
  3783. }
  3784. typ_lines = 0;
  3785. typ_mtchs = 0;
  3786. #ifdef UNICODE
  3787. if (outcs > -1 && (incs != outcs || incs == FC_UCS2)) { /* Translating? */
  3788. ffc = (CK_OFF_T)0;
  3789. initxlate(incs,outcs); /* Set up translation functions */
  3790. } else
  3791. #endif /* UNICODE */
  3792. outcs = -1; /* Means we don't know the charset */
  3793. debug(F101,"dotype ffc","",ffc);
  3794. debug(F101,"dotype outcs 2","",outcs);
  3795. #ifdef UNICODE
  3796. debug(F111,"dotype fileorder","C",fileorder);
  3797. #endif /* UNICODE */
  3798. /* Allow the buffer to contain NULs */
  3799. for (n = first;
  3800. (len = typegetline(incs,outcs,buf,TYPBUFL)) > -1;
  3801. lines++
  3802. ) {
  3803. debug(F011,"dotype line",buf,len);
  3804. #ifndef MAC
  3805. if (typ_int) { /* Interrupted? */
  3806. typ_int = 0;
  3807. debug(F101,"type interrupted line","",lines);
  3808. printf("^C...\n"); /* Print message */
  3809. if (ofp != stdout) { /* Close any output file */
  3810. if (ofp) fclose(ofp);
  3811. ofp = stdout;
  3812. }
  3813. goto xxdotype;
  3814. }
  3815. #endif /* MAC */
  3816. typ_lines++; /* For \v(ty_ln) */
  3817. if (pat) /* Matching? */
  3818. if (!ckmatch(pat,buf,1,1+4)) /* Line matches pattern? */
  3819. continue; /* No, skip it */
  3820. typ_mtchs++;
  3821. if (head > 0 && !tailing && lines == head) /* Handle /HEAD:n */
  3822. break;
  3823. buf[TYPBUFL+1] = NUL; /* Just in case... */
  3824. if (prefix) { /* Add specified prefix to each line */
  3825. char pbuf[64];
  3826. char * pp;
  3827. pp = prefix;
  3828. #ifndef NOSPL
  3829. if (evalpfx) { /* Prefix is a variable? */
  3830. int n = 63; /* Maybe - evaluate it and see */
  3831. char * p = pbuf;
  3832. zzstring(prefix,&p,&n); /* If there is no change */
  3833. if (!strcmp(prefix,pbuf)) { /* it's not a variable */
  3834. evalpfx = 0; /* So don't do this again. */
  3835. } else { /* It was a variable */
  3836. pp = pbuf; /* So substitute its value */
  3837. pfxlen = 63 - n; /* and get its new length */
  3838. }
  3839. }
  3840. #endif /* NOSPL */
  3841. if (len + pfxlen + 2 < TYPBUFL) {
  3842. /* Shift right to make room for prefix */
  3843. memcpy((char *)line+pfxlen,(char *)buf,len);
  3844. lset((char *)line,pp,pfxlen,SP);
  3845. debug(F110,"dotype prefix",line,pfxlen);
  3846. len += pfxlen;
  3847. memcpy((char *)buf,(char *)line,len);
  3848. }
  3849. } else if (number) { /* Line numbers */
  3850. int x;
  3851. sprintf(line,"%4d. ",typ_lines);
  3852. x = strlen(line);
  3853. len += x;
  3854. if (len < LINBUFSIZ) {
  3855. memcpy((char *)&line[x],(char *)buf,len);
  3856. memcpy((char *)buf,(char *)line,len);
  3857. }
  3858. }
  3859. if (width > 0 && width <= TYPBUFL) { /* Truncate at given width. */
  3860. char * obuf = line; /* But to do that first we must */
  3861. int i,k,z; /* expand tabs; assume every 8 cols. */
  3862. line[0] = NUL;
  3863. for (i = 0, k = 0; i < width; k++) { /* Character loop... */
  3864. if (!buf[k]) /* No more chars in this line, done. */
  3865. break;
  3866. if (buf[k] != '\t') { /* If it's not a tab */
  3867. if (i >= LINBUFSIZ) /* Check for overflow */
  3868. break;
  3869. obuf[i++] = buf[k]; /* and then deposit it. */
  3870. obuf[i] = NUL; /* Keep it null-terminated */
  3871. continue;
  3872. }
  3873. z = 8 - (i % 8); /* It's a tab, expand it. */
  3874. if (z == 0) z = 8;
  3875. for (j = 0; j < z && i < LINBUFSIZ; j++) {
  3876. #ifdef UNICODE
  3877. if (ucs2 && !ucsorder)
  3878. obuf[i++] = NUL;
  3879. #endif /* UNICODE */
  3880. obuf[i++] = ' ';
  3881. #ifdef UNICODE
  3882. if (ucs2 && ucsorder)
  3883. obuf[i++] = NUL;
  3884. #endif /* UNICODE */
  3885. }
  3886. obuf[i++] = NUL;
  3887. obuf[i] = NUL;
  3888. }
  3889. obuf[width] = NUL; /* Now truncate at given width. */
  3890. #ifdef COMMENT
  3891. /* This doesn't work for UCS-2 because it contains NULs */
  3892. ckstrncpy(buf,obuf,TYPBUFL); /* and copy it back (again?) */
  3893. #else
  3894. memcpy((char *)buf,(char *)obuf,i); /* Copy it back */
  3895. #endif /* COMMENT */
  3896. len = (i > width) ? width : i; /* Spare us another strlen()... */
  3897. }
  3898. if (tailing) { /* If /TAIL:n... */
  3899. k = lines % head; /* save this line in circular buffer */
  3900. if (!counting) {
  3901. if (tail[k]) free(tail[k]);
  3902. tail[k] = malloc(len+2);
  3903. if (!tail[k]) {
  3904. printf("?Memory allocation failure\n");
  3905. goto xdotype;
  3906. }
  3907. memcpy(tail[k],buf,len);
  3908. tlen[k] = len;
  3909. continue;
  3910. }
  3911. }
  3912. if (counting) /* If only counting */
  3913. continue; /* we're done with this line */
  3914. if (paging) { /* Displaying this line... */
  3915. int u;
  3916. u = len; /* Length in BYTES */
  3917. if (ucs2) /* If outputting in UCS-2 */
  3918. u /= 2; /* convert length to CHARACTERS */
  3919. x = (u / cmd_cols) + 1; /* Crudely allow for wrap */
  3920. if (cmd_rows > 0 && cmd_cols > 0)
  3921. n += x; /* This assumes terminal will wrap */
  3922. }
  3923. #ifdef KUI
  3924. if ( gui ) {
  3925. int i;
  3926. unsigned short * uch = (unsigned short *)buf;
  3927. for ( i=0; i<len/2; i++)
  3928. gui_text_popup_append(uch[i]);
  3929. gui_text_popup_append(CR);
  3930. gui_text_popup_append(LF);
  3931. }
  3932. else
  3933. #endif /* KUI */
  3934. typeline(buf,len,outcs,ofp); /* Print line, length based */
  3935. #ifdef CK_TTGWSIZ
  3936. debug(F101,"dotype n","",n);
  3937. if (paging > 0 && ofp == stdout) { /* Pause at end of screen */
  3938. if (cmd_rows > 0 && cmd_cols > 0) {
  3939. if (n > cmd_rows - 3) {
  3940. if (!askmore())
  3941. goto xdotype;
  3942. else
  3943. n = 0;
  3944. }
  3945. }
  3946. }
  3947. #endif /* CK_TTGWSIZ */
  3948. }
  3949. xdotype:
  3950. if (counting) {
  3951. fprintf(ofp,
  3952. "%s: %d line%s\n",file,typ_lines,typ_lines == 1 ? "" : "s");
  3953. if (pat)
  3954. fprintf(ofp,
  3955. "%s: %d match%s\n",pat,typ_mtchs,typ_mtchs == 1 ? "" : "es");
  3956. goto xxdotype;
  3957. }
  3958. if (tailing && tail) { /* Typing tail of file? */
  3959. if (lines < head) { /* Yes, show the lines we saved */
  3960. k = 0; /* Show all lines */
  3961. } else { /* More lines than tail number */
  3962. lines = k; /* Last line to show */
  3963. k++; /* First line to show */
  3964. if (k >= head)
  3965. k = 0;
  3966. }
  3967. n = first; /* Output line counter */
  3968. for (i = k ;; i++) { /* Loop thru circular buffer */
  3969. #ifndef MAC
  3970. if (typ_int) { /* Interrupted? */
  3971. printf("^C...\n"); /* Print message */
  3972. goto xxdotype;
  3973. }
  3974. #endif /* MAC */
  3975. j = i % head; /* Index of this line */
  3976. s = tail[j]; /* Point to line to display */
  3977. if (!s) /* (shouldn't happen...) */
  3978. break;
  3979. if (paging) { /* Crudely allow for line wrap */
  3980. x = tlen[j];
  3981. if (ucs2) x /= 2;
  3982. x = x / cmd_cols + 1;
  3983. if (cmd_rows > 0 && cmd_cols > 0)
  3984. n += x;
  3985. }
  3986. typeline(s,tlen[j],outcs,ofp); /* Display this line */
  3987. if (paging && ofp == stdout) { /* Pause at end of screen */
  3988. if (cmd_rows > 0 && cmd_cols > 0) {
  3989. if (n > cmd_rows - 3) {
  3990. if (!askmore())
  3991. break;
  3992. else
  3993. n = 0;
  3994. }
  3995. }
  3996. }
  3997. tail[j] = NULL;
  3998. free(s); /* Free the line */
  3999. if (i % head == lines) /* When to stop */
  4000. break;
  4001. }
  4002. free((char *)tail); /* Free the list */
  4003. tail = NULL;
  4004. if (tlen) free((char *)tlen);
  4005. tlen = NULL;
  4006. }
  4007. /* Come here when finished or on SIGINT */
  4008. xxdotype:
  4009. #ifndef AMIGA
  4010. #ifndef MAC
  4011. signal(SIGINT,oldsig); /* Put old signal action back. */
  4012. #endif /* MAC */
  4013. #endif /* AMIGA */
  4014. if (tailing && tail) {
  4015. for (i = 0; i < head; i++) { /* Free each line. */
  4016. if (tail[i])
  4017. free(tail[i]);
  4018. }
  4019. free((char *)tail); /* Free list pointer */
  4020. if (tlen)
  4021. free((char *)tlen);
  4022. }
  4023. x = zclose(ZIFILE); /* Done, close the input file */
  4024. if (ofp != stdout) { /* Close any output file */
  4025. if (ofp) fclose(ofp);
  4026. ofp = stdout;
  4027. }
  4028. binary = save; /* Restore text/binary mode */
  4029. #ifdef UNICODE
  4030. ucsbom = ucsbom_sav; /* Restore BOM usage */
  4031. #endif /* UNICODE */
  4032. #ifdef KUI
  4033. if ( gui )
  4034. gui_text_popup_wait(-1); /* Wait for user to close the dialog */
  4035. #endif /* KUI */
  4036. return(rc);
  4037. }
  4038. /* GREP command */
  4039. #define GREP_CASE 0 /* /CASE */
  4040. #define GREP_COUN 1 /* /COUNT */
  4041. #define GREP_DOTF 2 /* /DOTFILES */
  4042. #define GREP_NAME 3 /* /NAMEONLY */
  4043. #define GREP_NOBK 4 /* /NOBACKUP */
  4044. #define GREP_NODO 5 /* /NODOTFILES */
  4045. #define GREP_NOLI 6 /* /NOLIST */
  4046. #define GREP_NOMA 7 /* /INVERT = /NOMATCH */
  4047. #define GREP_NOPA 8 /* /NOPAGE */
  4048. #define GREP_NUMS 9 /* /LINENUMBERS */
  4049. #define GREP_PAGE 10 /* /PAGE */
  4050. #define GREP_RECU 11 /* /RECURSIVE */
  4051. #define GREP_TYPE 12 /* /TYPE: */
  4052. #define GREP_OUTP 13 /* /OUTPUTFILE: */
  4053. #define GREP_EXCP 14 /* /EXCEPT: */
  4054. #define GREP_ARRA 15 /* /ARRAY: */
  4055. static struct keytab greptab[] = {
  4056. { "/array", GREP_ARRA, CM_ARG },
  4057. { "/count", GREP_COUN, CM_ARG },
  4058. { "/dotfiles", GREP_DOTF, 0 },
  4059. { "/except", GREP_EXCP, CM_ARG },
  4060. { "/linenumbers", GREP_NUMS, 0 },
  4061. { "/nameonly", GREP_NAME, 0 },
  4062. { "/nobackupfiles",GREP_NOBK, 0 },
  4063. { "/nocase", GREP_CASE, 0 },
  4064. { "/nodotfiles", GREP_NODO, 0 },
  4065. { "/nolist", GREP_NOLI, 0 },
  4066. { "/nomatch", GREP_NOMA, 0 },
  4067. { "/nopage", GREP_NOPA, 0 },
  4068. { "/output", GREP_OUTP, CM_ARG },
  4069. { "/page", GREP_PAGE, 0 },
  4070. { "/quiet", GREP_NOLI, CM_INV },
  4071. #ifdef RECURSIVE
  4072. { "/recursive", GREP_RECU, 0 },
  4073. #endif /* RECURSIVE */
  4074. { "/type", GREP_TYPE, CM_ARG },
  4075. { "", 0, 0 }
  4076. };
  4077. static int ngreptab = sizeof(greptab)/sizeof(struct keytab)-1;
  4078. static char * grep_except = NULL;
  4079. int
  4080. dogrep() {
  4081. int match, x, y, fc, getval, mc = 0, count = 0, bigcount = 0;
  4082. int fline = 0, sline = 0, wild = 0, len = 0;
  4083. int xmode = -1, scan = 0;
  4084. char c, name[CKMAXPATH+1], outfile[CKMAXPATH+1], *p, *s, *cv = NULL;
  4085. FILE * fp = NULL;
  4086. #ifndef NOSPL
  4087. char array = NUL;
  4088. char ** ap = NULL;
  4089. int arrayindex = 0;
  4090. #endif /* NOSPL */
  4091. int /* Switch values and defaults */
  4092. gr_coun = 0,
  4093. gr_name = 0,
  4094. gr_nobk = 0,
  4095. gr_case = 1,
  4096. gr_noli = 0,
  4097. gr_noma = 0,
  4098. gr_nums = 0,
  4099. gr_excp = 0,
  4100. gr_page = xaskmore;
  4101. struct FDB sw, fl;
  4102. g_matchdot = matchdot; /* Save global matchdot setting */
  4103. outfile[0] = NUL;
  4104. makestr(&grep_except,NULL);
  4105. if (ofp != stdout) { /* In case of previous interruption */
  4106. if (ofp) fclose(ofp);
  4107. ofp = stdout;
  4108. }
  4109. cmfdbi(&sw, /* First FDB - command switches */
  4110. _CMKEY, /* fcode */
  4111. "String or pattern to search for, or switch",
  4112. "", /* default */
  4113. "", /* addtl string data */
  4114. ngreptab, /* addtl numeric data 1: tbl size */
  4115. 4, /* addtl numeric data 2: 4 = cmswi */
  4116. xxstring, /* Processing function */
  4117. greptab, /* Keyword table */
  4118. &fl /* Pointer to next FDB */
  4119. );
  4120. cmfdbi(&fl, /* Anything that doesn't match */
  4121. _CMFLD, /* fcode */
  4122. "", /* hlpmsg */
  4123. "", /* default */
  4124. "", /* addtl string data */
  4125. 0, /* addtl numeric data 1 */
  4126. 0, /* addtl numeric data 2 */
  4127. xxstring, /* xxstring */
  4128. NULL,
  4129. NULL
  4130. );
  4131. while (1) { /* Parse 0 or more switches */
  4132. x = cmfdb(&sw); /* Parse something */
  4133. if (x < 0)
  4134. return(x);
  4135. if (cmresult.fcode != _CMKEY) /* Break out if not a switch */
  4136. break;
  4137. c = cmgbrk();
  4138. if ((getval = (c == ':' || c == '=')) && !(cmgkwflgs() & CM_ARG)) {
  4139. printf("?This switch does not take an argument\n");
  4140. return(-9);
  4141. }
  4142. if ((cmresult.nresult != GREP_COUN) && !getval &&
  4143. (cmgkwflgs() & CM_ARG)) {
  4144. printf("?This switch requires an argument\n");
  4145. return(-9);
  4146. }
  4147. switch (cmresult.nresult) {
  4148. case GREP_COUN: {
  4149. gr_coun++;
  4150. if (getval) {
  4151. if ((x = cmfld("Variable for result","",&s,NULL)) < 0)
  4152. return(x);
  4153. makestr(&cv,s);
  4154. }
  4155. break;
  4156. }
  4157. case GREP_CASE: gr_case=0; break;
  4158. case GREP_NAME: gr_name++; gr_noli=0; break;
  4159. case GREP_NOBK: gr_nobk++; break;
  4160. case GREP_NOLI: gr_noli++; gr_name=0; gr_nums=0; break;
  4161. case GREP_NOMA: gr_noma++; break;
  4162. case GREP_NOPA: gr_page=0; break;
  4163. case GREP_NUMS: gr_nums++; gr_noli=0; break;
  4164. case GREP_PAGE: gr_page++; gr_noli=0; break;
  4165. case GREP_NODO:
  4166. matchdot = 0;
  4167. break;
  4168. case GREP_DOTF:
  4169. matchdot = 1;
  4170. break;
  4171. case GREP_ARRA: {
  4172. char * s2;
  4173. if (c != ':' && c != '=') {
  4174. printf("?Array name required\n");
  4175. return(-9);
  4176. }
  4177. if ((x = cmfld("Array name (a single letter will do)",
  4178. "",
  4179. &s,
  4180. NULL
  4181. )) < 0) {
  4182. if (x == -3) {
  4183. printf("?Array name required\n");
  4184. return(-9);
  4185. } else
  4186. return(x);
  4187. }
  4188. if (!*s) {
  4189. printf("?Array name required\n");
  4190. return(-9);
  4191. }
  4192. s2 = s;
  4193. if (*s == CMDQ) s++;
  4194. if (*s == '&') s++;
  4195. if (!isalpha(*s)) {
  4196. printf("?Bad array name - \"%s\"\n",s2);
  4197. return(-9);
  4198. }
  4199. array = *s++;
  4200. if (isupper(array)) array = tolower(array);
  4201. if (*s && (*s != '[' || *(s+1) != ']')) {
  4202. printf("?Bad array name - \"%s\"\n",s2);
  4203. return(-9);
  4204. }
  4205. gr_name = 1;
  4206. break;
  4207. }
  4208. #ifdef RECURSIVE
  4209. case GREP_RECU:
  4210. recursive = 1;
  4211. break;
  4212. #endif /* RECURSIVE */
  4213. case GREP_TYPE: {
  4214. extern struct keytab txtbin[];
  4215. if ((x = cmkey(txtbin,3,"","",xxstring)) < 0)
  4216. return(x);
  4217. if (x == 2) { /* ALL */
  4218. xmode = -1;
  4219. } else { /* TEXT or BINARY only */
  4220. xmode = x;
  4221. scan = 1;
  4222. }
  4223. break;
  4224. }
  4225. case GREP_OUTP: /* Send output to file */
  4226. if ((x = cmofi("File for GREP'd lines","",&s,xxstring)) < 0)
  4227. return(x);
  4228. ckstrncpy(outfile,s,CKMAXPATH);
  4229. break;
  4230. case GREP_EXCP: /* Exception pattern */
  4231. if (getval) {
  4232. if ((x = cmfld("Exception pattern",
  4233. "",
  4234. &s,
  4235. xxstring
  4236. )) < 0)
  4237. return(x);
  4238. gr_excp++;
  4239. makestr(&grep_except,s);
  4240. }
  4241. }
  4242. }
  4243. if (outfile[0]) {
  4244. ofp = fopen(outfile,"w"); /* Open output file */
  4245. if (!ofp) {
  4246. printf("?Can't open output file %s: %s\n",outfile,ck_errstr());
  4247. ofp = stdout;
  4248. return(-9);
  4249. }
  4250. gr_page = 0;
  4251. }
  4252. s = cmresult.sresult;
  4253. s = brstrip(s); /* Strip braces from pattern */
  4254. if (!*s) {
  4255. printf("?Pattern required\n");
  4256. return(-9);
  4257. }
  4258. ckstrncpy(tmpbuf,s,TMPBUFSIZ); /* Save pattern */
  4259. if ((x = cmifi("File(s) to search","",&s,&wild,xxstring)) < 0) {
  4260. if (x == -3) {
  4261. printf("?File specification required\n");
  4262. x = -9;
  4263. }
  4264. return(x);
  4265. }
  4266. s = brstrip(s); /* Strip braces from filename */
  4267. #ifndef ZXREWIND
  4268. ckstrncpy(line,s,LINBUFSIZ);
  4269. #endif /* ZXREWIND */
  4270. if ((y = cmcfm()) < 0)
  4271. return(y);
  4272. if (gr_page > -1)
  4273. xaskmore = gr_page; /* Paging... */
  4274. p = tmpbuf; /* Point to pattern */
  4275. #ifdef COMMENT
  4276. /* Now this is done in ckmatch */
  4277. if (*p == '^') { /* '^' anchors pattern to beginning */
  4278. p++;
  4279. } else if (*p != '*') { /* Otherwise prepend implied '*' */
  4280. tmpbuf[0] = '*';
  4281. p = tmpbuf;
  4282. }
  4283. x = strlen(p); /* Get length of result */
  4284. if (x > 0 && x < TMPBUFSIZ) { /* '$' at end anchors pattern to end */
  4285. if (p[x-1] == '$') {
  4286. p[x-1] = NUL;
  4287. } else if (p[x-1] != '*') {
  4288. p[x] = '*';
  4289. p[x+1] = NUL;
  4290. }
  4291. }
  4292. #endif /* COMMENT */
  4293. debug(F111,"grep pat",p,x);
  4294. #ifdef ZXREWIND
  4295. fc = zxrewind(); /* Rewind the file list */
  4296. #else
  4297. {
  4298. int flags = ZX_FILONLY; /* Expand file list */
  4299. if (matchdot) flags |= ZX_MATCHDOT;
  4300. if (recursive) flags |= ZX_RECURSE;
  4301. fc = nzxpand(line,flags);
  4302. }
  4303. #endif /* ZXREWIND */
  4304. #ifndef NOSPL
  4305. if (array) {
  4306. int n, xx;
  4307. n = (fc < 0) ? 0 : fc;
  4308. if ((xx = dclarray(array,n)) < 0) {
  4309. printf("?Array declaration failure\n");
  4310. mc = 0;
  4311. goto xgrep;
  4312. }
  4313. arrayindex = 0;
  4314. ap = a_ptr[xx]; /* Pointer to list of elements */
  4315. if (ap) /* Set element 0 to dimension */
  4316. makestr(&(ap[0]),"0"); /* which so far is zero */
  4317. if (n < 1) { /* No files matched, done. */
  4318. mc = 0;
  4319. goto xgrep;
  4320. }
  4321. }
  4322. #endif /* NOSPL */
  4323. #ifdef UNIX
  4324. sh_sort(mtchs,NULL,fc,0,0,filecase);
  4325. #endif /* UNIX */
  4326. debug(F101,"grep cmd_rows","",cmd_rows);
  4327. debug(F101,"grep cmd_cols","",cmd_cols);
  4328. while (1) { /* Loop for each file */
  4329. znext(name); /* Get next file */
  4330. if (!name[0]) /* No more, done */
  4331. break;
  4332. if (gr_nobk) /* Skipping backup files? */
  4333. if (ckmatch("*.~[1-9]*~",name,1,1)) /* Backup file? */
  4334. continue; /* Yes, skip */
  4335. if (scan) { /* /TYPE: given? */
  4336. switch (scanfile(name,&y,nscanfile)) { /* Yes, scan the file */
  4337. case FT_BIN:
  4338. if (xmode != 1)
  4339. continue;
  4340. break;
  4341. case FT_TEXT:
  4342. case FT_7BIT:
  4343. case FT_8BIT:
  4344. #ifdef UNICODE
  4345. case FT_UTF8:
  4346. case FT_UCS2:
  4347. #endif /* UNICODE */
  4348. if (xmode != 0)
  4349. continue;
  4350. }
  4351. }
  4352. fp = fopen(name,"r"); /* Open */
  4353. if (!fp) /* Can't */
  4354. continue; /* Skip */
  4355. count = 0; /* Match count, this file */
  4356. fline = 0; /* Line count, this file */
  4357. while (1) { /* Loop for each line */
  4358. if (fgets(line,LINBUFSIZ,fp) == NULL) { /* Get next line */
  4359. fclose(fp);
  4360. fp = NULL;
  4361. debug(F100,"GREP EOF","",0);
  4362. break;
  4363. }
  4364. fline++; /* Count this line */
  4365. line[LINBUFSIZ] = NUL; /* Make sure it's terminated */
  4366. debug(F111,"GREP",line,fline);
  4367. len = (int)strlen(line); /* Get length */
  4368. while (len > 0 && (line[len-1] == '\n' || line[len-1] == '\r'))
  4369. line[--len] = NUL; /* Chop off terminators */
  4370. match = ckmatch(p,line,gr_case,1+4); /* Match against pattern */
  4371. if (match && gr_excp) {
  4372. if (ckmatch(grep_except,line,gr_case,1+4))
  4373. match = 0;
  4374. }
  4375. if (gr_noma) /* Invert match sense if requested */
  4376. match = !match;
  4377. if (match) { /* Have a matching line */
  4378. mc++; /* Total match count */
  4379. count++; /* Match count this file */
  4380. if (gr_name) { /* Don't care how many lines match */
  4381. fclose(fp); /* Close the file */
  4382. fp = NULL; /* and quit the line-reading loop. */
  4383. break;
  4384. }
  4385. if (gr_coun || gr_noli) /* Not listing each line */
  4386. continue; /* so don't print anything now. */
  4387. if (wild) { /* If searching multiple files */
  4388. fprintf(ofp,"%s:",name); /* print filename. */
  4389. len += (int)strlen(name) + 1;
  4390. }
  4391. if (gr_nums) { /* If line numbers wanted */
  4392. char nbuf[32];
  4393. len += ckmakmsg(nbuf,32,ckitoa(fline),":",NULL,NULL);
  4394. fprintf(ofp,"%s",nbuf);
  4395. }
  4396. if (cmd_rows > 0 && cmd_cols > 0)
  4397. sline += (len / cmd_cols) + 1;
  4398. fprintf(ofp,"%s\n",line); /* Print the line. */
  4399. if (sline > cmd_rows - 3) {
  4400. if (!askmore()) goto xgrep; else sline = 0;
  4401. }
  4402. }
  4403. }
  4404. if (!gr_noli) { /* If not not listing... */
  4405. x = 0;
  4406. if (gr_coun) { /* Show match count only */
  4407. fprintf(ofp,"%s:%d\n",name,count);
  4408. x++;
  4409. } else if (gr_name && count > 0) { /* Show name only */
  4410. if (array) {
  4411. if (ap) {
  4412. makestr(&(ap[arrayindex++]),name);
  4413. }
  4414. } else {
  4415. fprintf(ofp,"%s\n",name);
  4416. x++;
  4417. }
  4418. }
  4419. if (x > 0) {
  4420. if (++sline > cmd_rows - 3) {
  4421. if (!askmore()) goto xgrep; else sline = 0;
  4422. }
  4423. }
  4424. }
  4425. bigcount += count; /* Overall count */
  4426. }
  4427. xgrep:
  4428. #ifndef NOSPL
  4429. if (array) if (ap) makestr(&(ap[0]),ckitoa(arrayindex));
  4430. if (gr_coun && cv) { /* /COUNT:blah */
  4431. addmac(cv,ckitoa(bigcount)); /* set the variable */
  4432. makestr(&cv,NULL); /* free this */
  4433. }
  4434. #endif /* NOSPL */
  4435. if (fp) fclose(fp); /* close input file if still open */
  4436. if (ofp != stdout) { /* Close any output file */
  4437. if (ofp) fclose(ofp);
  4438. ofp = stdout;
  4439. }
  4440. return(success = mc ? 1 : 0);
  4441. }
  4442. /* System-independent directory */
  4443. static char ** dirlist = NULL;
  4444. static int ndirlist = 0;
  4445. static VOID
  4446. freedirlist() {
  4447. if (dirlist) {
  4448. int i;
  4449. for (i = 0; i < ndirlist; i++) {
  4450. if (dirlist[i])
  4451. free(dirlist[i]);
  4452. }
  4453. free((char *)dirlist);
  4454. dirlist = NULL;
  4455. }
  4456. ndirlist = 0;
  4457. }
  4458. static struct keytab dirswtab[] = { /* DIRECTORY command switches */
  4459. { "/after", DIR_AFT, CM_ARG },
  4460. { "/all", DIR_ALL, 0 },
  4461. #ifndef NOSPL
  4462. { "/array", DIR_ARR, CM_ARG },
  4463. #endif /* NOSPL */
  4464. { "/ascending", DIR_ASC, 0 },
  4465. { "/backup", DIR_BUP, 0 },
  4466. { "/before", DIR_BEF, CM_ARG },
  4467. { "/brief", DIR_BRF, 0 },
  4468. { "/count", DIR_COU, CM_ARG },
  4469. { "/descending", DIR_DSC, CM_INV },
  4470. { "/directories", DIR_DIR, 0 },
  4471. { "/dotfiles", DIR_DOT, 0 },
  4472. { "/englishdate", DIR_DAT, 0 },
  4473. { "/except", DIR_EXC, CM_ARG },
  4474. { "/files", DIR_FIL, 0 },
  4475. #ifdef CKSYMLINK
  4476. { "/followlinks", DIR_LNK, 0 },
  4477. #endif /* CKSYMLINK */
  4478. { "/heading", DIR_HDG, 0 },
  4479. { "/isodate", DIR_ISO, 0 },
  4480. { "/larger-than", DIR_LAR, CM_ARG },
  4481. { "/message", DIR_MSG, CM_ARG },
  4482. { "/nobackupfiles",DIR_NOB, 0 },
  4483. { "/nodotfiles", DIR_NOD, 0 },
  4484. #ifdef CKSYMLINK
  4485. { "/nofollowlinks",DIR_NLK, 0 },
  4486. #endif /* CKSYMLINK */
  4487. { "/noheading", DIR_NOH, 0 },
  4488. #ifdef CKSYMLINK
  4489. { "/nolinks", DIR_NOL, 0 },
  4490. #endif /* CKSYMLINK */
  4491. { "/nomessage", DIR_NOM, 0 },
  4492. #ifdef CK_TTGWSIZ
  4493. { "/nopage", DIR_NOP, 0 },
  4494. #endif /* CK_TTGWSIZ */
  4495. #ifdef RECURSIVE
  4496. { "/norecursive", DIR_NOR, 0 },
  4497. #else
  4498. #ifdef VMS
  4499. { "/norecursive", DIR_NOR, 0 },
  4500. #else
  4501. #ifdef datageneral
  4502. { "/norecursive", DIR_NOR, 0 },
  4503. #endif /* datageneral */
  4504. #endif /* VMS */
  4505. #endif /* RECURSIVE */
  4506. { "/nosort", DIR_NOS, 0 },
  4507. { "/not-after", DIR_NAF, CM_ARG },
  4508. { "/not-before", DIR_NBF, CM_ARG },
  4509. { "/not-since", DIR_NAF, CM_INV|CM_ARG },
  4510. { "/noxfermode", DIR_NOT, 0 },
  4511. { "/output", DIR_OUT, CM_ARG },
  4512. #ifdef CK_TTGWSIZ
  4513. { "/page", DIR_PAG, 0 },
  4514. #endif /* CK_TTGWSIZ */
  4515. #ifdef RECURSIVE
  4516. { "/recursive", DIR_REC, 0 },
  4517. #else
  4518. #ifdef VMS
  4519. { "/recursive", DIR_REC, 0 },
  4520. #else
  4521. #ifdef datageneral
  4522. { "/recursive", DIR_REC, 0 },
  4523. #endif /* datageneral */
  4524. #endif /* VMS */
  4525. #endif /* RECURSIVE */
  4526. { "/reverse", DIR_DSC, 0 },
  4527. { "/since", DIR_AFT, CM_ARG|CM_INV },
  4528. { "/smaller-than",DIR_SMA, CM_ARG },
  4529. { "/sort", DIR_SRT, CM_ARG },
  4530. { "/summary", DIR_SUM, 0 },
  4531. { "/top", DIR_TOP, CM_ARG },
  4532. { "/type", DIR_BIN, CM_ARG },
  4533. { "/xfermode", DIR_TYP, 0 },
  4534. { "/verbose", DIR_VRB, 0 },
  4535. { "",0,0 }
  4536. };
  4537. static int ndirswtab = (sizeof(dirswtab) / sizeof(struct keytab)) - 1;
  4538. static struct keytab dirsort[] = { /* DIRECTORY /SORT: options */
  4539. { "date", DIRS_DT, 0 },
  4540. { "name", DIRS_NM, 0 },
  4541. { "size", DIRS_SZ, 0 }
  4542. };
  4543. static int ndirsort = (sizeof(dirsort) / sizeof(struct keytab));
  4544. static struct keytab touchswtab[] = { /* TOUCH command switches */
  4545. { "/after", DIR_AFT, CM_ARG },
  4546. { "/all", DIR_ALL, 0 },
  4547. { "/backup", DIR_BUP, 0 },
  4548. { "/before", DIR_BEF, CM_ARG },
  4549. { "/count", DIR_COU, CM_ARG },
  4550. { "/directories", DIR_DIR, 0 },
  4551. { "/dotfiles", DIR_DOT, 0 },
  4552. { "/except", DIR_EXC, CM_ARG },
  4553. { "/files", DIR_FIL, 0 },
  4554. #ifdef CKSYMLINK
  4555. { "/followlinks", DIR_LNK, 0 },
  4556. #endif /* CKSYMLINK */
  4557. { "/larger-than", DIR_LAR, CM_ARG },
  4558. { "/list", DIR_VRB, 0 },
  4559. { "/modtime", DIR_MOD, CM_ARG },
  4560. { "/nobackupfiles",DIR_NOB, 0 },
  4561. { "/nodotfiles", DIR_NOD, 0 },
  4562. #ifdef CKSYMLINK
  4563. { "/nofollowlinks",DIR_NLK, 0 },
  4564. #endif /* CKSYMLINK */
  4565. #ifdef CKSYMLINK
  4566. { "/nolinks", DIR_NOL, 0 },
  4567. #endif /* CKSYMLINK */
  4568. #ifdef CK_TTGWSIZ
  4569. #endif /* CK_TTGWSIZ */
  4570. #ifdef RECURSIVE
  4571. { "/norecursive", DIR_NOR, 0 },
  4572. #else
  4573. #ifdef VMS
  4574. { "/norecursive", DIR_NOR, 0 },
  4575. #else
  4576. #ifdef datageneral
  4577. { "/norecursive", DIR_NOR, 0 },
  4578. #endif /* datageneral */
  4579. #endif /* VMS */
  4580. #endif /* RECURSIVE */
  4581. { "/not-after", DIR_NAF, CM_ARG },
  4582. { "/not-before", DIR_NBF, CM_ARG },
  4583. { "/not-since", DIR_NAF, CM_INV|CM_ARG },
  4584. #ifdef RECURSIVE
  4585. { "/recursive", DIR_REC, 0 },
  4586. #else
  4587. #ifdef VMS
  4588. { "/recursive", DIR_REC, 0 },
  4589. #else
  4590. #ifdef datageneral
  4591. { "/recursive", DIR_REC, 0 },
  4592. #endif /* datageneral */
  4593. #endif /* VMS */
  4594. #endif /* RECURSIVE */
  4595. { "/simulate", DIR_SIM, 0 },
  4596. { "/since", DIR_AFT, CM_ARG|CM_INV },
  4597. { "/smaller-than",DIR_SMA, CM_ARG },
  4598. { "/type", DIR_BIN, CM_ARG },
  4599. { "/verbose", DIR_VRB, CM_INV },
  4600. { "",0,0 }
  4601. };
  4602. static int ntouchswtab = (sizeof(touchswtab) / sizeof(struct keytab)) - 1;
  4603. static struct keytab changeswtab[] = { /* CHANGE command switches */
  4604. { "/after", DIR_AFT, CM_ARG },
  4605. { "/backup", DIR_BAK, CM_ARG },
  4606. { "/before", DIR_BEF, CM_ARG },
  4607. { "/case", 7777, CM_ARG },
  4608. { "/count", DIR_COU, CM_ARG },
  4609. { "/destination", DIR_DES, CM_ARG },
  4610. { "/dotfiles", DIR_DOT, 0 },
  4611. { "/except", DIR_EXC, CM_ARG },
  4612. { "/larger-than", DIR_LAR, CM_ARG },
  4613. { "/list", DIR_VRB, 0 },
  4614. { "/modtime", DIR_MOD, CM_ARG },
  4615. { "/nodotfiles", DIR_NOD, 0 },
  4616. #ifdef RECURSIVE
  4617. { "/norecursive", DIR_NOR, 0 },
  4618. #endif /* RECURSIVE */
  4619. { "/not-after", DIR_NAF, CM_ARG },
  4620. { "/not-before", DIR_NBF, CM_ARG },
  4621. { "/not-since", DIR_NAF, CM_INV|CM_ARG },
  4622. #ifdef RECURSIVE
  4623. { "/recursive", DIR_REC, 0 },
  4624. #endif /* RECURSIVE */
  4625. { "/simulate", DIR_SIM, 0 },
  4626. { "/since", DIR_AFT, CM_ARG|CM_INV },
  4627. { "/smaller-than",DIR_SMA, CM_ARG },
  4628. { "/verbose", DIR_VRB, CM_INV },
  4629. { "",0,0 }
  4630. };
  4631. static int nchangeswtab = (sizeof(changeswtab) / sizeof(struct keytab)) - 1;
  4632. #define CHMT_U 0 /* CHANGE command modtime options */
  4633. #define CHMT_P 1
  4634. static struct keytab chmttab[] = {
  4635. { "preserve", CHMT_P, 0 },
  4636. { "update", CHMT_U, 0 }
  4637. };
  4638. static int nchmttab = 2;
  4639. static int dir_date = -1; /* Option defaults (-1 means none) */
  4640. static int dir_page = -1;
  4641. static int dir_verb = 1;
  4642. static int dir_msg = -1;
  4643. #ifdef VMS
  4644. static int dir_sort = -1; /* Names are already sorted in VMS */
  4645. static int dir_rvrs = -1;
  4646. #else
  4647. static int dir_sort = 1; /* Sort by default */
  4648. static int dir_rvrs = 0; /* Not in reverse */
  4649. #endif /* VMS */
  4650. static int dir_skey = DIRS_NM; /* By name */
  4651. #ifdef RECURSIVE
  4652. static int dir_recu = -1;
  4653. #endif /* RECURSIVE */
  4654. static int dir_mode = -1;
  4655. static int dir_show = -1; /* Show all files by default */
  4656. int dir_dots = -1; /* Except dot files */
  4657. int dir_back = 1;
  4658. int dir_head = 0;
  4659. static char * dirmsg = NULL;
  4660. static int dirmsglen = 0;
  4661. #ifndef NOSHOW
  4662. VOID
  4663. showdiropts() {
  4664. int x = 0;
  4665. extern int optlines;
  4666. prtopt(&optlines,"DIRECTORY");
  4667. if (dir_show > 0) {
  4668. prtopt(&optlines,(dir_show == 1) ? "/FILES" :
  4669. ((dir_show == 2) ? "/DIRECTORIES" : "/ALL"));
  4670. x++;
  4671. } else {
  4672. prtopt(&optlines,"/ALL");
  4673. x++;
  4674. }
  4675. if (dir_verb > -1) {
  4676. prtopt(&optlines,dir_verb ? "/VERBOSE" : "/BRIEF");
  4677. x++;
  4678. }
  4679. if (dir_page > -1) {
  4680. prtopt(&optlines,dir_page ? "/PAGE" : "/NOPAGE");
  4681. x++;
  4682. }
  4683. if (dir_date > -1) {
  4684. prtopt(&optlines,dir_date ? "/ENGLISHDATE" : "/ISODATE");
  4685. x++;
  4686. }
  4687. if (dir_dots > -1) {
  4688. prtopt(&optlines,dir_dots ? "/DOTFILES" : "/NODOTFILES");
  4689. x++;
  4690. }
  4691. if (dir_back > -1) {
  4692. prtopt(&optlines,dir_back ? "/BACKUP" : "/NOBACKUP");
  4693. x++;
  4694. }
  4695. if (dir_head > -1) {
  4696. prtopt(&optlines,dir_head ? "/HEADING" : "/NOHEADING");
  4697. x++;
  4698. }
  4699. #ifdef RECURSIVE
  4700. if (dir_recu > -1) {
  4701. prtopt(&optlines,dir_recu ? "/RECURSIVE" : "/NORECURSIVE");
  4702. x++;
  4703. }
  4704. #endif /* RECURSIVE */
  4705. if (dir_mode > -1) {
  4706. prtopt(&optlines,dir_mode ? "/XFERMODE" : "/NOXFERMODE");
  4707. x++;
  4708. }
  4709. if (dir_sort == 0) {
  4710. x++;
  4711. prtopt(&optlines,"/NOSORT ");
  4712. } else if (dir_sort > 0) {
  4713. x++;
  4714. if (dir_skey == DIRS_NM) s = "/SORT:NAME";
  4715. else if (dir_skey == DIRS_SZ) s = "/SORT:SIZE";
  4716. else if (dir_skey == DIRS_DT) s = "/SORT:DATE";
  4717. prtopt(&optlines,s);
  4718. }
  4719. if (dir_rvrs > -1) {
  4720. prtopt(&optlines,dir_rvrs ? "/REVERSE" : "/ASCENDING");
  4721. x++;
  4722. }
  4723. if (dir_msg > -1) {
  4724. if (dir_msg == 0) {
  4725. prtopt(&optlines,"/NOMESSAGE");
  4726. } else {
  4727. ckmakmsg(tmpbuf,TMPBUFSIZ,"/MESSAGE:{",dirmsg,"}",NULL);
  4728. prtopt(&optlines,tmpbuf);
  4729. }
  4730. x++;
  4731. }
  4732. if (!x) prtopt(&optlines,"(no options set)");
  4733. prtopt(&optlines,"");
  4734. }
  4735. #endif /* NOSHOW */
  4736. int
  4737. setdiropts() { /* Set DIRECTORY option defaults */
  4738. int xb = -1, xv = -1, xp = -1, xd = -1, xh = -1, xf = -1;
  4739. int xk = -1, xr = -1, xs = -1, xx = -1, xm = -1, xa = -1, xg = -1;
  4740. int getval;
  4741. char c;
  4742. while (1) {
  4743. if ((y = cmswi(dirswtab,ndirswtab,"Switch","",xxstring)) < 0) {
  4744. if (y == -3)
  4745. break;
  4746. else
  4747. return(y);
  4748. }
  4749. c = cmgbrk();
  4750. if ((getval = (c == ':' || c == '=')) && !(cmgkwflgs() & CM_ARG)) {
  4751. printf("?This switch does not take an argument\n");
  4752. return(-9);
  4753. }
  4754. if (!getval && (cmgkwflgs() & CM_ARG)) {
  4755. printf("?This switch requires an argument\n");
  4756. return(-9);
  4757. }
  4758. switch (y) {
  4759. case DIR_BRF: xv = 0; break;
  4760. case DIR_VRB: xv = 1; break;
  4761. case DIR_PAG: xp = 1; break;
  4762. case DIR_NOP: xp = 0; break;
  4763. case DIR_ISO: xd = 0; break;
  4764. case DIR_DAT: xd = 1; break;
  4765. case DIR_HDG: xh = 1; break;
  4766. case DIR_NOH: xh = 0; break;
  4767. case DIR_DOT: xf = 1; break;
  4768. case DIR_NOD: xf = 0; break;
  4769. case DIR_ALL: xa = 3; break;
  4770. case DIR_DIR: xa = 2; break;
  4771. case DIR_FIL: xa = 1; break;
  4772. case DIR_SRT:
  4773. x = DIRS_NM;
  4774. if (getval)
  4775. if ((x = cmkey(dirsort,ndirsort,"Sort key","name",xxstring)) < 0)
  4776. return(x);
  4777. xk = x;
  4778. xs = 1;
  4779. break;
  4780. case DIR_NOS: xs = 0; break;
  4781. case DIR_ASC: xx = 0; break;
  4782. case DIR_DSC: xx = 1; break;
  4783. case DIR_REC: xr = 1; break;
  4784. case DIR_NOR: xr = 0; break;
  4785. case DIR_TYP: xm = 1; break;
  4786. case DIR_NOT: xm = 0; break;
  4787. case DIR_BUP: xb = 1; break;
  4788. case DIR_NOB: xb = 0; break;
  4789. case DIR_NOM: xg = 0; break;
  4790. case DIR_MSG:
  4791. if (getval)
  4792. if ((x = cmfld("Message to append to each line",
  4793. "",
  4794. &s,
  4795. xxstring
  4796. )) < 0)
  4797. return(x);
  4798. xg = 1;
  4799. ckstrncpy(tmpbuf,brstrip(s),TMPBUFSIZ);
  4800. break;
  4801. default:
  4802. printf("?This option can not be set\n");
  4803. return(-9);
  4804. }
  4805. }
  4806. if ((x = cmcfm()) < 0) /* Get confirmation */
  4807. return(x);
  4808. if (xv > -1) dir_verb = xv; /* Confirmed, save defaults */
  4809. if (xp > -1) dir_page = xp;
  4810. if (xd > -1) dir_date = xd;
  4811. if (xh > -1) dir_head = xh;
  4812. if (xs > -1) dir_sort = xs;
  4813. if (xk > -1) dir_skey = xk;
  4814. if (xx > -1) dir_rvrs = xx;
  4815. if (xf > -1) dir_dots = xf;
  4816. if (xa > -1) dir_show = xa;
  4817. if (xm > -1) dir_mode = xm;
  4818. if (xb > -1) dir_back = xb;
  4819. #ifdef RECURSIVE
  4820. if (xr > -1) dir_recu = xr;
  4821. #endif /* RECURSIVE */
  4822. if (xg > -1) dir_msg = xg;
  4823. if (xg > 0)
  4824. makestr(&dirmsg,tmpbuf);
  4825. return(success = 1);
  4826. }
  4827. int
  4828. domydir(cx) int cx; { /* Internal DIRECTORY command */
  4829. extern char *months[], *tempdir;
  4830. #ifdef VMS
  4831. _PROTOTYP( char * zrelname, (char *,char *) );
  4832. char * cdp = NULL;
  4833. #endif /* VMS */
  4834. struct zattr xxstruct;
  4835. int chmtopt = CHMT_U;
  4836. char name[CKMAXPATH+1], outfile[CKMAXPATH+1], *p = NULL, c = NUL;
  4837. char linebuf[CKMAXPATH+CKMAXPATH+256];
  4838. char string1[1024], string2[1024]; /* For CHANGE */
  4839. char modtime[100];
  4840. char * mstr = NULL, * dstr = NULL, * s2 = NULL, * cv = NULL;
  4841. CK_OFF_T len = (CK_OFF_T)0, nbytes = (CK_OFF_T)0;
  4842. CK_OFF_T minsize = (CK_OFF_T)-1, maxsize = (CK_OFF_T)-1;
  4843. long ndirs = 0, nfiles = 0, nmatches = 0;
  4844. int verbose = 0, wild = 0, page = 0, n = 0, engdate = 0, summary = 0;
  4845. int heading = 0, xsort = 0, reverse = 0, sortby = 0, msg = 0;
  4846. int k, i = 0, x = 0, nx = 0, skey = 0, dlen = 0, itsadir = 0;
  4847. int show = 3, xfermod = 0, backup = 1, rc = 0, getval = 0;
  4848. int touch = 0;
  4849. int change = 0; /* Doing CHANGE command */
  4850. int chcase = 0; /* CHANGE case dependence */
  4851. int s1len = 0; /* CHANGE string1 length */
  4852. int s2len = 0; /* CHANGE string2 length */
  4853. int fs = 0;
  4854. int multiple = 0;
  4855. int cmifn1 = 1, cmifn2 = 0;
  4856. int dir_top = 0, dir_cou = 0;
  4857. int dontshowlinks = 0;
  4858. int dontfollowlinks = 0;
  4859. int arrayindex = -1;
  4860. int simulate = 0;
  4861. struct FDB sw, fi, fl;
  4862. char dbuf[256], xbuf[32];
  4863. int reallysort = 0;
  4864. int changeinplace = 0;
  4865. int changebackup = 0;
  4866. int changes = 0; /* Change counter per file */
  4867. int totalchanges = 0; /* Change counter all files */
  4868. #ifndef NOSPL
  4869. char array = NUL;
  4870. char ** ap = NULL;
  4871. #endif /* NOSPL */
  4872. char
  4873. * dir_aft = NULL,
  4874. * dir_bef = NULL,
  4875. * dir_naf = NULL,
  4876. * dir_nbf = NULL,
  4877. * dir_exc = NULL;
  4878. char * xlist[16];
  4879. debug(F101,"domydir cx","",cx);
  4880. chgsourcedir[0] = NUL; /* CHANGE source directory */
  4881. chgdestdir[0] = NUL; /* CHANGE destination directory */
  4882. chgbackupdir[0] = NUL; /* CHANGE backup directory */
  4883. changeinplace = 1; /* CHANGE'ing files in place */
  4884. changebackup = 0; /* Backing up CHANGEd files */
  4885. changes = 0;
  4886. totalchanges = 0;
  4887. g_matchdot = matchdot; /* Save global matchdot setting */
  4888. #ifdef COMMENT
  4889. nolinks = 2; /* (it should already be 2) */
  4890. #endif /* COMMENT */
  4891. outfile[0] = NUL; /* No output file yet */
  4892. modtime[0] = '\0'; /* Initialize TOUCH /MODTIME */
  4893. if (ofp != stdout) { /* In case of previous interruption */
  4894. if (ofp) fclose(ofp);
  4895. ofp = stdout;
  4896. }
  4897. for (i = 0; i < 16; i++) xlist[i] = NULL;
  4898. dir_top = 0;
  4899. name[0] = NUL;
  4900. freedirlist(); /* In case not freed last time */
  4901. page = dir_page > -1 ? dir_page : xaskmore; /* Set option defaults */
  4902. engdate = dir_date > -1 ? dir_date : 0;
  4903. verbose = dir_verb > -1 ? dir_verb : 1;
  4904. heading = dir_head > -1 ? dir_head : 0;
  4905. xsort = dir_sort > -1 ? dir_sort : 0;
  4906. sortby = dir_skey > -1 ? dir_skey : 0;
  4907. reverse = dir_rvrs > -1 ? dir_rvrs : 0;
  4908. msg = dir_msg > -1 ? dir_msg : 0;
  4909. #ifdef UNIXOROSK
  4910. if (dir_dots > -1) matchdot = dir_dots;
  4911. #endif /* UNIXOROSK */
  4912. xfermod = dir_mode > -1 ? dir_mode : 0;
  4913. backup = dir_back > -1 ? dir_back : 1;
  4914. #ifdef RECURSIVE
  4915. recursive = dir_recu > -1 ? dir_recu : 0;
  4916. #endif /* RECURSIVE */
  4917. show = dir_show > -1 ? dir_show : 3;
  4918. diractive = 1; /* This is a DIRECTORY command */
  4919. switch (cx) {
  4920. case XXWDIR: /* WDIRECTORY */
  4921. debug(F100,"domydir WDIRECTORY","",0);
  4922. reverse = 1; /* Reverse chronological order */
  4923. xsort = 1;
  4924. sortby = DIRS_DT;
  4925. break;
  4926. case XXHDIR: /* HDIRECTORY */
  4927. debug(F100,"domydir HDIRECTORY","",0);
  4928. reverse = 1; /* Reverse order by size */
  4929. xsort = 1;
  4930. sortby = DIRS_SZ;
  4931. break;
  4932. case XXTOUC:
  4933. diractive = 0; /* This is NOT a DIRECTORY command */
  4934. touch = 1;
  4935. verbose = 0;
  4936. break;
  4937. case XXCHG: /* CHANGE 2013-04-18 */
  4938. diractive = 0; /* This is NOT a DIRECTORY command */
  4939. change = 1;
  4940. verbose = 0;
  4941. }
  4942. #ifdef CK_TTGWSIZ
  4943. #ifdef OS2
  4944. ttgcwsz(); /* Screen length for more-prompting */
  4945. #else /* OS2 */
  4946. /* Check whether window size changed */
  4947. if (ttgwsiz() > 0) {
  4948. if (tt_rows > 0 && tt_cols > 0) {
  4949. cmd_rows = tt_rows;
  4950. cmd_cols = tt_cols;
  4951. }
  4952. }
  4953. #endif /* OS2 */
  4954. #endif /* CK_TTGWSIZ */
  4955. cmifn1 = nolinks | 1; /* 1 = files or directories */
  4956. cmifn2 = 0; /* 0 = not directories only */
  4957. again:
  4958. cmfdbi(&sw, /* First FDB - command switches */
  4959. _CMKEY, /* fcode */
  4960. "Enter or Return to confirm the command, or\n\
  4961. file specification, or switch",
  4962. "", /* default */
  4963. "", /* addtl string data */
  4964. touch ? ntouchswtab : (change ? nchangeswtab : ndirswtab),
  4965. 4, /* addtl numeric data 2: 4 = cmswi */
  4966. xxstring, /* Processing function */
  4967. touch ? touchswtab : (change ? changeswtab : dirswtab),
  4968. &fi /* Pointer to next FDB */
  4969. );
  4970. cmfdbi(&fi, /* 2nd FDB - filespec to match */
  4971. _CMIFI, /* fcode */
  4972. "File specification", /* hlpmsg */
  4973. #ifdef datageneral
  4974. "+", /* Default filespec is wildcard */
  4975. #else /* that matches all files... */
  4976. #ifdef VMS
  4977. "*.*",
  4978. #else
  4979. "*",
  4980. #endif /* VMS */
  4981. #endif /* datageneral */
  4982. "", /* addtl string data */
  4983. cmifn1,
  4984. cmifn2, /* 1 = only dirs; 0 files or dirs */
  4985. xxstring,
  4986. NULL,
  4987. &fl
  4988. );
  4989. cmfdbi(&fl, /* Anything that doesn't match */
  4990. _CMFLD, /* fcode */
  4991. "", /* hlpmsg */
  4992. "", /* default */
  4993. "", /* addtl string data */
  4994. 0, /* addtl numeric data 1 */
  4995. 0, /* addtl numeric data 2 */
  4996. xxstring,
  4997. NULL,
  4998. NULL
  4999. );
  5000. while (1) { /* Parse 0 or more switches */
  5001. x = cmfdb(&sw); /* Parse something */
  5002. debug(F101,"domydir cmfdb","",x);
  5003. if (x < 0)
  5004. return(x);
  5005. if (cmresult.fcode != _CMKEY) /* Break out if not a switch */
  5006. break;
  5007. c = cmgbrk();
  5008. if ((getval = (c == ':' || c == '=')) && !(cmgkwflgs() & CM_ARG)) {
  5009. printf("?This switch does not take an argument\n");
  5010. return(-9);
  5011. }
  5012. k = cmresult.nresult;
  5013. if (!getval &&
  5014. (cmgkwflgs() & CM_ARG) && k != DIR_TOP && k != DIR_COU) {
  5015. printf("?This switch requires an argument\n");
  5016. return(-9);
  5017. }
  5018. switch (k) {
  5019. case DIR_COU: {
  5020. dir_cou++;
  5021. if (getval) {
  5022. if ((x = cmfld("Variable for result","",&s,NULL)) < 0)
  5023. return(x);
  5024. makestr(&cv,s);
  5025. }
  5026. break;
  5027. }
  5028. case DIR_BRF: verbose = 0; break;
  5029. case DIR_VRB: verbose = 1; break;
  5030. #ifdef CK_TTGWSIZ
  5031. case DIR_PAG: page = 1; break;
  5032. case DIR_NOP: page = 0; break;
  5033. #endif /* CK_TTGWSIZ */
  5034. case DIR_ISO: engdate = 0; break;
  5035. case DIR_DAT: engdate = 1; break;
  5036. case DIR_HDG: heading = 1; break;
  5037. case DIR_NOH: heading = 0; break;
  5038. #ifdef UNIXOROSK
  5039. case DIR_DOT: matchdot = 1; break;
  5040. case DIR_NOD: matchdot = 0; break;
  5041. #endif /* UNIXOROSK */
  5042. case DIR_ALL:
  5043. show = 3;
  5044. cmifn1 |= 1;
  5045. cmifn2 = 0;
  5046. goto again;
  5047. case DIR_DIR:
  5048. show = 2;
  5049. cmifn1 |= 1;
  5050. cmifn2 = 1;
  5051. goto again;
  5052. case DIR_FIL:
  5053. show = 1;
  5054. cmifn1 &= ~(1);
  5055. cmifn2 = 0;
  5056. goto again;
  5057. case DIR_SRT:
  5058. x = DIRS_NM;
  5059. if (c == ':' || c == '=')
  5060. if ((x = cmkey(dirsort,ndirsort,"Sort key","name",xxstring)) < 0)
  5061. return(x);
  5062. xsort = 1;
  5063. sortby = x;
  5064. break;
  5065. case DIR_BUP: backup = 1; fs++; break;
  5066. case DIR_NOB: backup = 0; fs++; break;
  5067. case DIR_NOS: xsort = 0; break;
  5068. case DIR_ASC: reverse = 0; break;
  5069. case DIR_DSC: reverse = 1; break;
  5070. #ifdef RECURSIVE
  5071. case DIR_REC: recursive = 1; diractive = 1; break;
  5072. case DIR_NOR: recursive = 0; diractive = 0; break;
  5073. #endif /* RECURSIVE */
  5074. case DIR_TYP: xfermod = 1; break;
  5075. case DIR_NOT: xfermod = 0; break;
  5076. #ifdef CKSYMLINK
  5077. case DIR_LNK: /* Follow links */
  5078. #ifdef COMMENT
  5079. /* A command switch shouldn't be setting a global value! */
  5080. nolinks = 0;
  5081. #endif /* COMMENT */
  5082. cmifn1 &= ~(2);
  5083. dontfollowlinks = 0;
  5084. goto again;
  5085. case DIR_NLK: /* Don't follow links */
  5086. #ifdef COMMENT
  5087. nolinks = 2;
  5088. #endif /* COMMENT */
  5089. cmifn1 &= ~(2);
  5090. dontfollowlinks = 1;
  5091. goto again;
  5092. case DIR_NOL: /* Don't show links at all */
  5093. dontshowlinks = 1;
  5094. goto again;
  5095. #endif /* CKSYMLINK */
  5096. case DIR_NOM: msg = 0; break;
  5097. case DIR_MSG:
  5098. if (c == ':' || c == '=')
  5099. if ((x = cmfld("Message to append to each line",
  5100. "",
  5101. &s,
  5102. xxstring
  5103. )) < 0)
  5104. return(x);
  5105. msg = 1;
  5106. ckstrncpy(tmpbuf,brstrip(s),TMPBUFSIZ);
  5107. break;
  5108. case DIR_SMA:
  5109. case DIR_LAR: {
  5110. CK_OFF_T y;
  5111. if (!getval) break;
  5112. if ((x = cmnumw("File size in bytes","0",10,&y,xxstring)) < 0)
  5113. return(x);
  5114. fs++;
  5115. show = 1;
  5116. switch (cmresult.nresult) {
  5117. case DIR_SMA: minsize = y; break;
  5118. case DIR_LAR: maxsize = y; break;
  5119. }
  5120. break;
  5121. }
  5122. case DIR_TOP:
  5123. dir_top = 10;
  5124. if (!getval) break;
  5125. if ((x = cmnum("How many lines to show","10",10,&y,xxstring))< 0)
  5126. return(x);
  5127. dir_top = y;
  5128. break;
  5129. #ifndef NOSPL
  5130. case DIR_ARR:
  5131. if (c != ':' && c != '=') {
  5132. printf("?Array name required\n");
  5133. return(-9);
  5134. }
  5135. if ((x = cmfld("Array name (a single letter will do)",
  5136. "",
  5137. &s,
  5138. NULL
  5139. )) < 0) {
  5140. if (x == -3) {
  5141. printf("?Array name required\n");
  5142. return(-9);
  5143. } else
  5144. return(x);
  5145. }
  5146. if (!*s) {
  5147. printf("?Array name required\n");
  5148. return(-9);
  5149. }
  5150. s2 = s;
  5151. if (*s == CMDQ) s++;
  5152. if (*s == '&') s++;
  5153. if (!isalpha(*s)) {
  5154. printf("?Bad array name - \"%s\"\n",s2);
  5155. return(-9);
  5156. }
  5157. array = *s++;
  5158. if (isupper(array)) array = tolower(array);
  5159. if (*s && (*s != '[' || *(s+1) != ']')) {
  5160. printf("?Bad array name - \"%s\"\n",s2);
  5161. return(-9);
  5162. }
  5163. break;
  5164. #endif /* NOSPL */
  5165. case DIR_AFT:
  5166. case DIR_BEF:
  5167. case DIR_NAF:
  5168. case DIR_NBF:
  5169. if (!getval) break;
  5170. if ((x = cmdate("File-time","",&s,0,xxstring)) < 0) {
  5171. if (x == -3) {
  5172. printf("?Date-time required\n");
  5173. rc = -9;
  5174. } else
  5175. rc = x;
  5176. goto xdomydir;
  5177. }
  5178. fs++;
  5179. switch (k) {
  5180. case DIR_AFT: makestr(&dir_aft,s); break;
  5181. case DIR_BEF: makestr(&dir_bef,s); break;
  5182. case DIR_NAF: makestr(&dir_naf,s); break;
  5183. case DIR_NBF: makestr(&dir_nbf,s); break;
  5184. }
  5185. break;
  5186. case DIR_EXC:
  5187. if (!getval) break;
  5188. if ((x = cmfld("Pattern","",&s,xxstring)) < 0) {
  5189. if (x == -3) {
  5190. printf("?Pattern required\n");
  5191. rc = -9;
  5192. } else
  5193. rc = x;
  5194. goto xdomydir;
  5195. }
  5196. fs++;
  5197. makestr(&dir_exc,s);
  5198. break;
  5199. case DIR_SUM:
  5200. summary = 1;
  5201. break;
  5202. case DIR_BIN: {
  5203. extern struct keytab txtbin[];
  5204. extern int xfiletype;
  5205. if (!getval) break;
  5206. if ((x = cmkey(txtbin,3,"","all",xxstring)) < 0) {
  5207. rc = x;
  5208. goto xdomydir;
  5209. }
  5210. if (x == 2) {
  5211. xfiletype = -1;
  5212. } else {
  5213. xfiletype = x;
  5214. fs = 1;
  5215. }
  5216. break;
  5217. }
  5218. case DIR_OUT:
  5219. if ((x = cmofi("File for directory listing","",&s,xxstring)) < 0)
  5220. return(x);
  5221. ckstrncpy(outfile,s,CKMAXPATH+1);
  5222. break;
  5223. case DIR_SIM: /* TOUCH or CHANGE /SIMULATE */
  5224. simulate = 1;
  5225. break;
  5226. case 7777: /* CASE: (CHANGE only) */
  5227. if (change) {
  5228. if ((x = cmkey(onoff,2,"","on",xxstring)) < 0)
  5229. return(x);
  5230. chcase = x;
  5231. }
  5232. break;
  5233. case DIR_MOD: /* TOUCH or CHANGE /MODTIME: */
  5234. if (change) {
  5235. if ((x = cmkey(chmttab,nchmttab,"","update",xxstring)) < 0)
  5236. return(x);
  5237. chmtopt = x;
  5238. break;
  5239. }
  5240. if ((x = cmdate("File modification date-time",
  5241. "now",&s,0,xxstring)) < 0)
  5242. return(x);
  5243. ckstrncpy(modtime,brstrip(s),100);
  5244. break;
  5245. case DIR_DES: /* CHANGE /DESTINATION:dirname */
  5246. case DIR_BAK: /* CHANGE /BACKUP:dirname */
  5247. if (change) {
  5248. int x;
  5249. char * whatdir = chgdestdir;
  5250. char * hmsg = "Directory for changed files";
  5251. if (k == DIR_BAK) {
  5252. hmsg = "Directory for backing up original files";
  5253. whatdir = chgbackupdir;
  5254. }
  5255. x = cmdir(hmsg,"",&s,xxstring);
  5256. if (x < 0) {
  5257. if (x == -3) {
  5258. printf("?Parse error\n");
  5259. return(-9);
  5260. }
  5261. return(x);
  5262. }
  5263. x = isdir(s); /* this is overkill but... */
  5264. if (x < 0) {
  5265. if (x == -3) {
  5266. printf("?Directory name required\n");
  5267. return(-9);
  5268. }
  5269. return(x);
  5270. }
  5271. ckstrncpy(whatdir,s,MAXPATHLEN);
  5272. if (!isdir(whatdir)) { /* Double overkill */
  5273. printf("?%s is not a directory name\n",whatdir);
  5274. return(-9);
  5275. }
  5276. switch (k) {
  5277. case DIR_DES: /* DESTINATION switch given */
  5278. changeinplace = 0; /* Making new files */
  5279. break;
  5280. case DIR_BAK: /* BACKUP switch given */
  5281. changebackup = 1; /* Backup up original files */
  5282. break;
  5283. }
  5284. }
  5285. break;
  5286. default:
  5287. printf("?Sorry, not implemented yet - \"%s\"\n", atmbuf);
  5288. goto xdomydir;
  5289. }
  5290. }
  5291. ckstrncpy(line,cmresult.sresult,LINBUFSIZ); /* Safe copy of filespec */
  5292. /* ^^^ START MULTIPLE */
  5293. while (!touch && !change) { /* Multiple filespecs only for DIR */
  5294. x = cmfld("Another filespec or Enter","",&s,xxstring);
  5295. if (x == -3)
  5296. break;
  5297. if (x < 0)
  5298. return(x);
  5299. ckstrncat(line,",",LINBUFSIZ);
  5300. ckstrncat(line,s,LINBUFSIZ);
  5301. multiple++;
  5302. }
  5303. ckmakmsg(tmpbuf,TMPBUFSIZ,"{",line,"}",NULL);
  5304. ckstrncpy(line,tmpbuf,LINBUFSIZ);
  5305. cmresult.nresult = 1;
  5306. cmresult.fcode = _CMIFI;
  5307. /* ^^^ END MULTIPLE */
  5308. ckstrncpy(name,line,MAXPATHLEN);
  5309. if (change) { /* Finish parsing CHANGE command */
  5310. debug(F110,"CHANGE source file",line,0);
  5311. x = cmfld("Text to be changed","",&s,xxstring);
  5312. if (x < 0) {
  5313. if (x == -3) {
  5314. printf("?You must specify the text to be changed\n");
  5315. return(-9);
  5316. } else {
  5317. return(x);
  5318. }
  5319. }
  5320. s = brstrip(s);
  5321. s1len = ckstrncpy(string1,s,1024);
  5322. debug(F110,"CHANGE string1",string1,0);
  5323. x = cmfld("Text to change it to","",&s2,xxstring);
  5324. if (x < 0 && x != -3) return(x);
  5325. s2 = brstrip(s2);
  5326. s2len = ckstrncpy(string2,s2,1024);
  5327. debug(F110,"CHANGE string2",string2,0);
  5328. }
  5329. if ((x = cmcfm()) < 0) /* Get confirmation */
  5330. return(x);
  5331. /*
  5332. Command is TOUCH and file doesn't exist.
  5333. */
  5334. if (touch) { /* TOUCH */
  5335. if ((cmresult.fcode == _CMIFI && zchki(s) == (CK_OFF_T)-1)) {
  5336. FILE * fp;
  5337. s = brstrip(s);
  5338. if (!iswild(s)) {
  5339. /* Given date-time, if any, else current date-time */
  5340. dstr = ckcvtdate(modtime[0] ? modtime : "",0);
  5341. xxstruct.date.val = dstr;
  5342. xxstruct.date.len = (int)strlen(xxstruct.date.val);
  5343. xxstruct.lprotect.len = 0;
  5344. xxstruct.gprotect.len = 0;
  5345. #ifdef UNIX
  5346. if (s[0] == '~')
  5347. s = tilde_expand(s);
  5348. #endif /* UNIX */
  5349. /* the IF condition was added 2013-04-15 */
  5350. if (zchki(s) < 0) { /* If file doesn't already exist... */
  5351. fp = fopen(s,"w"); /* Create it */
  5352. if (!fp) {
  5353. printf("?TOUCH %s: %s\n",s,ck_errstr());
  5354. rc = -9;
  5355. goto xdomydir;
  5356. }
  5357. fclose(fp);
  5358. }
  5359. debug(F110,"TOUCH CREATE NONEXISTENT",s,0);
  5360. if (zstime(s,&xxstruct,0) < 0) {
  5361. debug(F110,"TOUCH ZSTIME FAILED",s,0);
  5362. printf("?TOUCH %s: %s\n",name,ck_errstr());
  5363. rc = -9;
  5364. goto xdomydir;
  5365. }
  5366. debug(F110,"TOUCH ZSTIME OK",xxstruct.date.val,0);
  5367. multiple++; /* Force new directory scan */
  5368. }
  5369. }
  5370. } else
  5371. if (cmresult.fcode != _CMIFI) { /* Nothing matched */
  5372. /*
  5373. Note - this never gets executed because after the "begin
  5374. multiple" hack above, the result is always _CMIFI).
  5375. */
  5376. char * m;
  5377. if (*s == '/')
  5378. #ifdef UNIXOROSK
  5379. m = "does not match switch or name of accessible file";
  5380. #else
  5381. #ifdef OS2
  5382. m = "does not match switch or name of accessible file";
  5383. #else
  5384. m = "no switches match";
  5385. #endif /* OS2 */
  5386. #endif /* UNIXOROSX */
  5387. else
  5388. m = "not found or not accessible";
  5389. printf("\"%s\" - %s\n",s,m);
  5390. rc = -9;
  5391. goto xdomydir;
  5392. }
  5393. #ifdef COMMENT
  5394. /* This can't be right because it's based on _CMCFM */
  5395. wild = cmresult.nresult; /* Wildcard was given? */
  5396. debug(F111,"domydir cmifi2",s,wild);
  5397. #else
  5398. wild = 0;
  5399. #endif /* COMMENT */
  5400. if (outfile[0]) { /* If an output file was specified */
  5401. ofp = fopen(outfile,"w"); /* open it */
  5402. if (!ofp) {
  5403. printf("?Can't open output file %s: %s\n",outfile,ck_errstr());
  5404. ofp = stdout;
  5405. return(-9);
  5406. }
  5407. page = 0;
  5408. }
  5409. #ifdef OS2
  5410. if (!wild) {
  5411. if (zchki(s) == -2) { /* Found a directory */
  5412. p = s + (int)strlen(s) - 1; /* Yes */
  5413. if (*p == '\\' || *p == '/')
  5414. strcat(s, "*");
  5415. else if (*p == ':')
  5416. strcat(s, "./*");
  5417. else
  5418. strcat(s, "/*");
  5419. wild = 1; /* Now it's wild */
  5420. }
  5421. }
  5422. #else
  5423. if (!wild) if (isdir(s)) { /* Is it a directory? */
  5424. p = s + (int)strlen(s) - 1; /* Yes */
  5425. #ifdef VMS
  5426. {
  5427. /* Convert from FOO.DIR;1 to [x.FOO] if necessary */
  5428. char buf[CKMAXPATH+1];
  5429. debug(F000,"domydir directory 0",s,*p);
  5430. if (cvtdir(s,buf,CKMAXPATH) > 0)
  5431. ckstrncpy(line,buf,LINBUFSIZ);
  5432. }
  5433. #endif /* VMS */
  5434. debug(F000,"domydir directory 1",s,*p);
  5435. #ifdef VMS
  5436. if (*p == ']' || *p == '>' || *p == ':')
  5437. strcat(s, "*.*");
  5438. #else
  5439. #ifdef datageneral
  5440. if (*p == ':')
  5441. strcat(s, "+");
  5442. else
  5443. strcat(s, ":+");
  5444. #else
  5445. #ifdef STRATUS
  5446. if (*p == '>')
  5447. strcat(s, "*");
  5448. else
  5449. strcat(s, ">*");
  5450. #endif /* STRATUS */
  5451. #endif /* datageneral */
  5452. #endif /* VMS */
  5453. wild = 1; /* Now it's wild */
  5454. debug(F000,"domydir directory 2",s,*p);
  5455. }
  5456. #endif /* OS2 */
  5457. #ifdef ZXREWIND
  5458. /* cmifi() already called nzxpand so we can just re-use the same list. */
  5459. if (!multiple) {
  5460. x = zxrewind(); /* Rewind the list */
  5461. debug(F111,"domydir zxrewind",s,x);
  5462. } else {
  5463. #endif /* ZXREWIND */
  5464. /*
  5465. In case we gave multiple filespecs they are now in {a,b,c} list format.
  5466. Which is a valid wildcard. We pass it to nzxpand() to get back the list
  5467. of files that match. This is fine for DIRECTORY but it's not fine for
  5468. TOUCH because we want TOUCH to see those names so it can create the files.
  5469. So for now at least, if TOUCH is to be used to create files -- as opposed
  5470. to changing the timestamps of existing files -- it can only do one file
  5471. at a time.
  5472. */
  5473. nzxopts = (show == ZX_DIRONLY) ? ZX_DIRONLY :
  5474. (show == ZX_FILONLY ? ZX_FILONLY : 0);
  5475. if (matchdot) nzxopts |= ZX_MATCHDOT;
  5476. if (recursive) nzxopts |= ZX_RECURSE;
  5477. x = nzxpand(s,nzxopts); /* Expand file list */
  5478. debug(F111,"domydir nzxpand",s,x);
  5479. #ifdef ZXREWIND
  5480. }
  5481. #endif /* ZXREWIND */
  5482. #ifndef NOSPL
  5483. if (array) {
  5484. int n, xx;
  5485. n = (x < 0) ? 0 : x;
  5486. if ((xx = dclarray(array,n)) < 0) {
  5487. printf("?Array declaration failure\n");
  5488. rc = -9;
  5489. goto xdomydir;
  5490. }
  5491. arrayindex = xx;
  5492. ap = a_ptr[xx]; /* Pointer to list of elements */
  5493. if (ap) /* Set element 0 to dimension */
  5494. makestr(&(ap[0]),"0"); /* which so far is zero */
  5495. if (n < 1) { /* No files matched, done. */
  5496. rc = 0;
  5497. goto xdomydir;
  5498. }
  5499. } else
  5500. #endif /* NOSPL */
  5501. if (!touch && x < 1) {
  5502. #ifdef CKROOT
  5503. extern int ckrooterr;
  5504. if (ckrooterr)
  5505. printf("?Off limits: %s\n",s);
  5506. else
  5507. #endif /* CKROOT */
  5508. if (x == 0 && isdir(s))
  5509. printf("?Empty directory - \"%s\"\n", s);
  5510. else
  5511. printf("?%s %s match - \"%s\"\n",
  5512. (x == 0) ? "No" : "Too many",
  5513. (show == 2) ? "directories" : "files",
  5514. brstrip(s)
  5515. );
  5516. rc = -9;
  5517. goto xdomydir;
  5518. }
  5519. nx = x; /* Remember how many files */
  5520. reallysort = xsort;
  5521. if (nx < 2) reallysort = 0; /* Skip sorting if none or one */
  5522. xsort = 1; /* 2013-12-06 but do everything else */
  5523. if (msg) {
  5524. makestr(&dirmsg,tmpbuf);
  5525. dirmsglen = strlen(tmpbuf);
  5526. }
  5527. #ifdef VMS
  5528. cdp = zgtdir(); /* Get current directory */
  5529. debug(F110,"domydir VMS zgtdir",cdp,0);
  5530. #endif /* VMS */
  5531. if (xsort && verbose) { /* If sorting, allocate space */
  5532. if (!(dirlist = (char **) malloc((x + 1) * sizeof(char **)))) {
  5533. if (!quiet) {
  5534. printf("* Warning: Failure to allocate memory for sorting.\n");
  5535. printf("* Will proceed without sorting...\n");
  5536. }
  5537. xsort = 0;
  5538. }
  5539. debug(F101,"domydir sort malloc","",xsort);
  5540. }
  5541. /* Display the listing */
  5542. #ifndef NOSPL
  5543. if (array) /* Storing instead of printing */
  5544. heading = 0;
  5545. #endif /* NOSPL */
  5546. if (heading) { /* If /HEADING print heading */
  5547. zfnqfp(s,TMPBUFSIZ,tmpbuf);
  5548. fprintf(ofp,"\nDirectory of %s\n\n",tmpbuf);
  5549. n += 3;
  5550. }
  5551. if (page > -1) /* Paging */
  5552. xaskmore = page;
  5553. if (dir_exc) /* Have exception list? */
  5554. makelist(dir_exc,xlist,16); /* Yes, convert to array */
  5555. if (!verbose && !touch && !change) { /* /BRIEF */
  5556. if (outfile[0]) { /* To file */
  5557. int k = 0;
  5558. znext(name);
  5559. while (name[0]) { /* One line per file */
  5560. k++;
  5561. if (fs) if (fileselect(name,
  5562. dir_aft,dir_bef,dir_naf,dir_nbf,
  5563. minsize,maxsize,!backup,16,xlist) < 1) {
  5564. znext(name);
  5565. continue;
  5566. }
  5567. fprintf(ofp,"%s\n",name);
  5568. znext(name);
  5569. }
  5570. if (heading)
  5571. fprintf(ofp,"Files: %d\n\n",k);
  5572. rc = 1;
  5573. goto xdomydir;
  5574. } else {
  5575. rc = xfilhelp(x,"","",n,0,1,
  5576. dir_aft,dir_bef,dir_naf,dir_nbf,
  5577. minsize,maxsize,!backup,16,xlist);
  5578. if (rc < 0)
  5579. goto xdomydir;
  5580. if (heading && rc > 0)
  5581. fprintf(ofp,"Files: %d\n\n",x); /* (Might scroll a line or 2) */
  5582. rc = 1;
  5583. goto xdomydir;
  5584. }
  5585. }
  5586. ndirs = nfiles = 0L; /* Initialize counters */
  5587. nbytes = (CK_OFF_T)0;
  5588. if (change) { /* CHANGE - check for conflicts */
  5589. struct zfnfp * fp;
  5590. char dbuf[MAXPATHLEN+1];
  5591. char bbuf[MAXPATHLEN+1];
  5592. fp = zfnqfp(name,TMPBUFSIZ,chgsourcedir); /* Source directory path */
  5593. if (fp) {
  5594. chgsourcedir[fp->fname - fp->fpath] = NUL;
  5595. debug(F110,"CHANGE source directory",chgsourcedir,0);
  5596. if (chgdestdir[0]) {
  5597. debug(F110,"CHANGE destination directory",chgdestdir,0);
  5598. zfnqfp(chgdestdir,TMPBUFSIZ,dbuf);
  5599. debug(F110,"CHANGE destination directory",dbuf,0);
  5600. if (!strcmp(dbuf,chgsourcedir)) {
  5601. printf(
  5602. "?Destination and source directories are the same\n");
  5603. success = 0;
  5604. goto xdomydir;
  5605. }
  5606. }
  5607. if (chgbackupdir[0]) {
  5608. debug(F110,"CHANGE backup directory",chgbackupdir,0);
  5609. zfnqfp(chgbackupdir,TMPBUFSIZ,bbuf);
  5610. debug(F110,"CHANGE backup directory",bbuf,0);
  5611. if (!strcmp(bbuf,chgsourcedir)) {
  5612. printf("?Backup and source directories are the same\n");
  5613. success = 0;
  5614. goto xdomydir;
  5615. }
  5616. }
  5617. if (chgbackupdir[0] && chgdestdir[0]) {
  5618. if (!strcmp(bbuf,dbuf)) {
  5619. printf(
  5620. "?Backup and destination directories are the same\n");
  5621. success = 0;
  5622. goto xdomydir;
  5623. }
  5624. }
  5625. }
  5626. }
  5627. diractive = 1; /* DIRECTORY command is active */
  5628. znext(name); /* Get next file */
  5629. while (name[0]) { /* Loop for each file */
  5630. if (fs) if (fileselect(name,
  5631. dir_aft,dir_bef,dir_naf,dir_nbf,
  5632. minsize,maxsize,!backup,16,xlist) < 1) {
  5633. znext(name);
  5634. continue;
  5635. }
  5636. len = zgetfs(name); /* Get file length */
  5637. debug(F111,"domydir loop zgetfs",name,len);
  5638. #ifdef VMSORUNIX
  5639. itsadir = zgfs_dir; /* See if it's a directory */
  5640. #else
  5641. itsadir = (len == (CK_OFF_T)-2 || isdir(name));
  5642. #endif /* VMSOUNIX */
  5643. debug(F111,"domydir itsadir",name,itsadir);
  5644. changes = 0;
  5645. if ((itsadir && (show == 1)) || (!itsadir && (show == 2))) {
  5646. znext(name);
  5647. continue;
  5648. }
  5649. /* Get here when we know we have selected this file */
  5650. nmatches++;
  5651. if (itsadir) { /* Accumulate totals for summary */
  5652. ndirs++;
  5653. } else {
  5654. nfiles++;
  5655. nbytes += len;
  5656. }
  5657. dstr = NULL; /* File date-time string */
  5658. /* BEGIN CHANGE command */
  5659. if (cx == XXCHG) { /* Command was CHANGE, not DIRECTORY */
  5660. FILE * ifp = NULL; /* Input file pointer */
  5661. FILE * ofp = NULL; /* Output (temporary) file pointer */
  5662. FILE * bfp = NULL; /* Backup file pointer */
  5663. char backupfile[MAXPATHLEN+1]; /* Backup file */
  5664. char tmpfile[MAXPATHLEN]; /* Buffer for filename */
  5665. char * tdp = tmpfile; /* Temporary directory path */
  5666. int linebufsiz = 24575; /* Buf size for reading file lines */
  5667. char * linebuf = NULL; /* Input file buffer */
  5668. char * lbp = NULL; /* and pointer to it */
  5669. char * newbuf = NULL; /* Output file buffer */
  5670. char * nbp = NULL; /* and pointer */
  5671. int bufleft = 0; /* Space left in newbuf */
  5672. int i, j, k, x, y; /* Workers */
  5673. int failed = 0; /* Search string not found */
  5674. char c1, c2; /* Char for quick compare */
  5675. changes = 0; /* Change counter */
  5676. k = 0;
  5677. x = scanfile(name,NULL,nscanfile) ;
  5678. debug(F111,"domydir CHANGE scanfile",name,x);
  5679. switch (x) { /* Is it a text file? */
  5680. case FT_7BIT: k++; break;
  5681. case FT_UTF8: k++; break;
  5682. case FT_UCS2: k++; break;
  5683. case FT_8BIT: k++; break;
  5684. case FT_TEXT: k++; break;
  5685. }
  5686. if (!k) {
  5687. if (verbose)
  5688. printf("%s: Skipped (not a text file)\n");
  5689. znext(name);
  5690. continue;
  5691. }
  5692. debug(F101,"CHANGE changeinplace","",changeinplace);
  5693. if (changeinplace) { /* CHANGing in place? */
  5694. int x = 0;
  5695. if (!tempdir) { /* Need a temporary directory */
  5696. x++;
  5697. } else if (!*tempdir) {
  5698. x++;
  5699. }
  5700. /*
  5701. It might make more sense to fall back on the current directory, or the
  5702. directory specified in the filespec, because that one has to be writeable or
  5703. the files could not be changed.
  5704. */
  5705. if (x) {
  5706. printf(
  5707. "?Temporary directory not defined, use SET TEMP-DIRECTORY to define one.\n"
  5708. );
  5709. success = 0;
  5710. goto xdomydir;
  5711. }
  5712. ckstrncpy(tmpfile,tempdir,MAXPATHLEN); /* Temp directory */
  5713. ckstrncat(tmpfile,"__x",MAXPATHLEN); /* Temp filespec */
  5714. if (simulate) {
  5715. /* Too much */
  5716. /* printf("Would create temp file %s\n",tmpfile); */
  5717. } else {
  5718. ofp = fopen(tmpfile,"w"); /* Open temporary file */
  5719. debug(F110,"CHANGE in place tmpfile",tmpfile,0);
  5720. if (!ofp) {
  5721. printf("?Can't open temporary file %s: %s\n",
  5722. tmpfile,ck_errstr());
  5723. success = 0;
  5724. goto xdomydir;
  5725. }
  5726. }
  5727. } else { /* Making a new copy of the file */
  5728. char * p = name, * p2 = NULL;
  5729. debug(F110,"CHANGE chgdestdir",chgdestdir,0);
  5730. ckstrncpy(tmpfile,chgdestdir,MAXPATHLEN);
  5731. debug(F110,"CHANGE tmpfile",tmpfile,0);
  5732. while (*p++) { if (ISDIRSEP(*p)) p2 = p; } /* Just the name */
  5733. if (!p2) { /* name had no slashes in it */
  5734. p2 = name;
  5735. ckstrncat(tmpfile,STRDIRSEP,MAXPATHLEN);
  5736. }
  5737. debug(F110,"CHANGE name",p2,0);
  5738. ckstrncat(tmpfile,p2,MAXPATHLEN);
  5739. debug(F110,"CHANGE final tmpfile",tmpfile,0);
  5740. if (simulate) {
  5741. printf("Would create new file %s\n",tmpfile);
  5742. } else {
  5743. debug(F110,"CHANGE /dest tmpfile",tmpfile,0);
  5744. ofp = fopen(tmpfile,"w"); /* Open temporary file */
  5745. if (!ofp) {
  5746. printf("?Can't open destination file %s: %s\n",
  5747. tmpfile,ck_errstr());
  5748. success = 0;
  5749. goto xdomydir;
  5750. }
  5751. }
  5752. }
  5753. if (changebackup) { /* Backing up original file? */
  5754. char * p = name, * p2 = NULL;
  5755. ckstrncpy(backupfile,chgbackupdir,MAXPATHLEN);
  5756. debug(F111,"CHANGE backupfile",backupfile,1);
  5757. while (*p++) { if (ISDIRSEP(*p)) p2 = p; } /* Just the name */
  5758. if (!p2) { /* name had no slashes in it */
  5759. p2 = name;
  5760. ckstrncat(backupfile,STRDIRSEP,MAXPATHLEN);
  5761. }
  5762. debug(F111,"CHANGE backupfile",backupfile,2);
  5763. ckstrncat(backupfile,p2,MAXPATHLEN);
  5764. debug(F111,"CHANGE backupfile",backupfile,3);
  5765. if (simulate) {
  5766. printf("Would back up original file to %s\n",
  5767. backupfile);
  5768. } else {
  5769. bfp = fopen(backupfile,"w"); /* Open temporary file */
  5770. if (!bfp) {
  5771. printf("?Can't open backup file %s: %s\n",
  5772. backupfile,ck_errstr());
  5773. success = 0;
  5774. goto xdomydir;
  5775. }
  5776. }
  5777. }
  5778. if ((ifp = fopen(name,"r")) == NULL) { /* Open input file */
  5779. printf("?Can't open file %s: %s\n",s,ck_errstr());
  5780. fclose(ofp);
  5781. success = 0;
  5782. goto xdomydir;
  5783. }
  5784. /* Get timestamp of original file */
  5785. debug(F101,"CHANGE timestamp changebackup","",changebackup);
  5786. if (chmtopt == CHMT_P || changebackup) {
  5787. debug(F110,"CHANGE file timestamp name",name,0);
  5788. dstr = zfcdat(name);
  5789. if (!dstr) dstr = "";
  5790. if (!*dstr) printf("WARNING: can't get date for %s\n",name);
  5791. debug(F110,"CHANGE file timestamp dstr",dstr,0);
  5792. xxstruct.date.val = dstr; /* change file's modtime */
  5793. xxstruct.date.len = (int)strlen(xxstruct.date.val);
  5794. xxstruct.lprotect.len = 0;
  5795. xxstruct.gprotect.len = 0;
  5796. }
  5797. linebuf = (char *) malloc(linebufsiz+1); /* Malloc a line buffer */
  5798. if (!linebuf) {
  5799. printf("?Memory allocation failure\n");
  5800. fclose(ofp);
  5801. fclose(ifp);
  5802. if (bfp) fclose(bfp);
  5803. success = 0;
  5804. goto xdomydir;
  5805. }
  5806. newbuf = (char *) malloc(linebufsiz+1); /* Buffer for copy */
  5807. if (!newbuf) {
  5808. free(linebuf);
  5809. printf("?Memory allocation failure\n");
  5810. fclose(ofp);
  5811. fclose(ifp);
  5812. if (bfp) fclose(bfp);
  5813. success = 0;
  5814. goto xdomydir;
  5815. }
  5816. /* Loop through lines of each original file... */
  5817. while (fgets(linebuf, linebufsiz, ifp)) { /* Read a line */
  5818. if (changebackup && !simulate) {
  5819. if (fputs(linebuf, bfp) == EOF) { /* Backing up */
  5820. printf("?%s: Write failed - %s\n",
  5821. backupfile,ck_errstr());
  5822. failed++;
  5823. break;
  5824. }
  5825. }
  5826. nbp = newbuf;
  5827. lbp = linebuf;
  5828. bufleft = linebufsiz; /* Space left in newbuf */
  5829. x = ckindex(string1,lbp,0,0,chcase);
  5830. if (x == 0) { /* Nothing to replace */
  5831. if (!simulate) {
  5832. if (fputs(lbp, ofp) == EOF) {
  5833. printf("?%s: Write failed - %s\n",
  5834. tmpfile,ck_errstr());
  5835. failed++;
  5836. break;
  5837. }
  5838. }
  5839. } else while (1) { /* One or maybe more occurrences */
  5840. changes++; /* Count this change */
  5841. totalchanges++; /* Increment total changes */
  5842. j = x + s2len - 1; /* Size of addition to newbuf */
  5843. bufleft -= j; /* Remaining space in newbuf after */
  5844. if (bufleft > j) { /* If space enough */
  5845. char c;
  5846. c = lbp[x];
  5847. lbp[x] = NUL; /* Terminate for strncpy */
  5848. strncpy(nbp,lbp,bufleft); /* Copy this piece */
  5849. lbp[x] = c;
  5850. nbp += (x - 1); /* adjust destination pointer */
  5851. strncpy(nbp,string2,bufleft); /* replacement string */
  5852. nbp += s2len; /* and adjust destination pointer */
  5853. } else { /* Otherwise fail. */
  5854. failed++;
  5855. printf("?%s: Write failed - %s\n",tmpfile,ck_errstr());
  5856. break;
  5857. }
  5858. lbp += x + s1len - 1; /* Adjust source pointer */
  5859. x = ckindex(string1,lbp,0,0,chcase); /* Get next */
  5860. if (!x) { /* No more string1's found in this line */
  5861. if (!simulate) { /* Write changes */
  5862. if (fputs(newbuf, ofp) == EOF) {
  5863. printf("?%s: Write failed - %s\n",
  5864. tmpfile,ck_errstr());
  5865. failed++;
  5866. break;
  5867. }
  5868. if (*lbp) { /* And write out last chunk if any */
  5869. if (fputs(lbp, ofp) == EOF) {
  5870. printf("?%s: Write failed - %s\n",
  5871. tmpfile,ck_errstr());
  5872. failed++;
  5873. break;
  5874. }
  5875. }
  5876. }
  5877. break;
  5878. }
  5879. }
  5880. }
  5881. fclose(ifp); /* End... close files */
  5882. if (!simulate) {
  5883. if (bfp) fclose(bfp);
  5884. fclose(ofp);
  5885. }
  5886. bfp = ifp = ofp = NULL;
  5887. free(linebuf); /* and free buffers */
  5888. free(newbuf);
  5889. if (simulate) { /* Simulation run */
  5890. if (failed) {
  5891. printf("Would fail: %s\n",name);
  5892. } else if (changes) {
  5893. printf("Would change: %s\n",name);
  5894. } else if (verbose) {
  5895. printf("Would not change: %s\n",name);
  5896. }
  5897. zdelet(tmpfile);
  5898. } else if (!failed) { /* Really changing */
  5899. char * result = name;
  5900. if (changes) { /* If changes were made */
  5901. if (changeinplace) { /* Changing in place... */
  5902. x = zrename(tmpfile,name); /* Replace original file */
  5903. if (x < 0) {
  5904. printf("?Rename temporary file %s to %s failed",
  5905. tmpfile, name);
  5906. zdelet(tmpfile); /* delete temporary file */
  5907. success = 0;
  5908. goto xdomydir;
  5909. }
  5910. } else { /* Making new file... */
  5911. result = tmpfile;
  5912. }
  5913. if (chmtopt == CHMT_P) { /* If preserving file dates */
  5914. debug(F110,"Setting modtime",result,0);
  5915. if (zstime(result,&xxstruct,0) < 0) {
  5916. printf("?Error preserving original modtime: %s\n",
  5917. result,
  5918. ck_errstr()
  5919. );
  5920. rc = -9;
  5921. goto xdomydir;
  5922. }
  5923. }
  5924. /* Change modtime of backup file unconditionally */
  5925. debug(F111,"CHANGE modtime",backupfile,changebackup);
  5926. if (changebackup) {
  5927. if (zstime(backupfile,&xxstruct,0) < 0) {
  5928. printf("?Modtime error on backup file: %s\n",
  5929. backupfile,
  5930. ck_errstr()
  5931. );
  5932. rc = -9;
  5933. goto xdomydir;
  5934. }
  5935. }
  5936. if (verbose)
  5937. printf("Changed %s: %s -> %s\n",result,string1,string2);
  5938. } else if (changeinplace) {
  5939. zdelet(tmpfile); /* Delete temporary file */
  5940. if (changebackup) zdelet(backupfile); /* and backup */
  5941. }
  5942. }
  5943. if (znext(name)) /* Get next file */
  5944. continue;
  5945. success = 1; /* If none we're finished */
  5946. goto xdomydir;
  5947. }
  5948. /* TOUCH command... */
  5949. if (cx == XXTOUC) { /* Command was TOUCH, not DIRECTORY */
  5950. /* Given date-time, if any, else current date-time */
  5951. debug(F110,"TOUCH dstr before",dstr,0);
  5952. dstr = ckcvtdate(modtime[0] ? modtime : "",0);
  5953. debug(F110,"TOUCH dstr after",dstr,0);
  5954. xxstruct.date.val = dstr;
  5955. xxstruct.date.len = (int)strlen(xxstruct.date.val);
  5956. xxstruct.lprotect.len = 0;
  5957. xxstruct.gprotect.len = 0;
  5958. if (simulate) {
  5959. printf(" %s (%s)\n",name,dstr);
  5960. } else {
  5961. if (zstime(name,&xxstruct,0) < 0) {
  5962. printf("?TOUCH %s: %s\n",name,ck_errstr());
  5963. rc = -9;
  5964. goto xdomydir;
  5965. }
  5966. }
  5967. if (!verbose || simulate) { /* No listing so just go back */
  5968. znext(name); /* and do next file. */
  5969. continue;
  5970. }
  5971. }
  5972. if (summary) { /* Summary only, no detail */
  5973. znext(name);
  5974. continue;
  5975. }
  5976. /*
  5977. NOTE: The sprintf's in this routine should be safe. They involve
  5978. permission strings, date/time strings, and filenames, all of which have
  5979. known maximum lengths; none of these items is input from users. The
  5980. destination buffers are large enough to hold maximum sizes for any and
  5981. all items. NOTE 2: If command was TOUCH, dstr was already set just
  5982. above.
  5983. */
  5984. if (!dstr) { /* Get file's modification date/time */
  5985. dstr = zfcdat(name);
  5986. debug(F111,"domydir zcfdat",dstr,0);
  5987. }
  5988. if (!dstr) dstr = "";
  5989. {
  5990. /*
  5991. Note that zfcdat() always returns "" or yyyymmdd hh:mm:ss, so any warnings
  5992. about possible out-of-bounds dstr[] array refs do not apply. This block of
  5993. code is to stifle the warnings and also allows for any out-of-spec
  5994. zfcdat() implementations.
  5995. */
  5996. int x;
  5997. char * p = "00000000 00:00:00";
  5998. x = ckstrncpy(xbuf,dstr,32);
  5999. if (x < 17) ckstrncpy(&xbuf[x],p+x,32-x);
  6000. dstr = xbuf;
  6001. }
  6002. if (engdate) { /* English date requested? */
  6003. short month, day, year, hour, minute, seconds;
  6004. month = (dstr[4]-48)*10 + (dstr[5]-48);
  6005. mstr = (month > 0 && month <= 12) ? months[month-1] : "xxx";
  6006. day = (dstr[6]-48)*10 + (dstr[7]-48);
  6007. year = (((dstr[0]-48)*10 +
  6008. (dstr[1]-48))*10 +
  6009. (dstr[2]-48))*10 +
  6010. (dstr[3]-48);
  6011. hour = (dstr[9]-48)*10 + (dstr[10]-48);
  6012. minute = (dstr[12]-48)*10 + (dstr[13]-48);
  6013. seconds = (dstr[15]-48)*10 + (dstr[16]-48);
  6014. sprintf(dbuf, /* SAFE */
  6015. "%2d-%s-%4d %02d:%02d:%02d",
  6016. day,mstr,year,hour,minute,seconds
  6017. );
  6018. dstr = dbuf;
  6019. } else { /* ISO date */
  6020. dbuf[0] = dstr[0]; /* yyyy */
  6021. dbuf[1] = dstr[1];
  6022. dbuf[2] = dstr[2];
  6023. dbuf[3] = dstr[3];
  6024. dbuf[4] = '-';
  6025. dbuf[5] = dstr[4]; /* mm (numeric) */
  6026. dbuf[6] = dstr[5];
  6027. dbuf[7] = '-';
  6028. dbuf[8] = dstr[6]; /* dd */
  6029. dbuf[9] = dstr[7];
  6030. strcpy(dbuf+10,dstr+8); /* hh:mm:ss */
  6031. dstr = dbuf;
  6032. }
  6033. dlen = strlen(dbuf); /* Length of date */
  6034. name[CKMAXPATH] = NUL;
  6035. #ifdef CK_PERMS
  6036. #ifdef VMSORUNIX
  6037. p = ziperm(name); /* Get permissions */
  6038. debug(F110,"ziperm perms",p,0);
  6039. #else
  6040. p = zgperm(name);
  6041. debug(F110,"zgperm perms",p,0);
  6042. #endif /* VMSORUNIX */
  6043. #else
  6044. p = NULL;
  6045. debug(F110,"NULL perms",p,0);
  6046. #endif /* CK_PERMS */
  6047. #ifdef VMS
  6048. /* Get relative name to save space -- VMS fullnames are long... */
  6049. ckstrncpy(name,zrelname(name,cdp),CKMAXPATH);
  6050. #endif /* VMS */
  6051. if (itsadir && len < (CK_OFF_T)0) { /* Directory */
  6052. #ifdef VMS
  6053. sprintf(linebuf,"%-22s%-10s %s %s",p,"<DIR>",dstr,name);
  6054. #else
  6055. if (p)
  6056. sprintf(linebuf,"%10s%-10s %s %s",p,"<DIR>",dstr,name);
  6057. else
  6058. sprintf(linebuf,"%-10s %s %s", "<DIR>", dstr, name);
  6059. #endif /* VMS */
  6060. } else { /* Regular file */
  6061. #ifdef VMS
  6062. sprintf(linebuf,"%-22s%10s %s %s", p, ckfstoa(len), dstr, name);
  6063. #else
  6064. if (p)
  6065. sprintf(linebuf,"%10s%10s %s %s", p, ckfstoa(len), dstr, name);
  6066. else
  6067. sprintf(linebuf,"%10s %s %s", ckfstoa(len), dstr, name);
  6068. #endif /* VMS */
  6069. }
  6070. #ifdef UNIX
  6071. #ifdef CKSYMLINK
  6072. if (zgfs_link) { /* If it's a symlink */
  6073. if (dontshowlinks) { /* If /NOLINKS don't show it */
  6074. znext(name);
  6075. continue;
  6076. }
  6077. }
  6078. if (zgfs_link && !dontfollowlinks) { /* Symlink and following links */
  6079. int n, m; /* Show what the link points to */
  6080. extern char linkname[];
  6081. n = strlen(linebuf);
  6082. m = strlen(linkname) + n;
  6083. if (m < CKMAXPATH + 58)
  6084. strcpy(linebuf+n, " -> "); /* safe (checked) */
  6085. if (m + 4 < CKMAXPATH - 58)
  6086. strcpy(linebuf+n+4, linkname); /* safe (checked) */
  6087. } else
  6088. #endif /* CKSYMLINK */
  6089. #endif /* UNIX */
  6090. if (xfermod) { /* Show transfer mode */
  6091. int i, x, y;
  6092. char * s = "";
  6093. y = -1;
  6094. x = scanfile(name,&y,nscanfile);
  6095. switch (x) {
  6096. case FT_TEXT: s = " (T)"; break;
  6097. case FT_7BIT: s = " (T)(7BIT)"; break;
  6098. case FT_8BIT: s = " (T)(8BIT)"; break;
  6099. #ifdef UNICODE
  6100. case FT_UTF8: s = " (T)(UTF8)"; break;
  6101. case FT_UCS2:
  6102. s = y ? " (T)(UCS2LE)" : " (T)(UCS2BE)";
  6103. break;
  6104. #endif /* UNICODE */
  6105. case FT_BIN: s = " (B)"; break;
  6106. }
  6107. if (!*s) {
  6108. s = binary ? " (B)" : " (T)";
  6109. }
  6110. if (*s) {
  6111. int n;
  6112. n = strlen(linebuf);
  6113. if (n + 4 < CKMAXPATH - 58)
  6114. strcpy(linebuf+n, s); /* safe (checked) */
  6115. }
  6116. }
  6117. if (msg && dirmsg) {
  6118. int n;
  6119. n = strlen(linebuf);
  6120. if (n + dirmsglen + 2 < CKMAXPATH)
  6121. sprintf((char *)(linebuf+n)," %s", dirmsg); /* SAFE */
  6122. }
  6123. if (xsort) { /* Sorting - save line */
  6124. i = strlen(linebuf);
  6125. if ((ndirlist >= nx) ||
  6126. !(dirlist[ndirlist] = (char *)malloc(i+1))) {
  6127. printf("?Memory allocation error - try /NOSORT\n");
  6128. rc = -9;
  6129. goto xdomydir;
  6130. }
  6131. strcpy(dirlist[ndirlist],linebuf); /* safe */
  6132. ndirlist++;
  6133. }
  6134. znext(name); /* Peek ahead to next file */
  6135. if (!xsort) {
  6136. if (!touch || (touch && verbose))
  6137. fprintf(ofp,"%s\n",linebuf);
  6138. if (page && (name[0] || heading)) { /* If /PAGE */
  6139. if (cmd_cols > 0) {
  6140. int x = strlen(linebuf);
  6141. int y;
  6142. y = (x % cmd_cols) ? 1 : 0;
  6143. n += x / cmd_cols + y;
  6144. } else {
  6145. n++;
  6146. }
  6147. #ifdef CK_TTGWSIZ
  6148. if (n > (cmd_rows - 3)) { /* Do more-prompting */
  6149. if (!askmore()) {
  6150. rc = 0;
  6151. goto xdomydir;
  6152. } else
  6153. n = 0;
  6154. }
  6155. #endif /* CK_TTGWSIZ */
  6156. }
  6157. }
  6158. }
  6159. if (xsort) {
  6160. int namepos;
  6161. skey = 0;
  6162. #ifdef VMS
  6163. namepos = dlen + 35;
  6164. switch (sortby) {
  6165. case DIRS_NM: skey = namepos; break;
  6166. case DIRS_DT: skey = 33; break;
  6167. case DIRS_SZ: skey = 21;
  6168. }
  6169. #else
  6170. if (p) {
  6171. namepos = dlen + 24;
  6172. switch (sortby) {
  6173. case DIRS_NM: skey = namepos; break;
  6174. case DIRS_DT: skey = 22; break;
  6175. case DIRS_SZ: skey = 10;
  6176. }
  6177. } else {
  6178. namepos = dlen + 14;
  6179. switch (sortby) {
  6180. case DIRS_NM: skey = namepos; break;
  6181. case DIRS_DT: skey = 12; break;
  6182. case DIRS_SZ: skey = 0;
  6183. }
  6184. }
  6185. #endif /* VMS */
  6186. if (reallysort) sh_sort(dirlist,NULL,ndirlist,skey,reverse,filecase);
  6187. if (dir_top > 0 && dir_top < ndirlist)
  6188. ndirlist = dir_top;
  6189. for (i = 0; i < ndirlist; i++) {
  6190. #ifndef NOSPL
  6191. /* Storing result filenames in an array... */
  6192. if (array) {
  6193. char * name;
  6194. name = dirlist[i] + namepos;
  6195. debug(F111,"domydir array",name,nfiles);
  6196. if (ap)
  6197. makestr(&(ap[i+1]),name);
  6198. continue;
  6199. }
  6200. #endif /* NOSPL */
  6201. /* Printing the result filenames, size, date, etc... */
  6202. fprintf(ofp,"%s\n",dirlist[i]);
  6203. if (page && (i < ndirlist -1 || heading)) { /* If /PAGE */
  6204. if (cmd_cols > 0) {
  6205. int x = strlen(dirlist[i]);
  6206. int y;
  6207. y = (x % cmd_cols) ? 1 : 0;
  6208. n += ((int)strlen(dirlist[i]) / cmd_cols) + y;
  6209. } else {
  6210. n++;
  6211. }
  6212. #ifdef CK_TTGWSIZ
  6213. if (n > (cmd_rows - 3)) { /* Do more-prompting */
  6214. if (!askmore()) {
  6215. rc = 0;
  6216. goto xdomydir;
  6217. } else
  6218. n = 0;
  6219. }
  6220. #endif /* CK_TTGWSIZ */
  6221. }
  6222. }
  6223. #ifndef NOSPL
  6224. if (array) {
  6225. if (ap)
  6226. makestr(&(ap[0]),ckitoa(ndirlist));
  6227. rc = 1;
  6228. goto xdomydir;
  6229. }
  6230. #endif /* NOSPL */
  6231. }
  6232. if (heading || summary) {
  6233. #ifdef CKFLOAT
  6234. CKFLOAT gm;
  6235. #endif /* CKFLOAT */
  6236. fprintf(ofp,"\n%ld director%s, %ld file%s, %s byte%s",
  6237. ndirs,
  6238. (ndirs == 1) ? "y" : "ies",
  6239. nfiles,
  6240. (nfiles == 1) ? "" : "s",
  6241. ckfstoa(nbytes),
  6242. (nbytes == 1) ? "" : "s"
  6243. );
  6244. #ifdef CKFLOAT
  6245. gm = ((CKFLOAT) nbytes ) / 1000000.0;
  6246. if (gm > 1000.0)
  6247. fprintf(ofp," (%0.2fGB)",(gm / 1000.0));
  6248. else if (gm >= 0.01)
  6249. fprintf(ofp," (%0.2fMB)",gm);
  6250. #endif /* CKFLOAD */
  6251. fprintf(ofp,"\n\n");
  6252. } else if (dir_cou && !cv) {
  6253. fprintf(ofp,"\n Files: %ld\n\n",nfiles);
  6254. }
  6255. xdomydir:
  6256. #ifndef NOSPL
  6257. if (dir_cou && cv) { /* /COUNT:var */
  6258. int n;
  6259. n = totalchanges; /* Number of changes for CHANGE */
  6260. if (cx != XXCHG) /* Number for files for DIRECTORY */
  6261. n = nfiles;
  6262. addmac(cv,ckitoa(n)); /* set the variable */
  6263. makestr(&cv,NULL); /* free this */
  6264. }
  6265. if (ap) { /* If we have a result array */
  6266. if (a_dim[arrayindex] > nmatches) /* but it was not filled */
  6267. a_dim[arrayindex] = nmatches; /* adjust dimension */
  6268. }
  6269. #endif /* NOSPL */
  6270. if (g_matchdot > -1) {
  6271. matchdot = g_matchdot; /* Restore these... */
  6272. g_matchdot = -1;
  6273. }
  6274. freedirlist();
  6275. if (ofp != stdout) { /* Close any output file */
  6276. if (ofp) fclose(ofp);
  6277. ofp = stdout;
  6278. }
  6279. if (rc > 0)
  6280. success = 1;
  6281. return(rc);
  6282. }
  6283. int
  6284. dodir(cx) int cx; { /* Do the DIRECTORY command */
  6285. char *dc , *msg;
  6286. #ifdef OS2
  6287. return(domydir(cx));
  6288. #else /* OS2 */
  6289. if (nopush
  6290. #ifdef DOMYDIR /* Builds that domydir() by default */
  6291. || (cx == XXDIR || cx == XXLDIR || cx == XXWDIR ||
  6292. cx == XXHDIR || cx == XXTOUC || cx == XXCHG )
  6293. #endif /* DOMYDIR */
  6294. )
  6295. return(domydir(cx)); /* Built-in directory command */
  6296. /* Use the system's directory command. */
  6297. msg = (cx == XXLS) ?
  6298. "Arguments for ls" :
  6299. "Directory and/or file specification";
  6300. if ((x = cmtxt(msg,"",&s,xxstring)) < 0)
  6301. return(x);
  6302. ckstrncpy(tmpbuf,s,TMPBUFSIZ); /* Copy the filespec */
  6303. s = tmpbuf;
  6304. if ((y = cmcfm()) < 0) return(y);
  6305. lp = line;
  6306. if (!(dc = getenv("CK_DIR")))
  6307. dc = DIRCMD;
  6308. ckmakmsg(lp,LINBUFSIZ,dc," ",s,NULL);
  6309. debug(F110,"DIR",line,0);
  6310. #ifdef VMS
  6311. conres();
  6312. #endif /* VMS */
  6313. x = zshcmd(line);
  6314. #ifdef VMS
  6315. concb((char)escape);
  6316. #endif /* VMS */
  6317. return(success = (x < 1) ? 0 : 1);
  6318. #endif /* OS2 */
  6319. }
  6320. #ifndef NOSERVER
  6321. #ifndef NOFRILLS
  6322. /* Do the ENABLE and DISABLE commands */
  6323. int
  6324. doenable(y,x) int y, x; {
  6325. #ifdef CK_LOGIN
  6326. if (isguest) /* IKSD: Don't let guests */
  6327. return(0); /* enable anything that's disabled */
  6328. #endif /* CK_LOGIN */
  6329. switch (x) {
  6330. case EN_ALL:
  6331. en_cwd = en_cpy = en_del = en_dir = en_fin = en_get = y;
  6332. en_ren = en_sen = en_set = en_spa = en_typ = en_ret = y;
  6333. if (!inserver)
  6334. en_who = en_mai = en_pri = y;
  6335. en_mkd = en_rmd = y;
  6336. en_xit = y;
  6337. #ifndef datageneral
  6338. en_bye = y;
  6339. #endif /* datageneral */
  6340. #ifndef NOPUSH
  6341. if (!nopush && !inserver)
  6342. en_hos = y;
  6343. #endif /* NOPUSH */
  6344. #ifndef NOSPL
  6345. en_asg = en_que = y;
  6346. #endif /* NOSPL */
  6347. break;
  6348. case EN_BYE:
  6349. #ifndef datageneral
  6350. /*
  6351. In Data General AOS/VS Kermit can't log out its superior process.
  6352. */
  6353. en_bye = y;
  6354. #endif /* datageneral */
  6355. break;
  6356. case EN_CPY:
  6357. en_cpy = y;
  6358. break;
  6359. case EN_CWD:
  6360. en_cwd = y;
  6361. #ifdef IKSD
  6362. if (inserver && y == 0) {
  6363. fnrpath = PATH_OFF;
  6364. fnspath = PATH_OFF;
  6365. }
  6366. #endif /* IKSD */
  6367. break;
  6368. case EN_DEL: /* Deleting of files */
  6369. en_del = y;
  6370. break;
  6371. case EN_DIR:
  6372. en_dir = y;
  6373. break;
  6374. case EN_FIN:
  6375. en_fin = y;
  6376. break;
  6377. case EN_GET:
  6378. en_get = y;
  6379. break;
  6380. #ifndef NOPUSH
  6381. case EN_HOS:
  6382. if (!nopush)
  6383. en_hos = y;
  6384. break;
  6385. #endif /* NOPUSH */
  6386. case EN_REN:
  6387. en_ren = y;
  6388. break;
  6389. case EN_SEN:
  6390. en_sen = y;
  6391. break;
  6392. case EN_SET:
  6393. en_set = y;
  6394. break;
  6395. case EN_SPA:
  6396. en_spa = y;
  6397. break;
  6398. case EN_TYP:
  6399. en_typ = y;
  6400. break;
  6401. case EN_WHO:
  6402. en_who = y;
  6403. break;
  6404. #ifndef NOSPL
  6405. case EN_ASG:
  6406. en_asg = y;
  6407. break;
  6408. case EN_QUE:
  6409. en_que = y;
  6410. break;
  6411. #endif /* NOSPL */
  6412. case EN_RET:
  6413. en_del = y;
  6414. break;
  6415. case EN_MAI:
  6416. #ifdef CK_LOGIN
  6417. if (isguest && y) {
  6418. printf("?Sorry, not valid for guests\n");
  6419. return(-9);
  6420. }
  6421. #endif /* CK_LOGIN */
  6422. en_mai = y;
  6423. break;
  6424. case EN_PRI:
  6425. #ifdef CK_LOGIN
  6426. if (isguest && y) {
  6427. printf("?Sorry, not valid for guests\n");
  6428. return(-9);
  6429. }
  6430. #endif /* CK_LOGIN */
  6431. en_pri = y;
  6432. break;
  6433. case EN_MKD:
  6434. en_mkd = y;
  6435. break;
  6436. case EN_RMD:
  6437. en_rmd = y;
  6438. break;
  6439. case EN_XIT:
  6440. en_xit = y;
  6441. break;
  6442. case EN_ENA:
  6443. if (((y & 1) && !(en_ena & 1)) ||
  6444. ((y & 2) && !(en_ena & 2))) {
  6445. printf("?Sorry, DISABLE ENABLE can not be undone\n");
  6446. return(-9);
  6447. } else {
  6448. en_ena = y;
  6449. break;
  6450. }
  6451. default:
  6452. return(-2);
  6453. }
  6454. return(1);
  6455. }
  6456. #endif /* NOFRILLS */
  6457. #endif /* NOSERVER */
  6458. #ifndef NOFRILLS
  6459. static int del_lis = 0;
  6460. static int del_dot = 0;
  6461. static int del_hdg = 0;
  6462. static int del_pag = -1;
  6463. static int del_ask = 0;
  6464. #ifndef NOSHOW
  6465. VOID
  6466. showdelopts() {
  6467. int x = 0;
  6468. extern int optlines;
  6469. prtopt(&optlines,"");
  6470. prtopt(&optlines,"DELETE");
  6471. if (del_ask > -1) {
  6472. prtopt(&optlines, del_ask ? "/ASK" : "/NOASK");
  6473. x++;
  6474. }
  6475. #ifdef UNIXOROSK
  6476. if (del_dot > -1) {
  6477. prtopt(&optlines, del_dot ? "/DOTFILES" : "/NODOTFILES");
  6478. x++;
  6479. }
  6480. #endif /* UNIXOROSK */
  6481. if (del_lis > -1) {
  6482. prtopt(&optlines, del_lis ? "/LIST" : "/NOLIST");
  6483. x++;
  6484. }
  6485. if (del_hdg > -1) {
  6486. prtopt(&optlines, del_hdg ? "/HEADING" : "/NOHEADING");
  6487. x++;
  6488. }
  6489. #ifndef CK_TTGWSIZ
  6490. if (del_pag > -1) {
  6491. prtopt(&optlines, del_pag ? "/PAGE" : "/NOPAGE");
  6492. x++;
  6493. }
  6494. #endif /* CK_TTGWSIZ */
  6495. if (!x) prtopt(&optlines,"(no options set)");
  6496. prtopt(&optlines,"");
  6497. }
  6498. #endif /* NOSHOW */
  6499. int
  6500. setdelopts() {
  6501. int x_lis = -1, x_pag = -1, x_dot = -1, x_hdg = -1, x_ask = -1;
  6502. int getval = 0;
  6503. char c;
  6504. while (1) {
  6505. if ((y = cmswi(deltab,ndeltab,"Switch","",xxstring)) < 0) {
  6506. if (y == -3)
  6507. break;
  6508. else
  6509. return(y);
  6510. }
  6511. c = cmgbrk();
  6512. if ((getval = (c == ':' || c == '=')) && !(cmgkwflgs() & CM_ARG)) {
  6513. printf("?This switch does not take an argument\n");
  6514. return(-9);
  6515. }
  6516. if (!getval && (cmgkwflgs() & CM_ARG)) {
  6517. printf("?This switch requires an argument\n");
  6518. return(-9);
  6519. }
  6520. switch (y) {
  6521. case DEL_DOT:
  6522. x_dot = 1;
  6523. break;
  6524. case DEL_NOD:
  6525. x_dot = 0;
  6526. break;
  6527. case DEL_HDG:
  6528. x_hdg = 1;
  6529. break;
  6530. case DEL_LIS:
  6531. x_lis = 1;
  6532. break;
  6533. case DEL_NOL:
  6534. x_lis = 0;
  6535. break;
  6536. #ifndef CK_TTGWSIZ
  6537. case DEL_PAG:
  6538. x_pag = 1;
  6539. break;
  6540. case DEL_NOP:
  6541. x_pag = 0;
  6542. break;
  6543. #endif /* CK_TTGWSIZ */
  6544. case DEL_QUI:
  6545. x_lis = 0;
  6546. break;
  6547. case DEL_VRB:
  6548. x_lis = 1;
  6549. break;
  6550. case DEL_ASK:
  6551. x_ask = 1;
  6552. break;
  6553. case DEL_NAS:
  6554. x_ask = 0;
  6555. break;
  6556. default:
  6557. printf("?Sorry, this option can not be set\n");
  6558. return(-9);
  6559. }
  6560. }
  6561. if ((x = cmcfm()) < 0) /* Get confirmation */
  6562. return(x);
  6563. if (x_pag > -1) del_pag = x_pag;
  6564. if (x_dot > -1) del_dot = x_dot;
  6565. if (x_hdg > -1) del_hdg = x_hdg;
  6566. if (x_lis > -1) del_lis = x_lis;
  6567. if (x_ask > -1) del_ask = x_ask;
  6568. return(success = 1);
  6569. }
  6570. #ifdef OS2
  6571. static char ** xmtchs = NULL;
  6572. static int xmtchn = 0;
  6573. #endif /* OS2 */
  6574. int
  6575. dodel() { /* DELETE */
  6576. int i, j, k, x;
  6577. int fs = 0; /* Need to call fileselect() */
  6578. int len = 0;
  6579. int bad = 0;
  6580. int getval = 0, asking = 0;
  6581. int simulate = 0, rc = 0;
  6582. CK_OFF_T minsize = -1L, maxsize = -1L;
  6583. int havename = 0, confirmed = 0;
  6584. int qflag = 0;
  6585. int summary = 0;
  6586. int deldirs = 0;
  6587. int deltree = 0;
  6588. int itsadir = 0;
  6589. int argisdir = 0;
  6590. int xmode = -1, scan = 0, skip = 0;
  6591. #ifdef COMMENT
  6592. int pass = 0;
  6593. #endif /* COMMENT */
  6594. char c;
  6595. char * deldef = "";
  6596. char safebuf[CKMAXPATH+1];
  6597. struct FDB sw, fi, fl;
  6598. char
  6599. * del_aft = NULL,
  6600. * del_bef = NULL,
  6601. * del_naf = NULL,
  6602. * del_nbf = NULL,
  6603. * del_exc = NULL;
  6604. int
  6605. x_lis = 0,
  6606. /* x_dot = -1, */
  6607. x_hdg = 0;
  6608. char * dxlist[8];
  6609. for (i = 0; i < 8; i++) dxlist[i] = NULL;
  6610. g_matchdot = matchdot;
  6611. if (del_lis > -1) x_lis = del_lis;
  6612. if (del_dot > -1) matchdot = del_dot;
  6613. if (del_hdg > -1) x_hdg = del_hdg;
  6614. if (del_pag > -1) xaskmore = del_pag;
  6615. if (del_ask > -1) asking = del_ask;
  6616. diractive = 1;
  6617. nolinks = 2; /* By default don't follow links */
  6618. cmfdbi(&sw, /* First FDB - command switches */
  6619. _CMKEY, /* fcode */
  6620. "File specification;\n or switch",
  6621. "", /* default */
  6622. "", /* addtl string data */
  6623. ndeltab, /* addtl numeric data 1: tbl size */
  6624. 4, /* addtl numeric data 2: 4 = cmswi */
  6625. xxstring, /* Processing function */
  6626. deltab, /* Keyword table */
  6627. &fi /* Pointer to next FDB */
  6628. );
  6629. cmfdbi(&fl, /* Anything that doesn't match */
  6630. _CMFLD, /* fcode */
  6631. "", /* hlpmsg */
  6632. "", /* default */
  6633. "", /* addtl string data */
  6634. 0, /* addtl numeric data 1 */
  6635. 0, /* addtl numeric data 2 */
  6636. xxstring,
  6637. NULL,
  6638. NULL
  6639. );
  6640. again:
  6641. cmfdbi(&fi, /* 2nd FDB - file to delete */
  6642. _CMIFI, /* fcode */
  6643. "File(s) to delete", /* hlpmsg */
  6644. deldef, /* default */
  6645. "", /* addtl string data */
  6646. nolinks | deldirs, /* 0 = files, 1 = files or dirs */
  6647. 0, /* 1 = dirs only */
  6648. xxstring,
  6649. NULL,
  6650. &fl
  6651. );
  6652. while (!havename && !confirmed) {
  6653. x = cmfdb(&sw); /* Parse something */
  6654. if (x < 0) { /* Error */
  6655. if (x == -3)
  6656. break;
  6657. if (x == -2 || x == -9)
  6658. printf("?Does not match switch or filename: \"%s\"\n",atmbuf);
  6659. return(x);
  6660. }
  6661. if (cmresult.fcode != _CMKEY) /* Break out if not a switch */
  6662. break;
  6663. c = cmgbrk(); /* Get break character */
  6664. if ((getval = (c == ':' || c == '=')) && !(cmgkwflgs() & CM_ARG)) {
  6665. printf("?This switch does not take an argument\n");
  6666. rc = -9;
  6667. goto xdelete;
  6668. }
  6669. if (!getval && (cmgkwflgs() & CM_ARG)) {
  6670. printf("?This switch requires an argument\n");
  6671. rc = -9;
  6672. goto xdelete;
  6673. }
  6674. switch (k = cmresult.nresult) {
  6675. case DEL_AFT:
  6676. case DEL_BEF:
  6677. case DEL_NAF:
  6678. case DEL_NBF:
  6679. if (!getval) break;
  6680. if ((x = cmdate("File-time","",&s,0,xxstring)) < 0) {
  6681. if (x == -3) {
  6682. printf("?Date-time required\n");
  6683. x = -9;
  6684. } else
  6685. rc = x;
  6686. goto xdelete;
  6687. }
  6688. fs++;
  6689. deltree = 0;
  6690. switch (k) {
  6691. case DEL_AFT: makestr(&del_aft,s); break;
  6692. case DEL_BEF: makestr(&del_bef,s); break;
  6693. case DEL_NAF: makestr(&del_naf,s); break;
  6694. case DEL_NBF: makestr(&del_nbf,s); break;
  6695. }
  6696. break;
  6697. case DEL_DOT:
  6698. matchdot = 1;
  6699. break;
  6700. case DEL_NOD:
  6701. matchdot = 0;
  6702. break;
  6703. case DEL_ALL:
  6704. fs = 0;
  6705. #ifdef VMS
  6706. deldef = "*.*"; /* UNIX, Windows, OS/2 */
  6707. #else
  6708. #ifdef datageneral
  6709. deldef = "+"; /* AOS/VS */
  6710. #else
  6711. deldef = "*"; /* UNIX, Windows, OS/2, VMS... */
  6712. #endif /* datageneral */
  6713. #endif /* VMS */
  6714. deltree = 1;
  6715. nolinks = 2;
  6716. matchdot = 1;
  6717. recursive = 1; /* Fall through purposely... */
  6718. case DEL_DIR:
  6719. deldirs = 1;
  6720. goto again;
  6721. case DEL_EXC:
  6722. if (!getval) break;
  6723. if ((x = cmfld("Pattern","",&s,xxstring)) < 0) {
  6724. if (x == -3) {
  6725. printf("?Pattern required\n");
  6726. x = -9;
  6727. } else
  6728. rc = x;
  6729. goto xdelete;
  6730. }
  6731. fs++;
  6732. deltree = 0;
  6733. makestr(&del_exc,s);
  6734. break;
  6735. case DEL_HDG:
  6736. x_hdg = 1;
  6737. break;
  6738. #ifdef RECURSIVE
  6739. case DEL_REC:
  6740. recursive = 1;
  6741. break;
  6742. #endif /* RECURSIVE */
  6743. case DEL_LIS:
  6744. x_lis = 1;
  6745. break;
  6746. case DEL_SUM:
  6747. summary = 1;
  6748. x_lis = 0;
  6749. x_hdg = 1;
  6750. break;
  6751. case DEL_NOL:
  6752. x_lis = 0;
  6753. break;
  6754. #ifndef CK_TTGWSIZ
  6755. case DEL_PAG:
  6756. xaskmore = 1;
  6757. break;
  6758. case DEL_NOP:
  6759. xaskmore = 0;
  6760. break;
  6761. #endif /* CK_TTGWSIZ */
  6762. case DEL_QUI:
  6763. qflag = 1;
  6764. x_lis = 0;
  6765. break;
  6766. case DEL_VRB:
  6767. x_lis = 1;
  6768. break;
  6769. case DEL_SMA:
  6770. case DEL_LAR:
  6771. if (!getval) break;
  6772. if ((x = cmnum("File size in bytes","0",10,&y,xxstring)) < 0)
  6773. return(x);
  6774. fs++;
  6775. deltree = 0;
  6776. switch (cmresult.nresult) {
  6777. case DEL_SMA: minsize = y; break;
  6778. case DEL_LAR: maxsize = y; break;
  6779. }
  6780. break;
  6781. case DEL_SIM:
  6782. simulate = 1;
  6783. x_lis = 1;
  6784. break;
  6785. case DEL_ASK:
  6786. asking = 1;
  6787. break;
  6788. case DEL_NAS:
  6789. asking = 0;
  6790. break;
  6791. case DEL_TYP: {
  6792. extern struct keytab txtbin[];
  6793. if (!getval) break;
  6794. if ((x = cmkey(txtbin,3,"","",xxstring)) < 0)
  6795. return(x);
  6796. if (x == 2) { /* ALL */
  6797. xmode = -1;
  6798. } else { /* TEXT or BINARY only */
  6799. xmode = x;
  6800. scan = 1;
  6801. }
  6802. break;
  6803. }
  6804. default:
  6805. printf("?Not implemented yet - \"%s\"\n",atmbuf);
  6806. return(-9);
  6807. }
  6808. }
  6809. if (qflag && (cmresult.fcode == _CMFLD)) {
  6810. if ((x = cmcfm()) < 0)
  6811. return(x);
  6812. else
  6813. return(success = 0);
  6814. }
  6815. if (cmresult.fcode != _CMIFI) {
  6816. if (*atmbuf) {
  6817. int x;
  6818. if (iswild(atmbuf) && nzxpand(atmbuf,nzxopts) == 0)
  6819. printf("?No files match: %s\n",brstrip(atmbuf));
  6820. else if ((x = zchki(atmbuf)) == -1)
  6821. printf("?File not found: %s\n",brstrip(atmbuf));
  6822. else if (x == -2)
  6823. printf("?Not a regular file: %s\n",atmbuf);
  6824. else
  6825. /* printf("?Not a deletable file: %s\n",atmbuf); */
  6826. goto tryanyway;
  6827. } else {
  6828. printf("?A file specification is required\n");
  6829. }
  6830. return(-9);
  6831. }
  6832. tryanyway:
  6833. ckstrncpy(tmpbuf,cmresult.sresult,TMPBUFSIZ); /* Safe copy of filespec */
  6834. if (deldirs) {
  6835. ckstrncpy(safebuf,cmresult.sresult,CKMAXPATH);
  6836. #ifdef VMSORUNIX
  6837. len = zgetfs(tmpbuf); /* Is it a directory name? */
  6838. argisdir = zgfs_dir; /* Then because of how zxpand() */
  6839. if (argisdir && zgfs_link) /* works, we have to add it to */
  6840. argisdir = 0; /* the list. */
  6841. if (itsadir)
  6842. len = -2;
  6843. #else
  6844. len = zchki(tmpbuf);
  6845. if (len < 0)
  6846. argisdir = isdir(tmpbuf);
  6847. #endif /* VMSORUNIX */
  6848. }
  6849. debug(F110,"DELETE file",tmpbuf,0);
  6850. if ((x = cmcfm()) < 0)
  6851. return(x);
  6852. #ifdef IKSD
  6853. #ifdef CK_LOGIN
  6854. if (inserver && isguest) {
  6855. printf("?Sorry, DELETE unavailable to guests\n");
  6856. return(-9);
  6857. }
  6858. #endif /* CK_LOGIN */
  6859. #endif /* IKSD */
  6860. #ifndef OS2ORUNIX
  6861. if (simulate) {
  6862. printf("?Sorry, /SIMULATE not implemented on this platform\n");
  6863. return(-9);
  6864. }
  6865. #endif /* OS2ORUNIX */
  6866. #ifdef COMMENT
  6867. /* (not needed) */
  6868. if (!iswild(tmpbuf)) {
  6869. char *m;
  6870. errno = 0;
  6871. x = zchki(tmpbuf);
  6872. if (x < 0) {
  6873. switch (x) {
  6874. case -2: m = "Not a regular file"; break;
  6875. case -1: m = "File not found or not accessible"; break;
  6876. default: m = errno ? ck_errstr() : "Can't delete";
  6877. }
  6878. printf("?%s: \"%s\"\n",m,tmpbuf);
  6879. return(-9);
  6880. }
  6881. }
  6882. #endif /* COMMENT */
  6883. makelist(del_exc,dxlist,8);
  6884. /* tmpbuf[] has the name - now do any needed conversions on it */
  6885. #ifdef OS2
  6886. { /* Lower level functions change / to \, not good for CMD.EXE. */
  6887. char *p = tmpbuf;
  6888. while (*p) { /* Change them back to \ */
  6889. if (*p == '/') *p = '\\';
  6890. p++;
  6891. }
  6892. }
  6893. #endif /* OS2 */
  6894. #ifdef VMS
  6895. if (iswild(tmpbuf)) {
  6896. #ifdef COMMENT
  6897. /* Does not handle '.' as version separator */
  6898. char *p = tmpbuf;
  6899. x = 0;
  6900. while (*p) {
  6901. if (*p == ';') {
  6902. x = 1;
  6903. break;
  6904. } else
  6905. p++;
  6906. }
  6907. if (!x) ckstrncat(tmpbuf,";*",TMPBUFSIZ);
  6908. #else
  6909. j = 0; x = 0; /* for end_dot and number of dots */
  6910. i = strlen(tmpbuf);
  6911. if (tmpbuf[i] == ';') {
  6912. ckstrncat(tmpbuf,"0",TMPBUFSIZ);
  6913. } else {
  6914. if (tmpbuf[i--] == '.')
  6915. j++;
  6916. for (; i >= 0; i--) {
  6917. if (tmpbuf[i] == ';' || tmpbuf[i] == ':' ||
  6918. tmpbuf[i] == ']' || tmpbuf[i] == '>')
  6919. break;
  6920. else if (tmpbuf[i] == '.')
  6921. x++;
  6922. }
  6923. if (tmpbuf[i] != ';') { /* dot may have been used */
  6924. if (j) { /* last char is dot */
  6925. if (x) /* second is version separator */
  6926. ckstrncat(tmpbuf,"0",TMPBUFSIZ);
  6927. else /* 'foo.' */
  6928. ckstrncat(tmpbuf,";0",TMPBUFSIZ);
  6929. } else if (x == 1) /* lacking a version separator */
  6930. ckstrncat(tmpbuf,";0",TMPBUFSIZ);
  6931. else if (x == 0) /* x == 2 has a version */
  6932. ckstrncat(tmpbuf,".*;0",TMPBUFSIZ);
  6933. }
  6934. }
  6935. #endif /* COMMENT */
  6936. }
  6937. #endif /* VMS */
  6938. debug(F110,"dodel tmpbuf",tmpbuf,0); /* Filename */
  6939. #ifndef OS2ORUNIX /* No built-in DELETE code... */
  6940. /* Construct system command. */
  6941. ckmakmsg(line,LINBUFSIZ,DELCMD," ",tmpbuf,NULL);
  6942. #else
  6943. #ifdef VMS
  6944. if (asking) { /* Maybe overwrite in VMS */
  6945. if (x_lis) /* if options are needed... */
  6946. ckmakmsg(line,LINBUFSIZ,DELCMD," /confirm/log ",tmpbuf,NULL);
  6947. else
  6948. ckmakmsg(line,LINBUFSIZ,DELCMD," /confirm ",tmpbuf,NULL);
  6949. } else if (x_lis)
  6950. ckmakmsg(line,LINBUFSIZ,DELCMD," /log ",tmpbuf,NULL);
  6951. conres();
  6952. #endif /* VMS */
  6953. debug(F110,"dodel line",line,0);
  6954. #endif /* OS2ORUNIX */
  6955. #ifdef MAC
  6956. success = (zdelet(tmpbuf) == 0);
  6957. #else /* !MAC ... */
  6958. #ifdef OS2ORUNIX
  6959. {
  6960. int filespace = 0;
  6961. int count = 0;
  6962. int lines = 0;
  6963. int n = 0;
  6964. s = tmpbuf;
  6965. #ifdef CK_TTGWSIZ
  6966. #ifdef OS2
  6967. ttgcwsz();
  6968. #else /* OS2 */
  6969. /* Check whether window size changed */
  6970. if (ttgwsiz() > 0) {
  6971. if (tt_rows > 0 && tt_cols > 0) {
  6972. cmd_rows = tt_rows;
  6973. cmd_cols = tt_cols;
  6974. }
  6975. }
  6976. #endif /* OS2 */
  6977. #endif /* CK_TTGWSIZ */
  6978. if (x_hdg > 0 && !summary) {
  6979. printf("Deleting %s...%s\n", s, simulate ? " (SIMULATION)" : "");
  6980. n += 2;
  6981. }
  6982. #ifdef ZXREWIND
  6983. z = zxrewind(); /* Rewind file list */
  6984. #else
  6985. if (!deldirs)
  6986. nzxopts = ZX_FILONLY;
  6987. if (recursive) nzxopts |= ZX_RECURSE;
  6988. if (matchdot) nzxopts |= ZX_MATCHDOT;
  6989. errno = 0;
  6990. z = nzxpand(s,nzxopts); /* Expand file list */
  6991. #endif /* ZXREWIND */
  6992. debug(F111,"dodel",s,z);
  6993. /* If deleting directories, sort in reverse order */
  6994. /* so we delete the files first, then the directory. */
  6995. #ifdef OS2
  6996. /* In K95, we have no mtchs array, nor any control over */
  6997. /* the order in which znext() returns filenames, so we */
  6998. /* must copy the array and sort it. */
  6999. {
  7000. int i;
  7001. if (xmtchs) { /* Free previous list in case */
  7002. debug(F101,"dodel freeing previous list","",xmtchn);
  7003. for (i = 0; i < xmtchn; i++) /* it wasn't freed last time. */
  7004. if (xmtchs[i])
  7005. free(xmtchs[i]);
  7006. free(xmtchs);
  7007. }
  7008. xmtchn = 0;
  7009. xmtchs = (char **)malloc(z * (sizeof(char **))); /* Make new one */
  7010. if (!xmtchs) {
  7011. printf("?Memory allocation failure\n");
  7012. return(-9);
  7013. }
  7014. for (i = 0; i < z; i++) {
  7015. xmtchs[i] = NULL;
  7016. znext(tmpbuf);
  7017. if (!*tmpbuf)
  7018. break;
  7019. makestr(&(xmtchs[i]),tmpbuf);
  7020. if (!xmtchs[i]) {
  7021. printf("?Memory allocation failure\n");
  7022. xmtchn = i - 1;
  7023. rc = -9;
  7024. goto xdelete;
  7025. }
  7026. /* debug(F111,"dodel add",xmtchs[i],i); */
  7027. }
  7028. xmtchn = i;
  7029. debug(F101,"dodel xmtchn","",xmtchn);
  7030. sh_sort(xmtchs,NULL,z,0,deldirs,0);
  7031. }
  7032. #else
  7033. #ifdef UNIX
  7034. sh_sort(mtchs,NULL,z,0,deldirs,filecase);
  7035. #endif /* UNIX */
  7036. #endif /* OS2 */
  7037. if (z > 0) {
  7038. int i;
  7039. #ifdef OS2
  7040. int ix = 0;
  7041. #endif /* OS2 */
  7042. success = 1;
  7043. if (x_hdg > 0)
  7044. printf("\n");
  7045. while (
  7046. #ifdef OS2
  7047. ix < xmtchn
  7048. #else
  7049. 1
  7050. #endif /* OS2 */
  7051. ) { /* Loop for all files */
  7052. #ifdef OS2
  7053. ckstrncpy(tmpbuf,xmtchs[ix++],TMPBUFSIZ);
  7054. #else
  7055. znext(tmpbuf); /* Get next file */
  7056. #endif /* OS2 */
  7057. if (!*tmpbuf) { /* No more */
  7058. if (deldirs && recursive && argisdir) {
  7059. ckstrncpy(tmpbuf,safebuf,TMPBUFSIZ);
  7060. argisdir = 0; /* (only do this once) */
  7061. } else
  7062. break;
  7063. }
  7064. skip = 0;
  7065. if (!deltree) {
  7066. if (fs)
  7067. if (fileselect(tmpbuf,
  7068. del_aft,del_bef,del_naf,del_nbf,
  7069. minsize,maxsize,0,8,dxlist) < 1) {
  7070. skip++;
  7071. }
  7072. }
  7073. if (!skip && scan && itsadir) {
  7074. skip++;
  7075. }
  7076. if (!skip && scan) {
  7077. switch (scanfile(tmpbuf,&y,nscanfile)) {
  7078. case FT_BIN:
  7079. if (xmode != 1)
  7080. skip++;
  7081. break;
  7082. case FT_TEXT:
  7083. case FT_7BIT:
  7084. case FT_8BIT:
  7085. #ifdef UNICODE
  7086. case FT_UTF8:
  7087. case FT_UCS2:
  7088. #endif /* UNICODE */
  7089. if (xmode != 0)
  7090. skip++;
  7091. }
  7092. }
  7093. if (!skip && asking) {
  7094. int x;
  7095. ckmakmsg(line,LINBUFSIZ," Delete ",tmpbuf,"? ",NULL);
  7096. x = getyesno(line,3);
  7097. switch (x) {
  7098. case 0: continue; /* no */
  7099. case 1: break; /* yes */
  7100. case 2: goto xdelete; /* quit */
  7101. case 3: asking = 0; break; /* go */
  7102. }
  7103. }
  7104. #ifdef VMSORUNIX
  7105. len = zgetfs(tmpbuf); /* Get length and accessibility */
  7106. itsadir = zgfs_dir;
  7107. if (itsadir && zgfs_link) { /* Treat links to directories */
  7108. itsadir = 0; /* as regular files */
  7109. if (scan) /* But not if /TYPE: was given */
  7110. skip++;
  7111. }
  7112. if (itsadir) /* (emulate non-Unix code) */
  7113. len = -2;
  7114. #else
  7115. len = zchki(tmpbuf); /* Get accessibility */
  7116. if (len < 0) /* See if it's a directory */
  7117. itsadir = isdir(tmpbuf);
  7118. #endif /* VMSORUNIX */
  7119. if (skip) {
  7120. #ifdef COMMENT /* Too verbose */
  7121. if (x_lis > 0) {
  7122. lines++;
  7123. printf(" %s (SKIPPED)\n",tmpbuf);
  7124. #ifdef CK_TTGWSIZ
  7125. if (++n > cmd_rows - 3)
  7126. if (!askmore()) goto xdelete; else n = 0;
  7127. #endif /* CK_TTGWSIZ */
  7128. }
  7129. #endif /* COMMENT */
  7130. continue;
  7131. }
  7132. debug(F111,"DELETE len",tmpbuf,len);
  7133. if (simulate) {
  7134. filespace += len;
  7135. count++;
  7136. if (x_lis > 0) {
  7137. lines++;
  7138. printf(" %s (SELECTED)\n",tmpbuf);
  7139. if (++n > cmd_rows - 3) {
  7140. int xx;
  7141. xx = askmore();
  7142. if (!xx) goto xdelete; else n = 0;
  7143. }
  7144. }
  7145. } else if (len >= 0 || !itsadir) { /* Regular file */
  7146. zdelet(tmpbuf); /* or symlink, etc... */
  7147. if (zchki(tmpbuf) < 0) {
  7148. filespace += len;
  7149. count++;
  7150. if (x_lis > 0) {
  7151. lines++;
  7152. printf(" %s (OK)\n",tmpbuf);
  7153. if (++n > cmd_rows - 3)
  7154. if (!askmore()) goto xdelete; else n = 0;
  7155. }
  7156. } else {
  7157. bad++;
  7158. success = 0;
  7159. if (x_lis > 0) {
  7160. lines++;
  7161. printf(" %s (FAILED: %s)\n",tmpbuf,ck_errstr());
  7162. if (++n > cmd_rows - 3)
  7163. if (!askmore()) goto xdelete; else n = 0;
  7164. }
  7165. }
  7166. } else if (/* pass > 0 && */ deldirs && itsadir) {
  7167. /* It's a directory */
  7168. if (zrmdir(tmpbuf) > -1) { /* Only works if empty */
  7169. count++;
  7170. if (x_lis > 0) {
  7171. lines++;
  7172. printf(" %s (OK)\n",tmpbuf);
  7173. if (++n > cmd_rows - 3)
  7174. if (!askmore()) goto xdelete; else n = 0;
  7175. }
  7176. } else {
  7177. success = 0;
  7178. if (x_lis > 0) {
  7179. lines++;
  7180. printf(" %s (FAILED: %s)\n",
  7181. tmpbuf,
  7182. ck_errstr());
  7183. if (++n > cmd_rows - 3)
  7184. if (!askmore()) goto xdelete; else n = 0;
  7185. }
  7186. }
  7187. } else if (x_lis > 0) {
  7188. lines++;
  7189. if (isdir(tmpbuf))
  7190. printf(" %s (FAILED: directory)\n",tmpbuf);
  7191. else
  7192. printf(" %s (FAILED: not a regular file)\n",tmpbuf);
  7193. if (++n > cmd_rows - 3)
  7194. if (!askmore()) goto xdelete; else n = 0;
  7195. }
  7196. }
  7197. if (x_hdg > 0) {
  7198. if (lines > 0)
  7199. printf("\n");
  7200. if (++n > cmd_rows - 3)
  7201. if (!askmore()) goto xdelete; else n = 0;
  7202. printf("%d file%s %sdeleted, %d byte%s %sfreed%s\n",
  7203. count,
  7204. count != 1 ? "s" : "",
  7205. simulate ? "would be " : "",
  7206. filespace,
  7207. filespace != 1 ? "s" : "",
  7208. simulate ? "would be " : "",
  7209. simulate ? " (maybe)" : ""
  7210. );
  7211. }
  7212. if (!x_lis && !success && !quiet) {
  7213. printf("?DELETE failed for %d file%s \
  7214. (use DELETE /LIST to see details)\n",
  7215. bad, bad == 1 ? "" : "s"
  7216. );
  7217. }
  7218. } else if (x_lis > 0) {
  7219. if (errno)
  7220. printf("?%s: %s\n",ck_errstr(), tmpbuf);
  7221. else
  7222. printf("?Can't delete: %s\n",tmpbuf);
  7223. }
  7224. }
  7225. #else /* OS2ORUNIX */
  7226. #ifndef VMS /* Others - let the system do it. */
  7227. xsystem(line);
  7228. x = nzxpand(tmpbuf,nzxopts);
  7229. success = (x > 0) ? 0 : 1;
  7230. if (x_hdg > 0)
  7231. printf("%s - %sdeleted\n", tmpbuf, success ? "" : "not ");
  7232. #else
  7233. if (asking)
  7234. printf("\n");
  7235. x = xsystem(line); /* zshcmd returns 1 for success */
  7236. success = (x > 0) ? 1 : 0;
  7237. if (x_hdg > 0 && !asking)
  7238. printf("%s - %sdeleted\n", tmpbuf, success ? "" : "not ");
  7239. concb((char)escape);
  7240. #endif /* VMS */
  7241. #endif /* OS2ORUNIX */
  7242. #endif /* MAC */
  7243. xdelete:
  7244. if (g_matchdot > -1) {
  7245. matchdot = g_matchdot; /* Restore these... */
  7246. g_matchdot = -1;
  7247. }
  7248. #ifdef OS2
  7249. if (xmtchs) {
  7250. int i;
  7251. debug(F101,"dodel freeing list","",xmtchn);
  7252. for (i = 0; i < xmtchn; i++)
  7253. if (xmtchs[i]) free(xmtchs[i]);
  7254. free(xmtchs);
  7255. xmtchs = NULL;
  7256. xmtchn = 0;
  7257. }
  7258. #endif /* OS2 */
  7259. debug(F101,"dodel result","",rc);
  7260. return((rc < 0) ? rc : success);
  7261. }
  7262. #endif /* NOFRILLS */
  7263. #ifndef NOSPL /* The ELSE command */
  7264. _PROTOTYP( VOID pushqcmd, (char *) );
  7265. int
  7266. doelse() {
  7267. if (!ifcmd[cmdlvl]) {
  7268. printf("?ELSE doesn't follow IF\n");
  7269. return(-2);
  7270. }
  7271. #ifdef COMMENT
  7272. /*
  7273. Wrong. This prevents IF..ELSE IF...ELSE IF...ELSE IF...ELSE...
  7274. from working.
  7275. */
  7276. ifcmd[cmdlvl] = 0;
  7277. #endif /* COMMENT */
  7278. if (!iftest[cmdlvl]) { /* If IF was false do ELSE part */
  7279. if (maclvl > -1 || tlevel > -1) { /* In macro or command file */
  7280. debug(F100,"doelse pushing","",0);
  7281. #ifndef COMMENT
  7282. pushcmd(NULL); /* save rest of command. */
  7283. #else
  7284. /* This fixes certain obscure problems */
  7285. /* but breaks many other constructions that must work. */
  7286. pushqcmd(NULL);
  7287. #endif /* COMMENT */
  7288. } else { /* If interactive, */
  7289. cmini(ckxech); /* just start a new command */
  7290. printf("\n"); /* (like in MS-DOS Kermit) */
  7291. if (pflag) prompt(xxstring);
  7292. }
  7293. } else { /* Condition is false */
  7294. if ((y = cmtxt("command to be ignored","",&s,NULL)) < 0)
  7295. return(y); /* Gobble up rest of line */
  7296. }
  7297. return(0);
  7298. }
  7299. #endif /* NOSPL */
  7300. #ifndef NOSPL
  7301. int
  7302. doswitch() {
  7303. char *lp, *ap; /* Macro argument pointer */
  7304. int len = 0, x, y, pp = 0;
  7305. char brbuf[3];
  7306. /* Get variable name */
  7307. tmpbuf[0] = NUL;
  7308. brbuf[0] = '{';
  7309. brbuf[1] = '}';
  7310. brbuf[2] = NUL;
  7311. y = cmfld("Variable name","",&s,xxstring);
  7312. debug(F111,"doswitch cmfld",s,y);
  7313. if (y < 0) {
  7314. if (y == -3) /* Because brstrip() writes */
  7315. s = brbuf; /* into its argument. */
  7316. else
  7317. return(y);
  7318. }
  7319. debug(F110,"doswitch A",s,0);
  7320. if (!strcmp(s,"(")) {
  7321. pp++;
  7322. if ((y = cmfld("Variable name","",&s,xxstring)) < 0) {
  7323. if (y == -3)
  7324. s = brbuf;
  7325. else
  7326. return(y);
  7327. debug(F110,"doswitch B",s,0);
  7328. }
  7329. }
  7330. len = ckstrncpy(tmpbuf,brstrip(s),TMPBUFSIZ);
  7331. if (tmpbuf[0] == CMDQ) {
  7332. if (chkvar(s) < 1) {
  7333. printf("?Variable name required\n");
  7334. return(-9);
  7335. }
  7336. }
  7337. if (pp > 0) { /* If open paren given parse closing */
  7338. if ((y = cmfld("Closing parenthesis","",&s,NULL)) < 0)
  7339. return(y);
  7340. if (strcmp(atmbuf,")")) {
  7341. printf("?Closing parenthesis required\n");
  7342. return(-9);
  7343. }
  7344. }
  7345. lp = line;
  7346. x = ckstrncpy(lp,"_switx ",LINBUFSIZ); /* _switx + space */
  7347. lp += x;
  7348. ap = lp;
  7349. debug(F010,"SWITCH a",line,0);
  7350. #ifdef COMMENT
  7351. x = ckmakmsg(lp,LINBUFSIZ-x,tmpbuf," ",NULL,NULL); /* variable name + SP */
  7352. #else
  7353. { /* variable name + SP */
  7354. char * p = tmpbuf;
  7355. if (len > 0) {
  7356. if (tmpbuf[0] == '(' && tmpbuf[len-1] == ')') {
  7357. tmpbuf[len-1] = NUL;
  7358. p++;
  7359. }
  7360. }
  7361. x = ckmakmsg(lp,LINBUFSIZ-x,"{",brstrip(p),"}"," ");
  7362. }
  7363. #endif /* COMMENT */
  7364. debug(F010,"SWITCH b",line,0);
  7365. lp += x;
  7366. /* Get body */
  7367. if ((y = cmtxt("series of cases","",&s,NULL)) < 0) return(y);
  7368. if ((y = (int)strlen(s)) < 1) return(-2);
  7369. if (s[0] != '{' && s[y-1] != '}') { /* Supply braces if missing */
  7370. ckmakmsg(tmpbuf,TMPBUFSIZ,"{ ",s," }",NULL);
  7371. s = tmpbuf;
  7372. }
  7373. if (litcmd(&s,&lp,(LINBUFSIZ - (lp - (char *)line) - 2)) < 0) {
  7374. printf("?Unbalanced braces\n");
  7375. return(0);
  7376. }
  7377. debug(F010,"SWITCH c",line,0);
  7378. x = mlook(mactab,"_switx",nmac); /* Look up SWITCH macro definition */
  7379. if (x < 0) { /* Not there? */
  7380. addmmac("_switx",sw_def); /* Put it back. */
  7381. if ((x = mlook(mactab,"_switx",nmac)) < 0) { /* Look it up again. */
  7382. printf("?SWITCH macro definition gone!\n"); /* Shouldn't happen. */
  7383. return(success = 0);
  7384. }
  7385. }
  7386. debug(F010,"SWITCH command",line,0); /* Execute the SWITCH macro. */
  7387. success = dodo(x,ap,cmdstk[cmdlvl].ccflgs | CF_IMAC);
  7388. debug(F101,"SWITCH status","",success);
  7389. return(success);
  7390. }
  7391. int
  7392. dofor() { /* The FOR command. */
  7393. int i, fx, fy, fz; /* loop variables */
  7394. char *ap, *di; /* macro argument pointer */
  7395. int pp = 0; /* Paren level */
  7396. int mustquote = 0;
  7397. char loopvar[8], loopvar2[8]; /* \%x-style loop variable */
  7398. debug(F100,"dofor entry","",0);
  7399. for (i = 0; i < 2; i++) {
  7400. if ((y = cmfld("Variable name","",&s,NULL)) < 0) {
  7401. if (y == -3) {
  7402. printf("?Variable name required\n");
  7403. return(-9);
  7404. } else
  7405. return(y);
  7406. }
  7407. if (strcmp(s,"("))
  7408. break;
  7409. pp++;
  7410. }
  7411. #ifdef COMMENT
  7412. if ((y = parsevar(s,&x,&z)) < 0) /* Check variable. */
  7413. return(y);
  7414. #else
  7415. if (*s == CMDQ) /* If loop variable starts with */
  7416. mustquote++; /* backslash, mustquote is > 0. */
  7417. #endif /* COMMENT */
  7418. debug(F111," dofor loop variable mustquote",s,mustquote);
  7419. lp = line; /* Build a copy of the command */
  7420. ckstrncpy(lp,"_forx ",LINBUFSIZ);
  7421. lp += (int)strlen(line); /* "_for" macro. */
  7422. ap = lp; /* Save pointer to macro args. */
  7423. if (*s == CMDQ) s++; /* Skip past backslash if any. */
  7424. while ((*lp++ = *s++)) ; /* copy it */
  7425. lp--; *lp++ = SP; /* add a space */
  7426. if ((y = cmnum("initial value","",10,&fx,xxstring)) < 0) {
  7427. if (y == -3) return(-2);
  7428. else return(y);
  7429. }
  7430. debug(F101," dofor fx","",fx);
  7431. s = atmbuf; /* Copy the atom buffer */
  7432. if ((int)strlen(s) < 1) goto badfor;
  7433. /*
  7434. In edit 192, we change the loop variables to be evaluated at loop entry,
  7435. not each time through the loop. This was required in order to allow
  7436. \v(argc) to be used as a loop variable, or in a loop-variable expression.
  7437. Thus, we can't have FOR loops that modify their own exit conditions by
  7438. changing the final value or the increment. The problem with \v(argc) was
  7439. that it is on the macro stack; after entry into the _forx macro, it is at
  7440. the wrong place.
  7441. */
  7442. sprintf(tmpbuf,"%d",fx); /* (SAFE) Substitute actual value */
  7443. s = tmpbuf;
  7444. while ((*lp++ = *s++)) ; /* (what they actually typed) */
  7445. lp--; *lp++ = SP;
  7446. #ifdef DEBUG
  7447. *lp = NUL;
  7448. debug(F110," dofor line A",line,0);
  7449. #endif /* DEBUG */
  7450. if ((y = cmnum("final value","",10,&fy,xxstring)) < 0) {
  7451. if (y == -3) return(-2);
  7452. else return(y);
  7453. }
  7454. debug(F101," dofor loop exit value","",fy);
  7455. s = atmbuf; /* Same deal */
  7456. if ((int)strlen(s) < 1)
  7457. goto badfor;
  7458. sprintf(tmpbuf,"%d",fy); /* SAFE */
  7459. s = tmpbuf;
  7460. while ((*lp++ = *s++)) ;
  7461. lp--;
  7462. *lp++ = SP;
  7463. #ifdef DEBUG
  7464. *lp = NUL;
  7465. debug(F110," dofor line B",line,0);
  7466. #endif /* DEBUG */
  7467. x_ifnum = 1; /* Increment or parenthesis */
  7468. di = (fx < fy) ? "1" : "-1"; /* Default increment */
  7469. debug(F110," dofor default increment",di,0);
  7470. if ((y = cmnum("increment",di,10,&fz,xxstring)) < 0) {
  7471. debug(F111," dofor increment parse failed",atmbuf,y);
  7472. x_ifnum = 0;
  7473. if (y == -3) { /* Premature termination */
  7474. return(-2);
  7475. } else if (y == -2) { /* Maybe closing paren */
  7476. if (!strcmp(atmbuf,")")) {
  7477. pp--; /* Count it */
  7478. s = di; /* supply default interval */
  7479. fz = atoi(s);
  7480. } else /* Not closing paren, invalid */
  7481. return(y);
  7482. } else /* Other error */
  7483. return(y);
  7484. debug(F101," dofor default increment supplied","",fz);
  7485. } else { /* Number */
  7486. x_ifnum = 0;
  7487. debug(F101," dofor parsed increment ok","",fz);
  7488. s = atmbuf; /* Use it */
  7489. }
  7490. if ((int)strlen(s) < 1)
  7491. goto badfor;
  7492. sprintf(tmpbuf,"%d",fz); /* (SAFE) Same deal */
  7493. s = tmpbuf;
  7494. while ((*lp++ = *s++)) ;
  7495. lp--; *lp++ = SP;
  7496. #ifdef DEBUG
  7497. *lp = NUL;
  7498. debug(F110," dofor FOR command C",line,0);
  7499. #endif /* DEBUG */
  7500. /* Insert the appropriate comparison operator */
  7501. if (fz < 0)
  7502. *lp++ = '<';
  7503. else
  7504. *lp++ = '>';
  7505. *lp++ = SP;
  7506. #ifdef DEBUG
  7507. *lp = NUL;
  7508. debug(F110," dofor FOR command D",line,0);
  7509. #endif /* DEBUG */
  7510. if (pp > 0) { /* If open paren given parse closing */
  7511. if ((y = cmfld("Closing parenthesis","",&s,NULL)) < 0)
  7512. return(y);
  7513. if (strcmp(atmbuf,")")) {
  7514. printf("?Closing parenthesis required\n");
  7515. return(-9);
  7516. }
  7517. }
  7518. if ((y = cmtxt("Command(s) to execute","",&s,NULL)) < 0) return(y);
  7519. if ((y = (int)strlen(s)) < 1) return(-2);
  7520. debug(F110," doif FOR body A",s,0);
  7521. if (s[0] != '{' && s[y-1] != '}') { /* Supply braces if missing */
  7522. ckmakmsg(tmpbuf,TMPBUFSIZ,"{ ",s," }",NULL);
  7523. s = tmpbuf;
  7524. }
  7525. debug(F110," doif FOR body B",s,0);
  7526. if (litcmd(&s,&lp,(LINBUFSIZ - (lp - (char *)line) - 2)) < 0) {
  7527. printf("?Unbalanced braces\n");
  7528. return(0);
  7529. }
  7530. #ifdef DEBUG
  7531. *lp = NUL;
  7532. debug(F110," doif FOR body C",s,0);
  7533. #endif /* DEBUG */
  7534. #ifdef COMMENT
  7535. /* Too strict */
  7536. if (fz == 0) {
  7537. printf("?Zero increment not allowed\n");
  7538. return(0);
  7539. }
  7540. #endif /* COMMENT */
  7541. /*
  7542. In C-Kermit 8.0 we allow bare macro names anywhere a numeric-valed variable
  7543. could appear. But this caused trouble for the FOR loops because the quoting
  7544. in for_def[] assumed a \%i-style loop variable. We account for this here in
  7545. the if (mustquote)...else logic by invoking separate FOR macro definitions
  7546. in the two cases.
  7547. */
  7548. debug(F100," dofor choosing FOR macro definition","",0);
  7549. if (mustquote) { /* \%i-style loop variable */
  7550. debug(F101," dofor choosing _forx because mustquote","",mustquote);
  7551. x = mlook(mactab,"_forx",nmac); /* Look up FOR macro definition */
  7552. if (x < 0) { /* Not there? */
  7553. addmmac("_forx",for_def); /* Put it back. */
  7554. if ((x = mlook(mactab,"_forx",nmac)) < 0) { /* Look it up again. */
  7555. printf("?FOR macro definition gone!\n");
  7556. return(success = 0);
  7557. }
  7558. debug(F110," dofor loop var is \\%x",for_def[0],0);
  7559. }
  7560. } else { /* Loop variable is a macro */
  7561. debug(F101," dofor choosing _forz because mustquote","",mustquote);
  7562. x = mlook(mactab,"_forz",nmac);
  7563. if (x < 0) {
  7564. addmmac("_forz",foz_def);
  7565. if ((x = mlook(mactab,"_forz",nmac)) < 0) {
  7566. printf("?FOR macro definition gone!\n");
  7567. return(success = 0);
  7568. }
  7569. }
  7570. debug(F110," dofor loop var is macro",foz_def[0],0);
  7571. }
  7572. debug(F010," dofor final FOR body",line,0); /* Execute the FOR macro. */
  7573. debug(F100," dofor done, chaining to dodo()...","",0);
  7574. return(success = dodo(x,ap,cmdstk[cmdlvl].ccflgs | CF_IMAC));
  7575. badfor:
  7576. printf("?Incomplete FOR command\n");
  7577. debug(F100," dofoar parse failure","",0);
  7578. return(-2);
  7579. }
  7580. #endif /* NOSPL */
  7581. #ifndef NOSPL
  7582. /* T O D 2 S E C -- Convert time of day as hh:mm:ss to secs since midnite */
  7583. /*
  7584. Call with a string hh:mm or hh:mm:ss.
  7585. Returns a 0 to 86400 on success, or a negative number on failure.
  7586. */
  7587. long
  7588. tod2sec(t) char * t; {
  7589. long t2;
  7590. long hh = 0L, mm = 0L, ss = 0L;
  7591. if (!t) t = "";
  7592. if (!*t)
  7593. return(-3L);
  7594. debug(F110,"tod2sec",t,0);
  7595. if (isdigit(*t)) /* Get hours from argument */
  7596. hh = *t++ - '0';
  7597. else
  7598. return(-1L);
  7599. if (isdigit(*t))
  7600. hh = hh * 10 + *t++ - '0';
  7601. #ifdef COMMENT
  7602. if (hh > 24L)
  7603. return(-1L);
  7604. #endif /* COMMENT */
  7605. if (*t == ':')
  7606. t++;
  7607. else if (!*t)
  7608. goto xtod2sec;
  7609. else
  7610. return(-1L);
  7611. if (isdigit(*t)) /* Minutes */
  7612. mm = *t++ - '0';
  7613. else
  7614. return(-1L);
  7615. if (isdigit(*t))
  7616. mm = mm * 10 + *t++ - '0';
  7617. if (mm > 60L)
  7618. return(-1L);
  7619. if (*t == ':')
  7620. t++;
  7621. else if (!*t)
  7622. goto xtod2sec;
  7623. else
  7624. return(-1L);
  7625. if (isdigit(*t)) /* Seconds */
  7626. ss = *t++ - '0';
  7627. else
  7628. return(-1L);
  7629. if (isdigit(*t))
  7630. ss = ss * 10 + *t++ - '0';
  7631. if (ss > 60L)
  7632. return(-1L);
  7633. if (*t > 32) /* No trailing junk allowed */
  7634. return(-1L);
  7635. xtod2sec:
  7636. t2 = hh * 3600L + mm * 60L + ss; /* Seconds since midnight from arg */
  7637. debug(F101,"tod2sec t2","",t2);
  7638. return(t2);
  7639. }
  7640. int waitinterval = 1;
  7641. #ifdef OLDWAIT
  7642. #undef OLDWAIT
  7643. #endif /* OLDWAIT */
  7644. int kbchar = NUL;
  7645. int
  7646. dopaus(cx) int cx; {
  7647. long zz;
  7648. extern int sleepcan;
  7649. #ifdef OLDWAIT
  7650. zz = -1L;
  7651. x_ifnum = 1; /* Turn off internal complaints */
  7652. if (cx == XXWAI)
  7653. y = cmnum("seconds to wait, or time of day hh:mm:ss","1",10,&x,xxstring);
  7654. else if (cx == XXPAU)
  7655. y = cmnum("seconds to pause, or time of day hh:mm:ss",
  7656. "1",10,&x,xxstring);
  7657. else
  7658. y = cmnum("milliseconds to sleep, or time of day hh:mm:ss",
  7659. "100",10,&x,xxstring);
  7660. x_ifnum = 0;
  7661. if (y < 0) {
  7662. if (y == -2) { /* Invalid number or expression */
  7663. char *p = tmpbuf; /* Retrieve string from atmbuf */
  7664. int n = TMPBUFSIZ;
  7665. *p = NUL;
  7666. zzstring(atmbuf,&p,&n); /* Evaluate in case it's a variable */
  7667. zz = tod2sec(tmpbuf); /* Convert to secs since midnight */
  7668. if (zz < 0L) {
  7669. printf("?Number, expression, or time of day required\n");
  7670. return(-9);
  7671. } else {
  7672. char now[32]; /* Current time */
  7673. char *p;
  7674. long tnow;
  7675. p = now;
  7676. ztime(&p);
  7677. tnow = atol(p+11) * 3600L + atol(p+14) * 60L + atol(p+17);
  7678. if (zz < tnow) /* User's time before now */
  7679. zz += 86400L; /* So make it tomorrow */
  7680. zz -= tnow; /* Seconds from now. */
  7681. }
  7682. } else
  7683. return(y);
  7684. }
  7685. if (x < 0) x = 0;
  7686. switch (cx) {
  7687. case XXPAU: /* PAUSE */
  7688. case XXMSL: /* MSLEEP */
  7689. if ((y = cmcfm()) < 0) return(y);
  7690. break;
  7691. case XXWAI: /* WAIT */
  7692. z = 0; /* Modem signal mask */
  7693. while (1) { /* Read zero or more signal names */
  7694. y = cmkey(mstab,nms,"modem signal","",xxstring);
  7695. if (y == -3) break; /* -3 means they typed CR */
  7696. if (y < 0) return(y); /* Other negatives are errors */
  7697. z |= y; /* OR the bit into the signal mask */
  7698. }
  7699. if ((y = cmcfm()) < 0) return(y);
  7700. break;
  7701. default: /* Shouldn't happen */
  7702. return(-2);
  7703. }
  7704. /* Command is entered, now do it. */
  7705. if (zz > -1L) { /* Time of day given? */
  7706. x = zz;
  7707. if (zz != (long) x) {
  7708. printf(
  7709. "Sorry, arithmetic overflow - hh:mm:ss not usable on this platform.\n"
  7710. );
  7711. return(-9);
  7712. }
  7713. }
  7714. if (cx == XXMSL) { /* Millisecond sleep */
  7715. msleep(zz < 0 ? x : x * 1000);
  7716. return(success = 1);
  7717. }
  7718. if (cx == XXPAU && !sleepcan) { /* SLEEP CANCELLATION is OFF */
  7719. sleep(x);
  7720. return(success = 1);
  7721. }
  7722. /* WAIT, or else SLEEP with cancellation allowed... */
  7723. do { /* Sleep loop */
  7724. int mdmsig;
  7725. if (sleepcan) { /* Keyboard cancellation allowed? */
  7726. if (y = conchk()) { /* Did they type something? */
  7727. #ifdef COMMENT
  7728. while (y--) coninc(0); /* Yes, gobble it all up */
  7729. #else
  7730. /* There is a debate over whether PAUSE should absorb */
  7731. /* its cancelling character(s). There are several */
  7732. /* reasons why it should gobble at least one character: */
  7733. /* (1) MS-DOS Kermit does it */
  7734. /* (2) if not, subsequent PAUSE commands will terminate */
  7735. /* immediately */
  7736. /* (3) if not, subsequent ASK commands will use it as */
  7737. /* valid input. If \13, then it will get no input */
  7738. /* (4) if not, then the character appears on the command */
  7739. /* line after all enclosing macros are complete. */
  7740. kbchar = coninc(0); /* Gobble one up */
  7741. #endif /* COMMENT */
  7742. break; /* And quit PAUSing or WAITing */
  7743. }
  7744. }
  7745. if (cx == XXWAI) { /* WAIT (z == modem signal mask) */
  7746. debug(F101,"WAIT x","",x);
  7747. if (z > 0) { /* Looking for any modem signals? */
  7748. mdmsig = ttgmdm(); /* Yes, get them */
  7749. if (mdmsig < 0) /* Failed */
  7750. return(success = 0);
  7751. if ((mdmsig & z) == z) /* Got what we wanted? */
  7752. return(success = 1); /* Succeed */
  7753. }
  7754. if (x == 0) /* WAIT 0 and didn't get our signals */
  7755. break;
  7756. }
  7757. sleep(1); /* No interrupt, sleep one second */
  7758. } while (--x > 0);
  7759. if (cx == XXWAI) /* If WAIT and loop exhausted */
  7760. success = (z == 0); /* Fail. */
  7761. else /* */
  7762. success = (x == 0); /* Set SUCCESS/FAILURE for PAUSE. */
  7763. return(success);
  7764. #else /* New code uses chained FDBs and allows FILE waits... */
  7765. char * m = ""; /* Help message */
  7766. struct FDB nu, fl; /* Parse function descriptor blocks */
  7767. int filewait = 0;
  7768. int mdmsig = 0, fs = 0;
  7769. char filedate[32];
  7770. kbchar = 0;
  7771. switch (cx) {
  7772. case XXWAI: m = "seconds to wait, or time of day hh:mm:ss"; break;
  7773. case XXPAU: m = "seconds to pause, or time of day hh:mm:ss"; break;
  7774. case XXMSL: m = "milliseconds to sleep, or time of day hh:mm:ss"; break;
  7775. }
  7776. zz = -1L;
  7777. cmfdbi(&nu,
  7778. _CMNUM, /* Number */
  7779. m, /* Help message */
  7780. (cx == XXMSL) ? "100" : "1", /* Default */
  7781. "", /* N/A */
  7782. 0, /* N/A */
  7783. 0, /* N/A */
  7784. xxstring, /* Processing function */
  7785. NULL, /* N/A */
  7786. &fl /* Next */
  7787. );
  7788. cmfdbi(&fl, /* Time of day */
  7789. _CMFLD, /* Field */
  7790. "", /* hlpmsg */
  7791. "", /* default */
  7792. "", /* addtl string data */
  7793. 0, /* addtl numeric data 1 */
  7794. 0, /* addtl numeric data 2 */
  7795. xxstring, /* processing func */
  7796. NULL, /* N/A */
  7797. NULL /* No next */
  7798. );
  7799. x = cmfdb(&nu); /* Parse a number or a field */
  7800. if (x < 0) {
  7801. if (x == -3)
  7802. x = -2;
  7803. return(x);
  7804. }
  7805. switch (cmresult.fcode) {
  7806. case _CMNUM: /* Number */
  7807. x = cmresult.nresult;
  7808. break;
  7809. case _CMFLD: /* Field */
  7810. zz = tod2sec(cmresult.sresult); /* Convert to secs since midnight */
  7811. if (zz < 0L) {
  7812. printf("?Number, expression, or time of day required\n");
  7813. return(-9);
  7814. } else {
  7815. char now[32]; /* Current time */
  7816. char *p;
  7817. long tnow;
  7818. p = now;
  7819. ztime(&p);
  7820. tnow = atol(p+11) * 3600L + atol(p+14) * 60L + atol(p+17);
  7821. if (zz < tnow) /* User's time before now */
  7822. zz += 86400L; /* So make it tomorrow */
  7823. zz -= tnow; /* Seconds from now. */
  7824. }
  7825. }
  7826. debug(F101,"PAUSE/WAIT/MSLEEP zz","",zz);
  7827. switch (cx) {
  7828. case XXPAU: /* PAUSE */
  7829. case XXMSL: /* MSLEEP */
  7830. if ((y = cmcfm()) < 0) return(y);
  7831. break;
  7832. case XXWAI: /* WAIT */
  7833. z = 0; /* Modem signal mask */
  7834. y = cmkey(waittab,nwaittab,"","",xxstring);
  7835. if (y < 0) {
  7836. if (y == -3) {
  7837. if ((y = cmcfm()) < 0)
  7838. return(y);
  7839. break;
  7840. } else
  7841. return(y);
  7842. }
  7843. if (y == WAIT_FIL) { /* FILE */
  7844. int wild = 0;
  7845. if ((z = cmkey(wfswi,nwfswi,"event","",xxstring)) < 0)
  7846. return(z);
  7847. filewait = z;
  7848. if (filewait == WF_MOD || filewait == WF_DEL)
  7849. z = cmifi("Filename","",&s,&wild,xxstring);
  7850. else
  7851. z = cmfld("Filename","",&s,xxstring);
  7852. if (z < 0)
  7853. return(z);
  7854. if (wild || ((filewait == WF_CRE) && iswild(s))) {
  7855. printf("?Wildcards not valid here\n");
  7856. return(-9);
  7857. }
  7858. ckstrncpy(tmpbuf,s,TMPBUFSIZ);
  7859. if ((z = cmcfm()) < 0)
  7860. return(z);
  7861. break;
  7862. } else if (y != WAIT_MDM) { /* A modem signal */
  7863. z |= y; /* OR the bit into the signal mask */
  7864. }
  7865. if (!filewait) { /* Modem signals... */
  7866. while (1) { /* Get zero or more signal names */
  7867. y = cmkey(mstab,nms,"modem signal","",xxstring);
  7868. if (y == -3) break; /* -3 means they typed CR */
  7869. if (y < 0) return(y); /* Other negatives are errors */
  7870. z |= y; /* OR the bit into the signal mask */
  7871. }
  7872. if ((y = cmcfm()) < 0) return(y);
  7873. break;
  7874. }
  7875. default: /* Shouldn't happen */
  7876. return(-2);
  7877. } /* switch (cx) */
  7878. /* Command is entered, now do it. */
  7879. if (zz > -1L) { /* Time of day given? */
  7880. x = zz;
  7881. if (zz != (long) x) {
  7882. printf(
  7883. "Sorry, arithmetic overflow - hh:mm:ss not usable on this platform.\n"
  7884. );
  7885. return(-9);
  7886. }
  7887. }
  7888. if (sleepcan)
  7889. concb((char)escape); /* Ensure single-char wakeup */
  7890. if (cx == XXMSL) { /* Millisecond sleep */
  7891. msleep(zz < 0 ? x : x * 1000);
  7892. return(success = 1);
  7893. }
  7894. if (cx == XXPAU && !sleepcan) { /* SLEEP CANCELLATION is OFF */
  7895. sleep(x);
  7896. return(success = 1);
  7897. }
  7898. if (filewait) { /* FILE... */
  7899. fs = zchki(tmpbuf); /* Check if file exists */
  7900. switch (filewait) {
  7901. case WF_DEL:
  7902. if (fs == -1)
  7903. return(success = 1);
  7904. break;
  7905. case WF_MOD:
  7906. if (fs == -1) {
  7907. printf("?File does not exit: %s\n",tmpbuf);
  7908. return(-9);
  7909. }
  7910. s = zfcdat(tmpbuf); /* Get current modification date */
  7911. if (!s) s = "";
  7912. if (ckstrncpy(filedate,s,32) != 17) {
  7913. printf("?Can't get modification time: %s\n",tmpbuf);
  7914. return(-9);
  7915. }
  7916. break;
  7917. case WF_CRE:
  7918. if (fs > -1)
  7919. return(success = 1);
  7920. break;
  7921. }
  7922. }
  7923. do { /* Polling loop */
  7924. if (sleepcan) { /* Keyboard cancellation allowed? */
  7925. if ((y = conchk()) > 0) { /* Did they type something? */
  7926. kbchar = coninc(0); /* Yes, get first char they typed */
  7927. debug(F000,"WAIT kbchar","",kbchar);
  7928. #ifdef COMMENT
  7929. while (--y > 0) /* Gobble the rest up */
  7930. coninc(0);
  7931. #endif /* COMMENT */
  7932. return(success = 0); /* And quit PAUSing or WAITing */
  7933. }
  7934. }
  7935. if (filewait == 0) {
  7936. if (cx == XXWAI) { /* WAIT for modem signals */
  7937. if (z != 0) {
  7938. mdmsig = ttgmdm(); /* Get them. */
  7939. debug(F101,"WAIT ttgmdm","",mdmsig);
  7940. if (mdmsig < 0) /* Failure to get them? */
  7941. return(success = 0); /* Fail. */
  7942. if ((mdmsig & z) == z) /* Got desired ones? */
  7943. return(success = 1); /* Succeed. */
  7944. } else if (x == 0)
  7945. return(success = 0);
  7946. }
  7947. } else { /* FILE... */
  7948. fs = zchki(tmpbuf); /* Get file status */
  7949. if (filewait == WF_MOD) { /* Wait for modification */
  7950. if (fs == -1) /* Failure to get status */
  7951. return(success = 0); /* so WAIT fails. */
  7952. s = zfcdat(tmpbuf); /* Get current modification time */
  7953. if (!s) s = ""; /* And compare with the time */
  7954. if (strcmp(s,filedate)) /* when the WAIT started */
  7955. return(success = 1);
  7956. } else if (filewait == WF_DEL) { /* Wait for deletion */
  7957. if (fs == -1) /* If file doesn't exist, */
  7958. return(success = 1); /* succeed. */
  7959. } else if (filewait == WF_CRE) { /* Wait for creation */
  7960. if (fs != -1) /* If file exists */
  7961. return(success = 1); /* succeed. */
  7962. }
  7963. }
  7964. if (x < 1) /* SLEEP/WAIT/PAUSE 0 */
  7965. break;
  7966. sleep(waitinterval); /* No interrupt, sleep */
  7967. x -= waitinterval; /* Deduct sleep time */
  7968. } while (x > 0);
  7969. if (cx == XXWAI) /* WAIT time expired */
  7970. success = (z == 0); /* Succeed if no modem signals */
  7971. else /* For SLEEP or PAUSE, success */
  7972. success = (x == 0); /* depends on whether it was */
  7973. return(success); /* interrupted from the keyboard. */
  7974. #endif /* OLDWAIT */
  7975. }
  7976. #endif /* NOSPL */
  7977. #ifdef OS2ORUNIX
  7978. _PROTOTYP(int zcmpfn,(char *, char *));
  7979. #endif /* OS2ORUNIX */
  7980. #ifndef NOFRILLS
  7981. #ifdef NT
  7982. int
  7983. dolink() {
  7984. /* Parse a file or a directory name */
  7985. int i, x, z, listing = 0, havename = 0, wild = 0, rc = 1;
  7986. struct FDB sw, fi;
  7987. cmfdbi(&sw, /* 2nd FDB - optional /PAGE switch */
  7988. _CMKEY, /* fcode */
  7989. "Filename or switch", /* hlpmsg */
  7990. "", /* default */
  7991. "", /* addtl string data */
  7992. nqvswtab, /* addtl numeric data 1: tbl size */
  7993. 4, /* addtl numeric data 2: 4 = cmswi */
  7994. xxstring, /* Processing function */
  7995. qvswtab, /* Keyword table */
  7996. &fi /* Pointer to next FDB */
  7997. );
  7998. cmfdbi(&fi, /* 1st FDB - file to type */
  7999. _CMIFI, /* fcode */
  8000. "", /* hlpmsg */
  8001. "", /* default */
  8002. "", /* addtl string data */
  8003. 3, /* addtl numeric data 1 */
  8004. 0, /* addtl numeric data 2 */
  8005. xxstring,
  8006. NULL,
  8007. NULL
  8008. );
  8009. while (!havename) {
  8010. x = cmfdb(&sw); /* Parse something */
  8011. if (x < 0) /* Error */
  8012. return(x);
  8013. switch (cmresult.fcode) {
  8014. case _CMKEY:
  8015. switch (cmresult.nresult) {
  8016. case DEL_LIS:
  8017. case DEL_VRB:
  8018. listing = 1;
  8019. break;
  8020. case DEL_NOL:
  8021. case DEL_QUI:
  8022. listing = 0;
  8023. break;
  8024. }
  8025. break;
  8026. case _CMIFI:
  8027. s = cmresult.sresult;
  8028. havename = 1;
  8029. break;
  8030. default:
  8031. return(-2);
  8032. }
  8033. }
  8034. wild = cmresult.nresult; /* Source specification wild? */
  8035. ckstrncpy(line,s,LINBUFSIZ); /* Make a safe copy of source name */
  8036. s = line;
  8037. if (!wild)
  8038. wild = iswild(line);
  8039. p = tmpbuf; /* Place for new name */
  8040. if ((x = cmofi(wild ? "Target directory" : "New name",
  8041. "",&s,xxstring)) < 0) { /* Get new name */
  8042. if (x == -3) {
  8043. printf("?%s required\n", wild ? "Target directory" : "New name");
  8044. return(-9);
  8045. } else return(x);
  8046. }
  8047. ckstrncpy(p,s,TMPBUFSIZ); /* Make a safe copy of the new name */
  8048. if ((y = cmcfm()) < 0) return(y);
  8049. if (!wild) { /* Just one */
  8050. if (listing) printf("%s => %s ",line,p);
  8051. if (zlink(line,p) < 0) {
  8052. if (listing) printf("(FAILED: %s\n",ck_errstr());
  8053. rc = 0;
  8054. } else {
  8055. if (listing) printf("(OK)\n");
  8056. }
  8057. return(success = rc);
  8058. }
  8059. if (!isdir(p)) { /* Multiple */
  8060. printf( /* if target is not a directory */
  8061. "?Multiple source files not allowed if target is not a directory.\n");
  8062. return(-9);
  8063. }
  8064. #ifdef COMMENT
  8065. else { /* Show full path of target */
  8066. char buf[CKMAXPATH]; /* (too much) */
  8067. if (zfnqfp(p,CKMAXPATH,buf))
  8068. ckstrncpy(tmpbuf,buf,TMPBUFSIZ);
  8069. }
  8070. #endif /* COMMENT */
  8071. #ifdef VMS
  8072. conres(); /* Let Ctrl-C work. */
  8073. #endif /* VMS */
  8074. debug(F110,"dolink line",line,0);
  8075. #ifdef ZXREWIND
  8076. z = zxrewind(); /* Rewind file list */
  8077. #else
  8078. z = nzxpand(s,0); /* Expand file list */
  8079. #endif /* ZXREWIND */
  8080. debug(F111,"dolink p",p,z);
  8081. #ifdef UNIX
  8082. if (wild && z > 1)
  8083. sh_sort(mtchs,NULL,z,0,0,filecase); /* Alphabetize the filename list */
  8084. #endif /* UNIX */
  8085. while (z-- > 0) {
  8086. if (!(z == 0 && !wild))
  8087. znext(line);
  8088. if (!line[0])
  8089. break;
  8090. if (listing) printf("%s => %s ",line,p);
  8091. if (zlink(line,p) < 0) {
  8092. if (listing) printf("(FAILED: %s\n",ck_errstr());
  8093. rc = 0;
  8094. } else {
  8095. if (listing) printf("(OK)\n");
  8096. }
  8097. }
  8098. #ifdef VMS
  8099. concb((char)escape);
  8100. #endif /* VMS */
  8101. return(success = rc);
  8102. }
  8103. #endif /* NT */
  8104. #ifdef ZCOPY
  8105. int
  8106. docopy() {
  8107. int i, x, listing = 0, nolist = 0, havename = 0, getval;
  8108. char c;
  8109. struct FDB sw, fi;
  8110. int overwrite = OVW_ALWAYS;
  8111. int targetisdir = 0;
  8112. int targetlen = 0;
  8113. int appending = 0;
  8114. int preserve = 0;
  8115. int swapping = 0;
  8116. int fromb64 = 0;
  8117. int tob64 = 0;
  8118. int wild = 0;
  8119. int rc = 1;
  8120. char newname[CKMAXPATH], * nm;
  8121. nm = newname;
  8122. cmfdbi(&sw, /* 1st FDB - switches */
  8123. _CMKEY, /* fcode */
  8124. "Filename or switch", /* hlpmsg */
  8125. "", /* default */
  8126. "", /* addtl string data */
  8127. ncopytab, /* addtl numeric data 1: tbl size */
  8128. 4, /* addtl numeric data 2: 4 = cmswi */
  8129. xxstring, /* Processing function */
  8130. copytab, /* Keyword table */
  8131. &fi /* Pointer to next FDB */
  8132. );
  8133. cmfdbi(&fi, /* 2nd FDB - file to copy */
  8134. _CMIFI, /* fcode */
  8135. "", /* hlpmsg */
  8136. "", /* default */
  8137. "", /* addtl string data */
  8138. 0, /* addtl numeric data 1 */
  8139. 0, /* addtl numeric data 2 */
  8140. xxstring,
  8141. NULL,
  8142. NULL
  8143. );
  8144. while (!havename) {
  8145. x = cmfdb(&sw); /* Parse something */
  8146. if (x < 0) /* Error */
  8147. return(x);
  8148. switch (cmresult.fcode) {
  8149. case _CMKEY:
  8150. c = cmgbrk(); /* Get break character */
  8151. if ((getval = (c == ':' || c == '=')) && !(cmgkwflgs() & CM_ARG)) {
  8152. printf("?This switch does not take an argument\n");
  8153. rc = -9;
  8154. return(rc);
  8155. }
  8156. if (!getval && (cmgkwflgs() & CM_ARG)) {
  8157. printf("?This switch requires an argument\n");
  8158. rc = -9;
  8159. return(rc);
  8160. }
  8161. switch (cmresult.nresult) {
  8162. case DEL_LIS:
  8163. case DEL_VRB:
  8164. nolist = 0;
  8165. listing = 1;
  8166. break;
  8167. case DEL_NOL:
  8168. case DEL_QUI:
  8169. nolist = 1;
  8170. listing = 0;
  8171. break;
  8172. case 999:
  8173. swapping = 1;
  8174. break;
  8175. case 998:
  8176. appending = 1;
  8177. break;
  8178. case 995:
  8179. preserve = 1;
  8180. break;
  8181. case 994:
  8182. if ((x = cmkey(ovwtab,novwtab,
  8183. "When to overwrite existing destination file",
  8184. "",xxstring)) < 0)
  8185. return(x);
  8186. overwrite = x;
  8187. break;
  8188. #ifndef NOSPL
  8189. case 997:
  8190. fromb64 = 1;
  8191. break;
  8192. case 996:
  8193. tob64 = 1;
  8194. break;
  8195. #endif /* NOSPL */
  8196. }
  8197. break;
  8198. case _CMIFI:
  8199. s = cmresult.sresult;
  8200. havename = 1;
  8201. break;
  8202. default:
  8203. return(-2);
  8204. }
  8205. }
  8206. wild = cmresult.nresult;
  8207. ckstrncpy(line,s,LINBUFSIZ); /* Make a safe copy of source name */
  8208. s = line;
  8209. p = tmpbuf; /* Place for new name */
  8210. /* Get destination name */
  8211. if ((x = cmofi("destination name and/or directory",
  8212. #ifdef UNIX
  8213. "."
  8214. #else
  8215. ""
  8216. #endif /* UNIX */
  8217. ,&s,xxstring)) < 0) {
  8218. if (x == -3) {
  8219. printf("?Name for destination file required\n");
  8220. return(-9);
  8221. } else return(x);
  8222. }
  8223. ckstrncpy(p,s,TMPBUFSIZ); /* Safe copy of destination name */
  8224. if ((y = cmcfm()) < 0) return(y);
  8225. if (appending && swapping) {
  8226. printf("?Sorry, /APPEND and /SWAP conflict\n");
  8227. return(-9);
  8228. }
  8229. #ifdef COMMENT
  8230. /*
  8231. This unreasonably prevented "COPY /APPEND *.* bigfile" from concatenating
  8232. a bunch of files into one big file.
  8233. */
  8234. if (appending && wild) {
  8235. printf("?Sorry, /APPEND can be used only with single files\n");
  8236. return(-9);
  8237. }
  8238. #endif /* COMMENT */
  8239. targetisdir = isdir(p);
  8240. x = strlen(p);
  8241. if (targetisdir) {
  8242. #ifdef UNIXOROSK
  8243. if (p[x-1] != '/') {
  8244. ckstrncat(p,"/",TMPBUFSIZ);
  8245. x++;
  8246. }
  8247. #else
  8248. #ifdef OS2
  8249. if (p[x-1] != '/') {
  8250. ckstrncat(p,"/",TMPBUFSIZ);
  8251. x++;
  8252. }
  8253. #else
  8254. #ifdef STRATUS
  8255. if (p[x-1] != '>') {
  8256. ckstrncat(p,">",TMPBUFSIZ);
  8257. x++;
  8258. }
  8259. #else
  8260. #ifdef datageneral
  8261. if (p[x-1] != ':') {
  8262. ckstrncat(p,":",TMPBUFSIZ);
  8263. x++;
  8264. }
  8265. #else
  8266. if (p[x-1] != '/') {
  8267. ckstrncat(p,"/",TMPBUFSIZ);
  8268. x++;
  8269. }
  8270. #endif /* datageneral */
  8271. #endif /* STRATUS */
  8272. #endif /* OS2 */
  8273. #endif /* UNIXOROSK */
  8274. }
  8275. targetlen = x;
  8276. if (!appending) { /* If /APPEND not given */
  8277. if (wild && !targetisdir) { /* No wildcards allowed */
  8278. printf( /* if target is not a directory */
  8279. "?Multiple source files not allowed if target is not a directory.\n");
  8280. return(-9);
  8281. }
  8282. }
  8283. #ifdef VMS
  8284. conres(); /* Let Ctrl-C work. */
  8285. #endif /* VMS */
  8286. debug(F110,"docopy line",line,0);
  8287. debug(F110,"docopy p",p,0);
  8288. debug(F110,"docopy nm",nm,0);
  8289. #ifdef ZXREWIND
  8290. z = zxrewind(); /* Rewind file list */
  8291. #else
  8292. z = nzxpand(s,0); /* Expand file list */
  8293. #endif /* ZXREWIND */
  8294. #ifdef UNIX
  8295. if (wild)
  8296. sh_sort(mtchs,NULL,z,0,0,filecase); /* Alphabetize the filename list */
  8297. #endif /* UNIX */
  8298. #ifdef IKSD
  8299. if (!targetisdir && zchki(p) > -1) { /* Destination file exists? */
  8300. if (inserver && (!ENABLED(en_del)
  8301. #ifdef CK_LOGIN
  8302. || isguest
  8303. #endif /* CK_LOGIN */
  8304. )) {
  8305. printf("?Sorry, overwriting existing files is disabled\n");
  8306. return(-9);
  8307. }
  8308. }
  8309. #endif /* IKSD */
  8310. if (tob64 && fromb64) { /* To and from B64 = no conversion */
  8311. tob64 = 0;
  8312. fromb64 = 0;
  8313. }
  8314. debug(F110,"COPY dest",p,0);
  8315. while (z > 0) {
  8316. znext(line);
  8317. if (!line[0])
  8318. break;
  8319. errno = 0; /* Reset errno */
  8320. if (targetisdir) {
  8321. zstrip(line,&nm);
  8322. ckmakmsg(newname,CKMAXPATH,p,nm,NULL,NULL);
  8323. nm = newname;
  8324. } else {
  8325. nm = p;
  8326. }
  8327. if (overwrite) { /* Overwrite checking? */
  8328. if (zchki(nm) >= (CK_OFF_T)0) { /* Destination file exists? */
  8329. char d1[20], * d2;
  8330. char * n1, * n2;
  8331. int i, skip = 0;
  8332. i = strlen(line); /* Isolate source filename */
  8333. for (; i >= 0; i--) {
  8334. if (ISDIRSEP(line[i])) {
  8335. n1 = &line[i+1];
  8336. break;
  8337. }
  8338. }
  8339. debug(F110,"COPY n1", n1, 0);
  8340. i = strlen(nm); /* And destination filename */
  8341. for (; i >= 0; i--) {
  8342. if (ISDIRSEP(nm[i])) {
  8343. n2 = &nm[i+1];
  8344. break;
  8345. }
  8346. }
  8347. debug(F110,"COPY n2", n2, 0);
  8348. if (!strcmp(n1,n2)) { /* Same name? */
  8349. if (overwrite == OVW_NEVER) { /* Never overwrite? */
  8350. if (listing) /* Skip */
  8351. if (listing) printf("%s => %s (SKIPPED)\n",line,nm);
  8352. continue;
  8353. }
  8354. ckstrncpy(d1,zfcdat(line),20); /* Source file timestamp */
  8355. d2 = zfcdat(nm); /* Timestamp of dest file */
  8356. x = strcmp(d1,d2); /* Compare them */
  8357. if (((overwrite == OVW_NEWER) && (x < 0)) ||
  8358. ((overwrite == OVW_OLDER) && (x > 0))) {
  8359. if (listing)
  8360. if (listing) printf("%s => %s (SKIPPED)\n",line,nm);
  8361. continue;
  8362. }
  8363. }
  8364. }
  8365. }
  8366. if (listing) printf("%s => %s ",line,nm);
  8367. /* Straight copy */
  8368. if (!swapping && !appending && !fromb64 && !tob64) {
  8369. debug(F110,"COPY zcopy",line,0);
  8370. if ((x = zcopy(line,p)) < 0) { /* Let zcopy() do it. */
  8371. debug(F111,"COPY not OK",line,x);
  8372. switch (x) {
  8373. case -2:
  8374. if (listing)
  8375. printf("(FAILED: Not a regular file)\n");
  8376. else if (!nolist)
  8377. printf("?Not a regular file - %s\n",line);
  8378. rc = 0;
  8379. break;
  8380. case -3:
  8381. if (listing)
  8382. printf("(FAILED: Not found or not accessible)\n");
  8383. else if (!nolist)
  8384. printf("?Not found or not accessible - %s\n",line);
  8385. rc = 0;
  8386. break;
  8387. case -4:
  8388. if (listing)
  8389. printf("(FAILED: Permission denied)\n");
  8390. else if (!nolist)
  8391. printf("?Permission denied - %s\n",line);
  8392. rc = 0;
  8393. break;
  8394. case -5:
  8395. if (listing)
  8396. printf("(Source and destination are the same file)\n");
  8397. else if (!nolist)
  8398. printf(
  8399. "?Source and destination are the same file - %s\n",
  8400. line
  8401. );
  8402. break;
  8403. case -6:
  8404. if (listing)
  8405. printf("(FAILED: Input/Output error)\n");
  8406. else if (!nolist)
  8407. printf("?Input/Output error - %s\n",line);
  8408. rc = 0;
  8409. break;
  8410. case -7:
  8411. if (listing)
  8412. printf("(FAILED: %s - %s)\n",p,ck_errstr());
  8413. else if (!nolist)
  8414. printf("?%s - %s\n",ck_errstr(),p);
  8415. rc = 0;
  8416. break;
  8417. default:
  8418. if (listing)
  8419. printf("(FAILED: %s)\n",ck_errstr());
  8420. else if (!nolist)
  8421. printf("?%s\n",ck_errstr());
  8422. rc = 0;
  8423. }
  8424. } else { /* Regular copy succeeded */
  8425. debug(F110,"COPY OK..",newname,0);
  8426. #ifndef NOXFER
  8427. if (preserve) { /* Handle /PRESERVE */
  8428. char * pstr = ""; /* File permissions string */
  8429. struct zattr xx; /* File attribute structure */
  8430. extern char * cksysid;
  8431. initattr(&xx); /* Initialize the struct */
  8432. xx.systemid.val = cksysid; /* Set our system ID */
  8433. xx.systemid.len = (int)strlen(cksysid);
  8434. #ifdef CK_PERMS
  8435. pstr = zgperm(line); /* Get source file's permissions */
  8436. #endif /* CK_PERMS */
  8437. xx.lprotect.val = pstr;
  8438. xx.lprotect.len = (int)strlen(pstr);
  8439. xx.gprotect.len = 0;
  8440. xx.date.val = zfcdat(line); /* Source file's timestamp */
  8441. xx.date.len = (int)strlen(xx.date.val);
  8442. if (zstime(nm,&xx,0) < 0) {
  8443. printf("?COPY /PRESERVE %s: %s\n",nm,ck_errstr());
  8444. rc = -9;
  8445. }
  8446. }
  8447. #endif /* NOXFER */
  8448. if (listing && rc > -1)
  8449. printf("(OK)\n");
  8450. }
  8451. } else { /* Special options */
  8452. int prev, y, x = 0; /* Variables needed for them */
  8453. int i, t;
  8454. char ibuf[100];
  8455. char obuf[200];
  8456. FILE * in = NULL;
  8457. FILE * out = NULL;
  8458. if ((in = fopen(line,"r")) == NULL) { /* Open input file */
  8459. if (listing)
  8460. printf("(FAILED: %s)\n",ck_errstr());
  8461. else if (!nolist)
  8462. printf("?%s - %s)\n",ck_errstr(),line);
  8463. rc = 0;
  8464. continue;
  8465. }
  8466. if (targetisdir) { /* Target is directory */
  8467. char * buf = NULL; /* so append this filename to it */
  8468. zstrip(line,&buf);
  8469. p[targetlen] = NUL;
  8470. if (buf)
  8471. ckstrncat(p,buf,TMPBUFSIZ);
  8472. }
  8473. #ifdef OS2ORUNIX
  8474. if (zcmpfn(line,p)) { /* Input and output are same file? */
  8475. if (listing)
  8476. printf("(FAILED: Source and destination identical)\n");
  8477. else if (!nolist)
  8478. printf("?Source and destination identical - %s\n", line);
  8479. rc = 0;
  8480. continue;
  8481. }
  8482. #endif /* OS2ORUNIX */
  8483. if ((out = fopen(p, (appending ? "a" : "w"))) == NULL) {
  8484. fclose(in);
  8485. if (listing)
  8486. printf("(FAILED: %s - %s)\n",p,ck_errstr());
  8487. else if (!nolist)
  8488. printf("?%s - %s\n",p,ck_errstr());
  8489. rc = 0;
  8490. continue;
  8491. }
  8492. #ifndef NOSPL
  8493. if (tob64) { /* Converting to Base-64 */
  8494. debug(F110,"COPY tob64",line,0);
  8495. while (1) { /* Loop... */
  8496. prev = x;
  8497. if ((x = fread(ibuf,1,54,in)) < 1) { /* EOF */
  8498. if (listing)
  8499. printf("(OK)\n");
  8500. break;
  8501. }
  8502. if (prev % 3) {
  8503. if (listing)
  8504. printf("(FAILED: Phase error at %d)\n",prev);
  8505. else if (!nolist)
  8506. printf("?Phase error at %d\n",prev);
  8507. rc = 0;
  8508. break;
  8509. }
  8510. if (swapping) {
  8511. if (x & 1) {
  8512. if (listing)
  8513. printf("(FAILED: Swap error)\n");
  8514. else if (!nolist)
  8515. printf("?Swap error\n");
  8516. rc = 0;
  8517. break;
  8518. }
  8519. for (i = 0; i < x; i+=2) {
  8520. t = ibuf[i];
  8521. ibuf[i] = ibuf[i+1];
  8522. ibuf[i+1] = t;
  8523. }
  8524. }
  8525. if ((y = b8tob64(ibuf,x,obuf,180)) < 0) {
  8526. if (listing)
  8527. printf("(FAILED: Encoding error)\n");
  8528. else if (!nolist)
  8529. printf("?Encoding error\n");
  8530. rc = 0;
  8531. break;
  8532. }
  8533. fprintf(out,"%s\n",obuf);
  8534. }
  8535. } else if (fromb64) { /* Converting from Base 64 */
  8536. debug(F110,"COPY fromb64",line,0);
  8537. if ((out = fopen(p,appending ? "a" : "w")) == NULL) {
  8538. fclose(in);
  8539. if (listing)
  8540. printf("(FAILED: %s - %s)\n",p,ck_errstr());
  8541. else if (!nolist)
  8542. printf("?%s - %s\n",p,ck_errstr());
  8543. rc = 0;
  8544. continue;
  8545. }
  8546. x = 1;
  8547. while (x) {
  8548. x = fread(ibuf,1,80,in);
  8549. if ((y = b64tob8(ibuf,x,obuf,80)) < 0) {
  8550. if (listing)
  8551. printf("(FAILED: Decoding error)\n");
  8552. else if (!nolist)
  8553. printf("?Decoding error\n");
  8554. rc = 0;
  8555. break;
  8556. }
  8557. if (swapping) {
  8558. if (x & 1) {
  8559. if (listing)
  8560. printf("(FAILED: Swap error)\n");
  8561. else if (!nolist)
  8562. printf("?Swap error\n");
  8563. rc = 0;
  8564. break;
  8565. }
  8566. for (i = 0; i < y; i+=2) {
  8567. t = obuf[i];
  8568. obuf[i] = obuf[i+1];
  8569. obuf[i+1] = t;
  8570. }
  8571. }
  8572. if (y > 0) {
  8573. if (fwrite(obuf,1,y,out) < 1) {
  8574. if (listing)
  8575. printf("(FAILED: %s - %s)\n",p,ck_errstr());
  8576. else if (!nolist)
  8577. printf("?%s - %s\n",p,ck_errstr());
  8578. rc = 0;
  8579. break;
  8580. }
  8581. }
  8582. }
  8583. } else
  8584. #endif /* NOSPL */
  8585. if (swapping) { /* Swapping bytes */
  8586. CHAR c[3];
  8587. c[2] = NUL;
  8588. debug(F110,"COPY swapping",line,0);
  8589. while (1) {
  8590. x = fread((char *)c,1,2,in);
  8591. if (x < 1) {
  8592. if (listing)
  8593. printf("(OK)\n");
  8594. break;
  8595. } else if (x == 1) {
  8596. c[1] = c[0];
  8597. c[0] = NUL;
  8598. printf(
  8599. "(WARNING: Odd byte count)");
  8600. if (!listing) printf("\n");
  8601. }
  8602. if (fprintf(out,"%c%c",c[1],c[0]) == EOF) {
  8603. if (listing)
  8604. printf("(FAILED: %s - %s)\n",p,ck_errstr());
  8605. else if (!nolist)
  8606. printf("?%s - %s\n",p,ck_errstr());
  8607. rc = 0;
  8608. break;
  8609. }
  8610. }
  8611. } else if (appending) { /* Appending to target file */
  8612. char c;
  8613. debug(F110,"COPY appending",line,0);
  8614. while (1) {
  8615. x = fread(&c,1,1,in);
  8616. if (x < 1) {
  8617. if (listing)
  8618. printf("(OK)\n");
  8619. break;
  8620. }
  8621. if (fwrite(&c,1,1,out) < 1) {
  8622. if (listing)
  8623. printf("(FAILED: %s - %s)\n",p,ck_errstr());
  8624. else if (!nolist)
  8625. printf("?%s - %s\n",p,ck_errstr());
  8626. rc = 0;
  8627. break;
  8628. }
  8629. }
  8630. }
  8631. if (out) fclose(out);
  8632. if (in) fclose(in);
  8633. }
  8634. #ifdef VMSORUNIX
  8635. concb((char)escape);
  8636. #endif /* VMSORUNIX */
  8637. }
  8638. if (rc > -1) success = rc;
  8639. return(rc);
  8640. }
  8641. #endif /* ZCOPY */
  8642. #endif /* NOFRILLS */
  8643. #ifndef NOCSETS
  8644. #ifndef NOUNICODE
  8645. static struct keytab * xfcstab = NULL; /* For RENAME /CONVERT: */
  8646. static char cvtbufin[CKMAXPATH+8] = { NUL, NUL };
  8647. static char cvtbufout[CKMAXPATH+8] = { NUL, NUL };
  8648. static char * pcvtbufin = NULL;
  8649. static char * pcvtbufout = NULL;
  8650. static int /* Input function xgnbyte() */
  8651. cvtfnin() {
  8652. CHAR c;
  8653. c = *pcvtbufin++;
  8654. return(c ? c : -1);
  8655. }
  8656. _PROTOTYP(int cvtfnout,(char)); /* Output function for xpnbyte() */
  8657. int
  8658. #ifdef CK_ANSIC
  8659. cvtfnout(char c)
  8660. #else
  8661. cvtfnout(c) char c;
  8662. #endif /* CK_ANSIC */
  8663. {
  8664. if (pcvtbufout - cvtbufout >= CKMAXPATH)
  8665. return(-1);
  8666. *pcvtbufout++ = c;
  8667. *pcvtbufout = NUL;
  8668. return(1);
  8669. }
  8670. /* Convert a string from any charset to any other charset */
  8671. char *
  8672. cvtstring(s,csin,csout) char * s; int csin, csout; {
  8673. int c;
  8674. extern CK_OFF_T ffc;
  8675. ckstrncpy(cvtbufin,s,CKMAXPATH); /* Put it in a public place */
  8676. pcvtbufin = cvtbufin; /* with public pointers */
  8677. pcvtbufout = cvtbufout;
  8678. *pcvtbufout = NUL;
  8679. if (csin == csout) /* If the two sets are the same */
  8680. return((char *)cvtbufin); /* don't bother converting */
  8681. initxlate(csin,csout); /* Initialize the translator */
  8682. while ((c = xgnbyte(FC_UCS2,csin,cvtfnin)) > -1) { /* Loop thru string */
  8683. if (xpnbyte(c,TC_UCS2,csout,cvtfnout) < 0) {
  8684. ffc = (CK_OFF_T)0;
  8685. return("");
  8686. }
  8687. }
  8688. /* ffc is touched by xgnbyte() but this is not file transfer */
  8689. /* so we have to undo it */
  8690. ffc = (CK_OFF_T)0;
  8691. return((char *)cvtbufout);
  8692. }
  8693. #endif /* NOUNICODE */
  8694. #endif /* NOCSETS */
  8695. #ifndef NORENAME
  8696. #ifndef NOFRILLS
  8697. #ifdef ZRENAME
  8698. /* The RENAME command - expanded and improved in 8.0.212 April 2006 */
  8699. static char * ren_sub[4] = { NULL,NULL,NULL,NULL }; /* For RENAME /REPLACE */
  8700. int ren_list = 0; /* Default listing action for RENAME */
  8701. int ren_coll = RENX_OVWR; /* Default collision action */
  8702. int
  8703. shorename() {
  8704. char * s;
  8705. switch (ren_coll) {
  8706. case RENX_FAIL: s = "fail"; break;
  8707. case RENX_OVWR: s = "overwrite"; break;
  8708. case RENX_SKIP: s = "proceed"; break;
  8709. }
  8710. printf(" rename collision: %s\n",s);
  8711. printf(" rename list: %s\n",showoff(ren_list));
  8712. return(1);
  8713. }
  8714. int
  8715. setrename() { /* Parse SET RENAME options */
  8716. int x, y;
  8717. if ((x = cmkey(renamset,nrenamset,"","", xxstring)) < 0)
  8718. return(x);
  8719. switch (x) {
  8720. case REN_OVW: /* COLLISION */
  8721. if ((x = cmkey(r_collision,nr_collision,"","", xxstring)) < 0)
  8722. return(x);
  8723. if ((y = cmcfm()) < 0)
  8724. return(y);
  8725. ren_coll = x;
  8726. break;
  8727. case DEL_LIS: /* LIST */
  8728. return(seton(&ren_list));
  8729. }
  8730. return(success = 1);
  8731. }
  8732. /* Reverse a string - Assumes a single-byte character set */
  8733. int
  8734. gnirts(s1, s2, len) char * s1, * s2; int len; {
  8735. int n, m = 0;
  8736. if (!s1) /* Null source pointer, fail */
  8737. return(0);
  8738. n = (int) strlen(s1);
  8739. if (n > len-1) /* Source longer than dest, fail */
  8740. return(0);
  8741. s2[n--] = NUL; /* Deposit null byte at end of dest */
  8742. for (; n >= 0; n--) { /* Copy the rest backwards */
  8743. *s2++ = s1[n];
  8744. m++;
  8745. }
  8746. return(m);
  8747. }
  8748. /*
  8749. r e n a m e o n e
  8750. Worker function to rename one file for dorenam() (below).
  8751. old = name of file or directory to be renamed
  8752. new = new name (not required for /UPPER, /LOWER, and /REPLACE)
  8753. replacing = 1 if doing string replacement on the name
  8754. casing = 1 if converting name to lowercase, 2 if to uppercase
  8755. all = if doing case conversion on all names, not just monocase ones
  8756. converting = 1 if converting character sets
  8757. cset1 = character set to convert from (File Character Set index)
  8758. cset2 = character set to convert to (ditto, see ck?xla.h)
  8759. listing = 1 to show results of rename
  8760. nolist = 1 to be completely silent (don't even print error messages)
  8761. op = 1 means simulate, 2 means check for collision, 0 means rename
  8762. size = length of result buffer.
  8763. collision = action to take if destination file already exists:
  8764. 0 = fail
  8765. 1 = overwrite and succeed
  8766. 2 = skip and succeed
  8767. Returns:
  8768. 0: on failure to rename or when a forbidden collision would have occurred.
  8769. 1: on success (file was renamed or did not need to be renamed).
  8770. Note:
  8771. If this code is ever built on any platform that is not Unix, Windows,
  8772. VMS, or OS/2, this routine might need some adjustment.
  8773. */
  8774. /* Opcodes for op... */
  8775. #define REN_OP_SIM 1 /* Simulate */
  8776. #define REN_OP_CHK 2 /* Check for collisions */
  8777. static int
  8778. renameone(old,new,
  8779. replacing,casing,all,converting,cset1,cset2,
  8780. listing,nolist,op,size,collision)
  8781. char * old, * new;
  8782. int replacing,casing,all,converting,cset1,cset2,
  8783. listing,nolist,op,size,collision;
  8784. {
  8785. char buf[CKMAXPATH]; /* Temporary filename buffer */
  8786. char out[CKMAXPATH]; /* Buffer for new name */
  8787. char dir[CKMAXPATH]; /* Destination directory */
  8788. char pat[CKMAXPATH]; /* Path segment on old filename */
  8789. char * destdir; /* Destination directory, if any */
  8790. char * srcpath; /* Source path, if any */
  8791. int rc = 1, flag = 0, skip = 0; /* Control */
  8792. int honorcase = 0, replaced = 0;
  8793. int anchor = 0; /* 1 = beginning, 2 = end */
  8794. int occur = 0; /* Occurrence */
  8795. int minus = 0; /* Occurrence is negative */
  8796. int allbut = 0; /* Occurrence is "all but" */
  8797. int arg2isfile = 0; /* Arg2 ("new") is a filename */
  8798. debug(F110,"RENAMEONE old",old,0);
  8799. debug(F110,"RENAMEONE new",new,0);
  8800. debug(F110,"RENAMEONE ren_sub[0]",ren_sub[0],0);
  8801. debug(F110,"RENAMEONE ren_sub[1]",ren_sub[1],0);
  8802. debug(F110,"RENAMEONE ren_sub[2]",ren_sub[2],0);
  8803. if (op == REN_OP_SIM && !nolist) /* For convenience */
  8804. listing = 1;
  8805. #ifndef NOSPL
  8806. honorcase = inpcas[cmdlvl]; /* Inherit SET CASE value */
  8807. #else
  8808. #ifdef UNIX
  8809. honorcase = 1;
  8810. #else
  8811. honorcase = 0;
  8812. #endif /* UNIX */
  8813. #endif /* NOSPL */
  8814. if (!old) old = ""; /* In case of bad args */
  8815. if (!new) new = "";
  8816. if (!*old) return(success = 0);
  8817. ckstrncpy(out,new,CKMAXPATH); /* So we don't write into */
  8818. new = out; /* our argument... */
  8819. size = CKMAXPATH;
  8820. pat[0] = NUL; /* Assume no path in source file.. */
  8821. srcpath = pat;
  8822. {
  8823. int n; /* If the old name includes a path */
  8824. n = (int)strlen(old) - 1; /* put it in a separate place. */
  8825. for (; n >= 0; n--) { /* We are renaming the file only. */
  8826. if (ISDIRSEP(old[n])) {
  8827. ckstrncpy(pat,old,CKMAXPATH);
  8828. pat[n+1] = NUL;
  8829. old = old+n+1;
  8830. break;
  8831. }
  8832. }
  8833. }
  8834. debug(F110,"RENAMEONE old 2",old,0);
  8835. debug(F110,"RENAMEONE pat 2",pat,0);
  8836. dir[0] = NUL; /* Assume no destination directory */
  8837. destdir = dir;
  8838. if (*new) { /* If Arg2 given */
  8839. if (isdir(new)) { /* If it's a directory */
  8840. ckstrncpy(dir,new,CKMAXPATH); /* put it here */
  8841. } else { /* otherwise */
  8842. arg2isfile++; /* flag that it's a filename */
  8843. }
  8844. }
  8845. if (!casing && !replacing && !converting) {
  8846. if (!*new)
  8847. return(success = 0);
  8848. if (!arg2isfile) { /* Destination is a directory? */
  8849. if (!isdir(old)) { /* and source is not? */
  8850. #ifndef VMS
  8851. int n, x = 0; /* Concatenate them */
  8852. if ((n = strlen(new)) > 0) /* so we can check for */
  8853. if (ISDIRSEP(new[n-1])) /* collisions. */
  8854. x++;
  8855. ckmakmsg(buf,size,new,x ? "" : "/", old, "");
  8856. #else
  8857. ckmakmsg(buf,size,new, old, NULL, NULL);
  8858. #endif /* VMS */
  8859. debug(F110,"RENAMEONE new new",new,0);
  8860. new = buf;
  8861. size = CKMAXPATH;
  8862. }
  8863. }
  8864. } else if (*new) { /* Directory to move file to */
  8865. int n, x = 0; /* after changing its name */
  8866. if (!isdir(new))
  8867. return(success = 0);
  8868. #ifndef VMS
  8869. if ((n = strlen(new)) > 0)
  8870. if (ISDIRSEP(new[n-1]))
  8871. x++;
  8872. ckmakmsg(dir,CKMAXPATH,new,x ? "" : "/", "", "");
  8873. #else
  8874. ckstrncpy(dir,new,CKMAXPATH);
  8875. #endif /* VMS */
  8876. }
  8877. #ifndef NOCSETS
  8878. #ifndef NOUNICODE
  8879. if (converting) {
  8880. new = cvtstring(old,cset1,cset2);
  8881. }
  8882. #endif /* NOUNICODE */
  8883. #endif /* NOCSETS */
  8884. if (replacing) { /* Replacing strings */
  8885. int todo = 0;
  8886. int len0, len1, len2;
  8887. char c, *p, *s, *bp[3];
  8888. bp[0] = old; /* Original name */
  8889. bp[1] = ren_sub[0]; /* String to be replaced */
  8890. bp[2] = ren_sub[1]; /* What to replace it with */
  8891. if (!bp[2]) bp[2] = "";
  8892. len0 = (int)strlen(bp[0]); /* length of original filename */
  8893. len1 = (int)strlen(bp[1]); /* length of target substring */
  8894. len2 = (int)strlen(bp[2]); /* Length of replacement string */
  8895. if (ren_sub[2]) { /* Optional options */
  8896. p = ren_sub[2];
  8897. while ((c = *p++)) {
  8898. switch (c) {
  8899. case '^':
  8900. anchor = 1; occur = 0; minus = 0; allbut = 0; break;
  8901. case '$':
  8902. anchor = 2; occur = 0; minus = 0; allbut = 0; break;
  8903. case 'A': honorcase = 1; minus = 0; allbut = 0; break;
  8904. case 'a': honorcase = 0; minus = 0; allbut = 0; break;
  8905. case '-': minus = 1; break;
  8906. case '~': allbut = 1; break;
  8907. default:
  8908. if (isdigit(c)) {
  8909. occur = c - '0';
  8910. if (minus) occur = 0 - occur;
  8911. anchor = 0;
  8912. }
  8913. minus = 0;
  8914. }
  8915. }
  8916. }
  8917. if (anchor) { /* Anchored replacement... */
  8918. y = len0 - len1;
  8919. if (y > 0) {
  8920. int x;
  8921. switch (anchor) {
  8922. case 1: /* Anchored at beginning */
  8923. if (!ckstrcmp(bp[1],bp[0],len1,honorcase)) {
  8924. x = ckstrncpy(new,bp[2],size);
  8925. (VOID) ckstrncpy(new+x,bp[0]+len1,size-x);
  8926. replaced = 1;
  8927. }
  8928. break;
  8929. case 2: /* Anchored at end */
  8930. if (!ckstrcmp(bp[1],bp[0]+y,len1,honorcase)) {
  8931. x = ckstrncpy(new,bp[0],y+1);
  8932. (VOID) ckstrncpy(new+y,bp[2],size-x);
  8933. replaced = 1;
  8934. }
  8935. break;
  8936. }
  8937. }
  8938. if (!replaced) {
  8939. ckstrncpy(new,old,size); /* Keep old name */
  8940. replaced = 1;
  8941. }
  8942. } else { /* Replace all occurrences */
  8943. int j, n = 0; /* or a particular occurrence */
  8944. char c;
  8945. int x = 0;
  8946. char * s0 = NULL, * s1 = NULL, * s2 = NULL;
  8947. p = new; /* Pointer to new name */
  8948. if (occur < 0) { /* nth occurrence from the right */
  8949. occur = 0 - occur;
  8950. s0 = (char *)malloc(len0+1); /* Reverse original string */
  8951. if (s0) {
  8952. (VOID) gnirts(bp[0],s0,len0+1);
  8953. bp[0] = s0;
  8954. } else return(0);
  8955. s1 = (char *)malloc(len1+1); /* Reverse target string */
  8956. if (s1) {
  8957. (VOID) gnirts(bp[1],s1,len1+1);
  8958. bp[1] = s1;
  8959. } else return(0);
  8960. s2 = (char *)malloc(len2+1); /* Reverse replacement string */
  8961. if (s2) {
  8962. (VOID) gnirts(bp[2],s2,len2+1);
  8963. bp[2] = s2;
  8964. } else return(0);
  8965. debug(F111,"RENAMEONE s0",s0,len0);
  8966. debug(F111,"RENAMEONE s1",s1,len1);
  8967. debug(F111,"RENAMEONE s2",s2,len2);
  8968. }
  8969. s = bp[0]; /* Pointer to old name */
  8970. p = new; /* Pointer to new name */
  8971. j = len0 - len1 + 1; /* How much to scan */
  8972. while (j-- > 0) { /* For each character... */
  8973. if (!ckstrcmp(bp[1],s,len1,honorcase)) { /* Match? */
  8974. n++; /* Occurrence counter */
  8975. todo = (occur == 0) ||
  8976. (!allbut && n == occur) ||
  8977. (allbut && n != occur);
  8978. if (!todo) { /* Desired occurrence? */
  8979. size -= ckstrncpy(p,bp[1],size); /* No... */
  8980. p += len1; /* Copy target string */
  8981. s += len1; /* instead of replacement string */
  8982. continue;
  8983. }
  8984. if (len2) { /* If replacement string not empty */
  8985. size -= ckstrncpy(p,bp[2],size); /* Copy it */
  8986. p += len2;
  8987. }
  8988. s += len1; /* Advance source position */
  8989. } else { /* No match */
  8990. *p++ = *s++; /* just copy this character */
  8991. size--;
  8992. }
  8993. }
  8994. while ((*p++ = *s++)); /* Done copy the rest */
  8995. replaced = 1; /* Remember we changed the name */
  8996. if (s0) { /* Were we doing "all but"? */
  8997. debug(F110,"RENAMEONE new1",new,0);
  8998. x = (int)strlen(new); /* Unreverse the result */
  8999. if ((p = (char *)malloc(x+2))) {
  9000. (VOID) gnirts(new,p,x+2);
  9001. debug(F110,"RENAMEONE new2",new,0);
  9002. ckstrncpy(new,p,x+2);
  9003. free(p);
  9004. }
  9005. if (s0) free(s0); /* Free the temporary strings */
  9006. if (s1) free(s1);
  9007. if (s2) free(s2);
  9008. debug(F110,"RENAMEONE new3",new,0);
  9009. }
  9010. }
  9011. }
  9012. if (casing) { /* Changing case? */
  9013. char c, * t; /* See if mixed case. */
  9014. if (!replaced)
  9015. ckstrncpy(new,old,size); /* Copy old name to new name */