ckutio.c 447 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568756975707571757275737574757575767577757875797580758175827583758475857586758775887589759075917592759375947595759675977598759976007601760276037604760576067607760876097610761176127613761476157616761776187619762076217622762376247625762676277628762976307631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700770177027703770477057706770777087709771077117712771377147715771677177718771977207721772277237724772577267727772877297730773177327733773477357736773777387739774077417742774377447745774677477748774977507751775277537754775577567757775877597760776177627763776477657766776777687769777077717772777377747775777677777778777977807781778277837784778577867787778877897790779177927793779477957796779777987799780078017802780378047805780678077808780978107811781278137814781578167817781878197820782178227823782478257826782778287829783078317832783378347835783678377838783978407841784278437844784578467847784878497850785178527853785478557856785778587859786078617862786378647865786678677868786978707871787278737874787578767877787878797880788178827883788478857886788778887889789078917892789378947895789678977898789979007901790279037904790579067907790879097910791179127913791479157916791779187919792079217922792379247925792679277928792979307931793279337934793579367937793879397940794179427943794479457946794779487949795079517952795379547955795679577958795979607961796279637964796579667967796879697970797179727973797479757976797779787979798079817982798379847985798679877988798979907991799279937994799579967997799879998000800180028003800480058006800780088009801080118012801380148015801680178018801980208021802280238024802580268027802880298030803180328033803480358036803780388039804080418042804380448045804680478048804980508051805280538054805580568057805880598060806180628063806480658066806780688069807080718072807380748075807680778078807980808081808280838084808580868087808880898090809180928093809480958096809780988099810081018102810381048105810681078108810981108111811281138114811581168117811881198120812181228123812481258126812781288129813081318132813381348135813681378138813981408141814281438144814581468147814881498150815181528153815481558156815781588159816081618162816381648165816681678168816981708171817281738174817581768177817881798180818181828183818481858186818781888189819081918192819381948195819681978198819982008201820282038204820582068207820882098210821182128213821482158216821782188219822082218222822382248225822682278228822982308231823282338234823582368237823882398240824182428243824482458246824782488249825082518252825382548255825682578258825982608261826282638264826582668267826882698270827182728273827482758276827782788279828082818282828382848285828682878288828982908291829282938294829582968297829882998300830183028303830483058306830783088309831083118312831383148315831683178318831983208321832283238324832583268327832883298330833183328333833483358336833783388339834083418342834383448345834683478348834983508351835283538354835583568357835883598360836183628363836483658366836783688369837083718372837383748375837683778378837983808381838283838384838583868387838883898390839183928393839483958396839783988399840084018402840384048405840684078408840984108411841284138414841584168417841884198420842184228423842484258426842784288429843084318432843384348435843684378438843984408441844284438444844584468447844884498450845184528453845484558456845784588459846084618462846384648465846684678468846984708471847284738474847584768477847884798480848184828483848484858486848784888489849084918492849384948495849684978498849985008501850285038504850585068507850885098510851185128513851485158516851785188519852085218522852385248525852685278528852985308531853285338534853585368537853885398540854185428543854485458546854785488549855085518552855385548555855685578558855985608561856285638564856585668567856885698570857185728573857485758576857785788579858085818582858385848585858685878588858985908591859285938594859585968597859885998600860186028603860486058606860786088609861086118612861386148615861686178618861986208621862286238624862586268627862886298630863186328633863486358636863786388639864086418642864386448645864686478648864986508651865286538654865586568657865886598660866186628663866486658666866786688669867086718672867386748675867686778678867986808681868286838684868586868687868886898690869186928693869486958696869786988699870087018702870387048705870687078708870987108711871287138714871587168717871887198720872187228723872487258726872787288729873087318732873387348735873687378738873987408741874287438744874587468747874887498750875187528753875487558756875787588759876087618762876387648765876687678768876987708771877287738774877587768777877887798780878187828783878487858786878787888789879087918792879387948795879687978798879988008801880288038804880588068807880888098810881188128813881488158816881788188819882088218822882388248825882688278828882988308831883288338834883588368837883888398840884188428843884488458846884788488849885088518852885388548855885688578858885988608861886288638864886588668867886888698870887188728873887488758876887788788879888088818882888388848885888688878888888988908891889288938894889588968897889888998900890189028903890489058906890789088909891089118912891389148915891689178918891989208921892289238924892589268927892889298930893189328933893489358936893789388939894089418942894389448945894689478948894989508951895289538954895589568957895889598960896189628963896489658966896789688969897089718972897389748975897689778978897989808981898289838984898589868987898889898990899189928993899489958996899789988999900090019002900390049005900690079008900990109011901290139014901590169017901890199020902190229023902490259026902790289029903090319032903390349035903690379038903990409041904290439044904590469047904890499050905190529053905490559056905790589059906090619062906390649065906690679068906990709071907290739074907590769077907890799080908190829083908490859086908790889089909090919092909390949095909690979098909991009101910291039104910591069107910891099110911191129113911491159116911791189119912091219122912391249125912691279128912991309131913291339134913591369137913891399140914191429143914491459146914791489149915091519152915391549155915691579158915991609161916291639164916591669167916891699170917191729173917491759176917791789179918091819182918391849185918691879188918991909191919291939194919591969197919891999200920192029203920492059206920792089209921092119212921392149215921692179218921992209221922292239224922592269227922892299230923192329233923492359236923792389239924092419242924392449245924692479248924992509251925292539254925592569257925892599260926192629263926492659266926792689269927092719272927392749275927692779278927992809281928292839284928592869287928892899290929192929293929492959296929792989299930093019302930393049305930693079308930993109311931293139314931593169317931893199320932193229323932493259326932793289329933093319332933393349335933693379338933993409341934293439344934593469347934893499350935193529353935493559356935793589359936093619362936393649365936693679368936993709371937293739374937593769377937893799380938193829383938493859386938793889389939093919392939393949395939693979398939994009401940294039404940594069407940894099410941194129413941494159416941794189419942094219422942394249425942694279428942994309431943294339434943594369437943894399440944194429443944494459446944794489449945094519452945394549455945694579458945994609461946294639464946594669467946894699470947194729473947494759476947794789479948094819482948394849485948694879488948994909491949294939494949594969497949894999500950195029503950495059506950795089509951095119512951395149515951695179518951995209521952295239524952595269527952895299530953195329533953495359536953795389539954095419542954395449545954695479548954995509551955295539554955595569557955895599560956195629563956495659566956795689569957095719572957395749575957695779578957995809581958295839584958595869587958895899590959195929593959495959596959795989599960096019602960396049605960696079608960996109611961296139614961596169617961896199620962196229623962496259626962796289629963096319632963396349635963696379638963996409641964296439644964596469647964896499650965196529653965496559656965796589659966096619662966396649665966696679668966996709671967296739674967596769677967896799680968196829683968496859686968796889689969096919692969396949695969696979698969997009701970297039704970597069707970897099710971197129713971497159716971797189719972097219722972397249725972697279728972997309731973297339734973597369737973897399740974197429743974497459746974797489749975097519752975397549755975697579758975997609761976297639764976597669767976897699770977197729773977497759776977797789779978097819782978397849785978697879788978997909791979297939794979597969797979897999800980198029803980498059806980798089809981098119812981398149815981698179818981998209821982298239824982598269827982898299830983198329833983498359836983798389839984098419842984398449845984698479848984998509851985298539854985598569857985898599860986198629863986498659866986798689869987098719872987398749875987698779878987998809881988298839884988598869887988898899890989198929893989498959896989798989899990099019902990399049905990699079908990999109911991299139914991599169917991899199920992199229923992499259926992799289929993099319932993399349935993699379938993999409941994299439944994599469947994899499950995199529953995499559956995799589959996099619962996399649965996699679968996999709971997299739974997599769977997899799980998199829983998499859986998799889989999099919992999399949995999699979998999910000100011000210003100041000510006100071000810009100101001110012100131001410015100161001710018100191002010021100221002310024100251002610027100281002910030100311003210033100341003510036100371003810039100401004110042100431004410045100461004710048100491005010051100521005310054100551005610057100581005910060100611006210063100641006510066100671006810069100701007110072100731007410075100761007710078100791008010081100821008310084100851008610087100881008910090100911009210093100941009510096100971009810099101001010110102101031010410105101061010710108101091011010111101121011310114101151011610117101181011910120101211012210123101241012510126101271012810129101301013110132101331013410135101361013710138101391014010141101421014310144101451014610147101481014910150101511015210153101541015510156101571015810159101601016110162101631016410165101661016710168101691017010171101721017310174101751017610177101781017910180101811018210183101841018510186101871018810189101901019110192101931019410195101961019710198101991020010201102021020310204102051020610207102081020910210102111021210213102141021510216102171021810219102201022110222102231022410225102261022710228102291023010231102321023310234102351023610237102381023910240102411024210243102441024510246102471024810249102501025110252102531025410255102561025710258102591026010261102621026310264102651026610267102681026910270102711027210273102741027510276102771027810279102801028110282102831028410285102861028710288102891029010291102921029310294102951029610297102981029910300103011030210303103041030510306103071030810309103101031110312103131031410315103161031710318103191032010321103221032310324103251032610327103281032910330103311033210333103341033510336103371033810339103401034110342103431034410345103461034710348103491035010351103521035310354103551035610357103581035910360103611036210363103641036510366103671036810369103701037110372103731037410375103761037710378103791038010381103821038310384103851038610387103881038910390103911039210393103941039510396103971039810399104001040110402104031040410405104061040710408104091041010411104121041310414104151041610417104181041910420104211042210423104241042510426104271042810429104301043110432104331043410435104361043710438104391044010441104421044310444104451044610447104481044910450104511045210453104541045510456104571045810459104601046110462104631046410465104661046710468104691047010471104721047310474104751047610477104781047910480104811048210483104841048510486104871048810489104901049110492104931049410495104961049710498104991050010501105021050310504105051050610507105081050910510105111051210513105141051510516105171051810519105201052110522105231052410525105261052710528105291053010531105321053310534105351053610537105381053910540105411054210543105441054510546105471054810549105501055110552105531055410555105561055710558105591056010561105621056310564105651056610567105681056910570105711057210573105741057510576105771057810579105801058110582105831058410585105861058710588105891059010591105921059310594105951059610597105981059910600106011060210603106041060510606106071060810609106101061110612106131061410615106161061710618106191062010621106221062310624106251062610627106281062910630106311063210633106341063510636106371063810639106401064110642106431064410645106461064710648106491065010651106521065310654106551065610657106581065910660106611066210663106641066510666106671066810669106701067110672106731067410675106761067710678106791068010681106821068310684106851068610687106881068910690106911069210693106941069510696106971069810699107001070110702107031070410705107061070710708107091071010711107121071310714107151071610717107181071910720107211072210723107241072510726107271072810729107301073110732107331073410735107361073710738107391074010741107421074310744107451074610747107481074910750107511075210753107541075510756107571075810759107601076110762107631076410765107661076710768107691077010771107721077310774107751077610777107781077910780107811078210783107841078510786107871078810789107901079110792107931079410795107961079710798107991080010801108021080310804108051080610807108081080910810108111081210813108141081510816108171081810819108201082110822108231082410825108261082710828108291083010831108321083310834108351083610837108381083910840108411084210843108441084510846108471084810849108501085110852108531085410855108561085710858108591086010861108621086310864108651086610867108681086910870108711087210873108741087510876108771087810879108801088110882108831088410885108861088710888108891089010891108921089310894108951089610897108981089910900109011090210903109041090510906109071090810909109101091110912109131091410915109161091710918109191092010921109221092310924109251092610927109281092910930109311093210933109341093510936109371093810939109401094110942109431094410945109461094710948109491095010951109521095310954109551095610957109581095910960109611096210963109641096510966109671096810969109701097110972109731097410975109761097710978109791098010981109821098310984109851098610987109881098910990109911099210993109941099510996109971099810999110001100111002110031100411005110061100711008110091101011011110121101311014110151101611017110181101911020110211102211023110241102511026110271102811029110301103111032110331103411035110361103711038110391104011041110421104311044110451104611047110481104911050110511105211053110541105511056110571105811059110601106111062110631106411065110661106711068110691107011071110721107311074110751107611077110781107911080110811108211083110841108511086110871108811089110901109111092110931109411095110961109711098110991110011101111021110311104111051110611107111081110911110111111111211113111141111511116111171111811119111201112111122111231112411125111261112711128111291113011131111321113311134111351113611137111381113911140111411114211143111441114511146111471114811149111501115111152111531115411155111561115711158111591116011161111621116311164111651116611167111681116911170111711117211173111741117511176111771117811179111801118111182111831118411185111861118711188111891119011191111921119311194111951119611197111981119911200112011120211203112041120511206112071120811209112101121111212112131121411215112161121711218112191122011221112221122311224112251122611227112281122911230112311123211233112341123511236112371123811239112401124111242112431124411245112461124711248112491125011251112521125311254112551125611257112581125911260112611126211263112641126511266112671126811269112701127111272112731127411275112761127711278112791128011281112821128311284112851128611287112881128911290112911129211293112941129511296112971129811299113001130111302113031130411305113061130711308113091131011311113121131311314113151131611317113181131911320113211132211323113241132511326113271132811329113301133111332113331133411335113361133711338113391134011341113421134311344113451134611347113481134911350113511135211353113541135511356113571135811359113601136111362113631136411365113661136711368113691137011371113721137311374113751137611377113781137911380113811138211383113841138511386113871138811389113901139111392113931139411395113961139711398113991140011401114021140311404114051140611407114081140911410114111141211413114141141511416114171141811419114201142111422114231142411425114261142711428114291143011431114321143311434114351143611437114381143911440114411144211443114441144511446114471144811449114501145111452114531145411455114561145711458114591146011461114621146311464114651146611467114681146911470114711147211473114741147511476114771147811479114801148111482114831148411485114861148711488114891149011491114921149311494114951149611497114981149911500115011150211503115041150511506115071150811509115101151111512115131151411515115161151711518115191152011521115221152311524115251152611527115281152911530115311153211533115341153511536115371153811539115401154111542115431154411545115461154711548115491155011551115521155311554115551155611557115581155911560115611156211563115641156511566115671156811569115701157111572115731157411575115761157711578115791158011581115821158311584115851158611587115881158911590115911159211593115941159511596115971159811599116001160111602116031160411605116061160711608116091161011611116121161311614116151161611617116181161911620116211162211623116241162511626116271162811629116301163111632116331163411635116361163711638116391164011641116421164311644116451164611647116481164911650116511165211653116541165511656116571165811659116601166111662116631166411665116661166711668116691167011671116721167311674116751167611677116781167911680116811168211683116841168511686116871168811689116901169111692116931169411695116961169711698116991170011701117021170311704117051170611707117081170911710117111171211713117141171511716117171171811719117201172111722117231172411725117261172711728117291173011731117321173311734117351173611737117381173911740117411174211743117441174511746117471174811749117501175111752117531175411755117561175711758117591176011761117621176311764117651176611767117681176911770117711177211773117741177511776117771177811779117801178111782117831178411785117861178711788117891179011791117921179311794117951179611797117981179911800118011180211803118041180511806118071180811809118101181111812118131181411815118161181711818118191182011821118221182311824118251182611827118281182911830118311183211833118341183511836118371183811839118401184111842118431184411845118461184711848118491185011851118521185311854118551185611857118581185911860118611186211863118641186511866118671186811869118701187111872118731187411875118761187711878118791188011881118821188311884118851188611887118881188911890118911189211893118941189511896118971189811899119001190111902119031190411905119061190711908119091191011911119121191311914119151191611917119181191911920119211192211923119241192511926119271192811929119301193111932119331193411935119361193711938119391194011941119421194311944119451194611947119481194911950119511195211953119541195511956119571195811959119601196111962119631196411965119661196711968119691197011971119721197311974119751197611977119781197911980119811198211983119841198511986119871198811989119901199111992119931199411995119961199711998119991200012001120021200312004120051200612007120081200912010120111201212013120141201512016120171201812019120201202112022120231202412025120261202712028120291203012031120321203312034120351203612037120381203912040120411204212043120441204512046120471204812049120501205112052120531205412055120561205712058120591206012061120621206312064120651206612067120681206912070120711207212073120741207512076120771207812079120801208112082120831208412085120861208712088120891209012091120921209312094120951209612097120981209912100121011210212103121041210512106121071210812109121101211112112121131211412115121161211712118121191212012121121221212312124121251212612127121281212912130121311213212133121341213512136121371213812139121401214112142121431214412145121461214712148121491215012151121521215312154121551215612157121581215912160121611216212163121641216512166121671216812169121701217112172121731217412175121761217712178121791218012181121821218312184121851218612187121881218912190121911219212193121941219512196121971219812199122001220112202122031220412205122061220712208122091221012211122121221312214122151221612217122181221912220122211222212223122241222512226122271222812229122301223112232122331223412235122361223712238122391224012241122421224312244122451224612247122481224912250122511225212253122541225512256122571225812259122601226112262122631226412265122661226712268122691227012271122721227312274122751227612277122781227912280122811228212283122841228512286122871228812289122901229112292122931229412295122961229712298122991230012301123021230312304123051230612307123081230912310123111231212313123141231512316123171231812319123201232112322123231232412325123261232712328123291233012331123321233312334123351233612337123381233912340123411234212343123441234512346123471234812349123501235112352123531235412355123561235712358123591236012361123621236312364123651236612367123681236912370123711237212373123741237512376123771237812379123801238112382123831238412385123861238712388123891239012391123921239312394123951239612397123981239912400124011240212403124041240512406124071240812409124101241112412124131241412415124161241712418124191242012421124221242312424124251242612427124281242912430124311243212433124341243512436124371243812439124401244112442124431244412445124461244712448124491245012451124521245312454124551245612457124581245912460124611246212463124641246512466124671246812469124701247112472124731247412475124761247712478124791248012481124821248312484124851248612487124881248912490124911249212493124941249512496124971249812499125001250112502125031250412505125061250712508125091251012511125121251312514125151251612517125181251912520125211252212523125241252512526125271252812529125301253112532125331253412535125361253712538125391254012541125421254312544125451254612547125481254912550125511255212553125541255512556125571255812559125601256112562125631256412565125661256712568125691257012571125721257312574125751257612577125781257912580125811258212583125841258512586125871258812589125901259112592125931259412595125961259712598125991260012601126021260312604126051260612607126081260912610126111261212613126141261512616126171261812619126201262112622126231262412625126261262712628126291263012631126321263312634126351263612637126381263912640126411264212643126441264512646126471264812649126501265112652126531265412655126561265712658126591266012661126621266312664126651266612667126681266912670126711267212673126741267512676126771267812679126801268112682126831268412685126861268712688126891269012691126921269312694126951269612697126981269912700127011270212703127041270512706127071270812709127101271112712127131271412715127161271712718127191272012721127221272312724127251272612727127281272912730127311273212733127341273512736127371273812739127401274112742127431274412745127461274712748127491275012751127521275312754127551275612757127581275912760127611276212763127641276512766127671276812769127701277112772127731277412775127761277712778127791278012781127821278312784127851278612787127881278912790127911279212793127941279512796127971279812799128001280112802128031280412805128061280712808128091281012811128121281312814128151281612817128181281912820128211282212823128241282512826128271282812829128301283112832128331283412835128361283712838128391284012841128421284312844128451284612847128481284912850128511285212853128541285512856128571285812859128601286112862128631286412865128661286712868128691287012871128721287312874128751287612877128781287912880128811288212883128841288512886128871288812889128901289112892128931289412895128961289712898128991290012901129021290312904129051290612907129081290912910129111291212913129141291512916129171291812919129201292112922129231292412925129261292712928129291293012931129321293312934129351293612937129381293912940129411294212943129441294512946129471294812949129501295112952129531295412955129561295712958129591296012961129621296312964129651296612967129681296912970129711297212973129741297512976129771297812979129801298112982129831298412985129861298712988129891299012991129921299312994129951299612997129981299913000130011300213003130041300513006130071300813009130101301113012130131301413015130161301713018130191302013021130221302313024130251302613027130281302913030130311303213033130341303513036130371303813039130401304113042130431304413045130461304713048130491305013051130521305313054130551305613057130581305913060130611306213063130641306513066130671306813069130701307113072130731307413075130761307713078130791308013081130821308313084130851308613087130881308913090130911309213093130941309513096130971309813099131001310113102131031310413105131061310713108131091311013111131121311313114131151311613117131181311913120131211312213123131241312513126131271312813129131301313113132131331313413135131361313713138131391314013141131421314313144131451314613147131481314913150131511315213153131541315513156131571315813159131601316113162131631316413165131661316713168131691317013171131721317313174131751317613177131781317913180131811318213183131841318513186131871318813189131901319113192131931319413195131961319713198131991320013201132021320313204132051320613207132081320913210132111321213213132141321513216132171321813219132201322113222132231322413225132261322713228132291323013231132321323313234132351323613237132381323913240132411324213243132441324513246132471324813249132501325113252132531325413255132561325713258132591326013261132621326313264132651326613267132681326913270132711327213273132741327513276132771327813279132801328113282132831328413285132861328713288132891329013291132921329313294132951329613297132981329913300133011330213303133041330513306133071330813309133101331113312133131331413315133161331713318133191332013321133221332313324133251332613327133281332913330133311333213333133341333513336133371333813339133401334113342133431334413345133461334713348133491335013351133521335313354133551335613357133581335913360133611336213363133641336513366133671336813369133701337113372133731337413375133761337713378133791338013381133821338313384133851338613387133881338913390133911339213393133941339513396133971339813399134001340113402134031340413405134061340713408134091341013411134121341313414134151341613417134181341913420134211342213423134241342513426134271342813429134301343113432134331343413435134361343713438134391344013441134421344313444134451344613447134481344913450134511345213453134541345513456134571345813459134601346113462134631346413465134661346713468134691347013471134721347313474134751347613477134781347913480134811348213483134841348513486134871348813489134901349113492134931349413495134961349713498134991350013501135021350313504135051350613507135081350913510135111351213513135141351513516135171351813519135201352113522135231352413525135261352713528135291353013531135321353313534135351353613537135381353913540135411354213543135441354513546135471354813549135501355113552135531355413555135561355713558135591356013561135621356313564135651356613567135681356913570135711357213573135741357513576135771357813579135801358113582135831358413585135861358713588135891359013591135921359313594135951359613597135981359913600136011360213603136041360513606136071360813609136101361113612136131361413615136161361713618136191362013621136221362313624136251362613627136281362913630136311363213633136341363513636136371363813639136401364113642136431364413645136461364713648136491365013651136521365313654136551365613657136581365913660136611366213663136641366513666136671366813669136701367113672136731367413675136761367713678136791368013681136821368313684136851368613687136881368913690136911369213693136941369513696136971369813699137001370113702137031370413705137061370713708137091371013711137121371313714137151371613717137181371913720137211372213723137241372513726137271372813729137301373113732137331373413735137361373713738137391374013741137421374313744137451374613747137481374913750137511375213753137541375513756137571375813759137601376113762137631376413765137661376713768137691377013771137721377313774137751377613777137781377913780137811378213783137841378513786137871378813789137901379113792137931379413795137961379713798137991380013801138021380313804138051380613807138081380913810138111381213813138141381513816138171381813819138201382113822138231382413825138261382713828138291383013831138321383313834138351383613837138381383913840138411384213843138441384513846138471384813849138501385113852138531385413855138561385713858138591386013861138621386313864138651386613867138681386913870138711387213873138741387513876138771387813879138801388113882138831388413885138861388713888138891389013891138921389313894138951389613897138981389913900139011390213903139041390513906139071390813909139101391113912139131391413915139161391713918139191392013921139221392313924139251392613927139281392913930139311393213933139341393513936139371393813939139401394113942139431394413945139461394713948139491395013951139521395313954139551395613957139581395913960139611396213963139641396513966139671396813969139701397113972139731397413975139761397713978139791398013981139821398313984139851398613987139881398913990139911399213993139941399513996139971399813999140001400114002140031400414005140061400714008140091401014011140121401314014140151401614017140181401914020140211402214023140241402514026140271402814029140301403114032140331403414035140361403714038140391404014041140421404314044140451404614047140481404914050140511405214053140541405514056140571405814059140601406114062140631406414065140661406714068140691407014071140721407314074140751407614077140781407914080140811408214083140841408514086140871408814089140901409114092140931409414095140961409714098140991410014101141021410314104141051410614107141081410914110141111411214113141141411514116141171411814119141201412114122141231412414125141261412714128141291413014131141321413314134141351413614137141381413914140141411414214143141441414514146141471414814149141501415114152141531415414155141561415714158141591416014161141621416314164141651416614167141681416914170141711417214173141741417514176141771417814179141801418114182141831418414185141861418714188141891419014191141921419314194141951419614197141981419914200142011420214203142041420514206142071420814209142101421114212142131421414215142161421714218142191422014221142221422314224142251422614227142281422914230142311423214233142341423514236142371423814239142401424114242142431424414245142461424714248142491425014251142521425314254142551425614257142581425914260142611426214263142641426514266142671426814269142701427114272142731427414275142761427714278142791428014281142821428314284142851428614287142881428914290142911429214293142941429514296142971429814299143001430114302143031430414305143061430714308143091431014311143121431314314143151431614317143181431914320143211432214323143241432514326143271432814329143301433114332143331433414335143361433714338143391434014341143421434314344143451434614347143481434914350143511435214353143541435514356143571435814359143601436114362143631436414365143661436714368143691437014371143721437314374143751437614377143781437914380143811438214383143841438514386143871438814389143901439114392143931439414395143961439714398143991440014401144021440314404144051440614407144081440914410144111441214413144141441514416144171441814419144201442114422144231442414425144261442714428144291443014431144321443314434144351443614437144381443914440144411444214443144441444514446144471444814449144501445114452144531445414455144561445714458144591446014461144621446314464144651446614467144681446914470144711447214473144741447514476144771447814479144801448114482144831448414485144861448714488144891449014491144921449314494144951449614497144981449914500145011450214503145041450514506145071450814509145101451114512145131451414515145161451714518145191452014521145221452314524145251452614527145281452914530145311453214533145341453514536145371453814539145401454114542145431454414545145461454714548145491455014551145521455314554145551455614557145581455914560145611456214563145641456514566145671456814569145701457114572145731457414575145761457714578145791458014581145821458314584145851458614587145881458914590145911459214593145941459514596145971459814599146001460114602146031460414605146061460714608146091461014611146121461314614146151461614617146181461914620146211462214623146241462514626146271462814629146301463114632146331463414635146361463714638146391464014641146421464314644146451464614647146481464914650146511465214653146541465514656146571465814659146601466114662146631466414665146661466714668146691467014671146721467314674146751467614677146781467914680146811468214683146841468514686146871468814689146901469114692146931469414695146961469714698146991470014701147021470314704147051470614707147081470914710147111471214713147141471514716147171471814719147201472114722147231472414725147261472714728147291473014731147321473314734147351473614737147381473914740147411474214743147441474514746147471474814749147501475114752147531475414755147561475714758147591476014761147621476314764147651476614767147681476914770147711477214773147741477514776147771477814779147801478114782147831478414785147861478714788147891479014791147921479314794147951479614797147981479914800148011480214803148041480514806148071480814809148101481114812148131481414815148161481714818148191482014821148221482314824148251482614827148281482914830148311483214833148341483514836148371483814839148401484114842148431484414845148461484714848148491485014851148521485314854148551485614857148581485914860148611486214863148641486514866148671486814869148701487114872148731487414875148761487714878148791488014881148821488314884148851488614887148881488914890148911489214893148941489514896148971489814899149001490114902149031490414905149061490714908149091491014911149121491314914149151491614917149181491914920149211492214923149241492514926149271492814929149301493114932149331493414935149361493714938149391494014941149421494314944149451494614947149481494914950149511495214953149541495514956149571495814959149601496114962149631496414965149661496714968149691497014971149721497314974149751497614977149781497914980149811498214983149841498514986149871498814989149901499114992149931499414995149961499714998149991500015001150021500315004150051500615007150081500915010150111501215013150141501515016150171501815019150201502115022150231502415025150261502715028150291503015031150321503315034150351503615037150381503915040150411504215043150441504515046150471504815049150501505115052150531505415055150561505715058150591506015061150621506315064150651506615067150681506915070150711507215073150741507515076150771507815079150801508115082150831508415085150861508715088150891509015091150921509315094150951509615097150981509915100151011510215103151041510515106151071510815109151101511115112151131511415115151161511715118151191512015121151221512315124151251512615127151281512915130151311513215133151341513515136151371513815139151401514115142151431514415145151461514715148151491515015151151521515315154151551515615157151581515915160151611516215163151641516515166151671516815169151701517115172151731517415175151761517715178151791518015181151821518315184151851518615187151881518915190151911519215193151941519515196151971519815199152001520115202152031520415205152061520715208152091521015211152121521315214152151521615217152181521915220152211522215223152241522515226152271522815229152301523115232152331523415235152361523715238152391524015241152421524315244152451524615247152481524915250152511525215253152541525515256152571525815259152601526115262152631526415265152661526715268152691527015271152721527315274152751527615277152781527915280152811528215283152841528515286152871528815289152901529115292152931529415295152961529715298152991530015301153021530315304153051530615307153081530915310153111531215313153141531515316153171531815319153201532115322153231532415325153261532715328153291533015331153321533315334153351533615337153381533915340153411534215343153441534515346153471534815349153501535115352153531535415355153561535715358153591536015361153621536315364153651536615367153681536915370153711537215373153741537515376153771537815379153801538115382153831538415385153861538715388153891539015391153921539315394153951539615397153981539915400154011540215403154041540515406154071540815409154101541115412154131541415415154161541715418154191542015421154221542315424154251542615427154281542915430154311543215433154341543515436154371543815439154401544115442154431544415445154461544715448154491545015451154521545315454154551545615457154581545915460154611546215463154641546515466154671546815469154701547115472154731547415475154761547715478154791548015481154821548315484154851548615487154881548915490154911549215493154941549515496154971549815499155001550115502155031550415505155061550715508155091551015511155121551315514155151551615517155181551915520155211552215523155241552515526155271552815529155301553115532155331553415535155361553715538155391554015541155421554315544155451554615547155481554915550155511555215553155541555515556155571555815559155601556115562155631556415565155661556715568155691557015571155721557315574155751557615577155781557915580155811558215583155841558515586155871558815589155901559115592155931559415595155961559715598155991560015601156021560315604156051560615607156081560915610156111561215613156141561515616156171561815619156201562115622156231562415625156261562715628156291563015631156321563315634156351563615637156381563915640156411564215643156441564515646156471564815649156501565115652156531565415655156561565715658156591566015661156621566315664156651566615667156681566915670156711567215673156741567515676156771567815679156801568115682156831568415685156861568715688156891569015691156921569315694156951569615697156981569915700157011570215703157041570515706157071570815709157101571115712157131571415715157161571715718157191572015721157221572315724157251572615727157281572915730157311573215733157341573515736157371573815739157401574115742157431574415745157461574715748157491575015751157521575315754157551575615757157581575915760157611576215763157641576515766157671576815769157701577115772157731577415775157761577715778157791578015781157821578315784157851578615787157881578915790157911579215793157941579515796157971579815799158001580115802158031580415805158061580715808158091581015811158121581315814158151581615817158181581915820158211582215823158241582515826158271582815829158301583115832158331583415835158361583715838158391584015841158421584315844158451584615847158481584915850158511585215853158541585515856158571585815859158601586115862158631586415865158661586715868158691587015871158721587315874158751587615877158781587915880158811588215883158841588515886158871588815889158901589115892158931589415895158961589715898158991590015901159021590315904159051590615907159081590915910159111591215913159141591515916159171591815919159201592115922159231592415925159261592715928159291593015931159321593315934159351593615937159381593915940159411594215943159441594515946159471594815949159501595115952159531595415955159561595715958159591596015961159621596315964159651596615967159681596915970159711597215973159741597515976159771597815979159801598115982159831598415985159861598715988159891599015991159921599315994159951599615997159981599916000160011600216003160041600516006160071600816009160101601116012160131601416015160161601716018160191602016021160221602316024160251602616027160281602916030160311603216033160341603516036160371603816039160401604116042160431604416045160461604716048160491605016051160521605316054160551605616057160581605916060160611606216063160641606516066160671606816069160701607116072160731607416075160761607716078160791608016081160821608316084160851608616087160881608916090160911609216093160941609516096160971609816099161001610116102161031610416105161061610716108161091611016111161121611316114161151611616117161181611916120161211612216123161241612516126161271612816129161301613116132161331613416135161361613716138
  1. #define CKUTIO_C
  2. #ifdef aegis
  3. char *ckxv = "Aegis Communications support, 9.0.329, 18 September 2020";
  4. #else
  5. #ifdef Plan9
  6. char *ckxv = "Plan 9 Communications support, 9.0.329, 18 September 2020";
  7. #else
  8. char *ckxv = "UNIX Communications support, 9.0.329, 18 September 2020";
  9. #endif /* Plan9 */
  10. #endif /* aegis */
  11. /* C K U T I O */
  12. /* C-Kermit interrupt, communications control and I/O functions for UNIX */
  13. /*
  14. Author: Frank da Cruz (fdc@columbia.edu),
  15. The Kermit Project, Bronx, NY.
  16. Copyright (C) 1985, 2020,
  17. Trustees of Columbia University in the City of New York.
  18. All rights reserved. See the C-Kermit COPYING.TXT file or the
  19. copyright text in the ckcmai.c module for disclaimer and permissions.
  20. */
  21. /*
  22. NOTE TO CONTRIBUTORS: This file, and all the other C-Kermit files, must be
  23. compatible with C preprocessors that support only #ifdef, #else, #endif,
  24. #define, and #undef. Please do not use #if, logical operators, or other
  25. preprocessor features in any of the portable C-Kermit modules. You can,
  26. of course, use these constructions in platform-specific modules when they
  27. are supported by all compilers/preprocessors that could be used on that
  28. platform.
  29. */
  30. extern int nettype; /* Defined in ckcmai.c */
  31. extern int duplex;
  32. /* Includes */
  33. #include "ckcsym.h" /* This must go first */
  34. #include "ckcdeb.h" /* This must go second */
  35. #ifdef OSF13
  36. #ifdef CK_ANSIC
  37. #ifdef _NO_PROTO
  38. #undef _NO_PROTO
  39. #endif /* _NO_PROTO */
  40. #endif /* CK_ANSIC */
  41. #endif /* OSF13 */
  42. #ifndef HPUXPRE65
  43. #include <errno.h> /* Error number symbols */
  44. #else
  45. #ifndef ERRNO_INCLUDED
  46. #include <errno.h> /* Error number symbols */
  47. #endif /* ERRNO_INCLUDED */
  48. #endif /* HPUXPRE65 */
  49. #ifdef __386BSD__
  50. #define ENOTCONN 57
  51. #else
  52. #ifdef __bsdi__
  53. #define ENOTCONN 57
  54. #else
  55. #ifdef __FreeBSD__
  56. #define ENOTCONN 57
  57. #endif /* __FreeBSD__ */
  58. #endif /* __bsdi__ */
  59. #endif /* __386BSD__ */
  60. #ifdef SCO_OSR504
  61. #define NBBY 8
  62. #endif /* SCO_OSR504 */
  63. #ifdef Plan9
  64. #define SELECT
  65. #include <sys/time.h>
  66. #include <select.h>
  67. #define FD_SETSIZE (3 * sizeof(long) * 8)
  68. static struct timeval tv;
  69. #endif /* Plan9 */
  70. #ifdef CLIX
  71. #include <sys/time.h>
  72. #endif /* CLIX */
  73. #include "ckcnet.h" /* Symbols for network types. */
  74. #ifdef CK_SSL
  75. #include "ck_ssl.h"
  76. #endif /* CK_SSL */
  77. /*
  78. The directory-related includes are here because we need to test some
  79. file-system-related symbols to find out which system we're being compiled
  80. under. For example, MAXNAMLEN is defined in BSD4.2 but not 4.1.
  81. */
  82. #ifdef SDIRENT /* Directory bits... */
  83. #define DIRENT
  84. #endif /* SDIRENT */
  85. #ifdef XNDIR
  86. #include <sys/ndir.h>
  87. #else /* !XNDIR */
  88. #ifdef NDIR
  89. #include <ndir.h>
  90. #else /* !NDIR, !XNDIR */
  91. #ifdef RTU
  92. #include "/usr/lib/ndir.h"
  93. #else /* !RTU, !NDIR, !XNDIR */
  94. #ifdef DIRENT
  95. #ifdef SDIRENT
  96. #include <sys/dirent.h>
  97. #else
  98. #include <dirent.h>
  99. #endif /* SDIRENT */
  100. #else /* !RTU, !NDIR, !XNDIR, !DIRENT, i.e. all others */
  101. #include <sys/dir.h>
  102. #endif /* DIRENT */
  103. #endif /* RTU */
  104. #endif /* NDIR */
  105. #endif /* XNDIR */
  106. #ifdef QNX
  107. #include <sys/dev.h>
  108. #endif /* QNX */
  109. #ifdef HPUX5
  110. #ifndef TCPSOCKET
  111. /* I don't know why this is needed here since we never reference bzero(). */
  112. /* But without it C-Kermit won't link in an HP-UX 5.xx non-TCP build. */
  113. void
  114. bzero(s,n) char *s; int n; {
  115. extern char * memset();
  116. memset(s,0,n);
  117. }
  118. #endif /* TCPSOCKET */
  119. #endif /* HPUX5 */
  120. /* Definition of HZ, used in msleep() */
  121. #ifdef MIPS
  122. #define HZ ( 1000 / CLOCK_TICK )
  123. #else /* MIPS */
  124. #ifdef ATTSV
  125. #ifndef NAP
  126. #ifdef TRS16
  127. #define HZ ( 1000 / CLOCK_TICK )
  128. #endif /* TRS16 */
  129. #ifdef NAPHACK
  130. #define nap(x) (void)syscall(3112, (x))
  131. #define NAP
  132. #endif /* NAPHACK */
  133. #endif /* NAP */
  134. #endif /* ATTSV */
  135. #endif /* MIPS */
  136. #ifdef M_UNIX
  137. #undef NGROUPS_MAX /* Prevent multiple definition warnings */
  138. #endif /* M_UNIX */
  139. /*
  140. NOTE: HP-UX 8.0 has a <sys/poll.h>, but there is no corresponding
  141. library routine, so _poll comes up undefined at link time.
  142. */
  143. #ifdef CK_POLL
  144. #ifndef AIXRS /* IBM AIX needs special handling */
  145. #include <poll.h> /* "standard" (SVID) i/o multiplexing, etc */
  146. #else /* AIXRS */
  147. #ifdef SVR4 /* AIX 3.2 is like SVID... */
  148. #include <poll.h>
  149. #else /* But AIX 3.1 is not ... */
  150. #include <sys/poll.h> /* The include file is in include/sys */
  151. #define events reqevents /* And it does not map IBM-specific member */
  152. #define revents rtnevents /* names to the System V equivalents */
  153. #endif /* SVR4 */
  154. #endif /* AIXRS */
  155. #endif /* CK_POLL */
  156. #include <signal.h> /* Signals */
  157. /* For setjmp and longjmp */
  158. #ifndef ZILOG
  159. #include <setjmp.h>
  160. #else
  161. #include <setret.h>
  162. #endif /* ZILOG */
  163. /*
  164. The following test differentiates between 4.1 BSD and 4.2 & later.
  165. If you have a 4.1BSD system with the DIRENT library, this test could
  166. mistakenly diagnose 4.2BSD and then later enable the use of system calls
  167. that aren't defined. If indeed there are such systems, we can use some
  168. other way of testing for 4.1BSD, or add yet another compile-time switch.
  169. */
  170. #ifdef BSD4
  171. #ifdef MAXNAMLEN
  172. #ifndef FT21 /* Except for Fortune. */
  173. #ifndef FT18
  174. #ifndef BELLV10 /* And Bell Labs Research UNIX V10 */
  175. #define BSD42
  176. #endif /* BELLV10 */
  177. #endif /* FT18 */
  178. #endif /* FT21 */
  179. #endif /* MAXNAMLEN */
  180. #endif /* BSD4 */
  181. #ifdef SUNOS41 /* From Christian Corti */
  182. #define BSD44ORPOSIX /* Uni Stuttgart */
  183. #define SVORPOSIX /* February 2010 */
  184. #include <termios.h>
  185. #include <sys/ioctl.h>
  186. #include <unistd.h>
  187. #include <limits.h>
  188. #endif /* SUNOS41 */
  189. #ifdef SNI542
  190. #include <sys/filio.h> /* 299 for FIONREAD */
  191. #endif /* SNI542 */
  192. /*
  193. Minix 2.0 support added by Terry McConnell,
  194. Syracuse University <tmc@barnyard.syr.edu>
  195. No more sgtty interface, posix compliant.
  196. */
  197. #ifdef MINIX2
  198. #define _MINIX /* Needed for some Minix header files */
  199. #define BSD44ORPOSIX
  200. #define SVORPOSIX
  201. #ifndef MINIX3
  202. #define DCLTIMEVAL
  203. #endif /* MINIX3 */
  204. #define NOFILEH
  205. #include <sys/types.h>
  206. #include <sys/ioctl.h>
  207. #include <termios.h>
  208. #include <limits.h>
  209. #undef TIOCGETC /* defined in sys/ioctl.h, but not really supported */
  210. #define TANDEM 0
  211. #endif /* MINIX2 */
  212. /*
  213. MINIX 1.0 support added by Charles Hedrick,
  214. Rutgers University <hedrick@aramis.rutgers.edu>.
  215. MINIX also has V7 enabled.
  216. */
  217. #ifdef MINIX
  218. #define TANDEM 0
  219. #define MYREAD
  220. #define NOSYSIOCTLH
  221. #include <limits.h>
  222. #endif /* MINIX */
  223. #ifdef CK_REDIR /* <sys/wait.h> needed only for REDIRECT command. */
  224. /*
  225. If anybody can figure out how to make this work with NeXTSTEP, be
  226. my guest! (NeXTBlah/NeXTBlah/bsd/sys/wait.h does not define WEXITSTATUS)
  227. */
  228. #ifndef CK_WAIT_H /* If wait.h not already included... */
  229. #ifdef OSF /* force OSF to select POSIX wait */
  230. #ifdef _BSD /* instead of BSD (see ckcdeb.h) */
  231. #define CK_OSF_BSD
  232. #undef _BSD
  233. #endif /* _BSD */
  234. #endif /* OSF */
  235. #include <sys/wait.h> /* Include it */
  236. #ifdef OSF
  237. #ifdef CK_OSF_BSD
  238. #define _BSD /* Restore it */
  239. #undef CK_OSF_BSD
  240. #endif /* CK_OSF_BSD */
  241. #endif /* OSF */
  242. #endif /* CK_WAIT_H */
  243. #endif /* CK_REDIR */
  244. #include "ckuver.h" /* Version herald */
  245. char *ckxsys = HERALD;
  246. #ifdef CK_UTSNAME
  247. #include <sys/utsname.h>
  248. #ifdef TRU64 /* Tru64 UNIX 4.0 and later */
  249. /* Verified on Tru64 4.0F - might break on 4.0E or earlier */
  250. #include <sys/sysinfo.h> /* (don't know about OSF/1 or DU) */
  251. #include <machine/hal_sysinfo.h>
  252. #endif /* TRU64 */
  253. #ifdef SOLARIS25 /* Solaris 2.5 and later */
  254. #include <sys/systeminfo.h> /* (don't know about earlier ones) */
  255. #endif /* SOLARIS25 */
  256. #ifdef UW7
  257. #ifndef SYS_NMLN
  258. #define SYS_NMLN 257
  259. #endif /* NMLN */
  260. #endif /* UW7 */
  261. #ifdef HPUX9PLUS
  262. static int hpis800 = 0;
  263. #endif /* HPUX9PLUS */
  264. #ifdef SYS_NMLN
  265. #define CK_SYSNMLN SYS_NMLN
  266. #else
  267. #ifdef _SYS_NMLN
  268. #define CK_SYSNMLN _SYS_NMLN
  269. #else
  270. #ifdef UTSLEN
  271. #define CK_SYSNMLN UTSLEN
  272. #else
  273. #define CK_SYSNMLN 31
  274. #endif /* UTSLEN */
  275. #endif /* _SYS_NMLN */
  276. #endif /* SYS_NMLN */
  277. char unm_mch[CK_SYSNMLN+1] = { '\0', '\0' };
  278. char unm_mod[CK_SYSNMLN+1] = { '\0', '\0' };
  279. char unm_nam[CK_SYSNMLN+1] = { '\0', '\0' };
  280. char unm_rel[CK_SYSNMLN+1] = { '\0', '\0' };
  281. char unm_ver[CK_SYSNMLN+1] = { '\0', '\0' };
  282. #endif /* CK_UTSNAME */
  283. #ifdef CIE
  284. #include <stat.h> /* For chasing symlinks, etc. */
  285. #else
  286. #include <sys/stat.h>
  287. #endif /* CIE */
  288. #ifdef QNX /* 299 */
  289. #ifndef IXANY
  290. #define IXANY 0
  291. #endif /* IXANY */
  292. #endif /* QNX */
  293. /* UUCP lockfile material... */
  294. #ifndef NOUUCP
  295. #ifdef USETTYLOCK
  296. #ifdef HAVE_LOCKDEV /* Red Hat baudboy/lockdev */
  297. /*
  298. Watch out: baudboy.h references open() without making sure it has been
  299. declared, resulting in warnings on at least Red Hat 7.3. It's declared in
  300. fcntl.h, but we don't include that until later. In this case only, we
  301. include it here, and then the second include is harmless because in Red Hat
  302. Linux (the only place where you find baudboy.h) fcntl.h is protected from
  303. multiple inclusion by _FCNTL_H. - fdc, 10 May 2004.
  304. NOTE: Although Linux /usr/sbin/lockdev obviates the need for setuid or
  305. setgid bits to access the lockfile, C-Kermit will still need them to access
  306. the serial port itself unless the port is open for world read/write.
  307. Normally setgid uucp does the trick.
  308. Extra: HAVE_LOCKDEV has been added als openSuSE >= 11.3 doesn't use baudboy
  309. but ttylock. - jb, 26 Jul 2010
  310. */
  311. #include <fcntl.h> /* This has to come before baudboy */
  312. #ifdef HAVE_BAUDBOY /* Red Hat baudboy/lockdev */
  313. #include <baudboy.h>
  314. #else /* !HAVE_BAUDBOY */ /* openSuSE lock via ttylock */
  315. #include <ttylock.h>
  316. #endif /* HAVE_BAUDBOY */
  317. #define LOCK_DIR "/var/lock" /* (even though we don't care) */
  318. #else /* !HAVE_LOCKDEV */
  319. #ifdef USE_UU_LOCK
  320. #ifdef __FreeBSD__
  321. #include <libutil.h> /* FreeBSD */
  322. #else
  323. #include <util.h> /* OpenBSD */
  324. #endif /* HAVE_LOCKDEV */
  325. #endif /* __FreeBSD */
  326. #endif /* USE_UU_LOCK */
  327. #else /* USETTYLOCK */
  328. /* Name of UUCP tty device lockfile */
  329. #ifdef LINUXFSSTND
  330. #ifndef HDBUUCP
  331. #define HDBUUCP
  332. #endif /* HDBUUCP */
  333. #endif /* LINUXFSSTND */
  334. #ifdef ACUCNTRL
  335. #define LCKDIR
  336. #endif /* ACUCNTRL */
  337. /*
  338. PIDSTRING means use ASCII string to represent pid in lockfile.
  339. */
  340. #ifndef PIDSTRING
  341. #ifdef HDBUUCP
  342. #define PIDSTRING
  343. #else
  344. #ifdef BSD44
  345. #define PIDSTRING
  346. #else
  347. #ifdef RTAIX
  348. #define PIDSTRING
  349. #else
  350. #ifdef AIXRS
  351. #define PIDSTRING
  352. #else
  353. #ifdef COHERENT
  354. #define PIDSTRING
  355. #endif /* COHERENT */
  356. #endif /* AIXRS */
  357. #endif /* RTAIX */
  358. #endif /* BSD44 */
  359. #endif /* HDBUUCP */
  360. #endif /* PIDSTRING */
  361. /* Now the PIDSTRING exceptions... */
  362. #ifdef PIDSTRING
  363. #ifdef HPUX
  364. #undef PIDSTRING
  365. #endif /* HPUX */
  366. #endif /* PIDSTRING */
  367. #ifdef __bsdi__ /* BSDI (at least thru 1.1) */
  368. #ifdef PIDSTRING
  369. #undef PIDSTRING
  370. #endif /* PIDSTRING */
  371. #endif /* __bsdi__ */
  372. #ifdef OSF32 /* Digital UNIX (OSF/1) 3.2 */
  373. #ifdef PIDSTRING
  374. #undef PIDSTRING
  375. #endif /* PIDSTRING */
  376. #endif /* OSF32 */
  377. /*
  378. LOCK_DIR is the name of the lockfile directory.
  379. If LOCK_DIR is already defined (e.g. on command line), we don't change it.
  380. */
  381. #ifndef LOCK_DIR
  382. #ifdef MACOSX
  383. #define LOCK_DIR "/var/spool/lock"
  384. #endif /* MACOSX */
  385. #endif/* LOCK_DIR */
  386. #ifndef LOCK_DIR
  387. #ifdef BSD44
  388. #ifdef __386BSD__
  389. #define LOCK_DIR "/var/spool/lock"
  390. #else
  391. #ifdef __FreeBSD__
  392. #define LOCK_DIR "/var/spool/lock"
  393. #else
  394. #ifdef __NetBSD__
  395. #define LOCK_DIR "/var/spool/lock"
  396. #else
  397. #ifdef __OpenBSD__
  398. #define LOCK_DIR "/var/spool/lock"
  399. #else
  400. /* So which ones is this for? */
  401. /* Probably original 4.4BSD on Vangogh */
  402. /* Plus who knows about Mac OS X... It doesn't even have a cu program */
  403. #define LOCK_DIR "/var/spool/uucp"
  404. #endif /* __OpenBSD__ */
  405. #endif /* __NetBSD__ */
  406. #endif /* __FreeBSD__ */
  407. #endif /* __386BSD__ */
  408. #else
  409. #ifdef DGUX430
  410. #define LOCK_DIR "/var/spool/locks"
  411. #else
  412. #ifdef HPUX10
  413. #define LOCK_DIR "/var/spool/locks"
  414. #else
  415. #ifdef RTAIX /* IBM RT PC AIX 2.2.1 */
  416. #define LOCK_DIR "/etc/locks"
  417. #else
  418. #ifdef AIXRS
  419. #define LOCK_DIR "/etc/locks"
  420. #else
  421. #ifdef ISIII
  422. #define LOCK_DIR "/etc/locks"
  423. #else
  424. #ifdef HDBUUCP
  425. #ifdef M_SYS5
  426. #define LOCK_DIR "/usr/spool/uucp"
  427. #else
  428. #ifdef M_UNIX
  429. #define LOCK_DIR "/usr/spool/uucp"
  430. #else
  431. #ifdef SVR4
  432. #define LOCK_DIR "/var/spool/locks"
  433. #else
  434. #ifdef SUNOS4
  435. #define LOCK_DIR "/var/spool/locks"
  436. #else
  437. #ifdef LINUXFSSTND
  438. #define LOCK_DIR "/var/lock";
  439. #else
  440. #define LOCK_DIR "/usr/spool/locks"
  441. #endif /* LINUXFSSTND */
  442. #endif /* SUNOS4 */
  443. #endif /* SVR4 */
  444. #endif /* M_UNIX */
  445. #endif /* M_SYS5 */
  446. #else
  447. #ifdef LCKDIR
  448. #define LOCK_DIR "/usr/spool/uucp/LCK"
  449. #else
  450. #ifdef COHERENT
  451. #define LOCK_DIR "/usr/spool/uucp"
  452. #else
  453. #define LOCK_DIR "/usr/spool/uucp"
  454. #endif /* COHERENT */
  455. #endif /* LCKDIR */
  456. #endif /* HDBUUCP */
  457. #endif /* ISIII */
  458. #endif /* AIXRS */
  459. #endif /* RTAIX */
  460. #endif /* HPUX10 */
  461. #endif /* DGUX430 */
  462. #endif /* BSD44 */
  463. #endif /* !LOCK_DIR (outside ifndef) */
  464. #ifdef OSF2 /* OSF/1 2.0 or later */
  465. #ifdef LOCK_DIR /* (maybe 1.x too, who knows...) */
  466. #undef LOCK_DIR
  467. #define LOCK_DIR "/var/spool/locks"
  468. #endif /* LOCK_DIR */
  469. #endif /* OSF2 */
  470. #ifdef COMMENT
  471. /* Sorry no more lockf() -- we lock first and THEN open the device. */
  472. #ifdef SVR4
  473. #ifndef BSD44
  474. #ifndef LOCKF
  475. #define LOCKF /* Use lockf() on tty device in SVR4 */
  476. #endif /* LOCKF */
  477. #endif /* BSD44 */
  478. #endif /* SVR4 */
  479. #endif /* COMMENT */
  480. #ifdef NOLOCKF /* But NOLOCKF cancels LOCKF */
  481. #ifdef LOCKF
  482. #undef LOCKF
  483. #endif /* LOCKF */
  484. #endif /* NOLOCKF */
  485. /* More about this below... */
  486. #endif /* USETTYLOCK */
  487. #endif /* NOUUCP */
  488. /*
  489. MYREAD means use our internally defined nonblocking buffered read routine.
  490. */
  491. #ifdef ATTSV
  492. #define MYREAD
  493. #endif /* ATTSV */
  494. #ifdef ATT7300
  495. #ifndef MYREAD
  496. #define MYREAD
  497. #endif /* MYREAD */
  498. /* bits for attmodem: internal modem in use, restart getty */
  499. #define ISMODEM 1
  500. #define DOGETY 512
  501. #endif /* ATT7300 */
  502. #ifdef BSD42
  503. #define MYREAD
  504. #endif /* BSD42 */
  505. #ifdef POSIX
  506. #define MYREAD
  507. #endif /* POSIX */
  508. #ifdef __bsdi__
  509. #ifndef O_NDELAY
  510. #define O_NDELAY O_NONBLOCK
  511. #endif /* O_NDELAY */
  512. #endif /* __bsdi__ */
  513. /*
  514. Variables available to outside world:
  515. dftty -- Pointer to default tty name string, like "/dev/tty".
  516. dfloc -- 0 if dftty is console, 1 if external line.
  517. dfprty -- Default parity
  518. dfflow -- Default flow control
  519. ckxech -- Flag for who echoes console typein:
  520. 1 - The program (system echo is turned off)
  521. 0 - The system (or front end, or terminal).
  522. functions that want to do their own echoing should check this flag
  523. before doing so.
  524. flfnam -- Name of lock file, including its path, e.g.,
  525. "/usr/spool/uucp/LCK..cul0" or "/etc/locks/tty77"
  526. lkflfn -- Name of link to lock file, including its paths
  527. haslock -- Flag set if this kermit established a uucp lock.
  528. lockpid -- PID of other process that has desired line open, as string.
  529. backgrd -- Flag indicating program executing in background ( & on
  530. end of shell command). Used to ignore INT and QUIT signals.
  531. rtu_bug -- Set by stptrap(). RTU treats ^Z as EOF (but only when we handle
  532. SIGTSTP)
  533. Functions for assigned communication line (either external or console tty):
  534. sysinit() -- System dependent program initialization
  535. syscleanup() -- System dependent program shutdown
  536. ttopen(ttname,local,mdmtyp,timo) -- Open the named tty for exclusive access.
  537. ttclos() -- Close & reset the tty, releasing any access lock.
  538. ttsspd(cps) -- Set the transmission speed of the tty.
  539. ttgspd() -- Get (read) the the transmission speed of the tty.
  540. ttpkt(speed,flow,parity) -- Put the tty in packet mode and set the speed.
  541. ttvt(speed,flow) -- Put the tty in virtual terminal mode.
  542. or in DIALING or CONNECTED modem control state.
  543. ttres() -- Restore original tty modes.
  544. ttscarr(carrier) -- Set carrier control mode, on/off/auto.
  545. ttinl(dest,max,timo) -- Timed read line from the tty.
  546. ttinc(timo) -- Timed read character from tty.
  547. myread() -- Raw mode bulk buffer read, gives subsequent
  548. chars one at a time and simulates FIONREAD.
  549. myunrd(c) -- Places c back in buffer to be read (one only)
  550. ttchk() -- See how many characters in tty input buffer.
  551. ttxin(n,buf) -- Read n characters from tty (untimed).
  552. ttol(string,length) -- Write a string to the tty.
  553. ttoc(c) -- Write a character to the tty.
  554. ttflui() -- Flush tty input buffer.
  555. ttsndb() -- Send BREAK signal.
  556. ttsndlb() -- Send Long BREAK signal.
  557. ttlock(ttname) -- "Lock" tty device against uucp collisions.
  558. ttunlck() -- Unlock tty device.
  559. For ATT7300/Unix PC, System V:
  560. attdial(ttname,speed,telnbr) -- dials ATT7300/Unix PC internal modem
  561. offgetty(ttname) -- Turns off getty(1m) for comms line
  562. ongetty(ttname) -- Restores getty() to comms line
  563. */
  564. /*
  565. Functions for console terminal:
  566. congm() -- Get console terminal modes.
  567. concb(esc) -- Put the console in single-character wakeup mode with no echo.
  568. conbin(esc) -- Put the console in binary (raw) mode.
  569. conres() -- Restore the console to mode obtained by congm().
  570. conoc(c) -- Unbuffered output, one character to console.
  571. conol(s) -- Unbuffered output, null-terminated string to the console.
  572. conola(s) -- Unbuffered output, array of strings to the console.
  573. conxo(n,s) -- Unbuffered output, n characters to the console.
  574. conchk() -- Check if characters available at console (bsd 4.2).
  575. Check if escape char (^\) typed at console (System III/V).
  576. coninc(timo) -- Timed get a character from the console.
  577. congks(timo) -- Timed get keyboard scan code.
  578. conint() -- Enable terminal interrupts on the console if not background.
  579. connoi() -- Disable terminal interrupts on the console if not background.
  580. Time functions
  581. msleep(m) -- Millisecond sleep
  582. ztime(&s) -- Return pointer to date/time string
  583. rtimer() -- Reset timer
  584. gtimer() -- Get elapsed time since last call to rtimer()
  585. */
  586. /* Conditional Includes */
  587. /* Whether to include <sys/file.h> */
  588. #ifdef RTU /* RTU doesn't */
  589. #define NOFILEH
  590. #endif /* RTU */
  591. #ifdef CIE /* CIE does. */
  592. #undef NOFILEH
  593. #endif /* CIE */
  594. #ifdef BSD41 /* 4.1 BSD doesn't */
  595. #define NOFILEH
  596. #endif /* BSD41 */
  597. #ifdef is68k /* Integrated Solutions 68000 UNIX */
  598. #define NOFILEH /* e.g. on Plexux P60 and Sun-1 */
  599. #endif /* is68k */
  600. #ifdef MINIX /* MINIX */
  601. #define NOFILEH
  602. #endif /* MINIX */
  603. #ifdef COHERENT /* Coherent */
  604. #define NOFILEH
  605. #endif /* COHERENT */
  606. #ifndef NOFILEH /* Now include if selected. */
  607. #include <sys/file.h>
  608. #endif /* NOFILEH */
  609. /* POSIX */
  610. #ifdef BSD44ORPOSIX /* POSIX uses termios.h */
  611. #define TERMIOS
  612. #ifdef __bsdi__
  613. #ifdef POSIX
  614. #undef _POSIX_SOURCE /* Get extra stuff from termios.h */
  615. #endif /* POSIX */
  616. #endif /* __bsdi__ */
  617. #include <termios.h>
  618. #ifdef LINUX
  619. #include <sys/ioctl.h>
  620. #endif /* LINUX */
  621. #ifdef QNX16
  622. #include <ioctl.h>
  623. #else
  624. #ifdef QNX6
  625. #include <ioctl.h>
  626. #endif /* QNX6 */
  627. #endif /* QNX16 */
  628. #ifdef __bsdi__
  629. #ifdef POSIX
  630. #define _POSIX_SOURCE
  631. #endif /* POSIX */
  632. #endif /* __bsdi__ */
  633. #ifndef BSD44 /* Really POSIX */
  634. #ifndef CK_QNX32 /* was CK_QNX32 */
  635. #define NOSYSIOCTLH /* No ioctl's allowed. */
  636. #undef ultrix /* Turn off any ultrix features. */
  637. #endif /* CK_QNX32 */
  638. #endif /* BSD44 */
  639. #endif /* POSIX */
  640. /* System III, System V */
  641. #ifdef ATTSV
  642. #ifndef BSD44
  643. #ifndef POSIX
  644. #include <termio.h>
  645. #endif /* POSIX */
  646. #endif /* BSD44 */
  647. #ifdef TERMIOX
  648. /* Need this for termiox structure, RTS/CTS and DTR/CD flow control */
  649. #include <termiox.h>
  650. struct termiox rctsx;
  651. #else
  652. #ifdef STERMIOX
  653. #ifdef SCO_OSR504
  654. /* Sorry, this is truly disgusting but it's SCO's fault. */
  655. #ifndef _SVID3
  656. #define _CK_SVID3_X
  657. #define _SVID3
  658. #endif /* _SVID3 */
  659. #endif /* SCO_OSR504 */
  660. #include <sys/termiox.h>
  661. struct termiox rctsx;
  662. #ifdef CK_SVID3_X
  663. #undef _SVID3
  664. #undef CK_SVID3_X
  665. #endif /* CK_SVID3_X */
  666. #endif /* STERMIOX */
  667. #endif /* TERMIOX */
  668. #endif /* ATTSV */
  669. #ifdef COHERENT /* Use termio.h, not sgtty.h for Coherent */
  670. #include <termio.h>
  671. #endif /* COHERENT */
  672. #ifdef MINIX /* MINIX uses ioctl's */
  673. #define NOSYSIOCTLH /* but has no <sys/ioctl.h> */
  674. #endif /* MINIX */
  675. /* Others */
  676. #ifndef NOSYSIOCTLH /* Others use ioctl() */
  677. #ifdef SUN4S5
  678. /*
  679. This is to get rid of cpp warning messages that occur because all of
  680. these symbols are defined by both termios.h and ioctl.h on the SUN.
  681. */
  682. #undef ECHO
  683. #undef NL0
  684. #undef NL1
  685. #undef TAB0
  686. #undef TAB1
  687. #undef TAB2
  688. #undef XTABS
  689. #undef CR0
  690. #undef CR1
  691. #undef CR2
  692. #undef CR3
  693. #undef FF0
  694. #undef FF1
  695. #undef BS0
  696. #undef BS1
  697. #undef TOSTOP
  698. #undef FLUSHO
  699. #undef PENDIN
  700. #undef NOFLSH
  701. #endif /* SUN4S5 */
  702. #include <sys/ioctl.h>
  703. #endif /* NOSYSIOCTLH */
  704. /*
  705. We really, really, REALLY want FIONREAD, because it is the only way to find
  706. out not just *if* stuff is waiting to be read, but how much, which is
  707. critical to our sliding-window and streaming procedures, not to mention
  708. efficiency of CONNECT, etc.
  709. */
  710. #ifdef BELLV10
  711. #include <sys/filio.h> /* For FIONREAD */
  712. #ifdef FIONREAD
  713. #define MYREAD
  714. #endif /* MYREAD */
  715. #endif /* BELLV10 */
  716. #ifndef FIONREAD
  717. /* It wasn't found in ioctl.h or term*.h - try these places: */
  718. #ifdef UNIXWARE
  719. #include <sys/filio.h>
  720. #else
  721. #ifdef SOLARIS
  722. #include <sys/filio.h>
  723. #endif /* SOLARIS */
  724. #endif /* UNIXWARE */
  725. #endif /* FIONREAD */
  726. #ifdef XENIX /* Was M_UNIX but XENIX implies M_UNIX and applies to XENIX too */
  727. /*
  728. <sys/socket.h> included above via "ckcnet.h" defines FIONREAD as
  729. something. Due to this, in_chk() uses the FIONREAD instead of RDCHK
  730. and the hot keys during file transfer (X to cancel file etc) do not
  731. work because FIONREAD doesn't work even though it is defined.
  732. NOTE: This might also be true elsewhere.
  733. */
  734. #ifdef FIONREAD
  735. #undef FIONREAD
  736. #endif /* FIONREAD */
  737. #endif /* XENIX */
  738. #ifdef CK_SCOV5 /* Ditto for SCO OpenServer 5.0 */
  739. #ifndef SCO_OSR507 /* 299 */
  740. #ifdef FIONREAD
  741. #undef FIONREAD
  742. #endif /* FIONREAD */
  743. #endif /* SCO_OSR507 */
  744. #endif /* CK_SCOV5 */
  745. #ifdef SCO_OSR507 /* 299 */
  746. #ifdef RDCHK
  747. #undef RDCHK
  748. #endif /* RDCHK */
  749. #endif /* SCO_OSR507 */
  750. /* Whether to include <fcntl.h> */
  751. #ifndef is68k /* Only a few don't have this one. */
  752. #ifndef BSD41
  753. #ifndef FT21
  754. #ifndef FT18
  755. #ifndef COHERENT
  756. #include <fcntl.h>
  757. #endif /* COHERENT */
  758. #endif /* FT18 */
  759. #endif /* FT21 */
  760. #endif /* BSD41 */
  761. #endif /* not is68k */
  762. #ifdef COHERENT
  763. #ifdef _I386
  764. #include <fcntl.h>
  765. #else
  766. #include <sys/fcntl.h>
  767. #endif /* _I386 */
  768. #endif /* COHERENT */
  769. #ifdef ATT7300 /* Unix PC, internal modem dialer */
  770. #include <sys/phone.h>
  771. #endif /* ATT7300 */
  772. #ifdef HPUX /* HP-UX variations. */
  773. #define HPUXJOBCTL
  774. #include <sys/modem.h> /* HP-UX modem signals */
  775. #ifdef hp9000s500 /* Model 500 */
  776. #undef HPUXJOBCTL
  777. #endif /* hp9000s500 */
  778. #ifdef HPUXPRE65
  779. #undef HPUXJOBCTL
  780. typedef long mflag;
  781. #endif /* HPUXPRE65 */
  782. #ifdef HPUXJOBCTL
  783. #include <sys/bsdtty.h> /* HP-UX Berkeley tty support */
  784. #endif /* HPUXJOBCTL */
  785. #endif /* HPUX */
  786. /*
  787. Which time.h files to include... See ckcdeb.h for defaults.
  788. Note that 0, 1, 2, or all 3 of these can be included according to
  789. the symbol definitions.
  790. */
  791. #ifndef NOTIMEH
  792. #ifdef TIMEH
  793. #include <time.h>
  794. #endif /* TIMEH */
  795. #endif /* NOTIMEH */
  796. #ifndef NOSYSTIMEH
  797. #ifdef SYSTIMEH
  798. #include <sys/time.h>
  799. #endif /* SYSTIMEH */
  800. #endif /* NOSYSTIMEH */
  801. #ifndef NOSYSTIMEBH
  802. #ifdef SYSTIMEBH
  803. #include <sys/timeb.h>
  804. #endif /* SYSTIMEBH */
  805. #endif /* NOSYSTIMEBH */
  806. #ifndef NODCLTIMEVAL
  807. #ifdef DCLTIMEVAL
  808. /*
  809. In certain POSIX builds (like Unixware 7), <[sys/]time.h> refuses to
  810. define the structs we need to access the higher speeds, so we have to
  811. do it ourselves.
  812. */
  813. struct timeval {
  814. long tv_sec;
  815. long tv_usec;
  816. };
  817. struct timezone {
  818. int tz_minuteswest;
  819. int tz_dsttime;
  820. };
  821. #endif /* DCLTIMEVAL */
  822. #endif /* NODCLTIMEVAL */
  823. #ifdef __linux__
  824. /* THIS IS OBSOLETE since about Linux 0.92 */
  825. #ifdef OLINUXHISPEED
  826. #include <linux/serial.h>
  827. #endif /* OLINUXHISPEED */
  828. #ifdef __alpha__ /* Linux on DEC Alpha */
  829. #ifndef __GLIBC__ /* But not with glibc */
  830. #include <asm/termios.h>
  831. #endif /* __GLIBC__ */
  832. #endif /* __alpha__ */
  833. #endif /* __linux__ */
  834. #ifdef NOIEXTEN /* This is broken on some systems */
  835. #undef IEXTEN /* like Convex/OS 9.1 */
  836. #endif /* NOIEXTEN */
  837. #ifndef IEXTEN /* Turn off ^O/^V processing. */
  838. #define IEXTEN 0 /* Needed, at least, on BSDI. */
  839. #endif /* IEXTEN */
  840. /*
  841. Pick up definitions needed for select() if we don't have them already.
  842. Normally they come from <sys/types.h> but some systems get them from
  843. <sys/select.h>... Rather than hardwire all of them into the source, we
  844. include it if SELECT_H is defined in compile-time CFLAGS.
  845. */
  846. #ifndef SCO_OSR504
  847. #ifdef SELECT_H
  848. #include <sys/select.h>
  849. #endif /* SELECT_H */
  850. #endif /* SCO_OSR504 */
  851. #ifdef aegis
  852. #include "/sys/ins/base.ins.c"
  853. #include "/sys/ins/error.ins.c"
  854. #include "/sys/ins/ios.ins.c"
  855. #include "/sys/ins/sio.ins.c"
  856. #include "/sys/ins/pad.ins.c"
  857. #include "/sys/ins/time.ins.c"
  858. #include "/sys/ins/pfm.ins.c"
  859. #include "/sys/ins/pgm.ins.c"
  860. #include "/sys/ins/ec2.ins.c"
  861. #include "/sys/ins/type_uids.ins.c"
  862. #include <default_acl.h>
  863. #undef TIOCEXCL
  864. #undef FIONREAD
  865. #endif /* aegis */
  866. #ifdef sxaE50 /* PFU Compact A SX/A TISP V10/L50 */
  867. #undef FIONREAD
  868. #endif /* sxaE50 */
  869. /* The following #defines are catch-alls for those systems */
  870. /* that didn't have or couldn't find <file.h>... */
  871. #ifndef FREAD
  872. #define FREAD 0x01
  873. #endif /* FREAD */
  874. #ifndef FWRITE
  875. #define FWRITE 0x10
  876. #endif /* FWRITE */
  877. #ifndef O_RDONLY
  878. #define O_RDONLY 000
  879. #endif /* O_RDONLY */
  880. /* This is for ancient Unixes that don't have these tty symbols defined. */
  881. #ifndef PENDIN
  882. #define PENDIN ICANON
  883. #endif /* PENDIN */
  884. #ifndef FLUSHO
  885. #define FLUSHO ICANON
  886. #endif /* FLUSHO */
  887. #ifndef EXTPROC
  888. #define EXTPROC ICANON
  889. #endif /* EXTPROC */
  890. #ifdef SVORPOSIX
  891. /*
  892. Modem signals are also forbidden in the POSIX world. But some POSIX-based
  893. platforms let us at them anyway if we know where to look.
  894. */
  895. #ifndef NEEDMDMDEFS
  896. /* Doesn't work for Linux */
  897. #ifdef UNIXWARE7
  898. #define NEEDMDMDEFS
  899. #endif /* UNIXWARE7 */
  900. #endif /* NEEDMDMDEFS */
  901. #ifdef NEEDMDMDEFS
  902. #ifndef TIOCMGET
  903. #define TIOCMGET (('t'<<8)|29)
  904. #endif /* TIOCMGET */
  905. #ifndef TIOCM_DTR
  906. #define TIOCM_DTR 0x0002
  907. #endif /* TIOCM_DTR */
  908. #ifndef TIOCM_RTS
  909. #define TIOCM_RTS 0x0004
  910. #endif /* TIOCM_RTS */
  911. #ifndef TIOCM_CTS
  912. #define TIOCM_CTS 0x0020
  913. #endif /* TIOCM_CTS */
  914. #ifndef TIOCM_CAR
  915. #define TIOCM_CAR 0x0040
  916. #endif /* TIOCM_CAR */
  917. #ifndef TIOCM_RNG
  918. #define TIOCM_RNG 0x0080
  919. #endif /* TIOCM_RNG */
  920. #ifndef TIOCM_DSR
  921. #define TIOCM_DSR 0x0100
  922. #endif /* TIOCM_DSR */
  923. #endif /* NEEDMDMDEFS */
  924. #endif /* SVORPOSIX */
  925. /* Declarations */
  926. #ifdef OXOS
  927. #undef TCGETA
  928. #undef TCSETA
  929. #undef TCSETAW
  930. #undef TCSETAF
  931. #define TCGETA TCGETS
  932. #define TCSETA TCSETS
  933. #define TCSETAW TCSETSW
  934. #define TCSETAF TCSETSF
  935. #define termio termios
  936. #endif /* OXOS */
  937. #ifdef SVORPOSIX /* AT&T Sys V or POSIX */
  938. #ifdef UNIXWAREPOSIX /* UnixWare 7 POSIX build */
  939. /*
  940. In Unixware POSIX builds, <[sys/]time.h> refuses to define the
  941. structs we need to access the higher speeds, so we have to do it
  942. ourselves.
  943. */
  944. struct timeval {
  945. long tv_sec;
  946. long tv_usec;
  947. };
  948. struct timezone {
  949. int tz_minuteswest;
  950. int tz_dsttime;
  951. };
  952. #endif /* UNIXWAREPOSIX */
  953. #endif /* SVORPOSIX */
  954. #ifdef __GNUC__
  955. #ifdef XENIX
  956. /*
  957. Because Xenix <time.h> doesn't declare time() if we're using gcc.
  958. */
  959. time_t time();
  960. #endif /* XENIX */
  961. #endif /* __GNUC__ */
  962. /* Special stuff for V7 input buffer peeking */
  963. #ifdef V7
  964. int kmem[2] = { -1, -1};
  965. char *initrawq(), *qaddr[2]={0,0};
  966. #define CON 0
  967. #define TTY 1
  968. #endif /* V7 */
  969. /* dftty is the device name of the default device for file transfer */
  970. /* dfloc is 0 if dftty is the user's console terminal, 1 if an external line */
  971. #ifdef BEOS
  972. char * dftty = NULL;
  973. char * dfmdm = "none";
  974. int dfloc = 0; /* that goes in local mode by default */
  975. #else
  976. #ifndef DFTTY
  977. #ifdef PROVX1
  978. char *dftty = "/dev/com1.dout"; /* Only example so far of a system */
  979. char *dfmdm = "none";
  980. int dfloc = 1; /* that goes in local mode by default */
  981. #else
  982. char *dftty = CTTNAM; /* Remote by default, use normal */
  983. char *dfmdm = "none";
  984. int dfloc = 0; /* controlling terminal name. */
  985. #endif /* PROVX1 */
  986. #else
  987. char *dftty = DFTTY; /* Default location specified on */
  988. char *dfmdm = "none"; /* command line. */
  989. int dfloc = 1; /* controlling terminal name. */
  990. #endif /* DFTTY */
  991. #endif /* BEOS */
  992. #define CON_RES 0 /* Console state is "reset" */
  993. #define CON_CB 1 /* Console state is CBREAK */
  994. #define CON_BIN 2 /* Console state is binary */
  995. static int constate = CON_RES;
  996. #define CONI_RES 0 /* Console interrupts are "reset" */
  997. #define CONI_INT 1 /* Console intterupts are set */
  998. #define CONI_NOI 2 /* Console intterupts are disabled */
  999. static int conistate = CONI_RES;
  1000. #ifdef CK_SMALL
  1001. #define CONBUFSIZ 15
  1002. #else
  1003. #define CONBUFSIZ 255
  1004. #endif /* CK_SMALL */
  1005. static char conbuf[CONBUFSIZ]; /* Console readahead buffer */
  1006. static int conbufn = 0; /* Chars in readahead buffer */
  1007. static char *conbufp = conbuf; /* Next char in readahead buffer */
  1008. char cttnam[DEVNAMLEN+1] = { '\0', '\0' }; /* Determined at runtime */
  1009. #ifdef RTU
  1010. int rtu_bug = 0; /* set to 1 when returning from SIGTSTP */
  1011. #endif /* RTU */
  1012. int dfprty = DEFPAR; /* Default parity (0 = none) */
  1013. int ttprty = 0; /* The parity that is in use. */
  1014. static int ttpmsk = 0xff; /* Parity stripping mask. */
  1015. int ttmdm = 0; /* Modem in use. */
  1016. int ttcarr = CAR_AUT; /* Carrier handling mode. */
  1017. int dfflow = FLO_NONE; /* Default flow control is NONE */
  1018. int backgrd = 0; /* Assume in foreground (no '&' ) */
  1019. #ifdef F_SETFL
  1020. int iniflags = -1; /* fcntl flags for ttyfd */
  1021. #endif /* F_SETFL */
  1022. int fdflag = 0; /* Flag for redirected stdio */
  1023. int ttfdflg = 0; /* Open File descriptor was given */
  1024. int tvtflg = 0; /* Flag that ttvt has been called */
  1025. long ttspeed = -1L; /* For saving speed */
  1026. int ttflow = -9; /* For saving flow */
  1027. int ttld = -1; /* Line discipline */
  1028. #ifdef sony_news
  1029. static int km_con = -1; /* Kanji mode for console tty */
  1030. static int km_ext = -1; /* Kanji mode for external device */
  1031. #endif /* sony_news */
  1032. #ifdef PARSENSE
  1033. static int needpchk = 1; /* Need parity check */
  1034. #else
  1035. static int needpchk = 0;
  1036. #endif /* PARSENSE */
  1037. extern int stopbits; /* Stop bits */
  1038. #ifdef HWPARITY
  1039. /*
  1040. Unfortunately we must do this with global variables rather than through the
  1041. tt...() APIs to avoid changing the APIs and the many modules that use them.
  1042. If hwparity != 0, this indicates 8 data bits + parity, rather than 7 data
  1043. bits + parity or 8 data bits and no parity, and overrides the regular parity
  1044. variable, which is communicated to this module thru ttpkt(), and represented
  1045. locally by the ttprty variable.
  1046. */
  1047. extern int hwparity; /* Hardware parity */
  1048. #endif /* HWPARITY */
  1049. #ifdef TCPSOCKET
  1050. #ifdef TCP_NODELAY
  1051. static int nodelay_sav = -1;
  1052. #endif /* TCP_NODELAY */
  1053. #endif /* TCPSOCKET */
  1054. static int sigint_ign = 0; /* SIGINT is ignored */
  1055. /*
  1056. Having this module rely on external globals is bad, but fixing this
  1057. requires overhaul of the ck*tio.c modules for all the different operating
  1058. systems supported by C-Kermit. Left for a future release.
  1059. */
  1060. extern int ttnproto; /* Defined in ckcnet.c */
  1061. extern int ttnet; /* Defined in ckcnet.c */
  1062. extern int nopush, xfrcan, xfrchr, xfrnum; /* Defined in ckcmai.c */
  1063. extern int xsuspend, wasclosed;
  1064. extern int inserver, local;
  1065. int ckxech = 0; /* 0 if system normally echoes console characters, else 1 */
  1066. int ckmaxfiles = 0; /* Max number of open files */
  1067. #ifdef CK_ENCRYPTION /* Kerberos */
  1068. #include "ckuath.h"
  1069. extern int me_encrypt, u_encrypt;
  1070. #endif /* CK_ENCRYPTION */
  1071. /* Declarations of variables global within this module */
  1072. #ifdef TTLEBUF /* See ckcnet.h */
  1073. int ttpush = -1;
  1074. #define LEBUFSIZ 4096
  1075. static CHAR le_buf[LEBUFSIZ];
  1076. static int le_start = 0, le_end = 0, le_data = 0;
  1077. #endif /* TTLEBUF */
  1078. #define MSGBUF_SIZE 1024 /* For debugging */
  1079. static char msgbuf[MSGBUF_SIZE];
  1080. static int gotsigs = 0;
  1081. static time_t tcount = (time_t)0; /* Elapsed time counter */
  1082. static SIGTYP (*saval)() = NULL; /* For saving alarm() handler */
  1083. static SIGTYP (*savquit)() = NULL; /* and other signal handlers */
  1084. #ifdef SIGUSR1
  1085. static SIGTYP (*savusr1)() = NULL;
  1086. #endif /* SIGUSR1 */
  1087. #ifdef SIGUSR2
  1088. static SIGTYP (*savusr2)() = NULL;
  1089. #endif /* SIGUSR2 */
  1090. #ifdef SIGPIPE
  1091. static SIGTYP (*savpipe)() = NULL;
  1092. #endif /* SIGPIPE */
  1093. #ifdef SIGDANGER
  1094. static SIGTYP (*savdanger)() = NULL;
  1095. #endif /* SIGDANGER */
  1096. #ifndef NOJC
  1097. static SIGTYP (*jchdlr)() = NULL; /* For checking suspend handler */
  1098. #endif /* NOJC */
  1099. static int jcshell = -1; /* And flag for result */
  1100. /*
  1101. BREAKNULS is defined for systems that simulate sending a BREAK signal
  1102. by sending a bunch of NUL characters at low speed.
  1103. */
  1104. #ifdef PROVX1
  1105. #ifndef BREAKNULS
  1106. #define BREAKNULS
  1107. #endif /* BREAKNULS */
  1108. #endif /* PROVX1 */
  1109. #ifdef V7
  1110. #ifndef BREAKNULS
  1111. #define BREAKNULS
  1112. #endif /* BREAKNULS */
  1113. #endif /* V7 */
  1114. #ifdef BREAKNULS
  1115. static char /* A string of nulls */
  1116. *brnuls = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
  1117. #endif /* BREAKNULS */
  1118. #ifdef CK_POSIX_SIG /* Longjump buffers */
  1119. static sigjmp_buf sjbuf; /* POSIX signal handling */
  1120. #else
  1121. static jmp_buf sjbuf;
  1122. #endif /* CK_POSIX_SIG */
  1123. #ifdef V7
  1124. static jmp_buf jjbuf;
  1125. #endif /* V7 */
  1126. /* static */ /* (Not static any more) */
  1127. int ttyfd = -1; /* TTY file descriptor */
  1128. int ttpipe = 0; /* NETCMD: Use pipe instead of ttyfd */
  1129. int ttpty = 0; /* NETPTY: Use pty instead of ttfyd */
  1130. #ifdef NETPTY /* These are in ckupty.c */
  1131. extern PID_T pty_fork_pid;
  1132. extern int pty_master_fd, pty_slave_fd;
  1133. #endif /* NETPTY */
  1134. #ifdef NETCMD
  1135. #ifdef NETCONN
  1136. static int pipe0[2], pipe1[2]; /* Pipes for net i/o */
  1137. #endif /* NETCONN */
  1138. static PID_T ttpid = 0; /* Process ID for fork */
  1139. static int fdin, fdout; /* File descriptors for pipe */
  1140. static FILE * ttout = NULL; /* File pointer for output pipe */
  1141. #ifdef DCLFDOPEN
  1142. /* fdopen() needs declaring because it's not declared in <stdio.h> */
  1143. _PROTOTYP( FILE * fdopen, (int, char *) );
  1144. #endif /* DCLFDOPEN */
  1145. #endif /* NETCMD */
  1146. extern int pexitstat, quiet;
  1147. #ifdef Plan9
  1148. int ttyctlfd = -1; /* TTY control channel - What? UNIX doesn't have one? */
  1149. int consctlfd = -1; /* Console control channel */
  1150. int noisefd = -1; /* tone channel */
  1151. static int ttylastspeed = -1; /* So we can lie about the speed */
  1152. #endif /* Plan9 */
  1153. int telnetfd = 0; /* File descriptor is for telnet */
  1154. #ifdef NETCONN
  1155. int x25fd = 0; /* File descriptor is for X.25 */
  1156. #endif /* NETCONN */
  1157. char lockpid[16] = { '\0', '\0' }; /* PID stored in lockfile, as string */
  1158. static int lkf = 0, /* Line lock flag */
  1159. cgmf = 0, /* Flag that console modes saved */
  1160. xlocal = 0, /* Flag for tty local or remote */
  1161. curcarr = 0; /* Carrier mode: require/ignore. */
  1162. static int netconn = 0; /* 1 if network connection active */
  1163. static char escchr; /* Escape or attn character */
  1164. #ifdef CK_SCO32V4
  1165. #include <sys/time.h>
  1166. #endif /* CK_SCO32V4 */
  1167. #ifdef HAVE_TV
  1168. static struct timeval tv; /* For getting time, from sys/time.h */
  1169. #endif /* HAVE_TV */
  1170. #ifdef HAVE_TZ
  1171. static struct timezone tz;
  1172. #endif /* HAVE_TZ */
  1173. #ifdef OSF
  1174. static struct timeb ftp; /* And from sys/timeb.h */
  1175. #endif /* OSF */
  1176. #ifdef BSD29
  1177. static long xclock; /* For getting time from sys/time.h */
  1178. static struct timeb ftp; /* And from sys/timeb.h */
  1179. #endif /* BSD29 */
  1180. #ifdef BSD41
  1181. static long xclock; /* For getting time from sys/time.h */
  1182. static struct timeb ftp; /* And from sys/timeb.h */
  1183. #endif /* BSD41 */
  1184. #ifdef BELLV10
  1185. static long xclock; /* For getting time from sys/time.h */
  1186. static struct timeb ftp; /* And from sys/timeb.h */
  1187. #endif /* BELLV10 */
  1188. #ifdef FT21
  1189. static long xclock; /* For getting time from sys/time.h */
  1190. static struct timeb ftp; /* And from sys/timeb.h */
  1191. #endif /* FT21 */
  1192. #ifdef TOWER1
  1193. static long xclock; /* For getting time from sys/time.h */
  1194. static struct timeb ftp; /* And from sys/timeb.h */
  1195. #endif /* TOWER1 */
  1196. #ifdef COHERENT
  1197. static long xclock; /* For getting time from sys/time.h */
  1198. static struct timeb ftp; /* And from sys/timeb.h */
  1199. #endif /* COHERENT */
  1200. #ifdef V7
  1201. static long xclock;
  1202. #endif /* V7 */
  1203. /* sgtty/termio information... */
  1204. #ifdef BSD44ORPOSIX /* POSIX or BSD44 */
  1205. static struct termios
  1206. ttold, ttraw, tttvt, ttcur,
  1207. ccold, ccraw, cccbrk;
  1208. #else /* BSD, V7, etc */
  1209. #ifdef COHERENT /* Hack alert... */
  1210. #define ATTSV
  1211. #endif /* COHERENT */
  1212. #ifdef ATTSV
  1213. static struct termio ttold = {0}; /* Init'd for word alignment, */
  1214. static struct termio ttraw = {0}; /* which is important for some */
  1215. static struct termio tttvt = {0}; /* systems, like Zilog... */
  1216. static struct termio ttcur = {0};
  1217. static struct termio ccold = {0};
  1218. static struct termio ccraw = {0};
  1219. static struct termio cccbrk = {0};
  1220. #else
  1221. static struct sgttyb /* sgtty info... */
  1222. ttold, ttraw, tttvt, ttcur, /* for communication line */
  1223. ccold, ccraw, cccbrk; /* and for console */
  1224. #ifdef BELLV10
  1225. static struct ttydevb /* Device info... */
  1226. tdold, tdcur; /* for communication device */
  1227. #endif /* BELLV10 */
  1228. #ifdef TIOCGETC
  1229. static struct tchars tchold, tchnoi;
  1230. static int tcharf;
  1231. #endif /* TIOCGETC */
  1232. #ifdef TIOCGLTC
  1233. static struct ltchars ltchold, ltchnoi;
  1234. static int ltcharf;
  1235. #endif /* TIOCGLTC */
  1236. int lmodef = 0; /* Local modes */
  1237. int lmode = 0;
  1238. #endif /* ATTSV */
  1239. #endif /* BSD44ORPOSIX */
  1240. #ifdef COMMENT
  1241. /* It picks up the speeds but they don't work */
  1242. #ifdef UNIXWARE /* For higher serial speeds */
  1243. #ifdef UW7 /* in Unixware 7.0 */
  1244. #include <sys/asyc.h> /* This picks up 57600 and 115200 */
  1245. #endif /* UW7 */
  1246. #endif /* UNIXWARE */
  1247. #endif /* COMMENT */
  1248. #ifdef PROVX1
  1249. static struct sgttyb ttbuf;
  1250. #endif /* PROVX1 */
  1251. #ifdef ultrix
  1252. /* do we really need this? */
  1253. static struct sgttyb vanilla;
  1254. #endif /* ultrix */
  1255. #ifdef ATT7300
  1256. static int attmodem = 0; /* ATT7300 internal-modem status */
  1257. struct updata dialer = {0}; /* Condition dialer for data call */
  1258. #endif /* ATT7300 */
  1259. #ifndef NOUUCP
  1260. #define FLFNAML 128
  1261. #ifndef USETTYLOCK
  1262. #ifdef RTAIX
  1263. char lkflfn[FLFNAML] = { '\0', '\0' }; /* and possible link to it */
  1264. #endif /* RTAIX */
  1265. char lock2[FLFNAML] = { '\0', '\0' }; /* Name of second lockfile */
  1266. #endif /* USETTYLOCK */
  1267. #else
  1268. #define FLFNAML 7
  1269. #endif /* NOUUCP */
  1270. char flfnam[FLFNAML+1] = { '\0', '\0' }; /* UUCP lock file path name */
  1271. int haslock = 0; /* =1 if this kermit locked uucp */
  1272. #ifndef OXOS
  1273. #ifdef SVORPOSIX
  1274. static int conesc = 0; /* set to 1 if esc char (^\) typed */
  1275. #else
  1276. #ifdef V7
  1277. static int conesc = 0;
  1278. #else
  1279. #ifdef C70
  1280. static int conesc = 0;
  1281. #endif /* C70 */
  1282. #endif /* V7 */
  1283. #endif /* SVORPOSIX */
  1284. #endif /* OXOS */
  1285. /* Local copy of comm device name or network host */
  1286. static char ttnmsv[DEVNAMLEN+1] = { '\0', '\0' };
  1287. #ifdef USETTYLOCK
  1288. static char lockname[DEVNAMLEN+1]; /* Ditto, the part after "/dev/". */
  1289. #endif /* USETTYLOCK */
  1290. #ifdef aegis
  1291. static status_$t st; /* error status return value */
  1292. static short concrp = 0; /* true if console is CRP pad */
  1293. static uid_$t ttyuid; /* tty type uid */
  1294. static uid_$t conuid; /* stdout type uid */
  1295. /* APOLLO Aegis main()
  1296. * establish acl usage and cleanup handling
  1297. * this makes sure that CRP pads
  1298. * get restored to a usable mode
  1299. */
  1300. main(argc,argv) int argc; char **argv; {
  1301. status_$t status;
  1302. pfm_$cleanup_rec dirty;
  1303. PID_T pid = getpid();
  1304. /* acl usage according to invoking environment */
  1305. default_acl(USE_DEFENV);
  1306. /* establish a cleanup continuation */
  1307. status = pfm_$cleanup(dirty);
  1308. if (status.all != pfm_$cleanup_set) {
  1309. /* only handle faults for the original process */
  1310. if (pid == getpid() && status.all > pgm_$max_severity) {
  1311. /* blew up in main process */
  1312. status_$t quo;
  1313. pfm_$cleanup_rec clean;
  1314. /* restore the console in any case */
  1315. conres();
  1316. /* attempt a clean exit */
  1317. debug(F101, "cleanup fault status", "", status.all);
  1318. /* doexit(), then send status to continuation */
  1319. quo = pfm_$cleanup(clean);
  1320. if (quo.all == pfm_$cleanup_set)
  1321. doexit(pgm_$program_faulted,-1);
  1322. else if (quo.all > pgm_$max_severity)
  1323. pfm_$signal(quo); /* blew up in doexit() */
  1324. }
  1325. /* send to the original continuation */
  1326. pfm_$signal(status);
  1327. /*NOTREACHED*/
  1328. }
  1329. return(ckcmai(argc, argv));
  1330. }
  1331. #endif /* aegis */
  1332. /* ANSI-style prototypes for internal functions. */
  1333. /* Functions used outside this module are prototyped in ckcker.h. */
  1334. #ifdef apollo
  1335. _PROTOTYP( SIGTYP timerh, () );
  1336. _PROTOTYP( SIGTYP cctrap, () );
  1337. _PROTOTYP( SIGTYP esctrp, () );
  1338. _PROTOTYP( SIGTYP sig_ign, () );
  1339. #else
  1340. _PROTOTYP( SIGTYP timerh, (int) );
  1341. _PROTOTYP( SIGTYP cctrap, (int) );
  1342. _PROTOTYP( SIGTYP esctrp, (int) );
  1343. #endif /* apollo */
  1344. _PROTOTYP( int do_open, (char *) );
  1345. _PROTOTYP( static int in_chk, (int, int) );
  1346. _PROTOTYP( static int ttrpid, (char *) );
  1347. _PROTOTYP( static int ttchkpid, (char *) );
  1348. _PROTOTYP( static int ttlock, (char *) );
  1349. _PROTOTYP( static int ttunlck, (void) );
  1350. _PROTOTYP( static VOID sigchld_handler, (int) );
  1351. _PROTOTYP( int mygetbuf, (void) );
  1352. _PROTOTYP( int myfillbuf, (void) );
  1353. _PROTOTYP( VOID conbgt, (int) );
  1354. #ifdef ACUCNTRL
  1355. _PROTOTYP( VOID acucntrl, (char *, char *) );
  1356. #endif /* ACUCNTRL */
  1357. #ifdef BSD44ORPOSIX
  1358. _PROTOTYP( int carrctl, (struct termios *, int) );
  1359. #else
  1360. #ifdef ATTSV
  1361. _PROTOTYP( int carrctl, (struct termio *, int) );
  1362. #else
  1363. _PROTOTYP( int carrctl, (struct sgttyb *, int) );
  1364. #endif /* ATTSV */
  1365. #endif /* BSD44ORPOSIX */
  1366. #ifdef ATT7300
  1367. _PROTOTYP( int attdial, (char *, long, char *) );
  1368. _PROTOTYP( int offgetty, (char *) );
  1369. _PROTOTYP( int ongetty, (char *) );
  1370. #endif /* ATT7300 */
  1371. #ifdef BEOSORBEBOX
  1372. #ifdef SELECT
  1373. /* BeOS is not capable of using SELECT on anything but sockets */
  1374. #undef SELECT
  1375. #endif /* SELECT */
  1376. #include <kernel/OS.h>
  1377. /* #ifdef BE_DR_7 */
  1378. static double time_started = 0.0;
  1379. struct ALARM_STRUCT {
  1380. thread_id thread;
  1381. int time;
  1382. };
  1383. static thread_id alarm_thread = -1;
  1384. static struct ALARM_STRUCT alarm_struct;
  1385. _PROTOTYP( long do_alarm, (void *) );
  1386. _PROTOTYP( unsigned int alarm, (unsigned int) );
  1387. _PROTOTYP( void alarm_expired, (void) );
  1388. /* #endif */ /* BE_DR_7 */
  1389. #endif /* BEOSORBEBOX */
  1390. #ifndef xunchar
  1391. #define xunchar(ch) (((ch) - 32 ) & 0xFF ) /* Character to number */
  1392. #endif /* xunchar */
  1393. #ifdef CK_ANSIC
  1394. static char *
  1395. xxlast(char *s, char c)
  1396. #else
  1397. static char *
  1398. xxlast(s,c) char *s; char c;
  1399. #endif /* CK_ANSIC */
  1400. /* xxlast */ { /* Last occurrence of character c in string s. */
  1401. int i;
  1402. for (i = (int)strlen(s); i > 0; i--)
  1403. if (s[i-1] == c ) return(s + (i - 1));
  1404. return(NULL);
  1405. }
  1406. /* Timeout handler for communication line input functions */
  1407. /*ARGSUSED*/
  1408. SIGTYP
  1409. timerh(foo) int foo; {
  1410. ttimoff();
  1411. #ifdef BEOSORBEBOX
  1412. /* #ifdef BE_DR_7 */
  1413. alarm_expired();
  1414. /* #endif */ /* BE_DR_7 */
  1415. #endif /* BEOSORBEBOX */
  1416. #ifdef CK_POSIX_SIG
  1417. siglongjmp(sjbuf,1);
  1418. #else
  1419. longjmp(sjbuf,1);
  1420. #endif /* CK_POSIX_SIG */
  1421. }
  1422. /*ARGSUSED*/
  1423. SIGTYP
  1424. xtimerh(foo) int foo; { /* Like timerh() but does */
  1425. #ifdef BEOSORBEBOX /* not reset the timer itself */
  1426. /* #ifdef BE_DR_7 */
  1427. alarm_expired();
  1428. /* #endif */ /* BE_DR_7 */
  1429. #endif /* BEOSORBEBOX */
  1430. #ifdef CK_POSIX_SIG
  1431. siglongjmp(sjbuf,1);
  1432. #else
  1433. longjmp(sjbuf,1);
  1434. #endif /* CK_POSIX_SIG */
  1435. }
  1436. /* Control-C trap for communication line input functions */
  1437. int cc_int; /* Flag */
  1438. SIGTYP (* occt)(); /* For saving old SIGINT handler */
  1439. /*ARGSUSED*/
  1440. SIGTYP
  1441. cctrap(foo) int foo; { /* Needs arg for ANSI C */
  1442. cc_int = 1; /* signal() prototype. */
  1443. return;
  1444. }
  1445. /* S Y S I N I T -- System-dependent program initialization. */
  1446. /*
  1447. * ttgwsiz() returns:
  1448. * 1 tt_rows and tt_cols are known, both altered, both > 0
  1449. * 0 tt_rows and/or tt_cols are known, both altered, one or both <= 0
  1450. * -1 tt_rows and tt_cols are unknown and unaltered
  1451. */
  1452. extern int tt_rows, tt_cols;
  1453. static int
  1454. xttgwsiz() {
  1455. char *p;
  1456. int rows = 0, cols = 0;
  1457. p = getenv("LINES");
  1458. debug(F110,"xttgwsiz LINES",p,0);
  1459. if (p) {
  1460. rows = atol(p);
  1461. if (rows > 0) {
  1462. p = getenv("COLUMNS");
  1463. debug(F110,"xttgwsiz COLUMNS",p,0);
  1464. if (p) {
  1465. cols = atol(p);
  1466. if (cols > 0) {
  1467. tt_rows = rows;
  1468. tt_cols = cols;
  1469. return(1);
  1470. }
  1471. return(0);
  1472. }
  1473. }
  1474. }
  1475. return(-1);
  1476. }
  1477. #ifdef TTLEBUF
  1478. VOID
  1479. le_init() { /* LocalEchoInit() */
  1480. int i;
  1481. for (i = 0; i < LEBUFSIZ; i++)
  1482. le_buf[i] = '\0';
  1483. le_start = 0;
  1484. le_end = 0;
  1485. le_data = 0;
  1486. }
  1487. VOID
  1488. le_clean() { /* LocalEchoCleanup() */
  1489. le_init();
  1490. return;
  1491. }
  1492. int
  1493. le_inbuf() {
  1494. int rc = 0;
  1495. if (le_start != le_end) {
  1496. rc = (le_end -
  1497. le_start +
  1498. LEBUFSIZ) % LEBUFSIZ;
  1499. }
  1500. debug(F111,"le_inbuf","chars waiting",rc);
  1501. return(rc);
  1502. }
  1503. int
  1504. #ifdef CK_ANSIC
  1505. le_putchar(CHAR ch)
  1506. #else
  1507. le_putchar(ch) CHAR ch;
  1508. #endif /* CK_ANSIC */
  1509. /* le_putchar */ {
  1510. #ifdef COMMENT
  1511. /* In UNIX we do not have another thread taking chars out of the buffer */
  1512. while ((le_start - le_end == 1) ||
  1513. (le_start == 0 && le_end == LEBUFSIZ - 1)) {
  1514. /* Buffer is full */
  1515. debug(F111,"le_putchar","Buffer is Full",ch);
  1516. ReleaseLocalEchoMutex() ;
  1517. msleep(250);
  1518. RequestLocalEchoMutex( SEM_INDEFINITE_WAIT ) ;
  1519. }
  1520. #else
  1521. if ((le_start - le_end + LEBUFSIZ)%LEBUFSIZ == 1) {
  1522. debug(F110,"le_putchar","buffer is full",0);
  1523. return(-1);
  1524. }
  1525. #endif /* COMMENT */
  1526. le_buf[le_end++] = ch;
  1527. if (le_end == LEBUFSIZ)
  1528. le_end = 0;
  1529. le_data = 1;
  1530. return(0);
  1531. }
  1532. int
  1533. #ifdef CK_ANSIC
  1534. le_puts(CHAR * s, int n)
  1535. #else
  1536. le_puts(s,n) CHAR * s; int n;
  1537. #endif /* CK_ANSIC */
  1538. /* le_puts */ {
  1539. int rc = 0;
  1540. int i = 0;
  1541. CHAR * p = (CHAR *)"le_puts";
  1542. ckhexdump(p,s,n);
  1543. for (i = 0; i < n; i++)
  1544. rc = le_putchar((char)s[i]);
  1545. debug(F101,"le_puts","",rc);
  1546. return(rc);
  1547. }
  1548. int
  1549. #ifdef CK_ANSIC
  1550. le_putstr(CHAR * s)
  1551. #else
  1552. le_putstr(s) CHAR * s;
  1553. #endif /* CK_ANSIC */
  1554. /* le_puts */ {
  1555. CHAR * p;
  1556. int rc = 0;
  1557. p = (CHAR *)"le_putstr";
  1558. ckhexdump(p,s,(int)strlen((char *)s));
  1559. for (p = s; *p && !rc; p++)
  1560. rc = le_putchar(*p);
  1561. return(rc);
  1562. }
  1563. int
  1564. #ifdef CK_ANSIC
  1565. le_getchar(CHAR * pch)
  1566. #else /* CK_ANSIC */
  1567. le_getchar(pch) CHAR * pch;
  1568. #endif /* CK_ANSIC */
  1569. /* le_gatchar */ {
  1570. int rc = 0;
  1571. if (le_start != le_end) {
  1572. *pch = le_buf[le_start];
  1573. le_buf[le_start] = 0;
  1574. le_start++;
  1575. if (le_start == LEBUFSIZ)
  1576. le_start = 0;
  1577. if (le_start == le_end) {
  1578. le_data = 0;
  1579. }
  1580. rc++;
  1581. } else {
  1582. *pch = 0;
  1583. }
  1584. return(rc);
  1585. }
  1586. #endif /* TTLEBUF */
  1587. #ifdef COMMENT
  1588. /*
  1589. Some systems like OSF/1 use TIOCGSIZE instead of TIOCGWINSZ.
  1590. But as far as I know, whenever TIOCGSIZE is defined, it is
  1591. equated to TIOCGWINSZ. For cases where this is not done, try this:
  1592. */
  1593. #ifndef TIOCGWINSZ
  1594. #ifdef TIOCGSIZE
  1595. #define TIOCGWINSZ TIOCGSIZE
  1596. #endif /* TIOCGSIZE */
  1597. #endif /* TIOCGWINSZ */
  1598. #endif /* COMMENT */
  1599. static int tt_xpixel = 0, tt_ypixel = 0;
  1600. int
  1601. ttgwsiz() {
  1602. int x = 0;
  1603. #ifndef NONAWS
  1604. #ifdef QNX
  1605. /*
  1606. NOTE: TIOCGWSIZ works here too, but only in the 32-bit version.
  1607. This code works for both the 16- and 32-bit versions.
  1608. */
  1609. extern int dev_size(int, int, int, int *, int *);
  1610. int r, c;
  1611. if (dev_size(0, -1, -1, &r, &c) == 0) {
  1612. debug(F101,"ttgwsiz QNX r","",r);
  1613. debug(F101,"ttgwsiz QNX c","",c);
  1614. tt_rows = r;
  1615. tt_cols = c;
  1616. return ((r > 0 && c > 0) ? 1 : 0);
  1617. } else return(xttgwsiz());
  1618. #else /* QNX */
  1619. #ifdef TIOCGWINSZ
  1620. /* Note, this was M_UNIX, changed to XENIX to allow cross compilation... */
  1621. #ifdef XENIX /* SCO UNIX 3.2v4.0 */
  1622. #include <sys/stream.h> /* typedef mblk_t needed by ptem.h */
  1623. #include <sys/ptem.h> /* for ttgwsiz() */
  1624. #endif /* XENIX */
  1625. #ifdef I386IX /* Ditto for Interactive */
  1626. #include <sys/stream.h>
  1627. #include <sys/ptem.h>
  1628. #endif /* I386IX */
  1629. /* Note, the above might be needed for some other older SVR3 Intel makes... */
  1630. struct winsize w;
  1631. tt_xpixel = 0;
  1632. tt_ypixel = 0;
  1633. #ifdef IKSD
  1634. if (inserver)
  1635. return(xttgwsiz());
  1636. #endif /* IKSD */
  1637. x = ioctl(0, (int)TIOCGWINSZ, (char *)&w);
  1638. debug(F101,"ttgwsiz TIOCGWINSZ","",x);
  1639. if (x < 0) {
  1640. return(xttgwsiz());
  1641. } else if (w.ws_row > 0 && w.ws_col > 0) {
  1642. tt_rows = w.ws_row;
  1643. tt_cols = w.ws_col;
  1644. tt_xpixel = w.ws_xpixel;
  1645. tt_ypixel = w.ws_ypixel;
  1646. debug(F101,"ttgwsiz tt_rows","",tt_rows);
  1647. debug(F101,"ttgwsiz tt_cols","",tt_cols);
  1648. return(1);
  1649. } else {
  1650. debug(F100,"ttgwsiz TIOCGWINSZ 00","",0);
  1651. return(xttgwsiz());
  1652. }
  1653. #else
  1654. return(xttgwsiz());
  1655. #endif /* TIOCGWINSZ */
  1656. #endif /* QNX */
  1657. #endif /* NONAWS */
  1658. }
  1659. #ifdef RLOGCODE
  1660. _PROTOTYP( int rlog_naws, (void) );
  1661. #endif /* RLOGCODE */
  1662. #ifndef NOSIGWINCH
  1663. #ifdef SIGWINCH
  1664. SIGTYP
  1665. winchh(foo) int foo; { /* SIGWINCH handler */
  1666. int x = 0;
  1667. #ifdef CK_TTYFD
  1668. #ifndef VMS
  1669. extern int ttyfd;
  1670. #endif /* VMS */
  1671. #endif /* CK_TTYFD */
  1672. extern int tt_rows, tt_cols, cmd_rows, cmd_cols;
  1673. #ifdef DEBUG
  1674. if (deblog) {
  1675. debug(F100,"***************","",0);
  1676. debug(F100,"SIGWINCH caught","",0);
  1677. debug(F100,"***************","",0);
  1678. #ifdef NETPTY
  1679. debug(F101,"SIGWINCH pty_fork_pid","",pty_fork_pid);
  1680. #endif /* NETPTY */
  1681. }
  1682. #endif /* DEUB */
  1683. signal(SIGWINCH,winchh); /* Re-arm the signal */
  1684. x = ttgwsiz(); /* Get new window size */
  1685. cmd_rows = tt_rows; /* Adjust command screen too */
  1686. cmd_cols = tt_cols;
  1687. #ifdef CK_TTYFD
  1688. if /* If we don't have a connection */
  1689. #ifdef VMS /* we're done. */
  1690. (vmsttyfd() == -1)
  1691. #else
  1692. (ttyfd == -1)
  1693. #endif /* VMS */
  1694. #else
  1695. (!local)
  1696. #endif /* CK_TTYFD */
  1697. return;
  1698. #ifdef NETPTY
  1699. if (pty_fork_pid > -1) { /* "set host" to a PTY? */
  1700. int x;
  1701. #ifdef TIOCSWINSZ
  1702. struct winsize w; /* Resize the PTY */
  1703. errno = 0;
  1704. w.ws_col = tt_cols;
  1705. w.ws_row = tt_rows;
  1706. w.ws_xpixel = tt_xpixel;
  1707. w.ws_ypixel = tt_ypixel;
  1708. x = ioctl(ttyfd,TIOCSWINSZ,&w);
  1709. debug(F101,"winchh TIOCSWINSZ","",x);
  1710. debug(F101,"winchh TIOCSWINSZ errno","",errno);
  1711. #endif /* TIOCSWINSZ */
  1712. errno = 0;
  1713. x = kill(pty_fork_pid,SIGWINCH);
  1714. debug(F101,"winchh kill","",x);
  1715. debug(F101,"winchh kill errno","",errno);
  1716. }
  1717. #endif /* NETPTY */
  1718. /*
  1719. This should be OK. It might seem that sending this from
  1720. interrupt level could interfere with another TELNET IAC string
  1721. that was in the process of being sent. But we always send
  1722. TELNET strings with a single write(), which should prevent mixups.
  1723. blah_snaws() should protect themselves from being called on the
  1724. wrong kind of connection.
  1725. */
  1726. #ifdef TCPSOCKET
  1727. #ifndef NOTTGWSIZ
  1728. if (x > 0 && tt_rows > 0 && tt_cols > 0) {
  1729. tn_snaws();
  1730. #ifdef RLOGCODE
  1731. rlog_naws();
  1732. #endif /* RLOGCODE */
  1733. }
  1734. #endif /* NOTTGWSIZ */
  1735. #endif /* TCPSOCKET */
  1736. SIGRETURN;
  1737. }
  1738. #endif /* SIGWINCH */
  1739. #endif /* NOSIGWINCH */
  1740. SIGTYP
  1741. sighup(foo) int foo; { /* SIGHUP handler */
  1742. backgrd = 1;
  1743. debug(F100,"***************","",0);
  1744. debug(F100,"SIGHUP received","",0);
  1745. debug(F100,"***************","",0);
  1746. doexit(BAD_EXIT,-1);
  1747. /*NOTREACHED*/
  1748. SIGRETURN; /* Shut picky compilers up... */
  1749. }
  1750. #ifdef CK_SCO32V4
  1751. /* Exists but there is no prototype in the header files */
  1752. _PROTOTYP( char * ttyname, (int) );
  1753. #else
  1754. #ifdef SV68R3V6
  1755. _PROTOTYP( char * ttyname, (int) );
  1756. #else
  1757. #ifdef ultrix
  1758. _PROTOTYP( char * ttyname, (int) );
  1759. #else
  1760. #ifdef HPUX6
  1761. _PROTOTYP( char * ttyname, (int) );
  1762. #else
  1763. #ifdef HPUX5
  1764. _PROTOTYP( char * ttyname, (int) );
  1765. #else
  1766. #ifdef PS2AIX10
  1767. _PROTOTYP( char * ttyname, (int) );
  1768. #else
  1769. #ifdef BSD42
  1770. _PROTOTYP( char * ttyname, (int) );
  1771. #endif /* BSD42 */
  1772. #endif /* PS2AIX10 */
  1773. #endif /* HPUX5 */
  1774. #endif /* HPUX6 */
  1775. #endif /* ultrix */
  1776. #endif /* SV68R3V6 */
  1777. #endif /* CK_SCO32V4 */
  1778. #ifndef SIGUSR1 /* User-defined signals */
  1779. #define SIGUSR1 30
  1780. #endif /* SIGUSR1 */
  1781. #ifndef SIGUSR2
  1782. #define SIGUSR2 31
  1783. #endif /* SIGUSR2 */
  1784. /*
  1785. ignorsigs() sets certain signals to SIG_IGN. But when a signal is
  1786. ignored, it remains ignored across exec(), so we have to restore these
  1787. signals before exec(), which is the purpose of restorsigs().
  1788. */
  1789. static VOID
  1790. ignorsigs() { /* Ignore these signals */
  1791. savquit = signal(SIGQUIT,SIG_IGN); /* Ignore Quit signal */
  1792. #ifdef SIGDANGER /* Ignore danger signals */
  1793. /*
  1794. This signal is sent when the system is low on swap space. Processes
  1795. that don't handle it are candidates for termination. If swap space doesn't
  1796. clear out enough, we still might be terminated via kill() -- nothing we can
  1797. do about that! Conceivably, this could be improved by installing a real
  1798. signal handler that warns the user, but that would be pretty complicated,
  1799. since we are not always in control of the screen -- e.g. during remote-mode
  1800. file transfer.
  1801. */
  1802. savdanger = signal(SIGDANGER,SIG_IGN); /* e.g. in AIX */
  1803. #endif /* SIGDANGER */
  1804. #ifdef SIGPIPE
  1805. /*
  1806. This one comes when a TCP/IP connection is broken by the remote.
  1807. We prefer to catch this situation by examining error codes from write().
  1808. */
  1809. savpipe = signal(SIGPIPE,SIG_IGN);
  1810. #endif /* SIGPIPE */
  1811. savusr1 = signal(SIGUSR1,SIG_IGN); /* Ignore user-defined signals */
  1812. savusr2 = signal(SIGUSR2,SIG_IGN);
  1813. }
  1814. VOID
  1815. restorsigs() { /* Restore these signals */
  1816. (VOID) signal(SIGQUIT,savquit); /* (used in ckufio.c) */
  1817. #ifdef SIGDANGER
  1818. (VOID) signal(SIGDANGER,savdanger);
  1819. #endif /* SIGDANGER */
  1820. #ifdef SIGPIPE
  1821. (VOID) signal(SIGPIPE,savpipe);
  1822. #endif /* SIGPIPE */
  1823. (VOID) signal(SIGUSR1,savusr1);
  1824. (VOID) signal(SIGUSR2,savusr2);
  1825. }
  1826. int
  1827. sysinit() {
  1828. int x;
  1829. char * s;
  1830. #ifdef CK_UTSNAME
  1831. struct utsname name;
  1832. #endif /* CK_UTSNAME */
  1833. extern char startupdir[];
  1834. /*
  1835. BEFORE ANYTHING ELSE: Initialize the setuid package.
  1836. Change to the user's real user and group ID.
  1837. If this can't be done, don't run at all.
  1838. */
  1839. x = priv_ini();
  1840. #ifdef SUIDDEBUG
  1841. fprintf(stderr,"PRIV_INI=%d\n",x);
  1842. #endif /* SUIDDEBUG */
  1843. if (x) {
  1844. if (x & 1) fprintf(stderr,"Fatal: setuid failure.\n");
  1845. if (x & 2) fprintf(stderr,"Fatal: setgid failure.\n");
  1846. if (x & 4) fprintf(stderr,"Fatal: C-Kermit setuid to root!\n");
  1847. exit(1);
  1848. }
  1849. signal(SIGINT,SIG_IGN); /* Ignore interrupts at first */
  1850. signal(SIGFPE,SIG_IGN); /* Ignore floating-point exceptions */
  1851. signal(SIGHUP,sighup); /* Catch SIGHUP */
  1852. #ifndef NOSIGWINCH
  1853. #ifdef SIGWINCH
  1854. signal(SIGWINCH,winchh); /* Catch window-size change */
  1855. #endif /* SIGWINCH */
  1856. #endif /* NOSIGWINCH */
  1857. #ifdef SIGXFSZ
  1858. signal(SIGXFSZ,SIG_IGN); /* Ignore writing past file limit */
  1859. #endif /* SIGXFSZ */
  1860. #ifndef NOJC
  1861. /*
  1862. Get the initial job control state.
  1863. If it is SIG_IGN, that means the shell does not support job control,
  1864. and so we'd better not suspend ourselves.
  1865. */
  1866. #ifdef SIGTSTP
  1867. jchdlr = signal(SIGTSTP,SIG_IGN);
  1868. if (jchdlr == SIG_IGN) {
  1869. jcshell = 0;
  1870. debug(F100,"sysinit jchdlr: SIG_IGN","",0);
  1871. } else if (jchdlr == SIG_DFL) {
  1872. debug(F100,"sysinit jchdlr: SIG_DFL","",0);
  1873. jcshell = 1;
  1874. } else {
  1875. debug(F100,"sysinit jchdlr: other","",0);
  1876. jcshell = 3;
  1877. }
  1878. (VOID) signal(SIGTSTP,jchdlr); /* Put it back... */
  1879. #endif /* SIGTSTP */
  1880. #endif /* NOJC */
  1881. conbgt(0); /* See if we're in the background */
  1882. congm(); /* Get console modes */
  1883. (VOID) signal(SIGALRM,SIG_IGN); /* Ignore alarms */
  1884. ignorsigs(); /* Ignore some other signals */
  1885. #ifdef F_SETFL
  1886. iniflags = fcntl(0,F_GETFL,0); /* Get stdin flags */
  1887. #endif /* F_SETFL */
  1888. #ifdef ultrix
  1889. gtty(0,&vanilla); /* Get sgtty info */
  1890. #else
  1891. #ifdef AUX
  1892. set42sig(); /* Don't ask! (hakanson@cs.orst.edu) */
  1893. #endif /* AUX */
  1894. #endif /* ultrix */
  1895. /*
  1896. Warning: on some UNIX systems (SVR4?), ttyname() reportedly opens /dev but
  1897. never closes it. If it is called often enough, we run out of file
  1898. descriptors and subsequent open()'s of other devices or files can fail.
  1899. */
  1900. s = NULL;
  1901. #ifndef MINIX
  1902. if (isatty(0)) /* Name of controlling terminal */
  1903. s = ttyname(0);
  1904. else if (isatty(1))
  1905. s = ttyname(1);
  1906. else if (isatty(2))
  1907. s = ttyname(2);
  1908. debug(F110,"sysinit ttyname(0)",s,0);
  1909. #endif /* MINIX */
  1910. #ifdef BEOS
  1911. if (!dftty)
  1912. makestr(&dftty,s);
  1913. #endif /* BEOS */
  1914. if (s)
  1915. ckstrncpy((char *)cttnam,s,DEVNAMLEN+1);
  1916. #ifdef SVORPOSIX
  1917. #ifndef ANDROID
  1918. if (!cttnam[0])
  1919. ctermid(cttnam);
  1920. #endif /* ANDROID */
  1921. #endif /* SVORPOSIX */
  1922. if (!cttnam[0])
  1923. ckstrncpy((char *)cttnam,dftty,DEVNAMLEN+1);
  1924. debug(F110,"sysinit CTTNAM",CTTNAM,0);
  1925. debug(F110,"sysinit cttnam",cttnam,0);
  1926. ttgwsiz(); /* Get window (screen) dimensions. */
  1927. #ifndef NOSYSCONF
  1928. #ifdef _SC_OPEN_MAX
  1929. ckmaxfiles = sysconf(_SC_OPEN_MAX);
  1930. #endif /* _SC_OPEN_MAX */
  1931. #endif /* NOSYSCONF */
  1932. #ifdef Plan9
  1933. if (!backgrd) {
  1934. consctlfd = open("/dev/consctl", O_WRONLY);
  1935. /*noisefd = open("/dev/noise", O_WRONLY)*/
  1936. }
  1937. ckxech = 1;
  1938. #endif /* Plan9 */
  1939. #ifdef CK_UTSNAME
  1940. if (uname(&name) > -1) {
  1941. ckstrncpy(unm_mch,name.machine,CK_SYSNMLN);
  1942. ckstrncpy(unm_nam,name.sysname,CK_SYSNMLN);
  1943. ckstrncpy(unm_rel,name.release,CK_SYSNMLN);
  1944. ckstrncpy(unm_ver,name.version,CK_SYSNMLN);
  1945. #ifdef DEBUG
  1946. if (deblog) {
  1947. debug(F110,"sysinit uname machine",unm_mch,0);
  1948. debug(F110,"sysinit uname sysname",unm_nam,0);
  1949. debug(F110,"sysinit uname release",unm_rel,0);
  1950. debug(F110,"sysinit uname version",unm_ver,0);
  1951. }
  1952. #endif /* DEBUG */
  1953. #ifdef HPUX9PLUS
  1954. if (name.machine[5] == '8')
  1955. hpis800 = 1;
  1956. else
  1957. hpis800 = 0;
  1958. debug(F101,"sysinit hpis800","",hpis800);
  1959. #endif /* HPUX9PLUS */
  1960. #ifdef TRU64
  1961. getsysinfo(GSI_PLATFORM_NAME, unm_mod, CK_SYSNMLN, 0, 0);
  1962. debug(F110,"sysinit getsysinfo model",unm_mod,0);
  1963. #endif /* TRU64 */
  1964. #ifdef SOLARIS25
  1965. sysinfo(SI_PLATFORM, unm_mod, CK_SYSNMLN);
  1966. debug(F110,"sysinit sysinfo model",unm_mod,0);
  1967. #endif /* SOLARIS25 */
  1968. }
  1969. #endif /* CK_UTSNAME */
  1970. #ifdef CK_ENVIRONMENT
  1971. {
  1972. #ifdef TNCODE
  1973. extern char tn_env_acct[], tn_env_disp[], tn_env_job[],
  1974. tn_env_prnt[], tn_env_sys[];
  1975. #endif /* TNCODE */
  1976. extern char uidbuf[];
  1977. extern char * whoami();
  1978. char *p;
  1979. #ifdef CKSENDUID
  1980. uidbuf[0] = '\0';
  1981. #ifdef IKSD
  1982. if (!inserver) {
  1983. #endif /* IKSD */
  1984. p = getenv("USER");
  1985. debug(F110,"sysinit uidbuf from USER",uidbuf,0);
  1986. if (!p) p = "";
  1987. if (!*p) {
  1988. p = getenv("LOGNAME");
  1989. debug(F110,"sysinit uidbuf from LOGNAME",uidbuf,0);
  1990. }
  1991. if (!p) p = "";
  1992. if (!*p) {
  1993. p = whoami();
  1994. debug(F110,"sysinit uidbuf from whoami()",uidbuf,0);
  1995. }
  1996. if (!p) p = "";
  1997. ckstrncpy(uidbuf, *p ? p : "UNKNOWN", UIDBUFLEN);
  1998. #ifdef IKSD
  1999. }
  2000. #endif /* IKSD */
  2001. debug(F110,"sysinit final uidbuf",uidbuf,0);
  2002. #endif /* CKSENDUID */
  2003. #ifdef TNCODE
  2004. if ((p = getenv("JOB"))) ckstrncpy(tn_env_job,p,63);
  2005. if ((p = getenv("ACCT"))) ckstrncpy(tn_env_acct,p,63);
  2006. if ((p = getenv("PRINTER"))) ckstrncpy(tn_env_prnt,p,63);
  2007. if ((p = getenv("DISPLAY"))) ckstrncpy(tn_env_disp,p,63);
  2008. #ifdef aegis
  2009. ckstrncpy(tn_env_sys,"Aegis",64);
  2010. #else
  2011. #ifdef Plan9
  2012. ckstrncpy(tn_env_sys,"Plan9",64);
  2013. #else
  2014. ckstrncpy(tn_env_sys,"UNIX",64);
  2015. #endif /* Plan9 */
  2016. #endif /* aegis */
  2017. #endif /* TNCODE */
  2018. }
  2019. #endif /* CK_ENVIRONMENT */
  2020. #ifdef CK_SNDLOC
  2021. {
  2022. extern char * tn_loc;
  2023. char *p;
  2024. if (p = getenv("LOCATION"))
  2025. if (tn_loc = (char *)malloc((int)strlen(p)+1))
  2026. strcpy(tn_loc,p); /* safe */
  2027. }
  2028. #endif /* CK_SNDLOC */
  2029. ckstrncpy(startupdir, zgtdir(), CKMAXPATH);
  2030. startupdir[CKMAXPATH] = '\0';
  2031. x = strlen(startupdir);
  2032. if (x <= 0) {
  2033. startupdir[0] = '/';
  2034. startupdir[1] = '\0';
  2035. } else if (startupdir[x-1] != '/') {
  2036. startupdir[x] = '/';
  2037. startupdir[x+1] = '\0';
  2038. }
  2039. debug(F110,"sysinit startupdir",startupdir,0);
  2040. #ifdef TTLEBUF
  2041. le_init();
  2042. #endif /* TTLEBUF */
  2043. #ifdef BSD44ORPOSIX
  2044. /* This should catch the ncurses platforms */
  2045. /* Some platforms don't have putenv(), like NeXTSTEP */
  2046. putenv("NCURSES_NO_SETBUF=1");
  2047. #endif /* BSD44ORPOSIX */
  2048. return(0);
  2049. }
  2050. /* S Y S C L E A N U P -- System-dependent program cleanup. */
  2051. int
  2052. syscleanup() {
  2053. #ifdef F_SETFL
  2054. if (iniflags > -1)
  2055. fcntl(0,F_SETFL,iniflags); /* Restore stdin flags */
  2056. #endif /* F_SETFL */
  2057. #ifdef ultrix
  2058. stty(0,&vanilla); /* Get sgtty info */
  2059. #endif /* ultrix */
  2060. #ifdef NETCMD
  2061. if (ttpid) kill(ttpid,9);
  2062. #endif /* NETCMD */
  2063. return(0);
  2064. }
  2065. /* T T O P E N -- Open a tty for exclusive access. */
  2066. /*
  2067. Call with:
  2068. ttname: character string - device name or network host name.
  2069. lcl:
  2070. If called with lcl < 0, sets value of lcl as follows:
  2071. 0: the terminal named by ttname is the job's controlling terminal.
  2072. 1: the terminal named by ttname is not the job's controlling terminal.
  2073. But watch out: if a line is already open, or if requested line can't
  2074. be opened, then lcl remains (and is returned as) -1.
  2075. modem:
  2076. Less than zero: ttname is a network host name.
  2077. Zero or greater: ttname is a terminal device name.
  2078. Zero means a local connection (don't use modem signals).
  2079. Positive means use modem signals.
  2080. timo:
  2081. 0 = no timer.
  2082. nonzero = number of seconds to wait for open() to return before timing out.
  2083. Returns:
  2084. 0 on success
  2085. -5 if device is in use
  2086. -4 if access to device is denied
  2087. -3 if access to lock directory denied
  2088. -2 upon timeout waiting for device to open
  2089. -1 on other error
  2090. */
  2091. static int ttotmo = 0; /* Timeout flag */
  2092. /* Flag kept here to avoid being clobbered by longjmp. */
  2093. int
  2094. ttopen(ttname,lcl,modem,timo) char *ttname; int *lcl, modem, timo; {
  2095. #ifdef BSD44
  2096. #define ctermid(x) strcpy(x,"")
  2097. #else
  2098. #ifdef SVORPOSIX
  2099. #ifndef CIE
  2100. #ifndef ANDROID
  2101. extern char *ctermid(); /* Wish they all had this! */
  2102. #endif /* ANDROID */
  2103. #else /* CIE Regulus */
  2104. #define ctermid(x) strcpy(x,"")
  2105. #endif /* CIE */
  2106. #endif /* SVORPOSIX */
  2107. #endif /* BSD44 */
  2108. #ifdef ultrix
  2109. int temp = 0;
  2110. #endif /* ultrix */
  2111. #ifndef OPENFIRST
  2112. char fullname[DEVNAMLEN+1];
  2113. #endif /* OPENFIRST */
  2114. char * fnam; /* Full name after expansion */
  2115. int y;
  2116. #ifndef pdp11
  2117. #define NAMEFD /* Feature to allow name to be an open file descriptor */
  2118. #endif /* pdp11 */
  2119. #ifdef NAMEFD
  2120. char *p;
  2121. debug(F101,"ttopen telnetfd","",telnetfd);
  2122. #endif /* NAMEFD */
  2123. debug(F110,"ttopen ttname",ttname,0);
  2124. debug(F110,"ttopen ttnmsv",ttnmsv,0);
  2125. debug(F101,"ttopen modem","",modem);
  2126. debug(F101,"ttopen netconn","",netconn);
  2127. debug(F101,"ttopen ttyfd","",ttyfd);
  2128. debug(F101,"ttopen *lcl","",*lcl);
  2129. debug(F101,"ttopen ttmdm","",ttmdm);
  2130. debug(F101,"ttopen ttnet","",ttnet);
  2131. ttpmsk = 0xff;
  2132. lockpid[0] = '\0';
  2133. if (ttyfd > -1) { /* If device already opened */
  2134. if (!strncmp(ttname,ttnmsv,DEVNAMLEN)) /* are new & old names equal? */
  2135. return(0); /* Yes, nothing to do - just return */
  2136. ttnmsv[0] = '\0'; /* No, clear out old name */
  2137. ttclos(ttyfd); /* close old connection. */
  2138. }
  2139. wasclosed = 0; /* New connection, not closed yet. */
  2140. ttpipe = 0; /* Assume it's not a pipe */
  2141. ttpty = 0; /* or a pty... */
  2142. #ifdef NETCONN
  2143. /*
  2144. This is a bit tricky... Suppose that previously Kermit had dialed a telnet
  2145. modem server ("set host xxx:2001, set modem type usr, dial ..."). Then the
  2146. connection was closed (ttyfd = -1), and then a REDIAL command was given. At
  2147. this point we've obliterated the negative modem type hack, and so would
  2148. treat the IP hostname as a device name, and would then fail because of "No
  2149. such device or directory". But the previous connection has left behind some
  2150. clues, so let's use them...
  2151. */
  2152. if (ttyfd < 0) { /* Connection is not open */
  2153. if (!strcmp(ttname,ttnmsv)) { /* Old and new names the same? */
  2154. if (((netconn > 0) && (ttmdm < 0)) ||
  2155. ((ttnet > 0) &&
  2156. (!ckstrchr(ttname,'/')) && (ckstrchr(ttname,':')))
  2157. ) {
  2158. int x, rc;
  2159. x = (ttmdm < 0) ? -ttmdm : ttnet;
  2160. rc = netopen(ttname, lcl, x);
  2161. debug(F111,"ttopen REOPEN netopen",ttname,rc);
  2162. if (rc > -1) {
  2163. netconn = 1;
  2164. xlocal = *lcl = 1;
  2165. } else {
  2166. netconn = 0;
  2167. }
  2168. gotsigs = 0;
  2169. return(rc);
  2170. }
  2171. }
  2172. }
  2173. #endif /* NETCONN */
  2174. #ifdef MAXNAMLEN
  2175. debug(F100,"ttopen MAXNAMLEN defined","",0);
  2176. #else
  2177. debug(F100,"ttopen MAXNAMLEN *NOT* defined","",0);
  2178. #endif
  2179. #ifdef BSD4
  2180. debug(F100,"ttopen BSD4 defined","",0);
  2181. #else
  2182. debug(F100,"ttopen BSD4 *NOT* defined","",0);
  2183. #endif /* BSD4 */
  2184. #ifdef BSD42
  2185. debug(F100,"ttopen BSD42 defined","",0);
  2186. #else
  2187. debug(F100,"ttopen BSD42 *NOT* defined","",0);
  2188. #endif /* BSD42 */
  2189. #ifdef MYREAD
  2190. debug(F100,"ttopen MYREAD defined","",0);
  2191. #else
  2192. debug(F100,"ttopen MYREAD *NOT* defined","",0);
  2193. #endif /* MYREAD */
  2194. #ifdef NETCONN
  2195. if (modem < 0) { /* modem < 0 = code for network */
  2196. int x;
  2197. ttmdm = modem;
  2198. modem = -modem; /* Positive network type number */
  2199. fdflag = 0; /* Stdio not redirected. */
  2200. netconn = 1; /* And it's a network connection */
  2201. debug(F111,"ttopen net",ttname,modem);
  2202. #ifdef NAMEFD
  2203. for (p = ttname; isdigit(*p); p++) ; /* Check for all digits */
  2204. if (*p == '\0' && (telnetfd || x25fd)) { /* Avoid X.121 addresses */
  2205. ttyfd = atoi(ttname); /* Is there a way to test it's open? */
  2206. ttfdflg = 1; /* We got an open file descriptor */
  2207. debug(F111,"ttopen net ttfdflg",ttname,ttfdflg);
  2208. debug(F101,"ttopen net ttyfd","",ttyfd);
  2209. ckstrncpy(ttnmsv,ttname,DEVNAMLEN); /* Remember the "name". */
  2210. x = 1; /* Return code is "good". */
  2211. if (telnetfd) {
  2212. ttnet = NET_TCPB;
  2213. if (ttnproto != NP_TCPRAW)
  2214. ttnproto = NP_TELNET;
  2215. #ifdef SUNX25
  2216. } else if (x25fd) {
  2217. ttnet = NET_SX25;
  2218. ttnproto = NP_NONE;
  2219. #endif /* SUNX25 */
  2220. }
  2221. } else { /* Host name or address given */
  2222. #ifdef NETPTY
  2223. if (modem == NET_PTY) {
  2224. int x;
  2225. if (nopush) {
  2226. debug(F100,"ttopen PTY: nopush","",0);
  2227. return(-1);
  2228. }
  2229. ttnet = NET_PTY;
  2230. ttnproto = NP_NONE;
  2231. netconn = 1; /* but we don't use network i/o */
  2232. ttpty = 1;
  2233. debug(F110,"ttopen PTY",ttname,0);
  2234. x = do_pty(&ttyfd,ttname,0);
  2235. if (x > -1) {
  2236. ckstrncpy(ttnmsv,ttname,DEVNAMLEN);
  2237. xlocal = *lcl = 1; /* It's local */
  2238. } else {
  2239. ttpty = 0;
  2240. netconn = 0;
  2241. }
  2242. gotsigs = 0;
  2243. return(x);
  2244. }
  2245. #endif /* NETPTY */
  2246. #ifdef NETCMD
  2247. /*
  2248. dup2() is not available on older System V platforms like AT&T 3Bx. For
  2249. those systems we punt by not defining NETCMD, but we might be able to do
  2250. better -- see workarounds for this problem in ckufio.c (search for dup2).
  2251. */
  2252. if (modem == NET_CMD) {
  2253. if (nopush) {
  2254. debug(F100,"ttopen pipe: nopush","",0);
  2255. return(-1);
  2256. }
  2257. if (pipe(pipe0) || pipe(pipe1)) {
  2258. perror("Pipe error");
  2259. return(-1);
  2260. }
  2261. ttpid = fork(); /* Make a fork */
  2262. switch (ttpid) {
  2263. case -1: /* Error making fork */
  2264. close(pipe0[0]);
  2265. close(pipe0[1]);
  2266. close(pipe1[0]);
  2267. close(pipe1[1]);
  2268. perror("Fork error");
  2269. return(-1);
  2270. case 0: /* Child. */
  2271. close(pipe0[0]);
  2272. close(pipe1[1]);
  2273. dup2(pipe0[1], 1);
  2274. close(pipe0[1]);
  2275. dup2(pipe1[0], 0);
  2276. close(pipe1[0]);
  2277. /*
  2278. I can't image what this is; system() executes a shell command.
  2279. ttname holds the name of terminal device, it's not a command.
  2280. --fdc Fri Sep 18 15:51:18 2020
  2281. system(ttname);
  2282. */
  2283. _exit(0);
  2284. default: /* Parent */
  2285. close(pipe0[1]);
  2286. close(pipe1[0]);
  2287. fdin = pipe0[0]; /* Read from pipe */
  2288. fdout = pipe1[1]; /* Write to pipe */
  2289. ttout = fdopen(fdout,"w"); /* Get stream so we can */
  2290. if (!ttout) { /* make it unbuffered. */
  2291. perror("fdopen failure");
  2292. return(-1);
  2293. }
  2294. setbuf(ttout,NULL);
  2295. ckstrncpy(ttnmsv,ttname,DEVNAMLEN);
  2296. xlocal = *lcl = 1; /* It's local */
  2297. netconn = 1; /* Call it a network connection */
  2298. ttmdm = modem; /* Remember network type */
  2299. ttyfd = fdin;
  2300. ttpipe = 1;
  2301. gotsigs = 0;
  2302. return(0);
  2303. }
  2304. }
  2305. #endif /* NETCMD */
  2306. #endif /* NAMEFD */
  2307. x = netopen(ttname, lcl, modem); /* (see ckcnet.h) */
  2308. if (x > -1) {
  2309. ckstrncpy(ttnmsv,ttname,DEVNAMLEN);
  2310. } else netconn = 0;
  2311. #ifdef NAMEFD
  2312. }
  2313. #endif /* NAMEFD */
  2314. #ifdef sony_news /* Sony NEWS */
  2315. if (ioctl(ttyfd,TIOCKGET,&km_ext) < 0) { /* Get Kanji mode */
  2316. perror("ttopen error getting Kanji mode (network)");
  2317. debug(F111,"ttopen error getting Kanji mode","network",0);
  2318. km_ext = -1; /* Make sure this stays undefined. */
  2319. }
  2320. #endif /* sony_news */
  2321. xlocal = *lcl = 1; /* Network connections are local. */
  2322. debug(F101,"ttopen net x","",x);
  2323. #ifdef COMMENT
  2324. /* Let netopen() do this */
  2325. if (x > -1 && !x25fd)
  2326. x = tn_ini(); /* Initialize TELNET protocol */
  2327. #endif /* COMMENT */
  2328. gotsigs = 0;
  2329. return(x);
  2330. } else { /* Terminal device */
  2331. #endif /* NETCONN */
  2332. #ifdef NAMEFD
  2333. /*
  2334. This code lets you give Kermit an open file descriptor for a serial
  2335. communication device, rather than a device name. Kermit assumes that the
  2336. line is already open, locked, conditioned with the right parameters, etc.
  2337. */
  2338. for (p = ttname; isdigit(*p); p++) ; /* Check for all-digits */
  2339. if (*p == '\0') {
  2340. ttyfd = atoi(ttname); /* Is there a way to test it's open? */
  2341. debug(F111,"ttopen got open fd",ttname,ttyfd);
  2342. ckstrncpy(ttnmsv,ttname,DEVNAMLEN); /* Remember the "name". */
  2343. if (ttyfd >= 0 && ttyfd < 3) /* If it's stdio... */
  2344. xlocal = *lcl = 0; /* we're in remote mode */
  2345. else /* otherwise */
  2346. xlocal = *lcl = 1; /* local mode. */
  2347. netconn = 0; /* Assume it's not a network. */
  2348. tvtflg = 0; /* Might need to initialize modes. */
  2349. ttmdm = modem; /* Remember modem type. */
  2350. fdflag = 0; /* Stdio not redirected. */
  2351. ttfdflg = 1; /* Flag we were opened this way. */
  2352. debug(F111,"ttopen non-net ttfdflg",ttname,ttfdflg);
  2353. debug(F101,"ttopen non-net ttyfd","",ttyfd);
  2354. #ifdef sony_news /* Sony NEWS */
  2355. /* Get device Kanji mode */
  2356. if (ioctl(ttyfd,TIOCKGET,&km_ext) < 0) {
  2357. perror("ttopen error getting Kanji mode");
  2358. debug(F101,"ttopen error getting Kanji mode","",0);
  2359. km_ext = -1; /* Make sure this stays undefined. */
  2360. }
  2361. #endif /* sony_news */
  2362. gotsigs = 0;
  2363. return(0); /* Return success */
  2364. }
  2365. #endif /* NAMEFD */
  2366. #ifdef NETCONN
  2367. }
  2368. #endif /* NETCONN */
  2369. /* Here we have to open a serial device of the given name. */
  2370. netconn = 0; /* So it's not a network connection */
  2371. occt = signal(SIGINT, cctrap); /* Set Control-C trap, save old one */
  2372. sigint_ign = 0;
  2373. tvtflg = 0; /* Flag for use by ttvt(). */
  2374. /* 0 = ttvt not called yet for this device */
  2375. fdflag = (!isatty(0) || !isatty(1)); /* Flag for stdio redirected */
  2376. debug(F101,"ttopen fdflag","",fdflag);
  2377. ttmdm = modem; /* Make this available to other fns */
  2378. xlocal = *lcl; /* Make this available to other fns */
  2379. /* Code for handling bidirectional tty lines goes here. */
  2380. /* Use specified method for turning off logins and suppressing getty. */
  2381. #ifdef ACUCNTRL
  2382. /* Should put call to priv_on() here, but that would be very risky! */
  2383. acucntrl("disable",ttname); /* acucntrl() program. */
  2384. /* and priv_off() here... */
  2385. #else
  2386. #ifdef ATT7300
  2387. if ((attmodem & DOGETY) == 0) /* offgetty() program. */
  2388. attmodem |= offgetty(ttname); /* Remember response. */
  2389. #endif /* ATT7300 */
  2390. #endif /* ACUCNTRL */
  2391. #ifdef OPENFIRST
  2392. /*
  2393. 1985-2001: opens device first then gets lock; reason:
  2394. Kermit usually has to run setuid or setgid in order to create a lockfile.
  2395. If you give a SET LINE command for a device that happens to be your job's
  2396. controlling terminal, Kermit doesn't have to create a lockfile, and in fact
  2397. should not create one, and would fail if it tried to if it did not have the
  2398. required privileges. But you can't find out if two tty device names are
  2399. equivalent until you have a file descriptor that you can give to ttyname().
  2400. But this can cause a race condition between Kermit and [m]getty. So see
  2401. the [#]else part...
  2402. */
  2403. /*
  2404. In the following section, we open the tty device for read/write.
  2405. If a modem has been specified via "set modem" prior to "set line"
  2406. then the O_NDELAY parameter is used in the open, provided this symbol
  2407. is defined (e.g. in fcntl.h), so that the program does not hang waiting
  2408. for carrier (which in most cases won't be present because a connection
  2409. has not been dialed yet). O_NDELAY is removed later on in ttopen(). It
  2410. would make more sense to first determine if the line is local before
  2411. doing this, but because ttyname() requires a file descriptor, we have
  2412. to open it first. See do_open().
  2413. Now open the device using the desired treatment of carrier.
  2414. If carrier is REQUIRED, then open could hang forever, so an optional
  2415. timer is provided. If carrier is not required, the timer should never
  2416. go off, and should do no harm...
  2417. */
  2418. ttotmo = 0; /* Flag no timeout */
  2419. debug(F101,"ttopen timo","",timo);
  2420. debug(F101,"ttopen xlocal","",xlocal);
  2421. if (timo > 0) {
  2422. int xx;
  2423. saval = signal(SIGALRM,timerh); /* Timed, set up timer. */
  2424. xx = alarm(timo); /* Timed open() */
  2425. debug(F101,"ttopen alarm","",xx);
  2426. if (
  2427. #ifdef CK_POSIX_SIG
  2428. sigsetjmp(sjbuf,1)
  2429. #else
  2430. setjmp(sjbuf)
  2431. #endif /* CK_POSIX_SIG */
  2432. ) {
  2433. ttotmo = 1; /* Flag timeout. */
  2434. } else ttyfd = do_open(ttname);
  2435. ttimoff();
  2436. debug(F111,"ttopen","modem",modem);
  2437. debug(F101,"ttopen ttyfd","",ttyfd);
  2438. debug(F101,"ttopen alarm return","",ttotmo);
  2439. } else {
  2440. errno = 0;
  2441. ttyfd = do_open(ttname);
  2442. }
  2443. debug(F111,"ttopen ttyfd",ttname,ttyfd);
  2444. if (ttyfd < 0) { /* If couldn't open, fail. */
  2445. debug(F101,"ttopen errno","",errno);
  2446. if (errno > 0 && !quiet)
  2447. perror(ttname); /* Print message */
  2448. #ifdef ATT7300
  2449. if (attmodem & DOGETY) /* was getty(1m) running before us? */
  2450. ongetty(ttnmsv); /* yes, restart on tty line */
  2451. attmodem &= ~DOGETY; /* no phone in use, getty restored */
  2452. #else
  2453. #ifdef ACUCNTRL
  2454. /* Should put call to priv_on() here, but that would be risky! */
  2455. acucntrl("enable",ttname); /* acucntrl() program. */
  2456. /* and priv_off() here... */
  2457. #endif /* ACUNTRL */
  2458. #endif /* ATT7300 */
  2459. signal(SIGINT,occt); /* Put old Ctrl-C trap back. */
  2460. if (errno == EACCES) { /* Device is protected against user */
  2461. debug(F110,"ttopen EACCESS",ttname,0); /* Return -4 */
  2462. return(-4);
  2463. } else return(ttotmo ? -2 : -1); /* Otherwise -2 if timeout, or -1 */
  2464. }
  2465. #ifdef QNX
  2466. {
  2467. extern int qnxportlock;
  2468. x = qnxopencount();
  2469. debug(F101,"ttopen qnxopencount","",x);
  2470. debug(F101,"ttopen qnxportlock","",qnxportlock);
  2471. if (x < 0 && qnxportlock) {
  2472. ttclos(0);
  2473. printf("?Can't get port open count\n");
  2474. printf("(Try again with SET QNX-PORT-LOCK OFF)\n");
  2475. return(-1); /* Indicate device is in use */
  2476. }
  2477. if (x > 1) { /* 1 == me */
  2478. if (qnxportlock)
  2479. ttclos(0);
  2480. return(-2); /* Indicate device is in use */
  2481. else if (!quiet)
  2482. printf("WARNING: \"%s\" looks busy...\n",ttdev);
  2483. }
  2484. }
  2485. #endif /* QNX */
  2486. #ifdef Plan9
  2487. /* take this opportunity to open the control channel */
  2488. if (p9openttyctl(ttname) < 0)
  2489. #else
  2490. /* Make sure it's a real tty. */
  2491. if (!ttfdflg && !isatty(ttyfd) && strcmp(ttname,"/dev/null"))
  2492. #endif /* Plan9 */
  2493. {
  2494. fprintf(stderr,"%s is not a terminal device\n",ttname);
  2495. debug(F111,"ttopen not a tty",ttname,errno);
  2496. close(ttyfd);
  2497. ttyfd = -1;
  2498. wasclosed = 1;
  2499. signal(SIGINT,occt);
  2500. return(-1);
  2501. }
  2502. #ifdef aegis
  2503. /* Apollo C runtime claims that console pads are tty devices, which
  2504. * is reasonable, but they aren't any good for packet transfer. */
  2505. ios_$inq_type_uid((short)ttyfd, ttyuid, st);
  2506. if (st.all != status_$ok) {
  2507. fprintf(stderr, "problem getting tty object type: ");
  2508. error_$print(st);
  2509. } else if (ttyuid != sio_$uid) { /* reject non-SIO lines */
  2510. close(ttyfd); ttyfd = -1;
  2511. wasclosed = 1;
  2512. errno = ENOTTY; perror(ttname);
  2513. signal(SIGINT,occt);
  2514. return(-1);
  2515. }
  2516. #endif /* aegis */
  2517. sigint_ign = (occt == SIG_IGN) ? 1 : 0;
  2518. ckstrncpy(ttnmsv,ttname,DEVNAMLEN); /* Keep copy of name locally. */
  2519. /* Caller wants us to figure out if line is controlling tty */
  2520. if (*lcl < 0) {
  2521. if (strcmp(ttname,CTTNAM) == 0) { /* "/dev/tty" always remote */
  2522. xlocal = 0;
  2523. debug(F111,"ttopen ttname=CTTNAM",ttname,xlocal);
  2524. } else if (strcmp(ttname,cttnam) == 0) {
  2525. xlocal = 0;
  2526. debug(F111,"ttopen ttname=cttnam",ttname,xlocal);
  2527. } else if (cttnam[0]) {
  2528. #ifdef BEBOX_DR7
  2529. x = ttnmsv; /* ttyname() is broken */
  2530. #else
  2531. x = ttyname(ttyfd); /* Get real name of ttname. */
  2532. #endif /* BEBOX_DR7 */
  2533. if (!x) x = "";
  2534. if (*x)
  2535. xlocal = ((strncmp(x,cttnam,DEVNAMLEN) == 0) ? 0 : 1);
  2536. else
  2537. xlocal = 1;
  2538. debug(F111,"ttopen ttyname(ttyfd) xlocal",x,xlocal);
  2539. }
  2540. }
  2541. #ifndef NOFDZERO
  2542. /* Note, the following code was added so that Unix "idle-line" snoopers */
  2543. /* would not think Kermit was idle when it was transferring files, and */
  2544. /* maybe log people out. */
  2545. if (xlocal == 0) { /* Remote mode */
  2546. if (fdflag == 0) { /* Standard i/o is not redirected */
  2547. debug(F100,"ttopen setting ttyfd = 0","",0);
  2548. #ifdef LYNXOS
  2549. /* On Lynx OS, fd 0 is open for read only. */
  2550. dup2(ttyfd,0);
  2551. #endif /* LYNXOS */
  2552. close(ttyfd); /* Use file descriptor 0 */
  2553. ttyfd = 0;
  2554. } else { /* Standard i/o is redirected */
  2555. debug(F101,"ttopen stdio redirected","",ttyfd);
  2556. }
  2557. }
  2558. #endif /* NOFDZERO */
  2559. /* Now check if line is locked -- if so fail, else lock for ourselves */
  2560. /* Note: After having done this, don't forget to delete the lock if you */
  2561. /* leave ttopen() with an error condition. */
  2562. lkf = 0; /* Check lock */
  2563. if (xlocal > 0) {
  2564. int xx; int xpid;
  2565. if ((xx = ttlock(ttname)) < 0) { /* Can't lock it. */
  2566. debug(F111,"ttopen ttlock fails",ttname,xx);
  2567. /* WARNING - This close() can hang if tty is an empty socket... */
  2568. close(ttyfd); /* Close the device. */
  2569. ttyfd = -1; /* Erase its file descriptor. */
  2570. wasclosed = 1;
  2571. signal(SIGINT,occt); /* Put old SIGINT back. */
  2572. sigint_ign = (occt == SIG_IGN) ? 1 : 0;
  2573. if (xx == -2) { /* If lockfile says device in use, */
  2574. #ifndef NOUUCP
  2575. debug(F111,"ttopen reading lockfile pid",flfnam,xx);
  2576. xpid = ttrpid(flfnam); /* Try to read pid from lockfile */
  2577. if (xpid > -1) { /* If we got a pid */
  2578. if (!quiet)
  2579. printf("Locked by process %d\n",xpid); /* tell them. */
  2580. sprintf(lockpid,"%d",xpid); /* Record it too */
  2581. debug(F110,"ttopen lockpid",lockpid,0);
  2582. } else if (*flfnam) {
  2583. extern char *DIRCMD;
  2584. char *p = NULL;
  2585. int x;
  2586. x = (int)strlen(flfnam) + (int)strlen(DIRCMD) + 2;
  2587. p = malloc(x); /* Print a directory listing. */
  2588. /*
  2589. Note: priv_on() won't help here, because we do not pass privs along to
  2590. to inferior processes, in this case ls. So if the real user does not have
  2591. directory-listing access to the lockfile directory, this will result in
  2592. something like "not found". That's why we try this only as a last resort.
  2593. */
  2594. if (p) { /* If we got the space... */
  2595. ckmakmsg(p,x,DIRCMD," ",flfnam,NULL);
  2596. zsyscmd(p); /* Get listing. */
  2597. if (p) { /* free the space */
  2598. free(p);
  2599. p = NULL;
  2600. }
  2601. }
  2602. }
  2603. #endif /* NOUUCP */
  2604. return(-5); /* Code for device in use */
  2605. } else return(-3); /* Access denied */
  2606. } else lkf = 1;
  2607. }
  2608. #else /* OPENFIRST */
  2609. /*
  2610. 27 Oct 2001: New simpler code that gets the lock first and then opens the
  2611. device, which eliminates the race condition. The downside is you can no
  2612. longer say "set line /dev/ttyp0" or whatever, where /dev/ttyp0 is your login
  2613. terminal, without trying to create a lockfile, which fails if C-Kermit lacks
  2614. privs, and if it succeeds, it has created a lockfile where it didn't create
  2615. one before.
  2616. */
  2617. xlocal = *lcl; /* Is the device my login terminal? */
  2618. debug(F111,"ttopen xlocal","A",xlocal);
  2619. fnam = ttname;
  2620. if (strcmp(ttname,CTTNAM) && netconn == 0) {
  2621. if (zfnqfp(ttname,DEVNAMLEN+1,fullname)) {
  2622. if ((int)strlen(fullname) > 0)
  2623. fnam = fullname;
  2624. }
  2625. }
  2626. debug(F110,"ttopen fnam",fnam,0);
  2627. if (xlocal < 0) {
  2628. xlocal = (strcmp(fnam,CTTNAM) != 0);
  2629. }
  2630. debug(F111,"ttopen xlocal","B",xlocal);
  2631. lkf = 0; /* No lock yet */
  2632. if (xlocal > 0) { /* If not... */
  2633. int xx; int xpid;
  2634. xx = ttlock(fnam); /* Try to lock it. */
  2635. debug(F101,"ttopen ttlock","",xx);
  2636. if (xx < 0) { /* Can't lock it. */
  2637. debug(F111,"ttopen ttlock fails",fnam,xx);
  2638. if (xx == -2) { /* If lockfile says device in use, */
  2639. #ifndef NOUUCP
  2640. debug(F111,"ttopen reading lockfile pid",flfnam,xx);
  2641. xpid = ttrpid(flfnam); /* Try to read pid from lockfile */
  2642. if (xpid > -1) { /* If we got a pid */
  2643. if (!quiet)
  2644. printf("Locked by process %d\n",xpid); /* tell them. */
  2645. ckstrncpy(lockpid,ckitoa(xpid),16);
  2646. debug(F110,"ttopen lockpid",lockpid,0);
  2647. #ifndef NOPUSH
  2648. } else if (flfnam[0] && !nopush) {
  2649. extern char *DIRCMD;
  2650. char *p = NULL;
  2651. int x;
  2652. x = (int)strlen(flfnam) + (int)strlen(DIRCMD) + 2;
  2653. p = malloc(x); /* Print a directory listing. */
  2654. /*
  2655. Note: priv_on() won't help here, because we do not pass privs along to
  2656. to inferior processes, in this case ls. So if the real user does not have
  2657. directory-listing access to the lockfile directory, this will result in
  2658. something like "not found". That's why we try this only as a last resort.
  2659. */
  2660. if (p) { /* If we got the space... */
  2661. ckmakmsg(p,x,DIRCMD," ",flfnam,NULL);
  2662. zsyscmd(p); /* Get listing. */
  2663. if (p) { /* free the space */
  2664. free(p);
  2665. p = NULL;
  2666. }
  2667. }
  2668. #endif /* NOPUSH */
  2669. }
  2670. #endif /* NOUUCP */
  2671. return(-5); /* Code for device in use */
  2672. } else return(-3); /* Access denied */
  2673. } else lkf = 1;
  2674. }
  2675. /* Have lock -- now it's safe to open the device */
  2676. debug(F101,"ttopen lkf","",lkf);
  2677. debug(F101,"ttopen timo","",timo);
  2678. ttotmo = 0; /* Flag no timeout */
  2679. if (timo > 0) {
  2680. int xx;
  2681. saval = signal(SIGALRM,timerh); /* Timed, set up timer. */
  2682. xx = alarm(timo); /* Timed open() */
  2683. debug(F101,"ttopen alarm","",xx);
  2684. if (
  2685. #ifdef CK_POSIX_SIG
  2686. sigsetjmp(sjbuf,1)
  2687. #else
  2688. setjmp(sjbuf)
  2689. #endif /* CK_POSIX_SIG */
  2690. ) {
  2691. ttotmo = 1; /* Flag timeout. */
  2692. } else {
  2693. ttyfd = do_open(fnam);
  2694. }
  2695. ttimoff();
  2696. debug(F111,"ttopen timed ttyfd",fnam,ttyfd);
  2697. } else {
  2698. errno = 0;
  2699. ttyfd = do_open(fnam);
  2700. debug(F111,"ttopen untimed ttyfd",fnam,ttyfd);
  2701. }
  2702. if (ttyfd < 0) { /* If couldn't open, fail. */
  2703. debug(F111,"ttopen errno",fnam,errno);
  2704. debug(F111,"ttopen xlocal","C",xlocal);
  2705. if (xlocal == 0) {
  2706. debug(F100,"ttopen substituting 0","",0);
  2707. ttyfd = 0;
  2708. } else {
  2709. if (errno > 0 && !quiet) {
  2710. debug(F111,"ttopen perror",fnam,errno);
  2711. perror(fnam); /* Print message */
  2712. }
  2713. if (ttunlck()) /* Release the lock file */
  2714. fprintf(stderr,"Warning, problem releasing lock\r\n");
  2715. }
  2716. }
  2717. if (ttyfd < 0) { /* ttyfd is still < 0? */
  2718. #ifdef ATT7300
  2719. if (attmodem & DOGETY) /* was getty(1m) running before us? */
  2720. ongetty(ttnmsv); /* yes, restart on tty line */
  2721. attmodem &= ~DOGETY; /* no phone in use, getty restored */
  2722. #else
  2723. #ifdef ACUCNTRL
  2724. /* Should put call to priv_on() here, but that would be risky! */
  2725. acucntrl("enable",fnam); /* acucntrl() program. */
  2726. /* and priv_off() here... */
  2727. #endif /* ACUNTRL */
  2728. #endif /* ATT7300 */
  2729. signal(SIGINT,occt); /* Put old Ctrl-C trap back. */
  2730. if (errno == EACCES) { /* Device is protected against user */
  2731. debug(F110,"ttopen EACCESS",fnam,0); /* Return -4 */
  2732. return(-4);
  2733. } else return(ttotmo ? -2 : -1); /* Otherwise -2 if timeout, or -1 */
  2734. }
  2735. /* Make sure it's a real tty. */
  2736. #ifdef Plan9
  2737. /* take this opportunity to open the control channel */
  2738. if (p9openttyctl(fnam) < 0)
  2739. #else
  2740. if (!ttfdflg && !isatty(ttyfd) && strcmp(fnam,"/dev/null"))
  2741. #endif /* Plan9 */
  2742. {
  2743. fprintf(stderr,"%s is not a terminal device\n",fnam);
  2744. debug(F111,"ttopen not a tty",fnam,errno);
  2745. if (ttunlck()) /* Release the lock file */
  2746. fprintf(stderr,"Warning, problem releasing lock\r\n");
  2747. close(ttyfd);
  2748. ttyfd = -1;
  2749. wasclosed = 1;
  2750. signal(SIGINT,occt);
  2751. return(-1);
  2752. }
  2753. #ifdef aegis
  2754. /*
  2755. Apollo C runtime claims that console pads are tty devices, which
  2756. is reasonable, but they aren't any good for packet transfer.
  2757. */
  2758. ios_$inq_type_uid((short)ttyfd, ttyuid, st);
  2759. if (st.all != status_$ok) {
  2760. fprintf(stderr, "problem getting tty object type: ");
  2761. error_$print(st);
  2762. } else if (ttyuid != sio_$uid) { /* Reject non-SIO lines */
  2763. close(ttyfd); ttyfd = -1;
  2764. wasclosed = 1;
  2765. errno = ENOTTY; perror(fnam);
  2766. signal(SIGINT,occt);
  2767. return(-1);
  2768. }
  2769. #endif /* aegis */
  2770. sigint_ign = (occt == SIG_IGN) ? 1 : 0;
  2771. ckstrncpy(ttnmsv,ttname,DEVNAMLEN); /* Keep copy of name locally. */
  2772. /* Caller wants us to figure out if line is controlling tty */
  2773. if (*lcl < 0) {
  2774. char * s;
  2775. if (strcmp(fnam,CTTNAM) == 0) { /* "/dev/tty" always remote */
  2776. xlocal = 0;
  2777. debug(F111,"ttopen fnam=CTTNAM",fnam,xlocal);
  2778. } else if (strcmp(fnam,cttnam) == 0) {
  2779. xlocal = 0;
  2780. debug(F111,"ttopen fnam=cttnam",fnam,xlocal);
  2781. } else if (cttnam[0]) {
  2782. #ifdef BEBOX_DR7
  2783. s = ttnmsv; /* ttyname() is broken */
  2784. #else
  2785. s = ttyname(ttyfd); /* Get real name of ttname. */
  2786. #endif /* BEBOX_DR7 */
  2787. if (!s) s = "";
  2788. if (*s)
  2789. xlocal = ((strncmp(s,cttnam,DEVNAMLEN) == 0) ? 0 : 1);
  2790. else
  2791. xlocal = 1;
  2792. debug(F111,"ttopen ttyname(ttyfd) xlocal",s,xlocal);
  2793. }
  2794. }
  2795. #ifndef NOFDZERO
  2796. /* Note, the following code was added so that Unix "idle-line" snoopers */
  2797. /* would not think Kermit was idle when it was transferring files, and */
  2798. /* maybe log people out. */
  2799. if (xlocal == 0) { /* Remote mode */
  2800. if (fdflag == 0) { /* Standard i/o is not redirected */
  2801. debug(F100,"ttopen setting ttyfd = 0","",0);
  2802. #ifdef LYNXOS
  2803. /* On Lynx OS, fd 0 is open for read only. */
  2804. dup2(ttyfd,0);
  2805. #endif /* LYNXOS */
  2806. close(ttyfd); /* Use file descriptor 0 */
  2807. ttyfd = 0;
  2808. } else { /* Standard i/o is redirected */
  2809. debug(F101,"ttopen stdio redirected","",ttyfd);
  2810. }
  2811. }
  2812. #endif /* NOFDZERO */
  2813. #endif /* OPENFIRST */
  2814. /* Got the line, now set the desired value for local. */
  2815. if (*lcl != 0) *lcl = xlocal;
  2816. /* Some special stuff for v7... */
  2817. #ifdef V7
  2818. #ifndef MINIX
  2819. if (kmem[TTY] < 0) { /* If open, then skip this. */
  2820. qaddr[TTY] = initrawq(ttyfd); /* Init the queue. */
  2821. if ((kmem[TTY] = open("/dev/kmem", 0)) < 0) {
  2822. fprintf(stderr, "Can't read /dev/kmem in ttopen.\n");
  2823. perror("/dev/kmem");
  2824. exit(1);
  2825. }
  2826. }
  2827. #endif /* !MINIX */
  2828. #endif /* V7 */
  2829. /* No failure returns after this point */
  2830. #ifdef ultrix
  2831. ioctl(ttyfd, TIOCMODEM, &temp);
  2832. #ifdef TIOCSINUSE
  2833. if (xlocal && ioctl(ttyfd, TIOCSINUSE, NULL) < 0) {
  2834. if (!quiet)
  2835. perror(fnam);
  2836. }
  2837. #endif /* TIOCSINUSE */
  2838. #endif /* ultrix */
  2839. /* Get tty device settings */
  2840. #ifdef BSD44ORPOSIX /* POSIX */
  2841. tcgetattr(ttyfd,&ttold);
  2842. debug(F101,"ttopen tcgetattr ttold.c_lflag","",ttold.c_lflag);
  2843. tcgetattr(ttyfd,&ttraw);
  2844. debug(F101,"ttopen tcgetattr ttraw.c_lflag","",ttraw.c_lflag);
  2845. tcgetattr(ttyfd,&tttvt);
  2846. debug(F101,"ttopen tcgetattr tttvt.c_lflag","",tttvt.c_lflag);
  2847. #else /* BSD, V7, and all others */
  2848. #ifdef ATTSV /* AT&T UNIX */
  2849. ioctl(ttyfd,TCGETA,&ttold);
  2850. debug(F101,"ttopen ioctl TCGETA ttold.c_lflag","",ttold.c_lflag);
  2851. ioctl(ttyfd,TCGETA,&ttraw);
  2852. ioctl(ttyfd,TCGETA,&tttvt);
  2853. #else
  2854. #ifdef BELLV10
  2855. ioctl(ttyfd,TIOCGETP,&ttold);
  2856. debug(F101,"ttopen BELLV10 ttold.sg_flags","",ttold.sg_flags);
  2857. ioctl(ttyfd,TIOCGDEV,&tdold);
  2858. debug(F101,"ttopen BELLV10 tdold.flags","",tdold.flags);
  2859. #else
  2860. gtty(ttyfd,&ttold);
  2861. debug(F101,"ttopen gtty ttold.sg_flags","",ttold.sg_flags);
  2862. #endif /* BELLV10 */
  2863. #ifdef sony_news /* Sony NEWS */
  2864. if (ioctl(ttyfd,TIOCKGET,&km_ext) < 0) { /* Get console Kanji mode */
  2865. perror("ttopen error getting Kanji mode");
  2866. debug(F101,"ttopen error getting Kanji mode","",0);
  2867. km_ext = -1; /* Make sure this stays undefined. */
  2868. }
  2869. #endif /* sony_news */
  2870. #ifdef TIOCGETC
  2871. debug(F100,"ttopen TIOCGETC","",0);
  2872. tcharf = 0; /* In remote mode, also get */
  2873. if (xlocal == 0) { /* special characters */
  2874. if (ioctl(ttyfd,TIOCGETC,&tchold) < 0) {
  2875. debug(F100,"ttopen TIOCGETC failed","",0);
  2876. } else {
  2877. tcharf = 1; /* It worked. */
  2878. ioctl(ttyfd,TIOCGETC,&tchnoi); /* Get another copy */
  2879. debug(F100,"ttopen TIOCGETC ok","",0);
  2880. }
  2881. }
  2882. #else
  2883. debug(F100,"ttopen TIOCGETC not defined","",0);
  2884. #endif /* TIOCGETC */
  2885. #ifdef TIOCGLTC
  2886. debug(F100,"ttopen TIOCGLTC","",0);
  2887. ltcharf = 0; /* In remote mode, also get */
  2888. if (xlocal == 0) { /* local special characters */
  2889. if (ioctl(ttyfd,TIOCGLTC,&ltchold) < 0) {
  2890. debug(F100,"ttopen TIOCGLTC failed","",0);
  2891. } else {
  2892. ltcharf = 1; /* It worked. */
  2893. ioctl(ttyfd,TIOCGLTC,&ltchnoi); /* Get another copy */
  2894. debug(F100,"ttopen TIOCGLTC ok","",0);
  2895. }
  2896. }
  2897. #else
  2898. debug(F100,"ttopen TIOCGLTC not defined","",0);
  2899. #endif /* TIOCGLTC */
  2900. #ifdef TIOCLGET
  2901. debug(F100,"ttopen TIOCLGET","",0);
  2902. lmodef = 0;
  2903. if (ioctl(ttyfd,TIOCLGET,&lmode) < 0) {
  2904. debug(F100,"ttopen TIOCLGET failed","",0);
  2905. } else {
  2906. lmodef = 1;
  2907. debug(F100,"ttopen TIOCLGET ok","",0);
  2908. }
  2909. #endif /* TIOCLGET */
  2910. #ifdef BELLV10
  2911. ioctl(ttyfd,TIOCGETP,&ttraw);
  2912. ioctl(ttyfd,TIOCGETP,&tttvt);
  2913. #else
  2914. gtty(ttyfd,&ttraw); /* And a copy of it for packets*/
  2915. gtty(ttyfd,&tttvt); /* And one for virtual tty service */
  2916. #endif /* BELLV10 */
  2917. #endif /* ATTSV */
  2918. #endif /* BSD44ORPOSIX */
  2919. /* Section for changing line discipline. It's restored in ttres(). */
  2920. #ifdef AIXRS
  2921. #ifndef AIX41
  2922. { union txname ld_name; int ld_idx = 0;
  2923. ttld = 0;
  2924. do {
  2925. ld_name.tx_which = ld_idx++;
  2926. ioctl(ttyfd, TXGETCD, &ld_name);
  2927. if (!strncmp(ld_name.tx_name, "rts", 3))
  2928. ttld |= 1;
  2929. } while (*ld_name.tx_name);
  2930. debug(F101,"AIX line discipline","",ttld);
  2931. }
  2932. #endif /* AIX41 */
  2933. #endif /* AIXRS */
  2934. #ifdef BSD41
  2935. /* For 4.1BSD only, force "old" tty driver, new one botches TANDEM. */
  2936. { int k;
  2937. ioctl(ttyfd, TIOCGETD, &ttld); /* Get and save line discipline */
  2938. debug(F101,"4.1bsd line discipline","",ttld);
  2939. k = OTTYDISC; /* Switch to "old" discipline */
  2940. k = ioctl(ttyfd, TIOCSETD, &k);
  2941. debug(F101,"4.1bsd tiocsetd","",k);
  2942. }
  2943. #endif /* BSD41 */
  2944. #ifdef aegis
  2945. /* This was previously done before the last two TCGETA or gtty above,
  2946. * in both the ATTSV and not-ATTSV case. If it is not okay to have only
  2947. * one copy if it here instead, give us a shout!
  2948. */
  2949. sio_$control((short)ttyfd, sio_$raw_nl, false, st);
  2950. if (xlocal) { /* ignore breaks from local line */
  2951. sio_$control((short)ttyfd, sio_$int_enable, false, st);
  2952. sio_$control((short)ttyfd, sio_$quit_enable, false, st);
  2953. }
  2954. #endif /* aegis */
  2955. #ifdef VXVE
  2956. ttraw.c_line = 0; /* STTY line 0 for VX/VE */
  2957. tttvt.c_line = 0; /* STTY line 0 for VX/VE */
  2958. ioctl(ttyfd,TCSETA,&ttraw);
  2959. #endif /* vxve */
  2960. /* If O_NDELAY was used during open(), then remove it now. */
  2961. #ifdef O_NDELAY
  2962. debug(F100,"ttopen O_NDELAY","",0);
  2963. if (xlocal > 0) {
  2964. if (fcntl(ttyfd, F_GETFL, 0) & O_NDELAY) {
  2965. debug(F100,"ttopen fcntl O_NDELAY","",0);
  2966. #ifndef aegis
  2967. if (fcntl(ttyfd,F_SETFL, fcntl(ttyfd, F_GETFL, 0) & ~O_NDELAY) < 0) {
  2968. debug(F100,"ttopen fcntl failure to unset O_NDELAY","",0);
  2969. perror("Can't unset O_NDELAY");
  2970. }
  2971. #endif /* aegis */
  2972. /* Some systems, notably Xenix (don't know how common this is in
  2973. * other systems), need special treatment to get rid of the O_NDELAY
  2974. * behaviour on read() with respect to carrier presence (i.e. read()
  2975. * returning 0 when carrier absent), even though the above fcntl()
  2976. * is enough to make read() wait for input when carrier is present.
  2977. * This magic, in turn, requires CLOCAL for working when the carrier
  2978. * is absent. But if xlocal == 0, presumably you already have CLOCAL
  2979. * or you have a carrier, otherwise you wouldn't be running this.
  2980. */
  2981. debug(F101,"ttopen xlocal","",xlocal);
  2982. #ifdef ATTSV
  2983. #ifdef BSD44ORPOSIX
  2984. #ifdef COMMENT /* 12 Aug 1997 */
  2985. #ifdef __bsdi__
  2986. if (xlocal)
  2987. ttraw.c_cflag |= CLOCAL;
  2988. #else
  2989. #ifdef __FreeBSD__
  2990. if (xlocal)
  2991. ttraw.c_cflag |= CLOCAL;
  2992. #endif /* __FreeBSD__ */
  2993. #endif /* __bsdi__ */
  2994. #else /* Not COMMENT */
  2995. #ifdef CLOCAL
  2996. if (xlocal) /* Unset this if it's defined. */
  2997. ttraw.c_cflag |= CLOCAL;
  2998. #endif /* CLOCAL */
  2999. #endif /* COMMENT */
  3000. debug(F101,"ttopen BSD44ORPOSIX calling tcsetattr","",TCSADRAIN);
  3001. if (tcsetattr(ttyfd, TCSADRAIN, &ttraw) < 0) {
  3002. debug(F100,"ttopen POSIX tcseattr fails","",0);
  3003. perror("tcsetattr");
  3004. }
  3005. #else /* !BSD44ORPOSIX */
  3006. if (xlocal) {
  3007. ttraw.c_cflag |= CLOCAL;
  3008. debug(F100,"ttopen calling ioctl(TCSETA)","",0);
  3009. errno = 0;
  3010. if (ioctl(ttyfd, TCSETA, &ttraw) < 0) {
  3011. debug(F101,"ttopen ioctl(TCSETA) fails","",errno);
  3012. perror("ioctl(TCSETA)");
  3013. }
  3014. }
  3015. #endif /* BSD44ORPOSIX */
  3016. #endif /* ATTSV */
  3017. #ifndef NOCOTFMC /* = NO Close(Open()) To Force Mode Change */
  3018. /* Reportedly lets uugetty grab the device in SCO UNIX 3.2 / XENIX 2.3 */
  3019. debug(F100,"ttopen executing close/open","",0);
  3020. close( priv_opn(fnam, O_RDWR) ); /* Magic to force change. */
  3021. #endif /* NOCOTFMC */
  3022. }
  3023. }
  3024. #endif /* O_NDELAY */
  3025. /* Instruct the system how to treat the carrier, and set a few other tty
  3026. * parameters.
  3027. *
  3028. * This also undoes the temporary setting of CLOCAL that may have been done
  3029. * for the close(open()) above (except in Xenix). Also throw in ~ECHO, to
  3030. * prevent the other end of the line from sitting there talking to itself,
  3031. * producing garbage when the user performs a connect.
  3032. *
  3033. * SCO Xenix unfortunately seems to ignore the actual state of CLOCAL.
  3034. * Now it thinks CLOCAL is always on. It seems the only real solution for
  3035. * Xenix is to switch between the lower and upper case device names.
  3036. *
  3037. * This section may at some future time expand into setting a complete
  3038. * collection of tty parameters, or call a function shared with ttpkt()/
  3039. * ttvt() that does so. On the other hand, the initial parameters are not
  3040. * that important, since ttpkt() or ttvt() should always fix that before
  3041. * any communication is done. Well, we'll see...
  3042. */
  3043. if (xlocal) {
  3044. curcarr = -2;
  3045. debug(F100,"ttopen calling carrctl","",0);
  3046. carrctl(&ttraw, ttcarr == CAR_ON);
  3047. debug(F100,"ttopen carrctl ok","",0);
  3048. #ifdef COHERENT
  3049. #define SVORPOSIX
  3050. #endif /* COHERENT */
  3051. #ifdef SVORPOSIX
  3052. ttraw.c_lflag &= ~ECHO;
  3053. ttold.c_lflag &= ~ECHO;
  3054. #ifdef BSD44ORPOSIX
  3055. y = tcsetattr(ttyfd, TCSADRAIN, &ttraw);
  3056. debug(F101,"ttopen tcsetattr","",y);
  3057. #else
  3058. y = ioctl(ttyfd, TCSETA, &ttraw);
  3059. debug(F100,"ttopen ioctl","",y);
  3060. #endif /* BSD44ORPOSIX */
  3061. #else /* BSD, etc */
  3062. ttraw.sg_flags &= ~ECHO;
  3063. ttold.sg_flags &= ~ECHO;
  3064. #ifdef BELLV10
  3065. y = ioctl(ttyfd,TIOCSETP,&ttraw);
  3066. debug(F100,"ttopen ioctl","",y);
  3067. #else
  3068. y = stty(ttyfd,&ttraw);
  3069. debug(F100,"ttopen stty","",y);
  3070. #endif /* BELLV10 */
  3071. #endif /* SVORPOSIX */
  3072. #ifdef COHERENT
  3073. #undef SVORPOSIX
  3074. #endif /* COHERENT */
  3075. /* ttflui(); */ /* This fails for some reason. */
  3076. }
  3077. /* Get current speed */
  3078. #ifndef BEBOX
  3079. ttspeed = ttgspd();
  3080. #else
  3081. ttspeed = 19200;
  3082. #endif /* !BEBOX */
  3083. debug(F101,"ttopen ttspeed","",ttspeed);
  3084. /* Done, make entries in debug log, restore Ctrl-C trap, and return. */
  3085. debug(F101,"ttopen ttyfd","",ttyfd);
  3086. debug(F101,"ttopen *lcl","",*lcl);
  3087. debug(F111,"ttopen lock file",flfnam,lkf);
  3088. signal(SIGINT,occt);
  3089. sigint_ign = (occt == SIG_IGN) ? 1 : 0;
  3090. gotsigs = 0;
  3091. return(0);
  3092. }
  3093. /* D O _ O P E N -- Do the right kind of open() call for the tty. */
  3094. int
  3095. do_open(ttname) char *ttname; {
  3096. int flags;
  3097. #ifdef QNX6
  3098. /* O_NONBLOCK on /dev/tty makes open() fail */
  3099. return(priv_opn(ttname, O_RDWR |
  3100. (
  3101. ((int)strcmp(ttname,"/dev/tty") == 0) ?
  3102. 0 :
  3103. (ttcarr != CAR_ON) ? O_NONBLOCK : 0)
  3104. )
  3105. );
  3106. #else /* !QNX6 */
  3107. #ifndef O_NDELAY /* O_NDELAY not defined */
  3108. return(priv_opn(ttname,2));
  3109. #else /* O_NDELAY defined */
  3110. #ifdef ATT7300
  3111. /*
  3112. Open comms line without waiting for carrier so initial call does not hang
  3113. because state of "modem" is likely unknown at the initial call -jrd.
  3114. If this is needed for the getty stuff to work, and the open would not work
  3115. without O_NDELAY when getty is still on, then this special case is ok.
  3116. Otherwise, get rid of it. -ske
  3117. */
  3118. return(priv_opn(ttname, O_RDWR | O_NDELAY));
  3119. #else /* !ATT7300 */
  3120. /* Normal case. Use O_NDELAY according to SET CARRIER. See ttscarr(). */
  3121. flags = O_RDWR;
  3122. debug(F101,"do_open xlocal","",xlocal);
  3123. debug(F111,"do_open flags A",ttname,flags);
  3124. if (xlocal && (ttcarr != CAR_ON))
  3125. flags |= O_NDELAY;
  3126. debug(F111,"do_open flags B",ttname,flags);
  3127. return(priv_opn(ttname, flags));
  3128. #endif /* !ATT7300 */
  3129. #endif /* O_NDELAY */
  3130. #endif /* QNX6 */
  3131. }
  3132. /* T T C L O S -- Close the TTY, releasing any lock. */
  3133. static int ttc_state = 0; /* ttclose() state */
  3134. static char * ttc_nam[] = { "setup", "hangup", "reset", "close" };
  3135. int
  3136. ttclos(foo) int foo; { /* Arg req'd for signal() prototype */
  3137. int xx, x = 0;
  3138. extern int exithangup;
  3139. debug(F101,"ttclos ttyfd","",ttyfd);
  3140. debug(F101,"ttclos netconn","",netconn);
  3141. debug(F101,"ttclos xlocal","",xlocal);
  3142. #ifdef NOFDZERO
  3143. debug(F100,"ttclos NOFDZERO","",0);
  3144. #endif /* NOFDZERO */
  3145. #ifdef COMMENT
  3146. #ifdef TTLEBUF
  3147. le_init(); /* No need for any of this */
  3148. #endif /* TTLEBUF */
  3149. #endif /* COMMENT */
  3150. if (ttyfd < 0) /* Wasn't open. */
  3151. return(0);
  3152. if (ttfdflg) /* If we inherited ttyfd from */
  3153. return(0); /* another process, don't close it. */
  3154. tvtflg = 0; /* (some day get rid of this...) */
  3155. gotsigs = 0;
  3156. #ifdef IKSD
  3157. if (inserver) {
  3158. #ifdef TNCODE
  3159. tn_push(); /* Place any waiting data into input*/
  3160. tn_sopt(DO,TELOPT_LOGOUT); /* Send LOGOUT option before close */
  3161. TELOPT_UNANSWERED_DO(TELOPT_LOGOUT) = 1;
  3162. tn_reset(); /* The Reset Telnet Option table. */
  3163. #endif /* TNCODE */
  3164. #ifdef CK_SSL
  3165. if (ssl_active_flag) {
  3166. if (ssl_debug_flag)
  3167. BIO_printf(bio_err,"calling SSL_shutdown(ssl)\n");
  3168. SSL_shutdown(ssl_con);
  3169. SSL_free(ssl_con);
  3170. ssl_con = NULL;
  3171. ssl_active_flag = 0;
  3172. }
  3173. if (tls_active_flag) {
  3174. if (ssl_debug_flag)
  3175. BIO_printf(bio_err,"calling SSL_shutdown(tls)\n");
  3176. SSL_shutdown(tls_con);
  3177. SSL_free(tls_con);
  3178. tls_con = NULL;
  3179. tls_active_flag = 0;
  3180. }
  3181. #endif /* CK_SSL */
  3182. }
  3183. #endif /* IKSD */
  3184. #ifdef NETCMD
  3185. if (ttpipe) { /* We've been using a pipe */
  3186. /* ttpipe = 0; */
  3187. if (ttpid > 0) {
  3188. int wstat;
  3189. int statusp;
  3190. close(fdin); /* Close these. */
  3191. close(fdout);
  3192. fdin = fdout = -1;
  3193. kill(ttpid,1); /* Kill fork with SIGHUP */
  3194. while (1) {
  3195. wstat = wait(&statusp);
  3196. if (wstat == ttpid || wstat == -1)
  3197. break;
  3198. pexitstat = (statusp & 0xff) ? statusp : statusp >> 8;
  3199. }
  3200. ttpid = 0;
  3201. }
  3202. netconn = 0;
  3203. wasclosed = 1;
  3204. ttyfd = -1;
  3205. return(0);
  3206. }
  3207. #endif /* NETCMD */
  3208. #ifdef NETPTY
  3209. if (ttpty) {
  3210. #ifndef NODOPTY
  3211. end_pty();
  3212. #endif /* NODOPTY */
  3213. close(ttyfd);
  3214. netconn = 0;
  3215. wasclosed = 1;
  3216. ttpty = 0;
  3217. ttyfd = -1;
  3218. return(0);
  3219. }
  3220. #endif /* NETPTY */
  3221. #ifdef NETCONN
  3222. if (netconn) { /* If it's a network connection. */
  3223. debug(F100,"ttclos closing net","",0);
  3224. netclos(); /* Let the network module close it. */
  3225. netconn = 0; /* No more network connection. */
  3226. debug(F101,"ttclos ttyfd after netclos","",ttyfd); /* Should be -1 */
  3227. return(0);
  3228. }
  3229. #endif /* NETCONN */
  3230. if (xlocal) { /* We're closing a SET LINE device */
  3231. #ifdef FT21 /* Fortune 2.1-specific items ... */
  3232. ioctl(ttyfd,TIOCHPCL, NULL);
  3233. #endif /* FT21 */
  3234. #ifdef ultrix /* Ultrix-specific items ... */
  3235. #ifdef TIOCSINUSE
  3236. /* Unset the INUSE flag that we set in ttopen() */
  3237. ioctl(ttyfd, TIOCSINUSE, NULL);
  3238. #endif /* TIOCSINUSE */
  3239. ioctl(ttyfd, TIOCNMODEM, &x);
  3240. #ifdef COMMENT
  3241. /* What was this? */
  3242. ioctl(ttyfd, TIOCNCAR, NULL);
  3243. #endif /* COMMENT */
  3244. #endif /* ultrix */
  3245. }
  3246. /* This is to prevent us from sticking in tthang() or close(). */
  3247. #ifdef O_NDELAY
  3248. #ifndef aegis
  3249. if (ttyfd > 0) { /* But skip it on stdin. */
  3250. debug(F100,"ttclos setting O_NDELAY","",0);
  3251. x = fcntl(ttyfd,F_SETFL,fcntl(ttyfd,F_GETFL, 0)|O_NDELAY);
  3252. #ifdef DEBUG
  3253. if (deblog && x == -1) {
  3254. perror("Warning - Can't set O_NDELAY");
  3255. debug(F101,"ttclos fcntl failure to set O_NDELAY","",x);
  3256. }
  3257. #endif /* DEBUG */
  3258. }
  3259. #endif /* aegis */
  3260. #endif /* O_NDELAY */
  3261. x = 0;
  3262. ttc_state = 0;
  3263. if (xlocal
  3264. #ifdef NOFDZERO
  3265. || ttyfd > 0
  3266. #endif /* NOFDZERO */
  3267. ) {
  3268. saval = signal(SIGALRM,xtimerh); /* Enable timer interrupt. */
  3269. xx = alarm(8); /* Allow 8 seconds. */
  3270. debug(F101,"ttclos alarm","",xx);
  3271. if (
  3272. #ifdef CK_POSIX_SIG
  3273. sigsetjmp(sjbuf,1)
  3274. #else
  3275. setjmp(sjbuf)
  3276. #endif /* CK_POSIX_SIG */
  3277. ) { /* Timer went off? */
  3278. x = -1;
  3279. #ifdef DEBUG
  3280. debug(F111,"ttclos ALARM TRAP errno",ckitoa(ttc_state),errno);
  3281. printf("ttclos() timeout: %s\n", ttc_nam[ttc_state]);
  3282. #endif /* DEBUG */
  3283. }
  3284. /* Hang up the device (drop DTR) */
  3285. errno = 0;
  3286. debug(F111,"ttclos A",ckitoa(x),ttc_state);
  3287. if (ttc_state < 1) {
  3288. ttc_state = 1;
  3289. debug(F101,"ttclos exithangup","",exithangup);
  3290. if (exithangup) {
  3291. alarm(8); /* Re-arm the timer */
  3292. debug(F101,"ttclos calling tthang()","",x);
  3293. x = tthang(); /* Hang up first, then... */
  3294. debug(F101,"ttclos tthang()","",x);
  3295. }
  3296. #ifndef CK_NOHUPCL
  3297. /*
  3298. Oct 2006 - Leave DTR on if SET EXIT HANGUP OFF.
  3299. Suggested by Soewono Effendi.
  3300. */
  3301. #ifdef HUPCL
  3302. else {
  3303. ttold.c_cflag &= ~HUPCL; /* Let's see how this travels */
  3304. #ifdef BSD44ORPOSIX
  3305. tcsetattr(ttyfd,TCSANOW,&ttold);
  3306. #else /* !BSD44ORPOSIX */
  3307. #ifdef ATTSV
  3308. ioctl(ttyfd,TCSETAW,&ttold);
  3309. #else /* !ATTSV */
  3310. stty(ttyfd,&ttold);
  3311. #endif /* ATTSV */
  3312. #endif /* BSD44ORPOSIX */
  3313. }
  3314. #endif /* HUPCL */
  3315. #endif /* CK_NOHUPCL */
  3316. }
  3317. /* Put back device modes as we found them */
  3318. errno = 0;
  3319. debug(F111,"ttclos B",ckitoa(x),ttc_state);
  3320. if (ttc_state < 2) {
  3321. ttc_state = 2;
  3322. /* Don't try to mess with tty modes if tthang failed() */
  3323. /* since it probably won't work. */
  3324. if (x > -1) {
  3325. debug(F101,"ttclos calling ttres()","",x);
  3326. signal(SIGALRM,xtimerh); /* Re-enable the alarm. */
  3327. alarm(8); /* Re-arm the timer */
  3328. x = ttres(); /* Reset device modes. */
  3329. debug(F101,"ttclos ttres()","",x);
  3330. alarm(0);
  3331. }
  3332. }
  3333. /* Close the device */
  3334. errno = 0;
  3335. debug(F101,"ttclos C","",ttc_state);
  3336. if (ttc_state < 3) {
  3337. ttc_state = 3;
  3338. errno = 0;
  3339. debug(F101,"ttclos calling close","",x);
  3340. signal(SIGALRM,xtimerh); /* Re-enable alarm. */
  3341. alarm(8); /* Re-arm the timer */
  3342. x = close(ttyfd); /* Close the device. */
  3343. debug(F101,"ttclos close()","",x);
  3344. if (x > -1)
  3345. ttc_state = 3;
  3346. }
  3347. debug(F101,"ttclos D","",ttc_state);
  3348. ttimoff(); /* Turn off timer. */
  3349. if (x < 0) {
  3350. printf("?WARNING - close failed: %s\n",ttnmsv);
  3351. #ifdef DEBUG
  3352. if (deblog) {
  3353. printf("errno = %d\n", errno);
  3354. debug(F101,"ttclos failed","",errno);
  3355. }
  3356. #endif /* DEBUG */
  3357. }
  3358. /* Unlock after closing but before any getty mumbo jumbo */
  3359. debug(F100,"ttclos about to call ttunlck","",0);
  3360. if (ttunlck()) /* Release uucp-style lock */
  3361. fprintf(stderr,"Warning, problem releasing lock\r\n");
  3362. }
  3363. /* For bidirectional lines, restore getty if it was there before. */
  3364. #ifdef ACUCNTRL /* 4.3BSD acucntrl() method. */
  3365. if (xlocal) {
  3366. debug(F100,"ttclos ACUCNTRL","",0);
  3367. acucntrl("enable",ttnmsv); /* Enable getty on the device. */
  3368. }
  3369. #else
  3370. #ifdef ATT7300 /* ATT UNIX PC (3B1, 7300) method. */
  3371. if (xlocal) {
  3372. debug(F100,"ttclos ATT7300 ongetty","",0);
  3373. if (attmodem & DOGETY) /* Was getty(1m) running before us? */
  3374. ongetty(ttnmsv); /* Yes, restart getty on tty line */
  3375. attmodem &= ~DOGETY; /* No phone in use, getty restored */
  3376. }
  3377. #endif /* ATT7300 */
  3378. #endif /* System-dependent getty-restoring methods */
  3379. #ifdef sony_news
  3380. km_ext = -1; /* Invalidate device's Kanji-mode */
  3381. #endif /* sony_news */
  3382. ttyfd = -1; /* Invalidate the file descriptor. */
  3383. wasclosed = 1;
  3384. debug(F100,"ttclos done","",0);
  3385. return(0);
  3386. }
  3387. /* T T H A N G -- Hangup phone line or network connection. */
  3388. /*
  3389. Returns:
  3390. 0 if it does nothing.
  3391. 1 if it believes that it hung up successfully.
  3392. -1 if it believes that the hangup attempt failed.
  3393. */
  3394. #define HUPTIME 500 /* Milliseconds for hangup */
  3395. #ifdef COMMENT
  3396. /* The following didn't work but TIOCSDTR does work */
  3397. #ifdef UNIXWARE
  3398. /* Define HUP_POSIX to force non-POSIX builds to use the POSIX hangup method */
  3399. #ifndef POSIX /* Such as Unixware 1.x, 2.x */
  3400. #ifndef HUP_POSIX
  3401. #define HUP_POSIX
  3402. #endif /* HUP_POSIX */
  3403. #endif /* POSIX */
  3404. #endif /* UNIXWARE */
  3405. #endif /* COMMENT */
  3406. #ifndef USE_TIOCSDTR
  3407. #ifdef __NetBSD__
  3408. /* Because the POSIX method (set output speed to 0) doesn't work in NetBSD */
  3409. #ifdef TIOCSDTR
  3410. #ifdef TIOCCDTR
  3411. #define USE_TIOCSDTR
  3412. #endif /* TIOCCDTR */
  3413. #endif /* TIOCSDTR */
  3414. #endif /* __NetBSD__ */
  3415. #endif /* USE_TIOCSDTR */
  3416. #ifndef HUP_CLOSE_POSIX
  3417. #ifdef OU8
  3418. #define HUP_CLOSE_POSIX
  3419. #else
  3420. #ifdef CK_SCOV5
  3421. #define HUP_CLOSE_POSIX
  3422. #endif /* CK_SCOV5 */
  3423. #endif /* OU8 */
  3424. #endif /* HUP_CLOSE_POSIX */
  3425. #ifdef NO_HUP_CLOSE_POSIX
  3426. #ifdef HUP_CLOSE_POSIX
  3427. #undef HUP_CLOSE_POSIX
  3428. #endif /* HUP_CLOSE_POSIX */
  3429. #endif /* NO_HUP_CLOSE_POSIX */
  3430. int
  3431. tthang() {
  3432. #ifdef NOLOCAL
  3433. return(0);
  3434. #else
  3435. int x = 0; /* Sometimes used as return code. */
  3436. #ifndef POSIX
  3437. int z; /* worker */
  3438. #endif /* POSIX */
  3439. #ifdef COHERENT
  3440. #define SVORPOSIX
  3441. #endif /* COHERENT */
  3442. #ifdef SVORPOSIX /* AT&T, POSIX, HPUX declarations. */
  3443. int spdsav; /* for saving speed */
  3444. #ifdef HUP_POSIX
  3445. int spdsavi;
  3446. #else
  3447. #ifdef BSD44ORPOSIX
  3448. int spdsavi;
  3449. #endif /* BSD44ORPOSIX */
  3450. #endif /* HUP_POSIX */
  3451. #ifdef HPUX
  3452. /*
  3453. Early versions of HP-UX omitted the mflag typedef. If you get complaints
  3454. about it, just change it to long (or better still, unsigned long).
  3455. */
  3456. mflag
  3457. dtr_down = 00000000000,
  3458. modem_rtn,
  3459. modem_sav;
  3460. char modem_state[64];
  3461. #endif /* HPUX */
  3462. int flags; /* fcntl flags */
  3463. unsigned short ttc_save;
  3464. #endif /* SVORPOSIX */
  3465. if (ttyfd < 0) return(0); /* Don't do this if not open */
  3466. if (xlocal < 1) return(0); /* Don't do this if not local */
  3467. #ifdef NETCMD
  3468. if (ttpipe)
  3469. return((ttclos(0) < 0) ? -1 : 1);
  3470. #endif /* NETCMD */
  3471. #ifdef NETPTY
  3472. if (ttpty)
  3473. return((ttclos(0) < 0) ? -1 : 1);
  3474. #endif /* NETPTY */
  3475. #ifdef NETCONN
  3476. if (netconn) { /* Network connection. */
  3477. #ifdef TN_COMPORT
  3478. if (istncomport()) {
  3479. int rc = tnc_set_dtr_state(0);
  3480. if (rc >= 0) {
  3481. msleep(HUPTIME);
  3482. rc = tnc_set_dtr_state(1);
  3483. }
  3484. return(rc >= 0 ? 1 : -1);
  3485. } else
  3486. #endif /* TN_COMPORT */
  3487. return((netclos() < 0) ? -1 : 1); /* Just close it. */
  3488. }
  3489. #endif /* NETCONN */
  3490. /* From here down, we handle real tty devices. */
  3491. #ifdef HUP_POSIX
  3492. /*
  3493. e.g. for Unixware 2, where we don't have a full POSIX build, we
  3494. still have to use POSIX-style hangup. Thus the duplication of this
  3495. and the next case, the only difference being we use a local termios
  3496. struct here, since a different model is used elsewhere.
  3497. NO LONGER USED as of C-Kermit 8.0 -- it turns out that this method,
  3498. even though it compiles and executes without error, doesn't actually
  3499. work (i.e. DTR does not drop), whereas the TIOCSDTR method works just fine,
  3500. */
  3501. {
  3502. struct termios ttcur;
  3503. int x;
  3504. debug(F100,"tthang HUP_POSIX style","",0);
  3505. x = tcgetattr(ttyfd, &ttcur); /* Get current attributes */
  3506. debug(F111,"tthang tcgetattr",ckitoa(errno),x);
  3507. if (x < 0) return(-1);
  3508. spdsav = cfgetospeed(&ttcur); /* Get current speed */
  3509. debug(F111,"tthang cfgetospeed",ckitoa(errno),spdsav);
  3510. spdsavi = cfgetispeed(&ttcur); /* Get current speed */
  3511. debug(F111,"tthang cfgetispeed",ckitoa(errno),spdsavi);
  3512. x = cfsetospeed(&ttcur,B0); /* Replace by 0 */
  3513. debug(F111,"tthang cfsetospeed",ckitoa(errno),x);
  3514. if (x < 0) return(-1);
  3515. x = cfsetispeed(&ttcur,B0);
  3516. debug(F111,"tthang cfsetispeed",ckitoa(errno),x);
  3517. if (x < 0) return(-1);
  3518. x = tcsetattr(ttyfd,TCSADRAIN,&ttcur);
  3519. debug(F111,"tthang tcsetattr B0",ckitoa(errno),x);
  3520. if (x < 0) return(-1);
  3521. msleep(HUPTIME); /* Sleep 0.5 sec */
  3522. x = cfsetospeed(&ttcur,spdsav); /* Restore prev speed */
  3523. if (x < 0) return(-1);
  3524. debug(F111,"tthang cfsetospeed prev",ckitoa(errno),x);
  3525. x = cfsetispeed(&ttcur,spdsavi);
  3526. debug(F111,"tthang cfsetispeed prev",ckitoa(errno),x);
  3527. if (x < 0) return(-1);
  3528. x = tcsetattr(ttyfd,TCSADRAIN,&ttcur);
  3529. debug(F111,"tthang tcsetattr restore",ckitoa(errno),x);
  3530. if (x < 0) return(-1);
  3531. return(1);
  3532. }
  3533. #else
  3534. #ifdef BSD44ORPOSIX
  3535. #ifdef QNX
  3536. {
  3537. int x;
  3538. x = tcdropline(ttyfd,500);
  3539. debug(F101,"tthang QNX tcdropline","",x);
  3540. ttcur.c_cflag |= CLOCAL;
  3541. x = tcsetattr(ttyfd,TCSADRAIN,&ttcur);
  3542. debug(F101,"tthang QNX tcsetattr restore","",x);
  3543. if (x < 0) {
  3544. debug(F101,"tthang QNX tcsetattr restore errno","",errno);
  3545. return(-1);
  3546. }
  3547. /* Fix flags - ensure O_NONBLOCK is off */
  3548. errno = 0;
  3549. debug(F101,"tthang QNX iniflags","",iniflags);
  3550. if (fcntl(ttyfd, F_SETFL, iniflags) == -1) {
  3551. debug(F101,"tthang QNX F_SETFL errno","",errno);
  3552. return(-1);
  3553. }
  3554. return(x);
  3555. }
  3556. #else /* QNX */
  3557. {
  3558. int x;
  3559. #ifdef USE_TIOCSDTR
  3560. debug(F100,"tthang BSD44ORPOSIX USE_TIOCSDTR","",0);
  3561. errno = 0;
  3562. x = ioctl(ttyfd, TIOCCDTR, NULL);
  3563. debug(F111,"tthang BSD44ORPOSIX ioctl TIOCCDTR",ckitoa(errno),x);
  3564. if (x < 0) return(-1);
  3565. msleep(HUPTIME); /* Sleep 0.5 sec */
  3566. errno = 0;
  3567. x = ioctl(ttyfd, TIOCSDTR, NULL);
  3568. debug(F111,"tthang BSD44ORPOSIX ioctl TIOCSDTR",ckitoa(errno),x);
  3569. if (x < 0) return(-1);
  3570. #else /* USE_TIOCSDTR */
  3571. #ifdef HUP_CLOSE_POSIX
  3572. /*
  3573. In OSR5 versions where TIOCSDTR is not defined (up to and including at
  3574. least 5.0.6a) the POSIX APIs in the "#else" part below are available but
  3575. don't work, and no other APIs are available that do work. In this case
  3576. we have to drop DTR by brute force: close and reopen the port. This
  3577. code actually works, but all the steps are crucial: setting CLOCAL, the
  3578. O_NDELAY manipulations, etc.
  3579. */
  3580. debug(F100,"tthang HUP_CLOSE_POSIX close/open","",0);
  3581. debug(F101,"tthang HUP_CLOSE_POSIX O_NONBLOCK","",O_NONBLOCK);
  3582. debug(F101,"tthang HUP_CLOSE_POSIX O_NDELAY","",O_NDELAY);
  3583. errno = 0;
  3584. x = tcgetattr(ttyfd, &ttcur); /* Get current attributes */
  3585. debug(F101,"tthang HUP_CLOSE_POSIX tcgetattr","",x);
  3586. if (x < 0) {
  3587. debug(F101,"tthang HUP_CLOSE_POSIX tcgetattr errno","",errno);
  3588. return(-1);
  3589. }
  3590. errno = 0;
  3591. x = close(ttyfd); /* Close without releasing lock */
  3592. if (x < 0) {
  3593. debug(F101,"tthang HUP_CLOSE_POSIX close errno","",errno);
  3594. return(-1);
  3595. }
  3596. errno = 0;
  3597. x = msleep(500); /* Pause half a second */
  3598. if (x < 0) { /* Or if that doesn't work, 1 sec */
  3599. debug(F101,"tthang HUP_CLOSE_POSIX msleep errno","",errno);
  3600. sleep(1);
  3601. }
  3602. errno = 0;
  3603. ttyfd = priv_opn(ttnmsv, (O_RDWR|O_NDELAY)); /* Reopen the device */
  3604. debug(F111,"tthang HUP_CLOSE_POSIX reopen",ttnmsv,ttyfd);
  3605. if (ttyfd < 0) {
  3606. debug(F101,"tthang HUP_CLOSE_POSIX reopen errno","",errno);
  3607. return(-1);
  3608. }
  3609. debug(F101,"tthang HUP_CLOSE_POSIX re-ttopen ttyfd","",ttyfd);
  3610. /* Restore previous attributes */
  3611. errno = 0;
  3612. tvtflg = 0;
  3613. ttcur.c_cflag |= CLOCAL;
  3614. x = tcsetattr(ttyfd,TCSADRAIN,&ttcur);
  3615. debug(F101,"tthang HUP_CLOSE_POSIX tcsetattr restore","",x);
  3616. if (x < 0) {
  3617. debug(F101,"tthang HUP_CLOSE_POSIX tcsetattr restore errno",
  3618. "",errno);
  3619. return(-1);
  3620. }
  3621. /* Fix flags - ensure O_NDELAY and O_NONBLOCK are off */
  3622. errno = 0;
  3623. if ((x = fcntl(ttyfd, F_GETFL, 0)) == -1) {
  3624. debug(F101,"tthang HUP_CLOSE_POSIX F_GETFL errno","",errno);
  3625. return(-1);
  3626. }
  3627. debug(F101,"tthang HUP_CLOSE_POSIX flags","",x);
  3628. errno = 0;
  3629. x &= ~(O_NONBLOCK|O_NDELAY);
  3630. debug(F101,"tthang HUP_CLOSE_POSIX flags to set","",x);
  3631. debug(F101,"tthang HUP_CLOSE_POSIX iniflags","",iniflags);
  3632. if (fcntl(ttyfd, F_SETFL, x) == -1) {
  3633. debug(F101,"tthang HUP_CLOSE_POSIX F_SETFL errno","",errno);
  3634. return(-1);
  3635. }
  3636. #ifdef DEBUG
  3637. if (deblog) {
  3638. if ((x = fcntl(ttyfd, F_GETFL, 0)) > -1) {
  3639. debug(F101,"tthang HUP_CLOSE_POSIX flags","",x);
  3640. debug(F101,"tthang HUP_CLOSE_POSIX flags & O_NONBLOCK",
  3641. "",x&O_NONBLOCK);
  3642. debug(F101,"tthang HUP_CLOSE_POSIX flags & O_NDELAY",
  3643. "",x&O_NDELAY);
  3644. }
  3645. }
  3646. #endif /* DEBUG */
  3647. #else /* HUP_CLOSE_POSIX */
  3648. /* General BSD44ORPOSIX case (Linux, BSDI, FreeBSD, etc) */
  3649. debug(F100,"tthang BSD44ORPOSIX B0","",0);
  3650. x = tcgetattr(ttyfd, &ttcur); /* Get current attributes */
  3651. debug(F111,"tthang BSD44ORPOSIX tcgetattr",ckitoa(errno),x);
  3652. if (x < 0) return(-1);
  3653. spdsav = cfgetospeed(&ttcur); /* Get current speed */
  3654. debug(F111,"tthang BSD44ORPOSIX cfgetospeed",ckitoa(errno),spdsav);
  3655. spdsavi = cfgetispeed(&ttcur); /* Get current speed */
  3656. debug(F111,"tthang BSD44ORPOSIX cfgetispeed",ckitoa(errno),spdsavi);
  3657. x = cfsetospeed(&ttcur,B0); /* Replace by 0 */
  3658. debug(F111,"tthang BSD44ORPOSIX cfsetospeed",ckitoa(errno),x);
  3659. if (x < 0) return(-1);
  3660. x = cfsetispeed(&ttcur,B0);
  3661. debug(F111,"tthang BSD44ORPOSIX cfsetispeed",ckitoa(errno),x);
  3662. if (x < 0) return(-1);
  3663. /* This gets EINVAL on NetBSD 1.4.1 because of B0... */
  3664. x = tcsetattr(ttyfd,TCSADRAIN,&ttcur);
  3665. debug(F111,"tthang BSD44ORPOSIX tcsetattr B0",ckitoa(errno),x);
  3666. if (x < 0) return(-1);
  3667. msleep(HUPTIME); /* Sleep 0.5 sec */
  3668. debug(F101,"tthang BSD44ORPOSIX restore output speed","",spdsav);
  3669. x = cfsetospeed(&ttcur,spdsav); /* Restore prev speed */
  3670. debug(F111,"tthang BSD44ORPOSIX cfsetospeed prev",ckitoa(errno),x);
  3671. if (x < 0) return(-1);
  3672. debug(F101,"tthang BSD44ORPOSIX restore input speed","",spdsavi);
  3673. x = cfsetispeed(&ttcur,spdsavi);
  3674. debug(F111,"tthang BSD44ORPOSIX cfsetispeed prev",ckitoa(errno),x);
  3675. if (x < 0) return(-1);
  3676. ttcur.c_cflag |= CLOCAL; /* Don't expect CD after hangup */
  3677. x = tcsetattr(ttyfd,TCSADRAIN,&ttcur);
  3678. debug(F111,"tthang BSD44ORPOSIX tcsetattr restore",ckitoa(errno),x);
  3679. if (x < 0) return(-1);
  3680. #endif /* HUP_CLOSE_POSIX */
  3681. #endif /* USE_TIOCSDTR */
  3682. return(1);
  3683. }
  3684. #endif /* QNX */
  3685. #else /* BSD44ORPOSIX */
  3686. #ifdef aegis /* Apollo Aegis */
  3687. sio_$control((short)ttyfd, sio_$dtr, false, st); /* DTR down */
  3688. msleep(HUPTIME); /* pause */
  3689. sio_$control((short)ttyfd, sio_$dtr, true, st); /* DTR up */
  3690. return(1);
  3691. #endif /* aegis */
  3692. #ifdef ANYBSD /* Any BSD version. */
  3693. #ifdef TIOCCDTR /* Except those that don't have this */
  3694. debug(F100,"tthang BSD style","",0);
  3695. if (ioctl(ttyfd,TIOCCDTR,0) < 0) { /* Clear DTR. */
  3696. debug(F101,"tthang TIOCCDTR fails","",errno);
  3697. return(-1);
  3698. }
  3699. msleep(HUPTIME); /* For about 1/2 sec */
  3700. errno = 0;
  3701. x = ioctl(ttyfd,TIOCSDTR,0); /* Restore DTR */
  3702. if (x < 0) {
  3703. /*
  3704. For some reason, this tends to fail with "no such device or address"
  3705. but the operation still works, probably because of the close/open
  3706. later on. So let's not scare the user unnecessarily here.
  3707. */
  3708. debug(F101,"tthang TIOCSDTR errno","",errno); /* Log the error */
  3709. x = 1; /* Pretend we succeeded */
  3710. } else if (x == 0) x = 1; /* Success */
  3711. #ifdef COMMENT
  3712. #ifdef FT21
  3713. ioctl(ttyfd, TIOCSAVEMODES, 0);
  3714. ioctl(ttyfd, TIOCHPCL, 0);
  3715. close(ttyfd); /* Yes, must do this twice */
  3716. if ((ttyfd = open(ttnmsv,2)) < 0) /* on Fortune computers... */
  3717. return(-1); /* (but why?) */
  3718. else x = 1;
  3719. #endif /* FT21 */
  3720. #endif /* COMMENT */
  3721. #endif /* TIOCCDTR */
  3722. close(do_open(ttnmsv)); /* Clear i/o error condition */
  3723. errno = 0;
  3724. #ifdef COMMENT
  3725. /* This is definitely dangerous. Why was it here? */
  3726. z = ttvt(ttspeed,ttflow); /* Restore modes. */
  3727. debug(F101,"tthang ttvt returns","",z);
  3728. return(z < 0 ? -1 : 1);
  3729. #else
  3730. return(x);
  3731. #endif /* COMMENT */
  3732. #endif /* ANYBSD */
  3733. #ifdef ATTSV
  3734. /* AT&T UNIX section, includes HP-UX and generic AT&T System III/V... */
  3735. #ifdef HPUX
  3736. /* Hewlett Packard allows explicit manipulation of modem signals. */
  3737. #ifdef COMMENT
  3738. /* Old way... */
  3739. debug(F100,"tthang HP-UX style","",0);
  3740. if (ioctl(ttyfd,MCSETAF,&dtr_down) < 0) /* lower DTR */
  3741. return(-1); /* oops, can't. */
  3742. msleep(HUPTIME); /* Pause half a second. */
  3743. x = 1; /* Set return code */
  3744. if (ioctl(ttyfd,MCGETA,&modem_rtn) > -1) { /* Get line status. */
  3745. if ((modem_rtn & MDCD) != 0) /* Check if CD is low. */
  3746. x = -1; /* CD didn't drop, fail. */
  3747. } else x = -1;
  3748. /* Even if above calls fail, RTS & DTR should be turned back on. */
  3749. modem_rtn = MRTS | MDTR;
  3750. if (ioctl(ttyfd,MCSETAF,&modem_rtn) < 0) x = -1;
  3751. return(x);
  3752. #else
  3753. /* New way, from Hellmuth Michaelis */
  3754. debug(F100,"tthang HP-UX style, HPUXDEBUG","",0);
  3755. if (ioctl(ttyfd,MCGETA,&modem_rtn) == -1) { /* Get current status. */
  3756. debug(F100,"tthang HP-UX: can't get modem lines, NO HANGUP!","",0);
  3757. return(-1);
  3758. }
  3759. sprintf(modem_state,"%#lx",modem_rtn);
  3760. debug(F110,"tthang HP-UX: modem lines = ",modem_state,0);
  3761. modem_sav = modem_rtn; /* Save current modem signals */
  3762. modem_rtn &= ~MDTR; /* Turn DTR bit off */
  3763. sprintf(modem_state,"%#lx",modem_rtn);
  3764. debug(F110,"tthang HP-UX: DTR down = ",modem_state,0);
  3765. if (ioctl(ttyfd,MCSETAF,&modem_rtn) < 0) { /* lower DTR */
  3766. debug(F100,"tthang HP-UX: can't lower DTR!","",0);
  3767. return(-1); /* oops, can't. */
  3768. }
  3769. msleep(HUPTIME); /* Pause half a second. */
  3770. x = 1; /* Set return code */
  3771. if (ioctl(ttyfd,MCGETA,&modem_rtn) > -1) { /* Get line status. */
  3772. sprintf(modem_state,"%#lx",modem_rtn);
  3773. debug(F110,"tthang HP-UX: modem lines got = ",modem_state,0);
  3774. if ((modem_rtn & MDCD) != 0) { /* Check if CD is low. */
  3775. debug(F100,"tthang HP-UX: DCD not down","",0);
  3776. x = -1; /* CD didn't drop, fail. */
  3777. } else {
  3778. debug(F100,"tthang HP-UX: DCD down","",0);
  3779. }
  3780. } else {
  3781. x = -1;
  3782. debug(F100,"tthang HP-UX: can't get DCD status !","",0);
  3783. }
  3784. /* Even if above calls fail, DTR should be turned back on. */
  3785. modem_sav |= MDTR;
  3786. if (ioctl(ttyfd,MCSETAF,&modem_sav) < 0) {
  3787. x = -1;
  3788. debug(F100,"tthang HP-UX: can't set saved state","",0);
  3789. } else {
  3790. sprintf(modem_state,"%#lx",modem_sav);
  3791. debug(F110,"tthang HP-UX: final modem lines = ",modem_state,0);
  3792. }
  3793. return(x);
  3794. #endif /* COMMENT */
  3795. #else /* AT&T but not HP-UX */
  3796. /* SVID for AT&T System V R3 defines ioctl's for handling modem signals. */
  3797. /* It is not known how many, if any, systems actually implement them, */
  3798. /* so we include them here in ifdef's. */
  3799. /*
  3800. Unixware has the TIOCMxxx symbols defined, but calling ioctl() with them
  3801. gives error 22 (invalid argument).
  3802. */
  3803. #ifndef _IBMR2
  3804. /*
  3805. No modem-signal twiddling for IBM RT PC or RS/6000.
  3806. In AIX 3.1 and earlier, the ioctl() call is broken.
  3807. This code could be activated for AIX 3.1 with PTF 2006 or later
  3808. (e.g. AIX 3.2), but close/open does the job too, so why bother.
  3809. */
  3810. #ifdef TIOCMBIS /* Bit Set */
  3811. #ifdef TIOCMBIC /* Bit Clear */
  3812. #ifdef TIOCM_DTR /* DTR */
  3813. /* Clear DTR, sleep 300 msec, turn it back on. */
  3814. /* If any of the ioctl's return failure, go on to the next section. */
  3815. z = TIOCM_DTR; /* Code for DTR. */
  3816. #ifdef COMMENT
  3817. /*
  3818. This was the cause of the troubles with the Solaris Port Monitor.
  3819. The problem is: RTS never comes back on. Moral: Don't do it!
  3820. (But why doesn't it come back on? See the TIOCMBIS call...)
  3821. */
  3822. #ifdef TIOCM_RTS /* Lower RTS too if symbol is known. */
  3823. z |= TIOCM_RTS;
  3824. #endif /* TIOCM_RTS */
  3825. #endif /* COMMENT */
  3826. debug(F101,"tthang TIOCM signal mask","",z);
  3827. if (ioctl(ttyfd,TIOCMBIC,&z) > -1) { /* Try to lower DTR. */
  3828. debug(F100,"tthang TIOCMBIC ok","",0);
  3829. msleep(HUPTIME); /* Pause half a second. */
  3830. if (ioctl(ttyfd,TIOCMBIS,&z) > -1) { /* Try to turn it back on. */
  3831. debug(F100,"tthang TIOCMBIS ok","",0);
  3832. #ifndef CLSOPN
  3833. return(1); /* Success, done. */
  3834. #endif /* CLSOPN */
  3835. } else { /* Couldn't raise, continue. */
  3836. debug(F101,"tthang TIOCMBIS errno","",errno);
  3837. }
  3838. } else { /* Couldn't lower, continue. */
  3839. debug(F101,"tthang TIOCMBIC errno","",errno);
  3840. }
  3841. #endif /* TIOCM_DTR */
  3842. #endif /* TIOCMBIC */
  3843. #endif /* TIOCMBIS */
  3844. #endif /* _IBMR2 */
  3845. /*
  3846. General AT&T UNIX case, not HPUX. The following code is highly suspect. No
  3847. two AT&T-based systems seem to do this the same way. The object is simply
  3848. to turn off DTR and then turn it back on. SVID says the universal method
  3849. for turning off DTR is to set the speed to zero, and this does seem to do
  3850. the trick in all cases. But neither SVID nor any known man pages say how to
  3851. turn DTR back on again. Some variants, like most Xenix implementations,
  3852. raise DTR again when the speed is restored to a nonzero value. Others
  3853. require the device to be closed and opened again, but this is risky because
  3854. getty could seize the device during the instant it is closed.
  3855. */
  3856. /* Return code for ioctl failures... */
  3857. #ifdef ATT6300
  3858. x = 1; /* ATT6300 doesn't want to fail... */
  3859. #else
  3860. x = -1;
  3861. #endif /* ATT6300 */
  3862. debug(F100,"tthang get settings","",0);
  3863. if (ioctl(ttyfd,TCGETA,&ttcur) < 0) /* Get current settings. */
  3864. return(x); /* Fail if this doesn't work. */
  3865. if ((flags = fcntl(ttyfd,F_GETFL,0)) < 0) /* Get device flags. */
  3866. return(x);
  3867. ttc_save = ttcur.c_cflag; /* Remember current speed. */
  3868. spdsav = ttc_save & CBAUD;
  3869. debug(F101,"tthang speed","",spdsav);
  3870. #ifdef O_NDELAY
  3871. debug(F100,"tthang turning O_NDELAY on","",0);
  3872. fcntl(ttyfd, F_SETFL, flags | O_NDELAY); /* Activate O_NDELAY */
  3873. #endif /* O_NDELAY */
  3874. #ifdef ATT7300 /* This is the way it is SUPPOSED to work */
  3875. ttcur.c_cflag &= ~CBAUD; /* Change the speed to zero. */
  3876. #else
  3877. #ifdef RTAIX
  3878. ttcur.c_cflag &= ~CBAUD; /* Change the speed to zero. */
  3879. #else /* This way really works but may be dangerous */
  3880. #ifdef u3b2
  3881. ttcur.c_cflag = ~(CBAUD|CLOCAL); /* Special for AT&T 3B2s */
  3882. /* (CLOCAL must be OFF) */
  3883. #else
  3884. #ifdef SCO3R2 /* SCO UNIX 3.2 */
  3885. /*
  3886. This is complete nonsense, but an SCO user claimed this change made
  3887. hanging up work. Comments from other SCO UNIX 3.2 users would be
  3888. appreciated.
  3889. */
  3890. ttcur.c_cflag = CBAUD|B0;
  3891. #else
  3892. #ifdef AIXRS /* AIX on RS/6000 */
  3893. /*
  3894. Can't set speed to zero on AIX 3.1 on RS/6000 64-port adapter,
  3895. even though you can do it on the built-in port and the 8- and 16-port
  3896. adapters. (Untested on 128-port adapter.)
  3897. */
  3898. ttcur.c_cflag = CLOCAL|HUPCL|spdsav; /* Speed 0 causes EINVAL */
  3899. #else /* None of the above */
  3900. /*
  3901. Set everything, including the speed, to zero, except for the CLOCAL
  3902. and HUPCL bits.
  3903. */
  3904. ttcur.c_cflag = CLOCAL|HUPCL;
  3905. #endif /* AIXRS */
  3906. #endif /* SCO3R2 */
  3907. #endif /* u3b2 */
  3908. #endif /* RTAIX */
  3909. #endif /* ATT7300 */
  3910. #ifdef COMMENT
  3911. /* and if none of those work, try one of these... */
  3912. ttcur.c_cflag = 0;
  3913. ttcur.c_cflag = CLOCAL;
  3914. ttcur.c_cflag &= ~(CBAUD|HUPCL);
  3915. ttcur.c_cflag &= ~(CBAUD|CREAD);
  3916. ttcur.c_cflag &= ~(CBAUD|CREAD|HUPCL);
  3917. /* or other combinations */
  3918. #endif /* COMMENT */
  3919. #ifdef TCXONC
  3920. debug(F100,"tthang TCXONC","",0);
  3921. if (ioctl(ttyfd, TCXONC, 1) < 0) {
  3922. debug(F101,"tthang TCXONC failed","",errno);
  3923. }
  3924. #endif /* TCXONC */
  3925. #ifdef TIOCSTART
  3926. debug(F100,"tthang TIOCSTART","",0);
  3927. if (ioctl(ttyfd, TIOCSTART, 0) < 0) {
  3928. debug(F101,"tthang TIOCSTART failed","",errno);
  3929. }
  3930. #endif /* TIOCSTART */
  3931. if (ioctl(ttyfd,TCSETAF,&ttcur) < 0) { /* Fail if we can't. */
  3932. debug(F101,"tthang TCSETAF failed","",errno);
  3933. fcntl(ttyfd, F_SETFL, flags); /* Restore flags */
  3934. return(-1); /* before returning. */
  3935. }
  3936. msleep(300); /* Give modem time to notice. */
  3937. #ifndef NOCOTFMC
  3938. /* Now, even though it doesn't say this in SVID or any man page, we have */
  3939. /* to close and reopen the device. This is not necessary for all systems, */
  3940. /* but it's impossible to predict which ones need it and which ones don't. */
  3941. #ifdef ATT7300
  3942. /*
  3943. Special handling for ATT 7300 UNIX PC and 3B1, which have "phone"
  3944. related ioctl's for their internal modems. attmodem has getty status and
  3945. modem-in-use bit. Reportedly the ATT7300/3B1 PIOCDISC call is necessary,
  3946. but also ruins the file descriptor, and no other phone(7) ioctl call can fix
  3947. it. Whatever it does, it seems to escape detection with PIOCGETA and TCGETA.
  3948. The only way to undo the damage is to close the fd and then reopen it.
  3949. */
  3950. if (attmodem & ISMODEM) {
  3951. debug(F100,"tthang attmodem close/open","",0);
  3952. ioctl(ttyfd,PIOCUNHOLD,&dialer); /* Return call to handset. */
  3953. ioctl(ttyfd,PIOCDISC,&dialer); /* Disconnect phone. */
  3954. close(ttyfd); /* Close and reopen the fd. */
  3955. ttyfd = priv_opn(ttnmsv, O_RDWR | O_NDELAY);
  3956. attmodem &= ~ISMODEM; /* Phone no longer in use. */
  3957. }
  3958. #else /* !ATT7300 */
  3959. /* It seems we have to close and open the device for other AT&T systems */
  3960. /* too, and this is the place to do it. The following code does the */
  3961. /* famous close(open(...)) magic by default. If that doesn't work for you, */
  3962. /* then try uncommenting the following statement or putting -DCLSOPN in */
  3963. /* the makefile CFLAGS. */
  3964. /* #define CLSOPN */
  3965. #ifndef SCO32 /* Not needed by, and harmful to, SCO UNIX 3.2 / Xenix 2.3 */
  3966. #ifdef O_NDELAY
  3967. #define OPENFLGS O_RDWR | O_NDELAY
  3968. #else
  3969. #define OPENFLGS O_RDWR
  3970. #endif
  3971. #ifndef CLSOPN
  3972. /* This method is used by default, i.e. unless CLSOPN is defined. */
  3973. /* It is thought to be safer because there is no window where getty */
  3974. /* can seize control of the device. The drawback is that it might not work. */
  3975. debug(F101,"tthang close(open()), OPENFLGS","",OPENFLGS);
  3976. close(priv_opn(ttnmsv, OPENFLGS));
  3977. #else
  3978. /* This method is used if you #define CLSOPN. It is more likely to work */
  3979. /* than the previous method, but it's also more dangerous. */
  3980. debug(F101,"tthang close/open, OPENFLGS","",OPENFLGS);
  3981. close(ttyfd);
  3982. msleep(10);
  3983. ttyfd = priv_opn(ttnmsv, OPENFLGS); /* Open it again */
  3984. #endif /* CLSOPN */
  3985. #undef OPENFLGS
  3986. #endif /* SCO32 */
  3987. #endif /* ATT7300 */
  3988. #endif /* NOCOTFMC */
  3989. /* Now put all flags & modes back the way we found them. */
  3990. /* (Does the order of ioctl & fcntl matter ? ) */
  3991. debug(F100,"tthang restore settings","",0);
  3992. ttcur.c_cflag = ttc_save; /* Get old speed back. */
  3993. if (ioctl(ttyfd,TCSETAF,&ttcur) < 0) /* ioctl parameters. */
  3994. return(-1);
  3995. #ifdef O_NDELAY
  3996. /*
  3997. This is required for IBM RT and RS/6000, probably helps elsewhere too (?).
  3998. After closing a modem line, the modem will probably not be asserting
  3999. carrier any more, so we should not require carrier any more. If this
  4000. causes trouble on non-IBM UNIXes, change the #ifdef to use _IBMR2 rather
  4001. than O_NDELAY.
  4002. */
  4003. flags &= ~O_NDELAY; /* Don't require carrier on reopen */
  4004. #endif /* O_NDELAY */
  4005. if (fcntl(ttyfd,F_SETFL,flags) < 0) /* fcntl parameters */
  4006. return(-1);
  4007. return(1);
  4008. #endif /* not HPUX */
  4009. #endif /* ATTSV */
  4010. #endif /* BSD44ORPOSIX */
  4011. #endif /* HUP_POSIX */
  4012. #endif /* NOLOCAL */
  4013. }
  4014. /*
  4015. Major change in 5A(174). We used to use LPASS8, if it was defined, to
  4016. allow 8-bit data and Xon/Xoff flow control at the same time. But this
  4017. LPASS8 business seems to have been causing trouble for everybody but me!
  4018. For example, Annex terminal servers, commonly used with Encore computers,
  4019. do not support LPASS8 even though the Encore itself does. Ditto for many
  4020. other terminal servers, TELNET connections, rlogin connections, etc etc.
  4021. Now, reportedly, even vanilla 4.3 BSD systems can't do this right on their
  4022. serial lines, even though LPASS8 is a feature of 4.3BSD. So let's turn it
  4023. off for everybody. That means we goes back to using raw mode, with no
  4024. flow control. Phooey.
  4025. NOTE: This must be done before the first reference to LPASS8 in this file,
  4026. and after the last #include statment.
  4027. */
  4028. #ifdef LPASS8
  4029. #undef LPASS8
  4030. #endif /* LPASS8 */
  4031. /* T T R E S -- Restore terminal to "normal" mode. */
  4032. /* ske@pkmab.se: There are two choices for what this function should do.
  4033. * (1) Restore the tty to current "normal" mode, with carrier treatment
  4034. * according to ttcarr, to be used after every kermit command. (2) Restore
  4035. * the tty to the state it was in before kermit opened it. These choices
  4036. * conflict, since ttold can't hold both choices of tty parameters. ttres()
  4037. * is currently being called as in choice (1), but ttold basically holds
  4038. * the initial parameters, as in (2), and the description at the beginning
  4039. * of this file says (2).
  4040. *
  4041. * I don't think restoring tty parameters after all kermit commands makes
  4042. * much of a difference. Restoring them upon exit from kermit may be of
  4043. * some use in some cases (when the line is not restored automatically on
  4044. * close, by the operating system).
  4045. *
  4046. * I can't choose which one it should be, so I haven't changed it. It
  4047. * probably works as it is, too. It would probably even work even with
  4048. * ttres() entirely deleted...
  4049. *
  4050. * (from fdc: Actually, this function operates in remote mode too, so
  4051. * it restores the console (command) terminal to whatever mode it was
  4052. * in before packet operations began, so that commands work right again.)
  4053. */
  4054. int
  4055. ttres() { /* Restore the tty to normal. */
  4056. int x;
  4057. if (ttyfd < 0) return(-1); /* Not open. */
  4058. if (ttfdflg) return(0); /* Don't mess with terminal modes if */
  4059. /* we got ttyfd from another process */
  4060. #ifdef NETCONN
  4061. if (netconn) { /* Network connection */
  4062. tvtflg = 0;
  4063. #ifdef TCPSOCKET
  4064. #ifdef TCP_NODELAY
  4065. {
  4066. extern int tcp_nodelay; /* Just put this back if necessary */
  4067. if (ttnet == NET_TCPB) {
  4068. if (nodelay_sav > -1) {
  4069. no_delay(ttyfd,nodelay_sav);
  4070. nodelay_sav = -1;
  4071. }
  4072. }
  4073. }
  4074. #endif /* TCP_NODELAY */
  4075. #ifdef TN_COMPORT
  4076. if (istncomport()) {
  4077. int rc = -1;
  4078. if ((rc = tnsetflow(ttflow)) < 0)
  4079. return(rc);
  4080. if (ttspeed <= 0)
  4081. ttspeed = tnc_get_baud();
  4082. else if ((rc = tnc_set_baud(ttspeed)) < 0)
  4083. return(rc);
  4084. tnc_set_datasize(8);
  4085. tnc_set_stopsize(stopbits);
  4086. #ifdef HWPARITY
  4087. if (hwparity) {
  4088. switch (hwparity) {
  4089. case 'e': /* Even */
  4090. debug(F100,"ttres 8 bits + even parity","",0);
  4091. tnc_set_parity(3);
  4092. break;
  4093. case 'o': /* Odd */
  4094. debug(F100,"ttres 8 bits + odd parity","",0);
  4095. tnc_set_parity(2);
  4096. break;
  4097. case 'm': /* Mark */
  4098. debug(F100,"ttres 8 bits + invalid parity: mark","",0);
  4099. tnc_set_parity(4);
  4100. break;
  4101. case 's': /* Space */
  4102. debug(F100,"ttres 8 bits + invalid parity: space","",0);
  4103. tnc_set_parity(5);
  4104. break;
  4105. }
  4106. } else
  4107. #endif /* HWPARITY */
  4108. {
  4109. tnc_set_parity(1); /* None */
  4110. }
  4111. tvtflg = 0;
  4112. return(0);
  4113. }
  4114. #endif /* TN_COMPORT */
  4115. #endif /* TCPSOCKET */
  4116. return(0);
  4117. }
  4118. #endif /* NETCONN */
  4119. #ifdef NETCMD
  4120. if (ttpipe) return(0);
  4121. #endif /* NETCMD */
  4122. #ifdef NETPTY
  4123. if (ttpty) return(0);
  4124. #endif /* NETPTY */
  4125. /* Real terminal device, so restore its original modes */
  4126. #ifdef BSD44ORPOSIX /* For POSIX like this */
  4127. debug(F100,"ttres BSD44ORPOSIX","",0);
  4128. x = tcsetattr(ttyfd,TCSADRAIN,&ttold);
  4129. #else /* For all others... */
  4130. #ifdef ATTSV /* For AT&T versions... */
  4131. debug(F100,"ttres ATTSV","",0);
  4132. x = ioctl(ttyfd,TCSETAW,&ttold); /* Restore tty modes this way. */
  4133. #else
  4134. /* Here we restore the modes for BSD */
  4135. #ifdef LPASS8 /* Undo "pass8" if it were done */
  4136. if (lmodef) {
  4137. if (ioctl(ttyfd,TIOCLSET,&lmode) < 0)
  4138. debug(F100,"ttres TIOCLSET failed","",0);
  4139. else
  4140. debug(F100,"ttres TIOCLSET ok","",0);
  4141. }
  4142. #endif /* LPASS8 */
  4143. #ifdef CK_DTRCTS /* Undo hardware flow if it were done */
  4144. if (lmodef) {
  4145. if (ioctl(ttyfd,TIOCLSET,&lmode) < 0)
  4146. debug(F100,"ttres TIOCLSET failed","",0);
  4147. else
  4148. debug(F100,"ttres TIOCLSET ok","",0);
  4149. }
  4150. #endif /* CK_DTRCTS */
  4151. #ifdef TIOCGETC /* Put back special characters */
  4152. if (tcharf && (xlocal == 0)) {
  4153. if (ioctl(ttyfd,TIOCSETC,&tchold) < 0)
  4154. debug(F100,"ttres TIOCSETC failed","",0);
  4155. else
  4156. debug(F100,"ttres TIOCSETC ok","",0);
  4157. }
  4158. #endif /* TIOCGETC */
  4159. #ifdef TIOCGLTC /* Put back local special characters */
  4160. if (ltcharf && (xlocal == 0)) {
  4161. if (ioctl(ttyfd,TIOCSLTC,&ltchold) < 0)
  4162. debug(F100,"ttres TIOCSLTC failed","",0);
  4163. else
  4164. debug(F100,"ttres TIOCSLTC ok","",0);
  4165. }
  4166. #endif /* TIOCGLTC */
  4167. #ifdef BELLV10
  4168. debug(F100,"ttres BELLV10","",0);
  4169. x = ioctl(ttyfd,TIOCSETP,&ttold); /* Restore both structs */
  4170. x = ioctl(ttyfd,TIOCSDEV,&tdold);
  4171. #else
  4172. debug(F100,"ttres stty","",0);
  4173. x = stty(ttyfd,&ttold); /* Restore tty modes the old way. */
  4174. #endif /* BELLV10 */
  4175. if (!xlocal)
  4176. msleep(100); /* This replaces sleep(1)... */
  4177. /* Put back sleep(1) if tty is */
  4178. /* messed up after close. */
  4179. #endif /* ATTSV */
  4180. #endif /* BSD44ORPOSIX */
  4181. debug(F101,"ttres result","",x);
  4182. #ifndef QNX
  4183. if (x < 0) debug(F101,"ttres errno","",errno);
  4184. #endif /* QNX */
  4185. #ifdef AIXRS
  4186. #ifndef AIX41
  4187. x = ioctl(ttyfd, ttld & 1 ? TXADDCD : TXDELCD, "rts");
  4188. debug(F101,"ttres AIX line discipline rts restore","",x);
  4189. #endif /* AIX41 */
  4190. #endif /* AIXRS */
  4191. #ifdef BSD41
  4192. if (ttld > -1) { /* Put back line discipline */
  4193. x = ioctl(ttyfd, TIOCSETD, &ttld);
  4194. debug(F101,"ttres BSD41 line discipline restore","",x);
  4195. if (x < 0) debug(F101,"...ioctl errno","",errno);
  4196. ttld = -1;
  4197. }
  4198. #endif /* BSD41 */
  4199. #ifdef sony_news
  4200. x = xlocal ? km_ext : km_con; /* Restore Kanji mode. */
  4201. if (x != -1) { /* Make sure we know original modes. */
  4202. if (ioctl(ttyfd,TIOCKSET, &x) < 0) {
  4203. perror("ttres can't set Kanji mode");
  4204. debug(F101,"ttres error setting Kanji mode","",x);
  4205. return(-1);
  4206. }
  4207. }
  4208. debug(F100,"ttres set Kanji mode ok","",0);
  4209. #endif /* sony_news */
  4210. tvtflg = 0; /* Invalidate terminal mode settings */
  4211. debug(F101,"ttres return code","",x);
  4212. return(x);
  4213. }
  4214. #ifndef NOUUCP
  4215. /* T T C H K P I D -- Check lockfile pid */
  4216. /*
  4217. Read pid from lockfile named f, check that it's still valid.
  4218. If so, return 1.
  4219. On failure to read pid, return 1.
  4220. Otherwise, try to delete lockfile f and return 0 if successful, else 1.
  4221. */
  4222. static int
  4223. ttchkpid(f) char *f; {
  4224. int pid, mypid, x;
  4225. pid = ttrpid(f); /* Read pid from file. */
  4226. if (pid > -1) { /* If we were able to read the pid.. */
  4227. debug(F101,"ttchkpid lock pid","",pid);
  4228. errno = 0; /* See if process still exists. */
  4229. mypid = (int)getpid(); /* Get my own pid. */
  4230. debug(F101,"ttchkpid my pid","",mypid);
  4231. if (pid == mypid) { /* It's me! */
  4232. x = -1; /* So I can delete it */
  4233. errno = ESRCH; /* pretend it's invalid */
  4234. } else { /* It's not me */
  4235. x = kill((PID_T)pid, 0); /* See if it's a live process */
  4236. debug(F101,"ttchkpid kill errno","",errno);
  4237. }
  4238. debug(F101,"ttchkpid pid test","",x);
  4239. if (x < 0 && errno == ESRCH) { /* pid is invalid */
  4240. debug(F111,"removing stale lock",f,pid);
  4241. if (!backgrd)
  4242. printf("Removing stale lock %s (pid %d terminated)\n", f, pid);
  4243. priv_on();
  4244. x = unlink(f); /* Remove the lockfile. */
  4245. priv_off();
  4246. debug(F111,"ttchkpid unlink",f,x);
  4247. if (x > -1)
  4248. return(0); /* Device is not locked after all */
  4249. else if (!backgrd)
  4250. perror(f);
  4251. }
  4252. return(1);
  4253. }
  4254. return(1); /* Failure to read pid */
  4255. }
  4256. #ifdef HPUX
  4257. /* Aliases (different drivers) for HP-UX dialout devices: */
  4258. static char *devprefix[] = { "tty", "ttyd", "cul", "cua", "cuad", "culd", "" };
  4259. static int ttydexists = 0;
  4260. #endif /* HPUX */
  4261. /* T T R P I D -- Read pid from lockfile "name" */
  4262. static int
  4263. ttrpid(name) char *name; {
  4264. long len;
  4265. int x, fd, pid;
  4266. short spid;
  4267. char buf[32];
  4268. debug(F110,"ttrpid",name,0);
  4269. if (!name) return(-1);
  4270. if (!*name) return(-1);
  4271. priv_on();
  4272. len = zchki(name); /* Get file length */
  4273. priv_off();
  4274. debug(F101,"ttrpid zchki","",len);
  4275. if (len < 0)
  4276. return(-1);
  4277. if (len > 31)
  4278. return(-1);
  4279. priv_on();
  4280. fd = open(name,O_RDONLY); /* Try to open lockfile. */
  4281. priv_off();
  4282. debug(F101,"ttrpid fd","",fd);
  4283. if (fd <= 0)
  4284. return(-1);
  4285. /*
  4286. Here we try to be flexible and allow for all different binary and string
  4287. formats at runtime, rather than a specific format for each configuration
  4288. hardwired at compile time.
  4289. */
  4290. pid = -1;
  4291. #ifndef COHERENT
  4292. /*
  4293. COHERENT uses a string PID but without leading spaces or 0's, so there is
  4294. no way to tell from the file's length whether it contains a string or binary
  4295. pid. So for COHERENT only, we only allow string pids. For all others, we
  4296. decide based on the size of the lockfile.
  4297. */
  4298. if (len > 4) { /* If file > 4 bytes it's a string */
  4299. #endif /* COHERENT */
  4300. x = read(fd,buf,(int)len);
  4301. debug(F111,"ttrpid string read",buf,x);
  4302. if (x < 0) {
  4303. pid = -1;
  4304. } else {
  4305. buf[31] = '\0';
  4306. x = sscanf(buf,"%d",&pid); /* Get the integer pid from it. */
  4307. }
  4308. #ifndef COHERENT
  4309. } else if (len == 4) { /* 4 bytes so binary */
  4310. x = read(fd, (char *)&pid, 4); /* Read the bytes into an int */
  4311. debug(F101,"ttrpid integer read","",x);
  4312. if (x < 4)
  4313. pid = -1;
  4314. } else if (len == 2) { /* 2 bytes binary */
  4315. x = read(fd, (char *)&spid, 2); /* Read the bytes into a short */
  4316. debug(F101,"ttrpid short read","",x);
  4317. if (x < 2)
  4318. pid = -1;
  4319. else
  4320. pid = spid;
  4321. } else
  4322. pid = -1;
  4323. #endif /* COHERENT */
  4324. close(fd); /* Close the lockfile */
  4325. debug(F101,"ttrpid pid","",pid);
  4326. return(pid);
  4327. }
  4328. #endif /* NOUUCP */
  4329. /* T T L O C K */
  4330. /*
  4331. This function attempts to coordinate use of the communication device with
  4332. other copies of Kermit and any other program that follows the UUCP
  4333. device-locking conventions, which, unfortunately, vary among different UNIX
  4334. implementations. The idea is to look for a file of a certain name, the
  4335. "lockfile", in a certain directory. If such a file is found, then the line
  4336. is presumed to be in use, and Kermit should not use it. If no such file is
  4337. found, Kermit attempts to create one so that other programs will not use the
  4338. same line at the same time. Because the lockfile and/or the directory it's
  4339. in might lack write permission for the person running Kermit, Kermit could
  4340. find itself running setuid to uucp or other user that does have the
  4341. necessary permissions. At startup, Kermit has changed its effective uid to
  4342. the user's real uid, and so ttlock() must switch back to the original
  4343. effective uid in order to create the lockfile, and then back again to the
  4344. real uid to prevent unauthorized access to other directories or files owned
  4345. by the user the program is setuid to.
  4346. Totally rewritten for C-Kermit 5A to eliminate windows of vulnerability,
  4347. based on suggestions from Warren Tucker. Call with pointer to name of
  4348. tty device. Returns:
  4349. 0 on success
  4350. -1 on failure
  4351. Note: Once privileges are turned on using priv_on(), it is essential that
  4352. they are turned off again before this function returns.
  4353. */
  4354. #ifdef SVR4 /* Lockfile uses device numbers. */
  4355. /*
  4356. Although I can't find this in writing anywhere (e.g. in SVID for SVR4),
  4357. it is the behavior of the "reference version" of SVR4, i.e. the Intel
  4358. port from UNIX Systems Laboratories, then called Univel UnixWare,
  4359. then called Novell UnixWare, then called SCO Unixware, then called Caldera
  4360. Open UNIX... It also makes much more sense than device-name-based lockfiles
  4361. since there can be multiple names for the same device, symlinks, etc.
  4362. */
  4363. #ifndef NOLFDEVNO
  4364. #ifndef LFDEVNO /* Define this for SVR4 */
  4365. #ifndef AIXRS /* But not for RS/6000 AIX 3.2, etc. */
  4366. #ifndef BSD44 /* If anybody else needs it... */
  4367. #ifndef __386BSD__
  4368. #ifndef __FreeBSD__
  4369. #ifndef HPUX10
  4370. #ifndef IRIX51 /* SGI IRIX 5.1 or later */
  4371. #ifndef CK_SCOV5 /* SCO Open Server 5.0 */
  4372. #define LFDEVNO
  4373. #endif /* CK_SCOV5 */
  4374. #endif /* IRIX51 */
  4375. #endif /* HPUX10 */
  4376. #endif /* __FreeBSD__ */
  4377. #endif /* __386BSD__ */
  4378. #endif /* BSD44 */
  4379. #endif /* AIXRS */
  4380. #endif /* LFDEVNO */ /* ... define it here or on CC */
  4381. #endif /* NOLFDEVNO */
  4382. #endif /* SVR4 */ /* command line. */
  4383. #ifdef COHERENT
  4384. #define LFDEVNO
  4385. #endif /* COHERENT */
  4386. /*
  4387. For platforms where the lockfile name is made from device/major/minor
  4388. device number, as in SVR4. Which, if we must have lockfiles at all, is
  4389. by far the best format, since it eliminates all the confusion that stems
  4390. from multiple names (or drivers) for the same port, not to mention
  4391. symlinks. It might even be a good idea to start using this form even
  4392. on platforms where it's not supported, alongside the normal forms for those
  4393. platforms, in order to get people used to it...
  4394. */
  4395. #ifdef LFDEVNO
  4396. #ifndef major /* If we didn't find it */
  4397. #ifdef SVR4 /* then for Sys V R4 */
  4398. #include <sys/mkdev.h> /* look here */
  4399. #else /* or for SunOS versions */
  4400. #ifdef SUNOS4 /* ... */
  4401. #include <sys/sysmacros.h> /* look here */
  4402. #else /* Otherwise take a chance: */
  4403. #define major(dev) ( (int) ( ((unsigned)(dev) >> 8) & 0xff))
  4404. #define minor(dev) ( (int) ( (dev) & 0xff))
  4405. #endif /* SUNOS4 */
  4406. #endif /* SVR4 */
  4407. #endif /* major */
  4408. #endif /* LFDEVNO */
  4409. /* No advisory locks if F_TLOCK and F_ULOCK are not defined at this point */
  4410. #ifdef LOCKF
  4411. #ifndef F_TLOCK
  4412. #undef LOCKF
  4413. #ifndef NOLOCKF
  4414. #define NOLOCKF
  4415. #endif /* NOLOCKF */
  4416. #endif /* F_TLOCK */
  4417. #endif /* LOCKF */
  4418. #ifdef LOCKF
  4419. #ifndef F_ULOCK
  4420. #undef LOCKF
  4421. #ifndef NOLOCKF
  4422. #define NOLOCKF
  4423. #endif /* NOLOCKF */
  4424. #endif /* F_ULOCK */
  4425. #endif /* LOCKF */
  4426. static char linkto[DEVNAMLEN+1];
  4427. static char * linkdev = NULL;
  4428. #ifndef NOUUCP
  4429. #ifdef USETTYLOCK
  4430. #ifdef LOCK_DIR
  4431. char * uucplockdir = LOCK_DIR;
  4432. #else
  4433. char * uucplockdir = "";
  4434. #endif /* LOCK_DIR */
  4435. #else
  4436. #ifdef LOCK_DIR
  4437. char * uucplockdir = LOCK_DIR;
  4438. #else
  4439. char * uucplockdir = "";
  4440. #endif /* LOCK_DIR */
  4441. #endif /* USETTYLOCK */
  4442. #else
  4443. char * uucplockdir = "";
  4444. #endif /* NOUUCP */
  4445. #ifdef QNX /* Only for QNX4 */
  4446. int /* Visible to outside world */
  4447. qnxopencount() { /* Get QNX device open count */
  4448. struct _dev_info_entry info;
  4449. int x;
  4450. x = -1; /* Unknown */
  4451. if (ttyfd > -1) {
  4452. if (!dev_info(ttyfd, &info)) {
  4453. debug(F101,"ttlock QNX open_count","",info.open_count);
  4454. x = info.open_count;
  4455. }
  4456. }
  4457. return(x);
  4458. }
  4459. #endif /* QNX */
  4460. char *
  4461. ttglckdir() { /* Get Lockfile directory name */
  4462. #ifdef __OpenBSD__
  4463. return("/var/spool/lock");
  4464. #else /* __OpenBSD__ */
  4465. #ifdef __FreeBSD__
  4466. return("/var/spool/lock");
  4467. #else /* __FreeBSD__ */
  4468. #ifdef LOCK_DIR
  4469. char * s = LOCK_DIR;
  4470. #endif /* LOCK_DIR */
  4471. #ifdef NOUUCP
  4472. return("");
  4473. #else /* NOUUCP */
  4474. #ifdef LOCK_DIR
  4475. return(s);
  4476. #else /* LOCK_DIR */
  4477. return("");
  4478. #endif /* LOCK_DIR */
  4479. #endif /* NOUUCP */
  4480. #endif /* __FreeBSD__ */
  4481. #endif /* __OpenBSD__ */
  4482. }
  4483. static int
  4484. ttlock(ttdev) char *ttdev; {
  4485. int x, n;
  4486. int islink = 0;
  4487. #ifdef __FreeBSD__
  4488. char *devname;
  4489. #endif /* __FreeBSD__ */
  4490. #ifdef NOUUCP
  4491. debug(F100,"ttlock NOUUCP","",0);
  4492. ckstrncpy(flfnam,"NOLOCK",FLFNAML);
  4493. haslock = 1;
  4494. return(0);
  4495. #else /* !NOUUCP */
  4496. #ifdef USETTYLOCK
  4497. haslock = 0; /* Not locked yet. */
  4498. *flfnam = '\0'; /* Lockfile name is empty. */
  4499. #ifdef __FreeBSD__
  4500. if ((devname = xxlast(ttdev,'/')) != NULL)
  4501. #ifdef FREEBSD8
  4502. ckstrncat(lockname,devname+1,DEVNAMLEN-ckstrncpy(lockname,"pts",4));
  4503. #else
  4504. ckstrncpy(lockname,devname+1,DEVNAMLEN);
  4505. #endif /* FREEBSD8 */
  4506. #else
  4507. if (!strncmp(ttdev,"/dev/",5) && ttdev[5])
  4508. ckstrncpy(lockname,ttdev+5,DEVNAMLEN);
  4509. #endif /* __FreeBSD__ */
  4510. else
  4511. ckstrncpy(lockname,ttdev,DEVNAMLEN);
  4512. /*
  4513. This might be overkill, but it's not clear from the man pages whether
  4514. ttylock() can be called without calling ttylocked() first, since the doc
  4515. says that ttylocked() removes any stale lockfiles, but it does not say this
  4516. about ttylock(). Also the docs don't say what ttylocked() returns in the
  4517. case when it finds and removes a stale lockfile. So one or both calls to
  4518. to ttylocked() might be superfluous, but they should do no harm. Also I'm
  4519. assuming that we have to do all the same ID swapping, etc, with these
  4520. routines as we do without them. Thus the priv_on/off() sandwich.
  4521. */
  4522. #ifdef USE_UU_LOCK
  4523. priv_on(); /* Turn on privs */
  4524. x = uu_lock(lockname); /* Try to set the lock */
  4525. priv_off(); /* Turn privs off */
  4526. debug(F111,"ttlock uu_lock",lockname,x);
  4527. switch (x) {
  4528. case UU_LOCK_INUSE:
  4529. return(-2);
  4530. case UU_LOCK_OK:
  4531. #ifdef BSD44
  4532. ckmakmsg(flfnam,FLFNAML,"/var/spool/lock/LCK..",lockname,NULL,NULL);
  4533. #endif /* BSD44 */
  4534. haslock = 1;
  4535. return(0);
  4536. default:
  4537. return(-1);
  4538. }
  4539. #else /* USE_UU_LOCK */
  4540. priv_on(); /* Turn on privs */
  4541. if (ttylocked(lockname)) { /* This should remove any stale lock */
  4542. if (ttylocked(lockname)) { /* so check again. */
  4543. priv_off();
  4544. return(-5); /* Still locked, fail. */
  4545. }
  4546. }
  4547. x = ttylock(lockname); /* Lock it. */
  4548. priv_off(); /* Turn off privs */
  4549. debug(F111,"ttlock lockname",lockname,x);
  4550. if (x > -1) {
  4551. /*
  4552. We don't really know the name of the lockfile, but
  4553. this is what the man page says it is. In USETTYLOCK
  4554. builds, it is used only for display by SHOW COMM.
  4555. */
  4556. ckmakmsg(flfnam,FLFNAML,"/etc/locks/LCK..",lockname,NULL,NULL);
  4557. haslock = 1;
  4558. }
  4559. return(x);
  4560. #endif /* USE_UU_LOCK */
  4561. #else /* Systems that don't have ttylock()... */
  4562. #ifndef HPUX
  4563. int lockfd; /* File descriptor for lock file. */
  4564. PID_T pid; /* Process id of this process. */
  4565. int tries; /* How many times we've tried... */
  4566. int dummy;
  4567. struct stat devbuf; /* For device numbers (SVR4). */
  4568. #ifdef PIDSTRING
  4569. char pid_str[32]; /* My pid in string format. */
  4570. #endif /* PIDSTRING */
  4571. char *device, *devname;
  4572. /* Note: ridiculously long to prevent gcc complaints when used in sprintf */
  4573. #define LFNAML 5126 /* Max length for lock file name. */
  4574. char lockfil[LFNAML]; /* Lock file name */
  4575. #ifdef RTAIX
  4576. char lklockf[LFNAML]; /* Name for link to lock file */
  4577. #endif /* RTAIX */
  4578. #ifdef CKSYMLINK
  4579. char symlock[LFNAML]; /* Name for symlink lockfile name */
  4580. #endif /* CKSYMLINK */
  4581. char tmpnam[LFNAML+30]; /* Temporary lockfile name. */
  4582. char *lockdir = LOCK_DIR; /* Defined near top of this file, */
  4583. /* or on cc command line. */
  4584. haslock = 0; /* Not locked yet. */
  4585. *flfnam = '\0'; /* Lockfile name is empty. */
  4586. lock2[0] = '\0'; /* Clear secondary lockfile name. */
  4587. pid = getpid(); /* Get id of this process. */
  4588. /* Construct name of lockfile and temporary file */
  4589. /* device = name of tty device without the path, e.g. "ttyh8" */
  4590. /* lockfil = name of lock file, without path, e.g. "LCK..ttyh8" */
  4591. device = ((devname = xxlast(ttdev,'/')) != NULL ? devname+1 : ttdev);
  4592. if (stat(ttdev,&devbuf) < 0)
  4593. return(-1);
  4594. #ifdef CKSYMLINK
  4595. islink = 1; /* Assume it's a symlink */
  4596. linkto[0] = '\0'; /* But we don't know to what */
  4597. #ifdef COMMENT
  4598. /*
  4599. This is undependable. If it worked it would save the readlink call if
  4600. we knew the device name was not a link.
  4601. */
  4602. #ifdef S_ISLNK
  4603. islink = S_ISLNK(devbuf.st_mode);
  4604. debug(F101,"ttlock stat S_ISLNK","",islink);
  4605. #endif /* S_ISLNK */
  4606. #endif /* COMMENT */
  4607. if (islink) {
  4608. n = readlink(ttdev,linkto,DEVNAMLEN); /* See if it's a link */
  4609. debug(F111,"ttlock readlink",ttdev,n);
  4610. if (n > -1) /* It is */
  4611. linkto[n] = '\0';
  4612. else /* It's not */
  4613. islink = 0;
  4614. debug(F111,"ttlock link",linkto,islink);
  4615. }
  4616. if (islink) {
  4617. linkdev = (devname = xxlast(linkto,'/')) ? devname + 1 : linkto;
  4618. debug(F110,"ttlock linkdev",linkdev,0);
  4619. }
  4620. #endif /* CKSYMLINK */
  4621. /*
  4622. On SCO platforms, if we don't have a symlink, then let's pretend the
  4623. name given for the device is a symlink, because later we will change
  4624. the name if it contains any uppercase characters.
  4625. */
  4626. #ifdef CK_SCOV5 /* SCO Open Server 5.0 */
  4627. if (!islink) {
  4628. islink = 1;
  4629. ckstrncpy(linkto,ttdev,DEVNAMLEN);
  4630. linkdev = (devname = xxlast(linkto,'/')) ? devname + 1 : linkto;
  4631. debug(F110,"ttlock linkdev",linkdev,0);
  4632. }
  4633. #else
  4634. #ifdef M_XENIX /* SCO Xenix or UNIX */
  4635. if (!islink) {
  4636. islink = 1;
  4637. ckstrncpy(linkto,ttdev,DEVNAMLEN);
  4638. linkdev = (devname = xxlast(linkto,'/')) ? devname + 1 : linkto;
  4639. debug(F110,"ttlock linkdev",linkdev,0);
  4640. }
  4641. #endif /* M_XENIX */
  4642. #endif /* CK_SCOV5 */
  4643. #ifdef ISIII /* Interactive System III, PC/IX */
  4644. ckstrncpy(lockfil, device, DEVNAMLEN);
  4645. #else /* not ISIII */
  4646. #ifdef LFDEVNO /* Lockfilename has device numbers. */
  4647. #ifdef COHERENT
  4648. sprintf(lockfil,"LCK..%d.%d", /* SAFE */
  4649. major(devbuf.st_rdev), /* major device number */
  4650. 0x1f & minor(devbuf.st_rdev)); /* minor device number */
  4651. #else
  4652. /* Note: %d changed to %u in 8.0 -- %u is part of SVID for SVR4 */
  4653. /* Lockfile name format verified to agree with Solaris cu, Dec 2001 */
  4654. sprintf(lockfil,"LK.%03u.%03u.%03u", /* SAFE */
  4655. major(devbuf.st_dev), /* device */
  4656. major(devbuf.st_rdev), /* major device number */
  4657. minor(devbuf.st_rdev)); /* minor device number */
  4658. #endif /* COHERENT */
  4659. #else /* Not LFDEVNO */
  4660. #ifdef PTX /* Dynix PTX */
  4661. if ((device != &ttdev[5]) && (strncmp(ttdev,"/dev/",5) == 0)) {
  4662. if ((int)strlen(device) + 8 < LFNAML)
  4663. sprintf(lockfil,"LCK..%.3s%s", &ttdev[5], device);
  4664. else
  4665. ckstrncpy(lockfil,"LOCKFILE_NAME_TOO_LONG",LFNAML);
  4666. } else
  4667. #endif /* PTX */
  4668. if ((int)strlen(device) + 5 < LFNAML)
  4669. sprintf(lockfil,"LCK..%s", device);
  4670. else
  4671. ckstrncpy(lockfil,"LOCKFILE_NAME_TOO_LONG",LFNAML);
  4672. #ifdef RTAIX
  4673. ckstrncpy(lklockf,device,DEVNAMLEN);
  4674. #endif /* RTAIX */
  4675. #ifdef CKSYMLINK
  4676. symlock[0] = '\0';
  4677. if (islink)
  4678. ckmakmsg(symlock,LFNAML, "LCK..", linkdev, NULL, NULL);
  4679. #endif /* CKSYMLINK */
  4680. #endif /* LFDEVNO */
  4681. #endif /* ISIII */
  4682. #ifdef CK_SCOV5 /* SCO Open Server 5.0 */
  4683. {
  4684. /* Lowercase the entire filename. */
  4685. /* SCO says we must do this in V5.0 and later. */
  4686. /* BUT... watch out for devices -- like Digiboard Portserver */
  4687. /* That can have hundreds of ports... */
  4688. char *p = (char *)(lockfil + 5);
  4689. while (*p) { if (isupper(*p)) *p = (char) tolower(*p); p++; }
  4690. }
  4691. #ifdef CKSYMLINK
  4692. if (islink) { /* If no change */
  4693. if (!strcmp(lockfil,symlock)) { /* then no second lockfile needed */
  4694. islink = 0;
  4695. symlock[0] = '\0';
  4696. }
  4697. }
  4698. #endif /* CKSYMLINK */
  4699. #else
  4700. #ifdef M_XENIX /* SCO Xenix or UNIX */
  4701. {
  4702. int x; char c;
  4703. x = (int)strlen(lockfil) - 1; /* Get last letter of device name. */
  4704. if (x > 0) { /* If it's uppercase, lower it. */
  4705. c = lockfil[x];
  4706. if (c >= 'A' && c <= 'Z') lockfil[x] += ('a' - 'A');
  4707. }
  4708. }
  4709. #ifdef CKSYMLINK
  4710. if (islink) {
  4711. if (!strcmp(lockfil,symlock)) { /* No change */
  4712. islink = 0; /* so no second lockfile */
  4713. symlock[0] = '\0';
  4714. }
  4715. }
  4716. #endif /* CKSYMLINK */
  4717. #endif /* M_XENIX */
  4718. #endif /* CK_SCOV5 */
  4719. /* flfnam = full lockfile pathname, e.g. "/usr/spool/uucp/LCK..ttyh8" */
  4720. /* tmpnam = temporary unique, e.g. "/usr/spool/uucp/LTMP..pid" */
  4721. ckmakmsg(flfnam,LFNAML,lockdir,"/",lockfil,NULL);
  4722. #ifdef RTAIX
  4723. ckmakmsg(lkflfn,FLFNAML,lockdir,"/",lklockf,NULL);
  4724. #endif /* RTAIX */
  4725. #ifndef LFDEVNO
  4726. #ifdef CKSYMLINK
  4727. /* If it's a link then also make a lockfile for the real name */
  4728. debug(F111,"ttlock link symlock",symlock,islink);
  4729. if (islink && symlock[0]) {
  4730. /* But only if the lockfile names would be different. */
  4731. /* WARNING: They won't be, e.g. for /dev/ttyd2 => /hw/ttys/ttyd2 */
  4732. ckmakmsg(lock2,FLFNAML,lockdir,"/",symlock,NULL);
  4733. debug(F110,"ttlock lock2",lock2,0);
  4734. if (!strcmp(lock2,flfnam)) { /* Are lockfile names the same? */
  4735. debug(F100,"ttlock lock2 cleared","",0);
  4736. lock2[0] = '\0'; /* Clear secondary lockfile name. */
  4737. }
  4738. }
  4739. #endif /* CKSYMLINK */
  4740. #endif /* LFDEVNO */
  4741. sprintf(tmpnam,"%s/LTMP.%05d",lockdir,(int) pid); /* safe */
  4742. debug(F110,"ttlock flfnam",flfnam,0);
  4743. debug(F110,"ttlock tmpnam",tmpnam,0);
  4744. priv_on(); /* Turn on privileges if possible. */
  4745. lockfd = creat(tmpnam, 0444); /* Try to create temp lock file. */
  4746. if (lockfd < 0) { /* Create failed. */
  4747. debug(F111,"ttlock creat failed",tmpnam,errno);
  4748. if (errno == ENOENT) {
  4749. perror(lockdir);
  4750. printf("UUCP not installed or Kermit misconfigured\n");
  4751. } else {
  4752. if (!quiet)
  4753. perror(lockdir);
  4754. unlink(tmpnam); /* Get rid of the temporary file. */
  4755. }
  4756. priv_off(); /* Turn off privileges!!! */
  4757. return(-1); /* Return failure code. */
  4758. }
  4759. /* Now write the pid into the temp lockfile in the appropriate format */
  4760. #ifdef PIDSTRING /* For Honey DanBer UUCP, */
  4761. sprintf( /* write PID as decimal string */
  4762. pid_str,
  4763. #ifdef LINUXFSSTND /* The "Linux File System Standard" */
  4764. #ifdef FSSTND10 /* Version 1.0 calls for */
  4765. "%010d\n", /* leading zeros */
  4766. #else /* while version 1.2 calls for */
  4767. "%10d\n", /* leading spaces */
  4768. #endif /* FSSTND10 */
  4769. #else
  4770. #ifdef COHERENT
  4771. "%d\n", /* with leading nothing */
  4772. #else
  4773. "%10d\n", /* with leading blanks */
  4774. #endif /* COHERENT */
  4775. #endif /* LINUXFSSTND */
  4776. (int) pid
  4777. ); /* safe */
  4778. dummy = write(lockfd, pid_str, 11);
  4779. debug(F111,"ttlock hdb pid string",pid_str,(int) pid);
  4780. #else /* Not PIDSTRING, use integer PID */
  4781. write(lockfd, (char *)&pid, sizeof(pid) );
  4782. debug(F101,"ttlock pid","",(int) pid);
  4783. #endif /* PIDSTRING */
  4784. /* Now try to rename the temp file to the real lock file name. */
  4785. /* This will fail if a lock file of that name already exists. */
  4786. close(lockfd); /* Close the temp lockfile. */
  4787. chmod(tmpnam,0444); /* Permission for a valid lock. */
  4788. tries = 0;
  4789. while (!haslock && tries++ < 2) {
  4790. haslock = 0;
  4791. dummy = link(tmpnam,flfnam); /* Create a link to it. */
  4792. if (dummy == 0) haslock = 1;
  4793. if (haslock) { /* If we got the lockfile */
  4794. #ifdef RTAIX
  4795. link(flfnam,lkflfn);
  4796. #endif /* RTAIX */
  4797. #ifdef CKSYMLINK
  4798. #ifndef LFDEVNO
  4799. if (islink && lock2[0])
  4800. dummy = link(flfnam,lock2);
  4801. #endif /* LFDEVNO */
  4802. #endif /* CKSYMLINK */
  4803. #ifdef COMMENT
  4804. /* Can't do this any more because device is not open yet so no ttyfd. */
  4805. #ifdef LOCKF
  4806. /*
  4807. Advisory file locking works on SVR4, so we use it. In fact, it is
  4808. necessary in some cases, e.g. when SLIP is involved. But it still doesn't
  4809. seem to prevent multiple users accessing the same device by different names.
  4810. */
  4811. while (lockf(ttyfd, F_TLOCK, 0L) != 0) {
  4812. debug(F111, "ttlock lockf returns errno", "", errno);
  4813. if ((++tries >= 3) || (errno != EAGAIN)) {
  4814. x = unlink(flfnam); /* remove the lockfile */
  4815. #ifdef RTAIX
  4816. unlink(lkflfn); /* And any links to it... */
  4817. #endif /* RTAIX */
  4818. #ifdef CKSYMLINK
  4819. #ifndef LFDEVNO
  4820. if (islink && lock2[0])
  4821. unlink(lock2); /* ditto... */
  4822. #endif /* LFDEVNO */
  4823. #endif /* CKSYMLINK */
  4824. debug(F111,"ttlock unlink",flfnam,x);
  4825. haslock = 0;
  4826. break;
  4827. }
  4828. sleep(2);
  4829. }
  4830. if (haslock) /* If we got an advisory lock */
  4831. #endif /* LOCKF */
  4832. #endif /* COMMENT */
  4833. break; /* We're done. */
  4834. } else { /* We didn't create a new lockfile. */
  4835. priv_off();
  4836. if (ttchkpid(flfnam)) { /* Check existing lockfile */
  4837. priv_on(); /* cause ttchkpid turns priv_off... */
  4838. unlink(tmpnam); /* Delete the tempfile */
  4839. debug(F100,"ttlock found tty locked","",0);
  4840. priv_off(); /* Turn off privs */
  4841. return(-2); /* Code for device is in use. */
  4842. }
  4843. priv_on();
  4844. }
  4845. }
  4846. unlink(tmpnam); /* Unlink (remove) the temp file. */
  4847. priv_off(); /* Turn off privs */
  4848. return(haslock ? 0 : -1); /* Return link's return code. */
  4849. #else /* HPUX */
  4850. /*
  4851. HP-UX gets its own copy of this routine, modeled after the observed behavior
  4852. of the HP-UX 'cu' program. HP-UX serial device names consist of a base name
  4853. such as "tty", "ttyd", "cua", "cul", "cuad", or "culd", followed by a unit
  4854. designator which is a string of digits, possibly containing an imbedded
  4855. letter "p". Examples (for base name "tty"):
  4856. /dev/tty0, /dev/tty00, dev/ttyd00, /dev/tty0p0
  4857. According to the HP-UX UUCP manual of 1988, the "0p0" notation has been
  4858. used on Series 800 since HP-UX 2.00, and the "non-p" notation was used
  4859. on other models. In HP-UX 10.00, "0p0" notation was adopted for all models.
  4860. However, we make and enforce no such distinctions; either notation is
  4861. accepted on any model or HP-UX version as a valid unit designator.
  4862. If a valid unit is specified (as opposed to a designer name or symlink), we
  4863. check for all aliases of the given unit according to the devprefix[] array.
  4864. If no lockfiles are found for the given unit, we can have the device; we
  4865. create a lockfile LCK..name in the lockfile directory appropriate for the
  4866. HP-UX version (/var/spool/locks for 10.00 and later, /usr/spool/uucp for
  4867. 9.xx and earlier). If it is a "cua" or "cul" device, a second lockfile is
  4868. created with the "ttyd" prefix. This is exactly what cu does.
  4869. If the "set line" device does not have a valid unit designator, then it is
  4870. used literally and no synomyms are searched for and only one lockfile is
  4871. created.
  4872. -fdc, March 1998.
  4873. */
  4874. #define LFNAML 80 /* Max length for lock file name. */
  4875. int lockfd; /* File descriptor for lock file. */
  4876. PID_T pid; /* Process ID of this process. */
  4877. int fpid; /* pid found in existing lockfile. */
  4878. int tries; /* How many times we've tried... */
  4879. int i, k; /* Workers */
  4880. char *device, *devname; /* "/dev/xxx", "xxx" */
  4881. char *unit, *p; /* <instance>p<port> part of xxx */
  4882. char lockfil[LFNAML]; /* Lockfile name (no path) */
  4883. char tmpnam[LFNAML]; /* Temporary lockfile name. */
  4884. #ifdef HPUX10 /* Lockfile directory */
  4885. char *lockdir = "/var/spool/locks"; /* Always this for 10.00 and higher */
  4886. #else /* HP-UX 9.xx and below */
  4887. #ifdef LOCK_DIR
  4888. char *lockdir = LOCK_DIR; /* Defined near top of this file */
  4889. #else
  4890. char *lockdir = "/usr/spool/uucp"; /* or not... */
  4891. #endif /* LOCK_DIR */
  4892. #endif /* HPUX10 */
  4893. haslock = 0; /* Not locked yet. */
  4894. *flfnam = '\0'; /* Lockfile name is empty. */
  4895. lock2[0] = '\0'; /* Second one too. */
  4896. pid = getpid(); /* Get my process ID */
  4897. /*
  4898. Construct name of lockfile and temporary file...
  4899. device = name of tty device without the path, e.g. "tty0p0"
  4900. lockfil = name of lock file, without path, e.g. "LCK..tty0p0"
  4901. */
  4902. device = ((devname = xxlast(ttdev,'/')) != NULL ? devname+1 : ttdev);
  4903. debug(F110,"TTLOCK device",device,0);
  4904. ckmakmsg(lockfil,LFNAML,"LCK..",device,NULL,NULL);
  4905. k = 0; /* Assume device is not locked */
  4906. n = 0; /* Digit counter */
  4907. unit = device; /* Unit = <instance>p<port> */
  4908. while (*unit && !isdigit(*unit)) /* Search for digit... */
  4909. unit++;
  4910. p = unit; /* Verify <num>p<num> format... */
  4911. debug(F110,"TTLOCK unit 1",unit,0);
  4912. /*
  4913. The unit number is recognized as:
  4914. (a) any sequence of digits that runs to the end of the string.
  4915. (b) any (a) that includes one and only one letter "p", with at least
  4916. one digit before and after it.
  4917. */
  4918. while (isdigit(*p)) p++, n++; /* Get a run of digits */
  4919. if (*p && n > 0) { /* Have a "p"? */
  4920. if (*p == 'p' && isdigit(*(p+1))) {
  4921. p++;
  4922. n = 0;
  4923. while (isdigit(*p)) p++, n++;
  4924. }
  4925. }
  4926. if (n == 0 || *p) unit = "";
  4927. debug(F110,"TTLOCK unit 2",unit,0);
  4928. if (*unit) { /* Device name has unit number. */
  4929. /* The following loop not only searches for the various lockfile */
  4930. /* synonyms, but also removes all -- not just one -- stale lockfile */
  4931. /* for the device, should there be more than one. See ttchkpid(). */
  4932. ttydexists = 0;
  4933. for (i = 0; *devprefix[i]; i++) { /* For each driver... */
  4934. /* Make device name */
  4935. ckmakmsg(lock2,FLFNAML,"/dev/",devprefix[i],unit,NULL);
  4936. priv_on(); /* Privs on */
  4937. k = zchki(lock2) != -1; /* See if device exists */
  4938. priv_off(); /* Privs off */
  4939. debug(F111,"TTLOCK exist",lock2,k);
  4940. if (k) {
  4941. if (!strcmp(devprefix[i],"ttyd")) /* ttyd device exists */
  4942. ttydexists = 1;
  4943. /* Make lockfile name */
  4944. ckmakmsg(lock2,FLFNAML,lockdir,"/LCK..",devprefix[i],unit);
  4945. debug(F110,"TTLOCK checking",lock2,0);
  4946. priv_on(); /* Privs on */
  4947. k = zchki(lock2) != -1; /* See if lockfile exists */
  4948. priv_off(); /* Privs off */
  4949. debug(F111,"TTLOCK check for lock A",lock2,k);
  4950. if (k) if (ttchkpid(lock2)) { /* If pid still active, fail. */
  4951. ckstrncpy(flfnam,lock2,FLFNAML);
  4952. return(-2);
  4953. }
  4954. }
  4955. }
  4956. } else { /* Some other device-name format */
  4957. /* This takes care of symbolic links, etc... */
  4958. /* But does not chase them down! */
  4959. ckmakmsg(lock2,FLFNAML,lockdir,"/LCK..",device,NULL);
  4960. priv_on();
  4961. k = zchki(lock2) != -1; /* Check for existing lockfile */
  4962. priv_off();
  4963. debug(F111,"TTLOCK check for lock B",lock2,k);
  4964. if (k) if (ttchkpid(lock2)) { /* Check pid from lockfile */
  4965. ckstrncpy(flfnam,lock2,FLFNAML);
  4966. debug(F110,"TTLOCK in use",device,0);
  4967. debug(F101,"TTLOCK returns","",-2);
  4968. return(-2);
  4969. }
  4970. }
  4971. /*
  4972. Get here only if there is no (more) lockfile, so now we make one (or two)...
  4973. flfnam = full lockfile pathname, e.g. "/usr/spool/uucp/LCK..cul0p0".
  4974. tmpnam = unique temporary filname, e.g. "/usr/spool/uucp/LTMP..pid".
  4975. */
  4976. ckmakmsg(flfnam,FLFNAML,lockdir,"/",lockfil,NULL); /* SET LINE device */
  4977. /* If dialout device, also make one for corresponding dialin device */
  4978. lock2[0] = '\0';
  4979. if (!strncmp(device,"cu",2) && *unit && ttydexists)
  4980. ckmakmsg(lock2,FLFNAML,lockdir,"/LCK..ttyd",unit,NULL);
  4981. if ((int)strlen(lockdir)+12 < LFNAML)
  4982. sprintf(tmpnam,"%s/LTMP.%05d",lockdir,(int) pid); /* Make temp name */
  4983. #ifdef DEBUG
  4984. if (deblog) {
  4985. debug(F110,"TTLOCK flfnam",flfnam,0);
  4986. debug(F110,"TTLOCK lock2",lock2,0);
  4987. debug(F110,"TTLOCK tmpnam",tmpnam,0);
  4988. }
  4989. #endif /* DEBUG */
  4990. /*
  4991. Lockfile permissions...
  4992. 444 is standard, HP-UX 10.00 uses 664. It doesn't matter.
  4993. Kermit uses 444; the difference lets us tell whether Kermit created
  4994. the lock file.
  4995. */
  4996. priv_on(); /* Turn on privileges. */
  4997. lockfd = creat(tmpnam, 0444); /* Try to create temporary file. */
  4998. if (lockfd < 0) { /* Create failed. */
  4999. debug(F111,"TTLOCK creat failed",tmpnam,errno);
  5000. if (errno == ENOENT) {
  5001. perror(lockdir);
  5002. printf("UUCP not installed or Kermit misconfigured\n");
  5003. } else {
  5004. if (!quiet)
  5005. perror(lockdir);
  5006. unlink(tmpnam); /* Get rid of the temporary file. */
  5007. }
  5008. priv_off(); /* Turn off privileges!!! */
  5009. debug(F101,"TTLOCK returns","",-1);
  5010. return(-1); /* Return failure code. */
  5011. }
  5012. debug(F110,"TTLOCK temp ok",tmpnam,0);
  5013. /* Now write our pid into the temp lockfile in integer format. */
  5014. i = write(lockfd, (char *)&pid, sizeof(pid));
  5015. #ifdef DEBUG
  5016. if (deblog) {
  5017. debug(F101,"TTLOCK pid","",pid);
  5018. debug(F101,"TTLOCK sizeof pid","",sizeof(pid));
  5019. debug(F101,"TTLOCK write pid returns","",i);
  5020. }
  5021. #endif /* DEBUG */
  5022. /*
  5023. Now try to rename the temporary file to the real lockfile name.
  5024. This will fail if a lock file of that name already exists, which
  5025. will catch race conditions with other users.
  5026. */
  5027. close(lockfd); /* Close the temp lockfile. */
  5028. chmod(tmpnam,0444);
  5029. tries = 0;
  5030. while (!haslock && tries++ < 2) {
  5031. haslock = (link(tmpnam,flfnam) == 0); /* Create a link to it. */
  5032. debug(F101,"TTLOCK link","",haslock);
  5033. if (haslock) { /* If we made the lockfile... */
  5034. #ifdef COMMENT
  5035. /* We can't do this any more because we don't have a file descriptor yet. */
  5036. #ifdef LOCKF /* Can be canceled with -DNOLOCKF */
  5037. /*
  5038. Create an advisory lock on the device through its file descriptor.
  5039. This code actually seems to work. If it is executed, and then another
  5040. process tries to open the same device under a different name to circumvent
  5041. the lockfile, they get a "device busy" error.
  5042. */
  5043. debug(F100,"TTLOCK LOCKF code...","",0);
  5044. while ( lockf(ttyfd, F_TLOCK, 0L) != 0 ) {
  5045. debug(F111, "TTLOCK lockf error", "", errno);
  5046. if ((++tries >= 3) || (errno != EAGAIN)) {
  5047. x = unlink(flfnam); /* Remove the lockfile */
  5048. if (errno == EACCES && !quiet)
  5049. printf("Device already locked by another process\n");
  5050. haslock = 0;
  5051. break;
  5052. }
  5053. sleep(2);
  5054. }
  5055. #endif /* LOCKF */
  5056. #endif /* COMMENT */
  5057. if (haslock) { /* If we made the lockfile ... */
  5058. if (lock2[0]) { /* if there is to be a 2nd lockfile */
  5059. lockfd = creat(lock2, 0444); /* Create it */
  5060. debug(F111,"TTLOCK lock2 creat", lock2, lockfd);
  5061. if (lockfd > -1) { /* Created OK, write pid. */
  5062. write(lockfd, (char *)&pid, sizeof(pid) );
  5063. close(lockfd); /* Close and */
  5064. chmod(lock2, 0444); /* set permissions. */
  5065. } else { /* Not OK, but don't fail. */
  5066. lock2[0] = '\0'; /* Just remember it's not there. */
  5067. }
  5068. }
  5069. break; /* and we're done. */
  5070. }
  5071. }
  5072. }
  5073. unlink(tmpnam); /* Unlink (remove) the temp file. */
  5074. priv_off(); /* Turn off privs */
  5075. i = haslock ? 0 : -1; /* Our return value */
  5076. debug(F101,"TTLOCK returns","",i);
  5077. return(i);
  5078. #endif /* HPUX */
  5079. #endif /* USETTYLOCK */
  5080. #endif /* !NOUUCP */
  5081. }
  5082. /* T T U N L O C K */
  5083. static int
  5084. ttunlck() { /* Remove UUCP lockfile(s). */
  5085. #ifndef NOUUCP
  5086. int x;
  5087. debug(F111,"ttunlck",flfnam,haslock);
  5088. #ifdef USETTYLOCK
  5089. if (haslock && *flfnam) {
  5090. int x;
  5091. priv_on(); /* Turn on privs */
  5092. #ifdef USE_UU_LOCK
  5093. x = uu_unlock(lockname);
  5094. #else /* USE_UU_LOCK */
  5095. x = ttyunlock(lockname); /* Try to unlock */
  5096. #endif /* USE_UU_LOCK */
  5097. priv_off(); /* Turn off privs */
  5098. if (x < 0 && !quiet)
  5099. printf("Warning - Can't remove lockfile: %s\n", flfnam);
  5100. *flfnam = '\0'; /* Erase the name. */
  5101. haslock = 0;
  5102. return(0);
  5103. }
  5104. #else /* No ttylock()... */
  5105. if (haslock && *flfnam) {
  5106. /* Don't remove lockfile if we didn't make it ourselves */
  5107. if ((x = ttrpid(flfnam)) != (int)getpid()) {
  5108. debug(F111,"ttunlck lockfile seized",flfnam,x);
  5109. printf("Warning - Lockfile %s seized by pid %d\n",
  5110. flfnam,
  5111. x
  5112. );
  5113. return(0);
  5114. }
  5115. priv_on(); /* Turn privileges on. */
  5116. errno = 0;
  5117. x = unlink(flfnam); /* Remove the lockfile. */
  5118. debug(F111,"ttunlck unlink",flfnam,x);
  5119. if (x < 0) {
  5120. if (errno && !quiet)
  5121. perror(ttnmsv);
  5122. printf("Warning - Can't remove lockfile: %s\n", flfnam);
  5123. }
  5124. haslock = 0;
  5125. *flfnam = '\0'; /* Erase the name. */
  5126. #ifdef RTAIX
  5127. errno = 0;
  5128. x = unlink(lkflfn); /* Remove link to lockfile */
  5129. debug(F111,"ttunlck AIX link unlink",lkflfn,x);
  5130. if (x < 0) {
  5131. if (errno && !quiet)
  5132. perror(ttnmsv);
  5133. printf("Warning - Can't remove link to lockfile: %s\n", lkflfn);
  5134. }
  5135. *lkflfn = '\0';
  5136. #else
  5137. if (lock2[0]) { /* If there is a second lockfile, */
  5138. errno = 0;
  5139. x = unlink(lock2); /* remove it too. */
  5140. debug(F111,"ttunlck lock2 unlink",lock2,x);
  5141. if (x < 0) {
  5142. if (errno && !quiet)
  5143. perror(ttnmsv);
  5144. printf("Warning - Can't remove secondary lockfile: %s\n",
  5145. lock2
  5146. );
  5147. }
  5148. lock2[0] = '\0'; /* Forget its name. */
  5149. }
  5150. #endif /* RTAIX */
  5151. #ifdef COMMENT
  5152. #ifdef LOCKF
  5153. (VOID) lockf(ttyfd, F_ULOCK, 0L); /* Remove advisory lock */
  5154. #endif /* LOCKF */
  5155. #endif /* COMMENT */
  5156. priv_off(); /* Turn privileges off. */
  5157. }
  5158. #endif /* USETTYLOCK */
  5159. #endif /* !NOUUCP */
  5160. return(0);
  5161. }
  5162. /*
  5163. 4.3BSD-style UUCP line direction control.
  5164. (Stan Barber, Rice U, 1980-something...)
  5165. */
  5166. #ifndef NOUUCP
  5167. #ifdef ACUCNTRL
  5168. VOID
  5169. acucntrl(flag,ttname) char *flag, *ttname; {
  5170. char x[DEVNAMLEN+32], *device, *devname;
  5171. if (strcmp(ttname,CTTNAM) == 0 || xlocal == 0) /* If not local, */
  5172. return; /* just return. */
  5173. device = ((devname = xxlast(ttname,'/')) != NULL ? devname+1 : ttname);
  5174. if (strncmp(device,"LCK..",4) == 0) device += 5;
  5175. ckmakmsg(x,DEVNAMLEN+32,"/usr/lib/uucp/acucntrl ",flag," ",device);
  5176. debug(F110,"called ",x,0);
  5177. zsyscmd(x);
  5178. }
  5179. #endif /* ACUCNTRL */
  5180. #endif /* NOUUCP */
  5181. /*
  5182. T T H F L O W -- Set or Reset hardware flow control.
  5183. This is an attempt to collect all hardware-flow-control related code
  5184. into a single module. Thanks to Rick Sladkey and John Kohl for lots of
  5185. help here. Overview:
  5186. Hardware flow control is not supported in many UNIX implementions. Even
  5187. when it is supported, there is no (ha ha) "standard" for the programming
  5188. interface. In general, 4.3BSD and earlier (sometimes), 4.4BSD, System V,
  5189. SunOS, AIX, etc, have totally different methods. (And, not strictly
  5190. relevant here, the programming interface often brings one only to a no-op
  5191. in the device driver!)
  5192. Among all these, we have two major types of APIs: those in which hardware
  5193. flow control is determined by bits in the same termio/termios/sgtty mode
  5194. word(s) that are used for controlling such items as CBREAK vs RAW mode, and
  5195. which are also used by the ttvt(), ttpkt(), conbin(), and concb() routines
  5196. for changing terminal modes. And those that use entirely different
  5197. mechanisms.
  5198. In the first category, it is important that any change in the mode bits be
  5199. reflected in the relevant termio(s)/sgtty structure, so that subsequent
  5200. changes to that structure do not wipe out the effects of this routine. That
  5201. is why a pointer, attrs, to the appropriate structure is passed as a
  5202. parameter to this routine.
  5203. The second category should give us no worries, since any changes to hardware
  5204. flow control accomplished by this routine should not affect the termio(s)/
  5205. sgtty structures, and therefore will not be undone by later changes to them.
  5206. The second argument, status, means to turn on hardware flow control if
  5207. nonzero, and to turn it off if zero.
  5208. Returns: 0 on apparent success, -1 on probable failure.
  5209. */
  5210. /*
  5211. The following business is for BSDI, where it was discovered that two
  5212. separate bits, CCTS_OFLOW and CRTS_IFLOW, are used in hardware flow control,
  5213. but CTRSCTS is defined (in <termios.h>) to be just CCTS_OFLOW rather both
  5214. bits, so hwfc only works in one direction if you use CRTSCTS to control it.
  5215. Other 4.4BSD-based Unixes such as FreeBSD 4.1, which use these two bits,
  5216. define CRTSCTS correctly.
  5217. */
  5218. #ifdef FIXCRTSCTS
  5219. #ifdef CRTSCTS
  5220. #ifdef CCTS_OFLOW
  5221. #ifdef CRTS_IFLOW
  5222. #undef CRTSCTS
  5223. #define CRTSCTS (CRTS_IFLOW|CCTS_OFLOW)
  5224. #endif /* CRTS_IFLOW */
  5225. #endif /* CCTS_OFLOW */
  5226. #endif /* CRTSCTS */
  5227. #endif /* FIXCRTSCTS */
  5228. static int
  5229. tthflow(flow, status, attrs)
  5230. int flow, /* Type of flow control (ckcdeb.h) */
  5231. status; /* Nonzero = turn it on */
  5232. /* Zero = turn it off */
  5233. #ifdef BSD44ORPOSIX /* POSIX or BSD44 */
  5234. struct termios *attrs;
  5235. #else /* System V */
  5236. #ifdef ATTSV
  5237. #ifdef ATT7300
  5238. #ifdef UNIX351M
  5239. /* AT&T UNIX 3.51m can set but not test for hardware flow control */
  5240. #define RTSFLOW CTSCD
  5241. #define CTSFLOW CTSCD
  5242. #endif /* ATT7300 */
  5243. #endif /* UNIX351M */
  5244. struct termio *attrs;
  5245. #else /* BSD, V7, etc */
  5246. struct sgttyb *attrs; /* sgtty info... */
  5247. #endif /* ATTSV */
  5248. #endif /* BSD44ORPOSIX */
  5249. /* tthflow */ {
  5250. int x = 0; /* tthflow() return code */
  5251. #ifdef Plan9
  5252. return p9tthflow(flow, status);
  5253. #else
  5254. #ifndef OXOS /* NOT Olivetti X/OS... */
  5255. /*
  5256. For SunOS 4.0 and later in the BSD environment ...
  5257. The declarations are copied and interpreted from the System V header files,
  5258. so we don't actually have to pull in all the System V junk when building
  5259. C-Kermit for SunOS in the BSD environment, which would be dangerous because
  5260. having those symbols defined would cause us to take the wrong paths through
  5261. the code. The code in this section is used in both the BSD and Sys V SunOS
  5262. versions.
  5263. */
  5264. #ifdef SUNOS41
  5265. /*
  5266. In SunOS 4.1 and later, we use the POSIX calls rather than ioctl calls
  5267. because GNU CC uses different formats for the _IOxxx macros than regular CC;
  5268. the POSIX forms work for both. But the POSIX calls are not available in
  5269. SunOS 4.0.
  5270. */
  5271. #define CRTSCTS 0x80000000 /* RTS/CTS flow control */
  5272. #define TCSANOW 0 /* Do it now */
  5273. struct termios {
  5274. unsigned long c_iflag; /* Input modes */
  5275. unsigned long c_oflag; /* Output modes */
  5276. unsigned long c_cflag; /* Control modes */
  5277. unsigned long c_lflag; /* Line discipline modes */
  5278. char c_line;
  5279. CHAR c_cc[17];
  5280. };
  5281. struct termios temp;
  5282. _PROTOTYP( int tcgetattr, (int, struct termios *) );
  5283. _PROTOTYP( int tcsetattr, (int, int, struct termios *) );
  5284. /*
  5285. When CRTSCTS is set, SunOS won't do output unless both CTS and CD are
  5286. asserted. So we don't set CRTSCTS unless CD is up. This should be OK,
  5287. since we don't need RTS/CTS during dialing, and after dialing is complete,
  5288. we should have CD. If not, we still communicate, but without RTS/CTS.
  5289. */
  5290. int mflags; /* Modem signal flags */
  5291. #ifdef NETCMD
  5292. if (ttpipe) return(0);
  5293. #endif /* NETCMD */
  5294. #ifdef NETPTY
  5295. if (ttpty) return(0);
  5296. #endif /* NETPTY */
  5297. debug(F101,"tthflow SUNOS41 entry status","",status);
  5298. if (!status) { /* Turn hard flow off */
  5299. if (tcgetattr(ttyfd, &temp) > -1 && /* Get device attributes */
  5300. (temp.c_cflag & CRTSCTS)) { /* Check for RTS/CTS */
  5301. temp.c_cflag &= ~CRTSCTS; /* It's there, remove it */
  5302. x = tcsetattr(ttyfd,TCSANOW,&temp);
  5303. }
  5304. } else { /* Turn hard flow on */
  5305. if (ioctl(ttyfd,TIOCMGET,&mflags) > -1 && /* Get modem signals */
  5306. (mflags & TIOCM_CAR)) { /* Check for CD */
  5307. debug(F100,"tthflow SunOS has CD","",0);
  5308. if (tcgetattr(ttyfd, &temp) > -1 && /* Get device attributes */
  5309. !(temp.c_cflag & CRTSCTS)) { /* Check for RTS/CTS */
  5310. temp.c_cflag |= CRTSCTS; /* Not there, add it */
  5311. x = tcsetattr(ttyfd,TCSANOW,&temp);
  5312. }
  5313. } else {
  5314. x = -1;
  5315. debug(F100,"tthflow SunOS no CD","",0);
  5316. }
  5317. }
  5318. #else
  5319. #ifdef QNX
  5320. struct termios temp;
  5321. #ifdef NETCMD
  5322. if (ttpipe) return(0);
  5323. #endif /* NETCMD */
  5324. #ifdef NETPTY
  5325. if (ttpty) return(0);
  5326. #endif /* NETPTY */
  5327. debug(F101,"tthflow QNX entry status","",status);
  5328. if (tcgetattr(ttyfd, &temp) > -1) { /* Get device attributes */
  5329. if (!status) { /* Turn hard flow off */
  5330. if ((temp.c_cflag & (IHFLOW|OHFLOW)) == (IHFLOW|OHFLOW)) {
  5331. temp.c_cflag &= ~(IHFLOW|OHFLOW); /* It's there, remove it */
  5332. attrs->c_cflag &= ~(IHFLOW|OHFLOW);
  5333. x = tcsetattr(ttyfd,TCSANOW,&temp);
  5334. }
  5335. } else { /* Turn hard flow on */
  5336. if ((temp.c_cflag & (IHFLOW|OHFLOW)) != (IHFLOW|OHFLOW)) {
  5337. temp.c_cflag |= (IHFLOW|OHFLOW); /* Not there, add it */
  5338. temp.c_iflag &= ~(IXON|IXOFF); /* Bye to IXON/IXOFF */
  5339. ttraw.c_lflag |= IEXTEN; /* Must be on */
  5340. x = tcsetattr(ttyfd,TCSANOW,&temp);
  5341. attrs->c_cflag |= (IHFLOW|OHFLOW);
  5342. attrs->c_iflag &= ~(IXON|IXOFF);
  5343. }
  5344. }
  5345. } else {
  5346. x = -1;
  5347. debug(F100, "tthflow QNX getattr fails", "", 0);
  5348. }
  5349. #else
  5350. #ifdef POSIX_CRTSCTS
  5351. /*
  5352. POSIX_CRTSCTS is defined in ckcdeb.h or on CC command line.
  5353. Note: Do not assume CRTSCTS is a one-bit field!
  5354. */
  5355. struct termios temp;
  5356. #ifdef NETCMD
  5357. if (ttpipe) return(0);
  5358. #endif /* NETCMD */
  5359. #ifdef NETPTY
  5360. if (ttpty) return(0);
  5361. #endif /* NETPTY */
  5362. debug(F101,"tthflow POSIX_CRTSCTS entry status","",status);
  5363. errno = 0;
  5364. x = tcgetattr(ttyfd, &temp);
  5365. debug(F111,"tthflow POSIX_CRTSCTS tcgetattr",ckitoa(x),errno);
  5366. errno = 0;
  5367. if (x < 0) {
  5368. x = -1;
  5369. } else {
  5370. if (!status) { /* Turn hard flow off */
  5371. if (
  5372. #ifdef COMMENT
  5373. /* This can fail because of sign extension */
  5374. /* e.g. in Linux where it's Bit 31 */
  5375. (temp.c_cflag & CRTSCTS) == CRTSCTS
  5376. #else
  5377. (temp.c_cflag & CRTSCTS) != 0
  5378. #endif /* COMMENT */
  5379. ) {
  5380. temp.c_cflag &= ~CRTSCTS; /* It's there, remove it */
  5381. attrs->c_cflag &= ~CRTSCTS;
  5382. x = tcsetattr(ttyfd,TCSANOW,&temp);
  5383. debug(F111,"tthflow POSIX_CRTSCTS OFF tcsetattr",
  5384. ckitoa(x),errno);
  5385. } else { /* John Dunlap 2010-01-26 */
  5386. debug(F001,
  5387. "tthflow before forcing off attrs CRTSCTS",
  5388. "",
  5389. attrs->c_cflag&CRTSCTS
  5390. );
  5391. attrs->c_cflag &= ~CRTSCTS; /* force it off if !status */
  5392. debug(F001,
  5393. "tthflow after forcing off attrs CRTSCTS",
  5394. "",
  5395. attrs->c_cflag&CRTSCTS
  5396. );
  5397. }
  5398. } else { /* Turn hard flow on */
  5399. if (
  5400. #ifdef COMMENT
  5401. /* This can fail because of sign extension */
  5402. (temp.c_cflag & CRTSCTS) != CRTSCTS
  5403. #else
  5404. (temp.c_cflag & CRTSCTS) == 0
  5405. #endif /* COMMENT */
  5406. ) {
  5407. temp.c_cflag |= CRTSCTS; /* Not there, add it */
  5408. temp.c_iflag &= ~(IXON|IXOFF|IXANY); /* Bye to IXON/IXOFF */
  5409. x = tcsetattr(ttyfd,TCSANOW,&temp);
  5410. debug(F111,"tthflow POSIX_CRTSCTS ON tcsetattr",
  5411. ckitoa(x),errno);
  5412. attrs->c_cflag |= CRTSCTS;
  5413. attrs->c_iflag &= ~(IXON|IXOFF|IXANY);
  5414. }
  5415. }
  5416. }
  5417. #else
  5418. #ifdef SUNOS4
  5419. /*
  5420. SunOS 4.0 (and maybe earlier?). This code is dangerous because it
  5421. prevents compilation with GNU gcc, which uses different formats for the
  5422. _IORxxx macros than regular cc. SunOS 4.1 and later can use the POSIX
  5423. routines above, which work for both cc and gcc.
  5424. */
  5425. #define TCGETS _IOR(T, 8, struct termios) /* Get modes into termios struct */
  5426. #define TCSETS _IOW(T, 9, struct termios) /* Set modes from termios struct */
  5427. #define CRTSCTS 0x80000000 /* RTS/CTS flow control */
  5428. struct termios {
  5429. unsigned long c_iflag; /* Input modes */
  5430. unsigned long c_oflag; /* Output modes */
  5431. unsigned long c_cflag; /* Control modes */
  5432. unsigned long c_lflag; /* Line discipline modes */
  5433. char c_line;
  5434. CHAR c_cc[17];
  5435. };
  5436. struct termios temp;
  5437. #ifdef NETCMD
  5438. if (ttpipe) return(0);
  5439. #endif /* NETCMD */
  5440. #ifdef NETPTY
  5441. if (ttpty) return(0);
  5442. #endif /* NETPTY */
  5443. debug(F101,"tthflow entry status","",status);
  5444. if (ioctl(ttyfd,TCGETS,&temp) > -1) { /* Get terminal modes. */
  5445. if (status) { /* Turn hard flow on */
  5446. temp.c_cflag |= CRTSCTS; /* Add RTS/CTS to them. */
  5447. x = ioctl(ttyfd,TCSETS,&temp); /* Set them again. */
  5448. attrs->c_cflag |= CRTSCTS; /* Add to global info. */
  5449. } else { /* Turn hard flow off */
  5450. temp.c_cflag &= ~CRTSCTS;
  5451. x = ioctl(ttyfd,TCSETS,&temp);
  5452. attrs->c_cflag &= ~CRTSCTS;
  5453. }
  5454. }
  5455. #else /* Not SunOS 4.0 or later */
  5456. #ifdef AIXRS /* IBM AIX RS/6000 */
  5457. #ifndef AIX41 /* But only pre-4.x == SVR4 */
  5458. #ifdef NETCMD
  5459. if (ttpipe) return(0);
  5460. #endif /* NETCMD */
  5461. #ifdef NETPTY
  5462. if (ttpty) return(0);
  5463. #endif /* NETPTY */
  5464. if (status) {
  5465. if ((x = ioctl(ttyfd, TXADDCD, "rts")) < 0 && errno != EBUSY)
  5466. debug(F100,"hardflow TXADDCD (rts) error", "", 0);
  5467. } else {
  5468. if ((x = ioctl(ttyfd, TXDELCD, "rts")) < 0 && errno != EINVAL)
  5469. debug(F100,"hardflow TXDELCD (rts) error", "", 0);
  5470. }
  5471. #endif /* AIX41 */
  5472. #else /* Not AIX RS/6000 */
  5473. #ifdef ATTSV /* System V... */
  5474. #ifdef CK_SCOV5 /* SCO Open Server 5.0 */
  5475. #define CK_SCOUNIX
  5476. #else
  5477. #ifdef M_UNIX /* SCO UNIX 3.2v4.x or earlier */
  5478. #define CK_SCOUNIX
  5479. #endif /* M_UNIX */
  5480. #endif /* CK_SCOV5 */
  5481. #ifdef SCO_FORCE_RTSXOFF
  5482. #ifdef CK_SCOUNIX /* But not SCO OpenServer 5.0.4 */
  5483. #ifdef SCO_OSR504 /* or later... */
  5484. #undef CK_SCOUNIX
  5485. #endif /* SCO_OSR504 */
  5486. #endif /* CK_SCOUNIX */
  5487. #endif /* SCO_FORCE_RTSXOFF */
  5488. #ifdef CK_SCOUNIX
  5489. #ifdef POSIX
  5490. struct termios temp;
  5491. #ifdef NETCMD
  5492. if (ttpipe) return(0);
  5493. #endif /* NETCMD */
  5494. #ifdef NETPTY
  5495. if (ttpty) return(0);
  5496. #endif /* NETPTY */
  5497. debug(F101,"tthflow SCOUNIX POSIX entry status","",status);
  5498. errno = 0;
  5499. x = tcgetattr(ttyfd, &temp);
  5500. debug(F111,"tthflow SCO UNIX POSIX tcgetattr",ckitoa(x),errno);
  5501. #else /* POSIX */
  5502. struct termio temp;
  5503. #ifdef NETCMD
  5504. if (ttpipe) return(0);
  5505. #endif /* NETCMD */
  5506. #ifdef NETPTY
  5507. if (ttpty) return(0);
  5508. #endif /* NETPTY */
  5509. debug(F101,"tthflow SCOUNIX non-POSIX entry status","",status);
  5510. x = ioctl(ttyfd, TCGETA, &temp);
  5511. debug(F111,"tthflow SCO UNIX non-POSIX TCGETA",ckitoa(x),errno);
  5512. #endif /* POSIX */
  5513. /*
  5514. This is not really POSIX, since POSIX does not deal with hardware flow
  5515. control, but we are using the POSIX APIs. In fact, RTSFLOW and CTSFLOW
  5516. are defined in termio.h, but within #ifndef _POSIX_SOURCE..#endif. So
  5517. let's try forcing their definitions here.
  5518. */
  5519. #ifndef CTSFLOW
  5520. #define CTSFLOW 0020000
  5521. debug(F101,"tthflow SCO defining CTSFLOW","",CTSFLOW);
  5522. #else
  5523. debug(F101,"tthflow SCO CTSFLOW","",CTSFLOW);
  5524. #endif /* CTSFLOW */
  5525. #ifndef RTSFLOW
  5526. #define RTSFLOW 0040000
  5527. debug(F101,"tthflow SCO defining RTSFLOW","",RTSFLOW);
  5528. #else
  5529. debug(F101,"tthflow SCO RTSFLOW","",RTSFLOW);
  5530. #endif /* RTSFLOW */
  5531. #ifndef ORTSFL
  5532. #define ORTSFL 0100000
  5533. debug(F101,"tthflow SCO defining ORTSFL","",ORTSFL);
  5534. #else
  5535. debug(F101,"tthflow SCO ORTSFL","",ORTSFL);
  5536. #endif /* ORTSFL */
  5537. if (x != -1) {
  5538. if (status) { /* Turn it ON */
  5539. temp.c_cflag |= RTSFLOW|CTSFLOW;
  5540. attrs->c_cflag |= RTSFLOW|CTSFLOW;
  5541. #ifdef ORTSFL
  5542. temp.c_cflag &= ~ORTSFL;
  5543. attrs->c_cflag &= ~ORTSFL;
  5544. #endif /* ORTSFL */
  5545. temp.c_iflag &= ~(IXON|IXOFF|IXANY);
  5546. attrs->c_iflag &= ~(IXON|IXOFF|IXANY);
  5547. } else { /* Turn it OFF */
  5548. #ifdef ORTSFL
  5549. temp.c_cflag &= ~(RTSFLOW|CTSFLOW|ORTSFL);
  5550. attrs->c_cflag &= ~(RTSFLOW|CTSFLOW|ORTSFL);
  5551. #else /* ORTSFL */
  5552. temp.c_cflag &= ~(RTSFLOW|CTSFLOW);
  5553. attrs->c_cflag &= ~(RTSFLOW|CTSFLOW);
  5554. #endif /* ORTSFL */
  5555. }
  5556. #ifdef POSIX
  5557. x = tcsetattr(ttyfd, TCSADRAIN, &temp);
  5558. #else
  5559. x = ioctl(ttyfd, TCSETA, &temp);
  5560. #endif /* POSIX */
  5561. debug(F101,"tthflow SCO set modes","",x);
  5562. }
  5563. #else /* Not SCO UNIX */
  5564. #ifdef NETCMD
  5565. if (ttpipe) return(0);
  5566. #endif /* NETCMD */
  5567. #ifdef NETPTY
  5568. if (ttpty) return(0);
  5569. #endif /* NETPTY */
  5570. if (!status) { /* Turn it OFF */
  5571. #ifdef RTSXOFF
  5572. debug(F100,"tthflow ATTSV RTS/CTS OFF","",0);
  5573. rctsx.x_hflag &= ~(RTSXOFF|CTSXON);
  5574. #ifdef TCSETX
  5575. x = ioctl(ttyfd,TCSETX,&rctsx);
  5576. debug(F101,"tthflow ATTSV TCSETX OFF","",x);
  5577. #else
  5578. x = -1
  5579. debug(F100,"tthflow TCSETX not defined","",0);
  5580. #endif /* TCSETX */
  5581. #else
  5582. debug(F100,"tthflow ATTSV RTSXOFF not defined","",0);
  5583. #endif /* RTSXOFF */
  5584. #ifdef DTRXOFF
  5585. debug(F100,"tthflow ATTSV DTR/CD OFF","",0);
  5586. rctsx.x_hflag &= ~(DTRXOFF|CDXON);
  5587. x = ioctl(ttyfd,TCSETX,&rctsx);
  5588. debug(F101,"tthflow ATTSV DTRXOFF OFF","",x);
  5589. #else
  5590. debug(F100,"tthflow ATTSV DTRXOFF not defined","",0);
  5591. #endif /* DTRXOFF */
  5592. } else { /* Turn it ON. */
  5593. if (flow == FLO_RTSC) { /* RTS/CTS Flow control... */
  5594. debug(F100,"tthflow ATTSV RTS/CTS ON","",0);
  5595. #ifdef RTSXOFF
  5596. /* This is the preferred way, according to SVID3 */
  5597. #ifdef TCGETX
  5598. x = ioctl(ttyfd,TCGETX,&rctsx);
  5599. debug(F101,"tthflow TCGETX","",x);
  5600. if (x > -1) {
  5601. rctsx.x_hflag |= RTSXOFF | CTSXON;
  5602. x = ioctl(ttyfd,TCSETX,&rctsx);
  5603. debug(F100,"tthflow ATTSV ioctl","",x);
  5604. }
  5605. #else
  5606. debug(F100,"tthflow TCGETX not defined","",0);
  5607. x = -1
  5608. #endif /* TCGETX */
  5609. #else
  5610. debug(F100,"tthflow RTSXOFF not defined","",0);
  5611. x = -1;
  5612. #endif /* RTSXOFF */
  5613. } else if (flow == FLO_DTRC) { /* DTR/CD Flow control... */
  5614. debug(F100,"tthflow ATTSV DTR/CD ON","",0);
  5615. #ifdef DTRXOFF
  5616. /* This is straight out of SVID R4 */
  5617. if (ioctl(ttyfd,TCGETX,&rctsx) > -1) {
  5618. rctsx.x_hflag &= ~(DTRXOFF|CDXON);
  5619. x = ioctl(ttyfd,TCSETX,&rctsx);
  5620. }
  5621. #else
  5622. debug(F100,"tthflow ATTSV DTRXOFF not defined","",0);
  5623. x = -1;
  5624. #endif /* DTRXOFF */
  5625. }
  5626. }
  5627. #endif /* CK_SCOUNIX */
  5628. #else /* not System V... */
  5629. #ifdef CK_DTRCTS
  5630. #ifdef LDODTR
  5631. #ifdef LDOCTS
  5632. #ifdef NETCMD
  5633. if (ttpipe) return(0);
  5634. #endif /* NETCMD */
  5635. #ifdef NETPTY
  5636. if (ttpty) return(0);
  5637. #endif /* NETPTY */
  5638. x = LDODTR | LDOCTS; /* Found only on UTEK? */
  5639. if (flow == FLO_DTRT && status) { /* Use hardware flow control */
  5640. if (lmodef) {
  5641. x = ioctl(ttyfd,TIOCLBIS,&x);
  5642. if (x < 0) {
  5643. debug(F100,"hardflow TIOCLBIS error","",0);
  5644. } else {
  5645. lmodef++;
  5646. debug(F100,"hardflow TIOCLBIS ok","",0);
  5647. }
  5648. }
  5649. } else {
  5650. if (lmodef) {
  5651. x = ioctl(ttyfd,TIOCLBIC,&x);
  5652. if (x < 0) {
  5653. debug(F100,"hardflow TIOCLBIC error","",0);
  5654. } else {
  5655. lmodef++;
  5656. debug(F100,"hardflow TIOCLBIC ok","",0);
  5657. }
  5658. }
  5659. }
  5660. #endif /* LDODTR */
  5661. #endif /* LDOCTS */
  5662. #endif /* CK_DTRCTS */
  5663. #endif /* ATTSV */
  5664. #endif /* AIXRS */
  5665. #endif /* SUNOS4 */
  5666. #endif /* QNX */
  5667. #endif /* POSIX_CRTSCTS */
  5668. #endif /* SUNOS41 */
  5669. #else /* OXOS */
  5670. struct termios temp; /* Olivetti X/OS ... */
  5671. #ifdef NETCMD
  5672. if (ttpipe) return(0);
  5673. #endif /* NETCMD */
  5674. #ifdef NETPTY
  5675. if (ttpty) return(0);
  5676. #endif /* NETPTY */
  5677. x = ioctl(ttyfd,TCGETS,&temp);
  5678. if (x == 0) {
  5679. temp.c_cflag &= ~(CRTSCTS|CDTRCTS|CBRKFLOW|CDTRDSR|CRTSDSR);
  5680. if (status) {
  5681. switch (flow) {
  5682. case FLO_RTSC: temp.c_cflag |= CRTSCTS; /* RTS/CTS (hard) */
  5683. break;
  5684. case FLO_DTRT: temp.c_cflag |= CDTRCTS; /* DTR/CTS (hard) */
  5685. break;
  5686. }
  5687. }
  5688. x = ioctl(ttyfd,TCSETS,&temp);
  5689. }
  5690. #endif /* OXOS */
  5691. return(x);
  5692. #endif /* Plan9 */
  5693. }
  5694. /* T T P K T -- Condition the communication line for packets */
  5695. /* or for modem dialing */
  5696. /*
  5697. If called with speed > -1, also set the speed.
  5698. Returns 0 on success, -1 on failure.
  5699. NOTE: the "xflow" parameter is supposed to be the currently selected
  5700. type of flow control, but for historical reasons, this parameter is also
  5701. used to indicate that we are dialing. Therefore, when the true flow
  5702. control setting is needed, we access the external variable "flow", rather
  5703. than trusting our "xflow" argument.
  5704. */
  5705. int
  5706. #ifdef CK_ANSIC
  5707. ttpkt(long speed, int xflow, int parity)
  5708. #else
  5709. ttpkt(speed,xflow,parity) long speed; int xflow, parity;
  5710. #endif /* CK_ANSIC */
  5711. /* ttpkt */ {
  5712. #ifndef NOLOCAL
  5713. int s2;
  5714. int s = -1;
  5715. #endif /* NOLOCAL */
  5716. int x;
  5717. extern int flow; /* REAL flow-control setting */
  5718. if (ttyfd < 0) return(-1); /* Not open. */
  5719. debug(F101,"ttpkt parity","",parity);
  5720. debug(F101,"ttpkt xflow","",xflow);
  5721. debug(F101,"ttpkt speed","",(int) speed);
  5722. ttprty = parity; /* Let other tt functions see these. */
  5723. ttspeed = speed; /* Make global copy for this module */
  5724. ttpmsk = ttprty ? 0177 : 0377; /* Parity stripping mask */
  5725. #ifdef PARSENSE
  5726. needpchk = ttprty ? 0 : 1; /* Parity check needed? */
  5727. #else
  5728. needpchk = 0;
  5729. #endif /* PARSENSE */
  5730. debug(F101,"ttpkt ttpmsk","",ttpmsk);
  5731. debug(F101,"ttpkt netconn","",netconn);
  5732. #ifdef NETCONN /* No mode-changing for telnet */
  5733. if (netconn) {
  5734. #ifdef TCPSOCKET
  5735. #ifdef TCP_NODELAY
  5736. if (ttnet == NET_TCPB) { /* But turn off Nagle */
  5737. extern int tcp_nodelay;
  5738. nodelay_sav = tcp_nodelay;
  5739. no_delay(ttyfd,1);
  5740. }
  5741. #endif /* TCP_NODELAY */
  5742. #ifdef TN_COMPORT
  5743. if (istncomport()) {
  5744. int rc = -1;
  5745. if (tvtflg == 0 && speed == ttspeed && flow == ttflow
  5746. /* && ttcarr == curcarr */ ) {
  5747. debug(F100,"ttpkt modes already set, skipping...","",0);
  5748. return(0); /* Already been called. */
  5749. }
  5750. if (flow != ttflow) {
  5751. if ((rc = tnsetflow(flow)) < 0)
  5752. return(rc);
  5753. ttflow = flow;
  5754. }
  5755. if (speed != ttspeed) {
  5756. if (speed <= 0)
  5757. speed = tnc_get_baud();
  5758. else if ((rc = tnc_set_baud(speed)) < 0)
  5759. return(rc);
  5760. ttspeed = speed;
  5761. }
  5762. tnc_set_datasize(8);
  5763. tnc_set_stopsize(stopbits);
  5764. #ifdef HWPARITY
  5765. if (hwparity) {
  5766. switch (hwparity) {
  5767. case 'e': /* Even */
  5768. debug(F100,"ttres 8 bits + even parity","",0);
  5769. tnc_set_parity(3);
  5770. break;
  5771. case 'o': /* Odd */
  5772. debug(F100,"ttres 8 bits + odd parity","",0);
  5773. tnc_set_parity(2);
  5774. break;
  5775. case 'm': /* Mark */
  5776. debug(F100,"ttres 8 bits + invalid parity: mark","",0);
  5777. tnc_set_parity(4);
  5778. break;
  5779. case 's': /* Space */
  5780. debug(F100,"ttres 8 bits + invalid parity: space","",0);
  5781. tnc_set_parity(5);
  5782. break;
  5783. }
  5784. } else
  5785. #endif /* HWPARITY */
  5786. {
  5787. tnc_set_parity(1); /* None */
  5788. }
  5789. tvtflg = 0;
  5790. return(0);
  5791. }
  5792. #endif /* TN_COMPORT */
  5793. #endif /* TCPSOCKET */
  5794. tvtflg = 0;
  5795. return(0);
  5796. }
  5797. #endif /* NETCONN */
  5798. #ifdef NETCMD
  5799. if (ttpipe) return(0);
  5800. #endif /* NETCMD */
  5801. #ifdef NETPTY
  5802. if (ttpty) return(0);
  5803. #endif /* NETPTY */
  5804. #ifndef Plan9
  5805. if (ttfdflg && !isatty(ttyfd)) return(0);
  5806. #endif /* Plan9 */
  5807. #ifdef COHERENT
  5808. #define SVORPOSIX
  5809. #endif /* COHERENT */
  5810. #ifndef SVORPOSIX /* Berkeley, V7, etc. */
  5811. #ifdef LPASS8
  5812. /*
  5813. For some reason, with BSD terminal drivers, you can't set FLOW to XON/XOFF
  5814. after having previously set it to NONE without closing and reopening the
  5815. device. Unless there's something I overlooked below...
  5816. */
  5817. if (ttflow == FLO_NONE && flow == FLO_XONX && xlocal == 0) {
  5818. debug(F101,"ttpkt executing horrible flow kludge","",0);
  5819. ttclos(0); /* Close it */
  5820. x = 0;
  5821. ttopen(ttnmsv,&x,ttmdm,0); /* Open it again */
  5822. }
  5823. #endif /* LPASS8 */
  5824. #endif /* SVORPOSIX */
  5825. #ifdef COHERENT /* This must be vestigial since we */
  5826. #undef SVORPOSIX /* reverse it a few lines below... */
  5827. #endif /* COHERENT */
  5828. if (xflow != FLO_DIAL && xflow != FLO_DIAX)
  5829. ttflow = xflow; /* Now make this available too. */
  5830. #ifndef NOLOCAL
  5831. if (xlocal) {
  5832. s2 = (int) (speed / 10L); /* Convert bps to cps */
  5833. debug(F101,"ttpkt calling ttsspd","",s2);
  5834. s = ttsspd(s2); /* Check and set the speed */
  5835. debug(F101,"ttpkt ttsspd result","",s);
  5836. carrctl(&ttraw, xflow != FLO_DIAL /* Carrier control */
  5837. && (ttcarr == CAR_ON || (ttcarr == CAR_AUT && ttmdm != 0)));
  5838. tvtflg = 0; /* So ttvt() will work next time */
  5839. }
  5840. #endif /* NOLOCAL */
  5841. #ifdef COHERENT
  5842. #define SVORPOSIX
  5843. #endif /* COHERENT */
  5844. #ifndef SVORPOSIX /* BSD section */
  5845. if (flow == FLO_RTSC || /* Hardware flow control */
  5846. flow == FLO_DTRC ||
  5847. flow == FLO_DTRT) {
  5848. tthflow(flow, 1, &ttraw);
  5849. debug(F100,"ttpkt hard flow, TANDEM off, RAW on","",0);
  5850. ttraw.sg_flags &= ~TANDEM; /* Turn off software flow control */
  5851. ttraw.sg_flags |= RAW; /* Enter raw mode */
  5852. } else if (flow == FLO_NONE) { /* No flow control */
  5853. debug(F100,"ttpkt no flow, TANDEM off, RAW on","",0);
  5854. ttraw.sg_flags &= ~TANDEM; /* Turn off software flow control */
  5855. tthflow(flow, 0, &ttraw); /* Turn off any hardware f/c too */
  5856. ttraw.sg_flags |= RAW; /* Enter raw mode */
  5857. } else if (flow == FLO_KEEP) { /* Keep device's original setting */
  5858. debug(F100,"ttpkt keeping original TANDEM","",0);
  5859. ttraw.sg_flags &= ~TANDEM;
  5860. ttraw.sg_flags |= (ttold.sg_flags & TANDEM);
  5861. /* NOTE: We should also handle hardware flow control here! */
  5862. }
  5863. /* SET FLOW XON/XOFF is in effect, or SET FLOW KEEP resulted in Xon/Xoff */
  5864. if ((flow == FLO_XONX) || (ttraw.sg_flags & TANDEM)) {
  5865. debug(F100,"ttpkt turning on TANDEM","",0);
  5866. ttraw.sg_flags |= TANDEM; /* So ask for it. */
  5867. #ifdef LPASS8 /* Can pass 8-bit data through? */
  5868. /* If the LPASS8 local mode is available, then flow control can always */
  5869. /* be used, even if parity is none and we are transferring 8-bit data. */
  5870. /* But we only need to do all this if Xon/Xoff is requested. */
  5871. /* BUT... this tends not to work through IP or LAT connections, terminal */
  5872. /* servers, telnet, rlogin, etc, so it is currently disabled. */
  5873. x = LPASS8; /* If LPASS8 defined, then */
  5874. debug(F100,"ttpkt executing LPASS8 code","",0);
  5875. if (lmodef) { /* TIOCLBIS must be too. */
  5876. x = ioctl(ttyfd,TIOCLBIS,&x); /* Try to set LPASS8. */
  5877. if (x < 0) {
  5878. debug(F100,"ttpkt TIOCLBIS error","",0);
  5879. } else {
  5880. lmodef++;
  5881. debug(F100,"ttpkt TIOCLBIS ok","",0);
  5882. }
  5883. }
  5884. /*
  5885. But if we use LPASS8 mode, we must explicitly turn off
  5886. terminal interrupts of all kinds.
  5887. */
  5888. #ifdef TIOCGETC /* Not rawmode, */
  5889. if (tcharf && (xlocal == 0)) { /* must turn off */
  5890. tchnoi.t_intrc = -1; /* interrupt character */
  5891. tchnoi.t_quitc = -1; /* and quit character. */
  5892. tchnoi.t_startc = 17; /* Make sure xon */
  5893. tchnoi.t_stopc = 19; /* and xoff not ignored. */
  5894. #ifndef NOBRKC
  5895. tchnoi.t_eofc = -1; /* eof character. */
  5896. tchnoi.t_brkc = -1; /* brk character. */
  5897. #endif /* NOBRKC */
  5898. if (ioctl(ttyfd,TIOCSETC,&tchnoi) < 0) {
  5899. debug(F100,"ttpkt TIOCSETC failed","",0);
  5900. } else {
  5901. tcharf = 1;
  5902. debug(F100,"ttpkt TIOCSETC ok","",0);
  5903. }
  5904. #ifdef COMMENT
  5905. /* only for paranoid debugging */
  5906. if (tcharf) {
  5907. struct tchars foo;
  5908. char tchbuf[100];
  5909. ioctl(0,TIOCGETC,&foo);
  5910. sprintf(tchbuf,
  5911. "intr=%d,quit=%d, start=%d, stop=%d, eof=%d, brk=%d",
  5912. foo.t_intrc, foo.t_quitc, foo.t_startc,
  5913. foo.t_stopc, foo.t_eofc, foo.t_brkc);
  5914. debug(F110,"ttpkt chars",tchbuf,0);
  5915. }
  5916. #endif /* COMMENT */
  5917. }
  5918. ttraw.sg_flags |= CBREAK; /* Needed for unknown reason */
  5919. #endif /* TIOCGETC */
  5920. /* Prevent suspend during packet mode */
  5921. #ifdef TIOCGLTC /* Not rawmode, */
  5922. if (ltcharf && (xlocal == 0)) { /* must turn off */
  5923. ltchnoi.t_suspc = -1; /* suspend character */
  5924. ltchnoi.t_dsuspc = -1; /* and delayed suspend character */
  5925. if (ioctl(ttyfd,TIOCSLTC,&tchnoi) < 0) {
  5926. debug(F100,"ttpkt TIOCSLTC failed","",0);
  5927. } else {
  5928. ltcharf = 1;
  5929. debug(F100,"ttpkt TIOCSLTC ok","",0);
  5930. }
  5931. }
  5932. #endif /* TIOCGLTC */
  5933. #else /* LPASS8 not defined */
  5934. /* Previously, BSD-based implementations always */
  5935. /* used rawmode for packets. Now, we use rawmode only if parity is NONE. */
  5936. /* This allows the flow control requested above to actually work, but only */
  5937. /* if the user asks for parity (which also means they get 8th-bit quoting). */
  5938. if (parity) { /* If parity, */
  5939. ttraw.sg_flags &= ~RAW; /* use cooked mode */
  5940. #ifdef COMMENT
  5941. /* WHY??? */
  5942. if (xlocal)
  5943. #endif /* COMMENT */
  5944. ttraw.sg_flags |= CBREAK;
  5945. debug(F101,"ttpkt cooked, cbreak, parity","",parity);
  5946. #ifdef TIOCGETC /* Not rawmode, */
  5947. if (tcharf && (xlocal == 0)) { /* must turn off */
  5948. tchnoi.t_intrc = -1; /* interrupt character */
  5949. tchnoi.t_quitc = -1; /* and quit character. */
  5950. tchnoi.t_startc = 17; /* Make sure xon */
  5951. tchnoi.t_stopc = 19; /* and xoff not ignored. */
  5952. #ifndef NOBRKC
  5953. tchnoi.t_eofc = -1; /* eof character. */
  5954. tchnoi.t_brkc = -1; /* brk character. */
  5955. #endif /* NOBRKC */
  5956. if (ioctl(ttyfd,TIOCSETC,&tchnoi) < 0) {
  5957. debug(F100,"ttpkt TIOCSETC failed","",0);
  5958. } else {
  5959. tcharf = 1;
  5960. debug(F100,"ttpkt TIOCSETC ok","",0);
  5961. }
  5962. }
  5963. #endif /* TIOCGETC */
  5964. #ifdef TIOCGLTC /* Not rawmode, */
  5965. /* Prevent suspend during packet mode */
  5966. if (ltcharf && (xlocal == 0)) { /* must turn off */
  5967. ltchnoi.t_suspc = -1; /* suspend character */
  5968. ltchnoi.t_dsuspc = -1; /* and delayed suspend character */
  5969. if (ioctl(ttyfd,TIOCSLTC,&tchnoi) < 0) {
  5970. debug(F100,"ttpkt TIOCSLTC failed","",0);
  5971. } else {
  5972. ltcharf = 1;
  5973. debug(F100,"ttpkt TIOCSLTC ok","",0);
  5974. }
  5975. }
  5976. #endif /* TIOCGLTC */
  5977. } else { /* If no parity, */
  5978. ttraw.sg_flags |= RAW; /* must use 8-bit raw mode. */
  5979. debug(F101,"ttpkt setting rawmode, parity","",parity);
  5980. }
  5981. #endif /* LPASS8 */
  5982. } /* End of Xon/Xoff section */
  5983. /* Don't echo, don't map CR to CRLF on output, don't fool with case */
  5984. #ifdef LCASE
  5985. ttraw.sg_flags &= ~(ECHO|CRMOD|LCASE);
  5986. #else
  5987. ttraw.sg_flags &= ~(ECHO|CRMOD);
  5988. #endif /* LCASE */
  5989. #ifdef TOWER1
  5990. ttraw.sg_flags &= ~ANYP; /* Must set this on old Towers */
  5991. #endif /* TOWER1 */
  5992. #ifdef BELLV10
  5993. if (ioctl(ttyfd,TIOCSETP,&ttraw) < 0) /* Set the new modes. */
  5994. return(-1);
  5995. #else
  5996. errno = 0;
  5997. if (stty(ttyfd,&ttraw) < 0) { /* Set the new modes. */
  5998. debug(F101,"ttpkt stty failed","",errno);
  5999. return(-1);
  6000. }
  6001. #endif /* BELLV10 */
  6002. debug(F100,"ttpkt stty ok","",0);
  6003. #ifdef sony_news
  6004. x = xlocal ? km_ext : km_con; /* Put line in ASCII mode. */
  6005. if (x != -1) { /* Make sure we know original modes. */
  6006. x &= ~KM_TTYPE;
  6007. x |= KM_ASCII;
  6008. if (ioctl(ttyfd,TIOCKSET, &x) < 0) {
  6009. perror("ttpkt can't set ASCII mode");
  6010. debug(F101,"ttpkt error setting ASCII mode","",x);
  6011. return(-1);
  6012. }
  6013. }
  6014. debug(F100,"ttpkt set ASCII mode ok","",0);
  6015. #endif /* sony_news */
  6016. if (xlocal == 0) { /* Turn this off so we can read */
  6017. signal(SIGINT,SIG_IGN); /* Ctrl-C chars typed at console */
  6018. sigint_ign = 1;
  6019. }
  6020. tvtflg = 0; /* So ttvt() will work next time */
  6021. debug(F100,"ttpkt success","",0);
  6022. return(0);
  6023. #endif /* Not ATTSV or POSIX */
  6024. /* AT&T UNIX and POSIX */
  6025. #ifdef COHERENT
  6026. #define SVORPOSIX
  6027. #endif /* COHERENT */
  6028. #ifdef SVORPOSIX
  6029. if (flow == FLO_XONX) { /* Xon/Xoff */
  6030. ttraw.c_iflag |= (IXON|IXOFF);
  6031. tthflow(flow, 0, &ttraw);
  6032. } else if (flow == FLO_NONE) { /* None */
  6033. /* NOTE: We should also turn off hardware flow control here! */
  6034. ttraw.c_iflag &= ~(IXON|IXOFF);
  6035. tthflow(flow, 0, &ttraw);
  6036. } else if (flow == FLO_KEEP) { /* Keep */
  6037. ttraw.c_iflag &= ~(IXON|IXOFF); /* Turn off Xon/Xoff flags */
  6038. ttraw.c_iflag |= (ttold.c_iflag & (IXON|IXOFF)); /* OR in old ones */
  6039. /* NOTE: We should also handle hardware flow control here! */
  6040. #ifdef POSIX_CRTSCTS
  6041. /* In Linux case, we do this, which is unlikely to be portable */
  6042. ttraw.c_cflag &= ~CRTSCTS; /* Turn off RTS/CTS flag */
  6043. ttraw.c_cflag |= (ttold.c_cflag & CRTSCTS); /* OR in old one */
  6044. #endif /* POSIX_CRTSCTS */
  6045. } else if (flow == FLO_RTSC || /* Hardware */
  6046. flow == FLO_DTRC ||
  6047. flow == FLO_DTRT) {
  6048. ttraw.c_iflag &= ~(IXON|IXOFF); /* (190) */
  6049. tthflow(flow, 1, &ttraw);
  6050. }
  6051. ttraw.c_lflag &= ~(ICANON|ECHO);
  6052. ttraw.c_lflag &= ~ISIG; /* Do NOT check for interrupt chars */
  6053. #ifndef OXOS
  6054. #ifdef QNX
  6055. if (flow != FLO_RTSC && flow != FLO_DTRC && flow != FLO_DTRT)
  6056. #endif /* QNX */
  6057. #ifndef COHERENT
  6058. ttraw.c_lflag &= ~IEXTEN; /* Turn off ^O/^V processing */
  6059. #endif /* COHERENT */
  6060. #else /* OXOS */
  6061. ttraw.c_cc[VDISCARD] = ttraw.c_cc[VLNEXT] = CDISABLE;
  6062. #endif /* OXOS */
  6063. ttraw.c_lflag |= NOFLSH; /* Don't flush */
  6064. ttraw.c_iflag |= IGNPAR; /* Ignore parity errors */
  6065. #ifdef ATTSV
  6066. #ifdef BSD44
  6067. ttraw.c_iflag &= ~(IGNBRK|INLCR|IGNCR|ICRNL|INPCK|ISTRIP|IXANY);
  6068. #else
  6069. ttraw.c_iflag &= ~(IGNBRK|INLCR|IGNCR|ICRNL|IUCLC|INPCK|ISTRIP|IXANY);
  6070. #endif /* BSD44 */
  6071. #else /* POSIX */
  6072. ttraw.c_iflag &= ~(IGNBRK|INLCR|IGNCR|ICRNL|INPCK|ISTRIP);
  6073. #endif /* ATTSV */
  6074. ttraw.c_oflag &= ~OPOST;
  6075. ttraw.c_cflag &= ~(CSIZE);
  6076. ttraw.c_cflag |= (CS8|CREAD|HUPCL);
  6077. #ifdef CSTOPB
  6078. if (xlocal) {
  6079. if (stopbits == 2) {
  6080. ttraw.c_cflag |= CSTOPB; /* 2 stop bits */
  6081. debug(F100,"ttpkt 2 stopbits","",0);
  6082. } else if (stopbits == 1) {
  6083. ttraw.c_cflag &= ~(CSTOPB); /* 1 stop bit */
  6084. debug(F100,"ttpkt 1 stopbit","",0);
  6085. }
  6086. }
  6087. #endif /* CSTOPB */
  6088. #ifdef HWPARITY
  6089. if (hwparity && xlocal) { /* Hardware parity */
  6090. ttraw.c_cflag |= PARENB; /* Enable parity */
  6091. #ifdef COMMENT
  6092. /* Uncomment this only if needed -- I don't think it is */
  6093. ttraw.c_cflag &= ~(CSIZE); /* Clear out character-size mask */
  6094. ttraw.c_cflag |= CS8; /* And set it to 8 */
  6095. #endif /* COMMENT */
  6096. #ifdef IGNPAR
  6097. ttraw.c_iflag |= IGNPAR; /* Don't discard incoming bytes */
  6098. debug(F100,"ttpkt IGNPAR","",0); /* that have parity errors */
  6099. #endif /* IGNPAR */
  6100. switch (hwparity) {
  6101. case 'e': /* Even */
  6102. ttraw.c_cflag &= ~(PARODD);
  6103. debug(F100,"ttpkt 8 bits + even parity","",0);
  6104. break;
  6105. case 'o': /* Odd */
  6106. ttraw.c_cflag |= PARODD;
  6107. debug(F100,"ttpkt 8 bits + odd parity","",0);
  6108. break;
  6109. case 'm': /* Mark */
  6110. case 's': /* Space */
  6111. /* PAREXT is mentioned in SVID but the details are not given. */
  6112. /* PAREXT is not included in POSIX ISO/IEC 9945-1. */
  6113. debug(F100,"ttpkt 8 bits + invalid parity","",0);
  6114. break;
  6115. }
  6116. } else { /* We handle parity ourselves */
  6117. #endif /* HWPARITY */
  6118. ttraw.c_cflag &= ~(PARENB); /* Don't enable parity */
  6119. #ifdef HWPARITY
  6120. }
  6121. #endif /* HWPARITY */
  6122. #ifdef IX370
  6123. ttraw.c_cc[4] = 48; /* So Series/1 doesn't interrupt on every char */
  6124. ttraw.c_cc[5] = 1;
  6125. #else
  6126. #ifndef VEOF /* for DGUX this is VEOF, not VMIN */
  6127. ttraw.c_cc[4] = 1; /* [VMIN] return max of this many characters or */
  6128. #else
  6129. #ifndef OXOS
  6130. #ifdef VMIN
  6131. ttraw.c_cc[VMIN] = 1;
  6132. #endif /* VMIN */
  6133. #else /* OXOS */
  6134. ttraw.c_min = 1;
  6135. #endif /* OXOS */
  6136. #endif /* VEOF */
  6137. #ifndef VEOL /* for DGUX this is VEOL, not VTIME */
  6138. ttraw.c_cc[5] = 0; /* [VTIME] when this many secs/10 expire w/no input */
  6139. #else
  6140. #ifndef OXOS
  6141. #ifdef VTIME
  6142. ttraw.c_cc[VTIME] = 0;
  6143. #endif /* VTIME */
  6144. #else /* OXOS */
  6145. ttraw.c_time = 0;
  6146. #endif /* OXOS */
  6147. #endif /* VEOL */
  6148. #endif /* IX370 */
  6149. #ifdef VINTR /* Turn off interrupt character */
  6150. if (xlocal == 0) /* so ^C^C can break us out of */
  6151. ttraw.c_cc[VINTR] = 0; /* packet mode. */
  6152. #endif /* VINTR */
  6153. #ifdef Plan9
  6154. if (p9ttyparity('n') < 0)
  6155. return -1;
  6156. #else
  6157. #ifdef BSD44ORPOSIX
  6158. errno = 0;
  6159. #ifdef BEOSORBEBOX
  6160. ttraw.c_cc[VMIN] = 0; /* DR7 can only poll. */
  6161. #endif /* BEOSORBEBOX */
  6162. #define TESTING234
  6163. #ifdef TESTING234
  6164. if (1) {
  6165. debug(F100,"ttpkt TESTING234 rawmode","",0);
  6166. /* iflags */
  6167. ttraw.c_iflag &= ~(PARMRK|ISTRIP|BRKINT|INLCR|IGNCR|ICRNL);
  6168. ttraw.c_iflag &= ~(INPCK|IGNPAR|IXON|IXOFF);
  6169. ttraw.c_iflag |= IGNBRK;
  6170. #ifdef IMAXBEL
  6171. ttraw.c_iflag &= ~IMAXBEL;
  6172. #endif /* IMAXBEL */
  6173. #ifdef IXANY
  6174. ttraw.c_iflag &= ~IXANY;
  6175. #endif /* IXANY */
  6176. #ifdef IUCLC
  6177. ttraw.c_iflag &= ~IUCLC;
  6178. #endif /* IUCLC */
  6179. /* oflags */
  6180. ttraw.c_oflag &= ~OPOST;
  6181. #ifdef OXTABS
  6182. ttraw.c_oflag &= ~OXTABS;
  6183. #endif /* OXTABS */
  6184. #ifdef ONOCR
  6185. ttraw.c_oflag &= ~ONOCR;
  6186. #endif /* ONOCR */
  6187. #ifdef ONLRET
  6188. ttraw.c_oflag &= ~ONLRET;
  6189. #endif /* ONLRET */
  6190. #ifdef ONLCR
  6191. ttraw.c_oflag &= ~ONLCR;
  6192. #endif /* ONLCR */
  6193. /* lflags */
  6194. ttraw.c_lflag &= ~ECHO;
  6195. #ifdef ECHOE
  6196. ttraw.c_lflag &= ~ECHOE;
  6197. #endif /* ECHOE */
  6198. #ifdef ECHONL
  6199. ttraw.c_lflag &= ~ECHONL;
  6200. #endif /* ECHONL */
  6201. #ifdef ECHOPRT
  6202. ttraw.c_lflag &= ~ECHOPRT;
  6203. #endif /* ECHOPRT */
  6204. #ifdef ECHOKE
  6205. ttraw.c_lflag &= ~ECHOKE;
  6206. #endif /* ECHOKE */
  6207. #ifdef ECHOCTL
  6208. ttraw.c_lflag &= ~ECHOCTL;
  6209. #endif /* ECHOCTL */
  6210. #ifdef ALTWERASE
  6211. ttraw.c_lflag &= ~ALTWERASE;
  6212. #endif /* ALTWERASE */
  6213. #ifdef EXTPROC
  6214. ttraw.c_lflag &= ~EXTPROC;
  6215. #endif /* EXTPROC */
  6216. ttraw.c_lflag &= ~(ICANON|ISIG|IEXTEN|TOSTOP|FLUSHO|PENDIN);
  6217. #ifdef NOKERNINFO
  6218. ttraw.c_lflag |= NOKERNINFO;
  6219. #endif /* NOKERNINFO */
  6220. /* ttraw.c_lflag |= NOFLSH; */
  6221. ttraw.c_lflag &= ~NOFLSH;
  6222. /* cflags */
  6223. ttraw.c_cflag &= ~(CSIZE|PARENB|PARODD);
  6224. ttraw.c_cflag |= CS8|CREAD;
  6225. #ifdef VMIN
  6226. ttraw.c_cc[VMIN] = 1; /* Supposedly needed for AIX */
  6227. #endif /* VMIN */
  6228. }
  6229. #endif /* TESTING234 */
  6230. debug(F100,"ttpkt calling tcsetattr(TCSETAW)","",0);
  6231. x = tcsetattr(ttyfd,TCSADRAIN,&ttraw);
  6232. debug(F101,"ttpkt BSD44ORPOSIX tcsetattr","",x);
  6233. if (x < 0) {
  6234. debug(F101,"ttpkt BSD44ORPOSIX tcsetattr errno","",errno);
  6235. return(-1);
  6236. }
  6237. #else /* BSD44ORPOSIX */
  6238. x = ioctl(ttyfd,TCSETAW,&ttraw);
  6239. debug(F101,"ttpkt ATTSV ioctl TCSETAW","",x);
  6240. if (x < 0) { /* set new modes . */
  6241. debug(F101,"ttpkt ATTSV ioctl TCSETAW errno","",errno);
  6242. return(-1);
  6243. }
  6244. #endif /* BSD44ORPOSIX */
  6245. #endif /* Plan9 */
  6246. tvtflg = 0;
  6247. debug(F100,"ttpkt ok","",0);
  6248. return(0);
  6249. #endif /* ATTSV */
  6250. #ifdef COHERENT
  6251. #undef SVORPOSIX
  6252. #endif /* COHERENT */
  6253. }
  6254. /* T T S E T F L O W -- Set flow control immediately. */
  6255. #ifdef COHERENT
  6256. #define SVORPOSIX
  6257. #endif /* COHERENT */
  6258. int
  6259. ttsetflow(flow) int flow; {
  6260. if (ttyfd < 0) /* A channel must be open */
  6261. return(-1);
  6262. debug(F101,"ttsetflow flow","",flow);
  6263. #ifdef TN_COMPORT
  6264. if (netconn && istncomport()) {
  6265. debug(F101,"ttsetflow net modem","",ttmdm);
  6266. return(tnsetflow(flow));
  6267. }
  6268. #endif /* TN_COMPORT */
  6269. #ifdef NETCMD
  6270. if (ttpipe) return(0);
  6271. #endif /* NETCMD */
  6272. #ifdef NETPTY
  6273. if (ttpty) return(0);
  6274. #endif /* NETPTY */
  6275. #ifdef COMMENT
  6276. /* This seems to hurt... */
  6277. if (flow == FLO_KEEP)
  6278. return(0);
  6279. #endif /* COMMENT */
  6280. if (flow == FLO_RTSC || /* Hardware flow control... */
  6281. flow == FLO_DTRC ||
  6282. flow == FLO_DTRT) {
  6283. tthflow(flow, 1, &ttraw);
  6284. #ifndef SVORPOSIX
  6285. ttraw.sg_flags &= ~TANDEM; /* Turn off software flow control */
  6286. #else
  6287. ttraw.c_iflag &= ~(IXON|IXOFF);
  6288. #endif /* SVORPOSIX */
  6289. } else if (flow == FLO_XONX) { /* Xon/Xoff... */
  6290. #ifndef SVORPOSIX
  6291. ttraw.sg_flags |= TANDEM;
  6292. #else
  6293. ttraw.c_iflag |= (IXON|IXOFF);
  6294. #endif /* SVORPOSIX */
  6295. tthflow(FLO_RTSC, 0, &ttraw); /* Turn off hardware flow control */
  6296. } else if (flow == FLO_NONE) { /* No flow control */
  6297. #ifndef SVORPOSIX
  6298. ttraw.sg_flags &= ~TANDEM; /* Turn off software flow control */
  6299. #else
  6300. ttraw.c_iflag &= ~(IXON|IXOFF);
  6301. #endif /* SVORPOSIX */
  6302. tthflow(FLO_RTSC, 0, &ttraw); /* Turn off any hardware f/c too */
  6303. }
  6304. /* Set the new modes... */
  6305. #ifndef SVORPOSIX /* BSD and friends */
  6306. #ifdef BELLV10
  6307. if (ioctl(ttyfd,TIOCSETP,&ttraw) < 0)
  6308. return(-1);
  6309. #else
  6310. #ifndef MINIX2
  6311. if (stty(ttyfd,&ttraw) < 0)
  6312. return(-1);
  6313. #endif /* MINIX2 */
  6314. #endif /* BELLV10 */
  6315. #else
  6316. #ifdef BSD44ORPOSIX /* POSIX */
  6317. if (tcsetattr(ttyfd,TCSADRAIN,&ttraw) < 0)
  6318. return(-1);
  6319. #else /* System V */
  6320. if (ioctl(ttyfd,TCSETAW,&ttraw) < 0)
  6321. return(-1);
  6322. #endif /* BSD44ORPOSIX */
  6323. #endif /* SVORPOSIX */
  6324. return(0);
  6325. }
  6326. #ifdef COHERENT
  6327. #undef SVORPOSIX
  6328. #endif /* COHERENT */
  6329. /* T T V T -- Condition communication device for use as virtual terminal. */
  6330. int
  6331. #ifdef CK_ANSIC
  6332. ttvt(long speed, int flow)
  6333. #else
  6334. ttvt(speed,flow) long speed; int flow;
  6335. #endif /* CK_ANSIC */
  6336. /* ttvt */ {
  6337. int s, s2, x;
  6338. debug(F101,"ttvt ttyfd","",ttyfd);
  6339. debug(F101,"ttvt tvtflg","",tvtflg);
  6340. debug(F111,"ttvt speed",ckitoa(ttspeed),speed);
  6341. debug(F111,"ttvt flow",ckitoa(ttflow),flow);
  6342. debug(F111,"ttvt curcarr",ckitoa(ttcarr),curcarr);
  6343. /* Note: NetBSD and maybe other BSD44s have cfmakeraw() */
  6344. /* Maybe it would be simpler to use it... */
  6345. ttpmsk = 0xff;
  6346. #ifdef NOLOCAL
  6347. return(conbin((char)escchr));
  6348. #else
  6349. if (ttyfd < 0) { /* Not open. */
  6350. if (ttchk() < 0)
  6351. return(-1);
  6352. else /* But maybe something buffered. */
  6353. return(0);
  6354. }
  6355. #ifdef NETCMD
  6356. if (ttpipe) return(0);
  6357. #endif /* NETCMD */
  6358. #ifdef NETPTY
  6359. if (ttpty) return(0);
  6360. #endif /* NETPTY */
  6361. #ifdef NETCONN
  6362. if (netconn) {
  6363. #ifdef TCPSOCKET
  6364. #ifdef TCP_NODELAY
  6365. {
  6366. extern int tcp_nodelay;
  6367. if (ttnet == NET_TCPB) {
  6368. if (nodelay_sav > -1) {
  6369. no_delay(ttyfd,nodelay_sav);
  6370. nodelay_sav = -1;
  6371. }
  6372. }
  6373. }
  6374. #endif /* TCP_NODELAY */
  6375. #ifdef TN_COMPORT
  6376. if (istncomport()) {
  6377. int rc = -1;
  6378. if (tvtflg != 0 && speed == ttspeed && flow == ttflow
  6379. /* && ttcarr == curcarr */ ) {
  6380. debug(F100,"ttvt modes already set, skipping...","",0);
  6381. return(0); /* Already been called. */
  6382. }
  6383. if (flow != ttflow) {
  6384. if ((rc = tnsetflow(flow)) < 0)
  6385. return(rc);
  6386. ttflow = flow;
  6387. }
  6388. if (speed != ttspeed) {
  6389. if (speed <= 0)
  6390. speed = tnc_get_baud();
  6391. else if ((rc = tnc_set_baud(speed)) < 0)
  6392. return(rc);
  6393. ttspeed = speed;
  6394. }
  6395. tnc_set_datasize(8);
  6396. tnc_set_stopsize(stopbits);
  6397. #ifdef HWPARITY
  6398. if (hwparity) {
  6399. switch (hwparity) {
  6400. case 'e': /* Even */
  6401. debug(F100,"ttres 8 bits + even parity","",0);
  6402. tnc_set_parity(3);
  6403. break;
  6404. case 'o': /* Odd */
  6405. debug(F100,"ttres 8 bits + odd parity","",0);
  6406. tnc_set_parity(2);
  6407. break;
  6408. case 'm': /* Mark */
  6409. debug(F100,"ttres 8 bits + invalid parity: mark","",0);
  6410. tnc_set_parity(4);
  6411. break;
  6412. case 's': /* Space */
  6413. debug(F100,"ttres 8 bits + invalid parity: space","",0);
  6414. tnc_set_parity(5);
  6415. break;
  6416. }
  6417. } else
  6418. #endif /* HWPARITY */
  6419. {
  6420. tnc_set_parity(1); /* None */
  6421. }
  6422. tvtflg = 1;
  6423. return(0);
  6424. }
  6425. #endif /* TN_COMPORT */
  6426. #endif /* TCPSOCKET */
  6427. tvtflg = 1; /* Network connections... */
  6428. debug(F100,"ttvt network connection, skipping...","",0);
  6429. return(0); /* ... require no special setup */
  6430. }
  6431. #endif /* NETCONN */
  6432. if (tvtflg != 0 && speed == ttspeed && flow == ttflow
  6433. /* && ttcarr == curcarr */ )
  6434. {
  6435. debug(F100,"ttvt modes already set, skipping...","",0);
  6436. return(0); /* Already been called. */
  6437. }
  6438. if (ttfdflg
  6439. #ifndef Plan9
  6440. && !isatty(ttyfd)
  6441. #endif /* Plan9 */
  6442. ) {
  6443. debug(F100,"ttvt using external fd, skipping...","",0);
  6444. return(0);
  6445. }
  6446. debug(F100,"ttvt setting modes...","",0);
  6447. if (xlocal) { /* For external lines... */
  6448. s2 = (int) (speed / 10L);
  6449. s = ttsspd(s2); /* Check/set the speed */
  6450. carrctl(&tttvt, flow != FLO_DIAL /* Do carrier control */
  6451. && (ttcarr == CAR_ON || (ttcarr == CAR_AUT && ttmdm != 0)));
  6452. } else
  6453. s = s2 = -1;
  6454. #ifdef COHERENT
  6455. #define SVORPOSIX
  6456. #endif /* COHERENT */
  6457. #ifndef SVORPOSIX
  6458. /* Berkeley, V7, etc */
  6459. if (flow == FLO_RTSC || /* Hardware flow control */
  6460. flow == FLO_DTRC ||
  6461. flow == FLO_DTRT) {
  6462. tthflow(flow, 1, &tttvt);
  6463. debug(F100,"ttvt hard flow, TANDEM off","",0);
  6464. tttvt.sg_flags &= ~TANDEM; /* Turn off software flow control */
  6465. } else if (flow == FLO_XONX) { /* Xon/Xoff flow control */
  6466. debug(F100,"ttvt TANDEM on","",0);
  6467. tttvt.sg_flags |= TANDEM; /* Ask for it. */
  6468. tthflow(flow, 0, &tttvt); /* Turn off hardware f/c */
  6469. } else if (flow == FLO_NONE) {
  6470. debug(F100,"ttvt no flow, TANDEM off, RAW on","",0);
  6471. tttvt.sg_flags &= ~TANDEM; /* Turn off software flow control */
  6472. tthflow(flow, 0, &tttvt); /* Turn off any hardware f/c too */
  6473. tttvt.sg_flags |= RAW; /* Enter raw mode */
  6474. } else if (flow == FLO_KEEP) { /* Keep device's original setting */
  6475. debug(F100,"ttvt keeping original TANDEM","",0);
  6476. tttvt.sg_flags &= ~TANDEM;
  6477. tttvt.sg_flags |= (ttold.sg_flags & TANDEM);
  6478. /* NOTE: We should also handle hardware flow control here! */
  6479. }
  6480. tttvt.sg_flags |= RAW; /* Raw mode in all cases */
  6481. #ifdef TOWER1
  6482. tttvt.sg_flags &= ~(ECHO|ANYP); /* No echo or parity */
  6483. #else
  6484. tttvt.sg_flags &= ~ECHO; /* No echo */
  6485. #endif /* TOWER1 */
  6486. #ifdef BELLV10
  6487. if (ioctl(ttyfd,TIOCSETP,&tttvt) < 0) /* Set the new modes */
  6488. return(-1);
  6489. #else
  6490. if (stty(ttyfd,&tttvt) < 0) /* Set the new modes */
  6491. return(-1);
  6492. #endif /* BELLV10 */
  6493. #else /* It is ATTSV or POSIX */
  6494. if (flow == FLO_XONX) { /* Software flow control */
  6495. tttvt.c_iflag |= (IXON|IXOFF); /* On if requested. */
  6496. tthflow(flow, 0, &tttvt); /* Turn off hardware f/c */
  6497. debug(F100,"ttvt SVORPOSIX flow XON/XOFF","",0);
  6498. } else if (flow == FLO_NONE) { /* NONE */
  6499. tttvt.c_iflag &= ~(IXON|IXOFF); /* Turn off Xon/Xoff */
  6500. tthflow(flow, 0, &tttvt); /* Turn off hardware f/c */
  6501. debug(F100,"ttvt SVORPOSIX flow NONE","",0);
  6502. } else if (flow == FLO_KEEP) {
  6503. tttvt.c_iflag &= ~(IXON|IXOFF); /* Turn off Xon/Xoff flags */
  6504. tttvt.c_iflag |= (ttold.c_iflag & (IXON|IXOFF)); /* OR in old ones */
  6505. #ifdef POSIX_CRTSCTS
  6506. tttvt.c_cflag &= ~CRTSCTS; /* Turn off RTS/CTS flag */
  6507. tttvt.c_cflag |= (ttold.c_cflag & CRTSCTS); /* OR in old one */
  6508. #endif /* POSIX_CRTSCTS */
  6509. debug(F100,"ttvt SVORPOSIX flow KEEP","",0);
  6510. } else if (flow == FLO_RTSC || /* Hardware flow control */
  6511. flow == FLO_DTRC ||
  6512. flow == FLO_DTRT) {
  6513. tttvt.c_iflag &= ~(IXON|IXOFF); /* (196) */
  6514. tthflow(flow, 1, &tttvt);
  6515. debug(F100,"ttvt SVORPOSIX flow HARD","",0);
  6516. }
  6517. #ifndef OXOS
  6518. #ifdef COHERENT
  6519. tttvt.c_lflag &= ~(ISIG|ICANON|ECHO);
  6520. #else
  6521. tttvt.c_lflag &= ~(ISIG|ICANON|ECHO|IEXTEN);
  6522. #endif /* COHERENT */
  6523. #ifdef QNX
  6524. /* Needed for hwfc */
  6525. if (flow == FLO_RTSC || flow == FLO_DTRC || flow == FLO_DTRT)
  6526. tttvt.c_lflag |= IEXTEN;
  6527. #endif /* QNX */
  6528. #else /* OXOS */
  6529. tttvt.c_lflag &= ~(ISIG|ICANON|ECHO);
  6530. tttvt.c_cc[VDISCARD] = tttvt.c_cc[VLNEXT] = CDISABLE;
  6531. #endif /* OXOS */
  6532. tttvt.c_iflag |= (IGNBRK|IGNPAR);
  6533. /* Stop bits */
  6534. #ifdef CSTOPB
  6535. if (xlocal) {
  6536. if (stopbits == 2) {
  6537. tttvt.c_cflag |= CSTOPB; /* 2 stop bits */
  6538. debug(F100,"ttvt 2 stopbits","",0);
  6539. } else if (stopbits == 1) {
  6540. tttvt.c_cflag &= ~(CSTOPB); /* 1 stop bit */
  6541. debug(F100,"ttvt 1 stopbit","",0);
  6542. }
  6543. }
  6544. #endif /* CSTOPB */
  6545. /* Parity */
  6546. #ifdef HWPARITY
  6547. if (hwparity && xlocal) { /* Hardware parity */
  6548. #ifdef COMMENT
  6549. /* Uncomment this only if needed -- I don't think it is */
  6550. ttraw.c_cflag &= ~(CSIZE); /* Clear out character-size mask */
  6551. ttraw.c_cflag |= CS8; /* And set it to 8 */
  6552. #endif /* COMMENT */
  6553. #ifdef IGNPAR
  6554. debug(F101,"ttvt hwparity IGNPAR","",IGNPAR);
  6555. tttvt.c_iflag |= IGNPAR; /* Don't discard incoming bytes */
  6556. #endif /* IGNPAR */
  6557. tttvt.c_cflag |= PARENB; /* Enable parity */
  6558. switch (hwparity) {
  6559. case 'e': /* Even */
  6560. tttvt.c_cflag &= ~(PARODD);
  6561. debug(F100,"ttvt 8 bits + even parity","",0);
  6562. break;
  6563. case 'o': /* Odd */
  6564. tttvt.c_cflag |= PARODD;
  6565. debug(F100,"ttvt 8 bits + odd parity","",0);
  6566. break;
  6567. case 'm': /* Mark */
  6568. case 's': /* Space */
  6569. /* PAREXT is mentioned in SVID but the details are not given. */
  6570. /* PAREXT is not included in POSIX ISO/IEC 9945-1. */
  6571. debug(F100,"ttvt 8 bits + invalid parity","",0);
  6572. break;
  6573. }
  6574. } else { /* We handle parity ourselves */
  6575. #endif /* HWPARITY */
  6576. tttvt.c_cflag &= ~(PARENB); /* Don't enable parity */
  6577. #ifdef HWPARITY
  6578. }
  6579. #endif /* HWPARITY */
  6580. #ifdef ATTSV
  6581. #ifdef BSD44
  6582. /* Things not to do... */
  6583. tttvt.c_iflag &= ~(INLCR|IGNCR|ICRNL|INPCK|ISTRIP|IXANY);
  6584. #else
  6585. tttvt.c_iflag &= ~(INLCR|IGNCR|ICRNL|IUCLC|INPCK|ISTRIP|IXANY);
  6586. #endif /* BSD44 */
  6587. #else /* POSIX */
  6588. tttvt.c_iflag &= ~(INLCR|IGNCR|ICRNL|INPCK|ISTRIP);
  6589. #endif /* ATTSV */
  6590. tttvt.c_cflag &= ~(CSIZE); /* Zero out the char size field */
  6591. tttvt.c_cflag |= (CS8|CREAD|HUPCL); /* Char size 8, enable receiver, hup */
  6592. tttvt.c_oflag &= ~OPOST; /* Don't postprocess output */
  6593. #ifndef VEOF /* DGUX termio has VEOF at entry 4, see comment above */
  6594. tttvt.c_cc[4] = 1;
  6595. #else
  6596. #ifndef OXOS
  6597. #ifdef VMIN
  6598. tttvt.c_cc[VMIN] = 1;
  6599. #endif /* VMIN */
  6600. #else /* OXOS */
  6601. tttvt.c_min = 1;
  6602. #endif /* OXOS */
  6603. #endif /* VEOF */
  6604. #ifndef VEOL /* DGUX termio has VEOL at entry 5, see comment above */
  6605. tttvt.c_cc[5] = 0;
  6606. #else
  6607. #ifndef OXOS
  6608. #ifdef VTIME
  6609. tttvt.c_cc[VTIME] = 0;
  6610. #endif /* VTIME */
  6611. #else /* OXOS */
  6612. tttvt.c_time = 0;
  6613. #endif /* OXOS */
  6614. #endif /* VEOL */
  6615. #ifdef Plan9
  6616. if (p9ttyparity('n') < 0)
  6617. return -1;
  6618. #else
  6619. #ifdef BSD44ORPOSIX
  6620. errno = 0;
  6621. #ifdef BEOSORBEBOX
  6622. tttvt.c_cc[VMIN] = 0; /* DR7 can only poll. */
  6623. #endif /* BEOSORBEBOX */
  6624. x = tcsetattr(ttyfd,TCSADRAIN,&tttvt);
  6625. debug(F101,"ttvt BSD44ORPOSIX tcsetattr","",x);
  6626. if (x < 0) {
  6627. debug(F101,"ttvt BSD44ORPOSIX tcsetattr errno","",errno);
  6628. return(-1);
  6629. }
  6630. #else /* ATTSV */
  6631. x = ioctl(ttyfd,TCSETAW,&tttvt);
  6632. debug(F101,"ttvt ATTSV ioctl TCSETAW","",x);
  6633. if (x < 0) { /* set new modes . */
  6634. debug(F101,"ttvt ATTSV ioctl TCSETAW errno","",errno);
  6635. return(-1);
  6636. }
  6637. #endif /* BSD44ORPOSIX */
  6638. #endif /* Plan9 */
  6639. #endif /* ATTSV */
  6640. ttspeed = speed; /* Done, remember how we were */
  6641. ttflow = flow; /* called, so we can decide how to */
  6642. tvtflg = 1; /* respond next time. */
  6643. debug(F100,"ttvt ok","",0);
  6644. return(0);
  6645. #ifdef COHERENT
  6646. #undef SVORPOSIX
  6647. #endif /* COHERENT */
  6648. #endif /* NOLOCAL */
  6649. }
  6650. #ifndef NOLOCAL
  6651. /* Serial speed department . . . */
  6652. /*
  6653. SCO OSR5.0.x might or might not support high speeds. Sometimes they are not
  6654. defined in the header files but they are supported (e.g. when building with
  6655. UDK compiler rather than /bin/cc), sometimes vice versa. Even though 5.0.4
  6656. was the first release that came with high serial speeds standard, releases
  6657. back to 5.0.0 could use them if certain patches (or "supplements") were
  6658. applied to the SIO driver. Plus a lot of SCO installations run third-party
  6659. drivers.
  6660. */
  6661. #ifdef CK_SCOV5
  6662. #ifndef B38400
  6663. #define B38400 0000017
  6664. #endif /* B38400 */
  6665. #ifndef B57600
  6666. #define B57600 0000021
  6667. #endif /* B57600 */
  6668. #ifndef B76800
  6669. #define B76800 0000022
  6670. #endif /* B76800 */
  6671. #ifndef B115200
  6672. #define B115200 0000023
  6673. #endif /* B115200 */
  6674. #ifndef B230400
  6675. #define B230400 0000024
  6676. #endif /* B230400 */
  6677. #ifndef B460800
  6678. #define B460800 0000025
  6679. #endif /* B460800 */
  6680. #ifndef B921600
  6681. #define B921600 0000026
  6682. #endif /* B921600 */
  6683. #ifndef B1500000
  6684. #define B1500000 0000027
  6685. #endif /* B1500000 */
  6686. #endif /* CK_SCOV5 */
  6687. /*
  6688. Plan 9's native speed setting interface lets you set anything you like,
  6689. but will fail if the hardware doesn't like it, so we allow all the common
  6690. speeds.
  6691. */
  6692. #ifdef Plan9
  6693. #ifndef B50
  6694. #define B50 50
  6695. #endif /* B50 */
  6696. #ifndef B75
  6697. #define B75 75
  6698. #endif /* B75 */
  6699. #ifndef B110
  6700. #define B110 110
  6701. #endif /* B110 */
  6702. #ifndef B134
  6703. #define B134 134
  6704. #endif /* B134 */
  6705. #ifndef B200
  6706. #define B200 200
  6707. #endif /* B200 */
  6708. #ifndef B300
  6709. #define B300 300
  6710. #endif /* B300 */
  6711. #ifndef B1200
  6712. #define B1200 1200
  6713. #endif /* B1200 */
  6714. #ifndef B1800
  6715. #define B1800 1800
  6716. #endif /* B1800 */
  6717. #ifndef B2400
  6718. #define B2400 2400
  6719. #endif /* B2400 */
  6720. #ifndef B4800
  6721. #define B4800 4800
  6722. #endif /* B4800 */
  6723. #ifndef B9600
  6724. #define B9600 9600
  6725. #endif /* B9600 */
  6726. #ifndef B14400
  6727. #define B14400 14400
  6728. #endif /* B14400 */
  6729. #ifndef B19200
  6730. #define B19200 19200
  6731. #endif /* B19200 */
  6732. #ifndef B28800
  6733. #define B28800 28800
  6734. #endif /* B28800 */
  6735. #ifndef B38400
  6736. #define B38400 38400
  6737. #endif /* B38400 */
  6738. #ifndef B57600
  6739. #define B57600 57600
  6740. #endif /* B57600 */
  6741. #ifndef B76800
  6742. #define B76800 76800
  6743. #endif /* B76800 */
  6744. #ifndef B115200
  6745. #define B115200 115200
  6746. #endif /* B115200 */
  6747. #ifndef B230400
  6748. #define B230400 230400
  6749. #endif /* B230400 */
  6750. #ifndef B460800
  6751. #define B460800 460800
  6752. #endif /* B460800 */
  6753. #ifndef B921600
  6754. #define B921600 921600
  6755. #endif /* B921600 */
  6756. #ifndef B1500000
  6757. #define B1500000 1500000
  6758. #endif /* B1500000 */
  6759. #endif /* Plan9 */
  6760. /* T T S S P D -- Checks and sets transmission rate. */
  6761. /* Call with speed in characters (not bits!) per second. */
  6762. /* Returns -1 on failure, 0 if it did nothing, 1 if it changed the speed. */
  6763. #ifdef USETCSETSPEED
  6764. /*
  6765. The tcsetspeed() / tcgetspeed() interface lets you pass any number at all
  6766. to be used as a speed to be set, rather than forcing a choice from a
  6767. predefined list. It seems to be peculiar to UnixWare 7.
  6768. These are the function codes to be passed to tc[gs]etspeed(),
  6769. but for some reason they don't seem to be picked up from termios.h.
  6770. */
  6771. #ifndef TCS_ALL
  6772. #define TCS_ALL 0
  6773. #endif /* TCS_ALL */
  6774. #ifndef TCS_IN
  6775. #define TCS_IN 1
  6776. #endif /* TCS_IN */
  6777. #ifndef TCS_OUT
  6778. #define TCS_OUT 2
  6779. #endif /* TCS_OUT */
  6780. #endif /* USETCSETSPEED */
  6781. int
  6782. ttsspd(cps) int cps; {
  6783. int x;
  6784. #ifdef POSIX
  6785. /* Watch out, speed_t should be unsigned, so don't compare with -1, etc... */
  6786. speed_t
  6787. #else
  6788. int
  6789. #endif /* POSIX */
  6790. s, s2;
  6791. int ok = 1; /* Speed check result, assume ok */
  6792. #ifdef OLINUXHISPEED
  6793. unsigned int spd_flags = 0;
  6794. struct serial_struct serinfo;
  6795. #endif /* OLINUXHISPEED */
  6796. debug(F101,"ttsspd cps","",cps);
  6797. debug(F101,"ttsspd ttyfd","",ttyfd);
  6798. debug(F101,"ttsspd xlocal","",xlocal);
  6799. if (ttyfd < 0 || xlocal == 0) /* Don't set speed on console */
  6800. return(0);
  6801. #ifdef NETCONN
  6802. if (netconn) {
  6803. #ifdef TN_COMPORT
  6804. if (istncomport())
  6805. return(tnc_set_baud(cps * 10));
  6806. else
  6807. #endif /* TN_COMPORT */
  6808. return(0);
  6809. }
  6810. #endif /* NETCONN */
  6811. #ifdef NETCMD
  6812. if (ttpipe) return(0);
  6813. #endif /* NETCMD */
  6814. #ifdef NETPTY
  6815. if (ttpty) return(0);
  6816. #endif /* NETPTY */
  6817. if (cps < 0) return(-1);
  6818. s = s2 = 0; /* NB: s and s2 might be unsigned */
  6819. #ifdef USETCSETSPEED
  6820. s = cps * 10L;
  6821. x = tcgetattr(ttyfd,&ttcur); /* Get current speed */
  6822. debug(F101,"ttsspd tcgetattr","",x);
  6823. if (x < 0)
  6824. return(-1);
  6825. debug(F101,"ttsspd TCSETSPEED speed","",s);
  6826. errno = 0;
  6827. if (s == 8880L) { /* 75/1200 split speed requested */
  6828. tcsetspeed(TCS_IN, &ttcur, 1200L);
  6829. tcsetspeed(TCS_OUT, &ttcur, 75L);
  6830. } else
  6831. tcsetspeed(TCS_ALL, &ttcur, s); /* Put new speed in structs */
  6832. #ifdef DEBUG
  6833. if (errno & deblog) {
  6834. debug(F101,"ttsspd TCSETSPEED errno","",errno);
  6835. }
  6836. #endif /* DEBUG */
  6837. #ifdef COMMENT
  6838. tcsetspeed(TCS_ALL, &ttraw, s);
  6839. tcsetspeed(TCS_ALL, &tttvt, s);
  6840. tcsetspeed(TCS_ALL, &ttold, s);
  6841. #else
  6842. if (s == 8880L) { /* 75/1200 split speed requested */
  6843. tcsetspeed(TCS_IN, &ttraw, 1200L);
  6844. tcsetspeed(TCS_OUT, &ttraw, 75L);
  6845. tcsetspeed(TCS_IN, &tttvt, 1200L);
  6846. tcsetspeed(TCS_OUT, &tttvt, 75L);
  6847. tcsetspeed(TCS_IN, &ttold, 1200L);
  6848. tcsetspeed(TCS_OUT, &ttold, 75L);
  6849. } else {
  6850. tcsetspeed(TCS_ALL, &ttraw, s);
  6851. tcsetspeed(TCS_ALL, &tttvt, s);
  6852. tcsetspeed(TCS_ALL, &ttold, s);
  6853. }
  6854. #endif /* COMMENT */
  6855. x = tcsetattr(ttyfd,TCSADRAIN,&ttcur); /* Set the speed */
  6856. debug(F101,"ttsspd tcsetattr","",x);
  6857. if (x < 0)
  6858. return(-1);
  6859. #else /* Not USETCSETSPEED */
  6860. /* First check that the given speed is valid. */
  6861. switch (cps) {
  6862. #ifndef MINIX
  6863. case 0: s = B0; break;
  6864. case 5: s = B50; break;
  6865. case 7: s = B75; break;
  6866. #endif /* MINIX */
  6867. case 11: s = B110; break;
  6868. #ifndef MINIX
  6869. case 13: s = B134; break;
  6870. case 15: s = B150; break;
  6871. case 20: s = B200; break;
  6872. #endif /* MINIX */
  6873. case 30: s = B300; break;
  6874. #ifndef MINIX
  6875. case 60: s = B600; break;
  6876. #endif /* MINIX */
  6877. case 120: s = B1200; break;
  6878. #ifndef MINIX
  6879. case 180: s = B1800; break;
  6880. #endif /* MINIX */
  6881. case 240: s = B2400; break;
  6882. case 480: s = B4800; break;
  6883. #ifndef MINIX
  6884. case 888: s = B75; s2 = B1200; break; /* 888 = 75/1200 split speed */
  6885. #endif /* MINIX */
  6886. #ifdef B7200
  6887. case 720: s = B7200; break;
  6888. #endif /* B7200 */
  6889. case 960: s = B9600; break;
  6890. #ifdef B14400
  6891. case 1440: s = B14400; break;
  6892. #endif /* B14400 */
  6893. #ifdef B19200
  6894. case 1920: s = B19200; break;
  6895. #else
  6896. #ifdef EXTA
  6897. case 1920: s = EXTA; break;
  6898. #endif /* EXTA */
  6899. #endif /* B19200 */
  6900. #ifdef B28800
  6901. case 2880: s = B28800; break;
  6902. #endif /* B28800 */
  6903. #ifdef B38400
  6904. case 3840: s = B38400;
  6905. #ifdef OLINUXHISPEED
  6906. spd_flags = ~ASYNC_SPD_MASK; /* Nonzero, but zero flags */
  6907. #endif /* OLINUXHISPEED */
  6908. break;
  6909. #else /* B38400 not defined... */
  6910. #ifdef EXTB
  6911. case 3840: s = EXTB; break;
  6912. #endif /* EXTB */
  6913. #endif /* B38400 */
  6914. #ifdef HPUX
  6915. #ifdef _B57600
  6916. case 5760: s = _B57600; break;
  6917. #endif /* _B57600 */
  6918. #ifdef _B115200
  6919. case 11520: s = _B115200; break;
  6920. #endif /* _B115200 */
  6921. #else
  6922. #ifdef OLINUXHISPEED
  6923. /*
  6924. This bit from <carlo@sg.tn.tudelft.nl>:
  6925. "Only note to make is maybe this: When the ASYNC_SPD_CUST flags are set then
  6926. setting the speed to 38400 will set the custom speed (and ttgspd returns
  6927. 38400), but speeds 57600 and 115200 won't work any more because I didn't
  6928. want to mess up the speed flags when someone is doing sophisticated stuff
  6929. like custom speeds..."
  6930. */
  6931. case 5760: s = B38400; spd_flags = ASYNC_SPD_HI; break;
  6932. case 11520: s = B38400; spd_flags = ASYNC_SPD_VHI; break;
  6933. #else
  6934. #ifdef B57600
  6935. case 5760: s = B57600; break;
  6936. #endif /* B57600 */
  6937. #ifdef B76800
  6938. case 7680: s = B76800; break;
  6939. #endif /* B76800 */
  6940. #ifdef B115200
  6941. case 11520: s = B115200; break;
  6942. #endif /* B115200 */
  6943. #endif /* OLINUXHISPEED */
  6944. #ifdef B153600
  6945. case 15360: s = B153600; break;
  6946. #endif /* B153600 */
  6947. #ifdef B230400
  6948. case 23040: s = B230400; break;
  6949. #endif /* B230400 */
  6950. #ifdef B307200
  6951. case 30720: s = B307200; break;
  6952. #endif /* B307200 */
  6953. #ifdef B460800
  6954. case 46080: s = B460800; break;
  6955. #endif /* 460800 */
  6956. #ifdef B921600
  6957. case 92160: s = B921600; break;
  6958. #endif /* B921600 */
  6959. #ifdef B1500000
  6960. case 150000: s = B1500000; break;
  6961. #endif /* B1500000 */
  6962. #endif /* HPUX */
  6963. default:
  6964. ok = 0; /* Good speed not found, so not ok */
  6965. break;
  6966. }
  6967. debug(F101,"ttsspd ok","",ok);
  6968. debug(F101,"ttsspd s","",s);
  6969. if (!ok) {
  6970. debug(F100,"ttsspd fails","",0);
  6971. return(-1);
  6972. } else {
  6973. if (!s2) s2 = s; /* Set input speed */
  6974. #ifdef Plan9
  6975. if (p9ttsspd(cps) < 0)
  6976. return(-1);
  6977. #else
  6978. #ifdef BSD44ORPOSIX
  6979. x = tcgetattr(ttyfd,&ttcur); /* Get current speed */
  6980. debug(F101,"ttsspd tcgetattr","",x);
  6981. if (x < 0)
  6982. return(-1);
  6983. #ifdef OLINUXHISPEED
  6984. debug(F101,"ttsspd spd_flags","",spd_flags);
  6985. if (spd_flags && spd_flags != ASYNC_SPD_CUST) {
  6986. if (ioctl(ttyfd, TIOCGSERIAL, &serinfo) < 0) {
  6987. debug(F100,"ttsspd: TIOCGSERIAL failed","",0);
  6988. return(-1);
  6989. } else debug(F100,"ttsspd: TIOCGSERIAL ok","",0);
  6990. serinfo.flags &= ~ASYNC_SPD_MASK;
  6991. serinfo.flags |= (spd_flags & ASYNC_SPD_MASK);
  6992. if (ioctl(ttyfd, TIOCSSERIAL, &serinfo) < 0)
  6993. return(-1);
  6994. }
  6995. #endif /* OLINUXHISPEED */
  6996. cfsetospeed(&ttcur,s);
  6997. cfsetispeed(&ttcur,s2);
  6998. cfsetospeed(&ttraw,s);
  6999. cfsetispeed(&ttraw,s2);
  7000. cfsetospeed(&tttvt,s);
  7001. cfsetispeed(&tttvt,s2);
  7002. cfsetospeed(&ttold,s);
  7003. cfsetispeed(&ttold,s2);
  7004. x = tcsetattr(ttyfd,TCSADRAIN,&ttcur);
  7005. debug(F101,"ttsspd tcsetattr","",x);
  7006. if (x < 0) return(-1);
  7007. #else
  7008. #ifdef ATTSV
  7009. if (cps == 888) return(-1); /* No split speeds, sorry. */
  7010. x = ioctl(ttyfd,TCGETA,&ttcur);
  7011. debug(F101,"ttsspd TCGETA ioctl","",x);
  7012. if (x < 0) return(-1);
  7013. ttcur.c_cflag &= ~CBAUD;
  7014. ttcur.c_cflag |= s;
  7015. tttvt.c_cflag &= ~CBAUD;
  7016. tttvt.c_cflag |= s;
  7017. ttraw.c_cflag &= ~CBAUD;
  7018. ttraw.c_cflag |= s;
  7019. ttold.c_cflag &= ~CBAUD;
  7020. ttold.c_cflag |= s;
  7021. x = ioctl(ttyfd,TCSETAW,&ttcur);
  7022. debug(F101,"ttsspd TCSETAW ioctl","",x);
  7023. if (x < 0) return(-1);
  7024. #else
  7025. #ifdef BELLV10
  7026. x = ioctl(ttyfd,TIOCGDEV,&tdcur);
  7027. debug(F101,"ttsspd TIOCGDEV ioctl","",x);
  7028. if (x < 0) return(-1);
  7029. tdcur.ispeed = s2;
  7030. tdcur.ospeed = s;
  7031. errno = 0;
  7032. ok = ioctl(ttyfd,TIOCSDEV,&tdcur);
  7033. debug(F101,"ttsspd BELLV10 ioctl","",ok);
  7034. if (ok < 0) {
  7035. perror(ttnmsv);
  7036. debug(F101,"ttsspd BELLV10 errno","",ok);
  7037. return(-1);
  7038. }
  7039. #else
  7040. x = gtty(ttyfd,&ttcur);
  7041. debug(F101,"ttsspd gtty","",x);
  7042. if (x < 0) return(-1);
  7043. ttcur.sg_ospeed = s; ttcur.sg_ispeed = s2;
  7044. tttvt.sg_ospeed = s; tttvt.sg_ispeed = s2;
  7045. ttraw.sg_ospeed = s; ttraw.sg_ispeed = s2;
  7046. ttold.sg_ospeed = s; ttold.sg_ispeed = s2;
  7047. x = stty(ttyfd,&ttcur);
  7048. debug(F101,"ttsspd stty","",x);
  7049. if (x < 0) return(-1);
  7050. #endif /* BELLV10 */
  7051. #endif /* ATTSV */
  7052. #endif /* BSD44ORPOSIX */
  7053. #endif /* Plan9 */
  7054. }
  7055. return(1); /* Return 1 = success. */
  7056. #endif /* USETCSETSPEED */
  7057. }
  7058. #endif /* NOLOCAL */
  7059. /* C O N G S P D - Get speed of console terminal */
  7060. long
  7061. congspd() {
  7062. /*
  7063. This is a disgusting hack. The right way to do this would be to pass an
  7064. argument to ttgspd(), but then we'd need to change the Kermit API and
  7065. all of the ck?tio.c modules. (Currently used only for rlogin.)
  7066. */
  7067. int t1;
  7068. long spd;
  7069. #ifdef NETCONN
  7070. int t2 = netconn;
  7071. netconn = 0;
  7072. #endif /* NETCONN */
  7073. t1 = ttyfd;
  7074. ttyfd = -1;
  7075. spd = ttgspd();
  7076. debug(F101,"congspd","",spd);
  7077. #ifdef NETCONN
  7078. netconn = t2;
  7079. #endif /* NETCONN */
  7080. ttyfd = t1;
  7081. return(spd);
  7082. }
  7083. /* T T S P D L I S T -- Get list of serial speeds allowed on this platform */
  7084. #define NSPDLIST 64
  7085. static long spdlist[NSPDLIST];
  7086. /*
  7087. As written, this picks up the speeds known at compile time, and thus
  7088. apply to the system where C-Kermit was built, rather than to the one where
  7089. it is running. Suggestions for improvement are always welcome.
  7090. */
  7091. long *
  7092. ttspdlist() {
  7093. int i;
  7094. for (i = 0; i < NSPDLIST; i++) /* Initialize the list */
  7095. spdlist[i] = -1L;
  7096. i = 1;
  7097. #ifdef USETCSETSPEED /* No way to find out what's legal */
  7098. debug(F100,"ttspdlist USETCSETSPEED","",0);
  7099. spdlist[i++] = 50L;
  7100. #ifndef UW7
  7101. spdlist[i++] = 75L;
  7102. #endif /* UW7 */
  7103. spdlist[i++] = 110L;
  7104. #ifndef UW7
  7105. spdlist[i++] = 134L;
  7106. #endif /* UW7 */
  7107. spdlist[i++] = 150L;
  7108. spdlist[i++] = 200L;
  7109. spdlist[i++] = 300L;
  7110. spdlist[i++] = 600L;
  7111. spdlist[i++] = 1200L;
  7112. spdlist[i++] = 1800L;
  7113. spdlist[i++] = 2400L;
  7114. spdlist[i++] = 4800L;
  7115. spdlist[i++] = 8880L;
  7116. spdlist[i++] = 9600L;
  7117. spdlist[i++] = 14400L;
  7118. spdlist[i++] = 19200L;
  7119. spdlist[i++] = 28800L;
  7120. #ifndef UW7
  7121. spdlist[i++] = 33600L;
  7122. #endif /* UW7 */
  7123. spdlist[i++] = 38400L;
  7124. spdlist[i++] = 57600L;
  7125. spdlist[i++] = 76800L;
  7126. spdlist[i++] = 115200L;
  7127. #ifndef UW7
  7128. spdlist[i++] = 153600L;
  7129. spdlist[i++] = 230400L;
  7130. spdlist[i++] = 307200L;
  7131. spdlist[i++] = 460800L;
  7132. spdlist[i++] = 921600L;
  7133. spdlist[i++] = 1500000L;
  7134. #endif /* UW7 */
  7135. #else /* USETCSETSPEED */
  7136. debug(F100,"ttspdlist no USETCSETSPEED","",0);
  7137. #ifdef B50
  7138. debug(F101,"ttspdlist B50","",B50);
  7139. spdlist[i++] = 50L;
  7140. #endif /* B50 */
  7141. #ifdef B75
  7142. debug(F101,"ttspdlist B75","",B75);
  7143. spdlist[i++] = 75L;
  7144. #endif /* B75 */
  7145. #ifdef B110
  7146. debug(F101,"ttspdlist B110","",B110);
  7147. spdlist[i++] = 110L;
  7148. #endif /* B110 */
  7149. #ifdef B134
  7150. debug(F101,"ttspdlist B134","",B134);
  7151. spdlist[i++] = 134L;
  7152. #endif /* B134 */
  7153. #ifdef B150
  7154. debug(F101,"ttspdlist B150","",B150);
  7155. spdlist[i++] = 150L;
  7156. #endif /* B150 */
  7157. #ifdef B200
  7158. debug(F101,"ttspdlist B200","",B200);
  7159. spdlist[i++] = 200L;
  7160. #endif /* B200 */
  7161. #ifdef B300
  7162. debug(F101,"ttspdlist B300","",B300);
  7163. spdlist[i++] = 300L;
  7164. #endif /* B300 */
  7165. #ifdef B600
  7166. debug(F101,"ttspdlist B600","",B600);
  7167. spdlist[i++] = 600L;
  7168. #endif /* B600 */
  7169. #ifdef B1200
  7170. debug(F101,"ttspdlist B1200","",B1200);
  7171. spdlist[i++] = 1200L;
  7172. #endif /* B1200 */
  7173. #ifdef B1800
  7174. debug(F101,"ttspdlist B1800","",B1800);
  7175. spdlist[i++] = 1800L;
  7176. #endif /* B1800 */
  7177. #ifdef B2400
  7178. debug(F101,"ttspdlist B2400","",B2400);
  7179. spdlist[i++] = 2400L;
  7180. #endif /* B2400 */
  7181. #ifdef B4800
  7182. debug(F101,"ttspdlist B4800","",B4800);
  7183. spdlist[i++] = 4800L;
  7184. #endif /* B4800 */
  7185. #ifdef B9600
  7186. debug(F101,"ttspdlist B9600","",B9600);
  7187. spdlist[i++] = 9600L;
  7188. #endif /* B9600 */
  7189. #ifdef B14400
  7190. debug(F101,"ttspdlist B14400","",B14400);
  7191. spdlist[i++] = 14400L;
  7192. #endif /* B14400 */
  7193. #ifdef B19200
  7194. debug(F101,"ttspdlist B19200","",B19200);
  7195. spdlist[i++] = 19200L;
  7196. #else
  7197. #ifdef EXTA
  7198. debug(F101,"ttspdlist EXTA","",EXTA);
  7199. spdlist[i++] = 19200L;
  7200. #endif /* EXTA */
  7201. #endif /* B19200 */
  7202. #ifdef B28800
  7203. debug(F101,"ttspdlist B28800","",B28800);
  7204. spdlist[i++] = 28800L;
  7205. #endif /* B28800 */
  7206. #ifdef B33600
  7207. debug(F101,"ttspdlist B33600","",B33600);
  7208. spdlist[i++] = 33600L;
  7209. #endif /* B33600 */
  7210. #ifdef B38400
  7211. debug(F101,"ttspdlist B38400","",B38400);
  7212. spdlist[i++] = 38400L;
  7213. #else
  7214. #ifdef EXTB
  7215. debug(F101,"ttspdlist EXTB","",EXTB);
  7216. spdlist[i++] = 38400L;
  7217. #endif /* EXTB */
  7218. #endif /* B38400 */
  7219. #ifdef _B57600
  7220. debug(F101,"ttspdlist _B57600","",_B57600);
  7221. spdlist[i++] = 57600L;
  7222. #else
  7223. #ifdef B57600
  7224. debug(F101,"ttspdlist B57600","",B57600);
  7225. spdlist[i++] = 57600L;
  7226. #endif /* B57600 */
  7227. #endif /* _B57600 */
  7228. #ifdef B76800
  7229. debug(F101,"ttspdlist B76800","",B76800);
  7230. spdlist[i++] = 76800L;
  7231. #endif /* B76800 */
  7232. #ifdef _B115200
  7233. debug(F101,"ttspdlist _B115200","",_B115200);
  7234. spdlist[i++] = 115200L;
  7235. #else
  7236. #ifdef B115200
  7237. debug(F101,"ttspdlist B115200","",B115200);
  7238. spdlist[i++] = 115200L;
  7239. #endif /* B115200 */
  7240. #endif /* _B115200 */
  7241. #ifdef B153600
  7242. debug(F101,"ttspdlist B153600","",B153600);
  7243. spdlist[i++] = 153600L;
  7244. #endif /* B153600 */
  7245. #ifdef B230400
  7246. debug(F101,"ttspdlist B230400","",B230400);
  7247. spdlist[i++] = 230400L;
  7248. #endif /* B230400 */
  7249. #ifdef B307200
  7250. debug(F101,"ttspdlist B307200","",B307200);
  7251. spdlist[i++] = 307200L;
  7252. #endif /* B307200 */
  7253. #ifdef B460800
  7254. debug(F101,"ttspdlist B460800","",B460800);
  7255. spdlist[i++] = 460800L;
  7256. #endif /* B460800 */
  7257. #ifdef B921600
  7258. debug(F101,"ttspdlist B921600","",B921600);
  7259. spdlist[i++] = 921600L;
  7260. #endif /* B921600 */
  7261. #ifdef B1500000
  7262. spdlist[i++] = 1500000L;
  7263. #endif /* B1500000 */
  7264. #endif /* USETCSETSPEED */
  7265. spdlist[0] = i - 1; /* Return count in 0th element */
  7266. debug(F111,"ttspdlist spdlist","0",spdlist[0]);
  7267. return((long *)spdlist);
  7268. }
  7269. /* T T G S P D - Get speed of currently selected tty line */
  7270. /*
  7271. Unreliable. After SET LINE, it returns an actual speed, but not necessarily
  7272. the real speed. On some systems, it returns the line's nominal speed, from
  7273. /etc/ttytab. Even if you SET SPEED to something else, this function might
  7274. not notice.
  7275. */
  7276. long
  7277. ttgspd() { /* Get current serial device speed */
  7278. #ifdef NOLOCAL
  7279. return(-1L);
  7280. #else
  7281. #ifdef POSIX
  7282. speed_t /* Should be unsigned */
  7283. #else
  7284. int /* Isn't unsigned */
  7285. #endif /* POSIX */
  7286. s;
  7287. int x;
  7288. long ss;
  7289. #ifdef OLINUXHISPEED
  7290. unsigned int spd_flags = 0;
  7291. struct serial_struct serinfo;
  7292. #endif /* OLINUXHISPEED */
  7293. #ifdef NETCONN
  7294. if (netconn) {
  7295. #ifdef TN_COMPORT
  7296. if (istncomport())
  7297. return(tnc_get_baud());
  7298. else
  7299. #endif /* TN_COMPORT */
  7300. return(-1); /* -1 if network connection */
  7301. }
  7302. #endif /* NETCONN */
  7303. #ifdef NETCMD
  7304. if (ttpipe) return(-1);
  7305. #endif /* NETCMD */
  7306. #ifdef NETPTY
  7307. if (ttpty) return(-1);
  7308. #endif /* NETPTY */
  7309. debug(F101,"ttgspd ttyfd","",ttyfd);
  7310. #ifdef USETCSETSPEED
  7311. x = tcgetattr(ttyfd,&ttcur); /* Get current speed */
  7312. debug(F101,"ttgspd tcgetattr","",x);
  7313. printf("ttgspd tcgetattr x=%d\n",x);
  7314. if (x < 0)
  7315. return(-1);
  7316. errno = 0;
  7317. s = tcgetspeed(TCS_ALL, &ttcur);
  7318. debug(F101,"ttsspd TCGETSPEED speed","",s);
  7319. if (s == 0) {
  7320. long s1, s2;
  7321. s1 = tcgetspeed(TCS_IN, &ttcur);
  7322. s2 = tcgetspeed(TCS_OUT, &ttcur);
  7323. if (s1 == 1200L && s2 == 75L)
  7324. return(8880L);
  7325. }
  7326. #ifdef DEBUG
  7327. if (errno & deblog) {
  7328. debug(F101,"ttsspd TCGETSPEED errno","",errno);
  7329. }
  7330. #endif /* DEBUG */
  7331. return(s);
  7332. #else /* Not USETCSETSPEED */
  7333. #ifdef Plan9
  7334. if (ttyfd < 0)
  7335. ss = -1;
  7336. else
  7337. ss = ttylastspeed;
  7338. #else
  7339. #ifdef OLINUXHISPEED
  7340. debug(F100,"ttgspd Linux OLINUXHISPEED","",0);
  7341. #endif /* OLINUXHISPEED */
  7342. if (ttyfd < 0) {
  7343. #ifdef BSD44ORPOSIX
  7344. s = cfgetospeed(&ccold);
  7345. debug(F101,"ttgspd cfgetospeed 1 POSIX","",s);
  7346. #else
  7347. #ifdef ATTSV
  7348. s = ccold.c_cflag & CBAUD;
  7349. debug(F101,"ttgspd c_cflag CBAUD 1 ATTSV","",s);
  7350. #else
  7351. s = ccold.sg_ospeed; /* (obtained by congm()) */
  7352. debug(F101,"ttgspd sg_ospeed 1","",s);
  7353. #endif /* ATTSV */
  7354. #endif /* BSD44POSIX */
  7355. } else {
  7356. #ifdef BSD44ORPOSIX
  7357. if (tcgetattr(ttyfd,&ttcur) < 0) return(-1);
  7358. s = cfgetospeed(&ttcur);
  7359. debug(F101,"ttgspd cfgetospeed 2 BSDORPOSIX","",s);
  7360. #ifdef OLINUXHISPEED
  7361. if (ioctl(ttyfd,TIOCGSERIAL,&serinfo) > -1)
  7362. spd_flags = serinfo.flags & ASYNC_SPD_MASK;
  7363. debug(F101,"ttgspd spd_flags","",spd_flags);
  7364. #endif /* OLINUXHISPEED */
  7365. #else
  7366. #ifdef ATTSV
  7367. x = ioctl(ttyfd,TCGETA,&ttcur);
  7368. debug(F101,"ttgspd ioctl 2 ATTSV x","",x);
  7369. debug(F101,"ttgspd ioctl 2 ATTSV errno","",errno);
  7370. if (x < 0) return(-1);
  7371. s = ttcur.c_cflag & CBAUD;
  7372. debug(F101,"ttgspd ioctl 2 ATTSV speed","",s);
  7373. #else
  7374. #ifdef BELLV10
  7375. x = ioctl(ttyfd,TIOCGDEV,&tdcur);
  7376. debug(F101,"ttgspd ioctl 2 BELLV10 x","",x);
  7377. if (x < 0) return(-1);
  7378. s = tdcur.ospeed;
  7379. debug(F101,"ttgspd ioctl 2 BELLV10 speed","",s);
  7380. #else
  7381. x = gtty(ttyfd,&ttcur);
  7382. debug(F101,"ttgspd gtty 2 x","",x);
  7383. debug(F101,"ttgspd gtty 2 errno","",errno);
  7384. if (x < 0) return(-1);
  7385. s = ttcur.sg_ospeed;
  7386. debug(F101,"ttgspd gtty 2 speed","",s);
  7387. #endif /* BELLV10 */
  7388. #endif /* ATTSV */
  7389. #endif /* BSD44ORPOSIX */
  7390. }
  7391. debug(F101,"ttgspd code","",s);
  7392. #ifdef OLINUXHISPEED
  7393. debug(F101,"ttgspd spd_flags","",spd_flags);
  7394. #endif /* OLINUXHISPEED */
  7395. printf("ttgspd spd s=%d,B150000=%d\n",s,B1500000);
  7396. switch (s) {
  7397. #ifdef B0
  7398. case B0: ss = 0L; break;
  7399. #endif /* B0 */
  7400. #ifdef B1500000
  7401. case B1500000: ss = 1500000L; break;
  7402. #endif /* B1500000 */
  7403. #ifndef MINIX
  7404. /*
  7405. MINIX defines the Bxx symbols to be bps/100, so B50==B75, B110==B134==B150,
  7406. etc, making for many "duplicate case in switch" errors, which are fatal.
  7407. */
  7408. #ifdef B50
  7409. case B50: ss = 50L; break;
  7410. #endif /* B50 */
  7411. #ifdef B75
  7412. case B75: ss = 75L; break;
  7413. #endif /* B75 */
  7414. #endif /* MINIX */
  7415. #ifdef B110
  7416. case B110: ss = 110L; break;
  7417. #endif /* B110 */
  7418. #ifndef MINIX
  7419. #ifdef B134
  7420. case B134: ss = 134L; break;
  7421. #endif /* B134 */
  7422. #ifdef B150
  7423. case B150: ss = 150L; break;
  7424. #endif /* B150 */
  7425. #endif /* MINIX */
  7426. #ifdef B200
  7427. case B200: ss = 200L; break;
  7428. #endif /* B200 */
  7429. #ifdef B300
  7430. case B300: ss = 300L; break;
  7431. #endif /* B300 */
  7432. #ifdef B600
  7433. case B600: ss = 600L; break;
  7434. #endif /* B600 */
  7435. #ifdef B1200
  7436. case B1200: ss = 1200L; break;
  7437. #endif /* B1200 */
  7438. #ifdef B1800
  7439. case B1800: ss = 1800L; break;
  7440. #endif /* B1800 */
  7441. #ifdef B2400
  7442. case B2400: ss = 2400L; break;
  7443. #endif /* B2400 */
  7444. #ifdef B4800
  7445. case B4800: ss = 4800L; break;
  7446. #endif /* B4800 */
  7447. #ifdef B7200
  7448. case B7200: ss = 7200L; break;
  7449. #endif /* B7200 */
  7450. #ifdef B9600
  7451. case B9600: ss = 9600L; break;
  7452. #endif /* B9600 */
  7453. #ifdef B19200
  7454. case B19200: ss = 19200L; break;
  7455. #else
  7456. #ifdef EXTA
  7457. case EXTA: ss = 19200L; break;
  7458. #endif /* EXTA */
  7459. #endif /* B19200 */
  7460. #ifndef MINIX
  7461. #ifdef B38400
  7462. case B38400:
  7463. ss = 38400L;
  7464. #ifdef OLINUXHISPEED
  7465. switch(spd_flags) {
  7466. case ASYNC_SPD_HI: ss = 57600L; break;
  7467. case ASYNC_SPD_VHI: ss = 115200L; break;
  7468. }
  7469. #endif /* OLINUXHISPEED */
  7470. break;
  7471. #else
  7472. #ifdef EXTB
  7473. case EXTB: ss = 38400L; break;
  7474. #endif /* EXTB */
  7475. #endif /* B38400 */
  7476. #endif /* MINIX */
  7477. #ifdef HPUX
  7478. #ifdef _B57600
  7479. case _B57600: ss = 57600L; break;
  7480. #endif /* _B57600 */
  7481. #ifdef _B115200
  7482. case _B115200: ss = 115200L; break;
  7483. #endif /* _B115200 */
  7484. #else
  7485. #ifdef B57600
  7486. case B57600: ss = 57600L; break;
  7487. #endif /* B57600 */
  7488. #ifdef B76800
  7489. case B76800: ss = 76800L; break;
  7490. #endif /* B76800 */
  7491. #ifdef B115200
  7492. case B115200: ss = 115200L; break;
  7493. #endif /* B115200 */
  7494. #ifdef B153600
  7495. case B153600: ss = 153600L; break;
  7496. #endif /* B153600 */
  7497. #ifdef B230400
  7498. case B230400: ss = 230400L; break;
  7499. #endif /* B230400 */
  7500. #ifdef B307200
  7501. case B307200: ss = 307200L; break;
  7502. #endif /* B307200 */
  7503. #ifdef B460800
  7504. case B460800: ss = 460800L; break;
  7505. #endif /* B460800 */
  7506. #endif /* HPUX */
  7507. #ifdef B921600
  7508. case B921600: ss = 921600L; break;
  7509. #endif /* B921600 */
  7510. default:
  7511. ss = -1; break;
  7512. }
  7513. #endif /* Plan9 */
  7514. debug(F101,"ttgspd speed","",ss);
  7515. printf("ttgspd speed=%d\n",ss);
  7516. return(ss);
  7517. #endif /* USETCSETSPEED */
  7518. #endif /* NOLOCAL */
  7519. }
  7520. #ifdef MINIX2 /* Another hack alert */
  7521. #define MINIX
  7522. #endif /* MINIX2 */
  7523. /*
  7524. FIONREAD data type... This has been defined as "long" for many, many
  7525. years, and it worked OK until 64-bit platforms appeared. Thus we use
  7526. int for 64-bit platforms, but keep long for the others. If we changed
  7527. the default PEEKTYPE to int, this would probably break 16-bit builds
  7528. (note that sizeof(long) == sizeof(int) on most 32-bit platforms), many
  7529. of which we have no way of testing any more. Therefore, do not change
  7530. the default definition of PEEKTYPE -- only add exceptions to it as needed.
  7531. */
  7532. #ifdef COHERENT
  7533. #ifdef FIONREAD
  7534. #undef FIONREAD
  7535. #endif /* FIONREAD */
  7536. /* #define FIONREAD TIOCQUERY */
  7537. /* #define PEEKTYPE int */
  7538. #else /* Not COHERENT... */
  7539. #ifdef OSF32 /* Digital UNIX 3.2 or higher */
  7540. #define PEEKTYPE int
  7541. #else
  7542. #define PEEKTYPE long /* Elsewhere (see notes above) */
  7543. #endif /* OSF32 */
  7544. #endif /* COHERENT */
  7545. /* ckumyr.c by Kristoffer Eriksson, ske@pkmab.se, 15 Mar 1990. */
  7546. #ifdef MYREAD
  7547. /* Private buffer for myread() and its companions. Not for use by anything
  7548. * else. ttflui() is allowed to reset them to initial values. ttchk() is
  7549. * allowed to read my_count.
  7550. *
  7551. * my_item is an index into mybuf[]. Increment it *before* reading mybuf[].
  7552. *
  7553. * A global parity mask variable could be useful too. We could use it to
  7554. * let myread() strip the parity on its own, instead of stripping sign
  7555. * bits as it does now.
  7556. */
  7557. #ifdef BIGBUFOK
  7558. #define MYBUFLEN 32768
  7559. #else
  7560. #ifdef pdp11
  7561. #define MYBUFLEN 256
  7562. #else
  7563. #define MYBUFLEN 1024
  7564. #endif /* pdp11 */
  7565. #endif /* BIGBUFOK */
  7566. #ifdef ANYX25
  7567. #undef MYBUFLEN
  7568. #define MYBUFLEN 256
  7569. /*
  7570. On X.25 connections, there is an extra control byte at the beginning.
  7571. */
  7572. static CHAR x25buf[MYBUFLEN+1]; /* Communication device input buffer */
  7573. static CHAR *mybuf = x25buf+1;
  7574. #else
  7575. static CHAR mybuf[MYBUFLEN];
  7576. #endif /* ANYX25 */
  7577. static int my_count = 0; /* Number of chars still in mybuf */
  7578. static int my_item = -1; /* Last index read from mybuf[] */
  7579. /* T T P E E K -- Peek into our internal communications input buffers. */
  7580. /*
  7581. NOTE: This routine is peculiar to UNIX, and is used only by the
  7582. select()-based CONNECT module, ckucns.c. It need not be replicated in
  7583. the ck?tio.c of other platforms.
  7584. */
  7585. int
  7586. ttpeek() {
  7587. #ifdef TTLEBUF
  7588. int rc = 0;
  7589. if (ttpush >= 0)
  7590. rc++;
  7591. rc += le_inbuf();
  7592. if (rc > 0)
  7593. return(rc);
  7594. else
  7595. #endif /* TTLEBUF */
  7596. #ifdef MYREAD
  7597. return(my_count);
  7598. #else
  7599. return(0);
  7600. #endif /* MYREAD */
  7601. }
  7602. /* myread() -- Efficient read of one character from communications line.
  7603. *
  7604. * NOTE: myread() and its helpers mygetbuf() and myfillbuf() return raw
  7605. * bytes from connection, so when the connection is encrypted, these bytes
  7606. * must be decrypted.
  7607. *
  7608. * Uses a private buffer to minimize the number of expensive read() system
  7609. * calls. Essentially performs the equivalent of read() of 1 character, which
  7610. * is then returned. By reading all available input from the system buffers
  7611. * to the private buffer in one chunk, and then working from this buffer, the
  7612. * number of system calls is reduced in any case where more than one character
  7613. * arrives during the processing of the previous chunk, for instance high
  7614. * baud rates or network type connections where input arrives in packets.
  7615. * If the time needed for a read() system call approaches the time for more
  7616. * than one character to arrive, then this mechanism automatically compensates
  7617. * for that by performing bigger read()s less frequently. If the system load
  7618. * is high, the same mechanism compensates for that too.
  7619. *
  7620. * myread() is a macro that returns the next character from the buffer. If the
  7621. * buffer is empty, mygetbuf() is called. See mygetbuf() for possible error
  7622. * returns.
  7623. *
  7624. * This should be efficient enough for any one-character-at-a-time loops.
  7625. * For even better efficiency you might use memcpy()/bcopy() or such between
  7626. * buffers (since they are often better optimized for copying), but it may not
  7627. * be worth it if you have to take an extra pass over the buffer to strip
  7628. * parity and check for CTRL-C anyway.
  7629. *
  7630. * Note that if you have been using myread() from another program module, you
  7631. * may have some trouble accessing this macro version and the private variables
  7632. * it uses. In that case, just add a function in this module, that invokes the
  7633. * macro.
  7634. */
  7635. #define myread() (--my_count < 0 ? mygetbuf() : 255 & (int)mybuf[++my_item])
  7636. /* Specification: Push back up to one character onto myread()'s queue.
  7637. *
  7638. * This implementation: Push back characters into mybuf. At least one character
  7639. * must have been read through myread() before myunrd() may be used. After
  7640. * EOF or read error, again, myunrd() can not be used. Sometimes more than
  7641. * one character can be pushed back, but only one character is guaranteed.
  7642. * Since a previous myread() must have read its character out of mybuf[],
  7643. * that guarantees that there is space for at least one character. If push
  7644. * back was really needed after EOF, a small addition could provide that.
  7645. *
  7646. * As of 02/2007 myunrd() is used by ttinl().
  7647. */
  7648. VOID
  7649. #ifdef CK_ANSIC
  7650. myunrd(CHAR ch)
  7651. #else
  7652. myunrd(ch) CHAR ch;
  7653. #endif /* CK_ANSIC */
  7654. {
  7655. if (my_item >= 0) {
  7656. mybuf[my_item--] = ch;
  7657. ++my_count;
  7658. }
  7659. }
  7660. /* T T P U S H B A C K -- Put n bytes back into the myread buffer */
  7661. static CHAR * pushbuf = NULL;
  7662. /* static int pushed = 0; */
  7663. int
  7664. ttpushback(s,n) CHAR * s; int n; {
  7665. debug(F101,"ttpushback n","",n);
  7666. if (pushbuf || n > MYBUFLEN || n < 1)
  7667. return(-1);
  7668. debug(F101,"ttpushback my_count","",my_count);
  7669. if (my_count > 0) {
  7670. if (!(pushbuf = (CHAR *)malloc(n+1)))
  7671. return(-1);
  7672. memcpy(pushbuf,mybuf,my_count);
  7673. /* pushed = my_count; */ /* (set but never used) */
  7674. }
  7675. memcpy(mybuf,s,n);
  7676. my_count = n;
  7677. my_item = -1;
  7678. return(0);
  7679. }
  7680. /* mygetbuf() -- Fill buffer for myread() and return first character.
  7681. *
  7682. * This function is what myread() uses when it can't get the next character
  7683. * directly from its buffer. First, it calls a system dependent myfillbuf()
  7684. * to read at least one new character into the buffer, and then it returns
  7685. * the first character just as myread() would have done. This function also
  7686. * is responsible for all error conditions that myread() can indicate.
  7687. *
  7688. * Returns: When OK => a positive character, 0 or greater.
  7689. * When EOF => -2.
  7690. * When error => -3, error code in errno.
  7691. *
  7692. * Older myread()s additionally returned -1 to indicate that there was nothing
  7693. * to read, upon which the caller would call myread() again until it got
  7694. * something. The new myread()/mygetbuf() always gets something. If it
  7695. * doesn't, then make it do so! Any program that actually depends on the old
  7696. * behaviour will break.
  7697. *
  7698. * The older version also used to return -2 both for EOF and other errors,
  7699. * and used to set errno to 9999 on EOF. The errno stuff is gone, EOF and
  7700. * other errors now return different results, although Kermit currently never
  7701. * checks to see which it was. It just disconnects in both cases.
  7702. *
  7703. * Kermit lets the user use the quit key to perform some special commands
  7704. * during file transfer. This causes read(), and thus also mygetbuf(), to
  7705. * finish without reading anything and return the EINTR error. This should
  7706. * be checked by the caller. Mygetbuf() could retry the read() on EINTR,
  7707. * but if there is nothing to read, this could delay Kermit's reaction to
  7708. * the command, and make Kermit appear unresponsive.
  7709. *
  7710. * The debug() call should be removed for optimum performance.
  7711. */
  7712. int
  7713. mygetbuf() {
  7714. int x;
  7715. errno = 0;
  7716. #ifdef DEBUG
  7717. if (deblog && my_count > 0)
  7718. debug(F101,"mygetbuf IMPROPERLY CALLED with my_count","",my_count);
  7719. #endif /* DEBUG */
  7720. if (my_count <= 0)
  7721. my_count = myfillbuf();
  7722. #ifdef DEBUG
  7723. #ifdef COMMENT
  7724. if (deblog) debug(F101, "mygetbuf read", "", my_count);
  7725. #else /* COMMENT */
  7726. ckhexdump("mygetbuf read", mybuf, my_count);
  7727. #endif /* COMMENT */
  7728. #endif /* DEBUG */
  7729. x = my_count;
  7730. if (my_count <= 0) {
  7731. my_count = 0;
  7732. my_item = -1;
  7733. debug(F101,"mygetbuf errno","",errno);
  7734. #ifdef TCPSOCKET
  7735. if (netconn && ttnet == NET_TCPB && errno != 0) {
  7736. if (errno != EINTR) {
  7737. debug(F101,"mygetbuf TCP error","",errno);
  7738. ttclos(0); /* Close the connection. */
  7739. }
  7740. return(-3);
  7741. }
  7742. #endif /* TCPSOCKET */
  7743. if (!netconn && xlocal && errno) {
  7744. if (errno != EINTR) {
  7745. debug(F101,"mygetbuf SERIAL error","",errno);
  7746. x = -3;
  7747. ttclos(0); /* Close the connection. */
  7748. }
  7749. }
  7750. return((x < 0) ? -3 : -2);
  7751. }
  7752. --my_count;
  7753. return((unsigned)(0xff & mybuf[my_item = 0]));
  7754. }
  7755. /* myfillbuf():
  7756. * System-dependent read() into mybuf[], as many characters as possible.
  7757. *
  7758. * Returns: OK => number of characters read, always more than zero.
  7759. * EOF => 0
  7760. * Error => -1, error code in errno.
  7761. *
  7762. * If there is input available in the system's buffers, all of it should be
  7763. * read into mybuf[] and the function return immediately. If no input is
  7764. * available, it should wait for a character to arrive, and return with that
  7765. * one in mybuf[] as soon as possible. It may wait somewhat past the first
  7766. * character, but be aware that any such delay lengthens the packet turnaround
  7767. * time during kermit file transfers. Should never return with zero characters
  7768. * unless EOF or irrecoverable read error.
  7769. *
  7770. * Correct functioning depends on the correct tty parameters being used.
  7771. * Better control of current parameters is required than may have been the
  7772. * case in older Kermit releases. For instance, O_NDELAY (or equivalent) can
  7773. * no longer be sometimes off and sometimes on like it used to, unless a
  7774. * special myfillbuf() is written to handle that. Otherwise the ordinary
  7775. * myfillbuf()s may think they have come to EOF.
  7776. *
  7777. * If your system has a facility to directly perform the functioning of
  7778. * myfillbuf(), then use it. If the system can tell you how many characters
  7779. * are available in its buffers, then read that amount (but not less than 1).
  7780. * If the system can return a special indication when you try to read without
  7781. * anything to read, while allowing you to read all there is when there is
  7782. * something, you may loop until there is something to read, but probably that
  7783. * is not good for the system load.
  7784. */
  7785. #ifdef SVORPOSIX
  7786. /* This is for System III/V with VMIN>0, VTIME=0 and O_NDELAY off,
  7787. * and CLOCAL set any way you like. This way, read() will do exactly
  7788. * what is required by myfillbuf(): If there is data in the buffers
  7789. * of the O.S., all available data is read into mybuf, up to the size
  7790. * of mybuf. If there is none, the first character to arrive is
  7791. * awaited and returned.
  7792. */
  7793. int
  7794. myfillbuf() {
  7795. int fd, n;
  7796. #ifdef NETCMD
  7797. if (ttpipe)
  7798. fd = fdin;
  7799. else
  7800. #endif /* NETCMD */
  7801. fd = ttyfd;
  7802. #ifdef sxaE50
  7803. /* From S. Dezawa at Fujifilm in Japan. I don't know why this is */
  7804. /* necessary for the sxa E50, but it is. */
  7805. return read(fd, mybuf, 255);
  7806. #else
  7807. #ifdef BEOSORBEBOX
  7808. while (1) {
  7809. #ifdef NETCONN
  7810. if (netconn) {
  7811. n = netxin(sizeof(mybuf), (char *)mybuf);
  7812. debug(F101,"BEBOX SVORPOSIX network myfillbuf","",n);
  7813. }
  7814. else
  7815. #endif /* NETCONN */
  7816. n = read(fd, mybuf, sizeof(mybuf));
  7817. debug(F101,"BEBOX SVORPOSIX notnet myfillbuf","",n);
  7818. if (n > 0)
  7819. return(n);
  7820. snooze(1000.0);
  7821. }
  7822. #else /* BEOSORBEBOX */
  7823. errno = 0;
  7824. /* debug(F101,"SVORPOSIX myfillbuf calling read() fd","",fd); */
  7825. #ifdef IBMX25
  7826. if (netconn && (nettype == NET_IX25)) {
  7827. /* can't use sizeof because mybuf is a pointer, and not an array! */
  7828. n = x25xin( MYBUFLEN, mybuf );
  7829. } else
  7830. #endif /* IBMX25 */
  7831. #ifdef CK_SSL
  7832. if (ssl_active_flag || tls_active_flag) {
  7833. int error, n = 0;
  7834. debug(F100,"myfillbuf calling SSL_read() fd","",0);
  7835. while (n == 0) {
  7836. if (ssl_active_flag)
  7837. n = SSL_read(ssl_con, (char *)mybuf, sizeof(mybuf));
  7838. else if (tls_active_flag)
  7839. n = SSL_read(tls_con, (char *)mybuf, sizeof(mybuf));
  7840. else
  7841. break;
  7842. switch (SSL_get_error(ssl_active_flag?ssl_con:tls_con,n)) {
  7843. case SSL_ERROR_NONE:
  7844. if (n > 0)
  7845. return(n);
  7846. if (n < 0)
  7847. return(-2);
  7848. msleep(50);
  7849. break;
  7850. case SSL_ERROR_WANT_WRITE:
  7851. case SSL_ERROR_WANT_READ:
  7852. return(-1);
  7853. case SSL_ERROR_SYSCALL:
  7854. if (n != 0)
  7855. return(-1);
  7856. case SSL_ERROR_WANT_X509_LOOKUP:
  7857. case SSL_ERROR_SSL:
  7858. case SSL_ERROR_ZERO_RETURN:
  7859. default:
  7860. ttclos(0);
  7861. return(-3);
  7862. }
  7863. }
  7864. }
  7865. #endif /* CK_SSL */
  7866. #ifdef CK_KERBEROS
  7867. #ifdef KRB4
  7868. #ifdef RLOGCODE
  7869. if (ttnproto == NP_EK4LOGIN) {
  7870. debug(F101,"myfillbuf calling krb4_des_read() fd","",ttyfd);
  7871. if ((n = krb4_des_read(ttyfd,(char *)mybuf,sizeof(mybuf))) < 0)
  7872. return(-3);
  7873. else
  7874. return(n);
  7875. }
  7876. #endif /* RLOGCODE */
  7877. #endif /* KRB4 */
  7878. #ifdef KRB5
  7879. #ifdef RLOGCODE
  7880. if (ttnproto == NP_EK5LOGIN) {
  7881. debug(F101,"myfillbuf calling krb5_des_read() fd","",ttyfd);
  7882. if ((n = krb5_des_read(ttyfd,(char *)mybuf,sizeof(mybuf),0)) < 0)
  7883. return(-3);
  7884. else
  7885. return(n);
  7886. }
  7887. #endif /* RLOGCODE */
  7888. #ifdef KRB5_U2U
  7889. if (ttnproto == NP_K5U2U) {
  7890. debug(F101,"myfillbuf calling krb5_u2u_read() fd","",ttyfd);
  7891. if ((n = krb5_u2u_read(ttyfd,(char *)mybuf,sizeof(mybuf))) < 0)
  7892. return(-3);
  7893. else
  7894. return(n);
  7895. }
  7896. #endif /* KRB5_U2U */
  7897. #endif /* KRB5 */
  7898. #endif /* CK_KERBEROS */
  7899. #ifdef NETPTY
  7900. #ifdef HAVE_PTYTRAP
  7901. /* Special handling for HP-UX pty i/o */
  7902. ptyread:
  7903. if (ttpty && pty_trap_pending(ttyfd) > 0) {
  7904. debug(F101,"myfillbuf calling pty_trap_handler() fd","",ttyfd);
  7905. if (pty_trap_handler(ttyfd) > 0) {
  7906. ttclos(0);
  7907. return(-3);
  7908. }
  7909. }
  7910. #endif /* HAVE_PTYTRAP */
  7911. #endif /* NETPTY */
  7912. debug(F101,"myfillbuf calling read() fd","",ttyfd);
  7913. n = read(fd, mybuf, sizeof(mybuf));
  7914. debug(F101,"SVORPOSIX myfillbuf read","",n);
  7915. debug(F101,"SVORPOSIX myfillbuf errno","",errno);
  7916. debug(F101,"SVORPOSIX myfillbuf ttcarr","",ttcarr);
  7917. if (n < 1) {
  7918. #ifdef NETPTY
  7919. #ifdef HAVE_PTYTRAP
  7920. /* When we have a PTY trap in place the connection cannot */
  7921. /* be closed until the trap receives a close indication. */
  7922. if (n == 0 && ttpty)
  7923. goto ptyread;
  7924. #endif /* HAVE_PTYTRAP */
  7925. #endif /* NETPTY */
  7926. return(-3);
  7927. }
  7928. return(n);
  7929. #endif /* BEOSORBEBOX */
  7930. #endif /* sxaE50 */
  7931. }
  7932. #else /* not AT&T or POSIX */
  7933. #ifdef aegis
  7934. /* This is quoted from the old myread(). The semantics seem to be
  7935. * alright, but maybe errno would not need to be set even when
  7936. * there is no error? I don't know aegis.
  7937. */
  7938. int
  7939. myfillbuf() {
  7940. int count;
  7941. #ifdef NETCMD
  7942. if (ttpipe)
  7943. fd = fdin;
  7944. else
  7945. #endif /* NETCMD */
  7946. fd = ttyfd;
  7947. count = ios_$get((short)fd, ios_$cond_opt, mybuf, 256L, st);
  7948. errno = EIO;
  7949. if (st.all == ios_$get_conditional_failed) /* get at least one */
  7950. count = ios_$get((short)fd, 0, mybuf, 1L, st);
  7951. if (st.all == ios_$end_of_file)
  7952. return(-3);
  7953. else if (st.all != status_$ok) {
  7954. errno = EIO;
  7955. return(-1);
  7956. }
  7957. return(count > 0 ? count : -3);
  7958. }
  7959. #else /* !aegis */
  7960. #ifdef FIONREAD
  7961. /* This is for systems with FIONREAD. FIONREAD returns the number
  7962. * of characters available for reading. If none are available, wait
  7963. * until something arrives, otherwise return all there is.
  7964. */
  7965. int
  7966. myfillbuf() {
  7967. PEEKTYPE avail = 0;
  7968. int x, fd;
  7969. #ifdef NETCMD
  7970. if (ttpipe)
  7971. fd = fdin;
  7972. else
  7973. #endif /* NETCMD */
  7974. fd = ttyfd;
  7975. #ifdef SUNX25
  7976. /*
  7977. SunLink X.25 support in this routine from Stefaan A. Eeckels, Eurostat (CEC).
  7978. Depends on SunOS having FIONREAD, not because we use it, but just so this
  7979. code is grouped correctly within the #ifdefs. Let's hope Solaris keeps it.
  7980. We call x25xin() instead of read() so that Q-Bit packets, which contain
  7981. X.25 service-level information (e.g. PAD parameter changes), can be processed
  7982. transparently to the upper-level code. This is a blocking read, and so
  7983. we depend on higher-level code (such as ttinc()) to set any necessary alarms.
  7984. */
  7985. extern int nettype;
  7986. if (netconn && nettype == NET_SX25) {
  7987. while ((x = x25xin(sizeof(x25buf), x25buf)) < 1) ;
  7988. return(x - 1); /* "-1" compensates for extra status byte */
  7989. }
  7990. #endif /* SUNX25 */
  7991. #ifdef CK_SSL
  7992. if (ssl_active_flag || tls_active_flag) {
  7993. int error, n = 0;
  7994. while (n == 0) {
  7995. if (ssl_active_flag)
  7996. n = SSL_read(ssl_con, (char *)mybuf, sizeof(mybuf));
  7997. else
  7998. n = SSL_read(tls_con, (char *)mybuf, sizeof(mybuf));
  7999. switch (SSL_get_error(ssl_active_flag?ssl_con:tls_con,n)) {
  8000. case SSL_ERROR_NONE:
  8001. if (n > 0)
  8002. return(n);
  8003. if (n < 0)
  8004. return(-2);
  8005. msleep(50);
  8006. break;
  8007. case SSL_ERROR_WANT_WRITE:
  8008. case SSL_ERROR_WANT_READ:
  8009. return(-1);
  8010. case SSL_ERROR_SYSCALL:
  8011. if (n != 0)
  8012. return(-1);
  8013. case SSL_ERROR_WANT_X509_LOOKUP:
  8014. case SSL_ERROR_SSL:
  8015. case SSL_ERROR_ZERO_RETURN:
  8016. default:
  8017. ttclos(0);
  8018. return(-2);
  8019. }
  8020. }
  8021. }
  8022. #endif /* CK_SSL */
  8023. #ifdef CK_KERBEROS
  8024. #ifdef KRB4
  8025. #ifdef RLOGCODE
  8026. if (ttnproto == NP_EK4LOGIN) {
  8027. if ((x = krb4_des_read(ttyfd,mybuf,sizeof(mybuf))) < 0)
  8028. return(-1);
  8029. else
  8030. return(x);
  8031. }
  8032. #endif /* RLOGCODE */
  8033. #endif /* KRB4 */
  8034. #ifdef KRB5
  8035. #ifdef RLOGCODE
  8036. if (ttnproto == NP_EK5LOGIN) {
  8037. if ((x = krb5_des_read(ttyfd,mybuf,sizeof(mybuf),0)) < 0)
  8038. return(-1);
  8039. els