archive_write_set_format_iso9660.c 207 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980798179827983798479857986798779887989799079917992799379947995799679977998799980008001800280038004800580068007800880098010801180128013801480158016801780188019802080218022802380248025802680278028802980308031803280338034803580368037803880398040804180428043804480458046804780488049805080518052805380548055805680578058805980608061806280638064806580668067806880698070807180728073807480758076807780788079808080818082808380848085808680878088808980908091809280938094809580968097809880998100810181028103810481058106810781088109811081118112811381148115811681178118811981208121812281238124812581268127812881298130813181328133813481358136813781388139814081418142814381448145814681478148814981508151815281538154815581568157815881598160816181628163816481658166816781688169817081718172817381748175817681778178817981808181
  1. /*-
  2. * Copyright (c) 2009-2012 Michihiro NAKAJIMA
  3. * All rights reserved.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions
  7. * are met:
  8. * 1. Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. * 2. Redistributions in binary form must reproduce the above copyright
  11. * notice, this list of conditions and the following disclaimer in the
  12. * documentation and/or other materials provided with the distribution.
  13. *
  14. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
  15. * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  16. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  17. * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
  18. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  19. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  20. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  21. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  22. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  23. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  24. */
  25. #include "archive_platform.h"
  26. #ifdef HAVE_SYS_TYPES_H
  27. #include <sys/types.h>
  28. #endif
  29. #ifdef HAVE_SYS_UTSNAME_H
  30. #include <sys/utsname.h>
  31. #endif
  32. #ifdef HAVE_ERRNO_H
  33. #include <errno.h>
  34. #endif
  35. #ifdef HAVE_LIMITS_H
  36. #include <limits.h>
  37. #endif
  38. #include <stdio.h>
  39. #include <stdarg.h>
  40. #ifdef HAVE_STDLIB_H
  41. #include <stdlib.h>
  42. #endif
  43. #include <time.h>
  44. #ifdef HAVE_UNISTD_H
  45. #include <unistd.h>
  46. #endif
  47. #ifdef HAVE_ZLIB_H
  48. #include <cm3p/zlib.h>
  49. #endif
  50. #ifdef __clang_analyzer__
  51. #include <assert.h>
  52. #endif
  53. #include "archive.h"
  54. #include "archive_endian.h"
  55. #include "archive_entry.h"
  56. #include "archive_entry_locale.h"
  57. #include "archive_private.h"
  58. #include "archive_rb.h"
  59. #include "archive_write_private.h"
  60. #if defined(_WIN32) && !defined(__CYGWIN__)
  61. #define getuid() 0
  62. #define getgid() 0
  63. #endif
  64. /*#define DEBUG 1*/
  65. #ifdef DEBUG
  66. /* To compare to the ISO image file made by mkisofs. */
  67. #define COMPAT_MKISOFS 1
  68. #endif
  69. #define LOGICAL_BLOCK_BITS 11
  70. #define LOGICAL_BLOCK_SIZE 2048
  71. #define PATH_TABLE_BLOCK_SIZE 4096
  72. #define SYSTEM_AREA_BLOCK 16
  73. #define PRIMARY_VOLUME_DESCRIPTOR_BLOCK 1
  74. #define SUPPLEMENTARY_VOLUME_DESCRIPTOR_BLOCK 1
  75. #define BOOT_RECORD_DESCRIPTOR_BLOCK 1
  76. #define VOLUME_DESCRIPTOR_SET_TERMINATOR_BLOCK 1
  77. #define NON_ISO_FILE_SYSTEM_INFORMATION_BLOCK 1
  78. #define RRIP_ER_BLOCK 1
  79. #define PADDING_BLOCK 150
  80. #define FD_1_2M_SIZE (1024 * 1200)
  81. #define FD_1_44M_SIZE (1024 * 1440)
  82. #define FD_2_88M_SIZE (1024 * 2880)
  83. #define MULTI_EXTENT_SIZE (ARCHIVE_LITERAL_LL(1) << 32) /* 4Gi bytes. */
  84. #define MAX_DEPTH 8
  85. #define RR_CE_SIZE 28 /* SUSP "CE" extension size */
  86. #define FILE_FLAG_EXISTENCE 0x01
  87. #define FILE_FLAG_DIRECTORY 0x02
  88. #define FILE_FLAG_ASSOCIATED 0x04
  89. #define FILE_FLAG_RECORD 0x08
  90. #define FILE_FLAG_PROTECTION 0x10
  91. #define FILE_FLAG_MULTI_EXTENT 0x80
  92. static const char rrip_identifier[] =
  93. "RRIP_1991A";
  94. static const char rrip_descriptor[] =
  95. "THE ROCK RIDGE INTERCHANGE PROTOCOL PROVIDES SUPPORT FOR "
  96. "POSIX FILE SYSTEM SEMANTICS";
  97. static const char rrip_source[] =
  98. "PLEASE CONTACT DISC PUBLISHER FOR SPECIFICATION SOURCE. "
  99. "SEE PUBLISHER IDENTIFIER IN PRIMARY VOLUME DESCRIPTOR FOR "
  100. "CONTACT INFORMATION.";
  101. #define RRIP_ER_ID_SIZE (sizeof(rrip_identifier)-1)
  102. #define RRIP_ER_DSC_SIZE (sizeof(rrip_descriptor)-1)
  103. #define RRIP_ER_SRC_SIZE (sizeof(rrip_source)-1)
  104. #define RRIP_ER_SIZE (8 + RRIP_ER_ID_SIZE + \
  105. RRIP_ER_DSC_SIZE + RRIP_ER_SRC_SIZE)
  106. static const unsigned char zisofs_magic[8] = {
  107. 0x37, 0xE4, 0x53, 0x96, 0xC9, 0xDB, 0xD6, 0x07
  108. };
  109. #define ZF_HEADER_SIZE 16 /* zisofs header size. */
  110. #define ZF_LOG2_BS 15 /* log2 block size; 32K bytes. */
  111. #define ZF_BLOCK_SIZE (1UL << ZF_LOG2_BS)
  112. /*
  113. * Manage extra records.
  114. */
  115. struct extr_rec {
  116. int location;
  117. int offset;
  118. unsigned char buf[LOGICAL_BLOCK_SIZE];
  119. struct extr_rec *next;
  120. };
  121. struct ctl_extr_rec {
  122. int use_extr;
  123. unsigned char *bp;
  124. struct isoent *isoent;
  125. unsigned char *ce_ptr;
  126. int cur_len;
  127. int dr_len;
  128. int limit;
  129. int extr_off;
  130. int extr_loc;
  131. };
  132. #define DR_SAFETY RR_CE_SIZE
  133. #define DR_LIMIT (254 - DR_SAFETY)
  134. /*
  135. * The relation of struct isofile and isoent and archive_entry.
  136. *
  137. * Primary volume tree --> struct isoent
  138. * |
  139. * v
  140. * struct isofile --> archive_entry
  141. * ^
  142. * |
  143. * Joliet volume tree --> struct isoent
  144. *
  145. * struct isoent has specific information for volume.
  146. */
  147. struct isofile {
  148. /* Used for managing struct isofile list. */
  149. struct isofile *allnext;
  150. struct isofile *datanext;
  151. /* Used for managing a hardlinked struct isofile list. */
  152. struct isofile *hlnext;
  153. struct isofile *hardlink_target;
  154. struct archive_entry *entry;
  155. /*
  156. * Used for making a directory tree.
  157. */
  158. struct archive_string parentdir;
  159. struct archive_string basename;
  160. struct archive_string basename_utf16;
  161. struct archive_string symlink;
  162. int dircnt; /* The number of elements of
  163. * its parent directory */
  164. /*
  165. * Used for a Directory Record.
  166. */
  167. struct content {
  168. int64_t offset_of_temp;
  169. int64_t size;
  170. int blocks;
  171. uint32_t location;
  172. /*
  173. * One extent equals one content.
  174. * If this entry has multi extent, `next' variable points
  175. * next content data.
  176. */
  177. struct content *next; /* next content */
  178. } content, *cur_content;
  179. int write_content;
  180. enum {
  181. NO = 0,
  182. BOOT_CATALOG,
  183. BOOT_IMAGE
  184. } boot;
  185. /*
  186. * Used for a zisofs.
  187. */
  188. struct {
  189. unsigned char header_size;
  190. unsigned char log2_bs;
  191. uint32_t uncompressed_size;
  192. } zisofs;
  193. };
  194. struct isoent {
  195. /* Keep `rbnode' at the first member of struct isoent. */
  196. struct archive_rb_node rbnode;
  197. struct isofile *file;
  198. struct isoent *parent;
  199. /* A list of children.(use chnext) */
  200. struct {
  201. struct isoent *first;
  202. struct isoent **last;
  203. int cnt;
  204. } children;
  205. struct archive_rb_tree rbtree;
  206. /* A list of sub directories.(use drnext) */
  207. struct {
  208. struct isoent *first;
  209. struct isoent **last;
  210. int cnt;
  211. } subdirs;
  212. /* A sorted list of sub directories. */
  213. struct isoent **children_sorted;
  214. /* Used for managing struct isoent list. */
  215. struct isoent *chnext;
  216. struct isoent *drnext;
  217. struct isoent *ptnext;
  218. /*
  219. * Used for making a Directory Record.
  220. */
  221. int dir_number;
  222. struct {
  223. int vd;
  224. int self;
  225. int parent;
  226. int normal;
  227. } dr_len;
  228. uint32_t dir_location;
  229. int dir_block;
  230. /*
  231. * Identifier:
  232. * on primary, ISO9660 file/directory name.
  233. * on joliet, UCS2 file/directory name.
  234. * ext_off : offset of identifier extension.
  235. * ext_len : length of identifier extension.
  236. * id_len : byte size of identifier.
  237. * on primary, this is ext_off + ext_len + version length.
  238. * on joliet, this is ext_off + ext_len.
  239. * mb_len : length of multibyte-character of identifier.
  240. * on primary, mb_len and id_len are always the same.
  241. * on joliet, mb_len and id_len are different.
  242. */
  243. char *identifier;
  244. int ext_off;
  245. int ext_len;
  246. int id_len;
  247. int mb_len;
  248. /*
  249. * Used for making a Rockridge extension.
  250. * This is a part of Directory Records.
  251. */
  252. struct isoent *rr_parent;
  253. struct isoent *rr_child;
  254. /* Extra Record.(which we call in this source file)
  255. * A maximum size of the Directory Record is 254.
  256. * so, if generated RRIP data of a file cannot into a Directory
  257. * Record because of its size, that surplus data relocate this
  258. * Extra Record.
  259. */
  260. struct {
  261. struct extr_rec *first;
  262. struct extr_rec **last;
  263. struct extr_rec *current;
  264. } extr_rec_list;
  265. unsigned int virtual:1;
  266. /* If set to one, this file type is a directory.
  267. * A convenience flag to be used as
  268. * "archive_entry_filetype(isoent->file->entry) == AE_IFDIR".
  269. */
  270. unsigned int dir:1;
  271. };
  272. struct hardlink {
  273. struct archive_rb_node rbnode;
  274. int nlink;
  275. struct {
  276. struct isofile *first;
  277. struct isofile **last;
  278. } file_list;
  279. };
  280. /*
  281. * ISO writer options
  282. */
  283. struct iso_option {
  284. /*
  285. * Usage : abstract-file=<value>
  286. * Type : string, max 37 bytes
  287. * Default: Not specified
  288. * COMPAT : mkisofs -abstract <value>
  289. *
  290. * Specifies Abstract Filename.
  291. * This file shall be described in the Root Directory
  292. * and containing a abstract statement.
  293. */
  294. unsigned int abstract_file:1;
  295. #define OPT_ABSTRACT_FILE_DEFAULT 0 /* Not specified */
  296. #define ABSTRACT_FILE_SIZE 37
  297. /*
  298. * Usage : application-id=<value>
  299. * Type : string, max 128 bytes
  300. * Default: Not specified
  301. * COMPAT : mkisofs -A/-appid <value>.
  302. *
  303. * Specifies Application Identifier.
  304. * If the first byte is set to '_'(5F), the remaining
  305. * bytes of this option shall specify an identifier
  306. * for a file containing the identification of the
  307. * application.
  308. * This file shall be described in the Root Directory.
  309. */
  310. unsigned int application_id:1;
  311. #define OPT_APPLICATION_ID_DEFAULT 0 /* Use default identifier */
  312. #define APPLICATION_IDENTIFIER_SIZE 128
  313. /*
  314. * Usage : !allow-vernum
  315. * Type : boolean
  316. * Default: Enabled
  317. * : Violates the ISO9660 standard if disable.
  318. * COMPAT: mkisofs -N
  319. *
  320. * Allow filenames to use version numbers.
  321. */
  322. unsigned int allow_vernum:1;
  323. #define OPT_ALLOW_VERNUM_DEFAULT 1 /* Enabled */
  324. /*
  325. * Usage : biblio-file=<value>
  326. * Type : string, max 37 bytes
  327. * Default: Not specified
  328. * COMPAT : mkisofs -biblio <value>
  329. *
  330. * Specifies Bibliographic Filename.
  331. * This file shall be described in the Root Directory
  332. * and containing bibliographic records.
  333. */
  334. unsigned int biblio_file:1;
  335. #define OPT_BIBLIO_FILE_DEFAULT 0 /* Not specified */
  336. #define BIBLIO_FILE_SIZE 37
  337. /*
  338. * Usage : boot=<value>
  339. * Type : string
  340. * Default: Not specified
  341. * COMPAT : mkisofs -b/-eltorito-boot <value>
  342. *
  343. * Specifies "El Torito" boot image file to make
  344. * a bootable CD.
  345. */
  346. unsigned int boot:1;
  347. #define OPT_BOOT_DEFAULT 0 /* Not specified */
  348. /*
  349. * Usage : boot-catalog=<value>
  350. * Type : string
  351. * Default: "boot.catalog"
  352. * COMPAT : mkisofs -c/-eltorito-catalog <value>
  353. *
  354. * Specifies a fullpath of El Torito boot catalog.
  355. */
  356. unsigned int boot_catalog:1;
  357. #define OPT_BOOT_CATALOG_DEFAULT 0 /* Not specified */
  358. /*
  359. * Usage : boot-info-table
  360. * Type : boolean
  361. * Default: Disabled
  362. * COMPAT : mkisofs -boot-info-table
  363. *
  364. * Modify the boot image file specified by `boot'
  365. * option; ISO writer stores boot file information
  366. * into the boot file in ISO image at offset 8
  367. * through offset 64.
  368. */
  369. unsigned int boot_info_table:1;
  370. #define OPT_BOOT_INFO_TABLE_DEFAULT 0 /* Disabled */
  371. /*
  372. * Usage : boot-load-seg=<value>
  373. * Type : hexadecimal
  374. * Default: Not specified
  375. * COMPAT : mkisofs -boot-load-seg <value>
  376. *
  377. * Specifies a load segment for boot image.
  378. * This is used with no-emulation mode.
  379. */
  380. unsigned int boot_load_seg:1;
  381. #define OPT_BOOT_LOAD_SEG_DEFAULT 0 /* Not specified */
  382. /*
  383. * Usage : boot-load-size=<value>
  384. * Type : decimal
  385. * Default: Not specified
  386. * COMPAT : mkisofs -boot-load-size <value>
  387. *
  388. * Specifies a sector count for boot image.
  389. * This is used with no-emulation mode.
  390. */
  391. unsigned int boot_load_size:1;
  392. #define OPT_BOOT_LOAD_SIZE_DEFAULT 0 /* Not specified */
  393. /*
  394. * Usage : boot-type=<boot-media-type>
  395. * : 'no-emulation' : 'no emulation' image
  396. * : 'fd' : floppy disk image
  397. * : 'hard-disk' : hard disk image
  398. * Type : string
  399. * Default: Auto detect
  400. * : We check a size of boot image;
  401. * : If the size is just 1.22M/1.44M/2.88M,
  402. * : we assume boot_type is 'fd';
  403. * : otherwise boot_type is 'no-emulation'.
  404. * COMPAT :
  405. * boot=no-emulation
  406. * mkisofs -no-emul-boot
  407. * boot=fd
  408. * This is a default on the mkisofs.
  409. * boot=hard-disk
  410. * mkisofs -hard-disk-boot
  411. *
  412. * Specifies a type of "El Torito" boot image.
  413. */
  414. unsigned int boot_type:2;
  415. #define OPT_BOOT_TYPE_AUTO 0 /* auto detect */
  416. #define OPT_BOOT_TYPE_NO_EMU 1 /* ``no emulation'' image */
  417. #define OPT_BOOT_TYPE_FD 2 /* floppy disk image */
  418. #define OPT_BOOT_TYPE_HARD_DISK 3 /* hard disk image */
  419. #define OPT_BOOT_TYPE_DEFAULT OPT_BOOT_TYPE_AUTO
  420. /*
  421. * Usage : compression-level=<value>
  422. * Type : decimal
  423. * Default: Not specified
  424. * COMPAT : NONE
  425. *
  426. * Specifies compression level for option zisofs=direct.
  427. */
  428. unsigned int compression_level:1;
  429. #define OPT_COMPRESSION_LEVEL_DEFAULT 0 /* Not specified */
  430. /*
  431. * Usage : copyright-file=<value>
  432. * Type : string, max 37 bytes
  433. * Default: Not specified
  434. * COMPAT : mkisofs -copyright <value>
  435. *
  436. * Specifies Copyright Filename.
  437. * This file shall be described in the Root Directory
  438. * and containing a copyright statement.
  439. */
  440. unsigned int copyright_file:1;
  441. #define OPT_COPYRIGHT_FILE_DEFAULT 0 /* Not specified */
  442. #define COPYRIGHT_FILE_SIZE 37
  443. /*
  444. * Usage : gid=<value>
  445. * Type : decimal
  446. * Default: Not specified
  447. * COMPAT : mkisofs -gid <value>
  448. *
  449. * Specifies a group id to rewrite the group id of all files.
  450. */
  451. unsigned int gid:1;
  452. #define OPT_GID_DEFAULT 0 /* Not specified */
  453. /*
  454. * Usage : iso-level=[1234]
  455. * Type : decimal
  456. * Default: 1
  457. * COMPAT : mkisofs -iso-level <value>
  458. *
  459. * Specifies ISO9600 Level.
  460. * Level 1: [DEFAULT]
  461. * - limits each file size less than 4Gi bytes;
  462. * - a File Name shall not contain more than eight
  463. * d-characters or eight d1-characters;
  464. * - a File Name Extension shall not contain more than
  465. * three d-characters or three d1-characters;
  466. * - a Directory Identifier shall not contain more
  467. * than eight d-characters or eight d1-characters.
  468. * Level 2:
  469. * - limits each file size less than 4Giga bytes;
  470. * - a File Name shall not contain more than thirty
  471. * d-characters or thirty d1-characters;
  472. * - a File Name Extension shall not contain more than
  473. * thirty d-characters or thirty d1-characters;
  474. * - a Directory Identifier shall not contain more
  475. * than thirty-one d-characters or thirty-one
  476. * d1-characters.
  477. * Level 3:
  478. * - no limit of file size; use multi extent.
  479. * Level 4:
  480. * - this level 4 simulates mkisofs option
  481. * '-iso-level 4';
  482. * - crate a enhanced volume as mkisofs doing;
  483. * - allow a File Name to have leading dot;
  484. * - allow a File Name to have all ASCII letters;
  485. * - allow a File Name to have multiple dots;
  486. * - allow more then 8 depths of directory trees;
  487. * - disable a version number to a File Name;
  488. * - disable a forced period to the tail of a File Name;
  489. * - the maximum length of files and directories is raised to 193.
  490. * if rockridge option is disabled, raised to 207.
  491. */
  492. unsigned int iso_level:3;
  493. #define OPT_ISO_LEVEL_DEFAULT 1 /* ISO Level 1 */
  494. /*
  495. * Usage : joliet[=long]
  496. * : !joliet
  497. * : Do not generate Joliet Volume and Records.
  498. * : joliet [DEFAULT]
  499. * : Generates Joliet Volume and Directory Records.
  500. * : [COMPAT: mkisofs -J/-joliet]
  501. * : joliet=long
  502. * : The joliet filenames are up to 103 Unicode
  503. * : characters.
  504. * : This option breaks the Joliet specification.
  505. * : [COMPAT: mkisofs -J -joliet-long]
  506. * Type : boolean/string
  507. * Default: Enabled
  508. * COMPAT : mkisofs -J / -joliet-long
  509. *
  510. * Generates Joliet Volume and Directory Records.
  511. */
  512. unsigned int joliet:2;
  513. #define OPT_JOLIET_DISABLE 0 /* Not generate Joliet Records. */
  514. #define OPT_JOLIET_ENABLE 1 /* Generate Joliet Records. */
  515. #define OPT_JOLIET_LONGNAME 2 /* Use long joliet filenames.*/
  516. #define OPT_JOLIET_DEFAULT OPT_JOLIET_ENABLE
  517. /*
  518. * Usage : !limit-depth
  519. * Type : boolean
  520. * Default: Enabled
  521. * : Violates the ISO9660 standard if disable.
  522. * COMPAT : mkisofs -D/-disable-deep-relocation
  523. *
  524. * The number of levels in hierarchy cannot exceed eight.
  525. */
  526. unsigned int limit_depth:1;
  527. #define OPT_LIMIT_DEPTH_DEFAULT 1 /* Enabled */
  528. /*
  529. * Usage : !limit-dirs
  530. * Type : boolean
  531. * Default: Enabled
  532. * : Violates the ISO9660 standard if disable.
  533. * COMPAT : mkisofs -no-limit-pathtables
  534. *
  535. * Limits the number of directories less than 65536 due
  536. * to the size of the Parent Directory Number of Path
  537. * Table.
  538. */
  539. unsigned int limit_dirs:1;
  540. #define OPT_LIMIT_DIRS_DEFAULT 1 /* Enabled */
  541. /*
  542. * Usage : !pad
  543. * Type : boolean
  544. * Default: Enabled
  545. * COMPAT : -pad/-no-pad
  546. *
  547. * Pads the end of the ISO image by null of 300Ki bytes.
  548. */
  549. unsigned int pad:1;
  550. #define OPT_PAD_DEFAULT 1 /* Enabled */
  551. /*
  552. * Usage : publisher=<value>
  553. * Type : string, max 128 bytes
  554. * Default: Not specified
  555. * COMPAT : mkisofs -publisher <value>
  556. *
  557. * Specifies Publisher Identifier.
  558. * If the first byte is set to '_'(5F), the remaining
  559. * bytes of this option shall specify an identifier
  560. * for a file containing the identification of the user.
  561. * This file shall be described in the Root Directory.
  562. */
  563. unsigned int publisher:1;
  564. #define OPT_PUBLISHER_DEFAULT 0 /* Not specified */
  565. #define PUBLISHER_IDENTIFIER_SIZE 128
  566. /*
  567. * Usage : rockridge
  568. * : !rockridge
  569. * : disable to generate SUSP and RR records.
  570. * : rockridge
  571. * : the same as 'rockridge=useful'.
  572. * : rockridge=strict
  573. * : generate SUSP and RR records.
  574. * : [COMPAT: mkisofs -R]
  575. * : rockridge=useful [DEFAULT]
  576. * : generate SUSP and RR records.
  577. * : [COMPAT: mkisofs -r]
  578. * : NOTE Our rockridge=useful option does not set a zero
  579. * : to uid and gid, you should use application
  580. * : option such as --gid,--gname,--uid and --uname
  581. * : bsdtar options instead.
  582. * Type : boolean/string
  583. * Default: Enabled as rockridge=useful
  584. * COMPAT : mkisofs -r / -R
  585. *
  586. * Generates SUSP and RR records.
  587. */
  588. unsigned int rr:2;
  589. #define OPT_RR_DISABLED 0
  590. #define OPT_RR_STRICT 1
  591. #define OPT_RR_USEFUL 2
  592. #define OPT_RR_DEFAULT OPT_RR_USEFUL
  593. /*
  594. * Usage : volume-id=<value>
  595. * Type : string, max 32 bytes
  596. * Default: Not specified
  597. * COMPAT : mkisofs -V <value>
  598. *
  599. * Specifies Volume Identifier.
  600. */
  601. unsigned int volume_id:1;
  602. #define OPT_VOLUME_ID_DEFAULT 0 /* Use default identifier */
  603. #define VOLUME_IDENTIFIER_SIZE 32
  604. /*
  605. * Usage : !zisofs [DEFAULT]
  606. * : Disable to generate RRIP 'ZF' extension.
  607. * : zisofs
  608. * : Make files zisofs file and generate RRIP 'ZF'
  609. * : extension. So you do not need mkzftree utility
  610. * : for making zisofs.
  611. * : When the file size is less than one Logical Block
  612. * : size, that file will not zisofs'ed since it does
  613. * : reduce an ISO-image size.
  614. * :
  615. * : When you specify option 'boot=<boot-image>', that
  616. * : 'boot-image' file won't be converted to zisofs file.
  617. * Type : boolean
  618. * Default: Disabled
  619. *
  620. * Generates RRIP 'ZF' System Use Entry.
  621. */
  622. unsigned int zisofs:1;
  623. #define OPT_ZISOFS_DISABLED 0
  624. #define OPT_ZISOFS_DIRECT 1
  625. #define OPT_ZISOFS_DEFAULT OPT_ZISOFS_DISABLED
  626. };
  627. struct iso9660 {
  628. /* The creation time of ISO image. */
  629. time_t birth_time;
  630. /* A file stream of a temporary file, which file contents
  631. * save to until ISO image can be created. */
  632. int temp_fd;
  633. struct isofile *cur_file;
  634. struct isoent *cur_dirent;
  635. struct archive_string cur_dirstr;
  636. uint64_t bytes_remaining;
  637. int need_multi_extent;
  638. /* Temporary string buffer for Joliet extension. */
  639. struct archive_string utf16be;
  640. struct archive_string mbs;
  641. struct archive_string_conv *sconv_to_utf16be;
  642. struct archive_string_conv *sconv_from_utf16be;
  643. /* A list of all of struct isofile entries. */
  644. struct {
  645. struct isofile *first;
  646. struct isofile **last;
  647. } all_file_list;
  648. /* A list of struct isofile entries which have its
  649. * contents and are not a directory, a hardlinked file
  650. * and a symlink file. */
  651. struct {
  652. struct isofile *first;
  653. struct isofile **last;
  654. } data_file_list;
  655. /* Used for managing to find hardlinking files. */
  656. struct archive_rb_tree hardlink_rbtree;
  657. /* Used for making the Path Table Record. */
  658. struct vdd {
  659. /* the root of entry tree. */
  660. struct isoent *rootent;
  661. enum vdd_type {
  662. VDD_PRIMARY,
  663. VDD_JOLIET,
  664. VDD_ENHANCED
  665. } vdd_type;
  666. struct path_table {
  667. struct isoent *first;
  668. struct isoent **last;
  669. struct isoent **sorted;
  670. int cnt;
  671. } *pathtbl;
  672. int max_depth;
  673. int path_table_block;
  674. int path_table_size;
  675. int location_type_L_path_table;
  676. int location_type_M_path_table;
  677. int total_dir_block;
  678. } primary, joliet;
  679. /* Used for making a Volume Descriptor. */
  680. int volume_space_size;
  681. int volume_sequence_number;
  682. int total_file_block;
  683. struct archive_string volume_identifier;
  684. struct archive_string publisher_identifier;
  685. struct archive_string data_preparer_identifier;
  686. struct archive_string application_identifier;
  687. struct archive_string copyright_file_identifier;
  688. struct archive_string abstract_file_identifier;
  689. struct archive_string bibliographic_file_identifier;
  690. /* Used for making rockridge extensions. */
  691. int location_rrip_er;
  692. /* Used for making zisofs. */
  693. struct {
  694. unsigned int detect_magic:1;
  695. unsigned int making:1;
  696. unsigned int allzero:1;
  697. unsigned char magic_buffer[64];
  698. int magic_cnt;
  699. #ifdef HAVE_ZLIB_H
  700. /*
  701. * Copy a compressed file to iso9660.zisofs.temp_fd
  702. * and also copy a uncompressed file(original file) to
  703. * iso9660.temp_fd . If the number of logical block
  704. * of the compressed file is less than the number of
  705. * logical block of the uncompressed file, use it and
  706. * remove the copy of the uncompressed file.
  707. * but if not, we use uncompressed file and remove
  708. * the copy of the compressed file.
  709. */
  710. uint32_t *block_pointers;
  711. size_t block_pointers_allocated;
  712. int block_pointers_cnt;
  713. int block_pointers_idx;
  714. int64_t total_size;
  715. int64_t block_offset;
  716. z_stream stream;
  717. int stream_valid;
  718. int64_t remaining;
  719. int compression_level;
  720. #endif
  721. } zisofs;
  722. struct isoent *directories_too_deep;
  723. int dircnt_max;
  724. /* Write buffer. */
  725. #define wb_buffmax() (LOGICAL_BLOCK_SIZE * 32)
  726. #define wb_remaining(a) (((struct iso9660 *)(a)->format_data)->wbuff_remaining)
  727. #define wb_offset(a) (((struct iso9660 *)(a)->format_data)->wbuff_offset \
  728. + wb_buffmax() - wb_remaining(a))
  729. unsigned char wbuff[LOGICAL_BLOCK_SIZE * 32];
  730. size_t wbuff_remaining;
  731. enum {
  732. WB_TO_STREAM,
  733. WB_TO_TEMP
  734. } wbuff_type;
  735. int64_t wbuff_offset;
  736. int64_t wbuff_written;
  737. int64_t wbuff_tail;
  738. /* 'El Torito' boot data. */
  739. struct {
  740. /* boot catalog file */
  741. struct archive_string catalog_filename;
  742. struct isoent *catalog;
  743. /* boot image file */
  744. struct archive_string boot_filename;
  745. struct isoent *boot;
  746. unsigned char platform_id;
  747. #define BOOT_PLATFORM_X86 0
  748. #define BOOT_PLATFORM_PPC 1
  749. #define BOOT_PLATFORM_MAC 2
  750. struct archive_string id;
  751. unsigned char media_type;
  752. #define BOOT_MEDIA_NO_EMULATION 0
  753. #define BOOT_MEDIA_1_2M_DISKETTE 1
  754. #define BOOT_MEDIA_1_44M_DISKETTE 2
  755. #define BOOT_MEDIA_2_88M_DISKETTE 3
  756. #define BOOT_MEDIA_HARD_DISK 4
  757. unsigned char system_type;
  758. uint16_t boot_load_seg;
  759. uint16_t boot_load_size;
  760. #define BOOT_LOAD_SIZE 4
  761. } el_torito;
  762. struct iso_option opt;
  763. };
  764. /*
  765. * Types of Volume Descriptor
  766. */
  767. enum VD_type {
  768. VDT_BOOT_RECORD=0, /* Boot Record Volume Descriptor */
  769. VDT_PRIMARY=1, /* Primary Volume Descriptor */
  770. VDT_SUPPLEMENTARY=2, /* Supplementary Volume Descriptor */
  771. VDT_TERMINATOR=255 /* Volume Descriptor Set Terminator */
  772. };
  773. /*
  774. * Types of Directory Record
  775. */
  776. enum dir_rec_type {
  777. DIR_REC_VD, /* Stored in Volume Descriptor. */
  778. DIR_REC_SELF, /* Stored as Current Directory. */
  779. DIR_REC_PARENT, /* Stored as Parent Directory. */
  780. DIR_REC_NORMAL /* Stored as Child. */
  781. };
  782. /*
  783. * Kinds of Volume Descriptor Character
  784. */
  785. enum vdc {
  786. VDC_STD,
  787. VDC_LOWERCASE,
  788. VDC_UCS2,
  789. VDC_UCS2_DIRECT
  790. };
  791. /*
  792. * IDentifier Resolver.
  793. * Used for resolving duplicated filenames.
  794. */
  795. struct idr {
  796. struct idrent {
  797. struct archive_rb_node rbnode;
  798. /* Used in wait_list. */
  799. struct idrent *wnext;
  800. struct idrent *avail;
  801. struct isoent *isoent;
  802. int weight;
  803. int noff;
  804. int rename_num;
  805. } *idrent_pool;
  806. struct archive_rb_tree rbtree;
  807. struct {
  808. struct idrent *first;
  809. struct idrent **last;
  810. } wait_list;
  811. int pool_size;
  812. int pool_idx;
  813. int num_size;
  814. int null_size;
  815. char char_map[0x80];
  816. };
  817. enum char_type {
  818. A_CHAR,
  819. D_CHAR
  820. };
  821. static int iso9660_options(struct archive_write *,
  822. const char *, const char *);
  823. static int iso9660_write_header(struct archive_write *,
  824. struct archive_entry *);
  825. static ssize_t iso9660_write_data(struct archive_write *,
  826. const void *, size_t);
  827. static int iso9660_finish_entry(struct archive_write *);
  828. static int iso9660_close(struct archive_write *);
  829. static int iso9660_free(struct archive_write *);
  830. static void get_system_identifier(char *, size_t);
  831. static void set_str(unsigned char *, const char *, size_t, char,
  832. const char *);
  833. static inline int joliet_allowed_char(unsigned char, unsigned char);
  834. static int set_str_utf16be(struct archive_write *, unsigned char *,
  835. const char *, size_t, uint16_t, enum vdc);
  836. static int set_str_a_characters_bp(struct archive_write *,
  837. unsigned char *, int, int, const char *, enum vdc);
  838. static int set_str_d_characters_bp(struct archive_write *,
  839. unsigned char *, int, int, const char *, enum vdc);
  840. static void set_VD_bp(unsigned char *, enum VD_type, unsigned char);
  841. static inline void set_unused_field_bp(unsigned char *, int, int);
  842. static unsigned char *extra_open_record(unsigned char *, int,
  843. struct isoent *, struct ctl_extr_rec *);
  844. static void extra_close_record(struct ctl_extr_rec *, int);
  845. static unsigned char * extra_next_record(struct ctl_extr_rec *, int);
  846. static unsigned char *extra_get_record(struct isoent *, int *, int *, int *);
  847. static void extra_tell_used_size(struct ctl_extr_rec *, int);
  848. static int extra_setup_location(struct isoent *, int);
  849. static int set_directory_record_rr(unsigned char *, int,
  850. struct isoent *, struct iso9660 *, enum dir_rec_type);
  851. static int set_directory_record(unsigned char *, size_t,
  852. struct isoent *, struct iso9660 *, enum dir_rec_type,
  853. enum vdd_type);
  854. static inline int get_dir_rec_size(struct iso9660 *, struct isoent *,
  855. enum dir_rec_type, enum vdd_type);
  856. static inline unsigned char *wb_buffptr(struct archive_write *);
  857. static int wb_write_out(struct archive_write *);
  858. static int wb_consume(struct archive_write *, size_t);
  859. #ifdef HAVE_ZLIB_H
  860. static int wb_set_offset(struct archive_write *, int64_t);
  861. #endif
  862. static int write_null(struct archive_write *, size_t);
  863. static int write_VD_terminator(struct archive_write *);
  864. static int set_file_identifier(unsigned char *, int, int, enum vdc,
  865. struct archive_write *, struct vdd *,
  866. struct archive_string *, const char *, int,
  867. enum char_type);
  868. static int write_VD(struct archive_write *, struct vdd *);
  869. static int write_VD_boot_record(struct archive_write *);
  870. static int write_information_block(struct archive_write *);
  871. static int write_path_table(struct archive_write *, int,
  872. struct vdd *);
  873. static int write_directory_descriptors(struct archive_write *,
  874. struct vdd *);
  875. static int write_file_descriptors(struct archive_write *);
  876. static int write_rr_ER(struct archive_write *);
  877. static void calculate_path_table_size(struct vdd *);
  878. static void isofile_init_entry_list(struct iso9660 *);
  879. static void isofile_add_entry(struct iso9660 *, struct isofile *);
  880. static void isofile_free_all_entries(struct iso9660 *);
  881. static void isofile_init_entry_data_file_list(struct iso9660 *);
  882. static void isofile_add_data_file(struct iso9660 *, struct isofile *);
  883. static struct isofile * isofile_new(struct archive_write *,
  884. struct archive_entry *);
  885. static void isofile_free(struct isofile *);
  886. static int isofile_gen_utility_names(struct archive_write *,
  887. struct isofile *);
  888. static int isofile_register_hardlink(struct archive_write *,
  889. struct isofile *);
  890. static void isofile_connect_hardlink_files(struct iso9660 *);
  891. static void isofile_init_hardlinks(struct iso9660 *);
  892. static void isofile_free_hardlinks(struct iso9660 *);
  893. static struct isoent *isoent_new(struct isofile *);
  894. static int isoent_clone_tree(struct archive_write *,
  895. struct isoent **, struct isoent *);
  896. static void _isoent_free(struct isoent *isoent);
  897. static void isoent_free_all(struct isoent *);
  898. static struct isoent * isoent_create_virtual_dir(struct archive_write *,
  899. struct iso9660 *, const char *);
  900. static int isoent_cmp_node(const struct archive_rb_node *,
  901. const struct archive_rb_node *);
  902. static int isoent_cmp_key(const struct archive_rb_node *,
  903. const void *);
  904. static int isoent_add_child_head(struct isoent *, struct isoent *);
  905. static int isoent_add_child_tail(struct isoent *, struct isoent *);
  906. static void isoent_remove_child(struct isoent *, struct isoent *);
  907. static void isoent_setup_directory_location(struct iso9660 *,
  908. int, struct vdd *);
  909. static void isoent_setup_file_location(struct iso9660 *, int);
  910. static int get_path_component(char *, size_t, const char *);
  911. static int isoent_tree(struct archive_write *, struct isoent **);
  912. static struct isoent *isoent_find_child(struct isoent *, const char *);
  913. static struct isoent *isoent_find_entry(struct isoent *, const char *);
  914. static void idr_relaxed_filenames(char *);
  915. static void idr_init(struct iso9660 *, struct vdd *, struct idr *);
  916. static void idr_cleanup(struct idr *);
  917. static int idr_ensure_poolsize(struct archive_write *, struct idr *,
  918. int);
  919. static int idr_start(struct archive_write *, struct idr *,
  920. int, int, int, int, const struct archive_rb_tree_ops *);
  921. static void idr_register(struct idr *, struct isoent *, int,
  922. int);
  923. static void idr_extend_identifier(struct idrent *, int, int);
  924. static void idr_resolve(struct idr *, void (*)(unsigned char *, int));
  925. static void idr_set_num(unsigned char *, int);
  926. static void idr_set_num_beutf16(unsigned char *, int);
  927. static int isoent_gen_iso9660_identifier(struct archive_write *,
  928. struct isoent *, struct idr *);
  929. static int isoent_gen_joliet_identifier(struct archive_write *,
  930. struct isoent *, struct idr *);
  931. static int isoent_cmp_iso9660_identifier(const struct isoent *,
  932. const struct isoent *);
  933. static int isoent_cmp_node_iso9660(const struct archive_rb_node *,
  934. const struct archive_rb_node *);
  935. static int isoent_cmp_key_iso9660(const struct archive_rb_node *,
  936. const void *);
  937. static int isoent_cmp_joliet_identifier(const struct isoent *,
  938. const struct isoent *);
  939. static int isoent_cmp_node_joliet(const struct archive_rb_node *,
  940. const struct archive_rb_node *);
  941. static int isoent_cmp_key_joliet(const struct archive_rb_node *,
  942. const void *);
  943. static inline void path_table_add_entry(struct path_table *, struct isoent *);
  944. static inline struct isoent * path_table_last_entry(struct path_table *);
  945. static int isoent_make_path_table(struct archive_write *);
  946. static int isoent_find_out_boot_file(struct archive_write *,
  947. struct isoent *);
  948. static int isoent_create_boot_catalog(struct archive_write *,
  949. struct isoent *);
  950. static size_t fd_boot_image_size(int);
  951. static int make_boot_catalog(struct archive_write *);
  952. static int setup_boot_information(struct archive_write *);
  953. static int zisofs_init(struct archive_write *, struct isofile *);
  954. static void zisofs_detect_magic(struct archive_write *,
  955. const void *, size_t);
  956. static int zisofs_write_to_temp(struct archive_write *,
  957. const void *, size_t);
  958. static int zisofs_finish_entry(struct archive_write *);
  959. static int zisofs_rewind_boot_file(struct archive_write *);
  960. static int zisofs_free(struct archive_write *);
  961. int
  962. archive_write_set_format_iso9660(struct archive *_a)
  963. {
  964. struct archive_write *a = (struct archive_write *)_a;
  965. struct iso9660 *iso9660;
  966. archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
  967. ARCHIVE_STATE_NEW, "archive_write_set_format_iso9660");
  968. /* If another format was already registered, unregister it. */
  969. if (a->format_free != NULL)
  970. (a->format_free)(a);
  971. iso9660 = calloc(1, sizeof(*iso9660));
  972. if (iso9660 == NULL) {
  973. archive_set_error(&a->archive, ENOMEM,
  974. "Can't allocate iso9660 data");
  975. return (ARCHIVE_FATAL);
  976. }
  977. iso9660->birth_time = 0;
  978. iso9660->temp_fd = -1;
  979. iso9660->cur_file = NULL;
  980. iso9660->primary.max_depth = 0;
  981. iso9660->primary.vdd_type = VDD_PRIMARY;
  982. iso9660->primary.pathtbl = NULL;
  983. iso9660->joliet.rootent = NULL;
  984. iso9660->joliet.max_depth = 0;
  985. iso9660->joliet.vdd_type = VDD_JOLIET;
  986. iso9660->joliet.pathtbl = NULL;
  987. isofile_init_entry_list(iso9660);
  988. isofile_init_entry_data_file_list(iso9660);
  989. isofile_init_hardlinks(iso9660);
  990. iso9660->directories_too_deep = NULL;
  991. iso9660->dircnt_max = 1;
  992. iso9660->wbuff_remaining = wb_buffmax();
  993. iso9660->wbuff_type = WB_TO_TEMP;
  994. iso9660->wbuff_offset = 0;
  995. iso9660->wbuff_written = 0;
  996. iso9660->wbuff_tail = 0;
  997. archive_string_init(&(iso9660->utf16be));
  998. archive_string_init(&(iso9660->mbs));
  999. /*
  1000. * Init Identifiers used for PVD and SVD.
  1001. */
  1002. archive_string_init(&(iso9660->volume_identifier));
  1003. archive_strcpy(&(iso9660->volume_identifier), "CDROM");
  1004. archive_string_init(&(iso9660->publisher_identifier));
  1005. archive_string_init(&(iso9660->data_preparer_identifier));
  1006. archive_string_init(&(iso9660->application_identifier));
  1007. archive_strcpy(&(iso9660->application_identifier),
  1008. archive_version_string());
  1009. archive_string_init(&(iso9660->copyright_file_identifier));
  1010. archive_string_init(&(iso9660->abstract_file_identifier));
  1011. archive_string_init(&(iso9660->bibliographic_file_identifier));
  1012. /*
  1013. * Init El Torito bootable CD variables.
  1014. */
  1015. archive_string_init(&(iso9660->el_torito.catalog_filename));
  1016. iso9660->el_torito.catalog = NULL;
  1017. /* Set default file name of boot catalog */
  1018. archive_strcpy(&(iso9660->el_torito.catalog_filename),
  1019. "boot.catalog");
  1020. archive_string_init(&(iso9660->el_torito.boot_filename));
  1021. iso9660->el_torito.boot = NULL;
  1022. iso9660->el_torito.platform_id = BOOT_PLATFORM_X86;
  1023. archive_string_init(&(iso9660->el_torito.id));
  1024. iso9660->el_torito.boot_load_seg = 0;
  1025. iso9660->el_torito.boot_load_size = BOOT_LOAD_SIZE;
  1026. /*
  1027. * Init zisofs variables.
  1028. */
  1029. #ifdef HAVE_ZLIB_H
  1030. iso9660->zisofs.block_pointers = NULL;
  1031. iso9660->zisofs.block_pointers_allocated = 0;
  1032. iso9660->zisofs.stream_valid = 0;
  1033. iso9660->zisofs.compression_level = 9;
  1034. memset(&(iso9660->zisofs.stream), 0,
  1035. sizeof(iso9660->zisofs.stream));
  1036. #endif
  1037. /*
  1038. * Set default value of iso9660 options.
  1039. */
  1040. iso9660->opt.abstract_file = OPT_ABSTRACT_FILE_DEFAULT;
  1041. iso9660->opt.application_id = OPT_APPLICATION_ID_DEFAULT;
  1042. iso9660->opt.allow_vernum = OPT_ALLOW_VERNUM_DEFAULT;
  1043. iso9660->opt.biblio_file = OPT_BIBLIO_FILE_DEFAULT;
  1044. iso9660->opt.boot = OPT_BOOT_DEFAULT;
  1045. iso9660->opt.boot_catalog = OPT_BOOT_CATALOG_DEFAULT;
  1046. iso9660->opt.boot_info_table = OPT_BOOT_INFO_TABLE_DEFAULT;
  1047. iso9660->opt.boot_load_seg = OPT_BOOT_LOAD_SEG_DEFAULT;
  1048. iso9660->opt.boot_load_size = OPT_BOOT_LOAD_SIZE_DEFAULT;
  1049. iso9660->opt.boot_type = OPT_BOOT_TYPE_DEFAULT;
  1050. iso9660->opt.compression_level = OPT_COMPRESSION_LEVEL_DEFAULT;
  1051. iso9660->opt.copyright_file = OPT_COPYRIGHT_FILE_DEFAULT;
  1052. iso9660->opt.iso_level = OPT_ISO_LEVEL_DEFAULT;
  1053. iso9660->opt.joliet = OPT_JOLIET_DEFAULT;
  1054. iso9660->opt.limit_depth = OPT_LIMIT_DEPTH_DEFAULT;
  1055. iso9660->opt.limit_dirs = OPT_LIMIT_DIRS_DEFAULT;
  1056. iso9660->opt.pad = OPT_PAD_DEFAULT;
  1057. iso9660->opt.publisher = OPT_PUBLISHER_DEFAULT;
  1058. iso9660->opt.rr = OPT_RR_DEFAULT;
  1059. iso9660->opt.volume_id = OPT_VOLUME_ID_DEFAULT;
  1060. iso9660->opt.zisofs = OPT_ZISOFS_DEFAULT;
  1061. /* Create the root directory. */
  1062. iso9660->primary.rootent =
  1063. isoent_create_virtual_dir(a, iso9660, "");
  1064. if (iso9660->primary.rootent == NULL) {
  1065. free(iso9660);
  1066. archive_set_error(&a->archive, ENOMEM,
  1067. "Can't allocate memory");
  1068. return (ARCHIVE_FATAL);
  1069. }
  1070. iso9660->primary.rootent->parent = iso9660->primary.rootent;
  1071. iso9660->cur_dirent = iso9660->primary.rootent;
  1072. archive_string_init(&(iso9660->cur_dirstr));
  1073. if (archive_string_ensure(&(iso9660->cur_dirstr), 1) == NULL) {
  1074. free(iso9660);
  1075. archive_set_error(&a->archive, ENOMEM,
  1076. "Can't allocate memory");
  1077. return (ARCHIVE_FATAL);
  1078. }
  1079. iso9660->cur_dirstr.s[0] = 0;
  1080. iso9660->sconv_to_utf16be = NULL;
  1081. iso9660->sconv_from_utf16be = NULL;
  1082. a->format_data = iso9660;
  1083. a->format_name = "iso9660";
  1084. a->format_options = iso9660_options;
  1085. a->format_write_header = iso9660_write_header;
  1086. a->format_write_data = iso9660_write_data;
  1087. a->format_finish_entry = iso9660_finish_entry;
  1088. a->format_close = iso9660_close;
  1089. a->format_free = iso9660_free;
  1090. a->archive.archive_format = ARCHIVE_FORMAT_ISO9660;
  1091. a->archive.archive_format_name = "ISO9660";
  1092. return (ARCHIVE_OK);
  1093. }
  1094. static int
  1095. get_str_opt(struct archive_write *a, struct archive_string *s,
  1096. size_t maxsize, const char *key, const char *value)
  1097. {
  1098. if (strlen(value) > maxsize) {
  1099. archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
  1100. "Value is longer than %zu characters "
  1101. "for option ``%s''", maxsize, key);
  1102. return (ARCHIVE_FATAL);
  1103. }
  1104. archive_strcpy(s, value);
  1105. return (ARCHIVE_OK);
  1106. }
  1107. static int
  1108. get_num_opt(struct archive_write *a, int *num, int high, int low,
  1109. const char *key, const char *value)
  1110. {
  1111. const char *p = value;
  1112. int data = 0;
  1113. int neg = 0;
  1114. if (p == NULL) {
  1115. archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
  1116. "Invalid value(empty) for option ``%s''", key);
  1117. return (ARCHIVE_FATAL);
  1118. }
  1119. if (*p == '-') {
  1120. neg = 1;
  1121. p++;
  1122. }
  1123. while (*p) {
  1124. if (*p >= '0' && *p <= '9')
  1125. data = data * 10 + *p - '0';
  1126. else {
  1127. archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
  1128. "Invalid value for option ``%s''", key);
  1129. return (ARCHIVE_FATAL);
  1130. }
  1131. if (data > high) {
  1132. archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
  1133. "Invalid value(over %d) for "
  1134. "option ``%s''", high, key);
  1135. return (ARCHIVE_FATAL);
  1136. }
  1137. if (data < low) {
  1138. archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
  1139. "Invalid value(under %d) for "
  1140. "option ``%s''", low, key);
  1141. return (ARCHIVE_FATAL);
  1142. }
  1143. p++;
  1144. }
  1145. if (neg)
  1146. data *= -1;
  1147. *num = data;
  1148. return (ARCHIVE_OK);
  1149. }
  1150. static int
  1151. iso9660_options(struct archive_write *a, const char *key, const char *value)
  1152. {
  1153. struct iso9660 *iso9660 = a->format_data;
  1154. const char *p;
  1155. int r;
  1156. switch (key[0]) {
  1157. case 'a':
  1158. if (strcmp(key, "abstract-file") == 0) {
  1159. r = get_str_opt(a,
  1160. &(iso9660->abstract_file_identifier),
  1161. ABSTRACT_FILE_SIZE, key, value);
  1162. iso9660->opt.abstract_file = r == ARCHIVE_OK;
  1163. return (r);
  1164. }
  1165. if (strcmp(key, "application-id") == 0) {
  1166. r = get_str_opt(a,
  1167. &(iso9660->application_identifier),
  1168. APPLICATION_IDENTIFIER_SIZE, key, value);
  1169. iso9660->opt.application_id = r == ARCHIVE_OK;
  1170. return (r);
  1171. }
  1172. if (strcmp(key, "allow-vernum") == 0) {
  1173. iso9660->opt.allow_vernum = value != NULL;
  1174. return (ARCHIVE_OK);
  1175. }
  1176. break;
  1177. case 'b':
  1178. if (strcmp(key, "biblio-file") == 0) {
  1179. r = get_str_opt(a,
  1180. &(iso9660->bibliographic_file_identifier),
  1181. BIBLIO_FILE_SIZE, key, value);
  1182. iso9660->opt.biblio_file = r == ARCHIVE_OK;
  1183. return (r);
  1184. }
  1185. if (strcmp(key, "boot") == 0) {
  1186. if (value == NULL)
  1187. iso9660->opt.boot = 0;
  1188. else {
  1189. iso9660->opt.boot = 1;
  1190. archive_strcpy(
  1191. &(iso9660->el_torito.boot_filename),
  1192. value);
  1193. }
  1194. return (ARCHIVE_OK);
  1195. }
  1196. if (strcmp(key, "boot-catalog") == 0) {
  1197. r = get_str_opt(a,
  1198. &(iso9660->el_torito.catalog_filename),
  1199. 1024, key, value);
  1200. iso9660->opt.boot_catalog = r == ARCHIVE_OK;
  1201. return (r);
  1202. }
  1203. if (strcmp(key, "boot-info-table") == 0) {
  1204. iso9660->opt.boot_info_table = value != NULL;
  1205. return (ARCHIVE_OK);
  1206. }
  1207. if (strcmp(key, "boot-load-seg") == 0) {
  1208. uint32_t seg;
  1209. iso9660->opt.boot_load_seg = 0;
  1210. if (value == NULL)
  1211. goto invalid_value;
  1212. seg = 0;
  1213. p = value;
  1214. if (p[0] == '0' && (p[1] == 'x' || p[1] == 'X'))
  1215. p += 2;
  1216. while (*p) {
  1217. if (seg)
  1218. seg <<= 4;
  1219. if (*p >= 'A' && *p <= 'F')
  1220. seg += *p - 'A' + 0x0a;
  1221. else if (*p >= 'a' && *p <= 'f')
  1222. seg += *p - 'a' + 0x0a;
  1223. else if (*p >= '0' && *p <= '9')
  1224. seg += *p - '0';
  1225. else
  1226. goto invalid_value;
  1227. if (seg > 0xffff) {
  1228. archive_set_error(&a->archive,
  1229. ARCHIVE_ERRNO_MISC,
  1230. "Invalid value(over 0xffff) for "
  1231. "option ``%s''", key);
  1232. return (ARCHIVE_FATAL);
  1233. }
  1234. p++;
  1235. }
  1236. iso9660->el_torito.boot_load_seg = (uint16_t)seg;
  1237. iso9660->opt.boot_load_seg = 1;
  1238. return (ARCHIVE_OK);
  1239. }
  1240. if (strcmp(key, "boot-load-size") == 0) {
  1241. int num = 0;
  1242. r = get_num_opt(a, &num, 0xffff, 1, key, value);
  1243. iso9660->opt.boot_load_size = r == ARCHIVE_OK;
  1244. if (r != ARCHIVE_OK)
  1245. return (ARCHIVE_FATAL);
  1246. iso9660->el_torito.boot_load_size = (uint16_t)num;
  1247. return (ARCHIVE_OK);
  1248. }
  1249. if (strcmp(key, "boot-type") == 0) {
  1250. if (value == NULL)
  1251. goto invalid_value;
  1252. if (strcmp(value, "no-emulation") == 0)
  1253. iso9660->opt.boot_type = OPT_BOOT_TYPE_NO_EMU;
  1254. else if (strcmp(value, "fd") == 0)
  1255. iso9660->opt.boot_type = OPT_BOOT_TYPE_FD;
  1256. else if (strcmp(value, "hard-disk") == 0)
  1257. iso9660->opt.boot_type = OPT_BOOT_TYPE_HARD_DISK;
  1258. else
  1259. goto invalid_value;
  1260. return (ARCHIVE_OK);
  1261. }
  1262. break;
  1263. case 'c':
  1264. if (strcmp(key, "compression-level") == 0) {
  1265. #ifdef HAVE_ZLIB_H
  1266. if (value == NULL ||
  1267. !(value[0] >= '0' && value[0] <= '9') ||
  1268. value[1] != '\0')
  1269. goto invalid_value;
  1270. iso9660->zisofs.compression_level = value[0] - '0';
  1271. iso9660->opt.compression_level = 1;
  1272. return (ARCHIVE_OK);
  1273. #else
  1274. archive_set_error(&a->archive,
  1275. ARCHIVE_ERRNO_MISC,
  1276. "Option ``%s'' "
  1277. "is not supported on this platform.", key);
  1278. return (ARCHIVE_FATAL);
  1279. #endif
  1280. }
  1281. if (strcmp(key, "copyright-file") == 0) {
  1282. r = get_str_opt(a,
  1283. &(iso9660->copyright_file_identifier),
  1284. COPYRIGHT_FILE_SIZE, key, value);
  1285. iso9660->opt.copyright_file = r == ARCHIVE_OK;
  1286. return (r);
  1287. }
  1288. #ifdef DEBUG
  1289. /* Specifies Volume creation date and time;
  1290. * year(4),month(2),day(2),hour(2),minute(2),second(2).
  1291. * e.g. "20090929033757"
  1292. */
  1293. if (strcmp(key, "creation") == 0) {
  1294. struct tm tm;
  1295. char buf[5];
  1296. p = value;
  1297. if (p == NULL || strlen(p) < 14)
  1298. goto invalid_value;
  1299. memset(&tm, 0, sizeof(tm));
  1300. memcpy(buf, p, 4); buf[4] = '\0'; p += 4;
  1301. tm.tm_year = strtol(buf, NULL, 10) - 1900;
  1302. memcpy(buf, p, 2); buf[2] = '\0'; p += 2;
  1303. tm.tm_mon = strtol(buf, NULL, 10) - 1;
  1304. memcpy(buf, p, 2); buf[2] = '\0'; p += 2;
  1305. tm.tm_mday = strtol(buf, NULL, 10);
  1306. memcpy(buf, p, 2); buf[2] = '\0'; p += 2;
  1307. tm.tm_hour = strtol(buf, NULL, 10);
  1308. memcpy(buf, p, 2); buf[2] = '\0'; p += 2;
  1309. tm.tm_min = strtol(buf, NULL, 10);
  1310. memcpy(buf, p, 2); buf[2] = '\0';
  1311. tm.tm_sec = strtol(buf, NULL, 10);
  1312. iso9660->birth_time = mktime(&tm);
  1313. return (ARCHIVE_OK);
  1314. }
  1315. #endif
  1316. break;
  1317. case 'i':
  1318. if (strcmp(key, "iso-level") == 0) {
  1319. if (value != NULL && value[1] == '\0' &&
  1320. (value[0] >= '1' && value[0] <= '4')) {
  1321. iso9660->opt.iso_level = value[0]-'0';
  1322. return (ARCHIVE_OK);
  1323. }
  1324. goto invalid_value;
  1325. }
  1326. break;
  1327. case 'j':
  1328. if (strcmp(key, "joliet") == 0) {
  1329. if (value == NULL)
  1330. iso9660->opt.joliet = OPT_JOLIET_DISABLE;
  1331. else if (strcmp(value, "1") == 0)
  1332. iso9660->opt.joliet = OPT_JOLIET_ENABLE;
  1333. else if (strcmp(value, "long") == 0)
  1334. iso9660->opt.joliet = OPT_JOLIET_LONGNAME;
  1335. else
  1336. goto invalid_value;
  1337. return (ARCHIVE_OK);
  1338. }
  1339. break;
  1340. case 'l':
  1341. if (strcmp(key, "limit-depth") == 0) {
  1342. iso9660->opt.limit_depth = value != NULL;
  1343. return (ARCHIVE_OK);
  1344. }
  1345. if (strcmp(key, "limit-dirs") == 0) {
  1346. iso9660->opt.limit_dirs = value != NULL;
  1347. return (ARCHIVE_OK);
  1348. }
  1349. break;
  1350. case 'p':
  1351. if (strcmp(key, "pad") == 0) {
  1352. iso9660->opt.pad = value != NULL;
  1353. return (ARCHIVE_OK);
  1354. }
  1355. if (strcmp(key, "publisher") == 0) {
  1356. r = get_str_opt(a,
  1357. &(iso9660->publisher_identifier),
  1358. PUBLISHER_IDENTIFIER_SIZE, key, value);
  1359. iso9660->opt.publisher = r == ARCHIVE_OK;
  1360. return (r);
  1361. }
  1362. break;
  1363. case 'r':
  1364. if (strcmp(key, "rockridge") == 0 ||
  1365. strcmp(key, "Rockridge") == 0) {
  1366. if (value == NULL)
  1367. iso9660->opt.rr = OPT_RR_DISABLED;
  1368. else if (strcmp(value, "1") == 0)
  1369. iso9660->opt.rr = OPT_RR_USEFUL;
  1370. else if (strcmp(value, "strict") == 0)
  1371. iso9660->opt.rr = OPT_RR_STRICT;
  1372. else if (strcmp(value, "useful") == 0)
  1373. iso9660->opt.rr = OPT_RR_USEFUL;
  1374. else
  1375. goto invalid_value;
  1376. return (ARCHIVE_OK);
  1377. }
  1378. break;
  1379. case 'v':
  1380. if (strcmp(key, "volume-id") == 0) {
  1381. r = get_str_opt(a, &(iso9660->volume_identifier),
  1382. VOLUME_IDENTIFIER_SIZE, key, value);
  1383. iso9660->opt.volume_id = r == ARCHIVE_OK;
  1384. return (r);
  1385. }
  1386. break;
  1387. case 'z':
  1388. if (strcmp(key, "zisofs") == 0) {
  1389. if (value == NULL)
  1390. iso9660->opt.zisofs = OPT_ZISOFS_DISABLED;
  1391. else {
  1392. #ifdef HAVE_ZLIB_H
  1393. iso9660->opt.zisofs = OPT_ZISOFS_DIRECT;
  1394. #else
  1395. archive_set_error(&a->archive,
  1396. ARCHIVE_ERRNO_MISC,
  1397. "``zisofs'' "
  1398. "is not supported on this platform.");
  1399. return (ARCHIVE_FATAL);
  1400. #endif
  1401. }
  1402. return (ARCHIVE_OK);
  1403. }
  1404. break;
  1405. }
  1406. /* Note: The "warn" return is just to inform the options
  1407. * supervisor that we didn't handle it. It will generate
  1408. * a suitable error if no one used this option. */
  1409. return (ARCHIVE_WARN);
  1410. invalid_value:
  1411. archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
  1412. "Invalid value for option ``%s''", key);
  1413. return (ARCHIVE_FAILED);
  1414. }
  1415. static int
  1416. iso9660_write_header(struct archive_write *a, struct archive_entry *entry)
  1417. {
  1418. struct iso9660 *iso9660;
  1419. struct isofile *file;
  1420. struct isoent *isoent;
  1421. int r, ret = ARCHIVE_OK;
  1422. iso9660 = a->format_data;
  1423. iso9660->cur_file = NULL;
  1424. iso9660->bytes_remaining = 0;
  1425. iso9660->need_multi_extent = 0;
  1426. if (archive_entry_filetype(entry) == AE_IFLNK
  1427. && iso9660->opt.rr == OPT_RR_DISABLED) {
  1428. archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
  1429. "Ignore symlink file.");
  1430. iso9660->cur_file = NULL;
  1431. return (ARCHIVE_WARN);
  1432. }
  1433. if (archive_entry_filetype(entry) == AE_IFREG &&
  1434. archive_entry_size(entry) >= MULTI_EXTENT_SIZE) {
  1435. if (iso9660->opt.iso_level < 3) {
  1436. archive_set_error(&a->archive,
  1437. ARCHIVE_ERRNO_MISC,
  1438. "Ignore over %lld bytes file. "
  1439. "This file too large.",
  1440. MULTI_EXTENT_SIZE);
  1441. iso9660->cur_file = NULL;
  1442. return (ARCHIVE_WARN);
  1443. }
  1444. iso9660->need_multi_extent = 1;
  1445. }
  1446. file = isofile_new(a, entry);
  1447. if (file == NULL) {
  1448. archive_set_error(&a->archive, ENOMEM,
  1449. "Can't allocate data");
  1450. return (ARCHIVE_FATAL);
  1451. }
  1452. r = isofile_gen_utility_names(a, file);
  1453. if (r < ARCHIVE_WARN) {
  1454. isofile_free(file);
  1455. return (r);
  1456. }
  1457. else if (r < ret)
  1458. ret = r;
  1459. /*
  1460. * Ignore a path which looks like the top of directory name
  1461. * since we have already made the root directory of an ISO image.
  1462. */
  1463. if (archive_strlen(&(file->parentdir)) == 0 &&
  1464. archive_strlen(&(file->basename)) == 0) {
  1465. isofile_free(file);
  1466. return (r);
  1467. }
  1468. isofile_add_entry(iso9660, file);
  1469. isoent = isoent_new(file);
  1470. if (isoent == NULL) {
  1471. archive_set_error(&a->archive, ENOMEM,
  1472. "Can't allocate data");
  1473. return (ARCHIVE_FATAL);
  1474. }
  1475. if (isoent->file->dircnt > iso9660->dircnt_max)
  1476. iso9660->dircnt_max = isoent->file->dircnt;
  1477. /* Add the current file into tree */
  1478. r = isoent_tree(a, &isoent);
  1479. if (r != ARCHIVE_OK)
  1480. return (r);
  1481. /* If there is the same file in tree and
  1482. * the current file is older than the file in tree.
  1483. * So we don't need the current file data anymore. */
  1484. if (isoent->file != file)
  1485. return (ARCHIVE_OK);
  1486. /* Non regular files contents are unneeded to be saved to
  1487. * temporary files. */
  1488. if (archive_entry_filetype(file->entry) != AE_IFREG)
  1489. return (ret);
  1490. /*
  1491. * Set the current file to cur_file to read its contents.
  1492. */
  1493. iso9660->cur_file = file;
  1494. if (archive_entry_nlink(file->entry) > 1) {
  1495. r = isofile_register_hardlink(a, file);
  1496. if (r != ARCHIVE_OK)
  1497. return (ARCHIVE_FATAL);
  1498. }
  1499. /*
  1500. * Prepare to save the contents of the file.
  1501. */
  1502. if (iso9660->temp_fd < 0) {
  1503. iso9660->temp_fd = __archive_mktemp(NULL);
  1504. if (iso9660->temp_fd < 0) {
  1505. archive_set_error(&a->archive, errno,
  1506. "Couldn't create temporary file");
  1507. return (ARCHIVE_FATAL);
  1508. }
  1509. }
  1510. /* Save an offset of current file in temporary file. */
  1511. file->content.offset_of_temp = wb_offset(a);
  1512. file->cur_content = &(file->content);
  1513. r = zisofs_init(a, file);
  1514. if (r < ret)
  1515. ret = r;
  1516. iso9660->bytes_remaining = archive_entry_size(file->entry);
  1517. return (ret);
  1518. }
  1519. static int
  1520. write_to_temp(struct archive_write *a, const void *buff, size_t s)
  1521. {
  1522. struct iso9660 *iso9660 = a->format_data;
  1523. ssize_t written;
  1524. const unsigned char *b;
  1525. b = (const unsigned char *)buff;
  1526. while (s) {
  1527. written = write(iso9660->temp_fd, b, s);
  1528. if (written < 0) {
  1529. archive_set_error(&a->archive, errno,
  1530. "Can't write to temporary file");
  1531. return (ARCHIVE_FATAL);
  1532. }
  1533. s -= written;
  1534. b += written;
  1535. }
  1536. return (ARCHIVE_OK);
  1537. }
  1538. static int
  1539. wb_write_to_temp(struct archive_write *a, const void *buff, size_t s)
  1540. {
  1541. const char *xp = buff;
  1542. size_t xs = s;
  1543. /*
  1544. * If a written data size is big enough to use system-call
  1545. * and there is no waiting data, this calls write_to_temp() in
  1546. * order to reduce a extra memory copy.
  1547. */
  1548. if (wb_remaining(a) == wb_buffmax() && s > (1024 * 16)) {
  1549. struct iso9660 *iso9660 = (struct iso9660 *)a->format_data;
  1550. xs = s % LOGICAL_BLOCK_SIZE;
  1551. iso9660->wbuff_offset += s - xs;
  1552. if (write_to_temp(a, buff, s - xs) != ARCHIVE_OK)
  1553. return (ARCHIVE_FATAL);
  1554. if (xs == 0)
  1555. return (ARCHIVE_OK);
  1556. xp += s - xs;
  1557. }
  1558. while (xs) {
  1559. size_t size = xs;
  1560. if (size > wb_remaining(a))
  1561. size = wb_remaining(a);
  1562. memcpy(wb_buffptr(a), xp, size);
  1563. if (wb_consume(a, size) != ARCHIVE_OK)
  1564. return (ARCHIVE_FATAL);
  1565. xs -= size;
  1566. xp += size;
  1567. }
  1568. return (ARCHIVE_OK);
  1569. }
  1570. static int
  1571. wb_write_padding_to_temp(struct archive_write *a, int64_t csize)
  1572. {
  1573. size_t ns;
  1574. int ret;
  1575. ns = (size_t)(csize % LOGICAL_BLOCK_SIZE);
  1576. if (ns != 0)
  1577. ret = write_null(a, LOGICAL_BLOCK_SIZE - ns);
  1578. else
  1579. ret = ARCHIVE_OK;
  1580. return (ret);
  1581. }
  1582. static ssize_t
  1583. write_iso9660_data(struct archive_write *a, const void *buff, size_t s)
  1584. {
  1585. struct iso9660 *iso9660 = a->format_data;
  1586. size_t ws;
  1587. if (iso9660->temp_fd < 0) {
  1588. archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
  1589. "Couldn't create temporary file");
  1590. return (ARCHIVE_FATAL);
  1591. }
  1592. ws = s;
  1593. if (iso9660->need_multi_extent &&
  1594. (iso9660->cur_file->cur_content->size + ws) >=
  1595. (MULTI_EXTENT_SIZE - LOGICAL_BLOCK_SIZE)) {
  1596. struct content *con;
  1597. size_t ts;
  1598. ts = (size_t)(MULTI_EXTENT_SIZE - LOGICAL_BLOCK_SIZE -
  1599. iso9660->cur_file->cur_content->size);
  1600. if (iso9660->zisofs.detect_magic)
  1601. zisofs_detect_magic(a, buff, ts);
  1602. if (iso9660->zisofs.making) {
  1603. if (zisofs_write_to_temp(a, buff, ts) != ARCHIVE_OK)
  1604. return (ARCHIVE_FATAL);
  1605. } else {
  1606. if (wb_write_to_temp(a, buff, ts) != ARCHIVE_OK)
  1607. return (ARCHIVE_FATAL);
  1608. iso9660->cur_file->cur_content->size += ts;
  1609. }
  1610. /* Write padding. */
  1611. if (wb_write_padding_to_temp(a,
  1612. iso9660->cur_file->cur_content->size) != ARCHIVE_OK)
  1613. return (ARCHIVE_FATAL);
  1614. /* Compute the logical block number. */
  1615. iso9660->cur_file->cur_content->blocks = (int)
  1616. ((iso9660->cur_file->cur_content->size
  1617. + LOGICAL_BLOCK_SIZE -1) >> LOGICAL_BLOCK_BITS);
  1618. /*
  1619. * Make next extent.
  1620. */
  1621. ws -= ts;
  1622. buff = (const void *)(((const unsigned char *)buff) + ts);
  1623. /* Make a content for next extent. */
  1624. con = calloc(1, sizeof(*con));
  1625. if (con == NULL) {
  1626. archive_set_error(&a->archive, ENOMEM,
  1627. "Can't allocate content data");
  1628. return (ARCHIVE_FATAL);
  1629. }
  1630. con->offset_of_temp = wb_offset(a);
  1631. iso9660->cur_file->cur_content->next = con;
  1632. iso9660->cur_file->cur_content = con;
  1633. #ifdef HAVE_ZLIB_H
  1634. iso9660->zisofs.block_offset = 0;
  1635. #endif
  1636. }
  1637. if (iso9660->zisofs.detect_magic)
  1638. zisofs_detect_magic(a, buff, ws);
  1639. if (iso9660->zisofs.making) {
  1640. if (zisofs_write_to_temp(a, buff, ws) != ARCHIVE_OK)
  1641. return (ARCHIVE_FATAL);
  1642. } else {
  1643. if (wb_write_to_temp(a, buff, ws) != ARCHIVE_OK)
  1644. return (ARCHIVE_FATAL);
  1645. iso9660->cur_file->cur_content->size += ws;
  1646. }
  1647. return (s);
  1648. }
  1649. static ssize_t
  1650. iso9660_write_data(struct archive_write *a, const void *buff, size_t s)
  1651. {
  1652. struct iso9660 *iso9660 = a->format_data;
  1653. ssize_t r;
  1654. if (iso9660->cur_file == NULL)
  1655. return (0);
  1656. if (archive_entry_filetype(iso9660->cur_file->entry) != AE_IFREG)
  1657. return (0);
  1658. if (s > iso9660->bytes_remaining)
  1659. s = (size_t)iso9660->bytes_remaining;
  1660. if (s == 0)
  1661. return (0);
  1662. r = write_iso9660_data(a, buff, s);
  1663. if (r > 0)
  1664. iso9660->bytes_remaining -= r;
  1665. return (r);
  1666. }
  1667. static int
  1668. iso9660_finish_entry(struct archive_write *a)
  1669. {
  1670. struct iso9660 *iso9660 = a->format_data;
  1671. if (iso9660->cur_file == NULL)
  1672. return (ARCHIVE_OK);
  1673. if (archive_entry_filetype(iso9660->cur_file->entry) != AE_IFREG)
  1674. return (ARCHIVE_OK);
  1675. if (iso9660->cur_file->content.size == 0)
  1676. return (ARCHIVE_OK);
  1677. /* If there are unwritten data, write null data instead. */
  1678. while (iso9660->bytes_remaining > 0) {
  1679. size_t s;
  1680. s = (iso9660->bytes_remaining > a->null_length)?
  1681. a->null_length: (size_t)iso9660->bytes_remaining;
  1682. if (write_iso9660_data(a, a->nulls, s) < 0)
  1683. return (ARCHIVE_FATAL);
  1684. iso9660->bytes_remaining -= s;
  1685. }
  1686. if (iso9660->zisofs.making && zisofs_finish_entry(a) != ARCHIVE_OK)
  1687. return (ARCHIVE_FATAL);
  1688. /* Write padding. */
  1689. if (wb_write_padding_to_temp(a, iso9660->cur_file->cur_content->size)
  1690. != ARCHIVE_OK)
  1691. return (ARCHIVE_FATAL);
  1692. /* Compute the logical block number. */
  1693. iso9660->cur_file->cur_content->blocks = (int)
  1694. ((iso9660->cur_file->cur_content->size
  1695. + LOGICAL_BLOCK_SIZE -1) >> LOGICAL_BLOCK_BITS);
  1696. /* Add the current file to data file list. */
  1697. isofile_add_data_file(iso9660, iso9660->cur_file);
  1698. return (ARCHIVE_OK);
  1699. }
  1700. static int
  1701. iso9660_close(struct archive_write *a)
  1702. {
  1703. struct iso9660 *iso9660;
  1704. int ret, blocks;
  1705. iso9660 = a->format_data;
  1706. /*
  1707. * Write remaining data out to the temporary file.
  1708. */
  1709. if (wb_remaining(a) > 0) {
  1710. ret = wb_write_out(a);
  1711. if (ret < 0)
  1712. return (ret);
  1713. }
  1714. /*
  1715. * Preparations...
  1716. */
  1717. #ifdef DEBUG
  1718. if (iso9660->birth_time == 0)
  1719. #endif
  1720. time(&(iso9660->birth_time));
  1721. /*
  1722. * Prepare a bootable ISO image.
  1723. */
  1724. if (iso9660->opt.boot) {
  1725. /* Find out the boot file entry. */
  1726. ret = isoent_find_out_boot_file(a, iso9660->primary.rootent);
  1727. if (ret < 0)
  1728. return (ret);
  1729. /* Reconvert the boot file from zisofs'ed form to
  1730. * plain form. */
  1731. ret = zisofs_rewind_boot_file(a);
  1732. if (ret < 0)
  1733. return (ret);
  1734. /* Write remaining data out to the temporary file. */
  1735. if (wb_remaining(a) > 0) {
  1736. ret = wb_write_out(a);
  1737. if (ret < 0)
  1738. return (ret);
  1739. }
  1740. /* Create the boot catalog. */
  1741. ret = isoent_create_boot_catalog(a, iso9660->primary.rootent);
  1742. if (ret < 0)
  1743. return (ret);
  1744. }
  1745. /*
  1746. * Prepare joliet extensions.
  1747. */
  1748. if (iso9660->opt.joliet) {
  1749. /* Make a new tree for joliet. */
  1750. ret = isoent_clone_tree(a, &(iso9660->joliet.rootent),
  1751. iso9660->primary.rootent);
  1752. if (ret < 0)
  1753. return (ret);
  1754. /* Make sure we have UTF-16BE converters.
  1755. * if there is no file entry, converters are still
  1756. * uninitialized. */
  1757. if (iso9660->sconv_to_utf16be == NULL) {
  1758. iso9660->sconv_to_utf16be =
  1759. archive_string_conversion_to_charset(
  1760. &(a->archive), "UTF-16BE", 1);
  1761. if (iso9660->sconv_to_utf16be == NULL)
  1762. /* Couldn't allocate memory */
  1763. return (ARCHIVE_FATAL);
  1764. iso9660->sconv_from_utf16be =
  1765. archive_string_conversion_from_charset(
  1766. &(a->archive), "UTF-16BE", 1);
  1767. if (iso9660->sconv_from_utf16be == NULL)
  1768. /* Couldn't allocate memory */
  1769. return (ARCHIVE_FATAL);
  1770. }
  1771. }
  1772. /*
  1773. * Make Path Tables.
  1774. */
  1775. ret = isoent_make_path_table(a);
  1776. if (ret < 0)
  1777. return (ret);
  1778. /*
  1779. * Calculate a total volume size and setup all locations of
  1780. * contents of an iso9660 image.
  1781. */
  1782. blocks = SYSTEM_AREA_BLOCK
  1783. + PRIMARY_VOLUME_DESCRIPTOR_BLOCK
  1784. + VOLUME_DESCRIPTOR_SET_TERMINATOR_BLOCK
  1785. + NON_ISO_FILE_SYSTEM_INFORMATION_BLOCK;
  1786. if (iso9660->opt.boot)
  1787. blocks += BOOT_RECORD_DESCRIPTOR_BLOCK;
  1788. if (iso9660->opt.joliet)
  1789. blocks += SUPPLEMENTARY_VOLUME_DESCRIPTOR_BLOCK;
  1790. if (iso9660->opt.iso_level == 4)
  1791. blocks += SUPPLEMENTARY_VOLUME_DESCRIPTOR_BLOCK;
  1792. /* Setup the locations of Path Table. */
  1793. iso9660->primary.location_type_L_path_table = blocks;
  1794. blocks += iso9660->primary.path_table_block;
  1795. iso9660->primary.location_type_M_path_table = blocks;
  1796. blocks += iso9660->primary.path_table_block;
  1797. if (iso9660->opt.joliet) {
  1798. iso9660->joliet.location_type_L_path_table = blocks;
  1799. blocks += iso9660->joliet.path_table_block;
  1800. iso9660->joliet.location_type_M_path_table = blocks;
  1801. blocks += iso9660->joliet.path_table_block;
  1802. }
  1803. /* Setup the locations of directories. */
  1804. isoent_setup_directory_location(iso9660, blocks,
  1805. &(iso9660->primary));
  1806. blocks += iso9660->primary.total_dir_block;
  1807. if (iso9660->opt.joliet) {
  1808. isoent_setup_directory_location(iso9660, blocks,
  1809. &(iso9660->joliet));
  1810. blocks += iso9660->joliet.total_dir_block;
  1811. }
  1812. if (iso9660->opt.rr) {
  1813. iso9660->location_rrip_er = blocks;
  1814. blocks += RRIP_ER_BLOCK;
  1815. }
  1816. /* Setup the locations of all file contents. */
  1817. isoent_setup_file_location(iso9660, blocks);
  1818. blocks += iso9660->total_file_block;
  1819. if (iso9660->opt.boot && iso9660->opt.boot_info_table) {
  1820. ret = setup_boot_information(a);
  1821. if (ret < 0)
  1822. return (ret);
  1823. }
  1824. /* Now we have a total volume size. */
  1825. iso9660->volume_space_size = blocks;
  1826. if (iso9660->opt.pad)
  1827. iso9660->volume_space_size += PADDING_BLOCK;
  1828. iso9660->volume_sequence_number = 1;
  1829. /*
  1830. * Write an ISO 9660 image.
  1831. */
  1832. /* Switch to start using wbuff as file buffer. */
  1833. iso9660->wbuff_remaining = wb_buffmax();
  1834. iso9660->wbuff_type = WB_TO_STREAM;
  1835. iso9660->wbuff_offset = 0;
  1836. iso9660->wbuff_written = 0;
  1837. iso9660->wbuff_tail = 0;
  1838. /* Write The System Area */
  1839. ret = write_null(a, SYSTEM_AREA_BLOCK * LOGICAL_BLOCK_SIZE);
  1840. if (ret != ARCHIVE_OK)
  1841. return (ARCHIVE_FATAL);
  1842. /* Write Primary Volume Descriptor */
  1843. ret = write_VD(a, &(iso9660->primary));
  1844. if (ret != ARCHIVE_OK)
  1845. return (ARCHIVE_FATAL);
  1846. if (iso9660->opt.boot) {
  1847. /* Write Boot Record Volume Descriptor */
  1848. ret = write_VD_boot_record(a);
  1849. if (ret != ARCHIVE_OK)
  1850. return (ARCHIVE_FATAL);
  1851. }
  1852. if (iso9660->opt.iso_level == 4) {
  1853. /* Write Enhanced Volume Descriptor */
  1854. iso9660->primary.vdd_type = VDD_ENHANCED;
  1855. ret = write_VD(a, &(iso9660->primary));
  1856. iso9660->primary.vdd_type = VDD_PRIMARY;
  1857. if (ret != ARCHIVE_OK)
  1858. return (ARCHIVE_FATAL);
  1859. }
  1860. if (iso9660->opt.joliet) {
  1861. ret = write_VD(a, &(iso9660->joliet));
  1862. if (ret != ARCHIVE_OK)
  1863. return (ARCHIVE_FATAL);
  1864. }
  1865. /* Write Volume Descriptor Set Terminator */
  1866. ret = write_VD_terminator(a);
  1867. if (ret != ARCHIVE_OK)
  1868. return (ARCHIVE_FATAL);
  1869. /* Write Non-ISO File System Information */
  1870. ret = write_information_block(a);
  1871. if (ret != ARCHIVE_OK)
  1872. return (ARCHIVE_FATAL);
  1873. /* Write Type L Path Table */
  1874. ret = write_path_table(a, 0, &(iso9660->primary));
  1875. if (ret != ARCHIVE_OK)
  1876. return (ARCHIVE_FATAL);
  1877. /* Write Type M Path Table */
  1878. ret = write_path_table(a, 1, &(iso9660->primary));
  1879. if (ret != ARCHIVE_OK)
  1880. return (ARCHIVE_FATAL);
  1881. if (iso9660->opt.joliet) {
  1882. /* Write Type L Path Table */
  1883. ret = write_path_table(a, 0, &(iso9660->joliet));
  1884. if (ret != ARCHIVE_OK)
  1885. return (ARCHIVE_FATAL);
  1886. /* Write Type M Path Table */
  1887. ret = write_path_table(a, 1, &(iso9660->joliet));
  1888. if (ret != ARCHIVE_OK)
  1889. return (ARCHIVE_FATAL);
  1890. }
  1891. /* Write Directory Descriptors */
  1892. ret = write_directory_descriptors(a, &(iso9660->primary));
  1893. if (ret != ARCHIVE_OK)
  1894. return (ARCHIVE_FATAL);
  1895. if (iso9660->opt.joliet) {
  1896. ret = write_directory_descriptors(a, &(iso9660->joliet));
  1897. if (ret != ARCHIVE_OK)
  1898. return (ARCHIVE_FATAL);
  1899. }
  1900. if (iso9660->opt.rr) {
  1901. /* Write Rockridge ER(Extensions Reference) */
  1902. ret = write_rr_ER(a);
  1903. if (ret != ARCHIVE_OK)
  1904. return (ARCHIVE_FATAL);
  1905. }
  1906. /* Write File Descriptors */
  1907. ret = write_file_descriptors(a);
  1908. if (ret != ARCHIVE_OK)
  1909. return (ARCHIVE_FATAL);
  1910. /* Write Padding */
  1911. if (iso9660->opt.pad) {
  1912. ret = write_null(a, PADDING_BLOCK * LOGICAL_BLOCK_SIZE);
  1913. if (ret != ARCHIVE_OK)
  1914. return (ARCHIVE_FATAL);
  1915. }
  1916. if (iso9660->directories_too_deep != NULL) {
  1917. archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
  1918. "%s: Directories too deep.",
  1919. archive_entry_pathname(
  1920. iso9660->directories_too_deep->file->entry));
  1921. return (ARCHIVE_WARN);
  1922. }
  1923. /* Write remaining data out. */
  1924. ret = wb_write_out(a);
  1925. return (ret);
  1926. }
  1927. static int
  1928. iso9660_free(struct archive_write *a)
  1929. {
  1930. struct iso9660 *iso9660;
  1931. int i, ret;
  1932. iso9660 = a->format_data;
  1933. /* Close the temporary file. */
  1934. if (iso9660->temp_fd >= 0)
  1935. close(iso9660->temp_fd);
  1936. /* Free some stuff for zisofs operations. */
  1937. ret = zisofs_free(a);
  1938. /* Remove directory entries in tree which includes file entries. */
  1939. isoent_free_all(iso9660->primary.rootent);
  1940. for (i = 0; i < iso9660->primary.max_depth; i++)
  1941. free(iso9660->primary.pathtbl[i].sorted);
  1942. free(iso9660->primary.pathtbl);
  1943. if (iso9660->opt.joliet) {
  1944. isoent_free_all(iso9660->joliet.rootent);
  1945. for (i = 0; i < iso9660->joliet.max_depth; i++)
  1946. free(iso9660->joliet.pathtbl[i].sorted);
  1947. free(iso9660->joliet.pathtbl);
  1948. }
  1949. /* Remove isofile entries. */
  1950. isofile_free_all_entries(iso9660);
  1951. isofile_free_hardlinks(iso9660);
  1952. archive_string_free(&(iso9660->cur_dirstr));
  1953. archive_string_free(&(iso9660->volume_identifier));
  1954. archive_string_free(&(iso9660->publisher_identifier));
  1955. archive_string_free(&(iso9660->data_preparer_identifier));
  1956. archive_string_free(&(iso9660->application_identifier));
  1957. archive_string_free(&(iso9660->copyright_file_identifier));
  1958. archive_string_free(&(iso9660->abstract_file_identifier));
  1959. archive_string_free(&(iso9660->bibliographic_file_identifier));
  1960. archive_string_free(&(iso9660->el_torito.catalog_filename));
  1961. archive_string_free(&(iso9660->el_torito.boot_filename));
  1962. archive_string_free(&(iso9660->el_torito.id));
  1963. archive_string_free(&(iso9660->utf16be));
  1964. archive_string_free(&(iso9660->mbs));
  1965. free(iso9660);
  1966. a->format_data = NULL;
  1967. return (ret);
  1968. }
  1969. /*
  1970. * Get the System Identifier
  1971. */
  1972. static void
  1973. get_system_identifier(char *system_id, size_t size)
  1974. {
  1975. #if defined(HAVE_SYS_UTSNAME_H)
  1976. struct utsname u;
  1977. uname(&u);
  1978. strncpy(system_id, u.sysname, size-1);
  1979. system_id[size-1] = '\0';
  1980. #elif defined(_WIN32) && !defined(__CYGWIN__)
  1981. strncpy(system_id, "Windows", size-1);
  1982. system_id[size-1] = '\0';
  1983. #else
  1984. strncpy(system_id, "Unknown", size-1);
  1985. system_id[size-1] = '\0';
  1986. #endif
  1987. }
  1988. static void
  1989. set_str(unsigned char *p, const char *s, size_t l, char f, const char *map)
  1990. {
  1991. unsigned char c;
  1992. if (s == NULL)
  1993. s = "";
  1994. while ((c = *s++) != 0 && l > 0) {
  1995. if (c >= 0x80 || map[c] == 0)
  1996. {
  1997. /* illegal character */
  1998. if (c >= 'a' && c <= 'z') {
  1999. /* convert c from a-z to A-Z */
  2000. c -= 0x20;
  2001. } else
  2002. c = 0x5f;
  2003. }
  2004. *p++ = c;
  2005. l--;
  2006. }
  2007. /* If l isn't zero, fill p buffer by the character
  2008. * which indicated by f. */
  2009. if (l > 0)
  2010. memset(p , f, l);
  2011. }
  2012. static inline int
  2013. joliet_allowed_char(unsigned char high, unsigned char low)
  2014. {
  2015. int utf16 = (high << 8) | low;
  2016. if (utf16 <= 0x001F)
  2017. return (0);
  2018. switch (utf16) {
  2019. case 0x002A: /* '*' */
  2020. case 0x002F: /* '/' */
  2021. case 0x003A: /* ':' */
  2022. case 0x003B: /* ';' */
  2023. case 0x003F: /* '?' */
  2024. case 0x005C: /* '\' */
  2025. return (0);/* Not allowed. */
  2026. }
  2027. return (1);
  2028. }
  2029. static int
  2030. set_str_utf16be(struct archive_write *a, unsigned char *p, const char *s,
  2031. size_t l, uint16_t uf, enum vdc vdc)
  2032. {
  2033. size_t size, i;
  2034. int onepad;
  2035. if (s == NULL)
  2036. s = "\0\0";
  2037. if (l & 0x01) {
  2038. onepad = 1;
  2039. l &= ~1;
  2040. } else
  2041. onepad = 0;
  2042. if (vdc == VDC_UCS2) {
  2043. struct iso9660 *iso9660 = a->format_data;
  2044. if (archive_strncpy_l(&iso9660->utf16be, s, strlen(s),
  2045. iso9660->sconv_to_utf16be) != 0 && errno == ENOMEM) {
  2046. archive_set_error(&a->archive, ENOMEM,
  2047. "Can't allocate memory for UTF-16BE");
  2048. return (ARCHIVE_FATAL);
  2049. }
  2050. size = iso9660->utf16be.length;
  2051. if (size > l)
  2052. size = l;
  2053. memcpy(p, iso9660->utf16be.s, size);
  2054. } else {
  2055. const uint16_t *u16 = (const uint16_t *)s;
  2056. size = 0;
  2057. while (*u16++)
  2058. size += 2;
  2059. if (size > l)
  2060. size = l;
  2061. memcpy(p, s, size);
  2062. }
  2063. for (i = 0; i < size; i += 2, p += 2) {
  2064. if (!joliet_allowed_char(p[0], p[1]))
  2065. archive_be16enc(p, 0x005F);/* '_' */
  2066. }
  2067. l -= size;
  2068. while (l > 0) {
  2069. archive_be16enc(p, uf);
  2070. p += 2;
  2071. l -= 2;
  2072. }
  2073. if (onepad)
  2074. *p = 0;
  2075. return (ARCHIVE_OK);
  2076. }
  2077. static const char a_characters_map[0x80] = {
  2078. /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
  2079. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 00-0F */
  2080. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 10-1F */
  2081. 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 20-2F */
  2082. 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 30-3F */
  2083. 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 40-4F */
  2084. 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,/* 50-5F */
  2085. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 60-6F */
  2086. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 70-7F */
  2087. };
  2088. static const char a1_characters_map[0x80] = {
  2089. /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
  2090. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 00-0F */
  2091. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 10-1F */
  2092. 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 20-2F */
  2093. 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 30-3F */
  2094. 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 40-4F */
  2095. 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,/* 50-5F */
  2096. 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 60-6F */
  2097. 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,/* 70-7F */
  2098. };
  2099. static const char d_characters_map[0x80] = {
  2100. /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
  2101. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 00-0F */
  2102. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 10-1F */
  2103. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 20-2F */
  2104. 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,/* 30-3F */
  2105. 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 40-4F */
  2106. 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,/* 50-5F */
  2107. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 60-6F */
  2108. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 70-7F */
  2109. };
  2110. static const char d1_characters_map[0x80] = {
  2111. /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
  2112. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 00-0F */
  2113. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 10-1F */
  2114. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 20-2F */
  2115. 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,/* 30-3F */
  2116. 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 40-4F */
  2117. 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,/* 50-5F */
  2118. 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,/* 60-6F */
  2119. 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,/* 70-7F */
  2120. };
  2121. static int
  2122. set_str_a_characters_bp(struct archive_write *a, unsigned char *bp,
  2123. int from, int to, const char *s, enum vdc vdc)
  2124. {
  2125. int r;
  2126. switch (vdc) {
  2127. case VDC_STD:
  2128. set_str(bp+from, s, to - from + 1, 0x20,
  2129. a_characters_map);
  2130. r = ARCHIVE_OK;
  2131. break;
  2132. case VDC_LOWERCASE:
  2133. set_str(bp+from, s, to - from + 1, 0x20,
  2134. a1_characters_map);
  2135. r = ARCHIVE_OK;
  2136. break;
  2137. case VDC_UCS2:
  2138. case VDC_UCS2_DIRECT:
  2139. r = set_str_utf16be(a, bp+from, s, to - from + 1,
  2140. 0x0020, vdc);
  2141. break;
  2142. default:
  2143. r = ARCHIVE_FATAL;
  2144. }
  2145. return (r);
  2146. }
  2147. static int
  2148. set_str_d_characters_bp(struct archive_write *a, unsigned char *bp,
  2149. int from, int to, const char *s, enum vdc vdc)
  2150. {
  2151. int r;
  2152. switch (vdc) {
  2153. case VDC_STD:
  2154. set_str(bp+from, s, to - from + 1, 0x20,
  2155. d_characters_map);
  2156. r = ARCHIVE_OK;
  2157. break;
  2158. case VDC_LOWERCASE:
  2159. set_str(bp+from, s, to - from + 1, 0x20,
  2160. d1_characters_map);
  2161. r = ARCHIVE_OK;
  2162. break;
  2163. case VDC_UCS2:
  2164. case VDC_UCS2_DIRECT:
  2165. r = set_str_utf16be(a, bp+from, s, to - from + 1,
  2166. 0x0020, vdc);
  2167. break;
  2168. default:
  2169. r = ARCHIVE_FATAL;
  2170. }
  2171. return (r);
  2172. }
  2173. static void
  2174. set_VD_bp(unsigned char *bp, enum VD_type type, unsigned char ver)
  2175. {
  2176. /* Volume Descriptor Type */
  2177. bp[1] = (unsigned char)type;
  2178. /* Standard Identifier */
  2179. memcpy(bp + 2, "CD001", 5);
  2180. /* Volume Descriptor Version */
  2181. bp[7] = ver;
  2182. }
  2183. static inline void
  2184. set_unused_field_bp(unsigned char *bp, int from, int to)
  2185. {
  2186. memset(bp + from, 0, to - from + 1);
  2187. }
  2188. /*
  2189. * 8-bit unsigned numerical values.
  2190. * ISO9660 Standard 7.1.1
  2191. */
  2192. static inline void
  2193. set_num_711(unsigned char *p, unsigned char value)
  2194. {
  2195. *p = value;
  2196. }
  2197. /*
  2198. * 8-bit signed numerical values.
  2199. * ISO9660 Standard 7.1.2
  2200. */
  2201. static inline void
  2202. set_num_712(unsigned char *p, char value)
  2203. {
  2204. *((char *)p) = value;
  2205. }
  2206. /*
  2207. * Least significant byte first.
  2208. * ISO9660 Standard 7.2.1
  2209. */
  2210. static inline void
  2211. set_num_721(unsigned char *p, uint16_t value)
  2212. {
  2213. archive_le16enc(p, value);
  2214. }
  2215. /*
  2216. * Most significant byte first.
  2217. * ISO9660 Standard 7.2.2
  2218. */
  2219. static inline void
  2220. set_num_722(unsigned char *p, uint16_t value)
  2221. {
  2222. archive_be16enc(p, value);
  2223. }
  2224. /*
  2225. * Both-byte orders.
  2226. * ISO9660 Standard 7.2.3
  2227. */
  2228. static void
  2229. set_num_723(unsigned char *p, uint16_t value)
  2230. {
  2231. archive_le16enc(p, value);
  2232. archive_be16enc(p+2, value);
  2233. }
  2234. /*
  2235. * Least significant byte first.
  2236. * ISO9660 Standard 7.3.1
  2237. */
  2238. static inline void
  2239. set_num_731(unsigned char *p, uint32_t value)
  2240. {
  2241. archive_le32enc(p, value);
  2242. }
  2243. /*
  2244. * Most significant byte first.
  2245. * ISO9660 Standard 7.3.2
  2246. */
  2247. static inline void
  2248. set_num_732(unsigned char *p, uint32_t value)
  2249. {
  2250. archive_be32enc(p, value);
  2251. }
  2252. /*
  2253. * Both-byte orders.
  2254. * ISO9660 Standard 7.3.3
  2255. */
  2256. static inline void
  2257. set_num_733(unsigned char *p, uint32_t value)
  2258. {
  2259. archive_le32enc(p, value);
  2260. archive_be32enc(p+4, value);
  2261. }
  2262. static void
  2263. set_digit(unsigned char *p, size_t s, int value)
  2264. {
  2265. while (s--) {
  2266. p[s] = '0' + (value % 10);
  2267. value /= 10;
  2268. }
  2269. }
  2270. #if defined(HAVE_STRUCT_TM_TM_GMTOFF)
  2271. #define get_gmoffset(tm) ((tm)->tm_gmtoff)
  2272. #elif defined(HAVE_STRUCT_TM___TM_GMTOFF)
  2273. #define get_gmoffset(tm) ((tm)->__tm_gmtoff)
  2274. #else
  2275. static long
  2276. get_gmoffset(struct tm *tm)
  2277. {
  2278. long offset;
  2279. #if defined(HAVE__GET_TIMEZONE)
  2280. _get_timezone(&offset);
  2281. #elif defined(__CYGWIN__) || defined(__MINGW32__) || defined(__BORLANDC__)
  2282. offset = _timezone;
  2283. #else
  2284. offset = timezone;
  2285. #endif
  2286. offset *= -1;
  2287. if (tm->tm_isdst)
  2288. offset += 3600;
  2289. return (offset);
  2290. }
  2291. #endif
  2292. static void
  2293. get_tmfromtime(struct tm *tm, time_t *t)
  2294. {
  2295. #if HAVE_LOCALTIME_S
  2296. localtime_s(tm, t);
  2297. #elif HAVE_LOCALTIME_R
  2298. tzset();
  2299. localtime_r(t, tm);
  2300. #else
  2301. memcpy(tm, localtime(t), sizeof(*tm));
  2302. #endif
  2303. }
  2304. /*
  2305. * Date and Time Format.
  2306. * ISO9660 Standard 8.4.26.1
  2307. */
  2308. static void
  2309. set_date_time(unsigned char *p, time_t t)
  2310. {
  2311. struct tm tm;
  2312. get_tmfromtime(&tm, &t);
  2313. set_digit(p, 4, tm.tm_year + 1900);
  2314. set_digit(p+4, 2, tm.tm_mon + 1);
  2315. set_digit(p+6, 2, tm.tm_mday);
  2316. set_digit(p+8, 2, tm.tm_hour);
  2317. set_digit(p+10, 2, tm.tm_min);
  2318. set_digit(p+12, 2, tm.tm_sec);
  2319. set_digit(p+14, 2, 0);
  2320. set_num_712(p+16, (char)(get_gmoffset(&tm)/(60*15)));
  2321. }
  2322. static void
  2323. set_date_time_null(unsigned char *p)
  2324. {
  2325. memset(p, (int)'0', 16);
  2326. p[16] = 0;
  2327. }
  2328. static void
  2329. set_time_915(unsigned char *p, time_t t)
  2330. {
  2331. struct tm tm;
  2332. get_tmfromtime(&tm, &t);
  2333. set_num_711(p+0, tm.tm_year);
  2334. set_num_711(p+1, tm.tm_mon+1);
  2335. set_num_711(p+2, tm.tm_mday);
  2336. set_num_711(p+3, tm.tm_hour);
  2337. set_num_711(p+4, tm.tm_min);
  2338. set_num_711(p+5, tm.tm_sec);
  2339. set_num_712(p+6, (char)(get_gmoffset(&tm)/(60*15)));
  2340. }
  2341. /*
  2342. * Write SUSP "CE" System Use Entry.
  2343. */
  2344. static int
  2345. set_SUSP_CE(unsigned char *p, int location, int offset, int size)
  2346. {
  2347. unsigned char *bp = p -1;
  2348. /* Extend the System Use Area
  2349. * "CE" Format:
  2350. * len ver
  2351. * +----+----+----+----+-----------+-----------+
  2352. * | 'C'| 'E'| 1C | 01 | LOCATION1 | LOCATION2 |
  2353. * +----+----+----+----+-----------+-----------+
  2354. * 0 1 2 3 4 12 20
  2355. * +-----------+
  2356. * | LOCATION3 |
  2357. * +-----------+
  2358. * 20 28
  2359. * LOCATION1 : Location of Continuation of System Use Area.
  2360. * LOCATION2 : Offset to Start of Continuation.
  2361. * LOCATION3 : Length of the Continuation.
  2362. */
  2363. bp[1] = 'C';
  2364. bp[2] = 'E';
  2365. bp[3] = RR_CE_SIZE; /* length */
  2366. bp[4] = 1; /* version */
  2367. set_num_733(bp+5, location);
  2368. set_num_733(bp+13, offset);
  2369. set_num_733(bp+21, size);
  2370. return (RR_CE_SIZE);
  2371. }
  2372. /*
  2373. * The functions, which names are beginning with extra_, are used to
  2374. * control extra records.
  2375. * The maximum size of a Directory Record is 254. When a filename is
  2376. * very long, all of RRIP data of a file won't stored to the Directory
  2377. * Record and so remaining RRIP data store to an extra record instead.
  2378. */
  2379. static unsigned char *
  2380. extra_open_record(unsigned char *bp, int dr_len, struct isoent *isoent,
  2381. struct ctl_extr_rec *ctl)
  2382. {
  2383. ctl->bp = bp;
  2384. if (bp != NULL)
  2385. bp += dr_len;
  2386. ctl->use_extr = 0;
  2387. ctl->isoent = isoent;
  2388. ctl->ce_ptr = NULL;
  2389. ctl->cur_len = ctl->dr_len = dr_len;
  2390. ctl->limit = DR_LIMIT;
  2391. return (bp);
  2392. }
  2393. static void
  2394. extra_close_record(struct ctl_extr_rec *ctl, int ce_size)
  2395. {
  2396. int padding = 0;
  2397. if (ce_size > 0)
  2398. extra_tell_used_size(ctl, ce_size);
  2399. /* Padding. */
  2400. if (ctl->cur_len & 0x01) {
  2401. ctl->cur_len++;
  2402. if (ctl->bp != NULL)
  2403. ctl->bp[ctl->cur_len] = 0;
  2404. padding = 1;
  2405. }
  2406. if (ctl->use_extr) {
  2407. if (ctl->ce_ptr != NULL)
  2408. set_SUSP_CE(ctl->ce_ptr, ctl->extr_loc,
  2409. ctl->extr_off, ctl->cur_len - padding);
  2410. } else
  2411. ctl->dr_len = ctl->cur_len;
  2412. }
  2413. #define extra_space(ctl) ((ctl)->limit - (ctl)->cur_len)
  2414. static unsigned char *
  2415. extra_next_record(struct ctl_extr_rec *ctl, int length)
  2416. {
  2417. int cur_len = ctl->cur_len;/* save cur_len */
  2418. /* Close the current extra record or Directory Record. */
  2419. extra_close_record(ctl, RR_CE_SIZE);
  2420. /* Get a next extra record. */
  2421. ctl->use_extr = 1;
  2422. if (ctl->bp != NULL) {
  2423. /* Storing data into an extra record. */
  2424. unsigned char *p;
  2425. /* Save the pointer where a CE extension will be
  2426. * stored to. */
  2427. ctl->ce_ptr = &ctl->bp[cur_len+1];
  2428. p = extra_get_record(ctl->isoent,
  2429. &ctl->limit, &ctl->extr_off, &ctl->extr_loc);
  2430. ctl->bp = p - 1;/* the base of bp offset is 1. */
  2431. } else
  2432. /* Calculating the size of an extra record. */
  2433. (void)extra_get_record(ctl->isoent,
  2434. &ctl->limit, NULL, NULL);
  2435. ctl->cur_len = 0;
  2436. /* Check if an extra record is almost full.
  2437. * If so, get a next one. */
  2438. if (extra_space(ctl) < length)
  2439. (void)extra_next_record(ctl, length);
  2440. return (ctl->bp);
  2441. }
  2442. static inline struct extr_rec *
  2443. extra_last_record(struct isoent *isoent)
  2444. {
  2445. if (isoent->extr_rec_list.first == NULL)
  2446. return (NULL);
  2447. return ((struct extr_rec *)(void *)
  2448. ((char *)(isoent->extr_rec_list.last)
  2449. - offsetof(struct extr_rec, next)));
  2450. }
  2451. static unsigned char *
  2452. extra_get_record(struct isoent *isoent, int *space, int *off, int *loc)
  2453. {
  2454. struct extr_rec *rec;
  2455. isoent = isoent->parent;
  2456. if (off != NULL) {
  2457. /* Storing data into an extra record. */
  2458. rec = isoent->extr_rec_list.current;
  2459. if (DR_SAFETY > LOGICAL_BLOCK_SIZE - rec->offset)
  2460. rec = rec->next;
  2461. } else {
  2462. /* Calculating the size of an extra record. */
  2463. rec = extra_last_record(isoent);
  2464. if (rec == NULL ||
  2465. DR_SAFETY > LOGICAL_BLOCK_SIZE - rec->offset) {
  2466. rec = malloc(sizeof(*rec));
  2467. if (rec == NULL)
  2468. return (NULL);
  2469. rec->location = 0;
  2470. rec->offset = 0;
  2471. /* Insert `rec` into the tail of isoent->extr_rec_list */
  2472. rec->next = NULL;
  2473. /*
  2474. * Note: testing isoent->extr_rec_list.last == NULL
  2475. * here is really unneeded since it has been already
  2476. * initialized at isoent_new function but Clang Static
  2477. * Analyzer claims that it is dereference of null
  2478. * pointer.
  2479. */
  2480. if (isoent->extr_rec_list.last == NULL)
  2481. isoent->extr_rec_list.last =
  2482. &(isoent->extr_rec_list.first);
  2483. *isoent->extr_rec_list.last = rec;
  2484. isoent->extr_rec_list.last = &(rec->next);
  2485. }
  2486. }
  2487. *space = LOGICAL_BLOCK_SIZE - rec->offset - DR_SAFETY;
  2488. if (*space & 0x01)
  2489. *space -= 1;/* Keep padding space. */
  2490. if (off != NULL)
  2491. *off = rec->offset;
  2492. if (loc != NULL)
  2493. *loc = rec->location;
  2494. isoent->extr_rec_list.current = rec;
  2495. return (&rec->buf[rec->offset]);
  2496. }
  2497. static void
  2498. extra_tell_used_size(struct ctl_extr_rec *ctl, int size)
  2499. {
  2500. struct isoent *isoent;
  2501. struct extr_rec *rec;
  2502. if (ctl->use_extr) {
  2503. isoent = ctl->isoent->parent;
  2504. rec = isoent->extr_rec_list.current;
  2505. if (rec != NULL)
  2506. rec->offset += size;
  2507. }
  2508. ctl->cur_len += size;
  2509. }
  2510. static int
  2511. extra_setup_location(struct isoent *isoent, int location)
  2512. {
  2513. struct extr_rec *rec;
  2514. int cnt;
  2515. cnt = 0;
  2516. rec = isoent->extr_rec_list.first;
  2517. isoent->extr_rec_list.current = rec;
  2518. while (rec) {
  2519. cnt++;
  2520. rec->location = location++;
  2521. rec->offset = 0;
  2522. rec = rec->next;
  2523. }
  2524. return (cnt);
  2525. }
  2526. /*
  2527. * Create the RRIP entries.
  2528. */
  2529. static int
  2530. set_directory_record_rr(unsigned char *bp, int dr_len,
  2531. struct isoent *isoent, struct iso9660 *iso9660, enum dir_rec_type t)
  2532. {
  2533. /* Flags(BP 5) of the Rockridge "RR" System Use Field */
  2534. unsigned char rr_flag;
  2535. #define RR_USE_PX 0x01
  2536. #define RR_USE_PN 0x02
  2537. #define RR_USE_SL 0x04
  2538. #define RR_USE_NM 0x08
  2539. #define RR_USE_CL 0x10
  2540. #define RR_USE_PL 0x20
  2541. #define RR_USE_RE 0x40
  2542. #define RR_USE_TF 0x80
  2543. int length;
  2544. struct ctl_extr_rec ctl;
  2545. struct isoent *rr_parent, *pxent;
  2546. struct isofile *file;
  2547. bp = extra_open_record(bp, dr_len, isoent, &ctl);
  2548. if (t == DIR_REC_PARENT) {
  2549. rr_parent = isoent->rr_parent;
  2550. pxent = isoent->parent;
  2551. if (rr_parent != NULL)
  2552. isoent = rr_parent;
  2553. else
  2554. isoent = isoent->parent;
  2555. } else {
  2556. rr_parent = NULL;
  2557. pxent = isoent;
  2558. }
  2559. file = isoent->file;
  2560. if (t != DIR_REC_NORMAL) {
  2561. rr_flag = RR_USE_PX | RR_USE_TF;
  2562. if (rr_parent != NULL)
  2563. rr_flag |= RR_USE_PL;
  2564. } else {
  2565. rr_flag = RR_USE_PX | RR_USE_NM | RR_USE_TF;
  2566. if (archive_entry_filetype(file->entry) == AE_IFLNK)
  2567. rr_flag |= RR_USE_SL;
  2568. if (isoent->rr_parent != NULL)
  2569. rr_flag |= RR_USE_RE;
  2570. if (isoent->rr_child != NULL)
  2571. rr_flag |= RR_USE_CL;
  2572. if (archive_entry_filetype(file->entry) == AE_IFCHR ||
  2573. archive_entry_filetype(file->entry) == AE_IFBLK)
  2574. rr_flag |= RR_USE_PN;
  2575. #ifdef COMPAT_MKISOFS
  2576. /*
  2577. * mkisofs 2.01.01a63 records "RE" extension to
  2578. * the entry of "rr_moved" directory.
  2579. * I don't understand this behavior.
  2580. */
  2581. if (isoent->virtual &&
  2582. isoent->parent == iso9660->primary.rootent &&
  2583. strcmp(isoent->file->basename.s, "rr_moved") == 0)
  2584. rr_flag |= RR_USE_RE;
  2585. #endif
  2586. }
  2587. /* Write "SP" System Use Entry. */
  2588. if (t == DIR_REC_SELF && isoent == isoent->parent) {
  2589. length = 7;
  2590. if (bp != NULL) {
  2591. bp[1] = 'S';
  2592. bp[2] = 'P';
  2593. bp[3] = length;
  2594. bp[4] = 1; /* version */
  2595. bp[5] = 0xBE; /* Check Byte */
  2596. bp[6] = 0xEF; /* Check Byte */
  2597. bp[7] = 0;
  2598. bp += length;
  2599. }
  2600. extra_tell_used_size(&ctl, length);
  2601. }
  2602. /* Write "RR" System Use Entry. */
  2603. length = 5;
  2604. if (extra_space(&ctl) < length)
  2605. bp = extra_next_record(&ctl, length);
  2606. if (bp != NULL) {
  2607. bp[1] = 'R';
  2608. bp[2] = 'R';
  2609. bp[3] = length;
  2610. bp[4] = 1; /* version */
  2611. bp[5] = rr_flag;
  2612. bp += length;
  2613. }
  2614. extra_tell_used_size(&ctl, length);
  2615. /* Write "NM" System Use Entry. */
  2616. if (rr_flag & RR_USE_NM) {
  2617. /*
  2618. * "NM" Format:
  2619. * e.g. a basename is 'foo'
  2620. * len ver flg
  2621. * +----+----+----+----+----+----+----+----+
  2622. * | 'N'| 'M'| 08 | 01 | 00 | 'f'| 'o'| 'o'|
  2623. * +----+----+----+----+----+----+----+----+
  2624. * <----------------- len ----------------->
  2625. */
  2626. size_t nmlen = file->basename.length;
  2627. const char *nm = file->basename.s;
  2628. size_t nmmax;
  2629. if (extra_space(&ctl) < 6)
  2630. bp = extra_next_record(&ctl, 6);
  2631. if (bp != NULL) {
  2632. bp[1] = 'N';
  2633. bp[2] = 'M';
  2634. bp[4] = 1; /* version */
  2635. }
  2636. nmmax = extra_space(&ctl);
  2637. if (nmmax > 0xff)
  2638. nmmax = 0xff;
  2639. while (nmlen + 5 > nmmax) {
  2640. length = (int)nmmax;
  2641. if (bp != NULL) {
  2642. bp[3] = length;
  2643. bp[5] = 0x01;/* Alternate Name continues
  2644. * in next "NM" field */
  2645. memcpy(bp+6, nm, length - 5);
  2646. bp += length;
  2647. }
  2648. nmlen -= length - 5;
  2649. nm += length - 5;
  2650. extra_tell_used_size(&ctl, length);
  2651. if (extra_space(&ctl) < 6) {
  2652. bp = extra_next_record(&ctl, 6);
  2653. nmmax = extra_space(&ctl);
  2654. if (nmmax > 0xff)
  2655. nmmax = 0xff;
  2656. }
  2657. if (bp != NULL) {
  2658. bp[1] = 'N';
  2659. bp[2] = 'M';
  2660. bp[4] = 1; /* version */
  2661. }
  2662. }
  2663. length = 5 + (int)nmlen;
  2664. if (bp != NULL) {
  2665. bp[3] = length;
  2666. bp[5] = 0;
  2667. memcpy(bp+6, nm, nmlen);
  2668. bp += length;
  2669. }
  2670. extra_tell_used_size(&ctl, length);
  2671. }
  2672. /* Write "PX" System Use Entry. */
  2673. if (rr_flag & RR_USE_PX) {
  2674. /*
  2675. * "PX" Format:
  2676. * len ver
  2677. * +----+----+----+----+-----------+-----------+
  2678. * | 'P'| 'X'| 2C | 01 | FILE MODE | LINKS |
  2679. * +----+----+----+----+-----------+-----------+
  2680. * 0 1 2 3 4 12 20
  2681. * +-----------+-----------+------------------+
  2682. * | USER ID | GROUP ID |FILE SERIAL NUMBER|
  2683. * +-----------+-----------+------------------+
  2684. * 20 28 36 44
  2685. */
  2686. length = 44;
  2687. if (extra_space(&ctl) < length)
  2688. bp = extra_next_record(&ctl, length);
  2689. if (bp != NULL) {
  2690. mode_t mode;
  2691. int64_t uid;
  2692. int64_t gid;
  2693. mode = archive_entry_mode(file->entry);
  2694. uid = archive_entry_uid(file->entry);
  2695. gid = archive_entry_gid(file->entry);
  2696. if (iso9660->opt.rr == OPT_RR_USEFUL) {
  2697. /*
  2698. * This action is similar to mkisofs -r option
  2699. * but our rockridge=useful option does not
  2700. * set a zero to uid and gid.
  2701. */
  2702. /* set all read bit ON */
  2703. mode |= 0444;
  2704. #if !defined(_WIN32) && !defined(__CYGWIN__)
  2705. if (mode & 0111)
  2706. #endif
  2707. /* set all exec bit ON */
  2708. mode |= 0111;
  2709. /* clear all write bits. */
  2710. mode &= ~0222;
  2711. /* clear setuid,setgid,sticky bits. */
  2712. mode &= ~07000;
  2713. }
  2714. bp[1] = 'P';
  2715. bp[2] = 'X';
  2716. bp[3] = length;
  2717. bp[4] = 1; /* version */
  2718. /* file mode */
  2719. set_num_733(bp+5, mode);
  2720. /* file links (stat.st_nlink) */
  2721. set_num_733(bp+13,
  2722. archive_entry_nlink(file->entry));
  2723. set_num_733(bp+21, (uint32_t)uid);
  2724. set_num_733(bp+29, (uint32_t)gid);
  2725. /* File Serial Number */
  2726. if (pxent->dir)
  2727. set_num_733(bp+37, pxent->dir_location);
  2728. else if (file->hardlink_target != NULL)
  2729. set_num_733(bp+37,
  2730. file->hardlink_target->cur_content->location);
  2731. else
  2732. set_num_733(bp+37,
  2733. file->cur_content->location);
  2734. bp += length;
  2735. }
  2736. extra_tell_used_size(&ctl, length);
  2737. }
  2738. /* Write "SL" System Use Entry. */
  2739. if (rr_flag & RR_USE_SL) {
  2740. /*
  2741. * "SL" Format:
  2742. * e.g. a symbolic name is 'foo/bar'
  2743. * len ver flg
  2744. * +----+----+----+----+----+------------+
  2745. * | 'S'| 'L'| 0F | 01 | 00 | components |
  2746. * +----+----+----+----+----+-----+------+
  2747. * 0 1 2 3 4 5 ...|... 15
  2748. * <----------------- len --------+------>
  2749. * components : |
  2750. * cflg clen |
  2751. * +----+----+----+----+----+ |
  2752. * | 00 | 03 | 'f'| 'o'| 'o'| <---+
  2753. * +----+----+----+----+----+ |
  2754. * 5 6 7 8 9 10 |
  2755. * cflg clen |
  2756. * +----+----+----+----+----+ |
  2757. * | 00 | 03 | 'b'| 'a'| 'r'| <---+
  2758. * +----+----+----+----+----+
  2759. * 10 11 12 13 14 15
  2760. *
  2761. * - cflg : flag of component
  2762. * - clen : length of component
  2763. */
  2764. const char *sl;
  2765. char sl_last;
  2766. if (extra_space(&ctl) < 7)
  2767. bp = extra_next_record(&ctl, 7);
  2768. sl = file->symlink.s;
  2769. sl_last = '\0';
  2770. if (bp != NULL) {
  2771. bp[1] = 'S';
  2772. bp[2] = 'L';
  2773. bp[4] = 1; /* version */
  2774. }
  2775. for (;;) {
  2776. unsigned char *nc, *cf, *cl, cldmy = 0;
  2777. int sllen, slmax;
  2778. slmax = extra_space(&ctl);
  2779. if (slmax > 0xff)
  2780. slmax = 0xff;
  2781. if (bp != NULL)
  2782. nc = &bp[6];
  2783. else
  2784. nc = NULL;
  2785. cf = cl = NULL;
  2786. sllen = 0;
  2787. while (*sl && sllen + 11 < slmax) {
  2788. if (sl_last == '\0' && sl[0] == '/') {
  2789. /*
  2790. * flg len
  2791. * +----+----+
  2792. * | 08 | 00 | ROOT component.
  2793. * +----+----+ ("/")
  2794. *
  2795. * Root component has to appear
  2796. * at the first component only.
  2797. */
  2798. if (nc != NULL) {
  2799. cf = nc++;
  2800. *cf = 0x08; /* ROOT */
  2801. *nc++ = 0;
  2802. }
  2803. sllen += 2;
  2804. sl++;
  2805. sl_last = '/';
  2806. cl = NULL;
  2807. continue;
  2808. }
  2809. if (((sl_last == '\0' || sl_last == '/') &&
  2810. sl[0] == '.' && sl[1] == '.' &&
  2811. (sl[2] == '/' || sl[2] == '\0')) ||
  2812. (sl[0] == '/' &&
  2813. sl[1] == '.' && sl[2] == '.' &&
  2814. (sl[3] == '/' || sl[3] == '\0'))) {
  2815. /*
  2816. * flg len
  2817. * +----+----+
  2818. * | 04 | 00 | PARENT component.
  2819. * +----+----+ ("..")
  2820. */
  2821. if (nc != NULL) {
  2822. cf = nc++;
  2823. *cf = 0x04; /* PARENT */
  2824. *nc++ = 0;
  2825. }
  2826. sllen += 2;
  2827. if (sl[0] == '/')
  2828. sl += 3;/* skip "/.." */
  2829. else
  2830. sl += 2;/* skip ".." */
  2831. sl_last = '.';
  2832. cl = NULL;
  2833. continue;
  2834. }
  2835. if (((sl_last == '\0' || sl_last == '/') &&
  2836. sl[0] == '.' &&
  2837. (sl[1] == '/' || sl[1] == '\0')) ||
  2838. (sl[0] == '/' && sl[1] == '.' &&
  2839. (sl[2] == '/' || sl[2] == '\0'))) {
  2840. /*
  2841. * flg len
  2842. * +----+----+
  2843. * | 02 | 00 | CURRENT component.
  2844. * +----+----+ (".")
  2845. */
  2846. if (nc != NULL) {
  2847. cf = nc++;
  2848. *cf = 0x02; /* CURRENT */
  2849. *nc++ = 0;
  2850. }
  2851. sllen += 2;
  2852. if (sl[0] == '/')
  2853. sl += 2;/* skip "/." */
  2854. else
  2855. sl ++; /* skip "." */
  2856. sl_last = '.';
  2857. cl = NULL;
  2858. continue;
  2859. }
  2860. if (sl[0] == '/' || cl == NULL) {
  2861. if (nc != NULL) {
  2862. cf = nc++;
  2863. *cf = 0;
  2864. cl = nc++;
  2865. *cl = 0;
  2866. } else
  2867. cl = &cldmy;
  2868. sllen += 2;
  2869. if (sl[0] == '/') {
  2870. sl_last = *sl++;
  2871. continue;
  2872. }
  2873. }
  2874. sl_last = *sl++;
  2875. if (nc != NULL) {
  2876. *nc++ = sl_last;
  2877. (*cl) ++;
  2878. }
  2879. sllen++;
  2880. }
  2881. if (*sl) {
  2882. length = 5 + sllen;
  2883. if (bp != NULL) {
  2884. /*
  2885. * Mark flg as CONTINUE component.
  2886. */
  2887. *cf |= 0x01;
  2888. /*
  2889. * len ver flg
  2890. * +----+----+----+----+----+-
  2891. * | 'S'| 'L'| XX | 01 | 01 |
  2892. * +----+----+----+----+----+-
  2893. * ^
  2894. * continues in next "SL"
  2895. */
  2896. bp[3] = length;
  2897. bp[5] = 0x01;/* This Symbolic Link
  2898. * continues in next
  2899. * "SL" field */
  2900. bp += length;
  2901. }
  2902. extra_tell_used_size(&ctl, length);
  2903. if (extra_space(&ctl) < 11)
  2904. bp = extra_next_record(&ctl, 11);
  2905. if (bp != NULL) {
  2906. /* Next 'SL' */
  2907. bp[1] = 'S';
  2908. bp[2] = 'L';
  2909. bp[4] = 1; /* version */
  2910. }
  2911. } else {
  2912. length = 5 + sllen;
  2913. if (bp != NULL) {
  2914. bp[3] = length;
  2915. bp[5] = 0;
  2916. bp += length;
  2917. }
  2918. extra_tell_used_size(&ctl, length);
  2919. break;
  2920. }
  2921. }
  2922. }
  2923. /* Write "TF" System Use Entry. */
  2924. if (rr_flag & RR_USE_TF) {
  2925. /*
  2926. * "TF" Format:
  2927. * len ver
  2928. * +----+----+----+----+-----+-------------+
  2929. * | 'T'| 'F'| XX | 01 |FLAGS| TIME STAMPS |
  2930. * +----+----+----+----+-----+-------------+
  2931. * 0 1 2 3 4 5 XX
  2932. * TIME STAMPS : ISO 9660 Standard 9.1.5.
  2933. * If TF_LONG_FORM FLAGS is set,
  2934. * use ISO9660 Standard 8.4.26.1.
  2935. */
  2936. #define TF_CREATION 0x01 /* Creation time recorded */
  2937. #define TF_MODIFY 0x02 /* Modification time recorded */
  2938. #define TF_ACCESS 0x04 /* Last Access time recorded */
  2939. #define TF_ATTRIBUTES 0x08 /* Last Attribute Change time recorded */
  2940. #define TF_BACKUP 0x10 /* Last Backup time recorded */
  2941. #define TF_EXPIRATION 0x20 /* Expiration time recorded */
  2942. #define TF_EFFECTIVE 0x40 /* Effective time recorded */
  2943. #define TF_LONG_FORM 0x80 /* ISO 9660 17-byte time format used */
  2944. unsigned char tf_flags;
  2945. length = 5;
  2946. tf_flags = 0;
  2947. #ifndef COMPAT_MKISOFS
  2948. if (archive_entry_birthtime_is_set(file->entry) &&
  2949. archive_entry_birthtime(file->entry) <=
  2950. archive_entry_mtime(file->entry)) {
  2951. length += 7;
  2952. tf_flags |= TF_CREATION;
  2953. }
  2954. #endif
  2955. if (archive_entry_mtime_is_set(file->entry)) {
  2956. length += 7;
  2957. tf_flags |= TF_MODIFY;
  2958. }
  2959. if (archive_entry_atime_is_set(file->entry)) {
  2960. length += 7;
  2961. tf_flags |= TF_ACCESS;
  2962. }
  2963. if (archive_entry_ctime_is_set(file->entry)) {
  2964. length += 7;
  2965. tf_flags |= TF_ATTRIBUTES;
  2966. }
  2967. if (extra_space(&ctl) < length)
  2968. bp = extra_next_record(&ctl, length);
  2969. if (bp != NULL) {
  2970. bp[1] = 'T';
  2971. bp[2] = 'F';
  2972. bp[3] = length;
  2973. bp[4] = 1; /* version */
  2974. bp[5] = tf_flags;
  2975. bp += 5;
  2976. /* Creation time */
  2977. if (tf_flags & TF_CREATION) {
  2978. set_time_915(bp+1,
  2979. archive_entry_birthtime(file->entry));
  2980. bp += 7;
  2981. }
  2982. /* Modification time */
  2983. if (tf_flags & TF_MODIFY) {
  2984. set_time_915(bp+1,
  2985. archive_entry_mtime(file->entry));
  2986. bp += 7;
  2987. }
  2988. /* Last Access time */
  2989. if (tf_flags & TF_ACCESS) {
  2990. set_time_915(bp+1,
  2991. archive_entry_atime(file->entry));
  2992. bp += 7;
  2993. }
  2994. /* Last Attribute Change time */
  2995. if (tf_flags & TF_ATTRIBUTES) {
  2996. set_time_915(bp+1,
  2997. archive_entry_ctime(file->entry));
  2998. bp += 7;
  2999. }
  3000. }
  3001. extra_tell_used_size(&ctl, length);
  3002. }
  3003. /* Write "RE" System Use Entry. */
  3004. if (rr_flag & RR_USE_RE) {
  3005. /*
  3006. * "RE" Format:
  3007. * len ver
  3008. * +----+----+----+----+
  3009. * | 'R'| 'E'| 04 | 01 |
  3010. * +----+----+----+----+
  3011. * 0 1 2 3 4
  3012. */
  3013. length = 4;
  3014. if (extra_space(&ctl) < length)
  3015. bp = extra_next_record(&ctl, length);
  3016. if (bp != NULL) {
  3017. bp[1] = 'R';
  3018. bp[2] = 'E';
  3019. bp[3] = length;
  3020. bp[4] = 1; /* version */
  3021. bp += length;
  3022. }
  3023. extra_tell_used_size(&ctl, length);
  3024. }
  3025. /* Write "PL" System Use Entry. */
  3026. if (rr_flag & RR_USE_PL) {
  3027. /*
  3028. * "PL" Format:
  3029. * len ver
  3030. * +----+----+----+----+------------+
  3031. * | 'P'| 'L'| 0C | 01 | *LOCATION |
  3032. * +----+----+----+----+------------+
  3033. * 0 1 2 3 4 12
  3034. * *LOCATION: location of parent directory
  3035. */
  3036. length = 12;
  3037. if (extra_space(&ctl) < length)
  3038. bp = extra_next_record(&ctl, length);
  3039. if (bp != NULL) {
  3040. bp[1] = 'P';
  3041. bp[2] = 'L';
  3042. bp[3] = length;
  3043. bp[4] = 1; /* version */
  3044. set_num_733(bp + 5,
  3045. rr_parent->dir_location);
  3046. bp += length;
  3047. }
  3048. extra_tell_used_size(&ctl, length);
  3049. }
  3050. /* Write "CL" System Use Entry. */
  3051. if (rr_flag & RR_USE_CL) {
  3052. /*
  3053. * "CL" Format:
  3054. * len ver
  3055. * +----+----+----+----+------------+
  3056. * | 'C'| 'L'| 0C | 01 | *LOCATION |
  3057. * +----+----+----+----+------------+
  3058. * 0 1 2 3 4 12
  3059. * *LOCATION: location of child directory
  3060. */
  3061. length = 12;
  3062. if (extra_space(&ctl) < length)
  3063. bp = extra_next_record(&ctl, length);
  3064. if (bp != NULL) {
  3065. bp[1] = 'C';
  3066. bp[2] = 'L';
  3067. bp[3] = length;
  3068. bp[4] = 1; /* version */
  3069. set_num_733(bp + 5,
  3070. isoent->rr_child->dir_location);
  3071. bp += length;
  3072. }
  3073. extra_tell_used_size(&ctl, length);
  3074. }
  3075. /* Write "PN" System Use Entry. */
  3076. if (rr_flag & RR_USE_PN) {
  3077. /*
  3078. * "PN" Format:
  3079. * len ver
  3080. * +----+----+----+----+------------+------------+
  3081. * | 'P'| 'N'| 14 | 01 | dev_t high | dev_t low |
  3082. * +----+----+----+----+------------+------------+
  3083. * 0 1 2 3 4 12 20
  3084. */
  3085. length = 20;
  3086. if (extra_space(&ctl) < length)
  3087. bp = extra_next_record(&ctl, length);
  3088. if (bp != NULL) {
  3089. uint64_t dev;
  3090. bp[1] = 'P';
  3091. bp[2] = 'N';
  3092. bp[3] = length;
  3093. bp[4] = 1; /* version */
  3094. dev = (uint64_t)archive_entry_rdev(file->entry);
  3095. set_num_733(bp + 5, (uint32_t)(dev >> 32));
  3096. set_num_733(bp + 13, (uint32_t)(dev & 0xFFFFFFFF));
  3097. bp += length;
  3098. }
  3099. extra_tell_used_size(&ctl, length);
  3100. }
  3101. /* Write "ZF" System Use Entry. */
  3102. if (file->zisofs.header_size) {
  3103. /*
  3104. * "ZF" Format:
  3105. * len ver
  3106. * +----+----+----+----+----+----+-------------+
  3107. * | 'Z'| 'F'| 10 | 01 | 'p'| 'z'| Header Size |
  3108. * +----+----+----+----+----+----+-------------+
  3109. * 0 1 2 3 4 5 6 7
  3110. * +--------------------+-------------------+
  3111. * | Log2 of block Size | Uncompressed Size |
  3112. * +--------------------+-------------------+
  3113. * 7 8 16
  3114. */
  3115. length = 16;
  3116. if (extra_space(&ctl) < length)
  3117. bp = extra_next_record(&ctl, length);
  3118. if (bp != NULL) {
  3119. bp[1] = 'Z';
  3120. bp[2] = 'F';
  3121. bp[3] = length;
  3122. bp[4] = 1; /* version */
  3123. bp[5] = 'p';
  3124. bp[6] = 'z';
  3125. bp[7] = file->zisofs.header_size;
  3126. bp[8] = file->zisofs.log2_bs;
  3127. set_num_733(bp + 9, file->zisofs.uncompressed_size);
  3128. bp += length;
  3129. }
  3130. extra_tell_used_size(&ctl, length);
  3131. }
  3132. /* Write "CE" System Use Entry. */
  3133. if (t == DIR_REC_SELF && isoent == isoent->parent) {
  3134. length = RR_CE_SIZE;
  3135. if (bp != NULL)
  3136. set_SUSP_CE(bp+1, iso9660->location_rrip_er,
  3137. 0, RRIP_ER_SIZE);
  3138. extra_tell_used_size(&ctl, length);
  3139. }
  3140. extra_close_record(&ctl, 0);
  3141. return (ctl.dr_len);
  3142. }
  3143. /*
  3144. * Write data of a Directory Record or calculate writing bytes itself.
  3145. * If parameter `p' is NULL, calculates the size of writing data, which
  3146. * a Directory Record needs to write, then it saved and return
  3147. * the calculated size.
  3148. * Parameter `n' is a remaining size of buffer. when parameter `p' is
  3149. * not NULL, check whether that `n' is not less than the saved size.
  3150. * if that `n' is small, return zero.
  3151. *
  3152. * This format of the Directory Record is according to
  3153. * ISO9660 Standard 9.1
  3154. */
  3155. static int
  3156. set_directory_record(unsigned char *p, size_t n, struct isoent *isoent,
  3157. struct iso9660 *iso9660, enum dir_rec_type t,
  3158. enum vdd_type vdd_type)
  3159. {
  3160. unsigned char *bp;
  3161. size_t dr_len;
  3162. size_t fi_len;
  3163. if (p != NULL) {
  3164. /*
  3165. * Check whether a write buffer size is less than the
  3166. * saved size which is needed to write this Directory
  3167. * Record.
  3168. */
  3169. switch (t) {
  3170. case DIR_REC_VD:
  3171. dr_len = isoent->dr_len.vd; break;
  3172. case DIR_REC_SELF:
  3173. dr_len = isoent->dr_len.self; break;
  3174. case DIR_REC_PARENT:
  3175. dr_len = isoent->dr_len.parent; break;
  3176. case DIR_REC_NORMAL:
  3177. default:
  3178. dr_len = isoent->dr_len.normal; break;
  3179. }
  3180. if (dr_len > n)
  3181. return (0);/* Needs more buffer size. */
  3182. }
  3183. if (t == DIR_REC_NORMAL && isoent->identifier != NULL)
  3184. fi_len = isoent->id_len;
  3185. else
  3186. fi_len = 1;
  3187. if (p != NULL) {
  3188. struct isoent *xisoent;
  3189. struct isofile *file;
  3190. unsigned char flag;
  3191. if (t == DIR_REC_PARENT)
  3192. xisoent = isoent->parent;
  3193. else
  3194. xisoent = isoent;
  3195. file = isoent->file;
  3196. if (file->hardlink_target != NULL)
  3197. file = file->hardlink_target;
  3198. /* Make a file flag. */
  3199. if (xisoent->dir)
  3200. flag = FILE_FLAG_DIRECTORY;
  3201. else {
  3202. if (file->cur_content->next != NULL)
  3203. flag = FILE_FLAG_MULTI_EXTENT;
  3204. else
  3205. flag = 0;
  3206. }
  3207. bp = p -1;
  3208. /* Extended Attribute Record Length */
  3209. set_num_711(bp+2, 0);
  3210. /* Location of Extent */
  3211. if (xisoent->dir)
  3212. set_num_733(bp+3, xisoent->dir_location);
  3213. else
  3214. set_num_733(bp+3, file->cur_content->location);
  3215. /* Data Length */
  3216. if (xisoent->dir)
  3217. set_num_733(bp+11,
  3218. xisoent->dir_block * LOGICAL_BLOCK_SIZE);
  3219. else
  3220. set_num_733(bp+11, (uint32_t)file->cur_content->size);
  3221. /* Recording Date and Time */
  3222. /* NOTE:
  3223. * If a file type is symbolic link, you are seeing this
  3224. * field value is different from a value mkisofs makes.
  3225. * libarchive uses lstat to get this one, but it
  3226. * seems mkisofs uses stat to get.
  3227. */
  3228. set_time_915(bp+19,
  3229. archive_entry_mtime(xisoent->file->entry));
  3230. /* File Flags */
  3231. bp[26] = flag;
  3232. /* File Unit Size */
  3233. set_num_711(bp+27, 0);
  3234. /* Interleave Gap Size */
  3235. set_num_711(bp+28, 0);
  3236. /* Volume Sequence Number */
  3237. set_num_723(bp+29, iso9660->volume_sequence_number);
  3238. /* Length of File Identifier */
  3239. set_num_711(bp+33, (unsigned char)fi_len);
  3240. /* File Identifier */
  3241. switch (t) {
  3242. case DIR_REC_VD:
  3243. case DIR_REC_SELF:
  3244. set_num_711(bp+34, 0);
  3245. break;
  3246. case DIR_REC_PARENT:
  3247. set_num_711(bp+34, 1);
  3248. break;
  3249. case DIR_REC_NORMAL:
  3250. if (isoent->identifier != NULL)
  3251. memcpy(bp+34, isoent->identifier, fi_len);
  3252. else
  3253. set_num_711(bp+34, 0);
  3254. break;
  3255. }
  3256. } else
  3257. bp = NULL;
  3258. dr_len = 33 + fi_len;
  3259. /* Padding Field */
  3260. if (dr_len & 0x01) {
  3261. dr_len ++;
  3262. if (p != NULL)
  3263. bp[dr_len] = 0;
  3264. }
  3265. /* Volume Descriptor does not record extension. */
  3266. if (t == DIR_REC_VD) {
  3267. if (p != NULL)
  3268. /* Length of Directory Record */
  3269. set_num_711(p, (unsigned char)dr_len);
  3270. else
  3271. isoent->dr_len.vd = (int)dr_len;
  3272. return ((int)dr_len);
  3273. }
  3274. /* Rockridge */
  3275. if (iso9660->opt.rr && vdd_type != VDD_JOLIET)
  3276. dr_len = set_directory_record_rr(bp, (int)dr_len,
  3277. isoent, iso9660, t);
  3278. if (p != NULL)
  3279. /* Length of Directory Record */
  3280. set_num_711(p, (unsigned char)dr_len);
  3281. else {
  3282. /*
  3283. * Save the size which is needed to write this
  3284. * Directory Record.
  3285. */
  3286. switch (t) {
  3287. case DIR_REC_VD:
  3288. /* This case does not come, but compiler
  3289. * complains that DIR_REC_VD not handled
  3290. * in switch .... */
  3291. break;
  3292. case DIR_REC_SELF:
  3293. isoent->dr_len.self = (int)dr_len; break;
  3294. case DIR_REC_PARENT:
  3295. isoent->dr_len.parent = (int)dr_len; break;
  3296. case DIR_REC_NORMAL:
  3297. isoent->dr_len.normal = (int)dr_len; break;
  3298. }
  3299. }
  3300. return ((int)dr_len);
  3301. }
  3302. /*
  3303. * Calculate the size of a directory record.
  3304. */
  3305. static inline int
  3306. get_dir_rec_size(struct iso9660 *iso9660, struct isoent *isoent,
  3307. enum dir_rec_type t, enum vdd_type vdd_type)
  3308. {
  3309. return (set_directory_record(NULL, SIZE_MAX,
  3310. isoent, iso9660, t, vdd_type));
  3311. }
  3312. /*
  3313. * Manage to write ISO-image data with wbuff to reduce calling
  3314. * __archive_write_output() for performance.
  3315. */
  3316. static inline unsigned char *
  3317. wb_buffptr(struct archive_write *a)
  3318. {
  3319. struct iso9660 *iso9660 = (struct iso9660 *)a->format_data;
  3320. return (&(iso9660->wbuff[sizeof(iso9660->wbuff)
  3321. - iso9660->wbuff_remaining]));
  3322. }
  3323. static int
  3324. wb_write_out(struct archive_write *a)
  3325. {
  3326. struct iso9660 *iso9660 = (struct iso9660 *)a->format_data;
  3327. size_t wsize, nw;
  3328. int r;
  3329. wsize = sizeof(iso9660->wbuff) - iso9660->wbuff_remaining;
  3330. nw = wsize % LOGICAL_BLOCK_SIZE;
  3331. if (iso9660->wbuff_type == WB_TO_STREAM)
  3332. r = __archive_write_output(a, iso9660->wbuff, wsize - nw);
  3333. else
  3334. r = write_to_temp(a, iso9660->wbuff, wsize - nw);
  3335. /* Increase the offset. */
  3336. iso9660->wbuff_offset += wsize - nw;
  3337. if (iso9660->wbuff_offset > iso9660->wbuff_written)
  3338. iso9660->wbuff_written = iso9660->wbuff_offset;
  3339. iso9660->wbuff_remaining = sizeof(iso9660->wbuff);
  3340. if (nw) {
  3341. iso9660->wbuff_remaining -= nw;
  3342. memmove(iso9660->wbuff, iso9660->wbuff + wsize - nw, nw);
  3343. }
  3344. return (r);
  3345. }
  3346. static int
  3347. wb_consume(struct archive_write *a, size_t size)
  3348. {
  3349. struct iso9660 *iso9660 = (struct iso9660 *)a->format_data;
  3350. if (size > iso9660->wbuff_remaining ||
  3351. iso9660->wbuff_remaining == 0) {
  3352. archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
  3353. "Internal Programming error: iso9660:wb_consume()"
  3354. " size=%jd, wbuff_remaining=%jd",
  3355. (intmax_t)size, (intmax_t)iso9660->wbuff_remaining);
  3356. return (ARCHIVE_FATAL);
  3357. }
  3358. iso9660->wbuff_remaining -= size;
  3359. if (iso9660->wbuff_remaining < LOGICAL_BLOCK_SIZE)
  3360. return (wb_write_out(a));
  3361. return (ARCHIVE_OK);
  3362. }
  3363. #ifdef HAVE_ZLIB_H
  3364. static int
  3365. wb_set_offset(struct archive_write *a, int64_t off)
  3366. {
  3367. struct iso9660 *iso9660 = (struct iso9660 *)a->format_data;
  3368. int64_t used, ext_bytes;
  3369. if (iso9660->wbuff_type != WB_TO_TEMP) {
  3370. archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
  3371. "Internal Programming error: iso9660:wb_set_offset()");
  3372. return (ARCHIVE_FATAL);
  3373. }
  3374. used = sizeof(iso9660->wbuff) - iso9660->wbuff_remaining;
  3375. if (iso9660->wbuff_offset + used > iso9660->wbuff_tail)
  3376. iso9660->wbuff_tail = iso9660->wbuff_offset + used;
  3377. if (iso9660->wbuff_offset < iso9660->wbuff_written) {
  3378. if (used > 0 &&
  3379. write_to_temp(a, iso9660->wbuff, (size_t)used) != ARCHIVE_OK)
  3380. return (ARCHIVE_FATAL);
  3381. iso9660->wbuff_offset = iso9660->wbuff_written;
  3382. lseek(iso9660->temp_fd, iso9660->wbuff_offset, SEEK_SET);
  3383. iso9660->wbuff_remaining = sizeof(iso9660->wbuff);
  3384. used = 0;
  3385. }
  3386. if (off < iso9660->wbuff_offset) {
  3387. /*
  3388. * Write out waiting data.
  3389. */
  3390. if (used > 0) {
  3391. if (wb_write_out(a) != ARCHIVE_OK)
  3392. return (ARCHIVE_FATAL);
  3393. }
  3394. lseek(iso9660->temp_fd, off, SEEK_SET);
  3395. iso9660->wbuff_offset = off;
  3396. iso9660->wbuff_remaining = sizeof(iso9660->wbuff);
  3397. } else if (off <= iso9660->wbuff_tail) {
  3398. iso9660->wbuff_remaining = (size_t)
  3399. (sizeof(iso9660->wbuff) - (off - iso9660->wbuff_offset));
  3400. } else {
  3401. ext_bytes = off - iso9660->wbuff_tail;
  3402. iso9660->wbuff_remaining = (size_t)(sizeof(iso9660->wbuff)
  3403. - (iso9660->wbuff_tail - iso9660->wbuff_offset));
  3404. while (ext_bytes >= (int64_t)iso9660->wbuff_remaining) {
  3405. if (write_null(a, (size_t)iso9660->wbuff_remaining)
  3406. != ARCHIVE_OK)
  3407. return (ARCHIVE_FATAL);
  3408. ext_bytes -= iso9660->wbuff_remaining;
  3409. }
  3410. if (ext_bytes > 0) {
  3411. if (write_null(a, (size_t)ext_bytes) != ARCHIVE_OK)
  3412. return (ARCHIVE_FATAL);
  3413. }
  3414. }
  3415. return (ARCHIVE_OK);
  3416. }
  3417. #endif /* HAVE_ZLIB_H */
  3418. static int
  3419. write_null(struct archive_write *a, size_t size)
  3420. {
  3421. size_t remaining;
  3422. unsigned char *p, *old;
  3423. int r;
  3424. remaining = wb_remaining(a);
  3425. p = wb_buffptr(a);
  3426. if (size <= remaining) {
  3427. memset(p, 0, size);
  3428. return (wb_consume(a, size));
  3429. }
  3430. memset(p, 0, remaining);
  3431. r = wb_consume(a, remaining);
  3432. if (r != ARCHIVE_OK)
  3433. return (r);
  3434. size -= remaining;
  3435. old = p;
  3436. p = wb_buffptr(a);
  3437. memset(p, 0, old - p);
  3438. remaining = wb_remaining(a);
  3439. while (size) {
  3440. size_t wsize = size;
  3441. if (wsize > remaining)
  3442. wsize = remaining;
  3443. r = wb_consume(a, wsize);
  3444. if (r != ARCHIVE_OK)
  3445. return (r);
  3446. size -= wsize;
  3447. }
  3448. return (ARCHIVE_OK);
  3449. }
  3450. /*
  3451. * Write Volume Descriptor Set Terminator
  3452. */
  3453. static int
  3454. write_VD_terminator(struct archive_write *a)
  3455. {
  3456. unsigned char *bp;
  3457. bp = wb_buffptr(a) -1;
  3458. set_VD_bp(bp, VDT_TERMINATOR, 1);
  3459. set_unused_field_bp(bp, 8, LOGICAL_BLOCK_SIZE);
  3460. return (wb_consume(a, LOGICAL_BLOCK_SIZE));
  3461. }
  3462. static int
  3463. set_file_identifier(unsigned char *bp, int from, int to, enum vdc vdc,
  3464. struct archive_write *a, struct vdd *vdd, struct archive_string *id,
  3465. const char *label, int leading_under, enum char_type char_type)
  3466. {
  3467. char identifier[256];
  3468. struct isoent *isoent;
  3469. const char *ids;
  3470. size_t len;
  3471. int r;
  3472. if (id->length > 0 && leading_under && id->s[0] != '_') {
  3473. if (char_type == A_CHAR)
  3474. r = set_str_a_characters_bp(a, bp, from, to, id->s, vdc);
  3475. else
  3476. r = set_str_d_characters_bp(a, bp, from, to, id->s, vdc);
  3477. } else if (id->length > 0) {
  3478. ids = id->s;
  3479. if (leading_under)
  3480. ids++;
  3481. isoent = isoent_find_entry(vdd->rootent, ids);
  3482. if (isoent == NULL) {
  3483. archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
  3484. "Not Found %s `%s'.",
  3485. label, ids);
  3486. return (ARCHIVE_FATAL);
  3487. }
  3488. len = isoent->ext_off + isoent->ext_len;
  3489. if (vdd->vdd_type == VDD_JOLIET) {
  3490. if (len > sizeof(identifier)-2)
  3491. len = sizeof(identifier)-2;
  3492. } else {
  3493. if (len > sizeof(identifier)-1)
  3494. len = sizeof(identifier)-1;
  3495. }
  3496. memcpy(identifier, isoent->identifier, len);
  3497. identifier[len] = '\0';
  3498. if (vdd->vdd_type == VDD_JOLIET) {
  3499. identifier[len+1] = 0;
  3500. vdc = VDC_UCS2_DIRECT;
  3501. }
  3502. if (char_type == A_CHAR)
  3503. r = set_str_a_characters_bp(a, bp, from, to,
  3504. identifier, vdc);
  3505. else
  3506. r = set_str_d_characters_bp(a, bp, from, to,
  3507. identifier, vdc);
  3508. } else {
  3509. if (char_type == A_CHAR)
  3510. r = set_str_a_characters_bp(a, bp, from, to, NULL, vdc);
  3511. else
  3512. r = set_str_d_characters_bp(a, bp, from, to, NULL, vdc);
  3513. }
  3514. return (r);
  3515. }
  3516. /*
  3517. * Write Primary/Supplementary Volume Descriptor
  3518. */
  3519. static int
  3520. write_VD(struct archive_write *a, struct vdd *vdd)
  3521. {
  3522. struct iso9660 *iso9660;
  3523. unsigned char *bp;
  3524. uint16_t volume_set_size = 1;
  3525. char identifier[256];
  3526. enum VD_type vdt;
  3527. enum vdc vdc;
  3528. unsigned char vd_ver, fst_ver;
  3529. int r;
  3530. iso9660 = a->format_data;
  3531. switch (vdd->vdd_type) {
  3532. case VDD_JOLIET:
  3533. vdt = VDT_SUPPLEMENTARY;
  3534. vd_ver = fst_ver = 1;
  3535. vdc = VDC_UCS2;
  3536. break;
  3537. case VDD_ENHANCED:
  3538. vdt = VDT_SUPPLEMENTARY;
  3539. vd_ver = fst_ver = 2;
  3540. vdc = VDC_LOWERCASE;
  3541. break;
  3542. case VDD_PRIMARY:
  3543. default:
  3544. vdt = VDT_PRIMARY;
  3545. vd_ver = fst_ver = 1;
  3546. #ifdef COMPAT_MKISOFS
  3547. vdc = VDC_LOWERCASE;
  3548. #else
  3549. vdc = VDC_STD;
  3550. #endif
  3551. break;
  3552. }
  3553. bp = wb_buffptr(a) -1;
  3554. /* Volume Descriptor Type */
  3555. set_VD_bp(bp, vdt, vd_ver);
  3556. /* Unused Field */
  3557. set_unused_field_bp(bp, 8, 8);
  3558. /* System Identifier */
  3559. get_system_identifier(identifier, sizeof(identifier));
  3560. r = set_str_a_characters_bp(a, bp, 9, 40, identifier, vdc);
  3561. if (r != ARCHIVE_OK)
  3562. return (r);
  3563. /* Volume Identifier */
  3564. r = set_str_d_characters_bp(a, bp, 41, 72,
  3565. iso9660->volume_identifier.s, vdc);
  3566. if (r != ARCHIVE_OK)
  3567. return (r);
  3568. /* Unused Field */
  3569. set_unused_field_bp(bp, 73, 80);
  3570. /* Volume Space Size */
  3571. set_num_733(bp+81, iso9660->volume_space_size);
  3572. if (vdd->vdd_type == VDD_JOLIET) {
  3573. /* Escape Sequences */
  3574. bp[89] = 0x25;/* UCS-2 Level 3 */
  3575. bp[90] = 0x2F;
  3576. bp[91] = 0x45;
  3577. memset(bp + 92, 0, 120 - 92 + 1);
  3578. } else {
  3579. /* Unused Field */
  3580. set_unused_field_bp(bp, 89, 120);
  3581. }
  3582. /* Volume Set Size */
  3583. set_num_723(bp+121, volume_set_size);
  3584. /* Volume Sequence Number */
  3585. set_num_723(bp+125, iso9660->volume_sequence_number);
  3586. /* Logical Block Size */
  3587. set_num_723(bp+129, LOGICAL_BLOCK_SIZE);
  3588. /* Path Table Size */
  3589. set_num_733(bp+133, vdd->path_table_size);
  3590. /* Location of Occurrence of Type L Path Table */
  3591. set_num_731(bp+141, vdd->location_type_L_path_table);
  3592. /* Location of Optional Occurrence of Type L Path Table */
  3593. set_num_731(bp+145, 0);
  3594. /* Location of Occurrence of Type M Path Table */
  3595. set_num_732(bp+149, vdd->location_type_M_path_table);
  3596. /* Location of Optional Occurrence of Type M Path Table */
  3597. set_num_732(bp+153, 0);
  3598. /* Directory Record for Root Directory(BP 157 to 190) */
  3599. set_directory_record(bp+157, 190-157+1, vdd->rootent,
  3600. iso9660, DIR_REC_VD, vdd->vdd_type);
  3601. /* Volume Set Identifier */
  3602. r = set_str_d_characters_bp(a, bp, 191, 318, "", vdc);
  3603. if (r != ARCHIVE_OK)
  3604. return (r);
  3605. /* Publisher Identifier */
  3606. r = set_file_identifier(bp, 319, 446, vdc, a, vdd,
  3607. &(iso9660->publisher_identifier),
  3608. "Publisher File", 1, A_CHAR);
  3609. if (r != ARCHIVE_OK)
  3610. return (r);
  3611. /* Data Preparer Identifier */
  3612. r = set_file_identifier(bp, 447, 574, vdc, a, vdd,
  3613. &(iso9660->data_preparer_identifier),
  3614. "Data Preparer File", 1, A_CHAR);
  3615. if (r != ARCHIVE_OK)
  3616. return (r);
  3617. /* Application Identifier */
  3618. r = set_file_identifier(bp, 575, 702, vdc, a, vdd,
  3619. &(iso9660->application_identifier),
  3620. "Application File", 1, A_CHAR);
  3621. if (r != ARCHIVE_OK)
  3622. return (r);
  3623. /* Copyright File Identifier */
  3624. r = set_file_identifier(bp, 703, 739, vdc, a, vdd,
  3625. &(iso9660->copyright_file_identifier),
  3626. "Copyright File", 0, D_CHAR);
  3627. if (r != ARCHIVE_OK)
  3628. return (r);
  3629. /* Abstract File Identifier */
  3630. r = set_file_identifier(bp, 740, 776, vdc, a, vdd,
  3631. &(iso9660->abstract_file_identifier),
  3632. "Abstract File", 0, D_CHAR);
  3633. if (r != ARCHIVE_OK)
  3634. return (r);
  3635. /* Bibliographic File Identifier */
  3636. r = set_file_identifier(bp, 777, 813, vdc, a, vdd,
  3637. &(iso9660->bibliographic_file_identifier),
  3638. "Bibliongraphic File", 0, D_CHAR);
  3639. if (r != ARCHIVE_OK)
  3640. return (r);
  3641. /* Volume Creation Date and Time */
  3642. set_date_time(bp+814, iso9660->birth_time);
  3643. /* Volume Modification Date and Time */
  3644. set_date_time(bp+831, iso9660->birth_time);
  3645. /* Volume Expiration Date and Time(obsolete) */
  3646. set_date_time_null(bp+848);
  3647. /* Volume Effective Date and Time */
  3648. set_date_time(bp+865, iso9660->birth_time);
  3649. /* File Structure Version */
  3650. bp[882] = fst_ver;
  3651. /* Reserved */
  3652. bp[883] = 0;
  3653. /* Application Use */
  3654. memset(bp + 884, 0x20, 1395 - 884 + 1);
  3655. /* Reserved */
  3656. set_unused_field_bp(bp, 1396, LOGICAL_BLOCK_SIZE);
  3657. return (wb_consume(a, LOGICAL_BLOCK_SIZE));
  3658. }
  3659. /*
  3660. * Write Boot Record Volume Descriptor
  3661. */
  3662. static int
  3663. write_VD_boot_record(struct archive_write *a)
  3664. {
  3665. struct iso9660 *iso9660;
  3666. unsigned char *bp;
  3667. iso9660 = a->format_data;
  3668. bp = wb_buffptr(a) -1;
  3669. /* Volume Descriptor Type */
  3670. set_VD_bp(bp, VDT_BOOT_RECORD, 1);
  3671. /* Boot System Identifier */
  3672. memcpy(bp+8, "EL TORITO SPECIFICATION", 23);
  3673. set_unused_field_bp(bp, 8+23, 39);
  3674. /* Unused */
  3675. set_unused_field_bp(bp, 40, 71);
  3676. /* Absolute pointer to first sector of Boot Catalog */
  3677. set_num_731(bp+72,
  3678. iso9660->el_torito.catalog->file->content.location);
  3679. /* Unused */
  3680. set_unused_field_bp(bp, 76, LOGICAL_BLOCK_SIZE);
  3681. return (wb_consume(a, LOGICAL_BLOCK_SIZE));
  3682. }
  3683. enum keytype {
  3684. KEY_FLG,
  3685. KEY_STR,
  3686. KEY_INT,
  3687. KEY_HEX
  3688. };
  3689. static void
  3690. set_option_info(struct archive_string *info, int *opt, const char *key,
  3691. enum keytype type, ...)
  3692. {
  3693. va_list ap;
  3694. char prefix;
  3695. const char *s;
  3696. int d;
  3697. prefix = (*opt==0)? ' ':',';
  3698. va_start(ap, type);
  3699. switch (type) {
  3700. case KEY_FLG:
  3701. d = va_arg(ap, int);
  3702. archive_string_sprintf(info, "%c%s%s",
  3703. prefix, (d == 0)?"!":"", key);
  3704. break;
  3705. case KEY_STR:
  3706. s = va_arg(ap, const char *);
  3707. archive_string_sprintf(info, "%c%s=%s",
  3708. prefix, key, s);
  3709. break;
  3710. case KEY_INT:
  3711. d = va_arg(ap, int);
  3712. archive_string_sprintf(info, "%c%s=%d",
  3713. prefix, key, d);
  3714. break;
  3715. case KEY_HEX:
  3716. d = va_arg(ap, int);
  3717. archive_string_sprintf(info, "%c%s=%x",
  3718. prefix, key, (unsigned int)d);
  3719. break;
  3720. }
  3721. va_end(ap);
  3722. *opt = 1;
  3723. }
  3724. /*
  3725. * Make Non-ISO File System Information
  3726. */
  3727. static int
  3728. write_information_block(struct archive_write *a)
  3729. {
  3730. struct iso9660 *iso9660;
  3731. char buf[128];
  3732. const char *v;
  3733. int opt, r;
  3734. struct archive_string info;
  3735. size_t info_size = LOGICAL_BLOCK_SIZE *
  3736. NON_ISO_FILE_SYSTEM_INFORMATION_BLOCK;
  3737. iso9660 = (struct iso9660 *)a->format_data;
  3738. if (info_size > wb_remaining(a)) {
  3739. r = wb_write_out(a);
  3740. if (r != ARCHIVE_OK)
  3741. return (r);
  3742. }
  3743. archive_string_init(&info);
  3744. if (archive_string_ensure(&info, info_size) == NULL) {
  3745. archive_set_error(&a->archive, ENOMEM,
  3746. "Can't allocate memory");
  3747. return (ARCHIVE_FATAL);
  3748. }
  3749. memset(info.s, 0, info_size);
  3750. opt = 0;
  3751. #if defined(HAVE_CTIME_S)
  3752. ctime_s(buf, sizeof(buf), &(iso9660->birth_time));
  3753. #elif defined(HAVE_CTIME_R)
  3754. ctime_r(&(iso9660->birth_time), buf);
  3755. #else
  3756. strncpy(buf, ctime(&(iso9660->birth_time)), sizeof(buf)-1);
  3757. buf[sizeof(buf)-1] = '\0';
  3758. #endif
  3759. archive_string_sprintf(&info,
  3760. "INFO %s%s", buf, archive_version_string());
  3761. if (iso9660->opt.abstract_file != OPT_ABSTRACT_FILE_DEFAULT)
  3762. set_option_info(&info, &opt, "abstract-file",
  3763. KEY_STR, iso9660->abstract_file_identifier.s);
  3764. if (iso9660->opt.application_id != OPT_APPLICATION_ID_DEFAULT)
  3765. set_option_info(&info, &opt, "application-id",
  3766. KEY_STR, iso9660->application_identifier.s);
  3767. if (iso9660->opt.allow_vernum != OPT_ALLOW_VERNUM_DEFAULT)
  3768. set_option_info(&info, &opt, "allow-vernum",
  3769. KEY_FLG, iso9660->opt.allow_vernum);
  3770. if (iso9660->opt.biblio_file != OPT_BIBLIO_FILE_DEFAULT)
  3771. set_option_info(&info, &opt, "biblio-file",
  3772. KEY_STR, iso9660->bibliographic_file_identifier.s);
  3773. if (iso9660->opt.boot != OPT_BOOT_DEFAULT)
  3774. set_option_info(&info, &opt, "boot",
  3775. KEY_STR, iso9660->el_torito.boot_filename.s);
  3776. if (iso9660->opt.boot_catalog != OPT_BOOT_CATALOG_DEFAULT)
  3777. set_option_info(&info, &opt, "boot-catalog",
  3778. KEY_STR, iso9660->el_torito.catalog_filename.s);
  3779. if (iso9660->opt.boot_info_table != OPT_BOOT_INFO_TABLE_DEFAULT)
  3780. set_option_info(&info, &opt, "boot-info-table",
  3781. KEY_FLG, iso9660->opt.boot_info_table);
  3782. if (iso9660->opt.boot_load_seg != OPT_BOOT_LOAD_SEG_DEFAULT)
  3783. set_option_info(&info, &opt, "boot-load-seg",
  3784. KEY_HEX, iso9660->el_torito.boot_load_seg);
  3785. if (iso9660->opt.boot_load_size != OPT_BOOT_LOAD_SIZE_DEFAULT)
  3786. set_option_info(&info, &opt, "boot-load-size",
  3787. KEY_INT, iso9660->el_torito.boot_load_size);
  3788. if (iso9660->opt.boot_type != OPT_BOOT_TYPE_DEFAULT) {
  3789. v = "no-emulation";
  3790. if (iso9660->opt.boot_type == OPT_BOOT_TYPE_FD)
  3791. v = "fd";
  3792. if (iso9660->opt.boot_type == OPT_BOOT_TYPE_HARD_DISK)
  3793. v = "hard-disk";
  3794. set_option_info(&info, &opt, "boot-type",
  3795. KEY_STR, v);
  3796. }
  3797. #ifdef HAVE_ZLIB_H
  3798. if (iso9660->opt.compression_level != OPT_COMPRESSION_LEVEL_DEFAULT)
  3799. set_option_info(&info, &opt, "compression-level",
  3800. KEY_INT, iso9660->zisofs.compression_level);
  3801. #endif
  3802. if (iso9660->opt.copyright_file != OPT_COPYRIGHT_FILE_DEFAULT)
  3803. set_option_info(&info, &opt, "copyright-file",
  3804. KEY_STR, iso9660->copyright_file_identifier.s);
  3805. if (iso9660->opt.iso_level != OPT_ISO_LEVEL_DEFAULT)
  3806. set_option_info(&info, &opt, "iso-level",
  3807. KEY_INT, iso9660->opt.iso_level);
  3808. if (iso9660->opt.joliet != OPT_JOLIET_DEFAULT) {
  3809. if (iso9660->opt.joliet == OPT_JOLIET_LONGNAME)
  3810. set_option_info(&info, &opt, "joliet",
  3811. KEY_STR, "long");
  3812. else
  3813. set_option_info(&info, &opt, "joliet",
  3814. KEY_FLG, iso9660->opt.joliet);
  3815. }
  3816. if (iso9660->opt.limit_depth != OPT_LIMIT_DEPTH_DEFAULT)
  3817. set_option_info(&info, &opt, "limit-depth",
  3818. KEY_FLG, iso9660->opt.limit_depth);
  3819. if (iso9660->opt.limit_dirs != OPT_LIMIT_DIRS_DEFAULT)
  3820. set_option_info(&info, &opt, "limit-dirs",
  3821. KEY_FLG, iso9660->opt.limit_dirs);
  3822. if (iso9660->opt.pad != OPT_PAD_DEFAULT)
  3823. set_option_info(&info, &opt, "pad",
  3824. KEY_FLG, iso9660->opt.pad);
  3825. if (iso9660->opt.publisher != OPT_PUBLISHER_DEFAULT)
  3826. set_option_info(&info, &opt, "publisher",
  3827. KEY_STR, iso9660->publisher_identifier.s);
  3828. if (iso9660->opt.rr != OPT_RR_DEFAULT) {
  3829. if (iso9660->opt.rr == OPT_RR_DISABLED)
  3830. set_option_info(&info, &opt, "rockridge",
  3831. KEY_FLG, iso9660->opt.rr);
  3832. else if (iso9660->opt.rr == OPT_RR_STRICT)
  3833. set_option_info(&info, &opt, "rockridge",
  3834. KEY_STR, "strict");
  3835. else if (iso9660->opt.rr == OPT_RR_USEFUL)
  3836. set_option_info(&info, &opt, "rockridge",
  3837. KEY_STR, "useful");
  3838. }
  3839. if (iso9660->opt.volume_id != OPT_VOLUME_ID_DEFAULT)
  3840. set_option_info(&info, &opt, "volume-id",
  3841. KEY_STR, iso9660->volume_identifier.s);
  3842. if (iso9660->opt.zisofs != OPT_ZISOFS_DEFAULT)
  3843. set_option_info(&info, &opt, "zisofs",
  3844. KEY_FLG, iso9660->opt.zisofs);
  3845. memcpy(wb_buffptr(a), info.s, info_size);
  3846. archive_string_free(&info);
  3847. return (wb_consume(a, info_size));
  3848. }
  3849. static int
  3850. write_rr_ER(struct archive_write *a)
  3851. {
  3852. unsigned char *p;
  3853. p = wb_buffptr(a);
  3854. memset(p, 0, LOGICAL_BLOCK_SIZE);
  3855. p[0] = 'E';
  3856. p[1] = 'R';
  3857. p[3] = 0x01;
  3858. p[2] = RRIP_ER_SIZE;
  3859. p[4] = RRIP_ER_ID_SIZE;
  3860. p[5] = RRIP_ER_DSC_SIZE;
  3861. p[6] = RRIP_ER_SRC_SIZE;
  3862. p[7] = 0x01;
  3863. memcpy(&p[8], rrip_identifier, p[4]);
  3864. memcpy(&p[8+p[4]], rrip_descriptor, p[5]);
  3865. memcpy(&p[8+p[4]+p[5]], rrip_source, p[6]);
  3866. return (wb_consume(a, LOGICAL_BLOCK_SIZE));
  3867. }
  3868. static void
  3869. calculate_path_table_size(struct vdd *vdd)
  3870. {
  3871. int depth, size;
  3872. struct path_table *pt;
  3873. pt = vdd->pathtbl;
  3874. size = 0;
  3875. for (depth = 0; depth < vdd->max_depth; depth++) {
  3876. struct isoent **ptbl;
  3877. int i, cnt;
  3878. if ((cnt = pt[depth].cnt) == 0)
  3879. break;
  3880. ptbl = pt[depth].sorted;
  3881. for (i = 0; i < cnt; i++) {
  3882. int len;
  3883. if (ptbl[i]->identifier == NULL)
  3884. len = 1; /* root directory */
  3885. else
  3886. len = ptbl[i]->id_len;
  3887. if (len & 0x01)
  3888. len++; /* Padding Field */
  3889. size += 8 + len;
  3890. }
  3891. }
  3892. vdd->path_table_size = size;
  3893. vdd->path_table_block =
  3894. ((size + PATH_TABLE_BLOCK_SIZE -1) /
  3895. PATH_TABLE_BLOCK_SIZE) *
  3896. (PATH_TABLE_BLOCK_SIZE / LOGICAL_BLOCK_SIZE);
  3897. }
  3898. static int
  3899. _write_path_table(struct archive_write *a, int type_m, int depth,
  3900. struct vdd *vdd)
  3901. {
  3902. unsigned char *bp, *wb;
  3903. struct isoent **ptbl;
  3904. size_t wbremaining;
  3905. int i, r, wsize;
  3906. if (vdd->pathtbl[depth].cnt == 0)
  3907. return (0);
  3908. wsize = 0;
  3909. wb = wb_buffptr(a);
  3910. wbremaining = wb_remaining(a);
  3911. bp = wb - 1;
  3912. ptbl = vdd->pathtbl[depth].sorted;
  3913. for (i = 0; i < vdd->pathtbl[depth].cnt; i++) {
  3914. struct isoent *np;
  3915. size_t len;
  3916. np = ptbl[i];
  3917. if (np->identifier == NULL)
  3918. len = 1; /* root directory */
  3919. else
  3920. len = np->id_len;
  3921. if (wbremaining - ((bp+1) - wb) < (len + 1 + 8)) {
  3922. r = wb_consume(a, (bp+1) - wb);
  3923. if (r < 0)
  3924. return (r);
  3925. wb = wb_buffptr(a);
  3926. wbremaining = wb_remaining(a);
  3927. bp = wb -1;
  3928. }
  3929. /* Length of Directory Identifier */
  3930. set_num_711(bp+1, (unsigned char)len);
  3931. /* Extended Attribute Record Length */
  3932. set_num_711(bp+2, 0);
  3933. /* Location of Extent */
  3934. if (type_m)
  3935. set_num_732(bp+3, np->dir_location);
  3936. else
  3937. set_num_731(bp+3, np->dir_location);
  3938. /* Parent Directory Number */
  3939. if (type_m)
  3940. set_num_722(bp+7, np->parent->dir_number);
  3941. else
  3942. set_num_721(bp+7, np->parent->dir_number);
  3943. /* Directory Identifier */
  3944. if (np->identifier == NULL)
  3945. bp[9] = 0;
  3946. else
  3947. memcpy(&bp[9], np->identifier, len);
  3948. if (len & 0x01) {
  3949. /* Padding Field */
  3950. bp[9+len] = 0;
  3951. len++;
  3952. }
  3953. wsize += 8 + (int)len;
  3954. bp += 8 + len;
  3955. }
  3956. if ((bp + 1) > wb) {
  3957. r = wb_consume(a, (bp+1)-wb);
  3958. if (r < 0)
  3959. return (r);
  3960. }
  3961. return (wsize);
  3962. }
  3963. static int
  3964. write_path_table(struct archive_write *a, int type_m, struct vdd *vdd)
  3965. {
  3966. int depth, r;
  3967. size_t path_table_size;
  3968. r = ARCHIVE_OK;
  3969. path_table_size = 0;
  3970. for (depth = 0; depth < vdd->max_depth; depth++) {
  3971. r = _write_path_table(a, type_m, depth, vdd);
  3972. if (r < 0)
  3973. return (r);
  3974. path_table_size += r;
  3975. }
  3976. /* Write padding data. */
  3977. path_table_size = path_table_size % PATH_TABLE_BLOCK_SIZE;
  3978. if (path_table_size > 0)
  3979. r = write_null(a, PATH_TABLE_BLOCK_SIZE - path_table_size);
  3980. return (r);
  3981. }
  3982. static int
  3983. calculate_directory_descriptors(struct iso9660 *iso9660, struct vdd *vdd,
  3984. struct isoent *isoent, int depth)
  3985. {
  3986. struct isoent **enttbl;
  3987. int bs, block, i;
  3988. block = 1;
  3989. bs = get_dir_rec_size(iso9660, isoent, DIR_REC_SELF, vdd->vdd_type);
  3990. bs += get_dir_rec_size(iso9660, isoent, DIR_REC_PARENT, vdd->vdd_type);
  3991. if (isoent->children.cnt <= 0 || (vdd->vdd_type != VDD_JOLIET &&
  3992. !iso9660->opt.rr && depth + 1 >= vdd->max_depth))
  3993. return (block);
  3994. enttbl = isoent->children_sorted;
  3995. for (i = 0; i < isoent->children.cnt; i++) {
  3996. struct isoent *np = enttbl[i];
  3997. struct isofile *file;
  3998. file = np->file;
  3999. if (file->hardlink_target != NULL)
  4000. file = file->hardlink_target;
  4001. file->cur_content = &(file->content);
  4002. do {
  4003. int dr_l;
  4004. dr_l = get_dir_rec_size(iso9660, np, DIR_REC_NORMAL,
  4005. vdd->vdd_type);
  4006. if ((bs + dr_l) > LOGICAL_BLOCK_SIZE) {
  4007. block ++;
  4008. bs = dr_l;
  4009. } else
  4010. bs += dr_l;
  4011. file->cur_content = file->cur_content->next;
  4012. } while (file->cur_content != NULL);
  4013. }
  4014. return (block);
  4015. }
  4016. static int
  4017. _write_directory_descriptors(struct archive_write *a, struct vdd *vdd,
  4018. struct isoent *isoent, int depth)
  4019. {
  4020. struct iso9660 *iso9660 = a->format_data;
  4021. struct isoent **enttbl;
  4022. unsigned char *p, *wb;
  4023. int i, r;
  4024. int dr_l;
  4025. p = wb = wb_buffptr(a);
  4026. #define WD_REMAINING (LOGICAL_BLOCK_SIZE - (p - wb))
  4027. p += set_directory_record(p, WD_REMAINING, isoent,
  4028. iso9660, DIR_REC_SELF, vdd->vdd_type);
  4029. p += set_directory_record(p, WD_REMAINING, isoent,
  4030. iso9660, DIR_REC_PARENT, vdd->vdd_type);
  4031. if (isoent->children.cnt <= 0 || (vdd->vdd_type != VDD_JOLIET &&
  4032. !iso9660->opt.rr && depth + 1 >= vdd->max_depth)) {
  4033. memset(p, 0, WD_REMAINING);
  4034. return (wb_consume(a, LOGICAL_BLOCK_SIZE));
  4035. }
  4036. enttbl = isoent->children_sorted;
  4037. for (i = 0; i < isoent->children.cnt; i++) {
  4038. struct isoent *np = enttbl[i];
  4039. struct isofile *file = np->file;
  4040. if (file->hardlink_target != NULL)
  4041. file = file->hardlink_target;
  4042. file->cur_content = &(file->content);
  4043. do {
  4044. dr_l = set_directory_record(p, WD_REMAINING,
  4045. np, iso9660, DIR_REC_NORMAL,
  4046. vdd->vdd_type);
  4047. if (dr_l == 0) {
  4048. memset(p, 0, WD_REMAINING);
  4049. r = wb_consume(a, LOGICAL_BLOCK_SIZE);
  4050. if (r < 0)
  4051. return (r);
  4052. p = wb = wb_buffptr(a);
  4053. dr_l = set_directory_record(p,
  4054. WD_REMAINING, np, iso9660,
  4055. DIR_REC_NORMAL, vdd->vdd_type);
  4056. }
  4057. p += dr_l;
  4058. file->cur_content = file->cur_content->next;
  4059. } while (file->cur_content != NULL);
  4060. }
  4061. memset(p, 0, WD_REMAINING);
  4062. return (wb_consume(a, LOGICAL_BLOCK_SIZE));
  4063. }
  4064. static int
  4065. write_directory_descriptors(struct archive_write *a, struct vdd *vdd)
  4066. {
  4067. struct isoent *np;
  4068. int depth, r;
  4069. depth = 0;
  4070. np = vdd->rootent;
  4071. do {
  4072. struct extr_rec *extr;
  4073. r = _write_directory_descriptors(a, vdd, np, depth);
  4074. if (r < 0)
  4075. return (r);
  4076. if (vdd->vdd_type != VDD_JOLIET) {
  4077. /*
  4078. * This extract record is used by SUSP,RRIP.
  4079. * Not for joliet.
  4080. */
  4081. for (extr = np->extr_rec_list.first;
  4082. extr != NULL;
  4083. extr = extr->next) {
  4084. unsigned char *wb;
  4085. wb = wb_buffptr(a);
  4086. memcpy(wb, extr->buf, extr->offset);
  4087. memset(wb + extr->offset, 0,
  4088. LOGICAL_BLOCK_SIZE - extr->offset);
  4089. r = wb_consume(a, LOGICAL_BLOCK_SIZE);
  4090. if (r < 0)
  4091. return (r);
  4092. }
  4093. }
  4094. if (np->subdirs.first != NULL && depth + 1 < vdd->max_depth) {
  4095. /* Enter to sub directories. */
  4096. np = np->subdirs.first;
  4097. depth++;
  4098. continue;
  4099. }
  4100. while (np != np->parent) {
  4101. if (np->drnext == NULL) {
  4102. /* Return to the parent directory. */
  4103. np = np->parent;
  4104. depth--;
  4105. } else {
  4106. np = np->drnext;
  4107. break;
  4108. }
  4109. }
  4110. } while (np != np->parent);
  4111. return (ARCHIVE_OK);
  4112. }
  4113. /*
  4114. * Read file contents from the temporary file, and write it.
  4115. */
  4116. static int
  4117. write_file_contents(struct archive_write *a, int64_t offset, int64_t size)
  4118. {
  4119. struct iso9660 *iso9660 = a->format_data;
  4120. int r;
  4121. lseek(iso9660->temp_fd, offset, SEEK_SET);
  4122. while (size) {
  4123. size_t rsize;
  4124. ssize_t rs;
  4125. unsigned char *wb;
  4126. wb = wb_buffptr(a);
  4127. rsize = wb_remaining(a);
  4128. if (rsize > (size_t)size)
  4129. rsize = (size_t)size;
  4130. rs = read(iso9660->temp_fd, wb, rsize);
  4131. if (rs <= 0) {
  4132. archive_set_error(&a->archive, errno,
  4133. "Can't read temporary file(%jd)", (intmax_t)rs);
  4134. return (ARCHIVE_FATAL);
  4135. }
  4136. size -= rs;
  4137. r = wb_consume(a, rs);
  4138. if (r < 0)
  4139. return (r);
  4140. }
  4141. return (ARCHIVE_OK);
  4142. }
  4143. static int
  4144. write_file_descriptors(struct archive_write *a)
  4145. {
  4146. struct iso9660 *iso9660 = a->format_data;
  4147. struct isofile *file;
  4148. int64_t blocks, offset;
  4149. int r;
  4150. blocks = 0;
  4151. offset = 0;
  4152. /* Make the boot catalog contents, and write it. */
  4153. if (iso9660->el_torito.catalog != NULL) {
  4154. r = make_boot_catalog(a);
  4155. if (r < 0)
  4156. return (r);
  4157. }
  4158. /* Write the boot file contents. */
  4159. if (iso9660->el_torito.boot != NULL) {
  4160. file = iso9660->el_torito.boot->file;
  4161. blocks = file->content.blocks;
  4162. offset = file->content.offset_of_temp;
  4163. if (offset != 0) {
  4164. r = write_file_contents(a, offset,
  4165. blocks << LOGICAL_BLOCK_BITS);
  4166. if (r < 0)
  4167. return (r);
  4168. blocks = 0;
  4169. offset = 0;
  4170. }
  4171. }
  4172. /* Write out all file contents. */
  4173. for (file = iso9660->data_file_list.first;
  4174. file != NULL; file = file->datanext) {
  4175. if (!file->write_content)
  4176. continue;
  4177. if ((offset + (blocks << LOGICAL_BLOCK_BITS)) <
  4178. file->content.offset_of_temp) {
  4179. if (blocks > 0) {
  4180. r = write_file_contents(a, offset,
  4181. blocks << LOGICAL_BLOCK_BITS);
  4182. if (r < 0)
  4183. return (r);
  4184. }
  4185. blocks = 0;
  4186. offset = file->content.offset_of_temp;
  4187. }
  4188. file->cur_content = &(file->content);
  4189. do {
  4190. blocks += file->cur_content->blocks;
  4191. /* Next fragment */
  4192. file->cur_content = file->cur_content->next;
  4193. } while (file->cur_content != NULL);
  4194. }
  4195. /* Flush out remaining blocks. */
  4196. if (blocks > 0) {
  4197. r = write_file_contents(a, offset,
  4198. blocks << LOGICAL_BLOCK_BITS);
  4199. if (r < 0)
  4200. return (r);
  4201. }
  4202. return (ARCHIVE_OK);
  4203. }
  4204. static void
  4205. isofile_init_entry_list(struct iso9660 *iso9660)
  4206. {
  4207. iso9660->all_file_list.first = NULL;
  4208. iso9660->all_file_list.last = &(iso9660->all_file_list.first);
  4209. }
  4210. static void
  4211. isofile_add_entry(struct iso9660 *iso9660, struct isofile *file)
  4212. {
  4213. file->allnext = NULL;
  4214. *iso9660->all_file_list.last = file;
  4215. iso9660->all_file_list.last = &(file->allnext);
  4216. }
  4217. static void
  4218. isofile_free_all_entries(struct iso9660 *iso9660)
  4219. {
  4220. struct isofile *file, *file_next;
  4221. file = iso9660->all_file_list.first;
  4222. while (file != NULL) {
  4223. file_next = file->allnext;
  4224. isofile_free(file);
  4225. file = file_next;
  4226. }
  4227. }
  4228. static void
  4229. isofile_init_entry_data_file_list(struct iso9660 *iso9660)
  4230. {
  4231. iso9660->data_file_list.first = NULL;
  4232. iso9660->data_file_list.last = &(iso9660->data_file_list.first);
  4233. }
  4234. static void
  4235. isofile_add_data_file(struct iso9660 *iso9660, struct isofile *file)
  4236. {
  4237. file->datanext = NULL;
  4238. *iso9660->data_file_list.last = file;
  4239. iso9660->data_file_list.last = &(file->datanext);
  4240. }
  4241. static struct isofile *
  4242. isofile_new(struct archive_write *a, struct archive_entry *entry)
  4243. {
  4244. struct isofile *file;
  4245. file = calloc(1, sizeof(*file));
  4246. if (file == NULL)
  4247. return (NULL);
  4248. if (entry != NULL)
  4249. file->entry = archive_entry_clone(entry);
  4250. else
  4251. file->entry = archive_entry_new2(&a->archive);
  4252. if (file->entry == NULL) {
  4253. free(file);
  4254. return (NULL);
  4255. }
  4256. archive_string_init(&(file->parentdir));
  4257. archive_string_init(&(file->basename));
  4258. archive_string_init(&(file->basename_utf16));
  4259. archive_string_init(&(file->symlink));
  4260. file->cur_content = &(file->content);
  4261. return (file);
  4262. }
  4263. static void
  4264. isofile_free(struct isofile *file)
  4265. {
  4266. struct content *con, *tmp;
  4267. con = file->content.next;
  4268. while (con != NULL) {
  4269. tmp = con;
  4270. con = con->next;
  4271. free(tmp);
  4272. }
  4273. archive_entry_free(file->entry);
  4274. archive_string_free(&(file->parentdir));
  4275. archive_string_free(&(file->basename));
  4276. archive_string_free(&(file->basename_utf16));
  4277. archive_string_free(&(file->symlink));
  4278. free(file);
  4279. }
  4280. #if defined(_WIN32) || defined(__CYGWIN__)
  4281. static int
  4282. cleanup_backslash_1(char *p)
  4283. {
  4284. int mb, dos;
  4285. mb = dos = 0;
  4286. while (*p) {
  4287. if (*(unsigned char *)p > 127)
  4288. mb = 1;
  4289. if (*p == '\\') {
  4290. /* If we have not met any multi-byte characters,
  4291. * we can replace '\' with '/'. */
  4292. if (!mb)
  4293. *p = '/';
  4294. dos = 1;
  4295. }
  4296. p++;
  4297. }
  4298. if (!mb || !dos)
  4299. return (0);
  4300. return (-1);
  4301. }
  4302. static void
  4303. cleanup_backslash_2(wchar_t *p)
  4304. {
  4305. /* Convert a path-separator from '\' to '/' */
  4306. while (*p != L'\0') {
  4307. if (*p == L'\\')
  4308. *p = L'/';
  4309. p++;
  4310. }
  4311. }
  4312. #endif
  4313. /*
  4314. * Generate a parent directory name and a base name from a pathname.
  4315. */
  4316. static int
  4317. isofile_gen_utility_names(struct archive_write *a, struct isofile *file)
  4318. {
  4319. struct iso9660 *iso9660;
  4320. const char *pathname;
  4321. char *p, *dirname, *slash;
  4322. size_t len;
  4323. int ret = ARCHIVE_OK;
  4324. iso9660 = a->format_data;
  4325. archive_string_empty(&(file->parentdir));
  4326. archive_string_empty(&(file->basename));
  4327. archive_string_empty(&(file->basename_utf16));
  4328. archive_string_empty(&(file->symlink));
  4329. pathname = archive_entry_pathname(file->entry);
  4330. if (pathname == NULL || pathname[0] == '\0') {/* virtual root */
  4331. file->dircnt = 0;
  4332. return (ret);
  4333. }
  4334. /*
  4335. * Make a UTF-16BE basename if Joliet extension enabled.
  4336. */
  4337. if (iso9660->opt.joliet) {
  4338. const char *u16, *ulast;
  4339. size_t u16len, ulen_last;
  4340. if (iso9660->sconv_to_utf16be == NULL) {
  4341. iso9660->sconv_to_utf16be =
  4342. archive_string_conversion_to_charset(
  4343. &(a->archive), "UTF-16BE", 1);
  4344. if (iso9660->sconv_to_utf16be == NULL)
  4345. /* Couldn't allocate memory */
  4346. return (ARCHIVE_FATAL);
  4347. iso9660->sconv_from_utf16be =
  4348. archive_string_conversion_from_charset(
  4349. &(a->archive), "UTF-16BE", 1);
  4350. if (iso9660->sconv_from_utf16be == NULL)
  4351. /* Couldn't allocate memory */
  4352. return (ARCHIVE_FATAL);
  4353. }
  4354. /*
  4355. * Convert a filename to UTF-16BE.
  4356. */
  4357. if (0 > archive_entry_pathname_l(file->entry, &u16, &u16len,
  4358. iso9660->sconv_to_utf16be)) {
  4359. if (errno == ENOMEM) {
  4360. archive_set_error(&a->archive, ENOMEM,
  4361. "Can't allocate memory for UTF-16BE");
  4362. return (ARCHIVE_FATAL);
  4363. }
  4364. archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
  4365. "A filename cannot be converted to UTF-16BE;"
  4366. "You should disable making Joliet extension");
  4367. ret = ARCHIVE_WARN;
  4368. }
  4369. /*
  4370. * Make sure a path separator is not in the last;
  4371. * Remove trailing '/'.
  4372. */
  4373. while (u16len >= 2) {
  4374. #if defined(_WIN32) || defined(__CYGWIN__)
  4375. if (u16[u16len-2] == 0 &&
  4376. (u16[u16len-1] == '/' || u16[u16len-1] == '\\'))
  4377. #else
  4378. if (u16[u16len-2] == 0 && u16[u16len-1] == '/')
  4379. #endif
  4380. {
  4381. u16len -= 2;
  4382. } else
  4383. break;
  4384. }
  4385. /*
  4386. * Find a basename in UTF-16BE.
  4387. */
  4388. ulast = u16;
  4389. u16len >>= 1;
  4390. ulen_last = u16len;
  4391. while (u16len > 0) {
  4392. #if defined(_WIN32) || defined(__CYGWIN__)
  4393. if (u16[0] == 0 && (u16[1] == '/' || u16[1] == '\\'))
  4394. #else
  4395. if (u16[0] == 0 && u16[1] == '/')
  4396. #endif
  4397. {
  4398. ulast = u16 + 2;
  4399. ulen_last = u16len -1;
  4400. }
  4401. u16 += 2;
  4402. u16len --;
  4403. }
  4404. ulen_last <<= 1;
  4405. if (archive_string_ensure(&(file->basename_utf16),
  4406. ulen_last) == NULL) {
  4407. archive_set_error(&a->archive, ENOMEM,
  4408. "Can't allocate memory for UTF-16BE");
  4409. return (ARCHIVE_FATAL);
  4410. }
  4411. /*
  4412. * Set UTF-16BE basename.
  4413. */
  4414. memcpy(file->basename_utf16.s, ulast, ulen_last);
  4415. file->basename_utf16.length = ulen_last;
  4416. }
  4417. archive_strcpy(&(file->parentdir), pathname);
  4418. #if defined(_WIN32) || defined(__CYGWIN__)
  4419. /*
  4420. * Convert a path-separator from '\' to '/'
  4421. */
  4422. if (cleanup_backslash_1(file->parentdir.s) != 0) {
  4423. const wchar_t *wp = archive_entry_pathname_w(file->entry);
  4424. struct archive_wstring ws;
  4425. if (wp != NULL) {
  4426. int r;
  4427. archive_string_init(&ws);
  4428. archive_wstrcpy(&ws, wp);
  4429. cleanup_backslash_2(ws.s);
  4430. archive_string_empty(&(file->parentdir));
  4431. r = archive_string_append_from_wcs(&(file->parentdir),
  4432. ws.s, ws.length);
  4433. archive_wstring_free(&ws);
  4434. if (r < 0 && errno == ENOMEM) {
  4435. archive_set_error(&a->archive, ENOMEM,
  4436. "Can't allocate memory");
  4437. return (ARCHIVE_FATAL);
  4438. }
  4439. }
  4440. }
  4441. #endif
  4442. len = file->parentdir.length;
  4443. p = dirname = file->parentdir.s;
  4444. /*
  4445. * Remove leading '/', '../' and './' elements
  4446. */
  4447. while (*p) {
  4448. if (p[0] == '/') {
  4449. p++;
  4450. len--;
  4451. } else if (p[0] != '.')
  4452. break;
  4453. else if (p[1] == '.' && p[2] == '/') {
  4454. p += 3;
  4455. len -= 3;
  4456. } else if (p[1] == '/' || (p[1] == '.' && p[2] == '\0')) {
  4457. p += 2;
  4458. len -= 2;
  4459. } else if (p[1] == '\0') {
  4460. p++;
  4461. len--;
  4462. } else
  4463. break;
  4464. }
  4465. if (p != dirname) {
  4466. memmove(dirname, p, len+1);
  4467. p = dirname;
  4468. }
  4469. /*
  4470. * Remove "/","/." and "/.." elements from tail.
  4471. */
  4472. while (len > 0) {
  4473. size_t ll = len;
  4474. if (len > 0 && p[len-1] == '/') {
  4475. p[len-1] = '\0';
  4476. len--;
  4477. }
  4478. if (len > 1 && p[len-2] == '/' && p[len-1] == '.') {
  4479. p[len-2] = '\0';
  4480. len -= 2;
  4481. }
  4482. if (len > 2 && p[len-3] == '/' && p[len-2] == '.' &&
  4483. p[len-1] == '.') {
  4484. p[len-3] = '\0';
  4485. len -= 3;
  4486. }
  4487. if (ll == len)
  4488. break;
  4489. }
  4490. while (*p) {
  4491. if (p[0] == '/') {
  4492. if (p[1] == '/')
  4493. /* Convert '//' --> '/' */
  4494. memmove(p, p+1, strlen(p+1) + 1);
  4495. else if (p[1] == '.' && p[2] == '/')
  4496. /* Convert '/./' --> '/' */
  4497. memmove(p, p+2, strlen(p+2) + 1);
  4498. else if (p[1] == '.' && p[2] == '.' && p[3] == '/') {
  4499. /* Convert 'dir/dir1/../dir2/'
  4500. * --> 'dir/dir2/'
  4501. */
  4502. char *rp = p -1;
  4503. while (rp >= dirname) {
  4504. if (*rp == '/')
  4505. break;
  4506. --rp;
  4507. }
  4508. if (rp > dirname) {
  4509. strcpy(rp, p+3);
  4510. p = rp;
  4511. } else {
  4512. strcpy(dirname, p+4);
  4513. p = dirname;
  4514. }
  4515. } else
  4516. p++;
  4517. } else
  4518. p++;
  4519. }
  4520. p = dirname;
  4521. len = strlen(p);
  4522. if (archive_entry_filetype(file->entry) == AE_IFLNK) {
  4523. /* Convert symlink name too. */
  4524. pathname = archive_entry_symlink(file->entry);
  4525. archive_strcpy(&(file->symlink), pathname);
  4526. #if defined(_WIN32) || defined(__CYGWIN__)
  4527. /*
  4528. * Convert a path-separator from '\' to '/'
  4529. */
  4530. if (archive_strlen(&(file->symlink)) > 0 &&
  4531. cleanup_backslash_1(file->symlink.s) != 0) {
  4532. const wchar_t *wp =
  4533. archive_entry_symlink_w(file->entry);
  4534. struct archive_wstring ws;
  4535. if (wp != NULL) {
  4536. int r;
  4537. archive_string_init(&ws);
  4538. archive_wstrcpy(&ws, wp);
  4539. cleanup_backslash_2(ws.s);
  4540. archive_string_empty(&(file->symlink));
  4541. r = archive_string_append_from_wcs(
  4542. &(file->symlink),
  4543. ws.s, ws.length);
  4544. archive_wstring_free(&ws);
  4545. if (r < 0 && errno == ENOMEM) {
  4546. archive_set_error(&a->archive, ENOMEM,
  4547. "Can't allocate memory");
  4548. return (ARCHIVE_FATAL);
  4549. }
  4550. }
  4551. }
  4552. #endif
  4553. }
  4554. /*
  4555. * - Count up directory elements.
  4556. * - Find out the position which points the last position of
  4557. * path separator('/').
  4558. */
  4559. slash = NULL;
  4560. file->dircnt = 0;
  4561. for (; *p != '\0'; p++)
  4562. if (*p == '/') {
  4563. slash = p;
  4564. file->dircnt++;
  4565. }
  4566. if (slash == NULL) {
  4567. /* The pathname doesn't have a parent directory. */
  4568. file->parentdir.length = len;
  4569. archive_string_copy(&(file->basename), &(file->parentdir));
  4570. archive_string_empty(&(file->parentdir));
  4571. *file->parentdir.s = '\0';
  4572. return (ret);
  4573. }
  4574. /* Make a basename from dirname and slash */
  4575. *slash = '\0';
  4576. file->parentdir.length = slash - dirname;
  4577. archive_strcpy(&(file->basename), slash + 1);
  4578. if (archive_entry_filetype(file->entry) == AE_IFDIR)
  4579. file->dircnt ++;
  4580. return (ret);
  4581. }
  4582. /*
  4583. * Register a entry to get a hardlink target.
  4584. */
  4585. static int
  4586. isofile_register_hardlink(struct archive_write *a, struct isofile *file)
  4587. {
  4588. struct iso9660 *iso9660 = a->format_data;
  4589. struct hardlink *hl;
  4590. const char *pathname;
  4591. archive_entry_set_nlink(file->entry, 1);
  4592. pathname = archive_entry_hardlink(file->entry);
  4593. if (pathname == NULL) {
  4594. /* This `file` is a hardlink target. */
  4595. hl = malloc(sizeof(*hl));
  4596. if (hl == NULL) {
  4597. archive_set_error(&a->archive, ENOMEM,
  4598. "Can't allocate memory");
  4599. return (ARCHIVE_FATAL);
  4600. }
  4601. hl->nlink = 1;
  4602. /* A hardlink target must be the first position. */
  4603. file->hlnext = NULL;
  4604. hl->file_list.first = file;
  4605. hl->file_list.last = &(file->hlnext);
  4606. __archive_rb_tree_insert_node(&(iso9660->hardlink_rbtree),
  4607. (struct archive_rb_node *)hl);
  4608. } else {
  4609. hl = (struct hardlink *)__archive_rb_tree_find_node(
  4610. &(iso9660->hardlink_rbtree), pathname);
  4611. if (hl != NULL) {
  4612. /* Insert `file` entry into the tail. */
  4613. file->hlnext = NULL;
  4614. *hl->file_list.last = file;
  4615. hl->file_list.last = &(file->hlnext);
  4616. hl->nlink++;
  4617. }
  4618. archive_entry_unset_size(file->entry);
  4619. }
  4620. return (ARCHIVE_OK);
  4621. }
  4622. /*
  4623. * Hardlinked files have to have the same location of extent.
  4624. * We have to find out hardlink target entries for the entries
  4625. * which have a hardlink target name.
  4626. */
  4627. static void
  4628. isofile_connect_hardlink_files(struct iso9660 *iso9660)
  4629. {
  4630. struct archive_rb_node *n;
  4631. struct hardlink *hl;
  4632. struct isofile *target, *nf;
  4633. ARCHIVE_RB_TREE_FOREACH(n, &(iso9660->hardlink_rbtree)) {
  4634. hl = (struct hardlink *)n;
  4635. /* The first entry must be a hardlink target. */
  4636. target = hl->file_list.first;
  4637. archive_entry_set_nlink(target->entry, hl->nlink);
  4638. /* Set a hardlink target to reference entries. */
  4639. for (nf = target->hlnext;
  4640. nf != NULL; nf = nf->hlnext) {
  4641. nf->hardlink_target = target;
  4642. archive_entry_set_nlink(nf->entry, hl->nlink);
  4643. }
  4644. }
  4645. }
  4646. static int
  4647. isofile_hd_cmp_node(const struct archive_rb_node *n1,
  4648. const struct archive_rb_node *n2)
  4649. {
  4650. const struct hardlink *h1 = (const struct hardlink *)n1;
  4651. const struct hardlink *h2 = (const struct hardlink *)n2;
  4652. return (strcmp(archive_entry_pathname(h1->file_list.first->entry),
  4653. archive_entry_pathname(h2->file_list.first->entry)));
  4654. }
  4655. static int
  4656. isofile_hd_cmp_key(const struct archive_rb_node *n, const void *key)
  4657. {
  4658. const struct hardlink *h = (const struct hardlink *)n;
  4659. return (strcmp(archive_entry_pathname(h->file_list.first->entry),
  4660. (const char *)key));
  4661. }
  4662. static void
  4663. isofile_init_hardlinks(struct iso9660 *iso9660)
  4664. {
  4665. static const struct archive_rb_tree_ops rb_ops = {
  4666. isofile_hd_cmp_node, isofile_hd_cmp_key,
  4667. };
  4668. __archive_rb_tree_init(&(iso9660->hardlink_rbtree), &rb_ops);
  4669. }
  4670. static void
  4671. isofile_free_hardlinks(struct iso9660 *iso9660)
  4672. {
  4673. struct archive_rb_node *n, *tmp;
  4674. ARCHIVE_RB_TREE_FOREACH_SAFE(n, &(iso9660->hardlink_rbtree), tmp) {
  4675. __archive_rb_tree_remove_node(&(iso9660->hardlink_rbtree), n);
  4676. free(n);
  4677. }
  4678. }
  4679. static struct isoent *
  4680. isoent_new(struct isofile *file)
  4681. {
  4682. struct isoent *isoent;
  4683. static const struct archive_rb_tree_ops rb_ops = {
  4684. isoent_cmp_node, isoent_cmp_key,
  4685. };
  4686. isoent = calloc(1, sizeof(*isoent));
  4687. if (isoent == NULL)
  4688. return (NULL);
  4689. isoent->file = file;
  4690. isoent->children.first = NULL;
  4691. isoent->children.last = &(isoent->children.first);
  4692. __archive_rb_tree_init(&(isoent->rbtree), &rb_ops);
  4693. isoent->subdirs.first = NULL;
  4694. isoent->subdirs.last = &(isoent->subdirs.first);
  4695. isoent->extr_rec_list.first = NULL;
  4696. isoent->extr_rec_list.last = &(isoent->extr_rec_list.first);
  4697. isoent->extr_rec_list.current = NULL;
  4698. if (archive_entry_filetype(file->entry) == AE_IFDIR)
  4699. isoent->dir = 1;
  4700. return (isoent);
  4701. }
  4702. static inline struct isoent *
  4703. isoent_clone(struct isoent *src)
  4704. {
  4705. return (isoent_new(src->file));
  4706. }
  4707. static void
  4708. _isoent_free(struct isoent *isoent)
  4709. {
  4710. struct extr_rec *er, *er_next;
  4711. free(isoent->children_sorted);
  4712. free(isoent->identifier);
  4713. er = isoent->extr_rec_list.first;
  4714. while (er != NULL) {
  4715. er_next = er->next;
  4716. free(er);
  4717. er = er_next;
  4718. }
  4719. free(isoent);
  4720. }
  4721. static void
  4722. isoent_free_all(struct isoent *isoent)
  4723. {
  4724. struct isoent *np, *np_temp;
  4725. if (isoent == NULL)
  4726. return;
  4727. np = isoent;
  4728. for (;;) {
  4729. if (np->dir) {
  4730. if (np->children.first != NULL) {
  4731. /* Enter to sub directories. */
  4732. np = np->children.first;
  4733. continue;
  4734. }
  4735. }
  4736. for (;;) {
  4737. np_temp = np;
  4738. if (np->chnext == NULL) {
  4739. /* Return to the parent directory. */
  4740. np = np->parent;
  4741. _isoent_free(np_temp);
  4742. if (np == np_temp)
  4743. return;
  4744. } else {
  4745. np = np->chnext;
  4746. _isoent_free(np_temp);
  4747. break;
  4748. }
  4749. }
  4750. }
  4751. }
  4752. static struct isoent *
  4753. isoent_create_virtual_dir(struct archive_write *a, struct iso9660 *iso9660, const char *pathname)
  4754. {
  4755. struct isofile *file;
  4756. struct isoent *isoent;
  4757. file = isofile_new(a, NULL);
  4758. if (file == NULL)
  4759. return (NULL);
  4760. archive_entry_set_pathname(file->entry, pathname);
  4761. archive_entry_unset_mtime(file->entry);
  4762. archive_entry_unset_atime(file->entry);
  4763. archive_entry_unset_ctime(file->entry);
  4764. archive_entry_set_uid(file->entry, getuid());
  4765. archive_entry_set_gid(file->entry, getgid());
  4766. archive_entry_set_mode(file->entry, 0555 | AE_IFDIR);
  4767. archive_entry_set_nlink(file->entry, 2);
  4768. if (isofile_gen_utility_names(a, file) < ARCHIVE_WARN) {
  4769. isofile_free(file);
  4770. return (NULL);
  4771. }
  4772. isofile_add_entry(iso9660, file);
  4773. isoent = isoent_new(file);
  4774. if (isoent == NULL)
  4775. return (NULL);
  4776. isoent->dir = 1;
  4777. isoent->virtual = 1;
  4778. return (isoent);
  4779. }
  4780. static int
  4781. isoent_cmp_node(const struct archive_rb_node *n1,
  4782. const struct archive_rb_node *n2)
  4783. {
  4784. const struct isoent *e1 = (const struct isoent *)n1;
  4785. const struct isoent *e2 = (const struct isoent *)n2;
  4786. return (strcmp(e1->file->basename.s, e2->file->basename.s));
  4787. }
  4788. static int
  4789. isoent_cmp_key(const struct archive_rb_node *n, const void *key)
  4790. {
  4791. const struct isoent *e = (const struct isoent *)n;
  4792. return (strcmp(e->file->basename.s, (const char *)key));
  4793. }
  4794. static int
  4795. isoent_add_child_head(struct isoent *parent, struct isoent *child)
  4796. {
  4797. if (!__archive_rb_tree_insert_node(
  4798. &(parent->rbtree), (struct archive_rb_node *)child))
  4799. return (0);
  4800. if ((child->chnext = parent->children.first) == NULL)
  4801. parent->children.last = &(child->chnext);
  4802. parent->children.first = child;
  4803. parent->children.cnt++;
  4804. child->parent = parent;
  4805. /* Add a child to a sub-directory chain */
  4806. if (child->dir) {
  4807. if ((child->drnext = parent->subdirs.first) == NULL)
  4808. parent->subdirs.last = &(child->drnext);
  4809. parent->subdirs.first = child;
  4810. parent->subdirs.cnt++;
  4811. child->parent = parent;
  4812. } else
  4813. child->drnext = NULL;
  4814. return (1);
  4815. }
  4816. static int
  4817. isoent_add_child_tail(struct isoent *parent, struct isoent *child)
  4818. {
  4819. if (!__archive_rb_tree_insert_node(
  4820. &(parent->rbtree), (struct archive_rb_node *)child))
  4821. return (0);
  4822. child->chnext = NULL;
  4823. *parent->children.last = child;
  4824. parent->children.last = &(child->chnext);
  4825. parent->children.cnt++;
  4826. child->parent = parent;
  4827. /* Add a child to a sub-directory chain */
  4828. child->drnext = NULL;
  4829. if (child->dir) {
  4830. *parent->subdirs.last = child;
  4831. parent->subdirs.last = &(child->drnext);
  4832. parent->subdirs.cnt++;
  4833. child->parent = parent;
  4834. }
  4835. return (1);
  4836. }
  4837. static void
  4838. isoent_remove_child(struct isoent *parent, struct isoent *child)
  4839. {
  4840. struct isoent *ent;
  4841. /* Remove a child entry from children chain. */
  4842. ent = parent->children.first;
  4843. while (ent->chnext != child)
  4844. ent = ent->chnext;
  4845. if ((ent->chnext = ent->chnext->chnext) == NULL)
  4846. parent->children.last = &(ent->chnext);
  4847. parent->children.cnt--;
  4848. if (child->dir) {
  4849. /* Remove a child entry from sub-directory chain. */
  4850. ent = parent->subdirs.first;
  4851. while (ent->drnext != child)
  4852. ent = ent->drnext;
  4853. if ((ent->drnext = ent->drnext->drnext) == NULL)
  4854. parent->subdirs.last = &(ent->drnext);
  4855. parent->subdirs.cnt--;
  4856. }
  4857. __archive_rb_tree_remove_node(&(parent->rbtree),
  4858. (struct archive_rb_node *)child);
  4859. }
  4860. static int
  4861. isoent_clone_tree(struct archive_write *a, struct isoent **nroot,
  4862. struct isoent *root)
  4863. {
  4864. struct isoent *np, *xroot, *newent;
  4865. np = root;
  4866. xroot = NULL;
  4867. do {
  4868. newent = isoent_clone(np);
  4869. if (newent == NULL) {
  4870. archive_set_error(&a->archive, ENOMEM,
  4871. "Can't allocate memory");
  4872. return (ARCHIVE_FATAL);
  4873. }
  4874. if (xroot == NULL) {
  4875. *nroot = xroot = newent;
  4876. newent->parent = xroot;
  4877. } else
  4878. isoent_add_child_tail(xroot, newent);
  4879. if (np->dir && np->children.first != NULL) {
  4880. /* Enter to sub directories. */
  4881. np = np->children.first;
  4882. xroot = newent;
  4883. continue;
  4884. }
  4885. while (np != np->parent) {
  4886. if (np->chnext == NULL) {
  4887. /* Return to the parent directory. */
  4888. np = np->parent;
  4889. xroot = xroot->parent;
  4890. } else {
  4891. np = np->chnext;
  4892. break;
  4893. }
  4894. }
  4895. } while (np != np->parent);
  4896. return (ARCHIVE_OK);
  4897. }
  4898. /*
  4899. * Setup directory locations.
  4900. */
  4901. static void
  4902. isoent_setup_directory_location(struct iso9660 *iso9660, int location,
  4903. struct vdd *vdd)
  4904. {
  4905. struct isoent *np;
  4906. int depth;
  4907. vdd->total_dir_block = 0;
  4908. depth = 0;
  4909. np = vdd->rootent;
  4910. do {
  4911. int block;
  4912. np->dir_block = calculate_directory_descriptors(
  4913. iso9660, vdd, np, depth);
  4914. vdd->total_dir_block += np->dir_block;
  4915. np->dir_location = location;
  4916. location += np->dir_block;
  4917. block = extra_setup_location(np, location);
  4918. vdd->total_dir_block += block;
  4919. location += block;
  4920. if (np->subdirs.first != NULL && depth + 1 < vdd->max_depth) {
  4921. /* Enter to sub directories. */
  4922. np = np->subdirs.first;
  4923. depth++;
  4924. continue;
  4925. }
  4926. while (np != np->parent) {
  4927. if (np->drnext == NULL) {
  4928. /* Return to the parent directory. */
  4929. np = np->parent;
  4930. depth--;
  4931. } else {
  4932. np = np->drnext;
  4933. break;
  4934. }
  4935. }
  4936. } while (np != np->parent);
  4937. }
  4938. static void
  4939. _isoent_file_location(struct iso9660 *iso9660, struct isoent *isoent,
  4940. int *symlocation)
  4941. {
  4942. struct isoent **children;
  4943. int n;
  4944. if (isoent->children.cnt == 0)
  4945. return;
  4946. children = isoent->children_sorted;
  4947. for (n = 0; n < isoent->children.cnt; n++) {
  4948. struct isoent *np;
  4949. struct isofile *file;
  4950. np = children[n];
  4951. if (np->dir)
  4952. continue;
  4953. if (np == iso9660->el_torito.boot)
  4954. continue;
  4955. file = np->file;
  4956. if (file->boot || file->hardlink_target != NULL)
  4957. continue;
  4958. if (archive_entry_filetype(file->entry) == AE_IFLNK ||
  4959. file->content.size == 0) {
  4960. /*
  4961. * Do not point a valid location.
  4962. * Make sure entry is not hardlink file.
  4963. */
  4964. file->content.location = (*symlocation)--;
  4965. continue;
  4966. }
  4967. file->write_content = 1;
  4968. }
  4969. }
  4970. /*
  4971. * Setup file locations.
  4972. */
  4973. static void
  4974. isoent_setup_file_location(struct iso9660 *iso9660, int location)
  4975. {
  4976. struct isoent *isoent;
  4977. struct isoent *np;
  4978. struct isofile *file;
  4979. size_t size;
  4980. int block;
  4981. int depth;
  4982. int joliet;
  4983. int symlocation;
  4984. int total_block;
  4985. iso9660->total_file_block = 0;
  4986. if ((isoent = iso9660->el_torito.catalog) != NULL) {
  4987. isoent->file->content.location = location;
  4988. block = (int)((archive_entry_size(isoent->file->entry) +
  4989. LOGICAL_BLOCK_SIZE -1) >> LOGICAL_BLOCK_BITS);
  4990. location += block;
  4991. iso9660->total_file_block += block;
  4992. }
  4993. if ((isoent = iso9660->el_torito.boot) != NULL) {
  4994. isoent->file->content.location = location;
  4995. size = fd_boot_image_size(iso9660->el_torito.media_type);
  4996. if (size == 0)
  4997. size = (size_t)archive_entry_size(isoent->file->entry);
  4998. block = ((int)size + LOGICAL_BLOCK_SIZE -1)
  4999. >> LOGICAL_BLOCK_BITS;
  5000. location += block;
  5001. iso9660->total_file_block += block;
  5002. isoent->file->content.blocks = block;
  5003. }
  5004. depth = 0;
  5005. symlocation = -16;
  5006. if (!iso9660->opt.rr && iso9660->opt.joliet) {
  5007. joliet = 1;
  5008. np = iso9660->joliet.rootent;
  5009. } else {
  5010. joliet = 0;
  5011. np = iso9660->primary.rootent;
  5012. }
  5013. do {
  5014. _isoent_file_location(iso9660, np, &symlocation);
  5015. if (np->subdirs.first != NULL &&
  5016. (joliet ||
  5017. ((iso9660->opt.rr == OPT_RR_DISABLED &&
  5018. depth + 2 < iso9660->primary.max_depth) ||
  5019. (iso9660->opt.rr &&
  5020. depth + 1 < iso9660->primary.max_depth)))) {
  5021. /* Enter to sub directories. */
  5022. np = np->subdirs.first;
  5023. depth++;
  5024. continue;
  5025. }
  5026. while (np != np->parent) {
  5027. if (np->drnext == NULL) {
  5028. /* Return to the parent directory. */
  5029. np = np->parent;
  5030. depth--;
  5031. } else {
  5032. np = np->drnext;
  5033. break;
  5034. }
  5035. }
  5036. } while (np != np->parent);
  5037. total_block = 0;
  5038. for (file = iso9660->data_file_list.first;
  5039. file != NULL; file = file->datanext) {
  5040. if (!file->write_content)
  5041. continue;
  5042. file->cur_content = &(file->content);
  5043. do {
  5044. file->cur_content->location = location;
  5045. location += file->cur_content->blocks;
  5046. total_block += file->cur_content->blocks;
  5047. /* Next fragment */
  5048. file->cur_content = file->cur_content->next;
  5049. } while (file->cur_content != NULL);
  5050. }
  5051. iso9660->total_file_block += total_block;
  5052. }
  5053. static int
  5054. get_path_component(char *name, size_t n, const char *fn)
  5055. {
  5056. char *p;
  5057. size_t l;
  5058. p = strchr(fn, '/');
  5059. if (p == NULL) {
  5060. if ((l = strlen(fn)) == 0)
  5061. return (0);
  5062. } else
  5063. l = p - fn;
  5064. if (l > n -1)
  5065. return (-1);
  5066. memcpy(name, fn, l);
  5067. name[l] = '\0';
  5068. return ((int)l);
  5069. }
  5070. /*
  5071. * Add a new entry into the tree.
  5072. */
  5073. static int
  5074. isoent_tree(struct archive_write *a, struct isoent **isoentpp)
  5075. {
  5076. #if defined(_WIN32) && !defined(__CYGWIN__)
  5077. char name[_MAX_FNAME];/* Included null terminator size. */
  5078. #elif defined(NAME_MAX) && NAME_MAX >= 255
  5079. char name[NAME_MAX+1];
  5080. #else
  5081. char name[256];
  5082. #endif
  5083. struct iso9660 *iso9660 = a->format_data;
  5084. struct isoent *dent, *isoent, *np;
  5085. struct isofile *f1, *f2;
  5086. const char *fn, *p;
  5087. int l;
  5088. isoent = *isoentpp;
  5089. dent = iso9660->primary.rootent;
  5090. if (isoent->file->parentdir.length > 0)
  5091. fn = p = isoent->file->parentdir.s;
  5092. else
  5093. fn = p = "";
  5094. /*
  5095. * If the path of the parent directory of `isoent' entry is
  5096. * the same as the path of `cur_dirent', add isoent to
  5097. * `cur_dirent'.
  5098. */
  5099. if (archive_strlen(&(iso9660->cur_dirstr))
  5100. == archive_strlen(&(isoent->file->parentdir)) &&
  5101. strcmp(iso9660->cur_dirstr.s, fn) == 0) {
  5102. if (!isoent_add_child_tail(iso9660->cur_dirent, isoent)) {
  5103. np = (struct isoent *)__archive_rb_tree_find_node(
  5104. &(iso9660->cur_dirent->rbtree),
  5105. isoent->file->basename.s);
  5106. goto same_entry;
  5107. }
  5108. return (ARCHIVE_OK);
  5109. }
  5110. for (;;) {
  5111. l = get_path_component(name, sizeof(name), fn);
  5112. if (l == 0) {
  5113. np = NULL;
  5114. break;
  5115. }
  5116. if (l < 0) {
  5117. archive_set_error(&a->archive,
  5118. ARCHIVE_ERRNO_MISC,
  5119. "A name buffer is too small");
  5120. _isoent_free(isoent);
  5121. return (ARCHIVE_FATAL);
  5122. }
  5123. np = isoent_find_child(dent, name);
  5124. if (np == NULL || fn[0] == '\0')
  5125. break;
  5126. /* Find next subdirectory. */
  5127. if (!np->dir) {
  5128. /* NOT Directory! */
  5129. archive_set_error(&a->archive,
  5130. ARCHIVE_ERRNO_MISC,
  5131. "`%s' is not directory, we cannot insert `%s' ",
  5132. archive_entry_pathname(np->file->entry),
  5133. archive_entry_pathname(isoent->file->entry));
  5134. _isoent_free(isoent);
  5135. *isoentpp = NULL;
  5136. return (ARCHIVE_FAILED);
  5137. }
  5138. fn += l;
  5139. if (fn[0] == '/')
  5140. fn++;
  5141. dent = np;
  5142. }
  5143. if (np == NULL) {
  5144. /*
  5145. * Create virtual parent directories.
  5146. */
  5147. while (fn[0] != '\0') {
  5148. struct isoent *vp;
  5149. struct archive_string as;
  5150. archive_string_init(&as);
  5151. archive_strncat(&as, p, fn - p + l);
  5152. if (as.s[as.length-1] == '/') {
  5153. as.s[as.length-1] = '\0';
  5154. as.length--;
  5155. }
  5156. vp = isoent_create_virtual_dir(a, iso9660, as.s);
  5157. if (vp == NULL) {
  5158. archive_string_free(&as);
  5159. archive_set_error(&a->archive, ENOMEM,
  5160. "Can't allocate memory");
  5161. _isoent_free(isoent);
  5162. *isoentpp = NULL;
  5163. return (ARCHIVE_FATAL);
  5164. }
  5165. archive_string_free(&as);
  5166. if (vp->file->dircnt > iso9660->dircnt_max)
  5167. iso9660->dircnt_max = vp->file->dircnt;
  5168. isoent_add_child_tail(dent, vp);
  5169. np = vp;
  5170. fn += l;
  5171. if (fn[0] == '/')
  5172. fn++;
  5173. l = get_path_component(name, sizeof(name), fn);
  5174. if (l < 0) {
  5175. archive_string_free(&as);
  5176. archive_set_error(&a->archive,
  5177. ARCHIVE_ERRNO_MISC,
  5178. "A name buffer is too small");
  5179. _isoent_free(isoent);
  5180. *isoentpp = NULL;
  5181. return (ARCHIVE_FATAL);
  5182. }
  5183. dent = np;
  5184. }
  5185. /* Found out the parent directory where isoent can be
  5186. * inserted. */
  5187. iso9660->cur_dirent = dent;
  5188. archive_string_empty(&(iso9660->cur_dirstr));
  5189. if (archive_string_ensure(&(iso9660->cur_dirstr),
  5190. archive_strlen(&(dent->file->parentdir)) +
  5191. archive_strlen(&(dent->file->basename)) + 2) == NULL) {
  5192. archive_set_error(&a->archive, ENOMEM,
  5193. "Can't allocate memory");
  5194. _isoent_free(isoent);
  5195. *isoentpp = NULL;
  5196. return (ARCHIVE_FATAL);
  5197. }
  5198. if (archive_strlen(&(dent->file->parentdir)) +
  5199. archive_strlen(&(dent->file->basename)) == 0)
  5200. iso9660->cur_dirstr.s[0] = 0;
  5201. else {
  5202. if (archive_strlen(&(dent->file->parentdir)) > 0) {
  5203. archive_string_copy(&(iso9660->cur_dirstr),
  5204. &(dent->file->parentdir));
  5205. archive_strappend_char(&(iso9660->cur_dirstr), '/');
  5206. }
  5207. archive_string_concat(&(iso9660->cur_dirstr),
  5208. &(dent->file->basename));
  5209. }
  5210. if (!isoent_add_child_tail(dent, isoent)) {
  5211. np = (struct isoent *)__archive_rb_tree_find_node(
  5212. &(dent->rbtree), isoent->file->basename.s);
  5213. goto same_entry;
  5214. }
  5215. return (ARCHIVE_OK);
  5216. }
  5217. same_entry:
  5218. /*
  5219. * We have already has the entry the filename of which is
  5220. * the same.
  5221. */
  5222. f1 = np->file;
  5223. f2 = isoent->file;
  5224. /* If the file type of entries is different,
  5225. * we cannot handle it. */
  5226. if (archive_entry_filetype(f1->entry) !=
  5227. archive_entry_filetype(f2->entry)) {
  5228. archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
  5229. "Found duplicate entries `%s' and its file type is "
  5230. "different",
  5231. archive_entry_pathname(f1->entry));
  5232. _isoent_free(isoent);
  5233. *isoentpp = NULL;
  5234. return (ARCHIVE_FAILED);
  5235. }
  5236. /* Swap file entries. */
  5237. np->file = f2;
  5238. isoent->file = f1;
  5239. np->virtual = 0;
  5240. _isoent_free(isoent);
  5241. *isoentpp = np;
  5242. return (ARCHIVE_OK);
  5243. }
  5244. /*
  5245. * Find a entry from `isoent'
  5246. */
  5247. static struct isoent *
  5248. isoent_find_child(struct isoent *isoent, const char *child_name)
  5249. {
  5250. struct isoent *np;
  5251. np = (struct isoent *)__archive_rb_tree_find_node(
  5252. &(isoent->rbtree), child_name);
  5253. return (np);
  5254. }
  5255. /*
  5256. * Find a entry full-path of which is specified by `fn' parameter,
  5257. * in the tree.
  5258. */
  5259. static struct isoent *
  5260. isoent_find_entry(struct isoent *rootent, const char *fn)
  5261. {
  5262. #if defined(_WIN32) && !defined(__CYGWIN__)
  5263. char name[_MAX_FNAME];/* Included null terminator size. */
  5264. #elif defined(NAME_MAX) && NAME_MAX >= 255
  5265. char name[NAME_MAX+1];
  5266. #else
  5267. char name[256];
  5268. #endif
  5269. struct isoent *isoent, *np;
  5270. int l;
  5271. isoent = rootent;
  5272. np = NULL;
  5273. for (;;) {
  5274. l = get_path_component(name, sizeof(name), fn);
  5275. if (l == 0)
  5276. break;
  5277. fn += l;
  5278. if (fn[0] == '/')
  5279. fn++;
  5280. np = isoent_find_child(isoent, name);
  5281. if (np == NULL)
  5282. break;
  5283. if (fn[0] == '\0')
  5284. break;/* We found out the entry */
  5285. /* Try sub directory. */
  5286. isoent = np;
  5287. np = NULL;
  5288. if (!isoent->dir)
  5289. break;/* Not directory */
  5290. }
  5291. return (np);
  5292. }
  5293. /*
  5294. * Following idr_* functions are used for resolving duplicated filenames
  5295. * and unreceivable filenames to generate ISO9660/Joliet Identifiers.
  5296. */
  5297. static void
  5298. idr_relaxed_filenames(char *map)
  5299. {
  5300. int i;
  5301. for (i = 0x21; i <= 0x2F; i++)
  5302. map[i] = 1;
  5303. for (i = 0x3A; i <= 0x41; i++)
  5304. map[i] = 1;
  5305. for (i = 0x5B; i <= 0x5E; i++)
  5306. map[i] = 1;
  5307. map[0x60] = 1;
  5308. for (i = 0x7B; i <= 0x7E; i++)
  5309. map[i] = 1;
  5310. }
  5311. static void
  5312. idr_init(struct iso9660 *iso9660, struct vdd *vdd, struct idr *idr)
  5313. {
  5314. idr->idrent_pool = NULL;
  5315. idr->pool_size = 0;
  5316. if (vdd->vdd_type != VDD_JOLIET) {
  5317. if (iso9660->opt.iso_level <= 3) {
  5318. memcpy(idr->char_map, d_characters_map,
  5319. sizeof(idr->char_map));
  5320. } else {
  5321. memcpy(idr->char_map, d1_characters_map,
  5322. sizeof(idr->char_map));
  5323. idr_relaxed_filenames(idr->char_map);
  5324. }
  5325. }
  5326. }
  5327. static void
  5328. idr_cleanup(struct idr *idr)
  5329. {
  5330. free(idr->idrent_pool);
  5331. }
  5332. static int
  5333. idr_ensure_poolsize(struct archive_write *a, struct idr *idr,
  5334. int cnt)
  5335. {
  5336. if (idr->pool_size < cnt) {
  5337. void *p;
  5338. const int bk = (1 << 7) - 1;
  5339. int psize;
  5340. psize = (cnt + bk) & ~bk;
  5341. p = realloc(idr->idrent_pool, sizeof(struct idrent) * psize);
  5342. if (p == NULL) {
  5343. archive_set_error(&a->archive, ENOMEM,
  5344. "Can't allocate memory");
  5345. return (ARCHIVE_FATAL);
  5346. }
  5347. idr->idrent_pool = (struct idrent *)p;
  5348. idr->pool_size = psize;
  5349. }
  5350. return (ARCHIVE_OK);
  5351. }
  5352. static int
  5353. idr_start(struct archive_write *a, struct idr *idr, int cnt, int ffmax,
  5354. int num_size, int null_size, const struct archive_rb_tree_ops *rbt_ops)
  5355. {
  5356. int r;
  5357. (void)ffmax; /* UNUSED */
  5358. r = idr_ensure_poolsize(a, idr, cnt);
  5359. if (r != ARCHIVE_OK)
  5360. return (r);
  5361. __archive_rb_tree_init(&(idr->rbtree), rbt_ops);
  5362. idr->wait_list.first = NULL;
  5363. idr->wait_list.last = &(idr->wait_list.first);
  5364. idr->pool_idx = 0;
  5365. idr->num_size = num_size;
  5366. idr->null_size = null_size;
  5367. return (ARCHIVE_OK);
  5368. }
  5369. static void
  5370. idr_register(struct idr *idr, struct isoent *isoent, int weight, int noff)
  5371. {
  5372. struct idrent *idrent, *n;
  5373. idrent = &(idr->idrent_pool[idr->pool_idx++]);
  5374. idrent->wnext = idrent->avail = NULL;
  5375. idrent->isoent = isoent;
  5376. idrent->weight = weight;
  5377. idrent->noff = noff;
  5378. idrent->rename_num = 0;
  5379. if (!__archive_rb_tree_insert_node(&(idr->rbtree), &(idrent->rbnode))) {
  5380. n = (struct idrent *)__archive_rb_tree_find_node(
  5381. &(idr->rbtree), idrent->isoent);
  5382. if (n != NULL) {
  5383. /* this `idrent' needs to rename. */
  5384. idrent->avail = n;
  5385. *idr->wait_list.last = idrent;
  5386. idr->wait_list.last = &(idrent->wnext);
  5387. }
  5388. }
  5389. }
  5390. static void
  5391. idr_extend_identifier(struct idrent *wnp, int numsize, int nullsize)
  5392. {
  5393. unsigned char *p;
  5394. int wnp_ext_off;
  5395. wnp_ext_off = wnp->isoent->ext_off;
  5396. if (wnp->noff + numsize != wnp_ext_off) {
  5397. p = (unsigned char *)wnp->isoent->identifier;
  5398. /* Extend the filename; foo.c --> foo___.c */
  5399. memmove(p + wnp->noff + numsize, p + wnp_ext_off,
  5400. wnp->isoent->ext_len + nullsize);
  5401. wnp->isoent->ext_off = wnp_ext_off = wnp->noff + numsize;
  5402. wnp->isoent->id_len = wnp_ext_off + wnp->isoent->ext_len;
  5403. }
  5404. }
  5405. static void
  5406. idr_resolve(struct idr *idr, void (*fsetnum)(unsigned char *p, int num))
  5407. {
  5408. struct idrent *n;
  5409. unsigned char *p;
  5410. for (n = idr->wait_list.first; n != NULL; n = n->wnext) {
  5411. idr_extend_identifier(n, idr->num_size, idr->null_size);
  5412. p = (unsigned char *)n->isoent->identifier + n->noff;
  5413. do {
  5414. fsetnum(p, n->avail->rename_num++);
  5415. } while (!__archive_rb_tree_insert_node(
  5416. &(idr->rbtree), &(n->rbnode)));
  5417. }
  5418. }
  5419. static void
  5420. idr_set_num(unsigned char *p, int num)
  5421. {
  5422. static const char xdig[] = {
  5423. '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
  5424. 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
  5425. 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
  5426. 'U', 'V', 'W', 'X', 'Y', 'Z'
  5427. };
  5428. num %= sizeof(xdig) * sizeof(xdig) * sizeof(xdig);
  5429. p[0] = xdig[(num / (sizeof(xdig) * sizeof(xdig)))];
  5430. num %= sizeof(xdig) * sizeof(xdig);
  5431. p[1] = xdig[ (num / sizeof(xdig))];
  5432. num %= sizeof(xdig);
  5433. p[2] = xdig[num];
  5434. }
  5435. static void
  5436. idr_set_num_beutf16(unsigned char *p, int num)
  5437. {
  5438. static const uint16_t xdig[] = {
  5439. 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035,
  5440. 0x0036, 0x0037, 0x0038, 0x0039,
  5441. 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046,
  5442. 0x0047, 0x0048, 0x0049, 0x004A, 0x004B, 0x004C,
  5443. 0x004D, 0x004E, 0x004F, 0x0050, 0x0051, 0x0052,
  5444. 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058,
  5445. 0x0059, 0x005A
  5446. };
  5447. #define XDIG_CNT (sizeof(xdig)/sizeof(xdig[0]))
  5448. num %= XDIG_CNT * XDIG_CNT * XDIG_CNT;
  5449. archive_be16enc(p, xdig[(num / (XDIG_CNT * XDIG_CNT))]);
  5450. num %= XDIG_CNT * XDIG_CNT;
  5451. archive_be16enc(p+2, xdig[ (num / XDIG_CNT)]);
  5452. num %= XDIG_CNT;
  5453. archive_be16enc(p+4, xdig[num]);
  5454. }
  5455. /*
  5456. * Generate ISO9660 Identifier.
  5457. */
  5458. static int
  5459. isoent_gen_iso9660_identifier(struct archive_write *a, struct isoent *isoent,
  5460. struct idr *idr)
  5461. {
  5462. struct iso9660 *iso9660;
  5463. struct isoent *np;
  5464. char *p;
  5465. int l, r;
  5466. const char *char_map;
  5467. char allow_ldots, allow_multidot, allow_period, allow_vernum;
  5468. int fnmax, ffmax, dnmax;
  5469. static const struct archive_rb_tree_ops rb_ops = {
  5470. isoent_cmp_node_iso9660, isoent_cmp_key_iso9660
  5471. };
  5472. if (isoent->children.cnt == 0)
  5473. return (0);
  5474. iso9660 = a->format_data;
  5475. char_map = idr->char_map;
  5476. if (iso9660->opt.iso_level <= 3) {
  5477. allow_ldots = 0;
  5478. allow_multidot = 0;
  5479. allow_period = 1;
  5480. allow_vernum = iso9660->opt.allow_vernum;
  5481. if (iso9660->opt.iso_level == 1) {
  5482. fnmax = 8;
  5483. ffmax = 12;/* fnmax + '.' + 3 */
  5484. dnmax = 8;
  5485. } else {
  5486. fnmax = 30;
  5487. ffmax = 31;
  5488. dnmax = 31;
  5489. }
  5490. } else {
  5491. allow_ldots = allow_multidot = 1;
  5492. allow_period = allow_vernum = 0;
  5493. if (iso9660->opt.rr)
  5494. /*
  5495. * MDR : The maximum size of Directory Record(254).
  5496. * DRL : A Directory Record Length(33).
  5497. * CE : A size of SUSP CE System Use Entry(28).
  5498. * MDR - DRL - CE = 254 - 33 - 28 = 193.
  5499. */
  5500. fnmax = ffmax = dnmax = 193;
  5501. else
  5502. /*
  5503. * XA : CD-ROM XA System Use Extension
  5504. * Information(14).
  5505. * MDR - DRL - XA = 254 - 33 -14 = 207.
  5506. */
  5507. fnmax = ffmax = dnmax = 207;
  5508. }
  5509. r = idr_start(a, idr, isoent->children.cnt, ffmax, 3, 1, &rb_ops);
  5510. if (r < 0)
  5511. return (r);
  5512. for (np = isoent->children.first; np != NULL; np = np->chnext) {
  5513. char *dot, *xdot;
  5514. int ext_off, noff, weight;
  5515. l = (int)np->file->basename.length;
  5516. p = malloc(l+31+2+1);
  5517. if (p == NULL) {
  5518. archive_set_error(&a->archive, ENOMEM,
  5519. "Can't allocate memory");
  5520. return (ARCHIVE_FATAL);
  5521. }
  5522. memcpy(p, np->file->basename.s, l);
  5523. p[l] = '\0';
  5524. np->identifier = p;
  5525. dot = xdot = NULL;
  5526. if (!allow_ldots) {
  5527. /*
  5528. * If there is a '.' character at the first byte,
  5529. * it has to be replaced by '_' character.
  5530. */
  5531. if (*p == '.')
  5532. *p++ = '_';
  5533. }
  5534. for (;*p; p++) {
  5535. if (*p & 0x80) {
  5536. *p = '_';
  5537. continue;
  5538. }
  5539. if (char_map[(unsigned char)*p]) {
  5540. /* if iso-level is '4', a character '.' is
  5541. * allowed by char_map. */
  5542. if (*p == '.') {
  5543. xdot = dot;
  5544. dot = p;
  5545. }
  5546. continue;
  5547. }
  5548. if (*p >= 'a' && *p <= 'z') {
  5549. *p -= 'a' - 'A';
  5550. continue;
  5551. }
  5552. if (*p == '.') {
  5553. xdot = dot;
  5554. dot = p;
  5555. if (allow_multidot)
  5556. continue;
  5557. }
  5558. *p = '_';
  5559. }
  5560. p = np->identifier;
  5561. weight = -1;
  5562. if (dot == NULL) {
  5563. int nammax;
  5564. if (np->dir)
  5565. nammax = dnmax;
  5566. else
  5567. nammax = fnmax;
  5568. if (l > nammax) {
  5569. p[nammax] = '\0';
  5570. weight = nammax;
  5571. ext_off = nammax;
  5572. } else
  5573. ext_off = l;
  5574. } else {
  5575. *dot = '.';
  5576. ext_off = (int)(dot - p);
  5577. if (iso9660->opt.iso_level == 1) {
  5578. if (dot - p <= 8) {
  5579. if (strlen(dot) > 4) {
  5580. /* A length of a file extension
  5581. * must be less than 4 */
  5582. dot[4] = '\0';
  5583. weight = 0;
  5584. }
  5585. } else {
  5586. p[8] = dot[0];
  5587. p[9] = dot[1];
  5588. p[10] = dot[2];
  5589. p[11] = dot[3];
  5590. p[12] = '\0';
  5591. weight = 8;
  5592. ext_off = 8;
  5593. }
  5594. } else if (np->dir) {
  5595. if (l > dnmax) {
  5596. p[dnmax] = '\0';
  5597. weight = dnmax;
  5598. if (ext_off > dnmax)
  5599. ext_off = dnmax;
  5600. }
  5601. } else if (l > ffmax) {
  5602. int extlen = (int)strlen(dot);
  5603. int xdoff;
  5604. if (xdot != NULL)
  5605. xdoff = (int)(xdot - p);
  5606. else
  5607. xdoff = 0;
  5608. if (extlen > 1 && xdoff < fnmax-1) {
  5609. int off;
  5610. if (extlen > ffmax)
  5611. extlen = ffmax;
  5612. off = ffmax - extlen;
  5613. if (off == 0) {
  5614. /* A dot('.') character
  5615. * doesn't place to the first
  5616. * byte of identifier. */
  5617. off ++;
  5618. extlen --;
  5619. }
  5620. memmove(p+off, dot, extlen);
  5621. p[ffmax] = '\0';
  5622. ext_off = off;
  5623. weight = off;
  5624. #ifdef COMPAT_MKISOFS
  5625. } else if (xdoff >= fnmax-1) {
  5626. /* Simulate a bug(?) of mkisofs. */
  5627. p[fnmax-1] = '\0';
  5628. ext_off = fnmax-1;
  5629. weight = fnmax-1;
  5630. #endif
  5631. } else {
  5632. p[fnmax] = '\0';
  5633. ext_off = fnmax;
  5634. weight = fnmax;
  5635. }
  5636. }
  5637. }
  5638. /* Save an offset of a file name extension to sort files. */
  5639. np->ext_off = ext_off;
  5640. np->ext_len = (int)strlen(&p[ext_off]);
  5641. np->id_len = l = ext_off + np->ext_len;
  5642. /* Make an offset of the number which is used to be set
  5643. * hexadecimal number to avoid duplicate identifier. */
  5644. if (iso9660->opt.iso_level == 1) {
  5645. if (ext_off >= 5)
  5646. noff = 5;
  5647. else
  5648. noff = ext_off;
  5649. } else {
  5650. if (l == ffmax)
  5651. noff = ext_off - 3;
  5652. else if (l == ffmax-1)
  5653. noff = ext_off - 2;
  5654. else if (l == ffmax-2)
  5655. noff = ext_off - 1;
  5656. else
  5657. noff = ext_off;
  5658. }
  5659. /* Register entry to the identifier resolver. */
  5660. idr_register(idr, np, weight, noff);
  5661. }
  5662. /* Resolve duplicate identifier. */
  5663. idr_resolve(idr, idr_set_num);
  5664. /* Add a period and a version number to identifiers. */
  5665. for (np = isoent->children.first; np != NULL; np = np->chnext) {
  5666. if (!np->dir && np->rr_child == NULL) {
  5667. p = np->identifier + np->ext_off + np->ext_len;
  5668. if (np->ext_len == 0 && allow_period) {
  5669. *p++ = '.';
  5670. np->ext_len = 1;
  5671. }
  5672. if (np->ext_len == 1 && !allow_period) {
  5673. *--p = '\0';
  5674. np->ext_len = 0;
  5675. }
  5676. np->id_len = np->ext_off + np->ext_len;
  5677. if (allow_vernum) {
  5678. *p++ = ';';
  5679. *p++ = '1';
  5680. np->id_len += 2;
  5681. }
  5682. *p = '\0';
  5683. } else
  5684. np->id_len = np->ext_off + np->ext_len;
  5685. np->mb_len = np->id_len;
  5686. }
  5687. return (ARCHIVE_OK);
  5688. }
  5689. /*
  5690. * Generate Joliet Identifier.
  5691. */
  5692. static int
  5693. isoent_gen_joliet_identifier(struct archive_write *a, struct isoent *isoent,
  5694. struct idr *idr)
  5695. {
  5696. struct iso9660 *iso9660;
  5697. struct isoent *np;
  5698. unsigned char *p;
  5699. size_t l;
  5700. int r;
  5701. size_t ffmax, parent_len;
  5702. static const struct archive_rb_tree_ops rb_ops = {
  5703. isoent_cmp_node_joliet, isoent_cmp_key_joliet
  5704. };
  5705. if (isoent->children.cnt == 0)
  5706. return (0);
  5707. iso9660 = a->format_data;
  5708. if (iso9660->opt.joliet == OPT_JOLIET_LONGNAME)
  5709. ffmax = 206;
  5710. else
  5711. ffmax = 128;
  5712. r = idr_start(a, idr, isoent->children.cnt, (int)ffmax, 6, 2, &rb_ops);
  5713. if (r < 0)
  5714. return (r);
  5715. parent_len = 1;
  5716. for (np = isoent; np->parent != np; np = np->parent)
  5717. parent_len += np->mb_len + 1;
  5718. for (np = isoent->children.first; np != NULL; np = np->chnext) {
  5719. unsigned char *dot;
  5720. int ext_off, noff, weight;
  5721. size_t lt;
  5722. if ((l = np->file->basename_utf16.length) > ffmax)
  5723. l = ffmax;
  5724. p = malloc((l+1)*2);
  5725. if (p == NULL) {
  5726. archive_set_error(&a->archive, ENOMEM,
  5727. "Can't allocate memory");
  5728. return (ARCHIVE_FATAL);
  5729. }
  5730. memcpy(p, np->file->basename_utf16.s, l);
  5731. p[l] = 0;
  5732. p[l+1] = 0;
  5733. np->identifier = (char *)p;
  5734. lt = l;
  5735. dot = p + l;
  5736. weight = 0;
  5737. while (lt > 0) {
  5738. if (!joliet_allowed_char(p[0], p[1]))
  5739. archive_be16enc(p, 0x005F); /* '_' */
  5740. else if (p[0] == 0 && p[1] == 0x2E) /* '.' */
  5741. dot = p;
  5742. p += 2;
  5743. lt -= 2;
  5744. }
  5745. ext_off = (int)(dot - (unsigned char *)np->identifier);
  5746. np->ext_off = ext_off;
  5747. np->ext_len = (int)l - ext_off;
  5748. np->id_len = (int)l;
  5749. /*
  5750. * Get a length of MBS of a full-pathname.
  5751. */
  5752. if (np->file->basename_utf16.length > ffmax) {
  5753. if (archive_strncpy_l(&iso9660->mbs,
  5754. (const char *)np->identifier, l,
  5755. iso9660->sconv_from_utf16be) != 0 &&
  5756. errno == ENOMEM) {
  5757. archive_set_error(&a->archive, errno,
  5758. "No memory");
  5759. return (ARCHIVE_FATAL);
  5760. }
  5761. np->mb_len = (int)iso9660->mbs.length;
  5762. if (np->mb_len != (int)np->file->basename.length)
  5763. weight = np->mb_len;
  5764. } else
  5765. np->mb_len = (int)np->file->basename.length;
  5766. /* If a length of full-pathname is longer than 240 bytes,
  5767. * it violates Joliet extensions regulation. */
  5768. if (parent_len > 240
  5769. || np->mb_len > 240
  5770. || parent_len + np->mb_len > 240) {
  5771. archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
  5772. "The regulation of Joliet extensions;"
  5773. " A length of a full-pathname of `%s' is "
  5774. "longer than 240 bytes, (p=%d, b=%d)",
  5775. archive_entry_pathname(np->file->entry),
  5776. (int)parent_len, (int)np->mb_len);
  5777. return (ARCHIVE_FATAL);
  5778. }
  5779. /* Make an offset of the number which is used to be set
  5780. * hexadecimal number to avoid duplicate identifier. */
  5781. if (l == ffmax)
  5782. noff = ext_off - 6;
  5783. else if (l == ffmax-2)
  5784. noff = ext_off - 4;
  5785. else if (l == ffmax-4)
  5786. noff = ext_off - 2;
  5787. else
  5788. noff = ext_off;
  5789. /* Register entry to the identifier resolver. */
  5790. idr_register(idr, np, weight, noff);
  5791. }
  5792. /* Resolve duplicate identifier with Joliet Volume. */
  5793. idr_resolve(idr, idr_set_num_beutf16);
  5794. return (ARCHIVE_OK);
  5795. }
  5796. /*
  5797. * This comparing rule is according to ISO9660 Standard 9.3
  5798. */
  5799. static int
  5800. isoent_cmp_iso9660_identifier(const struct isoent *p1, const struct isoent *p2)
  5801. {
  5802. const char *s1, *s2;
  5803. int cmp;
  5804. int l;
  5805. s1 = p1->identifier;
  5806. s2 = p2->identifier;
  5807. /* Compare File Name */
  5808. l = p1->ext_off;
  5809. if (l > p2->ext_off)
  5810. l = p2->ext_off;
  5811. cmp = memcmp(s1, s2, l);
  5812. if (cmp != 0)
  5813. return (cmp);
  5814. if (p1->ext_off < p2->ext_off) {
  5815. s2 += l;
  5816. l = p2->ext_off - p1->ext_off;
  5817. while (l--)
  5818. if (0x20 != *s2++)
  5819. return (0x20
  5820. - *(const unsigned char *)(s2 - 1));
  5821. } else if (p1->ext_off > p2->ext_off) {
  5822. s1 += l;
  5823. l = p1->ext_off - p2->ext_off;
  5824. while (l--)
  5825. if (0x20 != *s1++)
  5826. return (*(const unsigned char *)(s1 - 1)
  5827. - 0x20);
  5828. }
  5829. /* Compare File Name Extension */
  5830. if (p1->ext_len == 0 && p2->ext_len == 0)
  5831. return (0);
  5832. if (p1->ext_len == 1 && p2->ext_len == 1)
  5833. return (0);
  5834. if (p1->ext_len <= 1)
  5835. return (-1);
  5836. if (p2->ext_len <= 1)
  5837. return (1);
  5838. l = p1->ext_len;
  5839. if (l > p2->ext_len)
  5840. l = p2->ext_len;
  5841. s1 = p1->identifier + p1->ext_off;
  5842. s2 = p2->identifier + p2->ext_off;
  5843. if (l > 1) {
  5844. cmp = memcmp(s1, s2, l);
  5845. if (cmp != 0)
  5846. return (cmp);
  5847. }
  5848. if (p1->ext_len < p2->ext_len) {
  5849. s2 += l;
  5850. l = p2->ext_len - p1->ext_len;
  5851. while (l--)
  5852. if (0x20 != *s2++)
  5853. return (0x20
  5854. - *(const unsigned char *)(s2 - 1));
  5855. } else if (p1->ext_len > p2->ext_len) {
  5856. s1 += l;
  5857. l = p1->ext_len - p2->ext_len;
  5858. while (l--)
  5859. if (0x20 != *s1++)
  5860. return (*(const unsigned char *)(s1 - 1)
  5861. - 0x20);
  5862. }
  5863. /* Compare File Version Number */
  5864. /* No operation. The File Version Number is always one. */
  5865. return (cmp);
  5866. }
  5867. static int
  5868. isoent_cmp_node_iso9660(const struct archive_rb_node *n1,
  5869. const struct archive_rb_node *n2)
  5870. {
  5871. const struct idrent *e1 = (const struct idrent *)n1;
  5872. const struct idrent *e2 = (const struct idrent *)n2;
  5873. return (isoent_cmp_iso9660_identifier(e2->isoent, e1->isoent));
  5874. }
  5875. static int
  5876. isoent_cmp_key_iso9660(const struct archive_rb_node *node, const void *key)
  5877. {
  5878. const struct isoent *isoent = (const struct isoent *)key;
  5879. const struct idrent *idrent = (const struct idrent *)node;
  5880. return (isoent_cmp_iso9660_identifier(isoent, idrent->isoent));
  5881. }
  5882. static int
  5883. isoent_cmp_joliet_identifier(const struct isoent *p1, const struct isoent *p2)
  5884. {
  5885. const unsigned char *s1, *s2;
  5886. int cmp;
  5887. int l;
  5888. s1 = (const unsigned char *)p1->identifier;
  5889. s2 = (const unsigned char *)p2->identifier;
  5890. /* Compare File Name */
  5891. l = p1->ext_off;
  5892. if (l > p2->ext_off)
  5893. l = p2->ext_off;
  5894. cmp = memcmp(s1, s2, l);
  5895. if (cmp != 0)
  5896. return (cmp);
  5897. if (p1->ext_off < p2->ext_off) {
  5898. s2 += l;
  5899. l = p2->ext_off - p1->ext_off;
  5900. while (l--)
  5901. if (0 != *s2++)
  5902. return (- *(const unsigned char *)(s2 - 1));
  5903. } else if (p1->ext_off > p2->ext_off) {
  5904. s1 += l;
  5905. l = p1->ext_off - p2->ext_off;
  5906. while (l--)
  5907. if (0 != *s1++)
  5908. return (*(const unsigned char *)(s1 - 1));
  5909. }
  5910. /* Compare File Name Extension */
  5911. if (p1->ext_len == 0 && p2->ext_len == 0)
  5912. return (0);
  5913. if (p1->ext_len == 2 && p2->ext_len == 2)
  5914. return (0);
  5915. if (p1->ext_len <= 2)
  5916. return (-1);
  5917. if (p2->ext_len <= 2)
  5918. return (1);
  5919. l = p1->ext_len;
  5920. if (l > p2->ext_len)
  5921. l = p2->ext_len;
  5922. s1 = (unsigned char *)(p1->identifier + p1->ext_off);
  5923. s2 = (unsigned char *)(p2->identifier + p2->ext_off);
  5924. if (l > 1) {
  5925. cmp = memcmp(s1, s2, l);
  5926. if (cmp != 0)
  5927. return (cmp);
  5928. }
  5929. if (p1->ext_len < p2->ext_len) {
  5930. s2 += l;
  5931. l = p2->ext_len - p1->ext_len;
  5932. while (l--)
  5933. if (0 != *s2++)
  5934. return (- *(const unsigned char *)(s2 - 1));
  5935. } else if (p1->ext_len > p2->ext_len) {
  5936. s1 += l;
  5937. l = p1->ext_len - p2->ext_len;
  5938. while (l--)
  5939. if (0 != *s1++)
  5940. return (*(const unsigned char *)(s1 - 1));
  5941. }
  5942. /* Compare File Version Number */
  5943. /* No operation. The File Version Number is always one. */
  5944. return (cmp);
  5945. }
  5946. static int
  5947. isoent_cmp_node_joliet(const struct archive_rb_node *n1,
  5948. const struct archive_rb_node *n2)
  5949. {
  5950. const struct idrent *e1 = (const struct idrent *)n1;
  5951. const struct idrent *e2 = (const struct idrent *)n2;
  5952. return (isoent_cmp_joliet_identifier(e2->isoent, e1->isoent));
  5953. }
  5954. static int
  5955. isoent_cmp_key_joliet(const struct archive_rb_node *node, const void *key)
  5956. {
  5957. const struct isoent *isoent = (const struct isoent *)key;
  5958. const struct idrent *idrent = (const struct idrent *)node;
  5959. return (isoent_cmp_joliet_identifier(isoent, idrent->isoent));
  5960. }
  5961. static int
  5962. isoent_make_sorted_files(struct archive_write *a, struct isoent *isoent,
  5963. struct idr *idr)
  5964. {
  5965. struct archive_rb_node *rn;
  5966. struct isoent **children;
  5967. children = malloc(isoent->children.cnt * sizeof(struct isoent *));
  5968. if (children == NULL) {
  5969. archive_set_error(&a->archive, ENOMEM,
  5970. "Can't allocate memory");
  5971. return (ARCHIVE_FATAL);
  5972. }
  5973. isoent->children_sorted = children;
  5974. ARCHIVE_RB_TREE_FOREACH(rn, &(idr->rbtree)) {
  5975. struct idrent *idrent = (struct idrent *)rn;
  5976. *children ++ = idrent->isoent;
  5977. }
  5978. return (ARCHIVE_OK);
  5979. }
  5980. /*
  5981. * - Generate ISO9660 and Joliet identifiers from basenames.
  5982. * - Sort files by each directory.
  5983. */
  5984. static int
  5985. isoent_traverse_tree(struct archive_write *a, struct vdd* vdd)
  5986. {
  5987. struct iso9660 *iso9660 = a->format_data;
  5988. struct isoent *np;
  5989. struct idr idr;
  5990. int depth;
  5991. int r;
  5992. int (*genid)(struct archive_write *, struct isoent *, struct idr *);
  5993. idr_init(iso9660, vdd, &idr);
  5994. np = vdd->rootent;
  5995. depth = 0;
  5996. if (vdd->vdd_type == VDD_JOLIET)
  5997. genid = isoent_gen_joliet_identifier;
  5998. else
  5999. genid = isoent_gen_iso9660_identifier;
  6000. do {
  6001. if (np->virtual &&
  6002. !archive_entry_mtime_is_set(np->file->entry)) {
  6003. /* Set properly times to virtual directory */
  6004. archive_entry_set_mtime(np->file->entry,
  6005. iso9660->birth_time, 0);
  6006. archive_entry_set_atime(np->file->entry,
  6007. iso9660->birth_time, 0);
  6008. archive_entry_set_ctime(np->file->entry,
  6009. iso9660->birth_time, 0);
  6010. }
  6011. if (np->children.first != NULL) {
  6012. if (vdd->vdd_type != VDD_JOLIET &&
  6013. !iso9660->opt.rr && depth + 1 >= vdd->max_depth) {
  6014. if (np->children.cnt > 0)
  6015. iso9660->directories_too_deep = np;
  6016. } else {
  6017. /* Generate Identifier */
  6018. r = genid(a, np, &idr);
  6019. if (r < 0)
  6020. goto exit_traverse_tree;
  6021. r = isoent_make_sorted_files(a, np, &idr);
  6022. if (r < 0)
  6023. goto exit_traverse_tree;
  6024. if (np->subdirs.first != NULL &&
  6025. depth + 1 < vdd->max_depth) {
  6026. /* Enter to sub directories. */
  6027. np = np->subdirs.first;
  6028. depth++;
  6029. continue;
  6030. }
  6031. }
  6032. }
  6033. while (np != np->parent) {
  6034. if (np->drnext == NULL) {
  6035. /* Return to the parent directory. */
  6036. np = np->parent;
  6037. depth--;
  6038. } else {
  6039. np = np->drnext;
  6040. break;
  6041. }
  6042. }
  6043. } while (np != np->parent);
  6044. r = ARCHIVE_OK;
  6045. exit_traverse_tree:
  6046. idr_cleanup(&idr);
  6047. return (r);
  6048. }
  6049. /*
  6050. * Collect directory entries into path_table by a directory depth.
  6051. */
  6052. static int
  6053. isoent_collect_dirs(struct vdd *vdd, struct isoent *rootent, int depth)
  6054. {
  6055. struct isoent *np;
  6056. if (rootent == NULL)
  6057. rootent = vdd->rootent;
  6058. np = rootent;
  6059. do {
  6060. #ifdef __clang_analyzer__
  6061. /* Tell clang-analyzer that pathtbl[depth] is in bounds. */
  6062. assert(depth < vdd->max_depth);
  6063. #endif
  6064. /* Register current directory to pathtable. */
  6065. path_table_add_entry(&(vdd->pathtbl[depth]), np);
  6066. if (np->subdirs.first != NULL && depth + 1 < vdd->max_depth) {
  6067. /* Enter to sub directories. */
  6068. np = np->subdirs.first;
  6069. depth++;
  6070. continue;
  6071. }
  6072. while (np != rootent) {
  6073. if (np->drnext == NULL) {
  6074. /* Return to the parent directory. */
  6075. np = np->parent;
  6076. depth--;
  6077. } else {
  6078. np = np->drnext;
  6079. break;
  6080. }
  6081. }
  6082. } while (np != rootent);
  6083. return (ARCHIVE_OK);
  6084. }
  6085. /*
  6086. * The entry whose number of levels in a directory hierarchy is
  6087. * large than eight relocate to rr_move directory.
  6088. */
  6089. static int
  6090. isoent_rr_move_dir(struct archive_write *a, struct isoent **rr_moved,
  6091. struct isoent *curent, struct isoent **newent)
  6092. {
  6093. struct iso9660 *iso9660 = a->format_data;
  6094. struct isoent *rrmoved, *mvent, *np;
  6095. if ((rrmoved = *rr_moved) == NULL) {
  6096. struct isoent *rootent = iso9660->primary.rootent;
  6097. /* There isn't rr_move entry.
  6098. * Create rr_move entry and insert it into the root entry.
  6099. */
  6100. rrmoved = isoent_create_virtual_dir(a, iso9660, "rr_moved");
  6101. if (rrmoved == NULL) {
  6102. archive_set_error(&a->archive, ENOMEM,
  6103. "Can't allocate memory");
  6104. return (ARCHIVE_FATAL);
  6105. }
  6106. /* Add "rr_moved" entry to the root entry. */
  6107. isoent_add_child_head(rootent, rrmoved);
  6108. archive_entry_set_nlink(rootent->file->entry,
  6109. archive_entry_nlink(rootent->file->entry) + 1);
  6110. /* Register "rr_moved" entry to second level pathtable. */
  6111. path_table_add_entry(&(iso9660->primary.pathtbl[1]), rrmoved);
  6112. /* Save rr_moved. */
  6113. *rr_moved = rrmoved;
  6114. }
  6115. /*
  6116. * Make a clone of curent which is going to be relocated
  6117. * to rr_moved.
  6118. */
  6119. mvent = isoent_clone(curent);
  6120. if (mvent == NULL) {
  6121. archive_set_error(&a->archive, ENOMEM,
  6122. "Can't allocate memory");
  6123. return (ARCHIVE_FATAL);
  6124. }
  6125. /* linking.. and use for creating "CL", "PL" and "RE" */
  6126. mvent->rr_parent = curent->parent;
  6127. curent->rr_child = mvent;
  6128. /*
  6129. * Move subdirectories from the curent to mvent
  6130. */
  6131. if (curent->children.first != NULL) {
  6132. *mvent->children.last = curent->children.first;
  6133. mvent->children.last = curent->children.last;
  6134. }
  6135. for (np = mvent->children.first; np != NULL; np = np->chnext)
  6136. np->parent = mvent;
  6137. mvent->children.cnt = curent->children.cnt;
  6138. curent->children.cnt = 0;
  6139. curent->children.first = NULL;
  6140. curent->children.last = &curent->children.first;
  6141. if (curent->subdirs.first != NULL) {
  6142. *mvent->subdirs.last = curent->subdirs.first;
  6143. mvent->subdirs.last = curent->subdirs.last;
  6144. }
  6145. mvent->subdirs.cnt = curent->subdirs.cnt;
  6146. curent->subdirs.cnt = 0;
  6147. curent->subdirs.first = NULL;
  6148. curent->subdirs.last = &curent->subdirs.first;
  6149. /*
  6150. * The mvent becomes a child of the rr_moved entry.
  6151. */
  6152. isoent_add_child_tail(rrmoved, mvent);
  6153. archive_entry_set_nlink(rrmoved->file->entry,
  6154. archive_entry_nlink(rrmoved->file->entry) + 1);
  6155. /*
  6156. * This entry which relocated to the rr_moved directory
  6157. * has to set the flag as a file.
  6158. * See also RRIP 4.1.5.1 Description of the "CL" System Use Entry.
  6159. */
  6160. curent->dir = 0;
  6161. *newent = mvent;
  6162. return (ARCHIVE_OK);
  6163. }
  6164. static int
  6165. isoent_rr_move(struct archive_write *a)
  6166. {
  6167. struct iso9660 *iso9660 = a->format_data;
  6168. struct path_table *pt;
  6169. struct isoent *rootent, *rr_moved;
  6170. struct isoent *np, *last;
  6171. int r;
  6172. pt = &(iso9660->primary.pathtbl[MAX_DEPTH-1]);
  6173. /* There aren't level 8 directories reaching a deeper level. */
  6174. if (pt->cnt == 0)
  6175. return (ARCHIVE_OK);
  6176. rootent = iso9660->primary.rootent;
  6177. /* If "rr_moved" directory is already existing,
  6178. * we have to use it. */
  6179. rr_moved = isoent_find_child(rootent, "rr_moved");
  6180. if (rr_moved != NULL &&
  6181. rr_moved != rootent->children.first) {
  6182. /*
  6183. * It's necessary that rr_move is the first entry
  6184. * of the root.
  6185. */
  6186. /* Remove "rr_moved" entry from children chain. */
  6187. isoent_remove_child(rootent, rr_moved);
  6188. /* Add "rr_moved" entry into the head of children chain. */
  6189. isoent_add_child_head(rootent, rr_moved);
  6190. }
  6191. /*
  6192. * Check level 8 path_table.
  6193. * If find out sub directory entries, that entries move to rr_move.
  6194. */
  6195. np = pt->first;
  6196. while (np != NULL) {
  6197. last = path_table_last_entry(pt);
  6198. for (; np != NULL; np = np->ptnext) {
  6199. struct isoent *mvent;
  6200. struct isoent *newent;
  6201. if (!np->dir)
  6202. continue;
  6203. for (mvent = np->subdirs.first;
  6204. mvent != NULL; mvent = mvent->drnext) {
  6205. r = isoent_rr_move_dir(a, &rr_moved,
  6206. mvent, &newent);
  6207. if (r < 0)
  6208. return (r);
  6209. isoent_collect_dirs(&(iso9660->primary),
  6210. newent, 2);
  6211. }
  6212. }
  6213. /* If new entries are added to level 8 path_talbe,
  6214. * its sub directory entries move to rr_move too.
  6215. */
  6216. np = last->ptnext;
  6217. }
  6218. return (ARCHIVE_OK);
  6219. }
  6220. /*
  6221. * This comparing rule is according to ISO9660 Standard 6.9.1
  6222. */
  6223. static int
  6224. __LA_LIBC_CC
  6225. _compare_path_table(const void *v1, const void *v2)
  6226. {
  6227. const struct isoent *p1, *p2;
  6228. const char *s1, *s2;
  6229. int cmp, l;
  6230. p1 = *((const struct isoent **)(uintptr_t)v1);
  6231. p2 = *((const struct isoent **)(uintptr_t)v2);
  6232. /* Compare parent directory number */
  6233. cmp = p1->parent->dir_number - p2->parent->dir_number;
  6234. if (cmp != 0)
  6235. return (cmp);
  6236. /* Compare identifier */
  6237. s1 = p1->identifier;
  6238. s2 = p2->identifier;
  6239. l = p1->ext_off;
  6240. if (l > p2->ext_off)
  6241. l = p2->ext_off;
  6242. cmp = strncmp(s1, s2, l);
  6243. if (cmp != 0)
  6244. return (cmp);
  6245. if (p1->ext_off < p2->ext_off) {
  6246. s2 += l;
  6247. l = p2->ext_off - p1->ext_off;
  6248. while (l--)
  6249. if (0x20 != *s2++)
  6250. return (0x20
  6251. - *(const unsigned char *)(s2 - 1));
  6252. } else if (p1->ext_off > p2->ext_off) {
  6253. s1 += l;
  6254. l = p1->ext_off - p2->ext_off;
  6255. while (l--)
  6256. if (0x20 != *s1++)
  6257. return (*(const unsigned char *)(s1 - 1)
  6258. - 0x20);
  6259. }
  6260. return (0);
  6261. }
  6262. static int
  6263. __LA_LIBC_CC
  6264. _compare_path_table_joliet(const void *v1, const void *v2)
  6265. {
  6266. const struct isoent *p1, *p2;
  6267. const unsigned char *s1, *s2;
  6268. int cmp, l;
  6269. p1 = *((const struct isoent **)(uintptr_t)v1);
  6270. p2 = *((const struct isoent **)(uintptr_t)v2);
  6271. /* Compare parent directory number */
  6272. cmp = p1->parent->dir_number - p2->parent->dir_number;
  6273. if (cmp != 0)
  6274. return (cmp);
  6275. /* Compare identifier */
  6276. s1 = (const unsigned char *)p1->identifier;
  6277. s2 = (const unsigned char *)p2->identifier;
  6278. l = p1->ext_off;
  6279. if (l > p2->ext_off)
  6280. l = p2->ext_off;
  6281. cmp = memcmp(s1, s2, l);
  6282. if (cmp != 0)
  6283. return (cmp);
  6284. if (p1->ext_off < p2->ext_off) {
  6285. s2 += l;
  6286. l = p2->ext_off - p1->ext_off;
  6287. while (l--)
  6288. if (0 != *s2++)
  6289. return (- *(const unsigned char *)(s2 - 1));
  6290. } else if (p1->ext_off > p2->ext_off) {
  6291. s1 += l;
  6292. l = p1->ext_off - p2->ext_off;
  6293. while (l--)
  6294. if (0 != *s1++)
  6295. return (*(const unsigned char *)(s1 - 1));
  6296. }
  6297. return (0);
  6298. }
  6299. static inline void
  6300. path_table_add_entry(struct path_table *pathtbl, struct isoent *ent)
  6301. {
  6302. ent->ptnext = NULL;
  6303. *pathtbl->last = ent;
  6304. pathtbl->last = &(ent->ptnext);
  6305. pathtbl->cnt ++;
  6306. }
  6307. static inline struct isoent *
  6308. path_table_last_entry(struct path_table *pathtbl)
  6309. {
  6310. if (pathtbl->first == NULL)
  6311. return (NULL);
  6312. return (((struct isoent *)(void *)
  6313. ((char *)(pathtbl->last) - offsetof(struct isoent, ptnext))));
  6314. }
  6315. /*
  6316. * Sort directory entries in path_table
  6317. * and assign directory number to each entries.
  6318. */
  6319. static int
  6320. isoent_make_path_table_2(struct archive_write *a, struct vdd *vdd,
  6321. int depth, int *dir_number)
  6322. {
  6323. struct isoent *np;
  6324. struct isoent **enttbl;
  6325. struct path_table *pt;
  6326. int i;
  6327. pt = &vdd->pathtbl[depth];
  6328. if (pt->cnt == 0) {
  6329. pt->sorted = NULL;
  6330. return (ARCHIVE_OK);
  6331. }
  6332. enttbl = malloc(pt->cnt * sizeof(struct isoent *));
  6333. if (enttbl == NULL) {
  6334. archive_set_error(&a->archive, ENOMEM,
  6335. "Can't allocate memory");
  6336. return (ARCHIVE_FATAL);
  6337. }
  6338. pt->sorted = enttbl;
  6339. for (np = pt->first; np != NULL; np = np->ptnext)
  6340. *enttbl ++ = np;
  6341. enttbl = pt->sorted;
  6342. switch (vdd->vdd_type) {
  6343. case VDD_PRIMARY:
  6344. case VDD_ENHANCED:
  6345. #ifdef __COMPAR_FN_T
  6346. qsort(enttbl, pt->cnt, sizeof(struct isoent *),
  6347. (__compar_fn_t)_compare_path_table);
  6348. #else
  6349. qsort(enttbl, pt->cnt, sizeof(struct isoent *),
  6350. _compare_path_table);
  6351. #endif
  6352. break;
  6353. case VDD_JOLIET:
  6354. #ifdef __COMPAR_FN_T
  6355. qsort(enttbl, pt->cnt, sizeof(struct isoent *),
  6356. (__compar_fn_t)_compare_path_table_joliet);
  6357. #else
  6358. qsort(enttbl, pt->cnt, sizeof(struct isoent *),
  6359. _compare_path_table_joliet);
  6360. #endif
  6361. break;
  6362. }
  6363. for (i = 0; i < pt->cnt; i++)
  6364. enttbl[i]->dir_number = (*dir_number)++;
  6365. return (ARCHIVE_OK);
  6366. }
  6367. static int
  6368. isoent_alloc_path_table(struct archive_write *a, struct vdd *vdd,
  6369. int max_depth)
  6370. {
  6371. int i;
  6372. vdd->max_depth = max_depth;
  6373. vdd->pathtbl = malloc(sizeof(*vdd->pathtbl) * vdd->max_depth);
  6374. if (vdd->pathtbl == NULL) {
  6375. archive_set_error(&a->archive, ENOMEM,
  6376. "Can't allocate memory");
  6377. return (ARCHIVE_FATAL);
  6378. }
  6379. for (i = 0; i < vdd->max_depth; i++) {
  6380. vdd->pathtbl[i].first = NULL;
  6381. vdd->pathtbl[i].last = &(vdd->pathtbl[i].first);
  6382. vdd->pathtbl[i].sorted = NULL;
  6383. vdd->pathtbl[i].cnt = 0;
  6384. }
  6385. return (ARCHIVE_OK);
  6386. }
  6387. /*
  6388. * Make Path Tables
  6389. */
  6390. static int
  6391. isoent_make_path_table(struct archive_write *a)
  6392. {
  6393. struct iso9660 *iso9660 = a->format_data;
  6394. int depth, r;
  6395. int dir_number;
  6396. /*
  6397. * Init Path Table.
  6398. */
  6399. if (iso9660->dircnt_max >= MAX_DEPTH &&
  6400. (!iso9660->opt.limit_depth || iso9660->opt.iso_level == 4))
  6401. r = isoent_alloc_path_table(a, &(iso9660->primary),
  6402. iso9660->dircnt_max + 1);
  6403. else
  6404. /* The number of levels in the hierarchy cannot exceed
  6405. * eight. */
  6406. r = isoent_alloc_path_table(a, &(iso9660->primary),
  6407. MAX_DEPTH);
  6408. if (r < 0)
  6409. return (r);
  6410. if (iso9660->opt.joliet) {
  6411. r = isoent_alloc_path_table(a, &(iso9660->joliet),
  6412. iso9660->dircnt_max + 1);
  6413. if (r < 0)
  6414. return (r);
  6415. }
  6416. /* Step 0.
  6417. * - Collect directories for primary and joliet.
  6418. */
  6419. isoent_collect_dirs(&(iso9660->primary), NULL, 0);
  6420. if (iso9660->opt.joliet)
  6421. isoent_collect_dirs(&(iso9660->joliet), NULL, 0);
  6422. /*
  6423. * Rockridge; move deeper depth directories to rr_moved.
  6424. */
  6425. if (iso9660->opt.rr) {
  6426. r = isoent_rr_move(a);
  6427. if (r < 0)
  6428. return (r);
  6429. }
  6430. /* Update nlink. */
  6431. isofile_connect_hardlink_files(iso9660);
  6432. /* Step 1.
  6433. * - Renew a value of the depth of that directories.
  6434. * - Resolve hardlinks.
  6435. * - Convert pathnames to ISO9660 name or UCS2(joliet).
  6436. * - Sort files by each directory.
  6437. */
  6438. r = isoent_traverse_tree(a, &(iso9660->primary));
  6439. if (r < 0)
  6440. return (r);
  6441. if (iso9660->opt.joliet) {
  6442. r = isoent_traverse_tree(a, &(iso9660->joliet));
  6443. if (r < 0)
  6444. return (r);
  6445. }
  6446. /* Step 2.
  6447. * - Sort directories.
  6448. * - Assign all directory number.
  6449. */
  6450. dir_number = 1;
  6451. for (depth = 0; depth < iso9660->primary.max_depth; depth++) {
  6452. r = isoent_make_path_table_2(a, &(iso9660->primary),
  6453. depth, &dir_number);
  6454. if (r < 0)
  6455. return (r);
  6456. }
  6457. if (iso9660->opt.joliet) {
  6458. dir_number = 1;
  6459. for (depth = 0; depth < iso9660->joliet.max_depth; depth++) {
  6460. r = isoent_make_path_table_2(a, &(iso9660->joliet),
  6461. depth, &dir_number);
  6462. if (r < 0)
  6463. return (r);
  6464. }
  6465. }
  6466. if (iso9660->opt.limit_dirs && dir_number > 0xffff) {
  6467. /*
  6468. * Maximum number of directories is 65535(0xffff)
  6469. * doe to size(16bit) of Parent Directory Number of
  6470. * the Path Table.
  6471. * See also ISO9660 Standard 9.4.
  6472. */
  6473. archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
  6474. "Too many directories(%d) over 65535.", dir_number);
  6475. return (ARCHIVE_FATAL);
  6476. }
  6477. /* Get the size of the Path Table. */
  6478. calculate_path_table_size(&(iso9660->primary));
  6479. if (iso9660->opt.joliet)
  6480. calculate_path_table_size(&(iso9660->joliet));
  6481. return (ARCHIVE_OK);
  6482. }
  6483. static int
  6484. isoent_find_out_boot_file(struct archive_write *a, struct isoent *rootent)
  6485. {
  6486. struct iso9660 *iso9660 = a->format_data;
  6487. /* Find a isoent of the boot file. */
  6488. iso9660->el_torito.boot = isoent_find_entry(rootent,
  6489. iso9660->el_torito.boot_filename.s);
  6490. if (iso9660->el_torito.boot == NULL) {
  6491. archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
  6492. "Can't find the boot image file ``%s''",
  6493. iso9660->el_torito.boot_filename.s);
  6494. return (ARCHIVE_FATAL);
  6495. }
  6496. iso9660->el_torito.boot->file->boot = BOOT_IMAGE;
  6497. return (ARCHIVE_OK);
  6498. }
  6499. static int
  6500. isoent_create_boot_catalog(struct archive_write *a, struct isoent *rootent)
  6501. {
  6502. struct iso9660 *iso9660 = a->format_data;
  6503. struct isofile *file;
  6504. struct isoent *isoent;
  6505. struct archive_entry *entry;
  6506. (void)rootent; /* UNUSED */
  6507. /*
  6508. * Create the entry which is the "boot.catalog" file.
  6509. */
  6510. file = isofile_new(a, NULL);
  6511. if (file == NULL) {
  6512. archive_set_error(&a->archive, ENOMEM,
  6513. "Can't allocate memory");
  6514. return (ARCHIVE_FATAL);
  6515. }
  6516. archive_entry_set_pathname(file->entry,
  6517. iso9660->el_torito.catalog_filename.s);
  6518. archive_entry_set_size(file->entry, LOGICAL_BLOCK_SIZE);
  6519. archive_entry_set_mtime(file->entry, iso9660->birth_time, 0);
  6520. archive_entry_set_atime(file->entry, iso9660->birth_time, 0);
  6521. archive_entry_set_ctime(file->entry, iso9660->birth_time, 0);
  6522. archive_entry_set_uid(file->entry, getuid());
  6523. archive_entry_set_gid(file->entry, getgid());
  6524. archive_entry_set_mode(file->entry, AE_IFREG | 0444);
  6525. archive_entry_set_nlink(file->entry, 1);
  6526. if (isofile_gen_utility_names(a, file) < ARCHIVE_WARN) {
  6527. isofile_free(file);
  6528. return (ARCHIVE_FATAL);
  6529. }
  6530. file->boot = BOOT_CATALOG;
  6531. file->content.size = LOGICAL_BLOCK_SIZE;
  6532. isofile_add_entry(iso9660, file);
  6533. isoent = isoent_new(file);
  6534. if (isoent == NULL) {
  6535. archive_set_error(&a->archive, ENOMEM,
  6536. "Can't allocate memory");
  6537. return (ARCHIVE_FATAL);
  6538. }
  6539. isoent->virtual = 1;
  6540. /* Add the "boot.catalog" entry into tree */
  6541. if (isoent_tree(a, &isoent) != ARCHIVE_OK)
  6542. return (ARCHIVE_FATAL);
  6543. iso9660->el_torito.catalog = isoent;
  6544. /*
  6545. * Get a boot media type.
  6546. */
  6547. switch (iso9660->opt.boot_type) {
  6548. default:
  6549. case OPT_BOOT_TYPE_AUTO:
  6550. /* Try detecting a media type of the boot image. */
  6551. entry = iso9660->el_torito.boot->file->entry;
  6552. if (archive_entry_size(entry) == FD_1_2M_SIZE)
  6553. iso9660->el_torito.media_type =
  6554. BOOT_MEDIA_1_2M_DISKETTE;
  6555. else if (archive_entry_size(entry) == FD_1_44M_SIZE)
  6556. iso9660->el_torito.media_type =
  6557. BOOT_MEDIA_1_44M_DISKETTE;
  6558. else if (archive_entry_size(entry) == FD_2_88M_SIZE)
  6559. iso9660->el_torito.media_type =
  6560. BOOT_MEDIA_2_88M_DISKETTE;
  6561. else
  6562. /* We cannot decide whether the boot image is
  6563. * hard-disk. */
  6564. iso9660->el_torito.media_type =
  6565. BOOT_MEDIA_NO_EMULATION;
  6566. break;
  6567. case OPT_BOOT_TYPE_NO_EMU:
  6568. iso9660->el_torito.media_type = BOOT_MEDIA_NO_EMULATION;
  6569. break;
  6570. case OPT_BOOT_TYPE_HARD_DISK:
  6571. iso9660->el_torito.media_type = BOOT_MEDIA_HARD_DISK;
  6572. break;
  6573. case OPT_BOOT_TYPE_FD:
  6574. entry = iso9660->el_torito.boot->file->entry;
  6575. if (archive_entry_size(entry) <= FD_1_2M_SIZE)
  6576. iso9660->el_torito.media_type =
  6577. BOOT_MEDIA_1_2M_DISKETTE;
  6578. else if (archive_entry_size(entry) <= FD_1_44M_SIZE)
  6579. iso9660->el_torito.media_type =
  6580. BOOT_MEDIA_1_44M_DISKETTE;
  6581. else if (archive_entry_size(entry) <= FD_2_88M_SIZE)
  6582. iso9660->el_torito.media_type =
  6583. BOOT_MEDIA_2_88M_DISKETTE;
  6584. else {
  6585. archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
  6586. "Boot image file(``%s'') size is too big "
  6587. "for fd type.",
  6588. iso9660->el_torito.boot_filename.s);
  6589. return (ARCHIVE_FATAL);
  6590. }
  6591. break;
  6592. }
  6593. /*
  6594. * Get a system type.
  6595. * TODO: `El Torito' specification says "A copy of byte 5 from the
  6596. * Partition Table found in the boot image".
  6597. */
  6598. iso9660->el_torito.system_type = 0;
  6599. /*
  6600. * Get an ID.
  6601. */
  6602. if (iso9660->opt.publisher)
  6603. archive_string_copy(&(iso9660->el_torito.id),
  6604. &(iso9660->publisher_identifier));
  6605. return (ARCHIVE_OK);
  6606. }
  6607. /*
  6608. * If a media type is floppy, return its image size.
  6609. * otherwise return 0.
  6610. */
  6611. static size_t
  6612. fd_boot_image_size(int media_type)
  6613. {
  6614. switch (media_type) {
  6615. case BOOT_MEDIA_1_2M_DISKETTE:
  6616. return (FD_1_2M_SIZE);
  6617. case BOOT_MEDIA_1_44M_DISKETTE:
  6618. return (FD_1_44M_SIZE);
  6619. case BOOT_MEDIA_2_88M_DISKETTE:
  6620. return (FD_2_88M_SIZE);
  6621. default:
  6622. return (0);
  6623. }
  6624. }
  6625. /*
  6626. * Make a boot catalog image data.
  6627. */
  6628. static int
  6629. make_boot_catalog(struct archive_write *a)
  6630. {
  6631. struct iso9660 *iso9660 = a->format_data;
  6632. unsigned char *block;
  6633. unsigned char *p;
  6634. uint16_t sum, *wp;
  6635. block = wb_buffptr(a);
  6636. memset(block, 0, LOGICAL_BLOCK_SIZE);
  6637. p = block;
  6638. /*
  6639. * Validation Entry
  6640. */
  6641. /* Header ID */
  6642. p[0] = 1;
  6643. /* Platform ID */
  6644. p[1] = iso9660->el_torito.platform_id;
  6645. /* Reserved */
  6646. p[2] = p[3] = 0;
  6647. /* ID */
  6648. if (archive_strlen(&(iso9660->el_torito.id)) > 0)
  6649. strncpy((char *)p+4, iso9660->el_torito.id.s, 23);
  6650. p[27] = 0;
  6651. /* Checksum */
  6652. p[28] = p[29] = 0;
  6653. /* Key */
  6654. p[30] = 0x55;
  6655. p[31] = 0xAA;
  6656. sum = 0;
  6657. wp = (uint16_t *)block;
  6658. while (wp < (uint16_t *)&block[32])
  6659. sum += archive_le16dec(wp++);
  6660. set_num_721(&block[28], (~sum) + 1);
  6661. /*
  6662. * Initial/Default Entry
  6663. */
  6664. p = &block[32];
  6665. /* Boot Indicator */
  6666. p[0] = 0x88;
  6667. /* Boot media type */
  6668. p[1] = iso9660->el_torito.media_type;
  6669. /* Load Segment */
  6670. if (iso9660->el_torito.media_type == BOOT_MEDIA_NO_EMULATION)
  6671. set_num_721(&p[2], iso9660->el_torito.boot_load_seg);
  6672. else
  6673. set_num_721(&p[2], 0);
  6674. /* System Type */
  6675. p[4] = iso9660->el_torito.system_type;
  6676. /* Unused */
  6677. p[5] = 0;
  6678. /* Sector Count */
  6679. if (iso9660->el_torito.media_type == BOOT_MEDIA_NO_EMULATION)
  6680. set_num_721(&p[6], iso9660->el_torito.boot_load_size);
  6681. else
  6682. set_num_721(&p[6], 1);
  6683. /* Load RBA */
  6684. set_num_731(&p[8],
  6685. iso9660->el_torito.boot->file->content.location);
  6686. /* Unused */
  6687. memset(&p[12], 0, 20);
  6688. return (wb_consume(a, LOGICAL_BLOCK_SIZE));
  6689. }
  6690. static int
  6691. setup_boot_information(struct archive_write *a)
  6692. {
  6693. struct iso9660 *iso9660 = a->format_data;
  6694. struct isoent *np;
  6695. int64_t size;
  6696. uint32_t sum;
  6697. unsigned char buff[4096];
  6698. np = iso9660->el_torito.boot;
  6699. lseek(iso9660->temp_fd,
  6700. np->file->content.offset_of_temp + 64, SEEK_SET);
  6701. size = archive_entry_size(np->file->entry) - 64;
  6702. if (size <= 0) {
  6703. archive_set_error(&a->archive, errno,
  6704. "Boot file(%jd) is too small", (intmax_t)size + 64);
  6705. return (ARCHIVE_FATAL);
  6706. }
  6707. sum = 0;
  6708. while (size > 0) {
  6709. size_t rsize;
  6710. ssize_t i, rs;
  6711. if (size > (int64_t)sizeof(buff))
  6712. rsize = sizeof(buff);
  6713. else
  6714. rsize = (size_t)size;
  6715. rs = read(iso9660->temp_fd, buff, rsize);
  6716. if (rs <= 0) {
  6717. archive_set_error(&a->archive, errno,
  6718. "Can't read temporary file(%jd)",
  6719. (intmax_t)rs);
  6720. return (ARCHIVE_FATAL);
  6721. }
  6722. for (i = 0; i < rs; i += 4)
  6723. sum += archive_le32dec(buff + i);
  6724. size -= rs;
  6725. }
  6726. /* Set the location of Primary Volume Descriptor. */
  6727. set_num_731(buff, SYSTEM_AREA_BLOCK);
  6728. /* Set the location of the boot file. */
  6729. set_num_731(buff+4, np->file->content.location);
  6730. /* Set the size of the boot file. */
  6731. size = fd_boot_image_size(iso9660->el_torito.media_type);
  6732. if (size == 0)
  6733. size = archive_entry_size(np->file->entry);
  6734. set_num_731(buff+8, (uint32_t)size);
  6735. /* Set the sum of the boot file. */
  6736. set_num_731(buff+12, sum);
  6737. /* Clear reserved bytes. */
  6738. memset(buff+16, 0, 40);
  6739. /* Overwrite the boot file. */
  6740. lseek(iso9660->temp_fd,
  6741. np->file->content.offset_of_temp + 8, SEEK_SET);
  6742. return (write_to_temp(a, buff, 56));
  6743. }
  6744. #ifdef HAVE_ZLIB_H
  6745. static int
  6746. zisofs_init_zstream(struct archive_write *a)
  6747. {
  6748. struct iso9660 *iso9660 = a->format_data;
  6749. int r;
  6750. iso9660->zisofs.stream.next_in = NULL;
  6751. iso9660->zisofs.stream.avail_in = 0;
  6752. iso9660->zisofs.stream.total_in = 0;
  6753. iso9660->zisofs.stream.total_out = 0;
  6754. if (iso9660->zisofs.stream_valid)
  6755. r = deflateReset(&(iso9660->zisofs.stream));
  6756. else {
  6757. r = deflateInit(&(iso9660->zisofs.stream),
  6758. iso9660->zisofs.compression_level);
  6759. iso9660->zisofs.stream_valid = 1;
  6760. }
  6761. switch (r) {
  6762. case Z_OK:
  6763. break;
  6764. default:
  6765. case Z_STREAM_ERROR:
  6766. archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
  6767. "Internal error initializing "
  6768. "compression library: invalid setup parameter");
  6769. return (ARCHIVE_FATAL);
  6770. case Z_MEM_ERROR:
  6771. archive_set_error(&a->archive, ENOMEM,
  6772. "Internal error initializing "
  6773. "compression library");
  6774. return (ARCHIVE_FATAL);
  6775. case Z_VERSION_ERROR:
  6776. archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
  6777. "Internal error initializing "
  6778. "compression library: invalid library version");
  6779. return (ARCHIVE_FATAL);
  6780. }
  6781. return (ARCHIVE_OK);
  6782. }
  6783. #endif /* HAVE_ZLIB_H */
  6784. static int
  6785. zisofs_init(struct archive_write *a, struct isofile *file)
  6786. {
  6787. struct iso9660 *iso9660 = a->format_data;
  6788. #ifdef HAVE_ZLIB_H
  6789. uint64_t tsize;
  6790. size_t _ceil, bpsize;
  6791. int r;
  6792. #endif
  6793. iso9660->zisofs.detect_magic = 0;
  6794. iso9660->zisofs.making = 0;
  6795. if (!iso9660->opt.rr || !iso9660->opt.zisofs)
  6796. return (ARCHIVE_OK);
  6797. if (archive_entry_size(file->entry) >= 24 &&
  6798. archive_entry_size(file->entry) < MULTI_EXTENT_SIZE) {
  6799. /* Acceptable file size for zisofs. */
  6800. iso9660->zisofs.detect_magic = 1;
  6801. iso9660->zisofs.magic_cnt = 0;
  6802. }
  6803. if (!iso9660->zisofs.detect_magic)
  6804. return (ARCHIVE_OK);
  6805. #ifdef HAVE_ZLIB_H
  6806. /* The number of Logical Blocks which uncompressed data
  6807. * will use in iso-image file is the same as the number of
  6808. * Logical Blocks which zisofs(compressed) data will use
  6809. * in ISO-image file. It won't reduce iso-image file size. */
  6810. if (archive_entry_size(file->entry) <= LOGICAL_BLOCK_SIZE)
  6811. return (ARCHIVE_OK);
  6812. /* Initialize compression library */
  6813. r = zisofs_init_zstream(a);
  6814. if (r != ARCHIVE_OK)
  6815. return (ARCHIVE_FATAL);
  6816. /* Mark file->zisofs to create RRIP 'ZF' Use Entry. */
  6817. file->zisofs.header_size = ZF_HEADER_SIZE >> 2;
  6818. file->zisofs.log2_bs = ZF_LOG2_BS;
  6819. file->zisofs.uncompressed_size =
  6820. (uint32_t)archive_entry_size(file->entry);
  6821. /* Calculate a size of Block Pointers of zisofs. */
  6822. _ceil = (file->zisofs.uncompressed_size + ZF_BLOCK_SIZE -1)
  6823. >> file->zisofs.log2_bs;
  6824. iso9660->zisofs.block_pointers_cnt = (int)_ceil + 1;
  6825. iso9660->zisofs.block_pointers_idx = 0;
  6826. /* Ensure a buffer size used for Block Pointers */
  6827. bpsize = iso9660->zisofs.block_pointers_cnt *
  6828. sizeof(iso9660->zisofs.block_pointers[0]);
  6829. if (iso9660->zisofs.block_pointers_allocated < bpsize) {
  6830. free(iso9660->zisofs.block_pointers);
  6831. iso9660->zisofs.block_pointers = malloc(bpsize);
  6832. if (iso9660->zisofs.block_pointers == NULL) {
  6833. archive_set_error(&a->archive, ENOMEM,
  6834. "Can't allocate data");
  6835. return (ARCHIVE_FATAL);
  6836. }
  6837. iso9660->zisofs.block_pointers_allocated = bpsize;
  6838. }
  6839. /*
  6840. * Skip zisofs header and Block Pointers, which we will write
  6841. * after all compressed data of a file written to the temporary
  6842. * file.
  6843. */
  6844. tsize = ZF_HEADER_SIZE + bpsize;
  6845. if (write_null(a, (size_t)tsize) != ARCHIVE_OK)
  6846. return (ARCHIVE_FATAL);
  6847. /*
  6848. * Initialize some variables to make zisofs.
  6849. */
  6850. archive_le32enc(&(iso9660->zisofs.block_pointers[0]),
  6851. (uint32_t)tsize);
  6852. iso9660->zisofs.remaining = file->zisofs.uncompressed_size;
  6853. iso9660->zisofs.making = 1;
  6854. iso9660->zisofs.allzero = 1;
  6855. iso9660->zisofs.block_offset = tsize;
  6856. iso9660->zisofs.total_size = tsize;
  6857. iso9660->cur_file->cur_content->size = tsize;
  6858. #endif
  6859. return (ARCHIVE_OK);
  6860. }
  6861. static void
  6862. zisofs_detect_magic(struct archive_write *a, const void *buff, size_t s)
  6863. {
  6864. struct iso9660 *iso9660 = a->format_data;
  6865. struct isofile *file = iso9660->cur_file;
  6866. const unsigned char *p, *endp;
  6867. const unsigned char *magic_buff;
  6868. uint32_t uncompressed_size;
  6869. unsigned char header_size;
  6870. unsigned char log2_bs;
  6871. size_t _ceil, doff;
  6872. uint32_t bst, bed;
  6873. int magic_max;
  6874. int64_t entry_size;
  6875. entry_size = archive_entry_size(file->entry);
  6876. if ((int64_t)sizeof(iso9660->zisofs.magic_buffer) > entry_size)
  6877. magic_max = (int)entry_size;
  6878. else
  6879. magic_max = sizeof(iso9660->zisofs.magic_buffer);
  6880. if (iso9660->zisofs.magic_cnt == 0 && s >= (size_t)magic_max)
  6881. /* It's unnecessary we copy buffer. */
  6882. magic_buff = buff;
  6883. else {
  6884. if (iso9660->zisofs.magic_cnt < magic_max) {
  6885. size_t l;
  6886. l = sizeof(iso9660->zisofs.magic_buffer)
  6887. - iso9660->zisofs.magic_cnt;
  6888. if (l > s)
  6889. l = s;
  6890. memcpy(iso9660->zisofs.magic_buffer
  6891. + iso9660->zisofs.magic_cnt, buff, l);
  6892. iso9660->zisofs.magic_cnt += (int)l;
  6893. if (iso9660->zisofs.magic_cnt < magic_max)
  6894. return;
  6895. }
  6896. magic_buff = iso9660->zisofs.magic_buffer;
  6897. }
  6898. iso9660->zisofs.detect_magic = 0;
  6899. p = magic_buff;
  6900. /* Check the magic code of zisofs. */
  6901. if (memcmp(p, zisofs_magic, sizeof(zisofs_magic)) != 0)
  6902. /* This is not zisofs file which made by mkzftree. */
  6903. return;
  6904. p += sizeof(zisofs_magic);
  6905. /* Read a zisofs header. */
  6906. uncompressed_size = archive_le32dec(p);
  6907. header_size = p[4];
  6908. log2_bs = p[5];
  6909. if (uncompressed_size < 24 || header_size != 4 ||
  6910. log2_bs > 30 || log2_bs < 7)
  6911. return;/* Invalid or not supported header. */
  6912. /* Calculate a size of Block Pointers of zisofs. */
  6913. _ceil = (uncompressed_size +
  6914. (ARCHIVE_LITERAL_LL(1) << log2_bs) -1) >> log2_bs;
  6915. doff = (_ceil + 1) * 4 + 16;
  6916. if (entry_size < (int64_t)doff)
  6917. return;/* Invalid data. */
  6918. /* Check every Block Pointer has valid value. */
  6919. p = magic_buff + 16;
  6920. endp = magic_buff + magic_max;
  6921. while (_ceil && p + 8 <= endp) {
  6922. bst = archive_le32dec(p);
  6923. if (bst != doff)
  6924. return;/* Invalid data. */
  6925. p += 4;
  6926. bed = archive_le32dec(p);
  6927. if (bed < bst || bed > entry_size)
  6928. return;/* Invalid data. */
  6929. doff += bed - bst;
  6930. _ceil--;
  6931. }
  6932. file->zisofs.uncompressed_size = uncompressed_size;
  6933. file->zisofs.header_size = header_size;
  6934. file->zisofs.log2_bs = log2_bs;
  6935. /* Disable making a zisofs image. */
  6936. iso9660->zisofs.making = 0;
  6937. }
  6938. #ifdef HAVE_ZLIB_H
  6939. /*
  6940. * Compress data and write it to a temporary file.
  6941. */
  6942. static int
  6943. zisofs_write_to_temp(struct archive_write *a, const void *buff, size_t s)
  6944. {
  6945. struct iso9660 *iso9660 = a->format_data;
  6946. struct isofile *file = iso9660->cur_file;
  6947. const unsigned char *b;
  6948. z_stream *zstrm;
  6949. size_t avail, csize;
  6950. int flush, r;
  6951. zstrm = &(iso9660->zisofs.stream);
  6952. zstrm->next_out = wb_buffptr(a);
  6953. zstrm->avail_out = (uInt)wb_remaining(a);
  6954. b = (const unsigned char *)buff;
  6955. do {
  6956. avail = ZF_BLOCK_SIZE - zstrm->total_in;
  6957. if (s < avail) {
  6958. avail = s;
  6959. flush = Z_NO_FLUSH;
  6960. } else
  6961. flush = Z_FINISH;
  6962. iso9660->zisofs.remaining -= avail;
  6963. if (iso9660->zisofs.remaining <= 0)
  6964. flush = Z_FINISH;
  6965. zstrm->next_in = (Bytef *)(uintptr_t)(const void *)b;
  6966. zstrm->avail_in = (uInt)avail;
  6967. /*
  6968. * Check if current data block are all zero.
  6969. */
  6970. if (iso9660->zisofs.allzero) {
  6971. const unsigned char *nonzero = b;
  6972. const unsigned char *nonzeroend = b + avail;
  6973. while (nonzero < nonzeroend)
  6974. if (*nonzero++) {
  6975. iso9660->zisofs.allzero = 0;
  6976. break;
  6977. }
  6978. }
  6979. b += avail;
  6980. s -= avail;
  6981. /*
  6982. * If current data block are all zero, we do not use
  6983. * compressed data.
  6984. */
  6985. if (flush == Z_FINISH && iso9660->zisofs.allzero &&
  6986. avail + zstrm->total_in == ZF_BLOCK_SIZE) {
  6987. if (iso9660->zisofs.block_offset !=
  6988. file->cur_content->size) {
  6989. int64_t diff;
  6990. r = wb_set_offset(a,
  6991. file->cur_content->offset_of_temp +
  6992. iso9660->zisofs.block_offset);
  6993. if (r != ARCHIVE_OK)
  6994. return (r);
  6995. diff = file->cur_content->size -
  6996. iso9660->zisofs.block_offset;
  6997. file->cur_content->size -= diff;
  6998. iso9660->zisofs.total_size -= diff;
  6999. }
  7000. zstrm->avail_in = 0;
  7001. }
  7002. /*
  7003. * Compress file data.
  7004. */
  7005. while (zstrm->avail_in > 0) {
  7006. csize = zstrm->total_out;
  7007. r = deflate(zstrm, flush);
  7008. switch (r) {
  7009. case Z_OK:
  7010. case Z_STREAM_END:
  7011. csize = zstrm->total_out - csize;
  7012. if (wb_consume(a, csize) != ARCHIVE_OK)
  7013. return (ARCHIVE_FATAL);
  7014. iso9660->zisofs.total_size += csize;
  7015. iso9660->cur_file->cur_content->size += csize;
  7016. zstrm->next_out = wb_buffptr(a);
  7017. zstrm->avail_out = (uInt)wb_remaining(a);
  7018. break;
  7019. default:
  7020. archive_set_error(&a->archive,
  7021. ARCHIVE_ERRNO_MISC,
  7022. "Compression failed:"
  7023. " deflate() call returned status %d",
  7024. r);
  7025. return (ARCHIVE_FATAL);
  7026. }
  7027. }
  7028. if (flush == Z_FINISH) {
  7029. /*
  7030. * Save the information of one zisofs block.
  7031. */
  7032. iso9660->zisofs.block_pointers_idx ++;
  7033. archive_le32enc(&(iso9660->zisofs.block_pointers[
  7034. iso9660->zisofs.block_pointers_idx]),
  7035. (uint32_t)iso9660->zisofs.total_size);
  7036. r = zisofs_init_zstream(a);
  7037. if (r != ARCHIVE_OK)
  7038. return (ARCHIVE_FATAL);
  7039. iso9660->zisofs.allzero = 1;
  7040. iso9660->zisofs.block_offset = file->cur_content->size;
  7041. }
  7042. } while (s);
  7043. return (ARCHIVE_OK);
  7044. }
  7045. static int
  7046. zisofs_finish_entry(struct archive_write *a)
  7047. {
  7048. struct iso9660 *iso9660 = a->format_data;
  7049. struct isofile *file = iso9660->cur_file;
  7050. unsigned char buff[16];
  7051. size_t s;
  7052. int64_t tail;
  7053. /* Direct temp file stream to zisofs temp file stream. */
  7054. archive_entry_set_size(file->entry, iso9660->zisofs.total_size);
  7055. /*
  7056. * Save a file pointer which points the end of current zisofs data.
  7057. */
  7058. tail = wb_offset(a);
  7059. /*
  7060. * Make a header.
  7061. *
  7062. * +-----------------+----------------+-----------------+
  7063. * | Header 16 bytes | Block Pointers | Compressed data |
  7064. * +-----------------+----------------+-----------------+
  7065. * 0 16 +X
  7066. * Block Pointers :
  7067. * 4 * (((Uncompressed file size + block_size -1) / block_size) + 1)
  7068. *
  7069. * Write zisofs header.
  7070. * Magic number
  7071. * +----+----+----+----+----+----+----+----+
  7072. * | 37 | E4 | 53 | 96 | C9 | DB | D6 | 07 |
  7073. * +----+----+----+----+----+----+----+----+
  7074. * 0 1 2 3 4 5 6 7 8
  7075. *
  7076. * +------------------------+------------------+
  7077. * | Uncompressed file size | header_size >> 2 |
  7078. * +------------------------+------------------+
  7079. * 8 12 13
  7080. *
  7081. * +-----------------+----------------+
  7082. * | log2 block_size | Reserved(0000) |
  7083. * +-----------------+----------------+
  7084. * 13 14 16
  7085. */
  7086. memcpy(buff, zisofs_magic, 8);
  7087. set_num_731(buff+8, file->zisofs.uncompressed_size);
  7088. buff[12] = file->zisofs.header_size;
  7089. buff[13] = file->zisofs.log2_bs;
  7090. buff[14] = buff[15] = 0;/* Reserved */
  7091. /* Move to the right position to write the header. */
  7092. wb_set_offset(a, file->content.offset_of_temp);
  7093. /* Write the header. */
  7094. if (wb_write_to_temp(a, buff, 16) != ARCHIVE_OK)
  7095. return (ARCHIVE_FATAL);
  7096. /*
  7097. * Write zisofs Block Pointers.
  7098. */
  7099. s = iso9660->zisofs.block_pointers_cnt *
  7100. sizeof(iso9660->zisofs.block_pointers[0]);
  7101. if (wb_write_to_temp(a, iso9660->zisofs.block_pointers, s)
  7102. != ARCHIVE_OK)
  7103. return (ARCHIVE_FATAL);
  7104. /* Set a file pointer back to the end of the temporary file. */
  7105. wb_set_offset(a, tail);
  7106. return (ARCHIVE_OK);
  7107. }
  7108. static int
  7109. zisofs_free(struct archive_write *a)
  7110. {
  7111. struct iso9660 *iso9660 = a->format_data;
  7112. int ret = ARCHIVE_OK;
  7113. free(iso9660->zisofs.block_pointers);
  7114. if (iso9660->zisofs.stream_valid &&
  7115. deflateEnd(&(iso9660->zisofs.stream)) != Z_OK) {
  7116. archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
  7117. "Failed to clean up compressor");
  7118. ret = ARCHIVE_FATAL;
  7119. }
  7120. iso9660->zisofs.block_pointers = NULL;
  7121. iso9660->zisofs.stream_valid = 0;
  7122. return (ret);
  7123. }
  7124. struct zisofs_extract {
  7125. int pz_log2_bs; /* Log2 of block size */
  7126. uint64_t pz_uncompressed_size;
  7127. size_t uncompressed_buffer_size;
  7128. unsigned int initialized:1;
  7129. unsigned int header_passed:1;
  7130. uint32_t pz_offset;
  7131. unsigned char *block_pointers;
  7132. size_t block_pointers_size;
  7133. size_t block_pointers_avail;
  7134. size_t block_off;
  7135. uint32_t block_avail;
  7136. z_stream stream;
  7137. int stream_valid;
  7138. };
  7139. static ssize_t
  7140. zisofs_extract_init(struct archive_write *a, struct zisofs_extract *zisofs,
  7141. const unsigned char *p, size_t bytes)
  7142. {
  7143. size_t avail = bytes;
  7144. size_t _ceil, xsize;
  7145. /* Allocate block pointers buffer. */
  7146. _ceil = (size_t)((zisofs->pz_uncompressed_size +
  7147. (((int64_t)1) << zisofs->pz_log2_bs) - 1)
  7148. >> zisofs->pz_log2_bs);
  7149. xsize = (_ceil + 1) * 4;
  7150. if (zisofs->block_pointers == NULL) {
  7151. size_t alloc = ((xsize >> 10) + 1) << 10;
  7152. zisofs->block_pointers = malloc(alloc);
  7153. if (zisofs->block_pointers == NULL) {
  7154. archive_set_error(&a->archive, ENOMEM,
  7155. "No memory for zisofs decompression");
  7156. return (ARCHIVE_FATAL);
  7157. }
  7158. }
  7159. zisofs->block_pointers_size = xsize;
  7160. /* Allocate uncompressed data buffer. */
  7161. zisofs->uncompressed_buffer_size = (size_t)1UL << zisofs->pz_log2_bs;
  7162. /*
  7163. * Read the file header, and check the magic code of zisofs.
  7164. */
  7165. if (!zisofs->header_passed) {
  7166. int err = 0;
  7167. if (avail < 16) {
  7168. archive_set_error(&a->archive,
  7169. ARCHIVE_ERRNO_FILE_FORMAT,
  7170. "Illegal zisofs file body");
  7171. return (ARCHIVE_FATAL);
  7172. }
  7173. if (memcmp(p, zisofs_magic, sizeof(zisofs_magic)) != 0)
  7174. err = 1;
  7175. else if (archive_le32dec(p + 8) != zisofs->pz_uncompressed_size)
  7176. err = 1;
  7177. else if (p[12] != 4 || p[13] != zisofs->pz_log2_bs)
  7178. err = 1;
  7179. if (err) {
  7180. archive_set_error(&a->archive,
  7181. ARCHIVE_ERRNO_FILE_FORMAT,
  7182. "Illegal zisofs file body");
  7183. return (ARCHIVE_FATAL);
  7184. }
  7185. avail -= 16;
  7186. p += 16;
  7187. zisofs->header_passed = 1;
  7188. }
  7189. /*
  7190. * Read block pointers.
  7191. */
  7192. if (zisofs->header_passed &&
  7193. zisofs->block_pointers_avail < zisofs->block_pointers_size) {
  7194. xsize = zisofs->block_pointers_size
  7195. - zisofs->block_pointers_avail;
  7196. if (avail < xsize)
  7197. xsize = avail;
  7198. memcpy(zisofs->block_pointers
  7199. + zisofs->block_pointers_avail, p, xsize);
  7200. zisofs->block_pointers_avail += xsize;
  7201. avail -= xsize;
  7202. if (zisofs->block_pointers_avail
  7203. == zisofs->block_pointers_size) {
  7204. /* We've got all block pointers and initialize
  7205. * related variables. */
  7206. zisofs->block_off = 0;
  7207. zisofs->block_avail = 0;
  7208. /* Complete a initialization */
  7209. zisofs->initialized = 1;
  7210. }
  7211. }
  7212. return ((ssize_t)avail);
  7213. }
  7214. static ssize_t
  7215. zisofs_extract(struct archive_write *a, struct zisofs_extract *zisofs,
  7216. const unsigned char *p, size_t bytes)
  7217. {
  7218. size_t avail;
  7219. int r;
  7220. if (!zisofs->initialized) {
  7221. ssize_t rs = zisofs_extract_init(a, zisofs, p, bytes);
  7222. if (rs < 0)
  7223. return (rs);
  7224. if (!zisofs->initialized) {
  7225. /* We need more data. */
  7226. zisofs->pz_offset += (uint32_t)bytes;
  7227. return (bytes);
  7228. }
  7229. avail = rs;
  7230. p += bytes - avail;
  7231. } else
  7232. avail = bytes;
  7233. /*
  7234. * Get block offsets from block pointers.
  7235. */
  7236. if (zisofs->block_avail == 0) {
  7237. uint32_t bst, bed;
  7238. if (zisofs->block_off + 4 >= zisofs->block_pointers_size) {
  7239. /* There isn't a pair of offsets. */
  7240. archive_set_error(&a->archive,
  7241. ARCHIVE_ERRNO_FILE_FORMAT,
  7242. "Illegal zisofs block pointers");
  7243. return (ARCHIVE_FATAL);
  7244. }
  7245. bst = archive_le32dec(
  7246. zisofs->block_pointers + zisofs->block_off);
  7247. if (bst != zisofs->pz_offset + (bytes - avail)) {
  7248. archive_set_error(&a->archive,
  7249. ARCHIVE_ERRNO_FILE_FORMAT,
  7250. "Illegal zisofs block pointers(cannot seek)");
  7251. return (ARCHIVE_FATAL);
  7252. }
  7253. bed = archive_le32dec(
  7254. zisofs->block_pointers + zisofs->block_off + 4);
  7255. if (bed < bst) {
  7256. archive_set_error(&a->archive,
  7257. ARCHIVE_ERRNO_FILE_FORMAT,
  7258. "Illegal zisofs block pointers");
  7259. return (ARCHIVE_FATAL);
  7260. }
  7261. zisofs->block_avail = bed - bst;
  7262. zisofs->block_off += 4;
  7263. /* Initialize compression library for new block. */
  7264. if (zisofs->stream_valid)
  7265. r = inflateReset(&zisofs->stream);
  7266. else
  7267. r = inflateInit(&zisofs->stream);
  7268. if (r != Z_OK) {
  7269. archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
  7270. "Can't initialize zisofs decompression.");
  7271. return (ARCHIVE_FATAL);
  7272. }
  7273. zisofs->stream_valid = 1;
  7274. zisofs->stream.total_in = 0;
  7275. zisofs->stream.total_out = 0;
  7276. }
  7277. /*
  7278. * Make uncompressed data.
  7279. */
  7280. if (zisofs->block_avail == 0) {
  7281. /*
  7282. * It's basically 32K bytes NUL data.
  7283. */
  7284. unsigned char *wb;
  7285. size_t size, wsize;
  7286. size = zisofs->uncompressed_buffer_size;
  7287. while (size) {
  7288. wb = wb_buffptr(a);
  7289. if (size > wb_remaining(a))
  7290. wsize = wb_remaining(a);
  7291. else
  7292. wsize = size;
  7293. memset(wb, 0, wsize);
  7294. r = wb_consume(a, wsize);
  7295. if (r < 0)
  7296. return (r);
  7297. size -= wsize;
  7298. }
  7299. } else {
  7300. zisofs->stream.next_in = (Bytef *)(uintptr_t)(const void *)p;
  7301. if (avail > zisofs->block_avail)
  7302. zisofs->stream.avail_in = zisofs->block_avail;
  7303. else
  7304. zisofs->stream.avail_in = (uInt)avail;
  7305. zisofs->stream.next_out = wb_buffptr(a);
  7306. zisofs->stream.avail_out = (uInt)wb_remaining(a);
  7307. r = inflate(&zisofs->stream, 0);
  7308. switch (r) {
  7309. case Z_OK: /* Decompressor made some progress.*/
  7310. case Z_STREAM_END: /* Found end of stream. */
  7311. break;
  7312. default:
  7313. archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
  7314. "zisofs decompression failed (%d)", r);
  7315. return (ARCHIVE_FATAL);
  7316. }
  7317. avail -= zisofs->stream.next_in - p;
  7318. zisofs->block_avail -= (uint32_t)(zisofs->stream.next_in - p);
  7319. r = wb_consume(a, wb_remaining(a) - zisofs->stream.avail_out);
  7320. if (r < 0)
  7321. return (r);
  7322. }
  7323. zisofs->pz_offset += (uint32_t)bytes;
  7324. return (bytes - avail);
  7325. }
  7326. static int
  7327. zisofs_rewind_boot_file(struct archive_write *a)
  7328. {
  7329. struct iso9660 *iso9660 = a->format_data;
  7330. struct isofile *file;
  7331. unsigned char *rbuff;
  7332. ssize_t r;
  7333. size_t remaining, rbuff_size;
  7334. struct zisofs_extract zext;
  7335. int64_t read_offset, write_offset, new_offset;
  7336. int fd, ret = ARCHIVE_OK;
  7337. file = iso9660->el_torito.boot->file;
  7338. /*
  7339. * There is nothing to do if this boot file does not have
  7340. * zisofs header.
  7341. */
  7342. if (file->zisofs.header_size == 0)
  7343. return (ARCHIVE_OK);
  7344. /*
  7345. * Uncompress the zisofs'ed file contents.
  7346. */
  7347. memset(&zext, 0, sizeof(zext));
  7348. zext.pz_uncompressed_size = file->zisofs.uncompressed_size;
  7349. zext.pz_log2_bs = file->zisofs.log2_bs;
  7350. fd = iso9660->temp_fd;
  7351. new_offset = wb_offset(a);
  7352. read_offset = file->content.offset_of_temp;
  7353. remaining = (size_t)file->content.size;
  7354. if (remaining > 1024 * 32)
  7355. rbuff_size = 1024 * 32;
  7356. else
  7357. rbuff_size = remaining;
  7358. rbuff = malloc(rbuff_size);
  7359. if (rbuff == NULL) {
  7360. archive_set_error(&a->archive, ENOMEM, "Can't allocate memory");
  7361. return (ARCHIVE_FATAL);
  7362. }
  7363. while (remaining) {
  7364. size_t rsize;
  7365. ssize_t rs;
  7366. /* Get the current file pointer. */
  7367. write_offset = lseek(fd, 0, SEEK_CUR);
  7368. /* Change the file pointer to read. */
  7369. lseek(fd, read_offset, SEEK_SET);
  7370. rsize = rbuff_size;
  7371. if (rsize > remaining)
  7372. rsize = remaining;
  7373. rs = read(iso9660->temp_fd, rbuff, rsize);
  7374. if (rs <= 0) {
  7375. archive_set_error(&a->archive, errno,
  7376. "Can't read temporary file(%jd)", (intmax_t)rs);
  7377. ret = ARCHIVE_FATAL;
  7378. break;
  7379. }
  7380. remaining -= rs;
  7381. read_offset += rs;
  7382. /* Put the file pointer back to write. */
  7383. lseek(fd, write_offset, SEEK_SET);
  7384. r = zisofs_extract(a, &zext, rbuff, rs);
  7385. if (r < 0) {
  7386. ret = (int)r;
  7387. break;
  7388. }
  7389. }
  7390. if (ret == ARCHIVE_OK) {
  7391. /*
  7392. * Change the boot file content from zisofs'ed data
  7393. * to plain data.
  7394. */
  7395. file->content.offset_of_temp = new_offset;
  7396. file->content.size = file->zisofs.uncompressed_size;
  7397. archive_entry_set_size(file->entry, file->content.size);
  7398. /* Set to be no zisofs. */
  7399. file->zisofs.header_size = 0;
  7400. file->zisofs.log2_bs = 0;
  7401. file->zisofs.uncompressed_size = 0;
  7402. r = wb_write_padding_to_temp(a, file->content.size);
  7403. if (r < 0)
  7404. ret = ARCHIVE_FATAL;
  7405. }
  7406. /*
  7407. * Free the resource we used in this function only.
  7408. */
  7409. free(rbuff);
  7410. free(zext.block_pointers);
  7411. if (zext.stream_valid && inflateEnd(&(zext.stream)) != Z_OK) {
  7412. archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
  7413. "Failed to clean up compressor");
  7414. ret = ARCHIVE_FATAL;
  7415. }
  7416. return (ret);
  7417. }
  7418. #else
  7419. static int
  7420. zisofs_write_to_temp(struct archive_write *a, const void *buff, size_t s)
  7421. {
  7422. (void)buff; /* UNUSED */
  7423. (void)s; /* UNUSED */
  7424. archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, "Programming error");
  7425. return (ARCHIVE_FATAL);
  7426. }
  7427. static int
  7428. zisofs_rewind_boot_file(struct archive_write *a)
  7429. {
  7430. struct iso9660 *iso9660 = a->format_data;
  7431. if (iso9660->el_torito.boot->file->zisofs.header_size != 0) {
  7432. archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
  7433. "We cannot extract the zisofs imaged boot file;"
  7434. " this may not boot in being zisofs imaged");
  7435. return (ARCHIVE_FAILED);
  7436. }
  7437. return (ARCHIVE_OK);
  7438. }
  7439. static int
  7440. zisofs_finish_entry(struct archive_write *a)
  7441. {
  7442. (void)a; /* UNUSED */
  7443. return (ARCHIVE_OK);
  7444. }
  7445. static int
  7446. zisofs_free(struct archive_write *a)
  7447. {
  7448. (void)a; /* UNUSED */
  7449. return (ARCHIVE_OK);
  7450. }
  7451. #endif /* HAVE_ZLIB_H */